\ No newline at end of file
+404 Page not found - lavafroth
404
\ No newline at end of file
diff --git a/about/index.html b/about/index.html
index 77e91b41..c2c1bc2c 100644
--- a/about/index.html
+++ b/about/index.html
@@ -4,7 +4,7 @@ work. I’m doing a bachelors in data science at IITM.
I’m decent with programming languages like C and Java, the latter of which was
taught in school. I’m great at writing Golang and Rust. I render my YouTube
videos with Python and the manim framework, so I’d argue I’m competent at it
-as well.'>
Hi, this is Himadri!
I’m a self taught programmer and a digital artist. You might have arrived here
+as well.'>
Hi, this is Himadri!
I’m a self taught programmer and a digital artist. You might have arrived here
from my YouTube channel or my open source
work. I’m doing a bachelors in data science at IITM.
I’m decent with programming languages like C and Java, the latter of which was
taught in school. I’m great at writing Golang and Rust. I render my YouTube
diff --git a/art/amateur-blender-sculpture/index.html b/art/amateur-blender-sculpture/index.html
index c1ca5eea..890bf1cf 100644
--- a/art/amateur-blender-sculpture/index.html
+++ b/art/amateur-blender-sculpture/index.html
@@ -2,7 +2,7 @@
quality of the sculpt. I’m still pretty much in the learning stage. Big thank
you to Nichole Sebastian
for the reference photo. Also apologies if the empty eye sockets gave you a
-jumpscare.'>
Aug 3, 2024
Amateur Blender Sculpture
This is my first time trying out sculpting in blender, so forgive me for the
+jumpscare.'>
Aug 3, 2024
Amateur Blender Sculpture
This is my first time trying out sculpting in blender, so forgive me for the
quality of the sculpt. I’m still pretty much in the learning stage. Big thank
you to Nichole Sebastian
for the reference photo. Also apologies if the empty eye sockets gave you a
diff --git a/art/babe/index.html b/art/babe/index.html
index 167a1fac..e89c6e7c 100644
--- a/art/babe/index.html
+++ b/art/babe/index.html
@@ -1 +1 @@
-
Portrait study - lavafroth
Mar 11, 2026
Portrait study
I was playing with the pen pressure settings in Krita and tested it out with a portrait study of my significant other.
\ No newline at end of file
+Portrait study - lavafroth
Mar 11, 2026
Portrait study
I was playing with the pen pressure settings in Krita and tested it out with a portrait study of my significant other.
\ No newline at end of file
diff --git a/art/drawhearts/index.html b/art/drawhearts/index.html
index 3fafef73..77ffb526 100644
--- a/art/drawhearts/index.html
+++ b/art/drawhearts/index.html
@@ -33,7 +33,7 @@ void main (void) {
gl_FragColor = vec4(color,1.0);
}
I tinkered around for quite a while before discovering that I can intersect two xyxy skewed ellipses
-with the absolute value operator. Here’s my custom equation for the heart shape.'>
Jan 18, 2026
Step to the 💗 beat
My first procedurally generated animation using shaders.
The shader can be visualized with glslViewer.
uniformvec2 u_mouse;
+with the absolute value operator. Here’s my custom equation for the heart shape.'>
Jan 18, 2026
Step to the 💗 beat
My first procedurally generated animation using shaders.
A cyborg head sinking in a pool of water. What more did you expect? Here’s a timelapse.
\ No newline at end of file
+Drowning - lavafroth
Jun 18, 2024
Drowning
A cyborg head sinking in a pool of water. What more did you expect? Here’s a timelapse.
\ No newline at end of file
diff --git a/art/index.html b/art/index.html
index 2b41c365..90496d60 100644
--- a/art/index.html
+++ b/art/index.html
@@ -1,4 +1,4 @@
-Art - lavafroth
All the art I make is licensed under Creative Commons
Attribution-ShareAlike 4.0 International
license unless
specified otherwise. Please read the legal code before redistributing, adapting
diff --git a/art/shes-a-rebel/index.html b/art/shes-a-rebel/index.html
index 2d19b177..7f549e15 100644
--- a/art/shes-a-rebel/index.html
+++ b/art/shes-a-rebel/index.html
@@ -1 +1 @@
-
She's a Rebel - lavafroth
Apr 17, 2022
She's a Rebel
Clearly the title was an afterthought.
\ No newline at end of file
+She's a Rebel - lavafroth
Apr 17, 2022
She's a Rebel
Clearly the title was an afterthought.
\ No newline at end of file
diff --git a/art/sparkles/index.html b/art/sparkles/index.html
index 145e547c..66fe339b 100644
--- a/art/sparkles/index.html
+++ b/art/sparkles/index.html
@@ -1 +1 @@
-✨ - lavafroth
Jul 15, 2025
✨
\ No newline at end of file
+✨ - lavafroth
Jul 15, 2025
✨
\ No newline at end of file
diff --git a/art/thiserror/index.html b/art/thiserror/index.html
index 3c9d59c8..d9cc6fbb 100644
--- a/art/thiserror/index.html
+++ b/art/thiserror/index.html
@@ -1,5 +1,5 @@
This Error - lavafroth
Jun 18, 2024
This Error
My first hand drawn YouTube thumbnail, I’m might continue using
+as well as the sheer memeworthiness of the debacle.'>
Jun 18, 2024
This Error
My first hand drawn YouTube thumbnail, I’m might continue using
lawyer ferris as my mascot both due to ferris being in the public domain
as well as the sheer memeworthiness of the debacle.
\ No newline at end of file
diff --git a/art/tyler-joseph-portrait/index.html b/art/tyler-joseph-portrait/index.html
index a0484473..f2725d90 100644
--- a/art/tyler-joseph-portrait/index.html
+++ b/art/tyler-joseph-portrait/index.html
@@ -1,3 +1,3 @@
Truce - lavafroth
Jul 23, 2022
Truce
A painting of the lead vocalist of Twenty Øne Piløts, named
+after one of my favorite songs from their album Vessel.'>
Jul 23, 2022
Truce
A painting of the lead vocalist of Twenty Øne Piløts, named
after one of my favorite songs from their album Vessel.
\ No newline at end of file
diff --git a/art/wip-animation/index.html b/art/wip-animation/index.html
index d5261f05..4768b7cf 100644
--- a/art/wip-animation/index.html
+++ b/art/wip-animation/index.html
@@ -1 +1 @@
-Throwing knives - lavafroth
CTFForensicsPicoCTFThe Sleuth Kit
diff --git a/post/2-afternoons-2-languages-2-tuis/index.html b/post/2-afternoons-2-languages-2-tuis/index.html
index 12bf269f..d5c575ae 100644
--- a/post/2-afternoons-2-languages-2-tuis/index.html
+++ b/post/2-afternoons-2-languages-2-tuis/index.html
@@ -10,7 +10,7 @@ switching terminal panes and manually issuing a command. The idea is to have a
tool running in the background that listens for filesystem events, like when a
file gets created or modified, and if the file happens to contain an animation,
renders it. On linux systems, it’s mostly a bunch of bindings to inotify but I
-have used platform agnostic libraries for both the languages.'>
2 Afternoons, 2 Languages, 2 TUIs
Yesterday I created a tool in Golang to help me render my animations a little
+have used platform agnostic libraries for both the languages.'>
2 Afternoons, 2 Languages, 2 TUIs
Yesterday I created a tool in Golang to help me render my animations a little
faster. Although the alterior reason was to check my Golang proficiency, today
I rewrote it in Rust and I was blown away by the differences in the final
products.
When I’m rendering animations for a YouTube video, the general development
diff --git a/post/a-sweet-little-config-parser/index.html b/post/a-sweet-little-config-parser/index.html
index 7023d253..5c8efd94 100644
--- a/post/a-sweet-little-config-parser/index.html
+++ b/post/a-sweet-little-config-parser/index.html
@@ -3,7 +3,7 @@ be explanding upon that. I believe that to construct a good grammar, I should be
and explain it well. So here goes.
General Idea
SWHKD’s grammar parser, although similar to tools before it like sxhkd, has a more coherent
-syntax. For starters, every binding declaration is one or more accelerators followed by a composite key.'>
A SWEET Little Parser
A few days ago, I had announced my project for this year’s Google Summer of Code. Today I’ll
+syntax. For starters, every binding declaration is one or more accelerators followed by a composite key.'>
A SWEET Little Parser
A few days ago, I had announced my project for this year’s Google Summer of Code. Today I’ll
be explanding upon that. I believe that to construct a good grammar, I should be able to understand
and explain it well. So here goes.
General Idea
SWHKD’s grammar parser, although similar to tools before it like sxhkd, has a more coherent
syntax. For starters, every binding declaration is one or more accelerators followed by a composite key.
The line following the binding declaration must be a tab or space indented command to be run by the client.
Here’s a simple example to send a notification to myself using libnotify when I press Supera.
super + a
diff --git a/post/a-tale-of-a-frugal-home-server/index.html b/post/a-tale-of-a-frugal-home-server/index.html
index b96d91a1..50bd6bd9 100644
--- a/post/a-tale-of-a-frugal-home-server/index.html
+++ b/post/a-tale-of-a-frugal-home-server/index.html
@@ -3,7 +3,7 @@ matured enough to be worth talking about.
At any point, you can check out the source code for the server’s infrastructure here for a concrete example.
For each service I talk about, I will also link the respective definitions in my config.
My minimalist mindset has unsurprisingly aided the architecture of my server.
-Throughout the rest of the post, you will come across the following broad strokes:'>
A Tale of a Frugal Home Server
Having run an on-premise server for the past two years, I think my setup has finally
+Throughout the rest of the post, you will come across the following broad strokes:'>
A Tale of a Frugal Home Server
Having run an on-premise server for the past two years, I think my setup has finally
matured enough to be worth talking about.
At any point, you can check out the source code for the server’s infrastructure here for a concrete example.
For each service I talk about, I will also link the respective definitions in my config.
My minimalist mindset has unsurprisingly aided the architecture of my server.
Throughout the rest of the post, you will come across the following broad strokes:
Easy is not always simple
Simple is better than easy
There must be one (and exactly one) way of doing something
Hardware
The server is an old laptop which was on the verge becoming e-waste. Despite having a touchscreen
diff --git a/post/abstracting-structured-patterns-in-concurrent-programming/index.html b/post/abstracting-structured-patterns-in-concurrent-programming/index.html
index e6045d4d..4421601c 100644
--- a/post/abstracting-structured-patterns-in-concurrent-programming/index.html
+++ b/post/abstracting-structured-patterns-in-concurrent-programming/index.html
@@ -5,7 +5,7 @@ If you have questions or feel that I have missed something, feel free to talk ab
In recent months, I have come across multiple articles talking about the need
of structured concurrency in modern programming languages as a built-in. Notably, in the article Notes on structured concurrency, or: Go statement considered harmful,
the author compares the go statement used to spawn coroutines to goto statements used
-for jumping to other parts of code in early languages like COBOL.'>
Abstracting Structured Patterns in Concurrent Programming
I hope this article provides a solid blueprint for building a concurrency management API.
+for jumping to other parts of code in early languages like COBOL.'>
Abstracting Structured Patterns in Concurrent Programming
I hope this article provides a solid blueprint for building a concurrency management API.
If you have questions or feel that I have missed something, feel free to talk about it in this repository’s issue tracker or the discussion board.
In recent months, I have come across multiple articles talking about the need
of structured concurrency in modern programming languages as a built-in. Notably, in the article Notes on structured concurrency, or: Go statement considered harmful,
the author compares the go statement used to spawn coroutines to goto statements used
diff --git a/post/algebraic-python-enums/index.html b/post/algebraic-python-enums/index.html
index 6fbe91f5..470621e5 100644
--- a/post/algebraic-python-enums/index.html
+++ b/post/algebraic-python-enums/index.html
@@ -9,7 +9,7 @@ versions, most tutorials will suggest Union types as the equivalent to Rust&rsqu
enums.
I highly encourage you to try out the code snippets and follow along with this article.
-Use the collapse explanation button to copy multiple code blocks in one go.'>
Algebraic Python Enums
University has compelled me to use Python despite my preference for Rust,
+Use the collapse explanation button to copy multiple code blocks in one go.'>
Algebraic Python Enums
University has compelled me to use Python despite my preference for Rust,
primarily due to the machine learning and data science hype. One
Rust feature that I dearly miss is enumerable data types
that can encapsulate various other data types.
Although Python has the answer to creating structs as
diff --git a/post/android-phone-for-webcam-nixos/index.html b/post/android-phone-for-webcam-nixos/index.html
index 52c5afff..858ee5b6 100644
--- a/post/android-phone-for-webcam-nixos/index.html
+++ b/post/android-phone-for-webcam-nixos/index.html
@@ -1,7 +1,7 @@
Using an Android Phone as a webcam in NixOS - lavafroth
Using an Android Phone as a webcam in NixOS
I recently had to attend an online meeting for a software development event.
+No, it’s not a close-up of the moon, it’s the refraction caused by the scuffs to the lens plus other sciency stuff I’m not qualified enough to explain to you.'>
Using an Android Phone as a webcam in NixOS
I recently had to attend an online meeting for a software development event.
While my PC did have a decent microphone, the built-in camera has been damaged to the extent that the best it can capture is this:
No, it’s not a close-up of the moon, it’s the refraction caused by the scuffs to the lens plus other sciency stuff I’m not qualified enough to explain to you.
I was aware that one can use ADB to use an Android phone’s camera as a makeshift webcam. Since I would need this ability for any future meetings as well, it was worth having the functionality packaged into a one click tool.
Enter NixOS. I have praised NixOS before and I’ll do it again because of the sheer ease with which it allows me to create desktop entries for small scripts.
This is going to be relevant later but I’m going to assume that you’re running NixOS with home-manager enabled if you’re following along. First we have to enable developer mode and USB debugging on our phone.
To interact with our phone, we will need adb and scrcpy as dependencies.
If you have enabled flakes run the following:
nix shell nixpkgs#scrcpy nixpkgs#android-tools
diff --git a/post/changing-recents-provider-on-eos/index.html b/post/changing-recents-provider-on-eos/index.html
index 85b105cb..cb87e241 100644
--- a/post/changing-recents-provider-on-eos/index.html
+++ b/post/changing-recents-provider-on-eos/index.html
@@ -7,7 +7,7 @@ Icons can’t be rearranged
Pull down from top opens search instead of notification shade
Consumes a lot of RAM
-I started using Lawnchair as my default launcher but this did not change the recents provider (quickstep) from BlissLauncher to Lawnchair.'>
Guide: Changing Recents Provider on /e/OS
Overview
Over the past month I have been daily driving my new phone, the Nothing CMF 1 flashed with /e/OS after I unlocked its bootloader. It’s a very pleasant experience except for the default Bliss launcher (home app).
Reasons I do not prefer it:
iOS like feel
Icons can’t be rearranged
Pull down from top opens search instead of notification shade
Consumes a lot of RAM
I started using Lawnchair as my default launcher but this did not change the recents provider (quickstep) from BlissLauncher to Lawnchair.
Two problems with this:
Bliss has to keep running in the background to act as the recents provider.
When the screen is horizontally oriented and gesture navigation is used to go to the home screen, Bliss keeps crashing.
Note for Bliss devs: This behavior only occurs when using a different launcher as default.
I read a post on the forums about replacing Bliss completely but there was no step by step guide. Here, I document the steps I took to get Lawnchair as my default launcher and recents provider.
Guide
This guide assumes you have a basic understanding of adb and fastboot. Ensure that USB debugging is enabled and your device is visible in the output of adb devices.
Apatch
Extracting boot.img
Assuming you have the image used to flash /e/OS on your phone, extract the boot.img from it. This can be done with the 7zip command
7z e IMG-e-3.0.4-a14-20250708507308-official-tetris.zip -o. boot.img
+I started using Lawnchair as my default launcher but this did not change the recents provider (quickstep) from BlissLauncher to Lawnchair.'>
Guide: Changing Recents Provider on /e/OS
Overview
Over the past month I have been daily driving my new phone, the Nothing CMF 1 flashed with /e/OS after I unlocked its bootloader. It’s a very pleasant experience except for the default Bliss launcher (home app).
Reasons I do not prefer it:
iOS like feel
Icons can’t be rearranged
Pull down from top opens search instead of notification shade
Consumes a lot of RAM
I started using Lawnchair as my default launcher but this did not change the recents provider (quickstep) from BlissLauncher to Lawnchair.
Two problems with this:
Bliss has to keep running in the background to act as the recents provider.
When the screen is horizontally oriented and gesture navigation is used to go to the home screen, Bliss keeps crashing.
Note for Bliss devs: This behavior only occurs when using a different launcher as default.
I read a post on the forums about replacing Bliss completely but there was no step by step guide. Here, I document the steps I took to get Lawnchair as my default launcher and recents provider.
Guide
This guide assumes you have a basic understanding of adb and fastboot. Ensure that USB debugging is enabled and your device is visible in the output of adb devices.
Apatch
Extracting boot.img
Assuming you have the image used to flash /e/OS on your phone, extract the boot.img from it. This can be done with the 7zip command
7z e IMG-e-3.0.4-a14-20250708507308-official-tetris.zip -o. boot.img
Here IMG-e-3.0.4-a14-20250708507308-official-tetris.zip is the image for my phone. Replace this with the appropriate image name.This extract the boot.img to the current directory.
Push this image to your device with
adb push boot.img /storage/emulated/0/Download/
NOTE: You could also push the image over MTP (file transfer) but it may corrupt files and is hence discouraged.
Installing APatch
These instructions are also available in the APatch Docs.
Download the latest version of APatch Manager from GitHub.
Click on the patch button at the top right corner, and click Select a boot image to patch.
Select the boot.img we pushed to the Download directory.
Set a SuperKey at “SuperKey” card. The SuperKey should be 8-63 characters long and include numbers and letters, but no special characters. It will be used later to unlock root privileges.
Click on “Start” and wait for a minute. After the patch is successful, the patched boot.img path will be displayed. For example: /storage/emulated/0/Download/apatch_version_version_randomletter.img.
Flashing
Pull the patched boot.img with the command. Replace apatch_version_version_randomletter.img with the appropriate filename.
I found some hex in a file called fleg, but I’m not sure how it’s encoded. I’m pretty sure it’s some kind of xor…
Exploration
We begin by creating a new rust project.
cargo new amateurs
+To execute the code, issue the following.'>
Compact XOR
Description
I found some hex in a file called fleg, but I’m not sure how it’s encoded. I’m pretty sure it’s some kind of xor…
Exploration
We begin by creating a new rust project.
cargo new amateurs
cd amateurs
cargo add hex
cargo add itertools
diff --git a/post/cuda-on-nixos-without-sacrificing-ones-sanity/index.html b/post/cuda-on-nixos-without-sacrificing-ones-sanity/index.html
index a93717e5..600e1d50 100644
--- a/post/cuda-on-nixos-without-sacrificing-ones-sanity/index.html
+++ b/post/cuda-on-nixos-without-sacrificing-ones-sanity/index.html
@@ -8,7 +8,7 @@ TL;DR: Save this flake, run nix develop and setup PyTorch as described
CUDA is a proprietary vendor lock-in for machine learning folks.
Training ML models is incredibly fast with CUDA as compared to CPUs due to the parallel
processing. So if you’re doing something serious, you have no other choice besides CUDA as of writing.
-Although, OpenAI’s Triton and ZLUDA are worth keeping an eye on.'>
Painlessly setting up ML tooling on NixOS
Note: Use the following method only if you wish to have the latest version of CUDA that is
+Although, OpenAI’s Triton and ZLUDA are worth keeping an eye on.'>
Painlessly setting up ML tooling on NixOS
Note: Use the following method only if you wish to have the latest version of CUDA that is
not yet available in the nix-community cache, otherwise follow this.
CUDA is a proprietary vendor lock-in for machine learning folks.
Training ML models is incredibly fast with CUDA as compared to CPUs due to the parallel
processing. So if you’re doing something serious, you have no other choice besides CUDA as of writing.
diff --git a/post/detecting-stripped-go-binaries/index.html b/post/detecting-stripped-go-binaries/index.html
index 9689816e..11593144 100644
--- a/post/detecting-stripped-go-binaries/index.html
+++ b/post/detecting-stripped-go-binaries/index.html
@@ -2,7 +2,7 @@
When all else fails, the Go GC provides a few different specific traces that provide much deeper insights into GC behavior. These traces are always printed directly to STDERR, one line per GC cycle, and are configured through the GODEBUG environment variable that all Go programs recognize.
-An environment variable that all Go programs recognize, you say? I had a sneaking suspicion that I could just perform a string search for this term, given all Go programs would need to look for this environment variable definition. This way, we could guess if a binary was written in Go.'>
When all else fails, the Go GC provides a few different specific traces that provide much deeper insights into GC behavior. These traces are always printed directly to STDERR, one line per GC cycle, and are configured through the GODEBUG environment variable that all Go programs recognize.
An environment variable that all Go programs recognize, you say? I had a sneaking suspicion that I could just perform a string search for this term, given all Go programs would need to look for this environment variable definition. This way, we could guess if a binary was written in Go.
I created a program called hello to test this out. To make sure the binary is stripped, I compiled it with go build -ldflags '-w -s'.
grep GODEBUG hello
+An environment variable that all Go programs recognize, you say? I had a sneaking suspicion that I could just perform a string search for this term, given all Go programs would need to look for this environment variable definition. This way, we could guess if a binary was written in Go.'>
When all else fails, the Go GC provides a few different specific traces that provide much deeper insights into GC behavior. These traces are always printed directly to STDERR, one line per GC cycle, and are configured through the GODEBUG environment variable that all Go programs recognize.
An environment variable that all Go programs recognize, you say? I had a sneaking suspicion that I could just perform a string search for this term, given all Go programs would need to look for this environment variable definition. This way, we could guess if a binary was written in Go.
I created a program called hello to test this out. To make sure the binary is stripped, I compiled it with go build -ldflags '-w -s'.
grep GODEBUG hello
grep: hello: binary file matches
Sure enough, looks like this does provide a decent heuristic for Go programs! Of course, there’s the caveat that another binary can “pretend” to be a Go binary by simply having this string present in it.
We could try this technique with other environment variables like GOGC, available in all binaries and GOMEMLIMIT, available for Go 1.19 and up.
So if you have a hunch that a binary is written in Go 1.19 and above, try grepping with all the aforementioned variables.