Compare commits

..

5 Commits

Author SHA1 Message Date
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
98 changed files with 488 additions and 691 deletions
Generated
+17 -20
View File
@@ -443,7 +443,7 @@ dependencies = [
[[package]] [[package]]
name = "brk" name = "brk"
version = "0.0.61" version = "0.0.63"
dependencies = [ dependencies = [
"brk_bundler", "brk_bundler",
"brk_cli", "brk_cli",
@@ -463,7 +463,7 @@ dependencies = [
[[package]] [[package]]
name = "brk_bundler" name = "brk_bundler"
version = "0.0.61" version = "0.0.63"
dependencies = [ dependencies = [
"brk_rolldown", "brk_rolldown",
"log", "log",
@@ -474,7 +474,7 @@ dependencies = [
[[package]] [[package]]
name = "brk_cli" name = "brk_cli"
version = "0.0.61" version = "0.0.63"
dependencies = [ dependencies = [
"bitcoincore-rpc", "bitcoincore-rpc",
"brk_computer", "brk_computer",
@@ -499,7 +499,7 @@ dependencies = [
[[package]] [[package]]
name = "brk_computer" name = "brk_computer"
version = "0.0.61" version = "0.0.63"
dependencies = [ dependencies = [
"bitcoin", "bitcoin",
"bitcoincore-rpc", "bitcoincore-rpc",
@@ -520,7 +520,7 @@ dependencies = [
[[package]] [[package]]
name = "brk_core" name = "brk_core"
version = "0.0.61" version = "0.0.63"
dependencies = [ dependencies = [
"bincode", "bincode",
"bitcoin", "bitcoin",
@@ -541,7 +541,7 @@ dependencies = [
[[package]] [[package]]
name = "brk_exit" name = "brk_exit"
version = "0.0.61" version = "0.0.63"
dependencies = [ dependencies = [
"brk_logger", "brk_logger",
"ctrlc", "ctrlc",
@@ -550,7 +550,7 @@ dependencies = [
[[package]] [[package]]
name = "brk_fetcher" name = "brk_fetcher"
version = "0.0.61" version = "0.0.63"
dependencies = [ dependencies = [
"brk_core", "brk_core",
"brk_logger", "brk_logger",
@@ -563,7 +563,7 @@ dependencies = [
[[package]] [[package]]
name = "brk_indexer" name = "brk_indexer"
version = "0.0.61" version = "0.0.63"
dependencies = [ dependencies = [
"bitcoin", "bitcoin",
"bitcoincore-rpc", "bitcoincore-rpc",
@@ -581,7 +581,7 @@ dependencies = [
[[package]] [[package]]
name = "brk_logger" name = "brk_logger"
version = "0.0.61" version = "0.0.63"
dependencies = [ dependencies = [
"color-eyre", "color-eyre",
"env_logger", "env_logger",
@@ -591,7 +591,7 @@ dependencies = [
[[package]] [[package]]
name = "brk_parser" name = "brk_parser"
version = "0.0.61" version = "0.0.63"
dependencies = [ dependencies = [
"bitcoin", "bitcoin",
"bitcoincore-rpc", "bitcoincore-rpc",
@@ -606,7 +606,7 @@ dependencies = [
[[package]] [[package]]
name = "brk_query" name = "brk_query"
version = "0.0.61" version = "0.0.63"
dependencies = [ dependencies = [
"brk_computer", "brk_computer",
"brk_core", "brk_core",
@@ -929,7 +929,7 @@ dependencies = [
[[package]] [[package]]
name = "brk_server" name = "brk_server"
version = "0.0.61" version = "0.0.63"
dependencies = [ dependencies = [
"axum", "axum",
"bitcoincore-rpc", "bitcoincore-rpc",
@@ -959,7 +959,7 @@ dependencies = [
[[package]] [[package]]
name = "brk_state" name = "brk_state"
version = "0.0.61" version = "0.0.63"
dependencies = [ dependencies = [
"bincode", "bincode",
"brk_core", "brk_core",
@@ -973,7 +973,7 @@ dependencies = [
[[package]] [[package]]
name = "brk_store" name = "brk_store"
version = "0.0.61" version = "0.0.63"
dependencies = [ dependencies = [
"arc-swap", "arc-swap",
"brk_core", "brk_core",
@@ -995,7 +995,7 @@ dependencies = [
[[package]] [[package]]
name = "brk_vec" name = "brk_vec"
version = "0.0.61" version = "0.0.63"
dependencies = [ dependencies = [
"arc-swap", "arc-swap",
"brk_core", "brk_core",
@@ -3683,12 +3683,9 @@ checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d"
[[package]] [[package]]
name = "slab" name = "slab"
version = "0.4.9" version = "0.4.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" checksum = "04dc19736151f35336d325007ac991178d504a119863a2fcb3758cdb5e52c50d"
dependencies = [
"autocfg",
]
[[package]] [[package]]
name = "smallvec" name = "smallvec"
+15 -15
View File
@@ -4,7 +4,7 @@ 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.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.license = "MIT"
package.edition = "2024" package.edition = "2024"
package.version = "0.0.61" package.version = "0.0.63"
package.homepage = "https://bitcoinresearchkit.org" package.homepage = "https://bitcoinresearchkit.org"
package.repository = "https://github.com/bitcoinresearchkit/brk" package.repository = "https://github.com/bitcoinresearchkit/brk"
@@ -22,20 +22,20 @@ axum = "0.8.4"
bincode = { version = "2.0.1", features = ["serde"] } bincode = { version = "2.0.1", features = ["serde"] }
bitcoin = { version = "0.32.6", features = ["serde"] } bitcoin = { version = "0.32.6", features = ["serde"] }
bitcoincore-rpc = "0.19.0" bitcoincore-rpc = "0.19.0"
brk_bundler = { version = "0.0.61", path = "crates/brk_bundler" } brk_bundler = { version = "0.0.63", path = "crates/brk_bundler" }
brk_cli = { version = "0.0.61", path = "crates/brk_cli" } brk_cli = { version = "0.0.63", path = "crates/brk_cli" }
brk_computer = { version = "0.0.61", path = "crates/brk_computer" } brk_computer = { version = "0.0.63", path = "crates/brk_computer" }
brk_core = { version = "0.0.61", path = "crates/brk_core" } brk_core = { version = "0.0.63", path = "crates/brk_core" }
brk_exit = { version = "0.0.61", path = "crates/brk_exit" } brk_exit = { version = "0.0.63", path = "crates/brk_exit" }
brk_fetcher = { version = "0.0.61", path = "crates/brk_fetcher" } brk_fetcher = { version = "0.0.63", path = "crates/brk_fetcher" }
brk_indexer = { version = "0.0.61", path = "crates/brk_indexer" } brk_indexer = { version = "0.0.63", path = "crates/brk_indexer" }
brk_logger = { version = "0.0.61", path = "crates/brk_logger" } brk_logger = { version = "0.0.63", path = "crates/brk_logger" }
brk_parser = { version = "0.0.61", path = "crates/brk_parser" } brk_parser = { version = "0.0.63", path = "crates/brk_parser" }
brk_query = { version = "0.0.61", path = "crates/brk_query" } brk_query = { version = "0.0.63", path = "crates/brk_query" }
brk_server = { version = "0.0.61", path = "crates/brk_server" } brk_server = { version = "0.0.63", path = "crates/brk_server" }
brk_state = { version = "0.0.61", path = "crates/brk_state" } brk_state = { version = "0.0.63", path = "crates/brk_state" }
brk_store = { version = "0.0.61", path = "crates/brk_store" } brk_store = { version = "0.0.63", path = "crates/brk_store" }
brk_vec = { version = "0.0.61", path = "crates/brk_vec" } brk_vec = { version = "0.0.63", path = "crates/brk_vec" }
byteview = "=0.6.1" byteview = "=0.6.1"
clap = { version = "4.5.40", features = ["string"] } clap = { version = "4.5.40", features = ["string"] }
clap_derive = "4.5.40" clap_derive = "4.5.40"
+6 -4
View File
@@ -49,10 +49,12 @@ pub async fn bundle(websites_path: &Path, source_folder: &str, watch: bool) -> i
let mut contents = fs::read_to_string(&absolute_source_index_path).unwrap(); let mut contents = fs::read_to_string(&absolute_source_index_path).unwrap();
if let Ok(entry) = fs::read_to_string(absolute_dist_path_clone.join("scripts/entry.js")) { if let Ok(entry) = fs::read_to_string(absolute_dist_path_clone.join("scripts/entry.js")) {
let start = entry.find("main").unwrap(); if let Some(start) = entry.find("main") {
let end = entry.find(".js").unwrap(); if let Some(end) = entry.find(".js") {
let main_hashed = &entry[start..end]; let main_hashed = &entry[start..end];
contents = contents.replace("/scripts/main.js", &format!("/scripts/{main_hashed}.js")); contents = contents.replace("/scripts/main.js", &format!("/scripts/{main_hashed}.js"));
}
}
} }
let _ = fs::write(&absolute_dist_index_path, contents); let _ = fs::write(&absolute_dist_index_path, contents);
+6 -7
View File
@@ -61,9 +61,12 @@ export const VERSION = \"v{}\";
.join(" | ") .join(" | ")
); );
contents += "\n\nexport function createVecIdToIndexes() {\n"; contents += "\n\n/** @typedef {ReturnType<typeof createVecIdToIndexes>} VecIdToIndexes */";
contents += "\n/** @typedef {keyof VecIdToIndexes} VecId */\n";
contents += " return /** @type {const} */ ({\n"; contents += "\nexport function createVecIdToIndexes() {\n";
contents += " return {\n";
self.vec_trees self.vec_trees
.id_to_index_to_vec .id_to_index_to_vec
@@ -79,11 +82,7 @@ export const VERSION = \"v{}\";
contents += &format!(" \"{id}\": [{indexes}],\n"); contents += &format!(" \"{id}\": [{indexes}],\n");
}); });
contents += " });\n"; contents += " };\n}\n";
contents.push('}');
contents += "\n/** @typedef {ReturnType<typeof createVecIdToIndexes>} VecIdToIndexes */";
contents += "\n/** @typedef {keyof VecIdToIndexes} VecId */\n";
fs::write(path, contents) fs::write(path, contents)
} }
+12 -12
View File
@@ -94,19 +94,19 @@ fn path_to_response_(headers: &HeaderMap, path: &Path) -> color_eyre::Result<Res
let serialized_path = path.to_str().unwrap(); let serialized_path = path.to_str().unwrap();
if serialized_path.ends_with(".html") || serialized_path.ends_with("service-worker.js") { if path
headers.insert_cache_control_must_revalidate(); .extension()
} else if serialized_path.contains("fonts/") .is_some_and(|extension| extension == "html")
|| serialized_path.contains("assets/") || serialized_path.ends_with("service-worker.js")
|| serialized_path.contains("packages/")
|| path.extension().is_some_and(|extension| {
extension == "pdf"
|| extension == "jpg"
|| extension == "png"
|| extension == "woff2"
|| extension == "js"
})
{ {
headers.insert_cache_control_must_revalidate();
} else if path.extension().is_some_and(|extension| {
extension == "jpg"
|| extension == "png"
|| extension == "woff2"
|| extension == "js"
|| extension == "map"
}) {
headers.insert_cache_control_immutable(); headers.insert_cache_control_immutable();
} }
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

@@ -1,187 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<link
rel="icon"
type="image/png"
sizes="196x196"
href="/assets/pwa/2025-03-22_10-00-00/favicon-196.png"
/>
<link
rel="apple-touch-icon"
href="/assets/pwa/2025-03-22_10-00-00/apple-icon-180.png"
/>
<meta name="apple-mobile-web-app-capable" content="yes" />
<link
rel="apple-touch-startup-image"
href="/assets/pwa/2025-03-22_10-00-00/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/pwa/2025-03-22_10-00-00/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/pwa/2025-03-22_10-00-00/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/pwa/2025-03-22_10-00-00/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/pwa/2025-03-22_10-00-00/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/pwa/2025-03-22_10-00-00/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/pwa/2025-03-22_10-00-00/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/pwa/2025-03-22_10-00-00/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/pwa/2025-03-22_10-00-00/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/pwa/2025-03-22_10-00-00/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/pwa/2025-03-22_10-00-00/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/pwa/2025-03-22_10-00-00/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/pwa/2025-03-22_10-00-00/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/pwa/2025-03-22_10-00-00/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/pwa/2025-03-22_10-00-00/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/pwa/2025-03-22_10-00-00/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/pwa/2025-03-22_10-00-00/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/pwa/2025-03-22_10-00-00/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/pwa/2025-03-22_10-00-00/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/pwa/2025-03-22_10-00-00/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/pwa/2025-03-22_10-00-00/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/pwa/2025-03-22_10-00-00/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/pwa/2025-03-22_10-00-00/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/pwa/2025-03-22_10-00-00/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/pwa/2025-03-22_10-00-00/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/pwa/2025-03-22_10-00-00/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/pwa/2025-03-22_10-00-00/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/pwa/2025-03-22_10-00-00/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/pwa/2025-03-22_10-00-00/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/pwa/2025-03-22_10-00-00/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/pwa/2025-03-22_10-00-00/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/pwa/2025-03-22_10-00-00/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/pwa/2025-03-22_10-00-00/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/pwa/2025-03-22_10-00-00/apple-splash-1136-640.jpg"
media="(device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
/>
</head>
<body></body>
</html>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 511 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 594 B

+46 -3
View File
@@ -1,5 +1,48 @@
<!doctype html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head></head> <head>
<body></body> <link rel="icon" type="image/png" sizes="196x196" href="favicon-196.png">
<link rel="apple-touch-icon" href="apple-icon-180.png">
<meta name="apple-mobile-web-app-capable" content="yes">
<link rel="apple-touch-startup-image" href="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="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="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="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="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="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="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="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="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="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="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="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="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="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="apple-splash-1320-2868.jpg" media="(device-width: 440px) and (device-height: 956px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)">
<link rel="apple-touch-startup-image" href="apple-splash-2868-1320.jpg" media="(device-width: 440px) and (device-height: 956px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)">
<link rel="apple-touch-startup-image" href="apple-splash-1206-2622.jpg" media="(device-width: 402px) and (device-height: 874px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)">
<link rel="apple-touch-startup-image" href="apple-splash-2622-1206.jpg" media="(device-width: 402px) and (device-height: 874px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)">
<link rel="apple-touch-startup-image" href="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="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="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="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="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="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="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="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="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="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="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="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="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="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="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="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="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="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="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="apple-splash-1136-640.jpg" media="(device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)">
</head>
<body>
</body>
</html> </html>
Binary file not shown.

After

Width:  |  Height:  |  Size: 562 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

@@ -0,0 +1,43 @@
{
"name": "Bitcoin Research Kit",
"short_name": "₿RK",
"description": "A better, FOSS, Bitcoin-only, self-hostable Glassnode",
"categories": [
"bitcoin",
"on-chain",
"data"
],
"start_url": "/",
"scope": "/",
"display": "standalone",
"handle_links": "preferred",
"theme_color": "#f26610",
"background_color": "#f26610",
"lang": "en",
"icons": [
{
"src": "manifest-icon-192.maskable.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "any"
},
{
"src": "manifest-icon-192.maskable.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "maskable"
},
{
"src": "manifest-icon-512.maskable.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "any"
},
{
"src": "manifest-icon-512.maskable.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "maskable"
}
]
}
+65 -225
View File
@@ -1404,375 +1404,213 @@
if ("serviceWorker" in navigator) { if ("serviceWorker" in navigator) {
window.addEventListener("load", () => { window.addEventListener("load", () => {
navigator.serviceWorker.register("/service-worker.js"); navigator.serviceWorker.register("/service-worker.js", {
scope: "/",
});
}); });
} }
</script> </script>
<!-- --- --> <!-- --- -->
<!-- Icons --> <!-- PWA -->
<!-- --- --> <!-- --- -->
<link <link
rel="icon" rel="icon"
type="image/png" type="image/png"
sizes="196x196" sizes="196x196"
href="/assets/pwa/2025-03-22_10-00-00/favicon-196.png" href="/assets/pwa/favicon-196.png"
/>
<link
rel="apple-touch-icon"
href="/assets/pwa/2025-03-22_10-00-00/apple-icon-180.png"
/> />
<link rel="apple-touch-icon" href="/assets/pwa/apple-icon-180.png" />
<meta name="apple-mobile-web-app-capable" content="yes" /> <meta name="apple-mobile-web-app-capable" content="yes" />
<link <link
rel="apple-touch-startup-image" rel="apple-touch-startup-image"
href="/assets/pwa/2025-03-22_10-00-00/apple-splash-2048-2732.jpg" href="/assets/pwa/apple-splash-2048-2732.jpg"
media="(device-width: 1024px) and (device-height: 1366px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" media="(device-width: 1024px) and (device-height: 1366px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
/> />
<link <link
rel="apple-touch-startup-image" rel="apple-touch-startup-image"
href="/assets/pwa/2025-03-22_10-00-00/apple-splash-2732-2048.jpg" href="/assets/pwa/apple-splash-2732-2048.jpg"
media="(device-width: 1024px) and (device-height: 1366px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)" media="(device-width: 1024px) and (device-height: 1366px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
/> />
<link <link
rel="apple-touch-startup-image" rel="apple-touch-startup-image"
href="/assets/pwa/2025-03-22_10-00-00/apple-splash-1668-2388.jpg" href="/assets/pwa/apple-splash-1668-2388.jpg"
media="(device-width: 834px) and (device-height: 1194px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" media="(device-width: 834px) and (device-height: 1194px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
/> />
<link <link
rel="apple-touch-startup-image" rel="apple-touch-startup-image"
href="/assets/pwa/2025-03-22_10-00-00/apple-splash-2388-1668.jpg" href="/assets/pwa/apple-splash-2388-1668.jpg"
media="(device-width: 834px) and (device-height: 1194px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)" media="(device-width: 834px) and (device-height: 1194px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
/> />
<link <link
rel="apple-touch-startup-image" rel="apple-touch-startup-image"
href="/assets/pwa/2025-03-22_10-00-00/apple-splash-1536-2048.jpg" href="/assets/pwa/apple-splash-1536-2048.jpg"
media="(device-width: 768px) and (device-height: 1024px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" media="(device-width: 768px) and (device-height: 1024px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
/> />
<link <link
rel="apple-touch-startup-image" rel="apple-touch-startup-image"
href="/assets/pwa/2025-03-22_10-00-00/apple-splash-2048-1536.jpg" href="/assets/pwa/apple-splash-2048-1536.jpg"
media="(device-width: 768px) and (device-height: 1024px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)" media="(device-width: 768px) and (device-height: 1024px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
/> />
<link <link
rel="apple-touch-startup-image" rel="apple-touch-startup-image"
href="/assets/pwa/2025-03-22_10-00-00/apple-splash-1488-2266.jpg" href="/assets/pwa/apple-splash-1640-2360.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/pwa/2025-03-22_10-00-00/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/pwa/2025-03-22_10-00-00/apple-splash-1640-2360.jpg"
media="(device-width: 820px) and (device-height: 1180px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" media="(device-width: 820px) and (device-height: 1180px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
/> />
<link <link
rel="apple-touch-startup-image" rel="apple-touch-startup-image"
href="/assets/pwa/2025-03-22_10-00-00/apple-splash-2360-1640.jpg" href="/assets/pwa/apple-splash-2360-1640.jpg"
media="(device-width: 820px) and (device-height: 1180px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)" media="(device-width: 820px) and (device-height: 1180px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
/> />
<link <link
rel="apple-touch-startup-image" rel="apple-touch-startup-image"
href="/assets/pwa/2025-03-22_10-00-00/apple-splash-1668-2224.jpg" href="/assets/pwa/apple-splash-1668-2224.jpg"
media="(device-width: 834px) and (device-height: 1112px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" media="(device-width: 834px) and (device-height: 1112px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
/> />
<link <link
rel="apple-touch-startup-image" rel="apple-touch-startup-image"
href="/assets/pwa/2025-03-22_10-00-00/apple-splash-2224-1668.jpg" href="/assets/pwa/apple-splash-2224-1668.jpg"
media="(device-width: 834px) and (device-height: 1112px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)" media="(device-width: 834px) and (device-height: 1112px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
/> />
<link <link
rel="apple-touch-startup-image" rel="apple-touch-startup-image"
href="/assets/pwa/2025-03-22_10-00-00/apple-splash-1620-2160.jpg" href="/assets/pwa/apple-splash-1620-2160.jpg"
media="(device-width: 810px) and (device-height: 1080px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" media="(device-width: 810px) and (device-height: 1080px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
/> />
<link <link
rel="apple-touch-startup-image" rel="apple-touch-startup-image"
href="/assets/pwa/2025-03-22_10-00-00/apple-splash-2160-1620.jpg" href="/assets/pwa/apple-splash-2160-1620.jpg"
media="(device-width: 810px) and (device-height: 1080px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)" media="(device-width: 810px) and (device-height: 1080px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
/> />
<link <link
rel="apple-touch-startup-image" rel="apple-touch-startup-image"
href="/assets/pwa/2025-03-22_10-00-00/apple-splash-1290-2796.jpg" href="/assets/pwa/apple-splash-1488-2266.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/pwa/2025-03-22_10-00-00/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/pwa/2025-03-22_10-00-00/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/pwa/2025-03-22_10-00-00/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/pwa/2025-03-22_10-00-00/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/pwa/2025-03-22_10-00-00/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/pwa/2025-03-22_10-00-00/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/pwa/2025-03-22_10-00-00/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/pwa/2025-03-22_10-00-00/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/pwa/2025-03-22_10-00-00/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/pwa/2025-03-22_10-00-00/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/pwa/2025-03-22_10-00-00/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/pwa/2025-03-22_10-00-00/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/pwa/2025-03-22_10-00-00/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/pwa/2025-03-22_10-00-00/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/pwa/2025-03-22_10-00-00/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/pwa/2025-03-22_10-00-00/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/pwa/2025-03-22_10-00-00/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/pwa/2025-03-22_10-00-00/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/pwa/2025-03-22_10-00-00/apple-splash-1136-640.jpg"
media="(device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
/>
<link
rel="icon"
type="image/png"
sizes="196x196"
href="/assets/pwa/2025-03-22_10-00-00/favicon-196.png"
/>
<link
rel="apple-touch-icon"
href="/assets/pwa/2025-03-22_10-00-00/apple-icon-180.png"
/>
<meta name="apple-mobile-web-app-capable" content="yes" />
<link
rel="apple-touch-startup-image"
href="/assets/pwa/2025-03-22_10-00-00/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/pwa/2025-03-22_10-00-00/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/pwa/2025-03-22_10-00-00/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/pwa/2025-03-22_10-00-00/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/pwa/2025-03-22_10-00-00/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/pwa/2025-03-22_10-00-00/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/pwa/2025-03-22_10-00-00/apple-splash-1488-2266.jpg"
media="(device-width: 744px) and (device-height: 1133px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" media="(device-width: 744px) and (device-height: 1133px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
/> />
<link <link
rel="apple-touch-startup-image" rel="apple-touch-startup-image"
href="/assets/pwa/2025-03-22_10-00-00/apple-splash-2266-1488.jpg" href="/assets/pwa/apple-splash-2266-1488.jpg"
media="(device-width: 744px) and (device-height: 1133px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)" media="(device-width: 744px) and (device-height: 1133px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
/> />
<link <link
rel="apple-touch-startup-image" rel="apple-touch-startup-image"
href="/assets/pwa/2025-03-22_10-00-00/apple-splash-1640-2360.jpg" href="/assets/pwa/apple-splash-1320-2868.jpg"
media="(device-width: 820px) and (device-height: 1180px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" media="(device-width: 440px) and (device-height: 956px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"
/> />
<link <link
rel="apple-touch-startup-image" rel="apple-touch-startup-image"
href="/assets/pwa/2025-03-22_10-00-00/apple-splash-2360-1640.jpg" href="/assets/pwa/apple-splash-2868-1320.jpg"
media="(device-width: 820px) and (device-height: 1180px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)" media="(device-width: 440px) and (device-height: 956px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)"
/> />
<link <link
rel="apple-touch-startup-image" rel="apple-touch-startup-image"
href="/assets/pwa/2025-03-22_10-00-00/apple-splash-1668-2224.jpg" href="/assets/pwa/apple-splash-1206-2622.jpg"
media="(device-width: 834px) and (device-height: 1112px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" media="(device-width: 402px) and (device-height: 874px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"
/> />
<link <link
rel="apple-touch-startup-image" rel="apple-touch-startup-image"
href="/assets/pwa/2025-03-22_10-00-00/apple-splash-2224-1668.jpg" href="/assets/pwa/apple-splash-2622-1206.jpg"
media="(device-width: 834px) and (device-height: 1112px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)" media="(device-width: 402px) and (device-height: 874px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)"
/> />
<link <link
rel="apple-touch-startup-image" rel="apple-touch-startup-image"
href="/assets/pwa/2025-03-22_10-00-00/apple-splash-1620-2160.jpg" href="/assets/pwa/apple-splash-1290-2796.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/pwa/2025-03-22_10-00-00/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/pwa/2025-03-22_10-00-00/apple-splash-1290-2796.jpg"
media="(device-width: 430px) and (device-height: 932px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)" media="(device-width: 430px) and (device-height: 932px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"
/> />
<link <link
rel="apple-touch-startup-image" rel="apple-touch-startup-image"
href="/assets/pwa/2025-03-22_10-00-00/apple-splash-2796-1290.jpg" href="/assets/pwa/apple-splash-2796-1290.jpg"
media="(device-width: 430px) and (device-height: 932px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)" media="(device-width: 430px) and (device-height: 932px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)"
/> />
<link <link
rel="apple-touch-startup-image" rel="apple-touch-startup-image"
href="/assets/pwa/2025-03-22_10-00-00/apple-splash-1179-2556.jpg" href="/assets/pwa/apple-splash-1179-2556.jpg"
media="(device-width: 393px) and (device-height: 852px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)" media="(device-width: 393px) and (device-height: 852px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"
/> />
<link <link
rel="apple-touch-startup-image" rel="apple-touch-startup-image"
href="/assets/pwa/2025-03-22_10-00-00/apple-splash-2556-1179.jpg" href="/assets/pwa/apple-splash-2556-1179.jpg"
media="(device-width: 393px) and (device-height: 852px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)" media="(device-width: 393px) and (device-height: 852px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)"
/> />
<link <link
rel="apple-touch-startup-image" rel="apple-touch-startup-image"
href="/assets/pwa/2025-03-22_10-00-00/apple-splash-1284-2778.jpg" href="/assets/pwa/apple-splash-1170-2532.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/pwa/2025-03-22_10-00-00/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/pwa/2025-03-22_10-00-00/apple-splash-1170-2532.jpg"
media="(device-width: 390px) and (device-height: 844px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)" media="(device-width: 390px) and (device-height: 844px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"
/> />
<link <link
rel="apple-touch-startup-image" rel="apple-touch-startup-image"
href="/assets/pwa/2025-03-22_10-00-00/apple-splash-2532-1170.jpg" href="/assets/pwa/apple-splash-2532-1170.jpg"
media="(device-width: 390px) and (device-height: 844px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)" media="(device-width: 390px) and (device-height: 844px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)"
/> />
<link <link
rel="apple-touch-startup-image" rel="apple-touch-startup-image"
href="/assets/pwa/2025-03-22_10-00-00/apple-splash-1125-2436.jpg" href="/assets/pwa/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/pwa/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/pwa/apple-splash-1125-2436.jpg"
media="(device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)" media="(device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"
/> />
<link <link
rel="apple-touch-startup-image" rel="apple-touch-startup-image"
href="/assets/pwa/2025-03-22_10-00-00/apple-splash-2436-1125.jpg" href="/assets/pwa/apple-splash-2436-1125.jpg"
media="(device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)" media="(device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)"
/> />
<link <link
rel="apple-touch-startup-image" rel="apple-touch-startup-image"
href="/assets/pwa/2025-03-22_10-00-00/apple-splash-1242-2688.jpg" href="/assets/pwa/apple-splash-1242-2688.jpg"
media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)" media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"
/> />
<link <link
rel="apple-touch-startup-image" rel="apple-touch-startup-image"
href="/assets/pwa/2025-03-22_10-00-00/apple-splash-2688-1242.jpg" href="/assets/pwa/apple-splash-2688-1242.jpg"
media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)" media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)"
/> />
<link <link
rel="apple-touch-startup-image" rel="apple-touch-startup-image"
href="/assets/pwa/2025-03-22_10-00-00/apple-splash-828-1792.jpg" href="/assets/pwa/apple-splash-828-1792.jpg"
media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
/> />
<link <link
rel="apple-touch-startup-image" rel="apple-touch-startup-image"
href="/assets/pwa/2025-03-22_10-00-00/apple-splash-1792-828.jpg" href="/assets/pwa/apple-splash-1792-828.jpg"
media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)" media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
/> />
<link <link
rel="apple-touch-startup-image" rel="apple-touch-startup-image"
href="/assets/pwa/2025-03-22_10-00-00/apple-splash-1242-2208.jpg" href="/assets/pwa/apple-splash-1242-2208.jpg"
media="(device-width: 414px) and (device-height: 736px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)" media="(device-width: 414px) and (device-height: 736px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"
/> />
<link <link
rel="apple-touch-startup-image" rel="apple-touch-startup-image"
href="/assets/pwa/2025-03-22_10-00-00/apple-splash-2208-1242.jpg" href="/assets/pwa/apple-splash-2208-1242.jpg"
media="(device-width: 414px) and (device-height: 736px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)" media="(device-width: 414px) and (device-height: 736px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)"
/> />
<link <link
rel="apple-touch-startup-image" rel="apple-touch-startup-image"
href="/assets/pwa/2025-03-22_10-00-00/apple-splash-750-1334.jpg" href="/assets/pwa/apple-splash-750-1334.jpg"
media="(device-width: 375px) and (device-height: 667px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" media="(device-width: 375px) and (device-height: 667px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
/> />
<link <link
rel="apple-touch-startup-image" rel="apple-touch-startup-image"
href="/assets/pwa/2025-03-22_10-00-00/apple-splash-1334-750.jpg" href="/assets/pwa/apple-splash-1334-750.jpg"
media="(device-width: 375px) and (device-height: 667px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)" media="(device-width: 375px) and (device-height: 667px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
/> />
<link <link
rel="apple-touch-startup-image" rel="apple-touch-startup-image"
href="/assets/pwa/2025-03-22_10-00-00/apple-splash-640-1136.jpg" href="/assets/pwa/apple-splash-640-1136.jpg"
media="(device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" media="(device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
/> />
<link <link
rel="apple-touch-startup-image" rel="apple-touch-startup-image"
href="/assets/pwa/2025-03-22_10-00-00/apple-splash-1136-640.jpg" href="/assets/pwa/apple-splash-1136-640.jpg"
media="(device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)" media="(device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
/> />
</head> </head>
@@ -1852,13 +1690,15 @@
</div> </div>
<script> <script>
// Prevent width jumping try {
const savedWidth = localStorage.getItem("bar-width"); // Prevent width jumping
if (savedWidth) { const savedWidth = localStorage.getItem("bar-width");
const main = window.document.getElementById("main"); if (savedWidth) {
if (!main) throw "Should exist"; const main = window.document.getElementById("main");
main.style.width = `${savedWidth}px`; if (!main) throw "Should exist";
} main.style.width = `${savedWidth}px`;
}
} catch (_) {}
</script> </script>
</body> </body>
</html> </html>
+6 -6
View File
@@ -1,6 +1,6 @@
{ {
"name": "brk", "name": "Bitcoin Research Kit",
"short_name": "brk", "short_name": "₿RK",
"description": "A better, FOSS, Bitcoin-only, self-hostable Glassnode", "description": "A better, FOSS, Bitcoin-only, self-hostable Glassnode",
"categories": [ "categories": [
"bitcoin", "bitcoin",
@@ -16,25 +16,25 @@
"lang": "en", "lang": "en",
"icons": [ "icons": [
{ {
"src": "/assets/pwa/2025-03-22_10-00-00/manifest-icon-192.maskable.png", "src": "/assets/pwa/manifest-icon-192.maskable.png",
"sizes": "192x192", "sizes": "192x192",
"type": "image/png", "type": "image/png",
"purpose": "any" "purpose": "any"
}, },
{ {
"src": "/assets/pwa/2025-03-22_10-00-00/manifest-icon-192.maskable.png", "src": "/assets/pwa/manifest-icon-192.maskable.png",
"sizes": "192x192", "sizes": "192x192",
"type": "image/png", "type": "image/png",
"purpose": "maskable" "purpose": "maskable"
}, },
{ {
"src": "/assets/pwa/2025-03-22_10-00-00/manifest-icon-512.maskable.png", "src": "/assets/pwa/manifest-icon-512.maskable.png",
"sizes": "512x512", "sizes": "512x512",
"type": "image/png", "type": "image/png",
"purpose": "any" "purpose": "any"
}, },
{ {
"src": "/assets/pwa/2025-03-22_10-00-00/manifest-icon-512.maskable.png", "src": "/assets/pwa/manifest-icon-512.maskable.png",
"sizes": "512x512", "sizes": "512x512",
"type": "image/png", "type": "image/png",
"purpose": "maskable" "purpose": "maskable"
@@ -24,10 +24,10 @@
* @property {Signal<string | null>} url * @property {Signal<string | null>} url
* @property {VoidFunction} remove * @property {VoidFunction} remove
* *
* @typedef {ChartData<_SingleValueData<number>>} SingleValueData * @typedef {_SingleValueData<number>} SingleValueData
* @typedef {ChartData<_CandlestickData<number>>} CandlestickData * @typedef {_CandlestickData<number>} CandlestickData
* @typedef {ChartData<_LineData<number>>} LineData * @typedef {_LineData<number>} LineData
* @typedef {ChartData<_BaselineData<number>>} BaselineData * @typedef {_BaselineData<number>} BaselineData
* *
* @typedef {function({ iseries: ISeries; unit: Unit; index: Index }): void} SetDataCallback * @typedef {function({ iseries: ISeries; unit: Unit; index: Index }): void} SetDataCallback
* *
@@ -44,11 +44,6 @@
* @typedef {BaselineSeriesPartialOptions & PartialCreatePriceLineOptions} PartialBaselineStyleOptions * @typedef {BaselineSeriesPartialOptions & PartialCreatePriceLineOptions} PartialBaselineStyleOptions
*/ */
/**
* @template T
* @typedef {T & Valued} ChartData<T>
*/
import { import {
createChart, createChart,
CandlestickSeries, CandlestickSeries,
@@ -146,7 +141,7 @@ function createChartElement({
} }
: {}), : {}),
// ..._options, // ..._options,
}), })
); );
ichart.priceScale("right").applyOptions({ ichart.priceScale("right").applyOptions({
@@ -178,24 +173,20 @@ function createChartElement({
}, },
}, },
}); });
}, }
); );
let timeScaleSet = false;
signals.createEffect(index, (index) => { signals.createEffect(index, (index) => {
timeScaleSet = false;
const minBarSpacing = const minBarSpacing =
index === /** @satisfies {MonthIndex} */ (7) index === /** @satisfies {MonthIndex} */ (7)
? 1 ? 1
: index === /** @satisfies {QuarterIndex} */ (19) : index === /** @satisfies {QuarterIndex} */ (19)
? 3 ? 2
: index === /** @satisfies {YearIndex} */ (23) : index === /** @satisfies {YearIndex} */ (23)
? 12 ? 6
: index === /** @satisfies {DecadeIndex} */ (1) : index === /** @satisfies {DecadeIndex} */ (1)
? 120 ? 60
: 0.5; : 0.5;
ichart.applyOptions({ ichart.applyOptions({
timeScale: { timeScale: {
@@ -218,7 +209,7 @@ function createChartElement({
activeResources.forEach((v) => { activeResources.forEach((v) => {
v.fetch(); v.fetch();
}); });
}), })
); );
if (fitContent) { if (fitContent) {
@@ -249,8 +240,7 @@ function createChartElement({
const children = Array.from(parent.childNodes).filter( const children = Array.from(parent.childNodes).filter(
(element) => (element) =>
/** @type {HTMLElement} */ (element).dataset.position === /** @type {HTMLElement} */ (element).dataset.position === position
position,
); );
if (children.length === 1) { if (children.length === 1) {
@@ -272,7 +262,7 @@ function createChartElement({
fieldset.append(createChild(pane)); fieldset.append(createChild(pane));
}), }),
paneIndex ? 50 : 0, paneIndex ? 50 : 0
); );
} }
@@ -356,7 +346,7 @@ function createChartElement({
// Or remove ? // Or remove ?
iseries.applyOptions({ iseries.applyOptions({
visible: active, visible: active,
}), })
); );
iseries.setSeriesOrder(order); iseries.setSeriesOrder(order);
@@ -387,7 +377,7 @@ function createChartElement({
index, index,
index === /** @satisfies {Height} */ (5) index === /** @satisfies {Height} */ (5)
? "timestamp-fixed" ? "timestamp-fixed"
: "timestamp", : "timestamp"
); );
timeResource.fetch(); timeResource.fetch();
@@ -403,19 +393,21 @@ function createChartElement({
const fetchedKey = vecsResources.defaultFetchedKey; const fetchedKey = vecsResources.defaultFetchedKey;
signals.createEffect( signals.createEffect(
() => [ () => ({
timeResource.fetched().get(fetchedKey)?.vec(), _indexes: timeResource.fetched().get(fetchedKey)?.vec(),
valuesResource.fetched().get(fetchedKey)?.vec(), values: valuesResource.fetched().get(fetchedKey)?.vec(),
], }),
([indexes, _ohlcs]) => { ({ _indexes, values }) => {
if (!indexes?.length || !_ohlcs?.length) return; if (!_indexes?.length || !values?.length) return;
// const seriesData = series.inner.data(); const indexes = /** @type {number[]} */ (_indexes);
// const set = seriesData.length === 0;
const ohlcs = /** @type {OHLCTuple[]} */ (_ohlcs); let length = Math.min(indexes.length, values.length);
let length = Math.min(indexes.length, ohlcs.length);
// TODO: Don't create new Array if data already present, update instead
/** @type {LineData[] | CandlestickData[]} */
const data = new Array(length); const data = new Array(length);
let prevTime = null; let prevTime = null;
let timeOffset = 0; let timeOffset = 0;
@@ -425,7 +417,7 @@ function createChartElement({
if (sameTime) { if (sameTime) {
timeOffset += 1; timeOffset += 1;
} }
const v = ohlcs[i]; const v = values[i];
const offsetedI = i - timeOffset; const offsetedI = i - timeOffset;
if (v === null) { if (v === null) {
data[offsetedI] = { data[offsetedI] = {
@@ -441,16 +433,16 @@ function createChartElement({
if (sameTime) { if (sameTime) {
console.log(data[offsetedI]); console.log(data[offsetedI]);
} }
// const prev = sameTime ? data[offsetedI] : undefined; const candles = /** @type {CandlestickData[]} */ (data);
let [open, high, low, close] = v; let [open, high, low, close] = v;
data[offsetedI] = { candles[offsetedI] = {
time, time,
open: sameTime ? data[offsetedI].open : open, open: sameTime ? candles[offsetedI].open : open,
high: sameTime high: sameTime
? Math.max(data[offsetedI].high, high) ? Math.max(candles[offsetedI].high, high)
: high, : high,
low: sameTime low: sameTime
? Math.min(data[offsetedI].low, low) ? Math.min(candles[offsetedI].low, low)
: low, : low,
close, close,
}; };
@@ -460,41 +452,101 @@ function createChartElement({
data.length -= timeOffset; data.length -= timeOffset;
// if (set) {
iseries.setData(data);
if (fitContent) {
ichart.timeScale().fitContent();
}
// } else {
// let seriesDataOffset = 0;
// while seriesData
// data.forEach((bar) => {
// iseries.update(bar, true);
// });
// }
hasData.set(true); hasData.set(true);
const seriesData = series.inner.data();
if (!seriesData.length) {
iseries.setData(data);
if (fitContent) {
ichart.timeScale().fitContent();
}
timeScaleSetCallback?.(() => {
if (
index === /** @satisfies {QuarterIndex} */ (19) ||
index === /** @satisfies {YearIndex} */ (23) ||
index === /** @satisfies {DecadeIndex} */ (1)
) {
ichart.timeScale().setVisibleLogicalRange({
from: -1,
to: data.length,
});
}
});
} else if (data.length) {
let i = 0;
// console.log(seriesData);
const first = seriesData[0];
const last = seriesData.at(-1);
if (!last) throw Error("Unreachable");
while (data[i].time < first.time) {
iseries.update(data[i], true);
i++;
}
// console.log(i);
let j = 0;
while (i < data.length) {
const dataI = data[i];
const iTime = dataI.time;
const seriesDataJ = /** @type {typeof dataI} */ (
seriesData[j]
);
const jTime = seriesDataJ.time;
if (iTime === jTime) {
const historicalUpdate = iTime < last.time;
if ("value" in dataI) {
if (
// @ts-ignore
dataI.value !== seriesDataJ.value &&
// @ts-ignore
(!isNaN(dataI.value) || !isNaN(seriesDataJ.value))
) {
// console.log(vecId);
iseries.update(dataI, historicalUpdate);
}
} else if (
// @ts-ignore
dataI.open !== seriesDataJ.open ||
// @ts-ignore
dataI.high !== seriesDataJ.high ||
// @ts-ignore
dataI.low !== seriesDataJ.low ||
// @ts-ignore
dataI.close !== seriesDataJ.close
) {
// console.log({
// vecId,
// dataI,
// i,
// data,
// j,
// seriesDataJ,
// seriesData,
// });
iseries.update(dataI, historicalUpdate);
}
i++;
j++;
} else if (iTime < jTime) {
iseries.update(dataI, true);
i++;
} else if (iTime > last.time) {
iseries.update(dataI);
i++;
} else if (iTime > jTime) {
j++;
}
}
}
setDataCallback?.({ setDataCallback?.({
iseries, iseries,
index, index,
unit, unit,
}); });
}
timeScaleSetCallback?.(() => {
if (
!timeScaleSet &&
(index === /** @satisfies {QuarterIndex} */ (19) ||
index === /** @satisfies {YearIndex} */ (23) ||
index === /** @satisfies {DecadeIndex} */ (1))
) {
ichart.timeScale().setVisibleLogicalRange({
from: -1,
to: data.length,
});
}
});
timeScaleSet = true;
},
); );
} else { } else {
activeResources.delete(valuesResource); activeResources.delete(valuesResource);
@@ -587,7 +639,7 @@ function createChartElement({
borderVisible: false, borderVisible: false,
visible: defaultActive !== false, visible: defaultActive !== false,
}, },
paneIndex, paneIndex
) )
); );
@@ -643,7 +695,7 @@ function createChartElement({
color: color(), color: color(),
...options, ...options,
}, },
paneIndex, paneIndex
) )
); );
@@ -711,7 +763,7 @@ function createChartElement({
topFillColor2: "transparent", topFillColor2: "transparent",
lineVisible: true, lineVisible: true,
}, },
paneIndex, paneIndex
) )
); );
@@ -874,7 +926,7 @@ function createLegend({ signals, utils }) {
} else { } else {
spanColor.style.backgroundColor = tameColor(color); spanColor.style.backgroundColor = tameColor(color);
} }
}, }
); );
}); });
@@ -1034,17 +1086,17 @@ function numberToShortUSFormat(value, digits) {
if (modulused === 0) { if (modulused === 0) {
return `${numberToUSFormat( return `${numberToUSFormat(
value / (1_000_000 * 1_000 ** letterIndex), value / (1_000_000 * 1_000 ** letterIndex),
3, 3
)}${letter}`; )}${letter}`;
} else if (modulused === 1) { } else if (modulused === 1) {
return `${numberToUSFormat( return `${numberToUSFormat(
value / (1_000_000 * 1_000 ** letterIndex), value / (1_000_000 * 1_000 ** letterIndex),
2, 2
)}${letter}`; )}${letter}`;
} else { } else {
return `${numberToUSFormat( return `${numberToUSFormat(
value / (1_000_000 * 1_000 ** letterIndex), value / (1_000_000 * 1_000 ** letterIndex),
1, 1
)}${letter}`; )}${letter}`;
} }
} }
@@ -1094,7 +1146,7 @@ function createOklchToRGBA() {
return rgb.map((c) => return rgb.map((c) =>
Math.abs(c) > 0.0031308 Math.abs(c) > 0.0031308
? (c < 0 ? -1 : 1) * (1.055 * Math.abs(c) ** (1 / 2.4) - 0.055) ? (c < 0 ? -1 : 1) * (1.055 * Math.abs(c) ** (1 / 2.4) - 0.055)
: 12.92 * c, : 12.92 * c
); );
} }
/** /**
@@ -1106,7 +1158,7 @@ function createOklchToRGBA() {
1, 0.3963377773761749, 0.2158037573099136, 1, -0.1055613458156586, 1, 0.3963377773761749, 0.2158037573099136, 1, -0.1055613458156586,
-0.0638541728258133, 1, -0.0894841775298119, -1.2914855480194092, -0.0638541728258133, 1, -0.0894841775298119, -1.2914855480194092,
]), ]),
lab, lab
); );
const LMS = /** @type {[number, number, number]} */ ( const LMS = /** @type {[number, number, number]} */ (
LMSg.map((val) => val ** 3) LMSg.map((val) => val ** 3)
@@ -1117,7 +1169,7 @@ function createOklchToRGBA() {
-0.0405757452148008, 1.112286803280317, -0.0717110580655164, -0.0405757452148008, 1.112286803280317, -0.0717110580655164,
-0.0763729366746601, -0.4214933324022432, 1.5869240198367816, -0.0763729366746601, -0.4214933324022432, 1.5869240198367816,
]), ]),
LMS, LMS
); );
} }
/** /**
@@ -1130,7 +1182,7 @@ function createOklchToRGBA() {
-0.9692436362808796, 1.8759675015077202, 0.04155505740717559, -0.9692436362808796, 1.8759675015077202, 0.04155505740717559,
0.05563007969699366, -0.20397695888897652, 1.0569715142428786, 0.05563007969699366, -0.20397695888897652, 1.0569715142428786,
], ],
xyz, xyz
); );
} }
@@ -1153,8 +1205,8 @@ function createOklchToRGBA() {
}); });
const rgb = srgbLinear2rgb( const rgb = srgbLinear2rgb(
xyz2rgbLinear( xyz2rgbLinear(
oklab2xyz(oklch2oklab(/** @type {[number, number, number]} */ (lch))), oklab2xyz(oklch2oklab(/** @type {[number, number, number]} */ (lch)))
), )
).map((v) => { ).map((v) => {
return Math.max(Math.min(Math.round(v * 255), 255), 0); return Math.max(Math.min(Math.round(v * 255), 255), 0);
}); });
@@ -69,13 +69,13 @@ const signals = {
/** /**
* @template T * @template T
* @param {T} initialValue * @param {T} initialValue
* @param {SignalOptions<T> & {save?: {keyPrefix: string | Accessor<string>; key: string; serialize: (v: T) => string; deserialize: (v: string) => T; serializeParam?: boolean}}} [options] * @param {SignalOptions<T> & {save?: {keyPrefix: string | Accessor<string>; key: string; serialize: (v: T) => string; deserialize: (v: string) => T; serializeParam?: boolean; saveDefaultValue?: boolean}}} [options]
* @returns {Signal<T>} * @returns {Signal<T>}
*/ */
createSignal(initialValue, options) { createSignal(initialValue, options) {
const [get, set] = this.createSolidSignal( const [get, set] = this.createSolidSignal(
/** @type {any} */ (initialValue), /** @type {any} */ (initialValue),
options, options
); );
// @ts-ignore // @ts-ignore
@@ -94,7 +94,7 @@ const signals = {
typeof save.keyPrefix === "string" typeof save.keyPrefix === "string"
? save.keyPrefix ? save.keyPrefix
: save.keyPrefix() : save.keyPrefix()
}-${paramKey}`, }-${paramKey}`
); );
let serialized = /** @type {string | null} */ (null); let serialized = /** @type {string | null} */ (null);
@@ -102,7 +102,9 @@ const signals = {
serialized = new URLSearchParams(window.location.search).get(paramKey); serialized = new URLSearchParams(window.location.search).get(paramKey);
} }
if (serialized === null) { if (serialized === null) {
serialized = localStorage.getItem(storageKey()); try {
serialized = localStorage.getItem(storageKey());
} catch (_) {}
} }
if (serialized) { if (serialized) {
set(() => (serialized ? save.deserialize(serialized) : initialValue)); set(() => (serialized ? save.deserialize(serialized) : initialValue));
@@ -111,8 +113,12 @@ const signals = {
let firstRun1 = true; let firstRun1 = true;
this.createEffect(storageKey, (storageKey) => { this.createEffect(storageKey, (storageKey) => {
if (!firstRun1) { if (!firstRun1) {
serialized = localStorage.getItem(storageKey); try {
set(() => (serialized ? save.deserialize(serialized) : initialValue)); serialized = localStorage.getItem(storageKey);
set(() =>
serialized ? save.deserialize(serialized) : initialValue
);
} catch (_) {}
} }
firstRun1 = false; firstRun1 = false;
}); });
@@ -122,17 +128,20 @@ const signals = {
if (!save) return; if (!save) return;
if (!firstRun2) { if (!firstRun2) {
if ( try {
value !== undefined && if (
value !== null && value !== undefined &&
(initialValue === undefined || value !== null &&
initialValue === null || (initialValue === undefined ||
save.serialize(value) !== save.serialize(initialValue)) initialValue === null ||
) { save.saveDefaultValue ||
localStorage.setItem(storageKey(), save.serialize(value)); save.serialize(value) !== save.serialize(initialValue))
} else { ) {
localStorage.removeItem(storageKey()); localStorage.setItem(storageKey(), save.serialize(value));
} } else {
localStorage.removeItem(storageKey());
}
} catch (_) {}
} }
if ( if (
@@ -140,6 +149,7 @@ const signals = {
value !== null && value !== null &&
(initialValue === undefined || (initialValue === undefined ||
initialValue === null || initialValue === null ||
save.saveDefaultValue ||
save.serialize(value) !== save.serialize(initialValue)) save.serialize(value) !== save.serialize(initialValue))
) { ) {
writeParam(paramKey, save.serialize(value)); writeParam(paramKey, save.serialize(value));
@@ -174,7 +184,7 @@ function writeParam(key, value) {
window.history.replaceState( window.history.replaceState(
null, null,
"", "",
`${window.location.pathname}?${urlParams.toString()}`, `${window.location.pathname}?${urlParams.toString()}`
); );
} catch (_) {} } catch (_) {}
} }
+1 -2
View File
@@ -171,7 +171,6 @@ export function init({
latest.high = Math.floor(ONE_BTC_IN_SATS / latest.high); latest.high = Math.floor(ONE_BTC_IN_SATS / latest.high);
latest.low = Math.floor(ONE_BTC_IN_SATS / latest.low); latest.low = Math.floor(ONE_BTC_IN_SATS / latest.low);
latest.close = Math.floor(ONE_BTC_IN_SATS / latest.close); latest.close = Math.floor(ONE_BTC_IN_SATS / latest.close);
latest.value = Math.floor(ONE_BTC_IN_SATS / latest.value);
} }
const last_ = iseries.data().at(-1); const last_ = iseries.data().at(-1);
@@ -182,7 +181,7 @@ export function init({
last.close = latest.close; last.close = latest.close;
} }
if ("value" in last) { if ("value" in last) {
last.value = latest.value; last.value = latest.close;
} }
const date = new Date(latest.time * 1000); const date = new Date(latest.time * 1000);
+71 -62
View File
@@ -1,8 +1,8 @@
// @ts-check // @ts-check
/** /**
* @import { Option, PartialChartOption, ChartOption, AnyPartialOption, ProcessedOptionAddons, OptionsTree, SimulationOption, AnySeriesBlueprint, ChartableIndex, SeriesType } from "./options" * @import { Option, PartialChartOption, ChartOption, AnyPartialOption, ProcessedOptionAddons, OptionsTree, SimulationOption, AnySeriesBlueprint, SeriesType } from "./options"
* @import { Valued, SingleValueData, CandlestickData, ChartData, OHLCTuple, Series, ISeries, LineData, BaselineData, PartialLineStyleOptions, PartialBaselineStyleOptions, PartialCandlestickStyleOptions } from "../packages/lightweight-charts/wrapper" * @import { Valued, SingleValueData, CandlestickData, OHLCTuple, Series, ISeries, LineData, BaselineData, PartialLineStyleOptions, PartialBaselineStyleOptions, PartialCandlestickStyleOptions } from "../packages/lightweight-charts/wrapper"
* @import * as _ from "../packages/ufuzzy/v1.0.18/types" * @import * as _ from "../packages/ufuzzy/v1.0.18/types"
* @import { Signal, Signals, Accessor } from "../packages/solid-signals/wrapper"; * @import { Signal, Signals, Accessor } from "../packages/solid-signals/wrapper";
* @import { DateIndex, DecadeIndex, DifficultyEpoch, Index, HalvingEpoch, Height, MonthIndex, P2PK33Index, P2PK65Index, P2PKHIndex, P2SHIndex, P2MSIndex, P2AIndex, P2TRIndex, P2WPKHIndex, P2WSHIndex, TxIndex, InputIndex, OutputIndex, VecId, WeekIndex, YearIndex, VecIdToIndexes, QuarterIndex, EmptyOutputIndex, OpReturnIndex, UnknownOutputIndex } from "./vecid-to-indexes" * @import { DateIndex, DecadeIndex, DifficultyEpoch, Index, HalvingEpoch, Height, MonthIndex, P2PK33Index, P2PK65Index, P2PKHIndex, P2SHIndex, P2MSIndex, P2AIndex, P2TRIndex, P2WPKHIndex, P2WSHIndex, TxIndex, InputIndex, OutputIndex, VecId, WeekIndex, YearIndex, VecIdToIndexes, QuarterIndex, EmptyOutputIndex, OpReturnIndex, UnknownOutputIndex } from "./vecid-to-indexes"
@@ -63,14 +63,14 @@ function initPackages() {
const imports = { const imports = {
async signals() { async signals() {
return import("../packages/solid-signals/wrapper.js").then( return import("../packages/solid-signals/wrapper.js").then(
(d) => d.default, (d) => d.default
); );
}, },
async lightweightCharts() { async lightweightCharts() {
return window.document.fonts.ready.then(() => return window.document.fonts.ready.then(() =>
import("../packages/lightweight-charts/wrapper.js").then( import("../packages/lightweight-charts/wrapper.js").then(
(d) => d.default, (d) => d.default
), )
); );
}, },
async leanQr() { async leanQr() {
@@ -78,7 +78,7 @@ function initPackages() {
}, },
async ufuzzy() { async ufuzzy() {
return import("../packages/ufuzzy/v1.0.18/script.js").then( return import("../packages/ufuzzy/v1.0.18/script.js").then(
({ default: d }) => d, ({ default: d }) => d
); );
}, },
}; };
@@ -388,6 +388,7 @@ function createUtils() {
...serde.string, ...serde.string,
keyPrefix: keyPrefix ?? "", keyPrefix: keyPrefix ?? "",
key, key,
saveDefaultValue: true,
}, },
}); });
@@ -585,7 +586,7 @@ function createUtils() {
window.history.pushState( window.history.pushState(
null, null,
"", "",
`${pathname}?${urlParams.toString()}`, `${pathname}?${urlParams.toString()}`
); );
} catch (_) {} } catch (_) {}
}, },
@@ -602,7 +603,7 @@ function createUtils() {
window.history.replaceState( window.history.replaceState(
null, null,
"", "",
`${pathname}?${urlParams.toString()}`, `${pathname}?${urlParams.toString()}`
); );
} catch (_) {} } catch (_) {}
}, },
@@ -988,16 +989,22 @@ function createUtils() {
* @param {string} key * @param {string} key
*/ */
read(key) { read(key) {
return localStorage.getItem(key); try {
return localStorage.getItem(key);
} catch (_) {
return null;
}
}, },
/** /**
* @param {string} key * @param {string} key
* @param {string | boolean | null | undefined} value * @param {string | boolean | null | undefined} value
*/ */
write(key, value) { write(key, value) {
value !== undefined && value !== null try {
? localStorage.setItem(key, String(value)) value !== undefined && value !== null
: localStorage.removeItem(key); ? localStorage.setItem(key, String(value))
: localStorage.removeItem(key);
} catch (_) {}
}, },
/** /**
* @param {string} key * @param {string} key
@@ -1157,7 +1164,7 @@ function createUtils() {
}, },
chartableIndex: { chartableIndex: {
/** /**
* @param {Index} v * @param {number} v
*/ */
serialize(v) { serialize(v) {
switch (v) { switch (v) {
@@ -1185,7 +1192,7 @@ function createUtils() {
}, },
/** /**
* @param {string} v * @param {string} v
* @returns {ChartableIndex} * @returns {Index}
*/ */
deserialize(v) { deserialize(v) {
switch (v) { switch (v) {
@@ -1204,7 +1211,7 @@ function createUtils() {
case "decade": case "decade":
return /** @satisfies {DecadeIndex} */ (1); return /** @satisfies {DecadeIndex} */ (1);
default: default:
throw Error("Unsupported"); throw Error("todo");
} }
}, },
}, },
@@ -1235,8 +1242,8 @@ function createUtils() {
today.getUTCDate(), today.getUTCDate(),
0, 0,
0, 0,
0, 0
), )
); );
}, },
/** /**
@@ -1329,7 +1336,7 @@ function createUtils() {
*/ */
function getNumberOfDaysBetweenTwoDates(oldest, youngest) { function getNumberOfDaysBetweenTwoDates(oldest, youngest) {
return Math.round( return Math.round(
Math.abs((youngest.getTime() - oldest.getTime()) / date.ONE_DAY_IN_MS), Math.abs((youngest.getTime() - oldest.getTime()) / date.ONE_DAY_IN_MS)
); );
} }
@@ -1547,7 +1554,7 @@ function createVecsResources(signals, utils) {
const fetchedRecord = signals.createSignal( const fetchedRecord = signals.createSignal(
/** @type {Map<string, {loading: boolean, at: Date | null, vec: Signal<T[] | null>}>} */ ( /** @type {Map<string, {loading: boolean, at: Date | null, vec: Signal<T[] | null>}>} */ (
new Map() new Map()
), )
); );
return { return {
@@ -1595,7 +1602,7 @@ function createVecsResources(signals, utils) {
index, index,
id, id,
from, from,
to, to
) )
); );
fetched.at = new Date(); fetched.at = new Date();
@@ -1856,7 +1863,7 @@ function initWebSockets(signals, utils) {
window.document.addEventListener( window.document.addEventListener(
"visibilitychange", "visibilitychange",
reinitWebSocketIfDocumentNotHidden, reinitWebSocketIfDocumentNotHidden
); );
window.document.addEventListener("online", reinitWebSocket); window.document.addEventListener("online", reinitWebSocket);
@@ -1865,7 +1872,7 @@ function initWebSockets(signals, utils) {
ws?.close(); ws?.close();
window.document.removeEventListener( window.document.removeEventListener(
"visibilitychange", "visibilitychange",
reinitWebSocketIfDocumentNotHidden, reinitWebSocketIfDocumentNotHidden
); );
window.document.removeEventListener("online", reinitWebSocket); window.document.removeEventListener("online", reinitWebSocket);
live.set(false); live.set(false);
@@ -1891,7 +1898,7 @@ function initWebSockets(signals, utils) {
symbol: ["BTC/USD"], symbol: ["BTC/USD"],
interval: 1440, interval: 1440,
}, },
}), })
); );
}); });
@@ -1910,7 +1917,6 @@ function initWebSockets(signals, utils) {
high: Number(high), high: Number(high),
low: Number(low), low: Number(low),
close: Number(close), close: Number(close),
value: Number(close),
}; };
candle && callback({ ...candle }); candle && callback({ ...candle });
@@ -1921,7 +1927,7 @@ function initWebSockets(signals, utils) {
/** @type {ReturnType<typeof createWebsocket<CandlestickData>>} */ /** @type {ReturnType<typeof createWebsocket<CandlestickData>>} */
const kraken1dCandle = createWebsocket((callback) => const kraken1dCandle = createWebsocket((callback) =>
krakenCandleWebSocketCreator(callback), krakenCandleWebSocketCreator(callback)
); );
kraken1dCandle.open(); kraken1dCandle.open();
@@ -1980,7 +1986,7 @@ function main() {
} }
const frame = window.document.getElementById( const frame = window.document.getElementById(
/** @type {string} */ (input.value), /** @type {string} */ (input.value)
); );
if (!frame) { if (!frame) {
@@ -2078,23 +2084,23 @@ function main() {
function initDark() { function initDark() {
const preferredColorSchemeMatchMedia = window.matchMedia( const preferredColorSchemeMatchMedia = window.matchMedia(
"(prefers-color-scheme: dark)", "(prefers-color-scheme: dark)"
); );
const dark = signals.createSignal( const dark = signals.createSignal(
preferredColorSchemeMatchMedia.matches, preferredColorSchemeMatchMedia.matches
); );
preferredColorSchemeMatchMedia.addEventListener( preferredColorSchemeMatchMedia.addEventListener(
"change", "change",
({ matches }) => { ({ matches }) => {
dark.set(matches); dark.set(matches);
}, }
); );
return dark; return dark;
} }
const dark = initDark(); const dark = initDark();
const qrcode = signals.createSignal( const qrcode = signals.createSignal(
/** @type {string | null} */ (null), /** @type {string | null} */ (null)
); );
function createLastHeightResource() { function createLastHeightResource() {
@@ -2105,7 +2111,7 @@ function main() {
lastHeight.set(h); lastHeight.set(h);
}, },
/** @satisfies {Height} */ (5), /** @satisfies {Height} */ (5),
"height", "height"
); );
} }
fetchLastHeight(); fetchLastHeight();
@@ -2149,10 +2155,10 @@ function main() {
const owner = signals.getOwner(); const owner = signals.getOwner();
const chartOption = signals.createSignal( const chartOption = signals.createSignal(
/** @type {ChartOption | null} */ (null), /** @type {ChartOption | null} */ (null)
); );
const simOption = signals.createSignal( const simOption = signals.createSignal(
/** @type {SimulationOption | null} */ (null), /** @type {SimulationOption | null} */ (null)
); );
let previousElement = /** @type {HTMLElement | undefined} */ ( let previousElement = /** @type {HTMLElement | undefined} */ (
@@ -2198,9 +2204,9 @@ function main() {
webSockets, webSockets,
vecsResources, vecsResources,
vecIdToIndexes, vecIdToIndexes,
}), })
), )
), )
); );
} }
firstTimeLoadingChart = false; firstTimeLoadingChart = false;
@@ -2221,8 +2227,8 @@ function main() {
vecsResources, vecsResources,
option, option,
vecIdToIndexes, vecIdToIndexes,
}), })
), )
); );
} }
firstTimeLoadingTable = false; firstTimeLoadingTable = false;
@@ -2246,9 +2252,9 @@ function main() {
signals, signals,
utils, utils,
vecsResources, vecsResources,
}), })
), )
), )
); );
} }
firstTimeLoadingSimulation = false; firstTimeLoadingSimulation = false;
@@ -2277,7 +2283,7 @@ function main() {
createMobileSwitchEffect(); createMobileSwitchEffect();
utils.dom.onFirstIntersection(elements.aside, () => utils.dom.onFirstIntersection(elements.aside, () =>
signals.runWithOwner(owner, initSelectedFrame), signals.runWithOwner(owner, initSelectedFrame)
); );
} }
initSelected(); initSelected();
@@ -2355,7 +2361,7 @@ function main() {
if (indexes?.length) { if (indexes?.length) {
const maxIndex = Math.min( const maxIndex = Math.min(
(order || indexes).length - 1, (order || indexes).length - 1,
minIndex + RESULTS_PER_PAGE - 1, minIndex + RESULTS_PER_PAGE - 1
); );
list = Array(maxIndex - minIndex + 1); list = Array(maxIndex - minIndex + 1);
@@ -2431,7 +2437,7 @@ function main() {
haystack, haystack,
needle, needle,
undefined, undefined,
infoThresh, infoThresh
); );
if (!result?.[0]?.length || !result?.[1]) { if (!result?.[0]?.length || !result?.[1]) {
@@ -2439,7 +2445,7 @@ function main() {
haystack, haystack,
needle, needle,
outOfOrder, outOfOrder,
infoThresh, infoThresh
); );
} }
@@ -2448,7 +2454,7 @@ function main() {
haystack, haystack,
needle, needle,
outOfOrder, outOfOrder,
infoThresh, infoThresh
); );
} }
@@ -2457,7 +2463,7 @@ function main() {
haystack, haystack,
needle, needle,
outOfOrder, outOfOrder,
infoThresh, infoThresh
); );
} }
@@ -2466,7 +2472,7 @@ function main() {
haystack, haystack,
needle, needle,
undefined, undefined,
infoThresh, infoThresh
); );
} }
@@ -2475,7 +2481,7 @@ function main() {
haystack, haystack,
needle, needle,
outOfOrder, outOfOrder,
infoThresh, infoThresh
); );
} }
@@ -2558,7 +2564,7 @@ function main() {
shareDiv.hidden = false; shareDiv.hidden = false;
}); });
}), })
); );
} }
initShare(); initShare();
@@ -2575,15 +2581,18 @@ function main() {
* @param {number | null} width * @param {number | null} width
*/ */
function setBarWidth(width) { function setBarWidth(width) {
if (typeof width === "number") { // TODO: Check if should be a signal ??
elements.main.style.width = `${width}px`; try {
localStorage.setItem(barWidthLocalStorageKey, String(width)); if (typeof width === "number") {
} else { elements.main.style.width = `${width}px`;
elements.main.style.width = elements.style.getPropertyValue( utils.storage.write(barWidthLocalStorageKey, String(width));
"--default-main-width", } else {
); elements.main.style.width = elements.style.getPropertyValue(
localStorage.removeItem(barWidthLocalStorageKey); "--default-main-width"
} );
utils.storage.remove(barWidthLocalStorageKey);
}
} catch (_) {}
} }
/** /**
@@ -2616,9 +2625,9 @@ function main() {
window.addEventListener("mouseleave", setResizeFalse); window.addEventListener("mouseleave", setResizeFalse);
} }
initDesktopResizeBar(); initDesktopResizeBar();
}), })
), )
), )
); );
} }
main(); main();
+28 -39
View File
@@ -1,16 +1,5 @@
// @ts-check // @ts-check
/**
* @typedef {Height | DateIndex | WeekIndex | MonthIndex | QuarterIndex | YearIndex | DecadeIndex} ChartableIndex
*/
/**
* @template {readonly unknown[]} T
* @typedef {Extract<T[number], ChartableIndex> extends never ? false : true} IncludesChartableIndex
*/
/**
* @typedef {{[K in VecId]: IncludesChartableIndex<VecIdToIndexes[K]> extends true ? K : never}[VecId]} ChartableVecId
*/
/** /**
* @typedef {Object} BaseSeriesBlueprint * @typedef {Object} BaseSeriesBlueprint
* @property {string} title * @property {string} title
@@ -42,7 +31,7 @@
* *
* @typedef {AnySeriesBlueprint["type"]} SeriesType * @typedef {AnySeriesBlueprint["type"]} SeriesType
* *
* @typedef {{ key: ChartableVecId, unit?: Unit | Unit[] }} FetchedAnySeriesOptions * @typedef {{ key: VecId, unit?: Unit | Unit[] }} FetchedAnySeriesOptions
* *
* @typedef {BaselineSeriesBlueprint & FetchedAnySeriesOptions} FetchedBaselineSeriesBlueprint * @typedef {BaselineSeriesBlueprint & FetchedAnySeriesOptions} FetchedBaselineSeriesBlueprint
* @typedef {CandlestickSeriesBlueprint & FetchedAnySeriesOptions} FetchedCandlestickSeriesBlueprint * @typedef {CandlestickSeriesBlueprint & FetchedAnySeriesOptions} FetchedCandlestickSeriesBlueprint
@@ -122,11 +111,11 @@
function createPartialOptions(colors) { function createPartialOptions(colors) {
/** /**
* @template {string} S * @template {string} S
* @typedef {Extract<ChartableVecId, `${S}${string}`>} StartsWith * @typedef {Extract<VecId, `${S}${string}`>} StartsWith
*/ */
/** /**
* @template {string} S * @template {string} S
* @typedef {Extract<ChartableVecId, `${string}${S}`>} EndsWith * @typedef {Extract<VecId, `${string}${S}`>} EndsWith
*/ */
/** /**
* @template {string} K * @template {string} K
@@ -813,7 +802,7 @@ function createPartialOptions(colors) {
/** /**
* @param {Object} args * @param {Object} args
* @param {ChartableVecId} args.key * @param {VecId} args.key
* @param {string} args.name * @param {string} args.name
* @param {Color} [args.color] * @param {Color} [args.color]
* @param {boolean} [args.defaultActive] * @param {boolean} [args.defaultActive]
@@ -925,7 +914,7 @@ function createPartialOptions(colors) {
/** /**
* @param {Object} args * @param {Object} args
* @param {ChartableVecId & VecIdAverageBase & VecIdSumBase & CumulativeVecIdBase & VecIdMinBase & VecIdMaxBase & VecId90pBase & VecId75pBase & VecIdMedianBase & VecId25pBase & VecId10pBase} args.key * @param {VecId & VecIdAverageBase & VecIdSumBase & CumulativeVecIdBase & VecIdMinBase & VecIdMaxBase & VecId90pBase & VecId75pBase & VecIdMedianBase & VecId25pBase & VecId10pBase} args.key
* @param {string} args.name * @param {string} args.name
*/ */
function createBaseAverageSumCumulativeMinMaxPercentilesSeries({ function createBaseAverageSumCumulativeMinMaxPercentilesSeries({
@@ -943,7 +932,7 @@ function createPartialOptions(colors) {
/** /**
* @param {Object} args * @param {Object} args
* @param {ChartableVecId & VecIdSumBase & CumulativeVecIdBase} args.key * @param {VecId & VecIdSumBase & CumulativeVecIdBase} args.key
* @param {string} args.name * @param {string} args.name
*/ */
function createBaseSumCumulativeSeries({ key, name }) { function createBaseSumCumulativeSeries({ key, name }) {
@@ -1424,7 +1413,7 @@ function createPartialOptions(colors) {
key: `${fixKey(key)}realized-price`, key: `${fixKey(key)}realized-price`,
name, name,
color, color,
}), })
), ),
} }
: createPriceWithRatio({ : createPriceWithRatio({
@@ -1507,7 +1496,7 @@ function createPartialOptions(colors) {
/** @satisfies {FetchedBaselineSeriesBlueprint} */ ({ /** @satisfies {FetchedBaselineSeriesBlueprint} */ ({
type: "Baseline", type: "Baseline",
key: `${fixKey( key: `${fixKey(
key, key
)}net-realized-profit-and-loss-relative-to-realized-cap`, )}net-realized-profit-and-loss-relative-to-realized-cap`,
title: useGroupName ? name : "Net", title: useGroupName ? name : "Net",
color: useGroupName ? color : undefined, color: useGroupName ? color : undefined,
@@ -1578,7 +1567,7 @@ function createPartialOptions(colors) {
/** @satisfies {FetchedBaselineSeriesBlueprint} */ ({ /** @satisfies {FetchedBaselineSeriesBlueprint} */ ({
type: "Baseline", type: "Baseline",
key: `${fixKey( key: `${fixKey(
key, key
)}adjusted-spent-output-profit-ratio`, )}adjusted-spent-output-profit-ratio`,
title: useGroupName ? name : "asopr", title: useGroupName ? name : "asopr",
color: useGroupName ? color : undefined, color: useGroupName ? color : undefined,
@@ -1601,7 +1590,7 @@ function createPartialOptions(colors) {
key: `${fixKey(key)}sell-side-risk-ratio`, key: `${fixKey(key)}sell-side-risk-ratio`,
name: useGroupName ? name : "Risk", name: useGroupName ? name : "Risk",
color: color, color: color,
}), })
), ),
}, },
], ],
@@ -1690,7 +1679,7 @@ function createPartialOptions(colors) {
/** @satisfies {FetchedBaselineSeriesBlueprint} */ ({ /** @satisfies {FetchedBaselineSeriesBlueprint} */ ({
type: "Baseline", type: "Baseline",
key: `${fixKey( key: `${fixKey(
key, key
)}net-unrealized-profit-and-loss-relative-to-market-cap`, )}net-unrealized-profit-and-loss-relative-to-market-cap`,
title: useGroupName ? name : "Net", title: useGroupName ? name : "Net",
color: useGroupName ? color : undefined, color: useGroupName ? color : undefined,
@@ -1868,7 +1857,7 @@ function createPartialOptions(colors) {
key: `${key}-sma`, key: `${key}-sma`,
name: key, name: key,
color, color,
}), })
), ),
}, },
...averages.map(({ key, name, color }) => ...averages.map(({ key, name, color }) =>
@@ -1878,7 +1867,7 @@ function createPartialOptions(colors) {
title: `${name} Market Price Moving Average`, title: `${name} Market Price Moving Average`,
legend: "average", legend: "average",
color, color,
}), })
), ),
], ],
}, },
@@ -1969,7 +1958,7 @@ function createPartialOptions(colors) {
}, },
}), }),
], ],
}), })
), ),
.../** @type {const} */ ([ .../** @type {const} */ ([
{ name: "2 Year", key: "2y" }, { name: "2 Year", key: "2y" },
@@ -2040,7 +2029,7 @@ function createPartialOptions(colors) {
}, },
}), }),
], ],
}), })
), ),
], ],
}, },
@@ -2056,7 +2045,7 @@ function createPartialOptions(colors) {
name: `${year}`, name: `${year}`,
color, color,
defaultActive, defaultActive,
}), })
), ),
}, },
...dcaClasses.map( ...dcaClasses.map(
@@ -2083,7 +2072,7 @@ function createPartialOptions(colors) {
}, },
}), }),
], ],
}), })
), ),
], ],
}, },
@@ -2144,10 +2133,10 @@ function createPartialOptions(colors) {
bottom: [ bottom: [
...createAverageSumCumulativeMinMaxPercentilesSeries("fee"), ...createAverageSumCumulativeMinMaxPercentilesSeries("fee"),
...createAverageSumCumulativeMinMaxPercentilesSeries( ...createAverageSumCumulativeMinMaxPercentilesSeries(
"fee-in-btc", "fee-in-btc"
), ),
...createAverageSumCumulativeMinMaxPercentilesSeries( ...createAverageSumCumulativeMinMaxPercentilesSeries(
"fee-in-usd", "fee-in-usd"
), ),
], ],
}, },
@@ -2889,7 +2878,7 @@ export function initOptions({ colors, signals, env, utils, qrcode }) {
const LS_SELECTED_KEY = `selected-id`; const LS_SELECTED_KEY = `selected-id`;
const urlSelected = utils.url.pathnameToSelectedId(); const urlSelected = utils.url.pathnameToSelectedId();
const savedSelectedId = localStorage.getItem(LS_SELECTED_KEY); const savedSelectedId = utils.storage.read(LS_SELECTED_KEY);
/** @type {Signal<Option>} */ /** @type {Signal<Option>} */
const selected = signals.createSignal(/** @type {any} */ (undefined)); const selected = signals.createSignal(/** @type {any} */ (undefined));
@@ -2903,7 +2892,7 @@ export function initOptions({ colors, signals, env, utils, qrcode }) {
const detailsList = []; const detailsList = [];
const treeElement = signals.createSignal( const treeElement = signals.createSignal(
/** @type {HTMLDivElement | null} */ (null), /** @type {HTMLDivElement | null} */ (null)
); );
/** @type {string[] | undefined} */ /** @type {string[] | undefined} */
@@ -2973,7 +2962,7 @@ export function initOptions({ colors, signals, env, utils, qrcode }) {
signals.createEffect(selected, (selected) => { signals.createEffect(selected, (selected) => {
if (selected?.id === option.id) { if (selected?.id === option.id) {
input.checked = true; input.checked = true;
localStorage.setItem(LS_SELECTED_KEY, option.id); utils.storage.write(LS_SELECTED_KEY, option.id);
} else if (input.checked) { } else if (input.checked) {
input.checked = false; input.checked = false;
} }
@@ -3015,7 +3004,7 @@ export function initOptions({ colors, signals, env, utils, qrcode }) {
return null; return null;
} }
}, },
null, null
); );
partialTree.forEach((anyPartial, partialIndex) => { partialTree.forEach((anyPartial, partialIndex) => {
@@ -3038,7 +3027,7 @@ export function initOptions({ colors, signals, env, utils, qrcode }) {
if ("tree" in anyPartial) { if ("tree" in anyPartial) {
const folderId = utils.stringToId( const folderId = utils.stringToId(
`${(path || []).join(" ")} ${anyPartial.name} folder`, `${(path || []).join(" ")} ${anyPartial.name} folder`
); );
/** @type {Omit<OptionsGroup, keyof PartialOptionsGroup>} */ /** @type {Omit<OptionsGroup, keyof PartialOptionsGroup>} */
@@ -3053,13 +3042,13 @@ export function initOptions({ colors, signals, env, utils, qrcode }) {
const thisPath = groupAddons.id; const thisPath = groupAddons.id;
const passedDetails = signals.createSignal( const passedDetails = signals.createSignal(
/** @type {HTMLDivElement | HTMLDetailsElement | null} */ (null), /** @type {HTMLDivElement | HTMLDetailsElement | null} */ (null)
); );
const childOptionsCount = recursiveProcessPartialTree( const childOptionsCount = recursiveProcessPartialTree(
anyPartial.tree, anyPartial.tree,
passedDetails, passedDetails,
[...(path || []), thisPath], [...(path || []), thisPath]
); );
listForSum.push(childOptionsCount); listForSum.push(childOptionsCount);
@@ -3191,7 +3180,7 @@ export function initOptions({ colors, signals, env, utils, qrcode }) {
}); });
return signals.createMemo(() => return signals.createMemo(() =>
listForSum.reduce((acc, s) => acc + s(), 0), listForSum.reduce((acc, s) => acc + s(), 0)
); );
} }
recursiveProcessPartialTree(partialOptions, treeElement); recursiveProcessPartialTree(partialOptions, treeElement);
@@ -3218,7 +3207,7 @@ export function initOptions({ colors, signals, env, utils, qrcode }) {
console.log( console.log(
[...m.entries()] [...m.entries()]
.filter(([_, value]) => value > 1) .filter(([_, value]) => value > 1)
.map(([key, _]) => key), .map(([key, _]) => key)
); );
throw Error("ID duplicate"); throw Error("ID duplicate");
+6 -5
View File
@@ -2,7 +2,7 @@
// File auto-generated, any modifications will be overwritten // File auto-generated, any modifications will be overwritten
// //
export const VERSION = "v0.0.58"; export const VERSION = "v0.0.61";
/** @typedef {0} DateIndex */ /** @typedef {0} DateIndex */
/** @typedef {1} DecadeIndex */ /** @typedef {1} DecadeIndex */
@@ -31,8 +31,11 @@ export const VERSION = "v0.0.58";
/** @typedef {DateIndex | DecadeIndex | DifficultyEpoch | EmptyOutputIndex | HalvingEpoch | Height | InputIndex | MonthIndex | OpReturnIndex | OutputIndex | P2AIndex | P2MSIndex | P2PK33Index | P2PK65Index | P2PKHIndex | P2SHIndex | P2TRIndex | P2WPKHIndex | P2WSHIndex | QuarterIndex | TxIndex | UnknownOutputIndex | WeekIndex | YearIndex} Index */ /** @typedef {DateIndex | DecadeIndex | DifficultyEpoch | EmptyOutputIndex | HalvingEpoch | Height | InputIndex | MonthIndex | OpReturnIndex | OutputIndex | P2AIndex | P2MSIndex | P2PK33Index | P2PK65Index | P2PKHIndex | P2SHIndex | P2TRIndex | P2WPKHIndex | P2WSHIndex | QuarterIndex | TxIndex | UnknownOutputIndex | WeekIndex | YearIndex} Index */
/** @typedef {ReturnType<typeof createVecIdToIndexes>} VecIdToIndexes */
/** @typedef {keyof VecIdToIndexes} VecId */
export function createVecIdToIndexes() { export function createVecIdToIndexes() {
return /** @type {const} */ ({ return {
"0": [0, 1, 2, 5, 7, 19, 22, 23], "0": [0, 1, 2, 5, 7, 19, 22, 23],
"0sats-adjusted-spent-output-profit-ratio": [0], "0sats-adjusted-spent-output-profit-ratio": [0],
"0sats-adjusted-value-created": [0, 1, 2, 5, 7, 19, 22, 23], "0sats-adjusted-value-created": [0, 1, 2, 5, 7, 19, 22, 23],
@@ -9037,7 +9040,5 @@ export function createVecIdToIndexes() {
"weight": [5, 20], "weight": [5, 20],
"yearindex": [7, 23], "yearindex": [7, 23],
"yearindex-count": [1], "yearindex-count": [1],
}); };
} }
/** @typedef {ReturnType<typeof createVecIdToIndexes>} VecIdToIndexes */
/** @typedef {keyof VecIdToIndexes} VecId */