From ba76e77d935998e4b128053dcc61d2ed4884cdda Mon Sep 17 00:00:00 2001 From: soaos Date: Fri, 21 Nov 2025 21:14:12 -0500 Subject: zola migration --- .gitignore | 1 + .kateproject.build | 23 + .radicle/native.yaml | 2 +- assets/UnifontExMono.woff | Bin 3345136 -> 0 bytes assets/UnifontExMono.woff2 | Bin 2002128 -> 0 bytes assets/badges/go2hell.gif | Bin 1577 -> 0 bytes assets/badges/html.gif | Bin 8500 -> 0 bytes assets/badges/javascript.gif | Bin 1694 -> 0 bytes assets/badges/lynx.gif | Bin 3303 -> 0 bytes assets/badges/midi_files_now.gif | Bin 1395 -> 0 bytes assets/badges/neovim.gif | Bin 695 -> 0 bytes assets/badges/powered-by-debian.gif | Bin 904 -> 0 bytes assets/bg.jpg | Bin 31580 -> 0 bytes assets/construction.gif | Bin 9933 -> 0 bytes assets/unifont.woff2 | Bin 1605860 -> 0 bytes assets/unifont_upper.woff2 | Bin 283288 -> 0 bytes blog/blog.css | 99 -- blog/rockbox_stats/index.html | 560 --------- blog/rockbox_stats/log-setting.bmp | Bin 153666 -> 0 bytes blog/rockbox_stats/playback-settings.bmp | Bin 153666 -> 0 bytes blog/rockbox_stats/player.bmp | Bin 153666 -> 0 bytes blog/terminal_renderer_mkii/cover.png | Bin 6038269 -> 0 bytes blog/terminal_renderer_mkii/david.png | Bin 27218 -> 0 bytes blog/terminal_renderer_mkii/davidbayer.png | Bin 4213 -> 0 bytes blog/terminal_renderer_mkii/davidthreshold.png | Bin 3324 -> 0 bytes blog/terminal_renderer_mkii/index.html | 189 --- config.toml | 18 + content/_index.md | 39 + content/blog/_index.md | 6 + content/blog/blog.css | 99 ++ content/blog/rockbox_stats/index.md | 547 ++++++++ content/blog/rockbox_stats/log-setting.bmp | Bin 0 -> 153666 bytes content/blog/rockbox_stats/playback-settings.bmp | Bin 0 -> 153666 bytes content/blog/rockbox_stats/player.bmp | Bin 0 -> 153666 bytes content/blog/terminal_renderer_mkii/cover.png | Bin 0 -> 6038269 bytes content/blog/terminal_renderer_mkii/david.png | Bin 0 -> 27218 bytes content/blog/terminal_renderer_mkii/davidbayer.png | Bin 0 -> 4213 bytes .../blog/terminal_renderer_mkii/davidthreshold.png | Bin 0 -> 3324 bytes content/blog/terminal_renderer_mkii/index.md | 167 +++ content/heaven/_index.md | 4 + content/heaven/angel.gif | Bin 0 -> 6866 bytes content/heaven/angel2.gif | Bin 0 -> 89484 bytes content/heaven/angel3.gif | Bin 0 -> 8610 bytes content/heaven/bg.jpg | Bin 0 -> 53321 bytes content/heaven/everytime_we_touch_nightcore.ogg | Bin 0 -> 1946392 bytes content/heaven/heaven.css | 24 + content/hell/Flying_Skeleton_Hell.gif | Bin 0 -> 2004165 bytes content/hell/_index.md | 70 ++ content/hell/bg.jpg | Bin 0 -> 48691 bytes content/hell/bigguy.gif | Bin 0 -> 11228 bytes content/hell/comunismo.gif | Bin 0 -> 105570 bytes content/hell/demon.gif | Bin 0 -> 8734 bytes content/hell/demon2.gif | Bin 0 -> 37169 bytes content/hell/demon3.gif | Bin 0 -> 27765 bytes content/hell/demon4.gif | Bin 0 -> 29208 bytes content/hell/demon_face.gif | Bin 0 -> 22848 bytes content/hell/evilmind.gif | Bin 0 -> 101192 bytes content/hell/evilorb.gif | Bin 0 -> 6287 bytes content/hell/firebreak.gif | Bin 0 -> 40755 bytes content/hell/gay.gif | Bin 0 -> 41784 bytes content/hell/gay2.gif | Bin 0 -> 5601 bytes content/hell/gaydudes.gif | Bin 0 -> 101953 bytes content/hell/hell.ogg | Bin 0 -> 924991 bytes content/hell/hellisreal.gif | Bin 0 -> 59555 bytes content/hell/hitler.gif | Bin 0 -> 46349 bytes content/hell/hitler2.gif | Bin 0 -> 45803 bytes content/hell/hitler3.gif | Bin 0 -> 33592 bytes content/hell/hot.gif | Bin 0 -> 4071 bytes content/hell/kissing.jpg | Bin 0 -> 14011 bytes content/hell/obama.gif | Bin 0 -> 1532992 bytes content/hell/pitchfork.gif | Bin 0 -> 16727 bytes content/hell/redfire.gif | Bin 0 -> 21997 bytes content/hell/skull.gif | Bin 0 -> 13021 bytes content/hell/smallfire.gif | Bin 0 -> 5698 bytes content/hell/torch.gif | Bin 0 -> 7960 bytes content/projects/bevy_plugins/index.html | 5 + content/projects/games/NIX_AVREA/index.html | 26 + content/projects/piss_daemon/index.html | 43 + content/projects/piss_daemon/statusbar.png | Bin 0 -> 4546 bytes content/projects/project.css | 0 content/rockstats/index.html | 1301 ++++++++++++++++++++ content/things_i_like/music/867.png | Bin 0 -> 88542 bytes content/things_i_like/music/act_ii.jpg | Bin 0 -> 33123 bytes content/things_i_like/music/apollo.jpg | Bin 0 -> 5380 bytes content/things_i_like/music/atebts.jpg | Bin 0 -> 12938 bytes content/things_i_like/music/departure_songs.jpg | Bin 0 -> 49939 bytes content/things_i_like/music/index.html | 77 ++ content/things_i_like/music/jiminy.jpg | Bin 0 -> 135977 bytes content/things_i_like/music/lysf.jpg | Bin 0 -> 86650 bytes content/things_i_like/music/twin_fantasy.jpg | Bin 0 -> 20076 bytes content/things_i_like/music/wetdream.png | Bin 0 -> 72338 bytes favicon.png | Bin 4287 -> 0 bytes heaven/angel.gif | Bin 6866 -> 0 bytes heaven/angel2.gif | Bin 89484 -> 0 bytes heaven/angel3.gif | Bin 8610 -> 0 bytes heaven/bg.jpg | Bin 53321 -> 0 bytes heaven/everytime_we_touch_nightcore.ogg | Bin 1946392 -> 0 bytes heaven/heaven.css | 24 - heaven/index.html | 31 - hell/Flying_Skeleton_Hell.gif | Bin 2004165 -> 0 bytes hell/bg.jpg | Bin 48691 -> 0 bytes hell/bigguy.gif | Bin 11228 -> 0 bytes hell/comunismo.gif | Bin 105570 -> 0 bytes hell/demon.gif | Bin 8734 -> 0 bytes hell/demon2.gif | Bin 37169 -> 0 bytes hell/demon3.gif | Bin 27765 -> 0 bytes hell/demon4.gif | Bin 29208 -> 0 bytes hell/demon_face.gif | Bin 22848 -> 0 bytes hell/evilmind.gif | Bin 101192 -> 0 bytes hell/evilorb.gif | Bin 6287 -> 0 bytes hell/firebreak.gif | Bin 40755 -> 0 bytes hell/gay.gif | Bin 41784 -> 0 bytes hell/gay2.gif | Bin 5601 -> 0 bytes hell/gaydudes.gif | Bin 101953 -> 0 bytes hell/hell.css | 66 - hell/hell.ogg | Bin 924991 -> 0 bytes hell/hellisreal.gif | Bin 59555 -> 0 bytes hell/hitler.gif | Bin 46349 -> 0 bytes hell/hitler2.gif | Bin 45803 -> 0 bytes hell/hitler3.gif | Bin 33592 -> 0 bytes hell/hot.gif | Bin 4071 -> 0 bytes hell/index.html | 75 -- hell/kissing.jpg | Bin 14011 -> 0 bytes hell/obama.gif | Bin 1532992 -> 0 bytes hell/pitchfork.gif | Bin 16727 -> 0 bytes hell/redfire.gif | Bin 21997 -> 0 bytes hell/skull.gif | Bin 13021 -> 0 bytes hell/smallfire.gif | Bin 5698 -> 0 bytes hell/torch.gif | Bin 7960 -> 0 bytes index.css | 27 - index.html | 105 -- projects/bevy_plugins/index.html | 5 - projects/games/NIX_AVREA/index.html | 26 - projects/piss_daemon/index.html | 43 - projects/piss_daemon/statusbar.png | Bin 4546 -> 0 bytes projects/project.css | 0 rockstats/index.html | 1301 -------------------- static/98.css | 1040 ++++++++++++++++ static/assets/UnifontExMono.woff2 | Bin 0 -> 2002128 bytes static/assets/badges/cookies.png | Bin 0 -> 515 bytes static/assets/badges/go2hell.gif | Bin 0 -> 1577 bytes static/assets/badges/indieweb.png | Bin 0 -> 524 bytes static/assets/badges/javascript.png | Bin 0 -> 412 bytes static/assets/badges/lynx.gif | Bin 0 -> 3303 bytes static/assets/badges/midi_files_now.gif | Bin 0 -> 1395 bytes static/assets/badges/powered-by-debian.gif | Bin 0 -> 904 bytes static/assets/badges/soaos.png | Bin 0 -> 2563 bytes static/assets/bg.jpg | Bin 0 -> 31580 bytes static/assets/construction.gif | Bin 0 -> 9933 bytes static/assets/icon/button-down-active.svg | 5 + static/assets/icon/button-down.svg | 8 + static/assets/icon/button-left.svg | 8 + static/assets/icon/button-right.svg | 8 + static/assets/icon/button-up.svg | 8 + static/assets/icon/checkmark-disabled.svg | 3 + static/assets/icon/checkmark.svg | 3 + static/assets/icon/close.svg | 3 + static/assets/icon/groupbox-border.svg | 4 + static/assets/icon/help.svg | 8 + static/assets/icon/indicator-horizontal.svg | 6 + .../assets/icon/indicator-rectangle-horizontal.svg | 6 + static/assets/icon/maximize-disabled.svg | 4 + static/assets/icon/maximize.svg | 3 + static/assets/icon/minimize.svg | 3 + static/assets/icon/radio-border-disabled.svg | 7 + static/assets/icon/radio-border.svg | 8 + static/assets/icon/radio-dot-disabled.svg | 3 + static/assets/icon/radio-dot.svg | 3 + static/assets/icon/restore.svg | 10 + static/assets/icon/scrollbar-background.svg | 4 + static/assets/icon/sunken-panel-border.svg | 11 + static/favicon.png | Bin 0 -> 4287 bytes static/hell.css | 102 ++ static/index.css | 27 + static/style.css | 184 +++ static/style.css.bak | 224 ++++ style.css | 215 ---- templates/base.html | 95 ++ templates/blog.html | 38 + templates/heaven.html | 29 + templates/hell.html | 22 + templates/index.html | 2 + templates/macros.html | 3 + templates/page.html | 2 + templates/post.html | 19 + templates/section.html | 2 + templates/shortcodes/soaosed.html | 3 + templates/shortcodes/subtree.html | 8 + templates/shortcodes/title_bar.html | 8 + templates/shortcodes/tree_view.html | 5 + templates/shortcodes/treelink.html | 8 + templates/shortcodes/window.html | 3 + templates/shortcodes/window_body.html | 1 + things_i_like/music/867.png | Bin 88542 -> 0 bytes things_i_like/music/act_ii.jpg | Bin 33123 -> 0 bytes things_i_like/music/apollo.jpg | Bin 5380 -> 0 bytes things_i_like/music/atebts.jpg | Bin 12938 -> 0 bytes things_i_like/music/departure_songs.jpg | Bin 49939 -> 0 bytes things_i_like/music/index.html | 77 -- things_i_like/music/jiminy.jpg | Bin 135977 -> 0 bytes things_i_like/music/lysf.jpg | Bin 86650 -> 0 bytes things_i_like/music/twin_fantasy.jpg | Bin 20076 -> 0 bytes things_i_like/music/wetdream.png | Bin 72338 -> 0 bytes 203 files changed, 4402 insertions(+), 2844 deletions(-) create mode 100644 .gitignore create mode 100644 .kateproject.build delete mode 100644 assets/UnifontExMono.woff delete mode 100644 assets/UnifontExMono.woff2 delete mode 100644 assets/badges/go2hell.gif delete mode 100644 assets/badges/html.gif delete mode 100644 assets/badges/javascript.gif delete mode 100644 assets/badges/lynx.gif delete mode 100644 assets/badges/midi_files_now.gif delete mode 100644 assets/badges/neovim.gif delete mode 100644 assets/badges/powered-by-debian.gif delete mode 100644 assets/bg.jpg delete mode 100644 assets/construction.gif delete mode 100644 assets/unifont.woff2 delete mode 100644 assets/unifont_upper.woff2 delete mode 100644 blog/blog.css delete mode 100644 blog/rockbox_stats/index.html delete mode 100644 blog/rockbox_stats/log-setting.bmp delete mode 100644 blog/rockbox_stats/playback-settings.bmp delete mode 100644 blog/rockbox_stats/player.bmp delete mode 100644 blog/terminal_renderer_mkii/cover.png delete mode 100644 blog/terminal_renderer_mkii/david.png delete mode 100644 blog/terminal_renderer_mkii/davidbayer.png delete mode 100644 blog/terminal_renderer_mkii/davidthreshold.png delete mode 100644 blog/terminal_renderer_mkii/index.html create mode 100644 config.toml create mode 100644 content/_index.md create mode 100644 content/blog/_index.md create mode 100644 content/blog/blog.css create mode 100644 content/blog/rockbox_stats/index.md create mode 100644 content/blog/rockbox_stats/log-setting.bmp create mode 100644 content/blog/rockbox_stats/playback-settings.bmp create mode 100644 content/blog/rockbox_stats/player.bmp create mode 100644 content/blog/terminal_renderer_mkii/cover.png create mode 100644 content/blog/terminal_renderer_mkii/david.png create mode 100644 content/blog/terminal_renderer_mkii/davidbayer.png create mode 100644 content/blog/terminal_renderer_mkii/davidthreshold.png create mode 100644 content/blog/terminal_renderer_mkii/index.md create mode 100644 content/heaven/_index.md create mode 100644 content/heaven/angel.gif create mode 100644 content/heaven/angel2.gif create mode 100644 content/heaven/angel3.gif create mode 100644 content/heaven/bg.jpg create mode 100644 content/heaven/everytime_we_touch_nightcore.ogg create mode 100644 content/heaven/heaven.css create mode 100644 content/hell/Flying_Skeleton_Hell.gif create mode 100644 content/hell/_index.md create mode 100644 content/hell/bg.jpg create mode 100644 content/hell/bigguy.gif create mode 100644 content/hell/comunismo.gif create mode 100644 content/hell/demon.gif create mode 100644 content/hell/demon2.gif create mode 100644 content/hell/demon3.gif create mode 100644 content/hell/demon4.gif create mode 100644 content/hell/demon_face.gif create mode 100644 content/hell/evilmind.gif create mode 100644 content/hell/evilorb.gif create mode 100644 content/hell/firebreak.gif create mode 100644 content/hell/gay.gif create mode 100644 content/hell/gay2.gif create mode 100644 content/hell/gaydudes.gif create mode 100644 content/hell/hell.ogg create mode 100644 content/hell/hellisreal.gif create mode 100644 content/hell/hitler.gif create mode 100644 content/hell/hitler2.gif create mode 100644 content/hell/hitler3.gif create mode 100644 content/hell/hot.gif create mode 100644 content/hell/kissing.jpg create mode 100644 content/hell/obama.gif create mode 100644 content/hell/pitchfork.gif create mode 100644 content/hell/redfire.gif create mode 100644 content/hell/skull.gif create mode 100644 content/hell/smallfire.gif create mode 100644 content/hell/torch.gif create mode 100644 content/projects/bevy_plugins/index.html create mode 100644 content/projects/games/NIX_AVREA/index.html create mode 100644 content/projects/piss_daemon/index.html create mode 100644 content/projects/piss_daemon/statusbar.png create mode 100644 content/projects/project.css create mode 100644 content/rockstats/index.html create mode 100644 content/things_i_like/music/867.png create mode 100644 content/things_i_like/music/act_ii.jpg create mode 100644 content/things_i_like/music/apollo.jpg create mode 100644 content/things_i_like/music/atebts.jpg create mode 100644 content/things_i_like/music/departure_songs.jpg create mode 100644 content/things_i_like/music/index.html create mode 100644 content/things_i_like/music/jiminy.jpg create mode 100644 content/things_i_like/music/lysf.jpg create mode 100644 content/things_i_like/music/twin_fantasy.jpg create mode 100644 content/things_i_like/music/wetdream.png delete mode 100644 favicon.png delete mode 100644 heaven/angel.gif delete mode 100644 heaven/angel2.gif delete mode 100644 heaven/angel3.gif delete mode 100644 heaven/bg.jpg delete mode 100644 heaven/everytime_we_touch_nightcore.ogg delete mode 100644 heaven/heaven.css delete mode 100644 heaven/index.html delete mode 100644 hell/Flying_Skeleton_Hell.gif delete mode 100644 hell/bg.jpg delete mode 100644 hell/bigguy.gif delete mode 100644 hell/comunismo.gif delete mode 100644 hell/demon.gif delete mode 100644 hell/demon2.gif delete mode 100644 hell/demon3.gif delete mode 100644 hell/demon4.gif delete mode 100644 hell/demon_face.gif delete mode 100644 hell/evilmind.gif delete mode 100644 hell/evilorb.gif delete mode 100644 hell/firebreak.gif delete mode 100644 hell/gay.gif delete mode 100644 hell/gay2.gif delete mode 100644 hell/gaydudes.gif delete mode 100644 hell/hell.css delete mode 100644 hell/hell.ogg delete mode 100644 hell/hellisreal.gif delete mode 100644 hell/hitler.gif delete mode 100644 hell/hitler2.gif delete mode 100644 hell/hitler3.gif delete mode 100644 hell/hot.gif delete mode 100644 hell/index.html delete mode 100644 hell/kissing.jpg delete mode 100644 hell/obama.gif delete mode 100644 hell/pitchfork.gif delete mode 100644 hell/redfire.gif delete mode 100644 hell/skull.gif delete mode 100644 hell/smallfire.gif delete mode 100644 hell/torch.gif delete mode 100644 index.css delete mode 100644 index.html delete mode 100644 projects/bevy_plugins/index.html delete mode 100644 projects/games/NIX_AVREA/index.html delete mode 100644 projects/piss_daemon/index.html delete mode 100644 projects/piss_daemon/statusbar.png delete mode 100644 projects/project.css delete mode 100644 rockstats/index.html create mode 100644 static/98.css create mode 100644 static/assets/UnifontExMono.woff2 create mode 100644 static/assets/badges/cookies.png create mode 100644 static/assets/badges/go2hell.gif create mode 100644 static/assets/badges/indieweb.png create mode 100644 static/assets/badges/javascript.png create mode 100644 static/assets/badges/lynx.gif create mode 100644 static/assets/badges/midi_files_now.gif create mode 100644 static/assets/badges/powered-by-debian.gif create mode 100644 static/assets/badges/soaos.png create mode 100644 static/assets/bg.jpg create mode 100644 static/assets/construction.gif create mode 100644 static/assets/icon/button-down-active.svg create mode 100644 static/assets/icon/button-down.svg create mode 100644 static/assets/icon/button-left.svg create mode 100644 static/assets/icon/button-right.svg create mode 100644 static/assets/icon/button-up.svg create mode 100644 static/assets/icon/checkmark-disabled.svg create mode 100644 static/assets/icon/checkmark.svg create mode 100644 static/assets/icon/close.svg create mode 100644 static/assets/icon/groupbox-border.svg create mode 100644 static/assets/icon/help.svg create mode 100644 static/assets/icon/indicator-horizontal.svg create mode 100644 static/assets/icon/indicator-rectangle-horizontal.svg create mode 100644 static/assets/icon/maximize-disabled.svg create mode 100644 static/assets/icon/maximize.svg create mode 100644 static/assets/icon/minimize.svg create mode 100644 static/assets/icon/radio-border-disabled.svg create mode 100644 static/assets/icon/radio-border.svg create mode 100644 static/assets/icon/radio-dot-disabled.svg create mode 100644 static/assets/icon/radio-dot.svg create mode 100644 static/assets/icon/restore.svg create mode 100644 static/assets/icon/scrollbar-background.svg create mode 100644 static/assets/icon/sunken-panel-border.svg create mode 100644 static/favicon.png create mode 100644 static/hell.css create mode 100644 static/index.css create mode 100644 static/style.css create mode 100644 static/style.css.bak delete mode 100644 style.css create mode 100644 templates/base.html create mode 100644 templates/blog.html create mode 100644 templates/heaven.html create mode 100644 templates/hell.html create mode 100644 templates/index.html create mode 100644 templates/macros.html create mode 100644 templates/page.html create mode 100644 templates/post.html create mode 100644 templates/section.html create mode 100644 templates/shortcodes/soaosed.html create mode 100644 templates/shortcodes/subtree.html create mode 100644 templates/shortcodes/title_bar.html create mode 100644 templates/shortcodes/tree_view.html create mode 100644 templates/shortcodes/treelink.html create mode 100644 templates/shortcodes/window.html create mode 100644 templates/shortcodes/window_body.html delete mode 100644 things_i_like/music/867.png delete mode 100644 things_i_like/music/act_ii.jpg delete mode 100644 things_i_like/music/apollo.jpg delete mode 100644 things_i_like/music/atebts.jpg delete mode 100644 things_i_like/music/departure_songs.jpg delete mode 100644 things_i_like/music/index.html delete mode 100644 things_i_like/music/jiminy.jpg delete mode 100644 things_i_like/music/lysf.jpg delete mode 100644 things_i_like/music/twin_fantasy.jpg delete mode 100644 things_i_like/music/wetdream.png diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d70ebaa --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +public \ No newline at end of file diff --git a/.kateproject.build b/.kateproject.build new file mode 100644 index 0000000..ac117bf --- /dev/null +++ b/.kateproject.build @@ -0,0 +1,23 @@ +{ + "Auto_generated": "This file is auto-generated. Any extra tags or formatting will be lost", + "target_sets": [ + { + "cmake_config": "", + "directory": "/home/soaos/repo/soaos.dev", + "loaded_via_cmake": false, + "name": "Target Set", + "targets": [ + { + "build_cmd": "cd %w && zola build", + "name": "Build", + "run_cmd": "" + }, + { + "build_cmd": "", + "name": "Run Live Server", + "run_cmd": "cd %w && zola serve" + } + ] + } + ] +} diff --git a/.radicle/native.yaml b/.radicle/native.yaml index 2b826b5..6ff3eb6 100644 --- a/.radicle/native.yaml +++ b/.radicle/native.yaml @@ -1 +1 @@ -shell: rm -rf /var/www/soaos.dev && mkdir /var/www/soaos.dev && cp * -r /var/www/soaos.dev +shell: rm -rf /var/www/soaos.dev && mkdir /var/www/soaos.dev && zola build && cp public/* -r /var/www/soaos.dev diff --git a/assets/UnifontExMono.woff b/assets/UnifontExMono.woff deleted file mode 100644 index 89bc299..0000000 Binary files a/assets/UnifontExMono.woff and /dev/null differ diff --git a/assets/UnifontExMono.woff2 b/assets/UnifontExMono.woff2 deleted file mode 100644 index e7db71a..0000000 Binary files a/assets/UnifontExMono.woff2 and /dev/null differ diff --git a/assets/badges/go2hell.gif b/assets/badges/go2hell.gif deleted file mode 100644 index 7f1290a..0000000 Binary files a/assets/badges/go2hell.gif and /dev/null differ diff --git a/assets/badges/html.gif b/assets/badges/html.gif deleted file mode 100644 index 106af2d..0000000 Binary files a/assets/badges/html.gif and /dev/null differ diff --git a/assets/badges/javascript.gif b/assets/badges/javascript.gif deleted file mode 100644 index 7937f54..0000000 Binary files a/assets/badges/javascript.gif and /dev/null differ diff --git a/assets/badges/lynx.gif b/assets/badges/lynx.gif deleted file mode 100644 index 452ac5e..0000000 Binary files a/assets/badges/lynx.gif and /dev/null differ diff --git a/assets/badges/midi_files_now.gif b/assets/badges/midi_files_now.gif deleted file mode 100644 index 18a2422..0000000 Binary files a/assets/badges/midi_files_now.gif and /dev/null differ diff --git a/assets/badges/neovim.gif b/assets/badges/neovim.gif deleted file mode 100644 index c3670e2..0000000 Binary files a/assets/badges/neovim.gif and /dev/null differ diff --git a/assets/badges/powered-by-debian.gif b/assets/badges/powered-by-debian.gif deleted file mode 100644 index 1f617c8..0000000 Binary files a/assets/badges/powered-by-debian.gif and /dev/null differ diff --git a/assets/bg.jpg b/assets/bg.jpg deleted file mode 100644 index 4e9044c..0000000 Binary files a/assets/bg.jpg and /dev/null differ diff --git a/assets/construction.gif b/assets/construction.gif deleted file mode 100644 index b9c4eeb..0000000 Binary files a/assets/construction.gif and /dev/null differ diff --git a/assets/unifont.woff2 b/assets/unifont.woff2 deleted file mode 100644 index d6e201a..0000000 Binary files a/assets/unifont.woff2 and /dev/null differ diff --git a/assets/unifont_upper.woff2 b/assets/unifont_upper.woff2 deleted file mode 100644 index 47be929..0000000 Binary files a/assets/unifont_upper.woff2 and /dev/null differ diff --git a/blog/blog.css b/blog/blog.css deleted file mode 100644 index 372964d..0000000 --- a/blog/blog.css +++ /dev/null @@ -1,99 +0,0 @@ -html { - background: url("/assets/bg.jpg"); - background-attachment: fixed; - background-size: cover; - image-rendering: pixelated; -} - -figure { - background-color: var(--bg0); - margin: 0; - margin-bottom: 1em; -} - -figure > img, figure > * > img, figure > svg, figure > * svg { - background-color: var(--bg-dim); -} - -.cover-image > img { - width: 100%; - height: auto; - padding: 0 50px; - display: block; - box-sizing: border-box; -} - -figcaption { - padding: 0.5em; - font-style: italic; -} - -body { - max-width: 800px; - margin: 1em auto; - background-color: var(--bg1); -} - -.text-section { - padding: 1em; -} - -.fig { - margin: 0.5em; -} - -.fig-horizontal { - width: min-content; - margin: 0.5em auto; -} - -.fig-right { - float: right; - width: min-content; -} - -.fig-left { - float: left; - width: min-content; -} - - -.fig > img, .fig > * > img { - padding: 0.5em; -} - -pre { - padding: 1em 0.5em; - margin: 0; - overflow: scroll; - background-color: var(--bg-dim); -} - -code { - background-color: var(--bg-dim); -} - -table.schema-table { - border-collapse: collapse; - display: inline-table; - margin-bottom: 0.5em; - background-color: var(--bg-dim); -} - -.schema-table th { - background-color: var(--bg0); -} - -.schema-table th,td { - border: 2px solid var(--bg2); - padding: 0.25em; -} - - - -@media (max-width: 700px) { - .fig-left, .fig-right { - float: unset; - margin: 0.5em auto; - } -} \ No newline at end of file diff --git a/blog/rockbox_stats/index.html b/blog/rockbox_stats/index.html deleted file mode 100644 index 4aca821..0000000 --- a/blog/rockbox_stats/index.html +++ /dev/null @@ -1,560 +0,0 @@ - - - - - - - - - - - -
- ↰ Back - ⌂ Home -
-
-
-
- -

Rockbox Stat Tracking

-

September 22, 2025

-

In this post I talk about how I went about setting up a stat visualization page for my rockbox mp3 player.

-
-
- - - - - - - - - - - - - - - - - - -Progressive Rock -Alternative -Post-Rock -Post-Hardcore -Post-Metal -Rock -Shoegaze -Progressive Metal - - -
A static site generation experiment
-
-
-
-

Preamble: Digital Sovereignity & Rockbox

-

- I've been building up a pretty sizeable collection of digital music - over the last couple of years. I think there's a lot of value in owning - the music I pay for and being able to choose how I listen to it. - Purchasing music also allows me to support artists in a more direct - and substantial way than the fractions of cents for using streaming services, - but that's more of a happy consequence than some moral obligation I feel. -

-

- Over the years, I've enjoyed listening to my music in a variety of ways. - For years I kept all of my music files on all of my devices and used - various local music clients depending on the platform, most notably mpd - and ncmpcpp on linux. Eventually, as I charged headlong into the glorious - world of self-hosting, I began using a central Jellyfin media server that - I stream music and video from. It's super convenient, and works on all of - my devices (including my TV!). -

-

- My media server is great, and it's been the primary way I listen to music - for a while now. But it has limitations. For example, I don't expose my media - server to the internet, so I'm unable to stream from it while I'm out and - about. And even if I could, the bandwidth requirements would be pretty high. - I figured I would need a dedicated music player if I wanted to take my music - library on the go, and settled on the HIFI Walker H2 after reading some - online recommendations. The ability to install Rockbox, an open-source firmware, - was a big factor in my decision. I couldn't tell you how the device works - out of the box, since I flashed the firmware pretty much immediately once I got it, - but I've been super impressed with how the device works while running Rockbox. -

-

-

- Screenshot of Rockbox player showing cool theme. -
I'm using a modified version of the InfoMatrix-v2 theme, which looks great.
-
- Rockbox comes with many codecs for common audio formats including FLAC and MP3. The - device boots extremely quickly, and the interface is snappy. Virtually every aspect - of the user experience is tweakable and customizable to a crazy degree. I've even begun - listening to music on my player even at home, since a device specifically for the - purpose provides less distraction while I'm trying to be productive. -

-

- All this to say I'm pretty much sold on Rockbox. But there's certain things I - still miss from my days of being a user of popular services like Spotify with - fancy APIs and data tracking. Things like Spotify wrapped or third-party apps - for visualizing playback statistics are a fun way to see what my listening history - looks like and could potentially be used to help find more music that I'd enjoy. - This is why when I noticed that Rockbock has a playback logging feature, a little - lightbulb lit up over my head. -

-
-
-

Generating and Parsing Logs

-

-

- Logging -
The logging feature can be accessed through the settings menu.
-
- Rockbox has a feature that logs playback information to a text file. This feature can - be enabled by setting Playback Settings > Logging to "On". With this setting enabled, a - new line gets added to the end of the .rockbox/playback.log file every time you play a track, - containing info about what you played and when. -

-

- The logging feature is actually already used by the LastFM scrobbler plugin that comes preloaded with - Rockbox, which is probably the simplest way to get insights into your playback. However, - I personally want to avoid using third-party services as much as possible, because it's more fun. -

-

- If I take a look at a logfile generated after a bit of listening, I'll see that I've wound up with - a series of lines that each look something like this: -

-
1758478258:336689:336718:/<microSD0>/Music/This Is The Glasshouse/This Is The Glasshouse - 867/This Is The Glasshouse - 867 - 01 Streetlight By Streetlight.flac
-
An example of a log entry for "Streetlight by Streetlight" by This is the Glasshouse. -
-
-

-

- I wasn't really able to find any information online about the format of these logs, but they appear - to be simple enough to figure out. From what I can tell, each event is broken up into 4 pieces: -

    -
  1. Timestamp: The number of milliseconds since the UNIX epoch. -
  2. Playback Duration: The amount of the song that was played, in milliseconds. -
  3. Total Track Length: The length of the played track, in milliseconds. -
  4. File Path: An absolute path to the file containing the track on the filesystem. -
- All of this is enough to know what I was listening to and when. I can use the file path to check for - audio tags which can help glean even more information about my listening habits. -

-

Now that I have this information and know how to interpret it, I'm ready to start processing it!

-
-
-

Analyzing Playback History

-

- In order to get some useful information out of my playback history, I think it's a good idea to start by - building - a database. I created a sqlite database with the following tables: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
songs
idi64PK
titleString
artistsJSON
album_idi64?
genreString?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
albums
idi64PK
titleString
artistString
cover_artBlob?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
history
idi64PK
timestampDatetime
durationi64
song_idi64
-
- I can add more columns later, but this is a good place to start. -

-

- Now, as I read through the logfile line-by-line, I can check if each album exists before - inserting it into the database: -

-
for line in log_file.lines().flatten() {
-    println!("{line}");
-    // Skip comments
-    if line.starts_with("#") {
-        continue;
-    }
-    let chunks = line.split(":").collect::>();
-
-    let timestamp = DateTime::from_timestamp_secs(
-        i64::from_str_radix(chunks[0], 10).context("Failed to parse timestamp")?,
-    )
-    .context("Failed to convert timestamp")?;
-
-    // Load tags from file on device
-    let file_path = chunks[chunks.len() - 1][1..]
-        .split_once("/")
-        .context("Missing file")?
-        .1;
-    let tags = Tag::new()
-        .read_from_path(args.mount_point.join(file_path))
-        .context("Failed to read audio tags")?;
-
-    //...
-}
-
Parsing log entry and loading audio metadata.
-
-
-
if let Some(existing_album) =
-    sqlx::query("SELECT id FROM albums WHERE title=$1 AND artist=$2")
-        .bind(album_title)
-        .bind(album_artist)
-        .fetch_optional(&mut *db)
-        .await
-        .context("Failed to execute query to find existing album")?
-{
-    let album_id: i64 = existing_album.get("id");
-    info!("Album already exists, id {album_id}");
-    //...
-} else {
-    info!("Inserting new album: {album_title} by {album_artist}");
-    //...
-    let result = sqlx::query(
-        "INSERT INTO albums (title, artist, cover_art) VALUES ($1, $2, $3);",
-    )
-    .bind(album_title)
-    .bind(album_artist)
-    .bind(cover)
-    .execute(&mut *db)
-    .await
-    .context("Failed to execute query to insert album into database")?;
-
-    //...
-}
-
Checking for an album with matching artist and title before creating a new row in the - database.
-
- I did something similar with the songs and history tables, basically building up a cache - of history information and skipping anything that's already in the database on repeat runs. -

-

- With this database constructed, it's pretty easy to get a bunch of different information - about my listening. For example (forgive me if my SQL skills are kind of ass lol): -

-
SELECT 
-    songs.title AS song_title,
-    songs.artists AS song_artists,
-    songs.genre AS song_genre,
-    albums.title AS album_title,
-    albums.artist AS album_artist,
-    history.timestamp AS timestamp,
-    history.duration AS duration
-FROM history
-CROSS JOIN songs ON songs.id = history.song_id
-CROSS JOIN albums ON albums.id = songs.album_id
-ORDER BY timestamp DESC;
-
Querying for a list of each history entry along with track metadata, sorted from most to - least recent.
-
-
-
SELECT 
-    songs.genre,
-    SUM(history.duration) AS total_duration
-FROM history
-CROSS JOIN songs ON history.song_id = songs.id
-GROUP BY genre
-ORDER BY total_duration DESC
-LIMIT 10; 
-
Querying for the top 10 most listened genres by playtime.
-
-

-

- It's all well and good to be able to view this information using a database client, - but it would be really cool if I could visualize this data somehow. -

-
-
-

Visualizing this Data Somehow

-

- I wanted to make this data available on my website for people to view, and for a bunch of mostly trivial - reasons I won't get into here, I have a couple of requirements for pages on this site: -

    -
  1. Pages need to be static. -
  2. Pages need to be JavaScript-free. -
- This means any chart rendering needs to be done automatically at build time before - deploying. I don't currently use a static site generator for my site (just for fun), - so I'm basically going to need to write one specifically to generate this page. -

-

- I won't get too deep into the specifics of how I queried the database and generated each visualization - on - the page, but I can explain the visualizations I created using the queries from the previous section. - For the - listening history I wanted to generate a table displaying the information. To accomplish this, I first - used a combination of sqlx's ability to convert a row to a struct and serde to serialize - the rows as JSON values. -

-
#[derive(Serialize, Deserialize, FromRow)]
-struct HistoryEntry {
-    song_title: String,
-    song_artists: Value,
-    timestamp: DateTime<Utc>,
-    duration: i64,
-    album_title: String,
-    album_artist: Option<String>,
-    song_genre: Option<String>,
-}
-
-//...later
-let history = sqlx::query_as::<_, HistoryEntry>(
-    /* SELECT... */
-).fetch_all(&mut *db).await;
-
-//...later still, tera context accepts
-let mut context = tera::Context::new();
-context.insert("history", &history);
-
-
Struct definition for a history entry, allowing conversion from a sqlx row and - de/serialization from/to JSON.
-
-

-

- In order to keep the generation as painless as possible, I decided to use the Tera template - engine, which allows me to define a template HTML file and substitute in values from - a context which I can define before rendering. In the case of the table, I can just generate a <tr> - matching the data for each item: -

-
{% macro history_table(history) %}
-<h3>Playback History</h3>
-<div class="table-container">
-    <table>
-        <thead>
-            <tr>
-                <th>Timestamp</th>
-                <th>Played Duration</th>
-                <th>Title</th>
-                <th>Artists</th>
-                <th>Album</th>
-                <th>Genre</th>
-            </tr>
-        </thead>
-        <tbody>
-            {% for item in history %}<tr>
-                <td>{{ item.timestamp | date(format="%Y-%m-%d %H:%M:%S") }}</td>
-                <td>{{ item.duration | hms }}</td>
-                <td>{{ item.song_title }}</td>
-                <td>{{ item.song_artists }}</td>
-                <td>{{ item.album_title }}</td>
-                <td>{{ item.song_genre }}</td>
-            </tr>
-            {% endfor %}
-        </tbody>
-    </table>
-</div>
-{% endmacro history_table %}
-
- A Tera macro for generating a table from a list of playback history items. - I used a macro so I can re-use this later if I want to add time range views. - (last month, year, etc.) -
-
-

-

- I wrote similar macros for each of the visualizations I wanted to create. Most are - easy, but for my top 10 genres I wanted to display a pie chart. I found a pretty decent - data visualization crate called charming that's able to render to html, however - the output contains javascript so it's a no-go for me. Luckily, it can also render to - an SVG which I can embed nicely within the page. -

- - - - - - - - - - - - - - - - - - -Progressive Rock -Alternative -Post-Rock -Post-Hardcore -Post-Metal -Rock -Shoegaze -Progressive Metal - - -
Here's one I generated just now.
-
-

-

- And that's pretty much all there is to it! The finished thing can be found here. -

-
-
- - - \ No newline at end of file diff --git a/blog/rockbox_stats/log-setting.bmp b/blog/rockbox_stats/log-setting.bmp deleted file mode 100644 index 29789fa..0000000 Binary files a/blog/rockbox_stats/log-setting.bmp and /dev/null differ diff --git a/blog/rockbox_stats/playback-settings.bmp b/blog/rockbox_stats/playback-settings.bmp deleted file mode 100644 index cee3cfb..0000000 Binary files a/blog/rockbox_stats/playback-settings.bmp and /dev/null differ diff --git a/blog/rockbox_stats/player.bmp b/blog/rockbox_stats/player.bmp deleted file mode 100644 index 452a057..0000000 Binary files a/blog/rockbox_stats/player.bmp and /dev/null differ diff --git a/blog/terminal_renderer_mkii/cover.png b/blog/terminal_renderer_mkii/cover.png deleted file mode 100644 index b3ddfd9..0000000 Binary files a/blog/terminal_renderer_mkii/cover.png and /dev/null differ diff --git a/blog/terminal_renderer_mkii/david.png b/blog/terminal_renderer_mkii/david.png deleted file mode 100644 index 6cfa884..0000000 Binary files a/blog/terminal_renderer_mkii/david.png and /dev/null differ diff --git a/blog/terminal_renderer_mkii/davidbayer.png b/blog/terminal_renderer_mkii/davidbayer.png deleted file mode 100644 index af4bfc4..0000000 Binary files a/blog/terminal_renderer_mkii/davidbayer.png and /dev/null differ diff --git a/blog/terminal_renderer_mkii/davidthreshold.png b/blog/terminal_renderer_mkii/davidthreshold.png deleted file mode 100644 index 6c6e014..0000000 Binary files a/blog/terminal_renderer_mkii/davidthreshold.png and /dev/null differ diff --git a/blog/terminal_renderer_mkii/index.html b/blog/terminal_renderer_mkii/index.html deleted file mode 100644 index 326c5d4..0000000 --- a/blog/terminal_renderer_mkii/index.html +++ /dev/null @@ -1,189 +0,0 @@ - - - - - - Terminal Renderer Mk. II - Rendering to Text with Compute - - - - - - - - -
- ↰ Back - ⌂ Home -
-
-
-
- -

Terminal Renderer Mk. II - Rendering to Text with Compute

-

October 2, 2025

-

This week I brought my terminal renderer to the next level by performing text rendering on the GPU. -

-
-
- -
The Stanford Dragon, outlined and rendered as Braille characters in a terminal emulator. -Full video -
-
-
-
-

Context

-

Unicode Braille

-

- I first messed around with rendering images to the terminal with Braille characters in like 2022 I - think? I wrote a simple CLI tool - that applied a threshold to an input image and output it as Braille characters in the terminal. Here's a recording I took back - when I did it. -

- -

-

-
- - - - - - - - - - - - - - - - - - - -
03
14
25
67
-
-
The corresponding bit position for each braille dot.
-
- This effect is pretty cool, and it was pretty easy to implement as well. The trick lies in how the - Unicode Braille block - is laid out. Every 8-dot Braille combination happens to add up to 256 combinations, the perfect amount to - fit in the range between 0x2800 (⠀) and 0x28FF (⣿). In other words, every - character - within the block can be represented by changing the value of a single byte. -

-

- The lowest 6 bits of the pattern map on to a 6-dot braille pattern. However, due - to historical reasons the 8-dot values were tacked on after the fact, which adds - a slightly annoying mapping to the conversion process. Either way, it's a lot easier - than it could be to just read a pixel value, check its brightness, and then use a - bitwise operation to set/clear a dot. -

-

Ordered Dithering

-

- Comparing the brightnes of a pixel against a constant threshold is a fine way to - display black and white images, but it's far from ideal and often results in the loss - of a lot of detail from the original image. -

-
-
- - - -
-
From left to right: Original image, threshold, and ordered dither. Wikipedia
-
-

By using ordered dithering, - we - can preserve much more of the subtleties of the original image. While not the "truest" version of - dithering possible, - ordered dithering (and Bayer dithering in particular) provides a few advantages that make it very - well suited to realtime computer graphics: -

    -
  • Each pixel is dithered independent of any other pixel in the image, making it extremely - parallelizable and good for shaders.
  • -
  • It's visually stable, changes to one part of the image won't disturb other areas.
  • -
  • It's dead simple.
  • -
- Feel free to read up on the specifics of threshold maps and stuff, but for the purposes of this little - explanation it's - enough to know that it's basically just a matrix of 𝓃⨉𝓃 values between 0 and 1, and then to determine - whether a pixel (𝓍,𝓎) - is white or black, you check the brightness against the threshold value at (𝓍%𝓃,𝓎%𝓃) in the map. -

-
-
-

The old way™

-

- My first attempt at realtime terminal graphics with ordered dithering - (I put a video up at the time) - ran entirely on the CPU. I pre-calculated the threshold map at the beginning of execution and ran each - frame - through a sequential function to dither it and convert it to Braille characters. -

-

- To be honest, I never noticed - any significant performance issues doing this, as you can imagine the image size required to fill a - terminal - screen is signficantly smaller than a normal window. However, I knew I could easily perform the - dithering on the GPU - as a post-processing effect, so I eventually wrote a shader to do that. In combination with another - effect I used to - add outlines to objects, I was able to significantly improve the visual fidelity of the experience. A - good example of - where the renderer was at until like a week ago can be seen in this video. -

-

- Until now I hadn't really considered moving the text conversion to the GPU. I mean, GPU is for - graphics, - right? I just copied the entire framebuffer back onto the CPU after dithering - and used the same sequential conversion algorithm. Then I had an idea that would drastically reduce the - amount - of copying necessary. -

-
-
-

Compute post-processing

-

- What if, instead of extracting and copying the framebuffer every single frame, we "rendered" the text on - the GPU - and read that back instead? Assuming each pixel in a texture is 32 bits (RGBA8), and knowing that - each braille - character is a block of 8 pixels, could we not theoretically shave off at least 7/8 of the bytes - copied? -

-

- As it turns out, it's remarkably easy to do. I'm using the Bevy engine, - and hooking in a compute node to my existing post-processing render pipeline worked right out of the - box. - I allocated a storage buffer large enough to hold the necessary amount of characters, read it back each - frame, and dumped - the contents into the terminal. -

-

- I used UTF-32 encoding on the storage buffer because I knew I could easily convert a "wide string" into - UTF-8 before printing it, and - 32 bits provides a consistent space to fill for each workgroup in the shader versus a variable-length - encoding like UTF-8. Here's a video of the new renderer working. - Although now that I think about it, I could probably switch to using UTF-16 since all the Braille - characters could be represented - in 2 bytes, and that would be half the size of the UTF-32 text, which is half empty bytes anyways. -

-

- Okay so I went and tried that but remembered that shaders only accept 32-bit primitive types, so it doesn't matter anyways. This little side quest has been a part of my - broader efforts to revive a project I - spent a lot of time on. I'm taking the opportunity to really dig in and rework some of the stuff I'm not - totally happy with. So there might be quite a few of this kind of post in the near future. Stay tuned. -

-
-
- - - diff --git a/config.toml b/config.toml new file mode 100644 index 0000000..8ab9b67 --- /dev/null +++ b/config.toml @@ -0,0 +1,18 @@ +# The URL the site will be built for +base_url = "https://soaos.dev" + +# Whether to automatically compile all Sass files in the sass directory +compile_sass = false + +# Whether to build a search index to be used later on by a JavaScript library +build_search_index = false + +[markdown] +# Whether to do syntax highlighting +# Theme can be customised by setting the `highlight_theme` variable to a theme supported by Zola +highlight_code = true + +external_links_target_blank = true + +[extra] +# Put all your custom variables here diff --git a/content/_index.md b/content/_index.md new file mode 100644 index 0000000..4e36d29 --- /dev/null +++ b/content/_index.md @@ -0,0 +1,39 @@ ++++ +title = "soaos" +template = "index.html" ++++ + +{% window() %} +{% title_bar() %} +🧍 Welcome to {% soaosed() %}soaos{% end %}.dev +{% end %} +{% window_body() %} + +I'm an "artist" and professional software developer. In my free time I mostly work on eccentric software projects which you can read about here. + +{% tree_view(height="16rem") %} + +{% subtree(name="On this site", open=true) %} +{{ treelink(text="📖 Blog", url="/blog") }} +{{ treelink(text="♫ Rockbox Stats", url="/rockstats", wip=true, wip_tooltip="🦌 -this shit is under construction, pal!") }} +{{ treelink(text="🦌 Things I Like", url="/things_i_like", wip=true, wip_tooltip="🦌 -honestly these things are redundant, everything is under construction") }} +{% end %} + +{% subtree(name='Soaos Services') %} +{{ treelink(text="🌱 Source Code", url="https://app.radicle.xyz/nodes/seed.soaos.dev", blank=true) }} +{{ treelink(text="📺 Videos", url="https://tv.soaos.dev/c/soaosdev", blank=true) }} +{{ treelink(text="🗃 Web Archive", url="https://archive.soaos.dev", blank=true) }} +{{ treelink(text="🔍 Search Engine", url="https://search.soaos.dev", blank=true) }} +{{ treelink(text="♊ Gemini Site", url="gemini://soaos.dev", blank=true) }} +{% end %} + +{% subtree(name="Find me on the Web", open=true)%} +{{ treelink(text="📧 E-Mail: soaos@soaos.dev", url="mailto:soaos@soaos.dev", rel="me") }} +{{ treelink(text="🐘 Mastodon: soaos@furry.engineer", url="http://soaos.dog", rel="me", blank=true) }} +{{ treelink(text="🦀 SSB: @Y1EKP4PU77qby4lI+m5MN6+NcYdjTdRQlV6NmluevuY=.ed25519", url="https://ssb.soaos.dev/~core/ssb/#@Y1EKP4PU77qby4lI+m5MN6+NcYdjTdRQlV6NmluevuY=.ed25519", rel="me", blank=true) }} +{{ treelink(text="⬡ ListenBrainz: soaos", url="https://listenbrainz.org/user/soaos/", rel="me", blank=true) }} +{% end %} + +{% end %} +{% end %} +{% end %} diff --git a/content/blog/_index.md b/content/blog/_index.md new file mode 100644 index 0000000..44bbfa0 --- /dev/null +++ b/content/blog/_index.md @@ -0,0 +1,6 @@ ++++ +title = "soaos blog" +template = "blog.html" +page_template = "post.html" +sort_by = "date" ++++ \ No newline at end of file diff --git a/content/blog/blog.css b/content/blog/blog.css new file mode 100644 index 0000000..372964d --- /dev/null +++ b/content/blog/blog.css @@ -0,0 +1,99 @@ +html { + background: url("/assets/bg.jpg"); + background-attachment: fixed; + background-size: cover; + image-rendering: pixelated; +} + +figure { + background-color: var(--bg0); + margin: 0; + margin-bottom: 1em; +} + +figure > img, figure > * > img, figure > svg, figure > * svg { + background-color: var(--bg-dim); +} + +.cover-image > img { + width: 100%; + height: auto; + padding: 0 50px; + display: block; + box-sizing: border-box; +} + +figcaption { + padding: 0.5em; + font-style: italic; +} + +body { + max-width: 800px; + margin: 1em auto; + background-color: var(--bg1); +} + +.text-section { + padding: 1em; +} + +.fig { + margin: 0.5em; +} + +.fig-horizontal { + width: min-content; + margin: 0.5em auto; +} + +.fig-right { + float: right; + width: min-content; +} + +.fig-left { + float: left; + width: min-content; +} + + +.fig > img, .fig > * > img { + padding: 0.5em; +} + +pre { + padding: 1em 0.5em; + margin: 0; + overflow: scroll; + background-color: var(--bg-dim); +} + +code { + background-color: var(--bg-dim); +} + +table.schema-table { + border-collapse: collapse; + display: inline-table; + margin-bottom: 0.5em; + background-color: var(--bg-dim); +} + +.schema-table th { + background-color: var(--bg0); +} + +.schema-table th,td { + border: 2px solid var(--bg2); + padding: 0.25em; +} + + + +@media (max-width: 700px) { + .fig-left, .fig-right { + float: unset; + margin: 0.5em auto; + } +} \ No newline at end of file diff --git a/content/blog/rockbox_stats/index.md b/content/blog/rockbox_stats/index.md new file mode 100644 index 0000000..626cbe9 --- /dev/null +++ b/content/blog/rockbox_stats/index.md @@ -0,0 +1,547 @@ ++++ +title = "Rockbox Stat Tracking" +date = "2025-09-02" ++++ + +
+
+
+

In this post I talk about how I went about setting up a stat visualization page for my rockbox mp3 player.

+
+
+ + + + + + + + + + + + + + + + + + +Progressive Rock +Alternative +Post-Rock +Post-Hardcore +Post-Metal +Rock +Shoegaze +Progressive Metal + + +
A static site generation experiment
+
+
+
+

Preamble: Digital Sovereignity & Rockbox

+

+ I've been building up a pretty sizeable collection of digital music + over the last couple of years. I think there's a lot of value in owning + the music I pay for and being able to choose how I listen to it. + Purchasing music also allows me to support artists in a more direct + and substantial way than the fractions of cents for using streaming services, + but that's more of a happy consequence than some moral obligation I feel. +

+

+ Over the years, I've enjoyed listening to my music in a variety of ways. + For years I kept all of my music files on all of my devices and used + various local music clients depending on the platform, most notably mpd + and ncmpcpp on linux. Eventually, as I charged headlong into the glorious + world of self-hosting, I began using a central Jellyfin media server that + I stream music and video from. It's super convenient, and works on all of + my devices (including my TV!). +

+

+ My media server is great, and it's been the primary way I listen to music + for a while now. But it has limitations. For example, I don't expose my media + server to the internet, so I'm unable to stream from it while I'm out and + about. And even if I could, the bandwidth requirements would be pretty high. + I figured I would need a dedicated music player if I wanted to take my music + library on the go, and settled on the HIFI Walker H2 after reading some + online recommendations. The ability to install Rockbox, an open-source firmware, + was a big factor in my decision. I couldn't tell you how the device works + out of the box, since I flashed the firmware pretty much immediately once I got it, + but I've been super impressed with how the device works while running Rockbox. +

+

+

+ Screenshot of Rockbox player showing cool theme. +
I'm using a modified version of the InfoMatrix-v2 theme, which looks great.
+
+ Rockbox comes with many codecs for common audio formats including FLAC and MP3. The + device boots extremely quickly, and the interface is snappy. Virtually every aspect + of the user experience is tweakable and customizable to a crazy degree. I've even begun + listening to music on my player even at home, since a device specifically for the + purpose provides less distraction while I'm trying to be productive. +

+

+ All this to say I'm pretty much sold on Rockbox. But there's certain things I + still miss from my days of being a user of popular services like Spotify with + fancy APIs and data tracking. Things like Spotify wrapped or third-party apps + for visualizing playback statistics are a fun way to see what my listening history + looks like and could potentially be used to help find more music that I'd enjoy. + This is why when I noticed that Rockbock has a playback logging feature, a little + lightbulb lit up over my head. +

+
+
+

Generating and Parsing Logs

+

+

+ Logging +
The logging feature can be accessed through the settings menu.
+
+ Rockbox has a feature that logs playback information to a text file. This feature can + be enabled by setting Playback Settings > Logging to "On". With this setting enabled, a + new line gets added to the end of the .rockbox/playback.log file every time you play a track, + containing info about what you played and when. +

+

+ The logging feature is actually already used by the LastFM scrobbler plugin that comes preloaded with + Rockbox, which is probably the simplest way to get insights into your playback. However, + I personally want to avoid using third-party services as much as possible, because it's more fun. +

+

+ If I take a look at a logfile generated after a bit of listening, I'll see that I've wound up with + a series of lines that each look something like this: +

+
1758478258:336689:336718:/<microSD0>/Music/This Is The Glasshouse/This Is The Glasshouse - 867/This Is The Glasshouse - 867 - 01 Streetlight By Streetlight.flac
+
An example of a log entry for "Streetlight by Streetlight" by This is the Glasshouse. +
+
+

+

+ I wasn't really able to find any information online about the format of these logs, but they appear + to be simple enough to figure out. From what I can tell, each event is broken up into 4 pieces: +

    +
  1. Timestamp: The number of milliseconds since the UNIX epoch. +
  2. Playback Duration: The amount of the song that was played, in milliseconds. +
  3. Total Track Length: The length of the played track, in milliseconds. +
  4. File Path: An absolute path to the file containing the track on the filesystem. +
+ All of this is enough to know what I was listening to and when. I can use the file path to check for + audio tags which can help glean even more information about my listening habits. +

+

Now that I have this information and know how to interpret it, I'm ready to start processing it!

+
+
+

Analyzing Playback History

+

+ In order to get some useful information out of my playback history, I think it's a good idea to start by + building + a database. I created a sqlite database with the following tables: +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
songs
idi64PK
titleString
artistsJSON
album_idi64?
genreString?
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
albums
idi64PK
titleString
artistString
cover_artBlob?
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
history
idi64PK
timestampDatetime
durationi64
song_idi64
+
+
+ I can add more columns later, but this is a good place to start. +

+

+ Now, as I read through the logfile line-by-line, I can check if each album exists before + inserting it into the database: +

+
for line in log_file.lines().flatten() {
+println!("{line}");
+// Skip comments
+if line.starts_with("#") {
+continue;
+}
+let chunks = line.split(":").collect::>();
+
+let timestamp = DateTime::from_timestamp_secs(
+i64::from_str_radix(chunks[0], 10).context("Failed to parse timestamp")?,
+)
+.context("Failed to convert timestamp")?;
+
+// Load tags from file on device
+let file_path = chunks[chunks.len() - 1][1..]
+.split_once("/")
+.context("Missing file")?
+.1;
+let tags = Tag::new()
+.read_from_path(args.mount_point.join(file_path))
+.context("Failed to read audio tags")?;
+
+//...
+}
+
Parsing log entry and loading audio metadata.
+
+
+
if let Some(existing_album) =
+sqlx::query("SELECT id FROM albums WHERE title=$1 AND artist=$2")
+.bind(album_title)
+.bind(album_artist)
+.fetch_optional(&mut *db)
+.await
+.context("Failed to execute query to find existing album")?
+{
+let album_id: i64 = existing_album.get("id");
+info!("Album already exists, id {album_id}");
+//...
+} else {
+info!("Inserting new album: {album_title} by {album_artist}");
+//...
+let result = sqlx::query(
+"INSERT INTO albums (title, artist, cover_art) VALUES ($1, $2, $3);",
+)
+.bind(album_title)
+.bind(album_artist)
+.bind(cover)
+.execute(&mut *db)
+.await
+.context("Failed to execute query to insert album into database")?;
+
+//...
+}
+
Checking for an album with matching artist and title before creating a new row in the + database.
+
+ I did something similar with the songs and history tables, basically building up a cache + of history information and skipping anything that's already in the database on repeat runs. +

+

+ With this database constructed, it's pretty easy to get a bunch of different information + about my listening. For example (forgive me if my SQL skills are kind of ass lol): +

+
SELECT 
+songs.title AS song_title,
+songs.artists AS song_artists,
+songs.genre AS song_genre,
+albums.title AS album_title,
+albums.artist AS album_artist,
+history.timestamp AS timestamp,
+history.duration AS duration
+FROM history
+CROSS JOIN songs ON songs.id = history.song_id
+CROSS JOIN albums ON albums.id = songs.album_id
+ORDER BY timestamp DESC;
+
Querying for a list of each history entry along with track metadata, sorted from most to + least recent.
+
+
+
SELECT 
+songs.genre,
+SUM(history.duration) AS total_duration
+FROM history
+CROSS JOIN songs ON history.song_id = songs.id
+GROUP BY genre
+ORDER BY total_duration DESC
+LIMIT 10; 
+
Querying for the top 10 most listened genres by playtime.
+
+

+

+ It's all well and good to be able to view this information using a database client, + but it would be really cool if I could visualize this data somehow. +

+
+
+

Visualizing this Data Somehow

+

+ I wanted to make this data available on my website for people to view, and for a bunch of mostly trivial + reasons I won't get into here, I have a couple of requirements for pages on this site: +

    +
  1. Pages need to be static. +
  2. Pages need to be JavaScript-free. +
+ This means any chart rendering needs to be done automatically at build time before + deploying. I don't currently use a static site generator for my site (just for fun), + so I'm basically going to need to write one specifically to generate this page. +

+

+ I won't get too deep into the specifics of how I queried the database and generated each visualization + on + the page, but I can explain the visualizations I created using the queries from the previous section. + For the + listening history I wanted to generate a table displaying the information. To accomplish this, I first + used a combination of sqlx's ability to convert a row to a struct and serde to serialize + the rows as JSON values. +

+
#[derive(Serialize, Deserialize, FromRow)]
+struct HistoryEntry {
+song_title: String,
+song_artists: Value,
+timestamp: DateTime<Utc>,
+duration: i64,
+album_title: String,
+album_artist: Option<String>,
+song_genre: Option<String>,
+}
+
+//...later
+let history = sqlx::query_as::<_, HistoryEntry>(
+/* SELECT... */
+).fetch_all(&mut *db).await;
+
+//...later still, tera context accepts
+let mut context = tera::Context::new();
+context.insert("history", &history);
+
+
Struct definition for a history entry, allowing conversion from a sqlx row and + de/serialization from/to JSON.
+
+

+

+ In order to keep the generation as painless as possible, I decided to use the Tera template + engine, which allows me to define a template HTML file and substitute in values from + a context which I can define before rendering. In the case of the table, I can just generate a <tr> + matching the data for each item: +

+
{% macro history_table(history) %}
+<h3>Playback History</h3>
+<div class="table-container">
+<table>
+<thead>
+    <tr>
+        <th>Timestamp</th>
+        <th>Played Duration</th>
+        <th>Title</th>
+        <th>Artists</th>
+        <th>Album</th>
+        <th>Genre</th>
+    </tr>
+</thead>
+<tbody>
+    {% for item in history %}<tr>
+        <td>{{ item.timestamp | date(format="%Y-%m-%d %H:%M:%S") }}</td>
+        <td>{{ item.duration | hms }}</td>
+        <td>{{ item.song_title }}</td>
+        <td>{{ item.song_artists }}</td>
+        <td>{{ item.album_title }}</td>
+        <td>{{ item.song_genre }}</td>
+    </tr>
+    {% endfor %}
+</tbody>
+</table>
+</div>
+{% endmacro history_table %}
+
+ A Tera macro for generating a table from a list of playback history items. + I used a macro so I can re-use this later if I want to add time range views. + (last month, year, etc.) +
+
+

+

+ I wrote similar macros for each of the visualizations I wanted to create. Most are + easy, but for my top 10 genres I wanted to display a pie chart. I found a pretty decent + data visualization crate called charming that's able to render to html, however + the output contains javascript so it's a no-go for me. Luckily, it can also render to + an SVG which I can embed nicely within the page. +

+ + + + + + + + + + + + + + + + + + +Progressive Rock +Alternative +Post-Rock +Post-Hardcore +Post-Metal +Rock +Shoegaze +Progressive Metal + + +
Here's one I generated just now.
+
+

+

+ And that's pretty much all there is to it! The finished thing can be found here. +

+
+
\ No newline at end of file diff --git a/content/blog/rockbox_stats/log-setting.bmp b/content/blog/rockbox_stats/log-setting.bmp new file mode 100644 index 0000000..29789fa Binary files /dev/null and b/content/blog/rockbox_stats/log-setting.bmp differ diff --git a/content/blog/rockbox_stats/playback-settings.bmp b/content/blog/rockbox_stats/playback-settings.bmp new file mode 100644 index 0000000..cee3cfb Binary files /dev/null and b/content/blog/rockbox_stats/playback-settings.bmp differ diff --git a/content/blog/rockbox_stats/player.bmp b/content/blog/rockbox_stats/player.bmp new file mode 100644 index 0000000..452a057 Binary files /dev/null and b/content/blog/rockbox_stats/player.bmp differ diff --git a/content/blog/terminal_renderer_mkii/cover.png b/content/blog/terminal_renderer_mkii/cover.png new file mode 100644 index 0000000..b3ddfd9 Binary files /dev/null and b/content/blog/terminal_renderer_mkii/cover.png differ diff --git a/content/blog/terminal_renderer_mkii/david.png b/content/blog/terminal_renderer_mkii/david.png new file mode 100644 index 0000000..6cfa884 Binary files /dev/null and b/content/blog/terminal_renderer_mkii/david.png differ diff --git a/content/blog/terminal_renderer_mkii/davidbayer.png b/content/blog/terminal_renderer_mkii/davidbayer.png new file mode 100644 index 0000000..af4bfc4 Binary files /dev/null and b/content/blog/terminal_renderer_mkii/davidbayer.png differ diff --git a/content/blog/terminal_renderer_mkii/davidthreshold.png b/content/blog/terminal_renderer_mkii/davidthreshold.png new file mode 100644 index 0000000..6c6e014 Binary files /dev/null and b/content/blog/terminal_renderer_mkii/davidthreshold.png differ diff --git a/content/blog/terminal_renderer_mkii/index.md b/content/blog/terminal_renderer_mkii/index.md new file mode 100644 index 0000000..1797a4a --- /dev/null +++ b/content/blog/terminal_renderer_mkii/index.md @@ -0,0 +1,167 @@ ++++ +title = "Terminal Renderer Mk. II - Rendering to Text with Compute" +date = "2025-10-02" ++++ +
+
+

This week I brought my terminal renderer to the next level by performing text rendering on the GPU. +

+
+
+ +
The Stanford Dragon, outlined and rendered as Braille characters in a terminal emulator. +Full video +
+
+
+
+

Context

+

Unicode Braille

+

+I first messed around with rendering images to the terminal with Braille characters in like 2022 I +think? I wrote a simple CLI tool +that applied a threshold to an input image and output it as Braille characters in the terminal. Here's a recording I took back + when I did it. +

+ +

+

+
+ + + + + + + + + + + + + + + + + + + +
03
14
25
67
+
+
The corresponding bit position for each braille dot.
+
+This effect is pretty cool, and it was pretty easy to implement as well. The trick lies in how the +Unicode Braille block +is laid out. Every 8-dot Braille combination happens to add up to 256 combinations, the perfect amount to +fit in the range between 0x2800 (⠀) and 0x28FF (⣿). In other words, every +character +within the block can be represented by changing the value of a single byte. +

+

+The lowest 6 bits of the pattern map on to a 6-dot braille pattern. However, due +to historical reasons the 8-dot values were tacked on after the fact, which adds +a slightly annoying mapping to the conversion process. Either way, it's a lot easier +than it could be to just read a pixel value, check its brightness, and then use a +bitwise operation to set/clear a dot. +

+

Ordered Dithering

+

+Comparing the brightnes of a pixel against a constant threshold is a fine way to +display black and white images, but it's far from ideal and often results in the loss +of a lot of detail from the original image. +

+
+
+ + + +
+
From left to right: Original image, threshold, and ordered dither. Wikipedia
+
+

By using ordered dithering, +we +can preserve much more of the subtleties of the original image. While not the "truest" version of +dithering possible, +ordered dithering (and Bayer dithering in particular) provides a few advantages that make it very +well suited to realtime computer graphics: +

+Feel free to read up on the specifics of threshold maps and stuff, but for the purposes of this little +explanation it's +enough to know that it's basically just a matrix of 𝓃⨉𝓃 values between 0 and 1, and then to determine +whether a pixel (𝓍,𝓎) +is white or black, you check the brightness against the threshold value at (𝓍%𝓃,𝓎%𝓃) in the map. +

+
+
+

The old way™

+

+My first attempt at realtime terminal graphics with ordered dithering +(I put a video up at the time) +ran entirely on the CPU. I pre-calculated the threshold map at the beginning of execution and ran each +frame +through a sequential function to dither it and convert it to Braille characters. +

+

+To be honest, I never noticed +any significant performance issues doing this, as you can imagine the image size required to fill a +terminal +screen is signficantly smaller than a normal window. However, I knew I could easily perform the +dithering on the GPU +as a post-processing effect, so I eventually wrote a shader to do that. In combination with another +effect I used to +add outlines to objects, I was able to significantly improve the visual fidelity of the experience. A +good example of +where the renderer was at until like a week ago can be seen in this video. +

+

+Until now I hadn't really considered moving the text conversion to the GPU. I mean, GPU is for +graphics, +right? I just copied the entire framebuffer back onto the CPU after dithering +and used the same sequential conversion algorithm. Then I had an idea that would drastically reduce the +amount +of copying necessary. +

+
+
+

Compute post-processing

+

+What if, instead of extracting and copying the framebuffer every single frame, we "rendered" the text on +the GPU +and read that back instead? Assuming each pixel in a texture is 32 bits (RGBA8), and knowing that +each braille +character is a block of 8 pixels, could we not theoretically shave off at least 7/8 of the bytes +copied? +

+

+As it turns out, it's remarkably easy to do. I'm using the Bevy engine, +and hooking in a compute node to my existing post-processing render pipeline worked right out of the +box. +I allocated a storage buffer large enough to hold the necessary amount of characters, read it back each +frame, and dumped +the contents into the terminal. +

+

+I used UTF-32 encoding on the storage buffer because I knew I could easily convert a "wide string" into +UTF-8 before printing it, and +32 bits provides a consistent space to fill for each workgroup in the shader versus a variable-length + encoding like UTF-8. Here's a video of the new renderer working. +Although now that I think about it, I could probably switch to using UTF-16 since all the Braille +characters could be represented +in 2 bytes, and that would be half the size of the UTF-32 text, which is half empty bytes anyways. +

+

+Okay so I went and tried that but remembered that shaders only accept 32-bit primitive types, so it doesn't matter anyways. This little side quest has been a part of my +broader efforts to revive a project I +spent a lot of time on. I'm taking the opportunity to really dig in and rework some of the stuff I'm not +totally happy with. So there might be quite a few of this kind of post in the near future. Stay tuned. +

+
diff --git a/content/heaven/_index.md b/content/heaven/_index.md new file mode 100644 index 0000000..ce3b970 --- /dev/null +++ b/content/heaven/_index.md @@ -0,0 +1,4 @@ ++++ +title = "heaven" +template = "heaven.html" ++++ \ No newline at end of file diff --git a/content/heaven/angel.gif b/content/heaven/angel.gif new file mode 100644 index 0000000..1c591e8 Binary files /dev/null and b/content/heaven/angel.gif differ diff --git a/content/heaven/angel2.gif b/content/heaven/angel2.gif new file mode 100644 index 0000000..54adc92 Binary files /dev/null and b/content/heaven/angel2.gif differ diff --git a/content/heaven/angel3.gif b/content/heaven/angel3.gif new file mode 100644 index 0000000..e6aedcb Binary files /dev/null and b/content/heaven/angel3.gif differ diff --git a/content/heaven/bg.jpg b/content/heaven/bg.jpg new file mode 100644 index 0000000..91a9238 Binary files /dev/null and b/content/heaven/bg.jpg differ diff --git a/content/heaven/everytime_we_touch_nightcore.ogg b/content/heaven/everytime_we_touch_nightcore.ogg new file mode 100644 index 0000000..3ac875d Binary files /dev/null and b/content/heaven/everytime_we_touch_nightcore.ogg differ diff --git a/content/heaven/heaven.css b/content/heaven/heaven.css new file mode 100644 index 0000000..5968745 --- /dev/null +++ b/content/heaven/heaven.css @@ -0,0 +1,24 @@ +html { + background: url("bg.jpg"); + background-attachment: fixed; + background-size: cover; + image-rendering: pixelated; +} + +#heavenly-host { + width: 100%; + height: 100%; + position: fixed; + top: 0; + left: 0; + z-index: -999; + background-image: url("angel.gif"); + background-size: 128px 128px; + opacity: 0.25; + --pan: 128px -128px; + animation: pan linear 3s infinite; +} + +.section { + background-color: rgba(from var(--bg-yellow) r g b / 0.5); +} diff --git a/content/hell/Flying_Skeleton_Hell.gif b/content/hell/Flying_Skeleton_Hell.gif new file mode 100644 index 0000000..7cfd429 Binary files /dev/null and b/content/hell/Flying_Skeleton_Hell.gif differ diff --git a/content/hell/_index.md b/content/hell/_index.md new file mode 100644 index 0000000..310e63e --- /dev/null +++ b/content/hell/_index.md @@ -0,0 +1,70 @@ ++++ +title = "soaos" +template = "hell.html" ++++ + +
+
+ + (please enable autoplay to hear music lol) + + +
+

👿 WELLCOME INTO HELL... YOU SUCKER!!!!! 👿

+
+ +
+
+
+
+ +

+ Hey there pal. It's me haha... the "big" "guy"... AKA satan... I + hope you like it here in hell, i worked hard on making it evil :D +

+

+ idk what you did to wind up here, but now you're stuck here... + forever... with me haha ;) +

+

+ so... Make yourself comfortable... haha if you can lol >:] +

+

+ AND DON'T EFFING TRY ESCAPING!!! }:[ alright lucifer out +

+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + +
+
+F*CKSCREW YOU, SUCKER 💔🥀 +
+
diff --git a/content/hell/bg.jpg b/content/hell/bg.jpg new file mode 100644 index 0000000..8d0fad5 Binary files /dev/null and b/content/hell/bg.jpg differ diff --git a/content/hell/bigguy.gif b/content/hell/bigguy.gif new file mode 100644 index 0000000..c3314c7 Binary files /dev/null and b/content/hell/bigguy.gif differ diff --git a/content/hell/comunismo.gif b/content/hell/comunismo.gif new file mode 100644 index 0000000..18da593 Binary files /dev/null and b/content/hell/comunismo.gif differ diff --git a/content/hell/demon.gif b/content/hell/demon.gif new file mode 100644 index 0000000..a5868d2 Binary files /dev/null and b/content/hell/demon.gif differ diff --git a/content/hell/demon2.gif b/content/hell/demon2.gif new file mode 100644 index 0000000..ebbd919 Binary files /dev/null and b/content/hell/demon2.gif differ diff --git a/content/hell/demon3.gif b/content/hell/demon3.gif new file mode 100644 index 0000000..fc73814 Binary files /dev/null and b/content/hell/demon3.gif differ diff --git a/content/hell/demon4.gif b/content/hell/demon4.gif new file mode 100644 index 0000000..debe626 Binary files /dev/null and b/content/hell/demon4.gif differ diff --git a/content/hell/demon_face.gif b/content/hell/demon_face.gif new file mode 100644 index 0000000..5c71e60 Binary files /dev/null and b/content/hell/demon_face.gif differ diff --git a/content/hell/evilmind.gif b/content/hell/evilmind.gif new file mode 100644 index 0000000..1b6cb9b Binary files /dev/null and b/content/hell/evilmind.gif differ diff --git a/content/hell/evilorb.gif b/content/hell/evilorb.gif new file mode 100644 index 0000000..003ef97 Binary files /dev/null and b/content/hell/evilorb.gif differ diff --git a/content/hell/firebreak.gif b/content/hell/firebreak.gif new file mode 100644 index 0000000..981f1bf Binary files /dev/null and b/content/hell/firebreak.gif differ diff --git a/content/hell/gay.gif b/content/hell/gay.gif new file mode 100644 index 0000000..156bbea Binary files /dev/null and b/content/hell/gay.gif differ diff --git a/content/hell/gay2.gif b/content/hell/gay2.gif new file mode 100644 index 0000000..1a00852 Binary files /dev/null and b/content/hell/gay2.gif differ diff --git a/content/hell/gaydudes.gif b/content/hell/gaydudes.gif new file mode 100644 index 0000000..65c4ed3 Binary files /dev/null and b/content/hell/gaydudes.gif differ diff --git a/content/hell/hell.ogg b/content/hell/hell.ogg new file mode 100644 index 0000000..0abf641 Binary files /dev/null and b/content/hell/hell.ogg differ diff --git a/content/hell/hellisreal.gif b/content/hell/hellisreal.gif new file mode 100644 index 0000000..acbd894 Binary files /dev/null and b/content/hell/hellisreal.gif differ diff --git a/content/hell/hitler.gif b/content/hell/hitler.gif new file mode 100644 index 0000000..4edc5d8 Binary files /dev/null and b/content/hell/hitler.gif differ diff --git a/content/hell/hitler2.gif b/content/hell/hitler2.gif new file mode 100644 index 0000000..7fd7132 Binary files /dev/null and b/content/hell/hitler2.gif differ diff --git a/content/hell/hitler3.gif b/content/hell/hitler3.gif new file mode 100644 index 0000000..8edd36c Binary files /dev/null and b/content/hell/hitler3.gif differ diff --git a/content/hell/hot.gif b/content/hell/hot.gif new file mode 100644 index 0000000..4c1660f Binary files /dev/null and b/content/hell/hot.gif differ diff --git a/content/hell/kissing.jpg b/content/hell/kissing.jpg new file mode 100644 index 0000000..b6190c6 Binary files /dev/null and b/content/hell/kissing.jpg differ diff --git a/content/hell/obama.gif b/content/hell/obama.gif new file mode 100644 index 0000000..4f42d27 Binary files /dev/null and b/content/hell/obama.gif differ diff --git a/content/hell/pitchfork.gif b/content/hell/pitchfork.gif new file mode 100644 index 0000000..ab880fa Binary files /dev/null and b/content/hell/pitchfork.gif differ diff --git a/content/hell/redfire.gif b/content/hell/redfire.gif new file mode 100644 index 0000000..8f15a7a Binary files /dev/null and b/content/hell/redfire.gif differ diff --git a/content/hell/skull.gif b/content/hell/skull.gif new file mode 100644 index 0000000..89ed718 Binary files /dev/null and b/content/hell/skull.gif differ diff --git a/content/hell/smallfire.gif b/content/hell/smallfire.gif new file mode 100644 index 0000000..7b29fdf Binary files /dev/null and b/content/hell/smallfire.gif differ diff --git a/content/hell/torch.gif b/content/hell/torch.gif new file mode 100644 index 0000000..c06066b Binary files /dev/null and b/content/hell/torch.gif differ diff --git a/content/projects/bevy_plugins/index.html b/content/projects/bevy_plugins/index.html new file mode 100644 index 0000000..5f5c427 --- /dev/null +++ b/content/projects/bevy_plugins/index.html @@ -0,0 +1,5 @@ + + + + + diff --git a/content/projects/games/NIX_AVREA/index.html b/content/projects/games/NIX_AVREA/index.html new file mode 100644 index 0000000..47c914b --- /dev/null +++ b/content/projects/games/NIX_AVREA/index.html @@ -0,0 +1,26 @@ + + + + + + + NIX AVREA + + + + Go Home + Go Back +

NIX AVREA

+

This is a project I've been working on since April 2024. It's probably the longest-running personal project I've ever done and has been a monumental undertaking so far.

+

I'm unsure how much I want to reveal about this project while I'm developing it, I want the experience to be as novel as possible once it's out. I think I'll probably stick to posting about it here on my site and the occasional YouTube video until it's closer to ready.

+

About the Project

+

NIX AVREA is the codename for my first game project. The game is highly experimental and features mechanics that (as far as I know) have never been attempted. The game is centered around dynamic content, using steganographic techniques to embed binary payloads inside of asset files in order to construct the game world from a directory on the player's filesystem.

+

There is a ton of stuff that's already implemented for this project and I'll gradually add more to the following directories explaining in-depth some of the components:

+
++-- mechanics/
++-- design/
++-- narrative/
+    
+ + + \ No newline at end of file diff --git a/content/projects/piss_daemon/index.html b/content/projects/piss_daemon/index.html new file mode 100644 index 0000000..5cb9481 --- /dev/null +++ b/content/projects/piss_daemon/index.html @@ -0,0 +1,43 @@ + + + + + + Piss Daemon - soaos + + + + Go Home + Go Back +

Piss Daemon

+

About

+

This is a D-Bus daemon (pissd) and client (piss-level) that monitor the international + space station's urine tank level.

+

I have it integrated into my status bar (X version):

+ A screenshot of an X11 statusbar showing the piss daemon piss level next to a toilet icon. +
+	#...
+
+	function piss {
+		PISS_LEVEL="$(piss-level)";
+		if [ -n "$PISS_LEVEL" ]; then
+			echo "  ${PISS_LEVEL}%";
+		fi;
+	}
+
+	#...
+
+	while true; do
+		xsetroot -name "$(piss)$(batt)$(datetime)";
+		sleep 1;
+	done;
+	
+

I made this pretty much entirely so that I could call a program "piss daemon".

+

External Links

+ + + + \ No newline at end of file diff --git a/content/projects/piss_daemon/statusbar.png b/content/projects/piss_daemon/statusbar.png new file mode 100644 index 0000000..b98e021 Binary files /dev/null and b/content/projects/piss_daemon/statusbar.png differ diff --git a/content/projects/project.css b/content/projects/project.css new file mode 100644 index 0000000..e69de29 diff --git a/content/rockstats/index.html b/content/rockstats/index.html new file mode 100644 index 0000000..cfd916c --- /dev/null +++ b/content/rockstats/index.html @@ -0,0 +1,1301 @@ + + + + + + + + + + + + + + + + + +
+ ↰ Back + ⌂ Home +
+

Rockbox Stats

+

This page shows a bunch of information about the music I've been listening to on my mp3 player. Think of it kind of like my own personal Spotify wrapped, minus the antichrist.

+

This page is updated wehenever I feel like regenerating it.

+ +

Playback History

+

Total playtime: 7:57:48, 117 tracks

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TimestampPlayed DurationTitleArtistsAlbumGenre
2025-09-23 19:41:013:37The Misty Veil of May[Black Hill & Silent Island]Tales of the Night ForestPost-Rock
2025-09-23 19:37:242:26An Old Owl Calling[Black Hill & Silent Island]Tales of the Night ForestPost-Rock
2025-09-23 19:34:583:03Night in a Mossy Hut[Black Hill & Silent Island]Tales of the Night ForestPost-Rock
2025-09-23 19:31:552:31Crying Wind[Black Hill & Silent Island]Tales of the Night ForestPost-Rock
2025-09-23 19:29:233:05Dawn[Black Hill & Silent Island]Tales of the Night ForestPost-Rock
2025-09-23 19:26:173:27Hidden Valley[Black Hill & Silent Island]Tales of the Night ForestPost-Rock
2025-09-23 19:22:503:32The Gathering of Deer[Black Hill & Silent Island]Tales of the Night ForestPost-Rock
2025-09-23 19:19:173:49A Wild River to Take You Home[Black Hill & Silent Island]Tales of the Night ForestPost-Rock
2025-09-23 19:15:223:16A Wild River to Take You Home[Black Hill & Silent Island]Tales of the Night ForestPost-Rock
2025-09-23 16:05:052:49Twin Fantasy (Those Boys)[Car Seat Headrest]Twin FantasyAlternative
2025-09-23 15:52:1116:10Famous Prophets (Stars)[Car Seat Headrest]Twin FantasyAlternative
2025-09-23 15:36:017:39High to Death[Car Seat Headrest]Twin FantasyAlternative
2025-09-23 15:28:225:39Cute Thing[Car Seat Headrest]Twin FantasyAlternative
2025-09-23 15:22:426:46Bodys[Car Seat Headrest]Twin FantasyAlternative
2025-09-23 15:15:555:25Nervous Young Inhumans[Car Seat Headrest]Twin FantasyAlternative
2025-09-23 15:10:305:04Sober to Death[Car Seat Headrest]Twin FantasyAlternative
2025-09-23 15:05:251:29Stop Smoking (We Love You)[Car Seat Headrest]Twin FantasyAlternative
2025-09-23 15:03:5613:18Beach Life‐in‐Death[Car Seat Headrest]Twin FantasyAlternative
2025-09-23 14:50:372:52My Boy (Twin Fantasy)[Car Seat Headrest]Twin FantasyAlternative
2025-09-23 14:47:441:32The Light & the Glass[Coheed and Cambria]In Keeping Secrets of Silent Earth: 3Progressive Rock
2025-09-23 14:46:123:54A Favor House Atlantic[Coheed and Cambria]In Keeping Secrets of Silent Earth: 3Progressive Rock
2025-09-23 14:42:184:15The Camper Velourium III: Al the Killer[Coheed and Cambria]In Keeping Secrets of Silent Earth: 3Progressive Rock
2025-09-23 14:38:025:22The Camper Velourium II: Backend of Forever[Coheed and Cambria]In Keeping Secrets of Silent Earth: 3Progressive Rock
2025-09-23 14:32:405:21The Camper Velourium I: Faint of Hearts[Coheed and Cambria]In Keeping Secrets of Silent Earth: 3Progressive Rock
2025-09-23 14:27:184:05Blood Red Summer[Coheed and Cambria]In Keeping Secrets of Silent Earth: 3Progressive Rock
2025-09-23 14:23:136:35The Crowing[Coheed and Cambria]In Keeping Secrets of Silent Earth: 3Progressive Rock
2025-09-23 14:16:375:08Three Evils (Embodied in Love and Shadow)[Coheed and Cambria]In Keeping Secrets of Silent Earth: 3Progressive Rock
2025-09-23 14:11:295:00Cuts Marked in the March of Men[Coheed and Cambria]In Keeping Secrets of Silent Earth: 3Progressive Rock
2025-09-23 14:06:288:12In Keeping Secrets of Silent Earth: 3[Coheed and Cambria]In Keeping Secrets of Silent Earth: 3Progressive Rock
2025-09-23 13:49:392:07The Ring in Return[Coheed and Cambria]In Keeping Secrets of Silent Earth: 3Progressive Rock
2025-09-23 13:45:295:45Life and Death[The Dear Hunter]Act III: Life and DeathProgressive Rock
2025-09-23 13:39:433:25Father[The Dear Hunter]Act III: Life and DeathProgressive Rock
2025-09-23 13:36:172:16Son[The Dear Hunter]Act III: Life and DeathProgressive Rock
2025-09-23 13:34:013:15Go Get Your Gun[The Dear Hunter]Act III: Life and DeathProgressive Rock
2025-09-23 13:30:454:05This Beautiful Life[The Dear Hunter]Act III: Life and DeathProgressive Rock
2025-09-23 13:26:403:39He Said He Had a Story[The Dear Hunter]Act III: Life and DeathProgressive Rock
2025-09-23 13:23:014:41Saved[The Dear Hunter]Act III: Life and DeathProgressive Rock
2025-09-23 13:18:194:13Mustard Gas[The Dear Hunter]Act III: Life and DeathProgressive Rock
2025-09-23 13:14:065:01The Thief[The Dear Hunter]Act III: Life and DeathProgressive Rock
2025-09-23 13:09:054:51The Poison Woman[The Dear Hunter]Act III: Life and DeathProgressive Rock
2025-09-23 13:04:134:39The Tank[The Dear Hunter]Act III: Life and DeathProgressive Rock
2025-09-23 12:59:344:49What It Means to Be Alone[The Dear Hunter]Act III: Life and DeathProgressive Rock
2025-09-23 12:54:445:29In Cauda Venenum[The Dear Hunter]Act III: Life and DeathProgressive Rock
2025-09-23 12:49:151:38Writing on a Wall[The Dear Hunter]Act III: Life and DeathProgressive Rock
2025-09-23 12:47:367:09Vital Vessels Vindicate[The Dear Hunter]Act II: The Meaning of, & All Things Regarding Ms. LeadingProgressive Rock
2025-09-23 12:40:274:13Black Sandy Beaches[The Dear Hunter]Act II: The Meaning of, & All Things Regarding Ms. LeadingProgressive Rock
2025-09-23 12:36:134:28Dear Ms. Leading[The Dear Hunter]Act II: The Meaning of, & All Things Regarding Ms. LeadingProgressive Rock
2025-09-23 12:31:454:29Where the Road Parts[The Dear Hunter]Act II: The Meaning of, & All Things Regarding Ms. LeadingProgressive Rock
2025-09-23 12:27:156:07Red Hands[The Dear Hunter]Act II: The Meaning of, & All Things Regarding Ms. LeadingProgressive Rock
2025-09-23 12:22:051:13Red Hands[The Dear Hunter]Act II: The Meaning of, & All Things Regarding Ms. LeadingProgressive Rock
2025-09-23 12:15:593:48Blood of the Rose[The Dear Hunter]Act II: The Meaning of, & All Things Regarding Ms. LeadingProgressive Rock
2025-09-23 12:12:103:44Evicted[The Dear Hunter]Act II: The Meaning of, & All Things Regarding Ms. LeadingProgressive Rock
2025-09-23 12:08:264:45Smiling Swine[The Dear Hunter]Act II: The Meaning of, & All Things Regarding Ms. LeadingProgressive Rock
2025-09-23 12:03:407:46The Bitter Suite III: Embrace[The Dear Hunter]Act II: The Meaning of, & All Things Regarding Ms. LeadingProgressive Rock
2025-09-23 11:55:546:06The Bitter Suite I & II: Meeting Ms. Leading / Through the Dime[The Dear Hunter]Act II: The Meaning of, & All Things Regarding Ms. LeadingProgressive Rock
2025-09-23 11:49:474:57The Church & the Dime[The Dear Hunter]Act II: The Meaning of, & All Things Regarding Ms. LeadingProgressive Rock
2025-09-23 11:44:494:18The Oracles on the Delphi Express[The Dear Hunter]Act II: The Meaning of, & All Things Regarding Ms. LeadingProgressive Rock
2025-09-23 11:40:319:29The Lake and the River[The Dear Hunter]Act II: The Meaning of, & All Things Regarding Ms. LeadingProgressive Rock
2025-09-23 11:35:124:25The Lake and the River[The Dear Hunter]Act II: The Meaning of, & All Things Regarding Ms. LeadingProgressive Rock
2025-09-23 11:33:312:44The Lake and the River[The Dear Hunter]Act II: The Meaning of, & All Things Regarding Ms. LeadingProgressive Rock
2025-09-23 11:30:474:59The Procession[The Dear Hunter]Act II: The Meaning of, & All Things Regarding Ms. LeadingProgressive Rock
2025-09-23 11:25:570:38The Death and the Berth[The Dear Hunter]Act II: The Meaning of, & All Things Regarding Ms. LeadingProgressive Rock
2025-09-23 11:24:064:03The River North[The Dear Hunter]Act I: The Lake South, the River NorthProgressive Rock
2025-09-23 11:20:036:00His Hands Matched His Tongue[The Dear Hunter]Act I: The Lake South, the River NorthProgressive Rock
2025-09-23 11:14:026:00The Pimp and the Priest[The Dear Hunter]Act I: The Lake South, the River NorthProgressive Rock
2025-09-23 11:08:027:021878[The Dear Hunter]Act I: The Lake South, the River NorthProgressive Rock
2025-09-23 11:01:005:56The Inquiry of Ms. Terri[The Dear Hunter]Act I: The Lake South, the River NorthProgressive Rock
2025-09-23 10:55:035:56City Escape[The Dear Hunter]Act I: The Lake South, the River NorthProgressive Rock
2025-09-23 10:49:071:43The Lake South[The Dear Hunter]Act I: The Lake South, the River NorthProgressive Rock
2025-09-23 10:47:231:55Battesimo del fuoco[The Dear Hunter]Act I: The Lake South, the River NorthProgressive Rock
2025-09-23 10:44:364:24Chapter X[Sufferer]SuffererPost-Hardcore
2025-09-23 10:40:123:32Chapter IX[Sufferer]SuffererPost-Hardcore
2025-09-23 10:36:393:39Chapter VIII[Sufferer]SuffererPost-Hardcore
2025-09-23 10:33:006:08Chapter VII[Sufferer]SuffererPost-Hardcore
2025-09-23 10:26:513:45Chapter VI[Sufferer]SuffererPost-Hardcore
2025-09-23 10:23:063:39Chapter V[Sufferer]SuffererPost-Hardcore
2025-09-23 10:19:273:24Chapter IV[Sufferer]SuffererPost-Hardcore
2025-09-23 10:16:024:24Chapter III[Sufferer]SuffererPost-Hardcore
2025-09-23 10:11:372:28Chapter II[Sufferer]SuffererPost-Hardcore
2025-09-23 10:09:091:23Chapter I[Sufferer]SuffererPost-Hardcore
2025-09-21 19:50:5312:26Sleep[Godspeed You Black Emperor!]Lift Your Skinny Fists Like Antennas to HeavenPost-Rock
2025-09-21 19:50:183:27A Wild River to Take You Home[Black Hill & Silent Island]Tales of the Night ForestPost-Rock
2025-09-21 19:45:181:28A Wild River to Take You Home[Black Hill & Silent Island]Tales of the Night ForestPost-Rock
2025-09-21 19:43:490:28A Wild River to Take You Home[Black Hill & Silent Island]Tales of the Night ForestPost-Rock
2025-09-21 19:40:110:48Night Ela (Mystic Thing)[Candy Claws]Ceres & Calypso in the Deep TimeShoegaze
2025-09-21 19:28:371:28Night Ela (Mystic Thing)[Candy Claws]Ceres & Calypso in the Deep TimeShoegaze
2025-09-21 19:26:400:42The Tragedy[The Pax Cecilia]Blessed Are the BondsPost-Metal
2025-09-21 19:25:585:01A Dance With Death[We Lost the Sea]A Single FlowerPost-Rock
2025-09-21 19:25:003:26Homecoming: Denied![Harakiri for the Sky]Aokigahara MMXXIIPost-Metal
2025-09-21 19:21:331:18Keeping the Blade[Coheed and Cambria]Good Apollo I’m Burning Star IV, Volume One: From Fear Through the Eyes of MadnessProgressive Rock
2025-09-21 19:20:141:47I Existed[Snooze]I Know How You Will DieProgressive Metal
2025-09-21 19:14:227:40Robinson[This Is The Glasshouse]867Progressive Rock
2025-09-21 19:06:423:35October[This Is The Glasshouse]867Progressive Rock
2025-09-21 19:03:0710:21Old George[This Is The Glasshouse]867Progressive Rock
2025-09-21 18:52:459:34867[This Is The Glasshouse]867Progressive Rock
2025-09-21 18:43:113:38Two-Headed Calf[This Is The Glasshouse]867Progressive Rock
2025-09-21 18:39:336:257Bass / Lorne[This Is The Glasshouse]867Progressive Rock
2025-09-21 18:33:079:51January[This Is The Glasshouse]867Progressive Rock
2025-09-21 18:23:153:39Southpaw[This Is The Glasshouse]867Progressive Rock
2025-09-21 18:19:368:37Before Machinery[This Is The Glasshouse]867Progressive Rock
2025-09-21 18:10:585:36Streetlight by Streetlight[This Is The Glasshouse]867Progressive Rock
2025-09-21 18:05:210:17Streetlight by Streetlight[This Is The Glasshouse]867Progressive Rock
2025-09-21 15:00:220:02Before Machinery[This Is The Glasshouse]867Progressive Rock
2025-09-21 15:00:125:36Streetlight by Streetlight[This Is The Glasshouse]867Progressive Rock
2025-09-21 02:29:430:24The Diary of Jane[Breaking Benjamin]PhobiaRock
2025-09-21 02:29:201:13Intro[Breaking Benjamin]PhobiaRock
2025-09-21 01:23:282:00The Diary of Jane[Breaking Benjamin]PhobiaRock
2025-09-20 19:51:540:05Chapter X[Sufferer]SuffererPost-Hardcore
2025-09-20 19:51:410:01Chapter IX[Sufferer]SuffererPost-Hardcore
2025-09-20 19:51:390:01Chapter VIII[Sufferer]SuffererPost-Hardcore
2025-09-20 19:51:380:01Chapter VII[Sufferer]SuffererPost-Hardcore
2025-09-20 19:51:360:01Chapter VI[Sufferer]SuffererPost-Hardcore
2025-09-20 19:51:350:01Chapter V[Sufferer]SuffererPost-Hardcore
2025-09-20 19:51:330:01Chapter IV[Sufferer]SuffererPost-Hardcore
2025-09-20 19:51:320:01Chapter III[Sufferer]SuffererPost-Hardcore
2025-09-20 19:51:300:01Chapter II[Sufferer]SuffererPost-Hardcore
2025-09-20 19:51:290:02Chapter I[Sufferer]SuffererPost-Hardcore
+
+ + +

Top Genres

+
+
+ + + + + + + + + + + + + + + + + + +Progressive Rock +Alternative +Post-Rock +Post-Hardcore +Post-Metal +Rock +Shoegaze +Progressive Metal + + +
+
    + +
  1. Progressive Rock: 5:09:49 (64.8%) + +
  2. Alternative: 1:07:16 (14.1%) + +
  3. Post-Rock: 51:41 (10.8%) + +
  4. Post-Hardcore: 37:09 (7.8%) + +
  5. Post-Metal: 4:09 (0.9%) + +
  6. Rock: 3:39 (0.8%) + +
  7. Shoegaze: 2:17 (0.5%) + +
  8. Progressive Metal: 1:47 (0.4%) + +
+
+ + +

Top Albums

+
    +
  1. +
    + + 🖸 Act II: The Meaning of, & All Things Regarding Ms. Leading + 👤 The Dear Hunter + ⏱ 1:25:26 +
    +
  2. + +
  3. +
    + + 🖸 867 + 🫏 This Is The Glasshouse + ⏱ 1:14:56 +
    +
  4. + +
  5. +
    + + 🖸 Twin Fantasy + 👤 Car Seat Headrest + ⏱ 1:07:16 +
    +
  6. + +
  7. +
    + + 🖸 Act III: Life and Death + 👤 The Dear Hunter + ⏱ 57:51 +
    +
  8. + +
  9. +
    + + 🖸 In Keeping Secrets of Silent Earth: 3 + 👤 Coheed and Cambria + ⏱ 51:36 +
    +
  10. + +
  11. +
    + + 🖸 Act I: The Lake South, the River North + 👤 The Dear Hunter + ⏱ 38:38 +
    +
  12. + +
  13. +
    + + 🖸 Sufferer + 👤 Sufferer + ⏱ 37:09 +
    +
  14. + +
  15. +
    + + 🖸 Tales of the Night Forest + 👤 Black Hill & Silent Island + ⏱ 34:13 +
    +
  16. + +
  17. +
    + + 🖸 Lift Your Skinny Fists Like Antennas to Heaven + 👤 Godspeed You! Black Emperor + ⏱ 12:26 +
    +
  18. + +
  19. +
    + + 🖸 A Single Flower + 👤 We Lost the Sea + ⏱ 5:01 +
    +
  20. + +
+ + +

Top Artists

+
    +
  1. + The Dear Hunter: 3:01:57 +
  2. + +
  3. + This Is The Glasshouse: 1:14:56 +
  4. + +
  5. + Car Seat Headrest: 1:07:16 +
  6. + +
  7. + Coheed and Cambria: 52:55 +
  8. + +
  9. + Sufferer: 37:09 +
  10. + +
  11. + Black Hill & Silent Island: 34:13 +
  12. + +
  13. + Godspeed You Black Emperor!: 12:26 +
  14. + +
  15. + We Lost the Sea: 5:01 +
  16. + +
  17. + Breaking Benjamin: 3:39 +
  18. + +
  19. + Harakiri for the Sky: 3:26 +
  20. + +
+ + + + \ No newline at end of file diff --git a/content/things_i_like/music/867.png b/content/things_i_like/music/867.png new file mode 100644 index 0000000..d416100 Binary files /dev/null and b/content/things_i_like/music/867.png differ diff --git a/content/things_i_like/music/act_ii.jpg b/content/things_i_like/music/act_ii.jpg new file mode 100644 index 0000000..97b2e82 Binary files /dev/null and b/content/things_i_like/music/act_ii.jpg differ diff --git a/content/things_i_like/music/apollo.jpg b/content/things_i_like/music/apollo.jpg new file mode 100644 index 0000000..9c742ee Binary files /dev/null and b/content/things_i_like/music/apollo.jpg differ diff --git a/content/things_i_like/music/atebts.jpg b/content/things_i_like/music/atebts.jpg new file mode 100644 index 0000000..ca68692 Binary files /dev/null and b/content/things_i_like/music/atebts.jpg differ diff --git a/content/things_i_like/music/departure_songs.jpg b/content/things_i_like/music/departure_songs.jpg new file mode 100644 index 0000000..2699d5d Binary files /dev/null and b/content/things_i_like/music/departure_songs.jpg differ diff --git a/content/things_i_like/music/index.html b/content/things_i_like/music/index.html new file mode 100644 index 0000000..46ebc1f --- /dev/null +++ b/content/things_i_like/music/index.html @@ -0,0 +1,77 @@ + + + + + Music I Like - soaos + + + + Go Home + Go Back +

Music I Like

+

I might organize this better at some point, but for now there's no particular order to these. I just want to + share + my awful taste with everyone LMAO.

+

Albums (Click to Listen on YouTube)

+

I only included one album per artist in order to avoid making this list infinitely long LOL. It was difficult for + some of these bands...

+ +
+ Cover art for 867 by This is the Glasshouse +
This is the Glasshouse - 867
+
+
+ +
+ Cover art for wetdream by Willy Rodriguez +
Willy Rodriguez - wetdream
+
+
+ +
+ Cover art for Act II by The Dear Hunter +
The Dear Hunter - Act II: The Meaning of, and All Things Regarding Ms. Leading
+
+
+ +
+ Cover art for Good Apollo, I'm Burning Star IV, Volume One: From Fear Through the Eyes of Madness by Coheed and Cambria +
Coheed and Cambria - Good Apollo, I'm Burning Star IV, Volume One: From Fear Through the Eyes of + Madness
+
+
+ +
+ Cover art for Twin Fantasy by Car Seat Headrest +
Car Seat Headrest - Twin Fantasy
+
+
+ +
+ Cover art for Jiminy by Bear Ghost +
Bear Ghost - Jiminy
+
+
+ +
+ Cover art for Lift Your Skinny Fists Like Antennas to Heaven by Godspeed You! Black Emperor +
Godspeed You! Black Emperor - Lift Your Skinny Fists Like Antennas to Heaven
+
+
+ +
+ Cover art for Departure Songs by We Lost the Sea +
We Lost the Sea - Departure Songs
+
+
+ +
+ Cover art for Above the Earth, Below the Sky by If These Trees Could Talk +
If These Trees Could Talk - Above the Earth, Below the Sky
+
+
+ + + \ No newline at end of file diff --git a/content/things_i_like/music/jiminy.jpg b/content/things_i_like/music/jiminy.jpg new file mode 100644 index 0000000..a216de4 Binary files /dev/null and b/content/things_i_like/music/jiminy.jpg differ diff --git a/content/things_i_like/music/lysf.jpg b/content/things_i_like/music/lysf.jpg new file mode 100644 index 0000000..8605559 Binary files /dev/null and b/content/things_i_like/music/lysf.jpg differ diff --git a/content/things_i_like/music/twin_fantasy.jpg b/content/things_i_like/music/twin_fantasy.jpg new file mode 100644 index 0000000..f83e135 Binary files /dev/null and b/content/things_i_like/music/twin_fantasy.jpg differ diff --git a/content/things_i_like/music/wetdream.png b/content/things_i_like/music/wetdream.png new file mode 100644 index 0000000..862544c Binary files /dev/null and b/content/things_i_like/music/wetdream.png differ diff --git a/favicon.png b/favicon.png deleted file mode 100644 index fac014b..0000000 Binary files a/favicon.png and /dev/null differ diff --git a/heaven/angel.gif b/heaven/angel.gif deleted file mode 100644 index 1c591e8..0000000 Binary files a/heaven/angel.gif and /dev/null differ diff --git a/heaven/angel2.gif b/heaven/angel2.gif deleted file mode 100644 index 54adc92..0000000 Binary files a/heaven/angel2.gif and /dev/null differ diff --git a/heaven/angel3.gif b/heaven/angel3.gif deleted file mode 100644 index e6aedcb..0000000 Binary files a/heaven/angel3.gif and /dev/null differ diff --git a/heaven/bg.jpg b/heaven/bg.jpg deleted file mode 100644 index 91a9238..0000000 Binary files a/heaven/bg.jpg and /dev/null differ diff --git a/heaven/everytime_we_touch_nightcore.ogg b/heaven/everytime_we_touch_nightcore.ogg deleted file mode 100644 index 3ac875d..0000000 Binary files a/heaven/everytime_we_touch_nightcore.ogg and /dev/null differ diff --git a/heaven/heaven.css b/heaven/heaven.css deleted file mode 100644 index 5968745..0000000 --- a/heaven/heaven.css +++ /dev/null @@ -1,24 +0,0 @@ -html { - background: url("bg.jpg"); - background-attachment: fixed; - background-size: cover; - image-rendering: pixelated; -} - -#heavenly-host { - width: 100%; - height: 100%; - position: fixed; - top: 0; - left: 0; - z-index: -999; - background-image: url("angel.gif"); - background-size: 128px 128px; - opacity: 0.25; - --pan: 128px -128px; - animation: pan linear 3s infinite; -} - -.section { - background-color: rgba(from var(--bg-yellow) r g b / 0.5); -} diff --git a/heaven/index.html b/heaven/index.html deleted file mode 100644 index e8b40b1..0000000 --- a/heaven/index.html +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - hell - - - - - - - - - -
-
-
- 🕊🕊🕊 - (please enable autoplay to hear music lol) - -
-

😇 GOD BLESS YOU FRIEND... YOU ARE IN HEAVEN! 😇

-
- YOU ARE LOVED 💖🌹 -
- - - diff --git a/hell/Flying_Skeleton_Hell.gif b/hell/Flying_Skeleton_Hell.gif deleted file mode 100644 index 7cfd429..0000000 Binary files a/hell/Flying_Skeleton_Hell.gif and /dev/null differ diff --git a/hell/bg.jpg b/hell/bg.jpg deleted file mode 100644 index 8d0fad5..0000000 Binary files a/hell/bg.jpg and /dev/null differ diff --git a/hell/bigguy.gif b/hell/bigguy.gif deleted file mode 100644 index c3314c7..0000000 Binary files a/hell/bigguy.gif and /dev/null differ diff --git a/hell/comunismo.gif b/hell/comunismo.gif deleted file mode 100644 index 18da593..0000000 Binary files a/hell/comunismo.gif and /dev/null differ diff --git a/hell/demon.gif b/hell/demon.gif deleted file mode 100644 index a5868d2..0000000 Binary files a/hell/demon.gif and /dev/null differ diff --git a/hell/demon2.gif b/hell/demon2.gif deleted file mode 100644 index ebbd919..0000000 Binary files a/hell/demon2.gif and /dev/null differ diff --git a/hell/demon3.gif b/hell/demon3.gif deleted file mode 100644 index fc73814..0000000 Binary files a/hell/demon3.gif and /dev/null differ diff --git a/hell/demon4.gif b/hell/demon4.gif deleted file mode 100644 index debe626..0000000 Binary files a/hell/demon4.gif and /dev/null differ diff --git a/hell/demon_face.gif b/hell/demon_face.gif deleted file mode 100644 index 5c71e60..0000000 Binary files a/hell/demon_face.gif and /dev/null differ diff --git a/hell/evilmind.gif b/hell/evilmind.gif deleted file mode 100644 index 1b6cb9b..0000000 Binary files a/hell/evilmind.gif and /dev/null differ diff --git a/hell/evilorb.gif b/hell/evilorb.gif deleted file mode 100644 index 003ef97..0000000 Binary files a/hell/evilorb.gif and /dev/null differ diff --git a/hell/firebreak.gif b/hell/firebreak.gif deleted file mode 100644 index 981f1bf..0000000 Binary files a/hell/firebreak.gif and /dev/null differ diff --git a/hell/gay.gif b/hell/gay.gif deleted file mode 100644 index 156bbea..0000000 Binary files a/hell/gay.gif and /dev/null differ diff --git a/hell/gay2.gif b/hell/gay2.gif deleted file mode 100644 index 1a00852..0000000 Binary files a/hell/gay2.gif and /dev/null differ diff --git a/hell/gaydudes.gif b/hell/gaydudes.gif deleted file mode 100644 index 65c4ed3..0000000 Binary files a/hell/gaydudes.gif and /dev/null differ diff --git a/hell/hell.css b/hell/hell.css deleted file mode 100644 index 31119ed..0000000 --- a/hell/hell.css +++ /dev/null @@ -1,66 +0,0 @@ -html { - background: url("bg.jpg"); - background-attachment: fixed; - background-size: cover; - image-rendering: pixelated; -} - -@keyframes fire -{ -0% {text-shadow: 0 0 20px #fefcc9, - 10px -10px 30px #feec85, - -20px -20px 40px #ffae34, - 20px -40px 50px #ec760c, - -20px -60px 60px #cd4606, - 0 -80px 70px #973716, - 10px -90px 80px #451b0e;} -100% {text-shadow: 0 0 20px #fefcc9, - 10px -10px 30px #fefcc9, - -20px -20px 40px #feec85, - 22px -42px 60px #ffae34, - -22px -58px 50px #ec760c, - 0 -82px 80px #cd4606, - 10px -90px 80px #973716;} -} - -.hellfire { - color: var(--orange); - animation: fire 1s ease-in-out infinite alternate; -} - -massive-fucking-background-flame { - width: 100%; - height: 100%; - position: fixed; - top: 0; - left: 0; - z-index: -999; - background-image: url("smallfire.gif"); - background-size: auto 128px; - opacity: 0.25; - --pan: 0 -128px; - animation: pan linear 3s infinite -} - -a { - color: black; -} - -#inverted-cross { - display: inline-block; - rotate: 180deg; - transition: rotate 2s, color 0.5s; - --glow-color: red; - animation: glow 4s linear infinite; -} - -#inverted-cross:hover { - rotate: 0deg; - --glow-color: white; - color: var(--yellow); - transition: rotate 2s, color 1s; -} - -.evil { - color: black; -} diff --git a/hell/hell.ogg b/hell/hell.ogg deleted file mode 100644 index 0abf641..0000000 Binary files a/hell/hell.ogg and /dev/null differ diff --git a/hell/hellisreal.gif b/hell/hellisreal.gif deleted file mode 100644 index acbd894..0000000 Binary files a/hell/hellisreal.gif and /dev/null differ diff --git a/hell/hitler.gif b/hell/hitler.gif deleted file mode 100644 index 4edc5d8..0000000 Binary files a/hell/hitler.gif and /dev/null differ diff --git a/hell/hitler2.gif b/hell/hitler2.gif deleted file mode 100644 index 7fd7132..0000000 Binary files a/hell/hitler2.gif and /dev/null differ diff --git a/hell/hitler3.gif b/hell/hitler3.gif deleted file mode 100644 index 8edd36c..0000000 Binary files a/hell/hitler3.gif and /dev/null differ diff --git a/hell/hot.gif b/hell/hot.gif deleted file mode 100644 index 4c1660f..0000000 Binary files a/hell/hot.gif and /dev/null differ diff --git a/hell/index.html b/hell/index.html deleted file mode 100644 index c03f0d0..0000000 --- a/hell/index.html +++ /dev/null @@ -1,75 +0,0 @@ - - - - - - hell - - - - - - - - - - -
-
- - (please enable autoplay to hear music lol) - -
-

👿 WELLCOME INTO HELL... YOU SUCKER!!!!! 👿

-
- -
-
-
- -
- -

- Hey there pal. It's me haha... the "big" "guy"... AKA satan... I hope you like it here in - hell, i worked hard on - making it evil :D -

-

- idk what you did to wind up here, but now you're stuck here... forever... with me haha ;) -

-

- so... Make yourself comfortable... haha if you can lol >:] -

-

AND DON'T EFFING TRY ESCAPING!!! }:[ alright lucifer out

- - -
- -
- - -
-
-
-
- - - - - - - - - - -
-
- F*CKSCREW YOU, SUCKER 💔🥀 -
-
- - - diff --git a/hell/kissing.jpg b/hell/kissing.jpg deleted file mode 100644 index b6190c6..0000000 Binary files a/hell/kissing.jpg and /dev/null differ diff --git a/hell/obama.gif b/hell/obama.gif deleted file mode 100644 index 4f42d27..0000000 Binary files a/hell/obama.gif and /dev/null differ diff --git a/hell/pitchfork.gif b/hell/pitchfork.gif deleted file mode 100644 index ab880fa..0000000 Binary files a/hell/pitchfork.gif and /dev/null differ diff --git a/hell/redfire.gif b/hell/redfire.gif deleted file mode 100644 index 8f15a7a..0000000 Binary files a/hell/redfire.gif and /dev/null differ diff --git a/hell/skull.gif b/hell/skull.gif deleted file mode 100644 index 89ed718..0000000 Binary files a/hell/skull.gif and /dev/null differ diff --git a/hell/smallfire.gif b/hell/smallfire.gif deleted file mode 100644 index 7b29fdf..0000000 Binary files a/hell/smallfire.gif and /dev/null differ diff --git a/hell/torch.gif b/hell/torch.gif deleted file mode 100644 index c06066b..0000000 Binary files a/hell/torch.gif and /dev/null differ diff --git a/index.css b/index.css deleted file mode 100644 index 9ae6d1e..0000000 --- a/index.css +++ /dev/null @@ -1,27 +0,0 @@ -.section { - background-color: var(--bg1); -} - -html { - background: url("/assets/bg.jpg"); - background-attachment: fixed; - background-size: cover; - image-rendering: pixelated; -} - -#weird-fucking-header-container { - display: inline-grid; - grid-template-columns: 1fr; - grid-template-rows: 1fr; -} - -.whatever { - grid-area: 1 / 1 / 2 / 2; -} - -#badge-grid { - display: inline-grid; - grid-template-columns: 1fr 1fr 1fr; - gap: 4px; -} - diff --git a/index.html b/index.html deleted file mode 100644 index 42a9d2a..0000000 --- a/index.html +++ /dev/null @@ -1,105 +0,0 @@ - - - - - - - soaos - - - - - - - - - -
-
-
-

𐂂🌲🌲🌲 soaos 🌲🌲🌲𐂂

-

𐂂🌲🌲🌲 soaos 🌲🌲🌲𐂂

-
-
-

- I'm an "artist" and professional software developer. - In my free time I mostly work on eccentric software projects which you can - read about here. -

-
- -
-
-
-

Stuff on this Site

- -
- - - -
-
- -
-

Webrings

- - EVILRING - -
- -
- -
    -
  • Learn HTML Now!
  • -
  • Javascript-Free Page
  • -
  • Lynx Compatible
  • -
  • Powered by Debian
  • -
  • Made with Neovim
  • -
  • Go 2 Hell Now!
  • -
-
-
█🍁█ 2025
-
-
- - - diff --git a/projects/bevy_plugins/index.html b/projects/bevy_plugins/index.html deleted file mode 100644 index 5f5c427..0000000 --- a/projects/bevy_plugins/index.html +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/projects/games/NIX_AVREA/index.html b/projects/games/NIX_AVREA/index.html deleted file mode 100644 index 47c914b..0000000 --- a/projects/games/NIX_AVREA/index.html +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - NIX AVREA - - - - Go Home - Go Back -

NIX AVREA

-

This is a project I've been working on since April 2024. It's probably the longest-running personal project I've ever done and has been a monumental undertaking so far.

-

I'm unsure how much I want to reveal about this project while I'm developing it, I want the experience to be as novel as possible once it's out. I think I'll probably stick to posting about it here on my site and the occasional YouTube video until it's closer to ready.

-

About the Project

-

NIX AVREA is the codename for my first game project. The game is highly experimental and features mechanics that (as far as I know) have never been attempted. The game is centered around dynamic content, using steganographic techniques to embed binary payloads inside of asset files in order to construct the game world from a directory on the player's filesystem.

-

There is a ton of stuff that's already implemented for this project and I'll gradually add more to the following directories explaining in-depth some of the components:

-
-+-- mechanics/
-+-- design/
-+-- narrative/
-    
- - - \ No newline at end of file diff --git a/projects/piss_daemon/index.html b/projects/piss_daemon/index.html deleted file mode 100644 index 5cb9481..0000000 --- a/projects/piss_daemon/index.html +++ /dev/null @@ -1,43 +0,0 @@ - - - - - - Piss Daemon - soaos - - - - Go Home - Go Back -

Piss Daemon

-

About

-

This is a D-Bus daemon (pissd) and client (piss-level) that monitor the international - space station's urine tank level.

-

I have it integrated into my status bar (X version):

- A screenshot of an X11 statusbar showing the piss daemon piss level next to a toilet icon. -
-	#...
-
-	function piss {
-		PISS_LEVEL="$(piss-level)";
-		if [ -n "$PISS_LEVEL" ]; then
-			echo "  ${PISS_LEVEL}%";
-		fi;
-	}
-
-	#...
-
-	while true; do
-		xsetroot -name "$(piss)$(batt)$(datetime)";
-		sleep 1;
-	done;
-	
-

I made this pretty much entirely so that I could call a program "piss daemon".

-

External Links

- - - - \ No newline at end of file diff --git a/projects/piss_daemon/statusbar.png b/projects/piss_daemon/statusbar.png deleted file mode 100644 index b98e021..0000000 Binary files a/projects/piss_daemon/statusbar.png and /dev/null differ diff --git a/projects/project.css b/projects/project.css deleted file mode 100644 index e69de29..0000000 diff --git a/rockstats/index.html b/rockstats/index.html deleted file mode 100644 index cfd916c..0000000 --- a/rockstats/index.html +++ /dev/null @@ -1,1301 +0,0 @@ - - - - - - - - - - - - - - - - - -
- ↰ Back - ⌂ Home -
-

Rockbox Stats

-

This page shows a bunch of information about the music I've been listening to on my mp3 player. Think of it kind of like my own personal Spotify wrapped, minus the antichrist.

-

This page is updated wehenever I feel like regenerating it.

- -

Playback History

-

Total playtime: 7:57:48, 117 tracks

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TimestampPlayed DurationTitleArtistsAlbumGenre
2025-09-23 19:41:013:37The Misty Veil of May[Black Hill & Silent Island]Tales of the Night ForestPost-Rock
2025-09-23 19:37:242:26An Old Owl Calling[Black Hill & Silent Island]Tales of the Night ForestPost-Rock
2025-09-23 19:34:583:03Night in a Mossy Hut[Black Hill & Silent Island]Tales of the Night ForestPost-Rock
2025-09-23 19:31:552:31Crying Wind[Black Hill & Silent Island]Tales of the Night ForestPost-Rock
2025-09-23 19:29:233:05Dawn[Black Hill & Silent Island]Tales of the Night ForestPost-Rock
2025-09-23 19:26:173:27Hidden Valley[Black Hill & Silent Island]Tales of the Night ForestPost-Rock
2025-09-23 19:22:503:32The Gathering of Deer[Black Hill & Silent Island]Tales of the Night ForestPost-Rock
2025-09-23 19:19:173:49A Wild River to Take You Home[Black Hill & Silent Island]Tales of the Night ForestPost-Rock
2025-09-23 19:15:223:16A Wild River to Take You Home[Black Hill & Silent Island]Tales of the Night ForestPost-Rock
2025-09-23 16:05:052:49Twin Fantasy (Those Boys)[Car Seat Headrest]Twin FantasyAlternative
2025-09-23 15:52:1116:10Famous Prophets (Stars)[Car Seat Headrest]Twin FantasyAlternative
2025-09-23 15:36:017:39High to Death[Car Seat Headrest]Twin FantasyAlternative
2025-09-23 15:28:225:39Cute Thing[Car Seat Headrest]Twin FantasyAlternative
2025-09-23 15:22:426:46Bodys[Car Seat Headrest]Twin FantasyAlternative
2025-09-23 15:15:555:25Nervous Young Inhumans[Car Seat Headrest]Twin FantasyAlternative
2025-09-23 15:10:305:04Sober to Death[Car Seat Headrest]Twin FantasyAlternative
2025-09-23 15:05:251:29Stop Smoking (We Love You)[Car Seat Headrest]Twin FantasyAlternative
2025-09-23 15:03:5613:18Beach Life‐in‐Death[Car Seat Headrest]Twin FantasyAlternative
2025-09-23 14:50:372:52My Boy (Twin Fantasy)[Car Seat Headrest]Twin FantasyAlternative
2025-09-23 14:47:441:32The Light & the Glass[Coheed and Cambria]In Keeping Secrets of Silent Earth: 3Progressive Rock
2025-09-23 14:46:123:54A Favor House Atlantic[Coheed and Cambria]In Keeping Secrets of Silent Earth: 3Progressive Rock
2025-09-23 14:42:184:15The Camper Velourium III: Al the Killer[Coheed and Cambria]In Keeping Secrets of Silent Earth: 3Progressive Rock
2025-09-23 14:38:025:22The Camper Velourium II: Backend of Forever[Coheed and Cambria]In Keeping Secrets of Silent Earth: 3Progressive Rock
2025-09-23 14:32:405:21The Camper Velourium I: Faint of Hearts[Coheed and Cambria]In Keeping Secrets of Silent Earth: 3Progressive Rock
2025-09-23 14:27:184:05Blood Red Summer[Coheed and Cambria]In Keeping Secrets of Silent Earth: 3Progressive Rock
2025-09-23 14:23:136:35The Crowing[Coheed and Cambria]In Keeping Secrets of Silent Earth: 3Progressive Rock
2025-09-23 14:16:375:08Three Evils (Embodied in Love and Shadow)[Coheed and Cambria]In Keeping Secrets of Silent Earth: 3Progressive Rock
2025-09-23 14:11:295:00Cuts Marked in the March of Men[Coheed and Cambria]In Keeping Secrets of Silent Earth: 3Progressive Rock
2025-09-23 14:06:288:12In Keeping Secrets of Silent Earth: 3[Coheed and Cambria]In Keeping Secrets of Silent Earth: 3Progressive Rock
2025-09-23 13:49:392:07The Ring in Return[Coheed and Cambria]In Keeping Secrets of Silent Earth: 3Progressive Rock
2025-09-23 13:45:295:45Life and Death[The Dear Hunter]Act III: Life and DeathProgressive Rock
2025-09-23 13:39:433:25Father[The Dear Hunter]Act III: Life and DeathProgressive Rock
2025-09-23 13:36:172:16Son[The Dear Hunter]Act III: Life and DeathProgressive Rock
2025-09-23 13:34:013:15Go Get Your Gun[The Dear Hunter]Act III: Life and DeathProgressive Rock
2025-09-23 13:30:454:05This Beautiful Life[The Dear Hunter]Act III: Life and DeathProgressive Rock
2025-09-23 13:26:403:39He Said He Had a Story[The Dear Hunter]Act III: Life and DeathProgressive Rock
2025-09-23 13:23:014:41Saved[The Dear Hunter]Act III: Life and DeathProgressive Rock
2025-09-23 13:18:194:13Mustard Gas[The Dear Hunter]Act III: Life and DeathProgressive Rock
2025-09-23 13:14:065:01The Thief[The Dear Hunter]Act III: Life and DeathProgressive Rock
2025-09-23 13:09:054:51The Poison Woman[The Dear Hunter]Act III: Life and DeathProgressive Rock
2025-09-23 13:04:134:39The Tank[The Dear Hunter]Act III: Life and DeathProgressive Rock
2025-09-23 12:59:344:49What It Means to Be Alone[The Dear Hunter]Act III: Life and DeathProgressive Rock
2025-09-23 12:54:445:29In Cauda Venenum[The Dear Hunter]Act III: Life and DeathProgressive Rock
2025-09-23 12:49:151:38Writing on a Wall[The Dear Hunter]Act III: Life and DeathProgressive Rock
2025-09-23 12:47:367:09Vital Vessels Vindicate[The Dear Hunter]Act II: The Meaning of, & All Things Regarding Ms. LeadingProgressive Rock
2025-09-23 12:40:274:13Black Sandy Beaches[The Dear Hunter]Act II: The Meaning of, & All Things Regarding Ms. LeadingProgressive Rock
2025-09-23 12:36:134:28Dear Ms. Leading[The Dear Hunter]Act II: The Meaning of, & All Things Regarding Ms. LeadingProgressive Rock
2025-09-23 12:31:454:29Where the Road Parts[The Dear Hunter]Act II: The Meaning of, & All Things Regarding Ms. LeadingProgressive Rock
2025-09-23 12:27:156:07Red Hands[The Dear Hunter]Act II: The Meaning of, & All Things Regarding Ms. LeadingProgressive Rock
2025-09-23 12:22:051:13Red Hands[The Dear Hunter]Act II: The Meaning of, & All Things Regarding Ms. LeadingProgressive Rock
2025-09-23 12:15:593:48Blood of the Rose[The Dear Hunter]Act II: The Meaning of, & All Things Regarding Ms. LeadingProgressive Rock
2025-09-23 12:12:103:44Evicted[The Dear Hunter]Act II: The Meaning of, & All Things Regarding Ms. LeadingProgressive Rock
2025-09-23 12:08:264:45Smiling Swine[The Dear Hunter]Act II: The Meaning of, & All Things Regarding Ms. LeadingProgressive Rock
2025-09-23 12:03:407:46The Bitter Suite III: Embrace[The Dear Hunter]Act II: The Meaning of, & All Things Regarding Ms. LeadingProgressive Rock
2025-09-23 11:55:546:06The Bitter Suite I & II: Meeting Ms. Leading / Through the Dime[The Dear Hunter]Act II: The Meaning of, & All Things Regarding Ms. LeadingProgressive Rock
2025-09-23 11:49:474:57The Church & the Dime[The Dear Hunter]Act II: The Meaning of, & All Things Regarding Ms. LeadingProgressive Rock
2025-09-23 11:44:494:18The Oracles on the Delphi Express[The Dear Hunter]Act II: The Meaning of, & All Things Regarding Ms. LeadingProgressive Rock
2025-09-23 11:40:319:29The Lake and the River[The Dear Hunter]Act II: The Meaning of, & All Things Regarding Ms. LeadingProgressive Rock
2025-09-23 11:35:124:25The Lake and the River[The Dear Hunter]Act II: The Meaning of, & All Things Regarding Ms. LeadingProgressive Rock
2025-09-23 11:33:312:44The Lake and the River[The Dear Hunter]Act II: The Meaning of, & All Things Regarding Ms. LeadingProgressive Rock
2025-09-23 11:30:474:59The Procession[The Dear Hunter]Act II: The Meaning of, & All Things Regarding Ms. LeadingProgressive Rock
2025-09-23 11:25:570:38The Death and the Berth[The Dear Hunter]Act II: The Meaning of, & All Things Regarding Ms. LeadingProgressive Rock
2025-09-23 11:24:064:03The River North[The Dear Hunter]Act I: The Lake South, the River NorthProgressive Rock
2025-09-23 11:20:036:00His Hands Matched His Tongue[The Dear Hunter]Act I: The Lake South, the River NorthProgressive Rock
2025-09-23 11:14:026:00The Pimp and the Priest[The Dear Hunter]Act I: The Lake South, the River NorthProgressive Rock
2025-09-23 11:08:027:021878[The Dear Hunter]Act I: The Lake South, the River NorthProgressive Rock
2025-09-23 11:01:005:56The Inquiry of Ms. Terri[The Dear Hunter]Act I: The Lake South, the River NorthProgressive Rock
2025-09-23 10:55:035:56City Escape[The Dear Hunter]Act I: The Lake South, the River NorthProgressive Rock
2025-09-23 10:49:071:43The Lake South[The Dear Hunter]Act I: The Lake South, the River NorthProgressive Rock
2025-09-23 10:47:231:55Battesimo del fuoco[The Dear Hunter]Act I: The Lake South, the River NorthProgressive Rock
2025-09-23 10:44:364:24Chapter X[Sufferer]SuffererPost-Hardcore
2025-09-23 10:40:123:32Chapter IX[Sufferer]SuffererPost-Hardcore
2025-09-23 10:36:393:39Chapter VIII[Sufferer]SuffererPost-Hardcore
2025-09-23 10:33:006:08Chapter VII[Sufferer]SuffererPost-Hardcore
2025-09-23 10:26:513:45Chapter VI[Sufferer]SuffererPost-Hardcore
2025-09-23 10:23:063:39Chapter V[Sufferer]SuffererPost-Hardcore
2025-09-23 10:19:273:24Chapter IV[Sufferer]SuffererPost-Hardcore
2025-09-23 10:16:024:24Chapter III[Sufferer]SuffererPost-Hardcore
2025-09-23 10:11:372:28Chapter II[Sufferer]SuffererPost-Hardcore
2025-09-23 10:09:091:23Chapter I[Sufferer]SuffererPost-Hardcore
2025-09-21 19:50:5312:26Sleep[Godspeed You Black Emperor!]Lift Your Skinny Fists Like Antennas to HeavenPost-Rock
2025-09-21 19:50:183:27A Wild River to Take You Home[Black Hill & Silent Island]Tales of the Night ForestPost-Rock
2025-09-21 19:45:181:28A Wild River to Take You Home[Black Hill & Silent Island]Tales of the Night ForestPost-Rock
2025-09-21 19:43:490:28A Wild River to Take You Home[Black Hill & Silent Island]Tales of the Night ForestPost-Rock
2025-09-21 19:40:110:48Night Ela (Mystic Thing)[Candy Claws]Ceres & Calypso in the Deep TimeShoegaze
2025-09-21 19:28:371:28Night Ela (Mystic Thing)[Candy Claws]Ceres & Calypso in the Deep TimeShoegaze
2025-09-21 19:26:400:42The Tragedy[The Pax Cecilia]Blessed Are the BondsPost-Metal
2025-09-21 19:25:585:01A Dance With Death[We Lost the Sea]A Single FlowerPost-Rock
2025-09-21 19:25:003:26Homecoming: Denied![Harakiri for the Sky]Aokigahara MMXXIIPost-Metal
2025-09-21 19:21:331:18Keeping the Blade[Coheed and Cambria]Good Apollo I’m Burning Star IV, Volume One: From Fear Through the Eyes of MadnessProgressive Rock
2025-09-21 19:20:141:47I Existed[Snooze]I Know How You Will DieProgressive Metal
2025-09-21 19:14:227:40Robinson[This Is The Glasshouse]867Progressive Rock
2025-09-21 19:06:423:35October[This Is The Glasshouse]867Progressive Rock
2025-09-21 19:03:0710:21Old George[This Is The Glasshouse]867Progressive Rock
2025-09-21 18:52:459:34867[This Is The Glasshouse]867Progressive Rock
2025-09-21 18:43:113:38Two-Headed Calf[This Is The Glasshouse]867Progressive Rock
2025-09-21 18:39:336:257Bass / Lorne[This Is The Glasshouse]867Progressive Rock
2025-09-21 18:33:079:51January[This Is The Glasshouse]867Progressive Rock
2025-09-21 18:23:153:39Southpaw[This Is The Glasshouse]867Progressive Rock
2025-09-21 18:19:368:37Before Machinery[This Is The Glasshouse]867Progressive Rock
2025-09-21 18:10:585:36Streetlight by Streetlight[This Is The Glasshouse]867Progressive Rock
2025-09-21 18:05:210:17Streetlight by Streetlight[This Is The Glasshouse]867Progressive Rock
2025-09-21 15:00:220:02Before Machinery[This Is The Glasshouse]867Progressive Rock
2025-09-21 15:00:125:36Streetlight by Streetlight[This Is The Glasshouse]867Progressive Rock
2025-09-21 02:29:430:24The Diary of Jane[Breaking Benjamin]PhobiaRock
2025-09-21 02:29:201:13Intro[Breaking Benjamin]PhobiaRock
2025-09-21 01:23:282:00The Diary of Jane[Breaking Benjamin]PhobiaRock
2025-09-20 19:51:540:05Chapter X[Sufferer]SuffererPost-Hardcore
2025-09-20 19:51:410:01Chapter IX[Sufferer]SuffererPost-Hardcore
2025-09-20 19:51:390:01Chapter VIII[Sufferer]SuffererPost-Hardcore
2025-09-20 19:51:380:01Chapter VII[Sufferer]SuffererPost-Hardcore
2025-09-20 19:51:360:01Chapter VI[Sufferer]SuffererPost-Hardcore
2025-09-20 19:51:350:01Chapter V[Sufferer]SuffererPost-Hardcore
2025-09-20 19:51:330:01Chapter IV[Sufferer]SuffererPost-Hardcore
2025-09-20 19:51:320:01Chapter III[Sufferer]SuffererPost-Hardcore
2025-09-20 19:51:300:01Chapter II[Sufferer]SuffererPost-Hardcore
2025-09-20 19:51:290:02Chapter I[Sufferer]SuffererPost-Hardcore
-
- - -

Top Genres

-
-
- - - - - - - - - - - - - - - - - - -Progressive Rock -Alternative -Post-Rock -Post-Hardcore -Post-Metal -Rock -Shoegaze -Progressive Metal - - -
-
    - -
  1. Progressive Rock: 5:09:49 (64.8%) - -
  2. Alternative: 1:07:16 (14.1%) - -
  3. Post-Rock: 51:41 (10.8%) - -
  4. Post-Hardcore: 37:09 (7.8%) - -
  5. Post-Metal: 4:09 (0.9%) - -
  6. Rock: 3:39 (0.8%) - -
  7. Shoegaze: 2:17 (0.5%) - -
  8. Progressive Metal: 1:47 (0.4%) - -
-
- - -

Top Albums

-
    -
  1. -
    - - 🖸 Act II: The Meaning of, & All Things Regarding Ms. Leading - 👤 The Dear Hunter - ⏱ 1:25:26 -
    -
  2. - -
  3. -
    - - 🖸 867 - 🫏 This Is The Glasshouse - ⏱ 1:14:56 -
    -
  4. - -
  5. -
    - - 🖸 Twin Fantasy - 👤 Car Seat Headrest - ⏱ 1:07:16 -
    -
  6. - -
  7. -
    - - 🖸 Act III: Life and Death - 👤 The Dear Hunter - ⏱ 57:51 -
    -
  8. - -
  9. -
    - - 🖸 In Keeping Secrets of Silent Earth: 3 - 👤 Coheed and Cambria - ⏱ 51:36 -
    -
  10. - -
  11. -
    - - 🖸 Act I: The Lake South, the River North - 👤 The Dear Hunter - ⏱ 38:38 -
    -
  12. - -
  13. -
    - - 🖸 Sufferer - 👤 Sufferer - ⏱ 37:09 -
    -
  14. - -
  15. -
    - - 🖸 Tales of the Night Forest - 👤 Black Hill & Silent Island - ⏱ 34:13 -
    -
  16. - -
  17. -
    - - 🖸 Lift Your Skinny Fists Like Antennas to Heaven - 👤 Godspeed You! Black Emperor - ⏱ 12:26 -
    -
  18. - -
  19. -
    - - 🖸 A Single Flower - 👤 We Lost the Sea - ⏱ 5:01 -
    -
  20. - -
- - -

Top Artists

-
    -
  1. - The Dear Hunter: 3:01:57 -
  2. - -
  3. - This Is The Glasshouse: 1:14:56 -
  4. - -
  5. - Car Seat Headrest: 1:07:16 -
  6. - -
  7. - Coheed and Cambria: 52:55 -
  8. - -
  9. - Sufferer: 37:09 -
  10. - -
  11. - Black Hill & Silent Island: 34:13 -
  12. - -
  13. - Godspeed You Black Emperor!: 12:26 -
  14. - -
  15. - We Lost the Sea: 5:01 -
  16. - -
  17. - Breaking Benjamin: 3:39 -
  18. - -
  19. - Harakiri for the Sky: 3:26 -
  20. - -
- - - - \ No newline at end of file diff --git a/static/98.css b/static/98.css new file mode 100644 index 0000000..8012d93 --- /dev/null +++ b/static/98.css @@ -0,0 +1,1040 @@ +/*! 98.css v0.1.21 - https://github.com/jdan/98.css */ +/** + * 98.css + * Copyright (c) 2020 Jordan Scales + * https://github.com/jdan/98.css/blob/main/LICENSE + */ + +@font-face { + font-family: unifont; + src: url("/assets/UnifontExMono.woff2"); +} + +:root { + /* Color */ + --text-color: var(--fg); + --surface: var(--bg2); + --button-highlight: var(--bg4); + --button-face: var(--bg3); + --button-shadow: var(--bg-dim); + --window-frame: #0a0a0a; + --dialog-blue: var(--bg-blue); + --dialog-blue-light: var(--blue); + --dialog-gray: #808080; + --dialog-gray-light: #b5b5b5; + --link-blue: var(--blue); + + /* Spacing */ + --element-spacing: 8px; + --grouped-button-spacing: 4px; + --grouped-element-spacing: 6px; + --radio-width: 12px; + --checkbox-width: 13px; + --radio-label-spacing: 6px; + --range-track-height: 4px; + --range-spacing: 10px; + + /* Some detailed computations for radio buttons and checkboxes */ + --radio-total-width-precalc: var(--radio-width) + var(--radio-label-spacing); + --radio-total-width: calc(var(--radio-total-width-precalc)); + --radio-left: calc(-1 * var(--radio-total-width-precalc)); + --radio-dot-width: 4px; + --radio-dot-top: calc(var(--radio-width) / 2 - var(--radio-dot-width) / 2); + --radio-dot-left: calc( + -1 * (var(--radio-total-width-precalc)) + var(--radio-width) / 2 - + var(--radio-dot-width) / 2 + ); + + --checkbox-total-width-precalc: var(--checkbox-width) + + var(--radio-label-spacing); + --checkbox-total-width: calc(var(--checkbox-total-width-precalc)); + --checkbox-left: calc(-1 * var(--checkbox-total-width-precalc)); + --checkmark-width: 7px; + --checkmark-left: 3px; + + /* Borders */ + --border-width: 1px; + --border-raised-outer: + inset -1px -1px var(--window-frame), inset 1px 1px var(--button-highlight); + --border-raised-inner: + inset -2px -2px var(--button-shadow), inset 2px 2px var(--button-face); + --border-sunken-outer: + inset -1px -1px var(--button-highlight), inset 1px 1px var(--window-frame); + --border-sunken-inner: + inset -2px -2px var(--button-face), inset 2px 2px var(--button-shadow); + --default-button-border-raised-outer: + inset -2px -2px var(--window-frame), inset 1px 1px var(--window-frame); + --default-button-border-raised-inner: + inset 2px 2px var(--button-highlight), inset -3px -3px var(--button-shadow), + inset 3px 3px var(--button-face); + --default-button-border-sunken-outer: + inset 2px 2px var(--window-frame), inset -1px -1px var(--window-frame); + --default-button-border-sunken-inner: + inset -2px -2px var(--button-highlight), inset 3px 3px var(--button-shadow), + inset -3px -3px var(--button-face); + + /* Window borders flip button-face and button-highlight */ + --border-window-outer: + inset -1px -1px var(--window-frame), inset 1px 1px var(--button-face); + --border-window-inner: + inset -2px -2px var(--button-shadow), inset 2px 2px var(--button-highlight); + + /* Field borders (checkbox, input, etc) flip window-frame and button-shadow */ + --border-field: + inset -1px -1px var(--button-highlight), inset 1px 1px var(--button-shadow), + inset -2px -2px var(--button-face), inset 2px 2px var(--window-frame); + --border-status-field: + inset -1px -1px var(--button-face), inset 1px 1px var(--button-shadow); + + /* Tabs */ + --border-tab: + inset -1px 0 var(--window-frame), inset 1px 1px var(--button-face), + inset -2px 0 var(--button-shadow), inset 2px 2px var(--button-highlight); +} + +@font-face { + font-family: "Pixelated MS Sans Serif"; + src: url("fonts/converted/ms_sans_serif.woff") format("woff"); + src: url("fonts/converted/ms_sans_serif.woff2") format("woff2"); + font-weight: normal; + font-style: normal; +} + +@font-face { + font-family: "Pixelated MS Sans Serif"; + src: url("fonts/converted/ms_sans_serif_bold.woff") format("woff"); + src: url("fonts/converted/ms_sans_serif_bold.woff2") format("woff2"); + font-weight: bold; + font-style: normal; +} + +body { + font-family: unifont; + font-size: 1rem; + color: var(--text-color); +} + +button, +label, +input, +legend, +textarea, +select, +option, +table, +ul.tree-view, +.window, +.title-bar, +li[role="tab"] { + font-family: unifont; + -webkit-font-smoothing: none; + font-size: 1rem; +} + +h1 { + font-size: 2rem; +} + +h2 { + font-size: 1rem; +} + +h3 { + font-size: 1rem; +} + +h4 { + font-size: 1rem; +} + +u { + text-decoration: none; + border-bottom: 0.5px solid #222222; +} + +button, +input[type="submit"], +input[type="reset"] { + box-sizing: border-box; + border: none; + color: transparent; + text-shadow: 0 0 var(--text-color); + background: var(--surface); + box-shadow: var(--border-raised-outer), var(--border-raised-inner); + border-radius: 0; + + min-width: 75px; + min-height: 23px; + padding: 0 12px; +} + +button.default, +input[type="submit"].default, +input[type="reset"].default { + box-shadow: + var(--default-button-border-raised-outer), + var(--default-button-border-raised-inner); +} + +.vertical-bar { + width: 4px; + height: 20px; + background: #c0c0c0; + box-shadow: var(--border-raised-outer), var(--border-raised-inner); +} + +button:not(:disabled):active, +input[type="submit"]:not(:disabled):active, +input[type="reset"]:not(:disabled):active { + box-shadow: var(--border-sunken-outer), var(--border-sunken-inner); + text-shadow: 1px 1px var(--text-color); +} + +button.default:not(:disabled):active, +input[type="submit"].default:not(:disabled):active, +input[type="reset"].default:not(:disabled):active { + box-shadow: + var(--default-button-border-sunken-outer), + var(--default-button-border-sunken-inner); +} + +@media (not(hover)) { + button:not(:disabled):hover, + input[type="submit"]:not(:disabled):hover, + input[type="reset"]:not(:disabled):hover { + box-shadow: var(--border-sunken-outer), var(--border-sunken-inner); + } +} + +button:focus, +input[type="submit"]:focus, +input[type="reset"]:focus { + outline: 1px dotted #000000; + outline-offset: -4px; +} + +button::-moz-focus-inner, +input[type="submit"]::-moz-focus-inner, +input[type="reset"]::-moz-focus-inner { + border: 0; +} + +:disabled, +:disabled + label, +input[readonly], +input[readonly] + label { + color: var(--button-shadow); +} + +button:disabled, +input[type="submit"]:disabled, +input[type="reset"]:disabled, +:disabled + label { + text-shadow: 1px 1px 0 var(--button-highlight); +} + +.window { + box-shadow: var(--border-window-outer), var(--border-window-inner); + background: var(--surface); + padding: 3px; +} + +.title-bar { + background: linear-gradient(90deg, var(--bg0), var(--green)); + padding: 3px 2px 3px 3px; + display: flex; + justify-content: space-between; + align-items: center; +} + +.title-bar.inactive { + background: linear-gradient( + 90deg, + var(--dialog-gray), + var(--dialog-gray-light) + ); +} + +.title-bar-text { + font-weight: bold; + color: var(--fg); + letter-spacing: 0; + margin-right: 24px; +} + +.title-bar-controls { + display: flex; +} + +.title-bar-controls button { + padding: 0; + display: block; + min-width: 16px; + min-height: 14px; +} + +.title-bar-controls button:active { + padding: 0; +} + +.title-bar-controls button:focus { + outline: none; +} + +.title-bar-controls button[aria-label="Minimize"], +.title-bar-controls button[aria-label].minimize { + background-image: url("/assets/icon/minimize.svg"); + background-repeat: no-repeat; + background-position: bottom 3px left 4px; +} + +.title-bar-controls button[aria-label="Maximize"], +.title-bar-controls button[aria-label].maximize { + background-image: url("/assets/icon/maximize.svg"); + background-repeat: no-repeat; + background-position: top 2px left 3px; +} + +.title-bar-controls button[aria-label="Maximize"]:disabled, +.title-bar-controls button[aria-label].maximize:disabled { + background-image: url("/assets/icon/maximize-disabled.svg"); + background-repeat: no-repeat; + background-position: top 2px left 3px; +} + +.title-bar-controls button[aria-label="Restore"], +.title-bar-controls button[aria-label].restore { + background-image: url("/assets/icon/restore.svg"); + background-repeat: no-repeat; + background-position: top 2px left 3px; +} + +.title-bar-controls button[aria-label="Help"], +.title-bar-controls button[aria-label].help { + background-image: url("/assets/icon/help.svg"); + background-repeat: no-repeat; + background-position: top 2px left 5px; +} + +.title-bar-controls button[aria-label="Close"], +.title-bar-controls button[aria-label].close { + margin-left: 2px; + background-image: url("/assets/icon/close.svg"); + background-repeat: no-repeat; + background-position: top 3px left 4px; +} + +.status-bar { + margin: 0px 1px; + display: flex; + gap: 1px; +} + +.status-bar-field { + box-shadow: var(--border-status-field); + flex-grow: 1; + padding: 2px 3px; + margin: 0; +} + +.window-body { + margin: var(--element-spacing); +} + +fieldset { + border-image: url("/assets/icon/groupbox-border.svg") 2; + padding: calc(2 * var(--border-width) + var(--element-spacing)); + padding-block-start: var(--element-spacing); + margin: 0; +} + +legend { + background: var(--surface); +} + +.field-row { + display: flex; + align-items: center; +} + +[class^="field-row"] + [class^="field-row"] { + margin-top: var(--grouped-element-spacing); +} + +.field-row > * + * { + margin-left: var(--grouped-element-spacing); +} + +.field-row-stacked { + display: flex; + flex-direction: column; +} + +.field-row-stacked * + * { + margin-top: var(--grouped-element-spacing); +} + +label { + display: inline-flex; + align-items: center; + user-select: none; +} + +input[type="radio"], +input[type="checkbox"] { + appearance: none; + -webkit-appearance: none; + -moz-appearance: none; + margin: 0; + background: 0; + position: fixed; + opacity: 0; + border: none; +} + +input[type="radio"] + label, +input[type="checkbox"] + label { + line-height: 13px; +} + +input[type="radio"] + label { + position: relative; + margin-left: var(--radio-total-width); +} + +input[type="radio"] + label::before { + content: ""; + position: absolute; + top: 0; + left: calc(-1 * (var(--radio-total-width-precalc))); + display: inline-block; + width: var(--radio-width); + height: var(--radio-width); + margin-right: var(--radio-label-spacing); + background: url("/assets/icon/radio-border.svg"); +} + +input[type="radio"]:active + label::before { + background: url("/assets/icon/radio-border-disabled.svg"); +} + +input[type="radio"]:checked + label::after { + content: ""; + display: block; + width: var(--radio-dot-width); + height: var(--radio-dot-width); + top: var(--radio-dot-top); + left: var(--radio-dot-left); + position: absolute; + background: url("/assets/icon/radio-dot.svg"); +} + +input[type="radio"]:focus + label, +input[type="checkbox"]:focus + label { + outline: 1px dotted #000000; +} + +input[type="radio"][disabled] + label::before { + background: url("/assets/icon/radio-border-disabled.svg"); +} + +input[type="radio"][disabled]:checked + label::after { + background: url("/assets/icon/radio-dot-disabled.svg"); +} + +input[type="checkbox"] + label { + position: relative; + margin-left: var(--checkbox-total-width); +} + +input[type="checkbox"] + label::before { + content: ""; + position: absolute; + left: calc(-1 * (var(--checkbox-total-width-precalc))); + display: inline-block; + width: var(--checkbox-width); + height: var(--checkbox-width); + background: var(--button-highlight); + box-shadow: var(--border-field); + margin-right: var(--radio-label-spacing); +} + +input[type="checkbox"]:active + label::before { + background: var(--surface); +} + +input[type="checkbox"]:checked + label::after { + content: ""; + display: block; + width: var(--checkmark-width); + height: var(--checkmark-width); + position: absolute; + left: calc( + -1 * (var(--checkbox-total-width-precalc)) + var(--checkmark-left) + ); + background: url("/assets/icon/checkmark.svg"); +} + +input[type="checkbox"][disabled] + label::before { + background: var(--surface); +} + +input[type="checkbox"][disabled]:checked + label::after { + background: url("/assets/icon/checkmark-disabled.svg"); +} + +input[type="text"], +input[type="password"], +input[type="email"], +input[type="url"], +input[type="tel"], +input[type="number"], +input[type="search"], +select, +textarea { + padding: 3px 4px; + border: none; + box-shadow: var(--border-field); + background-color: var(--button-highlight); + box-sizing: border-box; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + border-radius: 0; +} + +input[type="text"], +input[type="password"], +input[type="email"], +input[type="url"], +input[type="tel"], +input[type="search"], +select { + height: 21px; +} +input[type="number"] { + /* need this 1 pixel to fit the spinner controls in box */ + height: 22px; +} +/* clears the ‘X’ from Internet Explorer */ +input[type="search"]::-ms-clear { + display: none; + width: 0; + height: 0; +} +input[type="search"]::-ms-reveal { + display: none; + width: 0; + height: 0; +} +/* clears the ‘X’ from Chrome */ +input[type="search"]::-webkit-search-decoration, +input[type="search"]::-webkit-search-cancel-button, +input[type="search"]::-webkit-search-results-button, +input[type="search"]::-webkit-search-results-decoration { + display: none; +} + +input[type="text"], +input[type="password"], +input[type="email"], +input[type="url"], +input[type="tel"], +input[type="number"], +input[type="search"] { + /* For some reason descenders are getting cut off without this */ + line-height: 2; +} + +input[type="email"]:disabled, +input[type="url"]:disabled, +input[type="tel"]:disabled, +input[type="password"]:disabled, +input[type="text"]:disabled, +input[type="number"]:disabled, +input[type="search"]:disabled, +input[type="email"]:read-only, +input[type="url"]:read-only, +input[type="tel"]:read-only, +input[type="password"]:read-only, +input[type="text"]:read-only, +input[type="number"]:read-only, +input[type="search"]:read-only, +textarea:disabled { + background-color: var(--surface); +} + +select { + appearance: none; + -webkit-appearance: none; + -moz-appearance: none; + position: relative; + padding-right: 32px; + background-image: url("/assets/icon/button-down.svg"); + background-position: top 2px right 2px; + background-repeat: no-repeat; + border-radius: 0; +} + +select:focus, +input[type="text"]:focus, +input[type="password"]:focus, +input[type="email"]:focus, +input[type="url"]:focus, +input[type="tel"]:focus, +input[type="number"]:focus, +input[type="search"]:focus, +textarea:focus { + outline: none; +} + +input[type="range"] { + -webkit-appearance: none; + width: 100%; + background: transparent; +} + +input[type="range"]:focus { + outline: none; +} + +input[type="range"]::-webkit-slider-thumb { + -webkit-appearance: none; + height: 21px; + width: 11px; + background: url("/assets/icon/indicator-horizontal.svg"); + transform: translateY(-8px); + box-shadow: none; + border: none; +} + +input[type="range"].has-box-indicator::-webkit-slider-thumb { + background: url("/assets/icon/indicator-rectangle-horizontal.svg"); + transform: translateY(-10px); +} + +input[type="range"]::-moz-range-thumb { + height: 21px; + width: 11px; + border: 0; + border-radius: 0; + background: url("/assets/icon/indicator-horizontal.svg"); + transform: translateY(2px); +} + +input[type="range"].has-box-indicator::-moz-range-thumb { + background: url("/assets/icon/indicator-rectangle-horizontal.svg"); + transform: translateY(0px); +} + +input[type="range"]::-webkit-slider-runnable-track { + width: 100%; + height: 2px; + box-sizing: border-box; + background: black; + border-right: 1px solid grey; + border-bottom: 1px solid grey; + box-shadow: + 1px 0 0 white, + 1px 1px 0 white, + 0 1px 0 white, + -1px 0 0 darkgrey, + -1px -1px 0 darkgrey, + 0 -1px 0 darkgrey, + -1px 1px 0 white, + 1px -1px darkgrey; +} + +input[type="range"]::-moz-range-track { + width: 100%; + height: 2px; + box-sizing: border-box; + background: black; + border-right: 1px solid grey; + border-bottom: 1px solid grey; + box-shadow: + 1px 0 0 white, + 1px 1px 0 white, + 0 1px 0 white, + -1px 0 0 darkgrey, + -1px -1px 0 darkgrey, + 0 -1px 0 darkgrey, + -1px 1px 0 white, + 1px -1px darkgrey; +} + +.is-vertical { + display: inline-block; + width: 4px; + height: 150px; + transform: translateY(50%); +} + +.is-vertical > input[type="range"] { + width: 150px; + height: 4px; + margin: 0 calc(var(--grouped-element-spacing) + var(--range-spacing)) 0 + var(--range-spacing); + transform-origin: left; + transform: rotate(270deg) translateX(calc(-50% + var(--element-spacing))); +} + +.is-vertical > input[type="range"]::-webkit-slider-runnable-track { + border-left: 1px solid grey; + border-right: 0; + border-bottom: 1px solid grey; + box-shadow: + -1px 0 0 white, + -1px 1px 0 white, + 0 1px 0 white, + 1px 0 0 darkgrey, + 1px -1px 0 darkgrey, + 0 -1px 0 darkgrey, + 1px 1px 0 white, + -1px -1px darkgrey; +} + +.is-vertical > input[type="range"]::-moz-range-track { + border-left: 1px solid grey; + border-right: 0; + border-bottom: 1px solid grey; + box-shadow: + -1px 0 0 white, + -1px 1px 0 white, + 0 1px 0 white, + 1px 0 0 darkgrey, + 1px -1px 0 darkgrey, + 0 -1px 0 darkgrey, + 1px 1px 0 white, + -1px -1px darkgrey; +} + +.is-vertical > input[type="range"]::-webkit-slider-thumb { + transform: translateY(-8px) scaleX(-1); +} + +.is-vertical > input[type="range"].has-box-indicator::-webkit-slider-thumb { + transform: translateY(-10px) scaleX(-1); +} + +.is-vertical > input[type="range"]::-moz-range-thumb { + transform: translateY(2px) scaleX(-1); +} + +.is-vertical > input[type="range"].has-box-indicator::-moz-range-thumb { + transform: translateY(0px) scaleX(-1); +} + +select:focus { + color: var(--button-highlight); + background-color: var(--dialog-blue); +} +select:focus option { + color: #000; + background-color: #fff; +} + +select:active { + background-image: url("/assets/icon/button-down-active.svg"); +} + +a { + color: var(--link-blue); +} + +a:focus { + outline: 1px dotted var(--link-blue); +} + +ul.tree-view { + display: block; + background: var(--button-highlight); + /* box-shadow: var(--border-field); */ + padding: 6px; + margin: 0; +} + +ul.tree-view li { + list-style-type: none; +} + +ul.tree-view a { + text-decoration: none; + color: var(--blue); +} + +ul.tree-view a:focus { + background-color: var(--dialog-blue); + color: var(--button-highlight); +} + +ul.tree-view ul, +ul.tree-view li { + margin-top: 3px; +} + +ul.tree-view ul { + margin-left: 16px; + padding-left: 16px; + /* Goes down too far */ + border-left: 1px dotted #808080; +} + +ul.tree-view ul > li { + position: relative; +} +ul.tree-view ul > li::before { + content: ""; + display: block; + position: absolute; + left: -16px; + top: 6px; + width: 12px; + border-bottom: 1px dotted #808080; +} + +/* Cover the bottom of the left dotted border */ +ul.tree-view ul > li:last-child::after { + content: ""; + display: block; + position: absolute; + left: -20px; + top: 7px; + bottom: 0px; + width: 8px; + background: var(--button-highlight); +} + +ul.tree-view details { + margin-top: 0; +} + +ul.tree-view details[open] summary { + margin-bottom: 0; +} + +ul.tree-view ul details > summary:before { + margin-left: -22px; + position: relative; + z-index: 1; +} + +ul.tree-view details > summary:before { + text-align: center; + display: block; + float: left; + content: "+"; + border: 1px solid var(--bg5); + width: 11px; + height: 11px; + line-height: 10px; + margin-right: 5px; + background-color: var(--bg1); +} + +ul.tree-view details[open] > summary:before { + content: "-"; +} + +ul.tree-view details > summary::marker, +ul.tree-view details > summary::-webkit-details-marker { + content: ""; +} + +pre { + display: block; + background: var(--button-highlight); + box-shadow: var(--border-field); + padding: 12px 8px; + margin: 0; +} + +code, +code * { + font-family: monospace; +} + +summary:focus { + outline: 1px dotted #000000; +} + +::-webkit-scrollbar { + width: 16px; +} +::-webkit-scrollbar:horizontal { + height: 17px; +} + +::-webkit-scrollbar-corner { + background: var(--button-face); +} + +::-webkit-scrollbar-track { + background-image: url("/assets/icon/scrollbar-background.svg"); +} + +::-webkit-scrollbar-thumb { + background-color: var(--button-face); + box-shadow: var(--border-raised-outer), var(--border-raised-inner); +} + +::-webkit-scrollbar-button:horizontal:start:decrement, +::-webkit-scrollbar-button:horizontal:end:increment, +::-webkit-scrollbar-button:vertical:start:decrement, +::-webkit-scrollbar-button:vertical:end:increment { + display: block; +} + +::-webkit-scrollbar-button:vertical:start { + height: 17px; + background-image: url("/assets/icon/button-up.svg"); +} +::-webkit-scrollbar-button:vertical:end { + height: 17px; + background-image: url("/assets/icon/button-down.svg"); +} +::-webkit-scrollbar-button:horizontal:start { + width: 16px; + background-image: url("/assets/icon/button-left.svg"); +} +::-webkit-scrollbar-button:horizontal:end { + width: 16px; + background-image: url("/assets/icon/button-right.svg"); +} + +.window[role="tabpanel"] { + position: relative; + z-index: 2; +} + +menu[role="tablist"] { + position: relative; + margin: 0 0 -2px 0; + text-indent: 0; + list-style-type: none; + display: flex; + padding-left: 3px; +} + +menu[role="tablist"] > li { + border-top-left-radius: 3px; + border-top-right-radius: 3px; + box-shadow: var(--border-tab); + z-index: 1; +} + +menu[role="tablist"] > li[aria-selected="true"] { + padding-bottom: 2px; + margin-top: -2px; + background-color: var(--surface); + position: relative; + z-index: 8; + margin-left: -3px; +} + +menu[role="tablist"] > li > a { + display: block; + color: #222; + margin: 6px; + text-decoration: none; +} +menu[role="tablist"] > li[aria-selected="true"] > a:focus { + outline: none; +} +menu[role="tablist"] > li > a:focus { + outline: 1px dotted #222; +} + +menu[role="tablist"].multirows > li { + flex-grow: 1; + text-align: center; +} +.sunken-panel { + box-sizing: border-box; + border: 2px groove transparent; + border-image: url("/assets/icon/sunken-panel-border.svg") 2; + overflow: auto; + background-color: #fff; +} + +table { + border-collapse: collapse; + position: relative; + text-align: left; + white-space: nowrap; + background-color: var(--bg0); +} + +table > thead > tr > * { + position: sticky; + top: 0; + height: 17px; + box-shadow: var(--border-raised-outer), var(--border-raised-inner); + background: var(--surface); + box-sizing: border-box; + font-weight: normal; + padding: 0 var(--grouped-element-spacing); +} + +table.interactive > tbody > tr { + cursor: pointer; +} + +table > tbody > tr.highlighted { + color: #fff; + background-color: var(--dialog-blue); +} + +table > tbody > tr > * { + padding: 0 var(--grouped-element-spacing); + height: 14px; +} + +.progress-indicator { + height: 32px; + position: relative; + box-shadow: var(--border-sunken-inner); + padding: 4px 4px; + border: none; + box-sizing: border-box; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + border-radius: 0; +} + +.progress-indicator > .progress-indicator-bar { + height: 100%; + display: block; + background-color: var(--dialog-blue); +} + +.progress-indicator.segmented > .progress-indicator-bar { + width: 100%; + background-color: transparent; /* resets the background color which is set to blue in the non-segmented selector */ + background-image: linear-gradient( + 90deg, + var(--dialog-blue) 0 16px, + transparent 0 2px + ); + background-repeat: repeat; + background-size: 18px 100%; +} + +.field-border { + background: var(--button-highlight); + box-shadow: var(--border-field); + padding: 2px; +} + +.field-border-disabled { + background: var(--surface); + box-shadow: var(--border-field); + padding: 2px; +} + +.status-field-border { + background: var(--surface); + box-shadow: var(--border-status-field); + padding: 1px; +} diff --git a/static/assets/UnifontExMono.woff2 b/static/assets/UnifontExMono.woff2 new file mode 100644 index 0000000..e7db71a Binary files /dev/null and b/static/assets/UnifontExMono.woff2 differ diff --git a/static/assets/badges/cookies.png b/static/assets/badges/cookies.png new file mode 100644 index 0000000..70994a7 Binary files /dev/null and b/static/assets/badges/cookies.png differ diff --git a/static/assets/badges/go2hell.gif b/static/assets/badges/go2hell.gif new file mode 100644 index 0000000..7f1290a Binary files /dev/null and b/static/assets/badges/go2hell.gif differ diff --git a/static/assets/badges/indieweb.png b/static/assets/badges/indieweb.png new file mode 100644 index 0000000..a241947 Binary files /dev/null and b/static/assets/badges/indieweb.png differ diff --git a/static/assets/badges/javascript.png b/static/assets/badges/javascript.png new file mode 100644 index 0000000..7ad573f Binary files /dev/null and b/static/assets/badges/javascript.png differ diff --git a/static/assets/badges/lynx.gif b/static/assets/badges/lynx.gif new file mode 100644 index 0000000..452ac5e Binary files /dev/null and b/static/assets/badges/lynx.gif differ diff --git a/static/assets/badges/midi_files_now.gif b/static/assets/badges/midi_files_now.gif new file mode 100644 index 0000000..18a2422 Binary files /dev/null and b/static/assets/badges/midi_files_now.gif differ diff --git a/static/assets/badges/powered-by-debian.gif b/static/assets/badges/powered-by-debian.gif new file mode 100644 index 0000000..1f617c8 Binary files /dev/null and b/static/assets/badges/powered-by-debian.gif differ diff --git a/static/assets/badges/soaos.png b/static/assets/badges/soaos.png new file mode 100644 index 0000000..486af90 Binary files /dev/null and b/static/assets/badges/soaos.png differ diff --git a/static/assets/bg.jpg b/static/assets/bg.jpg new file mode 100644 index 0000000..4e9044c Binary files /dev/null and b/static/assets/bg.jpg differ diff --git a/static/assets/construction.gif b/static/assets/construction.gif new file mode 100644 index 0000000..b9c4eeb Binary files /dev/null and b/static/assets/construction.gif differ diff --git a/static/assets/icon/button-down-active.svg b/static/assets/icon/button-down-active.svg new file mode 100644 index 0000000..fa7cac1 --- /dev/null +++ b/static/assets/icon/button-down-active.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/static/assets/icon/button-down.svg b/static/assets/icon/button-down.svg new file mode 100644 index 0000000..7bbaa80 --- /dev/null +++ b/static/assets/icon/button-down.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/static/assets/icon/button-left.svg b/static/assets/icon/button-left.svg new file mode 100644 index 0000000..80421a1 --- /dev/null +++ b/static/assets/icon/button-left.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/static/assets/icon/button-right.svg b/static/assets/icon/button-right.svg new file mode 100644 index 0000000..5573fe0 --- /dev/null +++ b/static/assets/icon/button-right.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/static/assets/icon/button-up.svg b/static/assets/icon/button-up.svg new file mode 100644 index 0000000..4b25846 --- /dev/null +++ b/static/assets/icon/button-up.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/static/assets/icon/checkmark-disabled.svg b/static/assets/icon/checkmark-disabled.svg new file mode 100644 index 0000000..f9d34b9 --- /dev/null +++ b/static/assets/icon/checkmark-disabled.svg @@ -0,0 +1,3 @@ + + + diff --git a/static/assets/icon/checkmark.svg b/static/assets/icon/checkmark.svg new file mode 100644 index 0000000..297996a --- /dev/null +++ b/static/assets/icon/checkmark.svg @@ -0,0 +1,3 @@ + + + diff --git a/static/assets/icon/close.svg b/static/assets/icon/close.svg new file mode 100644 index 0000000..9b426f5 --- /dev/null +++ b/static/assets/icon/close.svg @@ -0,0 +1,3 @@ + + + diff --git a/static/assets/icon/groupbox-border.svg b/static/assets/icon/groupbox-border.svg new file mode 100644 index 0000000..a205da9 --- /dev/null +++ b/static/assets/icon/groupbox-border.svg @@ -0,0 +1,4 @@ + + + + diff --git a/static/assets/icon/help.svg b/static/assets/icon/help.svg new file mode 100644 index 0000000..f7a5c07 --- /dev/null +++ b/static/assets/icon/help.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/static/assets/icon/indicator-horizontal.svg b/static/assets/icon/indicator-horizontal.svg new file mode 100644 index 0000000..026baf5 --- /dev/null +++ b/static/assets/icon/indicator-horizontal.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/static/assets/icon/indicator-rectangle-horizontal.svg b/static/assets/icon/indicator-rectangle-horizontal.svg new file mode 100644 index 0000000..9bbfb58 --- /dev/null +++ b/static/assets/icon/indicator-rectangle-horizontal.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/static/assets/icon/maximize-disabled.svg b/static/assets/icon/maximize-disabled.svg new file mode 100644 index 0000000..34c7ff9 --- /dev/null +++ b/static/assets/icon/maximize-disabled.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/static/assets/icon/maximize.svg b/static/assets/icon/maximize.svg new file mode 100644 index 0000000..19f8b09 --- /dev/null +++ b/static/assets/icon/maximize.svg @@ -0,0 +1,3 @@ + + + diff --git a/static/assets/icon/minimize.svg b/static/assets/icon/minimize.svg new file mode 100644 index 0000000..6231e4c --- /dev/null +++ b/static/assets/icon/minimize.svg @@ -0,0 +1,3 @@ + + + diff --git a/static/assets/icon/radio-border-disabled.svg b/static/assets/icon/radio-border-disabled.svg new file mode 100644 index 0000000..c53fa15 --- /dev/null +++ b/static/assets/icon/radio-border-disabled.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/static/assets/icon/radio-border.svg b/static/assets/icon/radio-border.svg new file mode 100644 index 0000000..e70978e --- /dev/null +++ b/static/assets/icon/radio-border.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/static/assets/icon/radio-dot-disabled.svg b/static/assets/icon/radio-dot-disabled.svg new file mode 100644 index 0000000..e1a76fc --- /dev/null +++ b/static/assets/icon/radio-dot-disabled.svg @@ -0,0 +1,3 @@ + + + diff --git a/static/assets/icon/radio-dot.svg b/static/assets/icon/radio-dot.svg new file mode 100644 index 0000000..f19e1b8 --- /dev/null +++ b/static/assets/icon/radio-dot.svg @@ -0,0 +1,3 @@ + + + diff --git a/static/assets/icon/restore.svg b/static/assets/icon/restore.svg new file mode 100644 index 0000000..bd8fe15 --- /dev/null +++ b/static/assets/icon/restore.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/static/assets/icon/scrollbar-background.svg b/static/assets/icon/scrollbar-background.svg new file mode 100644 index 0000000..04b2f59 --- /dev/null +++ b/static/assets/icon/scrollbar-background.svg @@ -0,0 +1,4 @@ + + + + diff --git a/static/assets/icon/sunken-panel-border.svg b/static/assets/icon/sunken-panel-border.svg new file mode 100644 index 0000000..c13e8ce --- /dev/null +++ b/static/assets/icon/sunken-panel-border.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/static/favicon.png b/static/favicon.png new file mode 100644 index 0000000..fac014b Binary files /dev/null and b/static/favicon.png differ diff --git a/static/hell.css b/static/hell.css new file mode 100644 index 0000000..572f3d1 --- /dev/null +++ b/static/hell.css @@ -0,0 +1,102 @@ +html { + background: url("/hell/bg.jpg"); + background-attachment: fixed; + background-size: cover; + image-rendering: pixelated; +} + +body { + margin: auto 0; + max-width: unset; + margin-right: auto; +} + +@keyframes fire { + 0% { + text-shadow: + 0 0 20px #fefcc9, + 10px -10px 30px #feec85, + -20px -20px 40px #ffae34, + 20px -40px 50px #ec760c, + -20px -60px 60px #cd4606, + 0 -80px 70px #973716, + 10px -90px 80px #451b0e; + } + 100% { + text-shadow: + 0 0 20px #fefcc9, + 10px -10px 30px #fefcc9, + -20px -20px 40px #feec85, + 22px -42px 60px #ffae34, + -22px -58px 50px #ec760c, + 0 -82px 80px #cd4606, + 10px -90px 80px #973716; + } +} + +.hellfire { + color: var(--orange); + animation: fire 1s ease-in-out infinite alternate; +} + +massive-fucking-background-flame { + width: 100%; + height: 100%; + position: fixed; + top: 0; + left: 0; + z-index: -999; + background-image: url("/hell/smallfire.gif"); + background-size: auto 128px; + opacity: 0.25; + --pan: 0 -128px; + animation: pan linear 3s infinite; +} + +a { + color: black; +} + +#inverted-cross { + display: inline-block; + rotate: 180deg; + transition: + rotate 2s, + color 0.5s; + --glow-color: red; + animation: glow 4s linear infinite; +} + +#inverted-cross:hover { + rotate: 0deg; + --glow-color: white; + color: var(--yellow); + transition: + rotate 2s, + color 1s; +} + +.evil { + color: black; +} + +.huge { + font-size: 8rem; +} + +.struck { + opacity: 0.5; + position: absolute; + left: 0; + z-index: -999; + user-select: none; +} + +@keyframes pan { + from { + background-position: 0 0; + } + to { + background-position: var(--pan); + } +} diff --git a/static/index.css b/static/index.css new file mode 100644 index 0000000..9ae6d1e --- /dev/null +++ b/static/index.css @@ -0,0 +1,27 @@ +.section { + background-color: var(--bg1); +} + +html { + background: url("/assets/bg.jpg"); + background-attachment: fixed; + background-size: cover; + image-rendering: pixelated; +} + +#weird-fucking-header-container { + display: inline-grid; + grid-template-columns: 1fr; + grid-template-rows: 1fr; +} + +.whatever { + grid-area: 1 / 1 / 2 / 2; +} + +#badge-grid { + display: inline-grid; + grid-template-columns: 1fr 1fr 1fr; + gap: 4px; +} + diff --git a/static/style.css b/static/style.css new file mode 100644 index 0000000..b4c788a --- /dev/null +++ b/static/style.css @@ -0,0 +1,184 @@ +:root { + --red: #e67e80; + --orange: #e69875; + --yellow: #dbbc7f; + --green: #a7c080; + --blue: #7fbbb3; + --aqua: #83c092; + --purple: #d699b6; + --fg: #d3c6aa; + --statusline1: #a7c080; + --statusline2: #d3c6aa; + --statusline3: #e67e80; + --gray0: #7a8478; + --gray1: #859289; + --gray2: #9da9a0; + + --bg-dim: #232a2e; + --bg0: #2d353b; + --bg1: #343f44; + --bg2: #3d484d; + --bg3: #475258; + --bg4: #4f585e; + --bg5: #56635f; + --bg-red: #4c3743; + --bg-visual: #493b40; + --bg-yellow: #45443c; + --bg-green: #3c4841; + --bg-blue: #384b55; +} + +html { + background: url("/assets/bg.jpg"); + background-attachment: fixed; + background-size: cover; + image-rendering: pixelated; +} + +a:not(:has(img, div))[target="_blank"]::after { + content: " ⎘"; +} + +a:not(:has(img,div))[href^="https://tv.soaos.dev/w/"]::before +{ + content: "📺 "; +} + +ul { + list-style-type: "• "; +} + +pre { + overflow: auto; +} + +@keyframes blinker { + 50% { + opacity: 0; + } +} + +.under-construction { + color: var(--yellow); + animation: blinker 1s linear infinite; +} + +@keyframes glow { + 50% { + text-shadow: + 0 0 0px var(--glow-color), + 0 0 20px hsl(from var(--glow-color) h s calc(l - 10)); + } +} + +@keyframes glow-box { + 50% { + box-shadow: + 0 0 0px var(--glow-color), + 0 0 20px hsl(from var(--glow-color) h s calc(l - 10)); + } +} + +.evil { + color: var(--red); + --glow-color: red; + animation: glow 4s linear infinite; +} + +.evil-box { + color: var(--red); + --glow-color: red; + animation: glow-box 4s linear infinite; +} + +.holy { + color: var(--yellow); + --glow-color: white; + animation: glow 4s linear infinite; +} + +a.evil:visited { + color: var(--red); +} + +a.evil:hover { + color: red; +} + +.hidden { + display: none; +} + +.no-bullets { + list-style-type: none; + padding-left: 0; + :w; +} + +#badge-grid { + display: flex; + gap: 4px; +} + +.unselectable { + user-select: none; +} + +.window { + margin: 1rem; +} + +.red-on-white { + color: red; + background-color: white; +} + +.centered { + display: flex; + justify-content: center; +} + +body { + margin: auto 0; + max-width: 800px; + margin-right: auto; +} + +[data-tooltip]:hover::after { + content: attr(data-tooltip); + border: 1px solid var(--bg-dim); + background: var(--fg); + color: var(--bg-dim); + display: inline-block; + white-space: pre-wrap; + text-align: left; + padding: 0.3em; + position: absolute; + z-index: 98; +} + +.flip { + position: relative; +} + +.hidden-selectable { + opacity: 0; +} + +.flip::after { + display: inline-block; + position: absolute; + content: attr(data-title); + transform: rotateY(180deg); + clip-path: polygon(0 0, 50.1% 0, 50.1% 100%, 0 100%); + visibility: visible; + left: 0; +} + +.flip::before { + display: inline-block; + position: absolute; + content: attr(data-title); + clip-path: polygon(0 0, 50.1% 0, 50.1% 100%, 0 100%); + visibility: visible; +} diff --git a/static/style.css.bak b/static/style.css.bak new file mode 100644 index 0000000..22815a7 --- /dev/null +++ b/static/style.css.bak @@ -0,0 +1,224 @@ +@font-face { + font-family: unifont; + src: url("/assets/UnifontExMono.woff2"); +} + +:root { + --red: #e67e80; + --orange: #e69875; + --yellow: #dbbc7f; + --green: #a7c080; + --blue: #7fbbb3; + --aqua: #83c092; + --purple: #d699b6; + --fg: #d3c6aa; + --statusline1: #a7c080; + --statusline2: #d3c6aa; + --statusline3: #e67e80; + --gray0: #7a8478; + --gray1: #859289; + --gray2: #9da9a0; + + --bg-dim: #232a2e; + --bg0: #2d353b; + --bg1: #343f44; + --bg2: #3d484d; + --bg3: #475258; + --bg4: #4f585e; + --bg5: #56635f; + --bg-red: #4c3743; + --bg-visual: #493b40; + --bg-yellow: #45443c; + --bg-green: #3c4841; + --bg-blue: #384b55; +} + +body { + font-family: unifont; + font-size: 16px; + color: var(--fg); + perspective-origin: top left; +} + +pre, +code, +samp { + font-family: unifont; +} + +samp { + color: var(--gray2); +} + +.section { + margin: 1rem; + padding: 1rem; +} + +.horizontal-container { + display: flex; + justify-content: space-between; +} + +a { + text-decoration: none; +} + +a:hover { + text-decoration: underline; +} + +h1, +h2, +h3, +h4, +h5, +h6 { + font-weight: normal; + text-decoration: underline; +} + +h1 { + font-size: 48px; +} + +h2 { + font-size: 32px; +} + +h3 { + font-size: 16px; +} + +.centered { + text-align: center; +} + +.center-content { + display: flex; + justify-content: center; +} + +.half { + clip-path: polygon(0 0, 50.1% 0, 50.1% 100%, 0 100%); +} + +.flip-x { + transform: scaleX(-1); +} + +.unselectable { + user-select: none; +} + +@keyframes blinker { + 50% { + opacity: 0; + } +} + +.under-construction { + color: var(--yellow); + animation: blinker 1s linear infinite; +} + +@keyframes glow { + 50% { + text-shadow: + 0 0 10px var(--glow-color), + 0 0 20px var(--glow-color), + 0 0 40px var(--glow-color), + 0 0 80px hsl(from var(--glow-color) h s calc(l - 10)), + 0 0 120px hsl(from var(--glow-color) h s calc(l - 10)); + } +} + +.evil { + color: var(--red); + --glow-color: red; + animation: glow 4s linear infinite; +} + +.holy { + color: var(--yellow); + --glow-color: white; + animation: glow 4s linear infinite; +} + +a.evil:visited { + color: var(--red); +} + +a.evil:hover { + color: red; +} + +.inline-block { + display: inline-block; +} + +.no-bullets { + list-style-type: none; + padding-left: 0; +} + +.red-on-white { + color: red; + background-color: white; +} + +.hidden { + display: none; +} + +.huge { + font-size: 128px; +} + +.struck { + opacity: 0.5; + position: absolute; + z-index: -999; + user-select: none; +} + +@keyframes pan { + from { + background-position: 0 0; + } + to { + background-position: var(--pan); + } +} + +.bold { + font-weight: bold; +} + +.column { + display: flex; + flex-direction: column; + align-items: center; +} + +/* Links */ +a { + color: var(--blue); +} + +a:visited { + color: var(--purple); +} + +a:not(:has(img, div))[target="_blank"]::after { + content: " ⎘"; +} + +a:not(:has(img,div))[href^="https://tv.soaos.dev/w/"]::before +{ + content: "📺 "; +} + +ul { + list-style-type: "• "; +} diff --git a/style.css b/style.css deleted file mode 100644 index a3a4364..0000000 --- a/style.css +++ /dev/null @@ -1,215 +0,0 @@ -@font-face { - font-family: unifont; - src: url("/assets/UnifontExMono.woff2"); -} - -:root { - --red: #e67e80; - --orange: #e69875; - --yellow: #dbbc7f; - --green: #a7c080; - --blue: #7fbbb3; - --aqua: #83c092; - --purple: #d699b6; - --fg: #d3c6aa; - --statusline1: #a7c080; - --statusline2: #d3c6aa; - --statusline3: #e67e80; - --gray0: #7a8478; - --gray1: #859289; - --gray2: #9da9a0; - - --bg-dim: #232a2e; - --bg0: #2d353b; - --bg1: #343f44; - --bg2: #3d484d; - --bg3: #475258; - --bg4: #4f585e; - --bg5: #56635f; - --bg-red: #4c3743; - --bg-visual: #493b40; - --bg-yellow: #45443c; - --bg-green: #3c4841; - --bg-blue: #384b55; -} - -body { - font-family: unifont; - font-size: 16px; - color: var(--fg); - perspective-origin: top left -} - -pre, code, samp { - font-family: unifont; -} - -samp { - color: var(--gray2) -} - -.section { - margin: 1rem; - padding: 1rem; -} - -.horizontal-container { - display: flex; - justify-content: space-between; -} - -a { - text-decoration: none; -} - -a:hover { - text-decoration: underline; -} - -h1, h2, h3, h4, h5, h6 { - font-weight: normal; - text-decoration: underline; -} - -h1 { - font-size: 48px; -} - -h2 { - font-size: 32px; -} - -h3 { - font-size: 16px; -} - -.centered { - text-align: center; -} - -.center-content { - display: flex; - justify-content: center; -} - -.half { - clip-path: polygon(0 0, 50.1% 0, 50.1% 100%, 0 100%); -} - -.flip-x { - transform: scaleX(-1); -} - -.unselectable { - user-select: none; -} - -@keyframes blinker { - 50% { - opacity: 0; - } -} - -.under-construction { - color: var(--yellow); - animation: blinker 1s linear infinite; -} - -@keyframes glow { - 50% { - text-shadow: 0 0 10px var(--glow-color), - 0 0 20px var(--glow-color), - 0 0 40px var(--glow-color), - 0 0 80px hsl(from var(--glow-color) h s calc(l - 10)), - 0 0 120px hsl(from var(--glow-color) h s calc(l - 10)); - } -} - -.evil { - color: var(--red); - --glow-color: red; - animation: glow 4s linear infinite; -} - -.holy { - color: var(--yellow); - --glow-color: white; - animation: glow 4s linear infinite; -} - -a.evil:visited { - color: var(--red); -} - -a.evil:hover { - color: red; -} - -.inline-block { - display: inline-block; -} - -.no-bullets { - list-style-type: none; - padding-left: 0; -} - -.red-on-white { - color: red; - background-color: white; -} - -.hidden { - display: none; -} - -.huge { - font-size: 128px; -} - -.struck { - opacity: 0.5; - position: absolute; - z-index: -999; - user-select: none; -} - -@keyframes pan { - from { - background-position: 0 0; - } - to { - background-position: var(--pan); - } -} - -.bold { - font-weight: bold; -} - -.column { - display: flex; - flex-direction: column; - align-items: center; -} - -/* Links */ -a { - color: var(--blue); -} - -a:visited { - color: var(--purple); -} - -a:not(:has(img,div))[target="_blank"]::after { - content: " ⎘"; -} - -a:not(:has(img,div))[href^="https://tv.soaos.dev/w/"]::before { - content: "📺 "; -} - -ul { - list-style-type: "• "; -} \ No newline at end of file diff --git a/templates/base.html b/templates/base.html new file mode 100644 index 0000000..7af29b7 --- /dev/null +++ b/templates/base.html @@ -0,0 +1,95 @@ +{% import "macros.html" as macros %} + + + + + soaos + + + + + + + +
+
+
+
𐂂 Badass header
+
+
+

+ 𐂂🌲🌲🌲 soaos 🌲🌲🌲𐂂 +

+
+
+
+
{% block content %} {% endblock content %}
+
+
+
🪪 Badges
+
+
+
    +
  • + Javascript-Free Page +
  • +
  • + Lynx Compatible +
  • +
  • + Powered by Debian +
  • +
  • + Go 2 Hell Now! +
  • +
  • + soaos.dev +
  • +
  • + Cookie-Free Page +
  • +
+
+
+

+ █🍁█ +

+

+ + EVILRING + +

+

+ {{ now() }} +

+

+ soaos +

+
+
+ + diff --git a/templates/blog.html b/templates/blog.html new file mode 100644 index 0000000..f659571 --- /dev/null +++ b/templates/blog.html @@ -0,0 +1,38 @@ +{% extends "base.html" %} {% block content %} +
+
+
📖 Blog
+
+ +
+
+
+

+ Welcome to my blog! This is where I'll post longer content about stuff I'm + working on. I'm working out some channels for posting day-to-day short + form shit too so keep an eye out for that. +

+

Latest Posts

+
+
    + {% set current_year = now() | date(format="%Y") | int %} {% for i in + range(start=0, end=current_year - 2024) %} +
  • +
    + {{current_year - i}} +
      + {% for post in section.pages %} {% if post.year == current_year - + i %} +
    • + {{post.title}} - {{post.date}} +
    • + {% endif %} {% endfor %} +
    +
    +
  • + {% endfor %} +
+
+
+
+{% endblock content %} diff --git a/templates/heaven.html b/templates/heaven.html new file mode 100644 index 0000000..93a86ac --- /dev/null +++ b/templates/heaven.html @@ -0,0 +1,29 @@ + + + + + + heaven + + + + + + +
+
+
+ 🕊🕊🕊 + (please enable autoplay to hear music lol) + +
+

😇 GOD BLESS YOU FRIEND... YOU ARE IN HEAVEN! 😇

+
+ YOU ARE LOVED 💖🌹 +
+ + + + diff --git a/templates/hell.html b/templates/hell.html new file mode 100644 index 0000000..d799db3 --- /dev/null +++ b/templates/hell.html @@ -0,0 +1,22 @@ + + + + + hell + + + + + + + + + + {{ section.content | safe }} + + diff --git a/templates/index.html b/templates/index.html new file mode 100644 index 0000000..0bf66d0 --- /dev/null +++ b/templates/index.html @@ -0,0 +1,2 @@ +{% extends "base.html" %} {% block content %} {{ section.content | safe }} {% +endblock content %} diff --git a/templates/macros.html b/templates/macros.html new file mode 100644 index 0000000..eae30fe --- /dev/null +++ b/templates/macros.html @@ -0,0 +1,3 @@ +{% macro post_list() %} {% for post in section.pages %} +{{ post.title }} +{% endfor %} {% endmacro input %} \ No newline at end of file diff --git a/templates/page.html b/templates/page.html new file mode 100644 index 0000000..4cd271b --- /dev/null +++ b/templates/page.html @@ -0,0 +1,2 @@ +{% extends "base.html" %} {% block content %} {{ page.content | safe }} {% +endblock content %} diff --git a/templates/post.html b/templates/post.html new file mode 100644 index 0000000..794c715 --- /dev/null +++ b/templates/post.html @@ -0,0 +1,19 @@ +{% extends "base.html" %} {% block content %} + +
+
+ 📰 Post: {{ page.title }} +
+ + +
+
+
+

{{ page.title }}

+
{{ page.content | safe}}
+
+
+{% endblock content %} diff --git a/templates/section.html b/templates/section.html new file mode 100644 index 0000000..0bf66d0 --- /dev/null +++ b/templates/section.html @@ -0,0 +1,2 @@ +{% extends "base.html" %} {% block content %} {{ section.content | safe }} {% +endblock content %} diff --git a/templates/shortcodes/soaosed.html b/templates/shortcodes/soaosed.html new file mode 100644 index 0000000..c5ae639 --- /dev/null +++ b/templates/shortcodes/soaosed.html @@ -0,0 +1,3 @@ +{{ body }} \ No newline at end of file diff --git a/templates/shortcodes/subtree.html b/templates/shortcodes/subtree.html new file mode 100644 index 0000000..2246718 --- /dev/null +++ b/templates/shortcodes/subtree.html @@ -0,0 +1,8 @@ +
  • +
    + {{ name | safe }} +
      + {{ body | markdown | safe }} +
    +
    +
  • \ No newline at end of file diff --git a/templates/shortcodes/title_bar.html b/templates/shortcodes/title_bar.html new file mode 100644 index 0000000..facc6fb --- /dev/null +++ b/templates/shortcodes/title_bar.html @@ -0,0 +1,8 @@ +
    +
    {{ body | safe }}
    +
    + {% if close %} + + {% endif %} +
    +
    diff --git a/templates/shortcodes/tree_view.html b/templates/shortcodes/tree_view.html new file mode 100644 index 0000000..e8de782 --- /dev/null +++ b/templates/shortcodes/tree_view.html @@ -0,0 +1,5 @@ +
    +
      + {{ body | markdown | safe }} +
    +
    diff --git a/templates/shortcodes/treelink.html b/templates/shortcodes/treelink.html new file mode 100644 index 0000000..ff80fdc --- /dev/null +++ b/templates/shortcodes/treelink.html @@ -0,0 +1,8 @@ +
  • + {{ text }} + {% if wip %} + + + + {% endif %} +
  • \ No newline at end of file diff --git a/templates/shortcodes/window.html b/templates/shortcodes/window.html new file mode 100644 index 0000000..8abddbe --- /dev/null +++ b/templates/shortcodes/window.html @@ -0,0 +1,3 @@ +
    +{{ body | safe }} +
    diff --git a/templates/shortcodes/window_body.html b/templates/shortcodes/window_body.html new file mode 100644 index 0000000..f7c84a7 --- /dev/null +++ b/templates/shortcodes/window_body.html @@ -0,0 +1 @@ +
    {{ body | markdown | safe }}
    diff --git a/things_i_like/music/867.png b/things_i_like/music/867.png deleted file mode 100644 index d416100..0000000 Binary files a/things_i_like/music/867.png and /dev/null differ diff --git a/things_i_like/music/act_ii.jpg b/things_i_like/music/act_ii.jpg deleted file mode 100644 index 97b2e82..0000000 Binary files a/things_i_like/music/act_ii.jpg and /dev/null differ diff --git a/things_i_like/music/apollo.jpg b/things_i_like/music/apollo.jpg deleted file mode 100644 index 9c742ee..0000000 Binary files a/things_i_like/music/apollo.jpg and /dev/null differ diff --git a/things_i_like/music/atebts.jpg b/things_i_like/music/atebts.jpg deleted file mode 100644 index ca68692..0000000 Binary files a/things_i_like/music/atebts.jpg and /dev/null differ diff --git a/things_i_like/music/departure_songs.jpg b/things_i_like/music/departure_songs.jpg deleted file mode 100644 index 2699d5d..0000000 Binary files a/things_i_like/music/departure_songs.jpg and /dev/null differ diff --git a/things_i_like/music/index.html b/things_i_like/music/index.html deleted file mode 100644 index 46ebc1f..0000000 --- a/things_i_like/music/index.html +++ /dev/null @@ -1,77 +0,0 @@ - - - - - Music I Like - soaos - - - - Go Home - Go Back -

    Music I Like

    -

    I might organize this better at some point, but for now there's no particular order to these. I just want to - share - my awful taste with everyone LMAO.

    -

    Albums (Click to Listen on YouTube)

    -

    I only included one album per artist in order to avoid making this list infinitely long LOL. It was difficult for - some of these bands...

    - -
    - Cover art for 867 by This is the Glasshouse -
    This is the Glasshouse - 867
    -
    -
    - -
    - Cover art for wetdream by Willy Rodriguez -
    Willy Rodriguez - wetdream
    -
    -
    - -
    - Cover art for Act II by The Dear Hunter -
    The Dear Hunter - Act II: The Meaning of, and All Things Regarding Ms. Leading
    -
    -
    - -
    - Cover art for Good Apollo, I'm Burning Star IV, Volume One: From Fear Through the Eyes of Madness by Coheed and Cambria -
    Coheed and Cambria - Good Apollo, I'm Burning Star IV, Volume One: From Fear Through the Eyes of - Madness
    -
    -
    - -
    - Cover art for Twin Fantasy by Car Seat Headrest -
    Car Seat Headrest - Twin Fantasy
    -
    -
    - -
    - Cover art for Jiminy by Bear Ghost -
    Bear Ghost - Jiminy
    -
    -
    - -
    - Cover art for Lift Your Skinny Fists Like Antennas to Heaven by Godspeed You! Black Emperor -
    Godspeed You! Black Emperor - Lift Your Skinny Fists Like Antennas to Heaven
    -
    -
    - -
    - Cover art for Departure Songs by We Lost the Sea -
    We Lost the Sea - Departure Songs
    -
    -
    - -
    - Cover art for Above the Earth, Below the Sky by If These Trees Could Talk -
    If These Trees Could Talk - Above the Earth, Below the Sky
    -
    -
    - - - \ No newline at end of file diff --git a/things_i_like/music/jiminy.jpg b/things_i_like/music/jiminy.jpg deleted file mode 100644 index a216de4..0000000 Binary files a/things_i_like/music/jiminy.jpg and /dev/null differ diff --git a/things_i_like/music/lysf.jpg b/things_i_like/music/lysf.jpg deleted file mode 100644 index 8605559..0000000 Binary files a/things_i_like/music/lysf.jpg and /dev/null differ diff --git a/things_i_like/music/twin_fantasy.jpg b/things_i_like/music/twin_fantasy.jpg deleted file mode 100644 index f83e135..0000000 Binary files a/things_i_like/music/twin_fantasy.jpg and /dev/null differ diff --git a/things_i_like/music/wetdream.png b/things_i_like/music/wetdream.png deleted file mode 100644 index 862544c..0000000 Binary files a/things_i_like/music/wetdream.png and /dev/null differ -- cgit v1.2.3