Compare commits

...

523 Commits

Author SHA1 Message Date
nym21 50bfdb0d68 release: v0.0.70 2025-06-24 23:53:30 +02:00
nym21 a6cb09ff1c fetcher: fix brk url 2025-06-24 23:53:10 +02:00
nym21 e4c9f23476 release: v0.0.69 2025-06-24 13:23:14 +02:00
nym21 44e5415d43 vec: undo storing file in struct, can overwhelm system 2025-06-24 13:20:44 +02:00
nym21 1c653693ed release: v0.0.68 2025-06-24 12:19:07 +02:00
nym21 39c470ad7a core: increase max open files limit 2025-06-24 12:18:49 +02:00
nym21 1103e538a5 release: v0.0.67 2025-06-24 11:57:25 +02:00
nym21 c0cd4cba6f global: snapshot 2025-06-24 11:56:54 +02:00
nym21 b91120e8d4 readme: update 2025-06-24 08:42:40 +00:00
nym21 005774a4c2 mcp: update readme 2025-06-24 08:41:08 +00:00
nym21 16bbfebfba changelog: update titles 2025-06-24 08:26:01 +00:00
nym21 15505cd82d web: fix index type imports 2025-06-24 10:23:16 +02:00
nym21 016d80e002 server: use etag for vecs instead of date modified 2025-06-24 10:11:03 +02:00
nym21 0f3c267a48 global: rename some indexes 2025-06-23 22:00:09 +02:00
nym21 589bb02411 vec: single file with header 2025-06-23 20:48:00 +02:00
nym21 c0f4ece17b mcp: part 2 2025-06-21 20:34:14 +02:00
nym21 c3ae3cb768 server: mcp + global: refactor 2025-06-21 12:43:14 +02:00
nym21 c9e0f9d985 query: remove dup 'h' short index 2025-06-19 14:16:24 +02:00
nym21 e3431c2fa3 release: v0.0.66 2025-06-19 12:32:04 +02:00
nym21 5979b9771e global: cointime part 1 2025-06-19 12:29:34 +02:00
nym21 aa61832fb2 web: fix options cmumulative possible vecids type 2025-06-18 10:14:09 +02:00
nym21 2ac6e982b1 computer: cumulative destroyed coinblocks and cointime 2025-06-18 10:13:33 +02:00
nym21 3204ddcf07 pr: merge #18 from StevenBlack/typos
Minor refinements to the brk_cli readme
2025-06-17 23:06:32 +02:00
nym21 c87b1c133c release: v0.0.65 2025-06-17 22:30:32 +02:00
nym21 9b275ecdae web: fix hang when candles fetched are slightly diff than before 2025-06-17 22:30:11 +02:00
Steven Black d6fd7de361 Minor refinements to the brk_cli readme
* Fix typos
* Rephrasing some descriptions
* Links to run command parameters now link to the code as it is in blob  49d66a133e specifically.
* Lightly introduce some nice features of Github flavored markdown (IMPORTANT and TIP) to assess how this nuance is received by maintainers.
2025-06-17 14:07:03 -04:00
nym21 49d66a133e release: v0.0.64 2025-06-17 18:49:17 +02:00
nym21 c559f26d0e global: add a bunch of realized datasets + charts 2025-06-17 18:47:04 +02:00
nym21 bbe9f1bad2 global: 4y zscore + 200d sma + mayer's multiple 2025-06-17 10:01:49 +02:00
nym21 7e1fb6472d release: v0.0.63 2025-06-16 23:46:57 +02:00
nym21 0ff8d20573 web: fix the fix for the stutter + pwa assets 2025-06-16 23:46:39 +02:00
nym21 9c1f9448dc release: v0.0.62 2025-06-16 18:56:59 +02:00
nym21 43a6081dd6 web: fix stutter on update and save default chart settings to url params 2025-06-16 18:56:38 +02:00
nym21 985e961876 web: fix error in lockdown safari + charts: update instead of setData when possible 2025-06-16 18:20:56 +02:00
nym21 098f6de047 release: v0.0.61 2025-06-15 17:30:49 +02:00
nym21 1b0f90fd68 release: v0.0.60 2025-06-15 17:27:41 +02:00
nym21 12252f407b computer: fix open of ohlc if fetched from different API than prev ohlc 2025-06-15 17:27:16 +02:00
nym21 3b6e3f47ab release: v0.0.59 2025-06-15 12:40:46 +02:00
nym21 6a9ac9b025 brk: fix bundler use + bundler: remove minify html crate 2025-06-15 12:39:50 +02:00
nym21 ae6aa4088b release: v0.0.58 2025-06-15 01:50:22 +02:00
nym21 c08f431180 bundler: deploy brk_rolldown + fix edge case 2025-06-15 01:50:01 +02:00
nym21 123c1f56e9 release: v0.0.57 2025-06-14 22:47:57 +02:00
nym21 35ac65a864 server: update cache control for bundled websites 2025-06-14 22:47:26 +02:00
nym21 e9f362cc87 bundler: init working version 2025-06-14 20:17:49 +02:00
nym21 65685c23e1 release: v0.0.56 2025-06-13 18:03:28 +02:00
nym21 2f74748cea computer: stateful: reset when reorg detected 2025-06-13 18:03:09 +02:00
nym21 f477bd66f3 release: v0.0.55 2025-06-13 10:23:38 +02:00
nym21 d7d77ae8f0 global: multiple fixes 2025-06-13 10:22:03 +02:00
nym21 31110a740d release: v0.0.54 2025-06-12 22:18:36 +02:00
nym21 b64d8b1d7f release: v0.0.53 2025-06-12 22:16:33 +02:00
nym21 c46006aacc web: filter possible index choices in charts 2025-06-12 22:09:33 +02:00
nym21 92f81b1493 web: fix css 2025-06-12 20:23:23 +02:00
nym21 70213cfc8f websites: default: add auto price series type 2025-06-12 18:41:56 +02:00
nym21 8a82bf5c50 websites: default: add live price 2025-06-12 18:10:24 +02:00
nym21 37405384a2 vec: fixed compressed, still slow par read, cli: made raw the default 2025-06-12 16:31:54 +02:00
nym21 54ea6cc53b indexer: only raw format + global: fixes 2025-06-12 12:33:43 +02:00
nym21 339c00d815 release: v0.0.52 2025-06-11 21:19:41 +02:00
nym21 ea6b4dcde2 websites: default: remove scrollToSelected 2025-06-11 21:19:22 +02:00
nym21 2b84623d1e release: v0.0.51 2025-06-11 21:09:07 +02:00
nym21 c8b3afa56b websites: default: fix sw adn co 2025-06-11 21:08:42 +02:00
nym21 1348f3c24c release: v0.0.50 2025-06-11 18:11:22 +02:00
nym21 62208ce3e1 websites: default: fix minBarSpacing 2025-06-11 18:11:11 +02:00
nym21 813b2481de release: v0.0.49 2025-06-11 17:51:31 +02:00
nym21 27b924ba61 cargo: set full version of crates 2025-06-11 17:51:11 +02:00
nym21 b40170b8ce websites: default: snapshot 2025-06-11 17:45:17 +02:00
nym21 8bfa9d2734 websites: default: snapshot 2025-06-11 11:25:25 +02:00
nym21 c7cf76d4a8 websites: default: snapshot 2025-06-10 18:54:18 +02:00
nym21 dfd2969b3e websites: default: snapshot 2025-06-09 17:58:26 +02:00
nym21 0e1866fe1d release: v0.0.48 2025-06-09 13:53:33 +02:00
nym21 b9ae46b913 readme: update 2025-06-09 13:53:09 +02:00
nym21 06e7284055 websites: default: snapshot 2025-06-09 13:05:03 +02:00
nym21 93289e8fca release: v0.0.47 2025-06-08 20:35:36 +02:00
nym21 130d5057d4 server: readme: add index-t-value documentation 2025-06-08 20:35:26 +02:00
nym21 be492d5084 server: add support for /api/X-to-Y + fix query cli + add meta api endpoints 2025-06-08 20:30:53 +02:00
nym21 e0bf1d736f query: add count param 2025-06-08 18:26:59 +02:00
nym21 5a6b71cbeb server: add ddos protection 2025-06-08 17:06:36 +02:00
nym21 e6934cd5e2 release: v0.0.46 2025-06-08 16:06:27 +02:00
nym21 b5aada0792 websites: mv sw to root 2025-06-08 16:05:21 +02:00
nym21 165ea83ac3 websites: update service worker 2025-06-08 13:03:37 +02:00
nym21 440a82dee4 release: v0.0.45 2025-06-08 09:11:31 +02:00
nym21 9c2d3e5e26 server: fix existing folder endpoints 2025-06-08 09:10:55 +02:00
nym21 6fb6abcbe5 release: v0.0.44 2025-06-07 18:53:51 +02:00
nym21 dc449dafd1 websites: default: up deps + fix css 2025-06-07 18:53:34 +02:00
nym21 ecdaeebbfb release: v0.0.43 2025-06-07 13:48:25 +02:00
nym21 fa958b59bd fetcher: support new api 2025-06-07 13:48:07 +02:00
nym21 fb3d8521cd computer: coinblocks fix overflow 2025-06-07 13:29:08 +02:00
nym21 608c401cf3 release: v0.0.42 2025-06-07 10:40:32 +02:00
nym21 1c3da90a24 release: v0.0.41 2025-06-07 10:31:36 +02:00
nym21 34567f3375 changelog: reset last 2025-06-07 10:31:07 +02:00
nym21 51bcbeb48f global: multiple fixes 2025-06-07 09:30:42 +02:00
nym21 cc0f9c42df global: snapshot 2025-06-06 16:08:20 +02:00
nym21 a11bf5523b global: wip 2025-06-06 12:23:45 +02:00
nym21 1921c3d901 global: wip 2025-06-06 10:46:38 +02:00
nym21 d568469e8b global: works but data is wrong 2025-06-04 17:01:16 +02:00
nym21 20d5c7e8d5 global: wip + fixed eager mode 2025-06-03 17:49:20 +02:00
nym21 9f289ed9de global: wip 2025-06-03 10:11:51 +02:00
nym21 93ee5e480b global: wip 2025-06-02 18:22:42 +02:00
nym21 98a312701f computer: more frequent flushes 2025-06-01 16:11:13 +02:00
nym21 cbcf603b63 global: wip 2025-06-01 14:37:19 +02:00
nym21 f976f672cf global: wip 2025-05-31 20:45:59 +02:00
nym21 cfc3081e8a global: snapshot 2025-05-29 10:39:58 +02:00
nym21 99818924ee global: snapshot 2025-05-28 16:53:18 +02:00
nym21 9bbf3a027f global: snapshot 2025-05-28 15:42:55 +02:00
nym21 93e01902e3 global: snapshot 2025-05-27 15:19:53 +02:00
nym21 34919aba05 global: versions 2025-05-26 11:34:37 +02:00
nym21 a8ee4cf57f release: v0.0.40 2025-05-25 13:38:48 +02:00
nym21 b39548b4c6 core: fix eq and cmp of float structs 2025-05-25 12:35:52 +02:00
nym21 4217c22ff6 global: utxos part 8 2025-05-25 00:27:18 +02:00
nym21 4ab10670c9 global: utxos part 7 2025-05-24 12:52:15 +02:00
nym21 2883f88de6 global: utxos part 6 2025-05-23 17:52:01 +02:00
nym21 e002a61a19 global: utxos part 5 2025-05-22 19:04:55 +02:00
nym21 5893376279 global: utxos part 4 2025-05-19 17:53:09 +02:00
nym21 411c5e4c4d global: snapshot 2025-05-18 17:28:09 +02:00
nym21 c2a77072d2 global: utxos part 3 2025-05-18 11:52:14 +02:00
nym21 c8a25934a6 global: utxos part 2 2025-05-17 19:51:52 +02:00
nym21 7b38355cd4 release: v0.0.39 2025-05-16 23:37:51 +02:00
nym21 ddc54e0b98 release: v0.0.38 2025-05-16 23:34:32 +02:00
nym21 8a7003782b global: utxos dataset part 1 2025-05-16 23:33:19 +02:00
nym21 8e6464dacb release: v0.0.37 2025-05-14 11:28:38 +02:00
nym21 92b1dc0afb global: dca classes 2025-05-14 11:28:18 +02:00
nym21 7562f51e07 release: v0.0.36 2025-05-13 13:01:32 +02:00
nym21 09bba99e68 kibo: add priceline 2025-05-13 13:01:11 +02:00
nym21 9d674cd49b global: snapshot 2025-05-13 11:46:03 +02:00
nym21 88a0c9ea03 global: returns (lump sum vs dca) 2025-05-13 01:27:21 +02:00
nym21 5014e0ce3e release: v0.0.35 2025-05-12 12:56:08 +02:00
nym21 b7a1ee9ebc global: averages + ratio datasets 2025-05-12 12:55:40 +02:00
nym21 292ceddd66 comp + kibo: add market smas 2025-05-10 13:17:51 +02:00
nym21 4b52b80000 release: v0.0.34 2025-05-09 21:35:07 +02:00
nym21 9f20664c6e global: add some market charts 2025-05-09 16:04:54 +02:00
nym21 851a6aac0e release: v0.0.33 2025-05-08 12:53:19 +02:00
nym21 1f1e73c47a vec: computed: fix eager path + delete path if lazy 2025-05-08 12:31:31 +02:00
nym21 112f61ca18 release: v0.0.32 2025-05-08 11:17:35 +02:00
nym21 96eeacbe2b lazy: done 2025-05-08 11:15:47 +02:00
nym21 3f62da879c comp + lazy: part 6 2025-05-06 12:23:37 +02:00
nym21 aa30feb875 comp + vec: snapshot before bug hunting 2025-05-06 00:44:39 +02:00
nym21 9ba3c2b7c5 global: big vec refactor + lazy 2025-05-05 12:47:52 +02:00
nym21 320c708e10 computer: lazy part 4 2025-05-03 17:28:48 +02:00
nym21 efa7294f59 computer: lazy part 3 2025-05-03 11:44:33 +02:00
nym21 ae0e092935 computer: lazy part 2 2025-05-01 20:52:39 +02:00
nym21 c77aecbfce computer: lazy part 1 2025-05-01 17:25:59 +02:00
nym21 700352ec45 vec: caching only in iter 2025-04-30 18:29:18 +02:00
nym21 664b125ce2 release: v0.0.31 2025-04-30 01:12:28 +02:00
nym21 5f4b1c9e32 global: fixes 2025-04-30 01:11:42 +02:00
nym21 d11d3f19bd fix: old X links that now directed to impersonater 2025-04-29 15:04:59 +02:00
nym21 f34f4f2738 computer: remove last indexes 2025-04-29 15:02:41 +02:00
nym21 15db7c2310 computer: use count instead of last_index 2025-04-29 11:33:14 +02:00
nym21 f9257ed04d global: vec iter part 2 2025-04-28 18:30:11 +02:00
nym21 15e6ef8488 computer: remove the need for &mut vecs 2025-04-28 11:21:28 +02:00
nym21 9ae0a57f22 global: snapshot 2025-04-27 16:29:21 +02:00
nym21 1e38c21f8e vec: make collect_range use into_iter 2025-04-27 10:39:14 +02:00
nym21 bdc3c19163 vec: iter + global: snapshot 2025-04-27 00:21:21 +02:00
nym21 d55478da54 kibo: remove old packages versions 2025-04-26 17:28:41 +02:00
nym21 82bcc55645 global: fixes + snapshot + packages 2025-04-26 17:22:58 +02:00
nym21 07618ebe43 global: renames + refactor + p2a support 2025-04-25 18:16:23 +02:00
nym21 1492834d1e fjall: use a single keyspace for all stores + core: locktime -> rawlocktime 2025-04-24 15:59:13 +02:00
nym21 5ab6197356 computer: init lazy/eager 2025-04-23 22:36:10 +02:00
nym21 0a789fe551 release: v0.0.30 2025-04-23 00:07:41 +02:00
nym21 caa8ff23ed kibo: fix charts data fetch 2025-04-23 00:04:09 +02:00
nym21 ee30d1d36d release: v0.0.29 2025-04-22 19:34:55 +02:00
nym21 0d9415db9d kibo: fix add ts-ignore 2025-04-22 19:33:57 +02:00
nym21 8020e1126f kibo: database: part 2 2025-04-22 19:31:30 +02:00
nym21 3439422057 kibo: database: part 1 2025-04-21 23:17:37 +02:00
nym21 68d2bf736f release: v0.0.28 2025-04-19 11:46:05 +02:00
nym21 d78c39fd8c computer + kibo: part 14 - fixes 2025-04-19 11:45:26 +02:00
nym21 b1dcad86b4 release: v0.0.27 2025-04-18 19:41:13 +02:00
nym21 9b6124074d dist: another fix 2025-04-18 19:40:09 +02:00
nym21 02cbaa1e80 release: v0.0.26 2025-04-18 19:00:19 +02:00
nym21 a12f1321c7 dist: fix format tag version 2025-04-18 18:59:53 +02:00
nym21 8b67f592ac release: v0.0.25 2025-04-18 18:48:10 +02:00
nym21 319d17b337 dist: fix ubuntu version 2025-04-18 18:45:27 +02:00
nym21 476eaa85da github: add manual trigger 2025-04-18 18:37:51 +02:00
nym21 d26099855c dist: update ubuntu version 2025-04-18 18:36:18 +02:00
nym21 e47456da17 release: v0.0.24 2025-04-18 18:22:23 +02:00
nym21 a464d5d0b6 crates: upgrade 2025-04-18 18:20:40 +02:00
nym21 1cfb7b5615 computer + kibo: part 13 2025-04-18 18:08:11 +02:00
nym21 ac7c2f3d03 kibo: cleanup 2025-04-17 17:06:44 +02:00
nym21 638d9e6e01 computer: part 12 2025-04-17 15:22:34 +02:00
nym21 8b9df2a396 parser: readme 2025-04-15 14:40:56 +02:00
nym21 d7fe911bde parser: readme 2025-04-15 11:56:50 +02:00
nym21 0acc3d511b parser: readme 2025-04-15 11:27:48 +02:00
nym21 4cf465f419 computer: unwrap 2025-04-15 11:18:31 +02:00
nym21 b686d317a9 release: v0.0.23 2025-04-14 22:22:19 +02:00
nym21 dcef541852 release: v0.0.22 2025-04-14 21:57:15 +02:00
nym21 abdd733f11 deps: upgrade 2025-04-14 21:56:47 +02:00
nym21 942431e882 computer + kibo: part 11 2025-04-14 16:27:22 +02:00
nym21 1c75ea046c computer + kibo: part 10 2025-04-11 19:21:35 +02:00
nym21 f32b6daa51 release: v0.0.21 2025-04-11 12:01:30 +02:00
nym21 3736d6ba5e computer + kibo: part 9 2025-04-11 12:00:26 +02:00
nym21 9788b01f35 readmes: update discord link yet again 2025-04-10 22:57:09 +02:00
nym21 9aec991da6 release: v0.0.20 2025-04-10 21:39:34 +02:00
nym21 910701ce04 cleanup: old files 2025-04-10 21:39:12 +02:00
nym21 34b462d511 global: snapshot 2025-04-10 21:38:39 +02:00
nym21 139e93b2f0 vec: rework part 4 2025-04-10 15:55:26 +02:00
nym21 0dd7e9359e vec: rework part 3 2025-04-10 01:11:52 +02:00
nym21 41cf0225e3 vec: rework part 2 2025-04-09 22:59:18 +02:00
nym21 962254e511 vec: rework part 1 2025-04-09 16:31:31 +02:00
nym21 a7f2b24bac comp + vec: tiny opti 2025-04-08 15:38:20 +02:00
nym21 1323d988af computer + kibo: part 8 2025-04-08 11:40:35 +02:00
nym21 7c49e5c749 release: v0.0.19 2025-04-07 15:48:39 +02:00
nym21 cd69ec4fa3 computer: part 7 2025-04-07 15:48:00 +02:00
nym21 4c7e9fbee2 computer: part 6 2025-04-07 12:18:18 +02:00
nym21 1639df5616 computer: part 5 2025-04-06 12:01:45 +02:00
nym21 810cdbd790 chore: Release 2025-04-05 12:13:31 +02:00
nym21 0d4f4aec4e computer: part 4 2025-04-05 12:12:55 +02:00
nym21 6b1863d3b4 chore: Release 2025-04-05 00:58:50 +02:00
nym21 27f5a3b16b dist: move config to config.toml 2025-04-05 00:55:22 +02:00
nym21 876cd8291b disk: init 2025-04-05 00:33:31 +02:00
nym21 d0c46e4ef3 server: yet another fix + release: v0.0.16 2025-04-04 19:20:28 +02:00
nym21 feb8898ebf server: forgot a 'v' + release: v0.0.15 2025-04-04 18:59:49 +02:00
nym21 4fef8c5cfd release: v0.0.14 2025-04-04 18:49:41 +02:00
nym21 7d56d8e35b server: fix downloaded repo version path 2025-04-04 18:49:21 +02:00
nym21 5f1a3a9c8f release: v0.0.13 2025-04-04 18:31:31 +02:00
nym21 0767b3156d global: snapshot 2025-04-04 18:31:10 +02:00
nym21 9f16379b41 readme: add warning 2025-04-04 18:23:03 +02:00
nym21 be632aaf37 kibo: fix simulation 2025-04-04 17:44:22 +02:00
nym21 118c87faf7 kibo: snapshot 2025-04-04 11:30:59 +02:00
nym21 ec1e53d566 kibo: finished converting ts types to jsdoc 2025-04-04 10:54:44 +02:00
nym21 6a17ee414a kibo: move types around 2025-04-04 00:40:40 +02:00
nym21 6700686e4b website: signals: upgrade to tresshaked v0.2.4 2025-04-03 15:15:55 +02:00
nym21 e8c34dd59b global: snapshot 2025-04-03 14:31:39 +02:00
nym21 4c2da31bb3 server: version repo url when not in dev mode 2025-04-02 16:49:35 +02:00
nym21 c0144b99bf release: v0.0.12 2025-04-02 16:45:19 +02:00
nym21 a0c32fc146 server: api doc 2025-04-02 16:43:31 +02:00
nym21 a07b641adb global: snapshot 2025-04-02 16:20:17 +02:00
nym21 0bb869fb33 kibo: changed font from satoshi to geist 2025-04-01 23:46:25 +02:00
nym21 72389e0129 readmes: update 2025-04-01 00:24:27 +02:00
nym21 f49529fa70 release: v0.0.11 2025-03-31 18:52:39 +02:00
nym21 afcc34b5cc readmes: add shields 2025-03-31 18:52:16 +02:00
nym21 655b99cac8 server: add not_modified check when no 'to' param 2025-03-31 17:19:33 +02:00
nym21 cc5091e28c kibo: part 5 2025-03-31 17:17:34 +02:00
nym21 1c72362c6b kibo: part 4 2025-03-31 10:02:59 +02:00
nym21 50ad5f681b kibo: part 3 (broken) 2025-03-29 13:01:46 +01:00
nym21 50bf670931 kibo: part 2 (broken) 2025-03-25 20:55:47 +01:00
nym21 7a8896864f kibo: part 1.1 2025-03-21 17:17:04 +01:00
nym21 51fbf148d9 kibo: part 1 2025-03-21 16:59:39 +01:00
nym21 a9929438cd computer: part 3 2025-03-21 11:45:23 +01:00
nym21 5a94b6b56c cargo: update crates 2025-03-20 21:40:57 +01:00
nym21 52cfbf60d4 computer: part 2 2025-03-20 21:40:06 +01:00
nym21 29c10f8854 computer: part 1 2025-03-19 12:01:54 +01:00
nym21 ad761e388d READMEs: updated 2025-03-17 09:55:06 +01:00
nym21 07493ab0a6 README: add badges 2025-03-15 17:51:54 +01:00
nym21 7441011ae7 pr: merge #17 from aki-mizu/main
Merge pull request #17 from aki-mizu/main
fix old biter link in README
2025-03-15 15:18:32 +00:00
Darrell d0818f456d fix biter link 2025-03-16 00:10:25 +09:00
nym21 06ea07a021 release: v0.0.9 2025-03-14 20:55:21 +01:00
nym21 36d97ad5ca compression: added everywhere 2025-03-14 18:10:03 +01:00
nym21 a995eb2929 vec: compression part 2 and done 2025-03-14 16:00:47 +01:00
nym21 c459a3033d vec: compression part 1 2025-03-13 17:11:04 +01:00
nym21 b4fbcf6bee global: snapshot 2025-03-11 17:55:14 +01:00
nym21 b9e679a514 vec: moved compute functions to computer 2025-03-11 16:27:45 +01:00
nym21 64d73b93e4 global: snapshot 2025-03-11 15:36:40 +01:00
nym21 db70b05088 global: snapshot 2025-03-10 23:08:07 +01:00
nym21 9428beeae5 global: snapshot 2025-03-10 11:42:15 +01:00
nym21 f9f7172702 brk: use brk_cli::main as bin 2025-03-07 00:00:27 +01:00
nym21 f1851b304c server: server struct 2025-03-06 14:52:26 +01:00
nym21 d2ca6f1d46 server: use query for search 2025-03-05 16:55:37 +01:00
nym21 b27297cdc6 server: multiple frontends + auto download from github when needed 2025-03-05 12:22:11 +01:00
nym21 0d0edd7917 global: snapshot + core: impl Display for bytes structs 2025-03-04 12:29:19 +01:00
nym21 fc6f12fb22 general: fixed builds 2025-03-03 19:36:17 +01:00
nym21 d24096374f cli: add config for run command 2025-03-03 19:11:47 +01:00
nym21 4f1d04009a readme: update 2025-03-03 12:50:49 +01:00
nym21 79e9fde937 readme: updatre 2025-03-03 12:34:27 +01:00
nym21 0ebaf6a171 readme: update 2025-03-03 10:52:07 +01:00
nym21 be2012f28d cli + query: improvements 2025-03-02 20:15:01 +01:00
nym21 ceefc8ffc6 global: snapshot 2025-03-02 12:45:33 +01:00
nym21 0453b6903a vec: readme: removed example 2025-03-02 11:19:01 +01:00
nym21 691952249b readme: update 2025-03-02 11:08:53 +01:00
nym21 0ceae2852e query: init 2025-03-02 11:08:35 +01:00
nym21 6d7ff38cf2 global: snapshot 2025-03-01 15:22:34 +01:00
nym21 1b93ccf608 global: snapshot 2025-02-28 11:52:25 +01:00
nym21 5b1ca3711a kibo.money: cleaned packages 2025-02-27 12:34:45 +01:00
nym21 877f9299e1 global: snapshot 2025-02-27 12:32:54 +01:00
nym21 677aca7a03 indexer: rollback fixed via fjall v2.6.6 (conv on discord) 2025-02-27 00:50:35 +01:00
nym21 66b31a62d0 readme: add disclaimer 2025-02-26 12:59:35 +01:00
nym21 34923638c5 global: cargo update 2025-02-26 10:45:00 +01:00
nym21 bb61b3dc22 global: init readmes 2025-02-26 10:07:05 +01:00
nym21 01ecae8979 indexer: fixed Fjalls rollback 2025-02-24 18:15:13 +01:00
nym21 53175c9ed7 core: init 2025-02-24 14:08:51 +01:00
nym21 bc7a76755b git: removed old files 2025-02-24 00:53:57 +01:00
nym21 92758f3e4e Merge pull request #16 from bitcoinresearchkit/bkr-v0.0
Bkr v0.0
2025-02-23 23:47:39 +00:00
nym21 b09767c526 cargo: update descriptions 2025-02-24 00:43:50 +01:00
nym21 2f93fd7c36 global: crates cleanup 2025-02-24 00:25:58 +01:00
nym21 8acbcc548c parser: fixed hanging + global: snapshot 2025-02-23 21:53:39 +01:00
nym21 19cf34f9d4 brk: first commit 2025-02-23 01:25:15 +01:00
nym21 8c3f519016 iterator: add xor support 2025-02-22 14:06:43 +01:00
nym21 e63b42278c iterator: simplified 2025-02-21 20:12:57 +01:00
nym21 66ecd2fcf8 iterator: small changes 2025-02-20 13:11:23 +01:00
nym21 f0d86f2392 indexer: moved height to iterator 2025-02-20 11:40:26 +01:00
nym21 5e39510f21 general: snapshot 2025-02-19 21:43:18 +01:00
nym21 2cb4d65f3d indexer: update readme 2025-02-19 10:56:07 +01:00
nym21 15f2e05192 indexer: improved rollback; global: snapshot 2025-02-18 22:43:12 +01:00
nym21 a122333aaa indexer: rm canopy+sanakirja + init rollback; svec: added truncate 2025-02-15 12:04:20 +01:00
nym21 06b2186bf9 cargo: updated deps 2025-02-14 19:04:14 +01:00
nym21 ed10dccfe2 pricer: snapshot 2025-02-14 19:02:46 +01:00
nym21 a1006dddb5 global: snapshot 2025-02-13 19:00:52 +01:00
nym21 443a32dc81 server: cleanup 2025-02-13 11:10:34 +01:00
nym21 b034b4fe2f python: add read bytes from vec example 2025-02-12 17:22:36 +01:00
nym21 27b270148b server: add tsv support 2025-02-12 16:00:31 +01:00
nym21 269c64e4ed server: smart generic vec routes build 2025-02-12 14:11:04 +01:00
nym21 eaf76e27f5 struct_iterable: removed, seems not needed anymore 2025-02-12 00:06:46 +01:00
nym21 385b881068 server: added csv support to api 2025-02-11 23:38:01 +01:00
nym21 cf26696d12 global: snapshot 2025-02-11 19:01:30 +01:00
nym21 cb7ea40e7c server: started 2025-02-11 18:52:08 +01:00
nym21 5aaa55197e workspace: use folder name for packages 2025-02-05 23:42:48 +01:00
nym21 d86d614520 global: from custom unsafe_slice to zerocopy 2025-02-05 16:42:53 +01:00
nym21 138ca80c10 global: snapshot 2025-02-05 00:23:58 +01:00
nym21 d11a1622f8 storable_vec: add modes 2025-02-04 20:56:48 +01:00
nym21 42c996e16e global: snapshot 2025-02-02 23:55:05 +01:00
nym21 1e37d75e49 global: snapshot 2025-02-02 23:28:03 +01:00
nym21 ad34d9d402 bomputer: init 2025-01-31 11:43:14 +01:00
nym21 8c610f8a83 workspace: reorg 2025-01-28 17:45:36 +01:00
nym21 f7f3e3cc03 bindex: no copy fjall get + small fixes 2025-01-28 11:30:10 +01:00
nym21 d68c6f9f2e bindex: contained fjall code 2025-01-27 23:25:28 +01:00
nym21 90a5c4fbf8 bindex: retrying fjall 2025-01-27 12:49:19 +01:00
nym21 042be6e229 bindex: removed addressindex to in/out puts as they're computable later 2025-01-27 09:55:28 +01:00
nym21 4923c2e204 bindex: converted txindex_to_txoutindex_in to storable vecs 2025-01-26 17:42:47 +01:00
nym21 b94d94e116 bindex: snapshot 2025-01-25 22:46:11 +01:00
nym21 d629ae8fbb bindex: snapshot 2025-01-23 11:11:39 +01:00
nym21 1296a2e9ec general: massive update 2025-01-22 11:38:50 +01:00
nym21 009d02fa68 storable_vec: general update 2025-01-16 13:25:35 +01:00
nym21 4cc57e9c91 bindex: back to sanakirja 2025-01-14 23:35:42 +01:00
nym21 d373c6398e bitbase: renamed to bindex 2025-01-14 12:38:06 +01:00
nym21 82746a0669 bitbase: vecdisk 2025-01-14 12:32:27 +01:00
nym21 1212c3627b cargo: update fjall to v2.5 2025-01-09 20:53:04 +01:00
nym21 813f16ccee bitbase: small optimization 2025-01-09 00:13:52 +01:00
nym21 1c3cb91ecd bitbase: rayon done 2025-01-08 18:01:28 +01:00
nym21 5b1735db2b bitbase: pre-rayon snapshot 2025-01-07 12:15:58 +01:00
nym21 bf31ee5fd6 bitbase: move to transactional 2025-01-06 10:45:04 +01:00
nym21 1380b42c1d bitbase: snapshot 2025-01-03 21:34:10 +01:00
nym21 dea853d840 init: separate parser crate 2025-01-01 10:32:39 +01:00
nym21 d72bf0739a changelog: update 2024-12-27 12:33:09 +01:00
nym21 481f5c0a97 server: add support for dataset by timestamp 2024-12-27 12:28:27 +01:00
nym21 2b017ac6b5 website: lc: update to v4.2.2 2024-12-22 10:22:55 +01:00
nym21 8a733ee337 changelog: update 2024-12-22 09:39:27 +01:00
nym21 9dd87a48a6 server: rework api side 2024-12-22 00:42:11 +01:00
nym21 8fabbde13b global: small fixes 2024-12-17 10:39:28 +01:00
nym21 e0a378cb81 biter: fix ? 2024-12-14 17:39:42 +01:00
nym21 0b3329ca35 git: fix ignore file 2024-12-14 14:56:55 +01:00
nym21 50c77b51db snkrj: move database struct to its own crate 2024-12-14 14:55:44 +01:00
nym21 c883ed19d6 biter: readme: update 2024-12-13 19:57:08 +01:00
nym21 795791219e global: snapshot 2024-12-13 19:55:32 +01:00
nym21 f6f4660cd2 website: fix the previous fix 2024-12-13 16:08:59 +01:00
nym21 9576f6e91e website: fix window resize brave bug 2024-12-13 12:30:56 +01:00
nym21 f5e5bbefb2 changelog: update 2024-12-04 11:22:28 +01:00
nym21 d4323fb5e0 website: dca sim: improve reactivity 2024-12-04 11:15:18 +01:00
nym21 8af1ddd10d website: moved more code to lc wrapper 2024-12-04 10:28:30 +01:00
nym21 62f6d9a413 website: lc: moved markers to container 2024-12-03 19:04:21 +01:00
nym21 783aed5826 website: start containing lc code in wrapper 2024-12-03 17:31:56 +01:00
k 141cd819a1 website: reorg 2024-12-02 10:03:41 +01:00
k 44fa96eb49 website: sim: wording 2024-11-28 21:52:40 +01:00
k 778b514b65 website: simulation: fix sats added 2024-11-28 18:36:22 +01:00
k afd58d69e4 website: simulation: fix 'days ago' 2024-11-28 18:34:01 +01:00
k 4af9849b2b website: simulation: small changes 2024-11-28 18:31:15 +01:00
k 4dac44e720 website: simulation: small fixes 2024-11-28 15:58:11 +01:00
k 71871901ef website: update 2024-11-27 18:36:43 +01:00
k d39e7584c0 website: update 2024-11-27 12:56:04 +01:00
k 4e9c5612ca website: small fixes 2024-11-25 11:28:28 +01:00
k c8510dd45b changelog: update 2024-11-23 16:18:57 +01:00
k c234c17352 general: snapshot 2024-11-23 16:17:06 +01:00
k cfae483d9d parser: fix gnericmap multi_insert_simple_average 2024-11-20 11:42:06 +01:00
k d01ea13de4 global: snapshot 2024-11-20 10:50:14 +01:00
k 9a73ee6952 readme: fix link 2024-11-15 13:44:14 +01:00
k 28eb9e8c17 readme: update 2024-11-15 13:41:16 +01:00
k 749c91f662 readme: removed the fluff 2024-11-15 13:15:30 +01:00
k 97ac17a12a website: delete useless logs 2024-11-11 15:23:07 +01:00
k 32fd4fa8ed website: big update 2024-11-11 15:20:31 +01:00
k 12fe4c6ba5 parser: fix metadata bug 2024-11-08 22:53:39 +01:00
k b1e9fd95ca readme: typos 2024-11-05 09:36:49 +01:00
k d83043d8f2 server: readd content disposition attachement if ext present 2024-11-04 12:44:15 +01:00
k 2abeca6220 readme: update 2024-11-04 12:35:48 +01:00
k 781810ed9c parser: databases: small changes 2024-11-04 11:09:54 +01:00
k 2142847de3 website: moved packages + added ratio charts to compare folders 2024-11-02 12:42:40 +01:00
k ca42c266ef website: update cohorts colors 2024-11-02 00:59:57 +01:00
k f258ef1011 website: readd ratio to individual cohort folders 2024-11-01 20:52:43 +01:00
k 38cb763fd3 website: add compare to liquidity 2024-11-01 20:47:23 +01:00
k 3fa78241ef parser: exit inside global defrag 2024-11-01 20:23:06 +01:00
k 3c7bc13be9 Merge branch 'main' of github.com:kibo-money/kibo 2024-11-01 20:20:54 +01:00
k 2441ca35b3 website: up signals + added compare folder to all groups 2024-11-01 20:19:43 +01:00
k 216a3977be parser: reactivate 'first_defragment' option 2024-10-31 11:39:36 +01:00
k 647a51af15 parser: fix defrag 2024-10-31 09:57:06 +01:00
k 530d4ce717 general: temp rollback 2024-10-30 19:22:42 +01:00
k e5d81b4d5c parser: added databases defragmentation 2024-10-30 19:13:41 +01:00
k 6eaeca1f3d parser: db: improve iter function 2024-10-29 19:38:52 +01:00
k 4220034eab parser: crates upgrade && remove ram from config 2024-10-29 15:22:44 +01:00
k 76a8ddd354 server: tried oxc vs swc, kept swc 2024-10-29 14:40:12 +01:00
k 0bad38a815 iterable: added custom version 2024-10-28 16:51:20 +01:00
k 48a8aad20e parser: AnyDataset DX improvements 2024-10-28 16:48:27 +01:00
k 36ad0b3014 parser: revert save logic 2024-10-27 12:10:22 +01:00
k 95fc103eaf parser: fix metadata versioning 2024-10-27 10:52:42 +01:00
k f5754780a8 global: snapshot 2024-10-26 16:41:38 +02:00
k 7114c3bdf9 general: fixes 2024-10-21 14:36:02 +02:00
k 5b9d599e83 global: snapshot 2024-10-20 18:31:43 +02:00
k ffa4871035 readme: update instances 2024-10-19 11:49:01 +02:00
k 01832ac139 server: add .json option to last value routes 2024-10-19 11:04:32 +02:00
k cb7ff2bb37 changelog: update 2024-10-19 10:46:00 +02:00
k 35dd194b28 general: snapshot 2024-10-19 10:34:12 +02:00
k 7dac857135 docker: snapshot 2024-10-17 19:53:00 +02:00
k 608ccafc70 server: add support for .json .csv and ?all=true 2024-10-16 18:38:43 +02:00
k 4cdc9ef9b3 changelog: update 2024-10-09 00:39:25 +02:00
k db60d4e453 parser: compress empty_address_data 2024-10-09 00:33:14 +02:00
k f5d427a04f parser: cargo cleanup 2024-10-08 22:37:36 +02:00
k e4893e446c cargo: update 2024-10-08 21:53:38 +02:00
k 79ffbf3d1d global: snapshot 2024-10-08 21:47:46 +02:00
k 068bb07d6e global: snapshot 2024-10-04 19:09:09 +02:00
k 1c9d118ba2 changelog: update 2024-10-03 18:37:00 +02:00
k 5308796bac parser: removed liquidity split for everything but all addresses 2024-10-03 17:38:43 +02:00
k 669205aa4d general: snapshot 2024-10-02 10:48:05 +02:00
k 9d2c2f7945 global: snapshot 2024-09-29 20:39:51 +02:00
k e3b44b0adb website: refactor 2024-09-24 17:13:29 +02:00
k 1a303a9c38 docker: init 2024-09-23 18:44:55 +02:00
k 2befa58fce global: add sell side risk ratio 2024-09-21 14:22:27 +02:00
k c8ded4ddb3 general: add /api/last route 2024-09-20 16:56:36 +02:00
k 7d211f74d1 website: fixes 2024-09-19 21:48:54 +02:00
k 0f95d41785 website: rm history log 2024-09-19 21:11:37 +02:00
k 6389b530d9 changelog: hide broken image links 2024-09-19 21:10:11 +02:00
k 412769ff03 general: fixes 2024-09-19 21:03:50 +02:00
k d2349741f7 changelog: update 2024-09-19 11:24:13 +02:00
k 821bf8d63a readme: update 2024-09-19 11:01:08 +02:00
k 7b296e4863 parser: price fetch fixes 2024-09-19 10:49:26 +02:00
k 1acfcf088c readme: update 2024-09-18 20:15:32 +02:00
k e9680afdff readme: update 2024-09-18 19:31:33 +02:00
k 9695f12322 server: create in dir if missing 2024-09-18 18:43:36 +02:00
k 4060b7457b index: update geyser url 2024-09-18 18:35:19 +02:00
k a68344959d website: fix pathname on first load 2024-09-18 18:25:27 +02:00
k 41638d10bf server: add date-modified to datasets 2024-09-18 17:58:33 +02:00
k 9b4e166608 website: fixes 2024-09-18 16:56:55 +02:00
k 52a65fcad1 general: update 2024-09-18 00:14:53 +02:00
k da7c114d41 general: snapshot 2024-09-17 10:57:21 +02:00
k 62edee0860 readme 2024-09-17 00:22:51 +02:00
k 22ba5e7c94 assets: update 2024-09-16 23:45:24 +02:00
k 48e9a9c7dd website: add sw 2024-09-16 19:17:19 +02:00
k 9dbffb0c93 global: snapshot 2024-09-16 13:17:18 +02:00
k f95eb0f1c9 script: snapshot 2024-09-14 13:40:58 +02:00
k f3197c1af7 general: fixes 2024-09-14 11:47:02 +02:00
k 59f04c96c5 readme: update 2024-09-13 23:47:25 +02:00
k bf2034b80c global: snapshot 2024-09-13 22:59:20 +02:00
k deffaef2b5 rename: GUIDELINES to CONTRIBUTING 2024-09-11 22:52:53 +02:00
k 157ec003b7 remove: app 2024-09-11 22:47:26 +02:00
k ba4021ad73 global: snapshot 2024-09-10 23:15:13 +02:00
k 5edb8111a2 app: html version almost done 2024-09-10 09:39:06 +02:00
k e206b40468 general: snapshot 2024-08-26 01:23:48 +02:00
k 6ebd9320db app: folder reorg + tradingview notice 2024-08-08 17:11:58 +02:00
k 597a750fff app: unignore paths.d.ts to allow to run app without needing the server first 2024-08-08 09:48:36 +02:00
k 1273da6e71 changelog: update 2024-08-08 09:25:00 +02:00
k eb9b57eef4 parser: split txid_to_txdata db 2024-08-08 09:21:59 +02:00
k 5aaa05d579 parser: rm heed module 2024-08-06 19:52:59 +02:00
k 07abb0840b global: rm heed 2024-08-06 19:51:40 +02:00
k b8064510e3 parser: address_to_address_index: fix bad copy pasta 2024-08-05 12:07:20 +02:00
k a88d84e6e6 changelog: update 2024-08-05 11:58:17 +02:00
k c3c8f16793 parser: fix rpc call 2024-08-05 11:55:08 +02:00
k ce1fed8c16 parser: rm multisig db 2024-08-05 11:47:52 +02:00
k 9a8f5edd58 parser: fix binance time 2024-08-05 11:23:41 +02:00
k 992d45c8af server: update run.sh 2024-08-05 10:42:28 +02:00
k c646d6dc60 global: datasets compression via zstd 2024-08-05 00:44:46 +02:00
k 9067c28d24 parser: switch to biter 2024-08-03 15:17:57 +02:00
k afacea3fbb parser: reactivate bkp url for price fetching 2024-07-26 17:07:19 +02:00
k b68b016091 release: v0.3.0 2024-07-26 00:59:00 +02:00
k f1f4ad2188 global: fix: bugs 2024-07-26 00:44:17 +02:00
k d3d5e7f8d7 general: snapshot 2024-07-25 14:43:20 +02:00
k 0f8d7d5fe2 readme: add bkp api 2024-07-24 00:18:55 +02:00
k 63855e93a1 changelog: update v0.3.0 screenshot 2024-07-24 00:15:35 +02:00
k 07c1f5ab76 changelog: add v0.3.0 screenshot 2024-07-24 00:13:01 +02:00
k 4cd605fd34 global: update versions 2024-07-24 00:09:09 +02:00
k 8f5f28ede6 app: charts: add unit and price mode switch 2024-07-24 00:05:18 +02:00
k bf169d6954 app: add ivo to donators 2024-07-23 08:44:52 +02:00
k 1934c4bfda price: rm folder 2024-07-22 23:40:15 +02:00
k 5a7050df02 app: add chart scroll buttons 2024-07-22 19:06:58 +02:00
k 9871fdffc9 parser: add auto fetch price from main instance 2024-07-22 15:58:02 +02:00
k 232276d106 app: add height datasets 2024-07-22 11:08:58 +02:00
k 8b08a82f07 parser: add recap dataset 2024-07-21 22:59:54 +02:00
k 180d044f5d app: add SOPR 2024-07-21 00:51:36 +02:00
k 5611459f03 server: fix port 2024-07-20 23:18:49 +02:00
k 6eb4b51168 parser: cleanup 2024-07-20 23:15:36 +02:00
k a145b35ad1 general: snapshot 2024-07-20 23:13:41 +02:00
k d8a5b4a2e6 price: update 2024-07-20 13:32:58 +02:00
k 1f9d1542f1 parser: fix utxo panic after soft reset 2024-07-18 12:27:24 +02:00
k 4d23fdef61 general: snapshot 2024-07-18 09:16:18 +02:00
k fb978211ae price: push new 2024-07-16 11:48:41 +02:00
k 4fd67ebd99 app: add address size in sidebar when needed 2024-07-15 19:59:44 +02:00
k 0c899b2c16 parser: fix config file creation and remove panic 2024-07-15 19:43:37 +02:00
k 1be22713f9 parser: create config.toml if needed 2024-07-15 19:07:00 +02:00
k ad51edbe07 parser: setup clap 2024-07-15 18:52:29 +02:00
k 91f2427b44 app: add random chart button 2024-07-15 08:54:55 +02:00
k fbbb0920c5 parser: cohort ratio name changes 2024-07-13 00:40:47 +02:00
k 66bca200b4 parser: cointime forgot to add compute 2024-07-12 20:46:11 +02:00
k 5f11f15fe1 global: cointime ratios 2024-07-12 20:39:27 +02:00
k 96a50dd09a global: snapshot 2024-07-12 19:31:21 +02:00
k dcf605aa69 parser: percentiles fixed 2024-07-12 19:06:52 +02:00
k 6c7bd2a63a parser: percentiles 2024-07-12 18:08:27 +02:00
k 85835ac1d3 parser: add min date and height for percentile datasets 2024-07-12 17:38:22 +02:00
k 61038b07f9 parser: trying to fix ratio smas 2024-07-12 13:55:44 +02:00
k 68700925b0 parser: add 0 and 1 constant datasets 2024-07-12 12:55:46 +02:00
k 46f8e3bafd app: lazy load lean-qr 2024-07-12 12:47:05 +02:00
k 9077fee4d6 parser: add ratio for price smas 2024-07-12 12:02:57 +02:00
k 35fd5054aa general: snapshot 2024-07-12 08:35:41 +02:00
k 350c835873 parser: improve error message when price cannot be found 2024-07-10 21:34:55 +02:00
k 707ed7ec26 parser: update readme 2024-07-10 20:56:36 +02:00
k e159f18bfc parser: add node.args to git ignore 2024-07-10 20:51:27 +02:00
k 2308fa173a parser: allow node args 2024-07-10 20:51:03 +02:00
k 4a82ee0b05 parser: added ratio and co datasets 2024-07-10 18:34:01 +02:00
k 6976f5af0f general: snapshot 2024-07-10 18:33:24 +02:00
k 59cb524226 server: remove cloudflared restart from run script 2024-07-10 13:20:45 +02:00
k 37e1d2ba5b changelog: add mempool links 2024-07-08 20:47:36 +02:00
k 6c21e970aa changelog: update v0.2.0 date 2024-07-08 20:46:17 +02:00
k d3a4e917fb assets: add v0.2.0 screenshot 2024-07-08 20:43:56 +02:00
k 2481878892 release: v0.2.0 2024-07-08 19:57:30 +02:00
k 04359fbf31 general: snapshot 2024-07-08 17:31:51 +02:00
k 80ea12ed48 app: flatten lightweight-chart scripts 2024-07-06 12:05:11 +02:00
k 9d2d4b7d5f readme: update 2024-07-06 11:10:02 +02:00
k 3de2862655 readme: update 2024-07-06 10:23:54 +02:00
k abb4def848 readme: update 2024-07-06 09:08:11 +02:00
k 04decabc46 parser: fix ulimit only running in Mac OS 2024-07-05 22:23:00 +02:00
k 334ff52084 app: fix start date not being 1970-01-01 2024-07-05 18:28:01 +02:00
k a931ad7a1e general: snapshot 2024-07-05 18:03:53 +02:00
k 069311dcf3 general: snapshot 2024-07-03 20:40:35 +02:00
k b7e8cbea20 general: snapshot 2024-06-30 17:01:15 +02:00
k 9905eff383 readme: update 2024-06-25 22:29:27 +02:00
k 48320197f9 app: add geyser button 2024-06-25 22:06:48 +02:00
k 9c9a835f33 changelog: deleted image by mistake 2024-06-25 16:21:09 +02:00
k ec477b916b update: readme 2024-06-25 16:12:59 +02:00
k dc5a1fcb9a update: readme 2024-06-25 16:11:09 +02:00
k 20a51f980b general: snapshot 2024-06-25 14:46:23 +02:00
k 7604787fbb app: add mini window support 2024-06-24 06:50:23 +02:00
k e55b5195a9 release: v0.1.1 2024-06-24 05:14:52 +02:00
709 changed files with 64249 additions and 40878 deletions
+291
View File
@@ -0,0 +1,291 @@
# This file was autogenerated by dist: https://opensource.axo.dev/cargo-dist/
#
# Copyright 2022-2024, axodotdev
# SPDX-License-Identifier: MIT or Apache-2.0
#
# CI that:
#
# * checks for a Git Tag that looks like a release
# * builds artifacts with dist (archives, installers, hashes)
# * uploads those artifacts to temporary workflow zip
# * on success, uploads the artifacts to a GitHub Release
#
# Note that the GitHub Release will be created with a generated
# title/body based on your changelogs.
name: Release
permissions:
"contents": "write"
# This task will run whenever you push a git tag that looks like a version
# like "1.0.0", "v0.1.0-prerelease.1", "my-app/0.1.0", "releases/v1.0.0", etc.
# Various formats will be parsed into a VERSION and an optional PACKAGE_NAME, where
# PACKAGE_NAME must be the name of a Cargo package in your workspace, and VERSION
# must be a Cargo-style SemVer Version (must have at least major.minor.patch).
#
# If PACKAGE_NAME is specified, then the announcement will be for that
# package (erroring out if it doesn't have the given version or isn't dist-able).
#
# If PACKAGE_NAME isn't specified, then the announcement will be for all
# (dist-able) packages in the workspace with that version (this mode is
# intended for workspaces with only one dist-able package, or with all dist-able
# packages versioned/released in lockstep).
#
# If you push multiple tags at once, separate instances of this workflow will
# spin up, creating an independent announcement for each one. However, GitHub
# will hard limit this to 3 tags per commit, as it will assume more tags is a
# mistake.
#
# If there's a prerelease-style suffix to the version, then the release(s)
# will be marked as a prerelease.
on:
pull_request:
push:
tags:
- '**[0-9]+.[0-9]+.[0-9]+*'
jobs:
# Run 'dist plan' (or host) to determine what tasks we need to do
plan:
runs-on: "ubuntu-latest"
outputs:
val: ${{ steps.plan.outputs.manifest }}
tag: ${{ !github.event.pull_request && github.ref_name || '' }}
tag-flag: ${{ !github.event.pull_request && format('--tag={0}', github.ref_name) || '' }}
publishing: ${{ !github.event.pull_request }}
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Install dist
# we specify bash to get pipefail; it guards against the `curl` command
# failing. otherwise `sh` won't catch that `curl` returned non-0
shell: bash
run: "curl --proto '=https' --tlsv1.2 -LsSf https://github.com/axodotdev/cargo-dist/releases/download/v0.28.0/cargo-dist-installer.sh | sh"
- name: Cache dist
uses: actions/upload-artifact@v4
with:
name: cargo-dist-cache
path: ~/.cargo/bin/dist
# sure would be cool if github gave us proper conditionals...
# so here's a doubly-nested ternary-via-truthiness to try to provide the best possible
# functionality based on whether this is a pull_request, and whether it's from a fork.
# (PRs run on the *source* but secrets are usually on the *target* -- that's *good*
# but also really annoying to build CI around when it needs secrets to work right.)
- id: plan
run: |
dist ${{ (!github.event.pull_request && format('host --steps=create --tag={0}', github.ref_name)) || 'plan' }} --output-format=json > plan-dist-manifest.json
echo "dist ran successfully"
cat plan-dist-manifest.json
echo "manifest=$(jq -c "." plan-dist-manifest.json)" >> "$GITHUB_OUTPUT"
- name: "Upload dist-manifest.json"
uses: actions/upload-artifact@v4
with:
name: artifacts-plan-dist-manifest
path: plan-dist-manifest.json
# Build and packages all the platform-specific things
build-local-artifacts:
name: build-local-artifacts (${{ join(matrix.targets, ', ') }})
# Let the initial task tell us to not run (currently very blunt)
needs:
- plan
if: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix.include != null && (needs.plan.outputs.publishing == 'true' || fromJson(needs.plan.outputs.val).ci.github.pr_run_mode == 'upload') }}
strategy:
fail-fast: false
# Target platforms/runners are computed by dist in create-release.
# Each member of the matrix has the following arguments:
#
# - runner: the github runner
# - dist-args: cli flags to pass to dist
# - install-dist: expression to run to install dist on the runner
#
# Typically there will be:
# - 1 "global" task that builds universal installers
# - N "local" tasks that build each platform's binaries and platform-specific installers
matrix: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix }}
runs-on: ${{ matrix.runner }}
container: ${{ matrix.container && matrix.container.image || null }}
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, '-') }}-dist-manifest.json
steps:
- name: enable windows longpaths
run: |
git config --global core.longpaths true
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Install Rust non-interactively if not already installed
if: ${{ matrix.container }}
run: |
if ! command -v cargo > /dev/null 2>&1; then
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
echo "$HOME/.cargo/bin" >> $GITHUB_PATH
fi
- name: Install dist
run: ${{ matrix.install_dist.run }}
# Get the dist-manifest
- name: Fetch local artifacts
uses: actions/download-artifact@v4
with:
pattern: artifacts-*
path: target/distrib/
merge-multiple: true
- name: Install dependencies
run: |
${{ matrix.packages_install }}
- name: Build artifacts
run: |
# Actually do builds and make zips and whatnot
dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json
echo "dist ran successfully"
- id: cargo-dist
name: Post-build
# We force bash here just because github makes it really hard to get values up
# to "real" actions without writing to env-vars, and writing to env-vars has
# inconsistent syntax between shell and powershell.
shell: bash
run: |
# Parse out what we just built and upload it to scratch storage
echo "paths<<EOF" >> "$GITHUB_OUTPUT"
dist print-upload-files-from-manifest --manifest dist-manifest.json >> "$GITHUB_OUTPUT"
echo "EOF" >> "$GITHUB_OUTPUT"
cp dist-manifest.json "$BUILD_MANIFEST_NAME"
- name: "Upload artifacts"
uses: actions/upload-artifact@v4
with:
name: artifacts-build-local-${{ join(matrix.targets, '_') }}
path: |
${{ steps.cargo-dist.outputs.paths }}
${{ env.BUILD_MANIFEST_NAME }}
# Build and package all the platform-agnostic(ish) things
build-global-artifacts:
needs:
- plan
- build-local-artifacts
runs-on: "ubuntu-latest"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Install cached dist
uses: actions/download-artifact@v4
with:
name: cargo-dist-cache
path: ~/.cargo/bin/
- run: chmod +x ~/.cargo/bin/dist
# Get all the local artifacts for the global tasks to use (for e.g. checksums)
- name: Fetch local artifacts
uses: actions/download-artifact@v4
with:
pattern: artifacts-*
path: target/distrib/
merge-multiple: true
- id: cargo-dist
shell: bash
run: |
dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json "--artifacts=global" > dist-manifest.json
echo "dist ran successfully"
# Parse out what we just built and upload it to scratch storage
echo "paths<<EOF" >> "$GITHUB_OUTPUT"
jq --raw-output ".upload_files[]" dist-manifest.json >> "$GITHUB_OUTPUT"
echo "EOF" >> "$GITHUB_OUTPUT"
cp dist-manifest.json "$BUILD_MANIFEST_NAME"
- name: "Upload artifacts"
uses: actions/upload-artifact@v4
with:
name: artifacts-build-global
path: |
${{ steps.cargo-dist.outputs.paths }}
${{ env.BUILD_MANIFEST_NAME }}
# Determines if we should publish/announce
host:
needs:
- plan
- build-local-artifacts
- build-global-artifacts
# Only run if we're "publishing", and only if local and global didn't fail (skipped is fine)
if: ${{ always() && needs.plan.outputs.publishing == 'true' && (needs.build-global-artifacts.result == 'skipped' || needs.build-global-artifacts.result == 'success') && (needs.build-local-artifacts.result == 'skipped' || needs.build-local-artifacts.result == 'success') }}
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
runs-on: "ubuntu-latest"
outputs:
val: ${{ steps.host.outputs.manifest }}
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Install cached dist
uses: actions/download-artifact@v4
with:
name: cargo-dist-cache
path: ~/.cargo/bin/
- run: chmod +x ~/.cargo/bin/dist
# Fetch artifacts from scratch-storage
- name: Fetch artifacts
uses: actions/download-artifact@v4
with:
pattern: artifacts-*
path: target/distrib/
merge-multiple: true
- id: host
shell: bash
run: |
dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json > dist-manifest.json
echo "artifacts uploaded and released successfully"
cat dist-manifest.json
echo "manifest=$(jq -c "." dist-manifest.json)" >> "$GITHUB_OUTPUT"
- name: "Upload dist-manifest.json"
uses: actions/upload-artifact@v4
with:
# Overwrite the previous copy
name: artifacts-dist-manifest
path: dist-manifest.json
# Create a GitHub Release while uploading all files to it
- name: "Download GitHub Artifacts"
uses: actions/download-artifact@v4
with:
pattern: artifacts-*
path: artifacts
merge-multiple: true
- name: Cleanup
run: |
# Remove the granular manifests
rm -f artifacts/*-dist-manifest.json
- name: Create GitHub Release
env:
PRERELEASE_FLAG: "${{ fromJson(steps.host.outputs.manifest).announcement_is_prerelease && '--prerelease' || '' }}"
ANNOUNCEMENT_TITLE: "${{ fromJson(steps.host.outputs.manifest).announcement_title }}"
ANNOUNCEMENT_BODY: "${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}"
RELEASE_COMMIT: "${{ github.sha }}"
run: |
# Write and read notes from a file to avoid quoting breaking things
echo "$ANNOUNCEMENT_BODY" > $RUNNER_TEMP/notes.txt
gh release create "${{ needs.plan.outputs.tag }}" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/*
announce:
needs:
- plan
- host
# use "always() && ..." to allow us to wait for all publish jobs while
# still allowing individual publish jobs to skip themselves (for prereleases).
# "host" however must run to completion, no skipping allowed!
if: ${{ always() && needs.host.result == 'success' }}
runs-on: "ubuntu-latest"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
+17 -4
View File
@@ -1,7 +1,20 @@
# Mac OS
.DS_Store
/datasets
/datasets2
/datasets_*
# Builds
target
dist
vecid-to-indexes.js
TODO.md
# Copies
*\ copy*
# Ignored
_*
# Editors
.vscode
.zed
# Logs
.log
+256 -8
View File
@@ -1,23 +1,257 @@
# Changelog
<!--
# v0.X.Y | WIP
![Image of the kibo Web App version 0.X.Y](https://github.com/bitcoinresearchkit/brk/blob/main/assets/v0.X.Y.jpg)
-->
## v. 0.1.1 - WIP
# v0.X.0 | WIP | A new beginning
### Parser
![Image of BRK's Web App version 0.1.0](https://github.com/bitcoinresearchkit/brk/blob/main/assets/brk-v0.1.0.png)
Full rewrite
# [kibo-v0.5.0](https://github.com/bitcoinresearchkit/brk/tree/eea56d394bf92c62c81da8b78b8c47ea730683f5) | [873199](https://mempool.space/block/0000000000000000000270925aa6a565be92e13164565a3f7994ca1966e48050) - 2024/12/04
![Image of the kibo Web App version 0.5.0](https://github.com/bitcoinresearchkit/brk/blob/main/assets/kibo-v0.5.0.jpg)
## Datasets
- Added `Sell Side Risk Ratio` to all entities
- Added `Open`, `High` and `Low` datasets
- Added `Satoshis Per Dollar`
- Added `All Time High`
- Added `All Time High Date`
- Added `Days Since All Time High`
- Added `Max Days Between All Time Highs`
- Added `Max Years Between All Time Highs`
- Added `Drawdown`
- Added `Adjusted Value Created`, `Adjusted Value Destroyed` and `Adjusted Spent Output Profit Ratio` to all entities
- Added `Realized Profit To Loss Ratio` to all entities
- Added `Hash Price Min`
- Added `Hash Price Rebound`
- Removed all year datasets (25) in favor for epoch datasets (5), the former was too granular to be really useful
- Removed datasets split by liquidity for all datasets **already split by any address kind**, while fun to have, they took time to compute, ram, and space to store and no one was actually checking them
- Fixed a lot of values in split by liquidity datasets
## Website
- Updated the design yet again which made the website for something more minimal and easier on the eyes
- Added a *Save In Bitcoin* (DCA) simulation page
- ~Added a dashboard~ Added the latest values to the tree next to each option instead, while less values are visible at a time, it's much more readable and organised
- Added a library of PDFs
- Fixed service worker not passing 304 (not modified) response and instead serving cached responses
- Fixed history not being properly registered
- Fixed window being moveable on iOS when in standalone mode when it shouldn't be
- Added `Compare` section to all groups, to compare all datasets within a group
- Updated `Solid Signals` library, which had an important breaking change on the `createEffect` function which might bring some bugs
- Fixed some datasets paths
- A lot of code reorg and file splits
- Adopted a framework like approach to load pages while still being pure JS without a build step
- Probably more that was forgotten
## Parser
- Added a `/datasets/last` json file with all the latest values
- Added `--rpcconnect` parameter to the config
- Added handling of SIGINT and SIGTERM terminal signals which menas you can now safely CTRL+C or kill the parser while it's exporting
- Added config print at the start of the program
- Compressed `empty_address_data` struct to save space (should shave of between up to 50% of the `address_index_to_empty_address_data` database)
- Doubled the number of `txid_to_tx_data` databases from 4096 to 8192
- ~Added `--recompute_computed true` argument, to allow recomputation of computed datasets in case of a bug~ Buggy for now
- Fixed not saved arguments, not being processed properly
- Fixed bug in `generic_map.multi_insert_simple_average`
- Added defragmentation option `--first-defragment true` of databases to save space (which can save up to 50%)
- Fixed bug in the computation of averages in `GenericMap`
- Added support and paramer for cookie files with `--rpccookiefile`, and auto find if the path is `--datadir/.cookie`
- Increased number of retries and time between them when fetching price from exchanges APIs
## Server
- Fixed links in several places missing the `/api` part and thus not working
- Fixed broken last values routes
- Added support for the `/datasets/last` file via the `/api/last` route
- Added support for `.json` (won't change anything) and `.csv` (will download a csv file) extension at the end of datasets routes
- Added `all=true` query parameter to dataset routes to get to full history
## Biter
- Moved back to this repo
# [kibo-v0.4.0](https://github.com/bitcoinresearchkit/brk/tree/a64c544815d9ef785e2fc1323582f774f16b9200) | [861950](https://mempool.space/block/00000000000000000000530d0e30ccf7deeace122dcc99f2668a06c6dad83629) - 2024/09/19
![Image of the kibo Web App version 0.4.0](https://github.com/bitcoinresearchkit/brk/blob/main/assets/kibo-v0.4.0.jpg)
## Brand
- **Satonomics** is now **kibo** 🎉
## Website
- Complete redesign of the website
- Rewrote the whole application and removed `node`/`npm`/`pnpm` dependencies in favor for pure `HTML`/`CSS`/`Javascript`
- Website is now served by the server
- Added Trading View attribution link to the settings frame and file in the lightweight charts folder
- Many other changes
## Parser
- Changed the block iterator from a custom version of [bitcoin-explorer](https://crates.io/crates/bitcoin-explorer) to the homemade [biter](https://crates.io/crates/biter) which allows the parser to run alongside `bitcoind`
- Added datasets compression thanks to [zstd](https://crates.io/crates/zstd) to reduce disk usage
- Use the Bitcoin RPC server for various calls instead of running cli commands and then parsing the JSON from the output
- **Important database changes that will need a full rescan**:
- Changed databases page size from 1MB to 4KB for improved disk usage
- Split txid_to_tx_data database in 4096 chunks (from 256) for improved disk usage
- Split address_index_to_X databases to chunks of 25_000 instead of 50_000
- Removed local Multisig database
- Updated the config, run with `-h` to see possible args
- Moved outputs from `/target/outputs` to `/out` to allow to run commands like `cargo clean` without side effects
- Various first run fixes
- Added to `-h` which arguments are saved, which is all of them at the time of writing
## Server
- Updated the code to support compressed binaries
- Added serving of the website
- Improved `Cache-Control` behavior
# [satonomics-v0.3.0](https://github.com/bitcoinresearchkit/brk/tree/b68b016091c45b071218fba01bac5b76e8eaf18c) | [853930](https://mempool.space/block/00000000000000000002eb5e9a7950ca2d5d98bd1ed28fc9098aa630d417985d) - 2024/07/26
![Image of the Satonomics Web App version 0.3.0](https://github.com/bitcoinresearchkit/brk/blob/main/assets/satonomics-v0.3.0.jpg)
## Parser
- Global
- Improved self-hosting by:
- Fixing an incredibly annoying bug that made the program panic because of a wrong utxo/address durable state after a or many new datasets were added/changed after a first successful parse of the chain
- Fixing a bug that would crash the program if launched for the first time ever
- Auto fetch prices from the main Satonomics instance if missing instead of only trying Kraken's and Binance's API which are limited to the last 16 hours
- Merged the core of `HeightMap` and `DateMap` structs into `GenericMap`
- Added `Height` struct and many others
- Reorganized outputs of both the parser and the server for ease of use and easier sync compatibility
- CLI
- Added an argument parser for improved UX with several options
- Datasets
- Added the following datasets for all entities:
- Value destroyed
- Value created
- Spent Output Profit Ratio (SOPR)
- Added the following ratio datasets and their variations to all prices {realized, moving average, any cointime, etc}:
- Market Price to {X}
- Market Price to {X} Ratio
- Market Price to {X} Ratio 1 Week SMA
- Market Price to {X} Ratio 1 Month SMA
- Market Price to {X} Ratio 1 Year SMA
- Market Price to {X} Ratio 1 Year SMA Momentum Oscillator
- Market Price to {X} Ratio 99th Percentile
- Market Price to {X} Ratio 99.5th Percentile
- Market Price to {X} Ratio 99.9th Percentile
- Market Price to {X} Ratio 1st Percentile
- Market Price to {X} Ratio 0.5th Percentile
- {X} 1% Top Probability
- {X} 0.5% Top Probability
- {X} 0.1% Top Probability
- {X} 1% Bottom Probability
- {X} 0.5% Bottom Probability
- {X} 0.1% Bottom Probability
- Added block metadatasets and their variants (raw/sum/average/min/max/percentiles):
- Block size
- Block weight
- Block VBytes
- Block interval
- Price
- Improved error message when price cannot be found
## App
- General
- Added chart scroll button for nice animations à la Wicked
- Added scale mode switch (Linear/Logarithmic) at the bottom right of all charts
- Added unit at the top left of all charts
- 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
- Added a 'Go to a random chart' button in several places
- 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
- Separated the QRCode generator library from the main chunk and made it imported on click
- Fixed timescale changing on small screen after changing charts
- Folders
- Added the size in the "filename" of address cohorts grouped by size
- Favorites
- Added a 'favorite' and 'unfavorite' button at the bottom
- Settings
- Removed the horizontal scroll bar which was unintended
## Server
- Run file
- Only run with a watcher if `cargo watch` is available
- Removed id_to_path file in favor for only `paths.d.ts` in `app/src/types`
# [satonomics-v0.2.0](https://github.com/bitcoinresearchkit/brk/tree/248187889283597c5dbb806292297453c25e97b8) | [851286](https://mempool.space/block/0000000000000000000281ca7f1bf8c50702bfca168c7af1bdc67c977c1ac8ed) - 2024/07/08
![Image of the Satonomics Web App version 0.2.0](https://github.com/bitcoinresearchkit/brk/blob/main/assets/satonomics-v0.2.0.jpg)
## App
- General
- Added the height version of all datasets and many optimizations to make them usable but only available on desktop and tablets for now
- Added a light theme
- Charts
- Added split panes in order to have the vertical axis visible for all datasets
- Added min and max values on the charts
- Fixed legend hovering on mobile not resetting on touch end
- Added "3 months" and yearly time scale setters (from year 2009 to today)
- Hide scrollbar of timescale setters and instead added scroll buttons to the legend only visible on desktop
- Improved Share/QR Code screen
- Changed all Area series to Line series
- Fixed horizontal scrollable legend not updating on preset change
- Performance
- Improved app's reactivity
- Added some chunk splitting for a faster initial load
- Global improvements that increased the Lighthouse's performance score
- Settings
- Finally made a proper component where you can chose the app's theme, between a moving or static background and its text opacity
- Added donations section with a leaderboard
- Added various links that are visible on the bottom side of the strip on desktop to mobile users
- Added install instructions when not installed for Apple users
- Misc
- Support mini window size, could be useful for embedded views
- Hopefully made scrollbars a little more subtle on WIndows and Linux, can't test
- Generale style updates
## Parser
- Fixed ulimit only being run in Mac OS instead of whenever the program is detected
# [satonomics-v0.1.1](https://github.com/bitcoinresearchkit/brk/tree/e55b5195a9de9aea306903c94ed63cb1720fda5f) | [849240](https://mempool.space/block/000000000000000000002b8653988655071c07bb5f7181c038f9326bc86db741) - 2024/06/24
![Image of the Satonomics Web App version 0.1.1](https://github.com/bitcoinresearchkit/brk/blob/main/assets/satonomics-v0.1.1.jpg)
## Parser
- Fixed overflow in `Price` struct which caused many Realized Caps and Realized Prices to have completely bogus data
- Fixed Realized Cap computation which was using rounded prices instead normal ones
### Server
## Server
- Added the chunk, date and time in the terminal logs
- Added the chunk, date and time of the request to the terminal logs
### App
## App
- Chart
- Added double click option on a legend to toggle the visibility of all other series
- Added highlight effect to a legend by darkening the color of all the other series on the chart while hovering it with the mouse
- Added an API link in the legend for each dataset where applicable (when isn't generated locally)
- Save fullscreen preference in local storage and url
- Improved resize bar on desktop
- Changed resize button logo
- Changed the share button to visible on small screen too
- Improved share screen
- Fixed time range shifting not being the one in url params or saved in local storage
- Fixed time range shifting on series toggling via the legend
- Fixed time range shifting on fullscreen
@@ -27,13 +261,27 @@
- History
- Changed background for the sticky dates from blur to a solid color as it didn't appear properly in Firefox
- Build
- Added lazy loads to have split chunks after build
- Tried to add lazy loads to have split chunks after build, to have much faster load times and they worked great ! But they completely broke Safari on iOS, we can't have nice things
- Removed many libraries and did some things manually instead to improve build size
- Strip
- Temporarily removed the Home button on the strip bar on desktop as there is no landing page yet
- Settings
- Added version
- PWA
- Fixed background update
- Changed update check frequency to 1 minute (~1kb to fetch every minute which is very reasonable)
- Added a nice banner to ask the user to install the update
- Misc
- Removed tracker even though it was a very privacy friendly as it appeared to not be working properly
### Price
## Price
- Deleted old price datasets and their backups
# [satonomics-v0.1.0](https://github.com/bitcoinresearchkit/brk/tree/a1a576d088c8f83ed32d48753a7611f70a964574) | [848642](https://mempool.space/block/000000000000000000020be5761d70751252219a9557f55e91ecdfb86c4e026a) - 2024/06/19
![Image of the Satonomics Web App version 0.1.0](https://github.com/bitcoinresearchkit/brk/blob/main/assets/satonomics-v0.1.0.jpg)
# satonomics-v0.0.1 | [835444](https://mempool.space/block/000000000000000000009f93907a0dd83c080d5585cc7ec82c076d45f6d7c872) - 2024/03/20
![Image of the Satonomics Web App version 0.0.X](https://github.com/bitcoinresearchkit/brk/blob/main/assets/satonomics-v0.0.1.jpg)
Generated
+4938
View File
File diff suppressed because it is too large Load Diff
+84
View File
@@ -0,0 +1,84 @@
[workspace]
resolver = "3"
members = ["crates/*"]
package.description = "The Bitcoin Research Kit is a suite of tools designed to extract, compute and display data stored on a Bitcoin Core node"
package.license = "MIT"
package.edition = "2024"
package.version = "0.0.70"
package.homepage = "https://bitcoinresearchkit.org"
package.repository = "https://github.com/bitcoinresearchkit/brk"
[profile.release]
lto = "fat"
codegen-units = 1
panic = "abort"
[profile.dist]
inherits = "release"
[workspace.dependencies]
arc-swap = "1.7.1"
axum = "0.8.4"
bincode = { version = "2.0.1", features = ["serde"] }
bitcoin = { version = "0.32.6", features = ["serde"] }
bitcoincore-rpc = "0.19.0"
brk_bundler = { version = "0.0.70", path = "crates/brk_bundler" }
brk_cli = { version = "0.0.70", path = "crates/brk_cli" }
brk_computer = { version = "0.0.70", path = "crates/brk_computer" }
brk_core = { version = "0.0.70", path = "crates/brk_core" }
brk_exit = { version = "0.0.70", path = "crates/brk_exit" }
brk_fetcher = { version = "0.0.70", path = "crates/brk_fetcher" }
brk_indexer = { version = "0.0.70", path = "crates/brk_indexer" }
brk_interface = { version = "0.0.70", path = "crates/brk_interface" }
brk_logger = { version = "0.0.70", path = "crates/brk_logger" }
brk_mcp = { version = "0.0.70", path = "crates/brk_mcp" }
brk_parser = { version = "0.0.70", path = "crates/brk_parser" }
brk_rmcp = { version = "0.1.7", features = ["transport-streamable-http-server", "transport-worker"]}
brk_server = { version = "0.0.70", path = "crates/brk_server" }
brk_state = { version = "0.0.70", path = "crates/brk_state" }
brk_store = { version = "0.0.70", path = "crates/brk_store" }
brk_vec = { version = "0.0.70", path = "crates/brk_vec" }
byteview = "=0.6.1"
clap = { version = "4.5.40", features = ["string"] }
clap_derive = "4.5.40"
color-eyre = "0.6.5"
derive_deref = "1.1.1"
fjall = "2.11.1"
jiff = "0.2.15"
log = { version = "0.4.27" }
minreq = { version = "2.13.4", features = ["https", "serde_json"] }
rayon = "1.10.0"
schemars = "1.0.0"
serde = { version = "1.0.219" }
serde_bytes = "0.11.17"
serde_derive = "1.0.219"
serde_json = { version = "1.0.140", features = ["float_roundtrip"] }
tabled = "0.20.0"
tokio = { version = "1.45.1", features = ["rt-multi-thread"] }
zerocopy = { version = "0.8.26" }
zerocopy-derive = "0.8.26"
[workspace.metadata.release]
shared-version = true
tag-name = "v{{version}}"
pre-release-commit-message = "release: v{{version}}"
tag-message = "release: v{{version}}"
[workspace.metadata.dist]
cargo-dist-version = "0.28.0"
ci = "github"
installers = []
targets = [
"aarch64-apple-darwin",
"aarch64-unknown-linux-gnu",
"x86_64-apple-darwin",
"x86_64-unknown-linux-gnu",
]
[workspace.metadata.dist.github-custom-runners]
global = "ubuntu-latest"
aarch64-apple-darwin.runner = "macos-14"
x86_64-unknown-linux-gnu.runner = "ubuntu-latest"
x86_64-unknown-linux-gnu.container = { image = "quay.io/pypa/manylinux_2_28_x86_64", host = "x86_64-unknown-linux-musl" }
aarch64-unknown-linux-gnu.runner = "ubuntu-latest"
aarch64-unknown-linux-gnu.container = { image = "quay.io/pypa/manylinux_2_28_x86_64", host = "x86_64-unknown-linux-musl" }
+1 -1
View File
@@ -1,6 +1,6 @@
MIT License
Copyright (c) 2024 Satonomics
Copyright (c) 2025 bitcoinresearchkit, kibo.money, satonomics
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
+90 -41
View File
@@ -1,59 +1,108 @@
# SATONOMICS
# Bitcoin Research Kit
## Description
<p align="left">
<a href="https://github.com/bitcoinresearchkit/brk">
<img alt="GitHub Repo stars" src="https://img.shields.io/github/stars/bitcoinresearchkit/brk?style=social">
</a>
<a href="https://github.com/bitcoinresearchkit/brk/blob/main/LICENSE.md">
<img src="https://img.shields.io/crates/l/brk" alt="License" />
</a>
<a href="https://crates.io/crates/brk">
<img src="https://img.shields.io/crates/v/brk" alt="Version" />
</a>
<a href="https://docs.rs/brk">
<img src="https://img.shields.io/docsrs/brk" alt="Documentation" />
</a>
<img src="https://img.shields.io/crates/size/brk" alt="Size" />
<a href="https://deps.rs/crate/brk">
<img src="https://deps.rs/crate/brk/latest/status.svg" alt="Dependency status">
</a>
<a href="https://discord.gg/HaR3wpH3nr">
<img src="https://img.shields.io/discord/1350431684562124850?label=discord" alt="Discord" />
</a>
<a href="https://primal.net/p/nprofile1qqsfw5dacngjlahye34krvgz7u0yghhjgk7gxzl5ptm9v6n2y3sn03sqxu2e6">
<img src="https://img.shields.io/badge/nostr-purple?link=https%3A%2F%2Fprimal.net%2Fp%2Fnprofile1qqsfw5dacngjlahye34krvgz7u0yghhjgk7gxzl5ptm9v6n2y3sn03sqxu2e6" alt="Nostr" />
</a>
<a href="https://bsky.app/profile/bitcoinresearchkit.org">
<img src="https://img.shields.io/badge/bluesky-blue?link=https%3A%2F%2Fbsky.app%2Fprofile%2Fbitcoinresearchkit.org" alt="Bluesky" />
</a>
<a href="https://x.com/brkdotorg">
<img src="https://img.shields.io/badge/x.com-black" alt="X" />
</a>
</p>
TLDR: FOSS [glassnode](https://glassnode.com).
The Bitcoin Research Kit is a high-performance toolchain designed to parse, index, compute, serve and visualize data from a Bitcoin node, enabling users to gain deeper insights into the Bitcoin network.
Satonomics is an open-source suite of tools that computes, distributes, and displays on-chain data, making it freely available for anyone to use.
In other words it's an alternative to [Glassnode](https://glassnode.com), [mempool.space](https://mempool.space/) (soon) and [electrs](https://github.com/romanz/electrs) (soon) all in one package with a particular focus on simplicity and ease of use.
The generated datasets are incredibly diverse and can be used for a wide range of purposes. Whether you're looking to conduct a health check on the network, gain insights into its current or past state, or leverage the data for trading purposes, these tools offer various charts, dashboards (Soon TM), and an extensive API to help you achieve your goals.
The toolkit can be used in various ways to accommodate as many needs as possible:
To promote transparency and trust in the network, this project is committed to making on-chain data accessible and verifiable to all, without discrimination and is a great complimentary tool to [mempool.space](https://mempool.space).
- **[Website](https://bitcoinresearchkit.org)** \
Everyone is welcome to visit the official instance and showcase of the suite's capabilities. \
It has a wide range of functionalities including charts, tables and simulations which you can visit for free and without the need for an account. \
Also available at: [kibo.money](https://kibo.money) // [satonomics.xyz](https://satonomics.xyz)
- **[API](https://github.com/bitcoinresearchkit/brk/tree/main/crates/brk_server#brk-server)** \
Researchers and developers are free to use BRK's public API with ![Datasets variant count](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fbitcoinresearchkit.org%2Fapi%2Fvecs%2Fvec-count&query=%24&style=flat&label=%20&color=white) dataset variants at their disposal. \
Just like the website, it's entirely free, with no authentication or rate-limiting.
- **[AI](https://github.com/bitcoinresearchkit/brk/blob/main/crates/brk_mcp/README.md#brk-mcp)** \
LLMs have to possibility to connect to BRK's backend through a [MCP](https://modelcontextprotocol.io/introduction). \
It will give them access to the same tools as the API, with no restrictions, and allow you to have your very own data analysts. \
One-shot output examples: [Document](https://claude.ai/public/artifacts/71194d29-f965-417c-ba09-fdf0e4ecb1d5) // [Dashboard](https://claude.ai/public/artifacts/beef143f-399a-4ed4-b8bf-c986b776de42) // [Dashboard 2](https://claude.ai/public/artifacts/5430ae49-bb3d-4fc1-ab24-f1e33deb40dc)
- **[CLI](https://crates.io/crates/brk_cli)** \
Node runners are strongly encouraged to try out and self-host their own instance using BRK's command line interface. \
The CLI has multiple cogs available for users to tweak to adapt to all situations with even the possibility for web developers to create their own custom website which could later on be added as an alternative front-end.
- **[Crates](https://crates.io/crates/brk)** \
Rust developers have access to a wide range crates, each built upon one another with its own specific purpose, enabling independent use and offering great flexibility.
PRs are welcome, especially if their goal is to introduce additional datasets.
## Instances
The primary goal of this project is to be fully-featured and accessible for everyone, regardless of their background or financial situation - whether that person is an enthusiast, researcher, miner, analyst, or simply curious.
Web App:
- [app.satonomics.xyz](https://app.satonomics.xyz)
In contrast, existing alternatives tend to be either [very costly](https://studio.glassnode.com/pricing) or missing essential features, with the vast majority being closed-source and unverifiable, which fundamentally undermines the principles of Bitcoin.
API:
- [api.satonomics.xyz](https://api.satonomics.xyz)
## Crates
## Structure
- [`brk`](https://crates.io/crates/brk): Wrapper around all other `brk-*` crates
- [`brk_cli`](https://crates.io/crates/brk_cli): A command line interface to run a Bitcoin Research Kit instance
- [`brk_computer`](https://crates.io/crates/brk_computer): A Bitcoin dataset computer, built on top of brk_indexer
- [`brk_core`](https://crates.io/crates/brk_core): The Core (Structs and Errors) of the Bitcoin Research Kit
- [`brk_exit`](https://crates.io/crates/brk_exit): An exit blocker built on top of ctrlc
- [`brk_fetcher`](https://crates.io/crates/brk_fetcher): A Bitcoin price fetcher
- [`brk_indexer`](https://crates.io/crates/brk_indexer): A Bitcoin Core indexer built on top of brk_parser
- [`brk_logger`](https://crates.io/crates/brk_logger): A clean logger used in the Bitcoin Research Kit
- [`brk_mcp`](https://crates.io/crates/brk_mcp): A Model Context Protocol (MCP) which gives LLMs access to all available tools in BRK
- [`brk_parser`](https://crates.io/crates/brk_parser): A very fast Bitcoin Core block parser and iterator built on top of bitcoin-rust
- [`brk_interface`](https://crates.io/crates/brk_interface): An interface to BRK's engine
- [`brk_server`](https://crates.io/crates/brk_server): A server that serves Bitcoin data and swappable front-ends, built on top of `brk_indexer`, `brk_fetcher` and `brk_computer`
- [`brk_state`](https://crates.io/crates/brk_state): Various states used mainly by the computer
- [`brk_store`](https://crates.io/crates/brk_store): A thin wrapper around [`fjall`](https://crates.io/crates/fjall)
- [`brk_vec`](https://crates.io/crates/brk_vec): A push-only, truncable, compressable, saveable Vec
- [`brk_bundler`](https://crates.io/crates/brk_bundler): A thin wrapper around [`rolldown`](https://rolldown.rs/)
- `parser`: The backbone of the project, it does most of the work by parsing and then computing datasets from the timechain.
- `server`: A small server which automatically creates routes to access through an API all created datasets.
- `app`: A web app which displays the generated datasets in various charts.
## Hosting as a service
## Git
If you'd like to have your own instance hosted for you please contact [hosting@bitcoinresearchkit.org](mailto:hosting@bitcoinresearchkit.org).
- [Repository](https://codeberg.org/satonomics/satonomics)
- [Issues](https://gitworkshop.dev/r/naddr1qq99xct5dahx7mtfvdesz9thwden5te0wp6hyurvv4ex2mrp0yhxxmmdqgsfw5dacngjlahye34krvgz7u0yghhjgk7gxzl5ptm9v6n2y3sn03srqsqqqaueek2h03/issues)
- [Proposals](https://gitworkshop.dev/r/naddr1qq99xct5dahx7mtfvdesz9thwden5te0wp6hyurvv4ex2mrp0yhxxmmdqgsfw5dacngjlahye34krvgz7u0yghhjgk7gxzl5ptm9v6n2y3sn03srqsqqqaueek2h03/proposals)
- 2 separate dedicated servers (1 GB/s each) with different ISPs and Cloudflare integration for enhanced performance and optimal availability
- 99.99% SLA
- Configured for speed
- Updates delivered at your convenience
- Direct communication for feature requests and support
- Bitcoin Core or Knots with desired version
- Optional subdomains: `*.bitcoinresearchkit.org`, `*.kibo.money` and `*.satonomics.xyz`
- Logo featured in the Readme if desired
## Goals
Pricing: `0.01 BTC / month` *or* `0.1 BTC / year`
- Be the absolute best on-chain data source and app
- Have as many datasets and charts as possible
- Be self-hostable on cheap computers
- Be runnable on a machine with 8 GB RAM (16 GB RAM is already possible right now)
- Still being runnable 10 years from now
- By not relying on any third-party dependencies besides price APIs (which are and should be very common and easy to update)
- By **NOT** doing address labelling/tagging (which means **NO** exchange or any other individual address tracking), for that please use [mempool.space](https://mempool.space) or any other tool
## Acknowledgments
## Proof of Work
Deepest gratitude to the [Open Sats](https://opensats.org/) public charity. Their grant — from December 2024 to the present — has been critical in sustaining this project.
Aka: Previous iterations
Heartfelt thanks go out to every donor on [Nostr](https://primal.net/p/npub1jagmm3x39lmwfnrtvxcs9ac7g300y3dusv9lgzhk2e4x5frpxlrqa73v44) and [Geyser.fund](https://geyser.fund/project/brk) whose support has ensured the availability of the [bitcoinresearchkit.org](https://bitcoinresearchkit.org) public instance.
The initial idea was totally different yet morphed over time into what it is today: a fully FOSS self-hostable on-chain data generator
## Donate
- https://github.com/drgarlic/satonomics
- https://github.com/drgarlic/satonomics-parser
- https://github.com/drgarlic/satonomics-explorer
- https://github.com/drgarlic/satonomics-server
- https://github.com/drgarlic/satonomics-app
- https://github.com/drgarlic/bitalisys
- https://github.com/drgarlic/bitesque-app
- https://github.com/drgarlic/bitesque-back
- https://github.com/drgarlic/bitesque-front
- https://github.com/drgarlic/bitesque-assets
- https://github.com/drgarlic/syf
[`bc1q09 8zsm89 m7kgyz e338vf ejhpdt 92ua9p 3peuve`](bitcoin:bc1q098zsm89m7kgyze338vfejhpdt92ua9p3peuve)
[`lnurl1dp68gurn8ghj7ampd3kx2ar0veekzar0wd5xjtnrdakj7tnhv4kxctttdehhwm30d3h82unvwqhkxmmww3jkuar8d35kgetj8yuq363hv4`](lightning:lnurl1dp68gurn8ghj7ampd3kx2ar0veekzar0wd5xjtnrdakj7tnhv4kxctttdehhwm30d3h82unvwqhkxmmww3jkuar8d35kgetj8yuq363hv4)
[Geyser Fund](https://geyser.fund/project/brk)
-9
View File
@@ -1,9 +0,0 @@
node_modules
charts
dist
dev-dist
.DS_Store
visualizer
# Local Netlify folder
.netlify
.wrangler
-10
View File
@@ -1,10 +0,0 @@
# Satonomics - App
## Description
A web app to view the generated datasets in various charts.
## Requirements
- `node`
- `pnpm`
-1
View File
@@ -1 +0,0 @@
/* /index.html
-372
View File
@@ -1,372 +0,0 @@
<!doctype html>
<html lang="en" class="overflow-hidden bg-black text-white">
<head>
<meta charset="utf-8" />
<title>Satonomics</title>
<meta
name="description"
content="An app to visualize Bitcoin on-chain data"
/>
<meta
name="viewport"
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"
/>
<link rel="manifest" href="/manifest.webmanifest" />
<meta name="theme-color" content="#0c0a09" />
<link
rel="icon"
type="image/png"
sizes="196x196"
href="/assets/favicon-196.png"
/>
<link rel="apple-touch-icon" href="/assets/apple-icon-180.png" />
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-2048-2732.jpg"
media="(device-width: 1024px) and (device-height: 1366px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-2732-2048.jpg"
media="(device-width: 1024px) and (device-height: 1366px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-1668-2388.jpg"
media="(device-width: 834px) and (device-height: 1194px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-2388-1668.jpg"
media="(device-width: 834px) and (device-height: 1194px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-1536-2048.jpg"
media="(device-width: 768px) and (device-height: 1024px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-2048-1536.jpg"
media="(device-width: 768px) and (device-height: 1024px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-1488-2266.jpg"
media="(device-width: 744px) and (device-height: 1133px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-2266-1488.jpg"
media="(device-width: 744px) and (device-height: 1133px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-1640-2360.jpg"
media="(device-width: 820px) and (device-height: 1180px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-2360-1640.jpg"
media="(device-width: 820px) and (device-height: 1180px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-1668-2224.jpg"
media="(device-width: 834px) and (device-height: 1112px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-2224-1668.jpg"
media="(device-width: 834px) and (device-height: 1112px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-1620-2160.jpg"
media="(device-width: 810px) and (device-height: 1080px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-2160-1620.jpg"
media="(device-width: 810px) and (device-height: 1080px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-1290-2796.jpg"
media="(device-width: 430px) and (device-height: 932px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-2796-1290.jpg"
media="(device-width: 430px) and (device-height: 932px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-1179-2556.jpg"
media="(device-width: 393px) and (device-height: 852px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-2556-1179.jpg"
media="(device-width: 393px) and (device-height: 852px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-1284-2778.jpg"
media="(device-width: 428px) and (device-height: 926px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-2778-1284.jpg"
media="(device-width: 428px) and (device-height: 926px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-1170-2532.jpg"
media="(device-width: 390px) and (device-height: 844px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-2532-1170.jpg"
media="(device-width: 390px) and (device-height: 844px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-1125-2436.jpg"
media="(device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-2436-1125.jpg"
media="(device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-1242-2688.jpg"
media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-2688-1242.jpg"
media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-828-1792.jpg"
media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-1792-828.jpg"
media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-1242-2208.jpg"
media="(device-width: 414px) and (device-height: 736px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-2208-1242.jpg"
media="(device-width: 414px) and (device-height: 736px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-750-1334.jpg"
media="(device-width: 375px) and (device-height: 667px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-1334-750.jpg"
media="(device-width: 375px) and (device-height: 667px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-640-1136.jpg"
media="(device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-1136-640.jpg"
media="(device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
/>
<meta name="apple-mobile-web-app-capable" content="yes" />
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-dark-2048-2732.jpg"
media="(prefers-color-scheme: dark) and (device-width: 1024px) and (device-height: 1366px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-dark-2732-2048.jpg"
media="(prefers-color-scheme: dark) and (device-width: 1024px) and (device-height: 1366px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-dark-1668-2388.jpg"
media="(prefers-color-scheme: dark) and (device-width: 834px) and (device-height: 1194px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-dark-2388-1668.jpg"
media="(prefers-color-scheme: dark) and (device-width: 834px) and (device-height: 1194px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-dark-1536-2048.jpg"
media="(prefers-color-scheme: dark) and (device-width: 768px) and (device-height: 1024px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-dark-2048-1536.jpg"
media="(prefers-color-scheme: dark) and (device-width: 768px) and (device-height: 1024px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-dark-1488-2266.jpg"
media="(prefers-color-scheme: dark) and (device-width: 744px) and (device-height: 1133px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-dark-2266-1488.jpg"
media="(prefers-color-scheme: dark) and (device-width: 744px) and (device-height: 1133px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-dark-1640-2360.jpg"
media="(prefers-color-scheme: dark) and (device-width: 820px) and (device-height: 1180px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-dark-2360-1640.jpg"
media="(prefers-color-scheme: dark) and (device-width: 820px) and (device-height: 1180px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-dark-1668-2224.jpg"
media="(prefers-color-scheme: dark) and (device-width: 834px) and (device-height: 1112px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-dark-2224-1668.jpg"
media="(prefers-color-scheme: dark) and (device-width: 834px) and (device-height: 1112px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-dark-1620-2160.jpg"
media="(prefers-color-scheme: dark) and (device-width: 810px) and (device-height: 1080px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-dark-2160-1620.jpg"
media="(prefers-color-scheme: dark) and (device-width: 810px) and (device-height: 1080px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-dark-1290-2796.jpg"
media="(prefers-color-scheme: dark) and (device-width: 430px) and (device-height: 932px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-dark-2796-1290.jpg"
media="(prefers-color-scheme: dark) and (device-width: 430px) and (device-height: 932px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-dark-1179-2556.jpg"
media="(prefers-color-scheme: dark) and (device-width: 393px) and (device-height: 852px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-dark-2556-1179.jpg"
media="(prefers-color-scheme: dark) and (device-width: 393px) and (device-height: 852px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-dark-1284-2778.jpg"
media="(prefers-color-scheme: dark) and (device-width: 428px) and (device-height: 926px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-dark-2778-1284.jpg"
media="(prefers-color-scheme: dark) and (device-width: 428px) and (device-height: 926px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-dark-1170-2532.jpg"
media="(prefers-color-scheme: dark) and (device-width: 390px) and (device-height: 844px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-dark-2532-1170.jpg"
media="(prefers-color-scheme: dark) and (device-width: 390px) and (device-height: 844px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-dark-1125-2436.jpg"
media="(prefers-color-scheme: dark) and (device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-dark-2436-1125.jpg"
media="(prefers-color-scheme: dark) and (device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-dark-1242-2688.jpg"
media="(prefers-color-scheme: dark) and (device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-dark-2688-1242.jpg"
media="(prefers-color-scheme: dark) and (device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-dark-828-1792.jpg"
media="(prefers-color-scheme: dark) and (device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-dark-1792-828.jpg"
media="(prefers-color-scheme: dark) and (device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-dark-1242-2208.jpg"
media="(prefers-color-scheme: dark) and (device-width: 414px) and (device-height: 736px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-dark-2208-1242.jpg"
media="(prefers-color-scheme: dark) and (device-width: 414px) and (device-height: 736px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-dark-750-1334.jpg"
media="(prefers-color-scheme: dark) and (device-width: 375px) and (device-height: 667px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-dark-1334-750.jpg"
media="(prefers-color-scheme: dark) and (device-width: 375px) and (device-height: 667px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-dark-640-1136.jpg"
media="(prefers-color-scheme: dark) and (device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-dark-1136-640.jpg"
media="(prefers-color-scheme: dark) and (device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
/>
</head>
<body style="font-size: 15px; line-height: 22px">
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<script src="/src/index.tsx" type="module"></script>
</body>
</html>
-48
View File
@@ -1,48 +0,0 @@
{
"name": "satonomics",
"description": "Satoshi Economics",
"version": "0.1.0",
"license": "MIT",
"type": "module",
"scripts": {
"dev": "($npm_execpath outdated || read -p \"Press enter to ignore...\") && vite --host",
"build": "vite build",
"check": "tsc --noEmit --skipLibCheck --pretty",
"check-watch": "$npm_execpath check --watch",
"format": "prettier --write './src'",
"prod": "$npm_execpath run build && vite preview --host",
"pages-prod": "pnpm build && pnpm wrangler pages deploy ./dist",
"pages-dev": "pnpm build && pnpm wrangler pages deploy --branch dev ./dist",
"assets": "pnpm pwa-asset-generator ./public/logo/white.svg ./public/assets --index ./index.html --manifest ./public/manifest.webmanifest --icon-only --favicon --background \"linear-gradient(to right bottom, rgb(249, 115, 22), rgb(154, 52, 18))\" --padding \"min(15vh, 15vw)\" --path-override \"/assets\" && pnpm pwa-asset-generator ./public/logo/white.svg ./public/assets --index ./index.html --splash-only --background \"linear-gradient(to right bottom, rgb(249, 115, 22), rgb(154, 52, 18))\" --padding \"min(33vh, 33vw)\" --path-override \"/assets\" && pnpm pwa-asset-generator ./public/logo/white.svg ./public/assets --index ./index.html --splash-only --dark-mode --background \"#0c0a09\" --padding \"min(33vh, 33vw)\" --path-override \"/assets\""
},
"dependencies": {
"@leeoniya/ufuzzy": "^1.0.14",
"@solid-primitives/event-listener": "^2.3.3",
"@solid-primitives/intersection-observer": "^2.1.6",
"@solid-primitives/memo": "^1.3.8",
"@solid-primitives/resize-observer": "^2.0.25",
"lean-qr": "^2.3.4",
"lightweight-charts": "^4.1.6",
"solid-js": "^1.8.17"
},
"devDependencies": {
"@ianvs/prettier-plugin-sort-imports": "^4.2.1",
"@iconify-json/tabler": "^1.1.114",
"@tailwindcss/container-queries": "^0.1.1",
"autoprefixer": "^10.4.19",
"postcss": "^8.4.38",
"prettier": "^3.3.2",
"prettier-plugin-tailwindcss": "^0.6.5",
"pwa-asset-generator": "^6.3.1",
"rollup-plugin-visualizer": "^5.12.0",
"tailwindcss": "^3.4.4",
"typescript": "^5.5.2",
"unplugin-auto-import": "^0.17.6",
"unplugin-icons": "^0.19.0",
"vite": "^5.3.1",
"vite-plugin-pwa": "^0.20.0",
"vite-plugin-solid": "^2.10.2",
"workbox-window": "^7.1.0",
"wrangler": "^3.61.0"
}
}
-6333
View File
File diff suppressed because it is too large Load Diff
-11
View File
@@ -1,11 +0,0 @@
/** @type {import("prettier").Options} */
export default {
plugins: [
'@ianvs/prettier-plugin-sort-imports',
'prettier-plugin-tailwindcss', // MUST come last
],
tailwindFunctions: ['classList'],
importOrder: ['<THIRD_PARTY_MODULES>', '', '^/?(~|src)/', '', '^[./]'],
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.
-17
View File
@@ -1,17 +0,0 @@
<svg width="100%" height="100%" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;" fill="black">
<g transform="matrix(1.14102,0,0,2.63158,-0.849652,5.12904)">
<rect x="4.25" y="3.751" width="14.023" height="1.52"/>
</g>
<g transform="matrix(1.14102,0,0,2.63158,-0.849652,0.129039)">
<rect x="4.25" y="3.751" width="14.023" height="1.52"/>
</g>
<g transform="matrix(1.14102,0,0,2.63158,-0.849652,-4.87096)">
<rect x="4.25" y="3.751" width="14.023" height="1.52"/>
</g>
<g transform="matrix(0.285256,0,0,2.63158,8.78759,-9.87096)">
<rect x="4.25" y="3.751" width="14.023" height="1.52"/>
</g>
<g transform="matrix(0.285256,0,0,2.63158,8.78759,10.129)">
<rect x="4.25" y="3.751" width="14.023" height="1.52"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1004 B

-17
View File
@@ -1,17 +0,0 @@
<svg width="100%" height="100%" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;" fill="white">
<g transform="matrix(1.14102,0,0,2.63158,-0.849652,5.12904)">
<rect x="4.25" y="3.751" width="14.023" height="1.52"/>
</g>
<g transform="matrix(1.14102,0,0,2.63158,-0.849652,0.129039)">
<rect x="4.25" y="3.751" width="14.023" height="1.52"/>
</g>
<g transform="matrix(1.14102,0,0,2.63158,-0.849652,-4.87096)">
<rect x="4.25" y="3.751" width="14.023" height="1.52"/>
</g>
<g transform="matrix(0.285256,0,0,2.63158,8.78759,-9.87096)">
<rect x="4.25" y="3.751" width="14.023" height="1.52"/>
</g>
<g transform="matrix(0.285256,0,0,2.63158,8.78759,10.129)">
<rect x="4.25" y="3.751" width="14.023" height="1.52"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1004 B

-37
View File
@@ -1,37 +0,0 @@
{
"name": "Satonomics",
"short_name": "Satonomics",
"description": "Satoshi Economics",
"start_url": "/",
"display": "standalone",
"theme_color": "#0c0a09",
"background_color": "#0c0a09",
"lang": "en",
"scope": "/",
"icons": [
{
"src": "/assets/manifest-icon-192.maskable.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "any"
},
{
"src": "/assets/manifest-icon-192.maskable.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "maskable"
},
{
"src": "/assets/manifest-icon-512.maskable.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "any"
},
{
"src": "/assets/manifest-icon-512.maskable.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "maskable"
}
]
}
-175
View File
@@ -1,175 +0,0 @@
import { createRWS } from "/src/solid/rws";
const texts = [
"satonomics",
"satonomics",
"satonomics",
"stay humble, stack sats",
"21 million",
"cold storage",
"utxo",
"satoshi nakamoto",
"hodl",
`don't trust, verify`,
"zap",
"bitcoin",
"lightning",
"nostr",
"freedom tech",
"2008/10/31",
"2009/01/03",
"2010/05/22",
"hodl!",
"Hal Finney",
"Vote for better money",
"gradually then suddenly",
"timechain",
"self custody",
"be your own bank",
"resistance money",
"foss",
];
export const LOCAL_STORAGE_MARQUEE_KEY = "bg-marquee";
export function Background({
marquee: on,
focused,
}: {
marquee: Accessor<boolean>;
focused: Accessor<boolean>;
}) {
createEffect(() => {
if (on()) {
localStorage.removeItem(LOCAL_STORAGE_MARQUEE_KEY);
} else {
localStorage.setItem(LOCAL_STORAGE_MARQUEE_KEY, "false");
}
});
return (
<>
<div class="absolute h-full w-full overflow-hidden opacity-[0.0333] will-change-auto">
<div class="-m-[2rem] -space-y-1 overflow-hidden md:-m-[1rem]">
<Line on={on} focused={focused} />
<Line on={on} focused={focused} />
<Line on={on} focused={focused} />
<Line on={on} focused={focused} />
<Line on={on} focused={focused} />
<Line on={on} focused={focused} />
<Line on={on} focused={focused} />
<Line on={on} focused={focused} />
<Line on={on} focused={focused} />
<Line on={on} focused={focused} />
<Line on={on} focused={focused} />
<Line on={on} focused={focused} />
<Line on={on} focused={focused} />
<Line on={on} focused={focused} />
<Line on={on} focused={focused} />
<Line on={on} focused={focused} />
<Line on={on} focused={focused} />
<Line on={on} focused={focused} />
<Line on={on} focused={focused} />
<Line on={on} focused={focused} />
<Line on={on} focused={focused} />
<Line on={on} focused={focused} />
<Line on={on} focused={focused} />
</div>
</div>
<div class="absolute h-full w-full opacity-10 mix-blend-multiply">
<Noise />
</div>
<div class="absolute h-full w-full opacity-10 mix-blend-hard-light">
<Noise />
</div>
</>
);
}
function Line({
on,
focused,
}: {
on: Accessor<boolean>;
focused: Accessor<boolean>;
}) {
const shuffled = shuffle([...texts]);
shuffled.pop();
const joined = shuffled.join(". ");
return (
<div class="select-none whitespace-nowrap">
<TextWrapper on={on} focused={focused} joined={joined} />
</div>
);
}
function TextWrapper({
joined,
on,
focused,
}: {
on: Accessor<boolean>;
focused: Accessor<boolean>;
joined: string;
}) {
const seconds = joined.length * 2;
const wasOnceOn = createRWS(false);
createEffect(() => {
if (!wasOnceOn() && on()) {
wasOnceOn.set(true);
}
});
return (
<p
class="inline-block px-2 text-[5dvh] font-black uppercase leading-none"
style={{
...(wasOnceOn()
? {
animation: `marquee ${seconds}s linear infinite`,
"animation-play-state": focused() && on() ? "running" : "paused",
}
: {}),
}}
>
{joined} {wasOnceOn() ? joined : undefined}
</p>
);
}
function shuffle<T>([...arr]: T[]): T[] {
let m = arr.length;
while (m) {
const i = Math.floor(Math.random() * m--);
[arr[m], arr[i]] = [arr[i], arr[m]];
}
return arr;
}
function Noise() {
return (
<svg
class="size-full"
viewBox="0 0 200 200"
preserveAspectRatio="none"
xmlns="http://www.w3.org/2000/svg"
>
<filter id="noiseFilter">
<feTurbulence
type="fractalNoise"
baseFrequency="3"
numOctaves="3"
stitchTiles="stitch"
/>
</filter>
<rect width="100%" height="100%" filter="url(#noiseFilter)" />
</svg>
);
}
-154
View File
@@ -1,154 +0,0 @@
import { createResizeObserver } from "@solid-primitives/resize-observer";
import { classPropToString } from "/src/solid/classes";
import { createRWS } from "/src/solid/rws";
export function Box({
flex = true,
absolute,
padded = true,
children,
dark,
overflowY,
}: {
flex?: boolean;
absolute?: "top" | "bottom";
padded?: boolean;
dark?: boolean;
overflowY?: boolean;
} & ParentProps) {
const maybeScrollable = createRWS<HTMLDivElement | undefined>(undefined);
const scrollable = createRWS(false);
const showLeftArrow = createRWS(false);
const showRightArrow = createRWS(false);
onMount(() => {
createResizeObserver(maybeScrollable, (_, el) => {
if (el !== maybeScrollable()) {
return;
}
scrollable.set(() => el.scrollWidth > el.clientWidth);
checkArrows();
});
});
function checkArrows() {
const offset = 20;
const target = maybeScrollable()!;
const left = target.scrollLeft;
const right = target.scrollWidth - target.scrollLeft - target.clientWidth;
showLeftArrow.set(() => left > offset);
showRightArrow.set(() => right > offset);
}
return (
<div
class={classPropToString([
"p-2",
absolute
? [
"absolute inset-x-0",
absolute === "top"
? "top-0"
: "pointer-events-none bottom-0 bg-gradient-to-b from-transparent to-black",
]
: "relative",
])}
>
<div
class={classPropToString([
"pointer-events-auto relative overflow-hidden rounded-xl border border-orange-200/10 shadow-md",
dark
? "bg-orange-100/5 backdrop-blur-sm"
: "bg-orange-200/10 backdrop-blur-md",
])}
>
<For
each={[
{
showArrow: showLeftArrow,
side: "left-0",
order: "",
buttonPadding: "pl-3 pr-2",
iconPadding: "pr-0.5",
scrollMultiplier: -1,
chevronIcon: IconTablerChevronLeft,
gradientDirection: "bg-gradient-to-r",
},
{
showArrow: showRightArrow,
side: "right-0",
order: "order-2",
buttonPadding: "pl-2 pr-3",
iconPadding: "pl-0.5",
scrollMultiplier: 1,
chevronIcon: IconTablerChevronRight,
gradientDirection: "bg-gradient-to-l",
},
]}
>
{(obj) => (
<Show when={scrollable() && obj.showArrow()}>
<div
class={[
obj.side,
"pointer-events-none absolute bottom-0 top-0 z-20 flex transition-opacity duration-200 ease-in-out",
].join(" ")}
>
<div
class={[
obj.order,
obj.buttonPadding,
"pointer-events-auto hidden h-full items-center bg-black/90 md:flex",
].join(" ")}
>
<button
onClick={() => {
maybeScrollable()?.scrollBy({
left: Math.floor(
maybeScrollable()!.clientWidth *
obj.scrollMultiplier *
0.8,
),
behavior: "smooth",
});
}}
class="rounded-full border border-orange-200/20 bg-black p-0.5 transition hover:scale-110 active:scale-100"
>
<Dynamic
component={obj.chevronIcon}
class={[`size-5 ${obj.iconPadding}`]}
/>
</button>
</div>
<div
class={[
obj.gradientDirection,
"h-full w-10 from-black/90 to-transparent",
].join(" ")}
/>
</div>
</Show>
)}
</For>
<div
ref={maybeScrollable.set}
onScroll={checkArrows}
class={classPropToString([
flex && "flex w-full space-x-2",
overflowY && "overflow-y-auto",
padded && "p-1.5",
])}
>
{children}
</div>
</div>
</div>
);
}
-13
View File
@@ -1,13 +0,0 @@
export function Button({
onClick,
children,
}: { onClick: VoidFunction } & ParentProps) {
return (
<button
class="group flex w-full flex-1 items-center justify-center rounded-lg px-2 py-1.5 hover:bg-orange-200/20 active:scale-95"
onClick={onClick}
>
{children}
</button>
);
}
@@ -1,102 +0,0 @@
import type { Generate } from "lean-qr";
import { chartState } from "/src/scripts/lightweightCharts/chart/state";
import { setTimeScale } from "/src/scripts/lightweightCharts/chart/time";
import { classPropToString } from "/src/solid/classes";
import { createRWS } from "/src/solid/rws";
export function Actions({
presets,
fullscreen,
qrcode,
}: {
presets: Presets;
qrcode: RWS<string>;
fullscreen?: RWS<boolean>;
}) {
const leanQRGenerate = createRWS<Generate | undefined>(undefined);
onMount(() => {
import("lean-qr").then((leanQR) => {
leanQRGenerate.set(() => leanQR.generate);
});
});
return (
<div class="flex space-x-1">
<Button
icon={() => IconTablerMaximize}
onClick={() => {
const range = chartState.range;
fullscreen?.set((b) => !b);
setTimeScale(range);
}}
classes="hidden md:block"
/>
<Button
icon={() => IconTablerShare}
disabled={() => !leanQRGenerate()}
onClick={() => {
let generate = leanQRGenerate();
if (generate) {
qrcode.set(() =>
generate(document.location.href).toDataURL({
on: [0xff, 0xff, 0xff, 0xff],
off: [0x00, 0x00, 0x00, 0x00],
}),
);
}
}}
classes="hidden md:block"
/>
<Button
colors={() =>
presets.selected().isFavorite()
? "text-amber-500 bg-amber-500/15 hover:bg-amber-500/30"
: ""
}
icon={() =>
presets.selected().isFavorite()
? IconTablerStarFilled
: IconTablerStar
}
onClick={() => presets.selected().isFavorite.set((b) => !b)}
/>
</div>
);
}
function Button({
icon,
colors,
onClick,
disabled,
classes,
}: {
icon: () => ValidComponent;
colors?: () => string;
onClick: VoidFunction;
disabled?: () => boolean;
classes?: string;
}) {
return (
<button
disabled={disabled?.()}
class={classPropToString([
colors?.() || (disabled?.() ? "" : "hover:bg-orange-200/15"),
!disabled?.() && "group",
classes,
"flex-none rounded-lg p-2 disabled:opacity-50",
])}
onClick={onClick}
>
<Dynamic
component={icon()}
class="size-[1.125rem] group-active:scale-90"
/>
</button>
);
}
@@ -1,33 +0,0 @@
import { cleanChart } from "/src/scripts/lightweightCharts/chart/clean";
import { renderChart } from "/src/scripts/lightweightCharts/chart/render";
export function Chart({
presets,
datasets,
legendSetter,
activeResources,
}: {
presets: Presets;
datasets: Datasets;
legendSetter: Setter<PresetLegend>;
activeResources: Accessor<Set<ResourceDataset<any, any>>>;
}) {
onMount(() => {
createEffect(() => {
const preset = presets.selected();
untrack(() =>
renderChart({
datasets,
preset,
legendSetter,
activeResources,
}),
);
});
onCleanup(cleanChart);
});
return <div id="chart" class="h-full w-full cursor-crosshair" />;
}
@@ -1,134 +0,0 @@
import { createRWS } from "/src/solid/rws";
const transparency = "66";
export function Legend({
legend: legendList,
}: {
legend: Accessor<PresetLegend>;
}) {
const hovering = createRWS<SeriesLegend | undefined>(undefined);
let toggle = false;
return (
<div class="flex flex-1 items-center gap-1 overflow-y-auto">
<For each={legendList()}>
{(legend) => {
const initialColors = {} as any;
const darkenColors = {} as any;
Object.entries(legend.series.options()).forEach(([k, v]) => {
if (k.toLowerCase().includes("color") && v) {
initialColors[k] = v;
darkenColors[k] = `${v}${transparency}`;
} else if (k === "lastValueVisible" && v) {
initialColors[k] = v;
darkenColors[k] = !v;
}
});
createEffect(() => {
if (hovering()) {
if (hovering()?.title !== legend.title) {
legend.series.applyOptions(darkenColors);
}
} else {
legend.series.applyOptions(initialColors);
}
});
let previousClickValueOf: number = 0;
return (
<Show when={!legend.disabled()}>
<button
onMouseEnter={() => {
hovering.set(legend);
}}
onMouseLeave={() => hovering.set(undefined)}
onClick={() => {
const currentClickValueOf = new Date().valueOf();
if (currentClickValueOf - previousClickValueOf > 300) {
legend.visible.set((visible) => !visible);
} else {
legendList().forEach((_legend) => {
if (_legend.title != legend.title) {
_legend.visible.set(toggle);
}
});
legend.visible.set(true);
toggle = !toggle;
}
previousClickValueOf = currentClickValueOf;
}}
class="flex flex-none items-center space-x-1.5 rounded-full py-1.5 pl-2 pr-2.5 hover:bg-orange-200/20 active:scale-[0.975]"
>
<span
class="flex size-4 flex-col overflow-hidden rounded-full"
style={{
opacity: legend.visible() ? 1 : 0.5,
}}
>
<For
each={
Array.isArray(legend.color())
? (legend.color() as string[])
: [legend.color() as string]
}
>
{(color) => (
<span
class="w-full flex-1"
style={{
"background-color": color,
}}
/>
)}
</For>
</span>
<span
class="text-white decoration-white decoration-wavy decoration-[1.5px]"
style={{
"text-decoration-line": !legend.visible()
? "line-through"
: undefined,
"--tw-text-opacity": legend.visible() ? 1 : 0.5,
}}
>
{legend.title}
</span>
<Show when={legend.url}>
{(url) => (
<a
class="-my-0.5 !-mr-1 inline-flex size-6 flex-col overflow-hidden rounded-full border border-orange-200/5 bg-orange-200 bg-opacity-5 p-1 pl-0.5 hover:bg-opacity-30"
style={{
opacity: legend.visible() ? 1 : 0.5,
}}
onClick={(event) => {
event.stopPropagation();
// event.preventDefault();
}}
href={url()}
target={
url()?.startsWith("/") || url()?.startsWith("http")
? "_blank"
: undefined
}
>
<IconTablerExternalLink />
</a>
)}
</Show>
</button>
</Show>
);
}}
</For>
</div>
);
}
@@ -1,67 +0,0 @@
import { chartState } from "/src/scripts/lightweightCharts/chart/state";
import { GENESIS_DAY } from "/src/scripts/lightweightCharts/chart/whitespace";
import { ONE_DAY_IN_MS } from "/src/scripts/utils/time";
import { Box } from "../../box";
export function TimeScale() {
return (
<Box dark padded overflowY>
<Button onClick={() => setTimeScale()}>All Time</Button>
<Button onClick={() => setTimeScale(7)}>1 Week</Button>
<Button onClick={() => setTimeScale(30)}>1 Month</Button>
<Button onClick={() => setTimeScale(30 * 6)}>6 Months</Button>
<Button
onClick={() =>
setTimeScale(
Math.ceil(
(new Date().valueOf() -
new Date(`${new Date().getUTCFullYear()}-01-01`).valueOf()) /
ONE_DAY_IN_MS,
),
)
}
>
Year To Date
</Button>
<Button onClick={() => setTimeScale(365)}>1 Year</Button>
<Button onClick={() => setTimeScale(2 * 365)}>2 Years</Button>
<Button onClick={() => setTimeScale(4 * 365)}>4 Years</Button>
<Button onClick={() => setTimeScale(8 * 365)}>8 Years</Button>
</Box>
);
}
function Button(props: ParentProps & { onClick: VoidFunction }) {
return (
<button
class="min-w-20 flex-shrink-0 flex-grow whitespace-nowrap rounded-lg px-2 py-1.5 hover:bg-white/20 active:scale-95"
onClick={props.onClick}
>
{props.children}
</button>
);
}
function setTimeScale(days?: number) {
const to = new Date();
if (days) {
const from = new Date();
from.setDate(from.getUTCDate() - days);
chartState.chart?.timeScale().setVisibleRange({
from: (from.getTime() / 1000) as Time,
to: (to.getTime() / 1000) as Time,
});
} else {
// chartState.chart?.timeScale().fitContent();
chartState.chart?.timeScale().setVisibleRange({
from: (new Date(
// datasets.candlesticks.values()?.[0]?.date || "",
GENESIS_DAY,
).getTime() / 1000) as Time,
to: (to.getTime() / 1000) as Time,
});
}
}
@@ -1,12 +0,0 @@
export function Title({ presets }: { presets: Presets }) {
return (
<div class="flex flex-1 items-center overflow-y-auto pb-1.5 text-orange-100/50">
<div class="flex-1 -space-y-1 whitespace-nowrap px-1 md:mt-0.5 md:-space-y-1.5">
<h3 class="text-xs">{`/ ${[...presets.selected().path.map(({ name }) => name), presets.selected().name].join(" / ")}`}</h3>
<h1 class="text-lg font-bold text-white md:text-xl">
{presets.selected().title}
</h1>
</div>
</div>
);
}
@@ -1,72 +0,0 @@
import { classPropToString } from "/src/solid/classes";
import { createRWS } from "/src/solid/rws";
import { Box } from "../box";
import { Actions } from "./components/actions";
import { Legend } from "./components/legend";
import { TimeScale } from "./components/timeScale";
import { Title } from "./components/title";
export function ChartFrame({
presets,
datasets,
activeResources,
hide,
qrcode,
standalone,
fullscreen,
}: {
presets: Presets;
hide?: Accessor<boolean>;
qrcode: RWS<string>;
activeResources: Accessor<Set<ResourceDataset<any, any>>>;
datasets: Datasets;
fullscreen?: RWS<boolean>;
standalone: boolean;
}) {
const legend = createRWS<PresetLegend>([]);
const Chart = lazy(() =>
import("./components/chart").then((d) => ({
default: d.Chart,
})),
);
return (
<div
class={classPropToString([
standalone &&
"rounded-2xl border border-orange-200/15 bg-gradient-to-b from-orange-100/5 to-black/10 to-80%",
"flex size-full min-h-0 flex-1 flex-col overflow-hidden",
])}
style={{
display: (hide ? !hide() : true) ? undefined : "none",
}}
>
<Box flex={false} dark>
<Title presets={presets} />
<div class="-mx-2 border-t border-orange-200/15" />
<div class="flex pt-1.5">
<Legend legend={legend} />
<div class="-my-1.5 border-l border-orange-200/15 pr-1.5" />
<Actions presets={presets} qrcode={qrcode} fullscreen={fullscreen} />
</div>
</Box>
<div class="-mt-2 min-h-0 flex-1">
<Chart
activeResources={activeResources}
datasets={datasets}
legendSetter={legend.set}
presets={presets}
/>
</div>
<TimeScale />
</div>
);
}
-25
View File
@@ -1,25 +0,0 @@
export function Counter({
count,
name,
setRef,
}: {
count: () => number;
name: string;
setRef?: Setter<HTMLDivElement | undefined>;
}) {
return (
<div
ref={setRef}
class="text-orange-100/75"
style={{
"border-style": count() ? "dashed" : "none",
}}
>
Counted{" "}
<span class="font-medium text-orange-400/75">
{count().toLocaleString("en-us")}
</span>{" "}
{name}
</div>
);
}
@@ -1,48 +0,0 @@
import { Header } from "./header";
import { Line } from "./line";
import { Number } from "./number";
export function FavoritesFrame({
presets,
selectedFrame,
}: {
presets: Presets;
selectedFrame: Accessor<FrameName>;
}) {
return (
<div
class="flex-1 overflow-y-auto"
hidden={selectedFrame() !== "Favorites"}
>
<div class="flex max-h-full min-h-0 flex-1 flex-col gap-4 p-4">
<Header title="Favorites">
<Number number={() => presets.favorites().length} /> presets marked as
favorites.
</Header>
<div class="-mx-4 border-t border-orange-200/10" />
<div
class="space-y-0.5 py-1"
style={{
display: !presets.favorites().length ? "none" : undefined,
}}
>
<For each={presets.favorites()}>
{(preset) => (
<Line
id={`favorite-${preset.id}`}
name={preset.title}
onClick={() => presets.select(preset)}
active={() => presets.selected() === preset}
header={`/ ${[...preset.path.map(({ name }) => name), preset.name].join(" / ")}`}
/>
)}
</For>
</div>
<div class="h-[25dvh] flex-none" />
</div>
</div>
);
}
-8
View File
@@ -1,8 +0,0 @@
export function Header({ title, children }: { title: string } & ParentProps) {
return (
<div>
<h3 class="text-lg font-bold md:text-xl">{title}</h3>
<p class="text-orange-100/75">{children}</p>
</div>
);
}
-80
View File
@@ -1,80 +0,0 @@
import { run } from "/src/scripts/utils/run";
import { Header } from "./header";
import { Line } from "./line";
export function HistoryFrame({
presets,
selectedFrame,
}: {
presets: Presets;
selectedFrame: Accessor<FrameName>;
}) {
return (
<div class="flex-1 overflow-y-auto" hidden={selectedFrame() !== "History"}>
<div class="flex max-h-full min-h-0 flex-1 flex-col p-4">
<Header title="History">List of previously visited presets.</Header>
<div
class="space-y-0.5 pt-4"
style={{
display: !presets.history().length ? "none" : undefined,
}}
>
<For each={presets.history()}>
{({ preset, date }, index) => (
<>
<Show
when={
index() === 0 ||
presets.history()[index()].date.toJSON().split("T")[0] !==
presets.history()[index() - 1].date.toJSON().split("T")[0]
}
>
<div class="sticky top-[-0.5rem] z-10 -mx-4 py-2">
<div class="border-y border-orange-200/10 bg-[rgb(25,15,15)] p-2">
<p class="ml-2">
<Switch fallback={date.toLocaleDateString()}>
<Match
when={
new Date().toJSON().split("T")[0] ===
date.toJSON().split("T")[0]
}
>
Today
</Match>
<Match
when={
run(() => {
const d = new Date();
d.setDate(d.getDate() - 1);
return d;
})
.toJSON()
.split("T")[0] === date.toJSON().split("T")[0]
}
>
Yesterday
</Match>
</Switch>
</p>
</div>
</div>
</Show>
<Line
id={`history-${preset.id}`}
name={preset.title}
onClick={() => presets.select(preset)}
active={() => presets.selected() === preset}
header={date.toLocaleTimeString()}
/>
</>
)}
</For>
</div>
<div class="h-[25dvh] flex-none" />
</div>
</div>
);
}
-90
View File
@@ -1,90 +0,0 @@
import { scrollIntoView } from "/src/scripts/utils/scroll";
import { classPropToString } from "/src/solid/classes";
import { createRWS } from "/src/solid/rws";
export function Line({
id,
name: _name,
icon,
active,
depth = 0,
onClick,
header,
tail,
classes: classes,
}: {
id: string;
name: string;
onClick: VoidFunction;
active?: Accessor<boolean>;
depth?: number;
header?: string;
icon?: () => JSXElement;
tail?: () => JSXElement;
classes?: () => string;
} & ParentProps) {
const ref = createRWS<HTMLButtonElement | undefined>(undefined);
const [name, ...nameRest] = _name.split(" - ");
return (
<button
id={id}
class={classPropToString([
active?.()
? "bg-orange-500/30 backdrop-blur-sm hover:bg-orange-500/50"
: "hover:bg-orange-500/15",
"relative -mx-2 flex w-[calc(100%+1rem)] items-center whitespace-nowrap rounded-lg px-2 hover:backdrop-blur-sm",
classes?.(),
])}
ref={ref.set}
onClick={() => {
onClick();
scrollIntoView(ref(), "nearest", "instant");
}}
title={name}
>
<For each={new Array(depth)}>
{() => (
<span class="ml-1 h-8 w-3 flex-none border-l border-orange-200/10" />
)}
</For>
<Show when={icon}>
{(icon) => (
<span
class="-my-0.5 mr-1"
// style={{
// "margin-left": `${depth}rem`,
// }}
>
{icon()()}
</span>
)}
</Show>
<span
class={classPropToString([
!icon && "px-1",
"inline-flex w-full flex-col -space-y-1 truncate py-1 text-left",
])}
>
<Show when={header}>
<span
class="truncate text-xs text-white text-opacity-50"
innerHTML={header}
/>
</Show>
<span class="space-x-1 truncate">
<span innerHTML={name} />
<Show when={nameRest.length}>
<span innerHTML={" - " + nameRest.join(" - ")} class="opacity-50" />
</Show>
</span>
</span>
<Show when={tail}>
{(absolute) => (
<span class="ml-0.5 flex items-center">{absolute()()}</span>
)}
</Show>
</button>
);
}
-7
View File
@@ -1,7 +0,0 @@
export function Number({ number }: { number: () => number }) {
return (
<span class="font-medium text-orange-400/75">
{number().toLocaleString("en-us")}
</span>
);
}
-318
View File
@@ -1,318 +0,0 @@
import uFuzzy from "@leeoniya/ufuzzy";
import { createVisibilityObserver } from "@solid-primitives/intersection-observer";
import { scrollIntoView } from "/src/scripts/utils/scroll";
import { createRWS } from "/src/solid/rws";
import { INPUT_PRESET_SEARCH_ID } from "../..";
import { Box } from "./box";
import { Button } from "./button";
import { Line } from "./line";
const PER_PAGE = 100;
export function SearchFrame({
presets,
selectedFrame,
}: {
presets: Presets;
selectedFrame: Accessor<FrameName>;
}) {
const counterRef = createRWS<HTMLDivElement | undefined>(undefined);
const search = createRWS("", {
equals: false,
});
const inputRef = createRWS<HTMLInputElement | undefined>(undefined);
const config: uFuzzy.Options = {
intraIns: Infinity,
intraChars: `[a-z\d' ]`,
};
const fuzzyMultiInsert = new uFuzzy({
intraIns: 1,
});
const fuzzyMultiInsertFuzzier = new uFuzzy(config);
const fuzzySingleError = new uFuzzy({
intraMode: 1,
...config,
});
const fuzzySingleErrorFuzzier = new uFuzzy({
intraMode: 1,
...config,
});
const haystack = presets.list.map(
(preset) =>
`${preset.title}\t/ ${[...preset.path.map(({ name }) => name), preset.name].join(" / ")}`,
);
const searchResult = createMemo(() => {
scrollIntoView(counterRef());
const needle = search();
if (!needle) return null;
const outOfOrder = 5;
const infoThresh = 5_000;
let result = fuzzyMultiInsert.search(
haystack,
needle,
undefined,
infoThresh,
);
if (!result?.[0]?.length || !result?.[1]) {
result = fuzzyMultiInsert.search(
haystack,
needle,
outOfOrder,
infoThresh,
);
}
if (!result?.[0]?.length || !result?.[1]) {
result = fuzzySingleError.search(
haystack,
needle,
outOfOrder,
infoThresh,
);
}
if (!result?.[0]?.length || !result?.[1]) {
result = fuzzySingleErrorFuzzier.search(
haystack,
needle,
outOfOrder,
infoThresh,
);
}
if (!result?.[0]?.length || !result?.[1]) {
result = fuzzyMultiInsertFuzzier.search(
haystack,
needle,
undefined,
infoThresh,
);
}
if (!result?.[0]?.length || !result?.[1]) {
result = fuzzyMultiInsertFuzzier.search(
haystack,
needle,
outOfOrder,
infoThresh,
);
}
return result;
});
const resultCount = createMemo(() => searchResult()?.[0]?.length || 0);
return (
<div
class="relative flex size-full flex-1 flex-col"
style={{
display: selectedFrame() !== "Search" ? "none" : undefined,
}}
>
<div class="flex-1 space-y-1 overflow-y-auto p-4 pt-16">
<p class="py-2 text-orange-100/75">
<Show when={search()} fallback={"Write in the top bar to search."}>
Found{" "}
<span class="font-medium text-orange-400/75">
{resultCount().toLocaleString("en-us")}
</span>{" "}
presets.
</Show>
</p>
<Show when={search()}>
<div class="-mx-4 border-t border-orange-200/10" />
<div
class="py-1"
style={{
display: !resultCount() ? "none" : undefined,
}}
>
{(() => {
const r = searchResult();
if (r) {
return (
<ListSection
haystack={haystack}
presets={presets}
searchResult={() => r}
/>
);
} else {
return undefined;
}
})()}
</div>
</Show>
</div>
<Box absolute="top" padded={false}>
<div
class="relative flex w-full cursor-text items-center space-x-0.5 px-3 py-2 hover:bg-orange-200/5"
onClick={() => inputRef()?.focus()}
>
<IconTablerSearch />
<input
id={INPUT_PRESET_SEARCH_ID}
ref={inputRef.set}
class="w-full bg-transparent p-1 caret-orange-500 placeholder:text-orange-200/50 focus:outline-none"
placeholder="Search by name or path"
value={search()}
onInput={(event) => search.set(event.target.value)}
/>
<span class="-mx-1 flex size-5 flex-none items-center justify-center rounded-md border border-white text-xs font-bold">
<IconTablerSlash />
</span>
</div>
</Box>
<Box absolute="bottom">
<Button
onClick={() => {
search.set("");
inputRef()?.focus();
}}
>
Clear search
</Button>
</Box>
</div>
);
}
function ListSection({
searchResult,
pageIndex = 0,
haystack,
presets,
}: {
searchResult: Accessor<uFuzzy.SearchResult>;
pageIndex?: number;
haystack: string[];
presets: Presets;
}) {
const div = createRWS<HTMLDivElement | undefined>(undefined);
const useVisibilityObserver = createVisibilityObserver();
const visible = useVisibilityObserver(div);
const showNextPage = createMemo<boolean>(
(previous) => previous || visible(),
false,
);
const list = createMemo(() =>
computeList({
searchResult: searchResult(),
pageIndex,
haystack,
presets,
}),
);
return (
<div>
<For each={list()}>
{({ preset, path, title }) => (
<Line
id={`search-${preset.id}`}
name={title}
onClick={() => presets.select(preset)}
active={() => presets.selected() === preset}
header={path}
/>
)}
</For>
<Show when={list().length === PER_PAGE}>
<div ref={div.set}>
<Show when={showNextPage()}>
<ListSection
searchResult={searchResult}
haystack={haystack}
presets={presets}
pageIndex={pageIndex + 1}
/>
</Show>
</div>
</Show>
</div>
);
}
function computeList({
searchResult,
pageIndex,
haystack,
presets,
}: {
searchResult: uFuzzy.SearchResult;
pageIndex: number;
haystack: string[];
presets: Presets;
}) {
let list: {
preset: Preset;
path: string;
title: string;
}[] = [];
let [indexes, info, order] = searchResult || [null, null, null];
const minIndex = pageIndex * PER_PAGE;
if (indexes?.length) {
const maxIndex = Math.min(
(order || indexes).length - 1,
minIndex + PER_PAGE - 1,
);
list = Array(maxIndex - minIndex + 1);
if (info && order) {
for (let i = minIndex; i <= maxIndex; i++) {
let infoIdx = order[i];
const [title, path] = uFuzzy
.highlight(haystack[info.idx[infoIdx]], info.ranges[infoIdx])
.split("\t");
list[i % 100] = {
preset: presets.list[info.idx[infoIdx]],
path,
title,
};
}
} else {
for (let i = minIndex; i <= maxIndex; i++) {
let index = indexes[i];
const [title, path] = haystack[index].split("\t");
list[i % 100] = {
preset: presets.list[index],
path,
title,
};
}
}
}
return list;
}
@@ -1,37 +0,0 @@
import { Header } from "./header";
export function SettingsFrame({
marquee,
selectedFrame,
}: {
marquee: RWS<boolean>;
selectedFrame: Accessor<FrameName>;
}) {
const value = marquee();
return (
<div class="flex-1 overflow-y-auto" hidden={selectedFrame() !== "Settings"}>
<div class="space-y-4 p-4">
<Header title="Settings" />
<div class="-mx-4 border-t border-orange-200/10" />
<div class="space-y-2">
<p>Background</p>
<div>Opacity</div>
<div>
<label class="switch">
Scroll
<input
type="checkbox"
checked={value}
onChange={(event) => marquee.set(event.target.checked || false)}
/>
<span class="slider"></span>
</label>
</div>
</div>
</div>
</div>
);
}
@@ -1,47 +0,0 @@
import { Line } from "../../line";
export function File({
id,
name,
icon,
active,
depth,
onClick,
favorite,
visited,
}: {
id: string;
name: string;
icon: JSXElement;
active: Accessor<boolean>;
depth: number;
onClick: VoidFunction;
favorite: Accessor<boolean>;
visited: Accessor<boolean>;
}) {
const tail = createMemo(() =>
favorite() ? (
<span class="rounded-full bg-yellow-950 p-1">
<IconTablerStarFilled class="size-3 text-amber-500" />
</span>
) : !visited() ? (
<span class="mx-1.5 rounded-full bg-orange-500/50 p-1 text-transparent" />
) : undefined,
);
return (
<Line
id={id}
depth={depth}
active={active}
name={name}
icon={() => icon}
onClick={onClick}
tail={tail}
/>
);
}
function randomDegree(min = 0, max = 360) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
@@ -1,39 +0,0 @@
import { Line } from "../../line";
export function Folder({
id,
name,
depth,
open,
onClick,
children,
}: {
id: string;
name: string;
depth: number;
open: Accessor<boolean>;
onClick: VoidFunction;
children: number;
}) {
const icon = createMemo(() =>
open() ? <IconTablerFolderOpen /> : <IconTablerFolder />,
);
return (
<Line
id={id}
depth={depth}
name={name}
icon={icon}
onClick={onClick}
classes={() => (open() ? "text-orange-100/75" : "")}
tail={() => (
<Show when={!open()}>
<span class="rounded-full bg-white bg-opacity-[0.075] px-2 py-0.5 text-xs text-neutral-400">
{children}
</span>
</Show>
)}
></Line>
);
}
@@ -1,117 +0,0 @@
import { File } from "./file";
import { Folder } from "./folder";
export function Tree({
tree,
selected,
openedFolders,
depth = 0,
visible,
selectPreset,
path = [],
favorites,
}: {
tree: PresetTree;
selected: Accessor<Preset>;
selectPreset(preset: Preset): void;
openedFolders: RWS<Set<string>>;
depth?: number;
visible?: Accessor<boolean>;
path?: FilePath;
favorites: Accessor<Preset[]>;
}) {
return (
<div style={{ display: visible?.() === false ? "none" : undefined }}>
<For each={tree}>
{(thing) => {
const active = createMemo(() => thing.id === selected().id);
const favorite = createMemo(() =>
favorites().includes(thing as Preset),
);
const visited = (thing as Preset).visited;
if (!("tree" in thing)) {
return (
<File
id={thing.id}
name={thing.name}
active={active}
depth={depth}
icon={thing.icon || IconTablerFile}
favorite={favorite}
visited={visited}
onClick={() => {
const selectedId = selected().id;
if (selectedId === thing.id) {
return;
}
// Has been filled in createPresets
selectPreset(thing as Preset);
}}
/>
);
}
const childrenVisible = createMemo(() =>
openedFolders().has(thing.id),
);
const childCount = countChildren(thing);
return (
<div>
<Folder
id={thing.id}
name={thing.name}
depth={depth}
open={childrenVisible}
children={childCount}
onClick={() => {
openedFolders.set((s) => {
if (childrenVisible()) {
s.delete(thing.id);
} else {
s.add(thing.id);
}
return s;
});
}}
/>
<Tree
tree={thing.tree}
selected={selected}
depth={depth + 1}
openedFolders={openedFolders}
visible={childrenVisible}
path={[...path, { name: thing.name, id: thing.id }]}
selectPreset={selectPreset}
favorites={favorites}
/>
</div>
);
}}
</For>
</div>
);
}
function countChildren(folder: PresetFolder) {
let count = 0;
function _countChildren(tree: PartialPresetTree) {
tree.forEach((anyPreset) => {
if ("tree" in anyPreset) {
_countChildren(anyPreset.tree);
} else {
count += 1;
}
});
}
_countChildren(folder.tree);
return count;
}
@@ -1,86 +0,0 @@
import { scrollIntoView } from "/src/scripts/utils/scroll";
import { sleep, tick } from "/src/scripts/utils/sleep";
import { createRWS } from "/src/solid/rws";
import { Box } from "../box";
import { Button } from "../button";
import { Header } from "../header";
import { Number } from "../number";
import { Tree } from "./components/tree";
export function TreeFrame({
presets,
selectedFrame,
}: {
presets: Presets;
selectedFrame: Accessor<FrameName>;
}) {
const div = createRWS<HTMLDivElement | undefined>(undefined);
onMount(() => {
goToSelected(presets);
});
return (
<div
class="relative flex size-full flex-1 flex-col"
style={{
display: selectedFrame() !== "Tree" ? "none" : undefined,
}}
>
<div class="flex-1 overflow-y-auto">
<div class="flex max-h-full min-h-0 flex-1 flex-col gap-4 p-4">
<Header title="Folders">
<Number number={() => presets.list.length} /> presets organized in a
tree like structure.
</Header>
<div class="-mx-4 border-t border-orange-200/10" />
<Tree
tree={presets.tree}
openedFolders={presets.openedFolders}
selected={presets.selected}
selectPreset={presets.select}
favorites={presets.favorites}
/>
<div class="h-[50dvh] flex-none" />
</div>
</div>
<Box absolute="bottom">
<Button
onClick={() => {
presets.openedFolders.set((s) => {
s.clear();
return s;
});
sleep(10);
scrollIntoView(div());
}}
>
Close all folders
</Button>
<Button onClick={() => goToSelected(presets)}>Go to selected</Button>
</Box>
</div>
);
}
async function goToSelected(presets: Presets) {
batch(() =>
presets.selected().path.forEach(({ id }) => {
presets.openedFolders.set((s) => {
s.add(id);
return s;
});
}),
);
await tick();
scrollIntoView(document.getElementById(presets.selected().id), "center");
}
-18
View File
@@ -1,18 +0,0 @@
export function Qrcode({ qrcode }: { qrcode: RWS<string> }) {
return (
<Show when={qrcode()}>
<div
class="absolute inset-0 z-50 flex h-full w-full items-center justify-center bg-black"
onClick={() => {
qrcode.set("");
}}
>
<img
class="aspect-square max-h-full grow object-contain"
src={qrcode()}
style={{ "image-rendering": "pixelated" }}
/>
</div>
</Show>
);
}
@@ -1,9 +0,0 @@
import { Clickable } from "./clickable";
export function Anchor(args: {
title: string;
href: string;
icon?: () => ValidComponent;
}) {
return <Clickable {...args} />;
}
@@ -1,26 +0,0 @@
import { Anchor } from "./anchor";
export function AnchorAPI() {
return (
<Anchor
title="API"
icon={() => () => (
<svg
width="20"
height="20"
viewBox="0 0 20 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M5.13468 2.41153C3.88395 3.0478 3.37143 3.79772 3.37143 4.4186C3.37143 5.03949 3.88395 5.78941 5.13468 6.42568C6.3444 7.04109 8.06359 7.44186 10 7.44186C11.9364 7.44186 13.6556 7.04109 14.8653 6.42568C16.1161 5.78941 16.6286 5.03949 16.6286 4.4186C16.6286 3.79772 16.1161 3.0478 14.8653 2.41153C13.6556 1.79612 11.9364 1.39535 10 1.39535C8.06359 1.39535 6.3444 1.79612 5.13468 2.41153ZM16.6286 6.93694C16.2841 7.21648 15.8934 7.46274 15.4786 7.67372C14.0411 8.40502 12.1032 8.83721 10 8.83721C7.89684 8.83721 5.95889 8.40502 4.52136 7.67372C4.10664 7.46274 3.71588 7.21648 3.37143 6.93694V10C3.37143 10.6209 3.88395 11.3708 5.13468 12.0071C6.3444 12.6225 8.06359 13.0233 10 13.0233C11.9364 13.0233 13.6556 12.6225 14.8653 12.0071C16.1161 11.3708 16.6286 10.6209 16.6286 10V6.93694ZM18 4.4186C18 2.98447 16.8752 1.87393 15.4786 1.16349C14.0411 0.432186 12.1032 0 10 0C7.89684 0 5.95889 0.432186 4.52136 1.16349C3.12484 1.87393 2 2.98447 2 4.4186V15.5814C2 17.0155 3.12484 18.1261 4.52136 18.8365C5.95889 19.5678 7.89684 20 10 20C12.1032 20 14.0411 19.5678 15.4786 18.8365C16.8752 18.1261 18 17.0155 18 15.5814V4.4186ZM16.6286 12.5183C16.2841 12.7979 15.8934 13.0441 15.4786 13.2551C14.0411 13.9864 12.1032 14.4186 10 14.4186C7.89684 14.4186 5.95889 13.9864 4.52136 13.2551C4.10664 13.0441 3.71588 12.7979 3.37143 12.5183V15.5814C3.37143 16.2023 3.88395 16.9522 5.13468 17.5885C6.3444 18.2039 8.06359 18.6047 10 18.6047C11.9364 18.6047 13.6556 18.2039 14.8653 17.5885C16.1161 16.9522 16.6286 16.2023 16.6286 15.5814V12.5183ZM6.34285 10C6.34285 10.5138 5.93351 10.9302 5.42857 10.9302C4.92362 10.9302 4.51428 10.5138 4.51428 10C4.51428 9.48625 4.92362 9.06977 5.42857 9.06977C5.93351 9.06977 6.34285 9.48625 6.34285 10ZM9.0857 11.8605C9.59065 11.8605 9.99999 11.444 9.99999 10.9302C9.99999 10.4165 9.59065 10 9.0857 10C8.58076 10 8.17142 10.4165 8.17142 10.9302C8.17142 11.444 8.58076 11.8605 9.0857 11.8605ZM6.34285 15.5814C6.34285 16.0951 5.93351 16.5116 5.42857 16.5116C4.92362 16.5116 4.51428 16.0951 4.51428 15.5814C4.51428 15.0676 4.92362 14.6512 5.42857 14.6512C5.93351 14.6512 6.34285 15.0676 6.34285 15.5814ZM9.0857 17.4419C9.59065 17.4419 9.99999 17.0254 9.99999 16.5116C9.99999 15.9979 9.59065 15.5814 9.0857 15.5814C8.58076 15.5814 8.17142 15.9979 8.17142 16.5116C8.17142 17.0254 8.58076 17.4419 9.0857 17.4419Z"
fill="currentColor"
></path>
</svg>
)}
href="https://api.satonomics.xyz"
/>
);
}
@@ -1,11 +0,0 @@
import { Anchor } from "./anchor";
export function AnchorGit() {
return (
<Anchor
title="Git"
icon={() => IconTablerGitMerge}
href="https://codeberg.org/satonomics/satonomics"
/>
);
}
@@ -1,32 +0,0 @@
import { Anchor } from "./anchor";
export function AnchorHome() {
return (
<Anchor
title="Home"
icon={() => () => (
<svg
width="20"
height="20"
viewBox="0 0 20 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M9.61843 17.395H10.3816C12.1046 17.395 13.288 17.3933 14.198 17.3045C15.0844 17.218 15.5498 17.0602 15.8839 16.8482C16.3124 16.5763 16.6761 16.2149 16.9497 15.7891C17.1631 15.4571 17.3218 14.9946 17.4089 14.1138C17.4983 13.2096 17.5 12.0337 17.5 10.3216C17.5 8.25521 17.4763 7.61464 17.2665 7.07287C17.1488 6.76889 16.9887 6.48284 16.7909 6.22312C16.4384 5.76023 15.9032 5.40234 14.1365 4.31233L13.9563 4.20109C12.9121 3.55687 12.2055 3.12231 11.6218 2.82577C11.0608 2.54075 10.7049 2.43259 10.3882 2.39747C10.1302 2.36886 9.86981 2.36886 9.61184 2.39747C9.29509 2.43259 8.9392 2.54075 8.37818 2.82577C7.79446 3.12231 7.08787 3.55687 6.04374 4.20109L5.86345 4.31233C4.09679 5.40234 3.56162 5.76023 3.20909 6.22312C3.01129 6.48284 2.85119 6.76889 2.73348 7.07287C2.52369 7.61464 2.5 8.25521 2.5 10.3216C2.5 12.0337 2.50169 13.2096 2.59108 14.1138C2.67816 14.9946 2.83688 15.4571 3.05029 15.7891C3.32393 16.2149 3.68762 16.5763 4.11606 16.8482C4.45021 17.0602 4.91563 17.218 5.80203 17.3045C6.71202 17.3933 7.89539 17.395 9.61843 17.395ZM1.33354 6.5376C1 7.39893 1 8.37315 1 10.3216C1 13.6861 1 15.3684 1.78613 16.5914C2.17705 17.1996 2.6966 17.7159 3.30866 18.1043C4.53951 18.8855 6.23249 18.8855 9.61843 18.8855H10.3816C13.7675 18.8855 15.4605 18.8855 16.6913 18.1043C17.3034 17.7159 17.823 17.1996 18.2139 16.5914C19 15.3684 19 13.6861 19 10.3216C19 8.37315 19 7.39893 18.6665 6.5376C18.4983 6.10334 18.2696 5.6947 17.987 5.32367C17.4265 4.58775 16.5936 4.07385 14.9278 3.04605L14.7475 2.93482C12.7009 1.67205 11.6775 1.04067 10.5545 0.916147C10.186 0.875282 9.81402 0.875282 9.44549 0.916147C8.32248 1.04067 7.29915 1.67205 5.25249 2.93482L5.0722 3.04605C3.40637 4.07385 2.57345 4.58775 2.01299 5.32367C1.73042 5.6947 1.5017 6.10334 1.33354 6.5376Z"
fill="currentColor"
></path>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M6.25 14.0001C6.25 13.5858 6.58579 13.2501 7 13.2501H13C13.4142 13.2501 13.75 13.5858 13.75 14.0001C13.75 14.4143 13.4142 14.7501 13 14.7501H7C6.58579 14.7501 6.25 14.4143 6.25 14.0001Z"
fill="currentColor"
></path>
</svg>
)}
href="https://satonomics.xyz"
/>
);
}

Some files were not shown because too many files have changed in this diff Show More