<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Aditya Thebe Personal Blog RSS Feed]]></title><description><![CDATA[This little corner on the Internet is where I pen down my random thoughts mostly on Bitcoin, Web security, Linux and various web technologies ...]]></description><link>https://www.adityathebe.com</link><generator>GatsbyJS</generator><lastBuildDate>Sun, 17 May 2026 14:07:17 GMT</lastBuildDate><item><title><![CDATA[Bypassing DRM protection to download a movie]]></title><description><![CDATA[Here's how I obtained a DRM protected video with Go and FFMPEG.]]></description><link>https://www.adityathebe.com/download-drm-protected-video</link><guid isPermaLink="false">https://www.adityathebe.com/download-drm-protected-video</guid><pubDate>Sat, 24 May 2025 19:00:00 GMT</pubDate><content:encoded>In this article, I&apos;ll walk you through the process of how I managed to reconstruct a complete video file from encrypted video stream segments. At the end of the article, you&apos;ll also find the source code for the script that I used to download the video. I recently bought a movie from a platform that was very restrictive. You could only watch the movie for a very limited period of time and from a very limited number of devices.

I&apos;m a media hoarder and naturally I wanted to download the movie for later. However, downloading it was not trivial as you&apos;ll see in a bit.

I couldn&apos;t resist the temptation to roll up my sleeves and reverse-engineer the stream. With a few hours of investigation and scripting, I was able to bypass the protection and piece together the entire movie using  &amp; .

Needless to say, the movie was not distributed and is only being used personally.

The usual approach

Generally, whenever I need to download a video, I grab the URL and pass that on to my trusty  tool.

For other websites, I open the developer tools, go to the network tab, filter by media, and then grab the video stream URL.

But this time, the movie didn&apos;t have a single URL. In fact, there were no network calls showing up under the media category at all.

Reconnaissance

What I noticed is that there were a lot of HTTP calls to different segments of the video.

This endpoint returned a binary data of content type  - which is just a stream of digital media. I tried downloading one of the segments and playing it with VLC but that didn&apos;t work.

In between those calls, there were also calls to get some sort of key

This endpoint also returned binary data. The name  in the url was quite interesting. Upon googling, I found out that drm stands for Digital Rights Management and it relies on encryption to protect the content.

At this point I was almost certain that the

 endpoint was returning a small encrypted segment of the video and the  endpoint was returning the encryption key for the web client to decrypt it.

If I could figure out the encryption algorithm used then I could download all the segments and the keys and then decrypt them one by one.

Encryption algorithm

The  endpoint returned a 128-bit encryption key (e.g. 9036fb5d2f6af3c153acecd37bde6da7 in hexadecimal). That&apos;s a strong signal that it&apos;s most likely using AES-128 - a very popular symmetric encryption algorithm.

With the ciphertext (from ) and the encryption key in hand, I tried decrypting it using 

However, when I tried to play the resulting file in VLC, it didn’t work – nothing happened.

I went back to examine the network traffic and found another intriguing endpoint:

It returned a plain-text response like this

M3U8

Now that&apos;s something! It&apos;s a  file which contains a list of urls to all the segments of the video file.

There are some pretty interesting stuff in here. Let&apos;s go through them

| Line | Directive | Description | | ---- | -------------------------- | ------------------------------------------------------------- | | 2 |  | uses the extended version 3 of  that supports encryption | | 5 |  | Indicates that each url points to a video | | 6 |  | we see the encryption algorithm used - AES-128 | | 7 |  | Indicates that this segment is 4 seconds long |

In the  directive, we can also see . That most likely represents the initialization vector of the AES-128 encryption.

Let&apos;s try decrypting once again using the CBC mode

And voila! I was able to play the video.

Code

Now all I needed to do was write a script to download all the segments and their keys and then decrypt them individually. And finally piece them together with .

You can find the source code at github.com/adityathebe/drm.

--

In hindsight this was pretty straightforward. The endpoints hinted the use of DRM and it turns out most modern DRM technologies use AES with 128-bit keys [1].

To validate the approach, I purchased another movie and successfully downloaded the entire film.

References</content:encoded></item><item><title><![CDATA[🕰️ Now]]></title><description><![CDATA[What I'm focused on right now.]]></description><link>https://www.adityathebe.com/now</link><guid isPermaLink="false">https://www.adityathebe.com/now</guid><content:encoded>&lt;ul&gt;
&lt;li&gt;🏠 In Kathmandu&lt;/li&gt;
&lt;li&gt;Working at &lt;a href=&quot;https://flanksource.com&quot;&gt;@Flanksource&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Go v1.21+ Auto-Downloads Toolchains and Verifies Them Using a Transparency Log]]></title><description><![CDATA[since Go 1.21, the go command can automatically download newer toolchains—and verify them against a cryptographically auditable log. This led me down a rabbit hole into how transparency logs work, what Merkle trees actually do, and why someone is independently rebuilding every Go toolchain from source.]]></description><link>https://www.adityathebe.com/go-toolchain-download</link><guid isPermaLink="false">https://www.adityathebe.com/go-toolchain-download</guid><pubDate>Sun, 07 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Before Go &lt;code class=&quot;language-text&quot;&gt;1.21&lt;/code&gt;, if you wanted to build a project requiring a newer Go version, you had to manually install that version yourself.
Since &lt;code class=&quot;language-text&quot;&gt;1.21&lt;/code&gt;, go automatically downloads the required toolchain (the &lt;code class=&quot;language-text&quot;&gt;go&lt;/code&gt; binary, compiler, linker, etc.) and uses it to build the project - all without touching your global Go installation.&lt;/p&gt;
&lt;p&gt;While very convenient, there&apos;s also a huge security concern in downloading a binary from the internet and running it on demand, completely transparently.
That&apos;s why the downloaded toolchains are locally verified against a transparency log.&lt;/p&gt;
&lt;div class=&quot;section-notes&quot;&gt;
Transparency logs are append-only logs that enable public auditability. They use Merkle trees - a highly optimized data structure for fast consistency verification.
&lt;/div&gt;
&lt;p&gt;Go has been using a module checksum db (Go sumdb) - a transparency log - which stores the checksum for all the go modules (that the mirror sees).
The same checksum db has been updated to support the toolchain checksum.&lt;/p&gt;
&lt;h2 id=&quot;who-audits-gos-transparency-log&quot;&gt;Who Audits Go’s Transparency Log?&lt;/h2&gt;
&lt;p&gt;It&apos;s reassuring that Go verifies the downloaded binaries for the toolchain, but who verifies that the same transparency log is being distributed to all the users?&lt;/p&gt;
&lt;p&gt;Let me break this down:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A Go client downloads a toolchain and locally verifies that the toolchain&apos;s checksum is present in the transparency log.&lt;/li&gt;
&lt;li&gt;A different client could download a different toolchain, and Google could serve a completely different transparency log that&apos;s internally consistent with that toolchain.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So two users could have two different toolchains, yet both believe they have the correct one. This is called a &lt;strong&gt;split-view attack&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;The solution is to audit that google serves the same transparency log to all users. This is where auditors come in.&lt;/p&gt;
&lt;p&gt;Andrew Ayer in his blog post - &lt;a href=&quot;https://www.agwa.name/blog/post/verifying_go_reproducible_builds&quot;&gt;https://www.agwa.name/blog/post/verifying_go_reproducible_builds&lt;/a&gt; - mentions that he has been running an independent auditor for Go&apos;s checksum database since 2020 - &lt;a href=&quot;https://sourcespotter.com/&quot;&gt;https://sourcespotter.com/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Sourcespotter independently builds the toolchain for every new release and verifies that against the Go sumdb.&lt;/p&gt;
&lt;h2 id=&quot;verifying-reproducibility-vs-consistency&quot;&gt;Verifying Reproducibility vs Consistency&lt;/h2&gt;
&lt;p&gt;It&apos;s important to distinguish what exactly the auditor is doing.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;For regular Go modules&lt;/strong&gt;, the auditor only verifies &lt;em&gt;consistency&lt;/em&gt;. It doesn&apos;t download every module, build it, and check that the checksum matches. That would be impossible at scale since there are millions of modules. Instead, it just watches the log over time, making sure Google doesn&apos;t alter old entries or serve different versions to different people.&lt;/p&gt;
&lt;p&gt;I don&apos;t understand how this works exactly. A naive solution would be&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;store_checksum_for_all_modules_to_db&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

loop&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; module &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; fetch_checksum_for_all_modules_from_sumdb&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    checksum_in_db &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; db&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get_module_checksum&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;module&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;not&lt;/span&gt; checksum_in_db&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      store_to_db&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;module&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;continue&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; checksum_in_db &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; module&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;checksum&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      alert&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;mismatch&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Of course, it doesn&apos;t work this way. In fact, the auditor stores a single root hash (not millions for each module) and can mathemtically verify that the tree hasn&apos;t been tampered - I just don&apos;t know how.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;For toolchains&lt;/strong&gt; however, the auditor also verifies &lt;a href=&quot;https://sourcespotter.com/toolchain/&quot;&gt;&lt;em&gt;reproducibility&lt;/em&gt;&lt;/a&gt;. Since there are relatively few toolchain releases (a few thousand across all versions and platforms), Source Spotter can actually download the source code, build each toolchain independently, and confirm the resulting binary matches the checksum Google published. This ensures the published binaries really are what you&apos;d get if you built from source yourself.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Why is Golang's atomic.Bool 32 bits (not 8 bits)]]></title><description><![CDATA[Exploring why Go's atomic.Bool uses 32 bits internally instead of a single byte—it's all about CPU architecture and atomic operation efficiency.]]></description><link>https://www.adityathebe.com/til-why-is-golang-atomic-bool-32-bit</link><guid isPermaLink="false">https://www.adityathebe.com/til-why-is-golang-atomic-bool-32-bit</guid><pubDate>Thu, 06 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;TIL that Go uses &lt;code class=&quot;language-text&quot;&gt;uint32&lt;/code&gt; instead of &lt;code class=&quot;language-text&quot;&gt;uint8&lt;/code&gt; or just &lt;code class=&quot;language-text&quot;&gt;bool&lt;/code&gt;.
At first glance, that seems counterintuitive because ideally a bool is just a bit. Why do we need the extra 31 bits?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The runtime picks a 32-bit slot so it can rely on the same word-sized compare-and-swap instruction on every architecture Go supports. Some CPUs expose byte-sized atomics, but others do not guarantee them (or require strict alignment), so Go standardizes on word-aligned storage instead.&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// A Bool is an atomic boolean value.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// The zero value is false.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;//&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// Bool must not be copied after first use.&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;type&lt;/span&gt; Bool &lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;token boolean&quot;&gt;_&lt;/span&gt; noCopy
	v &lt;span class=&quot;token builtin&quot;&gt;uint32&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Let&apos;s see how CompareAndSwap works for a bool&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// CompareAndSwap executes the compare-and-swap operation for the boolean value x.&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;Bool&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;CompareAndSwap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;old&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;swapped &lt;span class=&quot;token builtin&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;CompareAndSwapUint32&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;v&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;b32&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;old&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;b32&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Source: &lt;a href=&quot;https://github.com/golang/go/blob/47a63a331daa96de55562fbe0fa0201757c7d155/src/sync/atomic/type.go#L27C1-L30C2&quot;&gt;https://github.com/golang/go/blob/47a63a331daa96de55562fbe0fa0201757c7d155/src/sync/atomic/type.go#L27C1-L30C2&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;CompareAndSwapUint32&lt;/code&gt; is a Go-level wrapper around a lower-level atomic CAS operation in the runtime&lt;/p&gt;
&lt;p&gt;This function is implemented in assembly.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;asm&quot;&gt;&lt;pre class=&quot;language-asm&quot;&gt;&lt;code class=&quot;language-asm&quot;&gt;TEXT ·CompareAndSwapUint32(SB),NOSPLIT,$0
	JMP	internal∕runtime∕atomic·Cas(SB)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;On amd64, bool swap is implemented as shown below in assembly.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;asm&quot;&gt;&lt;pre class=&quot;language-asm&quot;&gt;&lt;code class=&quot;language-asm&quot;&gt;// bool Cas(int32 *val, int32 old, int32 new)
// Atomically:
// if(*val == old){
//     *val = new;
//     return 1;
// } else
//     return 0;
TEXT runtime∕internal∕atomic·Cas(SB),NOSPLIT,$0-17
    MOVQ ptr+0(FP), BX    // Load pointer address into BX
    MOVL old+8(FP), AX    // Load expected value into AX (required by CMPXCHG)
    MOVL new+12(FP), CX   // Load new value into CX
    LOCK                   // Lock prefix for atomicity
    CMPXCHGL CX, 0(BX)    // Compare AX with [BX], if equal swap with CX
    SETEQ ret+16(FP)      // Set return value based on ZF (zero flag)
    RET&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Source: &lt;a href=&quot;https://github.com/golang/go/blob/47a63a331daa96de55562fbe0fa0201757c7d155/src/internal/runtime/atomic/atomic_amd64.s#L22-L37&quot;&gt;https://github.com/golang/go/blob/47a63a331daa96de55562fbe0fa0201757c7d155/src/internal/runtime/atomic/atomic_amd64.s#L22-L37&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Backup your GitHub repositories now!]]></title><description><![CDATA[Account suspensions on GitHub are unpredictable and appeals take months. Here's how I use gickup to automatically backup all my repositories daily with a simple, hands-off setup.]]></description><link>https://www.adityathebe.com/backup-github</link><guid isPermaLink="false">https://www.adityathebe.com/backup-github</guid><pubDate>Sun, 19 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Over the past few days, I&apos;ve been seeing a surge of posts on Twitter regarding GitHub account suspension.&lt;/p&gt;
&lt;div style=&quot;display: flex; gap: 1em; flex-wrap: wrap;&quot;&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1090px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/21fac992606474f297858dc250a4a8e2/525d3/grimcodes-github-suspended.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 88.66666666666666%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAASCAYAAABb0P4QAAAACXBIWXMAABYlAAAWJQFJUiTwAAACO0lEQVR42q2U227aQBCGbfBx1we85mBsjPEBMCgJSUh6UFtUVcpVH6Cv0rfoI/+dXVNIpSqhVS8+LWNmP2bx7Gjf1iF+PBWYFSXKskTbbrBZrxA1d9AsBl3ToL2CaZoQQkDXdWhfKx/f303gRzGiSEDEQ7iui77lQNN76PUk/ReFUtTvU44U8jBCVjbI8xxJkiBNU0wmCWZZpipeLpcIAv+0Uddfqdh2GQIxhhfGVOUI/mAEHgpah+CBgOsNYLk+TInjET4cHqrnz2F+BMO0oTk8gC+m8KLkhC+6dTyrkRZLJHlNp1hjVrbI6xbRZAZPJGqfL7r8IE5hux4JmX8UTE7wwRgsHCpRXrWYFg3m9QZFvSU2COMp3GD42x4pt1z+Z2GcFEjmKwzTCiJZqHVEjLOS1hLZYk0/1hxPdoFwlNa43n/EzcMH7N9/xv7tAbvHT1jdHrDaHbB9+IK8uf4LYVZhdfWIYn2PcvsGRbtHtb1HvtorivYRSdGq/+1CYY2GBEm1w2hxS9xhvrxB3d6gaXdYX5G42l5e4SmJCERH97LOqG649KX8C2ch/89Cmz1rbHFubka9eDqaauCXCeKsa2zTssE8ukp0YzpCFUfxGMEgpmsVwKIrZzn8FTz0+gZVaJOQczVhJNzzwBhDVVWYTulG0Gc5cbQLxpjCtCzYjtPNsuNEkfFzicxxaYioEUWx/I4xDsMwTtNHzkQZa6bZJcskKZOrjC2S/HpmGGYnlBuOQll5J9SPQksJfwK3Q6umJNl+TwAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;grimcodes github suspended&quot;
        title=&quot;&quot;
        src=&quot;/static/21fac992606474f297858dc250a4a8e2/525d3/grimcodes-github-suspended.png&quot;
        srcset=&quot;/static/21fac992606474f297858dc250a4a8e2/5a46d/grimcodes-github-suspended.png 300w,
/static/21fac992606474f297858dc250a4a8e2/0a47e/grimcodes-github-suspended.png 600w,
/static/21fac992606474f297858dc250a4a8e2/525d3/grimcodes-github-suspended.png 1090w&quot;
        sizes=&quot;(max-width: 1090px) 100vw, 1090px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;
&lt;em&gt;&lt;a href=&quot;https://x.com/grimcodes/status/1977471153011933375&quot;&gt;https://x.com/grimcodes/status/1977471153011933375&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1098px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/69951f8a42152162c7a7634cfff70a94/99661/vmfunc-github-suspended.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 143.33333333333334%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAdCAYAAACqhkzFAAAACXBIWXMAABYlAAAWJQFJUiTwAAAEu0lEQVR42pVW2XLiVhDFBgQSEpJYtIAkxGJsbGOEAYvVMDZOOc7kIS9JnJckz6mab8hvpGpSyZ+edF8ZjD1VqeThVPfduk8vtEi5uoLYVWGYJizLRtk0oFZc+HoVSiqF1NERjggp0lkeHx8LPZ7N8P2Pz/jh+RnRcLg/T22iU/z+0yMsu4p2p4uz0y687gVqqpkYfIedwd8+fcIfn//E57/+xs+//ApJkpBOp5HK5RWYdg26YaBSrQpUy2WUKmVyYqNCepX2TIqgXKmgfLC2LEusDXqbzWYTp7VaDcPBAL1eDzYZKBaL0LQiTMMUD3VdJxhvJBvYge9XyBEzFAZzuRxUVRMH+bxMniThLZESMpmMWPODndzp2V2Yh2lRVVWEVq/XEfg+PJKu6woZhqHQ+cwPAoTNJhqNBjzPB0cW0B6Hvi8IG8zn8ug0T1ClnBWtOtLFKrKZNDHLChZfMHjBYeUPkZJlBbeLFcajEc6jMfyTC4SNAL4fwGPGxIZz6xIjn9aO4/y7Ez7knHCy1YICTS2IZGuahkIh0bmSHJpBheJ+lRUFCoPOWXLuk5Yig5xYbsxrYhhFQ4wnE0wIURQhjmORR642M2Np247IKzOue56IgM/2PcoMudIsMwSWfMD54wrvk/0fIO5mpTxySvENJEI2r0KSNbHOKzryBZ10Pbnzsi+rxh55QlbKUR/KKorlGrSSK6CaDoyqh4obwiRZdgKUbB+m5aFEOu9b9RaqtZDeuft3bINtpSS5ALXkkCEbGkEuVuA1z3Adr9C/nmI8vcXp5RDDyQzT9QNG4yWmyy2dL6GXbRTojXhLNqR8ITGo7QySPMQrAwd6pUbMKRLT+eLeG4M5ZkgbJoVVdkIYFocXkExg2oHYY+hVP9mvBkIXa9L5XZEcSjRoXg3Sxfb5GKPZBv3xAoMbCnk0x+VwhmvaG0xuMZmtMZl/QDRZUNh3iFd3uFnco9boksH6O4PEJOj0Md98jcliS7jH+uFbrLcfMZ7dY075640fEEaPCPsf0Bk9oT36iPD8horUJLZ16owDg0y77LZQqbVg+x3YXos8nwiwbnttlNwODIfRhm63oJM0bGp8qvo7g47I0dlVjBuqYNiL4Zyu4XYXhKXQu4Ml+sMpVX6OwXiF0XSD0ZxSQemxvA4V7V3IJQq5Tu3SOotQa57DavRhNy7hNCPY4ZXY81vnCNoXlJpLNAhht0/6BRlsveZQemHIbcFe9i3DrUJtw+D24fNdE2sHDc3gHwLLtwwdGpzEoE4Iu1eEATHuiT2f2NTCM/gv7Fgy+JzXTnDyvspJDs+jGeLbrajs9vE7TFcPVN2vqD34l7HBcvOE1fYbLO+eSH9EvKRzkn6rR6xf+pC7mw2WqMrMbjBZoTeY4nK0wDBe44oKcDaIEd1shMOryZIKcofxfCt6sze4oSp3RNuJXwrPQ0Wl4Vo0oeklKJoh9FLFhlGij73GE0ajyaOKHz8/4ryzzm3CUi5ogt3xMU1yntbJ1M0LsC7Lshj7Fg1U3vs/MzHFHyMe4bt/BPyY15l0Zn8pcVoQA3c3mQsFYnzgTHxy+WPPl/iAL+2+XDn6EvKFZC+F3R0xwV8MchTs6NUgfSEzGfwDLprZkJyfgwcAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;vmfunc github suspended&quot;
        title=&quot;&quot;
        src=&quot;/static/69951f8a42152162c7a7634cfff70a94/99661/vmfunc-github-suspended.png&quot;
        srcset=&quot;/static/69951f8a42152162c7a7634cfff70a94/5a46d/vmfunc-github-suspended.png 300w,
/static/69951f8a42152162c7a7634cfff70a94/0a47e/vmfunc-github-suspended.png 600w,
/static/69951f8a42152162c7a7634cfff70a94/99661/vmfunc-github-suspended.png 1098w&quot;
        sizes=&quot;(max-width: 1098px) 100vw, 1098px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;
&lt;em&gt;&lt;a href=&quot;https://x.com/ThePrimeagen/status/1978261656573501510&quot;&gt;https://x.com/ThePrimeagen/status/1978261656573501510&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;This isn&apos;t new. In February 2024, even &lt;a href=&quot;https://news.ycombinator.com/item?id=39267200&quot;&gt;GitHub&apos;s co-founder and ex-CEO, Chris Wanstrath, had his account suspended&lt;/a&gt;.
Of course, GitHub immediately responded and removed the suspension for him but the rest of us may not be so fortunate.&lt;/p&gt;
&lt;p&gt;Here&apos;s a bunch of other such incidents&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/orgs/community/discussions/171069&quot;&gt;A student lost access to their bachelor&apos;s thesis and work repositories for &lt;strong&gt;2 months&lt;/strong&gt;&lt;/a&gt; due to GitHub Education verification issues&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/orgs/community/discussions/116763&quot;&gt;Developers waiting &lt;strong&gt;up to 120 days&lt;/strong&gt;&lt;/a&gt; for appeal responses&lt;/li&gt;
&lt;li&gt;Account suspended when trying out &lt;a href=&quot;https://github.com/orgs/community/discussions/48787&quot;&gt;Codespaces&lt;/a&gt; and no response for over a month&lt;/li&gt;
&lt;li&gt;Account suspended when &lt;a href=&quot;https://github.com/orgs/community/discussions/48787#discussioncomment-5296577&quot;&gt;submitting multiple bug reports&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;GitHub&apos;s automated systems can flag accounts without warning, and appeals can take months. The solution? Keep your own backups.&lt;/p&gt;
&lt;h2 id=&quot;backup-with-gickup&quot;&gt;Backup with gickup&lt;/h2&gt;
&lt;p&gt;I&apos;m using &lt;a href=&quot;https://github.com/cooperspencer/gickup&quot;&gt;gickup&lt;/a&gt; to backup my repositories hosted on GitHub. I run it on Kubernetes as a &lt;a href=&quot;https://github.com/adityathebe/homelab/blob/main/kubernetes/apps/default/gickup/helmrelease.yaml&quot;&gt;CronJob&lt;/a&gt;, but you can also use gickup&apos;s built-in cron runner.&lt;/p&gt;
&lt;p&gt;I schedule daily backups, which is sufficient since actively developed repos are typically already cloned on my machine.&lt;/p&gt;
&lt;p&gt;I&apos;m currently backing up to the local filesystem, which is backed up separately but gickup also offers backing up to various remotes like - GitLab, Gitea, Gogs, OneDev, Sourcehut, S3.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Disclaimer&lt;/strong&gt;: This post is not sponsored or affiliated with gickup in any way. I&apos;m sharing my personal backup solution that works for me. See the &quot;Alternative Tools&quot; section at the end for other options.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;setup&quot;&gt;Setup&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Create a GitHub Personal Access Token&lt;/strong&gt; with &lt;code class=&quot;language-text&quot;&gt;repo&lt;/code&gt; scope - &lt;a href=&quot;https://github.com/settings/personal-access-tokens&quot;&gt;https://github.com/settings/personal-access-tokens&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Configure&lt;/strong&gt; - create a &lt;code class=&quot;language-text&quot;&gt;conf.yaml&lt;/code&gt; with your GitHub username and backup destination&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Here&apos;s my &lt;code class=&quot;language-text&quot;&gt;conf.yaml&lt;/code&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;source&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;github&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
      &lt;span class=&quot;token key atrule&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; adityathebe
      &lt;span class=&quot;token key atrule&quot;&gt;exclude&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; adityathebe/DefinitelyTyped &lt;span class=&quot;token comment&quot;&gt;# too Large, idc&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; DefinitelyTyped

&lt;span class=&quot;token key atrule&quot;&gt;destination&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;local&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;/data/github-backups&apos;&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;structured&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean important&quot;&gt;true&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;mirror&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean important&quot;&gt;true&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;lfs&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean important&quot;&gt;false&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# setting this true was 100x slower&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;Instead of providing the github token on the config file, you can also set the &lt;code class=&quot;language-text&quot;&gt;GITHUB_TOKEN&lt;/code&gt; env var.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Key points:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Source&lt;/strong&gt;: All my GitHub repositories (excluding a few large ones)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Mirror mode&lt;/strong&gt;: This backs up all git refs (branches, tags, and pull request refs)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Structured&lt;/strong&gt;: Creates organized folders for each repository&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Once configured, it&apos;s completely hands-off.&lt;/p&gt;
&lt;h2 id=&quot;restoration&quot;&gt;Restoration&lt;/h2&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; clone gickup/github-backups/github.com/adityathebe/nvim.git&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;output&quot;&gt;&lt;pre class=&quot;language-output&quot;&gt;&lt;code class=&quot;language-output&quot;&gt;Cloning into &amp;#39;nvim&amp;#39;...
done.
admin@truenas[/mnt/mega/aditya/backups]$&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;alternative-tools&quot;&gt;Alternative Tools&lt;/h2&gt;
&lt;p&gt;While I use gickup, there are several other tools available for backing up GitHub repositories:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://github.com/ChappIO/git-backup&quot;&gt;git-backup&lt;/a&gt;&lt;/strong&gt; - A simple tool for backing up git repositories&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://www.reddit.com/r/selfhosted/comments/u6dww1/a_simple_way_to_backup_all_your_github_and_gitlab/i580m8f/&quot;&gt;Gitea mirror feature&lt;/a&gt;&lt;/strong&gt; - Use Gitea&apos;s built-in mirroring capabilities to backup repositories&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://github.com/clockfort/GitHub-Backup&quot;&gt;GitHub-Backup&lt;/a&gt;&lt;/strong&gt; - Another backup solution for GitHub repositories&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;Note: I haven&apos;t personally tested these alternatives, but they may better suit your specific needs.&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Delete all files in a Cloudflare R2 bucket using rclone]]></title><description><![CDATA[How to quickly delete all files from a Cloudflare R2 bucket using rclone instead of the web UI or AWS CLI]]></description><link>https://www.adityathebe.com/delete-cloudflare-r2-bucket-files-using-rclone</link><guid isPermaLink="false">https://www.adityathebe.com/delete-cloudflare-r2-bucket-files-using-rclone</guid><pubDate>Wed, 15 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;div class=&apos;post-tldr&apos;&gt;
&lt;h2 id=&quot;tldr&quot;&gt;TLDR&lt;/h2&gt;
&lt;p&gt;This post explains how to delete all files in a Cloudflare R2 bucket using rclone instead of the web UI or AWS CLI.&lt;/p&gt;
&lt;p&gt;Quick steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Get credentials&lt;/strong&gt;: Create an Account API Token in R2 dashboard with &quot;Object Read &amp;#x26; Write&quot; permission&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Configure rclone&lt;/strong&gt;: Add R2 credentials to &lt;code class=&quot;language-text&quot;&gt;~/.config/rclone/rclone.conf&lt;/code&gt; with &lt;code class=&quot;language-text&quot;&gt;type=s3&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;provider=Cloudflare&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Delete files&lt;/strong&gt;: Run rclone delete r2:/bucket-name/ -P&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;p&gt;Object storage services do not allow deleting a bucket without deleting all the files in it first.
R2&apos;s web UI doesn&apos;t have a &quot;Select All&quot; button that would make deletion a simple 2-click process.
If you have tons and tons of files, the web UI becomes impractical for bucket cleanup.&lt;/p&gt;
&lt;p&gt;Cloudflare suggests using the AWS CLI, but I prefer &lt;code class=&quot;language-text&quot;&gt;rclone&lt;/code&gt; (&lt;a href=&quot;https://rclone.org/&quot;&gt;https://rclone.org/&lt;/a&gt;) because it provides a unified interface for many cloud services - not just object storage like MinIO, S3, and Backblaze B2, but also services like Google Photos and Google Drive. For example, I&apos;ve used rclone to upload photos to Google Photos and download files from Google Drive.&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;rclone&lt;/code&gt; has a massive list of services that it supports. See here - &lt;a href=&quot;https://rclone.org/#providers&quot;&gt;https://rclone.org/#providers&lt;/a&gt;.
Install &lt;code class=&quot;language-text&quot;&gt;rclone&lt;/code&gt; (guide: &lt;a href=&quot;https://rclone.org/install/&quot;&gt;https://rclone.org/install/&lt;/a&gt;) and let&apos;s begin by creating an access key for your bucket.&lt;/p&gt;
&lt;h2 id=&quot;get-the-access-key&quot;&gt;Get the Access key&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;On the web UI, go to R2&apos;s dashboard and on the top right you should see &quot;&lt;strong&gt;Manage API tokens&lt;/strong&gt;&quot; button.&lt;/li&gt;
&lt;li&gt;Create an &lt;strong&gt;Account API Token&lt;/strong&gt; &lt;em&gt;(not the User API Token)&lt;/em&gt;. You need to select &quot;&lt;strong&gt;Object Read &amp;#x26; Write&lt;/strong&gt;&quot; permission with the correct bucket.&lt;/li&gt;
&lt;li&gt;On the next page, you should see the Access Key ID and the Secret Access Key.
Keep note of them and also the endpoint - we&apos;ll need them in a while.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 884px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/16020eeb10a4dbcb1096b211aea93a1f/136a2/cloudflare-r2-access-keys.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 70.33333333333334%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAAAsTAAALEwEAmpwYAAABR0lEQVR42q2SiW6EMAxE+f+PbJdul1LuBQKBHNOMOYoqpAq1kZ7sxIoZD4mmaULbtjtN06DrOjyfTwzDgKsr4qUsy6SRMQbzPEsk1lp47y8hDZMkQZ7nqKoKZVkKSimM4ygqj/DsDNYoIOKmrms5dM7hryuiX3Ec43a7IU1TUblBpYy0oygK8Zaen6G1XhTSM/6Mzbejh8zJdulYO0M8NGZG3/fC5hOVbJFfvjSyUgPKqt6fDNn8pCKOcalh2w94/8jEI2H1jfAtkuOeis+giNXDCarvwNGdswuhYAUj+YKRmvduB2vkNEQ8VJPHvdB4y0eJ92IM+YC77Jdc9uWMuLR4zc3OS2aQNA7NCFQK0CaMPFuPfrTf6JM8xHawaJRF/YNeu9DIYw6CnQ8NKROr/F/BGaFZsO3zMw1PSyPCPyy+hsfjIT/nC6zkRoXgf01+AAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;cloudflare r2 access keys&quot;
        title=&quot;&quot;
        src=&quot;/static/16020eeb10a4dbcb1096b211aea93a1f/136a2/cloudflare-r2-access-keys.png&quot;
        srcset=&quot;/static/16020eeb10a4dbcb1096b211aea93a1f/5a46d/cloudflare-r2-access-keys.png 300w,
/static/16020eeb10a4dbcb1096b211aea93a1f/0a47e/cloudflare-r2-access-keys.png 600w,
/static/16020eeb10a4dbcb1096b211aea93a1f/136a2/cloudflare-r2-access-keys.png 884w&quot;
        sizes=&quot;(max-width: 884px) 100vw, 884px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;h2 id=&quot;setup-rclone&quot;&gt;Setup rclone&lt;/h2&gt;
&lt;p&gt;You can either use the setup wizard using the &lt;code class=&quot;language-text&quot;&gt;rclone config&lt;/code&gt; command or just use this template and place it in &lt;code class=&quot;language-text&quot;&gt;~/.config/rclone/rclone.conf&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;toml&quot;&gt;&lt;pre class=&quot;language-toml&quot;&gt;&lt;code class=&quot;language-toml&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token table class-name&quot;&gt;r2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token key property&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; s3
&lt;span class=&quot;token key property&quot;&gt;provider&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; Cloudflare
&lt;span class=&quot;token key property&quot;&gt;access_key_id&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; 6b82af45b9a94e281cd5ba7b111b68fe
&lt;span class=&quot;token key property&quot;&gt;secret_access_key&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; 61f58485d481ad5980635c388e5740f9a8abf94ab5b5acc442c1effb08a081b6
&lt;span class=&quot;token key property&quot;&gt;endpoint&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; https://5bdd9766a7ad14ae145db477f519gs21&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;r2&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cloudflarestorage&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;com&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Verify that the config was created properly.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;rclone listremotes &lt;span class=&quot;token parameter variable&quot;&gt;--long&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;output&quot;&gt;&lt;pre class=&quot;language-output&quot;&gt;&lt;code class=&quot;language-output&quot;&gt;r2:                  s3&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;emptying-the-bucket&quot;&gt;Emptying the bucket&lt;/h2&gt;
&lt;p&gt;My bucket is named &lt;code class=&quot;language-text&quot;&gt;longhorn&lt;/code&gt; so this is the command I ran. The &lt;code class=&quot;language-text&quot;&gt;-P&lt;/code&gt; flag shows the progress.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;rclone delete r2:/longhorn/ &lt;span class=&quot;token parameter variable&quot;&gt;-P&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;output&quot;&gt;&lt;pre class=&quot;language-output&quot;&gt;&lt;code class=&quot;language-output&quot;&gt;Transferred:              0 B / 0 B, -, 0 B/s, ETA -
Checks:                29 / 37, 78%, Listed 100
Deleted:               37 (files), 0 (dirs), 41.254 MiB (freed)
Elapsed time:         1.5s
Checking:
 * backups/backupstore/vo…c759acc982e2aff860.blk: deleting
 * backups/backupstore/vo…f23cab54f4acad0772.blk: deleting
 * backups/backupstore/vo…f27e50d08a22c62ab5.blk: deleting
 * backups/backupstore/vo…e80924cddebd00517b.blk: deleting
 * backups/backupstore/vo…92910deb42c89ff38f.blk: deleting
 * backups/backupstore/vo…6262258659adcdee58.blk: deleting
 * backups/backupstore/vo…f3ebd0010bfda1e995.blk: deleting
 * backups/backupstore/vo…606dd94efb994185b1.blk: deleting&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Fix invalid version: unknown revision from go get]]></title><description><![CDATA[Running go get on a version that hasn't been released poisons the go proxy cache.
Here's how you can bypass the cache and hit the module directly.
]]></description><link>https://www.adityathebe.com/bypass-go-get-cache</link><guid isPermaLink="false">https://www.adityathebe.com/bypass-go-get-cache</guid><pubDate>Mon, 13 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;go get&lt;/code&gt; by default talks to a proxy server - &lt;a href=&quot;https://proxy.golang.org&quot;&gt;https://proxy.golang.org&lt;/a&gt;.
The proxy server then fetches the module, caches it and returns it to you.&lt;/p&gt;
&lt;p&gt;If you request a version before it&apos;s published, the proxy gets a 404 and caches that negative response.
You&apos;ll then encounter an error like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;go get github.com/flanksource/duty@v1.0.1111&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;output&quot;&gt;&lt;pre class=&quot;language-output&quot;&gt;&lt;code class=&quot;language-output&quot;&gt;go: github.com/flanksource/duty@v1.0.1111: reading github.com/flanksource/duty/go.mod at revision v1.0.1111: unknown revision v1.0.1111&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I&apos;ve run into this issue even when running &lt;code class=&quot;language-text&quot;&gt;go get&lt;/code&gt; immediately after a new release.
According to the proxy documentation, new versions may not show up immediately but should be available within one minute:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;In order to improve our services&apos; caching and serving latencies, new versions may not show up right away ...
The new version should be available within one minute...&quot;&lt;/p&gt;
&lt;p&gt;- &lt;a href=&quot;https://proxy.golang.org/&quot;&gt;https://proxy.golang.org/&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This poisoned cache can persist even after the version is published, which is why you may still get 404 errors for up to 30 minutes even after a release.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;it may take up to 30 minutes for the mirror&apos;s cache to expire and fresh data about the version to become available&quot;&lt;/p&gt;
&lt;p&gt;- &lt;a href=&quot;https://proxy.golang.org/&quot;&gt;https://proxy.golang.org/&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;To understand what&apos;s happening behind the scenes, use the &lt;code class=&quot;language-text&quot;&gt;-x&lt;/code&gt; flag to see which servers &lt;code class=&quot;language-text&quot;&gt;go get&lt;/code&gt; contacts:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;go get &lt;span class=&quot;token parameter variable&quot;&gt;-x&lt;/span&gt; github.com/labstack/echo&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;output&quot;&gt;&lt;pre class=&quot;language-output&quot;&gt;&lt;code class=&quot;language-output&quot;&gt;# get https://proxy.golang.org/github.com/@v/list
# get https://proxy.golang.org/github.com/labstack/@v/list
# get https://proxy.golang.org/github.com/labstack/echo/@v/list
# get https://proxy.golang.org/github.com/labstack/echo/@v/list: 200 OK (0.914s)
# get https://proxy.golang.org/github.com/labstack/@v/list: 404 Not Found (0.940s)
# get https://proxy.golang.org/github.com/@v/list: 404 Not Found (0.940s)
# get https://proxy.golang.org/golang.org/x/crypto/@v/list
# get https://proxy.golang.org/github.com/labstack/gommon/@v/list&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As you can see, every request goes through the proxy.&lt;/p&gt;
&lt;h2 id=&quot;the-solution&quot;&gt;The Solution&lt;/h2&gt;
&lt;p&gt;To bypass the poisoned cache, you can override the default proxy using the &lt;code class=&quot;language-text&quot;&gt;GOPROXY&lt;/code&gt; environment variable. Setting it to &lt;code class=&quot;language-text&quot;&gt;direct&lt;/code&gt; skips all proxy servers and fetches directly from the module repository.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;inline-svg&quot; role=&quot;img&quot; aria-label=&quot;Go Module Mirror&quot;&gt;&lt;svg version=&quot;1.1&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; viewBox=&quot;0 0 1310.015625 745.41796875&quot; width=&quot;100%&quot; height=&quot;100%&quot;&gt;&lt;!-- svg-source:excalidraw --&gt;&lt;metadata&gt;&lt;/metadata&gt;&lt;defs&gt;&lt;style class=&quot;style-fonts&quot;&gt;
      @font-face { font-family: Excalifont; src: url(data:font/woff2;base64,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); }&lt;/style&gt;&lt;/defs&gt;&lt;rect x=&quot;0&quot; y=&quot;0&quot; width=&quot;1310.015625&quot; height=&quot;745.41796875&quot; fill=&quot;none&quot;&gt;&lt;/rect&gt;&lt;g stroke-linecap=&quot;round&quot; transform=&quot;translate(632.98828125 10) rotate(0 78.30859375 227.97265624999997)&quot;&gt;&lt;path d=&quot;M32 0 C61.04 2.5, 80.57 2.49, 124.62 0 C143.96 0.83, 156.58 7.94, 156.62 32 C158.36 154.12, 158.12 278.05, 156.62 423.95 C158.25 445.48, 146.22 459.13, 124.62 455.95 C100.97 456.71, 69.46 454.57, 32 455.95 C9.88 456.97, 2.49 444.78, 0 423.95 C-3.93 312.96, -3.5 206.21, 0 32 C-2.62 13.78, 14.2 2.13, 32 0&quot; stroke=&quot;none&quot; stroke-width=&quot;0&quot; fill=&quot;var(--color-good)&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M32 0 C61.24 -1.03, 90.55 -2.68, 124.62 0 M32 0 C68.27 -1.01, 106.08 -0.92, 124.62 0 M124.62 0 C146.42 1.76, 156.4 10.95, 156.62 32 M124.62 0 C146.26 2.1, 156.31 10.41, 156.62 32 M156.62 32 C154.98 139.1, 155.74 246.49, 156.62 423.95 M156.62 32 C154.8 179.69, 154.47 327.15, 156.62 423.95 M156.62 423.95 C155.67 446.67, 147.11 457.37, 124.62 455.95 M156.62 423.95 C155.53 445.96, 147.92 458.08, 124.62 455.95 M124.62 455.95 C96.48 454.54, 66.32 454.74, 32 455.95 M124.62 455.95 C88.12 455.63, 52.9 456.39, 32 455.95 M32 455.95 C11.39 454.94, 1.39 445.3, 0 423.95 M32 455.95 C11.64 456.12, -1.43 445.75, 0 423.95 M0 423.95 C-0.3 321.03, 1.3 217.32, 0 32 M0 423.95 C-0.69 329.4, -0.33 234.4, 0 32 M0 32 C1.93 10.21, 12.38 -1, 32 0 M0 32 C-2.07 9.36, 12.05 -1.4, 32 0&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(679.5168914794922 212.97265624999994) rotate(0 31.779983520507812 25)&quot;&gt;&lt;text x=&quot;31.779983520507812&quot; y=&quot;17.619999999999997&quot; font-family=&quot;Excalifont, Xiaolai, sans-serif, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;module&lt;/text&gt;&lt;text x=&quot;31.779983520507812&quot; y=&quot;42.62&quot; font-family=&quot;Excalifont, Xiaolai, sans-serif, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;mirror&lt;/text&gt;&lt;/g&gt;&lt;g stroke-linecap=&quot;round&quot; transform=&quot;translate(962.88671875 632.26953125) rotate(0 168.564453125 51.57421875)&quot;&gt;&lt;path d=&quot;M25.79 0 C112.66 -1.64, 195.27 -2.26, 311.34 0 C330.08 1.01, 337.88 6.47, 337.13 25.79 C337.67 37.53, 339.04 51.77, 337.13 77.36 C333.98 95.8, 325.9 105.89, 311.34 103.15 C230.64 101.47, 149.77 100.02, 25.79 103.15 C6.92 103.28, 3.46 97.96, 0 77.36 C-0.05 61.99, 0.68 47.65, 0 25.79 C-3.01 8.17, 8.07 0.22, 25.79 0&quot; stroke=&quot;none&quot; stroke-width=&quot;0&quot; fill=&quot;var(--color-good-2)&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M25.79 0 C112.95 -3.31, 198.86 -0.43, 311.34 0 M25.79 0 C130.09 0.08, 235.24 -0.24, 311.34 0 M311.34 0 C328.13 1.18, 337.69 7.14, 337.13 25.79 M311.34 0 C327.18 -1.2, 339.08 6.92, 337.13 25.79 M337.13 25.79 C339.52 46.29, 336.14 64.78, 337.13 77.36 M337.13 25.79 C336.69 39.02, 337.89 50.98, 337.13 77.36 M337.13 77.36 C338.88 96.15, 328.08 103.32, 311.34 103.15 M337.13 77.36 C338.74 95.91, 328.18 101.93, 311.34 103.15 M311.34 103.15 C204.07 105.35, 94.52 103.89, 25.79 103.15 M311.34 103.15 C243.14 101.96, 175.37 102.74, 25.79 103.15 M25.79 103.15 C9.77 104.78, 0.83 93.31, 0 77.36 M25.79 103.15 C10.5 102.14, 1.84 93.05, 0 77.36 M0 77.36 C-1.23 63.12, 0.54 50.8, 0 25.79 M0 77.36 C0.31 62.88, 0.02 50.02, 0 25.79 M0 25.79 C1.36 6.82, 9.95 -0.92, 25.79 0 M0 25.79 C-0.6 8.42, 8.34 1.93, 25.79 0&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(990.2312622070312 671.34375) rotate(0 141.21990966796875 12.5)&quot;&gt;&lt;text x=&quot;141.21990966796875&quot; y=&quot;17.619999999999997&quot; font-family=&quot;Excalifont, Xiaolai, sans-serif, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;github.com/adityathebe/hello&lt;/text&gt;&lt;/g&gt;&lt;g stroke-linecap=&quot;round&quot; transform=&quot;translate(10 132.57226562499994) rotate(0 205.0546875 105.40039062499997)&quot;&gt;&lt;path d=&quot;M32 0 C147.78 -1.84, 265.6 -2.91, 378.11 0 C400.24 0.85, 411.68 10.35, 410.11 32 C410.16 70.06, 405.78 110.77, 410.11 178.8 C410.71 202.19, 397.94 211.44, 378.11 210.8 C286.3 205.22, 191.21 207.09, 32 210.8 C11.48 213.47, -0.72 200.67, 0 178.8 C-2.37 121.22, -0.86 66.18, 0 32 C0.94 9.64, 8.65 0.28, 32 0&quot; stroke=&quot;none&quot; stroke-width=&quot;0&quot; fill=&quot;var(--color-good-3)&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M32 0 C112.82 -0.73, 193.92 -2.94, 378.11 0 M32 0 C109.58 0.73, 186.92 -0.26, 378.11 0 M378.11 0 C399.1 -0.95, 408.71 11.31, 410.11 32 M378.11 0 C400.85 1.34, 410.77 8.97, 410.11 32 M410.11 32 C409.29 76.89, 409.35 116.76, 410.11 178.8 M410.11 32 C411.08 71.17, 410.94 111.07, 410.11 178.8 M410.11 178.8 C410.42 199.52, 401.29 212.66, 378.11 210.8 M410.11 178.8 C409.79 199.26, 398.35 211.52, 378.11 210.8 M378.11 210.8 C263.75 212.49, 146.92 211.39, 32 210.8 M378.11 210.8 C271.61 210.14, 165.23 209.6, 32 210.8 M32 210.8 C12.03 212.15, 0.48 199.71, 0 178.8 M32 210.8 C10.62 212.07, 1.7 202.09, 0 178.8 M0 178.8 C0.02 135.73, -0.95 90.75, 0 32 M0 178.8 C-1.62 122.47, -0.86 66.82, 0 32 M0 32 C-1.03 10.41, 9.78 1.42, 32 0 M0 32 C0.56 12.6, 12.8 -1.78, 32 0&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(37.83479309082031 225.47265624999994) rotate(0 177.2198944091797 12.5)&quot;&gt;&lt;text x=&quot;177.2198944091797&quot; y=&quot;17.619999999999997&quot; font-family=&quot;Excalifont, Xiaolai, sans-serif, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;go get github.com/adityathebe/hello&lt;/text&gt;&lt;/g&gt;&lt;g stroke-linecap=&quot;round&quot;&gt;&lt;g transform=&quot;translate(423.6718750000001 240.671691358519) rotate(0 103.01562499999983 -2.4441089075583022)&quot;&gt;&lt;path d=&quot;M-0.49 0.38 C33.54 -0.37, 171.13 -3.39, 205.38 -4.08 M1.45 -0.47 C35.77 -1.58, 173.43 -4.93, 207.76 -5.78&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(423.6718750000001 240.671691358519) rotate(0 103.01562499999983 -2.4441089075583022)&quot;&gt;&lt;path d=&quot;M184.48 3.35 C194.39 -1.28, 204.42 -5.51, 207.76 -5.78 M184.48 3.35 C193.5 -1.11, 203.54 -4.61, 207.76 -5.78&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(423.6718750000001 240.671691358519) rotate(0 103.01562499999983 -2.4441089075583022)&quot;&gt;&lt;path d=&quot;M184.06 -13.75 C194.19 -11.54, 204.39 -8.93, 207.76 -5.78 M184.06 -13.75 C193.26 -11.48, 203.46 -8.27, 207.76 -5.78&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;/g&gt;&lt;mask&gt;&lt;/mask&gt;&lt;g stroke-linecap=&quot;round&quot;&gt;&lt;g transform=&quot;translate(795.1835937500002 218.73917515688373) rotate(0 169.51367187499977 205.69486554655805)&quot;&gt;&lt;path d=&quot;M1.1 0.65 C44.22 20, 201.78 47.83, 258.27 116.28 C314.77 184.74, 326.53 362.11, 340.09 411.38 M0.22 -0.05 C43.27 19.4, 201.01 48.5, 257.62 117.29 C314.23 186.08, 326.12 363.97, 339.89 412.69&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(795.1835937500002 218.73917515688373) rotate(0 169.51367187499977 205.69486554655805)&quot;&gt;&lt;path d=&quot;M327.27 391.11 C331.74 397.66, 332.31 404.22, 339.89 412.69 M327.27 391.11 C330.38 396.95, 335.02 403.86, 339.89 412.69&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(795.1835937500002 218.73917515688373) rotate(0 169.51367187499977 205.69486554655805)&quot;&gt;&lt;path d=&quot;M344.1 388.05 C344.11 395.56, 340.21 402.94, 339.89 412.69 M344.1 388.05 C342.19 394.88, 341.8 402.7, 339.89 412.69&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;/g&gt;&lt;mask&gt;&lt;/mask&gt;&lt;g mask=&quot;url(#mask-wA5TG398pZruY-Z0BzWik)&quot; stroke-linecap=&quot;round&quot;&gt;&lt;g transform=&quot;translate(195.7636595890899 354.7753906249999) rotate(0 382.65918583045504 165.93847656249991)&quot;&gt;&lt;path d=&quot;M0.42 1.19 C28.92 55.43, 42.33 270.24, 169.87 325.27 C297.41 380.3, 666.46 330.37, 765.66 331.36&quot; stroke=&quot;var(--color-good)&quot; stroke-width=&quot;2.5&quot; fill=&quot;none&quot; stroke-dasharray=&quot;8 10&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(195.7636595890899 354.7753906249999) rotate(0 382.65918583045504 165.93847656249991)&quot;&gt;&lt;path d=&quot;M742.7 341.26 C749.45 338.9, 753.62 337.65, 765.66 331.36&quot; stroke=&quot;var(--color-good)&quot; stroke-width=&quot;2.5&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(195.7636595890899 354.7753906249999) rotate(0 382.65918583045504 165.93847656249991)&quot;&gt;&lt;path d=&quot;M741.71 324.19 C748.63 325.36, 753.01 327.64, 765.66 331.36&quot; stroke=&quot;var(--color-good)&quot; stroke-width=&quot;2.5&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;/g&gt;&lt;mask id=&quot;mask-wA5TG398pZruY-Z0BzWik&quot;&gt;&lt;rect x=&quot;0&quot; y=&quot;0&quot; fill=&quot;#fff&quot; width=&quot;1061.08203125&quot; height=&quot;786.6523437499998&quot;&gt;&lt;/rect&gt;&lt;rect x=&quot;282.7273864746094&quot; y=&quot;666.71484375&quot; fill=&quot;var(--toggle-bg-color)&quot; width=&quot;166.09991455078125&quot; height=&quot;25&quot; opacity=&quot;1&quot;&gt;&lt;/rect&gt;&lt;/mask&gt;&lt;g transform=&quot;translate(282.7273864746094 666.71484375) rotate(0 296.07681283881163 -135.76214739467602)&quot;&gt;&lt;text x=&quot;83.04995727539062&quot; y=&quot;17.619999999999997&quot; font-family=&quot;Excalifont, Xiaolai, sans-serif, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--color-good)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;GOPROXY=direct&lt;/text&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token assign-left variable&quot;&gt;GOPROXY&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;direct go get &lt;span class=&quot;token parameter variable&quot;&gt;-x&lt;/span&gt; github.com/labstack/echo&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;output&quot;&gt;&lt;pre class=&quot;language-output&quot;&gt;&lt;code class=&quot;language-output&quot;&gt;mkdir -p /Users/aditya/go/pkg/mod/cache/vcs # git3 https://github.com/labstack/echo
# lock /Users/aditya/go/pkg/mod/cache/vcs/84bf749277ea54683052733eb9a9f7ea7f43e18090bed6ec5b8281cdee0a1f11.lock
mkdir -p /Users/aditya/go/pkg/mod/cache/vcs/84bf749277ea54683052733eb9a9f7ea7f43e18090bed6ec5b8281cdee0a1f11 # git3 https://github.com/labstack/echo
cd /Users/aditya/go/pkg/mod/cache/vcs/84bf749277ea54683052733eb9a9f7ea7f43e18090bed6ec5b8281cdee0a1f11; git ls-remote -q https://github.com/labstack/echo
1.158s # cd /Users/aditya/go/pkg/mod/cache/vcs/84bf749277ea54683052733eb9a9f7ea7f43e18090bed6ec5b8281cdee0a1f11; git ls-remote -q https://github.com/labstack/echo
cd /Users/aditya/go/pkg/mod/cache/vcs/84bf749277ea54683052733eb9a9f7ea7f43e18090bed6ec5b8281cdee0a1f11; git init --bare&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now &lt;code class=&quot;language-text&quot;&gt;go get&lt;/code&gt; clones the repository directly using Git, completely bypassing the proxy cache and fetching the latest version from the source.&lt;/p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://proxy.golang.org/&quot;&gt;https://proxy.golang.org/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://stackoverflow.com/a/67678279&quot;&gt;https://stackoverflow.com/a/67678279&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Git Objects]]></title><description><![CDATA[The best way to take your git knowledge to the next level is to understand the 4 fundamental objects in git.]]></description><link>https://www.adityathebe.com/git-objects</link><guid isPermaLink="false">https://www.adityathebe.com/git-objects</guid><pubDate>Sun, 12 Oct 2025 15:45:00 GMT</pubDate><content:encoded>&lt;p&gt;I have been using Git for almost a decade now and I&apos;m ashamed to admit that it was only today that I decided to get into the internals of Git.
I feel like I&apos;ve tried doing this before, but there just wasn&apos;t enough motivation at the time.&lt;/p&gt;
&lt;p&gt;But today was the perfect day for it because as it just so happens I lost one of my uncommitted files due to &lt;code class=&quot;language-text&quot;&gt;git reset --hard&lt;/code&gt;.
It was one file - a new weekly journal I was about to publish that had notes I&apos;d written throughout the week.
I know I had read somewhere that git still keeps file around so there&apos;s a possibility I could recover it.&lt;/p&gt;
&lt;p&gt;I asked &lt;a href=&quot;https://developers.openai.com/codex/cli/&quot;&gt;OpenAI&apos;s Codex&lt;/a&gt; to recover it. It ran a whole bunch of git commands and finally reported that it was impossible to recover. My file was permanently gone!
Then, I asked &lt;a href=&quot;https://www.claude.com/product/claude-code&quot;&gt;Claude Code&lt;/a&gt; to do it. Interestingly, it was able to recover my files after running a few git commands.&lt;/p&gt;
&lt;p&gt;I went through the commands that Claude ran to understand how it was able to do so, and one thing led to another, and I was already deep into Git documentation and learning about the four fundamental objects in git.&lt;/p&gt;
&lt;div class=&quot;section-notes&quot;&gt;
Since git-scm.com already does a fantastic job of explaining what the fundamental objects are, I&apos;ll focus this post on the hands-on experience of actually viewing and exploring them.
I&apos;ll also not be talking about the file recovery process - that&apos;s for another time.
&lt;/div&gt;
&lt;p&gt;&lt;span class=&quot;paragraph-break&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h2 id=&quot;git-command-categories&quot;&gt;Git Command Categories&lt;/h2&gt;
&lt;p&gt;Before jumping right into the git&apos;s objects internals, I think it helps to understand the git command categories&lt;/p&gt;
&lt;p&gt;Source: &lt;a href=&quot;https://git-scm.com/book/en/v2/Git-Internals-Plumbing-and-Porcelain&quot;&gt;https://git-scm.com/book/en/v2/Git-Internals-Plumbing-and-Porcelain&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;As a precursor, I think it&apos;s helpful to understand that git classifies the commands as&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Porcelain&lt;/strong&gt;: User facing, polished and highlevel&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Plumbing&lt;/strong&gt;: Low level. End users generally do not use it.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As far as I know, it&apos;s a Git specific taxonomy.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;because Git was initially a toolkit for a version control system rather than a full user-friendly VCS, it has a number of subcommands that do low-level work and were designed to be chained together UNIX-style or called from scripts. These commands are generally referred to as Git’s “plumbing” commands, while the more user-friendly commands are called “porcelain” commands.&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;span class=&quot;paragraph-break&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h2 id=&quot;git-objects&quot;&gt;Git Objects&lt;/h2&gt;
&lt;p&gt;Git has 4 fundamental objects - &lt;code class=&quot;language-text&quot;&gt;blob&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;tree&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;commit&lt;/code&gt;, and &lt;code class=&quot;language-text&quot;&gt;tag&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Let&apos;s create an empty repo and explore how git stores these objects and what they are.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token function&quot;&gt;mkdir&lt;/span&gt; my-project
&lt;span class=&quot;token builtin class-name&quot;&gt;cd&lt;/span&gt; my-project
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; init&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;output&quot;&gt;&lt;pre class=&quot;language-output&quot;&gt;&lt;code class=&quot;language-output&quot;&gt;Initialized empty Git repository in /Users/aditya/my-project/.git/&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Git stores everything about the repository in a &lt;code class=&quot;language-text&quot;&gt;.git&lt;/code&gt; directory. Let&apos;s take a peek.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;tree .git&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;output&quot;&gt;&lt;pre class=&quot;language-output&quot;&gt;&lt;code class=&quot;language-output&quot;&gt;.git
├── config
├── description
├── HEAD
├── hooks
│   ├── applypatch-msg.sample
│   ├── commit-msg.sample
│   ├── fsmonitor-watchman.sample
│   ├── post-update.sample
│   ├── pre-applypatch.sample
│   ├── pre-commit.sample
│   ├── pre-merge-commit.sample
│   ├── pre-push.sample
│   ├── pre-rebase.sample
│   ├── pre-receive.sample
│   ├── prepare-commit-msg.sample
│   ├── push-to-checkout.sample
│   └── update.sample
├── info
│   └── exclude
├── objects
│   ├── info
│   └── pack
└── refs
    ├── heads
    └── tags

9 directories, 17 files&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;By default, git creates a few place holder directories even on an empty repository.
The &lt;code class=&quot;language-text&quot;&gt;.git/objects&lt;/code&gt; dir comes with 2 empty directories &lt;code class=&quot;language-text&quot;&gt;info&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;pack&lt;/code&gt; but let&apos;s ignore them for now.&lt;/p&gt;
&lt;p&gt;Let&apos;s create a new file and make a commit to have some objects we can explore.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;hello world&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; first.txt
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;.&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; commit &lt;span class=&quot;token parameter variable&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;my first commit&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;output&quot;&gt;&lt;pre class=&quot;language-output&quot;&gt;&lt;code class=&quot;language-output&quot;&gt;[main (root-commit) 8dae705] my first commit
 1 file changed, 1 insertion(+)
 create mode 100644 first.txt&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;commit&quot;&gt;Commit&lt;/h3&gt;
&lt;p&gt;We have a commit with hash &lt;code class=&quot;language-text&quot;&gt;8dae705&lt;/code&gt;. We&apos;ll be using the plumbing command &lt;code class=&quot;language-text&quot;&gt;git cat-file&lt;/code&gt; to view the objects.
Let&apos;s start with the commit&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; cat-file &lt;span class=&quot;token parameter variable&quot;&gt;-p&lt;/span&gt; 8dae705&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;output&quot;&gt;&lt;pre class=&quot;language-output&quot;&gt;&lt;code class=&quot;language-output&quot;&gt;tree 2c06b36b1c3de1c0b0de9897b23c70bf835dc190
author Aditya Thebe &amp;lt;contact@adityathebe.com&amp;gt; 1760258223 +0545
committer Aditya Thebe &amp;lt;contact@adityathebe.com&amp;gt; 1760258223 +0545
gpgsig -----BEGIN SSH SIGNATURE-----
 U1NIU0lHAAAAAQAAADMAAAALc3NoLWVkMjU1MTkAAAAgOzmsUfKA9Ly4Ir4snhc6l6dWsa
 TplTM0tvrD14WJQjwAAAADZ2l0AAAAAAAAAAZzaGE1MTIAAABTAAAAC3NzaC1lZDI1NTE5
 AAAAQMO7YaDnbTdHKlp8Y42wpwAJM+EMzVRJoW5HeNU+Rc4HjvXAr+fH1vYxmIDkRJZGSA
 vgSRhG3q6QsAxzbXS/dQo=
 -----END SSH SIGNATURE-----

my first commit&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;A commit object is just a pointer to a tree object with some additional metadata like the author, commit time, signatures, commit message, and so on.
In this case, the commit points to the tree &lt;code class=&quot;language-text&quot;&gt;2c06b36b1c3de1c0b0de9897b23c70bf835dc190&lt;/code&gt; &lt;em&gt;(see the first line of the output)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;If you notice, we use the &lt;code class=&quot;language-text&quot;&gt;-p&lt;/code&gt; flag which pretty prints the contents of the object.
As you&apos;ll see in a while, &lt;code class=&quot;language-text&quot;&gt;git cat-file&lt;/code&gt; can print objects of all types. That should tell you that all objects have a hash (not just commits).&lt;/p&gt;
&lt;p&gt;Try out these other flags...&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; cat-file &lt;span class=&quot;token parameter variable&quot;&gt;-t&lt;/span&gt; 8dae705 &lt;span class=&quot;token comment&quot;&gt;# show the object type&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;output&quot;&gt;&lt;pre class=&quot;language-output&quot;&gt;&lt;code class=&quot;language-output&quot;&gt;commit&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; cat-file &lt;span class=&quot;token parameter variable&quot;&gt;-s&lt;/span&gt; 8dae705 &lt;span class=&quot;token comment&quot;&gt;# show the object size in bytes&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;output&quot;&gt;&lt;pre class=&quot;language-output&quot;&gt;&lt;code class=&quot;language-output&quot;&gt;498&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;tree&quot;&gt;Tree:&lt;/h3&gt;
&lt;p&gt;Since we have the tree hash, let&apos;s take a peek into it as well&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; cat-file &lt;span class=&quot;token parameter variable&quot;&gt;-p&lt;/span&gt; 2c06b36b1c3de1c0b0de9897b23c70bf835dc190&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;output&quot;&gt;&lt;pre class=&quot;language-output&quot;&gt;&lt;code class=&quot;language-output&quot;&gt;100644 blob 3b18e512dba79e4c8300dd08aeb37f8e728b8dad    first.txt&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; cat-file &lt;span class=&quot;token parameter variable&quot;&gt;-t&lt;/span&gt; 2c06b36b1c3de1c0b0de9897b23c70bf835dc190&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;output&quot;&gt;&lt;pre class=&quot;language-output&quot;&gt;&lt;code class=&quot;language-output&quot;&gt;tree&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The output lists all the files in the project at the time of commit. That&apos;s what a tree basically is - a snapshot of the directory listing of the project.&lt;/p&gt;
&lt;p&gt;Let&apos;s create a few more files and see how the tree appears for them&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;another file&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; second.txt
&lt;span class=&quot;token function&quot;&gt;mkdir&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;src&quot;&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;console.log(&apos;hello world&apos;)&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; src/index.js&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is what the project should look like at this stage&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;tree&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;output&quot;&gt;&lt;pre class=&quot;language-output&quot;&gt;&lt;code class=&quot;language-output&quot;&gt;.
├── first.txt
├── second.txt
└── src
    └── index.js&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Let&apos;s commit this.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; commit &lt;span class=&quot;token parameter variable&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;second commit&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;output&quot;&gt;&lt;pre class=&quot;language-output&quot;&gt;&lt;code class=&quot;language-output&quot;&gt;[main c5fa6f4] second commit
 2 files changed, 2 insertions(+)
 create mode 100644 second.txt
 create mode 100644 src/index.js&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Let&apos;s get the tree hash for this new commit&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; cat-file &lt;span class=&quot;token parameter variable&quot;&gt;-p&lt;/span&gt; c5fa6f4&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;output&quot;&gt;&lt;pre class=&quot;language-output&quot;&gt;&lt;code class=&quot;language-output&quot;&gt;tree 8b5a93d517fa8c8d9825f3c711f7cef02310ad91
parent 8dae70599ee87f208e86ad4ff65e9b05bf777630
author Aditya Thebe &amp;lt;contact@adityathebe.com&amp;gt; 1760259042 +0545
committer Aditya Thebe &amp;lt;contact@adityathebe.com&amp;gt; 1760259042 +0545
gpgsig -----BEGIN SSH SIGNATURE-----
 U1NIU0lHAAAAAQAAADMAAAALc3NoLWVkMjU1MTkAAAAgOzmsUfKA9Ly4Ir4snhc6l6dWsa
 TplTM0tvrD14WJQjwAAAADZ2l0AAAAAAAAAAZzaGE1MTIAAABTAAAAC3NzaC1lZDI1NTE5
 AAAAQBJcQdTma1GZumNRb4ALX0ZY8zJJdtWq17Tzzcobg3QxgHeRUnwIxG1Rsf8IT1pT6O
 PQHeRS4OrzPS3zezQb8AY=
 -----END SSH SIGNATURE-----

second commit&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; cat-file &lt;span class=&quot;token parameter variable&quot;&gt;-p&lt;/span&gt; 8b5a93d517fa8c8d9825f3c711f7cef02310ad91&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;output&quot;&gt;&lt;pre class=&quot;language-output&quot;&gt;&lt;code class=&quot;language-output&quot;&gt;100644 blob 3b18e512dba79e4c8300dd08aeb37f8e728b8dad    first.txt
100644 blob 17d5d9edf31a80878ad4911017cbd6d1d03322b8    second.txt
040000 tree 354f422855eb94b6325210f7dee06ffa8f91dfd0    src&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Perfect, this second tree shows exactly what the project structure was like at the time of the second commit.
If you notice, the tree object stores the directory structure for just one level, and the subdirectory &lt;code class=&quot;language-text&quot;&gt;src&lt;/code&gt; is represented by another tree &lt;code class=&quot;language-text&quot;&gt;354f422855eb94b6325210f7dee06ffa8f91dfd0&lt;/code&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; cat-file &lt;span class=&quot;token parameter variable&quot;&gt;-p&lt;/span&gt; 354f422855eb94b6325210f7dee06ffa8f91dfd0 &lt;span class=&quot;token comment&quot;&gt;# another tree&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;output&quot;&gt;&lt;pre class=&quot;language-output&quot;&gt;&lt;code class=&quot;language-output&quot;&gt;100644 blob cea4f10350c7c3a4acb44629234b5502c24d0989    index.js&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We have explored commit and trees. But where are the files actually stored? That&apos;s where &lt;code class=&quot;language-text&quot;&gt;blob&lt;/code&gt; comes in.&lt;/p&gt;
&lt;h3 id=&quot;blob&quot;&gt;Blob:&lt;/h3&gt;
&lt;p&gt;You must have noticed, when viewing the tree object, some of the listings were blob.
Let&apos;s take a look at the blob representing first.txt file&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; cat-file &lt;span class=&quot;token parameter variable&quot;&gt;-p&lt;/span&gt; 3b18e512dba79e4c8300dd08aeb37f8e728b8dad&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;output&quot;&gt;&lt;pre class=&quot;language-output&quot;&gt;&lt;code class=&quot;language-output&quot;&gt;hello world&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;A blob object stores the content of a file &lt;strong&gt;without&lt;/strong&gt; the metadata like size, extension, timestamp, filename, permission.
Some of those metadata are stored in the tree object while some metadata are never tracked by git like the creation timestamp.&lt;/p&gt;
&lt;h3 id=&quot;tags&quot;&gt;Tags:&lt;/h3&gt;
&lt;p&gt;Tags are pointer to another git object - most commonly a commit - with additional metadata like annotations, tagger information, and a message.&lt;/p&gt;
&lt;p&gt;There are two types of tags in Git:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Lightweight tags&lt;/strong&gt;: Simple pointers to commits (not stored as objects)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Annotated tags&lt;/strong&gt;: Full objects stored in Git&apos;s database with tagger name, email, date, and a message&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Let&apos;s create an annotated tag to explore it:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; tag &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; v1.0 &lt;span class=&quot;token parameter variable&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;First release&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To list all the tags&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; tag&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We do not need the tag&apos;s hash as &lt;code class=&quot;language-text&quot;&gt;cat-file&lt;/code&gt; command can also accept the tag name directly.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; cat-file &lt;span class=&quot;token parameter variable&quot;&gt;-p&lt;/span&gt; v1.0&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;output&quot;&gt;&lt;pre class=&quot;language-output&quot;&gt;&lt;code class=&quot;language-output&quot;&gt;object c5fa6f4cfca9fd790cb9bded39a2ae48983eddfd
type commit
tag v1.0
tagger Aditya Thebe &amp;lt;contact@adityathebe.com&amp;gt; 1760262129 +0545

First release&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The tag points to object &lt;code class=&quot;language-text&quot;&gt;c5fa6f4cfca9fd790cb9bded39a2ae48983eddfd&lt;/code&gt; of type &lt;code class=&quot;language-text&quot;&gt;commit&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Run &lt;code class=&quot;language-text&quot;&gt;git log&lt;/code&gt; and you&apos;ll see the commit with that hash.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;inline-svg&quot; role=&quot;img&quot; aria-label=&quot;Git objects linked together&quot;&gt;&lt;svg version=&quot;1.1&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; viewBox=&quot;0 0 1520.1544400154899 980.472303012676&quot; width=&quot;100%&quot; height=&quot;100%&quot;&gt;&lt;!-- svg-source:excalidraw --&gt;&lt;metadata&gt;&lt;/metadata&gt;&lt;defs&gt;&lt;style class=&quot;style-fonts&quot;&gt;
      @font-face { font-family: Excalifont; src: url(data:font/woff2;base64,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); }&lt;/style&gt;

&lt;/defs&gt;&lt;rect x=&quot;0&quot; y=&quot;0&quot; width=&quot;1520.1544400154899&quot; height=&quot;980.472303012676&quot; fill=&quot;none&quot;&gt;&lt;/rect&gt;&lt;g stroke-linecap=&quot;round&quot; transform=&quot;translate(938.4610806404897 247.18256060306675) rotate(0 120.365234375 64.29296875000001)&quot;&gt;&lt;path d=&quot;M32 0 C100.49 3.68, 167.09 0.08, 208.73 0 C227.93 -2.17, 240.97 8.06, 240.73 32 C239.99 60.42, 243.44 84.95, 240.73 96.59 C241.75 119.22, 227.83 129.75, 208.73 128.59 C166.19 125.23, 116.68 130.25, 32 128.59 C11.04 130.02, 3.27 114.49, 0 96.59 C3.97 83.33, -1.96 62.83, 0 32 C2.79 9.76, 13.03 1.63, 32 0&quot; stroke=&quot;none&quot; stroke-width=&quot;0&quot; fill=&quot;var(--color-good-2)&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M32 0 C76.12 -0.62, 117.88 2.01, 208.73 0 M32 0 C97.97 1.23, 163.35 0.08, 208.73 0 M208.73 0 C230.89 0.23, 241.38 8.96, 240.73 32 M208.73 0 C228.97 -2.15, 242.86 8.72, 240.73 32 M240.73 32 C238.88 52.14, 241.59 72.02, 240.73 96.59 M240.73 32 C241.81 47.24, 241.79 60.44, 240.73 96.59 M240.73 96.59 C240.87 117.58, 228.66 129.68, 208.73 128.59 M240.73 96.59 C239.58 117.12, 230.51 127.71, 208.73 128.59 M208.73 128.59 C150.57 125.91, 89.33 128.8, 32 128.59 M208.73 128.59 C154.75 128.78, 102.02 128.77, 32 128.59 M32 128.59 C12.16 126.82, -1.37 117.12, 0 96.59 M32 128.59 C12.2 129.63, -1.81 117.98, 0 96.59 M0 96.59 C-0.58 77.17, -0.39 59.09, 0 32 M0 96.59 C0.18 82.38, -0.11 69.25, 0 32 M0 32 C1.22 11.94, 8.67 0.09, 32 0 M0 32 C-1.09 10.31, 10.27 2.2, 32 0&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(1036.3963299691031 298.97552935306675) rotate(0 22.42998504638672 12.500000000000014)&quot;&gt;&lt;text x=&quot;22.42998504638672&quot; y=&quot;17.619999999999997&quot; font-family=&quot;Excalifont, Xiaolai, sans-serif, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;Tree&lt;/text&gt;&lt;/g&gt;&lt;g stroke-linecap=&quot;round&quot; transform=&quot;translate(598.1739712654897 600.1115018598126) rotate(0 98.576171875 57.951171875)&quot;&gt;&lt;path d=&quot;M28.98 0 C80.48 1.01, 132.6 -0.5, 168.18 0 C188.94 -0.11, 197.65 10.36, 197.15 28.98 C198.32 44.01, 193.34 54.81, 197.15 86.93 C195.54 108.56, 190.47 116.34, 168.18 115.9 C136.65 116.85, 109.82 113.47, 28.98 115.9 C11.66 112.52, -2.19 108.6, 0 86.93 C4.36 73.13, 3.74 56.38, 0 28.98 C-0.95 11.33, 7.96 -1.1, 28.98 0&quot; stroke=&quot;none&quot; stroke-width=&quot;0&quot; fill=&quot;var(--color-bad)&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M28.98 0 C70.99 2.12, 115.49 -1.23, 168.18 0 M28.98 0 C68.4 -1.36, 108.7 -1.89, 168.18 0 M168.18 0 C187.63 -1.45, 199.02 9.08, 197.15 28.98 M168.18 0 C187.08 -0.26, 199.07 11.6, 197.15 28.98 M197.15 28.98 C196.08 50.4, 196.5 69.9, 197.15 86.93 M197.15 28.98 C197.55 44.28, 197.78 58.15, 197.15 86.93 M197.15 86.93 C198.97 104.34, 186.7 114.13, 168.18 115.9 M197.15 86.93 C196.4 108.12, 189.76 113.99, 168.18 115.9 M168.18 115.9 C128.36 116.46, 84.03 114.13, 28.98 115.9 M168.18 115.9 C123.63 114.35, 76.67 114.21, 28.98 115.9 M28.98 115.9 C9.34 115.01, -0.38 104.6, 0 86.93 M28.98 115.9 C7.79 114.93, 0.61 106.34, 0 86.93 M0 86.93 C-0.57 67.97, -0.88 50.89, 0 28.98 M0 86.93 C1.14 68.68, 0.11 48.42, 0 28.98 M0 28.98 C1.82 9.19, 11.14 -0.6, 28.98 0 M0 28.98 C0.55 10.18, 11.56 -1.78, 28.98 0&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(654.5501767098257 633.0626737348126) rotate(0 42.19996643066406 25)&quot;&gt;&lt;text x=&quot;42.19996643066406&quot; y=&quot;17.619999999999997&quot; font-family=&quot;Excalifont, Xiaolai, sans-serif, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;first.txt&lt;/text&gt;&lt;text x=&quot;42.19996643066406&quot; y=&quot;42.62&quot; font-family=&quot;Excalifont, Xiaolai, sans-serif, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;(blob)&lt;/text&gt;&lt;/g&gt;&lt;g stroke-linecap=&quot;round&quot; transform=&quot;translate(912.0099087654897 593.7697049848126) rotate(0 120.365234375 64.29296875)&quot;&gt;&lt;path d=&quot;M32 0 C89.6 0.79, 142.88 -3.39, 208.73 0 C231.86 2.18, 243.71 7.86, 240.73 32 C243.19 54.91, 236.7 77.36, 240.73 96.59 C237.3 114.57, 233.4 126.58, 208.73 128.59 C153.74 127.95, 100.99 122.51, 32 128.59 C8.28 132.05, 0.13 120.76, 0 96.59 C-1.39 80.94, 2.83 68.59, 0 32 C2.83 10.01, 12.44 2.68, 32 0&quot; stroke=&quot;none&quot; stroke-width=&quot;0&quot; fill=&quot;var(--color-bad)&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M32 0 C74.07 -1.28, 112.29 -1, 208.73 0 M32 0 C75.28 0.99, 116.51 1.17, 208.73 0 M208.73 0 C231.73 1.69, 241.9 11.24, 240.73 32 M208.73 0 C230.9 -1.43, 241.48 9.73, 240.73 32 M240.73 32 C239.45 49.09, 242.23 66.89, 240.73 96.59 M240.73 32 C240.92 53.06, 240.99 76.7, 240.73 96.59 M240.73 96.59 C242.7 116.25, 229.97 130.14, 208.73 128.59 M240.73 96.59 C240.15 119.43, 231.11 126.42, 208.73 128.59 M208.73 128.59 C167.09 131.78, 126.37 128.79, 32 128.59 M208.73 128.59 C170.75 126.98, 132.33 127.38, 32 128.59 M32 128.59 C11.2 128.67, -0.06 118.72, 0 96.59 M32 128.59 C10.71 128.2, -2.01 117.18, 0 96.59 M0 96.59 C-0.84 84.09, 1.04 67.84, 0 32 M0 96.59 C0.15 82.15, -0.35 68.54, 0 32 M0 32 C1.65 9.12, 11.87 0.13, 32 0 M0 32 C1.23 11.56, 12.17 2.18, 32 0&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(979.5151806771108 633.0626737348126) rotate(0 52.859962463378906 25)&quot;&gt;&lt;text x=&quot;52.859962463378906&quot; y=&quot;17.619999999999997&quot; font-family=&quot;Excalifont, Xiaolai, sans-serif, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;second.txt&lt;/text&gt;&lt;text x=&quot;52.859962463378906&quot; y=&quot;42.62&quot; font-family=&quot;Excalifont, Xiaolai, sans-serif, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;(blob)&lt;/text&gt;&lt;/g&gt;&lt;g stroke-linecap=&quot;round&quot; transform=&quot;translate(1269.4239712654899 593.7697049848126) rotate(0 120.365234375 64.29296875)&quot;&gt;&lt;path d=&quot;M32 0 C70.89 -4.73, 105.54 -3.54, 208.73 0 C232.38 2.98, 241.17 7.15, 240.73 32 C242.96 50.15, 239.58 74.3, 240.73 96.59 C237.35 115.72, 232.42 126.44, 208.73 128.59 C170.99 134.49, 130.3 130.69, 32 128.59 C12.34 126.88, -1.1 120.44, 0 96.59 C0.86 77.94, -1.26 51.68, 0 32 C2.35 12.8, 11.1 2.53, 32 0&quot; stroke=&quot;none&quot; stroke-width=&quot;0&quot; fill=&quot;var(--color-good-2)&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M32 0 C73.09 1.75, 116.5 -0.48, 208.73 0 M32 0 C83.6 -1.21, 134.4 -2.11, 208.73 0 M208.73 0 C230.71 -0.82, 240.1 9.63, 240.73 32 M208.73 0 C232.15 -1.09, 240.44 12.78, 240.73 32 M240.73 32 C239.08 51.25, 239.21 71.44, 240.73 96.59 M240.73 32 C241.32 57.42, 241.11 81.95, 240.73 96.59 M240.73 96.59 C241.64 116.04, 228.64 129.12, 208.73 128.59 M240.73 96.59 C242.51 116.55, 232.17 126.92, 208.73 128.59 M208.73 128.59 C165.09 127.93, 121.58 126.68, 32 128.59 M208.73 128.59 C163.17 129.05, 117.69 128.49, 32 128.59 M32 128.59 C8.92 127.94, -1.61 118.42, 0 96.59 M32 128.59 C9.5 127.8, 1.94 119.3, 0 96.59 M0 96.59 C0.05 79.88, -0.07 60.69, 0 32 M0 96.59 C0.07 75.81, 0 55.3, 0 32 M0 32 C1.31 12.56, 11.13 0.8, 32 0 M0 32 C-0.07 10.99, 11.11 -2.12, 32 0&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(1361.1692257820914 633.0626737348126) rotate(0 28.619979858398438 25)&quot;&gt;&lt;text x=&quot;28.619979858398438&quot; y=&quot;17.619999999999997&quot; font-family=&quot;Excalifont, Xiaolai, sans-serif, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;src/&lt;/text&gt;&lt;text x=&quot;28.619979858398438&quot; y=&quot;42.62&quot; font-family=&quot;Excalifont, Xiaolai, sans-serif, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;(tree)&lt;/text&gt;&lt;/g&gt;&lt;g stroke-linecap=&quot;round&quot; transform=&quot;translate(1275.714058904793 854.569959262676) rotate(0 98.576171875 57.951171875)&quot;&gt;&lt;path d=&quot;M28.98 0 C81.62 -1.9, 132.77 -1.54, 168.18 0 C187.49 -1.5, 195.4 8.72, 197.15 28.98 C197.18 52.28, 199.09 68.73, 197.15 86.93 C197 105.18, 186.46 112.32, 168.18 115.9 C114.06 113.35, 60.08 114.35, 28.98 115.9 C9.37 116.99, -1.58 109.74, 0 86.93 C1.11 71, -1.43 58.53, 0 28.98 C1.15 6.46, 11.26 -3.13, 28.98 0&quot; stroke=&quot;none&quot; stroke-width=&quot;0&quot; fill=&quot;var(--color-bad)&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M28.98 0 C61.33 2.21, 96.72 2.22, 168.18 0 M28.98 0 C64.79 -0.34, 98.8 -0.96, 168.18 0 M168.18 0 C185.79 -1.21, 196.37 10.91, 197.15 28.98 M168.18 0 C186.44 -2.08, 195.41 8.01, 197.15 28.98 M197.15 28.98 C196.61 44.84, 197.49 55.11, 197.15 86.93 M197.15 28.98 C197.04 42.09, 198.36 54.52, 197.15 86.93 M197.15 86.93 C195.61 105.57, 187.98 116.44, 168.18 115.9 M197.15 86.93 C198.78 105.14, 187.82 116.94, 168.18 115.9 M168.18 115.9 C135.97 116.3, 100.58 115.59, 28.98 115.9 M168.18 115.9 C121.31 116.89, 74.45 117.69, 28.98 115.9 M28.98 115.9 C7.93 114.41, 0.65 105.82, 0 86.93 M28.98 115.9 C9.5 115.84, -2.27 106.44, 0 86.93 M0 86.93 C1.73 65.84, -0.05 42.01, 0 28.98 M0 86.93 C-0.74 66.96, -1.47 46.99, 0 28.98 M0 28.98 C1.46 9.31, 9.24 0.58, 28.98 0 M0 28.98 C1.55 10.97, 10.28 2.04, 28.98 0&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(1337.8102655698322 887.521131137676) rotate(0 36.47996520996094 25)&quot;&gt;&lt;text x=&quot;36.47996520996094&quot; y=&quot;17.619999999999997&quot; font-family=&quot;Excalifont, Xiaolai, sans-serif, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;index.js&lt;/text&gt;&lt;text x=&quot;36.47996520996094&quot; y=&quot;42.62&quot; font-family=&quot;Excalifont, Xiaolai, sans-serif, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;(blob)&lt;/text&gt;&lt;/g&gt;&lt;g stroke-linecap=&quot;round&quot; transform=&quot;translate(416.6627079837249 247.18256060306675) rotate(0 120.365234375 64.29296875000001)&quot;&gt;&lt;path d=&quot;M32 0 C101.93 -2.82, 169.46 1.02, 208.73 0 C230.75 -2.61, 240.67 7.41, 240.73 32 C244.11 49.16, 240.58 65.42, 240.73 96.59 C241 118, 230.79 129.01, 208.73 128.59 C162.31 127.79, 119.7 123.69, 32 128.59 C8.68 125.01, -0.88 116.43, 0 96.59 C-0.18 81.45, 3.44 67.19, 0 32 C-2.65 8.18, 14.23 -2.04, 32 0&quot; stroke=&quot;none&quot; stroke-width=&quot;0&quot; fill=&quot;var(--color-good)&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M32 0 C93.77 1.61, 155.86 -1.59, 208.73 0 M32 0 C97.66 1.07, 164.94 0.22, 208.73 0 M208.73 0 C231.49 -0.49, 241.34 9.87, 240.73 32 M208.73 0 C231.51 1.99, 239.75 12.41, 240.73 32 M240.73 32 C238.66 53.78, 241.11 73, 240.73 96.59 M240.73 32 C239.38 52.32, 241 72.46, 240.73 96.59 M240.73 96.59 C241.76 119.48, 231.16 128.04, 208.73 128.59 M240.73 96.59 C239.74 117.88, 229.24 127.19, 208.73 128.59 M208.73 128.59 C136.79 129.86, 67.94 130.29, 32 128.59 M208.73 128.59 C143.68 127.18, 79.69 127.11, 32 128.59 M32 128.59 C8.97 128, -0.16 116.35, 0 96.59 M32 128.59 C8.93 129.09, -0.79 117.63, 0 96.59 M0 96.59 C-0.05 72.22, -0.25 48.18, 0 32 M0 96.59 C-1.34 80.56, 0.08 62.72, 0 32 M0 32 C-1.75 10.81, 11.55 1.23, 32 0 M0 32 C1.44 12.28, 12.94 -1.21, 32 0&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(467.60798996614676 286.47552935306675) rotate(0 69.41995239257812 25.000000000000014)&quot;&gt;&lt;text x=&quot;69.41995239257812&quot; y=&quot;17.619999999999997&quot; font-family=&quot;Excalifont, Xiaolai, sans-serif, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;second commit&lt;/text&gt;&lt;text x=&quot;69.41995239257812&quot; y=&quot;42.62&quot; font-family=&quot;Excalifont, Xiaolai, sans-serif, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;(commit)&lt;/text&gt;&lt;/g&gt;&lt;g stroke-linecap=&quot;round&quot;&gt;&lt;g transform=&quot;translate(659.6802861087251 308.53585289328976) rotate(0 136.38976889686563 2.6973458137789805)&quot;&gt;&lt;path d=&quot;M-0.98 -0.53 C44.55 0.28, 227.92 3.99, 273.62 5.05 M0.7 1.81 C46.11 2.78, 227.78 6.09, 273.12 6.41&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(659.6802861087251 308.53585289328976) rotate(0 136.38976889686563 2.6973458137789805)&quot;&gt;&lt;path d=&quot;M249.51 14.64 C256.56 13.47, 264.8 10.07, 273.12 6.41 M249.51 14.64 C256.65 12.01, 266.15 9.83, 273.12 6.41&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(659.6802861087251 308.53585289328976) rotate(0 136.38976889686563 2.6973458137789805)&quot;&gt;&lt;path d=&quot;M249.74 -2.46 C256.73 2.12, 264.9 4.47, 273.12 6.41 M249.74 -2.46 C256.64 0.66, 266.07 4.24, 273.12 6.41&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;/g&gt;&lt;mask&gt;&lt;/mask&gt;&lt;g stroke-linecap=&quot;round&quot;&gt;&lt;g transform=&quot;translate(1054.5652117874174 377.27059437406473) rotate(0 -190.39049443779032 106.35495248237493)&quot;&gt;&lt;path d=&quot;M0.41 0.15 C-63.27 35.33, -317.33 176.39, -380.89 211.69 M-0.84 -0.81 C-64.79 34.43, -318.39 177.07, -381.89 212.69&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(1054.5652117874174 377.27059437406473) rotate(0 -190.39049443779032 106.35495248237493)&quot;&gt;&lt;path d=&quot;M-365.59 193.73 C-371.73 201.16, -380.18 208.59, -381.89 212.69 M-365.59 193.73 C-370.14 198.74, -373.62 201.92, -381.89 212.69&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(1054.5652117874174 377.27059437406473) rotate(0 -190.39049443779032 106.35495248237493)&quot;&gt;&lt;path d=&quot;M-357.22 208.64 C-366.77 210.16, -378.55 211.65, -381.89 212.69 M-357.22 208.64 C-363.66 210.2, -369.12 209.83, -381.89 212.69&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;/g&gt;&lt;mask&gt;&lt;/mask&gt;&lt;g stroke-linecap=&quot;round&quot;&gt;&lt;g transform=&quot;translate(1054.47669660957 381.7099043530667) rotate(0 -10.179506630164155 103.54838343037395)&quot;&gt;&lt;path d=&quot;M-0.11 -0.12 C-3.47 34.22, -17.48 171.65, -20.83 206.24 M-1.63 -1.22 C-5.12 33.22, -18.81 172.3, -22.03 207.32&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(1054.47669660957 381.7099043530667) rotate(0 -10.179506630164155 103.54838343037395)&quot;&gt;&lt;path d=&quot;M-28.3 183.12 C-26.93 188.19, -26.66 195.04, -22.03 207.32 M-28.3 183.12 C-27.02 190.09, -23.33 198.55, -22.03 207.32&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(1054.47669660957 381.7099043530667) rotate(0 -10.179506630164155 103.54838343037395)&quot;&gt;&lt;path d=&quot;M-11.28 184.75 C-14.03 189.41, -17.87 195.87, -22.03 207.32 M-11.28 184.75 C-15.54 191.05, -17.39 198.98, -22.03 207.32&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;/g&gt;&lt;mask&gt;&lt;/mask&gt;&lt;g stroke-linecap=&quot;round&quot;&gt;&lt;g transform=&quot;translate(1056.400220808241 379.0074304914985) rotate(0 162.6445603650518 105.27073125697387)&quot;&gt;&lt;path d=&quot;M-0.7 0.39 C53.58 35.73, 271.58 175.82, 326.11 210.89 M1.13 -0.45 C55.29 34.62, 271.4 173.49, 325.59 208.95&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(1056.400220808241 379.0074304914985) rotate(0 162.6445603650518 105.27073125697387)&quot;&gt;&lt;path d=&quot;M301.22 203.36 C309.93 206.73, 317.98 209.15, 325.59 208.95 M301.22 203.36 C310.13 205.45, 316.96 206.93, 325.59 208.95&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(1056.400220808241 379.0074304914985) rotate(0 162.6445603650518 105.27073125697387)&quot;&gt;&lt;path d=&quot;M310.52 189.01 C315.99 197.1, 320.95 204.3, 325.59 208.95 M310.52 189.01 C316.5 195.7, 320.31 201.86, 325.59 208.95&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;/g&gt;&lt;mask&gt;&lt;/mask&gt;&lt;g stroke-linecap=&quot;round&quot;&gt;&lt;g transform=&quot;translate(1375.996073214767 723.3556424848126) rotate(0 2.7652860628993494 62.728878545022155)&quot;&gt;&lt;path d=&quot;M0.76 -0.54 C1.73 20.62, 4.7 105.32, 5.4 126.41 M-0.3 1.79 C0.53 22.67, 3.69 104.42, 4.39 124.79&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(1375.996073214767 723.3556424848126) rotate(0 2.7652860628993494 62.728878545022155)&quot;&gt;&lt;path d=&quot;M-5.02 101.63 C-3.5 107.54, 1.5 112.98, 4.39 124.79 M-5.02 101.63 C-2.5 110.16, 0.95 117.87, 4.39 124.79&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(1375.996073214767 723.3556424848126) rotate(0 2.7652860628993494 62.728878545022155)&quot;&gt;&lt;path d=&quot;M12.07 101 C9.02 107.19, 9.46 112.79, 4.39 124.79 M12.07 101 C8.63 109.78, 6.11 117.71, 4.39 124.79&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;/g&gt;&lt;mask&gt;&lt;/mask&gt;&lt;g stroke-linecap=&quot;round&quot; transform=&quot;translate(390.011542545158 10) rotate(0 143.46761382800298 69.26683986226752)&quot;&gt;&lt;path d=&quot;M32 0 C93.01 1.62, 158.77 1.31, 254.94 0 C277.86 -1.41, 285.16 14.04, 286.94 32 C283.8 53.98, 289.57 80.3, 286.94 106.53 C285.94 131.42, 278.1 136.61, 254.94 138.53 C191.51 133.86, 127.8 134.41, 32 138.53 C12.74 138.38, -2.59 125.84, 0 106.53 C3.97 88.66, 2.63 70.29, 0 32 C-0.09 12.51, 9.52 2.62, 32 0&quot; stroke=&quot;none&quot; stroke-width=&quot;0&quot; fill=&quot;var(--color-good-3)&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M32 0 C115.91 2.28, 195.64 0.87, 254.94 0 M32 0 C112.28 1.74, 193.53 0.45, 254.94 0 M254.94 0 C275.85 -0.7, 287.57 8.72, 286.94 32 M254.94 0 C276.33 1.76, 284.84 12.74, 286.94 32 M286.94 32 C288.66 57.82, 285.83 79.81, 286.94 106.53 M286.94 32 C285.85 57.23, 286.53 82.25, 286.94 106.53 M286.94 106.53 C288.63 128.1, 276.92 139.87, 254.94 138.53 M286.94 106.53 C287.91 126.34, 276.05 137.03, 254.94 138.53 M254.94 138.53 C211.51 137.81, 164.97 138.38, 32 138.53 M254.94 138.53 C196.01 137.55, 135.35 137.87, 32 138.53 M32 138.53 C8.95 139.17, 1.68 129.62, 0 106.53 M32 138.53 C12.31 138.04, 1.01 128.2, 0 106.53 M0 106.53 C0.91 84.4, 0.01 61.85, 0 32 M0 106.53 C-0.26 79.07, 0.16 53.48, 0 32 M0 32 C1.15 9, 11.13 -0.71, 32 0 M0 32 C-1.92 12.37, 11.3 0.29, 32 0&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(508.20917498888366 54.26683986226752) rotate(0 25.269981384277344 25)&quot;&gt;&lt;text x=&quot;25.269981384277344&quot; y=&quot;17.619999999999997&quot; font-family=&quot;Excalifont, Xiaolai, sans-serif, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;v1.0&lt;/text&gt;&lt;text x=&quot;25.269981384277344&quot; y=&quot;42.62&quot; font-family=&quot;Excalifont, Xiaolai, sans-serif, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;(tag)&lt;/text&gt;&lt;/g&gt;&lt;g stroke-linecap=&quot;round&quot;&gt;&lt;g transform=&quot;translate(527.3020226162573 149.53367972453503) rotate(0 1.8709788631817332 46.2421262291602)&quot;&gt;&lt;path d=&quot;M0.25 0.68 C0.61 16.4, 2.25 77.89, 2.69 93.27 M-1.08 -0.01 C-0.4 15.47, 3.78 76.41, 4.84 91.55&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(527.3020226162573 149.53367972453503) rotate(0 1.8709788631817332 46.2421262291602)&quot;&gt;&lt;path d=&quot;M-5.3 68.71 C-0.89 74.78, 2.77 82.96, 4.84 91.55 M-5.3 68.71 C-1.52 75.64, 2.41 85.02, 4.84 91.55&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(527.3020226162573 149.53367972453503) rotate(0 1.8709788631817332 46.2421262291602)&quot;&gt;&lt;path d=&quot;M11.76 67.53 C10.29 74.04, 8.09 82.63, 4.84 91.55 M11.76 67.53 C9.74 74.77, 7.88 84.55, 4.84 91.55&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;/g&gt;&lt;mask&gt;&lt;/mask&gt;&lt;g stroke-linecap=&quot;round&quot; transform=&quot;translate(10 247.18256060306675) rotate(0 120.365234375 64.29296875000001)&quot;&gt;&lt;path d=&quot;M32 0 C69.85 1.53, 106.06 0.08, 208.73 0 C232.84 1.39, 242.58 11.15, 240.73 32 C242.77 51.31, 240.83 71.61, 240.73 96.59 C239.96 117.92, 231.47 125.79, 208.73 128.59 C141.05 130.65, 77.83 126.62, 32 128.59 C13.03 129.55, -2.92 119.26, 0 96.59 C1.4 81.67, -1.91 71.89, 0 32 C-0.34 10.64, 11.93 -0.2, 32 0&quot; stroke=&quot;none&quot; stroke-width=&quot;0&quot; fill=&quot;var(--color-good)&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M32 0 C70.22 0.27, 109.73 -0.23, 208.73 0 M32 0 C86.97 -0.05, 141.67 1.42, 208.73 0 M208.73 0 C228.99 -1.51, 239.18 11.16, 240.73 32 M208.73 0 C228.32 1.62, 242.93 10.49, 240.73 32 M240.73 32 C240.24 48.03, 240.15 66.92, 240.73 96.59 M240.73 32 C241.53 47.57, 241.49 62.45, 240.73 96.59 M240.73 96.59 C242.12 118.02, 230.31 127.81, 208.73 128.59 M240.73 96.59 C241.31 118.43, 232.19 127.57, 208.73 128.59 M208.73 128.59 C138.8 128.13, 71.6 131.54, 32 128.59 M208.73 128.59 C142.89 130.44, 75.22 129.73, 32 128.59 M32 128.59 C9.49 130.26, 1.05 116.55, 0 96.59 M32 128.59 C12.61 128.54, 2.12 116.92, 0 96.59 M0 96.59 C-1.31 82.5, 0.01 68.33, 0 32 M0 96.59 C-0.91 82.47, -0.97 68.5, 0 32 M0 32 C0.7 10.21, 12.57 0.6, 32 0 M0 32 C1.7 8.94, 9.08 -2.06, 32 0&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(55.67528533935547 286.47552935306675) rotate(0 74.68994903564453 25.000000000000014)&quot;&gt;&lt;text x=&quot;74.68994903564453&quot; y=&quot;17.619999999999997&quot; font-family=&quot;Excalifont, Xiaolai, sans-serif, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;my first commit&lt;/text&gt;&lt;text x=&quot;74.68994903564453&quot; y=&quot;42.62&quot; font-family=&quot;Excalifont, Xiaolai, sans-serif, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;(commit)&lt;/text&gt;&lt;/g&gt;&lt;g stroke-linecap=&quot;round&quot;&gt;&lt;g transform=&quot;translate(413.73896035381813 313.58914583266863) rotate(0 -80.33481941391375 -1.8722706754171838)&quot;&gt;&lt;path d=&quot;M-0.58 -0.05 C-27.23 -0.79, -133.08 -3.38, -159.66 -4.17 M1.32 -1.13 C-25.43 -1.72, -133.11 -2.37, -160.09 -2.86&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(413.73896035381813 313.58914583266863) rotate(0 -80.33481941391375 -1.8722706754171838)&quot;&gt;&lt;path d=&quot;M-136.5 -11.14 C-144.17 -6.91, -152.4 -4.94, -160.09 -2.86 M-136.5 -11.14 C-140.82 -9.55, -145.7 -7.19, -160.09 -2.86&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(413.73896035381813 313.58914583266863) rotate(0 -80.33481941391375 -1.8722706754171838)&quot;&gt;&lt;path d=&quot;M-136.69 5.96 C-144.34 4.68, -152.51 1.14, -160.09 -2.86 M-136.69 5.96 C-141.13 3.97, -145.96 2.76, -160.09 -2.86&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;/g&gt;&lt;mask&gt;&lt;/mask&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://jvns.ca/blog/2024/01/05/do-we-think-of-git-commits-as-diffs--snapshots--or-histories/&quot;&gt;https://jvns.ca/blog/2024/01/05/do-we-think-of-git-commits-as-diffs--snapshots--or-histories/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://git-scm.com/book/en/v2/Git-Internals-Git-Objects&quot;&gt;https://git-scm.com/book/en/v2/Git-Internals-Git-Objects&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://git-scm.com/book/en/v2/Git-Internals-Plumbing-and-Porcelain&quot;&gt;https://git-scm.com/book/en/v2/Git-Internals-Plumbing-and-Porcelain&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Running AI agents in parallel]]></title><description><![CDATA[Parallel agents to brrrr ....]]></description><link>https://www.adityathebe.com/journal/working-with-ai-agents</link><guid isPermaLink="false">https://www.adityathebe.com/journal/working-with-ai-agents</guid><pubDate>Sat, 11 Oct 2025 14:30:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;coding-agents-roles-and-commands&quot;&gt;Coding agents roles and commands&lt;/h2&gt;
&lt;p&gt;Src: &lt;a href=&quot;https://blog.fsck.com/2025/10/05/how-im-using-coding-agents-in-september-2025/&quot;&gt;https://blog.fsck.com/2025/10/05/how-im-using-coding-agents-in-september-2025/&lt;/a&gt;&lt;/p&gt;
&lt;h4 id=&quot;roles&quot;&gt;Roles&lt;/h4&gt;
&lt;p&gt;Got some good prompts from this article.
Now I run multiple sessions that take on different roles. Example:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Planner
&lt;ul&gt;
&lt;li&gt;interactive&lt;/li&gt;
&lt;li&gt;plans in chunks&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Implementer&lt;/li&gt;
&lt;li&gt;Architect verifies the work of the implementer&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I really like the planner session where I brainstorm with the AI to come up with a design.
I have found that it asks really good questions and addresses things that I had missed in my initial design. But it also asks too much questions which are not that important and I want it to decide for me.&lt;/p&gt;
&lt;h4 id=&quot;reviewing-pr-comments&quot;&gt;Reviewing PR comments&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;The only problem with tools like this is that our robot buddies are quite credulous. If you paste in a list of instructions for how to update a codebase, Claude&apos;s just going to take you at your word and make the changes, even if what you&apos;re asking for is crazy and wrong.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I faced a similar situation too. When I ask Claude to address GitHub Copilot&apos;s review comments, it blindly addresses them, taking them at face value.&lt;/p&gt;
&lt;p&gt;I&apos;m using this command &lt;code class=&quot;language-text&quot;&gt;~/.claude/commands/fix-pr-comments&lt;/code&gt; which works so much better.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Please list all the review comments in this GitHub PR: $ARGUMENTS.

Follow these steps:

- Use `gh api` to fetch comments not the `gh view --comments` command.

  example: gh api repos/flanksource/mission-control/pulls/2173/comments

A reviewer did some analysis of this PR.
They&apos;re external, so reading the codebase cold.
This is their analysis of the changes and I&apos;d like you to evaluate the analysis and the reviewer carefully.

Note: If the suggested fix are marked as resolved, skip them

1) should we hire this reviewer? If it&apos;s an automated review give it a score from 1-10 on how good he reviews were.
2) which of the issues they&apos;ve flagged should be fixed?
3) are the fixes they propose the correct ones?

Anything we *should* fix, put on your todo list.
Anything we should skip, tell me about now.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;With this prompt, the agent usually discards nitpicks and incorrect comments on the PR.&lt;/p&gt;
&lt;h2 id=&quot;doltgressql&quot;&gt;DoltgresSQL&lt;/h2&gt;
&lt;p&gt;Src: &lt;a href=&quot;https://www.dolthub.com/blog/2025-10-03-100-real-world-postgres-dumps/&quot;&gt;https://www.dolthub.com/blog/2025-10-03-100-real-world-postgres-dumps/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I came across this article and found out that this company was building a MySQL and PostgreSQL drop-in replacement in Go from scratch! That sounds really exciting but also massively challenging.&lt;/p&gt;
&lt;p&gt;This article in particular talks about using real world postgres dumps in their test suite which is pretty clever.&lt;/p&gt;
&lt;p&gt;I will definitely be keeping an eye on this project and hopefully consider contributing.&lt;/p&gt;
&lt;h2 id=&quot;containers-on-macos-&quot;&gt;Containers on MacOS !!&lt;/h2&gt;
&lt;p&gt;Src: &lt;a href=&quot;https://www.youtube.com/watch?v=x1t2GPChhX8&quot;&gt;https://www.youtube.com/watch?v=x1t2GPChhX8&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Native containers are finally here in macOS.&lt;/p&gt;
&lt;p&gt;When I migrated from Linux to macOS, one of the challenges I faced was deciding what Docker engine to use. Most people use Docker Desktop, but I decided to use OrbStack because people on Twitter were saying it is much more performant.&lt;/p&gt;
&lt;p&gt;I haven&apos;t really noticed any performance issues, but it&apos;s also because I&apos;m not running anything heavy on it.
However, you can tell that starting and stopping containers is so much slower.&lt;/p&gt;
&lt;p&gt;It also feels a bit weird that I need to open a GUI to start a Docker service.&lt;/p&gt;
&lt;p&gt;Key things about macOS containers:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Development after hype cycle means there is no need to move fast and break things.&lt;/li&gt;
&lt;li&gt;Native apps available as containers&lt;/li&gt;
&lt;li&gt;Native to OS. No need to download 3rd party like docker on Linux.&lt;/li&gt;
&lt;li&gt;OCI compliant. Support Dockerfile.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;notifications-on-claude-code&quot;&gt;Notifications on Claude Code&lt;/h2&gt;
&lt;p&gt;One of the things that I really liked about &lt;a href=&quot;https://sourcegraph.com/amp&quot;&gt;AMP&lt;/a&gt; was the notification bell you get when the agent completes the task or is waiting for a user input. For some reason the notification bell does not work for me with Claude code.&lt;/p&gt;
&lt;p&gt;Fortunately, Claude Code now provides a various set of hooks.
I have added these two hooks that will play a sound when the agent stops or needs to notify me about something.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;json&quot;&gt;&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;hooks&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Stop&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token property&quot;&gt;&quot;matcher&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token property&quot;&gt;&quot;hooks&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
          &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token property&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;command&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token property&quot;&gt;&quot;command&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;afplay /System/Library/Sounds/Blow.aiff&quot;&lt;/span&gt;
          &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Notification&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token property&quot;&gt;&quot;matcher&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token property&quot;&gt;&quot;hooks&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
          &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token property&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;command&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token property&quot;&gt;&quot;command&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;afplay /System/Library/Sounds/Glass.aiff&quot;&lt;/span&gt;
          &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;moving-to-claude-max-plan&quot;&gt;Moving to Claude Max Plan&lt;/h2&gt;
&lt;p&gt;I have also gone all in with Claude Code subscription and upgraded to the Max Plan ($100/mo).
I was rarely hitting the token limits on the $20/mo Pro plan but I really wanted to give Opus a try - which is only available on the Max Plan.
However, after using Opus and Sonnet 4.5, I don&apos;t think Opus is any better. In fact, it&apos;s probably worse.&lt;/p&gt;
&lt;p&gt;In order to keep my budget of $100 a month for AI tools, I had to cancel my OpenAI subscription as well as the Cursor subscription.
I don&apos;t really miss Cursor, and even if I do, the free plan will be sufficient.
However, I&apos;m starting to like OpenAI&apos;s Codex CLI, which probably means I might need to go over my budget and get the OpenAI $20/mo subscription.&lt;/p&gt;
&lt;h2 id=&quot;trying-out-codex-cli&quot;&gt;Trying out Codex CLI&lt;/h2&gt;
&lt;p&gt;As I mentioned, I&apos;ve been playing with Codex CLI. I don&apos;t really like its UX. Its permission system doesn&apos;t really make sense to me, and I hate that it doesn&apos;t even have syntax highlighting. It&apos;s also much slower than Claude.&lt;/p&gt;
&lt;p&gt;But - what I really like about this is that it was able to solve problems that Claude couldn&apos;t. Not to say that it&apos;s better, because there have been many cases where Claude just performed better. But when you use Claude and Codex together, you get a much more intelligent agent as a whole, because you can ask Codex to review Claude&apos;s changes, and almost always it will find something that Claude missed - and vice versa.&lt;/p&gt;
&lt;p&gt;I&apos;ll still be using Claude Code as my primary driver, but it&apos;s nice to have Codex CLI to verify Claude&apos;s work.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[ARP - The DNS for IP addresses]]></title><description><![CDATA[Address Resolution Protocol maps IP addresses to MAC addresses similar to how DNS maps domains to IP addresses.]]></description><link>https://www.adityathebe.com/address-resolution-protocol</link><guid isPermaLink="false">https://www.adityathebe.com/address-resolution-protocol</guid><pubDate>Sat, 17 May 2025 15:35:00 GMT</pubDate><content:encoded>&lt;p&gt;In the OSI model, devices in layer 2 - like a Switch - work with MAC address while devices on layer 3 work with IP addresses.
IP packets only know what IP address they are destined to but at the lower level we only have MAC addresses. This tells us that at some point
we need to map IP address to MAC address.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;As always, this post focuses specifically on Linux networking.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;span class=&quot;inline-svg&quot; role=&quot;img&quot; aria-label=&quot;what is arp&quot;&gt;&lt;svg version=&quot;1.1&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; viewBox=&quot;0 0 1259.35546875 596.4609375&quot; width=&quot;100%&quot; height=&quot;100%&quot;&gt;&lt;!-- svg-source:excalidraw --&gt;&lt;metadata&gt;&lt;/metadata&gt;&lt;defs&gt;&lt;style class=&quot;style-fonts&quot;&gt;
@font-face { font-family: Excalifont; src: url(data:font/woff2;base64,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); }&lt;/style&gt;&lt;/defs&gt;&lt;g stroke-linecap=&quot;round&quot; transform=&quot;translate(10 10.09756018902442) rotate(0 619.677734375 287.15234375)&quot;&gt;&lt;path d=&quot;M0 0 C308.23 -0.79, 615.75 -1.27, 1239.36 0 M1239.36 0 C1240.89 116.48, 1240.67 232.27, 1239.36 574.3 M1239.36 574.3 C943.24 571.34, 645.86 570.69, 0 574.3 M0 574.3 C2.68 369.97, 1.97 166.94, 0 0&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2.5&quot; fill=&quot;none&quot; stroke-dasharray=&quot;8 10&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g stroke-linecap=&quot;round&quot; transform=&quot;translate(843.423828125 10.843374102237817) rotate(0 202.27734375 287.5613082601607)&quot;&gt;&lt;path d=&quot;M-1.07 0.07 L405.6 0.55 L405.34 575.48 L-0.71 573.36&quot; stroke=&quot;none&quot; stroke-width=&quot;0&quot; fill=&quot;var(--color-bad)&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M0 0 C117.75 -2.66, 236.86 -1.54, 404.55 0 M404.55 0 C404.36 130.18, 404 261.35, 404.55 575.12 M404.55 575.12 C267.5 576.95, 127.93 576.01, 0 575.12 M0 575.12 C0.8 452.25, 1.25 328.34, 0 0&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;1.5&quot; fill=&quot;none&quot; stroke-dasharray=&quot;8 9&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g stroke-linecap=&quot;round&quot; transform=&quot;translate(11.1171875 10) rotate(0 202.748046875 288.23046875)&quot;&gt;&lt;path d=&quot;M-1.88 1.35 L404.94 0.02 L404.85 574.85 L-1.66 576.81&quot; stroke=&quot;none&quot; stroke-width=&quot;0&quot; fill=&quot;var(--color-good-3)&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M0 0 C84.57 1.57, 167.52 2.67, 405.5 0 M405.5 0 C406.4 196.17, 406.29 391.61, 405.5 576.46 M405.5 576.46 C253.27 576.67, 101.59 576.59, 0 576.46 M0 576.46 C-1.38 414.05, -1.46 250.76, 0 0&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;1.5&quot; fill=&quot;none&quot; stroke-dasharray=&quot;8 9&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g stroke-linecap=&quot;round&quot; transform=&quot;translate(898.1831209863917 413.7358662102483) rotate(0 147.51805088860817 69.714725667284)&quot;&gt;&lt;path d=&quot;M32 0 C89.86 -1.92, 140.8 2.43, 263.04 0 C282.85 0.72, 295.06 12.27, 295.04 32 C295.67 48.83, 291.79 71.96, 295.04 107.43 C293.64 131.2, 283.07 138.19, 263.04 139.43 C199.62 135.6, 133.81 138.43, 32 139.43 C9.34 135.9, 1.65 125.53, 0 107.43 C-2.7 86.4, 2.05 60.28, 0 32 C-0.71 12.04, 10.32 0.86, 32 0&quot; stroke=&quot;none&quot; stroke-width=&quot;0&quot; fill=&quot;var(--color-bad)&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M32 0 C107.79 1.27, 180.05 0.16, 263.04 0 M32 0 C115.79 0.72, 199.39 1.63, 263.04 0 M263.04 0 C282.41 0.23, 293.93 9.01, 295.04 32 M263.04 0 C282.94 0.68, 292.87 12.17, 295.04 32 M295.04 32 C295.2 53.76, 296.93 78.33, 295.04 107.43 M295.04 32 C295.63 47.47, 294.5 64.31, 295.04 107.43 M295.04 107.43 C296.79 130.62, 285.64 138.87, 263.04 139.43 M295.04 107.43 C294.24 128.62, 286.62 137.76, 263.04 139.43 M263.04 139.43 C205.44 141.88, 149.23 141.32, 32 139.43 M263.04 139.43 C194.22 140.65, 126.51 140.97, 32 139.43 M32 139.43 C8.71 140.69, -1.82 130.74, 0 107.43 M32 139.43 C11.97 141.38, 1.88 127.4, 0 107.43 M0 107.43 C0.09 78.34, -0.27 52.02, 0 32 M0 107.43 C-0.73 81.79, -1.03 54.01, 0 32 M0 32 C0.6 12.24, 8.99 1.48, 32 0 M0 32 C-0.43 12.16, 11.76 -1.89, 32 0&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(941.651985168457 470.9796120784821) rotate(0 104.04918670654297 12.470979799050156)&quot;&gt;&lt;text x=&quot;104.04918670654297&quot; y=&quot;17.579093124741107&quot; font-family=&quot;Excalifont, Xiaolai, Segoe UI Emoji&quot; font-size=&quot;19.95356767848026px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;MAC: AB:CD:AB:CD:00&lt;/text&gt;&lt;/g&gt;&lt;g stroke-linecap=&quot;round&quot; transform=&quot;translate(66.00390625 413.5736387525323) rotate(0 147.861328125 69.876953125)&quot;&gt;&lt;path d=&quot;M32 0 C120.04 -4.3, 203.18 -4.41, 263.72 0 C282.71 -0.45, 296.17 10.5, 295.72 32 C293.82 46.59, 298.66 70.83, 295.72 107.75 C296.79 132.68, 287.47 137.69, 263.72 139.75 C187.74 138.89, 104.49 134.89, 32 139.75 C10.78 140.03, -2.28 128.71, 0 107.75 C1.8 85.03, -0.78 68.73, 0 32 C-0.29 10.06, 10.38 1.98, 32 0&quot; stroke=&quot;none&quot; stroke-width=&quot;0&quot; fill=&quot;var(--color-good-3)&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M32 0 C82.3 0.42, 135.12 -0.32, 263.72 0 M32 0 C108.83 0.44, 185.59 0.74, 263.72 0 M263.72 0 C285.72 -0.8, 297.01 12.19, 295.72 32 M263.72 0 C285.3 -0.24, 295.84 10.45, 295.72 32 M295.72 32 C295.41 52.66, 296.71 75.95, 295.72 107.75 M295.72 32 C295.95 59.59, 295.17 89, 295.72 107.75 M295.72 107.75 C295.09 128.55, 283.38 137.94, 263.72 139.75 M295.72 107.75 C294.99 127.74, 284.34 140.94, 263.72 139.75 M263.72 139.75 C192.2 140.92, 116.71 138.48, 32 139.75 M263.72 139.75 C174.58 141.14, 86.27 139.88, 32 139.75 M32 139.75 C9.9 138.9, 0.75 127.81, 0 107.75 M32 139.75 C11.47 140.08, -0.2 131.05, 0 107.75 M0 107.75 C-1.31 82.27, -1.49 57.54, 0 32 M0 107.75 C0.32 77.92, 1.38 48.73, 0 32 M0 32 C-1.58 11.88, 9.08 1.95, 32 0 M0 32 C-0.42 9.51, 11.04 0.93, 32 0&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(133.25528717041016 470.9505918775323) rotate(0 80.60994720458984 12.5)&quot;&gt;&lt;text x=&quot;80.60994720458984&quot; y=&quot;17.619999999999997&quot; font-family=&quot;Excalifont, Xiaolai, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;MAC: 11:11:11:11:11&lt;/text&gt;&lt;/g&gt;&lt;g stroke-linecap=&quot;round&quot; transform=&quot;translate(494.0302734375 429.3061566885079) rotate(0 135.98828125 53.87890625)&quot;&gt;&lt;path d=&quot;M26.94 0 C96.42 3.35, 172.55 1.43, 245.04 0 C262.05 0.2, 274.89 9.49, 271.98 26.94 C269.37 42.5, 274.18 63.41, 271.98 80.82 C272.73 101.82, 261.57 107.7, 245.04 107.76 C197.2 106.67, 156.52 106.44, 26.94 107.76 C7.88 111.14, 0.27 102.35, 0 80.82 C2.38 58.91, -0.09 39.99, 0 26.94 C2.07 10.59, 8.14 0.2, 26.94 0&quot; stroke=&quot;none&quot; stroke-width=&quot;0&quot; fill=&quot;var(--color-good)&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M26.94 0 C111.63 1.25, 193.93 3.14, 245.04 0 M26.94 0 C93.91 -0.29, 162.33 0.63, 245.04 0 M245.04 0 C262.69 -0.42, 272.64 7.58, 271.98 26.94 M245.04 0 C264.87 -0.09, 272.22 7.2, 271.98 26.94 M271.98 26.94 C272.56 44.12, 270.76 62.42, 271.98 80.82 M271.98 26.94 C271.4 46.67, 271.04 64.18, 271.98 80.82 M271.98 80.82 C270.22 98.53, 263.7 107.85, 245.04 107.76 M271.98 80.82 C270.52 100.8, 263.62 105.47, 245.04 107.76 M245.04 107.76 C161.68 110.06, 76.45 107.94, 26.94 107.76 M245.04 107.76 C192 108.98, 139.41 108.76, 26.94 107.76 M26.94 107.76 C9.02 108.83, -0.69 100.31, 0 80.82 M26.94 107.76 C9.07 108.1, 1.74 97.17, 0 80.82 M0 80.82 C0.85 68.17, 1.21 50.77, 0 26.94 M0 80.82 C0.64 66.46, 0.66 52.88, 0 26.94 M0 26.94 C1.35 10.71, 8.34 -0.06, 26.94 0 M0 26.94 C-0.83 10.42, 8.55 0.58, 26.94 0&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(554.688606262207 470.6850629385079) rotate(0 75.32994842529297 12.5)&quot;&gt;&lt;text x=&quot;75.32994842529297&quot; y=&quot;17.619999999999997&quot; font-family=&quot;Excalifont, Xiaolai, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;Network Switch&lt;/text&gt;&lt;/g&gt;&lt;g stroke-linecap=&quot;round&quot; transform=&quot;translate(90.50390625 105.15615393902442) rotate(0 123.361328125 80)&quot;&gt;&lt;path d=&quot;M32 0 C102.15 -4.79, 169.57 -2.66, 214.72 0 C234.28 2.48, 249.44 9.24, 246.72 32 C250.5 56.02, 249.66 78.39, 246.72 128 C249.17 147.24, 234.26 162.29, 214.72 160 C150.48 156.7, 89.99 158.17, 32 160 C10.76 158.89, 2.98 146.79, 0 128 C-3.86 98.92, 0.31 64.57, 0 32 C1.45 11.28, 7.96 -1.47, 32 0&quot; stroke=&quot;none&quot; stroke-width=&quot;0&quot; fill=&quot;var(--color-good-3)&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M32 0 C99.48 -2.28, 163.3 -0.72, 214.72 0 M32 0 C102.87 0.08, 175.02 -1.39, 214.72 0 M214.72 0 C237.02 -1.2, 248.65 11.23, 246.72 32 M214.72 0 C237.83 -0.74, 246.81 9.68, 246.72 32 M246.72 32 C244.87 59.69, 245.69 88.27, 246.72 128 M246.72 32 C245.88 63.36, 247.2 96.03, 246.72 128 M246.72 128 C247.77 149.52, 235.97 158.92, 214.72 160 M246.72 128 C248.3 149.2, 236.25 159.44, 214.72 160 M214.72 160 C176.07 160.47, 140.59 158.84, 32 160 M214.72 160 C146.97 160.65, 79.31 160.6, 32 160 M32 160 C11.7 161.52, -1.6 150.24, 0 128 M32 160 C9.86 161.22, 1.49 149.94, 0 128 M0 128 C2.19 108.26, 2.58 88.11, 0 32 M0 128 C-1.05 96.02, -1.58 64.49, 0 32 M0 32 C-0.24 11.11, 10.39 0.13, 32 0 M0 32 C1.47 8.75, 12.03 1.49, 32 0&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(140.8552703857422 172.65615393902442) rotate(0 73.00996398925781 12.5)&quot;&gt;&lt;text x=&quot;73.00996398925781&quot; y=&quot;17.619999999999997&quot; font-family=&quot;Excalifont, Xiaolai, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;IP: 10.0.0.1/24&lt;/text&gt;&lt;/g&gt;&lt;g transform=&quot;translate(158.8671875 33.64834143902442) rotate(0 42.02996826171875 25)&quot;&gt;&lt;text x=&quot;0&quot; y=&quot;17.619999999999997&quot; font-family=&quot;Excalifont, Xiaolai, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;start&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;Device A&lt;/text&gt;&lt;text x=&quot;0&quot; y=&quot;42.62&quot; font-family=&quot;Excalifont, Xiaolai, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;start&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;&lt;/text&gt;&lt;/g&gt;&lt;g transform=&quot;translate(1004.2148281371074 32.60845938440383) rotate(0 42.7804159157281 12.470979799050161)&quot;&gt;&lt;text x=&quot;0&quot; y=&quot;17.579093124741107&quot; font-family=&quot;Excalifont, Xiaolai, Segoe UI Emoji&quot; font-size=&quot;19.95356767848026px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;start&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;Device B&lt;/text&gt;&lt;/g&gt;&lt;g transform=&quot;translate(251.24081420898438 107.17568518902442) rotate(0 36.059967041015625 12.5)&quot;&gt;&lt;text x=&quot;36.059967041015625&quot; y=&quot;17.619999999999997&quot; font-family=&quot;Excalifont, Xiaolai, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;Layer 3&lt;/text&gt;&lt;/g&gt;&lt;g transform=&quot;translate(250.81690216064453 415.4725601890244) rotate(0 36.97997283935547 12.5)&quot;&gt;&lt;text x=&quot;36.97997283935547&quot; y=&quot;17.619999999999997&quot; font-family=&quot;Excalifont, Xiaolai, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;Layer 2&lt;/text&gt;&lt;/g&gt;&lt;g transform=&quot;translate(1075.286937444885 422.377241460155) rotate(0 36.89411953992203 12.470979799050156)&quot;&gt;&lt;text x=&quot;36.89411953992205&quot; y=&quot;17.579093124741107&quot; font-family=&quot;Excalifont, Xiaolai, Segoe UI Emoji&quot; font-size=&quot;19.95356767848026px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;Layer 2&lt;/text&gt;&lt;/g&gt;&lt;g stroke-linecap=&quot;round&quot; transform=&quot;translate(922.6262413925301 120.08848549355349) rotate(0 123.07493048246988 79.81427071392103)&quot;&gt;&lt;path d=&quot;M32 0 C72.97 -0.82, 117.57 -0.78, 214.15 0 C233.76 1.87, 248.98 13.2, 246.15 32 C244.51 57.9, 243.46 79.87, 246.15 127.63 C249.72 147.55, 235.71 161.57, 214.15 159.63 C153.55 160.64, 92.67 161.74, 32 159.63 C8.29 162.39, 2.47 151.11, 0 127.63 C0.13 106.98, 2.37 86.31, 0 32 C-0.11 9.02, 11.36 -1.09, 32 0&quot; stroke=&quot;none&quot; stroke-width=&quot;0&quot; fill=&quot;var(--color-bad)&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M32 0 C89.31 1.07, 145.05 1.36, 214.15 0 M32 0 C87.23 1.8, 145.26 0.01, 214.15 0 M214.15 0 C236.23 0.5, 247.04 8.93, 246.15 32 M214.15 0 C234.19 0.75, 248.3 9.87, 246.15 32 M246.15 32 C245.47 53.7, 246.36 76.81, 246.15 127.63 M246.15 32 C245.75 65.78, 245.63 100.46, 246.15 127.63 M246.15 127.63 C247.64 149.64, 235.92 159.82, 214.15 159.63 M246.15 127.63 C248.42 147.72, 233.57 160.05, 214.15 159.63 M214.15 159.63 C155.31 156.37, 93.74 158.83, 32 159.63 M214.15 159.63 C145.05 158.76, 78.13 159.86, 32 159.63 M32 159.63 C11.49 158.55, 0.27 149.79, 0 127.63 M32 159.63 C11.72 158.49, 0.52 147.18, 0 127.63 M0 127.63 C2.05 98.01, 0.09 65.56, 0 32 M0 127.63 C0.88 93.72, -0.07 61.08, 0 32 M0 32 C1.8 12.03, 11.24 -1.34, 32 0 M0 32 C1.3 12.51, 9.53 -1.98, 32 0&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(970.1127014160156 187.43177640842435) rotate(0 75.58847045898438 12.470979799050156)&quot;&gt;&lt;text x=&quot;75.58847045898438&quot; y=&quot;17.579093124741107&quot; font-family=&quot;Excalifont, Xiaolai, Segoe UI Emoji&quot; font-size=&quot;19.95356767848026px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;IP: 10.0.0.2/24&lt;/text&gt;&lt;/g&gt;&lt;g transform=&quot;translate(1076.9024027754829 122.36443930688017) rotate(0 35.97624964183365 12.470979799050163)&quot;&gt;&lt;text x=&quot;35.97624964183364&quot; y=&quot;17.579093124741107&quot; font-family=&quot;Excalifont, Xiaolai, Segoe UI Emoji&quot; font-size=&quot;19.95356767848026px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;Layer 3&lt;/text&gt;&lt;/g&gt;&lt;g mask=&quot;url(#mask-Pda5XBN6nUZM_KkkOPi5x)&quot; stroke-linecap=&quot;round&quot;&gt;&lt;g transform=&quot;translate(206.45210287851808 268.3333191551128) rotate(0 0 70.99013411515007)&quot;&gt;&lt;path d=&quot;M0 0 C-1.29 44.2, -1.16 86.72, 0 141.98 M0 0 C0.04 29.88, -0.16 59.82, 0 141.98&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(206.45210287851808 268.3333191551128) rotate(0 0 70.99013411515007)&quot;&gt;&lt;path d=&quot;M8.36 23.56 C4.69 18.14, 2.32 11.05, 0 0 M8.36 23.56 C7.29 18.57, 5.32 13.59, 0 0&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(206.45210287851808 268.3333191551128) rotate(0 0 70.99013411515007)&quot;&gt;&lt;path d=&quot;M-8.74 23.42 C-7.29 18.07, -4.53 11.02, 0 0 M-8.74 23.42 C-6.21 18.32, -4.56 13.37, 0 0&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(206.45210287851808 268.3333191551128) rotate(0 0 70.99013411515007)&quot;&gt;&lt;path d=&quot;M-8.57 118.5 C-7.21 127.2, -4.5 134.21, 0 141.98 M-8.57 118.5 C-6.26 123.3, -4.65 128.24, 0 141.98&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(206.45210287851808 268.3333191551128) rotate(0 0 70.99013411515007)&quot;&gt;&lt;path d=&quot;M8.53 118.48 C4.77 127.16, 2.35 134.17, 0 141.98 M8.53 118.48 C7.23 123.42, 5.23 128.37, 0 141.98&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;/g&gt;&lt;mask id=&quot;mask-Pda5XBN6nUZM_KkkOPi5x&quot;&gt;&lt;rect x=&quot;0&quot; y=&quot;0&quot; fill=&quot;var(--primary-text-color)&quot; width=&quot;306.4521028785181&quot; height=&quot;510.3135873854129&quot;&gt;&lt;/rect&gt;&lt;rect x=&quot;115.66217062754151&quot; y=&quot;301.8234532702629&quot; fill=&quot;&quot; width=&quot;181.57986450195312&quot; height=&quot;75&quot; opacity=&quot;1&quot;&gt;&lt;/rect&gt;&lt;/mask&gt;&lt;g transform=&quot;translate(115.66217062754151 301.8234532702629) rotate(0 90.33281932066586 37.499999999999986)&quot;&gt;&lt;text x=&quot;90.78993225097656&quot; y=&quot;17.619999999999997&quot; font-family=&quot;Excalifont, Xiaolai, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;Hey can you please&lt;/text&gt;&lt;text x=&quot;90.78993225097656&quot; y=&quot;42.62&quot; font-family=&quot;Excalifont, Xiaolai, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;send this packet&lt;/text&gt;&lt;text x=&quot;90.78993225097656&quot; y=&quot;67.62&quot; font-family=&quot;Excalifont, Xiaolai, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;to 10.0.0.2/24?&lt;/text&gt;&lt;/g&gt;&lt;g stroke-linecap=&quot;round&quot; transform=&quot;translate(512.4342447916667 92.39366067595412) rotate(0 117.58430989583337 94.32623361070183)&quot;&gt;&lt;path d=&quot;M32 0 C89.04 3.29, 144.5 3.22, 203.17 0 M32 0 C74.94 3.33, 119.75 2.95, 203.17 0 M203.17 0 C223.37 -3.08, 234.38 6.97, 235.17 32 M203.17 0 C220.71 3.74, 237.47 15.06, 235.17 32 M235.17 32 C239.5 73.92, 234.72 112.81, 235.17 156.65 M235.17 32 C236.51 65.45, 235.16 98.75, 235.17 156.65 M235.17 156.65 C236.14 181.01, 227.08 192.29, 203.17 188.65 M235.17 156.65 C236.63 174.49, 228.12 192.64, 203.17 188.65 M203.17 188.65 C156.16 188.37, 101.57 187.91, 32 188.65 M203.17 188.65 C152.39 192.17, 99.48 190.66, 32 188.65 M32 188.65 C12.75 190.36, -3.83 177.19, 0 156.65 M32 188.65 C6.95 190.57, -2.14 181.78, 0 156.65 M0 156.65 C1.58 123.36, 2.33 95.33, 0 32 M0 156.65 C-3.2 122.23, -3.6 86.99, 0 32 M0 32 C-1.43 9.04, 12.53 1.77, 32 0 M0 32 C-1.38 7.57, 6.74 -4.46, 32 0&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;1&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(538.8622817993165 162.1467720043874) rotate(0 91.15627288818354 24.573122282268557)&quot;&gt;&lt;text x=&quot;91.1562728881836&quot; y=&quot;17.319136584542882&quot; font-family=&quot;Excalifont, Xiaolai, Segoe UI Emoji&quot; font-size=&quot;19.658497825814848px&quot; fill=&quot;var(--color-bad)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;I don&apos;t understand&lt;/text&gt;&lt;text x=&quot;91.1562728881836&quot; y=&quot;41.892258866811446&quot; font-family=&quot;Excalifont, Xiaolai, Segoe UI Emoji&quot; font-size=&quot;19.658497825814848px&quot; fill=&quot;var(--color-bad)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;what 10.0.0.2 is !!&lt;/text&gt;&lt;/g&gt;&lt;g stroke-linecap=&quot;round&quot;&gt;&lt;g transform=&quot;translate(364.42690476312134 448.20134660682004) rotate(0 70.10216534808603 -131.43340108122226)&quot;&gt;&lt;path d=&quot;M0 0 C8.43 -31.24, 27.19 -143.66, 50.56 -187.47 C73.93 -231.28, 125.26 -250.3, 140.2 -262.87 M0 0 C8.43 -31.24, 27.19 -143.66, 50.56 -187.47 C73.93 -231.28, 125.26 -250.3, 140.2 -262.87&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;1&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(364.42690476312134 448.20134660682004) rotate(0 70.10216534808603 -131.43340108122226)&quot;&gt;&lt;path d=&quot;M124.87 -243.12 C130.24 -250.03, 135.6 -256.93, 140.2 -262.87 M124.87 -243.12 C129.44 -249.01, 134.02 -254.9, 140.2 -262.87&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;1&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(364.42690476312134 448.20134660682004) rotate(0 70.10216534808603 -131.43340108122226)&quot;&gt;&lt;path d=&quot;M115.77 -257.6 C124.31 -259.44, 132.86 -261.28, 140.2 -262.87 M115.77 -257.6 C123.06 -259.17, 130.34 -260.74, 140.2 -262.87&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;1&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;/g&gt;&lt;mask&gt;&lt;/mask&gt;&lt;g stroke-linecap=&quot;round&quot;&gt;&lt;g transform=&quot;translate(751.9513737141349 480.42837102464387) rotate(0 72.37758358526958 0.041967477071892745)&quot;&gt;&lt;path d=&quot;M0 0 C24.13 0.01, 120.63 0.07, 144.76 0.08 M0 0 C24.13 0.01, 120.63 0.07, 144.76 0.08&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;4&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(751.9513737141349 480.42837102464387) rotate(0 72.37758358526958 0.041967477071892745)&quot;&gt;&lt;path d=&quot;M23.5 -8.54 C17.37 -6.31, 11.23 -4.08, 0 0 M23.5 -8.54 C14.48 -5.26, 5.47 -1.99, 0 0&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;4&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(751.9513737141349 480.42837102464387) rotate(0 72.37758358526958 0.041967477071892745)&quot;&gt;&lt;path d=&quot;M23.49 8.56 C17.36 6.33, 11.23 4.09, 0 0 M23.49 8.56 C14.48 5.28, 5.47 1.99, 0 0&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;4&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(751.9513737141349 480.42837102464387) rotate(0 72.37758358526958 0.041967477071892745)&quot;&gt;&lt;path d=&quot;M121.26 8.62 C127.39 6.39, 133.52 4.17, 144.76 0.08 M121.26 8.62 C130.27 5.35, 139.29 2.07, 144.76 0.08&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;4&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(751.9513737141349 480.42837102464387) rotate(0 72.37758358526958 0.041967477071892745)&quot;&gt;&lt;path d=&quot;M121.27 -8.48 C127.4 -6.25, 133.53 -4.01, 144.76 0.08 M121.27 -8.48 C130.28 -5.19, 139.29 -1.91, 144.76 0.08&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;4&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;/g&gt;&lt;mask&gt;&lt;/mask&gt;&lt;g stroke-linecap=&quot;round&quot;&gt;&lt;g transform=&quot;translate(475.80609376888697 483.55255800013566) rotate(0 -56.588324317705826 0.49349871842844095)&quot;&gt;&lt;path d=&quot;M0 0 C-18.86 0.16, -94.31 0.82, -113.18 0.99 M0 0 C-18.86 0.16, -94.31 0.82, -113.18 0.99&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;4&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(475.80609376888697 483.55255800013566) rotate(0 -56.588324317705826 0.49349871842844095)&quot;&gt;&lt;path d=&quot;M-23.42 8.76 C-15.99 5.98, -8.56 3.2, 0 0 M-23.42 8.76 C-16.79 6.28, -10.17 3.8, 0 0&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;4&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(475.80609376888697 483.55255800013566) rotate(0 -56.588324317705826 0.49349871842844095)&quot;&gt;&lt;path d=&quot;M-23.57 -8.35 C-16.09 -5.7, -8.62 -3.05, 0 0 M-23.57 -8.35 C-16.9 -5.98, -10.23 -3.62, 0 0&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;4&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(475.80609376888697 483.55255800013566) rotate(0 -56.588324317705826 0.49349871842844095)&quot;&gt;&lt;path d=&quot;M-89.76 -7.77 C-97.19 -4.99, -104.62 -2.21, -113.18 0.99 M-89.76 -7.77 C-96.38 -5.29, -103.01 -2.81, -113.18 0.99&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;4&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(475.80609376888697 483.55255800013566) rotate(0 -56.588324317705826 0.49349871842844095)&quot;&gt;&lt;path d=&quot;M-89.61 9.33 C-97.09 6.69, -104.56 4.04, -113.18 0.99 M-89.61 9.33 C-96.28 6.97, -102.94 4.61, -113.18 0.99&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;4&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;/g&gt;&lt;mask&gt;&lt;/mask&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;That&apos;s where ARP comes in. ARP &lt;em&gt;(Address Resolution Protocol)&lt;/em&gt; maps IP addresses to MAC addresses. If you are familiar with DNS, ARP is similar to that &lt;a href=&quot;#ref-1&quot;&gt;&lt;em&gt;[1]&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;DNS: Map Domain names -&gt; IP addresses

ARP: Map IP addresses -&gt; MAC addresses&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;ARP lives in-between L2 &amp;#x26; L3 - often called L2.5.&lt;/p&gt;
&lt;p&gt;It&apos;s clear that we need a record of mapping of IP addresses to MAC addresses. But where does that record live? And who populates it? If you consider DNS, the mapping needs to be supplied by a human and is stored in whatever nameserver is chosen.&lt;/p&gt;
&lt;p&gt;ARP, on the other hand, doesn&apos;t have a pre-populated record to refer to. This is because unlike DNS, IP -&gt; MAC address is much more dynamic.
Rather, the mapping is queried when required.&lt;/p&gt;
&lt;p&gt;In the example above, we need the mac address for &lt;code class=&quot;language-text&quot;&gt;10.0.0.2&lt;/code&gt;. The networking stack sends an &lt;code class=&quot;language-text&quot;&gt;ARP&lt;/code&gt; request to all the devices connected to the network segment &lt;a href=&quot;#ref-2&quot;&gt;&lt;em&gt;[2]&lt;/em&gt;&lt;/a&gt; requesting whoever has &lt;code class=&quot;language-text&quot;&gt;10.0.0.2&lt;/code&gt; to send it back the MAC address. The way to send this message to all the devices is by using the broadcast address &lt;a href=&quot;#ref-3&quot;&gt;&lt;em&gt;[3]&lt;/em&gt;&lt;/a&gt;.
The ARP request is received by all the devices in the network segment and the device that actually is assigned the IP address will send back an ARP response.
This response is addressed directly to the MAC address of the requester rather than broadcasting it to everyone.&lt;/p&gt;
&lt;p&gt;This mechanism prevents the network administrators from maintaining any sort of record as the protocol is self sufficient.&lt;/p&gt;
&lt;h3 id=&quot;caching&quot;&gt;Caching&lt;/h3&gt;
&lt;p&gt;It would be very inefficient if we had to query the MAC addresses for every single IP packet. That&apos;s why the ARP responses are cached.
The cache usually has a timeout period in the span of a few seconds.&lt;/p&gt;
&lt;p&gt;There&apos;s also another more efficient way to invalidate the cache - it&apos;s by sending a &lt;strong&gt;gratuitous ARP&lt;/strong&gt; message.
Basically, when a device gets a new IP address it&apos;ll simply send a gratuitous ARP message broadcasting its own IP address.
Other devices will then invalidate any stale records.&lt;/p&gt;
&lt;p&gt;Users can also manually flush the entire cache as we&apos;ll see in a minute.&lt;/p&gt;
&lt;h2 id=&quot;arp-inside-the-linux-kernel&quot;&gt;ARP inside the Linux kernel&lt;/h2&gt;
&lt;p&gt;ARP is maintained by the Linux kernel. More specifically by the IPV4 subsytem - &lt;a href=&quot;https://github.com/torvalds/linux/blob/master/net/ipv4/arp.c&quot;&gt;https://github.com/torvalds/linux/blob/master/net/ipv4/arp.c&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;IPV6 doesn&apos;t use ARP. It still does need a protocol to map IP addresses to MAC addresses, but that protocol is not ARP.
Instead, it uses &lt;strong&gt;Neighbor Discovery Protocol&lt;/strong&gt; (NDP).&lt;/p&gt;
&lt;p&gt;ARP is completely transparent. The IP subsytem in Linux automatically issues ARP requests when it doesn’t have a MAC address for a given.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;  ┌────────────────────────────┐                     ┌────────────────────────────┐
  │      Host A (sender)       │                     │      Host B (target)       │
  │────────────────────────────│                     │────────────────────────────│
  │  IP: 192.168.1.10          │                     │  IP: 192.168.1.20          │
  │  MAC: AA:AA:AA:AA:AA:AA    │                     │  MAC: BB:BB:BB:BB:BB:BB    │
  └────────────┬───────────────┘                     └────────────┬───────────────┘
               │                                                  │
               │ 1️⃣  **ARP REQUEST** (broadcast frame)            │
               │     ───────────────────────────────────────────▶ │
               │     Dest MAC: FF:FF:FF:FF:FF:FF                  │
               │     Src  MAC: AA:AA:AA:AA:AA:AA                  │
               │     Payload: “Who has 192.168.1.20?              │
               │               Tell 192.168.1.10.”                │
               │                                                  │
               │                                                  │
               │                2️⃣  **ARP REPLY** (unicast frame) │
               │     ◀─────────────────────────────────────────── │
               │     Dest MAC: AA:AA:AA:AA:AA:AA                  │
               │     Src  MAC: BB:BB:BB:BB:BB:BB                  │
               │     Payload: “192.168.1.20 is at                 │
               │               BB:BB:BB:BB:BB:BB.”                │
               │                                                  │
  ┌────────────▼───────────────┐                     ┌────────────▼───────────────┐
  │ 3️⃣  Host A updates its     │                     │ (Host B may also cache     │
  │     ARP cache:             │                     │  Host A’s mapping.)        │
  │     192.168.1.20 ↔ BB:BB…  │                     └────────────────────────────┘
  └────────────┬───────────────┘
               │
               │ 4️⃣  **Normal traffic** (e.g., IP packets)
               │     sent directly to MAC BB:BB:BB:BB:BB:BB
               ▼
        (Frame delivery continues as usual)



                        Fig: Created by OpenAI o3&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;demo&quot;&gt;Demo&lt;/h2&gt;
&lt;p&gt;Let&apos;s get our hands dirty. We&apos;ll use the mighty &lt;code class=&quot;language-text&quot;&gt;ip&lt;/code&gt; command line tool to investigate ARP records and get a live view of ARP messages.
You can follow along this demo if you&apos;re on a Linux system &lt;em&gt;(not unix - doesn&apos;t work on MacOS)&lt;/em&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token function&quot;&gt;ip&lt;/span&gt; neigh&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;10.99.99.1 dev vmbr0 lladdr 74:fe:ce:6e:01:59 STALE
10.99.99.115 dev vmbr0 lladdr 9c:9d:7e:54:16:78 STALE
10.99.99.51 dev vmbr0 lladdr 30:f9:ed:c1:26:07 REACHABLE
10.99.99.8 dev vmbr0 lladdr 26:f4:91:9d:2c:86 REACHABLE
10.99.99.5 dev vmbr0 lladdr 12:31:43:ab:7d:aa STALE
10.99.99.131 dev vmbr0 lladdr 92:95:3e:3f:cd:81 DELAY
10.99.99.9 dev vmbr0 lladdr fe:7a:08:2c:fa:4e STALE
fe80::c20:96e8:c4b7:d575 dev vmbr0 lladdr 92:95:3e:3f:cd:81 STALE
fe80::fc7a:8ff:fe2c:fa4e dev vmbr0 lladdr fe:7a:08:2c:fa:4e STALE
fe80::103c:2fff:4455:e2e9 dev vmbr0 lladdr 2a:13:6d:9e:b9:ff STALE
fe80::32f9:edff:fec1:2607 dev vmbr0 lladdr 30:f9:ed:c1:26:07 STALE
fe80::28b1:57ff:fe29:ef4a dev vmbr0 lladdr 2a:b1:57:29:ef:4a STALE
fe80::ac09:e9ff:fee2:75d6 dev vmbr0 lladdr ae:09:e9:e2:75:d6 STALE
fe80::901d:ccff:fe64:ad04 dev vmbr0 lladdr 92:1d:cc:64:ad:04 STALE
fe80::c295:cfff:fe8b:a269 dev vmbr0 lladdr c0:95:cf:8b:a2:69 STALE
fe80::88a1:5fff:fe2b:fcd1 dev vmbr0 lladdr 8a:a1:5f:2b:fc:d1 STALE
fe80::1031:43ff:feab:7daa dev vmbr0 lladdr 12:31:43:ab:7d:aa STALE
fe80::21d8:9d95:d19d:af8f dev vmbr0 lladdr 58:24:29:7a:5f:a6 STALE
fe80::1c5e:aa1b:fa11:bebd dev vmbr0 lladdr 02:fa:76:28:bb:25 STALE
fe80::24f4:91ff:fe9d:2c86 dev vmbr0 lladdr 26:f4:91:9d:2c:86 STALE&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;we mentioned ARP doesn&apos;t work with IPv6 and yet we still see ipv6 above. That&apos;s because &lt;code class=&quot;language-text&quot;&gt;ip neigh&lt;/code&gt; returns ARP &amp;#x26; NDISC cache entries.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Let&apos;s try cleaning up the cache&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token function&quot;&gt;ip&lt;/span&gt; neigh flush all&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;monitor-live-arp-message&quot;&gt;Monitor live ARP message&lt;/h3&gt;
&lt;p&gt;We&apos;ll use &lt;code class=&quot;language-text&quot;&gt;tcpdump&lt;/code&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token function&quot;&gt;sudo&lt;/span&gt; tcpdump &lt;span class=&quot;token parameter variable&quot;&gt;-n&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-i&lt;/span&gt; enp8s0 arp

&lt;span class=&quot;token comment&quot;&gt;# replace enp8s0 with your network interface.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# use `ip link` to see the list of network interfaces in your system.&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;listening on enp8s0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
15:15:43.403688 ARP, Reply 10.99.99.222 is-at 2a:b1:57:29:ef:4a, length 28
15:15:46.435738 ARP, Request who-has 10.99.99.222 (ff:ff:ff:ff:ff:ff) tell 10.99.99.222, length 28
15:15:49.467785 ARP, Reply 10.99.99.222 is-at 2a:b1:57:29:ef:4a, length 28
15:15:52.220755 ARP, Request who-has 10.99.99.5 tell 10.99.99.115, length 46
15:15:52.220947 ARP, Reply 10.99.99.5 is-at 12:31:43:ab:7d:aa, length 28
15:15:52.229263 ARP, Request who-has 10.99.99.115 tell 10.99.99.5, length 28
15:15:52.229574 ARP, Reply 10.99.99.115 is-at 9c:9d:7e:54:16:78, length 46
15:15:52.499759 ARP, Request who-has 10.99.99.222 (ff:ff:ff:ff:ff:ff) tell 10.99.99.222, length 28
15:15:55.420196 ARP, Request who-has 10.99.99.55 tell 10.99.99.4, length 28
15:15:55.531744 ARP, Reply 10.99.99.222 is-at 2a:b1:57:29:ef:4a, length 28
15:15:56.402074 ARP, Request who-has 192.168.1.254 tell 192.168.1.1, length 46
15:15:56.451366 ARP, Request who-has 10.99.99.55 tell 10.99.99.4, length 28
15:15:56.771925 ARP, Request who-has 10.99.99.51 tell 10.99.99.9, length 28
15:15:56.772240 ARP, Reply 10.99.99.51 is-at 30:f9:ed:c1:26:07, length 46
15:15:57.401975 ARP, Request who-has 192.168.1.254 tell 192.168.1.1, length 46
15:15:57.474439 ARP, Request who-has 10.99.99.55 tell 10.99.99.4, length 28
15:15:58.402074 ARP, Request who-has 192.168.1.254 tell 192.168.1.1, length 46
15:15:58.498718 ARP, Request who-has 10.99.99.55 tell 10.99.99.4, length 28
15:15:58.571763 ARP, Request who-has 10.99.99.222 (ff:ff:ff:ff:ff:ff) tell 10.99.99.222, length 28
15:15:59.522361 ARP, Request who-has 10.99.99.55 tell 10.99.99.4, length 28
15:16:00.547347 ARP, Request who-has 10.99.99.55 tell 10.99.99.4, length 28
15:16:01.603792 ARP, Reply 10.99.99.222 is-at 2a:b1:57:29:ef:4a, length 28
15:16:02.171191 ARP, Request who-has 10.99.99.1 tell 10.99.99.115, length 46
15:16:02.181128 ARP, Request who-has 10.99.99.2 tell 10.99.99.115, length 46
15:16:02.191115 ARP, Request who-has 10.99.99.3 tell 10.99.99.115, length 46
15:16:02.201213 ARP, Request who-has 10.99.99.4 tell 10.99.99.115, length 46
15:16:02.201264 ARP, Reply 10.99.99.4 is-at 08:97:98:75:cc:fd, length 28
15:16:02.211140 ARP, Request who-has 10.99.99.5 tell 10.99.99.115, length 46
15:16:02.211402 ARP, Reply 10.99.99.5 is-at 12:31:43:ab:7d:aa, length 28
15:16:02.221140 ARP, Request who-has 10.99.99.6 tell 10.99.99.115, length 46
15:16:02.222453 ARP, Reply 10.99.99.6 is-at 2a:b1:57:29:ef:4a, length 28
15:16:02.231200 ARP, Request who-has 10.99.99.7 tell 10.99.99.115, length 46
15:16:02.241218 ARP, Request who-has 10.99.99.8 tell 10.99.99.115, length 46
15:16:02.241411 ARP, Reply 10.99.99.8 is-at 26:f4:91:9d:2c:86, length 28
15:16:02.251118 ARP, Request who-has 10.99.99.9 tell 10.99.99.115, length 46
15:16:02.251278 ARP, Reply 10.99.99.9 is-at fe:7a:08:2c:fa:4e, length 28
15:16:02.261225 ARP, Request who-has 10.99.99.10 tell 10.99.99.115, length 46
15:16:02.271116 ARP, Request who-has 10.99.99.11 tell 10.99.99.115, length 46
15:16:02.281112 ARP, Request who-has 10.99.99.12 tell 10.99.99.115, length 46&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;things-we-didnt-cover&quot;&gt;Things we didn&apos;t cover&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Security aspects (ARP spoofing / Dynamic ARP)&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;div id=&quot;ref-1&quot;&gt;
&lt;i&gt;[1]&lt;/i&gt;. ARP and DNS are similar only at the surface level in the sense that both protocols map an address from a higher level &lt;i&gt;(in the OSI model)&lt;/i&gt; to a lower level. They have a lot of differences - example: DNS is global and hierarchical while ARP is local and flat. So take this analogy with a grain of salt.
&lt;/div&gt;
&lt;/br&gt;
&lt;div id=&quot;ref-2&quot;&gt;
&lt;i&gt;[2]&lt;/i&gt;. A network segment is a section of a computer network where all devices are directly connected and can communicate with each other at the data link layer (Layer 2) without needing to go through a router.
&lt;/div&gt;
&lt;/br&gt;
&lt;div id=&quot;ref-3&quot;&gt;
&lt;i&gt;[3]&lt;/i&gt;. A broadcast address in layer 2 is - &lt;code&gt;FF:FF:FF:FF:FF:FF&lt;/code&gt;. It&apos;s an address that doesn&apos;t belong to a single device but any message sent to that address is delivered to all the devices.
&lt;/div&gt;</content:encoded></item><item><title><![CDATA[IP Routing in Linux]]></title><description><![CDATA[Learn how a linux system decides to route packets out of it]]></description><link>https://www.adityathebe.com/ip-routing-in-linux/</link><guid isPermaLink="false">https://www.adityathebe.com/ip-routing-in-linux/</guid><pubDate>Sun, 27 Apr 2025 14:45:00 GMT</pubDate><content:encoded>&lt;p&gt;If you&apos;re looking to dip your toes into networking, IP routing is a great place to start.
I think it&apos;s the sweet spot because it&apos;s low level and at the same time, not very alien - we have all heard of IP addresses.
And not just that but IP routing is something that&apos;s much more applicable and relevant than starting from the very low level like the physical layer and data link layer.&lt;/p&gt;
&lt;p&gt;In this article, we&apos;ll be covering how a linux networking stack decides to route packets out of it.
We&apos;ll not be covering how the packets traverse the internet to reach their destination.
Although, the concepts we&apos;ll cover will apply there as well.&lt;/p&gt;
&lt;p&gt;In short, we&apos;ll be covering the decision making process of the linux system when it needs to send out a packet.&lt;/p&gt;
&lt;div class=&quot;section-notes&quot;&gt;
&lt;p&gt;Here&apos;s a question for you - Say you&apos;re connected to your home network via ethernet and also to your mobile hotspot via wifi.&lt;/p&gt;
&lt;p&gt;You&apos;re connected to two different networks&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Your home ISP&lt;/li&gt;
&lt;li&gt;Mobile network operator&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When you visit youtube.com, does it use the ethernet or the wifi? Would it be any different if you were to visit gmail.com?&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1200px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/22b66ae36d2a539d05d3e962a798da76/71c1d/packet-confused-dark.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 66.66666666666666%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAIAAAAmMtkJAAAACXBIWXMAAAsTAAALEwEAmpwYAAABD0lEQVR42o2S226DMBBE83VcgoGaWxDGXASCSPz/e069VUsJaTpPa9jxzOz6cn2CUipxSNNUiusLXA7nKIq6rrPWGmPqum7blrqqbmEYviHToWJlW0uB7H29U8RxzBXvlT/JSqHp+36SxH3fe54nX/5FRnAYxqqqGoebQ2c7+fuSzD8E8zwfx3EYhmma1nUdHYitHJjIKTlkqlprCckVvgNGqDFPsSwL9V7/ixwEQVmWiBRFQaH1hzQh5Y4aGiPgXjqPZNkQZNM0EgEO5rFDN7ZJIQ1Zln2L/2SmY55nRoVJWQ9S4p+0MLdta4zZx/41sP3CeCEQRAdggeuY2EnmA2RnLGn/ZZ/2L/KzndNH8gBn+u82OhqxwQAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;packet-confused-light&quot;
        title=&quot;&quot;
        src=&quot;/static/22b66ae36d2a539d05d3e962a798da76/c1b63/packet-confused-dark.png&quot;
        srcset=&quot;/static/22b66ae36d2a539d05d3e962a798da76/5a46d/packet-confused-dark.png 300w,
/static/22b66ae36d2a539d05d3e962a798da76/0a47e/packet-confused-dark.png 600w,
/static/22b66ae36d2a539d05d3e962a798da76/c1b63/packet-confused-dark.png 1200w,
/static/22b66ae36d2a539d05d3e962a798da76/71c1d/packet-confused-dark.png 1536w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;This is exactly the question that we&apos;ll be covering in this article.&lt;/p&gt;
&lt;h2 id=&quot;network-interface&quot;&gt;Network Interface&lt;/h2&gt;
&lt;p&gt;Before we dive into ip routing, it&apos;s important to understand what network interfaces are as they are a crucial part of routing.&lt;/p&gt;
&lt;p&gt;Network interfaces are devices that act as a point of connection in a network. They are the component that connect your device to a network. It&apos;s through them traffic flows in and out of your device.
An interface has a MAC address associated with it that is used to identify it on the network.&lt;/p&gt;
&lt;p&gt;For instance: an ethernet port or a wifi interface.&lt;/p&gt;
&lt;h3 id=&quot;virtual-interfaces&quot;&gt;Virtual interfaces&lt;/h3&gt;
&lt;p&gt;An interface can also be emulated. These virtual interfaces are mainly used in Virtual machines, Containers, VPNs, and in software development.
Examples:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;lo&lt;/strong&gt; loopback interface (127.0.0.1 aka localhost)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;docker0&lt;/strong&gt; interface (used by docker containers)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;tailscale0&lt;/strong&gt; interface (used by tailscale)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;wg0&lt;/strong&gt; interface (used by wireguard)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;veth&lt;/strong&gt; interface (used by virtual ethernet pair)&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;section-notes&quot;&gt;
&lt;h3 id=&quot;analogy-to-understand-network-interfaces&quot;&gt;Analogy to understand network interfaces&lt;/h3&gt;
&lt;p&gt;I&apos;ll use an analogy of social network to explain this.&lt;/p&gt;
&lt;p&gt;Let&apos;s say you want to upload an image to Instagram. To do that, you need to have an Instagram account - there&apos;s no way around it.
You need an entry point to connect to the Instagram world. Likewise, you need an interface to connect to a network.&lt;/p&gt;
&lt;h4 id=&quot;multiple-interfaces&quot;&gt;Multiple interfaces&lt;/h4&gt;
&lt;p&gt;You can have multiple social media accounts to connect to different social networks.
Likewise, your device can also have multiple network interfaces to connect to different networks.
Example, your laptop most likely has an ethernet port in addition to a wifi interface.&lt;/p&gt;
&lt;h4 id=&quot;routing-decision&quot;&gt;Routing decision&lt;/h4&gt;
&lt;p&gt;To upload an image you would visit Instagram - to make a tweet you would visit Twitter - to send an email you would log into your email provider.
In a similar way, IP routing involves which network interface should be chosen to send out a packet.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Pretty cheesy analogy? I think so too. Nonetheless, I think it does help a little.&lt;/p&gt;
&lt;p&gt;Now, to answer the previous question, your device needs a policy to decide whether to use the ethernet interface or the wifi interface to reach a destination like YouTube.&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id=&quot;ip-tool&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;ip&lt;/code&gt; tool&lt;/h2&gt;
&lt;p&gt;In Linux systems, the &lt;code class=&quot;language-text&quot;&gt;ip&lt;/code&gt; tool is the primary way to interact with networking internals and lower level networking APIs.
It&apos;s part of the &lt;code class=&quot;language-text&quot;&gt;iproute2&lt;/code&gt; software suite. It has several commands that manage various aspects of networking. For instance:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;ip link&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;manage network interfaces&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;ip addr&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;manage IP addresses&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;ip route&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;manage routing table&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;ip rule&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;manage routing rules&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;There are numerous more but these are the ones we&apos;ll be focusing on for this article.&lt;/p&gt;
&lt;h3 id=&quot;view-all-interfaces-on-your-system&quot;&gt;View all interfaces on your system&lt;/h3&gt;
&lt;p&gt;Try running &lt;code class=&quot;language-text&quot;&gt;ip link&lt;/code&gt; to see all the interfaces on your system. My Linux desktop has 2 physical interfaces and they are connected to different networks.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;ip&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;link&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;output&quot;&gt;&lt;pre class=&quot;language-output&quot;&gt;&lt;code class=&quot;language-output&quot;&gt;1: lo: &amp;lt;LOOPBACK,UP,LOWER_UP&amp;gt; mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: enp5s0: &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000
    link/ether d8:43:ae:45:c5:62 brd ff:ff:ff:ff:ff:ff
    altname enxd843ae45c562
3: wlo1: &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 qdisc noqueue state UP mode DORMANT group default qlen 1000
    link/ether f0:20:ff:21:57:cd brd ff:ff:ff:ff:ff:ff
    altname wlp0s20f3
    altname wlxf020ff2157cd
4: docker0: &amp;lt;NO-CARRIER,BROADCAST,MULTICAST,UP&amp;gt; mtu 1500 qdisc noqueue state DOWN mode DEFAULT group default
    link/ether ea:d5:3b:18:3f:ad brd ff:ff:ff:ff:ff:ff&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;There&apos;s a lot of information here. I like to use the &lt;code class=&quot;language-text&quot;&gt;-br&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;-c&lt;/code&gt; flags to get a colored brief output.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;ip&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-br&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-c&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;link&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;output&quot;&gt;&lt;pre class=&quot;language-output&quot;&gt;&lt;code class=&quot;language-output&quot;&gt;lo               UNKNOWN        00:00:00:00:00:00 &amp;lt;LOOPBACK,UP,LOWER_UP&amp;gt;
enp5s0           UP             d8:43:ae:45:c5:62 &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt;
wlo1             UP             f0:20:ff:21:57:cd &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt;
docker0          DOWN           ea:d5:3b:18:3f:ad &amp;lt;NO-CARRIER,BROADCAST,MULTICAST,UP&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I have 4 interfaces&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;lo&lt;/code&gt; a loopback interface (virtual). It&apos;s purely virtual and doesn&apos;t have a MAC address.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;enp5s0&lt;/code&gt; a physical interface connected to my home ISP with MAC address &lt;code class=&quot;language-text&quot;&gt;d8:43:ae:45:c5:62&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;wlo1&lt;/code&gt; a wifi interface with MAC address &lt;code class=&quot;language-text&quot;&gt;f0:20:ff:21:57:cd&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;docker0&lt;/code&gt; a virtual interface used by docker containers with MAC address &lt;code class=&quot;language-text&quot;&gt;ea:d5:3b:18:3f:ad&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;They are all enabled as shown by the &quot;UP&quot; flag inside the &lt;code class=&quot;language-text&quot;&gt;&amp;lt;&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;&gt;&lt;/code&gt; brackets.&lt;/p&gt;
&lt;h3 id=&quot;view-ip-addresses-of-all-network-interfaces&quot;&gt;View IP addresses of all network interfaces&lt;/h3&gt;
&lt;p&gt;To view the IP addresses associated with the interfaces, use &lt;code class=&quot;language-text&quot;&gt;ip addr&lt;/code&gt; command.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;ip&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-br&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-c&lt;/span&gt; addr&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;output&quot;&gt;&lt;pre class=&quot;language-output&quot;&gt;&lt;code class=&quot;language-output&quot;&gt;lo               UNKNOWN        127.0.0.1/8 ::1/128
enp5s0           UP             10.99.99.65/24 fe80::14ad:a0eb:c8f:c5b0/64
wlo1             UP             192.168.254.3/24 fe80::5fd6:c815:261b:5df7/64
docker0          DOWN           172.17.0.1/16&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As you can see, the wifi interface (wlo1) and ethernet interface (enp5s0) are connected to two different networks as they have IP addresses on different subnets - &lt;code class=&quot;language-text&quot;&gt;10.99.99.0/24&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;192.168.254.0/24&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;ip-destination-types&quot;&gt;IP destination types&lt;/h2&gt;
&lt;p&gt;Finally, one last thing to keep in mind is the different types of destinations.&lt;/p&gt;
&lt;p&gt;A networking device must be aware of&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;its own IP addresses&lt;/li&gt;
&lt;li&gt;addresses that are directly reachable&lt;/li&gt;
&lt;li&gt;and the rest.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;By &lt;strong&gt;directly reachable&lt;/strong&gt; we mean the destination is on the same network as your device. No routing is involved here.
Your device will use ARP to find the MAC address of the destination and send the packet directly to it.&lt;/p&gt;
&lt;p&gt;For any other destination, the packet will be sent to a router.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;th&gt;Examples&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;local&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;These are the ip addresses of the network interfaces on your system&lt;/td&gt;
&lt;td&gt;The loopback address &lt;code class=&quot;language-text&quot;&gt;127.0.0.1/8&lt;/code&gt;, the local IP addresses &lt;code class=&quot;language-text&quot;&gt;10.99.99.65&lt;/code&gt; &amp;#x26; &lt;code class=&quot;language-text&quot;&gt;192.168.254.3&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;connected networks&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;These are the ip addresses of other devices connected to the same network&lt;/td&gt;
&lt;td&gt;Other devices on &lt;code class=&quot;language-text&quot;&gt;10.99.99.0/24&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;192.168.254.0/24&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;remote&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;These are the ip addresses that are neither local nor connected networks&lt;/td&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;1.1.1.1&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;8.8.8.8&lt;/code&gt;, ...&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Alright, now let&apos;s get into the nitty gritty of routing.&lt;/p&gt;
&lt;p&gt;IP routing in Linux is handled by the IP routing subsystem called &lt;strong&gt;FIB&lt;/strong&gt; &lt;em&gt;(Forwarding Information Base)&lt;/em&gt;.
FIB is a general term, that&apos;s not specific to Linux, that refers to the data plane representation of a routing table.
Cisco, BSD, etc. all use this term.&lt;/p&gt;
&lt;p&gt;The subsystem consists of 3 components that work together to route packets:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Routes&lt;/li&gt;
&lt;li&gt;Routing table&lt;/li&gt;
&lt;li&gt;Routing policy database (RPDB)&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;Routes live in the routing table and RPDB contains rules that determine which routing table to use for a given packet.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;a-route&quot;&gt;A. Route&lt;/h2&gt;
&lt;p&gt;A route is an entry in the routing table that Linux kernel uses to decide where to send a packet (next hop) via what interface based on the destination IP address.
This applies to both incoming and outgoing packets.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;# dummy routes

- to reach (31.13.79.35/32) facebook.com send packets to the 10.99.99.1 (router) via wifi interface
- to reach (142.250.194.174/32) youtube.com send packets to the 10.99.99.1 (router) via ethernet interface&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;A route consists of the following components:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Component&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Destination&lt;/td&gt;
&lt;td&gt;The destination IP address&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Next hop&lt;/td&gt;
&lt;td&gt;When the destination is a remote IP, the next hop is the next router to send the packet to. Usually the &lt;a href=&quot;#default-gateway&quot;&gt;default gateway&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Interface&lt;/td&gt;
&lt;td&gt;The network interface to send the packet out&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Flags&lt;/td&gt;
&lt;td&gt;Special options (like UP, DOWN).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Metric&lt;/td&gt;
&lt;td&gt;A priority number - lower metric means higher priority if multiple routes match.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&quot;ip-route&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;ip route&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;Use &lt;code class=&quot;language-text&quot;&gt;ip route&lt;/code&gt; to see all the routes on your system. &lt;em&gt;(This isn&apos;t entirely accurate as we&apos;ll see when we get into the routing table)&lt;/em&gt;.
Below is an example of actual routes on my Linux machine.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;ip&lt;/span&gt; route list&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;output&quot;&gt;&lt;pre class=&quot;language-output&quot;&gt;&lt;code class=&quot;language-output&quot;&gt;default via 10.99.99.1 dev enp5s0 proto dhcp src 10.99.99.65 metric 100
default via 192.168.254.254 dev wlo1 proto dhcp src 192.168.254.3 metric 600
10.99.99.0/24 dev enp5s0 proto kernel scope link src 10.99.99.65 metric 100
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 linkdown
192.168.254.0/24 dev wlo1 proto kernel scope link src 192.168.254.3 metric 600&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Here&apos;s a breakdown:&lt;/p&gt;
&lt;p&gt;There are 3 routes and 2 default routes. The 3 routes target the connected networks (every device on the respective subnets) and the 2 default routes target the remote destinations.
It&apos;s interesting to note that the wifi interface has a higher metric (600) than the ethernet interface (100). This means the kernel will prefer using ethernet to reach the destination!&lt;/p&gt;
&lt;p&gt;That&apos;s why there&apos;s no next hop specified on them as they can be reached in the very next hop.&lt;/p&gt;
&lt;p&gt;For any other destination, the packet will be sent to the default gateway, which is &lt;code class=&quot;language-text&quot;&gt;10.99.99.1&lt;/code&gt; for &lt;code class=&quot;language-text&quot;&gt;enp5s0&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;192.168.254.254&lt;/code&gt; for &lt;code class=&quot;language-text&quot;&gt;wlo1&lt;/code&gt;, via the respective interfaces.&lt;/p&gt;
&lt;h3 id=&quot;default-gateway&quot;&gt;Default Gateway&lt;/h3&gt;
&lt;p&gt;Essentially, a default gateway is the fallback destination when no specific route is found. Think of it like the &lt;code class=&quot;language-text&quot;&gt;default&lt;/code&gt; case in a switch statement.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;packet &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;new_packet&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;src&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;10.99.99.65&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; dst&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;destination&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;switch&lt;/span&gt; destination &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;10.99.99.0&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;10.99.99.255&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;send_to_next_hop&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;destination&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; nexthop&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;destination&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;interface&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;enp5s0&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;send_to_next_hop&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;destination&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; nexthop&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;10.99.99.1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;interface&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;enp5s0&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// default gateway&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;packet &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;new_packet&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;src&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;192.168.254.3&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; dst&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;destination&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;switch&lt;/span&gt; destination &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;192.168.254.0&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;192.168.254.255&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;send_to_next_hop&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;destination&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; nexthop&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;destination&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;interface&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;wlo1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;send_to_next_hop&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;destination&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; nexthop&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;192.168.254.254&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;interface&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;wlo1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// default gateway&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Next hop means the layer2 packet sends to the MAC address of the next hop. The IP packet still contains the original destination.&lt;/p&gt;
&lt;h3 id=&quot;query-the-route-for-a-destination&quot;&gt;Query the route for a destination&lt;/h3&gt;
&lt;p&gt;You can even check which route a packet takes for a given destination using &lt;code class=&quot;language-text&quot;&gt;ip route get&lt;/code&gt; command.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Local addresses&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;ip&lt;/span&gt; route get &lt;span class=&quot;token number&quot;&gt;10.99&lt;/span&gt;.99.3&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;output&quot;&gt;&lt;pre class=&quot;language-output&quot;&gt;&lt;code class=&quot;language-output&quot;&gt;10.99.99.3 dev enp5s0 src 10.99.99.65 uid 1000
    cache&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Remote addresses&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;ip&lt;/span&gt; route get &lt;span class=&quot;token number&quot;&gt;1.1&lt;/span&gt;.1.1&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;output&quot;&gt;&lt;pre class=&quot;language-output&quot;&gt;&lt;code class=&quot;language-output&quot;&gt;1.1.1.1 via 10.99.99.1 dev enp5s0 src 10.99.99.65 uid 1000
    cache&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As you can see, &lt;code class=&quot;language-text&quot;&gt;1.1.1.1&lt;/code&gt; is not a device on the same subnet as my device. So, the packet will be sent to &lt;code class=&quot;language-text&quot;&gt;10.99.99.1&lt;/code&gt; - which is the default gateway.&lt;/p&gt;
&lt;div class=&quot;section-notes&quot;&gt;
&lt;p&gt;The router will also have its own routing table.
If the router doesn&apos;t have a route specified for &lt;code class=&quot;language-text&quot;&gt;1.1.1.1&lt;/code&gt;, it will send the packet to its own default gateway which is the ISP&apos;s router.&lt;/p&gt;
&lt;p&gt;Once the packet is inside the ISP&apos;s network, protocols like BGP (Border Gateway Protocol) may take over and figure out the best path to the destination.&lt;/p&gt;
&lt;/div&gt;
&lt;h3 id=&quot;adding-a-new-route&quot;&gt;Adding a new route&lt;/h3&gt;
&lt;p&gt;Let&apos;s get our hands dirty! I&apos;ll query &lt;a href=&quot;https://ipinfo.io/ip/&quot;&gt;https://ipinfo.io/ip&lt;/a&gt; to get my public IP address.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-s&lt;/span&gt; https://ipinfo.io/ip&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;output&quot;&gt;&lt;pre class=&quot;language-output&quot;&gt;&lt;code class=&quot;language-output&quot;&gt;43.231.211.110&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In order to see which route this destination will use, we need to get the IP address for ipinfo.io.
I&apos;ll use the &lt;code class=&quot;language-text&quot;&gt;dig&lt;/code&gt; command for it.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;dig&lt;/span&gt; +short ipinfo.io&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;output&quot;&gt;&lt;pre class=&quot;language-output&quot;&gt;&lt;code class=&quot;language-output&quot;&gt;34.117.59.81&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now, let&apos;s see which route this destination will use.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;ip&lt;/span&gt; route get &lt;span class=&quot;token number&quot;&gt;34.117&lt;/span&gt;.59.81&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;output&quot;&gt;&lt;pre class=&quot;language-output&quot;&gt;&lt;code class=&quot;language-output&quot;&gt;34.117.59.81 via 10.99.99.1 dev enp5s0 src 10.99.99.65 uid 1000
    cache&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Sure enough, it&apos;s using the ethernet interface.&lt;/p&gt;
&lt;p&gt;Let&apos;s add a new route so that this destination uses the wifi interface.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;sudo&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;ip&lt;/span&gt; route &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;34.117&lt;/span&gt;.59.81/32 via &lt;span class=&quot;token number&quot;&gt;192.168&lt;/span&gt;.254.254 dev wlo1&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now, let&apos;s check which route this destination will use.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;ip&lt;/span&gt; route get &lt;span class=&quot;token number&quot;&gt;34.117&lt;/span&gt;.59.81&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;output&quot;&gt;&lt;pre class=&quot;language-output&quot;&gt;&lt;code class=&quot;language-output&quot;&gt;34.117.59.81 via 192.168.254.254 dev wlo1 src 192.168.254.3 uid 1000
    cache&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-s&lt;/span&gt; https://ipinfo.io/ip&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;output&quot;&gt;&lt;pre class=&quot;language-output&quot;&gt;&lt;code class=&quot;language-output&quot;&gt;120.89.104.16&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And there it is — the public IP address has changed, confirming that traffic is now going through the Wi-Fi interface.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;It&apos;s important to note that this route isn&apos;t persistent and will be lost after a reboot.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Let&apos;s clean it up&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;sudo&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;ip&lt;/span&gt; route del &lt;span class=&quot;token number&quot;&gt;34.117&lt;/span&gt;.59.81/32&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;b-routing-table&quot;&gt;B. Routing Table&lt;/h2&gt;
&lt;p&gt;A routing table is a collection of routes. You can have multiple routing tables on a single system.
By default, there are three built-in routing tables:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;local&lt;/li&gt;
&lt;li&gt;main (ip route uses this table by default)&lt;/li&gt;
&lt;li&gt;default (often empty unless configured)&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;section-notes&quot;&gt;
&lt;p&gt;I couldn&apos;t find any command that lists out all the routing tables. Routing tables are defined in &lt;code class=&quot;language-text&quot;&gt;/etc/iproute2/rt_tables&lt;/code&gt; file. So just check that out.&lt;/p&gt;
&lt;p&gt;It&apos;s possible that file is not present on your system. My desktop didn&apos;t have it as well. Here&apos;s what it looks like in one of my vms.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;cat&lt;/span&gt; /etc/iproute2/rt_tables&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;output&quot;&gt;&lt;pre class=&quot;language-output&quot;&gt;&lt;code class=&quot;language-output&quot;&gt;#
# reserved values
#
255     local
254     main
253     default
0       unspec
#
# local
#
#1      inr.ruhep&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h3 id=&quot;local-routing-table&quot;&gt;local routing table&lt;/h3&gt;
&lt;p&gt;The local routing table contains routes for local destinations (i.e. its own IP addresses).
It&apos;s maintainted by the kernel itself and is used to route incoming packets or outgoing packets destined to the host itself.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;ip&lt;/span&gt; route show table &lt;span class=&quot;token builtin class-name&quot;&gt;local&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;output&quot;&gt;&lt;pre class=&quot;language-output&quot;&gt;&lt;code class=&quot;language-output&quot;&gt;local 10.99.99.65 dev enp5s0 proto kernel scope host src 10.99.99.65
broadcast 10.99.99.255 dev enp5s0 proto kernel scope link src 10.99.99.65
local 127.0.0.0/8 dev lo proto kernel scope host src 127.0.0.1
local 127.0.0.1 dev lo proto kernel scope host src 127.0.0.1
broadcast 127.255.255.255 dev lo proto kernel scope link src 127.0.0.1
local 172.17.0.1 dev docker0 proto kernel scope host src 172.17.0.1
broadcast 172.17.255.255 dev docker0 proto kernel scope link src 172.17.0.1 linkdown
local 192.168.254.3 dev wlo1 proto kernel scope host src 192.168.254.3
broadcast 192.168.254.255 dev wlo1 proto kernel scope link src 192.168.254.3&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code class=&quot;language-text&quot;&gt;broadcast&lt;/code&gt; entries are interesting ones. Broadcast IP addresses are special addresses that deliver packets to all the devices on the network.
If you send a packet to a broadcast address, it will be sent to all the devices on the network. Hence - the name.&lt;/p&gt;
&lt;h3 id=&quot;main-routing-table&quot;&gt;main routing table&lt;/h3&gt;
&lt;p&gt;The main routing table contains routes for all other destinations (connected networks &amp;#x26; remote destinations).&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;ip&lt;/span&gt; route show table main&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;output&quot;&gt;&lt;pre class=&quot;language-output&quot;&gt;&lt;code class=&quot;language-output&quot;&gt;default via 10.99.99.1 dev enp5s0 proto dhcp src 10.99.99.65 metric 100
default via 192.168.254.254 dev wlo1 proto dhcp src 192.168.254.3 metric 600
10.99.99.0/24 dev enp5s0 proto kernel scope link src 10.99.99.65 metric 100
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 linkdown
192.168.254.0/24 dev wlo1 proto kernel scope link src 192.168.254.3 metric 600&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is the default routing table that &lt;code class=&quot;language-text&quot;&gt;ip route&lt;/code&gt; uses.&lt;/p&gt;
&lt;h3 id=&quot;default-routing-table&quot;&gt;default routing table&lt;/h3&gt;
&lt;p&gt;I&apos;m not sure what the purpose of this table is. It isn&apos;t even present on my system.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;ip&lt;/span&gt; route show table default&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;output&quot;&gt;&lt;pre class=&quot;language-output&quot;&gt;&lt;code class=&quot;language-output&quot;&gt;Error: ipv4: FIB table does not exist.
Dump terminated&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;c-rule&quot;&gt;C. Rule&lt;/h2&gt;
&lt;p&gt;A rule, determines which routing table to use for a given packet.
Each rule has a priority, and rules are examined sequentially from rule 0 through rule 32767.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;ip&lt;/span&gt; rule show&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;output&quot;&gt;&lt;pre class=&quot;language-output&quot;&gt;&lt;code class=&quot;language-output&quot;&gt;0:      from all lookup local
32766:  from all lookup main
32767:  from all lookup default&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4 id=&quot;routing-policy-database-rpdb&quot;&gt;Routing Policy Database (RPDB)&lt;/h4&gt;
&lt;p&gt;Rules live in a database called the Routing Policy Database (RPDB).&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;RPDB (Rules: priority-ordered)
 └──&gt; Routing Table (chosen by rule)
      └──&gt; Routes (prefix + metric ordered)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;things-we-didnt-cover&quot;&gt;Things we didn&apos;t cover&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Why do we need more than one routing table?&lt;/li&gt;
&lt;li&gt;Routing cache&lt;/li&gt;
&lt;li&gt;Route matching algorithm (longest prefix match and lowest metric wins)&lt;/li&gt;
&lt;li&gt;Rule types (unicast, multicast, prohibit, blackhole, unreachable)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;references&quot;&gt;References:&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;iproute2 manual pages: &lt;code class=&quot;language-text&quot;&gt;man ip&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://datahacker.blog/industry/technology-menu/networking/routes-and-rules/iproute-and-routing-tables&quot;&gt;https://datahacker.blog/industry/technology-menu/networking/routes-and-rules/iproute-and-routing-tables&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://baturin.org/docs/iproute2/&quot;&gt;https://baturin.org/docs/iproute2/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://youtu.be/zstdOS_6ajY?si=gCPBv2c_N-7aNssi&quot;&gt;https://youtu.be/zstdOS_6ajY?si=gCPBv2c_N-7aNssi&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://linux-ip.net/html/ch-routing.html&quot;&gt;http://linux-ip.net/html/ch-routing.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Golang Footgun: Why is this interface not nil?]]></title><description><![CDATA[I recently ran into this nasty bug in Go where an interface that was supposed to be nil wasn't.]]></description><link>https://www.adityathebe.com/golang-nil-interface-check</link><guid isPermaLink="false">https://www.adityathebe.com/golang-nil-interface-check</guid><pubDate>Fri, 04 Apr 2025 23:30:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1200px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/21646607efe7707e7dbcfad365006bc2/71c1d/gopher-footgun.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 66.66666666666666%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAIAAAAmMtkJAAAACXBIWXMAAAsTAAALEwEAmpwYAAACaElEQVR42mWS709SURjH/Vt60xvftlmzpVu9aVYWq5XhFssCieXMjTV1KWpSICQ2DdIRJhoIZDmdudQEmUk1yYwfohCiiQT3Avfcy7387sAlKt2+Z+d5cT7n+32ePSUUjtKKAQQqHQfZJAGVycQTsSgJEBKgRDQIi+LLokroi8TRVBzLJnDnllP3YWF8YU6uGdvb8+54XfZ1q++HKxGLHOAhUgIPAZAMic2ajQKlskXxnCPpZT4USvqebNjXILmybPy57T7snIdhKgyBntqZ6fOCLqv102fTfGPj3R6pyGRZ9rhslo+moN8XJyIkjpB/MLLoDFtNUdi2d4urGpW8nexWqRjVVZWMS53jenTf59m0R0J+igjTwP8wyMFJMurzudmKIe7E1LGa2jPlx4+Uloo02mwcJCksZwsKJPUPn4OhKDyMowHBiJpnmDxbz70nFl9oaWvqlcWiIUgSWAgODBaxfOfkITgCEL/QMFE3PMrqlzOfPrvyqKdGKDKvmGMgnILB0F84hiTiOOQLMKBjYwj8FQnsNilf1r1QM6Wya4/Fp3kNVWzOrc5OtV7bwGNfrD5Xz745M/UmkyBgkL9wbhNysfcfqIZvawzcEQ13THe0rKyCc+c6n3+j9iqLVTuo6O9ob9Vp1SkKQDM6bwGGYbxuZ0t3F+N+M2dIdbmto7ziJL+1WdDeWnnqhEwqWjLOWZaN7o3vcDo0WYTR/A6GwoFdr8vmsK851ldtX7/Mz04vzr8bVAzIB/qWFt+/1r/y73gSZPSAMz0zlCIiSQqkKSxNAdgbiAThemw6vm27neHgHgxMD7zo/BvkPnZW6M2yVAAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;Gopher&quot;
        title=&quot;&quot;
        src=&quot;/static/21646607efe7707e7dbcfad365006bc2/c1b63/gopher-footgun.png&quot;
        srcset=&quot;/static/21646607efe7707e7dbcfad365006bc2/5a46d/gopher-footgun.png 300w,
/static/21646607efe7707e7dbcfad365006bc2/0a47e/gopher-footgun.png 600w,
/static/21646607efe7707e7dbcfad365006bc2/c1b63/gopher-footgun.png 1200w,
/static/21646607efe7707e7dbcfad365006bc2/71c1d/gopher-footgun.png 1536w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;
&lt;em&gt;Source: Gpt-4o&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;I&apos;m gonna show you a snippet of a Go code and you tell me what the output is gonna be.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;package&lt;/span&gt; main

&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;fmt&quot;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;type&lt;/span&gt; MyCustomType &lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getResult&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; any &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; t &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;MyCustomType
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; t
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  result &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getResult&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  fmt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;result &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Try it out: https://goplay.tools/snippet/-axDsS493LZ&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Here&apos;s what went through my mind:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;variable &lt;code class=&quot;language-text&quot;&gt;t&lt;/code&gt; is of type &lt;code class=&quot;language-text&quot;&gt;*MyCustomType&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;t&lt;/code&gt; is nil&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;getResult&lt;/code&gt; returns the nil &lt;code class=&quot;language-text&quot;&gt;t&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;so, result must also be nil&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Let&apos;s see what happens when we run the code.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;go run main.go
&lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;The crucial bit of information here is that the function returns an interface - in this case &lt;code class=&quot;language-text&quot;&gt;any&lt;/code&gt; or an empty interface &lt;code class=&quot;language-text&quot;&gt;interface{}&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;explanation&quot;&gt;Explanation&lt;/h2&gt;
&lt;p&gt;In Go, an interface is a pair of a type &amp;#x26; a value &lt;code class=&quot;language-text&quot;&gt;(T, V)&lt;/code&gt;.
Eg: in &lt;code class=&quot;language-text&quot;&gt;var myInterface any = 3&lt;/code&gt;, the interface &lt;code class=&quot;language-text&quot;&gt;myInterface&lt;/code&gt; has a type &lt;code class=&quot;language-text&quot;&gt;int&lt;/code&gt; and a value &lt;code class=&quot;language-text&quot;&gt;3&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;For an interface to be nil, both its type and value must be nil. The following example shows a nil interface:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; a any
fmt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// true&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Try it: https://go.dev/play/p/X0h-DCswGPG&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It&apos;s nil because it hasn&apos;t been assigned any concrete value yet.&lt;/p&gt;
&lt;p&gt;On the contrary, take a look at the following code:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; a &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; b any &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; a
fmt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Printf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;typeof a: %T\n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; a&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
fmt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Printf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;typeof b: %T\n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; b&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
fmt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Printf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;a == nil: %v\n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; a &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
fmt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Printf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;b == nil: %v\n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; b &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Try it: https://go.dev/play/p/3gq25jCzepx&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The interface &lt;code class=&quot;language-text&quot;&gt;b&lt;/code&gt; is not nil as its type is &lt;code class=&quot;language-text&quot;&gt;*int&lt;/code&gt; and its value is &lt;code class=&quot;language-text&quot;&gt;nil&lt;/code&gt;.
It&apos;s important to distinguish that the interface holds in a nil pointer, but it&apos;s not nil itself.&lt;/p&gt;
&lt;p&gt;The above program outputs:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;typeof a: *int
typeof b: *int
a == nil: true
b == nil: false&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;This is also addressed in the &lt;a href=&quot;https://go.dev/doc/faq#nil_error&quot;&gt;Go FAQ&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;how-to-check-the-underlying-value-for-nil&quot;&gt;How to Check the Underlying Value for Nil&lt;/h2&gt;
&lt;p&gt;So, what&apos;s the correct way to check if the underlying value is nil when you receive an interface?
The two approaches are:&lt;/p&gt;
&lt;h3 id=&quot;type-assertion&quot;&gt;Type assertion&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;package&lt;/span&gt; main

&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;fmt&quot;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;type&lt;/span&gt; MyCustomType &lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getResult&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; any &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; t &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;MyCustomType
	&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; t
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	result &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getResult&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; v&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; ok &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; result&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;MyCustomType&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; ok &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		fmt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Printf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;v is nil: %v, result is nil: %v\n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; v &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; result &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Try it out: https://goplay.tools/snippet/MeMUtzKG9LT&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;reflection&quot;&gt;Reflection&lt;/h3&gt;
&lt;p&gt;Type assertion works fine when you know exactly what type the function returns.
In our case, we know that the function returns a pointer to &lt;code class=&quot;language-text&quot;&gt;MyCustomType&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;But, imagine cases where getResult() could conditionally return various types.
We would need to assert all the possible types that getResult() could return.
Or, it could also return an unexported type so we cannot assert it.&lt;/p&gt;
&lt;p&gt;In such cases, we can use reflection to check if the result is nil.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;package&lt;/span&gt; main

&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
	&lt;span class=&quot;token string&quot;&gt;&quot;fmt&quot;&lt;/span&gt;
	&lt;span class=&quot;token string&quot;&gt;&quot;reflect&quot;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;type&lt;/span&gt; MyCustomType &lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getResult&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; any &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; t &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;MyCustomType
	&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; t
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	result &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getResult&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	fmt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Printf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;result is nil: %v\n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; result &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// false&lt;/span&gt;
	fmt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Printf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;result contains nil: %v\n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; reflect&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;ValueOf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;result&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;IsNil&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// true&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Try it out: https://goplay.tools/snippet/ZxJNYBW0pVz&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I must say that using &lt;code class=&quot;language-text&quot;&gt;reflection&lt;/code&gt; is generally frowned upon as it adds a lot of runtime overhead. There are also some caveats.
Eg: &lt;code class=&quot;language-text&quot;&gt;reflect.ValueOf(result).IsNil()&lt;/code&gt; can panic for certain types like a &lt;code class=&quot;language-text&quot;&gt;string&lt;/code&gt; or an &lt;code class=&quot;language-text&quot;&gt;int&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Here&apos;s a generic helper function that can be used to check if the underlying value is nil.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;isNil&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;i any&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;nil&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

	v &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; reflect&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;ValueOf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	k &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; v&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Kind&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

	&lt;span class=&quot;token comment&quot;&gt;// Check for kinds that have a concept of nilness&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;switch&lt;/span&gt; k &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; reflect&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Chan&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; reflect&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Func&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; reflect&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Interface&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; reflect&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Map&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; reflect&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Ptr&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; reflect&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Slice&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; reflect&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;UnsafePointer&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
		&lt;span class=&quot;token comment&quot;&gt;// For these kinds, IsNil() reports whether the value is nil&lt;/span&gt;
		&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; v&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;IsNil&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
		&lt;span class=&quot;token comment&quot;&gt;// Other kinds (structs, basic types, arrays) cannot be nil themselves&lt;/span&gt;
		&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Git Hygiene: How to Automatically Delete Stale Local Branches
]]></title><description><![CDATA[Learn how to keep your Git workflow clean by automatically detecting and removing stale local branches that no longer exist in the remote repository. This step-by-step guide shows you how to create a custom Git alias to streamline branch management
]]></description><link>https://www.adityathebe.com/delete-stale-git-branches</link><guid isPermaLink="false">https://www.adityathebe.com/delete-stale-git-branches</guid><pubDate>Thu, 27 Mar 2025 21:25:00 GMT</pubDate><content:encoded>&lt;p&gt;Feature branches in Git can quickly pile up. I like to keep my branches clean because when using auto completion I don&apos;t want to go through a list of branches that have already been merged or discarded. And I just like to keep things clean and tidy in general.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1200px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/8d726f1c9729fc1ff2c2268705805276/71c1d/git.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 66.66666666666666%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAIAAAAmMtkJAAAACXBIWXMAAAsTAAALEwEAmpwYAAACAUlEQVR42n2S62+aYBTG/cv3Ydn3fVg/dB92SbZmabba1arVCgqdFMVLkKlU0aKgQLiMWpWbwLujnZct25JDQuD8zvOc530Tq8BBcTCWhqoqx5Gv61PT0GRJjCI/XLnbcrblHlbiCe73O6nUGcNQw2HvzdvjdOZcVaUo9P7o/jvMtRofPr4rU4SmTfLX6Vv6ZjDg48jbyv4DhgcUDEOp1Wkcz5dK18VibiDwuq647txzH6Pwf7aXCMXVSpnjmoXCVTZ7AQBFEQRRwPGcaajgCzAYsZnigtM9DJ+WczuXu0xdJgkSA6ZcLgGWPD+dPRjxOjYHgE0tA38ZroNwdradwF+4zmwxt09O3p8lT6PIi+NIkoYPtgHdnjuH/QWBF0XhrteeTscIBTAIwMTTmI15RFFklbll2bqhK6apKsp4MhHtH/p3rsG2aq1Wne9yPM8hFIHeDl6Lw+YkiddrNIbnPn/5NBIF29YtSxOErij2Zfle1ybNJtPvdxEK1/5/hxFBYEBC6/MXzyB50ATx3l273WbxYr6AXdH0jSzdI7Q6tP0LTme+ZrIXo5FAkliZKsnSEAZJ627EVCm4QvDie/PdyW3gTfqdDnv8+ujV0UvwCSE1GhU4gkrlG6y6XNigTBLYan/gzl4Z6nFm2ZZumRoUJA+eTUOBywOZAwx/oQ5lw5X7EyVNvS0BOSJLAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;Git Branch Relationship&quot;
        title=&quot;&quot;
        src=&quot;/static/8d726f1c9729fc1ff2c2268705805276/c1b63/git.png&quot;
        srcset=&quot;/static/8d726f1c9729fc1ff2c2268705805276/5a46d/git.png 300w,
/static/8d726f1c9729fc1ff2c2268705805276/0a47e/git.png 600w,
/static/8d726f1c9729fc1ff2c2268705805276/c1b63/git.png 1200w,
/static/8d726f1c9729fc1ff2c2268705805276/71c1d/git.png 1536w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;
&lt;em&gt;Created with Gpt4o&lt;/em&gt;&lt;/p&gt;
&lt;h2 id=&quot;primer-on-git-branches&quot;&gt;Primer on Git branches&lt;/h2&gt;
&lt;p&gt;Let&apos;s say you have a feature branch &lt;code class=&quot;language-text&quot;&gt;feat/notifications&lt;/code&gt;.
You push that branch to the remote repository to create a PR.
The remote is usually named &lt;code class=&quot;language-text&quot;&gt;origin&lt;/code&gt; so you will have another branch, in your local repository, called &lt;code class=&quot;language-text&quot;&gt;origin/feat/notifications&lt;/code&gt; that tracks the remote branch.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Branch&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;feat/notifications&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The local branch you created&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;origin/feat/notifications&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The reference in your local repo that tracks the remote branch&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;feat/notifications&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The branch on the &lt;strong&gt;remote&lt;/strong&gt; repository&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Try &lt;code class=&quot;language-text&quot;&gt;git branch -vv&lt;/code&gt; to see all the branches and their tracking branches.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; branch &lt;span class=&quot;token parameter variable&quot;&gt;-vv&lt;/span&gt;
* feat/notifications a84be78 &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;origin/feat/notifications&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; feat: &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; notifications
  main               &lt;span class=&quot;token number&quot;&gt;2831500&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;origin/main&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; chore: remove deadcode&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;delete-remote-branches-locally&quot;&gt;Delete remote branches locally&lt;/h2&gt;
&lt;p&gt;Now, assume the PR got merged and the branch &lt;code class=&quot;language-text&quot;&gt;feat/notifications&lt;/code&gt; was deleted from the remote repository.&lt;/p&gt;
&lt;p&gt;Running &lt;code class=&quot;language-text&quot;&gt;git fetch -p&lt;/code&gt; (short for &lt;code class=&quot;language-text&quot;&gt;git fetch --prune&lt;/code&gt;) will delete the &lt;code class=&quot;language-text&quot;&gt;origin/feat/notifications&lt;/code&gt; branch from your local repository but not the &lt;code class=&quot;language-text&quot;&gt;feat/notifications&lt;/code&gt; branch.&lt;/p&gt;
&lt;p&gt;If you list the remote branches again, you&apos;ll see that the branch is marked as &lt;strong&gt;gone&lt;/strong&gt;.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; branch &lt;span class=&quot;token parameter variable&quot;&gt;-vv&lt;/span&gt;
* feat/notifications a84be78 &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;origin/feat/notifications: gone&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; feat: &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; notifications
  main               &lt;span class=&quot;token number&quot;&gt;2831500&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;origin/main&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; chore: remove deadcode&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;So we have just deleted the remote tracking branch. But how do we delete the local branch?&lt;/p&gt;
&lt;p&gt;When you run &lt;code class=&quot;language-text&quot;&gt;git fetch -p&lt;/code&gt;, it lists out all the remote tracking branches it just deleted.
Then, for each of those branches, you need to manually run &lt;code class=&quot;language-text&quot;&gt;git branch -D &amp;lt;branch-name&gt;&lt;/code&gt; to delete the branch from your local repository.&lt;/p&gt;
&lt;p&gt;This is how I&apos;ve been doing it so far but there&apos;s a better way to do it.&lt;/p&gt;
&lt;h3 id=&quot;list-out-all-the-stale-branches&quot;&gt;List out all the stale branches&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; branch &lt;span class=&quot;token parameter variable&quot;&gt;-vv&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; rg &lt;span class=&quot;token string&quot;&gt;&apos;\\[.*gone.*\\]&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;sed&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;s/^..//&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;cut&lt;/span&gt; -d&lt;span class=&quot;token string&quot;&gt;&apos; &apos;&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-f1&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This uses a few unix commands to extract the name of the branches that have been deleted from the remote repository.
Finally, we use &lt;code class=&quot;language-text&quot;&gt;xargs&lt;/code&gt; to delete the branches from the local repository.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; branch &lt;span class=&quot;token parameter variable&quot;&gt;-vv&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; rg &lt;span class=&quot;token string&quot;&gt;&apos;\\[.*gone.*\\]&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;sed&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;s/^..//&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;cut&lt;/span&gt; -d&lt;span class=&quot;token string&quot;&gt;&apos; &apos;&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-f1&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;xargs&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-r&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; branch &lt;span class=&quot;token parameter variable&quot;&gt;-D&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To break it down&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;git branch -vv&lt;/code&gt; - Lists all branches with their tracking information&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;rg &apos;\\[.*gone.*\\]&apos;&lt;/code&gt; - Filters branches that have been marked as &quot;gone&quot; (deleted from remote)&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;sed &apos;s/^..//&apos;&lt;/code&gt; - Removes the first two characters from each line (which are either &lt;code class=&quot;language-text&quot;&gt;* &lt;/code&gt; for the current branch or &lt;code class=&quot;language-text&quot;&gt;  &lt;/code&gt; for other branches)&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;cut -d&apos; &apos; -f1&lt;/code&gt; - Splits the line by spaces and extracts the first field, which is the branch name&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;xargs -r git branch -D&lt;/code&gt; - Passes each branch name to the &lt;code class=&quot;language-text&quot;&gt;git branch -D&lt;/code&gt; command to delete it locally&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;setup-an-alias-in-git-config&quot;&gt;Setup an alias in Git config&lt;/h2&gt;
&lt;p&gt;I have this as an alias in my git config in &lt;code class=&quot;language-text&quot;&gt;~/.config/git/config&lt;/code&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;[alias]
    clean-gone = &quot;!git branch -vv | rg &apos;\\[.*gone.*\\]&apos; | sed &apos;s/^..//&apos; | cut -d&apos; &apos; -f1 | xargs -r git branch -D&quot;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now, I can simply run &lt;code class=&quot;language-text&quot;&gt;git pull &amp;amp;&amp;amp; git fetch -p &amp;amp;&amp;amp; git clean-gone&lt;/code&gt; to clean up those stale branches.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; pull &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; fetch &lt;span class=&quot;token parameter variable&quot;&gt;-p&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; clean-gone
Deleted branch feat/notifications &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;was a84be78&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Why I switched from Arch Linux to MacOS]]></title><description><![CDATA[I recently bought a Macbook Pro and I've been using it exclusively as my development machine.]]></description><link>https://www.adityathebe.com/switching-from-arch-linux-to-mac-os</link><guid isPermaLink="false">https://www.adityathebe.com/switching-from-arch-linux-to-mac-os</guid><pubDate>Sat, 22 Mar 2025 18:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I&apos;ve been using Linux for about six or so years now and five of those years have been with Arch Linux.
I&apos;ve customized my development environment a lot over the years and not to sound like a braggart, but I consider myself a power user.
It was hard to imagine moving to a different operating system, because I had a very tailored development environment where I was very efficient.&lt;/p&gt;
&lt;p&gt;Arch wasn&apos;t perfect, but it was close. If you aren&apos;t familiar with Arch - it&apos;s a Linux distro that&apos;s very barebones and requires the user to place pieces together to have a working system. It&apos;s like Subway - you choose all the ingredients. It&apos;s also a rolling release distro - meaning the app store almost always will have the latest version unlike Ubuntu or Debian were you will find versions that are older than 2 years. For that reason, Arch is known to be unstable but my 5 year old installation never let me down even with daily &lt;code class=&quot;language-text&quot;&gt;sudo pacman -Syu&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;pain-of-using-a-desktop-machine&quot;&gt;Pain of using a desktop machine&lt;/h2&gt;
&lt;p&gt;For the past year, I have been working exclusively out of my desktop machine.
It has an &lt;code class=&quot;language-text&quot;&gt;Intel i9 14900k&lt;/code&gt; and 32GB of RAM and is seriously a beast of a machine.
And before that I used to work from a &lt;code class=&quot;language-text&quot;&gt;2019 Dell XPS 15&lt;/code&gt; which I gave to my dad so the desktop is the only machine I was left with.&lt;/p&gt;
&lt;p&gt;While the desktop is insanely powerful, it&apos;s not portable and susceptible to frequent power cuts.
I live in a country where powercuts are a regular thing and my tiny UPS only lasts for about 5-10 minutes.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1200px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/14032a8ace5fde4033d824c38a5562a8/71c1d/power-cut.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 66.66666666666666%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAIAAAAmMtkJAAAACXBIWXMAAAsTAAALEwEAmpwYAAABmUlEQVR42nWSj1aCMBTGff9n8QnSjlSCHpEiAwQrlXMQmJagWZs5tr5BFvbnnJ1x791+ux/f1igK/t/g/CD+XT1gNE7zzxlYEi8eH+73eyqEStU4JX/AnwtCFK+73YWmNZvNJI5RFEJIVGvY3zDn71KKl+1W0zrtdmuxiJCSNL2fBHmeIcaGOlyp5eroct4zOptNfX+MtlJKMIHv93tGGM6RQr9CuBqNL5IxumcszzJsch1nNLoNwxC7CUkR2PbNakWOcM0w5KhCoee5z89PyyXRu90g8Bml0Jlla9McnJ+3GWOl7CPMj7CQRbZeO84dtmKGyOn0sdfTraE59lzD0LVOB0dsNvmRrxkG2ZS+WZYVL6L5fAbSde7MwaDf7y1JulqS0a3dap0Rknz/dt1tlK4uL+HTcGhWhtm2DfHqnqSMoghHQ9cfcGUYBCOAN77vu65TBmN+UJcHFyH7N6w+1ZWMPa9yztB1Q+9eW9ZkEihHBN9uc6hIkriE30/gsvNb+QwkZRRvM01iXBsqVR803+3wdjZSFl+dPwCE4tooL/qF3QAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;power cut&quot;
        title=&quot;&quot;
        src=&quot;/static/14032a8ace5fde4033d824c38a5562a8/c1b63/power-cut.png&quot;
        srcset=&quot;/static/14032a8ace5fde4033d824c38a5562a8/5a46d/power-cut.png 300w,
/static/14032a8ace5fde4033d824c38a5562a8/0a47e/power-cut.png 600w,
/static/14032a8ace5fde4033d824c38a5562a8/c1b63/power-cut.png 1200w,
/static/14032a8ace5fde4033d824c38a5562a8/71c1d/power-cut.png 1536w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;
&lt;em&gt;created with: Gpt4o&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;What made it worse is that suspending was not working for me. It had something to do with NVIDIA drivers and I tried to troubleshoot it but never had any luck.
So, every time there was a powercut, even for a few minutes, I would have to completely shutdown the machine.&lt;/p&gt;
&lt;p&gt;The noise, although relatively quiter than other desktops, was still a bit too much for me. I prefer a quiet environment to work.&lt;/p&gt;
&lt;p&gt;Beyond these challenges, the most significant drawback was the desktop&apos;s inherent inflexibility.
My remote job offers complete freedom regarding when and where I work. However, I couldn&apos;t take advantage of this flexibility - working from cafes or during travel was impossible, and I couldn&apos;t even work from my own bed. I was essentially tethered to my desk at all times.&lt;/p&gt;
&lt;p&gt;So, really the main reason for me to switch to a Mac was that I needed a powerful laptop that was also power efficient - and no one does it better than Apple.
There are a few laptops with arm cpus that are probably more power efficient than Apple Silicon, but nowhere near as powerful.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;It wasn&apos;t the OS that made me switch to Mac, but it was the hardware.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So eventually after months or even years of convincing myself that a Mac wouldn&apos;t be worth it, I finally decided to make that switch.
&lt;em&gt;&lt;strong&gt;Spoiler alert&lt;/strong&gt;, it has been absolutely worth it.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 967px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/12b67b9b6520fec0dbd33a248e5d69f7/aa08e/macbook-pro-m4-pro.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 70%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAAAsTAAALEwEAmpwYAAAD1UlEQVR42kWUW0zbVRzH/z5sOjNiEGSDbFxKoTd6o9DCuFNaaKEUWkqvawuUQbiFbGwzYzJY5DI3xmCwEYSEuanzwW0JBCM+qFs0Ppi4LFFjjCZLjA9uiXGamPngxwMvPnzzTc45+fy+v5PfOdLa+RZWJwfZWJ1h670FNm4tMDbcQcarKezbm8rLL6azd08me/bkkbRfz0tJZvanVJCcXoNC4cdjnSZou05zzQSexlqk1OTX6PY5+ObOIts3L/PulbPMnYphVKqQpFeQXsgiPbUQZV49+9Ls6C0RtCUx0hQ+0lR+DmoDZOjiZGq99EWakOQHUxiMNvH1zTf5ZOkUdy4OM38yRmtJKZEGD3FvgrtjJ/l2boAbE0P8tn2JL5dG0VqHMThHUdvHUDkm0VV1cDLmRJruD/Lh9BAfL57m3lsD3L0wwOJIlPlKHT8NuPlndYxnm2s83XybJ7M9PB318eSdGR4sT3Gi5wSWwAKW0DXcgWFW3uhDioc8WKvKabFVsjU3woOVM1wZDNIly+J2mZIfmnT8cayav8ej/D47zLOJKH/113E/Xs/7cRdbs1PcXV7jeN8A85NnkWqqKtEo1cyPJPh18yofzY/gNBswJSXTq8xl2aTi0woND6uVPHYZeNxl5edTPv68Psi/t16He1M831hgvK+LeEcH0plEhC/WL/L8qw+4v36ZRLANtTwX5YEMSg9n4s3OYsqgYr3MwGe1hTxyFPFjUxHfR2p5dCbBd0vneDhznPNi/Wp7KdIv2zfYWr7Azdlpwr4gboed2nILmvw88rOzhXJQCxXnyLDnyenVa5gs0bNSLOea7gCT+kOMO8qZc+Sz2SZD+vz2Cv2JAbzNXlqb7NRbqygxmyg26jGI0dHK5ahyclBkZZNz6DCZGYeEZyIXMspysKvzadDpCFSb8eizkLo7+4n4g3hddhy2WirLj+yqrMSCSRw0qNToFUo0MplIKkMjpMrMQiGAGpmcXOE6hYpmpwvVzuwGvF78LQ1E21uI+T2EvM14XE6sFWVYTEaKDHqMBQUUqgtEYjUF8ny0eQpRZCe9YhdqFvvB1lZKjVokr2jT73ES9DRy1OemM9RGTzREIhwg7GnBXW8Td3qEUlMR5eYSLAYTJq0evUqDVqHGVKCnothMTyxOfdURpHaRbgfmczcQEN4RaudYNCKAIbojQqEgnX4/R0Unbc5GGq1WqsUrMhtNmAuLdgvZKqsY6u7FbatGctbZcNXX7EJjgTa6Baz7aPh/RcICHqYrFBbgAP5mJ77GBrzOBlx1VuyVFeJTcHLu9Bgd/nb+AzwBM8h/i+MQAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;macbook pro m4 pro&quot;
        title=&quot;&quot;
        src=&quot;/static/12b67b9b6520fec0dbd33a248e5d69f7/aa08e/macbook-pro-m4-pro.png&quot;
        srcset=&quot;/static/12b67b9b6520fec0dbd33a248e5d69f7/5a46d/macbook-pro-m4-pro.png 300w,
/static/12b67b9b6520fec0dbd33a248e5d69f7/0a47e/macbook-pro-m4-pro.png 600w,
/static/12b67b9b6520fec0dbd33a248e5d69f7/aa08e/macbook-pro-m4-pro.png 967w&quot;
        sizes=&quot;(max-width: 967px) 100vw, 967px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Don't think with your fingers]]></title><description><![CDATA[Using SuperWhisper to write better blog posts]]></description><link>https://www.adityathebe.com/dont-think-with-your-fingers</link><guid isPermaLink="false">https://www.adityathebe.com/dont-think-with-your-fingers</guid><pubDate>Sun, 16 Mar 2025 12:30:00 GMT</pubDate><content:encoded>&lt;p&gt;I have been writing blogs on this website for about 10 years now, and honestly, every time I&apos;ve sat down to write a blog post, it has taken me hours. And I would never complete the blog post in one sitting. I would put in a draft and keep coming back to it for several days before finally publishing it.&lt;/p&gt;
&lt;p&gt;That&apos;s because it was just too difficult or unnatural to write a blog post. The words just didn&apos;t come to me naturally. And I think that&apos;s because I used to think with my fingers. You know how when you think of words while your hands are on a keyboard, there&apos;s a disconnect? The words just don&apos;t come naturally to you - or maybe it&apos;s just me.&lt;/p&gt;
&lt;p&gt;Whenever I first thought of writing a blog, I would have a draft in my head of what to write, and it would sound really good. But then when I sat down and actually started to write, I would go blank. And the chain of thought just gets broken constantly because you&apos;re typing at the same time you&apos;re thinking.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1200px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/1423ec4e4b9de4c27ee3d33a6147882c/fa60d/think-with-your-head.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 57.00000000000001%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAIAAADwazoUAAAACXBIWXMAAAPoAAAD6AG1e1JrAAAChUlEQVR42h1S7U9ScRS+frfW5zJnxfob/ORqLe2FPvihWi3Dt9hKU0nGaBNDwV4MTZpuzuZyw5sgIFfkRUG4XsR7vYKEIBDiu6FI5KbOtfmpZ56d/bbf2TnPOc9zDhEKBWOxaDKZCAYXAgF+c3N9e3sTvrOz9Tu9nd7dwYsv4olfMWQmYtF4Ypll/XiJSCSMqMNGvW9T1lRV19XVITuT2d3f38tmMzRN7+2lbXYrz806HdYRUkcZ9QztgS8G5wl047i5Hq1GXC0qu11acPGSyWQ6OMih85/cfjabxVDzPEvqvje/ftncWC9pbGiofzXY3++gjITLPcn46I+qliePH94tLbt6RVBcXHx0dIRBN9ZSTqddr//R+1VbW1nR2/3JYhj2zUxbLGbtly6dTkeYx4zAHur/JpNKH5WXFxUWCIVCDazzs7imVi6XtbUqVO9aqFEyMO8DHDguL0fmZn2TDjthMIxgbH6B69F8ePHsaWXF84GBgVwuNz4+EQ4Fac+0dYKanWFSK3FoZrPZQGd1dSWVSkajS8TQ0CBFUeYxg/ztG7VScXh4yHFcOp0+Pj7OZDKQDRR4ng8EArm/WagALVG/tbWxtp4ilEqlQqGQSqXQuV2lBFC7Wh2Px09OTv6dmUgkun5NIBaLsTbUoxibQ3F4KUQ0NTXJZDK5XC6RSDo6VJ1dGr1x1GwZTySTp6en6F9SUnLrxs0L584XXS68V3YHcgoEgvz8/Ly8PMLtdvv8fpZlMRtuAIvVkcPgNmF3eGZol8uFuNVqJUmyr6+vR9sNCasrqx7cFwKFQMHamYEHzuNneNHpdE5NTXk8Hq/XCyyTeRSaMQwDheA4RHaOob0uh436D4MovbYPeIh0AAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;think with your head&quot;
        title=&quot;&quot;
        src=&quot;/static/1423ec4e4b9de4c27ee3d33a6147882c/c1b63/think-with-your-head.png&quot;
        srcset=&quot;/static/1423ec4e4b9de4c27ee3d33a6147882c/5a46d/think-with-your-head.png 300w,
/static/1423ec4e4b9de4c27ee3d33a6147882c/0a47e/think-with-your-head.png 600w,
/static/1423ec4e4b9de4c27ee3d33a6147882c/c1b63/think-with-your-head.png 1200w,
/static/1423ec4e4b9de4c27ee3d33a6147882c/fa60d/think-with-your-head.png 1792w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;
&lt;em&gt;created with: Gpt4o&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Now that&apos;s going to change because a few days ago I discovered an application called &lt;a href=&quot;https://superwhisper.com/&quot;&gt;SuperWhisper&lt;/a&gt;. I came across it from a video by &lt;a href=&quot;https://www.youtube.com/watch?v=EWvNQjAaOHw&quot;&gt;Andrei Karpathy&lt;/a&gt; where he shows how he uses LLMs and apparently the way he interacts with LLMs or even his computer is through dictation about half the time. So I installed this application and I&apos;ve been using it for a few days. And honestly, it&apos;s a game changer. I cannot praise it enough.&lt;/p&gt;
&lt;p&gt;So the first thing that came to my mind when I installed this application was that I could write my prompts to LLMs easily, but then it hit me that I could use this tool to write all my blog posts. And in fact, all of the writings I&apos;ve done so far in this blog, I did that through this app.&lt;/p&gt;
&lt;p&gt;And let me tell you the difference is, &lt;em&gt;what&apos;s the word I&apos;m looking for? The difference is... let me think... Claude just told me &quot;night and day&quot;.&lt;/em&gt; So yes, the difference is &lt;strong&gt;night and day&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;I think you can tell that this blog post feels much more natural than my other blog posts. I assume it feels like someone speaking to you because in a sense that&apos;s exactly it. I&apos;m really speaking out these words.
My eyes are closed and the words are just flowing out like a river.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I&apos;ve also always avoided using LLMs for my blog posts because I didn&apos;t want to fill my blog with words that came from an AI model rather than from me. The nice thing about using SuperWhisper is that while you&apos;re still using AI, you&apos;re not using it to generate thoughts, but just to transcribe your own thoughts.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;To top it off, the tool is completely* free. I mean it has premium offerings that will let you use much more powerful models. But I&apos;ve been using the most basic model offered in the free tier. And it&apos;s so, so good.
It also runs locally, so I don&apos;t need to be connected to the internet and my laptop is powerful enough that it&apos;s just instant.&lt;/p&gt;
&lt;p&gt;The first time you install the software it gives you 15 minutes of credit to use the top speech to text models.
I used the 3GB Ultra model that runs locally, but you can also choose a cloud model if you don&apos;t want to download anything to your device.
It was quite good, but the free model I&apos;m currently using is honestly good enough that I don&apos;t &lt;del&gt;want&lt;/del&gt; need the premium version.
So I&apos;m just gonna stick to it for now &amp;#x26; see how it works out.
And if I feel like it&apos;s inadequate, I will be more than happy to get a subscription.&lt;/p&gt;
&lt;p&gt;I think that&apos;s it for this post. I honestly cannot believe how much time this tool is going to save me, not to mention the improvement in the quality of my writing on this blog. This blog post took me just 5 minutes to &quot;write&quot; and then 20 more minutes to edit and finalize because I&apos;m not articulate.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Motorcycle Trip: Kathmandu to Mustang]]></title><description><![CDATA[Jomson, Mustang Itenerary for a motorcycle trip]]></description><link>https://www.adityathebe.com/mustang-motorcycle-trip</link><guid isPermaLink="false">https://www.adityathebe.com/mustang-motorcycle-trip</guid><pubDate>Sat, 08 Mar 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;It was a trip planned for 5 days but unfortunately we had to cut it short.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1200px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/6b137cdcd953f1471682c1afa17470b2/644c5/mutang-lete.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 133.33333333333331%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAbABQDASIAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAMEAv/EABYBAQEBAAAAAAAAAAAAAAAAAAIAA//aAAwDAQACEAMQAAABoUk0zaKCo6IqAmmSv//EABsQAAMBAQADAAAAAAAAAAAAAAABAhEDIkFC/9oACAEBAAEFAmho8iexXUVm5Sqdc89+kev/xAAWEQEBAQAAAAAAAAAAAAAAAAASABD/2gAIAQMBAT8BMd//xAAXEQADAQAAAAAAAAAAAAAAAAAAEBIR/9oACAECAQE/AbLWH//EABsQAAICAwEAAAAAAAAAAAAAAAABETEQEiBC/9oACAEBAAY/AiudoUMo9ZR//8QAHhAAAgICAgMAAAAAAAAAAAAAAAERITFBEFFhcZH/2gAIAQEAAT8htdDfIlKgQ80xPTKdFJnaGOzqo6HWcr64YE/A/9oADAMBAAIAAwAAABB46sD/xAAXEQEBAQEAAAAAAAAAAAAAAAAAEQFx/9oACAEDAQE/EMe1V//EABgRAAMBAQAAAAAAAAAAAAAAAAABESFR/9oACAECAQE/EME8JRJD/8QAHxABAAMAAQQDAAAAAAAAAAAAAQARITFBUWFxgaHB/9oACAEBAAE/EL2+jcy0tYVzF6keFqpnPuD+S6GPh5gPIV0SkiVCcKw+IgdyiUQ9ERjHXFQz1MmlctyR/9k=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;Thasang, Mustang (near Holiday Camp)&quot;
        title=&quot;&quot;
        src=&quot;/static/6b137cdcd953f1471682c1afa17470b2/e5166/mutang-lete.jpg&quot;
        srcset=&quot;/static/6b137cdcd953f1471682c1afa17470b2/f93b5/mutang-lete.jpg 300w,
/static/6b137cdcd953f1471682c1afa17470b2/b4294/mutang-lete.jpg 600w,
/static/6b137cdcd953f1471682c1afa17470b2/e5166/mutang-lete.jpg 1200w,
/static/6b137cdcd953f1471682c1afa17470b2/644c5/mutang-lete.jpg 1440w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;
&lt;em&gt;Thasang, Mustang (near Holiday Camp)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Here&apos;s a very not-so-detailed itenerary.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Day&lt;/th&gt;
&lt;th&gt;Time&lt;/th&gt;
&lt;th&gt;Location&lt;/th&gt;
&lt;th&gt;Details&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Feb 5&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;09:20am&lt;/td&gt;
&lt;td&gt;Left Pokhara&lt;/td&gt;
&lt;td&gt;Fuel: ₹2,250&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;10:20am&lt;/td&gt;
&lt;td&gt;Dimuwa&lt;/td&gt;
&lt;td&gt;Traffic violation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;10:50am - 01:00pm&lt;/td&gt;
&lt;td&gt;Kushma&lt;/td&gt;
&lt;td&gt;Food: ₹850 chicken rice&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;01:25pm - 02:20pm&lt;/td&gt;
&lt;td&gt;On the way to Beni&lt;/td&gt;
&lt;td&gt;Puncture&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;02:45pm&lt;/td&gt;
&lt;td&gt;Beni&lt;/td&gt;
&lt;td&gt;Fuel: ₹510&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;03:25pm - 03:50pm&lt;/td&gt;
&lt;td&gt;Tatopani&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;04:10pm - 04:20pm&lt;/td&gt;
&lt;td&gt;Rupse Jharna&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;04:30pm&lt;/td&gt;
&lt;td&gt;Ghasa&lt;/td&gt;
&lt;td&gt;Police checking. Takes 2 minutes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;06:00pm&lt;/td&gt;
&lt;td&gt;Marpha&lt;/td&gt;
&lt;td&gt;Room: ₹1,200; Food: ₹650 chicken rice&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Feb 6&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;10:10am&lt;/td&gt;
&lt;td&gt;Reached Jomsom&lt;/td&gt;
&lt;td&gt;Food: ₹650 chicken rice&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;12:10pm&lt;/td&gt;
&lt;td&gt;Dhumba Lake&lt;/td&gt;
&lt;td&gt;Coffee: ₹100; Entry fee: ₹30&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;03:00pm&lt;/td&gt;
&lt;td&gt;Muktinath&lt;/td&gt;
&lt;td&gt;Room: ₹2,000 (Dolma Inn)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Feb 7&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;11:00am&lt;/td&gt;
&lt;td&gt;Reached Jomsom&lt;/td&gt;
&lt;td&gt;Breakfast at MoonLight Hotel. It was good.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;12:40pm - 01:30pm&lt;/td&gt;
&lt;td&gt;Chhusang&lt;/td&gt;
&lt;td&gt;They register your vehicle if you cross this point.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;04:00pm&lt;/td&gt;
&lt;td&gt;Lete&lt;/td&gt;
&lt;td&gt;Took a lot of pictures. Incredibly beautiful place.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;06:00pm&lt;/td&gt;
&lt;td&gt;Tatopani&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;08:10pm&lt;/td&gt;
&lt;td&gt;Kushma (The Cliff, Nepal)&lt;/td&gt;
&lt;td&gt;Room with breakfast: ₹8,000, Bungee ₹9000&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&quot;notes-to-motorcycle-renters&quot;&gt;Notes to Motorcycle Renters&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Where to Rent:&lt;/strong&gt; Most bike rental shops are located in Hallanchowk, Lakeside. Nearly every store in the area, including barber shops and clothing stores, seem to have a few motorcycles available for rent.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Bike Condition:&lt;/strong&gt; The motorcycles are generally in good condition, with some having less than 1,000 km on the odometer.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Price Variation:&lt;/strong&gt; Rental prices vary significantly from shop to shop, so take the time to compare. For instance, we found an XPulse being offered for anywhere between Rs 2,400 and Rs 3,500 per day.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pricing Based on Route:&lt;/strong&gt; The rental cost depends on your destination. If you&apos;re heading to Lower Mustang, expect different rates than for Upper Mustang. We paid Rs 18,000 for a 5-day rental to Lower Mustang.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Security Deposit:&lt;/strong&gt; Renters require an advance payment, including a security deposit. We paid Rs 40,000 in total, with Rs 22,000 as a deposit.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Helmets:&lt;/strong&gt; Helmets are provided, but we opted to bring our own.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Required Documents:&lt;/strong&gt; You must present your original driving license and citizenship ID.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Legality Issues&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Technically, renting motorcycles is illegal since all rental bikes have private number plates. Renters will inform you of this beforehand, but it can still be a hassle. We rented a Royal Enfield Scram, and traffic police could immediately tell it was a rental. We had to pay Rs 2,000 as a fine for this, and turns out our bike had already been fined multiple times for the same offense.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;tips-to-avoid-getting-stopped&quot;&gt;Tips to Avoid Getting Stopped&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Try to rent a newer bike to stay under the radar.&lt;/li&gt;
&lt;li&gt;A bike with a Bagmati number plate is less suspicious.&lt;/li&gt;
&lt;li&gt;A Gandaki number plate will attract attention and likely get you stopped.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;frequent-tyre-punctures&quot;&gt;Frequent tyre punctures&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Ensure your rental bike has new tyres. We experienced three punctures in three days.&lt;/li&gt;
&lt;li&gt;Workshops in the region do not repair tubes - they only sell new ones.&lt;/li&gt;
&lt;li&gt;Each replacement tube cost us around Rs 1,000.&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Podcast Notes & Review - Modern SQL]]></title><description><![CDATA[My notes on an episode of postgres.fm]]></description><link>https://www.adityathebe.com/review/postgres-fm-modern-sql</link><guid isPermaLink="false">https://www.adityathebe.com/review/postgres-fm-modern-sql</guid><pubDate>Sat, 11 Jan 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;Episode: &lt;a href=&quot;https://postgres.fm/episodes/modern-sql/transcript&quot;&gt;https://postgres.fm/episodes/modern-sql/transcript&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This was one of my favorite episodes of &lt;a href=&quot;https://postgres.fm&quot;&gt;postgres.fm&lt;/a&gt; - a podcast I regularly listen to.
The guest - &lt;a href=&quot;https://winand.at/&quot;&gt;Markus Winand&lt;/a&gt; - had such a fresh perspective on the mundane and conventional wisdom of SQL that it honestly shifted my perspective
and also inspired me to learn some newer features.&lt;/p&gt;
&lt;p&gt;Most of us think of SQL as a query language - I mean, its very name indicates that - however Markus presents a different view.
And his emphasis on SQL window functions has given me enough motivation to take them seriously.
I&apos;d always seen them as this advanced feature I could probably live without. But the way Markus emphasized them made me realize I&apos;ve been missing out on some seriously powerful tools. It&apos;s funny how sometimes it takes someone else&apos;s excitement about a seemingly ordinary topic to reignite your own curiosity about it.&lt;/p&gt;
&lt;h2 id=&quot;flavors-of-sql&quot;&gt;Flavors of SQL&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;SQL has different flavors and most people do not know that.&lt;/li&gt;
&lt;li&gt;To most people, SQL means SQL 92.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;section-notes&quot;&gt;
I personally wasn&apos;t aware of this either.
&lt;p&gt;SQL standard, formally known as ISO/IEC 9075, is maintained jointly by ISO and IEC.
The standard has core features that every conforming SQL vendors like PostgreSQL, MySQL, SQL Server must implement.
How the vendors implement those features are up to them.
There are also a set of optional features that the vendors may choose not to implement.
PostgreSQL, seems to be the one that is highly compliant with the SQL standard.&lt;/p&gt;
&lt;p&gt;Here are some major SQL standards and their notable features:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;SQL-92&lt;/code&gt;: Introduced JOIN syntax, CASCADE operations, and foreign keys&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;SQL:1999&lt;/code&gt;: Added triggers, recursive queries (WITH RECURSIVE), and regular expressions&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;SQL:2003&lt;/code&gt;: Introduced Window functions, MERGE statement, and XML features&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;SQL:2016&lt;/code&gt;: &lt;a href=&quot;https://modern-sql.com/blog/2017-06/whats-new-in-sql-2016&quot;&gt;Added JSON operations, temporal tables, and row pattern matching&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;SQL:2023&lt;/code&gt;: Introduced property graph queries &amp;#x26; JSON data types&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id=&quot;modern-sql&quot;&gt;Modern SQL&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Modern SQL has features which are not rooted in the relational idea
&lt;ul&gt;
&lt;li&gt;Window functions&lt;/li&gt;
&lt;li&gt;Recursive queries&lt;/li&gt;
&lt;li&gt;JSON&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;SQL 92 was almost feature complete. So it&apos;s difficult to convince people to use modern SQL.&lt;/li&gt;
&lt;li&gt;Why should people use modern SQL when classic SQL has been serving them fine?
&lt;ul&gt;
&lt;li&gt;Eg: With SQL 92, it was very common (almost required) to do self JOINs.
&lt;ul&gt;
&lt;li&gt;Self joins are complex &amp;#x26; slow and Window functions are killers of self joins.&lt;/li&gt;
&lt;li&gt;Window functions are more concise, clear, readable, writable, maintainable, and performant&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;The most undervalued feature of modern sql is, and always was, Window functions.&quot;&lt;/p&gt;
&lt;p&gt;- Markus&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class=&quot;section-notes&quot;&gt;
My impression is that - modern sql is anything that has to do with more than just the relational stuff.
They also improve the language to do things, that may have been previously possible, but, in a more performant and concise way.
&lt;/div&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1200px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/a5d94bd5eba9769045530c6e6ca09248/882b9/history-of-sql-standards.webp&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 83.33333333333334%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/webp;base64,UklGRtYAAABXRUJQVlA4IMoAAABQBQCdASoUABEAPtFYpE0oJSOiKA1RABoJbACdMxMEP1AfwABaINx6Sv4eWr69qV+piQAA3l1ntSo+A69IU09n0arlpoOccpncdGKpSFvsiW21bCjm6LsuyWWceExI6VCFn3Y4PqI/jL4pPt3aEAmkKq+sp85i1zbXbscVk3FXrLAc6UEeAUA9/khxj87RzON7yK/9enNE9r6BYYEmox5PfTqdODV6IjkhWQV2LgO0TXwxTwYejp1p2yfEWavu/YTdZeuw9ffOjAAA&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;history of sql standards&quot;
        title=&quot;&quot;
        src=&quot;/static/a5d94bd5eba9769045530c6e6ca09248/92f8c/history-of-sql-standards.webp&quot;
        srcset=&quot;/static/a5d94bd5eba9769045530c6e6ca09248/c85cb/history-of-sql-standards.webp 300w,
/static/a5d94bd5eba9769045530c6e6ca09248/e88ff/history-of-sql-standards.webp 600w,
/static/a5d94bd5eba9769045530c6e6ca09248/92f8c/history-of-sql-standards.webp 1200w,
/static/a5d94bd5eba9769045530c6e6ca09248/62ed8/history-of-sql-standards.webp 1800w,
/static/a5d94bd5eba9769045530c6e6ca09248/882b9/history-of-sql-standards.webp 1920w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;
&lt;em&gt;&lt;a href=&quot;https://learnsql.com/blog/history-of-sql-standards/&quot;&gt;https://learnsql.com/blog/history-of-sql-standards/&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;h2 id=&quot;null-handling&quot;&gt;NULL handling&lt;/h2&gt;
&lt;p&gt;Modern SQL also offers various ways to handle NULL values. Example: here are some features in modern sql regarding NULL value handling&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;IS DISTINCT FROM&lt;/code&gt;/&lt;code class=&quot;language-text&quot;&gt;IS NOT DISTINCT FROM&lt;/code&gt; are NULL safe comparison operator.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;NULLS DISTINCT&lt;/code&gt;/&lt;code class=&quot;language-text&quot;&gt;NULLS NOT DISTINCT&lt;/code&gt; deals with how nulls are handled in unique contraints.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sql&quot;&gt;&lt;pre class=&quot;language-sql&quot;&gt;&lt;code class=&quot;language-sql&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;CREATE&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;TABLE&lt;/span&gt; users &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    email &lt;span class=&quot;token keyword&quot;&gt;TEXT&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;UNIQUE&lt;/span&gt; NULLS &lt;span class=&quot;token operator&quot;&gt;NOT&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;DISTINCT&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    backup_email &lt;span class=&quot;token keyword&quot;&gt;TEXT&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;UNIQUE&lt;/span&gt; NULLS &lt;span class=&quot;token operator&quot;&gt;NOT&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;DISTINCT&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Since Postgresql v15+, it&apos;s is now possible to have multiple rows with null values on a column with unique constraint.&lt;/p&gt;
&lt;div class=&quot;section-notes&quot;&gt;
I&apos;m only learning that NULL values in SQL have some nasty qwirks.
Only yesterday, there was a blog post on NULL values in SQL floating around in various subreddits &amp; Hackernews.
&lt;/div&gt;
&lt;h2 id=&quot;modern-perspective-on-sql&quot;&gt;Modern perspective on SQL&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;People in ORM world have misconception of SQL.
&lt;ul&gt;
&lt;li&gt;SQL isn&apos;t just about relation anymore; not since 99.&lt;/li&gt;
&lt;li&gt;A very popular ORM framework in JAVA is JPA. It stands for Java Persistence API. However, SQL isn&apos;t just about persistence. It doesn&apos;t &quot;just&quot; store data.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;SQL isn&apos;t a query language; it&apos;s a transformation language. Look at CSS selectors - that&apos;s a query language.
The focus is on transformation of data to answer a question at hand rather than to issue simple fetch queries.&quot;&lt;/p&gt;
&lt;p&gt;- Markus&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class=&quot;section-notes&quot;&gt;
Absolutely loved this section. It really emphasises the power of SQL.
&lt;/div&gt;
&lt;h2 id=&quot;data-normalization&quot;&gt;Data Normalization&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Causes confusion among layman and new comers.&lt;/li&gt;
&lt;li&gt;Just try to figure out in which tables will the data feel comfortable in. Forget the scientific definitions of normalization levels.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;section-notes&quot;&gt;
Very much in agreement with this sentiment.
&lt;p&gt;Normalization forms are highly emphasized in schools and I don&apos;t think they should be.
It&apos;s overwhelming to someone new to databases &amp;#x26; learning all the normal forms and conversion between them is not something that a beginner should be spending their time on.
It&apos;s like learning all about OOPs and then writing your first hello world.&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id=&quot;whats-new-in-sql2023&quot;&gt;What&apos;s new in &lt;code class=&quot;language-text&quot;&gt;SQL:2023&lt;/code&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Biggest &amp;#x26; killer feature - Property Graph Queries (SQL/PGQ). This allows data in tables to be queried as if it were a graph database.&lt;/li&gt;
&lt;li&gt;JSON type&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Read more here:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://modern-sql.com/standard/2023&quot;&gt;https://modern-sql.com/standard/2023&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://peter.eisentraut.org/blog/2023/04/04/sql-2023-is-finished-here-is-whats-new&quot;&gt;https://peter.eisentraut.org/blog/2023/04/04/sql-2023-is-finished-here-is-whats-new&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;building-a-mindset-to-use-new-features&quot;&gt;Building a mindset to use new features&lt;/h2&gt;
&lt;p&gt;Data types like &lt;code class=&quot;language-text&quot;&gt;json&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;jsonb&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;boolean&lt;/code&gt;, ... have 3 use cases&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Persistent schema. Eg: SQL 2016 didn&apos;t have a JSON data type for the schema but the operations on JSON practically meant JSON data types existed in SQL.&lt;/li&gt;
&lt;li&gt;During the transformation
&lt;ul&gt;
&lt;li&gt;eg: boolean data type is mainly used during transfomation in (WHERE, ON, WHEN clause of CASE) rather than in the schemas. MySQL doesn&apos;t even have a boolean type.&lt;/li&gt;
&lt;li&gt;It&apos;s not coming from the disk and it&apos;s not going up to the client&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;API Layer
&lt;ul&gt;
&lt;li&gt;where json can be very handy (json_array_agg)&lt;/li&gt;
&lt;li&gt;we don&apos;t want normalization in API Layer (normalization is fine for the disk)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Reflecting on My iPhone Experience: The Good and the Bad]]></title><description><![CDATA[My experience as an Android user moving to Apple.]]></description><link>https://www.adityathebe.com/reflection-on-iphone-experience</link><guid isPermaLink="false">https://www.adityathebe.com/reflection-on-iphone-experience</guid><pubDate>Sun, 29 Dec 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Almost three years ago, I dropped my Google Pixel 4a from a motorcycle, damaging the display.
Google has no official stores or service centers in Nepal and it was virtually impossible to get the replacement parts.
I searched for it even in India and had no luck. I knew finding a replacement would take time and it was time for me to find a provisional cheap phone for the time being.&lt;/p&gt;
&lt;p&gt;I obviously didn&apos;t want to cash out on a temporary phone but I also wanted a phone with a good camera.
The best option for me at the time was to get a used older iPhone model. Eventually I bought a used iPhone Xs (64GB) for around NPR 30k &lt;em&gt;(USD $240 at the time)&lt;/em&gt; which was surprisingly in really good condition.
Sellers are notorious for claiming &quot;not even a single scratch&quot; but this time it was actually true!&lt;/p&gt;
&lt;p&gt;After having used both platforms for a considerable amount of time, I think I&apos;m in a good position to offer a fair assessment of them.
So here are a few pros and cons from &lt;strong&gt;personal&lt;/strong&gt; experience.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Disclaimer&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I&apos;m fully aware that I&apos;m reflecting on my experience with a rather old iPhone, but most of the things on the list below are software related and I&apos;m still on the latest iOS version.&lt;/p&gt;
&lt;p&gt;On the flip side, Android users might argue this isn&apos;t a fair comparison since I&apos;m comparing a mid-range Android phone with a flagship iPhone. But again the list is mostly software related, and I was using stock Android.&lt;/p&gt;
&lt;p&gt;I also don&apos;t own a mac to fully benefit from the Apple ecosystem, but it&apos;s on it&apos;s way...&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;pros&quot;&gt;Pros&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Software updates&lt;/strong&gt;. It&apos;s &lt;del&gt;2024&lt;/del&gt; 2025 and I&apos;m still receiving major version upgrades albeit this is probably the last one.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Hardware&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Incredibly reliable camera. The camera&apos;s video quality is probably one of the major factors that&apos;ll keep me from switching back to Android. Pixel&apos;s camera was comparable to iPhone&apos;s but when it came to video, iPhone ran circles around Android.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Speakers&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;3D touch&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Premium feel, good display and all of that ...&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Airdrop&lt;/strong&gt;. It&apos;s so convenient and fast to transfer photos.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Swipe down and search&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;This is something that grew on me. I wasn&apos;t a fan initially. My frequent apps are on the homepage but for seldom used apps it&apos;s so much easier to swipe down and just search for it.
I rarely swipe right of the homepage to find an app. I just search for it.&lt;/p&gt;
&lt;p&gt;And this is a pattern in throughout iOS.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Link previews&lt;/strong&gt; on a pop up on browser. This is one my favorites. I like how homogenous the browsing experience is no matter which app you&apos;re on. I can just hard press on a link and a tab pops up. So handy!&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Focus modes&lt;/strong&gt;. I&apos;m sure Android has something similar by now or maybe it always did. But iOS actually made me want to setup focus modes. I have two Focus modes - work and sleep that activate on a schedule.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Do not disturb mode&lt;/strong&gt; - I can&apos;t quite recall exactly what it was on Pixel - but DND didn&apos;t really feel like DND because you&apos;d still get notifications &lt;em&gt;(don&apos;t quote me on this one)&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Silent button&lt;/strong&gt; - A physical button to activate Silent mode. I love this! Although it&apos;s easy to forget to switch it off.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;I like that the files app has native SMB support.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Beautiful fonts and coherent UI experience. As a Linux user, a consistent UI is something that really stands out to me because you rarely experience that in the Linux world.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Privacy&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Fine grained permissions for apps. I especially like that you can selectively allow which photos an app can access instead of allowing it your entire gallery or nothing at all. Also, you can select if you want to provide precise or imprecise location permission to apps but I think Android also has this maybe...&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Sign in with apple&lt;/strong&gt; allows me to regsiter with a unique pseudonymous email address.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;FaceTime&lt;/strong&gt; and &lt;strong&gt;iMessage&lt;/strong&gt; are also pretty cool.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I am aware that apps are generally better built on iOS, but I haven&apos;t personally experienced that.&lt;/p&gt;
&lt;h2 id=&quot;cons&quot;&gt;Cons&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;Based on your usage/experience you might probably not experience some of these.&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;No access to file system. &lt;strong&gt;Major major bummer!&lt;/strong&gt; I couldn&apos;t copy over all my mp3s like I could on Android. The hack to overcome this was to use &quot;Documents&quot; app and then transfer those mp3s to it and then use it as the music player 😐. No thanks!&lt;/p&gt;
&lt;p&gt;This isn&apos;t a problem for me anymore as I now have a self hosted music server and there are some really good free open source iOS music players that work with it.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Custom photos picker&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;I don&apos;t use iCloud because all my photos were already in a Google Photos &lt;em&gt;(I&apos;ve moved to Immich now)&lt;/em&gt;.
iOS doesn&apos;t allow using these 3rd party apps to pick files for upload.
You need to download it and then select it from the Photos app.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Auto rotation&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;This isn&apos;t about the screen auto rotation lock - or the Portait orientation lock. I&apos;m especially talking about deciding video rotation when you have auto rotation disabled.&lt;/p&gt;
&lt;p&gt;Android is really smart when it comes to rotating your screen based on your phones rotation.
If you rotate your phone to the right, the video is rotated to the right.
If you then rotate to the left, a small button pops up that&apos;ll change the screen&apos;s rotation to the left.&lt;/p&gt;
&lt;p&gt;iOS, on the other hand, is so freaking dumb!!
When I&apos;m in my bed watching YouTube and go full screen, it rotates the screen in the wrong direction.
Dude my phone is turned towards the right, why the heck is the video rotated towards left?
Now I need to flip my phone.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Keyboard&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Worst auto completion by far! Keyboards on android not only have extremely good auto suggestions but can also remember custom words which is really handy when you use english letters for Nepali words.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Hard to place a cursor in the middle of a word. You need to slide the cursor.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Copy / Paste / Select All are atrocious!&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Ecosystem&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Premium ecosystem. Apps that were free on android were behind paywall on App Store. This isn&apos;t really on iOS thing but if people are gonna boast about the ecosystem it&apos;s fair to mention all aspects of it. Example: I used to heavily use Syncthing to sync files between my computer and phone (like music and ebooks).&lt;/p&gt;
&lt;p&gt;This isn&apos;t a problem for me anymore as now I have NAS (network attached storage) that I can connect to from the Files app. And now, I also don&apos;t mind paying for apps.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;As a self hoster I use a lot of open source applications. And I&apos;ve noticed that usually these softwares do not have an ios app but they almost always do have an android as they can simply distribute the APK.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;You also miss out on the hacker culture of Android where you can try out lots of APKs that are not in the PlayStore. Example: Cracked Spotify.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Application &lt;strong&gt;call logs&lt;/strong&gt; in the phone call logs.&lt;/p&gt;
&lt;p&gt;Why the heck are my Messenger and Telegram call logs mixed in with my phone&apos;s call history? I honestly don&apos;t get this.
Hate it when I need to call someone and I tap the call history and Telegram pops up!&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Background activites&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;iOS has a really strict and biased policy against 3rd party apps when it comes to background activity. On android, Google Photos or Immich can sync your gallery in background but iOS doesn&apos;t allow that. You have to keep your apps open to upload your photos.&lt;/p&gt;
&lt;p&gt;On the same note, the native Mail is so slow to sync emails.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Can&apos;t &lt;strong&gt;force quit&lt;/strong&gt; apps. Oh this makes me furious!&lt;/p&gt;
&lt;p&gt;Hate it when I open Files app and then it resumes from the last directory I visited (even after restarts).
What makes me really mad is when the last location I opened was a remote file server and if it can&apos;t connect to the remote server it just freezes. And yup I can&apos;t force quit it. Restarting the phone doesn&apos;t help either.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Setting default apps for URLs.&lt;/p&gt;
&lt;p&gt;I used to use a 3rd party app (Apollo) for reddit and clicking a reddit link would not open in that app. It always opens up in browser. Ugh! On Android you can configure this.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Can&apos;t decline calls sometimes - there&apos;s just no decline button - WTF! I&apos;m sure there&apos;s a setting somewhere to enable this but the fact that I need to configure this in the first place is kinda wild!&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Nit picks&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Notifications&lt;/strong&gt;. I remember hating this a lot when I first started using iOS but honestly it&apos;s fine now.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Battery&lt;/strong&gt;. I know I can&apos;t really complain about the battery after using a used 5 year old model but still the battery really really sucks.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;I can&apos;t edit a number from my call history before I call it. Android has a pretty handy &quot;Edit and call&quot; feature.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;All the settings are in the settings app! Need to configure camera? Go to settings -&gt; apps -&gt; Camera.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Alarm&lt;/strong&gt;. On Android when you setup an alarm it tells you exactly when it&apos;s gonna go off. i.e. if you set an alarm for 6am tomorrow at 10pm today, a small popup notifies you that the alarm&apos;s gonna go off in 8 hours. It&apos;s a small touch but really helpful to be extra sure that you setup the alarm at the correct time.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;strong&gt;weather app&lt;/strong&gt; has a nice UI but the location search is really poor. Four out of five locations I search for - I can&apos;t find them.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;removed-recent-improvements&quot;&gt;Removed recent improvements&lt;/h3&gt;
&lt;p&gt;Some of the cons that I&apos;ve decided to remove from the list because they have been fixed in newer iOS / iPhone upates.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Doesn&apos;t suggest contact as I type the number. Really ? I need to type in the entire 10 digits before you show me if it&apos;s in my contact? This comes handy when you get an sms for a missed call and it just shows the number.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Thunderbolt port. Type-C all the way!&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;FaceID as a rider. Face id works on masks and helmets on newer iPhones.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I&apos;m not going to mention Siri in here because I don&apos;t really use it and I also didn&apos;t really use Google Assistant.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[How I use SimpleAnalytics to monitor traffic on this blog]]></title><description><![CDATA[My simple setup for checking blog stats: SimpleAnalytics + a custom Telegram bot]]></description><link>https://www.adityathebe.com/simple-analytics</link><guid isPermaLink="false">https://www.adityathebe.com/simple-analytics</guid><pubDate>Sat, 07 Dec 2024 16:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Analytics are super fun to look at. When you first integrate any analytics tool to your webiste - you can&apos;t stop refreshing
the page cuz it&apos;s just so fun.&lt;/p&gt;
&lt;p&gt;I personally have been using &lt;a href=&quot;https://simpleanalytics.com&quot;&gt;SimpleAnalytics&lt;/a&gt; to monitor this blog
for, I think, almost 5 years now.&lt;/p&gt;
&lt;p&gt;Few things that I really like about it are&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It has an API&lt;/li&gt;
&lt;li&gt;True to its name - it&apos;s in fact simple (I don&apos;t even want to remember the google analytics dashboard)&lt;/li&gt;
&lt;li&gt;It allows you to bypass ad-blockers by serving the &quot;tracking&quot; js via your own subdomain.
&lt;em&gt;(I must clarify that no personal identifiable information is collected. This blog serves it via stats.adityathebe.com.
&lt;a href=&quot;https://www.adityathebe.com/journal/2/#web-analytics&quot;&gt;I&apos;ve written about this before&lt;/a&gt;)&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Exporting data. I&apos;m a huge proponent of owning your own data. I have a &lt;a href=&quot;https://github.com/adityathebe/homelab&quot;&gt;homelab&lt;/a&gt;
where I run bunch of open source softwares in favor of proprietary softwares just so I can own my data.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I&apos;m sure it has a few other cool features too (I can see they&apos;ve added an AI feature), but these are my favorites.&lt;/p&gt;
&lt;p&gt;While I like their UI, I very rarely use it. Instead, I use their API.&lt;/p&gt;
&lt;p&gt;I have a telegram bot which presents today&apos;s analytics in response to a &lt;code class=&quot;language-text&quot;&gt;/sa&lt;/code&gt; command.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1034px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/c76506da3e05f742d251feea83f3b27a/709cb/simple-analytics-via-telegram.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 131.66666666666666%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAaCAIAAAA44esqAAAACXBIWXMAABCcAAAQnAEmzTo0AAAC4UlEQVR42pWUS3PTMBSFPUMTvy2/Yvn9dpzYeaeF0rSdLmDDggU/gWHY8f+3HMlpm0JbyswZRUr85dxzJVkouot2czXbHpJ2R4uFXy4HYU6L/hmVfdSsk3aLUZjkveFGsm6rpqdZVDEczfRk3bKjOmj2fr09Fa02ZlAPssNGcJLOTlozqKywtqKGTxrTL918QZs9rXf32gbtRdRe6JPCoBVEaCkYXoEP4tfEr05U43tjkkP641joTuKW++mn79PPP/LLb4JX7dL1Xdxdxd0h7g/J8iburzHh43WyuE2WtylXsrgJZ5f4XydbMaVLwStWpg+TmHgJRkQlXqbZgeaEGIlfIA5SWGGlWpTQHGXqbgoRL0fmmWr5+EGzfc0BE+huJGnWmSifiYqoGApxR5Iq6fZoLCvEQyiWyCtMZHbSDrDOfZgsHyMA8JJmS5opG85Y1rHEqMD8FLaTOaGZHTdO0kKEpjDHzoGBwChkAgzfMNj8G/ZzO56aAcJEsEUhokJE1RzLBkaZuK/BxiSxwtKgGRom6Y6sM08YSqopqgTL18o2vNT00cYMvUXNaB5OGwwV0wMzZH7RGSTSonLsBwuPSVSDF2UD5rLhcmf7GWfebara/pAWsbFEk1EwY3QbQTBnWyVqqOVPGIUNHRJVi5MWDCXecCwBoAq0AA/g5DyBJ8UqWd3y83iIF4eo+zgc0nD2wW92XHsuNsf1MGj5COPGZJu7uL+Cou6SYXOGBdPze+xRePgJ7KRzlDeSNNZY3lIEfnc2xoHHHTxxfhbO2PFkm4G9NT3WUjIZyRo6z+HXnbMefR4rxnFLJQ3+uAlWUL3JGQeDway92NK3wuThVh2dj5mtf8J4GVl+xWDc5P+HcyeaCi4yO8FwhljZvH7esDpo33Pm/EG03j+BrXhuJzM7bo+Kpg5fuvnSKzenYpvf7IbAHG6E7svPxddfYb3ESzxqNmGzHl7uXt69qKIPpvuoWf8GYSGbtifUya4AAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;simple analytics via telegram&quot;
        title=&quot;&quot;
        src=&quot;/static/c76506da3e05f742d251feea83f3b27a/709cb/simple-analytics-via-telegram.png&quot;
        srcset=&quot;/static/c76506da3e05f742d251feea83f3b27a/5a46d/simple-analytics-via-telegram.png 300w,
/static/c76506da3e05f742d251feea83f3b27a/0a47e/simple-analytics-via-telegram.png 600w,
/static/c76506da3e05f742d251feea83f3b27a/709cb/simple-analytics-via-telegram.png 1034w&quot;
        sizes=&quot;(max-width: 1034px) 100vw, 1034px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The source code to this bot is private as it does a lot of other things than just serving the analytics.&lt;/p&gt;
&lt;p&gt;However, I can share the bit of code that deals with simple anlaytics&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;t &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;SimpleAnalytics&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;callAPI&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;options &lt;span class=&quot;token keyword&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;APIResponse&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	r &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;APIResponse&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

	req&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; err &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; http&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;NewRequest&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;GET&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; t&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;apiURL&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; err &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;nil&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; r&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; err
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

	q &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; req&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;URL&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Query&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	q&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Add&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;version&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	q&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Add&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;info&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;false&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	q&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Add&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;fields&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;histogram,pages,countries&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	q&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Add&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;timezone&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Asia/Kathmandu&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; k&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; v &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;range&lt;/span&gt; options &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		q&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Add&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;k&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; v&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
	req&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;URL&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;RawQuery &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; q&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Encode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	req&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Header&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Api-Key&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; t&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;apiKey&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

	client &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;http&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Client&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
	resp&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; err &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; client&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Do&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;req&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; err &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;nil&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; r&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; err
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;defer&lt;/span&gt; resp&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Body&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Close&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

	&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; err &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; json&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;NewDecoder&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;resp&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Body&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Decode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;r&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; err &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;nil&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; r&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; err
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; r&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;nil&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;t &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;SimpleAnalytics&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;DailySummary&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	options &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;make&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	options&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;start&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; time&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;In&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;nepalLoc&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Format&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;2006-01-02&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

	apiResp&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; err &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; t&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;callAPI&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;options&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; err &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;nil&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; err
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; t&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;renderDailySummary&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;apiResp&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;t &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;SimpleAnalytics&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;renderDailySummary&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;r &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;APIResponse&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	tableString &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;strings&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Builder&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
	tableString&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;WriteString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&amp;lt;pre&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

	&lt;span class=&quot;token comment&quot;&gt;// Views by Page&lt;/span&gt;
	tablePageView &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; tablewriter&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;NewWriter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;tableString&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	tablePageView&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;SetHeader&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Page&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Views&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Visitors&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	tablePageView&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;SetBorder&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

	&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; p &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;range&lt;/span&gt; r&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Pages &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		tablePageView&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Append&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Value&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; fmt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Sprint&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Pageviews&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; fmt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Sprint&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Visitors&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; h &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;range&lt;/span&gt; r&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Histogram &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		tablePageView&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;SetFooter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Total&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; fmt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Sprint&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;h&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Pageviews&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; fmt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Sprint&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;h&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Visitors&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

	tablePageView&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Render&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	tableString&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;WriteString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&amp;lt;/pre&gt;\n\n&amp;lt;pre&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

	&lt;span class=&quot;token comment&quot;&gt;// Views by Country&lt;/span&gt;
	tableCountries &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; tablewriter&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;NewWriter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;tableString&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	tableCountries&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;SetHeader&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Country&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Views&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Visitors&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	tableCountries&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;SetBorder&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

	&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; c &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;range&lt;/span&gt; r&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Countries &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		tableCountries&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Append&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Value&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; fmt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Sprint&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Pageviews&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; fmt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Sprint&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Visitors&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
	tableCountries&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Render&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

	tableString&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;WriteString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&amp;lt;/pre&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

	&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; tableString&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;nil&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;hr&gt;
&lt;p&gt;It&apos;s been serving me great so far. &lt;del&gt;A slight complaint I have is that they only email based login.&lt;/del&gt;
Wait, they do actually support passwords now (or have they always had this ...?).&lt;/p&gt;</content:encoded></item><item><title><![CDATA[SET LOCAL, Stay GLOBAL - A PostgreSQL Cautionary Tale]]></title><description><![CDATA[A hidden quirk in PostgreSQL's SET LOCAL command and how it unexpectedly affected our Row Level Security policy.]]></description><link>https://www.adityathebe.com/postgres-parameter-gotcha</link><guid isPermaLink="false">https://www.adityathebe.com/postgres-parameter-gotcha</guid><pubDate>Fri, 06 Dec 2024 22:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Postgres&apos;s &lt;code class=&quot;language-text&quot;&gt;SET&lt;/code&gt; command allows you to modify runtime parameters or create your own custom parameters.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sql&quot;&gt;&lt;pre class=&quot;language-sql&quot;&gt;&lt;code class=&quot;language-sql&quot;&gt;my_database&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;SET&lt;/span&gt; my_domain&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;adityathebe.com&apos;&lt;/span&gt;
my_database&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;SHOW&lt;/span&gt; my_domain&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name
&lt;span class=&quot;token comment&quot;&gt;-- +-----------------+&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;-- | my_domain.name  |&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;-- |-----------------|&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;-- | adityathebe.com |&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;-- +-----------------+&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;With the &lt;code class=&quot;language-text&quot;&gt;LOCAL&lt;/code&gt; option, the parameter only lives within a transaction.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sql&quot;&gt;&lt;pre class=&quot;language-sql&quot;&gt;&lt;code class=&quot;language-sql&quot;&gt;my_database&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;BEGIN&lt;/span&gt;
my_database&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;SET&lt;/span&gt; my_domain&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;adityathebe.com&apos;&lt;/span&gt;
my_database&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;SHOW&lt;/span&gt; my_domain&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name
&lt;span class=&quot;token comment&quot;&gt;-- +-----------------+&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;-- | my_domain.name  |&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;-- |-----------------|&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;-- | adityathebe.com |&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;-- +-----------------+&lt;/span&gt;
my_database&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;ROLLBACK&lt;/span&gt;


my_database&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;SHOW&lt;/span&gt; my_domain&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name
&lt;span class=&quot;token comment&quot;&gt;-- +----------------+&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;-- | my_domain.name |&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;-- |----------------|&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;-- |                |&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;-- +----------------+&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Alternatively, you can also view the parameter using the &lt;code class=&quot;language-text&quot;&gt;current_setting&lt;/code&gt; function.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sql&quot;&gt;&lt;pre class=&quot;language-sql&quot;&gt;&lt;code class=&quot;language-sql&quot;&gt;my_database&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;SET&lt;/span&gt; my_domain&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;adityathebe.com&apos;&lt;/span&gt;
my_database&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;SELECT&lt;/span&gt; current_setting&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;my_domain.name&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;TRUE&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;-- +-----------------+&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;-- | current_setting |&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;-- |-----------------|&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;-- | adityathebe.com |&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;-- +-----------------+&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;adding-rls&quot;&gt;Adding RLS&lt;/h2&gt;
&lt;p&gt;With this in mind, I began writing a new Row Level Security Policy.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sql&quot;&gt;&lt;pre class=&quot;language-sql&quot;&gt;&lt;code class=&quot;language-sql&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;ALTER&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;TABLE&lt;/span&gt; config_items &lt;span class=&quot;token keyword&quot;&gt;ENABLE&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;ROW&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;LEVEL&lt;/span&gt; SECURITY&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;CREATE&lt;/span&gt; POLICY config_items_auth &lt;span class=&quot;token keyword&quot;&gt;ON&lt;/span&gt; config_items
  &lt;span class=&quot;token keyword&quot;&gt;FOR&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;ALL&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;TO&lt;/span&gt; postgrest_api&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; postgrest_anon
    &lt;span class=&quot;token keyword&quot;&gt;USING&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;CASE&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;WHEN&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        current_setting&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;request.jwt.claims&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;TRUE&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;IS&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;NULL&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;OR&lt;/span&gt; current_setting&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;request.jwt.claims&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;TRUE&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;::jsonb &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;disable_rls&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;IS&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;NOT&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;NULL&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;THEN&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;TRUE&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;ELSE&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
          &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;END&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The policy relies on the &lt;code class=&quot;language-text&quot;&gt;request.jwt.claims&lt;/code&gt; custom parameter.
If the parameter isn&apos;t set, the policy simply returns &lt;code class=&quot;language-text&quot;&gt;true&lt;/code&gt; - meaning the access is allowed.
Additionally, if the &lt;code class=&quot;language-text&quot;&gt;request.jwt.claims&lt;/code&gt; parameter is set, the policy still allows access if &lt;code class=&quot;language-text&quot;&gt;disable_rls&lt;/code&gt; key is present on it.&lt;/p&gt;
&lt;p&gt;After pushing this change &lt;em&gt;(along with a whole lot of other changes in the PR...)&lt;/em&gt;, our test suite went haywire.
Random tests would sporadically fail with varying errors on each run.
One commonly repeated error was this error&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;txt&quot;&gt;&lt;pre class=&quot;language-txt&quot;&gt;&lt;code class=&quot;language-txt&quot;&gt;invalid input syntax for type json
DETAIL:  The input string ended unexpectedly.
CONTEXT:  JSON data, line 1:&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The error came from a view using &lt;code class=&quot;language-text&quot;&gt;jsonb_object_agg&lt;/code&gt;.
My first guess? The RLS policy was blocking rows, causing the view to choke on empty data.
I deleted all the rows on another test db and the view worked fine however.&lt;/p&gt;
&lt;p&gt;But let&apos;s step back a bit. I never set &lt;code class=&quot;language-text&quot;&gt;request.jwt.claims&lt;/code&gt; parameter so the policy could not have blocked any rows.
As far as this test is concerned, RLS policy should practically be nonexistent.&lt;/p&gt;
&lt;p&gt;In the entire test suite, there was only one test where I had set the &lt;code class=&quot;language-text&quot;&gt;request.jwt.claims&lt;/code&gt; parameter.
And that test ran entirely within a transaction to avoid any side effects.
The parameter was also set with a &lt;code class=&quot;language-text&quot;&gt;LOCAL&lt;/code&gt; option.
Since the transaction would be rolled back the parameter should not persist outside of the transaction.
Even if the transaction was commited, the &lt;code class=&quot;language-text&quot;&gt;LOCAL&lt;/code&gt; option should ensure that it there&apos;s no trace of that parameter.&lt;/p&gt;
&lt;p&gt;This is where it gets even weirder - I disabled that test and the test suite passed consistently.
This didn&apos;t make sense.
How does disabling a test that runs entirely on a rolledback transaction have any effect on other tests?
Something was escaping our carefully constructed sandbox, but what?&lt;/p&gt;
&lt;p&gt;I also made sure that this test never runs in parallel with any other tests, but that didn&apos;t help.&lt;/p&gt;
&lt;h2 id=&quot;the-cause&quot;&gt;The Cause&lt;/h2&gt;
&lt;p&gt;After a bit of a research I found this weird behavior of &lt;code class=&quot;language-text&quot;&gt;SET&lt;/code&gt; command.
If you set a custom parameter and then unset it, it actually sets the parameter to an empty string!&lt;/p&gt;
&lt;p&gt;Let&apos;s try querying a non existing parameter.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sql&quot;&gt;&lt;pre class=&quot;language-sql&quot;&gt;&lt;code class=&quot;language-sql&quot;&gt;my_database&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;SHOW&lt;/span&gt; your_domain&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name
&lt;span class=&quot;token comment&quot;&gt;-- unrecognized configuration parameter &quot;your_domain.name&quot;&lt;/span&gt;

my_database&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;SELECT&lt;/span&gt; current_setting&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;your_domain.name&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;-- unrecognized configuration parameter &quot;my_domain.namespace&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Both the calls error out.&lt;/p&gt;
&lt;p&gt;If we pass in the optional second parameter to &lt;code class=&quot;language-text&quot;&gt;current_setting&lt;/code&gt; it returns &lt;code class=&quot;language-text&quot;&gt;NULL&lt;/code&gt; instead of throwing an error.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sql&quot;&gt;&lt;pre class=&quot;language-sql&quot;&gt;&lt;code class=&quot;language-sql&quot;&gt;my_database&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;SELECT&lt;/span&gt; current_setting&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;your_domain.name&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;TRUE&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;-- +-----------------+&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;-- | current_setting |&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;-- |-----------------|&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;-- | &amp;lt;null&gt;          |&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;-- +-----------------+&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Let&apos;s try setting the parameter in a transaction.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sql&quot;&gt;&lt;pre class=&quot;language-sql&quot;&gt;&lt;code class=&quot;language-sql&quot;&gt;my_database&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;BEGIN&lt;/span&gt;
my_database&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;SET&lt;/span&gt; your_domain&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;example.com&apos;&lt;/span&gt;
my_database&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;SHOW&lt;/span&gt; your_domain&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name
&lt;span class=&quot;token comment&quot;&gt;-- +-------------------+&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;-- | your_domain.name  |&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;-- |-------------------|&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;-- |   example.com     |&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;-- +-------------------+&lt;/span&gt;
my_database&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;ROLLBACK&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now, when I query the parameter I am expecting it to behave the same way as it did before - i.e. error out or return NULL.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sql&quot;&gt;&lt;pre class=&quot;language-sql&quot;&gt;&lt;code class=&quot;language-sql&quot;&gt;my_database&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;SHOW&lt;/span&gt; your_domain&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name
&lt;span class=&quot;token comment&quot;&gt;-- +------------------+&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;-- | your_domain.name |&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;-- |------------------|&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;-- |                  |&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;-- +------------------+&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Well there you go! A local parameter that was created inside a transaction has basically escaped and left a garbage
in the session. I couldn&apos;t find this behavior documented in the official docs.&lt;/p&gt;
&lt;p&gt;In fact, according to this &lt;a href=&quot;https://stackoverflow.com/questions/50923911/how-to-remove-configuration-parameter&quot;&gt;stackoverflow answer&lt;/a&gt;,
you cannot delete the parameter at all. Not with &lt;code class=&quot;language-text&quot;&gt;RESET&lt;/code&gt; as well. The parameter lives forever within the current
session.&lt;/p&gt;
&lt;p&gt;So the json error I was seeing was coming from the RLS policy as &lt;code class=&quot;language-text&quot;&gt;request.jwt.claim&lt;/code&gt; was an invalid json - it was an empty string.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Debugging disk usage On Linux]]></title><description><![CDATA[Here's how I am monitoring disk usage on Linux]]></description><link>https://www.adityathebe.com/debug-disk-usage</link><guid isPermaLink="false">https://www.adityathebe.com/debug-disk-usage</guid><pubDate>Sat, 19 Oct 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;My pretty powerful desktop with a intel i9-14900k feels a bit laggy sometimes.
A very identical Linux installation on my 9th gen i5 laptop never had this occasional lag.&lt;/p&gt;
&lt;p&gt;The weird thing is that the CPU usage is pretty low when the system is lagging. Upon further investigation I found out
that the CPU load on the other hand was pretty high!&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Yes, your CPU could be chilling at ~1% usage and still be peaking on CPU load.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;cat&lt;/span&gt; /proc/loadavg

&lt;span class=&quot;token comment&quot;&gt;# 0.71 0.58 0.56 2/1605 22984&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;That was quite baffling to me at first but it does make sense now. CPU load takes I/O into account.
If your disk cannot keep up with your CPU, processes have to basically pause &amp;#x26; wait for the disk to catch up.
This increases the CPU load metric.&lt;/p&gt;
&lt;p&gt;On my 24 core machine, the CPU load goes as high as 35-40 when I fireup my development environment after initial boot.
That includes launching&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;a Tmux session with 3 different go builds occuring simulataneously and about 6 docker containers&lt;/li&gt;
&lt;li&gt;and also launching the web browser with 6-7 tabs.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;cpu-load&quot;&gt;CPU Load&lt;/h2&gt;
&lt;p&gt;CPU load represents the average number of processes waiting for or using CPU time.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;Each process using or waiting for CPU (the ready queue or run queue) increments the load number by 1.
Each process that terminates decrements it by 1.
Most UNIX systems count only processes in the running (on CPU) or runnable (waiting for CPU) states&quot;&lt;/p&gt;
&lt;p&gt;-- Wikipedia&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;A CPU load of &lt;strong&gt;1&lt;/strong&gt; on a single-core machine indicates full CPU utilization.
On a quad-core CPU, a load of &lt;strong&gt;2&lt;/strong&gt; suggests 50% utilization across all cores.
When the load exceeds the number of CPU cores, processes begin to queue, and the system beings to lag.&lt;/p&gt;
&lt;p&gt;In my case, the fact that the CPU usage is pretty low suggests that the high load is caused by IO.&lt;/p&gt;
&lt;h2 id=&quot;tools-to-debug-slow-disk&quot;&gt;Tools to debug slow disk&lt;/h2&gt;
&lt;p&gt;2 tools seem to be the universal choice to debug disk operations.&lt;/p&gt;
&lt;h3 id=&quot;iotop&quot;&gt;iotop&lt;/h3&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;iotop&lt;/code&gt; lists out all the processes and the amount of data those processes have read from or written to the disk.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token function&quot;&gt;sudo&lt;/span&gt; iotop &lt;span class=&quot;token parameter variable&quot;&gt;-aoP&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Flags&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# -a accumulative mode where iotop shows the amount of I/O processes have done since iotop started.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# -o only shows processes actually doing I/O&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# -P shows processes instead of threads&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is helpful to figure out what processes are hogging the disk.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&gt; sudo iotop -aoP
Total DISK READ :       0.00 B/s | Total DISK WRITE :     178.60 K/s
Actual DISK READ:       0.00 B/s | Actual DISK WRITE:       0.00 B/s
    PID  PRIO  USER     DISK READ DISK WRITE&gt;  SWAPIN      IO    COMMAND
   5380 be/4 aditya      556.00 K     33.71 M  ?unavailable?  node /home/aditya/projects/adityathebe.com/.cache/tmp-5353-NH1acrOpTEuF
   3238 be/4 aditya       76.00 K     31.57 M  ?unavailable?  brave
   3277 be/4 aditya      128.00 K     17.25 M  ?unavailable?  brave --type=utility --utility-sub-type=network.mojom.NetworkService --lang=en-US
    464 be/3 root          0.00 B     15.47 M  ?unavailable?  [jbd2/nvme0n1p2-8]
  28731 be/4 aditya        0.00 B      3.20 M  ?unavailable?  nvim --embed .
    523 be/4 root          0.00 B    128.00 K  ?unavailable?  systemd-journald
   3293 be/4 aditya        0.00 B     88.00 K  ?unavailable?  brave --type=utility --utility-sub-type=storage.mojom.StorageService --lang=en-US
    222 be/7 root       1024.00 K      0.00 B  ?unavailable?  [khugepaged]
  30530 be/4 root         32.00 K      0.00 B  ?unavailable?  python /usr/bin/iotop -aoP&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I have sorted the list based on Disk Write. As you can see, &lt;code class=&quot;language-text&quot;&gt;node&lt;/code&gt; is the currently running process with the highest disk write.&lt;/p&gt;
&lt;p&gt;Unfortunately the biggest flaw with this tool is that if a process dies iotop removes it from the list.
It would have been nice to be able to leave iotop running in the background for few hours and then inspect the output later. Due to this reason, this tool wasn&apos;t really that helpful to me and I couldn&apos;t find any other tool that does that.&lt;/p&gt;
&lt;h3 id=&quot;iostat&quot;&gt;iostat&lt;/h3&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;iostat&lt;/code&gt; is another tool that gives you the current disk read/s &amp;#x26; write/s info along with couple of other similar metrics.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token function&quot;&gt;sudo&lt;/span&gt; iostat &lt;span class=&quot;token parameter variable&quot;&gt;-xm&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Flags&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# -x extended statistics&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# -m Display statistics in megabytes per second&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# argument&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# interval: the amount of time in seconds between each report.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# if 1 is supplied, the output refreshes every 1 second.&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This tool is really helpful to get the instaneous disk bandwidth.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token function&quot;&gt;sudo&lt;/span&gt; iostat &lt;span class=&quot;token parameter variable&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
Linux &lt;span class=&quot;token number&quot;&gt;6.11&lt;/span&gt;.4-arch1-1 &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;desktop&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; 	&lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;/19/2024 	_x86_64_	&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;32&lt;/span&gt; CPU&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           &lt;span class=&quot;token number&quot;&gt;1.32&lt;/span&gt;    &lt;span class=&quot;token number&quot;&gt;0.00&lt;/span&gt;    &lt;span class=&quot;token number&quot;&gt;0.56&lt;/span&gt;    &lt;span class=&quot;token number&quot;&gt;0.18&lt;/span&gt;    &lt;span class=&quot;token number&quot;&gt;0.00&lt;/span&gt;   &lt;span class=&quot;token number&quot;&gt;97.94&lt;/span&gt;

Device             tps    MB_read/s    MB_wrtn/s    MB_dscd/s    MB_read    MB_wrtn    MB_dscd
nvme0n1          &lt;span class=&quot;token number&quot;&gt;43.24&lt;/span&gt;         &lt;span class=&quot;token number&quot;&gt;0.70&lt;/span&gt;         &lt;span class=&quot;token number&quot;&gt;0.40&lt;/span&gt;         &lt;span class=&quot;token number&quot;&gt;0.00&lt;/span&gt;       &lt;span class=&quot;token number&quot;&gt;2799&lt;/span&gt;       &lt;span class=&quot;token number&quot;&gt;1594&lt;/span&gt;          &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
nvme1n1           &lt;span class=&quot;token number&quot;&gt;0.10&lt;/span&gt;         &lt;span class=&quot;token number&quot;&gt;0.00&lt;/span&gt;         &lt;span class=&quot;token number&quot;&gt;0.00&lt;/span&gt;         &lt;span class=&quot;token number&quot;&gt;0.00&lt;/span&gt;         &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;          &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;          &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;


avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           &lt;span class=&quot;token number&quot;&gt;0.25&lt;/span&gt;    &lt;span class=&quot;token number&quot;&gt;0.00&lt;/span&gt;    &lt;span class=&quot;token number&quot;&gt;0.22&lt;/span&gt;    &lt;span class=&quot;token number&quot;&gt;0.00&lt;/span&gt;    &lt;span class=&quot;token number&quot;&gt;0.00&lt;/span&gt;   &lt;span class=&quot;token number&quot;&gt;99.53&lt;/span&gt;

Device             tps    MB_read/s    MB_wrtn/s    MB_dscd/s    MB_read    MB_wrtn    MB_dscd
nvme0n1          &lt;span class=&quot;token number&quot;&gt;81.00&lt;/span&gt;         &lt;span class=&quot;token number&quot;&gt;0.00&lt;/span&gt;         &lt;span class=&quot;token number&quot;&gt;0.45&lt;/span&gt;         &lt;span class=&quot;token number&quot;&gt;0.00&lt;/span&gt;          &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;          &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;          &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
nvme1n1           &lt;span class=&quot;token number&quot;&gt;0.00&lt;/span&gt;         &lt;span class=&quot;token number&quot;&gt;0.00&lt;/span&gt;         &lt;span class=&quot;token number&quot;&gt;0.00&lt;/span&gt;         &lt;span class=&quot;token number&quot;&gt;0.00&lt;/span&gt;          &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;          &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;          &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;


avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           &lt;span class=&quot;token number&quot;&gt;0.38&lt;/span&gt;    &lt;span class=&quot;token number&quot;&gt;0.00&lt;/span&gt;    &lt;span class=&quot;token number&quot;&gt;0.25&lt;/span&gt;    &lt;span class=&quot;token number&quot;&gt;0.03&lt;/span&gt;    &lt;span class=&quot;token number&quot;&gt;0.00&lt;/span&gt;   &lt;span class=&quot;token number&quot;&gt;99.34&lt;/span&gt;

Device             tps    MB_read/s    MB_wrtn/s    MB_dscd/s    MB_read    MB_wrtn    MB_dscd
nvme0n1          &lt;span class=&quot;token number&quot;&gt;10.00&lt;/span&gt;         &lt;span class=&quot;token number&quot;&gt;0.00&lt;/span&gt;         &lt;span class=&quot;token number&quot;&gt;0.12&lt;/span&gt;         &lt;span class=&quot;token number&quot;&gt;0.00&lt;/span&gt;          &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;          &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;          &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
nvme1n1           &lt;span class=&quot;token number&quot;&gt;0.00&lt;/span&gt;         &lt;span class=&quot;token number&quot;&gt;0.00&lt;/span&gt;         &lt;span class=&quot;token number&quot;&gt;0.00&lt;/span&gt;         &lt;span class=&quot;token number&quot;&gt;0.00&lt;/span&gt;          &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;          &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;          &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;hr&gt;
&lt;p&gt;Ultimately, neither of these two tools really helped by get to the bottom of the issue however XD.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Video Files Demystified]]></title><description><![CDATA[A Guide to Understanding Containers, Codecs, and Transcoding]]></description><link>https://www.adityathebe.com/video-containers-and-codecs</link><guid isPermaLink="false">https://www.adityathebe.com/video-containers-and-codecs</guid><pubDate>Mon, 14 Oct 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;For the past couple of years I have been running Jellyfin on my &lt;a href=&quot;https://github.com/adityathebe/homelab&quot;&gt;homelab&lt;/a&gt;; think of it as a self-hosted Neflix.
I host all of my movies &amp;#x26; TV shows in there and then watch them from various clients - mobile app, TV &amp;#x26; web app.
It&apos;s a great piece of software - however I don&apos;t particularly use its webapp.
The reason being - it doesn&apos;t play &lt;strong&gt;some&lt;/strong&gt; movies very well.
It stutters so much and the server cpu usage goes through the roof.&lt;/p&gt;
&lt;p&gt;And that&apos;s why I prefer to watch the movies on Jellyfin from my media player instead of from the web app.
To do that, I simply grab the stream URL from Jellyfin and play it on the media player as&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;mpv &lt;span class=&quot;token string&quot;&gt;&apos;&amp;lt;jellyfin-stream-url&gt;&apos;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# or&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# vlc &apos;&amp;lt;jellyfin-stream-url&gt;&apos;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I had very little idea why some movies wouldn&apos;t play well on the web UI.
And interestingly, on the other hand, the TV app handles pretty much any video with ease.&lt;/p&gt;
&lt;p&gt;Now, I wasn&apos;t totally clueless here. I knew that &lt;em&gt;some&lt;/em&gt; videos needed to be transcoded with &lt;code class=&quot;language-text&quot;&gt;ffpmpeg&lt;/code&gt;
and that pins the CPU to 100% &lt;em&gt;(I don&apos;t have GPU attached so the transcoding is entirely performed on the CPU)&lt;/em&gt;. But I didn&apos;t really know why that was required for some videos
and not for others. And honestly, I didn&apos;t know what &quot;transcoding&quot; was to begin with.&lt;/p&gt;
&lt;p&gt;This curiousity led me to learn quite a bit about video files and ultimately
to write this blog post.&lt;/p&gt;
&lt;h2 id=&quot;the-two-defining-characterstics-of-a-video-file&quot;&gt;The two defining characterstics of a video file&lt;/h2&gt;
&lt;p&gt;The unusual thing about video files is that the file extension doesn&apos;t tell
you anything about the video format.&lt;/p&gt;
&lt;p&gt;When you encounter an &lt;code class=&quot;language-text&quot;&gt;.mp3&lt;/code&gt; file, you know that the file contains an mp3 encoded
audio data. Likewise, a &lt;code class=&quot;language-text&quot;&gt;.jpeg&lt;/code&gt; file contains a jpeg encoded image and a &lt;code class=&quot;language-text&quot;&gt;.json&lt;/code&gt; file contains json encoded
data.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Aside: I know you can rename the file to have an
incorrect extension, but let&apos;s assume that the file is named correctly with the appropriate extension.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;However, with video files, the extension doesn&apos;t give you the entire picture about
what&apos;s inside the file. Your media player could support one &lt;code class=&quot;language-text&quot;&gt;.mp4&lt;/code&gt; file but may not support another &lt;code class=&quot;language-text&quot;&gt;.mp4&lt;/code&gt; file.
i.e. two different mp4 files may have been encoded with two separate codecs.&lt;/p&gt;
&lt;p&gt;A video content thus has two distinct characterstics that defines it&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the file type (commonly referred to as the Container)&lt;/li&gt;
&lt;li&gt;the encoding algorithm (Compression / Codec)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;containers&quot;&gt;Containers&lt;/h2&gt;
&lt;p&gt;The thing that we commonly refer to as the video format like &lt;code class=&quot;language-text&quot;&gt;mp4&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;mkv&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;flv&lt;/code&gt; are actually
the just the file types. They are containers.&lt;/p&gt;
&lt;p&gt;Think of them as different types of lunchboxes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The container alone doesn&apos;t reveal its contents.&lt;/li&gt;
&lt;li&gt;Some containers are like multi-compartment lunchboxes, capable of neatly organizing different &quot;food items&quot; (such as multiple audio tracks or subtitle files).&lt;/li&gt;
&lt;li&gt;What the container does indicate is its capacity and structure.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Some popular container formats are: &lt;code class=&quot;language-text&quot;&gt;mp4&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;mkv&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;3gp&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;wEBm&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;flv&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;avi&lt;/code&gt;, ...&lt;/p&gt;
&lt;p&gt;Container formats differ from each other in various ways but here are some prominent defining characterstics&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Characteristic&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Compression&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Different formats use various compression algorithms, such as H.264, VP8/VP9, or lossless codecs like FLAC.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Metadata support&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Ability to store metadata, including subtitles, chapter markers, and custom tags.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Audio and video tracks&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Some formats support multiple audio and video streams, while others are limited to a single track.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Compatibility&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Different formats have varying levels of compatibility with different devices, operating systems, or software applications.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Licensing and royalties&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Container formats may be open-source (e.g. mkv), royalty-free (e.g. webm), proprietary (e.g. MP4, QuickTime,)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&quot;codecs&quot;&gt;Codecs&lt;/h2&gt;
&lt;p&gt;Codecs are the algorithms that encode the raw video data and compress them. The output of a codec is what&apos;s put inside the
containers. Codecs could also mean a hardware that is specifically designed to efficiently run the codecs.&lt;/p&gt;
&lt;p&gt;Here are &lt;strong&gt;some&lt;/strong&gt; of the most prominent characterstics of codecs to consider:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Characteristic&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Compression Ratio&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Amount of data reduction achieved by the codec, with higher ratios indicating better compression.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Licensing&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Whether the codec is open-source (free) or requires royalties or licenses from patent holders.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Complexity&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Computational resources required to encode and decode the video, affecting device performance.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Color Space&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Range of colors supported by the codec, impacting suitability for different applications (SD, HD, HDR).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Bit Depth&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Number of bits used to represent each pixel&apos;s color information, affecting overall quality and detail.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Some popular codecs are:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Codec&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;H.264 &lt;em&gt;(&lt;strong&gt;AVC&lt;/strong&gt;)&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;most popular and most well-supported codec&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;H.265 &lt;em&gt;(&lt;strong&gt;HEVC&lt;/strong&gt;)&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;More efficient than H.264 i.e. similar quality with lesser file size. However, has lesser support and it&apos;s patented. In fact, on windows, you need to purchase the codec for $0.99 from Microsoft - but there are free alternatives.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;VP9&lt;/td&gt;
&lt;td&gt;&lt;em&gt;(Open source)&lt;/em&gt; developed by Google and YouTube uses this.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AV1&lt;/td&gt;
&lt;td&gt;&lt;em&gt;(Open source)&lt;/em&gt; relatively newer and the considered the future of video compression. Isn&apos;t supported widely.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&quot;why-its-important-to-be-aware-of-the-codec&quot;&gt;Why it&apos;s important to be aware of the codec&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;For General Users&lt;/strong&gt;: Understanding codecs helps you troubleshoot issues with video playback.
By knowing which codecs are supported by your media player, you can diagnose and potentially fix problems when a video file won&apos;t play.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;For Videographers&lt;/strong&gt;: Being mindful of the codec used in your footage ensures that you can work seamlessly with your preferred editing software or share your content without
conversion issues.
For instance, if you record with HEVC but Davinci Resolve doesn&apos;t support it, you&apos;ll need to purchase the codec to edit your files.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;For Video Providers&lt;/strong&gt;: Choosing efficient and compatible codecs for your videos saves time and resources by avoiding unnecessary transcoding requests from clients.
By encoding in a format that&apos;s widely supported, you can ensure that your content is accessible and easily playable on various devices and platforms.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;looking-back-at-the-original-problem&quot;&gt;Looking back at the original problem&lt;/h2&gt;
&lt;p&gt;To circle back to the original problem, the reason why some movies weren&apos;t supported by the Jellyfin Webapp was because
those movies were encoded with HEVC.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 926px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/8c7e9b5f78ae2c4841d7c212b5ae8643/69476/extraction-2-movie-jellyfin-codec.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 59.333333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAIAAADtbgqsAAAACXBIWXMAABCcAAAQnAEmzTo0AAABT0lEQVR42nVRi3KDIBD0B6JJUEAFRdSIKE46SVvb//+wLprJu+vNzSnc7e4ZSCF+5vnr8/xxPE5umudvVZZJHKecITjzOVuKFahzzgRnMmWBVup3ns+nk+27oa/tYA+HttFaiFzkPqS4xfVLgVrkAaM0zzCdIWcpLZKk4DzlPH4B5NDkkn2RJMF+vxdCRlHE0ZNmBSFRGOJ1+w7RIwJCSFVVMNP3/TCM1jljetguXqCUAv/9XM+Mq1JKf75kGNmEm+gdwkdRnrnrTNs0Pg5t27S11nWNpOtmRVsvaHHYNKDJsbMCjwx2ux2lFO4ppNML0hV+Cx7rCV8ApTdm2DDGOOdsby1sW2tMV5YlHMI4+GHkqhm4359vhiQogSTsrKoUZq/3rla3/yAgcYzxEA9L0zQJIVBD55PCf5oJ0bUGP2jHcXTT1HUdRmDxTz/mtfkPFytGdUwMcuUAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;HEVC encoded movie on Jellyfin&quot;
        title=&quot;&quot;
        src=&quot;/static/8c7e9b5f78ae2c4841d7c212b5ae8643/69476/extraction-2-movie-jellyfin-codec.png&quot;
        srcset=&quot;/static/8c7e9b5f78ae2c4841d7c212b5ae8643/5a46d/extraction-2-movie-jellyfin-codec.png 300w,
/static/8c7e9b5f78ae2c4841d7c212b5ae8643/0a47e/extraction-2-movie-jellyfin-codec.png 600w,
/static/8c7e9b5f78ae2c4841d7c212b5ae8643/69476/extraction-2-movie-jellyfin-codec.png 926w&quot;
        sizes=&quot;(max-width: 926px) 100vw, 926px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;
&lt;em&gt;HEVC encoded movie on Jellyfin&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;My web browser (and most browsers today) doesn&apos;t &lt;a href=&quot;https://caniuse.com/hevc&quot;&gt;natively support hevc&lt;/a&gt;
encoded media files. The Jellyfin server then has to convert the hevc encoded files to a format that the client supports.
This process of converting a video file from one codec to another is called &lt;strong&gt;Transcoding&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Most people running Jellyfin servers pre-transcode necessary files into h264 so all clients can support it and the playbook
is smooth. Or, they have run the transcode on the fly when the client starts streaming.&lt;/p&gt;
&lt;p&gt;On the other hand, h264 encoded movies are natively supported by most browsers these days.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 809px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/c539d0b09f121f3b6b1235780961499d/e80ac/jaari-movie-jellyfin-codec.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 55.666666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAIAAADwazoUAAAACXBIWXMAABCcAAAQnAEmzTo0AAABSUlEQVR42oVRyXaDMAzknoQlLF4kL8SYkPfINf2B5v9/qWM7feml7WDEYCF5NFRMSkyT9z4uixCgWAmJCaGkVEoqKaSUpKRjsoYNadbYlpWzBomPx+P5+YzLZb+6GON1XW+3WwiBiQwDZAx7Z70xFvXMJq9KpvZi7Puh79FOy6mcRloTiJTYTFFrJk34oKycqtq2reua0ZkJ3CTCyIauU33fdV37O1Jx0zRQjjlPpxpCxnGcphFC8Kib5lRQ1zm8I/AuDuGCIS8Z3s+IeF3XFRaEJSUTCQG+lhTwkm2dm73HsTqBoNxaW0aAR3kmEKNJZw7/sG1fJw/DKDLGAXr74/F4OBwQX/p+CC54y8YL+sR1nWe/bRskymwv/nSDdPe9CroS0vXtNrNzDvbs+33Hfb9DttYKov5xG8VEhEnO5/N1S4hxKSLbP/EFldg89CayFHAAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;AVC encoded movie on Jellyfin&quot;
        title=&quot;&quot;
        src=&quot;/static/c539d0b09f121f3b6b1235780961499d/e80ac/jaari-movie-jellyfin-codec.png&quot;
        srcset=&quot;/static/c539d0b09f121f3b6b1235780961499d/5a46d/jaari-movie-jellyfin-codec.png 300w,
/static/c539d0b09f121f3b6b1235780961499d/0a47e/jaari-movie-jellyfin-codec.png 600w,
/static/c539d0b09f121f3b6b1235780961499d/e80ac/jaari-movie-jellyfin-codec.png 809w&quot;
        sizes=&quot;(max-width: 809px) 100vw, 809px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;
&lt;em&gt;AVC encoded movie on Jellyfin&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Here&apos;s a list of codecs and their support on different Jellyfin clients&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1197px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/5981e49a809bb5de174f43a543695e01/d326d/jellyfin.org_docs_general_clients_codec-support_.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 64.33333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAYAAACpUE5eAAAACXBIWXMAAAsTAAALEwEAmpwYAAACqUlEQVR42jVTyXKbQBTEFSm2JWE2sYpNQmgDhAAJ4ciJK3alnBxySFVu+YX8/7XTg5zDq3nbDK/7NZKzeETZ/cQsfYIVn+EsOohcb/OuN7uPO7jJp96u/iNc5qdR28cW+4zoDCktv+H3n7/YVG+It89I8hcsi1eer1jQTzLGws++Ylu/YcV+P73g+PSL8XfI8SNrL3DXz1DSL5BMvrxpfvBrn6DOGuj+EUZwgjY79r5GU/2rf603fU7zRJ84mWOvylNjXbrRC0jyFjfjFPLDCsOJONeY0L+VVxgLoz+YrPq66NONLZQwx4CxHueQvR2mixJDdQVpxJdHToWxtYdm7zERp1NCpS/TFJr6nhfn2CxgeAdo4aG/8+CV0IKK/NWYsC5p6TN0Yp/GHSJBcNgi4nJC+h4teDcnuuZM1pOkQ1xeMA1aGP4JcXFBUj3BTriUoVliYFUcd8uxK4zsvD+N5EAoBfT5gbBK3JsZpkmFj9oO3o58RSXuphnMtIIalLDTuo8lmYTK4RkKoQdZRxk08LdneGEN06/hBA1muzMXIOotFNITJSfmWmhuzb4G3qbllB30oIZ0Zx9w5/B1I4cdkRN3D3vZwGCsmDkMJ4cVkkO7gL0+YqRn8PwCFnvGRgbL4eQLPrxu+h7p3m1wH5wxMveIo4yyOHCSM2zGUy/HLMwQBBlUh/VtA5n55apAwIkUq0A0z+H2EwqUJaQHkipMQI7Igxk3CAndI3QrquAnpCCpCbmGT970WY05ufRXYiE1Qt75D9kgTdKA0D5QdwNl0y9AkC+WoMWE6RbXBYn8dAfTWWOo7KjDHTW5wS1z4o7i72FyibfMSzrlIv4MYcvqAi/tKIELFpRBkBwJ70T/wn/6hPWmoWzOSBctJXTqZSLuCNmsT5/hJC3+AT3ya+mwgdgVAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;jellyfin org docs general clients codec support &quot;
        title=&quot;&quot;
        src=&quot;/static/5981e49a809bb5de174f43a543695e01/d326d/jellyfin.org_docs_general_clients_codec-support_.png&quot;
        srcset=&quot;/static/5981e49a809bb5de174f43a543695e01/5a46d/jellyfin.org_docs_general_clients_codec-support_.png 300w,
/static/5981e49a809bb5de174f43a543695e01/0a47e/jellyfin.org_docs_general_clients_codec-support_.png 600w,
/static/5981e49a809bb5de174f43a543695e01/d326d/jellyfin.org_docs_general_clients_codec-support_.png 1197w&quot;
        sizes=&quot;(max-width: 1197px) 100vw, 1197px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;
&lt;em&gt;&lt;a href=&quot;https://jellyfin.org/docs/general/clients/codec-support/&quot;&gt;https://jellyfin.org/docs/general/clients/codec-support/&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;I have a handy function on my &lt;code class=&quot;language-text&quot;&gt;.zshrc&lt;/code&gt; that displays the file container format &amp;#x26; the codec for a given media file.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token function-name function&quot;&gt;video_info&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;File Container: &lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;file&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-b&lt;/span&gt; --mime-type &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;$1&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Video Codec: &lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$(&lt;/span&gt;ffprobe &lt;span class=&quot;token parameter variable&quot;&gt;-v&lt;/span&gt; quiet &lt;span class=&quot;token parameter variable&quot;&gt;-select_streams&lt;/span&gt; v:0 &lt;span class=&quot;token parameter variable&quot;&gt;-show_entries&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;stream&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;codec_name &lt;span class=&quot;token parameter variable&quot;&gt;-of&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;noprint_wrappers&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;:nokey&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;$1&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Audio Codec: &lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$(&lt;/span&gt;ffprobe &lt;span class=&quot;token parameter variable&quot;&gt;-v&lt;/span&gt; quiet &lt;span class=&quot;token parameter variable&quot;&gt;-select_streams&lt;/span&gt; a:0 &lt;span class=&quot;token parameter variable&quot;&gt;-show_entries&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;stream&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;codec_name &lt;span class=&quot;token parameter variable&quot;&gt;-of&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;noprint_wrappers&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;:nokey&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;$1&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;whos-responsible-in-supporting-a-codec&quot;&gt;Who&apos;s responsible in supporting a codec&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;The media player application is responsible in supporting a given codec.&lt;/li&gt;
&lt;li&gt;The operating system however provides system libraries and drivers that support various video codecs and facilitate communication between software and hardware components.
The application can either implement their own support for codec or use the OS&apos;s system libraries.&lt;/li&gt;
&lt;li&gt;The hardware accelerates specific codec operations using GPUs, SoCs, or specialized A/V codec chips.&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Understand Public Key Infrastructure & Certificates]]></title><description><![CDATA[Learn about about the shortcomings of public key encryption and the need for a trusted 3rd party - Certificate Authority.]]></description><link>https://www.adityathebe.com/public-key-infrastructures-and-certificates</link><guid isPermaLink="false">https://www.adityathebe.com/public-key-infrastructures-and-certificates</guid><pubDate>Mon, 29 Jul 2024 22:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;This article is targeted towards newcomers looking to explore the foundations of PKIs.&lt;br&gt;
It should be treated as the first chapter of PKI 101.&lt;br&gt;
Readers are assumed to have a basic understanding of Asymmetric Cryptography &amp;#x26; TLS.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Public Key encryption has enabled us to establish a secure channel for communication in an untrusted environment.&lt;/p&gt;
&lt;p&gt;If Alice wants to send confidential data to Bob, she needs to somehow obtain Bob&apos;s public key and then encrypt the message with that public key. Only Bob can decrypt the message. And likewise, Bob encrypts the message with Alice&apos;s public key, and only Alice can decrypt it. A secure communication channel is thus established.&lt;/p&gt;
&lt;p&gt;While &lt;strong&gt;confidentiality&lt;/strong&gt; is undoubtedly achieved with encryption, &lt;strong&gt;authenticity&lt;/strong&gt; isn&apos;t!
Let me ask you this - how does Alice guarantee that the public key is actually Bob&apos;s?
Cuz remember, they are in a potentially compromised environment.
Who is to say that Eve - a malicious actor - didn&apos;t offer her public key to Alice claiming it to be of Bob&apos;s.&lt;/p&gt;
&lt;h2 id=&quot;shortcomings-of-public-key-encryption&quot;&gt;Shortcomings of Public Key Encryption&lt;/h2&gt;
&lt;p&gt;If Alice doesn&apos;t verify that the public key is Bob&apos;s then she&apos;ll happily encrypt messages with Eve&apos;s key falsely believing that she&apos;s encrypting it for Bob.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;inline-svg&quot; role=&quot;img&quot; aria-label=&quot;Diagram showing Eve intercepting Bob&amp;#039;s public key&quot;&gt;&lt;svg version=&quot;1.1&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; viewBox=&quot;0 0 740.8699188232422 425.5&quot; style=&quot;max-height: 400px; width: 100%; height: auto;&quot;&gt;
  &lt;!-- svg-source:excalidraw --&gt;
  &lt;defs&gt;
    &lt;style class=&quot;style-fonts&quot;&gt;
      @font-face {
        font-family: Excalifont;
        src: url(data:font/woff2;base64,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);
      }
    &lt;/style&gt;
  &lt;/defs&gt;
  &lt;rect x=&quot;0&quot; y=&quot;0&quot; width=&quot;740.8699188232422&quot; height=&quot;425.5&quot; fill=&quot;none&quot;&gt;&lt;/rect&gt;
  &lt;g stroke-linecap=&quot;round&quot; transform=&quot;translate(638.8699188232422 223) rotate(0 46 20)&quot;&gt;
    &lt;path d=&quot;M10 0 C23.07 -1.18, 38.97 3.39, 82 0 C90.37 -2.44, 91.09 2.44, 92 10 C92.91 15.2, 89.65 22.78, 92 30 C90.61 35.82, 90.31 37.67, 82 40 C66.9 42.12, 45.9 40.41, 10 40 C6.11 37.44, 3.07 34.84, 0 30 C3.23 25.58, 2.48 12.48, 0 10 C-2.26 4.11, 1.42 -0.3, 10 0&quot; stroke=&quot;none&quot; stroke-width=&quot;0&quot; fill=&quot;var(--color-good)&quot;&gt;&lt;/path&gt;
    &lt;path d=&quot;M10 0 C30.61 -1.34, 49.95 -0.34, 82 0 M10 0 C27.98 -0.95, 45.72 -0.93, 82 0 M82 0 C90.56 -1.01, 93.43 1.65, 92 10 M82 0 C89.58 1.37, 92.93 2.84, 92 10 M92 10 C91.7 16.27, 91.29 21.05, 92 30 M92 10 C91.52 15.44, 91.99 22.48, 92 30 M92 30 C93.7 38.65, 88.23 39.79, 82 40 M92 30 C90.27 37.63, 86.58 40.8, 82 40 M82 40 C68.42 39.94, 52.34 41.02, 10 40 M82 40 C65.23 40.44, 46.96 39.98, 10 40 M10 40 C3.24 38.74, 0.39 35.05, 0 30 M10 40 C3.48 39.43, -1.47 36.96, 0 30 M0 30 C0.25 23.97, -0.31 22.91, 0 10 M0 30 C0.42 22.12, -0.65 16.12, 0 10 M0 10 C1.91 3.75, 2.28 -1.9, 10 0 M0 10 C1.61 2.21, 5.37 -1.23, 10 0&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;
  &lt;/g&gt;
  &lt;g transform=&quot;translate(665.7099380493164 230.5) rotate(0 19.15998077392578 12.5)&quot;&gt;
    &lt;text x=&quot;19.15998077392578&quot; y=&quot;17.619999999999997&quot; font-family=&quot;Excalifont, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;Bob&lt;/text&gt;
  &lt;/g&gt;
  &lt;g stroke-linecap=&quot;round&quot; transform=&quot;translate(26.869918823242188 124.5) rotate(0 40.5 23)&quot;&gt;
    &lt;path d=&quot;M11.5 0 C25.92 -0.96, 38.64 -1.07, 69.5 0 C76.41 -1.64, 77.87 6.55, 81 11.5 C83.41 15.09, 80.33 23.55, 81 34.5 C82.71 44.21, 78.91 49.02, 69.5 46 C57.47 45.23, 46.48 46.49, 11.5 46 C6.36 45.04, -3.38 39.69, 0 34.5 C-0.47 24.87, -0.85 13.46, 0 11.5 C0.97 7, 0.4 -1.56, 11.5 0&quot; stroke=&quot;none&quot; stroke-width=&quot;0&quot; fill=&quot;var(--color-good)&quot;&gt;&lt;/path&gt;
    &lt;path d=&quot;M11.5 0 C31.65 0.6, 47.93 0.56, 69.5 0 M11.5 0 C23.97 -0.37, 37.82 0.66, 69.5 0 M69.5 0 C78.13 -1.94, 81.78 4.73, 81 11.5 M69.5 0 C76.27 -1.85, 83.29 4, 81 11.5 M81 11.5 C81.5 15.66, 82.21 23.23, 81 34.5 M81 11.5 C80.53 17.81, 81.99 26.58, 81 34.5 M81 34.5 C81.57 43.24, 75.36 47.55, 69.5 46 M81 34.5 C79.42 43.25, 76.58 45.3, 69.5 46 M69.5 46 C50.01 45.25, 28.9 45.2, 11.5 46 M69.5 46 C47.59 45.54, 25.3 45.61, 11.5 46 M11.5 46 C4.87 46.94, 0.4 43.44, 0 34.5 M11.5 46 C2.38 46.32, -1.65 41.83, 0 34.5 M0 34.5 C-1.12 27.32, -1.06 20.53, 0 11.5 M0 34.5 C-0.11 28.74, -0.68 25.57, 0 11.5 M0 11.5 C0.96 2.95, 4.5 1.34, 11.5 0 M0 11.5 C-1.76 2.15, 2.45 1.2, 11.5 0&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;
  &lt;/g&gt;
  &lt;g transform=&quot;translate(45.37993621826172 135) rotate(0 21.98998260498047 12.5)&quot;&gt;
    &lt;text x=&quot;21.98998260498047&quot; y=&quot;17.619999999999997&quot; font-family=&quot;Excalifont, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;Alice&lt;/text&gt;
  &lt;/g&gt;
  &lt;g stroke-linecap=&quot;round&quot; transform=&quot;translate(288.8699188232422 380.5) rotate(0 36 17.5)&quot;&gt;
    &lt;path d=&quot;M8.75 0 C22.63 0.41, 39.68 -0.51, 63.25 0 C67.05 -0.78, 72.33 6.42, 72 8.75 C72.63 12.78, 71.13 16.96, 72 26.25 C73.79 28.57, 69.37 36.4, 63.25 35 C50.12 35.65, 40.78 35.15, 8.75 35 C4.98 38.54, -0.49 29.63, 0 26.25 C3.13 18.32, 2.92 16.44, 0 8.75 C1.71 5.75, 6.39 -1.47, 8.75 0&quot; stroke=&quot;none&quot; stroke-width=&quot;0&quot; fill=&quot;var(--color-bad)&quot;&gt;&lt;/path&gt;
    &lt;path d=&quot;M8.75 0 C23.52 -1.67, 40.93 0.05, 63.25 0 M8.75 0 C24.95 -1.16, 41.75 -1.28, 63.25 0 M63.25 0 C71.02 -1.09, 73.4 3.37, 72 8.75 M63.25 0 C71.31 -0.82, 69.89 3.23, 72 8.75 M72 8.75 C73.47 12.34, 72.56 18.49, 72 26.25 M72 8.75 C71.53 14.47, 72.6 20, 72 26.25 M72 26.25 C72.37 33.38, 68.74 34.12, 63.25 35 M72 26.25 C72.69 31.47, 70.69 36.31, 63.25 35 M63.25 35 C47.07 34.88, 29.24 33.64, 8.75 35 M63.25 35 C49.76 35.23, 36.51 34.94, 8.75 35 M8.75 35 C2.42 35.11, -0.4 31.91, 0 26.25 M8.75 35 C3.45 36.5, -1.29 30.04, 0 26.25 M0 26.25 C0.69 21.53, 0.37 13.4, 0 8.75 M0 26.25 C-0.7 20.47, 0.59 13.45, 0 8.75 M0 8.75 C0.39 1.44, 2.04 -1.58, 8.75 0 M0 8.75 C1.45 3.22, 4.28 1.9, 8.75 0&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;
  &lt;/g&gt;
  &lt;g transform=&quot;translate(306.54993438720703 385.5) rotate(0 18.319984436035156 12.5)&quot;&gt;
    &lt;text x=&quot;18.319984436035156&quot; y=&quot;17.619999999999997&quot; font-family=&quot;Excalifont, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;Eve&lt;/text&gt;
  &lt;/g&gt;
  &lt;g stroke-linecap=&quot;round&quot; transform=&quot;translate(39.36991882324219 10) rotate(0 79 17.5)&quot;&gt;
    &lt;path d=&quot;M8.75 0 C39.65 2.53, 67.95 0.7, 149.25 0 M8.75 0 C63.59 0.32, 116.49 -0.13, 149.25 0 M149.25 0 C158.55 -2.24, 156.67 2.91, 158 8.75 M149.25 0 C153.35 -3.79, 159.61 3.39, 158 8.75 M158 8.75 C160.05 12.41, 160.18 19.98, 158 26.25 M158 8.75 C156.66 16.31, 158.54 22.28, 158 26.25 M158 26.25 C155.03 34.22, 154.79 38.22, 149.25 35 M158 26.25 C155.6 31.55, 151.95 34.32, 149.25 35 M149.25 35 C92.88 36.47, 45.07 34.12, 8.75 35 M149.25 35 C117.51 30.9, 82.83 34.29, 8.75 35 M8.75 35 C5.2 31.46, -2.34 28.48, 0 26.25 M8.75 35 C3.51 30.7, -2.66 34.59, 0 26.25 M0 26.25 C-0.35 22.74, 0.82 13.25, 0 8.75 M0 26.25 C-1.79 22.09, -0.16 17.47, 0 8.75 M0 8.75 C-2.94 2.26, -1.06 -0.56, 8.75 0 M0 8.75 C-2.86 0.72, 2.36 1.44, 8.75 0&quot; stroke=&quot;#1971c2&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;
  &lt;/g&gt;
  &lt;g transform=&quot;translate(44.66999053955078 15) rotate(0 73.6999282836914 12.5)&quot;&gt;
    &lt;text x=&quot;73.6999282836914&quot; y=&quot;17.619999999999997&quot; font-family=&quot;Excalifont, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;#1971c2&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;Secret for Bob&lt;/text&gt;
  &lt;/g&gt;
  &lt;g mask=&quot;url(#mask-5drIIxW22PDIo90icC4pN)&quot; stroke-linecap=&quot;round&quot;&gt;
    &lt;g transform=&quot;translate(282.3699188232422 394.13842826294115) rotate(0 -109.87556193679092 -111.06921413147052)&quot;&gt;
      &lt;path d=&quot;M0 0 C-27.67 -13.52, -129.37 -44.12, -166 -81.14 C-202.63 -118.16, -210.79 -198.64, -219.75 -222.14 M0 0 C-27.67 -13.52, -129.37 -44.12, -166 -81.14 C-202.63 -118.16, -210.79 -198.64, -219.75 -222.14&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
    &lt;g transform=&quot;translate(282.3699188232422 394.13842826294115) rotate(0 -109.87556193679092 -111.06921413147052)&quot;&gt;
      &lt;path d=&quot;M-205.65 -201.49 C-209.24 -206.75, -212.83 -212.01, -219.75 -222.14 M-205.65 -201.49 C-210.76 -208.97, -215.86 -216.44, -219.75 -222.14&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
    &lt;g transform=&quot;translate(282.3699188232422 394.13842826294115) rotate(0 -109.87556193679092 -111.06921413147052)&quot;&gt;
      &lt;path d=&quot;M-222.22 -197.26 C-221.59 -203.6, -220.96 -209.93, -219.75 -222.14 M-222.22 -197.26 C-221.33 -206.27, -220.43 -215.27, -219.75 -222.14&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
  &lt;/g&gt;
  &lt;mask id=&quot;mask-5drIIxW22PDIo90icC4pN&quot;&gt;
    &lt;rect x=&quot;0&quot; y=&quot;0&quot; fill=&quot;#fff&quot; width=&quot;602.121042696824&quot; height=&quot;716.2768565258822&quot;&gt;&lt;/rect&gt;
    &lt;rect x=&quot;10&quot; y=&quot;288&quot; fill=&quot;#000&quot; width=&quot;212.73983764648438&quot; height=&quot;50&quot; opacity=&quot;1&quot;&gt;&lt;/rect&gt;
  &lt;/mask&gt;
  &lt;g transform=&quot;translate(10 288) rotate(0 162.49435688645127 -4.9307858685293695)&quot;&gt;
    &lt;text x=&quot;106.36991882324219&quot; y=&quot;17.619999999999997&quot; font-family=&quot;Excalifont, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;1. Hi, I am Bob.&lt;/text&gt;
    &lt;text x=&quot;106.36991882324219&quot; y=&quot;42.62&quot; font-family=&quot;Excalifont, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;Here&apos;s my Public key ;)&lt;/text&gt;
  &lt;/g&gt;
  &lt;g stroke-linecap=&quot;round&quot;&gt;
    &lt;g transform=&quot;translate(76.36991882324219 125) rotate(0 15 -40.5)&quot;&gt;
      &lt;path d=&quot;M-1.41 1.43 C3.9 -11.98, 24.94 -68.37, 30.48 -82.52&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2.5&quot; fill=&quot;none&quot; stroke-dasharray=&quot;1.5 8&quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
  &lt;/g&gt;
  &lt;mask&gt;&lt;/mask&gt;
  &lt;g mask=&quot;url(#mask-2hNiEKLoLuIfLre3IjNH6)&quot; stroke-linecap=&quot;round&quot;&gt;
    &lt;g transform=&quot;translate(113.36991882324219 146) rotate(0 107.5 116.5)&quot;&gt;
      &lt;path d=&quot;M-0.34 0.71 C34.39 9.18, 173.61 13.34, 209.47 51.87 C245.33 90.4, 214.02 201.85, 214.83 231.91 M1.68 0.04 C36.11 9.22, 172.86 14.57, 208.24 53.34 C243.62 92.11, 212.97 202.72, 213.97 232.66&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
    &lt;g transform=&quot;translate(113.36991882324219 146) rotate(0 107.5 116.5)&quot;&gt;
      &lt;path d=&quot;M208.09 208.36 C211.79 217, 212.69 227.12, 213.97 232.66 M208.09 208.36 C209.18 212.73, 210.05 217.7, 213.97 232.66&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
    &lt;g transform=&quot;translate(113.36991882324219 146) rotate(0 107.5 116.5)&quot;&gt;
      &lt;path d=&quot;M225.09 210.27 C222.11 218.12, 216.36 227.48, 213.97 232.66 M225.09 210.27 C222.63 214.13, 219.94 218.71, 213.97 232.66&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
  &lt;/g&gt;
  &lt;mask id=&quot;mask-2hNiEKLoLuIfLre3IjNH6&quot;&gt;
    &lt;rect x=&quot;0&quot; y=&quot;0&quot; fill=&quot;#fff&quot; width=&quot;428.3699188232422&quot; height=&quot;479&quot;&gt;&lt;/rect&gt;
    &lt;rect x=&quot;221.760009765625&quot; y=&quot;173&quot; fill=&quot;#000&quot; width=&quot;203.21981811523438&quot; height=&quot;50&quot; opacity=&quot;1&quot;&gt;&lt;/rect&gt;
  &lt;/mask&gt;
  &lt;g transform=&quot;translate(221.760009765625 173) rotate(0 4.798357762804699 89.34597921169365)&quot;&gt;
    &lt;text x=&quot;101.60990905761719&quot; y=&quot;17.619999999999997&quot; font-family=&quot;Excalifont, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;2. Here&apos;s the &lt;/text&gt;
    &lt;text x=&quot;101.60990905761719&quot; y=&quot;42.62&quot; font-family=&quot;Excalifont, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;encrypted message :)&lt;/text&gt;
  &lt;/g&gt;
  &lt;g transform=&quot;translate(676.3699188232422 102) rotate(0 9.659996032714844 12.5)&quot;&gt;
    &lt;text x=&quot;0&quot; y=&quot;17.619999999999997&quot; font-family=&quot;Excalifont, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;start&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;??&lt;/text&gt;
  &lt;/g&gt;
  &lt;g stroke-linecap=&quot;round&quot;&gt;
    &lt;g transform=&quot;translate(680.3699188232422 211) rotate(0 3 -38.5)&quot;&gt;
      &lt;path d=&quot;M0 0 C1 -12.83, 5 -64.17, 6 -77&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2.5&quot; fill=&quot;none&quot; stroke-dasharray=&quot;1.5 8&quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
  &lt;/g&gt;
  &lt;mask&gt;&lt;/mask&gt;
&lt;/svg&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;You see the problem we have in our hands right? Just obtaining a public key isn&apos;t sufficient.
We need a trusted entity that can tie down the public key to a certain identity.
If the trusted entity states that it is indeed Bob&apos;s public key then for all intents and purposes that is indeed Bob&apos;s public key.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;inline-svg&quot; role=&quot;img&quot; aria-label=&quot;Diagram showing a trusted entity confirming Bob&amp;#039;s key&quot;&gt;&lt;svg version=&quot;1.1&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; viewBox=&quot;0 0 882.8548355102539 604.75&quot; style=&quot;max-height: 400px; width: 100%; height: auto;&quot;&gt;
  &lt;!-- svg-source:excalidraw --&gt;
  &lt;defs&gt;
    &lt;style class=&quot;style-fonts&quot;&gt;
      @font-face {
        font-family: Excalifont;
        src: url(data:font/woff2;base64,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);
      }
    &lt;/style&gt;
  &lt;/defs&gt;
  &lt;rect x=&quot;0&quot; y=&quot;0&quot; width=&quot;882.8548355102539&quot; height=&quot;604.75&quot; fill=&quot;none&quot;&gt;&lt;/rect&gt;
  &lt;g stroke-linecap=&quot;round&quot; transform=&quot;translate(161.14990997314453 310.75) rotate(0 40.5 23)&quot;&gt;
    &lt;path d=&quot;M11.5 0 C25.92 -0.96, 38.64 -1.07, 69.5 0 C76.41 -1.64, 77.87 6.55, 81 11.5 C83.41 15.09, 80.33 23.55, 81 34.5 C82.71 44.21, 78.91 49.02, 69.5 46 C57.47 45.23, 46.48 46.49, 11.5 46 C6.36 45.04, -3.38 39.69, 0 34.5 C-0.47 24.87, -0.85 13.46, 0 11.5 C0.97 7, 0.4 -1.56, 11.5 0&quot; stroke=&quot;none&quot; stroke-width=&quot;0&quot; fill=&quot;var(--color-good)&quot;&gt;&lt;/path&gt;
    &lt;path d=&quot;M11.5 0 C31.65 0.6, 47.93 0.56, 69.5 0 M11.5 0 C23.97 -0.37, 37.82 0.66, 69.5 0 M69.5 0 C78.13 -1.94, 81.78 4.73, 81 11.5 M69.5 0 C76.27 -1.85, 83.29 4, 81 11.5 M81 11.5 C81.5 15.66, 82.21 23.23, 81 34.5 M81 11.5 C80.53 17.81, 81.99 26.58, 81 34.5 M81 34.5 C81.57 43.24, 75.36 47.55, 69.5 46 M81 34.5 C79.42 43.25, 76.58 45.3, 69.5 46 M69.5 46 C50.01 45.25, 28.9 45.2, 11.5 46 M69.5 46 C47.59 45.54, 25.3 45.61, 11.5 46 M11.5 46 C4.87 46.94, 0.4 43.44, 0 34.5 M11.5 46 C2.38 46.32, -1.65 41.83, 0 34.5 M0 34.5 C-1.12 27.32, -1.06 20.53, 0 11.5 M0 34.5 C-0.11 28.74, -0.68 25.57, 0 11.5 M0 11.5 C0.96 2.95, 4.5 1.34, 11.5 0 M0 11.5 C-1.76 2.15, 2.45 1.2, 11.5 0&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;
  &lt;/g&gt;
  &lt;g transform=&quot;translate(179.65992736816406 321.25) rotate(0 21.98998260498047 12.5)&quot;&gt;
    &lt;text x=&quot;21.98998260498047&quot; y=&quot;17.619999999999997&quot; font-family=&quot;Excalifont, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;Alice&lt;/text&gt;
  &lt;/g&gt;
  &lt;g stroke-linecap=&quot;round&quot; transform=&quot;translate(163.14990997314453 559.75) rotate(0 36 17.5)&quot;&gt;
    &lt;path d=&quot;M8.75 0 C22.63 0.41, 39.68 -0.51, 63.25 0 C67.05 -0.78, 72.33 6.42, 72 8.75 C72.63 12.78, 71.13 16.96, 72 26.25 C73.79 28.57, 69.37 36.4, 63.25 35 C50.12 35.65, 40.78 35.15, 8.75 35 C4.98 38.54, -0.49 29.63, 0 26.25 C3.13 18.32, 2.92 16.44, 0 8.75 C1.71 5.75, 6.39 -1.47, 8.75 0&quot; stroke=&quot;none&quot; stroke-width=&quot;0&quot; fill=&quot;var(--color-bad)&quot;&gt;&lt;/path&gt;
    &lt;path d=&quot;M8.75 0 C23.52 -1.67, 40.93 0.05, 63.25 0 M8.75 0 C24.95 -1.16, 41.75 -1.28, 63.25 0 M63.25 0 C71.02 -1.09, 73.4 3.37, 72 8.75 M63.25 0 C71.31 -0.82, 69.89 3.23, 72 8.75 M72 8.75 C73.47 12.34, 72.56 18.49, 72 26.25 M72 8.75 C71.53 14.47, 72.6 20, 72 26.25 M72 26.25 C72.37 33.38, 68.74 34.12, 63.25 35 M72 26.25 C72.69 31.47, 70.69 36.31, 63.25 35 M63.25 35 C47.07 34.88, 29.24 33.64, 8.75 35 M63.25 35 C49.76 35.23, 36.51 34.94, 8.75 35 M8.75 35 C2.42 35.11, -0.4 31.91, 0 26.25 M8.75 35 C3.45 36.5, -1.29 30.04, 0 26.25 M0 26.25 C0.69 21.53, 0.37 13.4, 0 8.75 M0 26.25 C-0.7 20.47, 0.59 13.45, 0 8.75 M0 8.75 C0.39 1.44, 2.04 -1.58, 8.75 0 M0 8.75 C1.45 3.22, 4.28 1.9, 8.75 0&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;
  &lt;/g&gt;
  &lt;g transform=&quot;translate(180.82992553710938 564.75) rotate(0 18.319984436035156 12.5)&quot;&gt;
    &lt;text x=&quot;18.319984436035156&quot; y=&quot;17.619999999999997&quot; font-family=&quot;Excalifont, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;Eve&lt;/text&gt;
  &lt;/g&gt;
  &lt;g mask=&quot;url(#mask-8lEV4kGAKNamQtwrbMAgV)&quot; stroke-linecap=&quot;round&quot;&gt;
    &lt;g transform=&quot;translate(199.20817677740376 555.25) rotate(0 0.778829333572105 -97.5)&quot;&gt;
      &lt;path d=&quot;M0.61 -0.75 C0.88 -33.21, 1.22 -161.99, 1.57 -194.47 M-0.52 1.47 C-0.42 -31.38, 0.11 -163.63, 0.62 -196.32&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
    &lt;g transform=&quot;translate(199.20817677740376 555.25) rotate(0 0.778829333572105 -97.5)&quot;&gt;
      &lt;path d=&quot;M8.96 -172.75 C5.16 -179.74, 4.8 -184.91, 0.62 -196.32 M8.96 -172.75 C6.99 -178.74, 5.45 -183.44, 0.62 -196.32&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
    &lt;g transform=&quot;translate(199.20817677740376 555.25) rotate(0 0.778829333572105 -97.5)&quot;&gt;
      &lt;path d=&quot;M-8.14 -172.91 C-6.83 -179.94, -2.08 -185.05, 0.62 -196.32 M-8.14 -172.91 C-5.91 -179, -3.24 -183.65, 0.62 -196.32&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
  &lt;/g&gt;
  &lt;mask id=&quot;mask-8lEV4kGAKNamQtwrbMAgV&quot;&gt;
    &lt;rect x=&quot;0&quot; y=&quot;0&quot; fill=&quot;#fff&quot; width=&quot;300.765835444548&quot; height=&quot;850.25&quot;&gt;&lt;/rect&gt;
    &lt;rect x=&quot;97.03709308607358&quot; y=&quot;432.75&quot; fill=&quot;#000&quot; width=&quot;205.8998260498047&quot; height=&quot;50&quot; opacity=&quot;1&quot;&gt;&lt;/rect&gt;
  &lt;/mask&gt;
  &lt;g transform=&quot;translate(97.03709308607358 432.75) rotate(0 102.69265123431097 25.07275146386587)&quot;&gt;
    &lt;text x=&quot;102.94991302490234&quot; y=&quot;17.619999999999997&quot; font-family=&quot;Excalifont, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;1. here&apos;s Bob&apos;s public &lt;/text&gt;
    &lt;text x=&quot;102.94991302490234&quot; y=&quot;42.62&quot; font-family=&quot;Excalifont, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;key ;)&lt;/text&gt;
  &lt;/g&gt;
  &lt;g stroke-linecap=&quot;round&quot; transform=&quot;translate(82.64990997314453 10.25) rotate(0 129.5 31.5)&quot;&gt;
    &lt;path d=&quot;M15.75 0 C108.98 2.04, 196.71 4.55, 243.25 0 C253.03 -2.57, 257.92 2.58, 259 15.75 C255.99 26.81, 258.08 28.57, 259 47.25 C258.37 56.28, 254.15 60.63, 243.25 63 C185.5 67.71, 126.29 64.61, 15.75 63 C6.17 60.87, -3.41 56.49, 0 47.25 C-1.99 36.93, 2.36 27.46, 0 15.75 C2.37 6.34, 2.13 -1.55, 15.75 0&quot; stroke=&quot;none&quot; stroke-width=&quot;0&quot; fill=&quot;var(--color-good-2)&quot;&gt;&lt;/path&gt;
    &lt;path d=&quot;M15.75 0 C101.83 -2.52, 186.21 -0.6, 243.25 0 M15.75 0 C103.43 0.02, 192.36 0.55, 243.25 0 M243.25 0 C255.48 -0.58, 259.43 4.96, 259 15.75 M243.25 0 C254.35 -0.99, 257.61 4.55, 259 15.75 M259 15.75 C260.05 26.72, 259.14 36.92, 259 47.25 M259 15.75 C258.49 27.83, 260.09 39.96, 259 47.25 M259 47.25 C260.64 57.6, 255.61 62.46, 243.25 63 M259 47.25 C256.82 55.89, 254.62 60.96, 243.25 63 M243.25 63 C153.92 61.49, 60.09 62.1, 15.75 63 M243.25 63 C185.7 64.17, 129.33 64.83, 15.75 63 M15.75 63 C5.5 64.65, -0.35 58.24, 0 47.25 M15.75 63 C3.24 61.64, -1.13 56.75, 0 47.25 M0 47.25 C1.08 38.07, 0.6 28.9, 0 15.75 M0 47.25 C0.41 39.35, -0.15 29.99, 0 15.75 M0 15.75 C0.14 4.65, 4.5 0.08, 15.75 0 M0 15.75 C-2.02 4.53, 4.91 1.94, 15.75 0&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;
  &lt;/g&gt;
  &lt;g transform=&quot;translate(110.57000732421875 29.25) rotate(0 101.57990264892578 12.5)&quot;&gt;
    &lt;text x=&quot;101.57990264892578&quot; y=&quot;17.619999999999997&quot; font-family=&quot;Excalifont, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;Trusted Entity ◉_◉&lt;/text&gt;
  &lt;/g&gt;
  &lt;g mask=&quot;url(#mask-WPi2H4RF4eeVlB2FNAhgU)&quot; stroke-linecap=&quot;round&quot;&gt;
    &lt;g transform=&quot;translate(157.54424497096238 331.25) rotate(0 -20.447167498908925 -127.34402107046304)&quot;&gt;
      &lt;path d=&quot;M0.77 -0.14 C-6.05 -23.85, -37.63 -100.42, -40.29 -143.04 C-42.94 -185.66, -19 -237.32, -15.17 -255.88 M-0.28 -1.26 C-7.26 -24.7, -38.41 -99.2, -40.92 -141.52 C-43.43 -183.84, -19.23 -236.59, -15.34 -255.18&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
    &lt;g transform=&quot;translate(157.54424497096238 331.25) rotate(0 -20.447167498908925 -127.34402107046304)&quot;&gt;
      &lt;path d=&quot;M-14.17 -230.21 C-14.65 -237.99, -14.89 -245.91, -15.34 -255.18 M-14.17 -230.21 C-13.88 -235.82, -13.56 -239.37, -15.34 -255.18&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
    &lt;g transform=&quot;translate(157.54424497096238 331.25) rotate(0 -20.447167498908925 -127.34402107046304)&quot;&gt;
      &lt;path d=&quot;M-30.49 -235.3 C-25.26 -241.39, -19.75 -247.52, -15.34 -255.18 M-30.49 -235.3 C-26.97 -239.94, -23.37 -242.46, -15.34 -255.18&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
  &lt;/g&gt;
  &lt;mask id=&quot;mask-WPi2H4RF4eeVlB2FNAhgU&quot;&gt;
    &lt;rect x=&quot;0&quot; y=&quot;0&quot; fill=&quot;#fff&quot; width=&quot;298.43857996878023&quot; height=&quot;685.9380421409261&quot;&gt;&lt;/rect&gt;
    &lt;rect x=&quot;10&quot; y=&quot;163.25&quot; fill=&quot;#000&quot; width=&quot;213.29981994628906&quot; height=&quot;50&quot; opacity=&quot;1&quot;&gt;&lt;/rect&gt;
  &lt;/mask&gt;
  &lt;g transform=&quot;translate(10 163.25) rotate(0 127.37938165589259 39.991849511402265)&quot;&gt;
    &lt;text x=&quot;106.64990997314453&quot; y=&quot;17.619999999999997&quot; font-family=&quot;Excalifont, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;2. Hey is this actually&lt;/text&gt;
    &lt;text x=&quot;106.64990997314453&quot; y=&quot;42.62&quot; font-family=&quot;Excalifont, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;Bob&apos;s public Key?&lt;/text&gt;
  &lt;/g&gt;
  &lt;g mask=&quot;url(#mask-Tr5a6oLq2TEzBHvRCRt9-)&quot; stroke-linecap=&quot;round&quot;&gt;
    &lt;g transform=&quot;translate(278.9680967979508 75.25000000000003) rotate(0 10.181813175193724 126.99999999999993)&quot;&gt;
      &lt;path d=&quot;M0.52 -0.65 C8.94 18.67, 54.52 74.47, 49.64 117 C44.75 159.53, -15.7 231.89, -28.79 254.53 M-0.67 1.62 C7.67 21.66, 53.44 76.73, 48.67 118.54 C43.9 160.35, -16.43 230, -29.28 252.46&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
    &lt;g transform=&quot;translate(278.9680967979508 75.25000000000003) rotate(0 10.181813175193724 126.99999999999993)&quot;&gt;
      &lt;path d=&quot;M-22.84 228.31 C-25.14 233.67, -25.5 240.03, -29.28 252.46 M-22.84 228.31 C-25.42 237.44, -26.35 245.34, -29.28 252.46&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
    &lt;g transform=&quot;translate(278.9680967979508 75.25000000000003) rotate(0 10.181813175193724 126.99999999999993)&quot;&gt;
      &lt;path d=&quot;M-8.82 238.1 C-14.35 241.33, -17.85 245.5, -29.28 252.46 M-8.82 238.1 C-16.25 243.72, -22.01 248.25, -29.28 252.46&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
  &lt;/g&gt;
  &lt;mask id=&quot;mask-Tr5a6oLq2TEzBHvRCRt9-&quot;&gt;
    &lt;rect x=&quot;0&quot; y=&quot;0&quot; fill=&quot;#fff&quot; width=&quot;457.9680967979508&quot; height=&quot;429.2499999999999&quot;&gt;&lt;/rect&gt;
    &lt;rect x=&quot;289.62994384765625&quot; y=&quot;179.74999999999997&quot; fill=&quot;#000&quot; width=&quot;78.03993225097656&quot; height=&quot;25&quot; opacity=&quot;1&quot;&gt;&lt;/rect&gt;
  &lt;/mask&gt;
  &lt;g transform=&quot;translate(289.62994384765625 179.75) rotate(0 -0.29983633351082517 22.439221984147977)&quot;&gt;
    &lt;text x=&quot;39.01996612548828&quot; y=&quot;17.619999999999997&quot; font-family=&quot;Excalifont, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;3. Nope!&lt;/text&gt;
  &lt;/g&gt;
  &lt;g stroke-linecap=&quot;round&quot; transform=&quot;translate(659.9648818969727 310.5) rotate(0 40.5 23)&quot;&gt;
    &lt;path d=&quot;M11.5 0 C24.3 -3.24, 33.67 -3.07, 69.5 0 C75.9 -1.32, 82.55 3.15, 81 11.5 C84.65 21.49, 79.37 27.04, 81 34.5 C80.49 41.69, 74.61 46.35, 69.5 46 C51.44 49.76, 33.2 44.67, 11.5 46 C7.19 48.94, -0.52 41.83, 0 34.5 C3.07 25.77, 1.19 21.79, 0 11.5 C-0.43 1.07, 0.59 -0.45, 11.5 0&quot; stroke=&quot;none&quot; stroke-width=&quot;0&quot; fill=&quot;var(--color-good)&quot;&gt;&lt;/path&gt;
    &lt;path d=&quot;M11.5 0 C29.93 1.1, 49.06 -1.16, 69.5 0 M11.5 0 C23.95 -1.01, 35.58 0.09, 69.5 0 M69.5 0 C76.87 -1.18, 82.73 4.54, 81 11.5 M69.5 0 C77.78 -1.98, 78.99 5.44, 81 11.5 M81 11.5 C79.08 15.97, 82.12 20.81, 81 34.5 M81 11.5 C81.02 16.96, 81.74 22.14, 81 34.5 M81 34.5 C79.59 41.36, 75.55 44.11, 69.5 46 M81 34.5 C80.28 41.74, 77.51 44.28, 69.5 46 M69.5 46 C56.93 48.11, 41.1 44.62, 11.5 46 M69.5 46 C53.2 46.04, 36.39 46.03, 11.5 46 M11.5 46 C3.79 44.46, -0.22 41.43, 0 34.5 M11.5 46 C2.41 46.61, -0.9 40.95, 0 34.5 M0 34.5 C-1.56 27.79, 0.45 23.92, 0 11.5 M0 34.5 C0.41 27.82, 0.07 21.28, 0 11.5 M0 11.5 C-0.07 2.03, 3.74 1.37, 11.5 0 M0 11.5 C-0.56 4.83, 3.44 0.29, 11.5 0&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;
  &lt;/g&gt;
  &lt;g transform=&quot;translate(678.4748992919922 321) rotate(0 21.98998260498047 12.5)&quot;&gt;
    &lt;text x=&quot;21.98998260498047&quot; y=&quot;17.619999999999997&quot; font-family=&quot;Excalifont, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;Alice&lt;/text&gt;
  &lt;/g&gt;
  &lt;g stroke-linecap=&quot;round&quot; transform=&quot;translate(661.9648818969727 559.5) rotate(0 36 17.5)&quot;&gt;
    &lt;path d=&quot;M8.75 0 C19.05 -0.51, 33.44 0.13, 63.25 0 C70.61 1.42, 75.32 6.4, 72 8.75 C71.39 14.61, 69.61 21.61, 72 26.25 C71.8 31.11, 70.35 34.02, 63.25 35 C45.13 37.48, 19.76 34.2, 8.75 35 C1.34 34.22, -0.68 35.06, 0 26.25 C-0.48 19.96, -2.94 18.11, 0 8.75 C3.26 5.5, -0.22 0.63, 8.75 0&quot; stroke=&quot;none&quot; stroke-width=&quot;0&quot; fill=&quot;var(--color-good)&quot;&gt;&lt;/path&gt;
    &lt;path d=&quot;M8.75 0 C27.16 0.96, 49.63 0.62, 63.25 0 M8.75 0 C20.27 -0.72, 32.94 0.22, 63.25 0 M63.25 0 C69.62 -1.72, 70.25 4.31, 72 8.75 M63.25 0 C67.71 -1.59, 70.7 0.89, 72 8.75 M72 8.75 C70.75 14.72, 71.41 17.06, 72 26.25 M72 8.75 C71.47 14.26, 71.38 19.64, 72 26.25 M72 26.25 C71.38 31.71, 69.38 33.5, 63.25 35 M72 26.25 C70.45 31.17, 71.08 36.07, 63.25 35 M63.25 35 C42.38 36.4, 19.83 35.87, 8.75 35 M63.25 35 C43.56 34.56, 23.8 34.95, 8.75 35 M8.75 35 C1.68 35.53, -0.79 31.02, 0 26.25 M8.75 35 C2.04 34.85, -0.33 30.28, 0 26.25 M0 26.25 C-0.55 22.84, 1.41 17.96, 0 8.75 M0 26.25 C-0.07 20.99, -0.08 17.91, 0 8.75 M0 8.75 C-0.49 3.78, 2.58 0.25, 8.75 0 M0 8.75 C-2.24 1.56, 3.1 0.66, 8.75 0&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;
  &lt;/g&gt;
  &lt;g transform=&quot;translate(678.8049011230469 564.5) rotate(0 19.15998077392578 12.5)&quot;&gt;
    &lt;text x=&quot;19.15998077392578&quot; y=&quot;17.619999999999997&quot; font-family=&quot;Excalifont, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;Bob&lt;/text&gt;
  &lt;/g&gt;
  &lt;g mask=&quot;url(#mask-KZClSA-nuAqqiTeDPl23w)&quot; stroke-linecap=&quot;round&quot;&gt;
    &lt;g transform=&quot;translate(698.023148701232 554) rotate(0 0.7788293335720482 -97.5)&quot;&gt;
      &lt;path d=&quot;M0.23 -1.03 C0.33 -33.54, 0.83 -162.27, 1.02 -194.71 M-1.11 1.04 C-1.25 -31.87, -0.47 -164.05, -0.2 -196.68&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
    &lt;g transform=&quot;translate(698.023148701232 554) rotate(0 0.7788293335720482 -97.5)&quot;&gt;
      &lt;path d=&quot;M8.19 -173.13 C3.58 -181.93, 2.96 -189.27, -0.2 -196.68 M8.19 -173.13 C6.23 -179.64, 3.07 -183.75, -0.2 -196.68&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
    &lt;g transform=&quot;translate(698.023148701232 554) rotate(0 0.7788293335720482 -97.5)&quot;&gt;
      &lt;path d=&quot;M-8.91 -173.25 C-7.76 -182.04, -2.63 -189.34, -0.2 -196.68 M-8.91 -173.25 C-6.75 -179.78, -5.79 -183.87, -0.2 -196.68&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
  &lt;/g&gt;
  &lt;mask id=&quot;mask-KZClSA-nuAqqiTeDPl23w&quot;&gt;
    &lt;rect x=&quot;0&quot; y=&quot;0&quot; fill=&quot;#fff&quot; width=&quot;799.5808073683762&quot; height=&quot;849&quot;&gt;&lt;/rect&gt;
    &lt;rect x=&quot;595.8520650099017&quot; y=&quot;431.5&quot; fill=&quot;#000&quot; width=&quot;205.8998260498047&quot; height=&quot;50&quot; opacity=&quot;1&quot;&gt;&lt;/rect&gt;
  &lt;/mask&gt;
  &lt;g transform=&quot;translate(595.8520650099017 431.5) rotate(0 102.120928780094 24.678410247778515)&quot;&gt;
    &lt;text x=&quot;102.94991302490234&quot; y=&quot;17.619999999999997&quot; font-family=&quot;Excalifont, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;1. here&apos;s Bob&apos;s public &lt;/text&gt;
    &lt;text x=&quot;102.94991302490234&quot; y=&quot;42.62&quot; font-family=&quot;Excalifont, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;key :)&lt;/text&gt;
  &lt;/g&gt;
  &lt;g stroke-linecap=&quot;round&quot; transform=&quot;translate(581.4648818969727 10) rotate(0 129.5 31.5)&quot;&gt;
    &lt;path d=&quot;M15.75 0 C94.79 -4.92, 170.05 -3.82, 243.25 0 C253.27 -2.55, 259.35 5.05, 259 15.75 C262.59 22.2, 257.5 36.32, 259 47.25 C261.94 57.23, 253.41 61.43, 243.25 63 C177.52 66.83, 115.83 65.52, 15.75 63 C2.49 59.76, -0.45 61.01, 0 47.25 C0.46 37.4, -0.92 25.16, 0 15.75 C-1.87 2.47, 5.26 -0.23, 15.75 0&quot; stroke=&quot;none&quot; stroke-width=&quot;0&quot; fill=&quot;var(--color-good-2)&quot;&gt;&lt;/path&gt;
    &lt;path d=&quot;M15.75 0 C72.89 1.76, 132.65 0.74, 243.25 0 M15.75 0 C63.92 -1.94, 112.63 -2.1, 243.25 0 M243.25 0 C252.69 1.27, 257.27 3.69, 259 15.75 M243.25 0 C255.91 -0.92, 258.55 6.05, 259 15.75 M259 15.75 C258.32 25.24, 257.25 37.34, 259 47.25 M259 15.75 C258.38 24.22, 259.92 33.96, 259 47.25 M259 47.25 C260.61 56.36, 251.87 62.86, 243.25 63 M259 47.25 C261.2 55.49, 255.34 64.4, 243.25 63 M243.25 63 C153.88 62.77, 66.51 61.9, 15.75 63 M243.25 63 C168.64 61.92, 94.56 61.3, 15.75 63 M15.75 63 C4.56 63.43, 1.47 57.17, 0 47.25 M15.75 63 C6.87 64.9, 1.32 56.73, 0 47.25 M0 47.25 C-1.57 36.97, 1.61 26.4, 0 15.75 M0 47.25 C-0.92 35.85, 0.13 25.92, 0 15.75 M0 15.75 C-1.75 4.5, 3.59 -0.71, 15.75 0 M0 15.75 C-0.85 6.24, 4.81 0.97, 15.75 0&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;
  &lt;/g&gt;
  &lt;g transform=&quot;translate(609.3849792480469 29) rotate(0 101.57990264892578 12.5)&quot;&gt;
    &lt;text x=&quot;101.57990264892578&quot; y=&quot;17.619999999999997&quot; font-family=&quot;Excalifont, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;Trusted Entity ◉_◉&lt;/text&gt;
  &lt;/g&gt;
  &lt;g mask=&quot;url(#mask-qRstCaQuIoaHce6jOloxd)&quot; stroke-linecap=&quot;round&quot;&gt;
    &lt;g transform=&quot;translate(656.3592168947905 331) rotate(0 -20.447167498908925 -127.34402107046304)&quot;&gt;
      &lt;path d=&quot;M0.32 -1.03 C-6.84 -24.8, -39.05 -99.75, -41.94 -142.16 C-44.83 -184.58, -21.18 -236.59, -17.01 -255.52 M-0.97 1.04 C-7.87 -23.09, -37.53 -101.23, -39.78 -143.85 C-42.03 -186.46, -18.28 -236.08, -14.5 -254.64&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
    &lt;g transform=&quot;translate(656.3592168947905 331) rotate(0 -20.447167498908925 -127.34402107046304)&quot;&gt;
      &lt;path d=&quot;M-13.38 -229.66 C-15.62 -241.05, -12.94 -250.15, -14.5 -254.64 M-13.38 -229.66 C-14.03 -234.8, -14.62 -241.98, -14.5 -254.64&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
    &lt;g transform=&quot;translate(656.3592168947905 331) rotate(0 -20.447167498908925 -127.34402107046304)&quot;&gt;
      &lt;path d=&quot;M-29.69 -234.78 C-25.61 -244.24, -16.63 -251.36, -14.5 -254.64 M-29.69 -234.78 C-26.6 -238.6, -23.43 -244.59, -14.5 -254.64&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
  &lt;/g&gt;
  &lt;mask id=&quot;mask-qRstCaQuIoaHce6jOloxd&quot;&gt;
    &lt;rect x=&quot;0&quot; y=&quot;0&quot; fill=&quot;#fff&quot; width=&quot;797.2535518926084&quot; height=&quot;685.6880421409261&quot;&gt;&lt;/rect&gt;
    &lt;rect x=&quot;508.8149719238281&quot; y=&quot;163&quot; fill=&quot;#000&quot; width=&quot;213.29981994628906&quot; height=&quot;50&quot; opacity=&quot;1&quot;&gt;&lt;/rect&gt;
  &lt;/mask&gt;
  &lt;g transform=&quot;translate(508.8149719238281 163) rotate(0 126.61088737480873 40.76147599714025)&quot;&gt;
    &lt;text x=&quot;106.64990997314453&quot; y=&quot;17.619999999999997&quot; font-family=&quot;Excalifont, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;2. Hey is this actually&lt;/text&gt;
    &lt;text x=&quot;106.64990997314453&quot; y=&quot;42.62&quot; font-family=&quot;Excalifont, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;Bob&apos;s public Key?&lt;/text&gt;
  &lt;/g&gt;
  &lt;g mask=&quot;url(#mask-3NEqLQ0xO07nAstSuTTD2)&quot; stroke-linecap=&quot;round&quot;&gt;
    &lt;g transform=&quot;translate(777.7830687217788 74) rotate(0 10.181813175193838 126.99999999999994)&quot;&gt;
      &lt;path d=&quot;M-0.72 -0.83 C7.62 18.36, 53.88 73.35, 49.01 115.95 C44.13 158.54, -16.73 231.91, -29.95 254.76 M1.1 1.35 C9.93 20.57, 56.72 75.02, 51.36 116.93 C46 158.84, -17.38 230.03, -31.05 252.82&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
    &lt;g transform=&quot;translate(777.7830687217788 74) rotate(0 10.181813175193838 126.99999999999994)&quot;&gt;
      &lt;path d=&quot;M-24.19 228.78 C-26.86 232.73, -28.7 237.91, -31.05 252.82 M-24.19 228.78 C-25.95 237.07, -29.58 246.57, -31.05 252.82&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
    &lt;g transform=&quot;translate(777.7830687217788 74) rotate(0 10.181813175193838 126.99999999999994)&quot;&gt;
      &lt;path d=&quot;M-10.34 238.82 C-16.03 240.55, -20.81 243.59, -31.05 252.82 M-10.34 238.82 C-17.06 243.35, -25.72 249.19, -31.05 252.82&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
  &lt;/g&gt;
  &lt;mask id=&quot;mask-3NEqLQ0xO07nAstSuTTD2&quot;&gt;
    &lt;rect x=&quot;0&quot; y=&quot;0&quot; fill=&quot;#fff&quot; width=&quot;956.7830687217788&quot; height=&quot;427.9999999999999&quot;&gt;&lt;/rect&gt;
    &lt;rect x=&quot;782.0749282836914&quot; y=&quot;178.5&quot; fill=&quot;#000&quot; width=&quot;90.7799072265625&quot; height=&quot;25&quot; opacity=&quot;1&quot;&gt;&lt;/rect&gt;
  &lt;/mask&gt;
  &lt;g transform=&quot;translate(782.0749282836914 178.5) rotate(0 6.0769998417013085 22.467764121293968)&quot;&gt;
    &lt;text x=&quot;45.38995361328125&quot; y=&quot;17.619999999999997&quot; font-family=&quot;Excalifont, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;Yes, it is!&lt;/text&gt;
  &lt;/g&gt;
&lt;/svg&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h2 id=&quot;certificate-authority&quot;&gt;Certificate Authority&lt;/h2&gt;
&lt;p&gt;On the web, Certificate Authorities (CA) are organizations that &lt;strong&gt;aim&lt;/strong&gt; to be such trusted entities.&lt;/p&gt;
&lt;p&gt;They do all the heavy lifting of verifying the identity and then issue a signed digital document called a &quot;Certificate&quot; which acts as proof of identity.&lt;/p&gt;
&lt;p&gt;When an unknown actor provides us with a certificate that was signed by a CA we trust, we can mathematically verify that the certificate was indeed certified by that CA and deem the certificate valid. This eliminates a massive burden off of us in individually verifying the identity of every single public key we deal with.
We trust one (or more) CAs and then get the benefit of having the thousands/millions of public keys identified.&lt;/p&gt;
&lt;p&gt;In our example above, Bob requests a certificate from the Trusted entity and then instead of providing a public key to Alice, he provides her with the signed certificate. Alice can then extract the public key from the certificate after verifying that the certificate is valid.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;inline-svg&quot; role=&quot;img&quot; aria-label=&quot;Diagram illustrating certificate issuance and validation flow&quot;&gt;&lt;svg version=&quot;1.1&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; viewBox=&quot;0 0 1046.5 576.996206303124&quot; style=&quot;max-height: 400px; width: 100%; height: auto;&quot;&gt;
  &lt;!-- svg-source:excalidraw --&gt;
  &lt;defs&gt;
    &lt;style class=&quot;style-fonts&quot;&gt;
      @font-face {
        font-family: Excalifont;
        src: url(data:font/woff2;base64,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);
      }
    &lt;/style&gt;
  &lt;/defs&gt;
  &lt;rect x=&quot;0&quot; y=&quot;0&quot; width=&quot;100%&quot; height=&quot;420&quot; fill=&quot;none&quot;&gt;&lt;/rect&gt;
  &lt;g stroke-linecap=&quot;round&quot; transform=&quot;translate(10 172.24620630312404) rotate(0 36 17.5)&quot;&gt;
    &lt;path d=&quot;M8.75 0 C19.05 -0.51, 33.44 0.13, 63.25 0 C70.61 1.42, 75.32 6.4, 72 8.75 C71.39 14.61, 69.61 21.61, 72 26.25 C71.8 31.11, 70.35 34.02, 63.25 35 C45.13 37.48, 19.76 34.2, 8.75 35 C1.34 34.22, -0.68 35.06, 0 26.25 C-0.48 19.96, -2.94 18.11, 0 8.75 C3.26 5.5, -0.22 0.63, 8.75 0&quot; stroke=&quot;none&quot; stroke-width=&quot;0&quot; fill=&quot;var(--color-good)&quot;&gt;&lt;/path&gt;
    &lt;path d=&quot;M8.75 0 C27.16 0.96, 49.63 0.62, 63.25 0 M8.75 0 C20.27 -0.72, 32.94 0.22, 63.25 0 M63.25 0 C69.62 -1.72, 70.25 4.31, 72 8.75 M63.25 0 C67.71 -1.59, 70.7 0.89, 72 8.75 M72 8.75 C70.75 14.72, 71.41 17.06, 72 26.25 M72 8.75 C71.47 14.26, 71.38 19.64, 72 26.25 M72 26.25 C71.38 31.71, 69.38 33.5, 63.25 35 M72 26.25 C70.45 31.17, 71.08 36.07, 63.25 35 M63.25 35 C42.38 36.4, 19.83 35.87, 8.75 35 M63.25 35 C43.56 34.56, 23.8 34.95, 8.75 35 M8.75 35 C1.68 35.53, -0.79 31.02, 0 26.25 M8.75 35 C2.04 34.85, -0.33 30.28, 0 26.25 M0 26.25 C-0.55 22.84, 1.41 17.96, 0 8.75 M0 26.25 C-0.07 20.99, -0.08 17.91, 0 8.75 M0 8.75 C-0.49 3.78, 2.58 0.25, 8.75 0 M0 8.75 C-2.24 1.56, 3.1 0.66, 8.75 0&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;
  &lt;/g&gt;
  &lt;g transform=&quot;translate(26.84001922607422 177.24620630312404) rotate(0 19.15998077392578 12.5)&quot;&gt;
    &lt;text x=&quot;19.15998077392578&quot; y=&quot;17.619999999999997&quot; font-family=&quot;Excalifont, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;Bob&lt;/text&gt;
  &lt;/g&gt;
  &lt;g stroke-linecap=&quot;round&quot; transform=&quot;translate(777.5 177.74620630312404) rotate(0 129.5 31.5)&quot;&gt;
    &lt;path d=&quot;M15.75 0 C94.79 -4.92, 170.05 -3.82, 243.25 0 C253.27 -2.55, 259.35 5.05, 259 15.75 C262.59 22.2, 257.5 36.32, 259 47.25 C261.94 57.23, 253.41 61.43, 243.25 63 C177.52 66.83, 115.83 65.52, 15.75 63 C2.49 59.76, -0.45 61.01, 0 47.25 C0.46 37.4, -0.92 25.16, 0 15.75 C-1.87 2.47, 5.26 -0.23, 15.75 0&quot; stroke=&quot;none&quot; stroke-width=&quot;0&quot; fill=&quot;var(--color-good-2)&quot;&gt;&lt;/path&gt;
    &lt;path d=&quot;M15.75 0 C72.89 1.76, 132.65 0.74, 243.25 0 M15.75 0 C63.92 -1.94, 112.63 -2.1, 243.25 0 M243.25 0 C252.69 1.27, 257.27 3.69, 259 15.75 M243.25 0 C255.91 -0.92, 258.55 6.05, 259 15.75 M259 15.75 C258.32 25.24, 257.25 37.34, 259 47.25 M259 15.75 C258.38 24.22, 259.92 33.96, 259 47.25 M259 47.25 C260.61 56.36, 251.87 62.86, 243.25 63 M259 47.25 C261.2 55.49, 255.34 64.4, 243.25 63 M243.25 63 C153.88 62.77, 66.51 61.9, 15.75 63 M243.25 63 C168.64 61.92, 94.56 61.3, 15.75 63 M15.75 63 C4.56 63.43, 1.47 57.17, 0 47.25 M15.75 63 C6.87 64.9, 1.32 56.73, 0 47.25 M0 47.25 C-1.57 36.97, 1.61 26.4, 0 15.75 M0 47.25 C-0.92 35.85, 0.13 25.92, 0 15.75 M0 15.75 C-1.75 4.5, 3.59 -0.71, 15.75 0 M0 15.75 C-0.85 6.24, 4.81 0.97, 15.75 0&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;
  &lt;/g&gt;
  &lt;g transform=&quot;translate(805.4200973510742 196.74620630312404) rotate(0 101.57990264892578 12.5)&quot;&gt;
    &lt;text x=&quot;101.57990264892578&quot; y=&quot;17.619999999999997&quot; font-family=&quot;Excalifont, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;Certificate Authority&lt;/text&gt;
  &lt;/g&gt;
  &lt;g mask=&quot;url(#mask-nX240NMzrp9ispd4fz74Z)&quot; stroke-linecap=&quot;round&quot;&gt;
    &lt;g transform=&quot;translate(882.8372505900488 245.99620630312404) rotate(0 -418.4511882164819 28)&quot;&gt;
      &lt;path d=&quot;M-0.67 0.48 C-77.83 15.01, -323.72 92.8, -463.11 87.48 C-602.5 82.17, -774.55 -11.75, -837.01 -31.4 M1.19 -0.31 C-75.59 13.82, -321.06 90.61, -460.9 85.62 C-600.74 80.62, -774.96 -10.58, -837.84 -30.3&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
    &lt;g transform=&quot;translate(882.8372505900488 245.99620630312404) rotate(0 -418.4511882164819 28)&quot;&gt;
      &lt;path d=&quot;M-812.85 -29.59 C-819.24 -31.53, -826.44 -30.32, -837.84 -30.3 M-812.85 -29.59 C-819.52 -30.24, -827.01 -30.71, -837.84 -30.3&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
    &lt;g transform=&quot;translate(882.8372505900488 245.99620630312404) rotate(0 -418.4511882164819 28)&quot;&gt;
      &lt;path d=&quot;M-819.15 -13.69 C-823.77 -20.17, -829.16 -23.55, -837.84 -30.3 M-819.15 -13.69 C-824.02 -18.6, -829.83 -23.31, -837.84 -30.3&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
  &lt;/g&gt;
  &lt;mask id=&quot;mask-nX240NMzrp9ispd4fz74Z&quot;&gt;
    &lt;rect x=&quot;0&quot; y=&quot;0&quot; fill=&quot;#fff&quot; width=&quot;1819.7396270230126&quot; height=&quot;463.99620630312404&quot;&gt;&lt;/rect&gt;
    &lt;rect x=&quot;312.0451354980469&quot; y=&quot;307.99620630312404&quot; fill=&quot;#000&quot; width=&quot;217.27978515625&quot; height=&quot;50&quot; opacity=&quot;1&quot;&gt;&lt;/rect&gt;
  &lt;/mask&gt;
  &lt;g transform=&quot;translate(312.0451354980469 307.99620630312404) rotate(0 152.4669469900257 -33.8305644060558)&quot;&gt;
    &lt;text x=&quot;108.639892578125&quot; y=&quot;17.619999999999997&quot; font-family=&quot;Excalifont, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;4. Sure Bob.&lt;/text&gt;
    &lt;text x=&quot;108.639892578125&quot; y=&quot;42.62&quot; font-family=&quot;Excalifont, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;Here&apos;s your certificate&lt;/text&gt;
  &lt;/g&gt;
  &lt;g stroke-linecap=&quot;round&quot; transform=&quot;translate(271.6850280761719 393.99620630312404) rotate(0 146 86.5)&quot;&gt;
    &lt;path d=&quot;M32 0 C87.15 3.11, 137.76 3.93, 260 0 C280.13 -2.09, 290.03 13.46, 292 32 C294.25 72.75, 291.78 111.97, 292 141 C293.33 160.12, 282.26 169.42, 260 173 C209.8 169.95, 162.07 168.28, 32 173 C8.88 172.33, -2.7 164.18, 0 141 C-2.08 104.14, 0.13 66.85, 0 32 C0.61 8.46, 14.2 1.45, 32 0&quot; stroke=&quot;none&quot; stroke-width=&quot;0&quot; fill=&quot;var(--color-good-3)&quot;&gt;&lt;/path&gt;
    &lt;path d=&quot;M32 0 C104.98 -1.03, 179.19 0.6, 260 0 M32 0 C91.98 -1.12, 151.19 -1.02, 260 0 M260 0 C279.91 0.02, 290.26 11.77, 292 32 M260 0 C279.43 -0.05, 290.65 8.45, 292 32 M292 32 C291.02 54.32, 290.18 80.99, 292 141 M292 32 C292.94 56.01, 292.01 81.6, 292 141 M292 141 C293.52 161.23, 282.64 172.91, 260 173 M292 141 C293.38 160.98, 282.23 171.89, 260 173 M260 173 C199.93 172.2, 135.75 171.03, 32 173 M260 173 C199.83 174.17, 137.54 173.89, 32 173 M32 173 C10.77 173.58, -0.65 161.12, 0 141 M32 173 C11.75 174.12, -1.11 164.02, 0 141 M0 141 C-0.83 104.83, 2.69 67.32, 0 32 M0 141 C0.18 108.63, 1.1 75.58, 0 32 M0 32 C1.48 10.8, 11.05 1.42, 32 0 M0 32 C-0.68 12.69, 8.7 -0.71, 32 0&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;
  &lt;/g&gt;
  &lt;g transform=&quot;translate(301.6850280761719 413.99620630312404) rotate(0 124.50252532958984 17.5)&quot;&gt;
    &lt;text x=&quot;0&quot; y=&quot;24.668&quot; font-family=&quot;Excalifont, Segoe UI Emoji&quot; font-size=&quot;28px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;start&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;Digital Certificate&lt;/text&gt;
  &lt;/g&gt;
  &lt;g transform=&quot;translate(357.6850280761719 474.99620630312404) rotate(0 72.12994384765625 25)&quot;&gt;
    &lt;text x=&quot;0&quot; y=&quot;17.619999999999997&quot; font-family=&quot;Excalifont, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;start&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;Public Key: 123&lt;/text&gt;
    &lt;text x=&quot;0&quot; y=&quot;42.62&quot; font-family=&quot;Excalifont, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;start&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;Subject: Bob&lt;/text&gt;
  &lt;/g&gt;
  &lt;g mask=&quot;url(#mask-FkzKZiL7uiIxOJJw6vacH)&quot; stroke-linecap=&quot;round&quot;&gt;
    &lt;g transform=&quot;translate(768.6850280761719 190.24022694850328) rotate(0 -341.9999999999999 -17.62201032268962)&quot;&gt;
      &lt;path d=&quot;M-1.04 0.97 C-60.06 -5.26, -241.45 -34.32, -355.16 -36.25 C-468.87 -38.18, -628.48 -14.8, -683.31 -10.63 M0.61 0.43 C-58.39 -5.17, -241.61 -33.58, -355.67 -35.24 C-469.72 -36.91, -629 -13.66, -683.71 -9.57&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
    &lt;g transform=&quot;translate(768.6850280761719 190.24022694850328) rotate(0 -341.9999999999999 -17.62201032268962)&quot;&gt;
      &lt;path d=&quot;M-661.24 -20.51 C-664.23 -17.01, -672.24 -14.97, -683.71 -9.57 M-661.24 -20.51 C-666.46 -18.26, -672.79 -15.66, -683.71 -9.57&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
    &lt;g transform=&quot;translate(768.6850280761719 190.24022694850328) rotate(0 -341.9999999999999 -17.62201032268962)&quot;&gt;
      &lt;path d=&quot;M-659.46 -3.5 C-662.99 -3.59, -671.36 -5.11, -683.71 -9.57 M-659.46 -3.5 C-665.13 -5.68, -671.91 -7.49, -683.71 -9.57&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
  &lt;/g&gt;
  &lt;mask id=&quot;mask-FkzKZiL7uiIxOJJw6vacH&quot;&gt;
    &lt;rect x=&quot;0&quot; y=&quot;0&quot; fill=&quot;#fff&quot; width=&quot;1552.6850280761716&quot; height=&quot;325.4842475938825&quot;&gt;&lt;/rect&gt;
    &lt;rect x=&quot;191.07522583007812&quot; y=&quot;129.99620630312404&quot; fill=&quot;#000&quot; width=&quot;443.2196044921875&quot; height=&quot;50&quot; opacity=&quot;1&quot;&gt;&lt;/rect&gt;
  &lt;/mask&gt;
  &lt;g transform=&quot;translate(191.07522583007812 129.99620630312404) rotate(0 236.05738948115157 42.5457573635693)&quot;&gt;
    &lt;text x=&quot;221.60980224609375&quot; y=&quot;17.619999999999997&quot; font-family=&quot;Excalifont, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;2. Prove that you have the private keys for &lt;/text&gt;
    &lt;text x=&quot;221.60980224609375&quot; y=&quot;42.62&quot; font-family=&quot;Excalifont, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;that public key. And prove that you&apos;re Bob&lt;/text&gt;
  &lt;/g&gt;
  &lt;g mask=&quot;url(#mask-6kNuHWduCFhIiNiVzhhYE)&quot; stroke-linecap=&quot;round&quot;&gt;
    &lt;g transform=&quot;translate(85.68502807617188 193.64539100328335) rotate(0 340 26.175407649920345)&quot;&gt;
      &lt;path d=&quot;M-0.8 0.87 C55 9.61, 221.6 49.79, 335.03 52.35 C448.46 54.91, 622.26 22.61, 679.79 16.25 M0.99 0.28 C57.13 9.24, 224.24 51.53, 337.23 53.89 C450.22 56.24, 621.69 20.94, 678.91 14.41&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
    &lt;g transform=&quot;translate(85.68502807617188 193.64539100328335) rotate(0 340 26.175407649920345)&quot;&gt;
      &lt;path d=&quot;M656.98 26.4 C665.45 21.09, 671.01 18.52, 678.91 14.41 M656.98 26.4 C665.77 21.22, 674.57 16.82, 678.91 14.41&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
    &lt;g transform=&quot;translate(85.68502807617188 193.64539100328335) rotate(0 340 26.175407649920345)&quot;&gt;
      &lt;path d=&quot;M654.4 9.5 C663.67 9.61, 670.07 12.44, 678.91 14.41 M654.4 9.5 C664.2 10.75, 673.97 12.77, 678.91 14.41&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
  &lt;/g&gt;
  &lt;mask id=&quot;mask-6kNuHWduCFhIiNiVzhhYE&quot;&gt;
    &lt;rect x=&quot;0&quot; y=&quot;0&quot; fill=&quot;#fff&quot; width=&quot;865.6850280761719&quot; height=&quot;345.99620630312404&quot;&gt;&lt;/rect&gt;
    &lt;rect x=&quot;295.5151138305664&quot; y=&quot;233.49620630312404&quot; fill=&quot;#000&quot; width=&quot;252.33982849121094&quot; height=&quot;25&quot; opacity=&quot;1&quot;&gt;&lt;/rect&gt;
  &lt;/mask&gt;
  &lt;g transform=&quot;translate(295.5151138305664 233.49620630312404) rotate(0 129.66528227925306 -12.713313221663043)&quot;&gt;
    &lt;text x=&quot;126.16991424560547&quot; y=&quot;17.619999999999997&quot; font-family=&quot;Excalifont, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;3. Sure, here&apos;s my ID card&lt;/text&gt;
  &lt;/g&gt;
  &lt;g mask=&quot;url(#mask-mg0PIlVbdIlhNke-jIsjG)&quot; stroke-linecap=&quot;round&quot;&gt;
    &lt;g transform=&quot;translate(82.82068698791682 162.02911411073075) rotate(0 352.97867976567136 -56.156010959168725)&quot;&gt;
      &lt;path d=&quot;M1.11 0.13 C52.88 -21.02, 193.7 -128.19, 311.15 -125.92 C428.6 -123.66, 640.07 -9.55, 705.8 13.7 M0.23 -0.85 C52.35 -22.4, 196.03 -130.02, 313.49 -127.46 C430.94 -124.91, 639.6 -9.11, 704.96 14.49&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
    &lt;g transform=&quot;translate(82.82068698791682 162.02911411073075) rotate(0 352.97867976567136 -56.156010959168725)&quot;&gt;
      &lt;path d=&quot;M680.02 12.75 C688.83 11.93, 699.05 13.46, 704.96 14.49 M680.02 12.75 C685.4 14.25, 691.23 13.88, 704.96 14.49&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
    &lt;g transform=&quot;translate(82.82068698791682 162.02911411073075) rotate(0 352.97867976567136 -56.156010959168725)&quot;&gt;
      &lt;path d=&quot;M686.97 -2.88 C693.51 1.75, 701.34 8.66, 704.96 14.49 M686.97 -2.88 C690.81 1.93, 695.13 4.93, 704.96 14.49&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
  &lt;/g&gt;
  &lt;mask id=&quot;mask-mg0PIlVbdIlhNke-jIsjG&quot;&gt;
    &lt;rect x=&quot;0&quot; y=&quot;0&quot; fill=&quot;#fff&quot; width=&quot;888.7780465192595&quot; height=&quot;403.7753204138548&quot;&gt;&lt;/rect&gt;
    &lt;rect x=&quot;166.15518188476562&quot; y=&quot;10&quot; fill=&quot;#000&quot; width=&quot;457.0596923828125&quot; height=&quot;50&quot; opacity=&quot;1&quot;&gt;&lt;/rect&gt;
  &lt;/mask&gt;
  &lt;g transform=&quot;translate(166.15518188476562 10.000000000000007) rotate(0 269.6837681902272 95.51948681740188)&quot;&gt;
    &lt;text x=&quot;228.52984619140625&quot; y=&quot;17.619999999999997&quot; font-family=&quot;Excalifont, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;1. Hey, I am Bob and here&apos;s my Public Key &quot;123&quot;&lt;/text&gt;
    &lt;text x=&quot;228.52984619140625&quot; y=&quot;42.62&quot; font-family=&quot;Excalifont, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;Can you please issue me a certificate?&lt;/text&gt;
  &lt;/g&gt;
&lt;/svg&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h3 id=&quot;digital-certificates&quot;&gt;Digital Certificates&lt;/h3&gt;
&lt;p&gt;In summary, a digital Certificate serves as a signed proof verifying that a public key belongs to a certain subject.
CAs are responsible for the creation, issuance, revocation, and management of Certificates.&lt;/p&gt;
&lt;h4 id=&quot;tls-certificates&quot;&gt;TLS Certificates&lt;/h4&gt;
&lt;p&gt;One of the most popular types of certificate is the TLS certificate where the subject is a domain name.
A domain owner must prove&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;his/her ownership over the domain&lt;/li&gt;
&lt;li&gt;ownership of the private key to the public key&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;to the CA.&lt;/p&gt;
&lt;p&gt;Below is a TLS certificate for my website (&lt;em&gt;stripped off for brevity&lt;/em&gt;).
You can see that the subject is set to &lt;code class=&quot;language-text&quot;&gt;adityathebe.com&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            0f:59:b4:d4:06:47:9a:1e:df:00:02:3b:48:6c:72:d5
        Signature Algorithm: ecdsa-with-SHA256
=====&gt;  Issuer: C=US, O=Cloudflare, Inc., CN=Cloudflare Inc ECC CA-3
        Validity
            Not Before: Feb 24 00:00:00 2024 GMT
            Not After : Dec 31 23:59:59 2024 GMT
=====&gt;  Subject: C=US, ST=California, L=San Francisco, O=Cloudflare, Inc., CN=adityathebe.com
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (256 bit)
=============&gt;    pub:
                    04:7d:2f:37:6a:b6:09:08:e4:00:18:54:6a:10:95:
                    25:c2:5a:09:a6:de:72:77:fe:ae:92:09:47:05:88:
                    de:f8:9a:89:0d:46:90:a8:ba:5b:03:69:88:32:12:
                    f5:ec:5a:42:51:7d:1e:93:60:d2:95:0d:5b:fa:fd:
                    b6:fc:64:e6:75
                ASN1 OID: prime256v1
                NIST CURVE: P-256
        X509v3 extensions:
            ...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The CA that signed and issued this certificate is Cloudflare Inc.&lt;/p&gt;
&lt;p&gt;When you visit my website over HTTPs, your browser is presented with this very certificate.
If your browser or OS trusts Cloudflare Inc as a CA then it can trust the certificate.
And if it doesn&apos;t, then it&apos;ll show a warning and probably not load the website at all.&lt;/p&gt;
&lt;h2 id=&quot;trust-store&quot;&gt;Trust store&lt;/h2&gt;
&lt;p&gt;Alright! So far we&apos;ve established the fact that CAs are entities that facilitate authenticity in public key cryptography.&lt;/p&gt;
&lt;p&gt;Now comes the question of which CAs to trust. Do you personally need to choose a certain bunch of CAs from a marketplace? Are there any popular well-trusted ones?&lt;/p&gt;
&lt;p&gt;Well, good news! The operating system you use has already done that for you. Additionally, web browsers also have selected their own set of CAs that they trust. These chosen set of trusted CAs are stored in a place called &lt;strong&gt;Truststore&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;If you&apos;re on Linux see the contents of &lt;code class=&quot;language-text&quot;&gt;/etc/ssl/certs/ca-certificates.crt&lt;/code&gt; for the list of root certificates.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token function&quot;&gt;cat&lt;/span&gt; /etc/ssl/certs/ca-certificates.crt &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;grep&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;BEGIN CERTIFICATE&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;wc&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-l&lt;/span&gt;
&lt;span class=&quot;token number&quot;&gt;148&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As you can see, on my Arch Linux machine there are &lt;code class=&quot;language-text&quot;&gt;148&lt;/code&gt; root certificates. On my Ubuntu server, there are &lt;code class=&quot;language-text&quot;&gt;137&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The set of CAs considered trustworthy isn&apos;t uniform across all OSs and web browsers.
For example: the CAs trusted by Google Chrome may not be trusted by Firefox and vice-versa.&lt;/p&gt;
&lt;p&gt;But why is that? Why is one CA trustworthy to one vendor but not to another?&lt;/p&gt;
&lt;h2 id=&quot;root-programs&quot;&gt;Root Programs&lt;/h2&gt;
&lt;p&gt;Each vendor has outlined a set of criteria for CAs to be considered trustworthy for them. This criteria is defined in a &lt;strong&gt;root program&lt;/strong&gt;. There are several major root programs:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://learn.microsoft.com/en-us/security/trusted-root/program-requirements&quot;&gt;Microsoft&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.apple.com/certificateauthority/ca_program.html&quot;&gt;Apple&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.chromium.org/Home/chromium-security/root-ca-policy/&quot;&gt;Chrome&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://wiki.mozilla.org/CA&quot;&gt;Mozilla&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id=&quot;supplementary-materials&quot;&gt;Supplementary Materials&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=5rT6fZUwhG8&quot;&gt;How digital certificates bind owners to their public key&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=x_I6Qc35PuQ&quot;&gt;Certificates and Certificate Authority Explained&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.checktls.com/showcas.html&quot;&gt;https://www.checktls.com/showcas.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;further-reading&quot;&gt;Further Reading&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Certificate_revocation&quot;&gt;Certificate Revocation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Chain_of_trust&quot;&gt;Chain of Trust&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[An overview of the gzip & zip file formats]]></title><description><![CDATA[This blog post explores the differences between gzip and zip, two popular file compression formats]]></description><link>https://www.adityathebe.com/gzip-zip-overview</link><guid isPermaLink="false">https://www.adityathebe.com/gzip-zip-overview</guid><pubDate>Sat, 20 Jul 2024 12:30:00 GMT</pubDate><content:encoded>&lt;p&gt;I just finished listening to an episode of the ShipIt podcast - &lt;a href=&quot;https://changelog.com/shipit/105&quot;&gt;Tars all the way down&lt;/a&gt; -
where Jon “gzip enthusiast” Johnson talks about gzip, zip &amp;#x26; Deflate. The episode goes on to talk about efficiently &amp;#x26; randomly accessing
the bits of compressed data from container images.&lt;/p&gt;
&lt;p&gt;This episode led me to scratch my long outstanding itch to understand - or at least acquaint myself with - the popular compression tools.
Naturally, this post isn&apos;t going to be anything in-depth. I took a peek at the compression world and boy it&apos;s deep.&lt;/p&gt;
&lt;p&gt;In the Linux world gzip along with tar is extremely popular. It wouldn&apos;t be inaccurate, in my opinion, to say that gzip is the
defacto compression tool &amp;#x26; tar is the defacto archive format. It&apos;s the format most software is distributed.&lt;/p&gt;
&lt;p&gt;On the other hand, on Windows, it&apos;s probably zip.&lt;/p&gt;
&lt;p&gt;Let&apos;s explore their differences.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;gzip and zip are file formats, not compression algorithms. They can also mean the command line tools.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;gzip can only compress one file at a time. So, how do we gzip a directory then? That&apos;s where you need an archiving tool
to first archive all the files and directories inside the directory into a single file - the archive. And then the archive is compressed.
As gzip compresses the archive as a single unit, it can optimize better and produce a more efficient smaller output.&lt;/p&gt;
&lt;p&gt;In the words of the creator himself&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;tar + gzip compresses better than zip, since the compression of the next file can use history from the previous file (sometimes referred to as a &quot;solid&quot; archive). zip can only compress files individually.&lt;/p&gt;
&lt;p&gt;-&gt; See comments: &lt;a href=&quot;https://stackoverflow.com/a/20765054/6199444&quot;&gt;https://stackoverflow.com/a/20765054/6199444&lt;/a&gt;&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;span class=&quot;inline-svg&quot; role=&quot;img&quot; aria-label=&quot;GZIP&quot;&gt;&lt;svg version=&quot;1.1&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; viewBox=&quot;0 0 501.5937499999999 328&quot; width=&quot;100%&quot; height=&quot;250&quot;&gt;
  &lt;!-- svg-source:excalidraw --&gt;

  &lt;defs&gt;
    &lt;style class=&quot;style-fonts&quot;&gt;
      @font-face {
        font-family: Excalifont;
        src: url(data:font/woff2;base64,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);
          }
    &lt;/style&gt;
    
  &lt;/defs&gt;
  &lt;rect x=&quot;0&quot; y=&quot;0&quot; width=&quot;501.5937499999999&quot; height=&quot;328&quot; fill=&quot;none&quot;&gt;&lt;/rect&gt;&lt;g stroke-linecap=&quot;round&quot; transform=&quot;translate(10 10) rotate(0 34.59375 22)&quot;&gt;&lt;path d=&quot;M0 0 C17.69 0.67, 38.63 0.6, 69.19 0 M0 0 C24.36 -0.4, 47.07 0.25, 69.19 0 M69.19 0 C68.58 14.76, 67.15 31.72, 69.19 44 M69.19 0 C68.81 15.61, 69.64 31.87, 69.19 44 M69.19 44 C44.04 43.2, 18.47 44.71, 0 44 M69.19 44 C45.25 43.85, 21.53 43.69, 0 44 M0 44 C1.55 26.96, -1.13 11.08, 0 0 M0 44 C0.39 28, -0.78 11.96, 0 0&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(23.653770446777344 19.5) rotate(0 20.939979553222656 12.5)&quot;&gt;&lt;text x=&quot;20.939979553222656&quot; y=&quot;17.619999999999997&quot; font-family=&quot;Excalifont, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;File1&lt;/text&gt;&lt;/g&gt;&lt;g stroke-linecap=&quot;round&quot; transform=&quot;translate(187.9374999999999 131) rotate(0 65.859375 22)&quot;&gt;&lt;path d=&quot;M0 0 C53.83 0.38, 104.61 -1.67, 131.72 0 M0 0 C27.63 0.97, 57.18 0.67, 131.72 0 M131.72 0 C129.88 14.13, 132.67 24.29, 131.72 44 M131.72 0 C132.1 11.52, 132.21 21.87, 131.72 44 M131.72 44 C96.16 44.56, 62.31 44.29, 0 44 M131.72 44 C85.8 42.8, 42.19 43.84, 0 44 M0 44 C-1.33 28.48, 0.98 9.47, 0 0 M0 44 C-0.91 26.96, -0.13 9.55, 0 0&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(200.60692596435536 140.5) rotate(0 53.18994903564453 12.5)&quot;&gt;&lt;text x=&quot;53.18994903564453&quot; y=&quot;17.619999999999997&quot; font-family=&quot;Excalifont, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;tar archive&lt;/text&gt;&lt;/g&gt;&lt;g stroke-linecap=&quot;round&quot; transform=&quot;translate(216.2031249999999 10) rotate(0 34.59375 22)&quot;&gt;&lt;path d=&quot;M0 0 C26.23 -1.23, 48.95 0.46, 69.19 0 M0 0 C14.31 -0.4, 27.62 0.06, 69.19 0 M69.19 0 C69.83 12.48, 67.61 24.96, 69.19 44 M69.19 0 C70.05 14.54, 69.08 27.65, 69.19 44 M69.19 44 C51.2 44.99, 32.5 43.42, 0 44 M69.19 44 C52.48 44, 34.82 44.44, 0 44 M0 44 C1.57 30.31, 2.11 16.83, 0 0 M0 44 C0.39 30.29, -0.35 16.84, 0 0&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(227.12689208984364 19.5) rotate(0 23.66998291015625 12.5)&quot;&gt;&lt;text x=&quot;23.66998291015625&quot; y=&quot;17.619999999999997&quot; font-family=&quot;Excalifont, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;File2&lt;/text&gt;&lt;/g&gt;&lt;g stroke-linecap=&quot;round&quot; transform=&quot;translate(422.4062499999999 10) rotate(0 34.59375 22)&quot;&gt;&lt;path d=&quot;M0 0 C23.38 1.17, 48.16 -1.24, 69.19 0 M0 0 C18.26 0.27, 36.83 -0.45, 69.19 0 M69.19 0 C68.22 16.6, 69.7 35.49, 69.19 44 M69.19 0 C69.13 17.31, 69.18 34.41, 69.19 44 M69.19 44 C46.05 43.33, 20.28 42.88, 0 44 M69.19 44 C53.63 45.16, 36.34 43.82, 0 44 M0 44 C1.6 27.5, 0.08 7.69, 0 0 M0 44 C-0.7 30.21, -0.23 14.17, 0 0&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(434.2500228881835 19.5) rotate(0 22.749977111816406 12.5)&quot;&gt;&lt;text x=&quot;22.749977111816406&quot; y=&quot;17.619999999999997&quot; font-family=&quot;Excalifont, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;File3&lt;/text&gt;&lt;/g&gt;&lt;g stroke-linecap=&quot;round&quot; transform=&quot;translate(161.5312499999999 274) rotate(0 92.265625 22)&quot;&gt;&lt;path d=&quot;M0 0 C45.97 -2.34, 95.24 -0.03, 184.53 0 M0 0 C43.64 -0.57, 88.38 0.82, 184.53 0 M184.53 0 C184.56 13.55, 186.14 26.3, 184.53 44 M184.53 0 C184.1 16.09, 184.85 33.05, 184.53 44 M184.53 44 C122.12 41.82, 60.28 45.09, 0 44 M184.53 44 C121.55 45.13, 59.15 46.28, 0 44 M0 44 C-0.04 28.58, 0.26 16.13, 0 0 M0 44 C0.1 28.95, -0.16 14.16, 0 0&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(177.52694702148426 283.5) rotate(0 76.26992797851562 12.5)&quot;&gt;&lt;text x=&quot;76.26992797851562&quot; y=&quot;17.619999999999997&quot; font-family=&quot;Excalifont, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;gzip tar archive&lt;/text&gt;&lt;/g&gt;&lt;g stroke-linecap=&quot;round&quot;&gt;&lt;g transform=&quot;translate(44.594187499999975 55) rotate(0 70.68998690514422 36.43767334976269)&quot;&gt;&lt;path d=&quot;M-0.91 -0.4 C1.58 6.26, -8.2 26.57, 15.48 38.74 C39.15 50.92, 120.17 67.16, 141.14 72.67 M0.81 -1.65 C3.14 5.24, -8.46 27.29, 14.78 39.88 C38.02 52.47, 119.13 68.47, 140.24 73.89&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(44.594187499999975 55) rotate(0 70.68998690514422 36.43767334976269)&quot;&gt;&lt;path d=&quot;M115.43 76.96 C123.35 76.88, 131.3 74.62, 140.24 73.89 M115.43 76.96 C123.38 76.82, 129.33 74.84, 140.24 73.89&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(44.594187499999975 55) rotate(0 70.68998690514422 36.43767334976269)&quot;&gt;&lt;path d=&quot;M119.26 60.29 C125.69 65.93, 132.32 69.41, 140.24 73.89 M119.26 60.29 C126.1 64.84, 130.98 67.58, 140.24 73.89&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;/g&gt;&lt;mask&gt;&lt;/mask&gt;&lt;g stroke-linecap=&quot;round&quot;&gt;&lt;g transform=&quot;translate(250.79718749999995 55) rotate(0 0.9716142119473261 34.85000000000002)&quot;&gt;&lt;path d=&quot;M0.48 -0.76 C0.59 2.53, -0.47 7.73, -0.24 19.3 C-0.02 30.87, 1.28 60.14, 1.83 68.64 M-0.73 1.46 C-0.72 4.97, -1.61 9.41, -1.32 20.73 C-1.03 32.05, 0.75 61.51, 1.01 69.4&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(250.79718749999995 55) rotate(0 0.9716142119473261 34.85000000000002)&quot;&gt;&lt;path d=&quot;M-8.64 46.34 C-7.82 51.06, -4.73 56.45, 1.01 69.4 M-8.64 46.34 C-6.54 50.58, -4.66 56.21, 1.01 69.4&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(250.79718749999995 55) rotate(0 0.9716142119473261 34.85000000000002)&quot;&gt;&lt;path d=&quot;M8.44 45.53 C5.44 50.5, 4.7 56.07, 1.01 69.4 M8.44 45.53 C6.93 50.03, 5.19 55.83, 1.01 69.4&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;/g&gt;&lt;mask&gt;&lt;/mask&gt;&lt;g stroke-linecap=&quot;round&quot;&gt;&lt;g transform=&quot;translate(457.0001874999999 55) rotate(0 -67.24738389528534 35.89774893888858)&quot;&gt;&lt;path d=&quot;M-0.24 -0.2 C-0.51 5.33, 21.08 20.34, -1.11 32.44 C-23.3 44.54, -111.13 65.97, -133.4 72.41 M1.83 -1.35 C1.35 4.36, 20.45 21.47, -2.12 33.42 C-24.69 45.38, -111.52 64, -133.58 70.39&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(457.0001874999999 55) rotate(0 -67.24738389528534 35.89774893888858)&quot;&gt;&lt;path d=&quot;M-112.9 56.36 C-120.35 60.9, -128.8 67.68, -133.58 70.39 M-112.9 56.36 C-120.51 61.31, -126.94 67.04, -133.58 70.39&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(457.0001874999999 55) rotate(0 -67.24738389528534 35.89774893888858)&quot;&gt;&lt;path d=&quot;M-108.71 72.94 C-117.48 71.84, -127.36 72.99, -133.58 70.39 M-108.71 72.94 C-117.77 72.04, -125.68 71.94, -133.58 70.39&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;/g&gt;&lt;mask&gt;&lt;/mask&gt;&lt;g mask=&quot;url(#mask-voTp8XeTVlWJX5IMeOO3J)&quot; stroke-linecap=&quot;round&quot;&gt;&lt;g transform=&quot;translate(252.27430315019012 176) rotate(0 -0.5921582339649376 45.85000000000002)&quot;&gt;&lt;path d=&quot;M-0.11 -1.06 C-0.13 7, -0.41 32.78, -0.38 48.12 C-0.34 63.46, 0.06 83.69, 0.11 90.99 M-1.63 1 C-1.69 8.72, -0.9 31.16, -0.75 46.32 C-0.6 61.47, -0.87 84.14, -0.76 91.93&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(252.27430315019012 176) rotate(0 -0.5921582339649376 45.85000000000002)&quot;&gt;&lt;path d=&quot;M-8.37 71.16 C-8.04 78.8, -3.12 82.47, -0.76 91.93 M-8.37 71.16 C-6.09 77.08, -4.14 81.85, -0.76 91.93&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(252.27430315019012 176) rotate(0 -0.5921582339649376 45.85000000000002)&quot;&gt;&lt;path d=&quot;M6.76 71.13 C2.86 78.77, 3.55 82.44, -0.76 91.93 M6.76 71.13 C5.41 77.07, 3.71 81.85, -0.76 91.93&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;/g&gt;&lt;mask id=&quot;mask-voTp8XeTVlWJX5IMeOO3J&quot;&gt;&lt;rect x=&quot;0&quot; y=&quot;0&quot; fill=&quot;#fff&quot; width=&quot;354.0442179826406&quot; height=&quot;367.70000000000005&quot;&gt;&lt;/rect&gt;&lt;rect x=&quot;228.83720367431624&quot; y=&quot;211&quot; fill=&quot;#000&quot; width=&quot;43.91996765136719&quot; height=&quot;25&quot; opacity=&quot;1&quot;&gt;&lt;/rect&gt;&lt;/mask&gt;&lt;g transform=&quot;translate(228.83720367431624 211) rotate(0 22.674555582500716 10.434725105254927)&quot;&gt;&lt;text x=&quot;21.959983825683594&quot; y=&quot;17.619999999999997&quot; font-family=&quot;Excalifont, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;Gzip&lt;/text&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;On the other hand, zip compresses one file at a time and then creates an archive. Since it&apos;s only compressing one file at a time,
it doesn&apos;t do as good of a job in compression. Usually, gzip produces smaller output.&lt;/p&gt;
&lt;p&gt;However, an advantage that zip offers over gzip is that you can browse the zipped archive without uncompressing the entire thing.
zip files have a central directory at the end, which provides a list of the contents. This along with the fact that each files are compressed
individually makes this possible. That&apos;s why you might have noticed, that on Windows you can simply open &amp;#x26; browse through a zip file without uncompressing it first.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;inline-svg&quot; role=&quot;img&quot; aria-label=&quot;ZIP&quot;&gt;&lt;svg version=&quot;1.1&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; viewBox=&quot;0 0 525.0174338386724 351&quot; width=&quot;100%&quot; height=&quot;280&quot;&gt;
  &lt;!-- svg-source:excalidraw --&gt;
  &lt;defs&gt;
    &lt;style class=&quot;style-fonts&quot;&gt;
      @font-face {
        font-family: Excalifont;
        src: url(data:font/woff2;base64,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);
      }
    &lt;/style&gt;
  &lt;/defs&gt;
  &lt;rect x=&quot;0&quot; y=&quot;0&quot; width=&quot;525.0174338386724&quot; height=&quot;351&quot; fill=&quot;none&quot;&gt;&lt;/rect&gt;
  &lt;g stroke-linecap=&quot;round&quot; transform=&quot;translate(21.480497043809464 11) rotate(0 34.59375 22)&quot;&gt;
    &lt;path d=&quot;M0 0 C17.69 0.67, 38.63 0.6, 69.19 0 M0 0 C24.36 -0.4, 47.07 0.25, 69.19 0 M69.19 0 C68.58 14.76, 67.15 31.72, 69.19 44 M69.19 0 C68.81 15.61, 69.64 31.87, 69.19 44 M69.19 44 C44.04 43.2, 18.47 44.71, 0 44 M69.19 44 C45.25 43.85, 21.53 43.69, 0 44 M0 44 C1.55 26.96, -1.13 11.08, 0 0 M0 44 C0.39 28, -0.78 11.96, 0 0&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;
  &lt;/g&gt;
  &lt;g transform=&quot;translate(35.13426749058681 20.5) rotate(0 20.939979553222656 12.5)&quot;&gt;
    &lt;text x=&quot;20.939979553222656&quot; y=&quot;17.619999999999997&quot; font-family=&quot;Excalifont, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;File1&lt;/text&gt;
  &lt;/g&gt;
  &lt;g stroke-linecap=&quot;round&quot; transform=&quot;translate(227.68362204380935 10) rotate(0 34.59375 22)&quot;&gt;
    &lt;path d=&quot;M0 0 C26.23 -1.23, 48.95 0.46, 69.19 0 M0 0 C14.31 -0.4, 27.62 0.06, 69.19 0 M69.19 0 C69.83 12.48, 67.61 24.96, 69.19 44 M69.19 0 C70.05 14.54, 69.08 27.65, 69.19 44 M69.19 44 C51.2 44.99, 32.5 43.42, 0 44 M69.19 44 C52.48 44, 34.82 44.44, 0 44 M0 44 C1.57 30.31, 2.11 16.83, 0 0 M0 44 C0.39 30.29, -0.35 16.84, 0 0&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;
  &lt;/g&gt;
  &lt;g transform=&quot;translate(238.6073891336531 19.5) rotate(0 23.66998291015625 12.5)&quot;&gt;
    &lt;text x=&quot;23.66998291015625&quot; y=&quot;17.619999999999997&quot; font-family=&quot;Excalifont, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;File2&lt;/text&gt;
  &lt;/g&gt;
  &lt;g stroke-linecap=&quot;round&quot; transform=&quot;translate(433.88674704380935 11) rotate(0 34.59375 22)&quot;&gt;
    &lt;path d=&quot;M0 0 C23.38 1.17, 48.16 -1.24, 69.19 0 M0 0 C18.26 0.27, 36.83 -0.45, 69.19 0 M69.19 0 C68.22 16.6, 69.7 35.49, 69.19 44 M69.19 0 C69.13 17.31, 69.18 34.41, 69.19 44 M69.19 44 C46.05 43.33, 20.28 42.88, 0 44 M69.19 44 C53.63 45.16, 36.34 43.82, 0 44 M0 44 C1.6 27.5, 0.08 7.69, 0 0 M0 44 C-0.7 30.21, -0.23 14.17, 0 0&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;
  &lt;/g&gt;
  &lt;g transform=&quot;translate(445.73051993199294 20.5) rotate(0 22.749977111816406 12.5)&quot;&gt;
    &lt;text x=&quot;22.749977111816406&quot; y=&quot;17.619999999999997&quot; font-family=&quot;Excalifont, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;File3&lt;/text&gt;
  &lt;/g&gt;
  &lt;g stroke-linecap=&quot;round&quot; transform=&quot;translate(173.01174704380935 297) rotate(0 92.265625 22)&quot;&gt;
    &lt;path d=&quot;M0 0 C45.97 -2.34, 95.24 -0.03, 184.53 0 M0 0 C43.64 -0.57, 88.38 0.82, 184.53 0 M184.53 0 C184.56 13.55, 186.14 26.3, 184.53 44 M184.53 0 C184.1 16.09, 184.85 33.05, 184.53 44 M184.53 44 C122.12 41.82, 60.28 45.09, 0 44 M184.53 44 C121.55 45.13, 59.15 46.28, 0 44 M0 44 C-0.04 28.58, 0.26 16.13, 0 0 M0 44 C0.1 28.95, -0.16 14.16, 0 0&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;
  &lt;/g&gt;
  &lt;g transform=&quot;translate(213.9674202615828 306.5) rotate(0 51.30995178222656 12.5)&quot;&gt;
    &lt;text x=&quot;51.30995178222656&quot; y=&quot;17.619999999999997&quot; font-family=&quot;Excalifont, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;zip archive&lt;/text&gt;
  &lt;/g&gt;
  &lt;g mask=&quot;url(#mask-voTp8XeTVlWJX5IMeOO3J)&quot; stroke-linecap=&quot;round&quot;&gt;
    &lt;g transform=&quot;translate(263.7548001939996 177) rotate(0 -0.46017388790119185 56.85000000000002)&quot;&gt;
      &lt;path d=&quot;M-0.11 -1.06 C-0.13 7, -0.46 29.11, -0.38 48.12 C-0.3 67.12, 0.28 102.03, 0.37 112.99 M-1.63 1 C-1.69 8.72, -0.94 27.5, -0.75 46.32 C-0.56 65.14, -0.65 102.47, -0.49 113.93&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
    &lt;g transform=&quot;translate(263.7548001939996 177) rotate(0 -0.46017388790119185 56.85000000000002)&quot;&gt;
      &lt;path d=&quot;M-9.18 90.48 C-8.55 98.88, -3.33 103.29, -0.49 113.93 M-9.18 90.48 C-6.65 97.04, -4.44 102.45, -0.49 113.93&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
    &lt;g transform=&quot;translate(263.7548001939996 177) rotate(0 -0.46017388790119185 56.85000000000002)&quot;&gt;
      &lt;path d=&quot;M7.92 90.39 C3.77 98.79, 4.21 103.23, -0.49 113.93 M7.92 90.39 C6.34 96.99, 4.44 102.43, -0.49 113.93&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
  &lt;/g&gt;
  &lt;mask id=&quot;mask-voTp8XeTVlWJX5IMeOO3J&quot;&gt;
    &lt;rect x=&quot;0&quot; y=&quot;0&quot; fill=&quot;#fff&quot; width=&quot;365.78868371857754&quot; height=&quot;390.70000000000005&quot;&gt;&lt;/rect&gt;
    &lt;rect x=&quot;246.0176976663679&quot; y=&quot;212&quot; fill=&quot;#000&quot; width=&quot;32.51997375488281&quot; height=&quot;25&quot; opacity=&quot;1&quot;&gt;&lt;/rect&gt;
  &lt;/mask&gt;
  &lt;g transform=&quot;translate(246.0176976663679 212) rotate(0 17.106447723964607 21.434725105254927)&quot;&gt;
    &lt;text x=&quot;16.259986877441406&quot; y=&quot;17.619999999999997&quot; font-family=&quot;Excalifont, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;Zip&lt;/text&gt;
  &lt;/g&gt;
  &lt;g stroke-linecap=&quot;round&quot; transform=&quot;translate(437.1736864611495 132.41289129739164) rotate(0 34.59375 22)&quot;&gt;
    &lt;path d=&quot;M0 0 C20.18 1.06, 41.2 2.36, 69.19 0 M0 0 C13.96 0.55, 28.68 0.28, 69.19 0 M69.19 0 C68.86 12.78, 67.23 25.93, 69.19 44 M69.19 0 C69.41 16.35, 70.12 34.43, 69.19 44 M69.19 44 C45.31 44.44, 22.47 42, 0 44 M69.19 44 C49.46 44.78, 28.71 44.34, 0 44 M0 44 C1.6 34.88, -0.81 22.38, 0 0 M0 44 C-0.17 34.89, 0.59 24.75, 0 0&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;
  &lt;/g&gt;
  &lt;g transform=&quot;translate(449.0174593493331 141.91289129739164) rotate(0 22.749977111816406 12.5)&quot;&gt;
    &lt;text x=&quot;22.749977111816406&quot; y=&quot;17.619999999999997&quot; font-family=&quot;Excalifont, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;File3&lt;/text&gt;
  &lt;/g&gt;
  &lt;g stroke-linecap=&quot;round&quot; transform=&quot;translate(228.1839345438092 138) rotate(0 34.59375 22)&quot;&gt;
    &lt;path d=&quot;M0 0 C17.33 -1.68, 35.01 1.86, 69.19 0 M0 0 C24.36 0.69, 50.46 0.48, 69.19 0 M69.19 0 C69.8 16.22, 67.36 30.66, 69.19 44 M69.19 0 C70.05 13.3, 69.61 25.28, 69.19 44 M69.19 44 C53.11 43.47, 33.66 42.95, 0 44 M69.19 44 C51.9 44.18, 33.57 43.79, 0 44 M0 44 C0.81 34.46, -0.43 24.47, 0 0 M0 44 C-0.58 33.74, -0.44 24.35, 0 0&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;
  &lt;/g&gt;
  &lt;g transform=&quot;translate(239.10770163365294 147.5) rotate(0 23.66998291015625 12.5)&quot;&gt;
    &lt;text x=&quot;23.66998291015625&quot; y=&quot;17.619999999999997&quot; font-family=&quot;Excalifont, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;File2&lt;/text&gt;
  &lt;/g&gt;
  &lt;g stroke-linecap=&quot;round&quot; transform=&quot;translate(27.173686461149714 137.43338746271127) rotate(0 34.59375 17.5)&quot;&gt;
    &lt;path d=&quot;M0 0 C15.52 1.01, 27.9 -0.08, 69.19 0 M0 0 C23.9 0.46, 47.58 1.22, 69.19 0 M69.19 0 C68.15 13.07, 70.89 29.36, 69.19 35 M69.19 0 C68.24 12.74, 69.2 25.94, 69.19 35 M69.19 35 C43.55 33.54, 16.25 35.92, 0 35 M69.19 35 C46.43 33.88, 24.37 35.46, 0 35 M0 35 C-1.18 26.91, 1.02 18.96, 0 0 M0 35 C-0.2 25.49, -0.02 17.21, 0 0&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;
  &lt;/g&gt;
  &lt;g transform=&quot;translate(40.82745690792706 142.43338746271127) rotate(0 20.939979553222656 12.5)&quot;&gt;
    &lt;text x=&quot;20.939979553222656&quot; y=&quot;17.619999999999997&quot; font-family=&quot;Excalifont, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;File1&lt;/text&gt;
  &lt;/g&gt;
  &lt;g mask=&quot;url(#mask-kdYM28mVux5Z7ZpK6YyTD)&quot; stroke-linecap=&quot;round&quot;&gt;
    &lt;g transform=&quot;translate(51.938523135426635 62) rotate(0 1.3214408538311773 35.71669373135563)&quot;&gt;
      &lt;path d=&quot;M0.66 0.4 C1.07 12.58, 3.1 60.03, 3.56 71.9 M-0.45 -0.43 C-0.22 11.49, 2.51 57.78, 3.1 70.03&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
    &lt;g transform=&quot;translate(51.938523135426635 62) rotate(0 1.3214408538311773 35.71669373135563)&quot;&gt;
      &lt;path d=&quot;M-6.69 47.02 C-2.4 57.56, 1.57 66.37, 3.1 70.03 M-6.69 47.02 C-3.27 54.84, -0.17 61.37, 3.1 70.03&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
    &lt;g transform=&quot;translate(51.938523135426635 62) rotate(0 1.3214408538311773 35.71669373135563)&quot;&gt;
      &lt;path d=&quot;M10.38 46.11 C7.95 57.1, 5.2 66.27, 3.1 70.03 M10.38 46.11 C8.42 54.35, 6.14 61.17, 3.1 70.03&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
  &lt;/g&gt;
  &lt;mask id=&quot;mask-kdYM28mVux5Z7ZpK6YyTD&quot;&gt;
    &lt;rect x=&quot;0&quot; y=&quot;0&quot; fill=&quot;#fff&quot; width=&quot;154.581404843089&quot; height=&quot;233.43338746271127&quot;&gt;&lt;/rect&gt;
    &lt;rect x=&quot;10&quot; y=&quot;85.21669373135569&quot; fill=&quot;#000&quot; width=&quot;86.51992797851562&quot; height=&quot;25&quot; opacity=&quot;1&quot;&gt;&lt;/rect&gt;
  &lt;/mask&gt;
  &lt;g transform=&quot;translate(10 85.21669373135569) rotate(0 43.49548092006239 12.51776686826247)&quot;&gt;
    &lt;text x=&quot;43.25996398925781&quot; y=&quot;17.619999999999997&quot; font-family=&quot;Excalifont, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;compress&lt;/text&gt;
  &lt;/g&gt;
  &lt;g mask=&quot;url(#mask-CbZYxyoJoM17rgKJFTyyv)&quot; stroke-linecap=&quot;round&quot;&gt;
    &lt;g transform=&quot;translate(265.8899189961463 57) rotate(0 -1.628550231786221 38)&quot;&gt;
      &lt;path d=&quot;M0.4 -0.96 C-0.07 11.77, -1.43 63.77, -2.11 76.7 M-0.86 1.14 C-1.43 13.5, -1.83 62.7, -2.45 74.94&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
    &lt;g transform=&quot;translate(265.8899189961463 57) rotate(0 -1.628550231786221 38)&quot;&gt;
      &lt;path d=&quot;M-10.37 51.22 C-9.1 61.54, -3.52 67.4, -2.45 74.94 M-10.37 51.22 C-6.48 60.01, -4.76 67.38, -2.45 74.94&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
    &lt;g transform=&quot;translate(265.8899189961463 57) rotate(0 -1.628550231786221 38)&quot;&gt;
      &lt;path d=&quot;M6.73 51.68 C1.92 61.89, 1.42 67.59, -2.45 74.94 M6.73 51.68 C4.61 60.47, 0.34 67.68, -2.45 74.94&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
  &lt;/g&gt;
  &lt;mask id=&quot;mask-CbZYxyoJoM17rgKJFTyyv&quot;&gt;
    &lt;rect x=&quot;0&quot; y=&quot;0&quot; fill=&quot;#fff&quot; width=&quot;369.14701945971876&quot; height=&quot;233&quot;&gt;&lt;/rect&gt;
    &lt;rect x=&quot;221.0014047751024&quot; y=&quot;82.5&quot; fill=&quot;#000&quot; width=&quot;86.51992797851562&quot; height=&quot;25&quot; opacity=&quot;1&quot;&gt;&lt;/rect&gt;
  &lt;/mask&gt;
  &lt;g transform=&quot;translate(221.0014047751024 82.5) rotate(0 43.859631004170524 12.365243713557675)&quot;&gt;
    &lt;text x=&quot;43.25996398925781&quot; y=&quot;17.619999999999997&quot; font-family=&quot;Excalifont, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;compress&lt;/text&gt;
  &lt;/g&gt;
  &lt;g mask=&quot;url(#mask-06GZJndmluioUXupD6Vl9)&quot; stroke-linecap=&quot;round&quot;&gt;
    &lt;g transform=&quot;translate(472.0018844559735 59) rotate(0 -0.2444146065587347 34.20644564869582)&quot;&gt;
      &lt;path d=&quot;M0.05 1.05 C0.09 12.67, -0.19 57.98, -0.45 69.01 M-1.39 0.55 C-1.43 11.88, -1.74 55.98, -1.38 67.2&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
    &lt;g transform=&quot;translate(472.0018844559735 59) rotate(0 -0.2444146065587347 34.20644564869582)&quot;&gt;
      &lt;path d=&quot;M-10.16 43.8 C-6.45 49.47, -5.09 53.26, -1.38 67.2 M-10.16 43.8 C-7.52 49.45, -6.87 52.96, -1.38 67.2&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
    &lt;g transform=&quot;translate(472.0018844559735 59) rotate(0 -0.2444146065587347 34.20644564869582)&quot;&gt;
      &lt;path d=&quot;M6.94 43.63 C6.55 49.35, 3.8 53.18, -1.38 67.2 M6.94 43.63 C6.16 49.18, 3.38 52.72, -1.38 67.2&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
  &lt;/g&gt;
  &lt;mask id=&quot;mask-06GZJndmluioUXupD6Vl9&quot;&gt;
    &lt;rect x=&quot;0&quot; y=&quot;0&quot; fill=&quot;#fff&quot; width=&quot;572.490713669091&quot; height=&quot;227.41289129739164&quot;&gt;&lt;/rect&gt;
    &lt;rect x=&quot;428.49750586015693&quot; y=&quot;80.70644564869576&quot; fill=&quot;#000&quot; width=&quot;86.51992797851562&quot; height=&quot;25&quot; opacity=&quot;1&quot;&gt;&lt;/rect&gt;
  &lt;/mask&gt;
  &lt;g transform=&quot;translate(428.4975058601567 80.70644564869576) rotate(0 42.75327831635843 13.074957372932772)&quot;&gt;
    &lt;text x=&quot;43.25996398925781&quot; y=&quot;17.619999999999997&quot; font-family=&quot;Excalifont, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;compress&lt;/text&gt;
  &lt;/g&gt;
  &lt;g mask=&quot;url(#mask-3DNLIbvJxBQKLtME7hmTg)&quot; stroke-linecap=&quot;round&quot;&gt;
    &lt;g transform=&quot;translate(69.12156254314289 190.43338746271127) rotate(0 94.4488175122143 49.78330626864437)&quot;&gt;
      &lt;path d=&quot;M0.97 -0.59 C9.16 8.15, 18.41 36.7, 49.67 53.39 C80.93 70.09, 165.41 92.09, 188.54 99.6 M0.01 1.72 C8 10.56, 17.47 38.3, 48.73 54.84 C79.99 71.37, 164.3 93.57, 187.59 100.93&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
    &lt;g transform=&quot;translate(69.12156254314289 190.43338746271127) rotate(0 94.4488175122143 49.78330626864437)&quot;&gt;
      &lt;path d=&quot;M162.64 102.52 C170.22 101.8, 179.48 100.63, 187.59 100.93 M162.64 102.52 C170.88 102.02, 177.97 101.23, 187.59 100.93&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
    &lt;g transform=&quot;translate(69.12156254314289 190.43338746271127) rotate(0 94.4488175122143 49.78330626864437)&quot;&gt;
      &lt;path d=&quot;M167.45 86.11 C173.51 91.07, 181.12 95.54, 187.59 100.93 M167.45 86.11 C174.18 90.53, 179.81 94.7, 187.59 100.93&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
  &lt;/g&gt;
  &lt;mask id=&quot;mask-3DNLIbvJxBQKLtME7hmTg&quot;&gt;
    &lt;rect x=&quot;0&quot; y=&quot;0&quot; fill=&quot;#fff&quot; width=&quot;358.0191975675715&quot; height=&quot;390&quot;&gt;&lt;/rect&gt;
    &lt;rect x=&quot;105.11769614048899&quot; y=&quot;231.5&quot; fill=&quot;#000&quot; width=&quot;27.319976806640625&quot; height=&quot;25&quot; opacity=&quot;1&quot;&gt;&lt;/rect&gt;
  &lt;/mask&gt;
  &lt;g transform=&quot;translate(105.11769614048899 231.5) rotate(0 58.28124687965112 9.103141630785672)&quot;&gt;
    &lt;text x=&quot;13.659988403320312&quot; y=&quot;17.619999999999997&quot; font-family=&quot;Excalifont, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;zip&lt;/text&gt;
  &lt;/g&gt;
  &lt;g mask=&quot;url(#mask-t0_rmxH_g9qgL5YmL96qh)&quot; stroke-linecap=&quot;round&quot;&gt;
    &lt;g transform=&quot;translate(468.18001419586574 187.41289129739164) rotate(0 -97.73206282181036 50.9016400605567)&quot;&gt;
      &lt;path d=&quot;M0.91 0.43 C-3.42 8.94, 7.66 34.43, -25.04 51.38 C-57.74 68.32, -166.74 93.71, -195.31 102.09 M-0.07 -0.39 C-4.61 8.28, 6.86 35.48, -25.8 52.8 C-58.45 70.13, -167.5 95.24, -196 103.56&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
    &lt;g transform=&quot;translate(468.18001419586574 187.41289129739164) rotate(0 -97.73206282181036 50.9016400605567)&quot;&gt;
      &lt;path d=&quot;M-175.46 89.32 C-182.5 95.48, -191.36 100.54, -196 103.56 M-175.46 89.32 C-182.59 94.64, -188.58 97.6, -196 103.56&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
    &lt;g transform=&quot;translate(468.18001419586574 187.41289129739164) rotate(0 -97.73206282181036 50.9016400605567)&quot;&gt;
      &lt;path d=&quot;M-171.1 105.85 C-179.85 105.78, -190.36 104.56, -196 103.56 M-171.1 105.85 C-179.51 105.82, -186.91 103.41, -196 103.56&quot; stroke=&quot;var(--primary-text-color)&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
  &lt;/g&gt;
  &lt;mask id=&quot;mask-t0_rmxH_g9qgL5YmL96qh&quot;&gt;
    &lt;rect x=&quot;0&quot; y=&quot;0&quot; fill=&quot;#fff&quot; width=&quot;763.6441398394865&quot; height=&quot;389.21617141850504&quot;&gt;&lt;/rect&gt;
    &lt;rect x=&quot;429.117696140489&quot; y=&quot;226.5&quot; fill=&quot;#000&quot; width=&quot;27.319976806640625&quot; height=&quot;25&quot; opacity=&quot;1&quot;&gt;&lt;/rect&gt;
  &lt;/mask&gt;
  &lt;g transform=&quot;translate(429.117696140489 226.5) rotate(0 -58.480645221266855 12.49793468797452)&quot;&gt;
    &lt;text x=&quot;13.659988403320312&quot; y=&quot;17.619999999999997&quot; font-family=&quot;Excalifont, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;var(--primary-text-color)&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;zip&lt;/text&gt;
  &lt;/g&gt;
&lt;/svg&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h2 id=&quot;compression-algorithms-under-the-hood&quot;&gt;Compression algorithms under the hood&lt;/h2&gt;
&lt;p&gt;gzip uses the Deflate method for compression which in turn uses &lt;code class=&quot;language-text&quot;&gt;LZ77&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;Huffman encoding&lt;/code&gt; compression algorithms.&lt;/p&gt;
&lt;p&gt;While zip also uses the same two algorithms, it can replace them with a wide variety of other algorithms that offer different balances between the speed of compression &amp;#x26; the efficiency of the compresion.
Example: zip can use &lt;code class=&quot;language-text&quot;&gt;LZMA&lt;/code&gt; instead of &lt;code class=&quot;language-text&quot;&gt;LZ77&lt;/code&gt; and produce smaller output but at the cost of compression speed.&lt;/p&gt;
&lt;p&gt;The ZIP format supports several compression methods:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Source: https://stackoverflow.com/a/20765054/6199444

0 - The file is stored (no compression)
1 - The file is Shrunk
2 - The file is Reduced with compression factor 1
3 - The file is Reduced with compression factor 2
4 - The file is Reduced with compression factor 3
5 - The file is Reduced with compression factor 4
6 - The file is Imploded
7 - Reserved for Tokenizing compression algorithm
8 - The file is Deflated
9 - Enhanced Deflating using Deflate64(tm)
10 - PKWARE Data Compression Library Imploding (old IBM TERSE)
11 - Reserved by PKWARE
12 - File is compressed using BZIP2 algorithm
13 - Reserved by PKWARE
14 - LZMA
15 - Reserved by PKWARE
16 - IBM z/OS CMPSC Compression
17 - Reserved by PKWARE
18 - File is compressed using IBM TERSE (new)
19 - IBM LZ77 z Architecture
20 - deprecated (use method 93 for zstd)
93 - Zstandard (zstd) Compression
94 - MP3 Compression
95 - XZ Compression
96 - JPEG variant
97 - WavPack compressed data
98 - PPMd version I, Rev 1
99 - AE-x encryption marker (see APPENDIX E)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Formats 0 &amp;#x26; 8 are by far the most used ones - 8 more so.&lt;/p&gt;
&lt;h2 id=&quot;use-cases&quot;&gt;Use cases&lt;/h2&gt;
&lt;p&gt;gzip (along with tar) is more common in the Unix world than zip.
tar preserves all of the Unix file attributes, whereas zip was not designed to do that.&lt;/p&gt;
&lt;p&gt;gzip also supports decompressing data streams which is why it&apos;s popular in network transfer.
HTTP widely uses gzip.&lt;/p&gt;
&lt;p&gt;zip is preferred when portability and random access are required.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[No, your sudo password is not incorrect]]></title><description><![CDATA[sudo rejects password that is correct]]></description><link>https://www.adityathebe.com/incorrect-sudo-password</link><guid isPermaLink="false">https://www.adityathebe.com/incorrect-sudo-password</guid><pubDate>Thu, 18 Jul 2024 23:50:00 GMT</pubDate><content:encoded>&lt;p&gt;I&apos;ve ocassionally run into this situation where I just cannot get the sudo password right no matter how many times I retry it.
Just to make sure, I carefully press one key at a time instead of typing fast in my regular pace. However, Linux still tells me
my password is incorrect!&lt;/p&gt;
&lt;p&gt;I&apos;ve also tried typing my password on a text editor where I can see what I&apos;m typing and it&apos;s flawless everytime.
Copy pasting a valid password doesn&apos;t help either!&lt;/p&gt;
&lt;p&gt;I&apos;ve blamed my keyboard and myself for misconfiguring my linux installation for this and I used to simply restart my system.
And after a restart, it would work.&lt;/p&gt;
&lt;h2 id=&quot;silently-locking-out-the-user&quot;&gt;Silently locking out the user&lt;/h2&gt;
&lt;p&gt;As it turns out, a few incorrect password attempts - I believe 3 - will lock you down for a period of time. But Linux doesn&apos;t tell you about that.
It just tells you to &quot;try again&quot;. That&apos;s the same thing it tells you when you do provide a wrong password.&lt;/p&gt;
&lt;p&gt;To know if you&apos;re currently locked out you need to explicitly look for it.&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;faillock --user &amp;lt;user&gt;&lt;/code&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;~/❯ faillock --user aditya
aditya:
When                Type  Source                                           Valid
2024-07-18 11:40:33 TTY   /dev/pts/11                                          V
2024-07-18 11:40:36 TTY   /dev/pts/11                                          V
2024-07-18 11:40:38 TTY   /dev/pts/11                                          V&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If you see a record there, that means you have been locked out.
Fortunately, you don&apos;t have to wait until the ban goes away.
With the same command, you can lift the restriction.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;~/❯ faillock --user &amp;lt;user&gt; --reset&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I found it pretty surprising that it doesn&apos;t even take sudo access to unlift the ban
(If it did, this would all be pretty useless wouldn&apos;t it?).&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;Disclaimer: I&apos;m on Arch (btw), and this may not be applicable to your system.&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[How to setup debugger for Golang in VS Code]]></title><description><![CDATA[Setup and configure Go debugger in VS Code. Learn to create launch.json, attach to running processes, and troubleshoot common issues for effective Golang debugging in VS Code.]]></description><link>https://www.adityathebe.com/setup-go-debugger-vscode</link><guid isPermaLink="false">https://www.adityathebe.com/setup-go-debugger-vscode</guid><pubDate>Tue, 09 Jul 2024 23:40:00 GMT</pubDate><content:encoded>&lt;p&gt;VS Code comes with a native debugger by default. If you have Go&apos;s debugger &lt;code class=&quot;language-text&quot;&gt;delve&lt;/code&gt; installed on your system
then you can simply go to the &quot;Run and Debug&quot; view and press the &quot;Run and Debug&quot; button. VS Code will then start
your program and attach the debugger.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 601px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/d8f3d8465d73571b77c82d73e7484e91/d8f62/vscode-run-and-debug.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 105.33333333333334%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAVCAIAAADJt1n/AAAACXBIWXMAAA7EAAAOxAGVKw4bAAAB9UlEQVR42qWTy27TQBSG/SqsKE3i2J4Zj69zsWO79thOExBKgAWIS5pKoJCm8BJsQF0hQUu7LtA35BiLiBVqjPRrdDzyd87/j8eajoXDCk+UQVTbQda3wgFi/5COOchyRshNNMpUWj7yxBjksBJ5B1thL8d+IxIUf+v3ZtbAdljEam7zigQKYJDLK5fXsEJNQ4WhkZu1attBX5OOTBprYBuxAoW5I6swHvuyAv88ncbFQ5YcerIyabR1uzVvEKkj3sA9Ixgg/vLD5/XlzerL9err9fLs6vjs6ujj+fLTxfrix8m3n5vLm/X5dzeZ9E04FA62najWhkQiZwQP5dPX0+X7w8XpdPlusthUL96CyuererGpF6ewFs/eID8DcmAxylU2f6UZdhTEY5ZM3TCnfkq91AtznynLTUwvNZ1kaMcGjWHGvR4FTIcCy6SYV7MjbWhHmJcQG4uStJIVYorGNZUVYQqyNdOQAB4yDrFghi+S+1H5uMncbBHZSv9TtLVORPtCi+2RKNXdkzt7BldCzbS2320E8D6Rs31kGz7iSo6f7AADCYYf9MhdIombWPCdbw8PsLAtZkF+LOCYzZ1gUB/LAW6uh+XEO8NbwWQAu8DNDfNSGuYdYfAMf2UXuGeG8AvxZNIxM1AQu3tmOzjoOLnVf8G/AKtQKarHOsjMAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;vscode run and debug&quot;
        title=&quot;&quot;
        src=&quot;/static/d8f3d8465d73571b77c82d73e7484e91/d8f62/vscode-run-and-debug.png&quot;
        srcset=&quot;/static/d8f3d8465d73571b77c82d73e7484e91/5a46d/vscode-run-and-debug.png 300w,
/static/d8f3d8465d73571b77c82d73e7484e91/0a47e/vscode-run-and-debug.png 600w,
/static/d8f3d8465d73571b77c82d73e7484e91/d8f62/vscode-run-and-debug.png 601w&quot;
        sizes=&quot;(max-width: 601px) 100vw, 601px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;This approach serves fine for simple use cases. However, it&apos;s likely that your application needs some arguments or flags or environement variables. To pass those in, you can create a &lt;code class=&quot;language-text&quot;&gt;.launch.json&lt;/code&gt; file for vscode to configure.&lt;/p&gt;
&lt;h2 id=&quot;create-launchjson-file&quot;&gt;Create &lt;code class=&quot;language-text&quot;&gt;launch.json&lt;/code&gt; file&lt;/h2&gt;
&lt;p&gt;The &lt;code class=&quot;language-text&quot;&gt;launch.json&lt;/code&gt; file in VS Code is a configuration file that defines how the debugger should run your application. It allows you to specify various settings such as the program to debug, command-line arguments, environment variables, and other debug-specific options. You can create the file manually in &lt;code class=&quot;language-text&quot;&gt;.vscode/launch.json&lt;/code&gt; or you can let VS Code create it for you.&lt;/p&gt;
&lt;p&gt;Besides the &quot;Run and Debug&quot; button you should be able to see a &lt;code class=&quot;language-text&quot;&gt;create a launch.json file&lt;/code&gt; link. Select &quot;Go: Launch Package&quot; option and the file should be created.&lt;/p&gt;
&lt;p&gt;If your application accepts a &lt;code class=&quot;language-text&quot;&gt;--config&lt;/code&gt; flag and an &lt;code class=&quot;language-text&quot;&gt;ENV&lt;/code&gt; environment variable, you can configure your &lt;code class=&quot;language-text&quot;&gt;launch.json&lt;/code&gt; file as follows&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;json&quot;&gt;&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Use IntelliSense to learn about possible attributes.&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Hover to view descriptions of existing attributes.&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;version&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;0.2.0&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;configurations&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Launch Package&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;go&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;request&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;launch&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;mode&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;auto&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;program&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;${fileDirname}&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;args&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;--config&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;/tmp/config.yaml&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;env&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token property&quot;&gt;&quot;ENV&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;dev&quot;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;attach-debugger-to-a-running-process&quot;&gt;Attach debugger to a running process&lt;/h2&gt;
&lt;p&gt;I personally do not prefer to run applications from VS Code&apos;s debugger. Instead, I run all the applications in the terminal and then attach the debugger to the running process.&lt;/p&gt;
&lt;p&gt;Let&apos;s setup &lt;code class=&quot;language-text&quot;&gt;launch.json&lt;/code&gt; to attach the debugger to a running process. You can delete the &lt;code class=&quot;language-text&quot;&gt;launch.json&lt;/code&gt; file and recreate it again. This time, choose the &quot;Go: Attach to Local Process&quot; option.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;json&quot;&gt;&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Use IntelliSense to learn about possible attributes.&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Hover to view descriptions of existing attributes.&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;version&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;0.2.0&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;configurations&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Attach to Process&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;go&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;request&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;attach&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;mode&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;local&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;processId&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is the default configuration generated by VS Code. The only change we will need to make is the &lt;code class=&quot;language-text&quot;&gt;processId&lt;/code&gt; field. While it&apos;s named &lt;code class=&quot;language-text&quot;&gt;processId&lt;/code&gt;, it can also take in the name of the process. Say you&apos;re running a go binary named &apos;my-application&apos;, you can set the &lt;code class=&quot;language-text&quot;&gt;processId&lt;/code&gt; to &lt;code class=&quot;language-text&quot;&gt;my-application&lt;/code&gt;. We&apos;ll also change the configuration name to &apos;my application&apos;.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;json&quot;&gt;&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Use IntelliSense to learn about possible attributes.&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Hover to view descriptions of existing attributes.&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;version&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;0.2.0&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;configurations&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;my application&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;go&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;request&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;attach&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;mode&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;local&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;processId&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;my-application&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;That&apos;s all the configuration we need to do. Now, if you go to the &quot;Run and Debug&quot; view again, you&apos;ll see &quot;my application&quot; in the dropdown.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 606px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/a1c89e0ed39d39934b3ea0b342e5297b/4d4a2/vscode-attach-to-local-process.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 84.66666666666669%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAARCAIAAABSJhvpAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABgklEQVR42p1SW0vDMBjN/3Fza9omabu2a9eml3Xs5q44mY5dUBBUEH3yQRibIPgkivhf/WrGGENEC4c0ab6TnHPyIc2uSrSSw1ZetgGHSllALHOyRc1IdxInbPPaQNZ8+AkjUDDzUPrRfJipeiD2Ug62JOaRUqgQnxkRAKtuEZdl6qkGh6OBBcUImG7U9at9GA23jjUuIOu8Nb2+fP68WL2dr99ny9f500djcsXMCHZVI1B0jkgp9pNh1Dix+ZFiRMSsAqiVyIz7nenobjW8eRzdLkf369OHl3CwwIxDgUQ9iVUQaDiQTABI3VoVymkpjpJju9IiWqTQQGUhphtfBdVJPX/H48BiG5UAkMFFvTdL2mdxaxw3x3bQA2kiVPAMQHucXcCJReKKYAFFsrkgr9ibtCGY3Rfaw9bFXo3pNmuDBSqo7i+X/3yiUnaCTq0/R/9lCjmgV/camcjYIlbsdydZyAAMaRM3o+y0PaHDspOht7PJhvcvZpP9pw77vfkKqvMFY+LrqP44yy0AAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;vscode attach to local process&quot;
        title=&quot;&quot;
        src=&quot;/static/a1c89e0ed39d39934b3ea0b342e5297b/4d4a2/vscode-attach-to-local-process.png&quot;
        srcset=&quot;/static/a1c89e0ed39d39934b3ea0b342e5297b/5a46d/vscode-attach-to-local-process.png 300w,
/static/a1c89e0ed39d39934b3ea0b342e5297b/0a47e/vscode-attach-to-local-process.png 600w,
/static/a1c89e0ed39d39934b3ea0b342e5297b/4d4a2/vscode-attach-to-local-process.png 606w&quot;
        sizes=&quot;(max-width: 606px) 100vw, 606px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Select it and press the play button to it&apos;s left.&lt;/p&gt;
&lt;p&gt;Personally, I use the keyboard shortcut &lt;code class=&quot;language-text&quot;&gt;Ctrl + p&lt;/code&gt; to bring up File Search modal. And then I typ in debug and a &lt;space&gt; character.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 862px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/9e1206c0ce092564c55f18400367ebce/f0551/file-search-debug.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 20%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAIAAAABPYjBAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAmUlEQVR42mPQM3HQMbKzdQm0dws2s/Mxt/c1B5L4kb2vkaWbjpEtg56xvb6ZY1Rpc3LTpNiarqSWKcmtU7GjtmmJTRPjanqSmif7phabWrsz6JnYA82wdQnwCIh18AixcPAxsnLDhQwtXEzsfex8I41tPGyc/IGaHYCW6xrZARHQICCpY2iDA1nrGdtZ2HsamDnomzrqGjsAAL16RGO1iZFZAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;file search debug&quot;
        title=&quot;&quot;
        src=&quot;/static/9e1206c0ce092564c55f18400367ebce/f0551/file-search-debug.png&quot;
        srcset=&quot;/static/9e1206c0ce092564c55f18400367ebce/5a46d/file-search-debug.png 300w,
/static/9e1206c0ce092564c55f18400367ebce/0a47e/file-search-debug.png 600w,
/static/9e1206c0ce092564c55f18400367ebce/f0551/file-search-debug.png 862w&quot;
        sizes=&quot;(max-width: 862px) 100vw, 862px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;h2 id=&quot;things-to-keep-in-mind&quot;&gt;Things to keep in mind&lt;/h2&gt;
&lt;h3 id=&quot;1-building-go-binary-with-debug-symbols&quot;&gt;1. Building go binary with debug symbols&lt;/h3&gt;
&lt;p&gt;For best debugging experience, you need to build the binary with debug symbols. This will turn of compiler optimizations and enable debug symbols.
To do so, you need to pass in the following flag&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;gcflags &lt;span class=&quot;token string&quot;&gt;&quot;all=-N -l&quot;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# example&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# go build -gcflags &quot;all=-N -l&quot; .&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;2-yama&quot;&gt;2. yama&lt;/h3&gt;
&lt;p&gt;By default, Linux kernel will not allow a process to attach to another process if it&apos;s not running as root. Due to this reason, attaching a debugger to our running application will not work.&lt;/p&gt;
&lt;p&gt;To fix this, we need to modify the ptrace scope setting in the Linux kernel&apos;s Yama security module.
The ptrace scope setting determines which processes can use ptrace-based debugging tools on other processes. The value &lt;code class=&quot;language-text&quot;&gt;0&lt;/code&gt; sets it to the least restrictive mode, allowing any process to ptrace any other process.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token function&quot;&gt;sudo&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;su&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; /proc/sys/kernel/yama/ptrace_scope&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Setting this to 0 is often necessary for certain debugging scenarios, including attaching a debugger to a running process. However, it&apos;s important to note that this reduces system security, so it should be used cautiously and typically only in development environments.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Setup DNS Over TLS with systemd-resolved & Next DNS]]></title><description><![CDATA[Setup DNS over TLS with systemd-resolved, NetworkManager and NextDNS]]></description><link>https://www.adityathebe.com/systemd-resolved-dns-over-tls</link><guid isPermaLink="false">https://www.adityathebe.com/systemd-resolved-dns-over-tls</guid><pubDate>Sat, 11 May 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I&apos;ve been using Adguard home for a few years as my DNS resolver.
It runs in a virtual machine in my homelab.
Some of the essential benefits it provides me are&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Adblocking &lt;em&gt;(ofcourse)&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Privacy &lt;em&gt;(I use quad9 and clouflare as the upstream DNS over HTTPS)&lt;/em&gt;. My ISP sees nothing.&lt;/li&gt;
&lt;li&gt;Bypass censorship &lt;em&gt;(unblock &apos;DNS&apos; banned sites in the country)&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Monitoring &lt;em&gt;(Logs &amp;#x26; Usage overview. I don&apos;t use this a lot, but incase I need it - it&apos;s there)&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;DNS overwrites &lt;em&gt;(I use it for a couple of my own websites that I frequently visit)&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1200px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/ad452b49d940dbacef44db16c214b973/ab40b/adguard-home.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 56.666666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAIAAADwazoUAAAACXBIWXMAABCcAAAQnAEmzTo0AAABkklEQVR42l1R2W7cMAz0N+wWK4mHLq98SF6nidMARQukfQgK9P8/qGNvghYdUDYtcsgh3TFzKcN1TLEok1wu5mKNIXsxZvdxPgD3fMfpdHxeOiKKMeTU//j59vbr9zAvJ6ufDCHjngec3+38HzpjbBrWcK2+n50z7GjxcVQlZnUkgTQEUZg6djmx+sjiFSrJdqR9eXjN7SVPj+B71prKFGJVTRhJNcTexyte0Oh9CAl+VtRyIPtrqi9x2mB+fC7EX8g9E31jXoiMswwxbFkcEcwKu92UrDUdTp2nWmdIIefQjA5zO0lCCG1ZYtzb8h3ESBPxxrrOOWrLbRgnKBHBaHdIwhZSEeaUcsLJWQ5A+FinMvSqvrPOXYfalwlh7/0HV0IuEsBKrS3DOCK0lxbJc63b56HmujT8Kreut/W2A/L+Nhd0FdxM04Qn9B5cLgOEPs7jjKKQ7VprtdZSiv4DTKveg1bneSfL0Zi5rU9fv79u29NtXbEwOx64k9+XQhQOQC1Cfd/LLmSPlLGtD1udq/fhD6I2UJ+4e+UBAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;My Adguard Home&quot;
        title=&quot;&quot;
        src=&quot;/static/ad452b49d940dbacef44db16c214b973/c1b63/adguard-home.png&quot;
        srcset=&quot;/static/ad452b49d940dbacef44db16c214b973/5a46d/adguard-home.png 300w,
/static/ad452b49d940dbacef44db16c214b973/0a47e/adguard-home.png 600w,
/static/ad452b49d940dbacef44db16c214b973/c1b63/adguard-home.png 1200w,
/static/ad452b49d940dbacef44db16c214b973/ab40b/adguard-home.png 1736w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;em&gt;My Adguard Home instance&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1200px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/b3e5b04c88797639ee61bb1780cc1a56/7c5b4/adguard-dns-rewrites.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 33%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAIAAACHqfpvAAAACXBIWXMAABCcAAAQnAEmzTo0AAAA00lEQVR42mWQC46EIBBEvQPIQPNHERxZ7n+8LXHcuJkXMNVFV0OcylbqXkIVjDPAOVdELymVUkIKSRISm0jP88wGENpYdE7Lmpdl1UQo4J57Flj8CRufB1c5YYYxVinCVVIR1pBKCHGNOycOIW4+AxE2RnvnvPfW2pSSQT2ACCHAhIaPhssES95QnuEYY2ut977l7e8YIAYfpzChz/fdxLV4H65wOlo7jtZ/es6rvkHT+33gcsK/+ocJKX9uDjHWWksp+77jec8wTOfcd9inDJ8x9gtYzy0NGycC2QAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;DNS Rewrites&quot;
        title=&quot;&quot;
        src=&quot;/static/b3e5b04c88797639ee61bb1780cc1a56/c1b63/adguard-dns-rewrites.png&quot;
        srcset=&quot;/static/b3e5b04c88797639ee61bb1780cc1a56/5a46d/adguard-dns-rewrites.png 300w,
/static/b3e5b04c88797639ee61bb1780cc1a56/0a47e/adguard-dns-rewrites.png 600w,
/static/b3e5b04c88797639ee61bb1780cc1a56/c1b63/adguard-dns-rewrites.png 1200w,
/static/b3e5b04c88797639ee61bb1780cc1a56/7c5b4/adguard-dns-rewrites.png 1309w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;em&gt;DNS Rewrites&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;I have setup my router to use the Adguard Home instance as the upstream DNS server
which means every devices connected to my network get adblocking and censorship bypassing benefits
out of the gate.&lt;/p&gt;
&lt;p&gt;This has been a fantastic solution so far. The only downside here is that when I&apos;m
not on my network I lose all those benefits.&lt;/p&gt;
&lt;p&gt;For this reason, I wanted to look for an alternative DNS solution that would work on whichever network I connect to.
This means I needed a local resolver that would connect to a public DNS server over HTTPs or TLS.&lt;/p&gt;
&lt;h2 id=&quot;systemd-resolved-as-the-resolver&quot;&gt;systemd-resolved as the resolver&lt;/h2&gt;
&lt;p&gt;I had some experience using &lt;code class=&quot;language-text&quot;&gt;systemd-resolved&lt;/code&gt; before, so I looked at it as the first option.
Currently, I have a bare minimum setup where Network manager sets up the DNS server on the machine.&lt;/p&gt;
&lt;p&gt;Fortunately, network manager &amp;#x26; systemd-resolved work together prefectly. The only change I needed
to make on Network manager side was to tell it to use &lt;code class=&quot;language-text&quot;&gt;systemd-resolved&lt;/code&gt; as the DNS resolver&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;cat&lt;/span&gt; /etc/NetworkManager/conf.d/dns.conf

&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;main&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token assign-left variable&quot;&gt;dns&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;systemd-resolved&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;systemd-resolved was also disabled on my machine, so I had to enable it&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;sudo&lt;/span&gt; systemctl &lt;span class=&quot;token builtin class-name&quot;&gt;enable&lt;/span&gt; systemd-resolved
&lt;span class=&quot;token function&quot;&gt;sudo&lt;/span&gt; systemctl start systemd-resolved&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;At this point, &lt;code class=&quot;language-text&quot;&gt;systemd-resolved&lt;/code&gt; was serving the DNS requests.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;cat&lt;/span&gt; /etc/resolv.conf

&lt;span class=&quot;token comment&quot;&gt;# Generated by NetworkManager&lt;/span&gt;
nameserver &lt;span class=&quot;token number&quot;&gt;127.0&lt;/span&gt;.0.53
options edns0 trust-ad&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;configuring-dns-over-tls&quot;&gt;Configuring DNS over TLS&lt;/h2&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;systemd-resolved&lt;/code&gt; doesn&apos;t seem to support DNS over HTTPS (DoH) but it does support
DNS over TLS (DoT) which is fine with me.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;DoH is the preferred option over DoT
since the former is indistinguishable from a normal HTTPs connection whereas the later
is easier to notice &amp;#x26; hence censor because it works on port &lt;code class=&quot;language-text&quot;&gt;853&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;To configure the upstream DNS server, I simply edited systemd-resolved config and
enabled &lt;code class=&quot;language-text&quot;&gt;DNSOverTLS&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;texttitle=&quot;/etc/systemd/resolved.conf&quot;&quot;&gt;&lt;pre class=&quot;language-texttitle=&quot;/etc/systemd/resolved.conf&quot;&quot;&gt;&lt;code class=&quot;language-texttitle=&quot;/etc/systemd/resolved.conf&quot;&quot;&gt;# /etc/systemd/resolved.conf

[Resolve]
DNS=1.1.1.1#cloudflare-dns.com 1.0.0.1#cloudflare-dns.com
DNSOverTLS=yes
Cache=yes&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;troubleshooting-slow-dns-responses&quot;&gt;Troubleshooting slow DNS responses&lt;/h3&gt;
&lt;p&gt;I could tell the DoT was working because I was able to access cencsored sites.
However, the surfing felt noticeably slow. Sites that used to open in few milliseconds
were now taking about 10 seconds (or more) just for the first contentful paint.
Something was off ...&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;sudo&lt;/span&gt; resolvectl log-level debug&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I enabled verbose logging on &lt;code class=&quot;language-text&quot;&gt;systemd-resolved&lt;/code&gt; and then tailed the logs&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;journalctl &lt;span class=&quot;token parameter variable&quot;&gt;-u&lt;/span&gt; systemd-resolved &lt;span class=&quot;token parameter variable&quot;&gt;-f&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I could see a lot of Connection refused error and systemd-resolved would just
use my router as the DNS server.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Connection failure for DNS TCP stream: Connection refused
Retrying transaction 10768.
Cache miss for 0pointer.de IN A
Transaction 10768 for &amp;lt;0pointer.de IN A&gt; scope dns on wlp2s0/*.
Using feature level TLS+EDNS0 for transaction 10768.
Sending query via TCP since UDP isn&apos;t supported or DNS-over-TLS is selected.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/systemd/systemd/issues/18060#issuecomment-803494767&quot;&gt;Reference GH issue&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I checked the status of systemd-resolved and I could see that the network interface
was still pointing to my router as the DNS server even though the global config
was pointing to the cloudflare DNS server.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; resolvectl status

&lt;span class=&quot;token comment&quot;&gt;# This text is altered as I&apos;m now I&apos;m using a private DNS server&lt;/span&gt;

Global
           Protocols: +LLMNR +mDNS +DNSOverTLS &lt;span class=&quot;token assign-left variable&quot;&gt;DNSSEC&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;no/unsupported
    resolv.conf mode: foreign
  Current DNS Server: &lt;span class=&quot;token number&quot;&gt;1.1&lt;/span&gt;.1.1&lt;span class=&quot;token comment&quot;&gt;#cloudflare-dns.com 9.9.9.9#dns.quad9.net 8.8.8.8#dns.google 2606:4700:4700::1111#cloudflare-dns.com 2620:fe::9#dns.quad9.net 2001:4860:4860::8888#dns.google&lt;/span&gt;

Link &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;enp5s0&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    Current Scopes: DNS LLMNR/IPv4 LLMNR/IPv6
Current DNS Server: &lt;span class=&quot;token number&quot;&gt;192.168&lt;/span&gt;.254.254&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I think I just needed to point my lan interface to use the same DNS server.&lt;/p&gt;
&lt;p&gt;I found this section quite confusing. &lt;code class=&quot;language-text&quot;&gt;resolvectl status&lt;/code&gt; shows that my LAN interface
is using my router as the DNS server, however when I make a DNS query, it&apos;s still
served by the cloudflare servers ...&lt;/p&gt;
&lt;p&gt;For now, I&apos;ve configured Network manager IPv4 &amp;#x26; IPv6 method to point the DNS server
to &lt;code class=&quot;language-text&quot;&gt;127.0.0.1&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;nextdns&quot;&gt;NextDNS&lt;/h2&gt;
&lt;p&gt;Cloudflare DNS works pretty well but now I&apos;ve lost some of the benefits I had with an Adguard Home setup.
Mainly, Ad blocking, DNS logs &amp;#x26; privacy (cloudflare still sees all my dns queries although not as big of a deal
as it can&apos;t really point back to my identity).&lt;/p&gt;
&lt;p&gt;I gave NextDNS a try which I suppose is kind of like your own private Adguard Instance on the cloud.
It has a free plan and offers&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;logs&lt;/li&gt;
&lt;li&gt;analytics&lt;/li&gt;
&lt;li&gt;dns rewrites&lt;/li&gt;
&lt;li&gt;safe browsing&lt;/li&gt;
&lt;li&gt;ad blocking&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1200px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/37a010acafbee4a38debed8f96d454b1/203d3/next-dns-analytics.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 71.33333333333334%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAIAAACgpqunAAAACXBIWXMAABCcAAAQnAEmzTo0AAABRElEQVR42o1SB46DMBDkJxTXdcUUXe7/H7uxFwiJIuWkkfGOt87S9aMaFUkbR+Ub3GjigLOZiqLxaZA06tALDQzSTNr2kwY6RArjNAWwg7QwGZOuZ2VOctIOJpyRjpmOP70wlJZ5/2Wn6qfIGq+MHxrDfCy7pghnZrrxfBOmNsmRDJjShsuEg3YJJ5s1GPPAKcybZBa5ThzdfmKebXNNAJdr5v/gmHkQVa0JeCsFnSt556FZEJTBd21PwfoMoHOB2U5I7YxLFGaI9MIj2GC1FjNb7XPeHmn9MT5z/wzkdXmdtwcUgVQX39SyTTCsRDsXCsVyKXmobXzJC+XV59WG+driTW2klzaXHUXE7W0y3lJc8ubLjrz3sJdgRSGU7a0y7tDi+EOa6we1e7iElJfdhpf0HPxlVRCM4uzSgsGgyn2wr2v/Azlyf7ri4kzyAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;NextDNS Analytics&quot;
        title=&quot;&quot;
        src=&quot;/static/37a010acafbee4a38debed8f96d454b1/c1b63/next-dns-analytics.png&quot;
        srcset=&quot;/static/37a010acafbee4a38debed8f96d454b1/5a46d/next-dns-analytics.png 300w,
/static/37a010acafbee4a38debed8f96d454b1/0a47e/next-dns-analytics.png 600w,
/static/37a010acafbee4a38debed8f96d454b1/c1b63/next-dns-analytics.png 1200w,
/static/37a010acafbee4a38debed8f96d454b1/203d3/next-dns-analytics.png 1322w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;em&gt;NextDNS Analytics&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1200px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/be17c043ccab04c4e61ca155c79285da/ce6cc/next-dns-analytics-traffic.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 67%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAIAAAAmMtkJAAAACXBIWXMAABCcAAAQnAEmzTo0AAABV0lEQVR42n2S2U4CQRBF+Qlfh+mtet+YAYIhEZcYTUxMfOHN+GP+q3dAkOBAch96uutU3aqaCVMWaqXRPtf5KuRqQjah4JOT86VP/ZJ8Jp+Ui8IEXO4RaHI8Ce1d6k19cLkLuQMsyIuURMmyZJ4Ti3GQHoNbZVOZzV6+Qr+OtZMmwI5LM2Uj8kKoudc4rG0oS5I20g5AnI49LJBLpylGYDz73EtTjjdD3EnotcrISsZC0kR+MMmkPQb81xF2XKqmPk7zxhlhYgEvyClX0LzQw5CR/QJMA9zOnpvVtll+UFpwjCB2Yb5WJkjSSIG+OI1XBu952zT92832uy0bJqTJ81Dnobul5Sv5Aj+/gxiBdzwTylj8MAmN2Fixc+Urr/c2Zqlo7/ECfEihQ9mN2gKGYcYY757Y3Sds8+swnrHYv23hIHUbV9PFuzghL1QemPPBMkFciLNp/wD6P3n6R5Y8FQAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;NextDNS Analytics Traffic&quot;
        title=&quot;&quot;
        src=&quot;/static/be17c043ccab04c4e61ca155c79285da/c1b63/next-dns-analytics-traffic.png&quot;
        srcset=&quot;/static/be17c043ccab04c4e61ca155c79285da/5a46d/next-dns-analytics-traffic.png 300w,
/static/be17c043ccab04c4e61ca155c79285da/0a47e/next-dns-analytics-traffic.png 600w,
/static/be17c043ccab04c4e61ca155c79285da/c1b63/next-dns-analytics-traffic.png 1200w,
/static/be17c043ccab04c4e61ca155c79285da/ce6cc/next-dns-analytics-traffic.png 1551w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;em&gt;NextDNS Traffic Analytics&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;I updated &lt;code class=&quot;language-text&quot;&gt;systemd-resolved&lt;/code&gt; &amp;#x26; &lt;code class=&quot;language-text&quot;&gt;networkd&lt;/code&gt; configs to use my private next dns resolver.&lt;/p&gt;
&lt;p&gt;So far it looks amazing! Although I&apos;m not sure if the 300k req/mo is going to be sufficient for me.
I guess we will find out ...&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Flying with NixOS]]></title><description><![CDATA[My NixOS Proxmox VM is ready to fly!]]></description><link>https://www.adityathebe.com/journal/8</link><guid isPermaLink="false">https://www.adityathebe.com/journal/8</guid><pubDate>Sat, 09 Mar 2024 14:30:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;nixos-setup-progress&quot;&gt;NixOS setup progress&lt;/h2&gt;
&lt;p&gt;So I finally fixed the &lt;a href=&quot;/journal/7&quot;&gt;previous issue&lt;/a&gt; with NixOS. I now have a remote NixOS vm that&apos;s just sufficiently configured to do
some actual development work. I haven&apos;t really done any development yet because the VM only has 2GB of RAM and my proxmox machine is maxed out in memory.
I ran some go builds and it took a while but it was a success.&lt;/p&gt;
&lt;p&gt;I do notice some occasional lags while I&apos;m ssh&apos;ing into the vm. There&apos;s about 1% packet loss which is a lot! It could be because I have 4 different wifi networks at home!&lt;/p&gt;
&lt;p&gt;I&apos;ll try to bump the RAM this week and maybe get an ethernet dongle and that should be enough to get a good stable connection to the VM.&lt;/p&gt;
&lt;h2 id=&quot;upgrade-immich&quot;&gt;Upgrade Immich&lt;/h2&gt;
&lt;p&gt;On my &lt;a href=&quot;https://github.com/adityathebe/homelab&quot;&gt;homelab&lt;/a&gt;, I run an Immich server. It&apos;s the single most important application that I host. If you&apos;re unfamiliar with it, it&apos;s basically a self hosted Google Photos alternative.&lt;/p&gt;
&lt;p&gt;The application is really really good but it&apos;s still in its early development phase and introduces breaking changes often. They do have very good notes on every release though and I haven&apos;t really faced any problem upgrading it so far. Except, this time I did.&lt;/p&gt;
&lt;p&gt;For some reason, I happen to be running postgres 16 while the recommended version is 14. The recent breaking release needed me to upgrade from 14.1 to 14.2 and that&apos;s when I realized I was running the wrong version of Postgres this whole time. There where some hiccups but I don&apos;t exactly remember what it was. It had something to do with the pg_vector extension. Something about that extension was changed in the Postgres 16 release.&lt;/p&gt;
&lt;p&gt;It took a while - about 30 minutes, I think - but I managed to get it up and running. I&apos;m still on postgres 16 though.&lt;/p&gt;
&lt;h2 id=&quot;dune-two&quot;&gt;Dune Two&lt;/h2&gt;
&lt;p&gt;I watched Dune Two in theater and it was soo soo good! I had very little expectation going in since I didn&apos;t really enjoy the first one.&lt;/p&gt;
&lt;p&gt;I had almost entirely forgotten anything about Dune. 30 minutes before the movie, I watched a YouTube refresher video and that made such a huge difference!
I rate the movie &lt;code class=&quot;language-text&quot;&gt;9/10&lt;/code&gt; or even &lt;code class=&quot;language-text&quot;&gt;10/10&lt;/code&gt; if I&apos;m being generous. The next day I watched Dune, the first part again, and that was equally as good. I can&apos;t wait to watch the next part.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I keep a log of all the movies I watch in &lt;a href=&quot;https://movies.adityathebe.com/users/adityathebe/dashboard&quot;&gt;Movary&lt;/a&gt;. Check it out.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;learning-rust&quot;&gt;Learning Rust&lt;/h2&gt;
&lt;p&gt;I gave Rust a shot this week. Before this, my only experience ever writing Rust was when I was applying for a role at &lt;a href=&quot;https://fly.io&quot;&gt;fly.io&lt;/a&gt;. It was about a 100 lines of code and pretty much just unit tests.&lt;/p&gt;
&lt;p&gt;I basically followed the official &lt;a href=&quot;https://doc.rust-lang.org/book/&quot;&gt;Rust book&lt;/a&gt; and got through the first 2 chapters. It was actually quite straightforward. Probably because I didn&apos;t get into the exciting part of Rust yet.&lt;/p&gt;
&lt;p&gt;Actually, the use of traits in the guessing game chapter was confusing now that I remember it. I still don&apos;t get it but I think I&apos;m supposed to not get it just yet.&lt;/p&gt;
&lt;p&gt;Macros seemed really cool. I don&apos;t understand what the &lt;code class=&quot;language-text&quot;&gt;println!&lt;/code&gt; macro offers over a &lt;code class=&quot;language-text&quot;&gt;print&lt;/code&gt; function. What can that macro possibly generate at compile time that it makes it more efficient than a function? And the use of macros in &lt;a href=&quot;https://github.com/launchbadge/sqlx&quot;&gt;sqlx&lt;/a&gt; was mind blowing!
The fact that the library performs sql calls during compile time to guarantee that the sql queries are correct was something I had never heard before! There&apos;s so much happening during compile time and as a Go programmer, the compile time in Rust scares me.&lt;/p&gt;
&lt;p&gt;I have heard that macros were quite complex and people don&apos;t really use it but that doesn&apos;t seem to be the case since there&apos;s a whole sql library that essentially works at the macro level. Also, &lt;a href=&quot;https://www.youtube.com/watch?v=MWRPYBoCEaY&quot;&gt;No Boilerplate&lt;/a&gt; seems to really love it!&lt;/p&gt;
&lt;h2 id=&quot;mapping-caps-key-to-ctrl&quot;&gt;Mapping CAPS key to CTRL&lt;/h2&gt;
&lt;p&gt;I have mapped my CAPS key to the Control key. A lot of people map it to the Escape key as well. The reason behind this is that the CAPS key is much more accessible than the ctrl key; it&apos;s right below your left pinky and on the home row. Commonly used key chords like &lt;code class=&quot;language-text&quot;&gt;Ctrl+C&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;Ctrl+V&lt;/code&gt; are easier to press.&lt;/p&gt;
&lt;p&gt;This is definitely going to take me some time to get used to it. In fact, I had even forgotten that I had this mapping turned on yesterday and just remembered it while writing about it.&lt;/p&gt;
&lt;p&gt;I used &lt;code class=&quot;language-text&quot;&gt;xmodmap&lt;/code&gt; to setup the mapping. It required me to create a &lt;code class=&quot;language-text&quot;&gt;~/.xmodmap&lt;/code&gt; file with instructions for the mapping. It wasn&apos;t quite comprehensive because you need to deal with key codes and key symbols. Undoing the map was also a pain because xmodmap doesn&apos;t keep a state of the mapping.&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;setxkbmap&lt;/code&gt; seems to be the modern and user-friendly way of doing it. I was able to reset the mapping I had messed up using &lt;code class=&quot;language-text&quot;&gt;setxkbmap -option us&lt;/code&gt;.
And then the actual mapping is done using&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;setxkbmap &lt;span class=&quot;token parameter variable&quot;&gt;-option&lt;/span&gt; ctrl:ctrl_modifier&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This line goes into my &lt;code class=&quot;language-text&quot;&gt;~/.xinitrc&lt;/code&gt; file.&lt;/p&gt;
&lt;h2 id=&quot;building-an-http-server-from-scratch---codecrafters&quot;&gt;Building an HTTP server from scratch - CodeCrafters&lt;/h2&gt;
&lt;p&gt;I came to know about CodeCrafters through &lt;a href=&quot;https://thesquareplanet.com/&quot;&gt;Jon Gjengset&lt;/a&gt;. It has a handful of catalogs where you build popular softwares like Redis, Git, etc from scratch.&lt;/p&gt;
&lt;p&gt;I tried the &lt;a href=&quot;https://app.codecrafters.io/courses/http-server/overview&quot;&gt;Building HTTP server&lt;/a&gt; course and it was quite fun. I din&apos;t really like that there were hints just below the course. I want to struggle and find the solution myself. Sometimes you just scroll down and accidentally see a comment that gives you some hint about the solution.&lt;/p&gt;
&lt;p&gt;Besides that, the platform looks really good. I&apos;ll probably do a stream in future with one of the courses.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Developing on a NixOS VM in Neovim]]></title><description><![CDATA[I did a lot of neovim work this week.]]></description><link>https://www.adityathebe.com/journal/7</link><guid isPermaLink="false">https://www.adityathebe.com/journal/7</guid><pubDate>Sat, 02 Mar 2024 12:40:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;website-updates&quot;&gt;Website updates&lt;/h2&gt;
&lt;p&gt;I added 2 new pages to my website &amp;#x26; also exposed my movary instance.&lt;/p&gt;
&lt;h3 id=&quot;now&quot;&gt;/now&lt;/h3&gt;
&lt;p&gt;I&apos;ve been seeing a &lt;a href=&quot;/now&quot;&gt;/now&lt;/a&gt; page in quite a few blogs these days. The /now page, unlike the /about page, is more frequently
updated.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;/now is a more personal look at what people are doing right now, what they care about, and what they could use help with.&lt;/p&gt;
&lt;p&gt;- &lt;a href=&quot;https://aboutideasnow.com/about&quot;&gt;https://aboutideasnow.com/about&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;links&quot;&gt;/links&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;/links&quot;&gt;/links&lt;/a&gt; is another page that&apos;s quite common these days. People put all kinds of things in their /links page - like links
to podcasts they listen to, their favorite books or blogs, etc.&lt;/p&gt;
&lt;p&gt;I&apos;m not quite sure what I should put in here but I mainly added this page to share the &lt;a href=&quot;%22https://movies.adityathebe.com/users/adityathebe/dashboard%22&quot;&gt;movary&lt;/a&gt;
instance. It&apos;s a web app that&apos;s currently running on my homelab but exposed to the internet via Cloudflare Tunnel.&lt;/p&gt;
&lt;h2 id=&quot;developing-on-a-vm&quot;&gt;Developing on a VM&lt;/h2&gt;
&lt;p&gt;I&apos;ve been wanting to develop on a VM for a over two years now. The goal is to have a beefy desktop
at home and ssh into it for all development purpose from my laptop.&lt;/p&gt;
&lt;p&gt;Developing on a VM means you can have a fairly basic laptop and still run huge projects.
It can be kept in one corner of your house so you don&apos;t have to deal with noise.
And remote development shouldn&apos;t be problem with Tailscale.&lt;/p&gt;
&lt;p&gt;What about when I&apos;m working away from home and there&apos;s a power outage? Who&apos;s gonna turn the PC back on?
Well, turns out you can configure the BIOS to automatically turn on when there&apos;s power.
You don&apos;t need to login because systemd turns on the ssh daemon automatically.
This is how one of my coworkers used to work.&lt;/p&gt;
&lt;p&gt;My laptop is getting old now and its fans are driving me nuts.
The keyboard also gets quite hot but I rarely use it.
A thin fanless laptop with a good battery backup developing off of a
beefy nixos vm would be my dream setup for now.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Mt.lynch&apos;s homelab for all developerment
&lt;a href=&quot;https://mtlynch.io/building-a-vm-homelab/&quot;&gt;https://mtlynch.io/building-a-vm-homelab/&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;blockquote class=&quot;twitter-tweet&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;&amp;quot;Between VSCode, WSL, and Intel’s latest desktop chips, I’ve been living with a PC that runs my programming tests faster than an M3 Max, and generally feels like a completely viable alternative to macOS.&amp;quot; &lt;a href=&quot;https://t.co/tP4UQNk1Ss&quot;&gt;https://t.co/tP4UQNk1Ss&lt;/a&gt;&lt;/p&gt;&amp;mdash; DHH (@dhh) &lt;a href=&quot;https://twitter.com/dhh/status/1761830698758066298?ref_src=twsrc%5Etfw&quot;&gt;February 25, 2024&lt;/a&gt;&lt;/blockquote&gt; &lt;script async src=&quot;https://platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;nixos&quot;&gt;Nixos&lt;/h2&gt;
&lt;p&gt;I learned about NixOS a few weeks ago and I&apos;ve wanted to migrate to it ever since.
It&apos;s not the most friendly OS and it has the worst in the business error messages.&lt;/p&gt;
&lt;p&gt;To test developing on a VM, I wanted to deploy it in a proxmox vm and see how
that turns out. However, &lt;a href=&quot;https://discourse.nixos.org/t/error-secret-key-is-corrupt-when-building-flake/40440&quot;&gt;I haven&apos;t been able to deploy it&lt;/a&gt;
and no one seems have the solution to the issue. Installing it is fine but migrating to flakes is where I&apos;m stuck right now.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://mtlynch.io/notes/nix-first-impressions/&quot;&gt;https://mtlynch.io/notes/nix-first-impressions/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;self-hosting-podcast&quot;&gt;Self Hosting Podcast&lt;/h2&gt;
&lt;p&gt;I installed AudioBookShelf this week to be my ultimate Podcast player. It looked
great at first but turned out it has some fatal issues.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Can&apos;t browse the episodes.&lt;/p&gt;
&lt;p&gt;ABS is fully local. That means discovering new podcasts through it is not possible.
While I can search for podcasts I can&apos;t really see/listen to the episodes without
first subscribing and then manually downloading episodes.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;You can&apos;t download episodes from mobile&lt;/p&gt;
&lt;p&gt;This was the fatal flaw that turned me away from ABS. If you add a podcast, it&apos;ll only download
future episodes! You have to configure it to download past episodes. And worse,
that&apos;s not possible from the mobile app.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Doesn&apos;t have an iOS app right now.&lt;/p&gt;
&lt;p&gt;There&apos;s a beta release but it&apos;s over the limit.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I have installed AntennaPod which I think will be my ultimate player.
I&apos;ll also try out podfetch or podgrab next week.&lt;/p&gt;
&lt;h2 id=&quot;neovim&quot;&gt;Neovim&lt;/h2&gt;
&lt;p&gt;This week I got a lot done with neovim. I did two days of development entirely
on Neovim. It&apos;s fun but I&apos;m still not as productive with it as I am with VSCode.
But, I certainly feel much more comfortable now. In fact, I&apos;m writing this journal in
Neovim right now.&lt;/p&gt;
&lt;h3 id=&quot;things-vscode-does-better&quot;&gt;Things VSCode does better&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Find and replace from all files in the workspace&lt;/li&gt;
&lt;li&gt;Multi cursor&lt;/li&gt;
&lt;li&gt;AI code completion&lt;/li&gt;
&lt;li&gt;Discovering new plugins&lt;/li&gt;
&lt;li&gt;Installing new plugins&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;vimimum-browser-extension&quot;&gt;Vimimum browser extension&lt;/h3&gt;
&lt;p&gt;This is an extension that lets you use vim bindings on your browser. I had tried
this before but didn&apos;t like it as it interferes with your normal keybindings. Example:
on YouTube, pressing &quot;F&quot; doesn&apos;t go full screen anymore. You have to get into
the &quot;Insert mode&quot; and then press F. Also, the &quot;Insert mode&quot; has a floating bar on the
bottom left panel that stays up when you&apos;re in insert mode; so after you press F you
need to exit out of the insert mode again.&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;Ctrl+C&lt;/code&gt; to copy also doesn&apos;t work in visual mode as that&apos;s default for ESC binding. I&apos;ve now
disabled vimimium on youtub.com.&lt;/p&gt;
&lt;p&gt;It&apos;s been an ok experience so far &amp;#x26; it doesn&apos;t get in your way most of the time
so I&apos;m going to continue using it.&lt;/p&gt;
&lt;h3 id=&quot;vim-setup-series-by-typecraft&quot;&gt;Vim setup series by TypeCraft&lt;/h3&gt;
&lt;p&gt;Watched this really good series by TypeCraft. The guy&apos;s really funny and you should
check him out.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/playlist?list=PLsz00TDipIffreIaUNk64KxTIkQaGguqn&quot;&gt;https://www.youtube.com/playlist?list=PLsz00TDipIffreIaUNk64KxTIkQaGguqn&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&quot;vim-plugins--exploration&quot;&gt;Vim Plugins &amp;#x26; exploration&lt;/h3&gt;
&lt;h4 id=&quot;better-escape-is-pretty-cool&quot;&gt;Better escape is pretty cool&lt;/h4&gt;
&lt;p&gt;When I was starting out with vim, getting out of the insert mode was a pain
because I had to press &lt;code class=&quot;language-text&quot;&gt;ESC&lt;/code&gt; key which isn&apos;t very accessible. You need to lift your hand
for that and I&apos;m realizing that this sounds like a first-world problem while I&apos;m writing it.
Nonetheless, it&apos;s still a problem.&lt;/p&gt;
&lt;p&gt;Then I started using &lt;code class=&quot;language-text&quot;&gt;Ctrl+C&lt;/code&gt; which is much more easier but still not the best
keymapping.&lt;/p&gt;
&lt;p&gt;This week I found out about &lt;a href=&quot;https://github.com/max397574/better-escape.nvim&quot;&gt;better escape&lt;/a&gt;
which lets you exit insert mode by pressing &lt;code class=&quot;language-text&quot;&gt;jj&lt;/code&gt; in quick succession.
AstroNvim ships this plugin be default so I got it for free.&lt;/p&gt;
&lt;p&gt;This was definitely my favorite vim finding of the week.&lt;/p&gt;
&lt;h4 id=&quot;telescope-for-other-stuffs&quot;&gt;Telescope for other stuffs&lt;/h4&gt;
&lt;p&gt;I use telescope for finding files and greping files but it seems to have lot of other
cool use cases.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;&amp;lt;leader&gt;gt&lt;/code&gt; for git status and easier access to the diffs on the right panel&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;&amp;lt;leader&gt;gb&lt;/code&gt; to show all the git branches was coool&lt;/li&gt;
&lt;li&gt;similary, &lt;code class=&quot;language-text&quot;&gt;&amp;lt;leader&gt;gc&lt;/code&gt; to show all the git commits was also pretty nice.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;preventing-logictech-from-waking-up&quot;&gt;Preventing logictech from waking up&lt;/h2&gt;
&lt;p&gt;I have a MX Master mouse which has a USB dongle that needs to be plugged in to my
laptop for wireless connection. It&apos;s been a pain so far to remember to plug it out
when I suspend my laptop because it wakes the computer.&lt;/p&gt;
&lt;p&gt;I added this udev rule and now all&apos;s good.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://wiki.archlinux.org/title/Udev#Waking_from_suspend_with_USB_device&quot;&gt;https://wiki.archlinux.org/title/Udev#Waking_from_suspend_with_USB_device&lt;/a&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token assign-left variable&quot;&gt;ACTION&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;add&quot;&lt;/span&gt;, &lt;span class=&quot;token assign-left variable&quot;&gt;SUBSYSTEM&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;usb&quot;&lt;/span&gt;, &lt;span class=&quot;token assign-left variable&quot;&gt;DRIVERS&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;usb&quot;&lt;/span&gt;, ATTRS&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;idVendor&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;046d&quot;&lt;/span&gt;, &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  ATTRS&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;idProduct&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;c548&quot;&lt;/span&gt;, ATTR&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;power/wakeup&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;disabled&quot;&lt;/span&gt;, ATTR&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;driver/1-1.1.1.4/power/wakeup&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;disabled&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;bcrypt-72-bytes-limit&quot;&gt;Bcrypt 72 bytes limit&lt;/h2&gt;
&lt;p&gt;When I saw this tweet, my immediate reaction was that this limitation is probably
coming from the &lt;code class=&quot;language-text&quot;&gt;VARCHAR(72)&lt;/code&gt; field on the database and that sha256 hashing
the password before bcrypting it would solve it.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 889px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/1cd1833966e4b47c8e886b0bc7ae33c2/83e77/password-length-limit.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAYAAADkmO9VAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAB0UlEQVR42p1TCW7bMBDM/z9XpLFbu02BxLEk6pZsydZB7nSWkmIlRQCjBMZ7kcPVcvwALmsdRMTDOcFoLQT/tx7053A44vHbE3Y/9tg8bnF8fQPGETIMd0H33gjZlT2dMFQ1htMZI325XoEZa/8zfK3rIHqG1hMK2R0TRV0jjAxMnCCIIpgk9jaKDUITs6b+lDNqjUFEBPQvVQVcLnOHznnCoWnQkbSnv6Cr1X7M9bpnQVl6a4sC8k7I5c5nCAtCUt++xouvVuMl384xwdeENuTnKLIizHPYwytcEMDxMxRW/TCEfTvCHie4YLZpCmF3Moz+QiX98MquKqfNJLEkcVnmD7m68pfpYR/nBVySTnX9THZtOVNoh2tC4etaDtcmCW0C6Xuvw0WbfqkVuU+H1t2ELXO8LOWwo73V1/h86UKoUnna/MR34vnPC3b739hs99hS6Ltfz8jz8v5/irIXZYUkzZFxRoq8KJFwTqnmshwVRV9RQh5rn6iJLCuo8+tEOHCguqnk4EM+iFHhqmhp41gFHc6xmeuzNWojH6e8tG1nHY6cj5K1bYsTH+d8nnBa7Cr3T41oKBs93/D8+wy7rueGxt/SNO3XaL/KNdS49YR/Aa2kiEq1VKWyAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;password length limit&quot;
        title=&quot;&quot;
        src=&quot;/static/1cd1833966e4b47c8e886b0bc7ae33c2/83e77/password-length-limit.png&quot;
        srcset=&quot;/static/1cd1833966e4b47c8e886b0bc7ae33c2/5a46d/password-length-limit.png 300w,
/static/1cd1833966e4b47c8e886b0bc7ae33c2/0a47e/password-length-limit.png 600w,
/static/1cd1833966e4b47c8e886b0bc7ae33c2/83e77/password-length-limit.png 889w&quot;
        sizes=&quot;(max-width: 889px) 100vw, 889px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;
&lt;em&gt;Source &lt;a href=&quot;https://x.com/_JohnHammond/status/1762360967844012418&quot;&gt;https://x.com/_JohnHammond/status/1762360967844012418&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Interestingly, there was a different genuine reason behind it.&lt;/p&gt;
&lt;p&gt;I learned that bcrypt has a 72 bytes input limit! If your password is longer than that
then the remaining bytes are simply discarded.&lt;/p&gt;
&lt;p&gt;Sha256 hashing beforehand doesn&apos;t help because it outputs 256 bits (just 32 bytes) and the 72 bytes
entropy that your password initially had gets reduced tremendously. &lt;a href=&quot;https://stackoverflow.com/a/16597402&quot;&gt;https://stackoverflow.com/a/16597402&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Whether the reduction is significant or not, it certainly doesn&apos;t help those
who want to use long passwords.&lt;/p&gt;
&lt;h2 id=&quot;vitess&quot;&gt;Vitess&lt;/h2&gt;
&lt;p&gt;I watched this really interesting &lt;a href=&quot;https://youtu.be/qTwDfW_T7Bg?si=wbNj4mTiSeQixAEc&amp;#x26;t=2502&quot;&gt;interview with Sugu Sougoumarane&lt;/a&gt;
where they talk about Vitess - a mysql proxy that enables horizontal scaling with sharding.&lt;/p&gt;
&lt;h3 id=&quot;interesting-bit&quot;&gt;Interesting bit:&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;At the &lt;code class=&quot;language-text&quot;&gt;42&lt;/code&gt; minute mark, he says that YouTube was initally built outside of the Google
Monorepo and then the YouTube build was pulling code from his laptop&apos;s home directory (which
was mounted to Google storage).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Vitess got its name from a japanese Anime. The word itself is derived from the
French word &quot;Vitesse&quot; (meaning speed).&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;devops-reimagined&quot;&gt;DevOps Reimagined&lt;/h2&gt;
&lt;p&gt;System Initiative is a company that&apos;s rethinking devops. Not sure how much I&apos;m
buying into it but it definitely looked interesting.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=zyEOYl23pd8&amp;#x26;t=252s&amp;#x26;pp=2AH8AZACAQ%3D%3D&quot;&gt;https://www.youtube.com/watch?v=zyEOYl23pd8&amp;#x26;t=252s&amp;#x26;pp=2AH8AZACAQ%3D%3D&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I think their greatest asset is their mock up of cloud services like AWS for instance.
You can run your infra in their mockup as a precheck before deploying which tremendously
speeds up the feedback loop and makes testing changes much much faster &amp;#x26; safer.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[All about Git & Unix]]></title><description><![CDATA[This week I share a couple of new things that I learned about Git]]></description><link>https://www.adityathebe.com/journal/6</link><guid isPermaLink="false">https://www.adityathebe.com/journal/6</guid><pubDate>Sat, 24 Feb 2024 23:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I can&apos;t believe it&apos;s been 3 years since my last weekly journal! It felt more like a year. Anyways, here&apos;s what I&apos;ve learned so far this week.&lt;/p&gt;
&lt;h2 id=&quot;git&quot;&gt;Git&lt;/h2&gt;
&lt;h3 id=&quot;git-configs&quot;&gt;Git configs&lt;/h3&gt;
&lt;p&gt;This week I added a tonne to my &lt;a href=&quot;https://github.com/adityathebe/dotfiles/blob/0b0df993ce09fad38ca3ea45cc86a04209e059c3/.config/git/config&quot;&gt;git config&lt;/a&gt; and it all started when I read &lt;a href=&quot;https://jvns.ca/blog/2024/02/16/popular-git-config-options/&quot;&gt;this blog post&lt;/a&gt; by Julia Evans. While I enjoyed a lot of those, my favorite one was&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;[push]
	autoSetupRemote = true
	default = current&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;At work, I spin off git branches every time. Small fixes, chores &amp;#x26; features are all in their own branch. The first time you push a new branch to the remote, you need to set the upstream&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;git push -u origin &amp;lt;new-branch&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You&apos;re used to just doing &lt;code class=&quot;language-text&quot;&gt;git push&lt;/code&gt; and it&apos;s annoying to see this error every once in a while. With the above config, your new local branch is automatically mapped to a remote branch with the same name!&lt;/p&gt;
&lt;h3 id=&quot;inside-git&quot;&gt;Inside git&lt;/h3&gt;
&lt;p&gt;It always helps to know your tools better!&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://jvns.ca/blog/2024/01/26/inside-git/&quot;&gt;https://jvns.ca/blog/2024/01/26/inside-git/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://youtu.be/hZS96dwKvt0?si=bbAaaeBx5yh6TGTp&quot;&gt;https://youtu.be/hZS96dwKvt0?si=bbAaaeBx5yh6TGTp&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;scott-chacons-awesome-talk-on-git&quot;&gt;Scott Chacon&apos;s awesome talk on git&lt;/h3&gt;
&lt;p&gt;Scott Chacon is the co-founder of GitHub who&apos;s currently working on GitButler. His &lt;a href=&quot;https://youtu.be/aolI_Rz0ZqY?si=vMju8wAUwQnA3JpN&quot;&gt;talk on git at FOSDEM 2024&lt;/a&gt; is honestly one of my favorite tech talks. I just love geeks (or nerd ... what&apos;s the difference?) who are also great at public speaking and add a lot of humor 😁. The information/duration density in this video is pretty high!&lt;/p&gt;
&lt;p&gt;I&apos;m not gonna write a lot about it here as I highly suggest you to watch the video but here are some of the highlights&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Git branch better &lt;a href=&quot;https://gist.github.com/schacon/e9e743dee2e92db9a464619b99e94eff&quot;&gt;https://gist.github.com/schacon/e9e743dee2e92db9a464619b99e94eff&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Force with lease &lt;em&gt;(&lt;code class=&quot;language-text&quot;&gt;git push --force&lt;/code&gt; but better)&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;salaries-made-public&quot;&gt;Salaries made public&lt;/h2&gt;
&lt;p&gt;A list of compensation history of software engineers.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://xeiaso.net/salary-transparency/&quot;&gt;https://xeiaso.net/salary-transparency/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://tomwithers.dev/salary&quot;&gt;https://tomwithers.dev/salary&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.heyal.co.uk/income/&quot;&gt;https://blog.heyal.co.uk/income/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://brunty.me/salary/&quot;&gt;https://brunty.me/salary/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://thorlaksson.com/salary/&quot;&gt;https://thorlaksson.com/salary/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://carol.gg/salary/&quot;&gt;https://carol.gg/salary/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.jvt.me/salary/&quot;&gt;https://www.jvt.me/salary/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I found out all these websites (except Xe Iaso&apos;s) through &lt;a href=&quot;https://jvt.me&quot;&gt;jvt.me&lt;/a&gt; who I discovered through the &lt;a href=&quot;https://changelog.com/friends/31&quot;&gt;Changelog podcast&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I think it&apos;s pretty cool but I&apos;m not sure if I&apos;ll ever do it myself. 1% of me thinks it&apos;s interesting to share but the other 99% thinks that this will do more harm than good.&lt;/p&gt;
&lt;h2 id=&quot;ssh-signing-key&quot;&gt;SSH Signing key&lt;/h2&gt;
&lt;p&gt;I recently added a new GPG key as a signing key to my GitHub account. If you&apos;re not aware of this, &lt;code class=&quot;language-text&quot;&gt;git&lt;/code&gt; has a feature to sign a commit which tells that the commit made from your email was actually made by you. Otherwise, I can just as easily set the commiter&apos;s email to YOUR email in my git config and and then push that commit to GitHub and GitHub will associate that commit to your account. By signing the commit, I can guarantee that the commit was made by me.&lt;/p&gt;
&lt;p&gt;Once you configure the signing key locally in git, you also need to tell GitHub that you&apos;re gonna be signing with that key. Once that&apos;s setup, GitHub will show &quot;verified&quot; status in the commit history.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1200px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/9d00752be8667c6bd77473b04ec3af27/b5a09/github-verified-commits.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 59.00000000000001%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAIAAADtbgqsAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABRElEQVR42m2S6XKEIBCE/Z9VDuUcBPFYtTbJ+z9eWq0ku6tVXRSCzXzTULh2iP1SClNJ+yd8XgpbQhFvPEZWu0JT9mna9ri5cX1j6oOpSyd2hQqhm03oQ55rEwuc0eY5DitWQQH5OGIRv17XbwxrHJMOc5i98Z3yXWMTeAADPbfwJmbA7LkizLfKwKbujoJowezC4gFfSXMyO662njdzY+O4fOfpkadPJBe6O7rAcZayooGrUL7ycyJpgtShhJkp0mHQPivXgQfMgD/EGl/JUwv1/7yoNcU8Iz1KE9LSLr2Vesd2XmiSKuzYpk3DEvu17RefRvhtO9SmPdsOcfJix97M0sY0PeBEwxhhpnSvXd6fir4IzHv5ZE7d/JX6NY3rERiE8F3odZiEbqtXBFSW9teMVBT1er/n0w27SpyeqoRsuT/hHzEvP0JjXXDuAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;Verified commits in Github&quot;
        title=&quot;&quot;
        src=&quot;/static/9d00752be8667c6bd77473b04ec3af27/c1b63/github-verified-commits.png&quot;
        srcset=&quot;/static/9d00752be8667c6bd77473b04ec3af27/5a46d/github-verified-commits.png 300w,
/static/9d00752be8667c6bd77473b04ec3af27/0a47e/github-verified-commits.png 600w,
/static/9d00752be8667c6bd77473b04ec3af27/c1b63/github-verified-commits.png 1200w,
/static/9d00752be8667c6bd77473b04ec3af27/b5a09/github-verified-commits.png 1360w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;
&lt;em&gt;Verified commits in Github&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;What I didn&apos;t know was that you can use a &lt;strong&gt;SSH key&lt;/strong&gt; to sign commits. This means I can use the same SSH Key to both authenticate &amp;#x26; sign commits. The benefit of this is, to me, is simply that I just have one key to maintain &amp;#x26; I can delete the GPG key.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://news.ycombinator.com/item?id=32835335&quot;&gt;People seem to not like the idea of using SSH keys to sign though&lt;/a&gt; as ssh keys are supposed to be ephemeral while the signing keys are supposed to be long lived. But no one says you can&apos;t keep your ssh keys for a long term.&lt;/p&gt;
&lt;h2 id=&quot;unix-magic-in-unicorn&quot;&gt;Unix Magic in Unicorn&lt;/h2&gt;
&lt;p&gt;I finally caught up to this &lt;a href=&quot;https://youtu.be/DGhlQomeqKc?si=0IK1YwHhbM4JMr9g&quot;&gt;video on Unix Magic by Thorsten Ball&lt;/a&gt;. It&apos;s being sitting on my YouTube&apos;s &quot;Watch later&quot; playlist for a while now.&lt;/p&gt;
&lt;p&gt;In this video, he talks about multi process workers in the Unicorn web server. Things I learned&lt;/p&gt;
&lt;h3 id=&quot;ipc-inter-process-communication-through-unix-pipe&quot;&gt;IPC (inter process communication) through Unix Pipe:&lt;/h3&gt;
&lt;p&gt;As a Linux user, I interact with unix pipes numerous times daily. But I never imagined that it was a common way to communicate between processes.&lt;/p&gt;
&lt;h3 id=&quot;sockets--select&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;sockets&lt;/code&gt; &amp;#x26; &lt;code class=&quot;language-text&quot;&gt;select&lt;/code&gt;:&lt;/h3&gt;
&lt;p&gt;Sockets are one of the fundamental features to working with anything networking related in UNIX. Life cycle of sockets&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;socket&lt;/li&gt;
&lt;li&gt;bind&lt;/li&gt;
&lt;li&gt;listen&lt;/li&gt;
&lt;li&gt;accept&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;select&lt;/code&gt; seems to be very similar to the &lt;code class=&quot;language-text&quot;&gt;select&lt;/code&gt; keyword in Go. In fact, Go might have probably derived the term from Unix. Basically, a &lt;code class=&quot;language-text&quot;&gt;select&lt;/code&gt; syscall allows us to accept from multiple sockets. i.e. if you have multiple sockets, &lt;code class=&quot;language-text&quot;&gt;accept&lt;/code&gt; on of the sockets blocks until it receives a message. No other sockets can be accept at the same time and &lt;code class=&quot;language-text&quot;&gt;select&lt;/code&gt; enables exactly that.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1200px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/13d9483dd5008f4cf14d2a5bf42cc697/0d98f/ruby-sockets-select.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 68.33333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAIAAACgpqunAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABn0lEQVR42o2SW2/TQBCF/a+Bh/LQBNQABUqEySMSImmSprbXe5/dtffm/C3GsZBABavSsdey9/OZObNFTNmHuN3dV1UNYDQY0tLTY9U0RCpNGa8bwoXE58eqPj6c8FPX+5QHBAtcQkyr1erq6vW6LMvN5u3NzfVi8e79h/XX8nqx/Hx3t1y+uf346cXLV1/W6/LbBozNw3mEwRjrg+i9kIpVzEIHBN/1ISTvfPARf42loVzXW9fhPcaE5AjXNWm5uq9byqU1TikD4KjtgvMROt/5mIf0tyZyhDVYY5zUBm1yOud8TpftaRgi1vbH1qcqWkq5cSdlWioEUZJqWctWmYCe2o3OszDDME9NK7Wdkg8p9Sljq9hu+N3ev2EFDowLMU4Vjl2lS2MXpfmylelrwjDG0XYMNnkfeh+nhFFzcMpZayMUIIbjUdbpy1ExtgPrxsHMwHgxZUXDKZMMLCUUqGRccqGE1L2bhYXSFdZNOQ665QLAgjaTOVaEwvP0PxX7/YFSxjg6j8LwCWXt81R83+5+bHc/t7v94Yg6HB+er19ad2HlH1NiSwAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;ruby sockets select&quot;
        title=&quot;&quot;
        src=&quot;/static/13d9483dd5008f4cf14d2a5bf42cc697/c1b63/ruby-sockets-select.png&quot;
        srcset=&quot;/static/13d9483dd5008f4cf14d2a5bf42cc697/5a46d/ruby-sockets-select.png 300w,
/static/13d9483dd5008f4cf14d2a5bf42cc697/0a47e/ruby-sockets-select.png 600w,
/static/13d9483dd5008f4cf14d2a5bf42cc697/c1b63/ruby-sockets-select.png 1200w,
/static/13d9483dd5008f4cf14d2a5bf42cc697/0d98f/ruby-sockets-select.png 1276w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;h3 id=&quot;signal&quot;&gt;&lt;a href=&quot;https://www.gnu.org/software/coreutils/manual/html_node/Signal-specifications.html&quot;&gt;Signal&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;I&apos;m not sure I fully understood this section but the interesting bit here was how signals are handled by Unicorn - or more specifically asynchronous signals. Techniques like self-pipe and queuing were used but I didn&apos;t fully get it.&lt;/p&gt;
&lt;p&gt;Some other cool use cases of signals were&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Scaling workers using &lt;code class=&quot;language-text&quot;&gt;TTIN&lt;/code&gt; signals was also pretty cool.&lt;/li&gt;
&lt;li&gt;Hot reloading with &lt;code class=&quot;language-text&quot;&gt;USR2&lt;/code&gt; signal.&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Dockerfile isn't the only way to create Container Images]]></title><description><![CDATA[Dockerfiles are a common way to create container images, but they aren’t the only option]]></description><link>https://www.adityathebe.com/building-container-images-without-docker</link><guid isPermaLink="false">https://www.adityathebe.com/building-container-images-without-docker</guid><pubDate>Sat, 24 Feb 2024 00:50:00 GMT</pubDate><content:encoded>&lt;p&gt;On a &lt;a href=&quot;https://changelog.com/shipit/91&quot;&gt;recent episode&lt;/a&gt; of the &lt;a href=&quot;https://changelog.com/shipit&quot;&gt;ShipIt Podcast&lt;/a&gt;, I learned that container images can be built without docker! This may be pretty obvious to someone with a foundational understanding of containers, but to me it was news.&lt;/p&gt;
&lt;p&gt;To a lot of people, container images are synonymous to docker images. You have to have a &lt;code class=&quot;language-text&quot;&gt;Dockerfile&lt;/code&gt; and then you need to build it - which can take quite a bit of time to download a bunch of things - .... and finally ... you have an image, right?&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Wrong&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I mean that&apos;s also true but that&apos;s not the only way to get a container image.&lt;/p&gt;
&lt;p&gt;Just like a &lt;code class=&quot;language-text&quot;&gt;Dockerfile&lt;/code&gt;, Podman (an alternative to docker) has its own &lt;a href=&quot;https://www.mankier.com/5/Containerfile&quot;&gt;&lt;strong&gt;Containerfile&lt;/strong&gt;&lt;/a&gt;. I had heard about Podman before but never gave it a shot. There seems to be another tool - &lt;a href=&quot;https://github.com/containers/buildah/blob/main/docs/tutorials/README.md&quot;&gt;buildah&lt;/a&gt; which can also build container images without using &lt;code class=&quot;language-text&quot;&gt;Dockerfile&lt;/code&gt;. &lt;a href=&quot;https://www.chainguard.dev/chainguard-images&quot;&gt;Chainguard&lt;/a&gt; builds a large host of images with Terraform and apko.&lt;/p&gt;
&lt;p&gt;This tells us that Docker and Dockerfile is just another way to build a container image. So what exactly is a container image then?&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;It turns out that it&apos;s simply a bunch of tarballs.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It&apos;s actually several other things as well. The image also has the details of&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;what command to run after starting the container&lt;/li&gt;
&lt;li&gt;what ports to expose&lt;/li&gt;
&lt;li&gt;what env vars to set&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These details and many other details are kept in a variety of manifests as defined in the &lt;a href=&quot;https://github.com/opencontainers/image-spec/blob/main/spec.md#understanding-the-specification&quot;&gt;spec&lt;/a&gt;. Example: Here&apos;s an image manifest file&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;json&quot;&gt;&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;schemaVersion&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;mediaType&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;application/vnd.oci.image.manifest.v1+json&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;config&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;mediaType&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;application/vnd.oci.image.config.v1+json&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;digest&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;sha256:b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;size&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;7023&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;layers&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;mediaType&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;application/vnd.oci.image.layer.v1.tar+gzip&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;digest&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;sha256:9834876dcfb05cb167a5c24953eba58c4ac89b1adf57f28f2f9d09af107ee8f0&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;size&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;32654&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;mediaType&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;application/vnd.oci.image.layer.v1.tar+gzip&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;digest&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;sha256:3c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c6b&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;size&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;16724&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;mediaType&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;application/vnd.oci.image.layer.v1.tar+gzip&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;digest&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;sha256:ec4b8955958665577945c89419d1af06b5f7636b4ac3da7f12184802ad867736&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;size&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;73109&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;subject&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;mediaType&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;application/vnd.oci.image.manifest.v1+json&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;digest&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;sha256:5b0bcabd1ed22e9fb1310cf6c2dec7cdef19f0ad69efa1f392e94a4333501270&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;size&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;7682&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;annotations&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;com.example.key1&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;value1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;com.example.key2&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;value2&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;But in the summary, the image is in two parts&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the Filesystem&lt;/li&gt;
&lt;li&gt;a collection of metadata&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;building-a-container-image&quot;&gt;Building a Container Image&lt;/h2&gt;
&lt;p&gt;I don&apos;t know about you but this terminology subconsciously made me think that an image is a byproduct of a build process. Kind of like how you need to build source code to get a binary. You don&apos;t just right binary by hand, right?&lt;/p&gt;
&lt;p&gt;But that&apos;s not the case. Since images are just a bunch of files, you can, in fact, &lt;del&gt;build&lt;/del&gt; create one by hand. An image can be as simple as a folder with a single static binary in it like this &lt;a href=&quot;https://registry.hub.docker.com/_/hello-world/&quot;&gt;hello-world&lt;/a&gt; image by Docker. Or it can even be an empty folder like the popular &lt;a href=&quot;https://hub.docker.com/_/scratch&quot;&gt;scratch&lt;/a&gt; image.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;In hindsight, I feel silly to have not known about this. I am aware of &lt;a href=&quot;https://opencontainers.org/&quot;&gt;OCI&lt;/a&gt; &amp;#x26; I&apos;ve also watched &lt;a href=&quot;https://www.youtube.com/watch?v=8fi7uSYlOdc&quot;&gt;Liz Rice build container from scratch&lt;/a&gt; but I just didn&apos;t put 1 and 1 together - dang it!&lt;/p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://iximiuz.com/en/posts/you-need-containers-to-build-an-image/&quot;&gt;https://iximiuz.com/en/posts/you-need-containers-to-build-an-image/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/opencontainers/image-spec&quot;&gt;https://github.com/opencontainers/image-spec&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;thanks&quot;&gt;Thanks&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://cycode.com/blog/introducing-container-secret-scanning/&quot;&gt;cycode.com for the featured image&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[My Backup Strategy]]></title><description><![CDATA[The 3-2-1 backup strategy with Restic, Backblaze B2 and rclone.]]></description><link>https://www.adityathebe.com/backup-plan</link><guid isPermaLink="false">https://www.adityathebe.com/backup-plan</guid><pubDate>Sat, 03 Feb 2024 20:55:00 GMT</pubDate><content:encoded>&lt;p&gt;In 2023, I started dabbling with self hosting applications. It all started with a plex server and an SMB share acting as a poor man&apos;s NAS. After multiple iterations, I am now &lt;a href=&quot;https://github.com/adityathebe/homelab&quot;&gt;managing about 20-30 self hosted applications&lt;/a&gt;. Self hosting applications is nice because you know you own your data. It&apos;s a blessing but also a curse because now you have to manage that data as well.&lt;/p&gt;
&lt;p&gt;When you use a cloud provider, the risk of data loss is practically zero. Whether they&apos;ll misuse your data or guarantee access to your data is a different story. But in terms of keeping your data from losing, they&apos;ve got you covered.&lt;/p&gt;
&lt;h2 id=&quot;3-2-1-backup-strategy&quot;&gt;3-2-1 backup strategy&lt;/h2&gt;
&lt;p&gt;I came across this strategy through &lt;a href=&quot;https://www.youtube.com/watch?v=S0KZ5iXTkzg&quot;&gt;this video&lt;/a&gt; by Jeff Geerling. It stands for&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;3&lt;/strong&gt; copies&lt;/li&gt;
&lt;li&gt;in &lt;strong&gt;2&lt;/strong&gt; different media&lt;/li&gt;
&lt;li&gt;and &lt;strong&gt;1&lt;/strong&gt; offsite backup&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1200px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/56f7f620c08e9db20271949678daae67/074aa/3-2-1-backup-rule.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 41.333333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAAAsTAAALEwEAmpwYAAABDklEQVR42nVRy4qDQBDMh3v25D/kC/Qi4iF4FbyYq4gQjG9FiC/UaKzQzepGN1swDFQPVdU1J/xgWRY+hNfrhSRJ+OR5Dtd1EUURiqJAHMe43W4YhgHfcMI/eDweLNa2LbIsQ1mWbFDXNfNN02xBdoIrQe7X65XdPx/O8wzP8+A4DgsdRWhOpiu3CaqqCsuyoOs6pmnaHlBSSZIgCAIURdkqIYzjiDAMEQQBB9qtbBgGZFmGaZrsuoJWPJ/PEEURmqbtEnZdh/v9zpWkabpPSE6Xy4Xdjivbts1Gvu//WZmSEf98PveCtBqJ9n2/K5nWo+7o0A8f58RXVfXb4TqgPqjcb6CU1Cvdx18lw0/uDf4/YjbLWmOKAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;3 2 1 backup rule&quot;
        title=&quot;&quot;
        src=&quot;/static/56f7f620c08e9db20271949678daae67/c1b63/3-2-1-backup-rule.png&quot;
        srcset=&quot;/static/56f7f620c08e9db20271949678daae67/5a46d/3-2-1-backup-rule.png 300w,
/static/56f7f620c08e9db20271949678daae67/0a47e/3-2-1-backup-rule.png 600w,
/static/56f7f620c08e9db20271949678daae67/c1b63/3-2-1-backup-rule.png 1200w,
/static/56f7f620c08e9db20271949678daae67/d61c2/3-2-1-backup-rule.png 1800w,
/static/56f7f620c08e9db20271949678daae67/97a96/3-2-1-backup-rule.png 2400w,
/static/56f7f620c08e9db20271949678daae67/074aa/3-2-1-backup-rule.png 2930w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The offsite copy does not have to be on the Cloud.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;There is another 3-2-1-1-0 strategy that extends on this where the additional 1 and 0 mean - &lt;strong&gt;1&lt;/strong&gt; offline backup and a recoverable backup with &lt;strong&gt;0&lt;/strong&gt; errors. With Restic, I do get to verify that my backups are not corrupted and can be recovered. However, I do not have an offline backup &lt;em&gt;(yet)&lt;/em&gt;.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Broadly speaking, I would categorize my backups into two types&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Computer backups&lt;/li&gt;
&lt;li&gt;Media backups&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Computer backups are important, but the media backups are of far more importance to me as those cannot be recreated in case of data loss. Regardless, I have a similar backup plan for both of them.&lt;/p&gt;
&lt;h2 id=&quot;computer-backups&quot;&gt;Computer backups&lt;/h2&gt;
&lt;p&gt;I use &lt;a href=&quot;https://github.com/restic/restic&quot;&gt;Restic&lt;/a&gt; to backup all my configs and some other directories on my system to a TrueNAS server. You can find the backup script &lt;a href=&quot;https://github.com/adityathebe/dotfiles/blob/master/.local/share/restic-backup/backup.sh&quot;&gt;here&lt;/a&gt;. These are the directories I&apos;m currently backing up with a few exclusions.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;/etc
/root
/boot
/home/gunners/.config
/home/gunners/.local/share&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Some sofwares, for whatever reason, have made the decision to use the &lt;code class=&quot;language-text&quot;&gt;XDG_CONFIG_HOME&lt;/code&gt; as a dump to put all the application data &lt;em&gt;(i.e. logs, cache, session, ...)&lt;/em&gt;. My &lt;code class=&quot;language-text&quot;&gt;XDG_CONFIG_HOME&lt;/code&gt; is 16GB right now of which more than 90% is just from Brave, Slack, Discord and VS Code.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 955px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/3956ea53d79373cd3a02da6540a10fee/a0b80/config-dir-diskonaut.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 49.66666666666666%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAIAAAA7N+mxAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABZElEQVR42n1Sy07CQBTtt5AIzKPz6GM69E2h2Lgy+gm6MyyIC39EF65Z4MKPIEZjNK5lQQgJKz7D21JIidHkZHLn5J57z8mMkfTzMB4A0iyPkqEfZsA4bipk1IS0YiFDIYIduPCBNEwWnHScNnLb3RIdVJ9drA7oYEVNTe0+sTPiDokzMHVBRGRwEdStBOBVBZzekRgpynoIeOJxsGAnUMC1IcZuF1U4FLu6FLsgZlZiWgl3+lJlQg1gxEHsIh5RryAqxzIlbk7UiOoC8bAaAbZ7RMTESpkenbCwRYNW22naBlcaU81EyO0YUV0x3n6zb8oIMz+Mi8nkbjy+vbq+adpWsASRMh601kHqzKVtqXNsJcPicr1eb7fbj88vgzXF+9bfDIyTVoQh1ej8e7FYrVbz+cvx5j9QPVVPekNT5fnpxXK53Gw2r2/vhrRCTD1i6v/B4FdYscmDOD2bTmezp+f7h8cf9YSLUhhDZrcAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;~/.config disk usage with Diskonaut&quot;
        title=&quot;&quot;
        src=&quot;/static/3956ea53d79373cd3a02da6540a10fee/a0b80/config-dir-diskonaut.png&quot;
        srcset=&quot;/static/3956ea53d79373cd3a02da6540a10fee/5a46d/config-dir-diskonaut.png 300w,
/static/3956ea53d79373cd3a02da6540a10fee/0a47e/config-dir-diskonaut.png 600w,
/static/3956ea53d79373cd3a02da6540a10fee/a0b80/config-dir-diskonaut.png 955w&quot;
        sizes=&quot;(max-width: 955px) 100vw, 955px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;
&lt;em&gt;~/.config disk usage with Diskonaut&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Which is why there are some exclusions in the backup script.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;# https://github.com/adityathebe/dotfiles/blob/master/.local/share/restic-backup/excludes.txt

/home/gunners/.config/asdf
/home/gunners/.config/BraveSoftware
/home/gunners/.config/Chromium
/home/gunners/.config/Code - OSS
/home/gunners/.config/Code
/home/gunners/.config/code-server
/home/gunners/.config/discord
/home/gunners/.config/Slack
/home/gunners/.config/go
/home/gunners/.config/gops
/home/gunners/.config/gcloud/logs

/home/gunners/.local/share/go
/home/gunners/.local/share/nvim
/home/gunners/.local/share/nvim.bak
/home/gunners/.local/share/TelegramDesktop/
/home/gunners/.local/share/.codeium/

/root/go&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Anyways, this backup script is run twice a day with a cron job&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;# Restic backup
00 11,22 * * * /home/gunners/.local/share/restic-backup/backup.sh&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Then, on the TrueNAS server I have a cron job that replicates the system backup to Backblaze B2 using rclone. This cron job runs twice a week and is set up using an Ansible playbook that you can find &lt;a href=&quot;https://github.com/adityathebe/homelab/blob/main/ansible/truenas/playbooks/backup.yaml&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1200px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/be8c3c6041fbfea5f3e87ec112d86a57/074aa/system-backup-strategy.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 41.333333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAuUlEQVR42q1R2w6CMAzlp/0HX/0BP0mejPEFEwIm8wE2gU12O9KJhsGDIWHJSU+b9rRdE2z8kjXJ3vvIjs5S0DkXYK2NkolT3M+KoibaxIJUIKVE27YBTdOAc46qqlDXNYQQId51HRhjH3/IcSTGn2gPR3ipftMm1F0pFUQJfd8HSzHiBGNMmFRrPXKLl7EQJUOx26O7FRjWW678b73p/5XlA2l6xemcIb9ksPl9/VE2v/J80i+ml34DCR91n5x8fKMAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;system backup strategy&quot;
        title=&quot;&quot;
        src=&quot;/static/be8c3c6041fbfea5f3e87ec112d86a57/c1b63/system-backup-strategy.png&quot;
        srcset=&quot;/static/be8c3c6041fbfea5f3e87ec112d86a57/5a46d/system-backup-strategy.png 300w,
/static/be8c3c6041fbfea5f3e87ec112d86a57/0a47e/system-backup-strategy.png 600w,
/static/be8c3c6041fbfea5f3e87ec112d86a57/c1b63/system-backup-strategy.png 1200w,
/static/be8c3c6041fbfea5f3e87ec112d86a57/d61c2/system-backup-strategy.png 1800w,
/static/be8c3c6041fbfea5f3e87ec112d86a57/97a96/system-backup-strategy.png 2400w,
/static/be8c3c6041fbfea5f3e87ec112d86a57/074aa/system-backup-strategy.png 2930w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;h3 id=&quot;why-not-directly-back-up-to-backblaze-b2-&quot;&gt;Why not directly back up to Backblaze B2 ?&lt;/h3&gt;
&lt;p&gt;So, intially I was indeed directly backing up to Cloud. However, the advantages of not directly backing up to a cloud provider are&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;backups are faster &lt;em&gt;(honestly not a big deal since it&apos;s a background job anyway)&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;but the more important reason is - the fact that I can perform the integrity check of the backup without needing to download the whole thing from the cloud. This saves time &amp;#x26; money.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;media-backups&quot;&gt;Media backups&lt;/h2&gt;
&lt;p&gt;Media backups include all the photos, videos and my music library. The NAS is the production copy for my media. So, to have another local copy on a different media, I simply backup to an external HDD with Restic.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I wouldn&apos;t say I love this approach because I need to have the external drive plugged in at all times to the NAS and also doing lots of IO operations through a USB is probably not a good idea &lt;em&gt;(don&apos;t quote me on this one)&lt;/em&gt; - but hey, it works. And the alternative would be to have another backup system that would cost equally as the main NAS system.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The &lt;a href=&quot;https://github.com/adityathebe/homelab/blob/main/ansible/truenas/playbooks/backup.yaml&quot;&gt;previous ansible playbook&lt;/a&gt; also sets up a systemd timer on the NAS to perform daily backups to the external drive.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token function&quot;&gt;cat&lt;/span&gt; restic-backup.service&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;output&quot;&gt;&lt;pre class=&quot;language-output&quot;&gt;&lt;code class=&quot;language-output&quot;&gt;[Unit]
Description=Restic backup

[Service]
Type=oneshot
User=root

CPUQuota=100%

Environment=&amp;quot;RESTIC_REPOSITORY=/home/admin/seagate/backups&amp;quot;
Environment=&amp;quot;RESTIC_PASSWORD=***************&amp;quot;


ExecStartPre=/usr/local/bin/restic check
ExecStart=/usr/local/bin/restic backup --verbose /mnt/mega/aditya
ExecStart=/usr/local/bin/restic backup --verbose /mnt/mega/photos --exclude=&amp;quot;/mnt/mega/photos/immich/thumbs&amp;quot; --exclude=&amp;quot;/mnt/mega/photos/immich/encoded-video&amp;quot;
ExecStartPost=/usr/local/bin/restic forget --keep-within 90d
ExecStartPost=/usr/local/bin/restic prune&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As you can see, this systemd service is backing up two directories&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;/mnt/mega/aditya&lt;/code&gt; - this is my personal documents&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;/mnt/mega/photos&lt;/code&gt; - this is my photos library&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;to &lt;code class=&quot;language-text&quot;&gt;/home/admin/seagate/backups&lt;/code&gt; where &lt;code class=&quot;language-text&quot;&gt;/home/admin/seagate&lt;/code&gt; is where the external drive is mounted.&lt;/p&gt;
&lt;p&gt;Then, as a 3rd offsite copy of the backup I, once again, use rclone to replicate the restic backup to backblaze.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1200px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/4d61e12744af17f9f142f3e0aba9142a/074aa/media-backup-strategy.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 41.333333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAr0lEQVR42q1RywrCMBDMx/oP/pk/4KUiKHjw7ANaIW1tDGmS5jGmgRZrtQfrwLDL7O7swhLMgfcjiXzu85jSv9UHhs65yNfmNu/4DntnkMl+dCnpBhljkZxzFEWBsixBKUWWZRBCRD3Pc7CqgvJh+SUFWyzhpRqY9hdKKSONMdBa92w1a23U2zxM4nROsU0O2KzWuO6OwI32puSXXyjV4MFr8BCVqIHGTD9lDv5u+ARFFHXiyH/aPgAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;media backup strategy&quot;
        title=&quot;&quot;
        src=&quot;/static/4d61e12744af17f9f142f3e0aba9142a/c1b63/media-backup-strategy.png&quot;
        srcset=&quot;/static/4d61e12744af17f9f142f3e0aba9142a/5a46d/media-backup-strategy.png 300w,
/static/4d61e12744af17f9f142f3e0aba9142a/0a47e/media-backup-strategy.png 600w,
/static/4d61e12744af17f9f142f3e0aba9142a/c1b63/media-backup-strategy.png 1200w,
/static/4d61e12744af17f9f142f3e0aba9142a/d61c2/media-backup-strategy.png 1800w,
/static/4d61e12744af17f9f142f3e0aba9142a/97a96/media-backup-strategy.png 2400w,
/static/4d61e12744af17f9f142f3e0aba9142a/074aa/media-backup-strategy.png 2930w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token function&quot;&gt;sudo&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;crontab&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-l&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;output&quot;&gt;&lt;pre class=&quot;language-output&quot;&gt;&lt;code class=&quot;language-output&quot;&gt;#Ansible: sync arch backups to b2
0 1 * * 2,5 rclone sync /home/admin/backups/arch b2:restic-backup-arch
#Ansible: sync nas backups to b2
0 1 * * 3,6 rclone sync /home/admin/seagate/backups b2:nas-backup-aditya&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;why-these-tools&quot;&gt;Why these tools?&lt;/h2&gt;
&lt;h3 id=&quot;backblaze&quot;&gt;Backblaze&lt;/h3&gt;
&lt;p&gt;The simple answer is that they are the cheapest solution out there. AWS Glacier could be cheaper depending on how much data you have and how often you need to retrieve it, but for me B2, was the best one.&lt;/p&gt;
&lt;p&gt;They are also fairly reputed among data hoarders so I am going to stick with B2 for now.&lt;/p&gt;
&lt;h3 id=&quot;restic&quot;&gt;Restic&lt;/h3&gt;
&lt;p&gt;Restic is one of my favorite open source tools out there. It&apos;s fairly aged, supports encryption out of the box &lt;em&gt;(in fact it doesn&apos;t even support unencrypted backup)&lt;/em&gt;, has configurable compression, &lt;a href=&quot;https://restic.readthedocs.io/en/latest/045_working_with_repos.html#checking-integrity-and-consistency&quot;&gt;allows verifying the integrity and recoverability of the backups&lt;/a&gt;, and supports a wide range of cloud providers as the backend. It&apos;s also written in Go and used by &lt;a href=&quot;https://words.filippo.io/restic-cryptography/&quot;&gt;Fillipo&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I can do a &quot;soft&quot; integrity check on the backup with&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;sudo restic check -r ~/seagate/backups&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;and a &quot;hard&quot; integrity check with&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;sudo restic check -r ~/seagate/backups --read-data&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;rclone&quot;&gt;rclone&lt;/h3&gt;
&lt;p&gt;Honestly, I chose this one simply because a lot of people have talked highly about it. It was also fairly easy to set up. Offers incremental backup and checksum as well.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Improve your Google dorking with keyboard shortcuts]]></title><description><![CDATA[In chrome based browsers, you can setup keyboard shortcuts for site search & search engines.]]></description><link>https://www.adityathebe.com/improve-search-with-shortcuts/</link><guid isPermaLink="false">https://www.adityathebe.com/improve-search-with-shortcuts/</guid><pubDate>Sat, 21 Jan 2023 23:11:00 GMT</pubDate><content:encoded>&lt;p&gt;I&apos;m sure you probably already know about Google dorking (also called Google Hacking). For those who don&apos;t know what it is - it&apos;s a way to narrow down your google search by using filters provided by Google. Example: if you are searching for a pdf of a book, you can narrow down your search using the &lt;code class=&quot;language-text&quot;&gt;filetype:pdf&lt;/code&gt; filter. If you want your search to only include a particular site you can use the &lt;code class=&quot;language-text&quot;&gt;site:&amp;lt;sitename.com&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1200px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/238e990259e5e24ca6e8c7d44bb6b23d/eb645/google-dork-compare.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 50.33333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAIAAAA7N+mxAAAACXBIWXMAAAsTAAALEwEAmpwYAAABeElEQVR42lWRXW9UIRCG+///kbHdZDXRmMY7vdlUq6ayBw4zHL6/wdmTTesSuJnhgZeHu5JLysX7kHOZc/beW+tzHzFG9pe11nwIPvha8iilhjhqm2PQhjtaARQCOOeC9wT0MUZMM4SolFiW1oZcNaD1SrflPLSeKdElV9hslnNENNvmrI1UyTH12q12nHOCOVeIllox1THfxg4bKwS1nTExp0YVa+kUJwF3uC8LAGiCjQ30ihtYa7euG4LVOuZcqQKAQmz7oYJgygVgUDmK9mrkCntfpXQIXqngXJqTnpxpE1mkm3sfQuB6lpKtclUp5hv4969nwVdSUC8aL1VtfCnFh7jDTaCE09Pz/YGxFxTrGOMNfv/u/nD8zLh6YcA4auOso/yFzHPB92gxhIS4BTJW6w18evpz+Pj4cPxy/PT14cPjt++n4jSCFGIV4iKMMeCLArAh5FfyCuPPHyDOqdD/9VwuPQXSaPq5jWLv/jaaCo1z8X9h/wDjKjtJewHYYQAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;Without the filetype filter&quot;
        title=&quot;&quot;
        src=&quot;/static/238e990259e5e24ca6e8c7d44bb6b23d/c1b63/google-dork-compare.png&quot;
        srcset=&quot;/static/238e990259e5e24ca6e8c7d44bb6b23d/5a46d/google-dork-compare.png 300w,
/static/238e990259e5e24ca6e8c7d44bb6b23d/0a47e/google-dork-compare.png 600w,
/static/238e990259e5e24ca6e8c7d44bb6b23d/c1b63/google-dork-compare.png 1200w,
/static/238e990259e5e24ca6e8c7d44bb6b23d/d61c2/google-dork-compare.png 1800w,
/static/238e990259e5e24ca6e8c7d44bb6b23d/97a96/google-dork-compare.png 2400w,
/static/238e990259e5e24ca6e8c7d44bb6b23d/eb645/google-dork-compare.png 2500w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;em&gt;Without the filetype filter&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;I frequently use the &lt;code class=&quot;language-text&quot;&gt;site&lt;/code&gt; filter - mostly with reddit &lt;code class=&quot;language-text&quot;&gt;site:reddit.com&lt;/code&gt;. Ocassionally I also use it with &lt;code class=&quot;language-text&quot;&gt;stackoverflow.com&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;github.com&lt;/code&gt;. However, it&apos;s not quite pleasant to type it out!&lt;/p&gt;
&lt;p&gt;I just found out about a shortcut you can use to avoid this typing. I&apos;ve only tried this on chrome-based browser (Brave in particular) but I&apos;m sure there&apos;s a similar feature in Firefox also.&lt;/p&gt;
&lt;h2 id=&quot;steps-to-configure-shortcuts&quot;&gt;Steps to configure shortcuts&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Right click on the address bar. Click on the &quot;&lt;strong&gt;Manage search engines &amp;#x26; Site search&lt;/strong&gt;&quot; context menu. &lt;a name=&quot;address-bar&quot;&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1024px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/2ced801075cd3c7d632b7b09a581c87e/2bef9/right-click-on-address-bar.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 51.66666666666666%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAIAAAA7N+mxAAAACXBIWXMAAA7EAAAOxAGVKw4bAAACQklEQVR42mNo7Z7aWdlcWV5XX9vQ2tTa0tJeV9fQVN8YFRVvbOZgZuFoauGoa2CppWumo2+hoW0SERHb3NhUW1VTWV7J8Pvv3z93br959vT3nz///v9/ffPGr7dv////P2/BUlVtc30Te20DGy0Day19a10jO2VN07nzlwJlf/369fv3b4bnz58/ffP2+4+fP3/8+Prt24ZVq9/s2AmUnDFvkbq2ua6RjaaeJRBp6VvqGtmqaZvPnL0AqPndu/dAHQzfvn37+P79p0+f//37CxS9dPb4+lmTjtQVxgQH6Vu6WVi7GZk7mVi6GJo5aelbaehZuXsGpiSnhUdETZ08leHHjx/fvgGt/Pbnzx+g5lPbFjaUhIfb6IQKCdlbuxlaOGsbWOsY2gCt1Ta0NjC25zcw8gx0LMrzSYyPZfj69euHDx+Bfvj3D+jl/7tX9NkZiYpJCFkrKblauZnaeVnaegAtNzB1APpfU9fS2MWjrrWyqCw5vzAd7OyPH798+fL3L8jZsdGRDAwMkS5mkd42gsIS6sqKVgZacfGJCipaSsoa0rIqVjZWSRnBDh7GpSVZDN+/f//w4cP7Dx8gNm/bumXVyhU7tm/ZsWXDsmVLt23eeOHc6SO7d8yfMX3r9h1btm7ds2/3vkO7L105+/jxAwagg4E2AzX/B4MvX76+fv36xcuX795/AAYHRPD7l8+vXzx/9fo1xHVwwAC0EKjo+/cfcKFfYACMRqBSoOwfsAZgcIIi88eP379B4QqMmn///gEAmn92YcpZmZQAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;Right click on the address bar&quot;
        title=&quot;&quot;
        src=&quot;/static/2ced801075cd3c7d632b7b09a581c87e/2bef9/right-click-on-address-bar.png&quot;
        srcset=&quot;/static/2ced801075cd3c7d632b7b09a581c87e/5a46d/right-click-on-address-bar.png 300w,
/static/2ced801075cd3c7d632b7b09a581c87e/0a47e/right-click-on-address-bar.png 600w,
/static/2ced801075cd3c7d632b7b09a581c87e/2bef9/right-click-on-address-bar.png 1024w&quot;
        sizes=&quot;(max-width: 1024px) 100vw, 1024px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;em&gt;Right click on the address bar&lt;/em&gt;&lt;/p&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;You should see the &quot;Search engine&quot; &amp;#x26; &quot;Site search&quot; sections. Click on &quot;&lt;strong&gt;Add&lt;/strong&gt;&quot; in the site search section. &lt;a name=&quot;add&quot;&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 676px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/92ec5c61a92742239b0730b7f94dfe4f/9bb7a/add-site-search-chrome.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 121%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAYCAIAAAB1KUohAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAB3ElEQVR42pWUaXLjIBCFdf+D5R7xr4wda2XfNB8gY8sjJTVdmEI0j37d/XBnjJmXZZpma936n9ZJqfp+uN97ZsY4jvyGYeyH+jmxYGZwhCVhRDHvfWetXbKJec6zxJRiWoQo30oIKcr2kiHSOZdSijEyd0T3PmhttNbO+8oHh1KKc7/Q5he9g9Xt9n29fhOMnRCCMbbe8mbErK4NHIKXSkOJ4PgqBjqH0aBrC/ONNmxJiZzBN9oEPwbHRF9ec/YASbvxxMdmOrIQMm2ufoBDkLk8+fQuMp+PnWa4KGRstHPkefGPUm85n9EutdxoVzIHp76+1stl7ftVqVXKPCu57m/sqDAKgjaXlUyY84LWBynDn2u4XBj+87PO/uPDT9MoZAwxg+9Fhyj0jkKHbKL0TWkjjJHWSWtZUJWssdvN8h4y89TlGDiyJBV7LpuvBYtv6fyTXemz80XRqiVPCsRA9q9NehPcBkZM0KTgRG5gXg+jNn8vEvpsniJRSvPW3iIDy8yLWn9SmDF6LkFKmqmCz54ULtJ5gtEiGdcnjaOeONf2HsyrGqeFmr0q7Fg5h5FJGNpN3j+AN203MHpVUlTatUK4GGeRd9WmeuPIP5horfrVnuDKBDsr0iH5lNJfUE2EBDVFEgoAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;Add new site search&quot;
        title=&quot;&quot;
        src=&quot;/static/92ec5c61a92742239b0730b7f94dfe4f/9bb7a/add-site-search-chrome.png&quot;
        srcset=&quot;/static/92ec5c61a92742239b0730b7f94dfe4f/5a46d/add-site-search-chrome.png 300w,
/static/92ec5c61a92742239b0730b7f94dfe4f/0a47e/add-site-search-chrome.png 600w,
/static/92ec5c61a92742239b0730b7f94dfe4f/9bb7a/add-site-search-chrome.png 676w&quot;
        sizes=&quot;(max-width: 676px) 100vw, 676px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;em&gt;Add new site search&lt;/em&gt;&lt;/p&gt;
&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;Finally just fill in the form &lt;a name=&quot;configure&quot;&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Here&apos;s an example of my shortcut for reddit site filter in google search.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 600px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/d7a8f29f3eb539bab74dc03e4001af59/0a47e/google-reddit-site-search.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 68.33333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAIAAACgpqunAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABqUlEQVR42o1Sy1KDMBTtV1po6UM77bjpTP/A8QFoW3fFjX/gR/hY6UJXrlxYRxG0ECQBEp4BL9SZ6qb15JDMTe7JvbmX2mg0mk6nxyfj6SmgnCabMB6Ph8Nhv9+vaZrGObctG7swCEJfYBZrkee5qqqdTqemzWbga5PE8dMMkKbFJoBYUZRSfHamsTh/fHr7+AqQxxBhNqZraLlBwOJVZLjMcilhCaEppilZSxykYZypahV5Vokxxpxnec6XLNYy5xwid7tdKFgpdokfsBDoAynzArokqej9IjiGUXwky5Ik/USmlEZRHFVIkmRjwWRZbrVaZavSjD+/vOqGqb+bb7ppfiwWFrJsx7LRp4U+F7aNHOL7YRyzMGIQJEn+pI0cl3g+fNBq4gUu9jApTVzueNjzfUoh2zCM4ApITVV+FQwaXPwbqz7/R5xlHLskBJeHq+J8P7+/VCannXa7Bj+q4zi6rhtLmIZplotZLUvA6Xw+f303jLsb4+Jcv73eOzjchjf3ej1RbAiCCNVriqJQryAIW/W6VKHRaDSbTTgtje0dabALM6gGg8E390O0uKT4pDwAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;Reddit site filter&quot;
        title=&quot;&quot;
        src=&quot;/static/d7a8f29f3eb539bab74dc03e4001af59/0a47e/google-reddit-site-search.png&quot;
        srcset=&quot;/static/d7a8f29f3eb539bab74dc03e4001af59/5a46d/google-reddit-site-search.png 300w,
/static/d7a8f29f3eb539bab74dc03e4001af59/0a47e/google-reddit-site-search.png 600w&quot;
        sizes=&quot;(max-width: 600px) 100vw, 600px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;em&gt;Reddit site filter&lt;/em&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;https://www.google.com/search?q=site:reddit.com %s&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/br&gt;
&lt;h2 id=&quot;using-the-shortcuts&quot;&gt;Using the shortcuts&lt;/h2&gt;
&lt;p&gt;This is my favorite part. Usually shortcuts involve chording keys. There&apos;s at least 2 keys involved and one&apos;s probably the &lt;code class=&quot;language-text&quot;&gt;Ctrl&lt;/code&gt; key. However, to use the site search shortcut you just need to type in the shortcut key that you configured and simply press space!&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 429px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/2eced6a080674b3bc9dab296c355a774/3d026/site-search-with-shortcut.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 36.66666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAIAAACHqfpvAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABOUlEQVR42mMw0Ui00s0QF7QUFtAS5NVSUbBWkDFTVbZVVrASE9JTlrdUkrOQlzZTB4rIW3KwKCEjhqyk7sLMSa7mIYqypiqK1vo6Llrq9toajvraLqpK1lrqDrqaTtrqDnrazkBBOWlTZMTw+8+f////T2/qMdRxsbcN9nKPASJ3l6gA30Qnu1Bbq0AH2xA76yB762ALE28TQ09TIy84Yvj69TtQc3ZqKT+3hrS4kbK8lbIc0KmWKgpWQHcCReSkTGUlTYCkjISxuLA+0C9wxPD1G0hzZEQWA4MIJ7uijKSJjKSxtISRvIyZnLQJJ5uiEJ8WP486H7cGH5caE6MMA4M0An3/8fPf//9bNu9qauzp7prc2tLX2tIPQR3tE3u6pnZ3TumGklN6e6YhI4YfP38B0Z8/f/+TDgAcOaIYpOwOhAAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;Using site search shortcut&quot;
        title=&quot;&quot;
        src=&quot;/static/2eced6a080674b3bc9dab296c355a774/3d026/site-search-with-shortcut.png&quot;
        srcset=&quot;/static/2eced6a080674b3bc9dab296c355a774/5a46d/site-search-with-shortcut.png 300w,
/static/2eced6a080674b3bc9dab296c355a774/3d026/site-search-with-shortcut.png 429w&quot;
        sizes=&quot;(max-width: 429px) 100vw, 429px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;em&gt;Using site search shortcut&lt;/em&gt;&lt;/p&gt;
&lt;h2 id=&quot;search-engine&quot;&gt;Search Engine&lt;/h2&gt;
&lt;p&gt;You can follow the same procedure to add shortcuts for search engines also. I don&apos;t really use this because Google works fine for me. But in case you need to search with DuckDuckGo, for example, you have the option to set a shortcut.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Pacman for newbies]]></title><description><![CDATA[A list of commonly used commands for the Pacman package manager.]]></description><link>https://www.adityathebe.com/pacman-for-newbies/</link><guid isPermaLink="false">https://www.adityathebe.com/pacman-for-newbies/</guid><pubDate>Thu, 19 Jan 2023 13:45:00 GMT</pubDate><content:encoded>&lt;h3 id=&quot;who-this-post-is-for&quot;&gt;Who this post is for&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Users who are new to &lt;code class=&quot;language-text&quot;&gt;pacman&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Someone who wants to see what other pacman users regularly use&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;what-this-post-isnt&quot;&gt;What this post isn&apos;t&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Principle of pacman design&lt;/li&gt;
&lt;li&gt;Detail explanation of the commands&lt;/li&gt;
&lt;li&gt;Replacement of the documentation (duh!)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Everything in this post can of course be found easily using &lt;code class=&quot;language-text&quot;&gt;pacman --help&lt;/code&gt;. But that&apos;s a documentation. It has a lot more than you&apos;d ever need. This post will help you filter out the few good stuff (&lt;em&gt;read: regularly used&lt;/em&gt;) from the vast documentation.&lt;/p&gt;
&lt;p&gt;Here&apos;s a list of commands I personally use. I never had the need to use anything more than what&apos;s listed here.&lt;/p&gt;
&lt;h2 id=&quot;the-basics&quot;&gt;The Basics&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Upgrade local packages&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token function&quot;&gt;sudo&lt;/span&gt; pacman &lt;span class=&quot;token parameter variable&quot;&gt;-Syu&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This command is probably the most used pacman command by quite some distance. It does 2 things&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;downloads a fresh package list.&lt;/li&gt;
&lt;li&gt;upgrades all the installed pacakges that are out of date.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;Pacman keeps a local copy of the package list in the system, so it doesn&apos;t have to download the list every time you run a command. The -y flag forces pacman to download a fresh copy of the package list from the repositories.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;Install packages&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token function&quot;&gt;sudo&lt;/span&gt; pacman &lt;span class=&quot;token parameter variable&quot;&gt;-S&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;package-name&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;Search for packages&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token function&quot;&gt;sudo&lt;/span&gt; pacman &lt;span class=&quot;token parameter variable&quot;&gt;-Ss&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;package-name&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ol start=&quot;4&quot;&gt;
&lt;li&gt;Remove packages&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token function&quot;&gt;sudo&lt;/span&gt; pacman &lt;span class=&quot;token parameter variable&quot;&gt;-Rns&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;package-name&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ol start=&quot;5&quot;&gt;
&lt;li&gt;Clean cache&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token function&quot;&gt;sudo&lt;/span&gt; pacman &lt;span class=&quot;token parameter variable&quot;&gt;-Sc&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;still-basics-but-rarely-used&quot;&gt;Still basics but rarely used&lt;/h2&gt;
&lt;p&gt;These are a list of commands that you probably wouldn&apos;t use on a daily basis.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;List all packages that are no longer required&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;pacman &lt;span class=&quot;token parameter variable&quot;&gt;-Qdt&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;Remove all packages that are no longer required&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token function&quot;&gt;sudo&lt;/span&gt; pacman &lt;span class=&quot;token parameter variable&quot;&gt;-Rns&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$(&lt;/span&gt;pacman &lt;span class=&quot;token parameter variable&quot;&gt;-Qdtq&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;Info of a package&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;pacman &lt;span class=&quot;token parameter variable&quot;&gt;-Qi&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;package-name&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I use this command to look for a few things&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;packages that require this package&lt;/li&gt;
&lt;li&gt;packages this package require&lt;/li&gt;
&lt;li&gt;whether it was installed explicitly&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;pacman &lt;span class=&quot;token parameter variable&quot;&gt;-Qi&lt;/span&gt; seahorse&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;output&quot;&gt;&lt;pre class=&quot;language-output&quot;&gt;&lt;code class=&quot;language-output&quot;&gt;...
Depends On      : gtk3  gcr  ...
Required By     : None
Install Reason  : Explicitly installed&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ol start=&quot;4&quot;&gt;
&lt;li&gt;List all the packages installed in your system&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;pacman &lt;span class=&quot;token parameter variable&quot;&gt;-Q&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# To get the count&lt;/span&gt;
pacman &lt;span class=&quot;token parameter variable&quot;&gt;-Q&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;wc&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-l&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ol start=&quot;5&quot;&gt;
&lt;li&gt;List packages that were explicitly installed&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;pacman &lt;span class=&quot;token parameter variable&quot;&gt;-Qe&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Packages come with dependencies. This is will only list those packages that you explicitly installed.&lt;/p&gt;
&lt;ol start=&quot;6&quot;&gt;
&lt;li&gt;List all the packages installed from aur&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Not possible. But you can get a close to accurate result with&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;pacman &lt;span class=&quot;token parameter variable&quot;&gt;-Qm&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;thanks&quot;&gt;Thanks&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Photo by &lt;a href=&quot;https://medium.com/@aliakbarzohour/use-pacman-in-arch-linux-and-manjaro-c987e4a0da66&quot;&gt;https://medium.com/@aliakbarzohour/use-pacman-in-arch-linux-and-manjaro-c987e4a0da66&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Here's how you can wake up early without waking up early]]></title><description><![CDATA[Here's a silly but effective life hack for the night owls out there.]]></description><link>https://www.adityathebe.com/timezone-lifehack-for-night-owls/</link><guid isPermaLink="false">https://www.adityathebe.com/timezone-lifehack-for-night-owls/</guid><pubDate>Thu, 05 Jan 2023 16:00:00 GMT</pubDate><content:encoded>&lt;p&gt;How nice would it be to have a turn off switch for your body? I would turn myself off every night at around 9/10 pm. Hold on ... that didn&apos;t sound right. A &quot;sleep switch&quot; might be a more appropriate word. Yes - that sounds better. I would press the sleep button every night at 9/10pm.&lt;/p&gt;
&lt;p&gt;There are some people out there who have this gift - a virtual sleep switch they can turn on to dose off whenever &amp;#x26; wherever they want. I, unfortunately, am not one of those people.&lt;/p&gt;
&lt;p&gt;Why does it matter &lt;em&gt;when&lt;/em&gt; you sleep if you get 8 hours of sleep, you say? Because, just as important as it is to get adequate sleep it&apos;s also important that you get the morning sunlight (&lt;a href=&quot;https://www.youtube.com/watch?v=yBjUR16AiBM&quot;&gt;shout out to Dr Andrew Huberman&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;And also if you happen to live with someone else who isn&apos;t a night owl, it would be nice to have a coherent schedule so you can get chores done &amp;#x26; have meals together.&lt;/p&gt;
&lt;p&gt;There&apos;s one other problem for late risers - and it&apos;s that you don&apos;t really have a good sense of where you are at your actual day. You see, I personally wake up at around 11am. By the time I wakeup and get ready for work it&apos;s almost noon. This gives me a feeling that half of my day has already passed but in fact it hasn&apos;t - it just started. I just woke up! Even worse, if it&apos;s winter - it&apos;s already dark 5/6 hours after you wake up.&lt;/p&gt;
&lt;p&gt;This has been a pretty major problem for me. This dissonance of your internal clock with your external clock affects how you set yourself up for the day. So, here&apos;s a hack I came up with (&lt;em&gt;just this morning actually&lt;/em&gt;).&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Follow a different timezone where you wake up at 6 in the morning.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I know it&apos;s super silly but it works. I have found that Cairo/Egypt (GMT+2) or Berlin/Germany (GMT+1) suits me perfectly. When I wake up at 11 am (GMT +05:45) it&apos;s 6:15am in Berlin.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 919px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/fc8f55f9b7a9c0fb69e76e5869eaff66/6295b/kathmandu-egypt-germany-timezone.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 87.33333333333334%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAARCAIAAABSJhvpAAAACXBIWXMAAA7EAAAOxAGVKw4bAAACI0lEQVR42o2SfW/aMBDG8/2/1dT9MaStLZNogQIJhISQxOTF8dvZpntshLRqarWTZeWce+5+d3bS9/12u93t0sPhcDwesyxjjO12O3yURVGW5dX7908s4ZynaVYUxbmq0izb7/fn8znP89VyCX1VVdfr9StxnqNk3nWXxWKx2WzqujmdTkW0uq79F+Kh70ORNF2v1tiNMe//bQlZ20mtrBOGeiG1dVjBJSfJkfMTOeO8tMF1wPjLEriDsXeBR7SJ+pvYBrEl71UUW/9BnThnjVZaKaO1kpLIOGtHZeDiUEycC1mwjrRiXAyTaPqRDSN2NJhY60bOx2AcvoP5UNxGIyQjmqQSUjQtu3SdVKGOipEQ27Zp+r6DIdG/U7kRkjGsbWMM2P3tPAxstsi//8baP8wPr9lZWCuIJMBRE+yhC6W9H6Q5tvz5rXx4Tr/NMy4MenZCKq2BTNY5Y0JipHfRKNbBjn9oDMj4g0ZsaM4HMbCR+rPLBN4tUVPXeEhXD5m7Y5P99XqcvRSAx/6Wt9oEZswdVQTgneOYkfej1AXji101Wxx+vBSTjNgDlz3WKEehuVA3WoCFLojC8CPnJIRQZpIa8YgEeJh2fT7hsr7ADm2TwYO/XFj07tNGifm6+Lk8Pq3Lx9WpYgN5d2PGkhF7AjYApToxvtrXT6vicV0KRQl46guvGC+bHvvIBU50fBsGeq3xonEVFFOMQrFBVO1YtZys+wN6vc+x6XKbAAAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;kathmandu egypt germany timezone&quot;
        title=&quot;&quot;
        src=&quot;/static/fc8f55f9b7a9c0fb69e76e5869eaff66/6295b/kathmandu-egypt-germany-timezone.png&quot;
        srcset=&quot;/static/fc8f55f9b7a9c0fb69e76e5869eaff66/5a46d/kathmandu-egypt-germany-timezone.png 300w,
/static/fc8f55f9b7a9c0fb69e76e5869eaff66/0a47e/kathmandu-egypt-germany-timezone.png 600w,
/static/fc8f55f9b7a9c0fb69e76e5869eaff66/6295b/kathmandu-egypt-germany-timezone.png 919w&quot;
        sizes=&quot;(max-width: 919px) 100vw, 919px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;em&gt;Timezone difference: &lt;a href=&quot;https://savvytime.com/converter/nepal-kathmandu-to-egypt-cairo-germany-berlin&quot;&gt;https://savvytime.com/converter/nepal-kathmandu-to-egypt-cairo-germany-berlin&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Here&apos;s how my time differs&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Local Time&lt;/th&gt;
&lt;th&gt;Berlin Time&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Wakeup&lt;/td&gt;
&lt;td&gt;11:00 am&lt;/td&gt;
&lt;td&gt;06:15 am&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Start Work&lt;/td&gt;
&lt;td&gt;12:00 pm&lt;/td&gt;
&lt;td&gt;07:15 am&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;First meal&lt;/td&gt;
&lt;td&gt;02:00 pm&lt;/td&gt;
&lt;td&gt;09:15 am&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sleep&lt;/td&gt;
&lt;td&gt;02:00 am&lt;/td&gt;
&lt;td&gt;09:15 pm&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;I have a much better track of where I am at the day now.&lt;/p&gt;
&lt;p&gt;There you go - that&apos;s how you wake up early without actually waking up early.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;thanks&quot;&gt;Thanks&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Photo by &lt;a href=&quot;https://unsplash.com/@qstevenson?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText&quot;&gt;Quin Stevenson&lt;/a&gt; on &lt;a href=&quot;https://unsplash.com/photos/3oyeaivM_fE?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText&quot;&gt;Unsplash&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://savvytime.com/&quot;&gt;https://savvytime.com/&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[My New Year's Resolution for 2023]]></title><description><![CDATA[It's that time of the year again... Here's my New Year's resolution for 2023. Unlike previous ones, I'm going to stick to this one.]]></description><link>https://www.adityathebe.com/my-new-years-resolution-2023/</link><guid isPermaLink="false">https://www.adityathebe.com/my-new-years-resolution-2023/</guid><pubDate>Sun, 01 Jan 2023 22:05:00 GMT</pubDate><content:encoded>&lt;p&gt;For the past few days I have been trying to decide which of these two topics to begin learning first: databases or Kubernetes. I&apos;ve grown a sudden interest in these topics because the companies that I want to work at had at least one of the above as a hard requirement - or sometimes both. Now, of course it&apos;s not the only reason why I&apos;m interested in them. My interest goes beyond just fulfilling job requirements as they are both highly essential skills to have in any backend engineer&apos;s arsenal. But it was for sure the spark that ignited the interest/motivation in me.&lt;/p&gt;
&lt;p&gt;While searching for learning resources and companies that are doing amazing things on these topics, I&apos;ve come across a few talented people. One such personality is Kelsey Hightower. He&apos;s an extremely prolific speaker and also a highly decorated software engineer at Google. I&apos;ve been watching his Talks on Youtube and also scrolling through his tweet history (because that&apos;s what I do when I find interesting personalities). One tweet in particular stood out to me&lt;/p&gt;
&lt;blockquote class=&quot;twitter-tweet&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;&amp;quot;What do you say to people who think you&amp;#39;re a one trick pony?&amp;quot;&lt;br&gt;&lt;br&gt;I&amp;#39;ve been a one trick pony my whole career. At one point I was all in on Python and contributed to tools like pip and virtualenv. Then it was Puppet, then Go, then Kubernetes, and now Serverless.&lt;br&gt;&lt;br&gt;It&amp;#39;s called focus. &lt;a href=&quot;https://t.co/nU7YByRB4T&quot;&gt;https://t.co/nU7YByRB4T&lt;/a&gt;&lt;/p&gt;&amp;mdash; Kelsey Hightower (@kelseyhightower) &lt;a href=&quot;https://twitter.com/kelseyhightower/status/1597993734011879426?ref_src=twsrc%5Etfw&quot;&gt;November 30, 2022&lt;/a&gt;&lt;/blockquote&gt; &lt;script async src=&quot;https://platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;
&lt;p&gt;&quot;Focus&quot; - that&apos;s interesting! But let&apos;s put that word aside for a second cuz I have a few more anecdotes to share.&lt;/p&gt;
&lt;p&gt;I&apos;m highly active on Reddit - especially on technology subreddits.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1200px; &quot;
    &gt;
      &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 56.333333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAALABQDASIAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAMFAf/EABYBAQEBAAAAAAAAAAAAAAAAAAQAAv/aAAwDAQACEAMQAAABeippWxyuWv/EABsQAAEEAwAAAAAAAAAAAAAAAAACAxITARAh/9oACAEBAAEFAkQhzWGUFLZS2f/EABgRAAIDAAAAAAAAAAAAAAAAAAACARMU/9oACAEDAQE/Ablg0Kf/xAAXEQADAQAAAAAAAAAAAAAAAAAAARMC/9oACAECAQE/AZaJM//EABgQAAIDAAAAAAAAAAAAAAAAAAAyAhAh/9oACAEBAAY/Atjaiin/xAAdEAACAgEFAAAAAAAAAAAAAAAAAREhMRBRweHw/9oACAEBAAE/IYJKb3svLxoz2Z6NmTkz/9oADAMBAAIAAwAAABD73//EABoRAAICAwAAAAAAAAAAAAAAAAABIfBRYYH/2gAIAQMBAT8QTTczcml3p//EABkRAQACAwAAAAAAAAAAAAAAAAEAMWGB8P/aAAgBAgEBPxAS07Uzk//EABwQAAICAwEBAAAAAAAAAAAAAAERACExYfCR0f/aAAgBAQABPxBKFMl8QtQRdAGh7CmViNmFHi5r8bgdRR4uf//Z&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;My 2022 Reddit Recap&quot;
        title=&quot;&quot;
        src=&quot;/static/1b9952933fd524adadd8dd0d7143bf6d/e5166/reddit-recap-aditya-thebe-2022.jpg&quot;
        srcset=&quot;/static/1b9952933fd524adadd8dd0d7143bf6d/f93b5/reddit-recap-aditya-thebe-2022.jpg 300w,
/static/1b9952933fd524adadd8dd0d7143bf6d/b4294/reddit-recap-aditya-thebe-2022.jpg 600w,
/static/1b9952933fd524adadd8dd0d7143bf6d/e5166/reddit-recap-aditya-thebe-2022.jpg 1200w,
/static/1b9952933fd524adadd8dd0d7143bf6d/7d013/reddit-recap-aditya-thebe-2022.jpg 1343w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
    &lt;/span&gt;&lt;em&gt;My 2022 Reddit Recap&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;I rarely engage though - maybe once in a blue moon. I&apos;m just a lurker.&lt;/p&gt;
&lt;p&gt;Anyway, there&apos;s this another highly skilled developer - Amos (@fasterthanlime) - who just &lt;a href=&quot;https://www.reddit.com/r/fasterthanlime/comments/zzzabq/end_of_year_ama_ask_me_anything/&quot;&gt;hosted an AMA (Ask Me Anything) on reddit&lt;/a&gt;. I wanted to share one of the questions on that AMA, but unfortunately it was deleted. Nevertheless, the answer alone should suffice to convey what I&apos;m trying to get across here.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;I&apos;m very selective about what I spend my time on, ...&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It&apos;s not rocket science but rather a common knowledge but when you hear it from people you look up to - it really hits you. Advices are nice but I think they only bear weight if they come from someone you respect. (Btw, I&apos;m not saying @fasterthanlime is my hero. Our view on the Go programming language differs radically.)&lt;/p&gt;
&lt;p&gt;There are a few others who I&apos;ve been following just as much&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Thomas Ptacek (I came to learn about him through my job application at fly.io but turns out he&apos;s a highly decorated security engineer)&lt;/li&gt;
&lt;li&gt;Fillipo (Just as &lt;del&gt;old&lt;/del&gt; young as me and has already led the Go security team at Google!)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;a-sudden-realization&quot;&gt;A sudden realization&lt;/h2&gt;
&lt;p&gt;If you notice one common thing among these guys - it&apos;s&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Focus&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;They specialize in something and they&apos;re very frugal with their time.&lt;/p&gt;
&lt;p&gt;I made a sudden realization that focus is something that I&apos;ve been lacking more and more recently.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Oh look - an interesting blog post on Reddit about creating SVG with Javascript - let&apos;s read it!&lt;/p&gt;
&lt;p&gt;Shoot! I can barely understand what&apos;s going on.&lt;/p&gt;
&lt;p&gt;Meh, back to Reddit.&lt;/p&gt;
&lt;p&gt;Now what&apos;s this...? a reddit post on how 1Password&apos;s cryptography is more secure than Lastpass&apos;.&lt;/p&gt;
&lt;p&gt;...CLICK!!!&lt;/p&gt;
&lt;p&gt;I don&apos;t understand a single thing about any cryptography jargon that&apos;s in this post.&lt;/p&gt;
&lt;p&gt;I better scroll down to the comments. That might be interesting.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Why am I hopping through these posts reading about things that I have very little understanding of? Is that even &quot;reading&quot; because as soon as I stop understanding some of the jargon, I&apos;ll just try to skim through the post and quickly scroll down to read the comments. In the end, I mostly likely will end up without gaining any knowledge. And even if I do, I will forget about it because when will I ever use it?&lt;/p&gt;
&lt;p&gt;On the flip side, I don&apos;t want to narrow down what I intake so much that I become a one trick pony. Diversity is important! But, the balance is even more important.&lt;/p&gt;
&lt;h2 id=&quot;a-look-back-at-school&quot;&gt;A look back at school&lt;/h2&gt;
&lt;p&gt;I have learned quite a few technologies in the past year but all of them in surface.&lt;/p&gt;
&lt;p&gt;That&apos;s not how I learned things when I was at school! I used to sit down and grok on topics for hours to grasp things from the root. I used to love making notes - and in fact I was pretty good at it.&lt;/p&gt;
&lt;p&gt;Where are all these good practices that I highly benefited from? I barely pickup pen &amp;#x26; paper these days. I don&apos;t have any notes and I haven&apos;t learned anything in detail lately.&lt;/p&gt;
&lt;p&gt;I think it&apos;s mainly because of focus. At school, I could stay focused on one thing because there were syllabuses! If I suddenly had a interest on something out of syllabus, I knew not to spend too much time on it because I had a syllabus to cover. The syllabus were a roadmap, an overseer to guide my focus. Oh, I wish there was a syllabus to go from Software engineer to a Staff Engineer - I would have aced it!&lt;/p&gt;
&lt;p&gt;So here&apos;s my new year&apos;s resolution.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;To maintain focus and balance in what I read.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id=&quot;thanks-to&quot;&gt;Thanks to&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Stefan Cosma for the Photo &lt;a href=&quot;https://unsplash.com/@stefanbc?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText&quot;&gt;Stefan Cosma&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ChatGPT for providing me with better words.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Places To Go On A Ride Around Kathmandu]]></title><description><![CDATA[Sharing a handful of places I've gone on a motorcycle ride around Kathmandu.]]></description><link>https://www.adityathebe.com/places-to-ride-around-kathmandu/</link><guid isPermaLink="false">https://www.adityathebe.com/places-to-ride-around-kathmandu/</guid><pubDate>Sun, 24 Jul 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;It has been around 2 months since I purchased my motorcycle and I&apos;ve already exhausted pretty much all the ride destinations around Kathmandu. I guess all riders can relate to this :).&lt;/p&gt;
&lt;p&gt;Apart from the obvious popular destinations, it takes a bit of an effort to find the lesser known ones. Few vlogs on YouTube and scouring through Google Maps have helped me find a few. Googling for desinations is pretty much useless as almost all of the handful of blog posts have an identical list of places and they focus more on the desination than the ride. I care about the enjoyable rides than the destination itself. This blog post is my attempt to provide information especially to motorcycle riders.&lt;/p&gt;
&lt;h2 id=&quot;my-ride&quot;&gt;My Ride&lt;/h2&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1200px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/42d264981fdba5e1f8165b43af341e0d/1d8ab/svartpilen-pilot-baba-bhaktapur.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAPABQDASIAAhEBAxEB/8QAGAAAAwEBAAAAAAAAAAAAAAAAAAIEAQP/xAAUAQEAAAAAAAAAAAAAAAAAAAAB/9oADAMBAAIQAxAAAAFXlwKDgD//xAAbEAACAQUAAAAAAAAAAAAAAAABAhIAAxETMf/aAAgBAQABBQLa0muxBoqQ0Rlef//EABURAQEAAAAAAAAAAAAAAAAAABAR/9oACAEDAQE/AYf/xAAVEQEBAAAAAAAAAAAAAAAAAAABEP/aAAgBAgEBPwEn/8QAGhABAAIDAQAAAAAAAAAAAAAAABEhATFhof/aAAgBAQAGPwJ1Uo8aXl//xAAcEAACAQUBAAAAAAAAAAAAAAAAASERMUFRYYH/2gAIAQEAAT8hVZN8Ni5MLEpbomBNsLQeiJya8P/aAAwDAQACAAMAAAAQzy//xAAXEQADAQAAAAAAAAAAAAAAAAAAARFR/9oACAEDAQE/EHoiP//EABYRAQEBAAAAAAAAAAAAAAAAAAEAIf/aAAgBAgEBPxBJbf/EAB0QAQACAgIDAAAAAAAAAAAAAAEAESExgZFBcaH/2gAIAQEAAT8Qc2ArahxBGI7U8dZ4gEC2WBNzLNNihPfcuWoFva4XclWGvs//2Q==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;Svartpilen 250 at Pilot Baba Bhaktapur&quot;
        title=&quot;&quot;
        src=&quot;/static/42d264981fdba5e1f8165b43af341e0d/e5166/svartpilen-pilot-baba-bhaktapur.jpg&quot;
        srcset=&quot;/static/42d264981fdba5e1f8165b43af341e0d/f93b5/svartpilen-pilot-baba-bhaktapur.jpg 300w,
/static/42d264981fdba5e1f8165b43af341e0d/b4294/svartpilen-pilot-baba-bhaktapur.jpg 600w,
/static/42d264981fdba5e1f8165b43af341e0d/e5166/svartpilen-pilot-baba-bhaktapur.jpg 1200w,
/static/42d264981fdba5e1f8165b43af341e0d/1d8ab/svartpilen-pilot-baba-bhaktapur.jpg 1627w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;em&gt;Svartpilen 250 at Pilot Baba Bhaktapur&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;I have a Svartpilen 250, which does alright on decent offroad. The ground clearance is pretty much one of the least on any bikes you can find on the market right now. And that&apos;s why I personally prefer to avoid offroad.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;I think it&apos;s best to categorize the list into two sections&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Good Roads&lt;/li&gt;
&lt;li&gt;Off-roads&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;good-roads&quot;&gt;Good Roads&lt;/h2&gt;
&lt;h3 id=&quot;1-nagarkot&quot;&gt;1. Nagarkot&lt;/h3&gt;
&lt;p&gt;You saw this coming from a mile away, didn&apos;t you? Obviously, it&apos;s number one on the list because there&apos;s no rider who hasn&apos;t ridden the twisties of Nagarkot. One of my best rides, if not the best, has been on this road on a rainy morning.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1200px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/b0a05091be1d05176eab4bf45fd30c84/1d8ab/svartpilen-250-nagarkot.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAPABQDASIAAhEBAxEB/8QAGAAAAgMAAAAAAAAAAAAAAAAAAAQBAgP/xAAVAQEBAAAAAAAAAAAAAAAAAAABAP/aAAwDAQACEAMQAAABmiQLRmF//8QAGBABAQEBAQAAAAAAAAAAAAAAAQACIRH/2gAIAQEAAQUC05nUvVjr5f/EABURAQEAAAAAAAAAAAAAAAAAAAAR/9oACAEDAQE/AYj/xAAVEQEBAAAAAAAAAAAAAAAAAAAAEf/aAAgBAgEBPwGq/8QAFhABAQEAAAAAAAAAAAAAAAAAAQAg/9oACAEBAAY/AiM//8QAGhABAAIDAQAAAAAAAAAAAAAAAQARITFRgf/aAAgBAQABPyFTR0uZYheey21RTRA5IT//2gAMAwEAAgADAAAAEEAf/8QAFREBAQAAAAAAAAAAAAAAAAAAEBH/2gAIAQMBAT8Qof/EABURAQEAAAAAAAAAAAAAAAAAABEA/9oACAECAQE/EEMr/8QAHBABAAMBAAMBAAAAAAAAAAAAAQARITFBYYGx/9oACAEBAAE/EKw17hp3fcpebog7CtxeBWQSvpcAuivIECt/Z//Z&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;Svartpilen 250 at Nagarkot&quot;
        title=&quot;&quot;
        src=&quot;/static/b0a05091be1d05176eab4bf45fd30c84/e5166/svartpilen-250-nagarkot.jpg&quot;
        srcset=&quot;/static/b0a05091be1d05176eab4bf45fd30c84/f93b5/svartpilen-250-nagarkot.jpg 300w,
/static/b0a05091be1d05176eab4bf45fd30c84/b4294/svartpilen-250-nagarkot.jpg 600w,
/static/b0a05091be1d05176eab4bf45fd30c84/e5166/svartpilen-250-nagarkot.jpg 1200w,
/static/b0a05091be1d05176eab4bf45fd30c84/1d8ab/svartpilen-250-nagarkot.jpg 1627w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;em&gt;Svartpilen 250 at Nagarkot&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;There&apos;s probably 3 or 4 different routes (or even more) to reach Nagarkot from Kathmandu and one, in particular, is my favorite. I&apos;m not sure how to show that route here but it&apos;s the one that Google Maps suggest.&lt;/p&gt;
&lt;p&gt;The road was under construction just a few months ago but at the time of writing this post, it&apos;s pretty good. What I like best about Nagarkot ride is that at some point in the middle you&apos;ll have to ride through the fogs and drizzle.&lt;/p&gt;
&lt;h3 id=&quot;2-dadagaun-shivapuri-national-park-budhanilkantha&quot;&gt;2. Dadagaun, Shivapuri National Park, Budhanilkantha&lt;/h3&gt;
&lt;p&gt;If I had to pick my favorite road on this list, it&apos;d probably be this. You get to ride through a mild forest on a road that&apos;s probably the best around Kathmandu.&lt;/p&gt;
&lt;p&gt;It&apos;s fairly close to where I live (just 16kms away) that sometimes I even ride here during my lunch break.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1200px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/53316ee457d4d7dedca72e05dc7cef70/d2602/svartpilen-250-dandagaun-shivapuri.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAPABQDASIAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAMEAv/EABYBAQEBAAAAAAAAAAAAAAAAAAIAAf/aAAwDAQACEAMQAAABzPZMZAwO/wD/xAAbEAABBAMAAAAAAAAAAAAAAAABAAIRIQMSE//aAAgBAQABBQLKS1pfI3U1F8gV/8QAFREBAQAAAAAAAAAAAAAAAAAAABH/2gAIAQMBAT8BR//EABURAQEAAAAAAAAAAAAAAAAAAAEQ/9oACAECAQE/AUn/xAAXEAEBAQEAAAAAAAAAAAAAAAAQATFR/9oACAEBAAY/AoaXh//EABsQAAMAAgMAAAAAAAAAAAAAAAABESExQXGR/9oACAEBAAE/IZb6XOsUeXAdQPaQ2Ef/2gAMAwEAAgADAAAAEMQ//8QAFhEBAQEAAAAAAAAAAAAAAAAAAQAR/9oACAEDAQE/EA1t3//EABYRAAMAAAAAAAAAAAAAAAAAAAABIf/aAAgBAgEBPxBCpD//xAAaEAEBAQEBAQEAAAAAAAAAAAABEQBBITFx/9oACAEBAAE/EIcUaEfR9N0Xo4FzfSrmcW2ddUaKLlysPzf/2Q==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;On The Way To Dandagaun, Shivapuri&quot;
        title=&quot;&quot;
        src=&quot;/static/53316ee457d4d7dedca72e05dc7cef70/e5166/svartpilen-250-dandagaun-shivapuri.jpg&quot;
        srcset=&quot;/static/53316ee457d4d7dedca72e05dc7cef70/f93b5/svartpilen-250-dandagaun-shivapuri.jpg 300w,
/static/53316ee457d4d7dedca72e05dc7cef70/b4294/svartpilen-250-dandagaun-shivapuri.jpg 600w,
/static/53316ee457d4d7dedca72e05dc7cef70/e5166/svartpilen-250-dandagaun-shivapuri.jpg 1200w,
/static/53316ee457d4d7dedca72e05dc7cef70/d9c39/svartpilen-250-dandagaun-shivapuri.jpg 1800w,
/static/53316ee457d4d7dedca72e05dc7cef70/df51d/svartpilen-250-dandagaun-shivapuri.jpg 2400w,
/static/53316ee457d4d7dedca72e05dc7cef70/d2602/svartpilen-250-dandagaun-shivapuri.jpg 4032w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;em&gt;On The Way To Dandagaun, Shivapuri&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Once you cross Mahargunj, the traffic is pretty light and even the road to Budhanilkantha is quite fun. Just 1 or 2 kms after Budhanilkantha, you&apos;ll start to make the climb up and then the fun begins.&lt;/p&gt;
&lt;p&gt;Just be aware that this road goes through an Army premise and that means you&apos;ll need to register your vehicle before you enter. Make sure you have your driving license and bill book with you as you&apos;ll need to provide them during entry registration.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1200px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/5b6d3dc2b95670020a0c2acb730c7abe/d2602/svartpilen-250-dandagaun-shivapuri-02.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAPABQDASIAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAMEAf/EABQBAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhADEAAAAZWRuNFB/8QAGRAAAwEBAQAAAAAAAAAAAAAAAAECAxIU/9oACAEBAAEFAvOLCSsZTVsdcpaI/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPwE//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPwE//8QAGxAAAgIDAQAAAAAAAAAAAAAAAAECIhARITL/2gAIAQEABj8CrItI9nTbSx//xAAbEAACAwEBAQAAAAAAAAAAAAAAAREhMWFxkf/aAAgBAQABPyGDxfpGxfCER+GqyGJgnVHQf//aAAwDAQACAAMAAAAQAN//xAAXEQEAAwAAAAAAAAAAAAAAAAAAEWGB/9oACAEDAQE/ENRb/8QAGBEAAgMAAAAAAAAAAAAAAAAAABEBUWH/2gAIAQIBAT8QcUPD/8QAGhABAQEBAQEBAAAAAAAAAAAAAREAIZExYf/aAAgBAQABPxCChwT4vmnpofgPdDJIJXe57Qh0AMXqMLbckUELerv/2Q==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;At Dandagaun Resort&quot;
        title=&quot;&quot;
        src=&quot;/static/5b6d3dc2b95670020a0c2acb730c7abe/e5166/svartpilen-250-dandagaun-shivapuri-02.jpg&quot;
        srcset=&quot;/static/5b6d3dc2b95670020a0c2acb730c7abe/f93b5/svartpilen-250-dandagaun-shivapuri-02.jpg 300w,
/static/5b6d3dc2b95670020a0c2acb730c7abe/b4294/svartpilen-250-dandagaun-shivapuri-02.jpg 600w,
/static/5b6d3dc2b95670020a0c2acb730c7abe/e5166/svartpilen-250-dandagaun-shivapuri-02.jpg 1200w,
/static/5b6d3dc2b95670020a0c2acb730c7abe/d9c39/svartpilen-250-dandagaun-shivapuri-02.jpg 1800w,
/static/5b6d3dc2b95670020a0c2acb730c7abe/df51d/svartpilen-250-dandagaun-shivapuri-02.jpg 2400w,
/static/5b6d3dc2b95670020a0c2acb730c7abe/d2602/svartpilen-250-dandagaun-shivapuri-02.jpg 4032w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;em&gt;At Dandagaun Resort&lt;/em&gt;
&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1200px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/d20ab80f16b3489657f0e84c4f9019d1/d2602/svartpilen-250-dandagaun-shivapuri-03.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAPABQDASIAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAABQACA//EABUBAQEAAAAAAAAAAAAAAAAAAAEA/9oADAMBAAIQAxAAAAFLmFuGYeH/xAAbEAACAQUAAAAAAAAAAAAAAAAAASICEBETIf/aAAgBAQABBQJ1WiSR3Gtn/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPwE//8QAFREBAQAAAAAAAAAAAAAAAAAAABH/2gAIAQIBAT8Bqv/EABcQAAMBAAAAAAAAAAAAAAAAAAABMSH/2gAIAQEABj8ChTWilZrP/8QAGxAAAwACAwAAAAAAAAAAAAAAAAERITFBgZH/2gAIAQEAAT8hSG7loiFcTZdka6XGympP0//aAAwDAQACAAMAAAAQ/wDv/8QAFREBAQAAAAAAAAAAAAAAAAAAABH/2gAIAQMBAT8QR//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQIBAT8QD//EAB0QAQADAAIDAQAAAAAAAAAAAAEAESExQVFhgaH/2gAIAQEAAT8QUrte8ln6pivIfbFIFXWZZRDoi6uc7wDf1P/Z&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;View From Dandagaun, Shivapuri&quot;
        title=&quot;&quot;
        src=&quot;/static/d20ab80f16b3489657f0e84c4f9019d1/e5166/svartpilen-250-dandagaun-shivapuri-03.jpg&quot;
        srcset=&quot;/static/d20ab80f16b3489657f0e84c4f9019d1/f93b5/svartpilen-250-dandagaun-shivapuri-03.jpg 300w,
/static/d20ab80f16b3489657f0e84c4f9019d1/b4294/svartpilen-250-dandagaun-shivapuri-03.jpg 600w,
/static/d20ab80f16b3489657f0e84c4f9019d1/e5166/svartpilen-250-dandagaun-shivapuri-03.jpg 1200w,
/static/d20ab80f16b3489657f0e84c4f9019d1/d9c39/svartpilen-250-dandagaun-shivapuri-03.jpg 1800w,
/static/d20ab80f16b3489657f0e84c4f9019d1/df51d/svartpilen-250-dandagaun-shivapuri-03.jpg 2400w,
/static/d20ab80f16b3489657f0e84c4f9019d1/d2602/svartpilen-250-dandagaun-shivapuri-03.jpg 4032w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;em&gt;View From Dandagaun, Shivapuri&lt;/em&gt;&lt;/p&gt;
&lt;h3 id=&quot;3-kalu-pandeys-crematorium-dahachowk&quot;&gt;3. Kalu Pandey&apos;s Crematorium, Dahachowk&lt;/h3&gt;
&lt;p&gt;This road actually exceeded my expectation. I was originally headed to Switzerland park, which I found pretty underwhelming (there&apos;s literally nothing), but then decided to keep moving.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 915px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/437d1046731b490a0df91e2df82feb48/6c74b/road-to-kalu-pandey-crematorium.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 133.33333333333331%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAbABQDASIAAhEBAxEB/8QAGAAAAwEBAAAAAAAAAAAAAAAAAAQFAQP/xAAWAQEBAQAAAAAAAAAAAAAAAAAAAQL/2gAMAwEAAhADEAAAAaOyGigSQktp9ZoNI//EAB0QAAIBBAMAAAAAAAAAAAAAAAECAwAEERIQITH/2gAIAQEAAQUC8EeSmtSydpcqqG+onJGupQZHP//EABQRAQAAAAAAAAAAAAAAAAAAACD/2gAIAQMBAT8BH//EABQRAQAAAAAAAAAAAAAAAAAAACD/2gAIAQIBAT8BH//EABsQAAIBBQAAAAAAAAAAAAAAAAABEBEgITEy/9oACAEBAAY/AhNxsyzmKW//xAAbEAEBAAMAAwAAAAAAAAAAAAABABEhMRBxof/aAAgBAQABPyFR2HUXcq4XLbo9RgPRbdfUlDBhcK6s+P/aAAwDAQACAAMAAAAQcMcC/8QAFxEBAQEBAAAAAAAAAAAAAAAAAQAQEf/aAAgBAwEBPxDAuF//xAAYEQACAwAAAAAAAAAAAAAAAAAAARARIf/aAAgBAgEBPxCHpbP/xAAbEAEAAgMBAQAAAAAAAAAAAAABABEhMUFRYf/aAAgBAQABPxBw1YKHsZgT04QjiNUVUVQ4M93LoHUFr8lj0XiPh9YlqFA77LiyHkxx5BVuW+z/2Q==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;Road To Kalu Pandey Crematorium&quot;
        title=&quot;&quot;
        src=&quot;/static/437d1046731b490a0df91e2df82feb48/6c74b/road-to-kalu-pandey-crematorium.jpg&quot;
        srcset=&quot;/static/437d1046731b490a0df91e2df82feb48/f93b5/road-to-kalu-pandey-crematorium.jpg 300w,
/static/437d1046731b490a0df91e2df82feb48/b4294/road-to-kalu-pandey-crematorium.jpg 600w,
/static/437d1046731b490a0df91e2df82feb48/6c74b/road-to-kalu-pandey-crematorium.jpg 915w&quot;
        sizes=&quot;(max-width: 915px) 100vw, 915px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;em&gt;Road To Kalu Pandey Crematorium&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;To my surprise, I found the Kalu Pandey Crematorium at the end of the road. Yes, THE Kalu Pandey about whom we all read in our secondary school. There&apos;s no entry fee and the site is well maintained.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1200px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/f3d3bf93a726ba9e8bb621ac430ebdc6/9568a/kalu-pandey-crematiorium.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 133.33333333333331%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAbABQDASIAAhEBAxEB/8QAGQAAAgMBAAAAAAAAAAAAAAAAAAQBAgMF/8QAFgEBAQEAAAAAAAAAAAAAAAAAAAEC/9oADAMBAAIQAxAAAAF3XjWR8UKUMpzbmYf/xAAZEAACAwEAAAAAAAAAAAAAAAAAAgEREhP/2gAIAQEAAQUCR4tmJImVOrX1NqaU0hRRR//EABQRAQAAAAAAAAAAAAAAAAAAACD/2gAIAQMBAT8BH//EABYRAQEBAAAAAAAAAAAAAAAAABEAEP/aAAgBAgEBPwFnf//EABwQAAIBBQEAAAAAAAAAAAAAAAAyARARICExof/aAAgBAQAGPwLtb6k5AvoggmH/xAAcEAADAAIDAQAAAAAAAAAAAAAAAREhkTFBUXH/2gAIAQEAAT8hblZC28s5EjtXkbqew+QtcNl+uxeXYk8I8IP/2gAMAwEAAgADAAAAELzb8//EABYRAQEBAAAAAAAAAAAAAAAAABEAEP/aAAgBAwEBPxAjf//EABYRAQEBAAAAAAAAAAAAAAAAAAAREP/aAAgBAgEBPxDCI//EAB0QAQACAgIDAAAAAAAAAAAAAAEAESFRMUFhcYH/2gAIAQEAAT8Qr3q1W/Urlz4iO0VMooLYemLGuVKC+sxWz5gCzhQlswcgGG84osD6mHtzE1rwhrn/2Q==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;Kalu Pandey Crematorium&quot;
        title=&quot;&quot;
        src=&quot;/static/f3d3bf93a726ba9e8bb621ac430ebdc6/e5166/kalu-pandey-crematiorium.jpg&quot;
        srcset=&quot;/static/f3d3bf93a726ba9e8bb621ac430ebdc6/f93b5/kalu-pandey-crematiorium.jpg 300w,
/static/f3d3bf93a726ba9e8bb621ac430ebdc6/b4294/kalu-pandey-crematiorium.jpg 600w,
/static/f3d3bf93a726ba9e8bb621ac430ebdc6/e5166/kalu-pandey-crematiorium.jpg 1200w,
/static/f3d3bf93a726ba9e8bb621ac430ebdc6/d9c39/kalu-pandey-crematiorium.jpg 1800w,
/static/f3d3bf93a726ba9e8bb621ac430ebdc6/df51d/kalu-pandey-crematiorium.jpg 2400w,
/static/f3d3bf93a726ba9e8bb621ac430ebdc6/9568a/kalu-pandey-crematiorium.jpg 3024w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;em&gt;Kalu Pandey Crematorium&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;There&apos;re also a few resorts at the top and also a view tower (as seen in the image below).&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1200px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/1e13c13c2946b29923e0b1ae7f2ef0bb/d2602/view-tower-resort.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAPABQDASIAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAABQACA//EABYBAQEBAAAAAAAAAAAAAAAAAAEAAv/aAAwDAQACEAMQAAABQwRycqxM3//EABsQAAEEAwAAAAAAAAAAAAAAAAEAAgMREhMh/9oACAEBAAEFAmqSUYtksbjXXI2v/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPwE//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPwE//8QAFxABAQEBAAAAAAAAAAAAAAAAEQAQMv/aAAgBAQAGPwLG6lc//8QAGxAAAwACAwAAAAAAAAAAAAAAAAERITFBUWH/2gAIAQEAAT8hgU6T3YhdJDozlgthmvLGV4R//9oADAMBAAIAAwAAABDPD//EABYRAQEBAAAAAAAAAAAAAAAAAAEAEf/aAAgBAwEBPxDQtL//xAAXEQEAAwAAAAAAAAAAAAAAAAAAESFB/9oACAECAQE/ENhb/8QAHBAAAgICAwAAAAAAAAAAAAAAAREAITFBUXGB/9oACAEBAAE/EEJlKFLGxHJoRtgRYeIBYsAAIj2cIFc1CEU9z//Z&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;View Tower Resort&quot;
        title=&quot;&quot;
        src=&quot;/static/1e13c13c2946b29923e0b1ae7f2ef0bb/e5166/view-tower-resort.jpg&quot;
        srcset=&quot;/static/1e13c13c2946b29923e0b1ae7f2ef0bb/f93b5/view-tower-resort.jpg 300w,
/static/1e13c13c2946b29923e0b1ae7f2ef0bb/b4294/view-tower-resort.jpg 600w,
/static/1e13c13c2946b29923e0b1ae7f2ef0bb/e5166/view-tower-resort.jpg 1200w,
/static/1e13c13c2946b29923e0b1ae7f2ef0bb/d9c39/view-tower-resort.jpg 1800w,
/static/1e13c13c2946b29923e0b1ae7f2ef0bb/df51d/view-tower-resort.jpg 2400w,
/static/1e13c13c2946b29923e0b1ae7f2ef0bb/d2602/view-tower-resort.jpg 4032w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;em&gt;View Tower Resort&lt;/em&gt;&lt;/p&gt;
&lt;h3 id=&quot;4-nuwakot-via-tokha---bardalinn-resort-shivapuri&quot;&gt;4. Nuwakot (via Tokha -&gt; Bardalinn Resort-Shivapuri).&lt;/h3&gt;
&lt;p&gt;In terms of what the journey has to provide, this is probably the top on the list. The road itself is decent as there are quite a few broken segments on the way but my god the scenery is just breathtaking. It feels like you&apos;re way away from Kathmandu and are in a different region of the country.&lt;/p&gt;
&lt;p&gt;There&apos;s a waterfall on the way - Jhor Waterfall, right after you cross Tokha. It&apos;s meh! No idea why it&apos;s so hyped as you can see all these bikes parked.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 915px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/ef97165b4647707e09f4a2b00ed88915/6c74b/jhor-waterfall-bike-queue.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 133.33333333333331%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAbABQDASIAAhEBAxEB/8QAGAABAQEBAQAAAAAAAAAAAAAABQABAgP/xAAWAQEBAQAAAAAAAAAAAAAAAAACAAH/2gAMAwEAAhADEAAAAUPPDEUYmyWHTGKy7rP/xAAcEAACAgIDAAAAAAAAAAAAAAACEQABAxIiMkP/2gAIAQEAAQUCUI9brIUHYRM0SjmW+Wyh9fVU/wD/xAAWEQEBAQAAAAAAAAAAAAAAAAARABD/2gAIAQMBAT8BI3//xAAWEQEBAQAAAAAAAAAAAAAAAAASABD/2gAIAQIBAT8Bc9//xAAcEAACAgIDAAAAAAAAAAAAAAAAARExEHEyQZH/2gAIAQEABj8CItnEhQObLfuHB3hbHs//xAAcEAEAAwACAwAAAAAAAAAAAAABABEhQXExUZH/2gAIAQEAAT8hMwiJbxOV8xruetmyX4qsvbTdRgh2HHHuFWEOlHbIy6wVT//aAAwDAQACAAMAAAAQC8nB/8QAFxEBAAMAAAAAAAAAAAAAAAAAEAEhMf/aAAgBAwEBPxConD//xAAYEQEBAQEBAAAAAAAAAAAAAAABABEhMf/aAAgBAgEBPxDScLEeyl//xAAfEAEAAwABBAMAAAAAAAAAAAABABEhMUFRYXGBodH/2gAIAQEAAT8Q5gj5OseBwA8e40dKULfs5WRbKy/MYYqaTe8WYRccviNl7QZFu6HtFAGO5Tf1GQNNQFMNi729lAqBC3Cf/9k=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;jhor waterfall bike queue&quot;
        title=&quot;&quot;
        src=&quot;/static/ef97165b4647707e09f4a2b00ed88915/6c74b/jhor-waterfall-bike-queue.jpg&quot;
        srcset=&quot;/static/ef97165b4647707e09f4a2b00ed88915/f93b5/jhor-waterfall-bike-queue.jpg 300w,
/static/ef97165b4647707e09f4a2b00ed88915/b4294/jhor-waterfall-bike-queue.jpg 600w,
/static/ef97165b4647707e09f4a2b00ed88915/6c74b/jhor-waterfall-bike-queue.jpg 915w&quot;
        sizes=&quot;(max-width: 915px) 100vw, 915px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;em&gt;Jhor Waterfall Bike Parking&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 915px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/ee043e487cba8541f16ef57c41f5a74e/6c74b/jhor-waterfall.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 133.33333333333331%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAbABQDASIAAhEBAxEB/8QAGQAAAgMBAAAAAAAAAAAAAAAAAAMBAgQF/8QAFgEBAQEAAAAAAAAAAAAAAAAAAAIB/9oADAMBAAIQAxAAAAFejm3lYQRtn520kYH/xAAbEAEBAAMAAwAAAAAAAAAAAAABAgAREgMTMv/aAAgBAQABBQKesLPVS7l0VU5Y7JypDOeh+PErTJv/xAAXEQADAQAAAAAAAAAAAAAAAAAAARAR/9oACAEDAQE/ATXf/8QAFxEBAAMAAAAAAAAAAAAAAAAAABARIf/aAAgBAgEBPwFUa//EAB4QAAIBBAMBAAAAAAAAAAAAAAABIRARMUECEmGh/9oACAEBAAY/Aly+nVRdzTQnggkt5kQxXeqf/8QAHRABAAICAgMAAAAAAAAAAAAAAQARIUExUXGBkf/aAAgBAQABPyFAbW3EMMrxIDl9mCVSxodRFw1MuFCdTKK2guuiuYm3dy1RyhKBXuf/2gAMAwEAAgADAAAAEJvswf/EABYRAQEBAAAAAAAAAAAAAAAAABEAEP/aAAgBAwEBPxAwYv/EABgRAAMBAQAAAAAAAAAAAAAAAAABESFR/9oACAECAQE/EHZEJzS9H//EAB4QAQEAAwEAAgMAAAAAAAAAAAERADFBIVFhgcHR/9oACAEBAAE/EKhA30o5leFGDSaMSnk4D3J7RRS2fn9YQ25iaPz49+8Q1wPcJBQti2axugPAe6ZD4wZU4J0uOsYsejcX2EmuymLkA4L+5//Z&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;jhor waterfall&quot;
        title=&quot;&quot;
        src=&quot;/static/ee043e487cba8541f16ef57c41f5a74e/6c74b/jhor-waterfall.jpg&quot;
        srcset=&quot;/static/ee043e487cba8541f16ef57c41f5a74e/f93b5/jhor-waterfall.jpg 300w,
/static/ee043e487cba8541f16ef57c41f5a74e/b4294/jhor-waterfall.jpg 600w,
/static/ee043e487cba8541f16ef57c41f5a74e/6c74b/jhor-waterfall.jpg 915w&quot;
        sizes=&quot;(max-width: 915px) 100vw, 915px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;em&gt;Jhor Waterfall&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Once you cross this waterfall it starts to get better and better. Although I have to warn you, the climbs are pretty stiff and maybe riding with a pillion on this road isn&apos;t the best idea.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 915px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/dbd68e068e0696d7884feabca637b9ba/6c74b/svartpilen-250-national-park-aditya-thebe.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 133.33333333333331%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAbABQDASIAAhEBAxEB/8QAGQAAAgMBAAAAAAAAAAAAAAAAAAQCAwUG/8QAFgEBAQEAAAAAAAAAAAAAAAAAAQAC/9oADAMBAAIQAxAAAAFtrltmGzMEUpvlnSo4F//EAB0QAAIBBQEBAAAAAAAAAAAAAAABAgMREhMhFDH/2gAIAQEAAQUCc4xPpYuyFXXT9bG9UzhbsEssIn//xAAWEQEBAQAAAAAAAAAAAAAAAAARABD/2gAIAQMBAT8BIwv/xAAWEQEBAQAAAAAAAAAAAAAAAAARABD/2gAIAQIBAT8BZ3//xAAcEAABBAMBAAAAAAAAAAAAAAABABARMRIgIXH/2gAIAQEABj8CEnQZGQ3O+qlT0v/EAB0QAQACAgIDAAAAAAAAAAAAAAEAESExQVGBofH/2gAIAQEAAT8hZoD1NLOdSnVwsd+Zh57iXrgS8S4K4QIcIv3iHIuUuIJxn//aAAwDAQACAAMAAAAQZxP/AP/EABURAQEAAAAAAAAAAAAAAAAAABAR/9oACAEDAQE/EAg//8QAFxEAAwEAAAAAAAAAAAAAAAAAABFBEP/aAAgBAgEBPxBLiDP/xAAfEAEAAgICAgMAAAAAAAAAAAABABEhMUFhUXGRobH/2gAIAQEAAT8QGnCDbJ3Foa+QiX6QFDblyl8dJdO012EsKwssUcGojFWmFiPUeLJ8N6lzB+RB6Vr36i1Spj6YE2tdT//Z&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;National Park Area On The Way To Nuwakot&quot;
        title=&quot;&quot;
        src=&quot;/static/dbd68e068e0696d7884feabca637b9ba/6c74b/svartpilen-250-national-park-aditya-thebe.jpg&quot;
        srcset=&quot;/static/dbd68e068e0696d7884feabca637b9ba/f93b5/svartpilen-250-national-park-aditya-thebe.jpg 300w,
/static/dbd68e068e0696d7884feabca637b9ba/b4294/svartpilen-250-national-park-aditya-thebe.jpg 600w,
/static/dbd68e068e0696d7884feabca637b9ba/6c74b/svartpilen-250-national-park-aditya-thebe.jpg 915w&quot;
        sizes=&quot;(max-width: 915px) 100vw, 915px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;em&gt;National Park Area On The Way To Nuwakot&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 915px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/f594f8b48a40736c525cbc61926961d0/6c74b/svartpilen-250-national-park-area.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 133.33333333333331%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAbABQDASIAAhEBAxEB/8QAGAAAAwEBAAAAAAAAAAAAAAAAAAMEBQL/xAAWAQEBAQAAAAAAAAAAAAAAAAABAAL/2gAMAwEAAhADEAAAAaWYtKbRklTcOdlBwX//xAAcEAEAAgIDAQAAAAAAAAAAAAABAAIDERATISL/2gAIAQEAAQUCrctNwt5jtqOW07kl/h9YYiIKHH//xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAEDAQE/AR//xAAXEQADAQAAAAAAAAAAAAAAAAAAAREQ/9oACAECAQE/AaVb/8QAGxAAAwACAwAAAAAAAAAAAAAAAAERITECECD/2gAIAQEABj8Cx3g2SpkXFFNteP/EABsQAQACAwEBAAAAAAAAAAAAAAEAESExQRBh/9oACAEBAAE/ISLUMoQAIryqIoATdUOkVzgbYnRgwVEgnyQwpCOef//aAAwDAQACAAMAAAAQoMpx/8QAFxEBAQEBAAAAAAAAAAAAAAAAABEBIf/aAAgBAwEBPxCOomP/xAAZEQABBQAAAAAAAAAAAAAAAAAAARARIVH/2gAIAQIBAT8QTbElH//EAB8QAQADAQAABwAAAAAAAAAAAAEAESExQVFhcaHB8f/aAAgBAQABPxDTsMfSWbhsM7cFKLxPOCWg9Cm/qDFX7BmRQ6W7Ns0sWn7AYCXxnxLhTadjTQKiBP/Z&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;National Park Area On The Way To Nuwakot&quot;
        title=&quot;&quot;
        src=&quot;/static/f594f8b48a40736c525cbc61926961d0/6c74b/svartpilen-250-national-park-area.jpg&quot;
        srcset=&quot;/static/f594f8b48a40736c525cbc61926961d0/f93b5/svartpilen-250-national-park-area.jpg 300w,
/static/f594f8b48a40736c525cbc61926961d0/b4294/svartpilen-250-national-park-area.jpg 600w,
/static/f594f8b48a40736c525cbc61926961d0/6c74b/svartpilen-250-national-park-area.jpg 915w&quot;
        sizes=&quot;(max-width: 915px) 100vw, 915px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;em&gt;National Park Area On The Way To Nuwakot&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;As you keep moving there&apos;s another much better waterfall - Mahtong falls, right beside the road.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 915px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/dc060bddd8d9a6e80070df5a65384521/6c74b/waterfall-nuwakot.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 133.33333333333331%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAbABQDASIAAhEBAxEB/8QAGAAAAwEBAAAAAAAAAAAAAAAAAAMEAgX/xAAVAQEBAAAAAAAAAAAAAAAAAAAAAf/aAAwDAQACEAMQAAABlZJpMiiVzV11yysP/8QAHRAAAgICAwEAAAAAAAAAAAAAAQIAAxESBCExQf/aAAgBAQABBQKu3WLyCqu7MwwI40OYOo6ljPtHlqjf/8QAFBEBAAAAAAAAAAAAAAAAAAAAIP/aAAgBAwEBPwEf/8QAFBEBAAAAAAAAAAAAAAAAAAAAIP/aAAgBAgEBPwEf/8QAHRAAAAUFAAAAAAAAAAAAAAAAAAERICESIjFRcf/aAAgBAQAGPwIrZIJnoUQyrbf/xAAdEAACAQUBAQAAAAAAAAAAAAAAAREhMUFRcRBh/9oACAEBAAE/IYkE3bQwpc74FQHzQnQLgr96OoVdEBYy4x5LF5YlmIuj/9oADAMBAAIAAwAAABB06kz/xAAZEQABBQAAAAAAAAAAAAAAAAAAARARITH/2gAIAQMBAT8Q0kWm/8QAFxEBAQEBAAAAAAAAAAAAAAAAAAERUf/aAAgBAgEBPxCVtTjH/8QAHhABAAICAgMBAAAAAAAAAAAAAQARIWExUUGBkXH/2gAIAQEAAT8QBgb3B0fidwd7hmt0NRFpAcaGoxmta4z6nLAroh5cQnk/SZLKay+DnB3KH2WGdq4fkaGqTUSQKGCJbzTB6gWhKFruf//Z&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;Mahtong Falls&quot;
        title=&quot;&quot;
        src=&quot;/static/dc060bddd8d9a6e80070df5a65384521/6c74b/waterfall-nuwakot.jpg&quot;
        srcset=&quot;/static/dc060bddd8d9a6e80070df5a65384521/f93b5/waterfall-nuwakot.jpg 300w,
/static/dc060bddd8d9a6e80070df5a65384521/b4294/waterfall-nuwakot.jpg 600w,
/static/dc060bddd8d9a6e80070df5a65384521/6c74b/waterfall-nuwakot.jpg 915w&quot;
        sizes=&quot;(max-width: 915px) 100vw, 915px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;em&gt;Mahtong Falls&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1200px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/ee5efe269cc9cde831a2e70311497277/9568a/waterfall-nuwakot-svartpilen-250.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 133.33333333333331%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAbABQDASIAAhEBAxEB/8QAGAAAAwEBAAAAAAAAAAAAAAAAAAMEAQX/xAAWAQEBAQAAAAAAAAAAAAAAAAABAAL/2gAMAwEAAhADEAAAAUOizI8QNfD0J1UaN//EABwQAAIBBQEAAAAAAAAAAAAAAAECABAREhMxIv/aAAgBAQABBQLrZqBua5BFMTH52eqNLT//xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAEDAQE/AR//xAAXEQADAQAAAAAAAAAAAAAAAAAAAhAR/9oACAECAQE/AVNv/8QAGxAAAgEFAAAAAAAAAAAAAAAAAAEgEBEhMlH/2gAIAQEABj8CphwuzhtD/8QAHBAAAwADAAMAAAAAAAAAAAAAAAERITFBUWGh/9oACAEBAAE/Iblom13ahrbChxhE49npZFcBqrjKCcK/RFGuCpJpLRHg/9oADAMBAAIAAwAAABCEC0z/xAAWEQEBAQAAAAAAAAAAAAAAAAARABD/2gAIAQMBAT8QZwv/xAAYEQADAQEAAAAAAAAAAAAAAAAAAREQIf/aAAgBAgEBPxBouFZT/8QAHBABAQADAQADAAAAAAAAAAAAAREAITFBYXGB/9oACAEBAAE/ENpJqq81iLLH5p36yYTNANYJYHu7rGVtFWF7hGDTXM0WOvQ1ntUgmKsWbrv7rOTPEwZALQeYuD6M/9k=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;Mahtong Falls Svartpilen 250&quot;
        title=&quot;&quot;
        src=&quot;/static/ee5efe269cc9cde831a2e70311497277/e5166/waterfall-nuwakot-svartpilen-250.jpg&quot;
        srcset=&quot;/static/ee5efe269cc9cde831a2e70311497277/f93b5/waterfall-nuwakot-svartpilen-250.jpg 300w,
/static/ee5efe269cc9cde831a2e70311497277/b4294/waterfall-nuwakot-svartpilen-250.jpg 600w,
/static/ee5efe269cc9cde831a2e70311497277/e5166/waterfall-nuwakot-svartpilen-250.jpg 1200w,
/static/ee5efe269cc9cde831a2e70311497277/d9c39/waterfall-nuwakot-svartpilen-250.jpg 1800w,
/static/ee5efe269cc9cde831a2e70311497277/df51d/waterfall-nuwakot-svartpilen-250.jpg 2400w,
/static/ee5efe269cc9cde831a2e70311497277/9568a/waterfall-nuwakot-svartpilen-250.jpg 3024w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;em&gt;Mahtong Falls Svartpilen 250&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;There&apos;s a local restaurant which offers one of the best Sukutis. I don&apos;t remember the name and unfortunately it&apos;s also not registered on Google Maps but here&apos;s a &lt;a href=&quot;https://goo.gl/maps/XVYSnpcETLYi2Znz6&quot;&gt;link to the place&lt;/a&gt;. I don&apos;t even have a picture of the Sukuti which should you tell you how good it was as I couldn&apos;t stop munching XD.&lt;/p&gt;
&lt;h3 id=&quot;5-chobhar---toudaha---kritipur&quot;&gt;5. Chobhar - Toudaha - Kritipur&lt;/h3&gt;
&lt;p&gt;Chobhar is arguably the most popular destination for riders simply because it&apos;s right around the valley. I&apos;ve been here more than any other places in the list.&lt;/p&gt;
&lt;h3 id=&quot;6-dolalghat---khadichaur&quot;&gt;6. Dolalghat - Khadichaur&lt;/h3&gt;
&lt;p&gt;All the other destinations on the list are mainly twisties. If you want to enjoy speed with a twist of twisties, then it can&apos;t get any better than this road. The scenary is pretty good, the traffic is light and the road is as good as they come in Nepal. Honestly, I found it quite difficult to believe that a road like this is just an hour away from the valley. For first timers on this road, it&apos;ll be quite an experience.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1200px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/0f994d9842bb76323d7c0e72c895a3c2/9568a/dolalghat-svartpilen-250.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 133.33333333333331%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAbABQDASIAAhEBAxEB/8QAGAAAAwEBAAAAAAAAAAAAAAAAAAQFAwb/xAAWAQEBAQAAAAAAAAAAAAAAAAABAAL/2gAMAwEAAhADEAAAAX2OXfKyTCIlmVXN7CwX/8QAHRAAAgIDAAMAAAAAAAAAAAAAAQIAAxAREgQhMf/aAAgBAQABBQJb0Yb3hZVbaYwvJ+Txl4TqAe8f/8QAFBEBAAAAAAAAAAAAAAAAAAAAIP/aAAgBAwEBPwEf/8QAFhEBAQEAAAAAAAAAAAAAAAAAEQAQ/9oACAECAQE/AWd//8QAHBABAAIBBQAAAAAAAAAAAAAAARARAAIhMlFh/9oACAEBAAY/ArGdnKKc5h4RfcaZ/8QAGxAAAgIDAQAAAAAAAAAAAAAAAAERITFBUYH/2gAIAQEAAT8hQfBwSJKdEjNS433A6rVtk7KToIkZDsIYulXCT//aAAwDAQACAAMAAAAQGz0y/8QAFxEAAwEAAAAAAAAAAAAAAAAAAAEREP/aAAgBAwEBPxCEZM//xAAYEQACAwAAAAAAAAAAAAAAAAAAARARQf/aAAgBAgEBPxAUG8j/xAAgEAEBAQACAAcBAAAAAAAAAAABEQAhMUFRYXGBobHR/9oACAEBAAE/EGjosY5939xG5FHMaW0PgyJIj0w68PXOiVOKQ+ucEcObnMO6vcx9MUJRYlzTOBH5q89//9k=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;Dolalghat Svartpilen 250&quot;
        title=&quot;&quot;
        src=&quot;/static/0f994d9842bb76323d7c0e72c895a3c2/e5166/dolalghat-svartpilen-250.jpg&quot;
        srcset=&quot;/static/0f994d9842bb76323d7c0e72c895a3c2/f93b5/dolalghat-svartpilen-250.jpg 300w,
/static/0f994d9842bb76323d7c0e72c895a3c2/b4294/dolalghat-svartpilen-250.jpg 600w,
/static/0f994d9842bb76323d7c0e72c895a3c2/e5166/dolalghat-svartpilen-250.jpg 1200w,
/static/0f994d9842bb76323d7c0e72c895a3c2/d9c39/dolalghat-svartpilen-250.jpg 1800w,
/static/0f994d9842bb76323d7c0e72c895a3c2/df51d/dolalghat-svartpilen-250.jpg 2400w,
/static/0f994d9842bb76323d7c0e72c895a3c2/9568a/dolalghat-svartpilen-250.jpg 3024w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;em&gt;Dolalghat&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;This is definitely a trip for the weekend as it can take up 4-5 hours to get there and be back.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1200px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/17b595a70b0155c8e9987737211f04ef/d2602/khadichaur-bridge.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAPABQDASIAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAIEBf/EABUBAQEAAAAAAAAAAAAAAAAAAAAB/9oADAMBAAIQAxAAAAG5Mxi8iE//xAAZEAEBAAMBAAAAAAAAAAAAAAABAgAREgP/2gAIAQEAAQUC2pTWbozm8D0B7p//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/AT//xAAVEQEBAAAAAAAAAAAAAAAAAAAAEf/aAAgBAgEBPwGq/8QAGxAAAgIDAQAAAAAAAAAAAAAAAAERMiIxQZH/2gAIAQEABj8CTxOFl4WLbJcH/8QAGRABAAMBAQAAAAAAAAAAAAAAAQARITFx/9oACAEBAAE/IdfV1WM5lYO5yOCuAygV7EgCuoYB/9oADAMBAAIAAwAAABBbP//EABYRAQEBAAAAAAAAAAAAAAAAAAARAf/aAAgBAwEBPxCJr//EABURAQEAAAAAAAAAAAAAAAAAAAAR/9oACAECAQE/EIS//8QAHRABAAICAwEBAAAAAAAAAAAAAREhADFBocGR8P/aAAgBAQABPxAsyhxFb5/RkmP7bEk3dvmMjIaJa+5EcGgVdYq0FFXzJoNgOa6z/9k=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;Khadichaur Bridge&quot;
        title=&quot;&quot;
        src=&quot;/static/17b595a70b0155c8e9987737211f04ef/e5166/khadichaur-bridge.jpg&quot;
        srcset=&quot;/static/17b595a70b0155c8e9987737211f04ef/f93b5/khadichaur-bridge.jpg 300w,
/static/17b595a70b0155c8e9987737211f04ef/b4294/khadichaur-bridge.jpg 600w,
/static/17b595a70b0155c8e9987737211f04ef/e5166/khadichaur-bridge.jpg 1200w,
/static/17b595a70b0155c8e9987737211f04ef/d9c39/khadichaur-bridge.jpg 1800w,
/static/17b595a70b0155c8e9987737211f04ef/df51d/khadichaur-bridge.jpg 2400w,
/static/17b595a70b0155c8e9987737211f04ef/d2602/khadichaur-bridge.jpg 4032w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;em&gt;Khadichaur Bridge&lt;/em&gt;&lt;/p&gt;
&lt;h1 id=&quot;offroads&quot;&gt;OffRoads&lt;/h1&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Chitlang - Markhu&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Manichud&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;</content:encoded></item><item><title><![CDATA[Hands-on Aerospike with Go]]></title><description><![CDATA[Get hands on introduction to Aerospike with Golang]]></description><link>https://www.adityathebe.com/aerospike-hands-on-golang/</link><guid isPermaLink="false">https://www.adityathebe.com/aerospike-hands-on-golang/</guid><pubDate>Sat, 08 May 2021 21:20:00 GMT</pubDate><content:encoded>&lt;p&gt;This is an extremely basic introduction to Aerospike. It&apos;s basically a compilation of resources to help you quickly get started.&lt;/p&gt;
&lt;h2 id=&quot;sql-analogy&quot;&gt;SQL Analogy&lt;/h2&gt;
&lt;p&gt;I think the best way to start learning Aerospike is to establish an analogy with SQL databases.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1200px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/1968afad1eac958698c5de6633790acb/01ccc/conceptual-components-of-aerospike-data-model.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 37.333333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAIAAACHqfpvAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAA2ElEQVR42j2Q2xKDIAxE+f+vtFqVagRKuTzY0R7J2H3IJBtCdmPWdV2WxTn3HMcQwudGjFGTlBLxfQOeCFlKMQznnGtK8/PCo2GapmEYKEnGBp69Gtg0W5s2963VlJxLrW+Ruev64ULXwGTf9/8oItu2IZB45SI5JUPtvUfNKsLH1lqW2Bu6DYZ5yrkBIZR4NGg+jgMPUJhRk/ghoU2iJFbV/P8iwEDt+84LPRsqNDIJGW6oYO26pp8vTK31PE8yVLEczxwJqcgjUfHYpnUp5lTe79gMIcb4A8wyhK+NSeArAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;Conceptual components of Aerospike Data model&quot;
        title=&quot;&quot;
        src=&quot;/static/1968afad1eac958698c5de6633790acb/c1b63/conceptual-components-of-aerospike-data-model.png&quot;
        srcset=&quot;/static/1968afad1eac958698c5de6633790acb/5a46d/conceptual-components-of-aerospike-data-model.png 300w,
/static/1968afad1eac958698c5de6633790acb/0a47e/conceptual-components-of-aerospike-data-model.png 600w,
/static/1968afad1eac958698c5de6633790acb/c1b63/conceptual-components-of-aerospike-data-model.png 1200w,
/static/1968afad1eac958698c5de6633790acb/01ccc/conceptual-components-of-aerospike-data-model.png 1399w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;em&gt;Conceptual components of Aerospike Data model&lt;/em&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Aerospike&lt;/th&gt;
&lt;th&gt;SQL&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;NameSpace&lt;/td&gt;
&lt;td&gt;TableSpace&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Set&lt;/td&gt;
&lt;td&gt;Table&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Record/Object&lt;/td&gt;
&lt;td&gt;Row&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bin&lt;/td&gt;
&lt;td&gt;Column&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Key&lt;/td&gt;
&lt;td&gt;Primary Key&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Knowing this much will be sufficient to get us started.&lt;/p&gt;
&lt;h2 id=&quot;install-aerospike&quot;&gt;Install Aerospike&lt;/h2&gt;
&lt;p&gt;I&apos;d recommend installing Aerospike with Docker just because it&apos;s simple that way. For this article, I&apos;m using version &lt;code class=&quot;language-text&quot;&gt;5.5.0.2&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Download aerospike docker image&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;docker&lt;/span&gt; image pull aerospike:5.5.0.2

&lt;span class=&quot;token comment&quot;&gt;# Start docker&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;docker&lt;/span&gt; container run &lt;span class=&quot;token parameter variable&quot;&gt;-p&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3000&lt;/span&gt;:3000 &lt;span class=&quot;token parameter variable&quot;&gt;--rm&lt;/span&gt; aerospike:5.5.0.2&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Aerospike server, by default, runs on port 3000. The &lt;code class=&quot;language-text&quot;&gt;-p&lt;/code&gt; flag tells Docker to map the container&apos;s port &lt;code class=&quot;language-text&quot;&gt;3000&lt;/code&gt; to our system&apos;s port &lt;code class=&quot;language-text&quot;&gt;3000&lt;/code&gt;. The flag &lt;code class=&quot;language-text&quot;&gt;--rm&lt;/code&gt; will automatically delete the docker container after we stop the aerospike server.&lt;/p&gt;
&lt;p&gt;You also need to download the Aerospike Go package which is officially available at &lt;code class=&quot;language-text&quot;&gt;github.com/aerospike/aerospike-client-go&lt;/code&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;go get github.com/aerospike/aerospike-client-go&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;With both of these installed, let&apos;s get started.&lt;/p&gt;
&lt;h2 id=&quot;1-connect-to-aerospike-from-go&quot;&gt;1. Connect to Aerospike from GO&lt;/h2&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;package&lt;/span&gt; main

&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
	&lt;span class=&quot;token string&quot;&gt;&quot;log&quot;&lt;/span&gt;

	as &lt;span class=&quot;token string&quot;&gt;&quot;github.com/aerospike/aerospike-client-go&quot;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	client&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; err &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; as&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;NewClient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;localhost&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; err &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;nil&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		log&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Fatal&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
	client&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Close&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;These few lines of code will connect to Aerospike and then close immediately.&lt;/p&gt;
&lt;h2 id=&quot;2-create-a-set&quot;&gt;2. Create a Set&lt;/h2&gt;
&lt;p&gt;Naturally, the next move you&apos;d think would be to create a &lt;strong&gt;Set&lt;/strong&gt; as we do in relational databases. However, that&apos;s not required in Aerospike because our table (Set) does not have a fixed schema.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The data model is determined through your use of the system. For example, if you wanted to add a new data type to a record, you would write that data type into the record without having to first update any schema&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;3-inserting-data&quot;&gt;3. Inserting data&lt;/h2&gt;
&lt;p&gt;Although we didn&apos;t need to explicitly create a Set, we do however require one. Let&apos;s call our Set &lt;code class=&quot;language-text&quot;&gt;&quot;Person&quot;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;And also a namespace is mandatory. Let&apos;s name it &lt;code class=&quot;language-text&quot;&gt;&quot;Avengers&quot;&lt;/code&gt; for lack of a better word right now 🤷‍♂️. The namespace cannot be created from a client but needs to be configured in the server itself. By default, a namespace called &lt;em&gt;&quot;test&quot;&lt;/em&gt; is created automatically. Let&apos;s create our namespace by modifying the docker command. We can pass in a &lt;code class=&quot;language-text&quot;&gt;NAMESPACE&lt;/code&gt; environment variable to the docker container and it&apos;ll create the namespace for us.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;docker container run -e &apos;NAMESPACE=Avengers&apos; --name &apos;Aero&apos; -p 3000:3000 --rm aerospike:5.5.0.2&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I&apos;ve assigned a name to the docker container so that&apos;s it&apos;ll be easier to reference it later.&lt;/p&gt;
&lt;p&gt;Close the previous container and run the above command to restart the Aerospike server.&lt;/p&gt;
&lt;h3 id=&quot;31-storing-records&quot;&gt;3.1 Storing Records&lt;/h3&gt;
&lt;p&gt;For every record that we want to store, we need a key to identify that record; just like a primary key in RDBMS. Let&apos;s use the person&apos;s name as the key 🙃.&lt;/p&gt;
&lt;p&gt;Then we need to create the record itself. Just so we have a reference, let&apos;s try to insert the person&apos;s age and the name.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;# Reference SQL table
+-----+----------+
| age | name     |
+-----+----------+
| 25  | &quot;Aditya&quot; |
+-----+----------+&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&quot;age&quot; and &quot;name&quot; are columns (bin). We can create them like this&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;binAge := as.NewBin(&quot;age&quot;, 25)
binName := as.NewBin(&quot;name&quot;, &quot;Aditya&quot;)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Finally, to piece everything together here&apos;s the code to store the record.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;package&lt;/span&gt; main

&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
	&lt;span class=&quot;token string&quot;&gt;&quot;log&quot;&lt;/span&gt;

	as &lt;span class=&quot;token string&quot;&gt;&quot;github.com/aerospike/aerospike-client-go&quot;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; Namespace &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Avengers&quot;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; Set &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Person&quot;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	client&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; err &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; as&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;NewClient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;localhost&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; err &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;nil&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		log&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Fatal&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;defer&lt;/span&gt; client&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Close&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

	&lt;span class=&quot;token comment&quot;&gt;// Create key for a record&lt;/span&gt;
	key&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; err &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; as&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;NewKey&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Namespace&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Set&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;aditya&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; err &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;nil&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		log&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Fatal&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

	binAge &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; as&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;NewBin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;age&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;25&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	binName &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; as&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;NewBin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Aditya&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

	client&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;PutBins&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; key&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; binAge&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; binName&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;em&gt;Notice that I never explicitly create the Set &quot;Person&quot;. It is created automatically on-demand&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;The &lt;code class=&quot;language-text&quot;&gt;PutBins()&lt;/code&gt; method can take in any number of bins. If you supply two bins with the same name, then the latter will take precedence.&lt;/p&gt;
&lt;h3 id=&quot;32-different-way-to-create-and-store-bins&quot;&gt;3.2 Different way to create and store bins&lt;/h3&gt;
&lt;p&gt;Instead of creating each bin one by one, we can instead create a BinMap.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;binMap &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; as&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;BinMap&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&quot;age&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;  &lt;span class=&quot;token number&quot;&gt;25&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Aditya&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

client&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Put&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; key&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; binMap&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To me, this looks neater and I think is more readable. Then we can use the &lt;code class=&quot;language-text&quot;&gt;.Put()&lt;/code&gt; method to store the bins.&lt;/p&gt;
&lt;h3 id=&quot;33-putbins-vs-put&quot;&gt;3.3 PutBins() vs Put()&lt;/h3&gt;
&lt;p&gt;So we have two methods to insert bins. Which one should you prefer? Well internally, &lt;code class=&quot;language-text&quot;&gt;Put()&lt;/code&gt; uses &lt;code class=&quot;language-text&quot;&gt;PutBins()&lt;/code&gt; and the &lt;a href=&quot;https://docs.aerospike.com/docs/client/go/usage/best_practices.html&quot;&gt;Official Best Practices&lt;/a&gt; recommends using PutBins over Put to avoid allocation for binmaps.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1200px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/357e3f325aa931224f19316d9bef8ec2/afd61/put-vs-putbins.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 29.666666666666668%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAIAAABM9SnKAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAuElEQVR42nWPSw6EMAxDuf8NQUUgKJRPC2xgAaKdB9bMbrqw7CR2k+w4Dudc0zRgWZZg13VgVVV1XVOHWGvbtjXG7Ps+DIP3nplpmrKUkgx93zNBDwliEKdICw4ix3EUJyKLMUqQBOKhrTj5tYgQSZc4Wud5PuYQgnsfE0VR/BaBaOE8zzmBdOocAs7z/Jjv+ybMfh9nMyQPi5GLlAG+LAsSxMWvz80qbdvG9LquuorR67rS/xdj/AANukndP4KkGwAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;put vs putbins&quot;
        title=&quot;&quot;
        src=&quot;/static/357e3f325aa931224f19316d9bef8ec2/c1b63/put-vs-putbins.png&quot;
        srcset=&quot;/static/357e3f325aa931224f19316d9bef8ec2/5a46d/put-vs-putbins.png 300w,
/static/357e3f325aa931224f19316d9bef8ec2/0a47e/put-vs-putbins.png 600w,
/static/357e3f325aa931224f19316d9bef8ec2/c1b63/put-vs-putbins.png 1200w,
/static/357e3f325aa931224f19316d9bef8ec2/afd61/put-vs-putbins.png 1431w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;h2 id=&quot;4-reading-records&quot;&gt;4. Reading records&lt;/h2&gt;
&lt;p&gt;We can read the records from Aerospike using the &lt;strong&gt;Key&lt;/strong&gt;.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;package&lt;/span&gt; main

&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
	&lt;span class=&quot;token string&quot;&gt;&quot;fmt&quot;&lt;/span&gt;
	&lt;span class=&quot;token string&quot;&gt;&quot;log&quot;&lt;/span&gt;

	as &lt;span class=&quot;token string&quot;&gt;&quot;github.com/aerospike/aerospike-client-go&quot;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; Namespace &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Avengers&quot;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; Set &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Person&quot;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	client&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; err &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; as&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;NewClient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;localhost&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; err &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;nil&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		log&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Fatal&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;defer&lt;/span&gt; client&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Close&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

	&lt;span class=&quot;token comment&quot;&gt;// Create key for a record&lt;/span&gt;
	key&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; err &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; as&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;NewKey&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Namespace&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Set&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;aditya&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; err &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;nil&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		log&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Fatal&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

	binMap &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; as&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;BinMap&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;token string&quot;&gt;&quot;age&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;  &lt;span class=&quot;token number&quot;&gt;25&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
		&lt;span class=&quot;token string&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Aditya&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

	client&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Put&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; key&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; binMap&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

	&lt;span class=&quot;token comment&quot;&gt;// Read a record&lt;/span&gt;
	record&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; err &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; client&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; key&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; err &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;nil&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		log&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Fatal&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
	fmt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;record&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Bins&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// OUTPUT&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;//s map[age:25 name:Aditya]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In addition to reading records with the key, Aerospike also offers a basic query language. It&apos;s similar to SQL but nowhere near as powerful. Here&apos;s an example query&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sql&quot;&gt;&lt;pre class=&quot;language-sql&quot;&gt;&lt;code class=&quot;language-sql&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;FROM&lt;/span&gt; Avengers&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Person &lt;span class=&quot;token keyword&quot;&gt;WHERE&lt;/span&gt; age &lt;span class=&quot;token operator&quot;&gt;BETWEEN&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;15&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;AND&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;30&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;em&gt;I won&apos;t be discussing Aerospike Query language (AQL) in this article.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id=&quot;5-deleting-records&quot;&gt;5. Deleting records&lt;/h2&gt;
&lt;p&gt;We can delete specific records by the key or drop the entire records in the Set.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;package&lt;/span&gt; main

&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
	&lt;span class=&quot;token string&quot;&gt;&quot;fmt&quot;&lt;/span&gt;
	&lt;span class=&quot;token string&quot;&gt;&quot;log&quot;&lt;/span&gt;

	as &lt;span class=&quot;token string&quot;&gt;&quot;github.com/aerospike/aerospike-client-go&quot;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; Namespace &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Avengers&quot;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; Set &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Person&quot;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	client&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; err &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; as&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;NewClient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;localhost&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; err &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;nil&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		log&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Fatal&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;defer&lt;/span&gt; client&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Close&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

	&lt;span class=&quot;token comment&quot;&gt;// Create key for a record&lt;/span&gt;
	key&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; err &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; as&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;NewKey&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Namespace&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Set&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;aditya&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; err &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;nil&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		log&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Fatal&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

	binMap &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; as&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;BinMap&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;token string&quot;&gt;&quot;age&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;  &lt;span class=&quot;token number&quot;&gt;25&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
		&lt;span class=&quot;token string&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Aditya&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

	client&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Put&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; key&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; binMap&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

	&lt;span class=&quot;token comment&quot;&gt;// Read a record&lt;/span&gt;
	record&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; err &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; client&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; key&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; err &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;nil&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		log&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Fatal&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
	fmt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;record&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Bins&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

	&lt;span class=&quot;token comment&quot;&gt;// Delete Record&lt;/span&gt;
	existed&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; err &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; client&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Delete&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; key&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; err &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;nil&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		log&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Fatal&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; existed &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		fmt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Record deleted&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Droping the entire records in the set&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;client.Truncate(nil, Namespace, Set, nil)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;6-policy&quot;&gt;6. Policy&lt;/h2&gt;
&lt;p&gt;Did you notice that the first argument when inserting and reading records was set to &lt;code class=&quot;language-text&quot;&gt;nil&lt;/code&gt;? That parameter is the policy. A Policy helps us define the behavior of read and write operation and much more. For example: what happens when we insert a record with a key that already exists? We can define a policy to overwrite the previous data or ignore the one being inserted.&lt;/p&gt;
&lt;p&gt;Let&apos;s create a write policy that&apos;ll tell Aerospike server to replace old records if new ones arrive&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;policy := as.NewWritePolicy(0, 0)
policy.RecordExistsAction = as.REPLACE
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;7-aql&quot;&gt;7. AQL&lt;/h2&gt;
&lt;p&gt;Aerospike offers a command-line utility - AQL. It comes preinstalled in the docker image we downloaded. Let&apos;s get an interactive shell on the container&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;docker&lt;/span&gt; container &lt;span class=&quot;token builtin class-name&quot;&gt;exec&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-it&lt;/span&gt; Aero aql&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Try out these few queries&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;SHOW NAMESPACES;

SELECT * FROM Avengers.Person;

TRUNCATE Avengers.Person;

SHOW BINS;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;hr&gt;
&lt;h1 id=&quot;references&quot;&gt;References&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.aerospike.com/docs/guide/glossary.html&quot;&gt;Aerospike Glossary&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.aerospike.com/docs/architecture/data-model.html&quot;&gt;Aerospike Data Model&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.aerospike.com/docs/tools/aql/data_management.html&quot;&gt;Aerospike AQL&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.aerospike.com/docs/guide/policies.html&quot;&gt;Aerospike Policy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.aerospike.com/docs/client/go/usage/index.html&quot;&gt;Aerospike Go client Usage&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=CF83TmR-NME&quot;&gt;Video demo of amazing scalability of Aerospike&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://stackoverflow.com/questions/56305522/redis-vs-aerospike-usecases&quot;&gt;Redis vs Aerospike use cases?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://stackoverflow.com/questions/24482337/how-is-aerospike-different-from-other-key-value-nosql-databases&quot;&gt;How is aerospike different from other key-value nosql databases?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://stackoverflow.com/questions/30692684/what-are-the-use-cases-where-redis-is-preferred-to-aerospike&quot;&gt;What are the use cases where Redis is preferred to Aerospike?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Cursor-based pagination vs Offset-based pagination]]></title><description><![CDATA[The basics of cursor vs offset based pagination]]></description><link>https://www.adityathebe.com/cursor-vs-offset-based-pagination/</link><guid isPermaLink="false">https://www.adityathebe.com/cursor-vs-offset-based-pagination/</guid><pubDate>Sat, 01 May 2021 18:45:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;a-offset-based-pagination&quot;&gt;A. Offset-based Pagination&lt;/h2&gt;
&lt;p&gt;This is the classic and the simplest way to achieve pagination. In essence, it&apos;s basically skipping X amount of data in front.&lt;/p&gt;
&lt;p&gt;Example: You have a list of 100 flowers and you want to show 10 of them at a time. On page 1 you fetch 10 flowers and skip 0 of them, one page 2 you fetch 10 and skip 10, and so on ...&lt;/p&gt;
&lt;p&gt;In SQL, a query would look something like this&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sql&quot;&gt;&lt;pre class=&quot;language-sql&quot;&gt;&lt;code class=&quot;language-sql&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;FROM&lt;/span&gt; flowers &lt;span class=&quot;token keyword&quot;&gt;OFFSET&lt;/span&gt; ? &lt;span class=&quot;token keyword&quot;&gt;LIMIT&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As simple as it is, it is still used heavily because of its sheer simplicity.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 511px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/5f108f0db1ee31753a3e2ad363aa8f90/92e00/google-pagination.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 48.666666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAIAAAA7N+mxAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABLklEQVR42n1R226DMAzl/z9rk0q3hz10a9cbrVoGSdvREXJPiLMABbFq25F1ZEe2j+1EvkftwAH4fwE/E6L2ycevItgp3/HNlCZTiWOBngR+bhjFPI8NnswTNJk97JaXBLmuKhLSUea2B7XP9BnlZD8vj+8VXhG0JnhT4TVBqzJbVtni8QVtky1Oy/RU35TTTM/e+CHVIbDWMy64rIUMDlAOXDZMGXwR0KaZmZB6sRS2htvY/T7tSp35wfzYv985uxgqXGhUFNfiWmrrhXJKA5NOalcQmxemaz3S6IuNhXDn4JkWg3a4fGBrQRn31/GjkNLmQTcS3KOZ141i1/5o96lRxc3HWXFlmdDF5yWETFrCDBMNV8J2YSVM4CvVJdVHLLmqb8qD4OC4Ef+C/nLfXwZD1L8fqtAAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;Google Pagination&quot;
        title=&quot;&quot;
        src=&quot;/static/5f108f0db1ee31753a3e2ad363aa8f90/92e00/google-pagination.png&quot;
        srcset=&quot;/static/5f108f0db1ee31753a3e2ad363aa8f90/5a46d/google-pagination.png 300w,
/static/5f108f0db1ee31753a3e2ad363aa8f90/92e00/google-pagination.png 511w&quot;
        sizes=&quot;(max-width: 511px) 100vw, 511px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;em&gt;Offset-based pagination in google.com&lt;/em&gt;&lt;/p&gt;
&lt;h3 id=&quot;disadvantages&quot;&gt;Disadvantages&lt;/h3&gt;
&lt;p&gt;A big disadvantage, and really a deal-breaker for some use cases, of this method is that it is not at all vialbe for realtime data.&lt;/p&gt;
&lt;h4 id=&quot;1-duplicate-data&quot;&gt;1. Duplicate data&lt;/h4&gt;
&lt;p&gt;Imagine in the above example a user is browsing on page 4, and 10 new flowers are added to the front. When the user visits page 5, he will see the same flowers again.&lt;/p&gt;
&lt;h4 id=&quot;2-skipping-data&quot;&gt;2. Skipping data&lt;/h4&gt;
&lt;p&gt;In contrast, if 10 flowers were removed from the front, then users will miss out on 10 flowers when navgating to page 5 from page 4.&lt;/p&gt;
&lt;h4 id=&quot;3-performance&quot;&gt;3. Performance&lt;/h4&gt;
&lt;p&gt;The above SQL may appear innocent but it&apos;s not! An &lt;code class=&quot;language-text&quot;&gt;OFFSET&lt;/code&gt;ed sql query will still scan through all the rows in front. So if you&apos;re offsetting by 100 rows, the database will still scan them.&lt;/p&gt;
&lt;p&gt;Due to this reason, as the offset factor grows, pagination time increases. Imagine cases where you need to offset by millions of rows - that could take a minute.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 941px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/2a5d1226120d093c73f23463dd242ebc/a8417/pagination-time-efficiency.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 70%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAAAsTAAALEwEAmpwYAAABnElEQVR42n1TDZOsIAzz///RdUf3FAWE8pGXot7q3b1lJpOhpLGU2qWUbClFiHgCQPTex8fjEZ/PZxzHMQ7DEPu+bwghNI1qc37nKbqcsxCotULXyRqjKZgMEUGMsUH3TMR1lfLObYasEgoNqFhZDXdxufFbU6gpWJwQWvAe/zbUKjSgRsoa+4srUWhkvWBeA0JMzCGO3I5CUbPz2tcKr3xW6EPCbAWOXGo5KntrOmOMaK/+Z7gbVfhNYHi91cd21av2yjdDDfzsoaSMlUYvw8dJ+1k9dH8aWmtFX+/n1RKN7JYwrXxdybek8slwn8EMdpI304an1qdpCdhiOvpTWuP3B8k3nLGboVaXmehjwWCkcT4qVdYxU9ZpK5p4QT1G6l5h4gi8Xlgmg2gNatqQvEUO7O3mUGVD9guZ++Ba7ERRZuxsAQ0hWSK25YuHFmLnZqTGKgzrzLMJ66uHm0fuDZLq3ALxK03tzmrEtrXBxoelV3GcAuc8VuvagH9aHf/N9qfoS+sXruAR+sFgmiYkM2D+GrFtbEeSX9oT/wBq30yWEeCKOwAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;Pagination Time Efficiency&quot;
        title=&quot;&quot;
        src=&quot;/static/2a5d1226120d093c73f23463dd242ebc/a8417/pagination-time-efficiency.png&quot;
        srcset=&quot;/static/2a5d1226120d093c73f23463dd242ebc/5a46d/pagination-time-efficiency.png 300w,
/static/2a5d1226120d093c73f23463dd242ebc/0a47e/pagination-time-efficiency.png 600w,
/static/2a5d1226120d093c73f23463dd242ebc/a8417/pagination-time-efficiency.png 941w&quot;
        sizes=&quot;(max-width: 941px) 100vw, 941px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;em&gt;Source: &lt;a href=&quot;https://laptrinhx.com/&quot;&gt;https://laptrinhx.com/&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;But to say that this is a disadvantage of offset-based pagination is not quite fair since this is a SQL problem. If we were using an index instead, then this wouldn&apos;t be a problem at all.&lt;/p&gt;
&lt;p&gt;You can see how none of these disadvantages really affect Google because their search index do not change in real time and offset doesn&apos;t add overhead.&lt;/p&gt;
&lt;h2 id=&quot;b-cursor-based-pagination&quot;&gt;B. Cursor-based Pagination&lt;/h2&gt;
&lt;p&gt;In this method, you have a cursor instead of an offset value. To continue with our example above, a cursor based query would be &quot;Give me 10 flowers after Anthurium&quot;. This method is extremely suitable where data changes frequently since you don&apos;t have the problem of duplicates or skipping over some data.&lt;/p&gt;
&lt;h3 id=&quot;disadvantages-1&quot;&gt;Disadvantages&lt;/h3&gt;
&lt;h4 id=&quot;1necessity-for-a-unique-cursor&quot;&gt;1.Necessity for a unique cursor&lt;/h4&gt;
&lt;p&gt;Imagine in the example above you have two rows with the same flower. Suppose we are on page 5 and the first element on the next page is Anthurium. This means our cursor is set to &quot;Anthurium&quot;. We start to navigate and reach page 8 and the cursor is set to &quot;Anthurium&quot; again because it&apos;s the first element on the 9th page. You can see how this can cause an infinite loop.&lt;/p&gt;
&lt;p&gt;To solve this problem, we need to make sure the cursor is guaranteed to be unique for each data. We can change our cursor to be the flower name + row id.&lt;/p&gt;
&lt;h4 id=&quot;2-implementation-overhead&quot;&gt;2. Implementation Overhead&lt;/h4&gt;
&lt;p&gt;Implementing cursor-based pagination can sometimes become really difficult and might limit us from performing sorting on certain fields.&lt;/p&gt;
&lt;p&gt;Megan Chan has done an excellent job in describing the implementation quirks which you can read &lt;a href=&quot;https://medium.com/swlh/how-to-implement-cursor-pagination-like-a-pro-513140b65f32&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://medium.com/swlh/how-to-implement-cursor-pagination-like-a-pro-513140b65f32&quot;&gt;How to Implement Cursor Pagination Like a Pro&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://uxdesign.cc/why-facebook-says-cursor-pagination-is-the-greatest-d6b98d86b6c0&quot;&gt;Is offset pagination dead? Why cursor pagination is taking over&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Dependency Injection In Go With Context API]]></title><description><![CDATA[This week I share a couple of new things that I learned about Go]]></description><link>https://www.adityathebe.com/journal/5</link><guid isPermaLink="false">https://www.adityathebe.com/journal/5</guid><pubDate>Sun, 25 Apr 2021 14:00:00 GMT</pubDate><content:encoded>&lt;h3 id=&quot;1-dependecy-injection-in-go-with-context-api-a-namectx-dependency-injectiona&quot;&gt;1. Dependecy injection in Go with Context API &lt;a name=&quot;ctx-dependency-injection&quot;&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;This week I found a really neat way to inject dependencies in Go using the context API. Here&apos;s the &lt;a href=&quot;https://www.youtube.com/watch?v=_KrV_VWP2n0&quot;&gt;YouTube link&lt;/a&gt; of a brief demo by the author himself.&lt;/p&gt;
&lt;p&gt;The classic way, that I know of, to inject dependencies is to make all the HTTP handlers a method of the main &lt;code class=&quot;language-text&quot;&gt;Server&lt;/code&gt; struct and the handlers can just access the necessary dependencies from the server.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;type&lt;/span&gt; Server &lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  db Database
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;s &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;Server&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;GetUsers&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;w http&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ResponseWriter&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; r &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;http&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Request&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; errror&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  users&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;db&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getUsers&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Nothing wrong with this approach really except maybe things will start to get a little messy as the number of handlers grows because all the handlers should reside inside the same package.&lt;/p&gt;
&lt;p&gt;Instead, with &lt;a href=&quot;https://github.com/kayleg&quot;&gt;Kayle&apos;s&lt;/a&gt; method, we can have handlers as standalone functions (and not methods on the server) and they can receive the dependencies from the context&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;
&lt;span class=&quot;token keyword&quot;&gt;type&lt;/span&gt; contextKeyType &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
	ContextKey contextKeyType &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;dep-provider&quot;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// This middleware will attach the dependencies in the request context on every request&lt;/span&gt;
&lt;span class=&quot;token boolean&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; http&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;ListenAndServe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;:8080&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; server&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;injectDB&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;router&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// My standalone handler&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Getusers&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;w http&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ResponseWriter&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; r &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;http&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Request&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  db &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; r&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Context&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Value&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;provider&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ContextKey&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Database&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  user&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; db&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getUsers&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To learn more about it, you can check out the &lt;a href=&quot;https://github.com/kayleg/yt-dependency-injection&quot;&gt;Github Repo&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&quot;2-go-type-conversion-vs-type-assertion-a-nameassertion-and-conversiona&quot;&gt;2. Go Type conversion vs Type assertion &lt;a name=&quot;assertion-and-conversion&quot;&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;I have been wrongly misusing the word type coercion not actually knowing the difference between type conversion and type assertion.&lt;/p&gt;
&lt;h4 id=&quot;a-type-assertion&quot;&gt;A. Type Assertion&lt;/h4&gt;
&lt;p&gt;The notation &lt;code class=&quot;language-text&quot;&gt;x.(T)&lt;/code&gt; is called a type assertion. With the absence of Generics in Go, interfaces and type assertions are used heavily. Even in the example above you can see that once we get the Database value from the context we perform type assertion to set the value of &lt;code class=&quot;language-text&quot;&gt;db&lt;/code&gt; to &lt;code class=&quot;language-text&quot;&gt;Database&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;For a type assertion to succeed, the variable must satisfy all the interfaces of the type that&apos;s being asserted. In case of failure to satisfy the interface, a panic will occur. A graceful way to perform type assertion is to perform a check on the second value returned by the assertion&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;t&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; ok &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; i&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;T&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;If i holds a T, then t will be the underlying value, and ok will be true. If not, ok will be false and t will be the zero value of type T, and no panic occurs.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 id=&quot;b-type-conversion&quot;&gt;B. Type Conversion&lt;/h4&gt;
&lt;p&gt;A Conversion changes the type of an expression to the type specified by the conversion. A simple example would be converting an int to int32&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; age &lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;
age &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;25&lt;/span&gt;

newAge &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;int32&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;age&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;3-time-formats-in-go-a-namego-time-formatsa&quot;&gt;3. Time formats in Go &lt;a name=&quot;go-time-formats&quot;&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;When converting a datetime object to a string, most programming languages offer different &quot;verbs&quot; to get the date in the format the way you want. For example: In python you can use &lt;code class=&quot;language-text&quot;&gt;datetime.now().strftime(&quot;%H:%M:%S&quot;)&lt;/code&gt; or in Java you have &lt;code class=&quot;language-text&quot;&gt;HH:mm:ss&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Go has a unique approach of formating date and time which I prefer more than any other ways out there. In Go, you can provide a human-readable format like this.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;x &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; time&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
fmt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Format&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;2006 Jan 03&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
fmt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Format&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;3 01 06&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
fmt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Format&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Monday, January 2006&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
fmt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Format&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Monday, January 2006 03:15&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// # Output&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// 2009 Nov 11&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// 11 11 09&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// Tuesday, November 2009&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// Tuesday, November 2009 11:23&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The key, and the only, thing to remember is the reference date&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Mon Jan 2 15:04:05 MST 2006&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;You see in the example above, I always used the month January and the year 2006. If I use any other month or year or date, Go will not understand it. So even though I can format the month anyway I like - Jan, January, 01 - it has to be the month January. The same is the case for date, day, year, hour, time, second, and timezone.&lt;/p&gt;
&lt;p&gt;At first glance, this seems pretty weird. Why this specific date and not any other one would ask. There&apos;s a pretty clever reason behind this - it&apos;s that in POSIX date format it actually is &lt;code class=&quot;language-text&quot;&gt;0 1 2 3 4 5 7 6&lt;/code&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Mon Jan 2 15:04:05 -0700 MST 2006
0   1   2  3  4  5  7        6&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;But why is 7 in front of 6 ? It&apos;s because if we had to interchange them then it would be the year 2007 and Jan 2nd 2007 is not Monday whereas Jan 2nd 2006 is.&lt;/p&gt;
&lt;h3 id=&quot;4-declaring-emtpy-slices-in-go-a-namedeclaring-empty-slicesa&quot;&gt;4. Declaring emtpy slices in Go &lt;a name=&quot;declaring-empty-slices&quot;&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;There are various ways to declare a slice in Go&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; x &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;
y &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
z &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;make&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

fmt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Printf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Len: %d\tCap: %d\tIsNil: %v\n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;cap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; x &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
fmt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Printf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Len: %d\tCap: %d\tIsNil: %v\n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;y&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;cap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;y&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; y &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
fmt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Printf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Len: %d\tCap: %d\tIsNil: %v\n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;z&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;cap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;z&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; z &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If you run the code above, you&apos;ll see that they all pretty much do the same thing except that the first command declares a nil slice value. They are functionally equivalent as the len and cap are both zero. But the &lt;a href=&quot;https://github.com/golang/go/wiki/CodeReviewComments#declaring-empty-slices&quot;&gt;official way&lt;/a&gt; to declare a slice is the first one.&lt;/p&gt;
&lt;p&gt;Do note that some libraries behave differently for nil slice value like the &quot;encoding/json&quot;. A nil slice encodes to &lt;code class=&quot;language-text&quot;&gt;null&lt;/code&gt;, while &lt;code class=&quot;language-text&quot;&gt;[]string{}&lt;/code&gt; encodes to the JSON array &lt;code class=&quot;language-text&quot;&gt;[]&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://golang.org/ref/spec#Type_assertions&quot;&gt;Go Type Assertions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://golang.org/pkg/time/#pkg-constants&quot;&gt;Go Time Formats&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/golang/go/wiki/CodeReviewComments#declaring-empty-slices&quot;&gt;Declaring Empty Slices&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Git tricks & Deterministic builds on NPM install]]></title><description><![CDATA[Try out this git one-liners like a git ninja!]]></description><link>https://www.adityathebe.com/journal/4</link><guid isPermaLink="false">https://www.adityathebe.com/journal/4</guid><pubDate>Sat, 10 Apr 2021 12:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;find-the-files-in-a-git-repository-that-have-changed-the-most-a-namegit-most-changed-filea&quot;&gt;Find the files in a git repository that have changed the most &lt;a name=&quot;git-most-changed-file&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;With a few CLI tools along with the git &lt;code class=&quot;language-text&quot;&gt;log&lt;/code&gt; command, you can see the files that have changed the most over a certain time period.&lt;/p&gt;
&lt;p&gt;I&apos;ve set up a ZSH function in my &lt;code class=&quot;language-text&quot;&gt;.zshrc&lt;/code&gt; file&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function-name function&quot;&gt;gitchangehist&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; log &lt;span class=&quot;token parameter variable&quot;&gt;--numstat&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;awk&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;/^[0-9-]+/{ print $NF}&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;sort&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;uniq&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-c&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;sort&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-nr&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;head&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I ran this on my website&apos;s codebase and here&apos;s the result&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;gitchangehist&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;output&quot;&gt;&lt;pre class=&quot;language-output&quot;&gt;&lt;code class=&quot;language-output&quot;&gt;37 src/components/Layout/layout.css
31 gatsby-config.js
23 package.json
20 src/templates/post.css
19 yarn.lock
19 src/pages/index.js
14 content/posts/twitter-bot-tutorial-nodejs/index.md
12 src/pages/portfolio.js
11 src/components/Portfolio/Project.css
10 content/posts/what-does-it-mean-to-own-a-bitcoin/index.md&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Git provides a convenient way to limit commits with the &lt;code class=&quot;language-text&quot;&gt;--since&lt;/code&gt; option.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;--since=&amp;lt;date&gt;, --after=&amp;lt;date&gt;
    Show commits more recent than a specific date.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You can use it like this to pass in a time frame&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; log &lt;span class=&quot;token parameter variable&quot;&gt;--since&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;.year.ago
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; log &lt;span class=&quot;token parameter variable&quot;&gt;--since&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;.month.ago&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;There are also other interesting options like &lt;code class=&quot;language-text&quot;&gt;--author&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;--grep&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;list-all-the-strings-inside-a-git-repository-a-namegit-stringsa&quot;&gt;List all the strings inside a git repository &lt;a name=&quot;git-strings&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;This is probably my favorite git trick provided by the awesome &lt;a href=&quot;https://twitter.com/TomNomNom&quot;&gt;@TomNomNom&lt;/a&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;gitstrings() {
  # Print all the strings in .git/objects/pack
  # Credits to tomnomnom - https://twitter.com/tomnomnom/status/1133345832688857095
  {
    find .git/objects/pack/ -name &quot;*.idx&quot; | while read i; do git show-index &amp;lt;&quot;$i&quot; | awk &apos;{print $2}&apos;; done
    find .git/objects/ -type f | grep -v &apos;/pack/&apos; | awk -F&apos;/&apos; &apos;{print $(NF-1)$NF}&apos;
  } | while read o; do git cat-file -p $o; done
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This one-liner will find all the strings in a git repo and just spit it out to the stdout. It&apos;s super useful especially to bug-bounty hunters to look for any leaked credentials or API keys. Sometimes developers commit confidential keys and then make another commit to remove them but git stores the entire history and this one-liner will help you find them.&lt;/p&gt;
&lt;p&gt;I used this trick to basically glide through the &lt;a href=&quot;https://pentesterlab.com/badges/recon&quot;&gt;Recon Badge&lt;/a&gt; in PentesterLab.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1200px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/cb52506e904ba73e87f5881070caf315/e84a7/pentesterlab-recon-solution.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 57.333333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAIAAADwazoUAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABXUlEQVR42m1SAXKCMBD0P7YiIgSBJBAghICgCGrttLb//0QX0zpqndnJXDK3t3d7mWR6T9NNojovkjYRc5LYJHl1ODBzuLWMR7jJU0x0e8r0oJoTIOtjWg5JsROqR8CyzTKQPteElrNl/B+TXO9j2YGA1FQP2eUK5NUBL2GynnviKXMkgxaJhufbFa+8SEHEZxpAQKhCbwigjyleFsxgnMiQdftetqe6+9Sbj3b4bvqv9e48oj/TfOvzCuKohbqoDqCWTdKrchcmNTLwijOIa2AVV5RpSVXCq1g0YVwTpgNeRQIJFRr5JRfrI8aDPWZUAy63QnaOJ+x55FqBa4WWTacLNrXv207LHsZgZpq2cOvWMJQIRWN5qVnY7LKzO8OwJxiGzs0kpvCtMeP1T+rRbdW8QRanrA8QhzHGcxPg2yB2w+I5GX46gSKsILwgTCEPLSz8zAB9Oqv8au8D+QcfnaFrLmkZywAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;Pentesterlab Recon Solution&quot;
        title=&quot;&quot;
        src=&quot;/static/cb52506e904ba73e87f5881070caf315/c1b63/pentesterlab-recon-solution.png&quot;
        srcset=&quot;/static/cb52506e904ba73e87f5881070caf315/5a46d/pentesterlab-recon-solution.png 300w,
/static/cb52506e904ba73e87f5881070caf315/0a47e/pentesterlab-recon-solution.png 600w,
/static/cb52506e904ba73e87f5881070caf315/c1b63/pentesterlab-recon-solution.png 1200w,
/static/cb52506e904ba73e87f5881070caf315/e84a7/pentesterlab-recon-solution.png 1317w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;You can use interesting grep patterns to find some juicy stuff.&lt;/p&gt;
&lt;h2 id=&quot;deterministic-npm-install&quot;&gt;Deterministic NPM install&lt;/h2&gt;
&lt;p&gt;NodeJS&apos; package manager &lt;code class=&quot;language-text&quot;&gt;npm&lt;/code&gt; keeps track of the dependency graph (the dependencies of the main dependencies and their dependencies and so on) in a &lt;code class=&quot;language-text&quot;&gt;package-lock.json&lt;/code&gt; file. This file is essential to have consistent versions of the dependencies. The next time we need to install dependencies, this file should help us get the right versions.&lt;/p&gt;
&lt;p&gt;Sounds good right? Nope. The command, &lt;code class=&quot;language-text&quot;&gt;npm install&lt;/code&gt;, that most of us use, does not use the lock file at all! You may have noticed that when you run &lt;code class=&quot;language-text&quot;&gt;npm install&lt;/code&gt; the lock file gets changed. If a dependency is not in the &lt;code class=&quot;language-text&quot;&gt;package-lock.json&lt;/code&gt; it will be added by &lt;code class=&quot;language-text&quot;&gt;npm install&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The command you want to use is &lt;code class=&quot;language-text&quot;&gt;npm ci&lt;/code&gt;. It&apos;s named after &lt;strong&gt;Continuous Integration&lt;/strong&gt;. If any dependencies are missing or have incompatible versions, it will throw an error.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 707px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/e278d1ab759ffdfa519ca3f5308d27f5/394f7/npm-install-vs-ci.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 82%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAIAAACZeshMAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABuklEQVR42pWTC2+bMBSF8///XjV1a6UmYAc/eNhADIRA2GfTqlW1RdtRTGxzH+eeezlcQvjx8+X17fT0/Mv5dtu2+/2+JdwfAoPDsqymrEWhpTLGli3oWu+98z4Mw/YQB1bf91rr0tqqqmIAW+ZC8jtluTbWOW/TDa8Kpau6bpqmrutlWaIzx1yILAcCC1uCir9oFe0aa+31esX6drut6wpnnu+ZYaqUkvJ8LopCwd6M04T1NE3jOA7DiNsj2mSrEnZ/0iaqZ5ifC0WyvzqTYbfGTkjcFYUfs/x4yt9YQl4+0HVd41zX9/QIaoc9hnNOSrHzFkJwRGpMfNtG2UNI9oE9DHnSknmeD6mfG1eUDKSUyEYU4nCT9DfamOMpo4To6TxlEh3x3jPP8w1WZEtJeuhxZBO5hsCRe7a7yJ81hzA8Pb9Ibbf/BxO2KB27T/iubX1/cVNs5T85s/BiLBimjGqVkcoiCL1Dcx0nrkJhn/Ct4R9DojWtVtogN7Lho5RG+V1/nTQjNFvCfMvcIylzSZNp7D5knFFexb1lSON4risKf00enYdhaBMgphJRePJ5si+rms8Fzz/W/BuUHY7s4HY4QQAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;npm install vs npm ci&quot;
        title=&quot;&quot;
        src=&quot;/static/e278d1ab759ffdfa519ca3f5308d27f5/394f7/npm-install-vs-ci.png&quot;
        srcset=&quot;/static/e278d1ab759ffdfa519ca3f5308d27f5/5a46d/npm-install-vs-ci.png 300w,
/static/e278d1ab759ffdfa519ca3f5308d27f5/0a47e/npm-install-vs-ci.png 600w,
/static/e278d1ab759ffdfa519ca3f5308d27f5/394f7/npm-install-vs-ci.png 707w&quot;
        sizes=&quot;(max-width: 707px) 100vw, 707px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;
&lt;em&gt;Source: &lt;a href=&quot;https://stackoverflow.com/a/53325242/6199444&quot;&gt;https://stackoverflow.com/a/53325242/6199444&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;In my internship, I had to work on an Angular project but I just couldn&apos;t make it run. I probably should have used &lt;code class=&quot;language-text&quot;&gt;ci&lt;/code&gt; instead of &lt;code class=&quot;language-text&quot;&gt;install&lt;/code&gt; 😁.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Number of lines of code in my website]]></title><description><![CDATA[My website apparently has fewer lines of code than I expected]]></description><link>https://www.adityathebe.com/journal/3</link><guid isPermaLink="false">https://www.adityathebe.com/journal/3</guid><pubDate>Sat, 03 Apr 2021 18:30:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;swapfiles-to-the-rescue-a-nameswapfilesa&quot;&gt;Swapfiles to the rescue &lt;a name=&quot;swapfiles&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;At my new job, I need to work on a massive project which is very demanding. I&apos;ve been rocking an 8GB RAM since forever but the time had finally come to give it an upgrade. My system would just crash due to unavailable memory. I couldn&apos;t upgrade RAM as the stores were closed on weekends. My time was ticking, since I am to complete 40hrs of work a week, and I wasn&apos;t even able to run the project.&lt;/p&gt;
&lt;p&gt;Fortunately for me, I could add swapfiles to act as virtual memory. I had completely forgotten about this and was waiting like an idiot for shops to open the next day.&lt;/p&gt;
&lt;p&gt;A downside of using a swapfile on an SSD is that SSDs have a limited lifespan. Every write (but not read) cycle (or more accurately every erasure) wears a memory cell, and at some point it will stop working.&lt;/p&gt;
&lt;p&gt;As always, the Arch wiki had all the &lt;a href=&quot;https://wiki.archlinux.org/index.php/swap&quot;&gt;instructions to create a swapfile&lt;/a&gt;. My system was still pushing the 6GB swapfile, I had created, to its limits. And since I&apos;d be running multiple users at once, I decided to opt for 32GB of RAM. Quite an upgrade!&lt;/p&gt;
&lt;h2 id=&quot;number-of-lines-in-a-git-repo-a-namecloca&quot;&gt;Number of lines in a git repo &lt;a name=&quot;cloc&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I was curious to see how many lines of Go code our project had. There were lots of possible solutions but the one that I liked the most was using the &lt;a href=&quot;https://github.com/AlDanial/cloc&quot;&gt;CLoC - Count Lines of Code&lt;/a&gt; CLI tool.&lt;/p&gt;
&lt;p&gt;What&apos;s nice about CLoC is that it can differentiate a real line of code from a comment or a blank line. It can also determine the lines of codes in a specific programming language. So if you have a project using multiple programming languages, then CLoC can help you get the LOC of just JavaScript code.&lt;/p&gt;
&lt;p&gt;I ran CLoC on the code running this website and this was the result&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;❯ cloc --exclude-dir=node_modules,public,.cache .
-------------------------------------------------------------------------------
Language                     files          blank        comment           code
-------------------------------------------------------------------------------
JSON                             2              0              0          45005
Markdown                        20            769              0           1602
JavaScript                      21             97             33           1020
CSS                              9            116             27            604
YAML                             6             36              0            204
-------------------------------------------------------------------------------
SUM:                            58           1018             60          48435
-------------------------------------------------------------------------------&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I&apos;m excluding the &lt;code class=&quot;language-text&quot;&gt;node_modules&lt;/code&gt; directory for obvious reason and also the &lt;code class=&quot;language-text&quot;&gt;public&lt;/code&gt; directory which is the build files along with the &lt;code class=&quot;language-text&quot;&gt;.cache&lt;/code&gt; directory which is the build cache.&lt;/p&gt;
&lt;p&gt;The high number of JSON code is due to the &lt;code class=&quot;language-text&quot;&gt;package-lock.json&lt;/code&gt; file.&lt;/p&gt;
&lt;h2 id=&quot;copy-image-from-x-clipboard-to-a-file-a-namex-clipboard-imagea&quot;&gt;Copy image from X clipboard to a file &lt;a name=&quot;x-clipboard-image&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I use Flameshot to instantly take screenshots and then copy them to my X clipboard. I have configured a key binding on SXHKD like this&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;super + &lt;span class=&quot;token builtin class-name&quot;&gt;shift&lt;/span&gt; + s
  flameshot gui &lt;span class=&quot;token parameter variable&quot;&gt;-p&lt;/span&gt; ~/Pictures/Screenshots/&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And with that, I can simply copy &amp;#x26; paste the images to apps like Telegram or web apps on a Browser. This makes it really simple and fast as I don&apos;t need to save the image to a file and then browse the files to select the image.&lt;/p&gt;
&lt;p&gt;But I want to copy those images, on the clipboard, to a file and the GUI file manager that I&apos;m using, PCMan File Manager, doesn&apos;t support it.&lt;/p&gt;
&lt;p&gt;I use xclip to manage my clipboards and it has a command to stream the image on the clipboard&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;xclip &lt;span class=&quot;token parameter variable&quot;&gt;-selection&lt;/span&gt; clipboard &lt;span class=&quot;token parameter variable&quot;&gt;-t&lt;/span&gt; image/png &lt;span class=&quot;token parameter variable&quot;&gt;-o&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; image.png

&lt;span class=&quot;token comment&quot;&gt;# Shorter&lt;/span&gt;
xclip &lt;span class=&quot;token parameter variable&quot;&gt;-sel&lt;/span&gt; clip &lt;span class=&quot;token parameter variable&quot;&gt;-t&lt;/span&gt; image/png &lt;span class=&quot;token parameter variable&quot;&gt;-o&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; image.png&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now, I can just add a shell alias and conveniently copy the image to a file&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;alias&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;cpimg&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;xclip -selection clipboard -t image/png -o&quot;&lt;/span&gt;

cpimg &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; myimg.png&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Moreover, if you&apos;re using a TUI FM like Ranger or NNN you can easily setup key bindings for this.&lt;/p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://wiki.archlinux.org/index.php/swap&quot;&gt;https://wiki.archlinux.org/index.php/swap&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://askubuntu.com/questions/652337/why-are-swap-partitions-discouraged-on-ssd-drives-are-they-harmful&quot;&gt;https://askubuntu.com/questions/652337/why-are-swap-partitions-discouraged-on-ssd-drives-are-they-harmful&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/AlDanial/cloc#install-via-package-manager&quot;&gt;https://github.com/AlDanial/cloc#install-via-package-manager&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://unix.stackexchange.com/questions/145131/copy-image-from-clipboard-to-file&quot;&gt;https://unix.stackexchange.com/questions/145131/copy-image-from-clipboard-to-file&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Make sure to clean your Go build cache]]></title><description><![CDATA[For faster build time, the go command caches build outputs for reuse in future builds. This cache dir piles up, so make sure to clean it periodically.]]></description><link>https://www.adityathebe.com/how-to-clean-go-build-cache/</link><guid isPermaLink="false">https://www.adityathebe.com/how-to-clean-go-build-cache/</guid><pubDate>Sat, 03 Apr 2021 13:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;useless-anecdote&quot;&gt;Useless Anecdote&lt;/h2&gt;
&lt;p&gt;I realized that my storage was quickly getting filled out. I had recently added a new user to my system so I thought maybe that accounted for the sudden spike in storage usage. When I finally checked what was actually going on, I saw that my Go build cache directory was taking up about 35GB!&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 464px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/3d36fceaa2b3a1fe6e3037b4594e879b/69096/go-build-cache-du.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 101%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAIAAAAC64paAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAB1klEQVR42o2Ui47aMBBF+Z5tt0DIm4Q8HPKCBEgCgWVRQWql9v9/oMdkRam6CkhWNLJ9fO/M2Bnkq4MVbdVpaonK8EvLFIolxmZkuJnupJa30KaJYkaKFU5sQaDa8evE+6b6jEG9O5vBeqiF7rzyk63O8lSo9nwaFJDefGPOMgAmNSdSrZiz/sKH958ofBm7mh0TvKoBa1+VGTO3LzNyKF4XdKSEm/Ziegs24VNkW5E2aflmzvKRHrI81ILb1v+HhEW+4zxkk+KAVQaeR7q4F/kcPp1/R3mLN5hsdXTFyglLBkG/rIT3xx/AiGAbw/NFG6aN4aa2v3wMN/tLdLVNnsCkDU8KiD+l7Cd1VzByxnnZnCfWnET6SQkfv/+y/eJl5ABjAcPchI/e/NuYT+C6vVBbdOg+sn5cYZ7ijQ2uSoyF/lad73MmpmDd9SJtJnvEB+v6dOszZLzccyUhWXtsu9i8eXFFBLzYnK7VlkfgH/0HN4yHMYvW5IxDqg2WrWS3Sfhxq6rdWbs+DJS7G8IpFO8hKeG0kA5R7voMHCQ18VN9TpctebJVd2SrSBvlZ2QlnCxbP2t5Q1ZQhvlO5DX+n5GVsBssR2bMf0ex06ERKWZ4/6Pph/8Ag+kcPMiebUkAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;Contents of ~/.cache&quot;
        title=&quot;&quot;
        src=&quot;/static/3d36fceaa2b3a1fe6e3037b4594e879b/69096/go-build-cache-du.png&quot;
        srcset=&quot;/static/3d36fceaa2b3a1fe6e3037b4594e879b/5a46d/go-build-cache-du.png 300w,
/static/3d36fceaa2b3a1fe6e3037b4594e879b/69096/go-build-cache-du.png 464w&quot;
        sizes=&quot;(max-width: 464px) 100vw, 464px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;h3 id=&quot;locate-go-build-cache-directory&quot;&gt;Locate Go build cache directory&lt;/h3&gt;
&lt;p&gt;The default location for build cache data is a directory named &lt;strong&gt;go-build&lt;/strong&gt; in the standard cache directory. For me, on Linux, it is &lt;code class=&quot;language-text&quot;&gt;~/.cache/go-build/&lt;/code&gt;. You can find out yours using this command&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;go &lt;span class=&quot;token function&quot;&gt;env&lt;/span&gt; GOCACHE&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Go also conveniently allows you to modify the cache location using the environment variable &lt;code class=&quot;language-text&quot;&gt;GOCACHE&lt;/code&gt;&lt;/p&gt;
&lt;h3 id=&quot;check-disk-usage-of-go-build-cache&quot;&gt;Check disk usage of Go build cache&lt;/h3&gt;
&lt;p&gt;Here&apos;s a quick one-liner to see the disk usage of the build cache&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;du&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-hs&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$(&lt;/span&gt;go &lt;span class=&quot;token function&quot;&gt;env&lt;/span&gt; GOCACHE&lt;span class=&quot;token variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;content-of-go-build-cache&quot;&gt;Content of Go build cache&lt;/h3&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1200px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/13768a9739acb81b17271f9565861fd8/09262/go-build-cache-content.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 53.666666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAIAAADwazoUAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABhUlEQVR42kVSO0vEQBDePyQoHHls9pHsbs57JNkkYKONgggiiO0VNhZX29rY+TMsrPxTwvnN7ImwDDObmfkeG1G30YbehsGvZreM/nysmp6OG+RfUjVDupR1nxLlYmE2omyGTG9yszXtXNgeZW465UcVJumibCJFF3Evm4Ei55WfMCWwtaw7RogA0WHEepmaCGco7LYEZtOjDRGlZDqZWgvMoC5sh7q0nXRDyrEC96CAhhQr0PEjNuowIQFZgYJWpisXTZiABs6JdnUk3LN+Ys68iFqu10KHGTuApnxMhAuo4DHkMAKtCQqKUHIy2eVMhhFbFmPaCRErmBgxxDCL6sg2VpGWYhgHzUKyJYk2G8a0/XGYYk0baR1xIfKnuT9ZNGd5EBVLJ5PYDJzc/tNO70Sf2Ge0ZWp1/7h72b9eXT8Ihbfhd0rI7GcHHE3IxL8kZKiFbHrITK8/v75/Doe39w+hQdX1iMZHBYdID02CZMUlq+0K/EhqBYcXcnlz97R73l9c3v4Cdgq1G+Hdk/YAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;Contents of ~/.cache/go-build/&quot;
        title=&quot;&quot;
        src=&quot;/static/13768a9739acb81b17271f9565861fd8/c1b63/go-build-cache-content.png&quot;
        srcset=&quot;/static/13768a9739acb81b17271f9565861fd8/5a46d/go-build-cache-content.png 300w,
/static/13768a9739acb81b17271f9565861fd8/0a47e/go-build-cache-content.png 600w,
/static/13768a9739acb81b17271f9565861fd8/c1b63/go-build-cache-content.png 1200w,
/static/13768a9739acb81b17271f9565861fd8/d61c2/go-build-cache-content.png 1800w,
/static/13768a9739acb81b17271f9565861fd8/09262/go-build-cache-content.png 1896w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;em&gt;Contents of go-build cache using Diskonaut&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Finally, to address the question of this article, you can run this command&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;go clean &lt;span class=&quot;token parameter variable&quot;&gt;-cache&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This command removes all the subdirectories inside go-build directory and leaves out just two files&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;README&lt;/li&gt;
&lt;li&gt;trim.txt&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The trim.txt file stores a Unix timestamp. I&apos;m guessing it&apos;s the timestamp of the time you run the clean command.&lt;/p&gt;
&lt;h3 id=&quot;other-caches&quot;&gt;Other caches&lt;/h3&gt;
&lt;p&gt;In addition to the build cache Go also has a few other caches.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;-testcache&lt;/code&gt;
expires all the test results cache inside the build cache&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;-fuzzcache&lt;/code&gt;
remove files stored in the Go buildcache for fuzz testing.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Both of those flags clean caches that are inside the build cache directory.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;-modcache&lt;/code&gt;
remove the entire module download cache located at &lt;code class=&quot;language-text&quot;&gt;$GOPATH/pkg/&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;All of this information is available with &lt;code class=&quot;language-text&quot;&gt;go help clean&lt;/code&gt;&lt;/p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://golang.org/pkg/cmd/go/#hdr-Build_and_test_caching&quot;&gt;https://golang.org/pkg/cmd/go/#hdr-Build_and_test_caching&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Security and Analytics]]></title><description><![CDATA[This week I re-added simple analytics to my website and fixed a major bug that was costing me $70 every month]]></description><link>https://www.adityathebe.com/journal/2</link><guid isPermaLink="false">https://www.adityathebe.com/journal/2</guid><pubDate>Sat, 06 Mar 2021 23:25:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;security-stuffs-a-namesecuritya&quot;&gt;Security Stuffs &lt;a name=&quot;security&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id=&quot;1-using-tls-as-a-mechanism-to-attack-web-based-systems&quot;&gt;1. Using TLS as a mechanism to attack web-based systems&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=udpamSmD_vU&quot;&gt;https://www.youtube.com/watch?v=udpamSmD_vU&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://portswigger.net/daily-swig/when-tls-hacks-you-security-friend-becomes-a-foe&quot;&gt;https://portswigger.net/daily-swig/when-tls-hacks-you-security-friend-becomes-a-foe&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Most of the things in this talk went over my head. The researcher demonstrated a novel way to use TLS with DNS rebinding to perform SSRF attacks that were previously considered impractical to achieve.&lt;/p&gt;
&lt;p&gt;TLS provides a custom field (session id - size upto 65KB) which can be controlled by the TLS client. The attacker injects the malicious payload as a session id.&lt;/p&gt;
&lt;h3 id=&quot;2-migrated-away-from-lastpass-to-bitwarden&quot;&gt;2. Migrated away from Lastpass to Bitwarden&lt;/h3&gt;
&lt;p&gt;Lastpass recently &lt;a href=&quot;https://blog.lastpass.com/2021/02/changes-to-lastpass-free/&quot;&gt;announced&lt;/a&gt; that they are restricting the free subscription to just one device. I&apos;ve been wanting to shift away from Lastpass for quite some time now mainly because of their bad UI in their chrome extension and also because security nerds don&apos;t speak highly of them.&lt;/p&gt;
&lt;p&gt;Besides Lastpass, there were a couple of other good choices but I wanted one with a free version and a nice chrome extension. Bitwarden ticked all my requirements and it&apos;s also fully open source! The transition was pretty simple. All I had to do was export a CSV from Lastpass and import it on Bitwarden. I believe it took me about 5-10 minutes.&lt;/p&gt;
&lt;h2 id=&quot;goatcounter-to-simpleanalytics-a-nameweb-analyticsa&quot;&gt;GoatCounter to SimpleAnalytics &lt;a name=&quot;web-analytics&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Analytics are super fun! When I first deployed my website, I used to have google analytics running on my phone at all times; just staring at the stats checking if a new user visited my site. However, analytics add overhead to your website and privacy is another issue. A couple of months ago I ditched Google Analytics and started using &lt;a href=&quot;https://simpleanalytics.com&quot;&gt;Simple Analytics&lt;/a&gt; in favor of a simpler UI and better privacy policy. However, after some thought, I got rid of Simple Analytics. The main motivation was to make my website free from any tracker.&lt;/p&gt;
&lt;p&gt;But recently, I tried &lt;a href=&quot;https://www.goatcounter.com/&quot;&gt;GoatCounter&lt;/a&gt; - an open source web analytics platform. I used it for a week or so. It was simple and pretty fast but I wasn&apos;t a big fan of the UI. And now I&apos;m back again with SimpleAnalaytics 😁. I remember them having a free version but apparently now they don&apos;t. I got a free 1-year subscription from my Github Students Benefit though.&lt;/p&gt;
&lt;h3 id=&quot;bypass-ad-blockers-with-a-custom-subdomain&quot;&gt;Bypass ad-blockers with a custom subdomain&lt;/h3&gt;
&lt;p&gt;Generally, when you add a tracker, the tracker sends all the data to its own server. Adblockers and privacy extensions block any requests to these tracker servers. In order to circumvent this, Simple Analytics provides a nice &lt;a href=&quot;https://docs.simpleanalytics.com/bypass-ad-blockers&quot;&gt;feature&lt;/a&gt; to setup our own subdomain to collect the data. All we need to do is setup a CNAME DNS record that points to Simple Analytics&apos; server. Easy Peasy!&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 985px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/c0d33a8468dad8dd183856a71a6a8854/58bb7/netlify-dns.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 20%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAIAAAABPYjBAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAg0lEQVR42n2O2woDIQxE/f9vLPSqq9W4WjVe9mWnFcq+tHAYkjBJRvgQrg95V8oRtd6/9DGMta+cldaO/Ng21HLRcN6kXIwpzGKN0Xn/nkpliTCqrU24VmipdRbQzJxKyYCZWxP4TOt6Ol9wApvT94tjNLQiphRifDqHbAb6OfFn/8gO+Obj5nhO3ocAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;netlify dns&quot;
        title=&quot;&quot;
        src=&quot;/static/c0d33a8468dad8dd183856a71a6a8854/58bb7/netlify-dns.png&quot;
        srcset=&quot;/static/c0d33a8468dad8dd183856a71a6a8854/5a46d/netlify-dns.png 300w,
/static/c0d33a8468dad8dd183856a71a6a8854/0a47e/netlify-dns.png 600w,
/static/c0d33a8468dad8dd183856a71a6a8854/58bb7/netlify-dns.png 985w&quot;
        sizes=&quot;(max-width: 985px) 100vw, 985px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;h3 id=&quot;a-better-way-to-embed-external-script-in-gatsbyjs&quot;&gt;A better way to embed external script in GatsbyJS&lt;/h3&gt;
&lt;p&gt;I&apos;m using GatsbyJS for this site and guess what? There&apos;s actually a plugin to add an analytics tracking script! How ridiculous is that! All I need to do is add one line of script tag and there&apos;s an NPM module for that? I&apos;m not sure what the plugin offers but I&apos;m for sure not installing it. I just added the simple analytics script tag to my Layout component.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;jsx&quot;&gt;&lt;pre class=&quot;language-jsx&quot;&gt;&lt;code class=&quot;language-jsx&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;Layout&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; children &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Navbar&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;main&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;className&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;page-content&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;className&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;wrapper&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;children&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;main&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Footer&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;script&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;defer&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;src&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;https://stats.adityathebe.com/latest.js&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;However, this layout component was embedded inside a div and I wanted the script tag to be as the first level child of &lt;code class=&quot;language-text&quot;&gt;body&lt;/code&gt; like this.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;___gatsby&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;...&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;script&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;async&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;defer&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;src&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;...&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token script&quot;&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Thankfully, gatsby provides a way to do this with &lt;code class=&quot;language-text&quot;&gt;gatsby-ssr.js&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;jsx&quot;&gt;&lt;pre class=&quot;language-jsx&quot;&gt;&lt;code class=&quot;language-jsx&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; React &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;react&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;onRenderBody&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; setPostBodyComponents &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;setPostBodyComponents&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;script&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;defer&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;src&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;https://stats.adityathebe.com/latest.js&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I found the solution &lt;a href=&quot;https://github.com/gatsbyjs/gatsby/issues/11013#issuecomment-610886184&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;fixed-a-bug-in-subdomain-takeover-scanner-to-reduce-azure-costa-nameazure-subdomain-takeovera&quot;&gt;Fixed a bug in Subdomain-Takeover scanner to reduce Azure cost&lt;a name=&quot;azure-subdomain-takeover&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I&apos;ve been running a scanner on my VPS for about a year now to hunt for subdomain takeover bugs. For that, Azure Free Student&apos;s subscription had been serving me well until I had to create Azure instances in regions that weren&apos;t available in the student&apos;s subscription. Due to that, I had to create a premium account. In the first 3 months of migrating, I racked a bill of $152! Although, I have to say it&apos;s not as bad as the guy who got a bill of &lt;a href=&quot;https://blog.tomilkieway.com/72k-1/&quot;&gt;$72k overnight&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Yesterday, I figured out the cause and fixed it. I was running an Azure App Service Plan 24x7! Now, the script creates one only when it&apos;s required and also uses a free version instead of the standard version. All I had to do was add two words &lt;code class=&quot;language-text&quot;&gt;--sku F1&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;As a precaution, I&apos;ve also added a new budget in Azure Cost Management so that I get an alert when I&apos;m near the end of my budget.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1200px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/7e22d07fb8389b2054c1d497e2d95c60/53ac9/azure-budget.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 52.33333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAIAAAA7N+mxAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAA4UlEQVR42pWRW6+CMBCE+///ntUY0QcfFDTB2u2VctGBxUYNJud8IWRpOrM7i1BKee9T24HHPxHOB010U3fS2o14N+P5WYSIYoyiOGzkSlZVeQan8nBc74rtvtjPFMtIKeu6FuVVVdXFGEMTWmMObYwlG+7WWxebJay1KSVBxoQQhmHISRAeg7UjXUot071A3ff9nLlp4mP4WANuwBh6mLq8gDfQeRbjIzsx8MYv+MvyRzGm/+qM5O9BfoqxJOi/TqHvJ1DjzVPAjmNzPYoRLGdgcBudeaW4ZCbyLpAfh+z7BAGgRBKhGKOAAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;Azure Cost Management&quot;
        title=&quot;&quot;
        src=&quot;/static/7e22d07fb8389b2054c1d497e2d95c60/c1b63/azure-budget.png&quot;
        srcset=&quot;/static/7e22d07fb8389b2054c1d497e2d95c60/5a46d/azure-budget.png 300w,
/static/7e22d07fb8389b2054c1d497e2d95c60/0a47e/azure-budget.png 600w,
/static/7e22d07fb8389b2054c1d497e2d95c60/c1b63/azure-budget.png 1200w,
/static/7e22d07fb8389b2054c1d497e2d95c60/53ac9/azure-budget.png 1287w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Introducing Weekly Journals]]></title><description><![CDATA[I have added a weekly journal section in my blog where I'll post updates about the things that I learn, build and experience every week]]></description><link>https://www.adityathebe.com/introducing-weekly-journals/</link><guid isPermaLink="false">https://www.adityathebe.com/introducing-weekly-journals/</guid><pubDate>Sun, 28 Feb 2021 12:30:00 GMT</pubDate><content:encoded>&lt;p&gt;I was a decent and an above-average student in college and I can say with some confidence that having clean and organized notes did help me a lot. I used to spend a tonne of time preparing notes and it&apos;s something I really take pride in.&lt;/p&gt;
&lt;p&gt;However, after my college, there have been rarely a few times that I&apos;ve picked a pen. I don&apos;t even have a pen on my desk right now. The habit of making notes has gone.&lt;/p&gt;
&lt;p&gt;Most of my time is spent in front of my computer - reading blogs and watching videos; mostly tech-related. I&apos;ve realized that I&apos;ve been bombarding my brain with new information so much that I&apos;ve difficulty retaining most of them. Sometimes, when I&apos;m scanning through my browser history, I see an article and go - &quot;ah ya, that was an interesting read. I totally forgot about it&quot;.&lt;/p&gt;
&lt;p&gt;And some other times, I read a blog and google the things I don&apos;t understand, and quite often I&apos;ll fall into this rabbit hole eventually not knowing where I started and what I was initially trying to read.&lt;/p&gt;
&lt;p&gt;In the end, all the time and effort spent learning will account for very little. This false sense of productivity is dragging me back as I&apos;m not making the most of my time. In reality, I&apos;m not learning much or rather not retaining much. For this reason, I&apos;ve decided to start writing a journal every week in hopes that it&apos;ll help me retain the things that I learn. And also, this will motivate me to write every week which is a good thing I guess.&lt;/p&gt;
&lt;h2 id=&quot;what-is-this-weekly-journal&quot;&gt;What is this weekly journal?&lt;/h2&gt;
&lt;p&gt;You can visit the weekly journal &lt;a href=&quot;/journal&quot;&gt;here&lt;/a&gt;. Every week I&apos;ll try to post an update on the things that I learned or built that week although certainly not limited to just these. It could be just about anything - I could maybe write about a podcast or a movie that I enjoyed, a new place I visited, and so and so.&lt;/p&gt;
&lt;p&gt;I&apos;m hoping this initiative will help me stay focused because at the back of my mind I&apos;ll always have this sense of responsibility to take a journal of everything that I learn. So, if I realize that something I&apos;m reading or watching is too much for me to understand, then I&apos;ll just quit instead of trying to force myself to sit through it. Likewise, if I get diverted too much from the subject at hand, then maybe this will help me focus less on the less-important things and get back to the subject.&lt;/p&gt;
&lt;p&gt;At the end of the week, I can also go through the journal and revise the things that I learned.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I believe simply reminding yourself of the things that you learned a while ago goes a long way.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;alternatives&quot;&gt;Alternatives&lt;/h2&gt;
&lt;p&gt;I highly encourage you to embrace this practice of taking notes. You don&apos;t need to have a blog; a pen and a notebook will do just fine. If you need it on the web, then you can use some services like &lt;strong&gt;Whatgotdone&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 id=&quot;references-and-influences&quot;&gt;References and Influences&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://macwright.com/reading/&quot;&gt;https://macwright.com/reading/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://macwright.com/2021/02/01/recently.html&quot;&gt;https://macwright.com/2021/02/01/recently.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://whatgotdone.com/michael/2021-02-26&quot;&gt;https://whatgotdone.com/michael/2021-02-26&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[GRPC, ProtoBuf and weekly journals]]></title><description><![CDATA[This week I learned about ProtoBuf, gRPC & sql in Go]]></description><link>https://www.adityathebe.com/journal/1</link><guid isPermaLink="false">https://www.adityathebe.com/journal/1</guid><pubDate>Sat, 27 Feb 2021 17:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;weekly-journals-a-nameweekly-journalsa&quot;&gt;Weekly Journals &lt;a name=&quot;weekly-journals&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;After having this idea of adding a new weekly journal section to my blog for literally more than a year, I have finally done it. It didn&apos;t take me as long as I had thought it would to implement this. GatsbyJS makes it super easy. I will soon write a blog post on what motivated me to add this new section to my blog.&lt;/p&gt;
&lt;h2 id=&quot;grpc-and-protocol-buffers-a-namegrpc-protobufa&quot;&gt;GRPC and Protocol Buffers &lt;a name=&quot;grpc-protobuf&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I have used and created a lot of REST APIs and almost all of them used JSON to exchange data. I love JSON cuz its so simple, human-readable, and easy to add and modify data. However, they&apos;re not the most efficient way to exchange data in terms of bandwidth. The most &quot;bang for bandwidth&quot; way to do it would be to encode message in binary. That&apos;s basically what GRPC and ProtoBuf is about. This week I have started learning them in Go.&lt;/p&gt;
&lt;h3 id=&quot;resources&quot;&gt;Resources&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=pMgty_RYIOc&amp;#x26;list=PLmD8u-IFdreyyTx93jJ5GkijwDXFqyr3T&amp;#x26;index=1&quot;&gt;https://www.youtube.com/watch?v=pMgty_RYIOc&amp;#x26;list=PLmD8u-IFdreyyTx93jJ5GkijwDXFqyr3T&amp;#x26;index=1&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/playlist?list=PLy_6D98if3UJd5hxWNfAqKMr15HZqFnqf&quot;&gt;https://www.youtube.com/playlist?list=PLy_6D98if3UJd5hxWNfAqKMr15HZqFnqf&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=BdzYdN_Zd9Q&quot;&gt;https://www.youtube.com/watch?v=BdzYdN_Zd9Q&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;gos-defer-panic-and-recover-a-namego-defer-panic-recovera&quot;&gt;Go&apos;s Defer, Panic and Recover &lt;a name=&quot;go-defer-panic-recover&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I took the time to learn a bit more about some of the in-built functions in Go. The defered functions in Go are executed no matter what; even when a panic occurs. However, in case of os.Exit() the program shuts down immediately giving no chance for the defered function to execute.&lt;/p&gt;
&lt;p&gt;One thing that really troubled me for quite some time was how the return value(s) of the defered function were handled. We are used to write &lt;code class=&quot;language-text&quot;&gt;defer file.Close()&lt;/code&gt; but this function call can return an error. It turns out the error or any other return value is simply ignored. To handle the return value, we need to wrap the function call inside an anonymous function.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;defer&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  err &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; file&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Close&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; err &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;nil&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    log&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Ooops&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;resources-1&quot;&gt;Resources&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.golang.org/defer-panic-and-recover&quot;&gt;https://blog.golang.org/defer-panic-and-recover&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://yourbasic.org/golang/defer/&quot;&gt;https://yourbasic.org/golang/defer/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;sql-in-go&quot;&gt;SQL in Go&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=prh0hTyI1sU&quot;&gt;https://www.youtube.com/watch?v=prh0hTyI1sU&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/kyleconroy/sqlc&quot;&gt;https://github.com/kyleconroy/sqlc&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/jmoiron/sqlx&quot;&gt;https://github.com/jmoiron/sqlx&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Anatomy of Go Slices]]></title><description><![CDATA[Let's take a closer look at the anatomy of Slices in Go.]]></description><link>https://www.adityathebe.com/anatomy-of-go-slices/</link><guid isPermaLink="false">https://www.adityathebe.com/anatomy-of-go-slices/</guid><pubDate>Wed, 10 Feb 2021 13:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I&apos;ve started to use a lot of Go recently. I just love the language! Seriously, I don&apos;t think I have felt this much love for any other language!&lt;/p&gt;
&lt;p&gt;I&apos;m ashamed to admit that it was up until yesterday that I didn&apos;t quite understand the behavior and implementations of Slices in Go. There are already so many great blog posts out there that I don&apos;t think I have anything to add. However, that shouldn&apos;t stop me from writing another blog post on the subject because with that mindset my blog wouldn&apos;t even exist. So in addition to the hundred articles out there on Go Slices, here&apos;s the 101th. 😁&lt;/p&gt;
&lt;h2 id=&quot;slices&quot;&gt;Slices&lt;/h2&gt;
&lt;p&gt;Slices are flexible and they should be preferred over arrays whenever possible. The most important thing to note is that slices have Arrays underneath them. I like to think of slices as the frontend for arrays.&lt;/p&gt;
&lt;p&gt;Visualizing a slice as a &lt;code class=&quot;language-text&quot;&gt;struct&lt;/code&gt; as shown below can be helpful&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;type&lt;/span&gt; sliceHeader &lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    Length        &lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;
    Capacity      &lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;
    ZerothElement &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;byte&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;ZerothElement&lt;/code&gt; in sliceHeader points to the first* element of the array underneath. It doesn&apos;t necessarily have to point to the *first* element itself as we will see later.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 548px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/a3bcdabe1b62f2c0a4b1b9f3a36a95dc/a58fe/go-slice-anatomy.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 63%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAYAAACpUE5eAAAACXBIWXMAAAsTAAALEwEAmpwYAAABFUlEQVR42p1T14qFUAz0/7/NN+uLBRELKvZeZpnAWbywsF4DIXpOnCQzUcPNruvCcRyvnd9r+75jmib0fY8sy3CepzwvyyLnbdtKbJoG27ahrmu5G4ZB8hi7rsO6rvKujeMoIPSqqlAUBdI0RZ7n4B2TCchIIBaY5/kDkJFnzBNAZQSxLAue50HXdanKMVTB/1xGJupfxss39tEhiSWnd6JZWZ09BqSTBxJP/hzHgWEYcF0Xtm0jSRLh6EnnmkpS6pJ0qh0EAXzfl2cqqyZ5BKgSCcjRqFwYhtIhlVWqvgbk6hCMzlV6BUjjh9y3siwRRRHiOP5dbHb6SJR7VYrCrkzTlMg/4+u1ub9wXC4zu6FTqG8BfwAjq/fePC1FhwAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;go slice anatomy&quot;
        title=&quot;&quot;
        src=&quot;/static/a3bcdabe1b62f2c0a4b1b9f3a36a95dc/a58fe/go-slice-anatomy.png&quot;
        srcset=&quot;/static/a3bcdabe1b62f2c0a4b1b9f3a36a95dc/5a46d/go-slice-anatomy.png 300w,
/static/a3bcdabe1b62f2c0a4b1b9f3a36a95dc/a58fe/go-slice-anatomy.png 548w&quot;
        sizes=&quot;(max-width: 548px) 100vw, 548px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;h2 id=&quot;slice-capacity&quot;&gt;Slice Capacity&lt;/h2&gt;
&lt;p&gt;One thing that just seemed a little off to me in the beginning was the need for capacity in slices. How is it any different from the length of the slice itself ? None of the languages that I was familiar with had this concept of length and capacity. Almost always, the length was sufficient to define the size of an array or a list or whatever you want to call it.&lt;/p&gt;
&lt;p&gt;The capacity of a slice can be set when creating the slice with the &lt;code class=&quot;language-text&quot;&gt;make&lt;/code&gt; function. If no capacity is supplied then it defaults to the length of the slice.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span class=&quot;token function&quot;&gt;make&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;Type&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; length&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; capacity&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;make&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;Type&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; length&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To put it simply, the capacity of a slice is the size of its underlying array*. &lt;em&gt;It&apos;s a little complicated than that. We&apos;ll cover it in a minute&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Let&apos;s start by making a new slice with a predefined capacity.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;mySlice &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;make&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// [0, 0]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This code will internally create an array of integers of size 5. However, the slice will have access to only the first two elements of the array since its length is 2. If we try to access the third element then we get a runtime error.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;mySlice&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// panic: runtime error: index out of range [2] with length 2&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now consider that we need to add a third element to &lt;code class=&quot;language-text&quot;&gt;mySlice&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;myNewSlice &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;mySlice&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// [0, 0, 10]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Take a moment to think and tell me this - did the &lt;code class=&quot;language-text&quot;&gt;append&lt;/code&gt; function create a new array?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;It didn&apos;t !&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;What actually happened here is we created a new slice with an incremented length of &lt;code class=&quot;language-text&quot;&gt;3&lt;/code&gt; and the new element &lt;code class=&quot;language-text&quot;&gt;10&lt;/code&gt; was inserted into the array. But this new slice still points to the same array. We have a situation where both &lt;code class=&quot;language-text&quot;&gt;mySlice&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;myNewSlice&lt;/code&gt; are pointing to the same array. I think that&apos;s pretty cool.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Multiple slices can point to the same array&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Now, of course, this was only possible because the array underneath actually had room for growth. If initially, we had set the capacity of &lt;code class=&quot;language-text&quot;&gt;mySlice&lt;/code&gt; to &lt;code class=&quot;language-text&quot;&gt;2&lt;/code&gt; then the &lt;code class=&quot;language-text&quot;&gt;append&lt;/code&gt; function would have no choice other than to create a new array. As an exercise, you can try appending more than 10 items to the slice and observer the behavior.&lt;/p&gt;
&lt;p&gt;Let&apos;s verify this in code&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;mySlice &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;make&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
fmt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;mySlice&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
fmt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Printf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;mySlice&apos;s Address: %p\n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; mySlice&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 0xc000100030&lt;/span&gt;

myNewSlice &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;mySlice&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
fmt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;myNewSlice&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
fmt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Printf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;myNewSlice&apos;s Address: %p\n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; mySlice&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 0xc000100030&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You&apos;ll see that the first elements of the two slices still point to the same address.&lt;/p&gt;
&lt;h3 id=&quot;a-closer-look-at-the-slice-capacity&quot;&gt;A closer look at the Slice Capacity&lt;/h3&gt;
&lt;p&gt;Earlier when I said &quot;The capacity of a slice is the size of its underlying array&quot;, I lied. It can be the case but it&apos;s not quite accurate. Let&apos;s take a look at the example below&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1200px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/d95fab28a3a181cfa14cc2791d5f2877/29007/go-slice-capacity-demo.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 56.333333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAsklEQVR42rVSywrDIBD0//9PaO5eQhKN8VVizLa7oEhqSguJMPgaZmdcGVw82G2CIQRYlgXGcQTvPZ3t+17wtyCKzPNM0FqTOMIYQ3ulFEzTRJBS0oxnaMA59ykYY4SUUnFUrzOQs64r3dWoExRBrIIVrbXkaNu2ZiRM0Pc98ZqRs/owDMA5JyJWPY7ME0LAo+vgWcU8bQpWx/nMXX5r/X7biI1rNIvd+g9//R7feJc7fAEvcWU8+EEp5gAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;go slice capacity demo&quot;
        title=&quot;&quot;
        src=&quot;/static/d95fab28a3a181cfa14cc2791d5f2877/c1b63/go-slice-capacity-demo.png&quot;
        srcset=&quot;/static/d95fab28a3a181cfa14cc2791d5f2877/5a46d/go-slice-capacity-demo.png 300w,
/static/d95fab28a3a181cfa14cc2791d5f2877/0a47e/go-slice-capacity-demo.png 600w,
/static/d95fab28a3a181cfa14cc2791d5f2877/c1b63/go-slice-capacity-demo.png 1200w,
/static/d95fab28a3a181cfa14cc2791d5f2877/29007/go-slice-capacity-demo.png 1600w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;We have that two slices &lt;code class=&quot;language-text&quot;&gt;sliceA&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;sliceB&lt;/code&gt; and both of them have a pointer to the same array but they represent different &lt;strong&gt;&quot;pieces&quot;&lt;/strong&gt; of the array. &lt;code class=&quot;language-text&quot;&gt;sliceA&lt;/code&gt; represents the first 5 elements of the array while &lt;code class=&quot;language-text&quot;&gt;sliceB&lt;/code&gt; represents the 3 elements starting from the 12th index.&lt;/p&gt;
&lt;p&gt;If you noticed, the capacity of &lt;code class=&quot;language-text&quot;&gt;sliceB&lt;/code&gt; is actually not 20 - it&apos;s 8 even though the underlying array has size 20. In order to measure the capacity of a slice, not only do we need to know the size of the underlying array we also need to know where in the array the slice begins. So a more accurate definition of capacity would be&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The Capacity of a slice is equal to the length of the underlying array, minus the index in the array of the first element of the slice (zero in this case).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Let&apos;s verify this in code&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;package&lt;/span&gt; main

&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;fmt&quot;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	parentSlice &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;11&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;13&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;14&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;15&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;17&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;18&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;19&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
	fmt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Printf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Parent Slice: %v\n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; parentSlice&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	fmt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Printf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Parent Slice&apos;s Address: %p\n\n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; parentSlice&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

	sliceA &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; parentSlice&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
	fmt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Printf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;sliceA: %v\n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; sliceA&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	fmt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Printf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;sliceA&apos;s Address: %p\n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; sliceA&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	fmt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Printf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;sliceA&apos;s Length %d\n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;sliceA&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	fmt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Printf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;sliceA&apos;s Capacity %d\n\n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;cap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;sliceA&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

	sliceB &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; parentSlice&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;15&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
	fmt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Printf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;sliceB: %v\n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; sliceB&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	fmt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Printf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;sliceB&apos;s Address: %p\n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; sliceB&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	fmt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Printf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;sliceB&apos;s Length %d\n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;sliceB&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	fmt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Printf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;sliceB&apos;s Capacity %d&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;cap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;sliceB&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We start by creating a &lt;code class=&quot;language-text&quot;&gt;parentSlice&lt;/code&gt; and then slicing it to create two new slices &lt;code class=&quot;language-text&quot;&gt;sliceA&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;sliceB&lt;/code&gt;. If you run the program above you can verify by checking the addresses that all the 3 slices are in fact pointing to the same array.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Parent Slice: [0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19]
Parent Slice&apos;s Address: 0xc000100000

sliceA: [0 1 2 3 4]
sliceA&apos;s Address: 0xc000100000
sliceA&apos;s Length 5
sliceA&apos;s Capacity 20

sliceB: [12 13 14]
sliceB&apos;s Address: 0xc000100060
sliceB&apos;s Length 3
sliceB&apos;s Capacity 8&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;But hold on, sliceB&apos;s address is different than the other two. That&apos;s because it&apos;s showing the address of the 12th element and not the first element. We can verify that by printing the address of the 12th element of the &lt;code class=&quot;language-text&quot;&gt;parentSlice&lt;/code&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;fmt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Printf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Parent Slice&apos;s 12th element address %p&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;parentSlice&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// 0xc000100060&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This address should match the address of sliceB&apos;s first element.&lt;/p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.godesignpatterns.com/2014/05/arrays-vs-slices.html&quot;&gt;Arrays vs Slices&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.golang.org/slices&quot;&gt;Arrays, slices (and strings): The mechanics of &apos;append&apos;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.golang.org/slices-intro&quot;&gt;Go Slices: usage and internals&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://stackoverflow.com/questions/45423667/what-is-the-point-in-setting-a-slices-capacity&quot;&gt;What is the point in setting a slice&apos;s capacity?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Pitfall in JavaScript's Array.prototype.sort()]]></title><description><![CDATA[Javascript has many obscure and weird behaviors. One of them is how Array.prototype.sort() functions.]]></description><link>https://www.adityathebe.com/array-sort-javascript-pitfall/</link><guid isPermaLink="false">https://www.adityathebe.com/array-sort-javascript-pitfall/</guid><pubDate>Tue, 09 Feb 2021 20:45:00 GMT</pubDate><content:encoded>&lt;p&gt;I was recently going through the problems in LeetCode where I was faced with a problem that required sorting an array of numbers. Pretty easy, I immediately used the &lt;code class=&quot;language-text&quot;&gt;.sort()&lt;/code&gt; method&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; nums &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
nums&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sort&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;nums&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// [1,4,8,9]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I ran the code and the test passed successfully. So I submitted the code but then I got an error. My code failed to pass all the tests 😧 ! If you&apos;ve done LeetCode you&apos;re probably familiar with the rage I felt at the time.&lt;/p&gt;
&lt;p&gt;This was the test case that my code failed&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;[74, 100, 60, 98, 8, 45, 6, 59, 69, 32, 93, 9]&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Baffled with what was going on, I ran the code on my local machine and started using the Javascript developer&apos;s greatest asset - &lt;code class=&quot;language-text&quot;&gt;console.log()&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;[100, 32, 45, 59, 6, 60, 69, 74, 8, 9, 93, 98]&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As soon as I saw this, I knew what was going on ! If no compare function is supplied to &lt;code class=&quot;language-text&quot;&gt;.sort()&lt;/code&gt; javascript coerces the array elements into strings and then sorts them in lexicographical manner. Damn it ! I knew this behavior and I still managed to fall for it.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The sort() method sorts the elements of an array in place and returns the sorted array. The default sort order is ascending, built upon &lt;strong&gt;converting the elements into strings&lt;/strong&gt;, then comparing their sequences of UTF-16 code units values.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;the-fix&quot;&gt;The Fix&lt;/h3&gt;
&lt;p&gt;I wrote a simple compare function to fix the bug.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;nums&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sort&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;a&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; b&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; a &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; b&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;nums&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// [6, 8, 9, 32, 45, 59, 60, 69, 74, 93, 98, 100]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[What the hell is even a Digital Fingerprint ?]]></title><description><![CDATA[Here's a gentle hands-on introduction to digital fingerprints.]]></description><link>https://www.adityathebe.com/hands-on-introduction-to-digital-fingerprints/</link><guid isPermaLink="false">https://www.adityathebe.com/hands-on-introduction-to-digital-fingerprints/</guid><pubDate>Fri, 15 Jan 2021 18:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Digital fingerprint, as complex as it sounds, is simply just the digest(output) of a hash function. Example:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;printf&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;adityathebe&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; sha256sum
62eb9a06b678df7d48eb59929ab07a9858ed940ddfd3d8596482458133babe67&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;There you go - we just created a digital fingerprint of the string &apos;adityathebe&apos;. As simple as that!&lt;/p&gt;
&lt;p&gt;The above command may not run on a Windows machine or on MacOS. In that case, you can try online tools to get the sha256 hash - &lt;a href=&quot;https://emn178.github.io/online-tools/sha256.html&quot;&gt;https://emn178.github.io/online-tools/sha256.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;It&apos;s important to mention what hash function was used to generate the fingerprint as we can generate different fingerprints for the same data with other hash functions.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;printf&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;adityathebe&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; sha1sum
7d6fa418a5cc416fc8e70551b4ea86fbbd9456d3

&lt;span class=&quot;token builtin class-name&quot;&gt;printf&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;adityathebe&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; md5sum
0673288a42e614ad56a7da35e5c88153&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;There are many more hash functions in addition to these.&lt;/p&gt;
&lt;h2 id=&quot;why-create-digital-fingerprints-&quot;&gt;Why create digital fingerprints ?&lt;/h2&gt;
&lt;p&gt;Digital fingerprints are created to ensure Intigrity. Let&apos;s imagine I have a will that says I want to donate all of my bitcoins to John Mayer. Here&apos;s the &lt;code class=&quot;language-text&quot;&gt;will.txt&lt;/code&gt; file where I state just that&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;txt&quot;&gt;&lt;pre class=&quot;language-txt&quot;&gt;&lt;code class=&quot;language-txt&quot;&gt;I declare that I sign and execute this instrument as my last will
to grant all of my million bitcoins to John Mayer.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;With that file in hand, I can create a digital fingerprint using sha256.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; sha256sum will.txt

7350c9d592a9b8a514efdf050c4ef658f21f497dab2ba4c1b99d8380da9bfcab&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I submit my will along with the fingeprint to the executor.&lt;/p&gt;
&lt;p&gt;Now comes sneaky Kanye. Kanye hacks into the executor&apos;s system and then changes the will.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;txt&quot;&gt;&lt;pre class=&quot;language-txt&quot;&gt;&lt;code class=&quot;language-txt&quot;&gt;I declare that I sign and execute this instrument as my last will
to grant all of my million bitcoins to Kanye West.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;img src=&quot;https://media.giphy.com/media/iKH3eRQQ1gUebMncdL/giphy.gif&quot; alt=&quot;&quot;&gt;&lt;em&gt;Kanye having the day of his life&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;But hold on, the executor can just create the fingerprint again and check if it matches the fingerprint I provided.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; sha256sum will.txt

a3571c15b7e5436d7483d26bf01383cf75d2227b298853818c0b8a540d5b2a0b&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The two fingerprints do not match. And that&apos;s how the executor will know the Will was tampered !&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://media.giphy.com/media/rJ0w60oeJ3Im4/giphy.gif&quot; alt=&quot;&quot;&gt;&lt;em&gt;Kanye in shambles&lt;/em&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Now, of course, if Kanye was smart he would have changed the fingerprint as well. All he had to do was regenerate the sha256 hash of the modified will.txt file and then saved that as the fingerprint.txt file.&lt;/p&gt;
&lt;p&gt;Authentication is not provided by digital fingerprints. Anyone can modify the data and the corresponding fingerprint. There&apos;s no way of ensuring that the fingerprint was created by the owner. Due to this reason, digital fingerprints should not be used for security purposes.&lt;/p&gt;
&lt;p&gt;This is where digital signatures come in play. Digital signatures offer intrigrity along with authentication.&lt;/p&gt;
&lt;p&gt;Read about Digital Signatures on my other blog post.&lt;/p&gt;
&lt;h2 id=&quot;digital-fingerprints-of-public-keys&quot;&gt;Digital Fingerprints of Public Keys&lt;/h2&gt;
&lt;p&gt;Digital fingerprints are extensively used in Public-key cryptography. Public keys in general are very length. You can find my PGP public key &lt;a href=&quot;https://www.adityathebe.com/public.pgp&quot;&gt;here&lt;/a&gt; which is around 3000 characters long.&lt;/p&gt;
&lt;p&gt;How would you verify that you actually have my correct public keys? Well you can simply check each character one by one or instead compare the digital fingerprint of the public key which is far less tedious. Here&apos;s the sha256 digital signature of my public key &lt;code class=&quot;language-text&quot;&gt;76070d7abecae498c02ed11d0f7c41bc9ca97a7108fea93edf3d98386d930e45&lt;/code&gt;&lt;/p&gt;
&lt;h4 id=&quot;1-githubs-ssl-fingerprint&quot;&gt;1. Github&apos;s SSL Fingerprint&lt;/h4&gt;
&lt;p&gt;You can visit github.com and then click on the lock screen in the address bar to see the certificates. There you can see the sha256 and sha1 digital fingerprints of Github&apos;s SSL public key.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 546px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/63e823098a481af9c28ae81fb580d666/76aed/github-ssl-fingerprints.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 123%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAZCAIAAAC+dZmEAAAACXBIWXMAAA7EAAAOxAGVKw4bAAACUElEQVR42nWUbXOCMAzH+f5fb3eb2wunVLBCeWh51IK3H2QydJrL9dI2aZJ/kgZVVVvrnKsQ4KZp4V+hbcdxGF9QXTeBMTmsdZqkJk0zrZMkMUedGJOxRen6goZhCJQ6bDabLMuctZVznHrvhxudb3R5RoG1tu/7+XpaxJJleQLn61fWFDRNQ8ZlWdqZkIuZFkGu/DMKgOp0OsVxfJwJmaRT0s3IOUXmBGEO55+xxDxhXdd4wwl6ZL6gKvC88uwmtJyTPZYCBvIam+fGODTGkBj+iaLrOk77mV7Z/BmjQahRFEnaEgKpHg4HIhL/L41xCKRKKSwBJs9zYuFEtgisIPIcMEolRRN4RGkp763svzV/AlgYhlrry9wlkIQqstRiTessppyJM72RREi2PEcKhC2rCILrnTFob7dbEBIDEuGV/X7PFm0U1vE/NgnXVEjK07atxNbdaD0Vj8a8TZ1wQqgCktC6yRZ6cD55JlRilsaU8HhRWpoXqbn0OScE8mfPSKLLj1FYy9/hxxHGqa2q6TcApKKY1rI0ec5Lbd9zi4loBvXHR/n25t7f/ff3uN8Pu53f7cYwvIbheM9XpURBdPx2G1SfnwelojCsrG3rusP/+dyBW9N0a25bVvCcmL4CvCgKLkoBNANp5/FCIB0EGp2xZrhlyPX8ucl4T8lTP62Ds1KuaUrnSIz06ACyQlAMyul0RJsvwRhW0kbQ88mZDxDj/uvL88vQDEUBI7Ctk6SIIpjtQM9RiIWdY/VVBUZBH8dE71nveTgeh/9XbBfW+gfjqJa7zGhU6wAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;github ssl fingerprints&quot;
        title=&quot;&quot;
        src=&quot;/static/63e823098a481af9c28ae81fb580d666/76aed/github-ssl-fingerprints.png&quot;
        srcset=&quot;/static/63e823098a481af9c28ae81fb580d666/5a46d/github-ssl-fingerprints.png 300w,
/static/63e823098a481af9c28ae81fb580d666/76aed/github-ssl-fingerprints.png 546w&quot;
        sizes=&quot;(max-width: 546px) 100vw, 546px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;h4 id=&quot;2-fingerprints-in-gpg&quot;&gt;2. Fingerprints in GPG&lt;/h4&gt;
&lt;p&gt;GPG, an encryption tool, also shows the digital fingerprints of the public keys instead of the entire public key.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 847px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/695be4b9dbdb83a216fb21f71af98cab/b2cef/gpg-list-keys.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 73.33333333333334%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAIAAABr+ngCAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAB00lEQVR42nVS2W7bMBD09zSJrFumSJPiIYmmTjuunRRF//8zOhKbBogVYLDgww53ZnZ3TE/CjFT1oj4rez1wlzP7HHOPH2n1nFZxzOOEB2n1BTtaddyc6+5Wd3eQm/4u21d8QbjLuLMh1RHjCafxFrkUHUZxMxt3AxlgaqRyKKue6ZHil+Mp5S4smw1yzlq0eg4IRz2mZbPPZJgr1CKkacSyiJGQBol4+cA/MhEO3eBDNtD0b+3wDixGhveBNjUxijYlbQvu8DscFdCyCtkJMwWZTEhdNRe4RT3qySsXZi7a11yNIbNPmUTb/gOfstGNnJA2N5Oo57Ia/ARk2RSKZVW6p3nEkofMdlT2CWmI6KDZzb8hGNWOS227+0WPXX129bmVPeen+GD+G/aeOxhYdiM6DMRfPuoDPxHRF2bOuUtpG5E6yNVD2rRd07pBNvTr00884IUsHKsDIsOShTREyI+r4nrar4Fhz/3ljx1/QXDtbogdmNbjqewVDcEmGZoRsoe/EwBvkGX/Bs1frH6SM7qkhVb4xKnBQgaHhfYo1sOOtg57IWMsALeQ588D+rHwZay92piJfVnE35CZGqAKM3EYmI8j90tGhc+nXOE8XlK5Sf4Lk3rc2HC5psgAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;gpg list keys&quot;
        title=&quot;&quot;
        src=&quot;/static/695be4b9dbdb83a216fb21f71af98cab/b2cef/gpg-list-keys.png&quot;
        srcset=&quot;/static/695be4b9dbdb83a216fb21f71af98cab/5a46d/gpg-list-keys.png 300w,
/static/695be4b9dbdb83a216fb21f71af98cab/0a47e/gpg-list-keys.png 600w,
/static/695be4b9dbdb83a216fb21f71af98cab/b2cef/gpg-list-keys.png 847w&quot;
        sizes=&quot;(max-width: 847px) 100vw, 847px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;h4 id=&quot;3-fingerprints-in-ssh&quot;&gt;3. Fingerprints in SSH&lt;/h4&gt;
&lt;p&gt;When you try to ssh into a new system, the host system&apos;s digital fingerprint will be displayed on the prompt.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1200px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/dee20ba8ad135d4bb470f1a25a217452/c56af/ssh-fingerprint.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 13.333333333333334%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAADCAIAAAAcOLh5AAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAgklEQVR42iWMCQ6DIBBFOZRdBAURgWGrNSnS5f736G9NXn7erEzabaGqTNZh87kBB1IbdOEq9jLyKUGQ8MtISCB0BkzZDcxUZ3pIe+9VMqEucUf68qLb28Td5SccCxCMbGrIsH7YeaDr72XAGei4OwQdPuW/RywcndGsQheUJ+E77r68/DDUosIEaQAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;ssh fingerprint&quot;
        title=&quot;&quot;
        src=&quot;/static/dee20ba8ad135d4bb470f1a25a217452/c1b63/ssh-fingerprint.png&quot;
        srcset=&quot;/static/dee20ba8ad135d4bb470f1a25a217452/5a46d/ssh-fingerprint.png 300w,
/static/dee20ba8ad135d4bb470f1a25a217452/0a47e/ssh-fingerprint.png 600w,
/static/dee20ba8ad135d4bb470f1a25a217452/c1b63/ssh-fingerprint.png 1200w,
/static/dee20ba8ad135d4bb470f1a25a217452/c56af/ssh-fingerprint.png 1231w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[How to follow redirections on a cross origin request with no CORS enabled]]></title><description><![CDATA[Follow redirection on a cross origin request on the browser using the Fetch API]]></description><link>https://www.adityathebe.com/follow-redirection-on-cross-origin-requests/</link><guid isPermaLink="false">https://www.adityathebe.com/follow-redirection-on-cross-origin-requests/</guid><pubDate>Fri, 15 Jan 2021 15:00:00 GMT</pubDate><content:encoded>&lt;p&gt;If you&apos;ve ever tried to perform cross origin requests to a server that doesn&apos;t support CORS then you&apos;ll get a &lt;code class=&quot;language-text&quot;&gt;net::ERR_FAILED&lt;/code&gt; which is the expected behaviour. Sometimes, we just need the redirection to occur even though we cannot access the response. This article shows how you make the browser perform the redirections when CORS isn&apos;t supported by some or even all of the urls involved in the redirection ...&lt;/p&gt;
&lt;h3 id=&quot;same-origin-policy-sop&quot;&gt;Same Origin Policy (SOP)&lt;/h3&gt;
&lt;p&gt;The image below demonstrates what happens when a cross origin request is made to &lt;code class=&quot;language-text&quot;&gt;localhost&lt;/code&gt; from &lt;code class=&quot;language-text&quot;&gt;example.com&lt;/code&gt; (&lt;em&gt;two different origins&lt;/em&gt;).&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1200px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/34bf6ff1c3650fdb6a2f00906b01adb3/9efb3/cors-net-err-failed.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 18%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAIAAAABPYjBAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAApklEQVR42o2NzQqDMBCEff+XE/Fikt1ERSPUqpiN2ubHNNBDrx3mMHwwM8U8z3ZZ6Dlf6xqsDZaCc+k/FRExCBEBLsQTwLYtAexCnFImxMSYByAhDOcZWgA3DKZpdsaOcSxiVfm69mXpOH9x/gYIUubFKETquuw757aNSsW+j5lonZTK3ClVuLwhpWXMIhLnR9/f389c3rZElIz5mcivK02T0foh5QfTQ94YSS7BjgAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;Accessing localhost from example.com&quot;
        title=&quot;&quot;
        src=&quot;/static/34bf6ff1c3650fdb6a2f00906b01adb3/c1b63/cors-net-err-failed.png&quot;
        srcset=&quot;/static/34bf6ff1c3650fdb6a2f00906b01adb3/5a46d/cors-net-err-failed.png 300w,
/static/34bf6ff1c3650fdb6a2f00906b01adb3/0a47e/cors-net-err-failed.png 600w,
/static/34bf6ff1c3650fdb6a2f00906b01adb3/c1b63/cors-net-err-failed.png 1200w,
/static/34bf6ff1c3650fdb6a2f00906b01adb3/d61c2/cors-net-err-failed.png 1800w,
/static/34bf6ff1c3650fdb6a2f00906b01adb3/9efb3/cors-net-err-failed.png 1894w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;em&gt;Accessing localhost from example.com&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;A common misconception about &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy&quot;&gt;Same Origin Policy&lt;/a&gt; is that it prevents making requests from one origin to another origin. That is a false assumption. SOP prevents &lt;strong&gt;accessing&lt;/strong&gt; the response, it doesn&apos;t prevent &lt;strong&gt;making&lt;/strong&gt; the request.&lt;/p&gt;
&lt;p&gt;So, in the example shown in the image above a request was actually made to localhost, although the response wasn&apos;t accessible. If we check our server log, we&apos;ll in fact see the request.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 887px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/d3f43a6a28ab76137382f073ecbeb38c/eac55/request-received-sop.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 32.33333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAIAAABM9SnKAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAA3klEQVR42m2QaW6EMAyFOVCHAbLgJJCNLJACLaj3P0sN0vRPR3qKYud9duzqyVwnIpEZ/C7CMaRzmD7HadNxt+nQ8UuYotxu4mHiOfgdxkBuf01tdcEQuEpgN2434b+VL2CycjPohalIRKAiwVj6YSEiUxmojG0fLrhmroXQcNfwqeH+yT1m8ILC5we192ke5E8WVVPz6qxyAwF0ITJRmbBVPy4Y4o8+Oo1AfZf4rwod1yRmFW6/ZFdpZmlXn39sOvkwM5XR8x4GU3AZDXMEAppwGThP20/dK7wz01v4F/F2U5SWWs6UAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;Server Logs&quot;
        title=&quot;&quot;
        src=&quot;/static/d3f43a6a28ab76137382f073ecbeb38c/eac55/request-received-sop.png&quot;
        srcset=&quot;/static/d3f43a6a28ab76137382f073ecbeb38c/5a46d/request-received-sop.png 300w,
/static/d3f43a6a28ab76137382f073ecbeb38c/0a47e/request-received-sop.png 600w,
/static/d3f43a6a28ab76137382f073ecbeb38c/eac55/request-received-sop.png 887w&quot;
        sizes=&quot;(max-width: 887px) 100vw, 887px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;em&gt;Server Logs&lt;/em&gt;&lt;/p&gt;
&lt;h3 id=&quot;cross-origin-resource-sharing-cors&quot;&gt;Cross Origin Resource Sharing (CORS)&lt;/h3&gt;
&lt;p&gt;Now, how do we make the resources on localhost available to example.com ? To circumvent this restriction by SOP, we can use CORS.&lt;/p&gt;
&lt;p&gt;Let&apos;s add a new endpoint that supports CORS. It&apos;s as simple as adding the header &lt;code class=&quot;language-text&quot;&gt;Access-Control-Allow-Origin: http://www.example.com&lt;/code&gt; to the response.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1200px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/7fa37d5f6e9bfe8c1e3f257678cfd513/6f464/cors-go-server.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 18.666666666666668%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAIAAAABPYjBAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAvElEQVR42iWOa46DIBhF3VAdlAEEEfh4g6/UmJn976S0Tc6/m5tzOqIqNTuzh4AsYJ1hW/z5ZVJlUpXrXdoT0t1WtsDA7MAcIvaBTQf1X5Y/5W4dn7YeMlQou0qbDKvdDumryaffbp9vpivVZTKR6oR4/CHQzfES4ZJwcfdc3Cp9nm0WH5ZQpGu2gIXnNrWbsIm7AqYNze+7kceWMYqEJo8oYO4G+m4buUMMEHE9Nq2web70BPCvjj2XaH4BU+s7qqnLrKUAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;Enable CORS with the Access-Control-Allow_origin header&quot;
        title=&quot;&quot;
        src=&quot;/static/7fa37d5f6e9bfe8c1e3f257678cfd513/c1b63/cors-go-server.png&quot;
        srcset=&quot;/static/7fa37d5f6e9bfe8c1e3f257678cfd513/5a46d/cors-go-server.png 300w,
/static/7fa37d5f6e9bfe8c1e3f257678cfd513/0a47e/cors-go-server.png 600w,
/static/7fa37d5f6e9bfe8c1e3f257678cfd513/c1b63/cors-go-server.png 1200w,
/static/7fa37d5f6e9bfe8c1e3f257678cfd513/6f464/cors-go-server.png 1464w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;em&gt;Enable CORS with the Access-Control-Allow-Origin header&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;And now if we make a request to localhost from example.com we will be able to access the response.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1200px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/531bfb7aa0cf51cd21a7966747fb8694/6aacb/cors-demo.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 18%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAIAAAABPYjBAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAfklEQVR42pWMywpDIQxE/f9/bKGKoNZgjFG54qPp+i5Kh2EWB+Yoa+3be0qppBRjemn3eGqIkagw99ZarY1ZtjrntNbGGABARCJSIQQGkJL3A3FlnMxyKNwRr3GNyoNofJnAwqKUFek5R2HOnUoDEPne+/wTtdY60jnvz5+qD4ga5483EXM2AAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;Access response from the client with CORS enabled&quot;
        title=&quot;&quot;
        src=&quot;/static/531bfb7aa0cf51cd21a7966747fb8694/c1b63/cors-demo.png&quot;
        srcset=&quot;/static/531bfb7aa0cf51cd21a7966747fb8694/5a46d/cors-demo.png 300w,
/static/531bfb7aa0cf51cd21a7966747fb8694/0a47e/cors-demo.png 600w,
/static/531bfb7aa0cf51cd21a7966747fb8694/c1b63/cors-demo.png 1200w,
/static/531bfb7aa0cf51cd21a7966747fb8694/6aacb/cors-demo.png 1347w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;em&gt;Access response from the client with CORS enabled&lt;/em&gt;&lt;/p&gt;
&lt;h3 id=&quot;redirection-with-cors-support&quot;&gt;Redirection with CORS support&lt;/h3&gt;
&lt;p&gt;Let&apos;s add a new endpoint &lt;code class=&quot;language-text&quot;&gt;/cors-redirect&lt;/code&gt; that redirects the user to &lt;code class=&quot;language-text&quot;&gt;/cors&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1200px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/5c2706ad93156a7d69a84bb0e5abc349/289dd/cors-redirection-go-server.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 16%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAADCAIAAAAcOLh5AAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAlUlEQVR42h3LyxaCIBSFYR+o1BIEgcP1eAEssUnv/yaRa32DPdh/w80u8OS+iPDmLkmMKmS7Hmo9IJYpZIlZ4cssJ6aPcHGQGwUkYu6pb2oM6SttUb5ALTFJH4WPO9M7VcCc0DMzSzXZjcH6GEM3uo66ltiGqpnqTCAxSBwi16l6Mhx6IA+w3SR7dSO2XtvB3P+uffkBVtor3e9OWugAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;Endpoint that redirects to /cors&quot;
        title=&quot;&quot;
        src=&quot;/static/5c2706ad93156a7d69a84bb0e5abc349/c1b63/cors-redirection-go-server.png&quot;
        srcset=&quot;/static/5c2706ad93156a7d69a84bb0e5abc349/5a46d/cors-redirection-go-server.png 300w,
/static/5c2706ad93156a7d69a84bb0e5abc349/0a47e/cors-redirection-go-server.png 600w,
/static/5c2706ad93156a7d69a84bb0e5abc349/c1b63/cors-redirection-go-server.png 1200w,
/static/5c2706ad93156a7d69a84bb0e5abc349/289dd/cors-redirection-go-server.png 1409w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;em&gt;Endpoint that redirects to /cors&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;On the browser we can make a request to this new endpoint. We&apos;ll see that the redirection does occur and the response is in fact from &lt;code class=&quot;language-text&quot;&gt;cors&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1200px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/cea4e0a8b74748f051a61bb9f6b8a0bf/21482/cors-redirect-demo.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 17%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAADCAIAAAAcOLh5AAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAeklEQVR42k2M2w4DIQgF/f//rFlbL7iCgnaxNM0mncwDkHNw3vsQQo0Ra8VS8isfj6PE2AE6UWvm4MG1UghPM6UMAAXgbM0hYs7Zai0lKkWZLzHlYp5z9iFEy+j9zbzmFJE5vt9sWa4hGYIoZ7WQ7q0/7mHfqOr/RVU/AqOtClWZi2UAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;Redirection successful&quot;
        title=&quot;&quot;
        src=&quot;/static/cea4e0a8b74748f051a61bb9f6b8a0bf/c1b63/cors-redirect-demo.png&quot;
        srcset=&quot;/static/cea4e0a8b74748f051a61bb9f6b8a0bf/5a46d/cors-redirect-demo.png 300w,
/static/cea4e0a8b74748f051a61bb9f6b8a0bf/0a47e/cors-redirect-demo.png 600w,
/static/cea4e0a8b74748f051a61bb9f6b8a0bf/c1b63/cors-redirect-demo.png 1200w,
/static/cea4e0a8b74748f051a61bb9f6b8a0bf/21482/cors-redirect-demo.png 1350w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;em&gt;Redirection successful&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;If we check our server log, we can see all the requests that were received.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 793px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/b81a401495954f59e2e8329e486735dc/73fd0/cors-redirection-go-output.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 21.333333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAIAAAABPYjBAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAn0lEQVR42n2O6Q6CMBCEeSDl6oFYKBQoPQJGATW+/4s4UH+bfNl0uzM7G2WlJrVLeV82npaaXsf8ormwvLJMmJi2f4iyoifCsNpzOaEy4bjQhbRCze24wH8mTcIUSHkHceBnrrpb757KbuP8kfqh/VuZpbPb4F/KrKhyuEOwa8wKitoB7NrN0OFUvLA4oW0ICcRHixyM9unxc8olbgnJXySuOQqdT+kaAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;Server Logs&quot;
        title=&quot;&quot;
        src=&quot;/static/b81a401495954f59e2e8329e486735dc/73fd0/cors-redirection-go-output.png&quot;
        srcset=&quot;/static/b81a401495954f59e2e8329e486735dc/5a46d/cors-redirection-go-output.png 300w,
/static/b81a401495954f59e2e8329e486735dc/0a47e/cors-redirection-go-output.png 600w,
/static/b81a401495954f59e2e8329e486735dc/73fd0/cors-redirection-go-output.png 793w&quot;
        sizes=&quot;(max-width: 793px) 100vw, 793px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;em&gt;Server Logs&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;So far so good ...&lt;/p&gt;
&lt;h3 id=&quot;redirection-without-cors-support&quot;&gt;Redirection without CORS support&lt;/h3&gt;
&lt;p&gt;Let&apos;s add a new endpoint &lt;code class=&quot;language-text&quot;&gt;/no-cors-redirect&lt;/code&gt; that redirects the user to &lt;code class=&quot;language-text&quot;&gt;/cors&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;handleNoCorsRedirection&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;w http&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ResponseWriter&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; req &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;http&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Request&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  fmt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;[/no-cors-redirect] Request received&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  fmt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Referer:&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; req&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Header&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Referer&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  w&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Header&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Location&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;/cors&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  w&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;WriteHeader&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;http&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;StatusFound&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If we try to call this endpoint, the browser will throw an error.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1200px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/40021c1be5c67de8f0fe9f8231088479/26c3a/no-cors-redirection-error.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 18.666666666666668%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAIAAAABPYjBAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAwElEQVR42iXMyY6DMBAEUP7/5wJJLggOZHHiDdvdabwQG49nRnoqqVRSdVJKNAaMFVwbpSORjxEp+riLFV5cWgAHaAG3GH1KbW32nN9cdImx9HwGzqNSQYiNc2p3XGYhCxdBr6QUShm1ro1SxZhN62QtGdul89lfr5++x77/DAOdTsflUoahjmOdprIs5fEojB2M1fu93m6tpmWhebbT3B3gMkB2rjh3IBaASlRTqvtev9/fbP7rnxLC5pxHRL3+AIo14Di24UIBAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;Error on redirection with no CORS support&quot;
        title=&quot;&quot;
        src=&quot;/static/40021c1be5c67de8f0fe9f8231088479/c1b63/no-cors-redirection-error.png&quot;
        srcset=&quot;/static/40021c1be5c67de8f0fe9f8231088479/5a46d/no-cors-redirection-error.png 300w,
/static/40021c1be5c67de8f0fe9f8231088479/0a47e/no-cors-redirection-error.png 600w,
/static/40021c1be5c67de8f0fe9f8231088479/c1b63/no-cors-redirection-error.png 1200w,
/static/40021c1be5c67de8f0fe9f8231088479/d61c2/no-cors-redirection-error.png 1800w,
/static/40021c1be5c67de8f0fe9f8231088479/26c3a/no-cors-redirection-error.png 1907w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;em&gt;Error on redirection with no CORS support&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Even though the endpoint &lt;code class=&quot;language-text&quot;&gt;/cors&lt;/code&gt; supports CORS, the redirection does not occur because on the very first response itself the browser will terminate the request.&lt;/p&gt;
&lt;p&gt;It doesn&apos;t matter whether the subsequent redirected urls support CORS or not if the ones before doesn&apos;t support it. For a redirection to occur, every urls on the redirection should support CORS.&lt;/p&gt;
&lt;p&gt;We can verify that the redirection didn&apos;t occur by checking our server log.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 843px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/cbba18bf9ed0b58607b88ecc6814e221/4ff83/no-cors-redirection-server-log.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 18%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAIAAAABPYjBAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAmElEQVR42mWOWwqDMBBFXVCrRqOJUfMy0VpDKi2F7n8lvX2QjxYOl2FgztysURvhrteBjSsVczuckJ3aQN35nOqiMf9gD7KSOcJ9LWYkLFVrCbPJcqzVD4dKIr/HvYm93Ud3Vctd2Iv2u3RR+n0OD7PcBhth4XJFEaEDGKfI5RlLKDLCppyqAvXeslcratKfsrWfnhgSqfkTgWA3aabareEAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;Server Logs&quot;
        title=&quot;&quot;
        src=&quot;/static/cbba18bf9ed0b58607b88ecc6814e221/4ff83/no-cors-redirection-server-log.png&quot;
        srcset=&quot;/static/cbba18bf9ed0b58607b88ecc6814e221/5a46d/no-cors-redirection-server-log.png 300w,
/static/cbba18bf9ed0b58607b88ecc6814e221/0a47e/no-cors-redirection-server-log.png 600w,
/static/cbba18bf9ed0b58607b88ecc6814e221/4ff83/no-cors-redirection-server-log.png 843w&quot;
        sizes=&quot;(max-width: 843px) 100vw, 843px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;em&gt;Server Logs&lt;/em&gt;&lt;/p&gt;
&lt;h4 id=&quot;no-cors-mode&quot;&gt;no-cors mode&lt;/h4&gt;
&lt;p&gt;The fetch API provides a special option called &lt;code class=&quot;language-text&quot;&gt;mode&lt;/code&gt;. It takes 5 possible values &quot;same-origin&quot;, &quot;cors&quot;, &quot;no-cors&quot;, &quot;navigate&quot;, or &quot;websocket&quot; and the default value is &quot;cors&quot; although the specs suggest that &quot;no-cors&quot; is the default value 🤷‍♂️.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1200px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/ebf46e29a669f2a0b0df33753f2496db/37048/fetch-mode-specification.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 32%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAIAAABM9SnKAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABDUlEQVR42kXO227DIAwG4L7/m20pCwEDhRxajXZTu05rAkkgaeqR7mLSd2HZ+m1vxLfIf3I7Wbu8P9nVfLJ3a6eP1WKPyzFJ0+NiP/EzOeHphreNe7httyUDoYHlA9BY0CmnXtER8oHTXtBIi9SMxVvPWYAKy0SjPuN549AVfcECg1Hytga/E0GAL6ErYQQYgAfgkbPImNOyq8qpqu51ieUFL2uYtIT2FGYQg1CtEZ0WI0ivtC8TNSk5SzFLNUvdG+WMidV/OLtlmcvISEh4zTr+8qWzlpNO6KlusNnjPklFg/sa6z8GzTP8cHzkPDDud7yrdDBy2DEvE54emaRMolzvR9k8mgMekrTritdfAy9BKmT7oAMAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;Fetch Mode Specification&quot;
        title=&quot;&quot;
        src=&quot;/static/ebf46e29a669f2a0b0df33753f2496db/c1b63/fetch-mode-specification.png&quot;
        srcset=&quot;/static/ebf46e29a669f2a0b0df33753f2496db/5a46d/fetch-mode-specification.png 300w,
/static/ebf46e29a669f2a0b0df33753f2496db/0a47e/fetch-mode-specification.png 600w,
/static/ebf46e29a669f2a0b0df33753f2496db/c1b63/fetch-mode-specification.png 1200w,
/static/ebf46e29a669f2a0b0df33753f2496db/37048/fetch-mode-specification.png 1352w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;em&gt;Fetch Mode Specification &lt;a href=&quot;https://fetch.spec.whatwg.org/&quot;&gt;https://fetch.spec.whatwg.org/&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Let&apos;s use the &lt;code class=&quot;language-text&quot;&gt;mode: &apos;no-cors&apos;&lt;/code&gt; option this time and see if the redirection occurs.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1200px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/b690fcd2566c8488808052408b940909/c2b0b/fetch-no-cors-mode.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 12.666666666666668%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAADCAIAAAAcOLh5AAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAfElEQVR42lWLUQrEIBBDe/9TlrLUUrGOY3S06rrTr7LwCC+ELOQ9E4HIGkPOFaDeN0SaCIDPbnbjAseLkg9MzD4EhQGpdZFty+vaj2Ne19f7YW13rqkTjZx7zg0ysrSokjqgNM2UdF2m3s5Tn5N5Ak/G+KAu8lLkv5aR0g/06avHDxI73QAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;fetch no cors mode&quot;
        title=&quot;&quot;
        src=&quot;/static/b690fcd2566c8488808052408b940909/c1b63/fetch-no-cors-mode.png&quot;
        srcset=&quot;/static/b690fcd2566c8488808052408b940909/5a46d/fetch-no-cors-mode.png 300w,
/static/b690fcd2566c8488808052408b940909/0a47e/fetch-no-cors-mode.png 600w,
/static/b690fcd2566c8488808052408b940909/c1b63/fetch-no-cors-mode.png 1200w,
/static/b690fcd2566c8488808052408b940909/d61c2/fetch-no-cors-mode.png 1800w,
/static/b690fcd2566c8488808052408b940909/c2b0b/fetch-no-cors-mode.png 1895w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Yay ! The redirection does occur. We can verify that by checking our server log.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1005px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/bf9a4a911957387bb80e7a48498d249b/18c13/fetch-mode-no-cors-server-log.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 15.666666666666668%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAADCAIAAAAcOLh5AAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAcUlEQVR42l2NSw6FIBRD3ZB/EBBEcvGvwThw/1ux+iYvJCdNBz1pUghfthNrJ66XWo6VHBqzgJy7tO4jMub+SZgaNQVNpxkulI4O44Nfb0NBdCuQdgMoOIhlXCm7AfntfmthX031u3I7kuu5FL5oKJIf7XEqBWq2cGQAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;Server Logs&quot;
        title=&quot;&quot;
        src=&quot;/static/bf9a4a911957387bb80e7a48498d249b/18c13/fetch-mode-no-cors-server-log.png&quot;
        srcset=&quot;/static/bf9a4a911957387bb80e7a48498d249b/5a46d/fetch-mode-no-cors-server-log.png 300w,
/static/bf9a4a911957387bb80e7a48498d249b/0a47e/fetch-mode-no-cors-server-log.png 600w,
/static/bf9a4a911957387bb80e7a48498d249b/18c13/fetch-mode-no-cors-server-log.png 1005w&quot;
        sizes=&quot;(max-width: 1005px) 100vw, 1005px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;em&gt;Server Logs&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;But if you noticed we have an error on the browser console. The error occurs because this time SOP prevents us from accessing the response of &lt;code class=&quot;language-text&quot;&gt;/cors&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Remember, the endpoint &lt;code class=&quot;language-text&quot;&gt;/no-cors-redirect&lt;/code&gt; doesn&apos;t support CORS.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;And if you look at the code we are calling the &lt;code class=&quot;language-text&quot;&gt;response.json()&lt;/code&gt; which tries to access the response body.&lt;/p&gt;
&lt;p&gt;Let&apos;s modify our code a little bit.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1200px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/98fd9b60cabbd93bdfe7b68db818def8/82c1e/fetch-mode-no-cors-opaque-response.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 16.666666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAADCAIAAAAcOLh5AAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAeElEQVR42jWLWxLDIAwDc/97lkwhvBrAlg1tnXayI//I2i2E4B6uen8eh6WFkNzeYuRShOnVTrSuvacU3e6e3pdSiYh/bADMrzlbqOTFPFWnCI/BjEEqgEBElEjtY/e52WCt7WyhusaYwDRUrbEKWHJxaX/ZnPfNFzAmrTRfVG2QAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;Opaque response type&quot;
        title=&quot;&quot;
        src=&quot;/static/98fd9b60cabbd93bdfe7b68db818def8/c1b63/fetch-mode-no-cors-opaque-response.png&quot;
        srcset=&quot;/static/98fd9b60cabbd93bdfe7b68db818def8/5a46d/fetch-mode-no-cors-opaque-response.png 300w,
/static/98fd9b60cabbd93bdfe7b68db818def8/0a47e/fetch-mode-no-cors-opaque-response.png 600w,
/static/98fd9b60cabbd93bdfe7b68db818def8/c1b63/fetch-mode-no-cors-opaque-response.png 1200w,
/static/98fd9b60cabbd93bdfe7b68db818def8/82c1e/fetch-mode-no-cors-opaque-response.png 1398w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;em&gt;Opaque response type&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;This time we&apos;re not trying to access the response body. We&apos;re simply logging the response to the console. This is an special type of response classified as - &quot;Opaque&quot; response. You can see in the log above.&lt;/p&gt;
&lt;p&gt;There other types of request too. You can read about them here - &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Response/type&quot;&gt;https://developer.mozilla.org/en-US/docs/Web/API/Response/type&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Let&apos;s take a step back and see the response type of the requests that we have made before.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1200px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/d675776208a28de15195e2c5e7ce4905/aa440/response-types-demo.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 24.333333333333332%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAIAAADKYVtkAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAw0lEQVR42i1Oi27DIBDL/39ktanZEpKlhPc9OFRTzVjIoDvby7Zt53GkEEqMPqT192/fXUyptgYSs4iEEJzbr+sqEzkXnIkFc6dz6bri66WPh31/KVFNGV41JRPp/xgfdlXrfXKMsYQQt/XnRrhzdDiGvffZe9hRiIOQzUStNWmk0K12ZiXuZragxHmc8b7RXNdVn09B1VI4Z621C14TmOaplQl/ikIzGQ7QqjrMRmsGgX4ig9nA2XNCxD53V7B30bn8Bi0SIBNKVSnqAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;Response types&quot;
        title=&quot;&quot;
        src=&quot;/static/d675776208a28de15195e2c5e7ce4905/c1b63/response-types-demo.png&quot;
        srcset=&quot;/static/d675776208a28de15195e2c5e7ce4905/5a46d/response-types-demo.png 300w,
/static/d675776208a28de15195e2c5e7ce4905/0a47e/response-types-demo.png 600w,
/static/d675776208a28de15195e2c5e7ce4905/c1b63/response-types-demo.png 1200w,
/static/d675776208a28de15195e2c5e7ce4905/aa440/response-types-demo.png 1500w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;em&gt;Response types&lt;/em&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;SOP prevents accessing response from a different origin&lt;/li&gt;
&lt;li&gt;CORS helps us access response from a different origin provided that the server supports it&lt;/li&gt;
&lt;li&gt;By default, cross origin redirects are prohibited if the server doesn&apos;t support CORS&lt;/li&gt;
&lt;li&gt;We used mode &apos;no-cors&apos; to make the redirections&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;This blog post was inspired by&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.teddykatz.com/2019/11/05/github-oauth-bypass.html&quot;&gt;Github OAuth bypass write-up by Teddy Katz&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://pentesterlab.com/exercises/oauth2_github/course&quot;&gt;Pentester Lab Course - OAuth2: Github HTTP HEAD&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Find the server-side go code &lt;a href=&quot;https://gist.github.com/adityathebe/f5905b9e28bbc78ba2abbd69e88a5c0d&quot;&gt;here&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Crack weak JWT HS256 secrets with a wordlist in Golang]]></title><description><![CDATA[JWT that uses HS256 algorithm should have strong secret. Weak secrets can be bruteforced or a dictionary attack can reveal the secret key]]></description><link>https://www.adityathebe.com/crack-weak-jwt-symmetric-secrets-keys/</link><guid isPermaLink="false">https://www.adityathebe.com/crack-weak-jwt-symmetric-secrets-keys/</guid><pubDate>Sat, 09 Jan 2021 12:30:00 GMT</pubDate><content:encoded>&lt;p&gt;If you&apos;re reading this article you probably know what JWTs are. Let&apos;s jump straight into the details&lt;/p&gt;
&lt;h1 id=&quot;symmetric-key-and-asymmetric-key-signatures&quot;&gt;Symmetric key and Asymmetric key Signatures&lt;/h1&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 961px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/28a95d15624df9f63d5270611711dc34/024d6/jwt-algorithms.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 81.33333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAIAAACZeshMAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABn0lEQVR42m3Th24CQQwE0Pz/1yGqCCWUI/Sj1wDJ44wOEbESK69vxh7PLh+73e5wOEyn0/F43O/3v7OVJIlMr9ezO6ZpOplMttvt7+v68JvNZkm2ut0u0Gg0QlBLRhwVxYPBYDgcOq5Wq8vl8iR/ZSsQVqfTUSViaEcqlNOc0uVyeT6f7+Tb7SaKLP329Xqd7/L7/f56vQoi4/iTrQeZDLUN5huFjUZDwzj6tNls4GQ+syXQ7Hg8PmQrSfPpdApQDCkwBZzqJqSZI4vFAkYywHeyJsViMc7NZrNSqdTr9VqtJtY2vMEsFAomV8sUD7IDBHsCpGGpVNKTYLJdVdyQBpqDhZYXMlCQ0aiwmwVtPp9zKMj5Vf/vDJSTydYkrDKkXTeBG1WCz8/OURUhDOSWmH8GtrdarXK53G63TWscmRfZfi49smIg6CBjOrJKT2/LFRIIQ+NTNmN8jnt34dVqFQE50HRRrgEM5JuZfYiZc7L3gCyPxrxw+41hUvwQhGxkTM4phBaGA/iTvCGzysDxYpmcZkscLymWZ28PWP7C/gD7q4JCmtrP+wAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;Reference: https://tools.ietf.org/html/rfc7518#section-3.1&quot;
        title=&quot;&quot;
        src=&quot;/static/28a95d15624df9f63d5270611711dc34/024d6/jwt-algorithms.png&quot;
        srcset=&quot;/static/28a95d15624df9f63d5270611711dc34/5a46d/jwt-algorithms.png 300w,
/static/28a95d15624df9f63d5270611711dc34/0a47e/jwt-algorithms.png 600w,
/static/28a95d15624df9f63d5270611711dc34/024d6/jwt-algorithms.png 961w&quot;
        sizes=&quot;(max-width: 961px) 100vw, 961px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;JWT uses cryptographic keys to generate signatures. It&apos;s possible to use one of either a symmetric key or an asymmetric key. There are various factors one should consider when choosing one of these two approaches but that&apos;s a discussion for another article.&lt;/p&gt;
&lt;p&gt;With a symmetric key, a single key is used to sign and validate the signature. &lt;em&gt;Technically, with symmetric keys we are encrypting the data and producing MAC (Message Authentication Token) and not Digital Signatures&lt;/em&gt;. And with the asymmetric keys two different keys are used to sign and validate the signature respectively. This article focuses on symmetric key signing.&lt;/p&gt;
&lt;h2 id=&quot;symmetric-key-algorithms&quot;&gt;Symmetric key algorithms&lt;/h2&gt;
&lt;p&gt;One of the most popular algorithms for JWT is the &lt;code class=&quot;language-text&quot;&gt;HS256&lt;/code&gt; algorithm. There are other variations to this algorithm like &lt;code class=&quot;language-text&quot;&gt;HS384&lt;/code&gt; &amp;#x26; &lt;code class=&quot;language-text&quot;&gt;HS512&lt;/code&gt; which are more secure.&lt;/p&gt;
&lt;p&gt;The HS256 algorithm takes in two inputs:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the message to encrypt (JWT header + JWT payload)&lt;/li&gt;
&lt;li&gt;the secret key used to encrypt the message&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;cracking-jwt-secrets&quot;&gt;Cracking JWT secrets&lt;/h2&gt;
&lt;p&gt;Since the JWT is just a base64URL encoded data we can simply decode it to see what the header and the payload are. Here&apos;s a pretty handy webapp that let&apos;s you play around with JWTs.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1200px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/b8fc2055c553b4a98a3bacb36abd41bd/ffaa5/jwt.io.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 34.333333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAIAAACHqfpvAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAsklEQVR42nWQWQ7DIAxEuf8d0/5ma6CIHS81pJWSKnkCyxIzeEABwLwsm9aADT5jrR3HMaaEV6eKiFIIxQeqhUphqXsDTeq9N/adShbwgIwUoyJmmDIMsTwCPEIdAgwhP33cmllU5DO5JNLjTOooaYylSfNL82p4Mbxpnh2tqZlrreAT5/oX+GuWjf1aWdjr3uwkQQKL5swvdoevICaUb3RcVwZ3M/nO3N+MWBgjU70wfwDgkZzKl0OjmQAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;Source: https://jwt.io&quot;
        title=&quot;&quot;
        src=&quot;/static/b8fc2055c553b4a98a3bacb36abd41bd/c1b63/jwt.io.png&quot;
        srcset=&quot;/static/b8fc2055c553b4a98a3bacb36abd41bd/5a46d/jwt.io.png 300w,
/static/b8fc2055c553b4a98a3bacb36abd41bd/0a47e/jwt.io.png 600w,
/static/b8fc2055c553b4a98a3bacb36abd41bd/c1b63/jwt.io.png 1200w,
/static/b8fc2055c553b4a98a3bacb36abd41bd/ffaa5/jwt.io.png 1299w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;With that in our hand we can simply try to generate signature by bruteforcing every single possible characters and see if the generated signature matches the one on the JWT. If we find a match then we have successfully cracked the secret key.&lt;/p&gt;
&lt;p&gt;In Golang, you can use this function to generate the HS256 signature. &lt;em&gt;Find the full code &lt;a href=&quot;https://github.com/adityathebe/jwt-wordlist-cracker&quot;&gt;here&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;hs256&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; secret &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	mac &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; hmac&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;New&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;sha256&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;New&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;secret&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	mac&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Write&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; base64&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;RawURLEncoding&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;EncodeToString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;mac&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Sum&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If the secret key is pretty weak, bruteforcing can be fruitful. However more often than not the secret keys are pretty lengthy for this attack to work.&lt;/p&gt;
&lt;p&gt;A dictionary attack can give us better results.&lt;/p&gt;
&lt;p&gt;Here&apos;s a public Github repository that has scraped JWT secrets from other public github repositories. You can find it here - &lt;a href=&quot;https://github.com/wallarm/jwt-secrets&quot;&gt;https://github.com/wallarm/jwt-secrets&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;You can try using the code I provided above to perform the dictionary attack. But there are more mature tools that are designed exactly for this purpose&lt;/p&gt;
&lt;h3 id=&quot;john-the-ripper&quot;&gt;John The Ripper&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;john token.txt &lt;span class=&quot;token parameter variable&quot;&gt;--wordlist&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;wordlist.txt &lt;span class=&quot;token parameter variable&quot;&gt;--format&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;HMAC-SHA256&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;hashcat&quot;&gt;Hashcat&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;hashcat &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;16500&lt;/span&gt; token.txt wordlist.txt&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;hashcat has better support for GPU and can perform signficantly better than john.&lt;/p&gt;
&lt;h2 id=&quot;recommended-practice-for-generating-jwt-secrets&quot;&gt;Recommended practice for generating JWT secrets&lt;/h2&gt;
&lt;p&gt;It&apos;s also important to note than we can perform this attack completely offline. We do not need to make any requests to the web server since we have all the data we need in the JWT itself.&lt;/p&gt;
&lt;p&gt;With a pretty powerful GPU we can test billions of hashes per second. This is why the length of the shared secret for HS256 is of the utmost importance. JSON Web Algorithms defines the minimum key length to be equal to the size in bits of the hash function used along with the HMAC algorithm which in case of HS256 would be 256bits.&lt;/p&gt;
&lt;h1 id=&quot;references&quot;&gt;References&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://pentesterlab.com/exercises/jwt_v/course&quot;&gt;https://pentesterlab.com/exercises/jwt_v/course&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://auth0.com/blog/a-look-at-the-latest-draft-for-jwt-bcp/&quot;&gt;https://auth0.com/blog/a-look-at-the-latest-draft-for-jwt-bcp/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://jwt.io&quot;&gt;https://jwt.io&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/HMAC&quot;&gt;https://en.wikipedia.org/wiki/HMAC&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Basic introduction to HTTP requests with TCP Sockets in NodeJs]]></title><description><![CDATA[Understand the structure of HTTP messages and how they work with network sockets in NodeJs]]></description><link>https://www.adityathebe.com/raw-http-request-with-sockets-nodejs/</link><guid isPermaLink="false">https://www.adityathebe.com/raw-http-request-with-sockets-nodejs/</guid><pubDate>Sun, 22 Mar 2020 22:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I love programming in NodeJs; mainly due to the speed in which I can quickly get an application up and running. Need to make an http request ? &lt;code class=&quot;language-text&quot;&gt;npm install axios&lt;/code&gt; and a few lines of code will do the trick. Need to create an http server? &lt;code class=&quot;language-text&quot;&gt;npm install express&lt;/code&gt; and with few lines you&apos;ve an http server running. Now take a look at this &lt;a href=&quot;https://stackoverflow.com/a/1359700/6199444&quot;&gt;StackOverflow answer&lt;/a&gt; on how to make http request in Java. There&apos;s just so much of code to write ...&lt;/p&gt;
&lt;p&gt;But this convenience comes at a cost. All these fancy easy-to-use libraries abstract the nitty gritties that&apos;s happening under the hood.&lt;/p&gt;
&lt;p&gt;I learned about sockets years after learning to make http requests in NodeJs. The convenience provided by RequestJs and ExpressJs never made the need for me to learn sockets. In fact I didn&apos;t even know that there&apos;s such thing as sockets just a while ago and I am sure many new devs don&apos;t either.&lt;/p&gt;
&lt;h2 id=&quot;what-are-sockets-&quot;&gt;What are sockets ?&lt;/h2&gt;
&lt;p&gt;You&apos;ve probably heard of &lt;a href=&quot;https://en.wikipedia.org/wiki/Transmission_Control_Protocol&quot;&gt;TCP&lt;/a&gt;. It is one of the protocols that governs the exchange of data over network connections.&lt;/p&gt;
&lt;p&gt;HTTP works over TCP (Any other protocol like UDP is fine as well but TCP is the standard). This means whenever we need to make an http request to a server - via whatever means like nodejs, python, curl or web browsers - we first need to establish a TCP connection with the server. Once the TCP connection is established, http requests and responses can be exchanged to-and-fro over the connection.&lt;/p&gt;
&lt;p&gt;So how do we establish a TCP connection? That&apos;s where sockets come in. A socket is an interface provided by the operating system that enables us to read and write to a network. There are 3 types of sockes&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Stream Sockets (TCP)&lt;/li&gt;
&lt;li&gt;Datagrap Sockets (UDP)&lt;/li&gt;
&lt;li&gt;Raw Sockets&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Since HTTP is most commonly used with TCP, we are only concerned with TCP sockets in this article.&lt;/p&gt;
&lt;p&gt;Most programming languages provide a socket interface. NodeJs provides the &lt;code class=&quot;language-text&quot;&gt;net&lt;/code&gt; library, python provides the &lt;code class=&quot;language-text&quot;&gt;socket&lt;/code&gt; library and likewise there&apos;s &lt;code class=&quot;language-text&quot;&gt;java.net.Socket&lt;/code&gt; in Java.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1200px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/571f564db0d3a6141667a1e5d2cde823/a5c12/sockets-zines.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 77%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAPABQDASIAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAAAAECBf/EABQBAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhADEAAAAezFNA//xAAWEAEBAQAAAAAAAAAAAAAAAAABEAD/2gAIAQEAAQUChTf/xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/AT//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/AT//xAAUEAEAAAAAAAAAAAAAAAAAAAAg/9oACAEBAAY/Al//xAAZEAADAAMAAAAAAAAAAAAAAAAAAREhMUH/2gAIAQEAAT8huHaWI0OvkFlQZTR//9oADAMBAAIAAwAAABBjD//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQMBAT8QP//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQIBAT8QP//EABsQAQADAQADAAAAAAAAAAAAAAEAESFRMUGR/9oACAEBAAE/EKggK5xhlGlfUSHXerLKatrISgfQngqU8n//2Q==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;Zines by Julia Evans&quot;
        title=&quot;&quot;
        src=&quot;/static/571f564db0d3a6141667a1e5d2cde823/e5166/sockets-zines.jpg&quot;
        srcset=&quot;/static/571f564db0d3a6141667a1e5d2cde823/f93b5/sockets-zines.jpg 300w,
/static/571f564db0d3a6141667a1e5d2cde823/b4294/sockets-zines.jpg 600w,
/static/571f564db0d3a6141667a1e5d2cde823/e5166/sockets-zines.jpg 1200w,
/static/571f564db0d3a6141667a1e5d2cde823/a5c12/sockets-zines.jpg 1481w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;em&gt;Zines by Julia Evans&lt;/em&gt;&lt;/p&gt;
&lt;h2 id=&quot;establish-a-tcp-connection-in-nodejs-with-sockets&quot;&gt;Establish a TCP connection in NodeJs with sockets&lt;/h2&gt;
&lt;p&gt;To establish a TCP connection we need the IP Address and the port number of the two communicating devices. As an example, if I want to establish a TCP connection with google&apos;s server then I&apos;ll need&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Google Server&apos;s IP Address&lt;/li&gt;
&lt;li&gt;Google Server&apos;s Port Number&lt;/li&gt;
&lt;li&gt;My IP Address (The OS takes care of this)&lt;/li&gt;
&lt;li&gt;My Port Number (The OS takes care of this one too)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There&apos;s a webserver running on adityathebe.com on port 80. Let&apos;s try to establish a TCP connection with that server.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; net &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;net&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; port &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;80&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; host &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;adityathebe.com&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Create a new socket&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; socket &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;net&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Socket&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Establish a TCP connection&lt;/span&gt;
socket&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;connect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;port&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; host&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

socket&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;connect&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;Established a TCP connection with &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;host&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;port&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  socket&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;destroy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If you run the code above, you&apos;ll establish a TCP connection and then also kill it right away. TCP connections remain active for as long as days or even months or, theoretically, forever as long as there&apos;s no network connection issues. That&apos;s why it&apos;s important to kill the connection after there&apos;s no need for it.&lt;/p&gt;
&lt;h2 id=&quot;send-an-http-request-over-the-socket&quot;&gt;Send an HTTP request over the socket&lt;/h2&gt;
&lt;p&gt;Now let&apos;s try to send some data over the TCP connection. The data could be anything from a simple text to a large media file. In our case, the data will be an &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/HTTP/Messages&quot;&gt;HTTP messages&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;HTTP is a really simple protocol - it&apos;s literally just plain texts! You can even craft http requests &amp;#x26; responses by hand. There are standards &amp;#x26; structures to HTTP messages.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 746px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/15bf76fbfd6076e19f01cda986b31ca7/62de4/http-structure.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 38.99999999999999%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAIAAAB2/0i6AAAACXBIWXMAAA7EAAAOxAGVKw4bAAAA3UlEQVR42k2QBw6DMBAE8/8/Qug1NIcOhkzOBrESqwXdXOE1jmNd103TdF3Xti1BKdWIzCt+f1nX9Xzote/7MAzfh/q+vwMYTQm4Eo2iaZr+MA91YRgWRRHHsed5uO/7eZ6TkySBpJoa472IeRZmMQDqyrJkwucSvLkIhppaRKiqCt7CLAMJD7wsyyQyuyGGGEfzPHPmtm24hemdZRn9cLqwPzPJd0BpmuJMhmes1trCYN6lIAhc13Uc5y3iCy34I1EUAeMmM8/CbMXCtKDx7dwGxkXHcehLu8iE8zx/Hd/DLdPh1cUAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;HTTP Structure&quot;
        title=&quot;&quot;
        src=&quot;/static/15bf76fbfd6076e19f01cda986b31ca7/62de4/http-structure.png&quot;
        srcset=&quot;/static/15bf76fbfd6076e19f01cda986b31ca7/5a46d/http-structure.png 300w,
/static/15bf76fbfd6076e19f01cda986b31ca7/0a47e/http-structure.png 600w,
/static/15bf76fbfd6076e19f01cda986b31ca7/62de4/http-structure.png 746w&quot;
        sizes=&quot;(max-width: 746px) 100vw, 746px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;em&gt;HTTP Structure&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;As a fun demo, let&apos;s try to make an http request to &lt;em&gt;example.com&lt;/em&gt;. We can send a very bare minimal http request like this that only consists of http header.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;GET / HTTP/1.1
Host: example.com
   
   &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Notice the two blank lines at the end? That&apos;s important. The blank line separates http header from the http body. If you leave out the blank line, then example.com&apos;s server will respond with an error because the http request is invalid. Give it a try... It&apos;s also important to note that the blank line is actually a &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Glossary/CRLF&quot;&gt;CRLF&lt;/a&gt; &lt;code class=&quot;language-text&quot;&gt;\r\n&lt;/code&gt; and not the Line Feed &lt;code class=&quot;language-text&quot;&gt;\n&lt;/code&gt; character. Although servers these days accept the LineFeed &lt;code class=&quot;language-text&quot;&gt;\n&lt;/code&gt; character.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; net &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;net&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; port &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;80&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; host &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;example.com&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Instead of \n as a line break we use \r\n&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// Because that&apos;s how it&apos;s defined in the http specification&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// https://stackoverflow.com/a/5757349/6199444&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; rawHttpRequest &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;GET / HTTP/1.1\r\nHost: example.com\r\n\r\n&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; socket &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;net&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Socket&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
socket&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;connect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;port&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; host&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

socket&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;connect&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;Connected to &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;host&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;port&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;Local port &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;socket&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;localPort&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  socket&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;rawHttpRequest&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

socket&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;data&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token parameter&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// data is an array buffer. We need to transform it to string&lt;/span&gt;
  console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// Close the connection&lt;/span&gt;
  socket&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;destroy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;http-response-from-examplecom&quot;&gt;HTTP Response from example.com&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;HTTP/1.1 200 OK
Age: 267333
Cache-Control: max-age=604800
Content-Type: text/html; charset=UTF-8
Date: Sun, 22 Mar 2020 17:23:08 GMT
Etag: &quot;3147526947+ident&quot;
Expires: Sun, 29 Mar 2020 17:23:08 GMT
Last-Modified: Thu, 17 Oct 2019 07:18:26 GMT
Server: ECS (nyb/1D2A)
Vary: Accept-Encoding
X-Cache: HIT
Content-Length: 1256

&amp;lt;!doctype html&gt;
&amp;lt;html&gt;
&amp;lt;head&gt;
  ...
&amp;lt;body&gt;
&amp;lt;div&gt;
  &amp;lt;h1&gt;Example Domain&amp;lt;/h1&gt;
  ...
&amp;lt;/div&gt;
&amp;lt;/body&gt;
&amp;lt;/html&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I hope this was fun and helpful. Under the hood, the libraries like axios, request, express, etc are doing all of these and much more ...&lt;/p&gt;</content:encoded></item><item><title><![CDATA[A handy way to know your public IP Address with DNS servers]]></title><description><![CDATA[You can use DNS servers to know your public address]]></description><link>https://www.adityathebe.com/query-public-ip-with-DNS-servers/</link><guid isPermaLink="false">https://www.adityathebe.com/query-public-ip-with-DNS-servers/</guid><pubDate>Mon, 10 Feb 2020 08:45:00 GMT</pubDate><content:encoded>&lt;p&gt;There are plenty websites that show you your public IP address when you visit them. The simplest way would be to just ask google. These sites get the job done but when you want to constantly monitor your public ip it becomes tedious to keep visiting them. You need to have a browser running and the website itself takes 3-4 seconds to load.&lt;/p&gt;
&lt;p&gt;There are some handy api services like ipify API. If you visit &lt;a href=&quot;https://api.ipify.org/&quot;&gt;https://api.ipify.org/&lt;/a&gt; you&apos;ll get a plain text http response. This method is slightly faster than asking google due to the smaller response size. It&apos;s also handy as you can use it in creating scripts.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 480px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/73258d3b00530814fbb5f2813e9e0f27/7cc5e/ipify.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 34.333333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAHABQDASIAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAAAAEF/8QAFAEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEAMQAAAB3KFB/8QAFhABAQEAAAAAAAAAAAAAAAAAABES/9oACAEBAAEFAsoj/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPwE//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPwE//8QAFBABAAAAAAAAAAAAAAAAAAAAEP/aAAgBAQAGPwJ//8QAFxAAAwEAAAAAAAAAAAAAAAAAAAERYf/aAAgBAQABPyFJhJB//9oADAMBAAIAAwAAABDwD//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQMBAT8QP//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQIBAT8QP//EABsQAAICAwEAAAAAAAAAAAAAAAERADEhUYGR/9oACAEBAAE/EBMrxEUgNKAVo8n/2Q==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;ipify&quot;
        title=&quot;&quot;
        src=&quot;/static/73258d3b00530814fbb5f2813e9e0f27/7cc5e/ipify.jpg&quot;
        srcset=&quot;/static/73258d3b00530814fbb5f2813e9e0f27/f93b5/ipify.jpg 300w,
/static/73258d3b00530814fbb5f2813e9e0f27/7cc5e/ipify.jpg 480w&quot;
        sizes=&quot;(max-width: 480px) 100vw, 480px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;
&lt;em&gt;Ipify Api Service&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;But there&apos;s a faster method. Much much faster! It&apos;s crazy how fast it is! It takes no more than a 100-200 milliseconds. This method involves quering a DNS server rather than an HTTP server.&lt;/p&gt;
&lt;p&gt;I use the &lt;code class=&quot;language-text&quot;&gt;dig&lt;/code&gt; command to make DNS queries. &lt;strong&gt;Dig&lt;/strong&gt; is a DNS lookup utility that comes preinstalled in most linux distros.&lt;/p&gt;
&lt;p&gt;You can use dig to find the ip address of a website like this.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# This will spill out a bunch of metadata&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;dig&lt;/span&gt; adityathebe.com

&lt;span class=&quot;token comment&quot;&gt;# This will simply return the ip address&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;dig&lt;/span&gt; +short adityathebe.com&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;But we&apos;re here to find the ip address of our router and not some website&apos;s. In order to get the ip address of our router, we need to query a special url &lt;strong&gt;myip.opendns.com&lt;/strong&gt; to the DNS resolver &lt;strong&gt;resolver1.opendns.com&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;This DNS resolver is programmed to return the requesters ip address when a request is made to that special url. If you simply query myip.opendns.com with any other DNS resolvers then you&apos;ll get NXDOMAIN response; which basically means that the domain does not exist.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# To know you public ipv4 address&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;dig&lt;/span&gt; +short myip.opendns.com @resolver1.opendns.com &lt;span class=&quot;token parameter variable&quot;&gt;-4&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# To know you public ipv6 address&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;dig&lt;/span&gt; +short AAAA myip.opendns.com @resolver1.opendns.com&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Besides OpenDNS, Google and Akamai also provide a similar feature&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;dig&lt;/span&gt; @ns1-1.akamaitech.net ANY whoami.akamai.net +short

&lt;span class=&quot;token function&quot;&gt;dig&lt;/span&gt; @ns1.google.com TXT o-o.myaddr.l.google.com +short&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;em&gt;Akamai&apos;s service was a bit slow for me.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id=&quot;alias&quot;&gt;Alias&lt;/h2&gt;
&lt;p&gt;I have added an alias to my &lt;em&gt;zshrc&lt;/em&gt; file so that I can query my public ip address from the terminal by simply typing &lt;code class=&quot;language-text&quot;&gt;publicip&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;alias&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;publicip&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;dig +short myip.opendns.com @resolver1.opendns.com -4&apos;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;polybar&quot;&gt;Polybar&lt;/h2&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;txt&quot;&gt;&lt;pre class=&quot;language-txt&quot;&gt;&lt;code class=&quot;language-txt&quot;&gt;# Polybar module

[module/publicip]
type = custom/script
exec = dig @resolver1.opendns.com A myip.opendns.com +short -4
interval = 100
label =  %output%&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;hr&gt;
&lt;h2 id=&quot;reference&quot;&gt;Reference&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://unix.stackexchange.com/questions/22615/how-can-i-get-my-external-ip-address-in-a-shell-script/81699#81699&quot;&gt;https://unix.stackexchange.com/questions/22615/how-can-i-get-my-external-ip-address-in-a-shell-script/81699#81699&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://unix.stackexchange.com/questions/335371/how-does-dig-find-my-wan-ip-adress-what-is-myip-opendns-com-doing&quot;&gt;https://unix.stackexchange.com/questions/335371/how-does-dig-find-my-wan-ip-adress-what-is-myip-opendns-com-doing&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[What does it mean to own bitcoins]]></title><description><![CDATA[There are no accounts in bitcoin. A user's bitcoin is not stored in an account but rather scattered in the blockchain as UTXO.]]></description><link>https://www.adityathebe.com/what-does-it-mean-to-own-bitcoins/</link><guid isPermaLink="false">https://www.adityathebe.com/what-does-it-mean-to-own-bitcoins/</guid><pubDate>Sun, 02 Feb 2020 00:05:00 GMT</pubDate><content:encoded>&lt;p&gt;What does it mean to &quot;have&quot; bitcoins? Where exactly are they stored? Where can one sign up for a bitcoin account? These were some of the questions that I had when I first started to study Bitcoin.&lt;/p&gt;
&lt;p&gt;The notion of owning bitcoins can be difficult to grasp to anyone who has dealt with cash all their lives. There&apos;s nothing physical to hold and everything is digital.&lt;/p&gt;
&lt;p&gt;When Bob says he has $5 we can understand that he either has a $5 bill or $5 in his bank account. But what does it mean when Alice says she owns 5 BTC? Well, that&apos;s what we are going to find out ...&lt;/p&gt;
&lt;p&gt;Bitcoin can mean both the currency and the protocol that governs the currency. The Bitcoin protocol differs fundamentally from our traditional financial system. And so to understand it, it&apos;s important to learn the fundamental concepts and the underlying building blocks.&lt;/p&gt;
&lt;h2 id=&quot;blockchain&quot;&gt;Blockchain&lt;/h2&gt;
&lt;p&gt;The blockchain is a double-entry bookkeeping ledger. The name is derived from the fact that it is literally a linear chain of blocks. A block consists of numerous transactions. Every single bitcoin transaction that has ever happened has an entry in one of the blocks in the blockchain.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1200px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/34398826990377354a7f58d21297aca6/fb8e0/structure-of-a-blockchain.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 55.99999999999999%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAALABQDASIAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAAAAECBf/EABQBAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhADEAAAAe5dCKP/xAAUEAEAAAAAAAAAAAAAAAAAAAAg/9oACAEBAAEFAl//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/AT//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/AT//xAAUEAEAAAAAAAAAAAAAAAAAAAAg/9oACAEBAAY/Al//xAAYEAADAQEAAAAAAAAAAAAAAAAAESEBEP/aAAgBAQABPyG0rMaFguf/2gAMAwEAAgADAAAAEITP/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPxA//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPxA//8QAGxABAAIDAQEAAAAAAAAAAAAAAQARITFBUYH/2gAIAQEAAT8QXrL6cmJSfZswZ3KeEACgqf/Z&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;Structure-of-a-blockchain&quot;
        title=&quot;&quot;
        src=&quot;/static/34398826990377354a7f58d21297aca6/e5166/structure-of-a-blockchain.jpg&quot;
        srcset=&quot;/static/34398826990377354a7f58d21297aca6/f93b5/structure-of-a-blockchain.jpg 300w,
/static/34398826990377354a7f58d21297aca6/b4294/structure-of-a-blockchain.jpg 600w,
/static/34398826990377354a7f58d21297aca6/e5166/structure-of-a-blockchain.jpg 1200w,
/static/34398826990377354a7f58d21297aca6/d9c39/structure-of-a-blockchain.jpg 1800w,
/static/34398826990377354a7f58d21297aca6/fb8e0/structure-of-a-blockchain.jpg 1939w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;
&lt;em&gt;Structure of a blockchain. Source: &lt;a href=&quot;https://blockspoint.com&quot;&gt;https://blockspoint.com&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The blockchain is public, and anyone can download it and look through the transactions that&apos;s not just theirs but anyone else&apos;s. If I have your bitcoin address then I can see all the transactions going in and out from your address. Despite the popular belief that Bitcoin is untraceable, it is actually the opposite. In fact, one would need to take extreme measures to stay anonymous in the Bitcoin network.&lt;/p&gt;
&lt;p&gt;The important thing to understand, for now, is just that the blockchain is a database of transactions.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Every single bitcoin transaction that has ever happened has an entry in one of the blocks in the blockchain.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;transactions&quot;&gt;Transactions&lt;/h2&gt;
&lt;p&gt;A bitcoin transaction is just an entry in the blockchain that indicates transfer of bitcoins. Transaction of bitcoins is quite different from a banking transaction. In a banking system, you have an account where you store all your money. To make a transaction you&apos;d transfer money from your account to the receiver&apos;s account. In Bitcoin, there&apos;s no such thing as an Account.&lt;/p&gt;
&lt;p&gt;Recall, the blockchain is just a list of transactions. There is no such entry in the blockchain that states that Bob&apos;s account has 5 BTC or even that there&apos;s an account that belongs to Bob. To put it precisely, there&apos;s no concept of balance in Bitcoin.&lt;/p&gt;
&lt;p&gt;So how and where does one store bitcoins? To answer that we need to understand &lt;em&gt;transactions&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;A transaction comprises of a bunch of metadata which are shown below.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1194px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/b6b45fd58bb5889f1e3a376cad19e6e4/187fa/structure-of-a-transaction.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 41.66666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAAA7DAAAOwwHHb6hkAAABkElEQVR42mWS207CQBCGeTYPaBFvNL6ARgLqtcbHURNBKKLyBCjPwKWGdrs9G0oJh5TyOzNEvHDSyc5sZ7/5d9rCYDDAZbWGQ6MEo7iH4tYWqucVVE7PUNzegbFbxFXtArfXN6hVKjjY30fZMGg1UCY/LJVQonMnR8eIwhCF0WgEs9lC9/UN/Y++ePeti3bLxHuvR/6OznNH8rZpovXUROOxAZPyp3qD4joe7u7x0nnBYrFAAWSTyQTjZIzxOEWaTiTnRinlWbZEkiR/Tvvr9xwnwIqe1Qq/VsjzHJ7rQdm2FM7ncwRBAO1oybMsk9x1NWyqUcqBqzUsy6I9D3m+EiBzBMhs3/cJ6pK6FNPpFFEUUbErwNlsJjnXhEEIrV2JuaGj9Aa0Ucj0OI6pUMtBvgavrDggADcJwwiBTyoJppSi2JeGtmXLSP4BHbqG7/mbzZiA9tCS67KJYoLxaDyP1TkiwBoO5QZsv3OUj+JQAatk+exx/I2vzy9RxxbS76BsJYrWc1RrIM2RlfOZ5XIp0B/sEDPh2mivegAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;Structure of a bitcoin transaction&quot;
        title=&quot;&quot;
        src=&quot;/static/b6b45fd58bb5889f1e3a376cad19e6e4/187fa/structure-of-a-transaction.png&quot;
        srcset=&quot;/static/b6b45fd58bb5889f1e3a376cad19e6e4/5a46d/structure-of-a-transaction.png 300w,
/static/b6b45fd58bb5889f1e3a376cad19e6e4/0a47e/structure-of-a-transaction.png 600w,
/static/b6b45fd58bb5889f1e3a376cad19e6e4/187fa/structure-of-a-transaction.png 1194w&quot;
        sizes=&quot;(max-width: 1194px) 100vw, 1194px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;
&lt;em&gt;Structure of a bitcoin transaction. Source: Mastering Bitcoin by Andreas Antonopolous&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The fields that are of interest to us are &lt;code class=&quot;language-text&quot;&gt;inputs&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;outputs&lt;/code&gt;. The input to a transaction is the source of funds, and the output is the destination. If there are no accounts in Bitcoin, then what is the source of funds and where is the destination?&lt;/p&gt;
&lt;h3 id=&quot;transaction-outputs&quot;&gt;Transaction Outputs&lt;/h3&gt;
&lt;p&gt;The output of a transaction is called &lt;strong&gt;UTXO&lt;/strong&gt; (&lt;em&gt;Unspent Transaction Outputs&lt;/em&gt;). A UTXO consists of a locking script &amp;#x26; the amount that is to be transferred. The locking script locks the transaction amount. For someone to use the transaction amount, an &lt;code class=&quot;language-text&quot;&gt;unlocking script&lt;/code&gt; is required.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1175px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/947075684e36ce67a3a9c1228b18f311/0d40b/utxo-structure.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 27.333333333333332%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAIAAADKYVtkAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAA80lEQVR42jVP7UrDMBTdsykoWz+dKP4a/hky8AEUn22+RMOadjALaZombUm3/Jil1OxE9HIh59x7z7k3s77vSZIURbFH5DmSUpo7sE93uzxzNKO0UU3bts1vKKWgstbOPrfbZRTFQYh8Xq2eHh6DhbcMo5f1+nWzuY/vvNu5P18gQ8+P/QCtm6vrj7d3JzbmRNNUVBWMvw4HrAKQUv6dkGWEEEpTQhJUeq2xU2ttjHHicRxxkpKy6zo04CLq+ng8ocLLshaiBq8FHPFg+Oc/nHgYhpKx8/kbBJ4V5/jVNE2Y5pyDSqkAnIEQlatUjDEst9ZeABQa8N6py7hwAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;Structure of a Bitcoin UTXO&quot;
        title=&quot;&quot;
        src=&quot;/static/947075684e36ce67a3a9c1228b18f311/0d40b/utxo-structure.png&quot;
        srcset=&quot;/static/947075684e36ce67a3a9c1228b18f311/5a46d/utxo-structure.png 300w,
/static/947075684e36ce67a3a9c1228b18f311/0a47e/utxo-structure.png 600w,
/static/947075684e36ce67a3a9c1228b18f311/0d40b/utxo-structure.png 1175w&quot;
        sizes=&quot;(max-width: 1175px) 100vw, 1175px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;
&lt;em&gt;Structure of a Bitcoin UTXO. Source: Mastering Bitcoin by Andreas Antonopolous&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Think of UTXO as a safe-deposit box that locks some amount of bitcoin. Anyone that has the key to that safe can spend that bitcoin.&lt;/p&gt;
&lt;p&gt;So to make a transaction, Bob asks Alice for her bitcoin address. He then creates a UTXO with an amount of 5 BTC and a locking script using Alice&apos;s bitcoin address such that only Alice can create an unlocking script using her private key.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Sending someone bitcoin is basically creating an unspent transaction output (UTXO) that is cryptographically locked and can only be accessed by the receiver&apos;s private key.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;transaction-inputs&quot;&gt;Transaction Inputs&lt;/h3&gt;
&lt;p&gt;The input to a transaction is actually a pointer to another transaction that&apos;s in the blockchain. Precisely, the input is a pointer to a UTXO.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1169px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/4e56496abcd10d6f233ae4f094214dab/5a3c9/structure-of-a-transaction-input.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 31%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAIAAABM9SnKAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABLUlEQVR42h2O207CQBCG+5SamIiUWtN4QYySGOIL4KsQWjABLxC0cIfPQGp32263B6Bsm2Bbm/rTf2cnc/hmd6T1an2vaUpblls3L/3+Q7ertNvydav3+PQ6GDz3eoosq4qids52K3dAaurd1cXlcrGUKKXGSF+Z5vdm8zGfv00mY103v8zP5WI2nb7PZhPDGOsG/Gg4RBfwmTGMgHMpz/Moiqqqquv6sN/7jAmRIk5TwX0eR/EOJ4rDMEQAUghxTJKiKMCchykhruui7TN/u91SSsIgAGdZFrFteABOI0LIbyMM4z/pdDrZto0cL0VhCBoEilmWOZTajRjz4D3Pw14o/kCWhREJF+sVeVH9Vbs4ZkBcL0mOqUhdx2GMcc59nzOPYRKG5ZEHQVCW5T8UTCLectaDfAAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;Structure of a transaction input&quot;
        title=&quot;&quot;
        src=&quot;/static/4e56496abcd10d6f233ae4f094214dab/5a3c9/structure-of-a-transaction-input.png&quot;
        srcset=&quot;/static/4e56496abcd10d6f233ae4f094214dab/5a46d/structure-of-a-transaction-input.png 300w,
/static/4e56496abcd10d6f233ae4f094214dab/0a47e/structure-of-a-transaction-input.png 600w,
/static/4e56496abcd10d6f233ae4f094214dab/5a3c9/structure-of-a-transaction-input.png 1169w&quot;
        sizes=&quot;(max-width: 1169px) 100vw, 1169px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;
&lt;em&gt;Structure of a transaction input&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;So essentially, when Bob wants to make the 5 BTC transaction, he needs to provide the following input.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A &lt;code class=&quot;language-text&quot;&gt;transaction hash&lt;/code&gt; which is a unique id that identifies the transaction.&lt;/li&gt;
&lt;li&gt;An &lt;code class=&quot;language-text&quot;&gt;output index&lt;/code&gt; that points to a UTXO (&lt;em&gt;fund source&lt;/em&gt;) in that transaction referenced by the transaction hash (&lt;em&gt;there can be more than one UTXO in a single transaction&lt;/em&gt;).&lt;/li&gt;
&lt;li&gt;An &lt;code class=&quot;language-text&quot;&gt;unlocking script&lt;/code&gt; indicating authority over the UTXO.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This transaction will be placed on the blockchain as a new transaction with a unique transaction hash. In future, Alice can refer to this transaction and the UTXO to use the fund locked in the UTXO.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1200px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/8d4781df42f866079eeec5317969b7f8/d2c28/utxo-transaction-model.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 60.66666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAAAsTAAALEwEAmpwYAAAC30lEQVR42mOwr2dg0apnYAPh0FAGZgZ84P9/pu7EiVp7jH2Mduv52Gx0StYrzltr6jb9pb5X/30Dj4nPRBncKthVnCrZtOzKWXUdS9nUYXqPMchwXmcQ5j0CxP8ZIBZp1WfxZOZnav5n4BG5xquodswiVCilYreay/RXqi6dD6U86m/xMZhXMohb1bCpW9ewatuXMEgA9THWMzAwnWOQ0LrAIG1+nkHG7AqfjBDIQNdiQR2H7rnmjjP/K/t3XLeyn/1dxX3+dwWo6xnB9DQ3VuPtGlxG27Q5TefbsxqEFjJw/mfQYrvFKSRznVVQ9za7qMoHBn5Bx2IOeZdsBimnBf+lzRf+0DRd/l/NbvYPTfspL0GOYAhdtYo5NPQ/M8OEIGnVDwyqSu/Z1RXmessp2VYzKHZ6s6meFNWS2C+so3GNwViyx5nfMDCHQR+ksS15igoo7LZZxhqu8szWLa7cpuUy9Y2md+89/cDuO2IMFpNn6vr3ftb1nPxT13zqck39FhnpOYYM8oWFq6TDm48o+03+L5WSoOQUmM6gb9CkqVqTlqb7n4FD/g6nsMllZRPZkpJteq79Twx8e+9beE/7IMjgVR9q4NLRoenR2qrl2RSlqzJRhR0YCWznJFREz0iqiVyTMhVeaywi6VzAoGRfH8/hOPOWcuDExzJJxft1DJf9l/KY+UHZrfeRkHvfNUmPibfYGaBJBRSgTDiSDSMkQhgU7YsYRNyn/1dwnP5O327mV1Onqe/03HqeyKJECg7A+B8JgwQsgJFlBUxWRUXrZbuSp+pNjurVbU2erZdStl/GefJHYa+u+xIeE9/wMRAJwIYaN2srV6T5mQMtEf/JwKr7X0xMvL5ki4HT5KdGHsAw9Ol5KsJACrDPCuXx6GrVq8/aL9EaMUEvEZgz/PrvqXtOvqvmMfWxHjAM+UgykKG+nsl7wiMd98mvjFynv7V2B7rMZcIdVUg6BKZBhv+MAAEP9N/xvOK9AAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;Bitcoin UTXO transaction model&quot;
        title=&quot;&quot;
        src=&quot;/static/8d4781df42f866079eeec5317969b7f8/c1b63/utxo-transaction-model.png&quot;
        srcset=&quot;/static/8d4781df42f866079eeec5317969b7f8/5a46d/utxo-transaction-model.png 300w,
/static/8d4781df42f866079eeec5317969b7f8/0a47e/utxo-transaction-model.png 600w,
/static/8d4781df42f866079eeec5317969b7f8/c1b63/utxo-transaction-model.png 1200w,
/static/8d4781df42f866079eeec5317969b7f8/d61c2/utxo-transaction-model.png 1800w,
/static/8d4781df42f866079eeec5317969b7f8/97a96/utxo-transaction-model.png 2400w,
/static/8d4781df42f866079eeec5317969b7f8/d2c28/utxo-transaction-model.png 4000w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;
&lt;em&gt;Bitcoin UTXO transaction model. Source: &lt;a href=&quot;https://medium.com/coinmonks&quot;&gt;https://medium.com/coinmonks&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;h3 id=&quot;calculating-bitcoin-balance&quot;&gt;Calculating Bitcoin Balance&lt;/h3&gt;
&lt;p&gt;You might have seen some bitcoin wallet applications that show the balance of a bitcoin address.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 828px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/77f3e7c88682ab8ece60475659583497/8efc2/bitcoin-wallet.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 113.33333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAXCAIAAACEf/j0AAAACXBIWXMAAAsTAAALEwEAmpwYAAACPklEQVR42qVSTW8SYRDe/9pbf4DVg+3B9uLJ9ODJxsbECEZ66aGJGmxtxGjbUEoLkS9ZWAiF3WVl3++vdXZXxFjApk6eTIY38zAzzz6WMUbrGHExxS3DokxQYSjXjEk+BaEc3tO8BDGZhD7Doc/pNUdDhj2GYREhtVRaKZ3Uaj6ZOMf4ZIufbdeq5f23+bNSud62z0uXnW7/5LRYa7Sq3xqDa5cLdXMRC1df48IjcbR+8Tm/s5vJZnOvMrlnOy8OP37KHx7n9vaf7778elrUJppDJm4bl7OkeoDC0A9CzwsQprCwgFGEMS6lMpAX3CwU1REz0QSR4cgfun6ISKoW49DBk4F8AZlymEAIJUzABAChAlO+HNADALWlSlQFSPVL4dsAiBZ83uhOAUSLc8U4t7vOcOSOXA+K8Ti42WqSPOF4QMYDGgijWGoSeNWJPyGrxBaLppk/akqnZOBwznUSqW/nkjXqKb+iglZkVHwzdNl25/6DjUz2zZPtp+sbm5tbjx2nF7fO/iIuoB8freLCw/BgRY0qVEYW+I5SelWpNpvfy5dX56WLYrEEL3H3X2QeoPyq6BXQuzXlfKEqsuDDws4j1xVyiewJWVL04R56vzbZW1FuLZ4MN8MExphKDp4KtuBm4ulxW4cDaJgJdoeYkWGaTEOpJYTEXNAiZ2QdmQmnvX6/bXfg+GjR0lHU6Tr1ZqtWb4CiINZ0sjEhQkHwYxKGZoluxoAdXM8DaWJ7/r4Zfv9z7ZQPdoZM2f8J9hM4vyZFosECKwAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;Mycelium Wallet homescreen&quot;
        title=&quot;&quot;
        src=&quot;/static/77f3e7c88682ab8ece60475659583497/8efc2/bitcoin-wallet.png&quot;
        srcset=&quot;/static/77f3e7c88682ab8ece60475659583497/5a46d/bitcoin-wallet.png 300w,
/static/77f3e7c88682ab8ece60475659583497/0a47e/bitcoin-wallet.png 600w,
/static/77f3e7c88682ab8ece60475659583497/8efc2/bitcoin-wallet.png 828w&quot;
        sizes=&quot;(max-width: 828px) 100vw, 828px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;
&lt;em&gt;wallet application&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;If there are no accounts then how is the bitcoin balance calculated? The concept of a user’s bitcoin balance is a derived construct created by the wallet application.&lt;/p&gt;
&lt;p&gt;The Bitcoin network actually keeps track of all the available unspent UTXO. A wallet application calculates the user’s balance by scanning the blockchain and aggregating all UTXO belonging to that user.&lt;/p&gt;
&lt;p&gt;A user&apos;s bitcoin balance is the sum of all unspent UTXO that can be unlocked by the user.&lt;/p&gt;
&lt;h3 id=&quot;how-are-bitcoins-generated&quot;&gt;How are Bitcoins generated?&lt;/h3&gt;
&lt;p&gt;Hold on... so Alice got her 5 BTC from Bob. Bob must have gotten them from someone else and that someone must have gotten from some other person. But where is the point of origination in this chain of ownership? How are bitcoins added into the blockchain? Who adds them?&lt;/p&gt;
&lt;p&gt;Bitcoins are generated by miners. They are the ones who introduce new bitcoins into the Bitcoin network.&lt;/p&gt;
&lt;p&gt;Did you not find it odd that the transactions are stored in blocks? Why is it not just a single block but rather a chain of blocks? The answer to that certainly deserves another article but just understand that when you make a transaction it does not get added into the blockchain immediately.&lt;/p&gt;
&lt;p&gt;When you press &quot;send&quot; in your wallet application you are basically announcing the network that you want to make a transaction. Your wallet application sends this transaction information to all the nodes they are connected to and then those nodes in turn send the transaction metadata to the nodes they are connected to. This way eventually the transaction metadata will reach every single node connected to the Bitcoin network. Some of the nodes are special nodes called &lt;strong&gt;Mining Nodes&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;The mining nodes receive lots of transaction information and they store them in their computer&apos;s memory. The task of a miner is to put the transactions in the blockchain in a new block. This process of placing a block into the blockchain is called &lt;strong&gt;Mining&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Mining bitcoins requires making a lot of autmoated calculations and only those miners with very powerful mining devices have a chance at successfully mining a block. Miners compete against each other to put a block into the blockchain and when one of them successfully mines a block, he/she gets some amount of BTC as a reward called a &lt;a href=&quot;https://www.investopedia.com/terms/b/block-reward.asp&quot;&gt;&lt;strong&gt;Block Reward&lt;/strong&gt;&lt;/a&gt;. Unlike a normal transaction, a block reward does not require an input. The money is generated out of thin air. This is the only way bitcoins are added into the blockchain.&lt;/p&gt;
&lt;p&gt;The block reward gets halved every 210,000 blocks or approximately every 4 years. When Bitcoin started in Jan 2009, the block reward was 50 BTC. On November 28, 2012 it dropped to 25 BTC per block and on July 9, 2016, it droped again to 12.5 BTC per block. It is estimated that on &lt;a href=&quot;https://www.bitcoinblockhalf.com/&quot;&gt;May 2020 the block reward will again get halved to 6.25 BTC per block.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The block reward will keep on decreasing exponentially. It is projected that in the year 2140, the last halvening will take place and there&apos;ll be no more block rewards. This essentially means that there is a limit to the production of bitcoins. It&apos;s &lt;em&gt;21 million&lt;/em&gt; and more than &lt;em&gt;18 million&lt;/em&gt; of them have already been mined.&lt;/p&gt;
&lt;h2 id=&quot;tldr&quot;&gt;Tldr&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;There are no bitcoin accounts.&lt;/li&gt;
&lt;li&gt;Bitcoins are locked in UTXO in the blockchain. In order to use the UTXO, a private key is required. Thus, a user&apos;s bitcoin may be scattered as UTXO amongst hundreds of transactions and hundreds of blocks.&lt;/li&gt;
&lt;li&gt;The UTXO consumed by a transaction are called transaction inputs, while the UTXO
created by a transaction are called transaction outputs&lt;/li&gt;
&lt;li&gt;Miners add the transactions in blocks into the blockchain. They get rewarded some amount of BTC for successfully adding a block into the blockchain. This is how new bitcoins are generated and it&apos;s the only way.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;Most of the things that I&apos;ve written in this blog post, I&apos;ve learned it from the book &lt;strong&gt;&quot;Mastering Bitcoin&quot; by Andreas Antonopolous&lt;/strong&gt;. It&apos;s &lt;a href=&quot;https://github.com/bitcoinbook/bitcoinbook&quot;&gt;open sourced&lt;/a&gt; !!&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[A beginner's guide to installing softwares in a Linux system]]></title><description><![CDATA[Learn several ways to install softwares in your linux system from using the package manager to managing the binaries.]]></description><link>https://www.adityathebe.com/how-to-install-softwares-in-linux/</link><guid isPermaLink="false">https://www.adityathebe.com/how-to-install-softwares-in-linux/</guid><pubDate>Mon, 27 Jan 2020 12:00:00 GMT</pubDate><content:encoded>&lt;p&gt;One of the main reasons I migrated to Linux from Windows was the ease of software management. I could install, update and remove &quot;&lt;em&gt;any&lt;/em&gt;&quot; software with just a few commands from the command line.&lt;/p&gt;
&lt;p&gt;Life was fun and easy until it wasn&apos;t when I had to install a software which wasn&apos;t in the distro&apos;s &lt;strong&gt;software repository&lt;/strong&gt;. A distro&apos;s software repository is basically a database of application installation packages and upgrade packages. If the software you want to install is not listed in the software repository then you&apos;ll have to look for other ways to install.&lt;/p&gt;
&lt;p&gt;In Windows, almost every software provides an installation wizard but that&apos;s rarely the case in Linux.&lt;/p&gt;
&lt;p&gt;So, what are some other ways to install a software when it&apos;s not available to install via the package manager? That&apos;s what you will be learning in this article.&lt;/p&gt;
&lt;h2 id=&quot;1-distros-package-manager&quot;&gt;1. Distro&apos;s Package Manager&lt;/h2&gt;
&lt;p&gt;This is my (and most peoples&apos;) preferred way of installing softwares because the distro&apos;s package manager makes it extremely easy, to not only just install, but also to update, remove and manage paths &amp;#x26; the launchers of a software.&lt;/p&gt;
&lt;p&gt;Ubuntu uses &lt;code class=&quot;language-text&quot;&gt;apt&lt;/code&gt; for package management and so does Debian and Linux Mint. Different distros have different package managers. Arch based distros use &lt;code class=&quot;language-text&quot;&gt;pacman&lt;/code&gt;, Red hat uses &lt;code class=&quot;language-text&quot;&gt;rpm&lt;/code&gt;, CentOS uses &lt;code class=&quot;language-text&quot;&gt;yum&lt;/code&gt; ...&lt;/p&gt;
&lt;p&gt;Every distro has its own set of software repositories. What may be available to install with &lt;code class=&quot;language-text&quot;&gt;apt&lt;/code&gt; in Ubuntu may not be available to install in Debian even though both distros use &lt;code class=&quot;language-text&quot;&gt;apt&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The package manager a distro provides can be a deciding factor in choosing a distro for many people. To give you an example: Debian is known for its solid stability and hence the softwares available in its official repositories may not be a latest release but a stable one. So Debian may not be a good choice for people who want the latest bleeding edge softwares.&lt;/p&gt;
&lt;p&gt;The package manager will not always be able to help you because well obviously the software repository cannot include every software in existence. Sometimes although the software is available, the required version isn&apos;t.&lt;/p&gt;
&lt;p&gt;Apart from the official software repositories, you can also add third-party software repositories. You may have noticed Google Chrome is not listed in any of the Ubuntu software repositories and so running &lt;code class=&quot;language-text&quot;&gt;sudo apt update google-chrome&lt;/code&gt; will not work. There are various other ways to install it and one of them is to add the Google Chrome&apos;s sofware repository. Once you add the repository, it&apos;s the same basic routine to install any software from that repository.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Read: &lt;a href=&quot;https://askubuntu.com/questions/510056/how-to-install-google-chrome&quot;&gt;How to install Google Chrome in Ubuntu&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If in case the software is not available through third-party repositories then you&apos;ll have to look for other options mentioned below.&lt;/p&gt;
&lt;h2 id=&quot;2-a-programming-languages-package-manager&quot;&gt;2. A programming language&apos;s package manager&lt;/h2&gt;
&lt;p&gt;Some softwares are available to install through a programming language&apos;s package manager. Python has &lt;code class=&quot;language-text&quot;&gt;pip&lt;/code&gt;, NodeJs has &lt;code class=&quot;language-text&quot;&gt;npm&lt;/code&gt; (or &lt;code class=&quot;language-text&quot;&gt;yarn&lt;/code&gt;), GoLang provides the convenient &lt;code class=&quot;language-text&quot;&gt;go get&lt;/code&gt; command and there are a lot others.&lt;/p&gt;
&lt;p&gt;Some of the softwares I install via a programming language&apos;s package managers are&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/localtunnel/localtunnel&quot;&gt;localtunnel&lt;/a&gt;, &lt;a href=&quot;https://github.com/tldr-pages/tldr&quot;&gt;tldr&lt;/a&gt;, &lt;a href=&quot;https://github.com/http-party/http-server&quot;&gt;http-server&lt;/a&gt;, &lt;a href=&quot;https://github.com/microsoft/TypeScript&quot;&gt;typescript&lt;/a&gt; (via NPM)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/cslarsen/wpm&quot;&gt;wpm&lt;/a&gt;, &lt;a href=&quot;https://github.com/aboul3la/Sublist3r&quot;&gt;sublist3r&lt;/a&gt;, &lt;a href=&quot;https://github.com/jakubroztocil/httpie&quot;&gt;httpie&lt;/a&gt; (via pip)&lt;/li&gt;
&lt;li&gt;amass (via go get)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It goes without saying that you need to have the programming language and the package manager installed. As far as I know, the package manager does come along when you install the programming language.&lt;/p&gt;
&lt;h2 id=&quot;3-compile-the-source-code&quot;&gt;3. Compile the source code&lt;/h2&gt;
&lt;p&gt;The above two methods are fairly straightforward. Now comes the time to get our hands dirty.&lt;/p&gt;
&lt;p&gt;Some softwares provide the source code, which could be in C, C++, Go, ... you name it, and you&apos;re supposed to compile them. Being provided with the source code enables a user to compile the the source code specifically tailored and optimized to his/her system.&lt;/p&gt;
&lt;p&gt;I have to say this is not an easy thing to do although I&apos;ve never done it myself.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;I am skipping this section for now&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;4-download-the-compiled-binary&quot;&gt;4. Download the compiled binary&lt;/h2&gt;
&lt;p&gt;Conveniently, you can also find the compiled binaries of a software. It may be provided by the official software developers or by some third party. The compiled binary is usually archived in a single &lt;a href=&quot;https://en.wikipedia.org/wiki/Tar_(computing)&quot;&gt;tar&lt;/a&gt; file. In some rare cases you may find a zip or a rar archive. All you need to do to install the software simply download the tar file, extract it and then run the binary file inside the extracted directory.&lt;/p&gt;
&lt;p&gt;As for an example: Jetbrains provide the &lt;a href=&quot;https://www.jetbrains.com/idea/download/#section=linux&quot;&gt;compiled binary for its IDEs&lt;/a&gt;. Check out the image below. Look! There&apos;s the tar file I told you about.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 841px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/aa598f3eaefa0d6f36ef57416cb7eecc/bad1b/intellij-download-tar.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 44.66666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAYAAAAywQxIAAAACXBIWXMAAA7DAAAOwwHHb6hkAAABWklEQVR42pWRy0rDQBSG+14iuFEruhEqiK/g46hP4NonEBcquChtTW1txVJUGkXSJmmT9DLJJJ8nEatRwXpgLpz55zu3AmLj8ZjAD/B9nyAImEwmeHLP/MEYz/NJkoRFrBDHMZ1Oh1arTaPRpNm8pdt9wKjXuRd/u32HYRhorTPoX+BCuoVhhI4ilJy+go8vi2b1A+i4Qwa2yyzUTELQSQojl5FSSnQOrutKAuE84PeghdTh2haO9UIUTkUVksSKWIc54XQ2w3EcbNthJvA58LcMu4OY8pOm/KgoPyiuuoqG+QF8/zIajaSXdentDbXaNZVqjUqlKgPzcu3JgPsnsHwAK0dyHsKS3PeOpbdahLHOhKenZ6ytb1Iq7VIsbrG9vcPq2gbnF5fZezrcOdCTSl99MB1Fz1a8StDhNF9K2jfL6tPrmZimrOdn+v0BkQzzR8mflgD/n+xX4BusHasaHg3/UAAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;intellij download tar&quot;
        title=&quot;&quot;
        src=&quot;/static/aa598f3eaefa0d6f36ef57416cb7eecc/bad1b/intellij-download-tar.png&quot;
        srcset=&quot;/static/aa598f3eaefa0d6f36ef57416cb7eecc/5a46d/intellij-download-tar.png 300w,
/static/aa598f3eaefa0d6f36ef57416cb7eecc/0a47e/intellij-download-tar.png 600w,
/static/aa598f3eaefa0d6f36ef57416cb7eecc/bad1b/intellij-download-tar.png 841w&quot;
        sizes=&quot;(max-width: 841px) 100vw, 841px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;There are handful of softwares that provide the compiled binaries in a tar file. Here are some to name a few:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.getpostman.com/downloads/&quot;&gt;Postman&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://desktop.telegram.org/&quot;&gt;Telegram&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.sublimetext.com/3&quot;&gt;Sublime Text&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://golang.org/dl/&quot;&gt;Golang&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Once you download the tar file you should extract it with the &lt;code class=&quot;language-text&quot;&gt;tar&lt;/code&gt; command.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Extract an archive into a target directory:&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# tar xf source.tar -C directory&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Extract Intellij Idea to /opt directory&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;sudo&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;tar&lt;/span&gt; xf ideaIC-2019.3.2.tar.gz &lt;span class=&quot;token parameter variable&quot;&gt;-C&lt;/span&gt; /opt&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If you look at the extracted directory you&apos;ll see a binary file. You may need to look a bit further if you do not find it in the main directory. Some softwares place the binary file in a &lt;code class=&quot;language-text&quot;&gt;/bin&lt;/code&gt; directory while some place them in the main directory itself. This directory structuring is unique to each software, but, more often than not, you&apos;ll find the binary file in the bin directory.&lt;/p&gt;
&lt;p&gt;Here&apos;s what the extracted directory of the Intellij tar file looks like&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token function&quot;&gt;ls&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-al&lt;/span&gt; idea-IC-193.6015.39&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;output&quot;&gt;&lt;pre class=&quot;language-output&quot;&gt;&lt;code class=&quot;language-output&quot;&gt;total 68K
drwxr-xr-x  8 root root 4.0K Jan 27 20:50 .
drwxr-xr-x  4 root root 4.0K Jan 27 20:50 ..
drwxr-xr-x  2 root root 4.0K Jan 27 20:50 bin (binary file in here ??)
drwxr-xr-x  7 root root 4.0K Jan 27 20:50 jbr
drwxr-xr-x  4 root root  12K Jan 27 20:50 lib
drwxr-xr-x  2 root root 4.0K Jan 27 20:50 license
drwxr-xr-x 44 root root 4.0K Jan 27 20:50 plugins
drwxr-xr-x  2 root root 4.0K Jan 27 20:50 redist
-rw-r--r--  1 root root   14 Jan 21 12:01 build.txt
-rw-r--r--  1 root root 1.9K Jan 21 12:01 Install-Linux-tar.txt
-rw-r--r--  1 root root  12K Jan 21 12:01 LICENSE.txt
-rw-r--r--  1 root root  128 Jan 21 12:01 NOTICE.txt
-rw-r--r--  1 root root  370 Jan 21 12:04 product-info.json&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You can run the software by simply running the binary file. To run, open the terminal in the extracted directory and simply write the name of the binary file prepending it with &lt;code class=&quot;language-text&quot;&gt;./&lt;/code&gt;. In case of Intellij, there&apos;s an &lt;code class=&quot;language-text&quot;&gt;idea.sh&lt;/code&gt; file inside the /bin directory.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# To Run Intellij&lt;/span&gt;
./idea.sh&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4 id=&quot;where-to-place-the-extracted-directory-&quot;&gt;Where to place the extracted directory ?&lt;/h4&gt;
&lt;p&gt;Practically you could place it anywhere you want; be it the /home directory or even the /Downloads directory itself but, it&apos;s a standard practice to place it in one of these two directories&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;/usr/local&lt;/li&gt;
&lt;li&gt;/opt&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;Did you notice that I extracted the IntelliJ tar file inside the &lt;code class=&quot;language-text&quot;&gt;/opt&lt;/code&gt; directory?&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;You might want to checkout these discussions in stackoverflow to get a better idea on where to place the software directory&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://askubuntu.com/questions/6897/where-to-install-programs&quot;&gt;Where to install programs?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://askubuntu.com/questions/1148/when-installing-user-applications-where-do-best-practices-suggest-they-be-loc&quot;&gt;When installing user applications, where do “best practices” suggest they be located?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;how-to-add-path-to-path-variable&quot;&gt;How to add path to PATH variable&lt;/h4&gt;
&lt;p&gt;Isn&apos;t it a bit tiresome to first open the terminal, then navigate to the software directory and only then being able to run the program? If you want to be able to run the program from anywhere in the terminal then you need to add the software&apos;s binary path to the Linux&apos;s PATH variable.&lt;/p&gt;
&lt;p&gt;To do so, first figure out where the binary file resides. In my Intellij example, it resides in the &lt;code class=&quot;language-text&quot;&gt;/opt/idea-IC-193.6015.39/bin&lt;/code&gt; directory.&lt;/p&gt;
&lt;p&gt;Now add this line to the &lt;code class=&quot;language-text&quot;&gt;~/.profile&lt;/code&gt; file.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# export PATH=$PATH:&amp;lt;new-path&gt;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Add Intellij binary to path&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;&lt;span class=&quot;token environment constant&quot;&gt;PATH&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token environment constant&quot;&gt;$PATH&lt;/span&gt;:/opt/idea-IC-193.6015.39/bin&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You won&apos;t be able to run the idea command just yet because the &lt;code class=&quot;language-text&quot;&gt;~/.profile&lt;/code&gt; is read only once when the computer first starts up. You can restart your system and everything will work fine. However, you could instead add line to &lt;code class=&quot;language-text&quot;&gt;~/.bash_profile&lt;/code&gt; file instead and the command will run immediately. The &lt;code class=&quot;language-text&quot;&gt;~/.bash_profile&lt;/code&gt; is run everytime you open your terminal. But, it&apos;s considered a good practice to export PATH variables in the .profile file.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;This post is just much as a guide to others as it is to me. I&apos;ll keep updating this post as I learn ...&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Configure ssh keys on Github]]></title><description><![CDATA[Set up ssh keys on your github account]]></description><link>https://www.adityathebe.com/configure-ssh-key-github/</link><guid isPermaLink="false">https://www.adityathebe.com/configure-ssh-key-github/</guid><pubDate>Fri, 24 Jan 2020 23:30:00 GMT</pubDate><content:encoded>&lt;p&gt;The reason I like to use ssh over https is because I hate to provide my username and password on every remote actions like &lt;code class=&quot;language-text&quot;&gt;git clone&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;git pull&lt;/code&gt;, or &lt;code class=&quot;language-text&quot;&gt;git push&lt;/code&gt;. Sure, I could use a credential manager but why would I do that when I can simply configure ssh keys ?&lt;/p&gt;
&lt;p&gt;On the contrary, &lt;a href=&quot;https://help.github.com/en/github/using-git/which-remote-url-should-i-use&quot;&gt;Github actually suggest using https over ssh&lt;/a&gt; mainly because it is the easiest to set up for novice users and https is almost never blocked by firewalls.&lt;/p&gt;
&lt;h2 id=&quot;1-generate-ssh-keys&quot;&gt;1. Generate ssh keys&lt;/h2&gt;
&lt;p&gt;First thing first - make sure you have a &lt;code class=&quot;language-text&quot;&gt;~/.ssh&lt;/code&gt; directory.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token function&quot;&gt;mkdir&lt;/span&gt; ~/.ssh&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is the file in which we&apos;ll store our keys and configuration for ssh.&lt;/p&gt;
&lt;p&gt;Create an ssh key pair with &lt;code class=&quot;language-text&quot;&gt;ssh-keygen&lt;/code&gt; command. It&apos;ll ask you for the key name - I&apos;d suggest using &lt;code class=&quot;language-text&quot;&gt;id_rsa_github&lt;/code&gt; just to stay consistent with this post.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;cd&lt;/span&gt; ~/.ssh &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; ssh-keygen &lt;span class=&quot;token parameter variable&quot;&gt;-t&lt;/span&gt; rsa &lt;span class=&quot;token parameter variable&quot;&gt;-b&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4096&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-C&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&amp;lt;your_email&gt;&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;output&quot;&gt;&lt;pre class=&quot;language-output&quot;&gt;&lt;code class=&quot;language-output&quot;&gt;Generating public/private rsa key pair.
Enter file in which to save the key (/home/gunners/.ssh/id_rsa): id_rsa_github
Enter passphrase (empty for no passphrase):
Enter same passphrase again:&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This command generates two files: &lt;code class=&quot;language-text&quot;&gt;id_rsa_github&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;id_rsa_github.pub&lt;/code&gt; in your &lt;code class=&quot;language-text&quot;&gt;~/.ssh&lt;/code&gt; directory. One is a public key which you should upload on Github and the other is a private key that you should keep on your local computer.&lt;/p&gt;
&lt;h2 id=&quot;2-upload-the-public-key-to-github&quot;&gt;2. Upload the public key to Github.&lt;/h2&gt;
&lt;p&gt;Go to &lt;a href=&quot;https://github.com/settings/keys&quot;&gt;https://github.com/settings/keys&lt;/a&gt; and click on &lt;strong&gt;New SSH Key&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Add a suitable title and copy all the content from the &lt;code class=&quot;language-text&quot;&gt;id_rsa_github.pub&lt;/code&gt; file to the key section. The pub file is just a simple plain text file. You can open it with any text editor like notepad, sublime text, gedit, etc...&lt;/p&gt;
&lt;h2 id=&quot;3-add-ssh-keys&quot;&gt;3. Add ssh-keys&lt;/h2&gt;
&lt;p&gt;If you try to perform some remote actions, like cloning a repo, you&apos;ll get an error like this.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; clone git@github.com:adityathebe/dotfiles.git&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;output&quot;&gt;&lt;pre class=&quot;language-output&quot;&gt;&lt;code class=&quot;language-output&quot;&gt;Cloning into &amp;#39;dotfiles&amp;#39;...
git@github.com: Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is because git does not know where to look for the ssh key (Remember the &lt;code class=&quot;language-text&quot;&gt;id_rsa_github&lt;/code&gt; key we generated in ~/.ssh directory?)&lt;/p&gt;
&lt;p&gt;So to let git know that you do indeed have an ssh key use these two commands&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;eval&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$(&lt;/span&gt;ssh-agent &lt;span class=&quot;token parameter variable&quot;&gt;-s&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;ssh-add ~/.ssh/id_rsa_github&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now you can perform any git remote actions.&lt;/p&gt;
&lt;p&gt;However, if you close the current terminal session and try to clone again, you&apos;ll get the same error.&lt;/p&gt;
&lt;p&gt;You could add the keys manually again with the ssh-add command but I&apos;ll show you a much elegant way.&lt;/p&gt;
&lt;h3 id=&quot;permanently-add-the-ssh-keys&quot;&gt;Permanently add the ssh-keys&lt;/h3&gt;
&lt;p&gt;Now make sure you have the ~/.ssh/config file. If it&apos;s not there you can simply create it&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token function&quot;&gt;touch&lt;/span&gt; ~/.ssh/config&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It&apos;s important the config file has it&apos;s permission set to 600.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token function&quot;&gt;chmod&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;600&lt;/span&gt; ~/.ssh/config&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This config file is read by the ssh command on every execution.&lt;/p&gt;
&lt;p&gt;Add the following lines to the ~/.ssh/config file.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Host github.com
  User git
  IdentityFile ~/.ssh/id_rsa_github&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And that&apos;s it !&lt;/p&gt;
&lt;h2 id=&quot;beware-&quot;&gt;Beware !!&lt;/h2&gt;
&lt;p&gt;You might still be prompted for your password. This happens if you initially cloned the repository with an https url. So make sure the remote origin url is an ssh url.&lt;/p&gt;
&lt;h4 id=&quot;1-check-your-existing-remotes-urls&quot;&gt;1. Check your existing remote&apos;s urls&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; remote &lt;span class=&quot;token parameter variable&quot;&gt;-v&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;output&quot;&gt;&lt;pre class=&quot;language-output&quot;&gt;&lt;code class=&quot;language-output&quot;&gt;origin  https://github.com/adityathebe/www.adityathebe.com.git (fetch)
origin  https://github.com/adityathebe/www.adityathebe.com.git (push)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4 id=&quot;2-change-your-remotes-url-from-https-to-ssh&quot;&gt;2. Change your remote&apos;s URL from HTTPS to SSH&lt;/h4&gt;
&lt;p&gt;Grab the ssh clone url from Github&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 607px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/e78cb4c033ce6a25594a1f2f8f84afba/ef9e5/github-clone-with-ssh.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 50%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAByUlEQVR42nWS24oUMRCG5829UW+9EEUEvRMRH2FFQRBFd2Z2nd11lRXRne3pQzLpTvqQU+e3kh4dGTDwUZV0pfJXdc2cG6G1hzEjQgDGMaAfbNpb5wEE8i2stfCjp+8j4goUrK2mM/d3H9dMqxUaPkfNjqHVGXR7lvaDXOLn1Qqr+Q8sPnzB8btzLN5fYvnxK76vbpBdcFzNr/Hrc4H8m4DTfkqIsaX03UT0CaVKNLJAxUpsNgzrmwKbrEp+mW3x9vITbh3dw503D3H39QPcfnUfWVNMCali2B1uRyk6rDccJRdQfY+8YmBCQMgGtZA4yS7waPkMT05f4OnpSzxePEeuqilhPQCHSAO02oEzUlRVYJwjzwt0XZ8u7ftIQqiFltQ45/cKDzEuYNAWglQVRQnGOJXPCI7tllS3iuIcxdHPcmStSXbqIQIOCSG+6NA0TVLXUgIpJURdJ2o6r8kqJVMF8aGwUz3Df1ZM6GmEotqIJcZYI/Hn3PoJ732Kn8bGkFxqRJw1rU2yyR8GqMFhUxvkxHprMBif1PdkM2FwzTUqGe+YfUIpFbqeLrcdpGoTbdelH2DjQFOfnJsG+1+01hTTJVqKHXeD/RtePP2jVual/gAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;github clone with ssh&quot;
        title=&quot;&quot;
        src=&quot;/static/e78cb4c033ce6a25594a1f2f8f84afba/ef9e5/github-clone-with-ssh.png&quot;
        srcset=&quot;/static/e78cb4c033ce6a25594a1f2f8f84afba/5a46d/github-clone-with-ssh.png 300w,
/static/e78cb4c033ce6a25594a1f2f8f84afba/0a47e/github-clone-with-ssh.png 600w,
/static/e78cb4c033ce6a25594a1f2f8f84afba/ef9e5/github-clone-with-ssh.png 607w&quot;
        sizes=&quot;(max-width: 607px) 100vw, 607px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; remote set-url origin git@github.com:adityathebe/www.adityathebe.com.git&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4 id=&quot;3-verify&quot;&gt;3. Verify&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; remote &lt;span class=&quot;token parameter variable&quot;&gt;-v&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;output&quot;&gt;&lt;pre class=&quot;language-output&quot;&gt;&lt;code class=&quot;language-output&quot;&gt;origin  git@github.com:adityathebe/www.adityathebe.com.git (fetch)
origin  git@github.com:adityathebe/www.adityathebe.com.git (push)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Be sure to clone with ssh from now on :)&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Setup mpd on your Linux system as a User service]]></title><description><![CDATA[Learn how to setup music player daemon (mpd) as a user service on Arch Linux]]></description><link>https://www.adityathebe.com/setup-mpd-in-linux-as-user-service/</link><guid isPermaLink="false">https://www.adityathebe.com/setup-mpd-in-linux-as-user-service/</guid><pubDate>Fri, 24 Jan 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;In this tutorial we&apos;ll go through the process of setting up mpd as a user service. This is just a bare minimum installation setup. If you want customizations then you can look up dotfiles on the internet - lots of people share it. Here&apos;s &lt;a href=&quot;https://www.github.com/adityathebe/dotfiles&quot;&gt;mine&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;First thing first - download the &lt;code class=&quot;language-text&quot;&gt;mpd&lt;/code&gt; package along with the mpd clients &lt;code class=&quot;language-text&quot;&gt;mpc&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;ncmpcpp&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# On Arch&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;sudo&lt;/span&gt; pacman &lt;span class=&quot;token parameter variable&quot;&gt;-S&lt;/span&gt; mpd ncmpcpp mpc

&lt;span class=&quot;token comment&quot;&gt;# On Ubuntu&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;sudo&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;apt&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; mpd ncmpcpp mpc&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;em&gt;You can choose other mpd clients instead of ncmpcpp of course.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id=&quot;setup-the-config-files&quot;&gt;Setup the config files&lt;/h2&gt;
&lt;p&gt;It&apos;s a good practice to keep all the mpd configs in the &lt;code class=&quot;language-text&quot;&gt;~/.config/mpd&lt;/code&gt; directory. If you don&apos;t have one create it.&lt;/p&gt;
&lt;p&gt;Just to get started, you can copy the example config file that mpd provides.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;cp&lt;/span&gt; /usr/share/doc/mpd/mpdconf.example ~/.config/mpd/mpd.conf&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In order to be able to run mpd, you&apos;ll need to set up at least these parameters in the mpd.conf file&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;music_directory       &lt;span class=&quot;token string&quot;&gt;&quot;~/Music&quot;&lt;/span&gt;
playlist_directory    &lt;span class=&quot;token string&quot;&gt;&quot;~/.config/mpd/playlists&quot;&lt;/span&gt;
db_file               &lt;span class=&quot;token string&quot;&gt;&quot;~/.config/mpd/database&quot;&lt;/span&gt;
log_file              &lt;span class=&quot;token string&quot;&gt;&quot;~/.config/mpd/database&quot;&lt;/span&gt;
pid_file              &lt;span class=&quot;token string&quot;&gt;&quot;~/.config/mpd/pid&quot;&lt;/span&gt;
state_file            &lt;span class=&quot;token string&quot;&gt;&quot;~/.config/mpd/state&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It&apos;s not necessary to create any of these files as mpd will itself create them. However, you&apos;ll need to create a new &quot;playlists&quot; directory to create new playlists.&lt;/p&gt;
&lt;h2 id=&quot;start-the-service-as-a-user&quot;&gt;Start the service as a user&lt;/h2&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;systemctl &lt;span class=&quot;token parameter variable&quot;&gt;--user&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;enable&lt;/span&gt; mpd
systemctl &lt;span class=&quot;token parameter variable&quot;&gt;--user&lt;/span&gt; start mpd&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Don&apos;t forget the &lt;code class=&quot;language-text&quot;&gt;--user&lt;/code&gt; flag !&lt;/p&gt;
&lt;h2 id=&quot;update-the-music-database&quot;&gt;Update the music database&lt;/h2&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;mpc update&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;For some reason this command alone does not work me. So I run an additional command&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;mpc &lt;span class=&quot;token function&quot;&gt;ls&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; mpc &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;That&apos;s it ! You should now be able to run ncmpcpp and see all your songs.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Twitter Bot Tutorial for Beginners In NodeJS]]></title><description><![CDATA[Learn to build a twitter bot with NodeJs and Javascript in under 50 lines of code.]]></description><link>https://www.adityathebe.com/twitter-bot-tutorial-nodejs/</link><guid isPermaLink="false">https://www.adityathebe.com/twitter-bot-tutorial-nodejs/</guid><pubDate>Wed, 07 Nov 2018 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Chat bots are growing in power with the increase in social media users and advancement in technology. They will be the app of the future and heck they probably already are. They can be useful in many aspects of the customer experience, including providing customer service, presenting product recommendations and engaging customers through targeted marketing campaigns. Although chat bots have still a long way to go in terms of AI, they&apos;re still powerful.&lt;/p&gt;
&lt;p&gt;We&apos;ll code our Twitter Bot in JavaScript - NodeJS. I have tried my best to be as detailed as possible and I hope you won&apos;t have any trouble following along.&lt;/p&gt;
&lt;h2 id=&quot;contents&quot;&gt;Contents&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;#1-creating-a-twitter-app&quot;&gt;Create A Twitter App&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#2-setup-and-install-nodejs&quot;&gt;Set up and Install NodeJs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#3-project-setup&quot;&gt;Project Setup&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#4-install-twit-module&quot;&gt;Install Twit Module&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#5-code&quot;&gt;Code&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#6-deploy-on-heroku&quot;&gt;Deploy on Heroku&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;1-creating-a-twitter-app&quot;&gt;1. CREATING A TWITTER APP&lt;/h3&gt;
&lt;p&gt;You can&apos;t create a bot without a twitter account. Sign up for a new account &lt;a href=&quot;https://twitter.com/signup?lang=en&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Great! Now we&apos;ll need something called &lt;code class=&quot;language-text&quot;&gt;API keys&lt;/code&gt;. API keys are the &apos;username and password&apos; for your bot. Your Bot will require them to make API calls, or in simple words, interact with the data on twitter&apos;s server. To get your API keys, you need to first create a Twitter app. Go to &lt;a href=&quot;https://apps.twitter.com&quot;&gt;apps.twitter.com&lt;/a&gt; to get them.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1200px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/66d6ec5544246db026ac90acf6b8c079/c367c/create_twitter_app_1.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 46%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAYAAAAywQxIAAAACXBIWXMAAAsTAAALEwEAmpwYAAAA40lEQVR42q2R0W7CMAxF8//fwhNs7AP4BDSmAUXAeGFUbdckbRM3uXMKXbMXKiEsHcX32rGiWMy3Kd6SFDM+J58XvK6/MV2fMU8uTDrKZHnCy2boFdK26DCE5PiFj2SP1XaHzfEETQ6Ka5r8Lb9qGRH8WAtE0RKhtRamrkHWwLsWdaUhy7KjUqqr3wtxr2iMQc3D8zxHlmWoOG+aBt77xwY+Es8fGJ4/hnMe5Mb7AiL8U4+NCLphPBm8nzUWBwlHV+/fnbDESAutNXoKqZCXzI+EVINfqlAb9J/Pmy+KAoq333u/Bea6IBpxMIQAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;Create new app on Twitter&quot;
        title=&quot;&quot;
        src=&quot;/static/66d6ec5544246db026ac90acf6b8c079/c1b63/create_twitter_app_1.png&quot;
        srcset=&quot;/static/66d6ec5544246db026ac90acf6b8c079/5a46d/create_twitter_app_1.png 300w,
/static/66d6ec5544246db026ac90acf6b8c079/0a47e/create_twitter_app_1.png 600w,
/static/66d6ec5544246db026ac90acf6b8c079/c1b63/create_twitter_app_1.png 1200w,
/static/66d6ec5544246db026ac90acf6b8c079/c367c/create_twitter_app_1.png 1349w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;em&gt;Create new app on Twitter&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Click on &lt;code class=&quot;language-text&quot;&gt;&quot;Create New app&quot;&lt;/code&gt; and fill up all the necessary details on the following page. If you don&apos;t have a website just put a placeholder in the &lt;code class=&quot;language-text&quot;&gt;&quot;Website field&quot;&lt;/code&gt;. You can leave out the Callback URL field. Tick the Developer Agreement and then finally click on &apos;Create Your Twitter application&apos; at the bottom. We now have a Twitter application. Let&apos;s get the API keys.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1200px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/70e004f11e07b9fc57f36030cd0aba3e/c367c/create_twitter_app_2.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 46%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAYAAAAywQxIAAAACXBIWXMAAAsTAAALEwEAmpwYAAAA5klEQVR42o2SiY6DMAxE+/+/CRLlSshNuNyMabocu+pGGhFH5HnG8KD3WpaFmqahqnqS6AUVRUFlWaa6onVd+Z1to6/rcSyMMSSlJK01zfPMIAj7aZq+6gbs+56B3nuWc45sapLrrBACjeN4UowxJdjOQMDatj1dBjQ/ee/2838BlVIkhCBrLbuAsqPgf2pcjilivES+AQHruo6B3oebU5xnx1ehyW2GcFjXNYMhjAASUtAwDGS0SVD3iX/Un0Bc5LkgZnqGsM8of4g8iqt+BcK6MZp/GwWlBlJpjnpUjg+3uyw3A/AFpFO9KcdCPNEAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;Create new app on Twitter&quot;
        title=&quot;&quot;
        src=&quot;/static/70e004f11e07b9fc57f36030cd0aba3e/c1b63/create_twitter_app_2.png&quot;
        srcset=&quot;/static/70e004f11e07b9fc57f36030cd0aba3e/5a46d/create_twitter_app_2.png 300w,
/static/70e004f11e07b9fc57f36030cd0aba3e/0a47e/create_twitter_app_2.png 600w,
/static/70e004f11e07b9fc57f36030cd0aba3e/c1b63/create_twitter_app_2.png 1200w,
/static/70e004f11e07b9fc57f36030cd0aba3e/c367c/create_twitter_app_2.png 1349w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;em&gt;Create new app on Twitter&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;On the next page go to the &lt;code class=&quot;language-text&quot;&gt;&quot;Key and access Tokens&quot;&lt;/code&gt; tab. We&apos;ll need four different key from here out of which 2 (Consumer Key and Consumer Secret) have already been created for us. To get the other 2 click on &lt;code class=&quot;language-text&quot;&gt;&quot;Create my access tokens&quot;&lt;/code&gt; at the bottom of the page, .&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1200px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/f7d860720d0fcdd63b39eee481343f07/c367c/twitter_api_keys.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 46%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAYAAAAywQxIAAAACXBIWXMAAAsTAAALEwEAmpwYAAABHklEQVR42pVS246CMBT0/39L46OKL7uJl6iBiIlAgQK9QGenXLLuxrjuSSYHmmbmzPTMMJZzDmVRIC9LlJcLis0GGVEEAdTxCBVFaMII3fUK3O+AUkDb4nfNHglzIVA3Dao0hVitkK0DJOst5Mcn9H4PtdvBecIsAygMY14TKq/K0rwo63o4x/9q9vijlYY1lsKGbn7a8YIT3iZMaTUMQ8RxDJHnKKWEYAw5vxtGobXu0T7J7imhMbq37SFJVtO271JWPNMwesBbhN6KnybjlH6yKb/JoO8d73Tuu7u/CAuuTUVrJkkgDwdUpzMM10UT5nyCvd1gKWj5yh4dB4C1L17Z52TbftfEfI5suYQYkS8W6LiPtODDHkBhjG4mwi+kVL0TM0gf2AAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;Grab the API Keys&quot;
        title=&quot;&quot;
        src=&quot;/static/f7d860720d0fcdd63b39eee481343f07/c1b63/twitter_api_keys.png&quot;
        srcset=&quot;/static/f7d860720d0fcdd63b39eee481343f07/5a46d/twitter_api_keys.png 300w,
/static/f7d860720d0fcdd63b39eee481343f07/0a47e/twitter_api_keys.png 600w,
/static/f7d860720d0fcdd63b39eee481343f07/c1b63/twitter_api_keys.png 1200w,
/static/f7d860720d0fcdd63b39eee481343f07/c367c/twitter_api_keys.png 1349w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;em&gt;Grab the api keys&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;If you did everything right, you shall now have the following keys:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Consumer Key&lt;/li&gt;
&lt;li&gt;Consumer Secret&lt;/li&gt;
&lt;li&gt;Access Token&lt;/li&gt;
&lt;li&gt;Access Token Secret&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;NEVER EVER SHARE YOUR KEYS&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Fire up your text editor and create a new file to hold all the configurations. Let&apos;s name it &lt;code class=&quot;language-text&quot;&gt;config.js&lt;/code&gt; for convenience. Copy the code below to &lt;code class=&quot;language-text&quot;&gt;config.js&lt;/code&gt; and fill up the necessary details.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;module&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;exports &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;consumer_key&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;&amp;lt;YOUR_CONSUMER_KEY_HERE&gt;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;consumer_secret&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;&amp;lt;YOUR_CONSUMER_SECRET_KEY_HERE&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;access_token&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;YOUR_ACCESS_TOKEN_HERE&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;access_token_secret&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;YOUR_ACCESS_TOKEN_SECRET_HERE&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Do not modify the parameters. For example : Do not change consumer_key to Consumer Key. The format should be exactly as shown above.&lt;/p&gt;
&lt;h3 id=&quot;2-setup-and-install-nodejs&quot;&gt;2. Setup and Install NodeJS&lt;/h3&gt;
&lt;p&gt;Now, let&apos;s install NodeJS. The instructions will vary a bit depending on your operating system, so just follow the official guide - it&apos;s pretty simple.&lt;/p&gt;
&lt;p&gt;Once you have installed NodeJS fire up your command line and type&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;node&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;--version&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If you get something like &lt;code class=&quot;language-text&quot;&gt;v6.10.3&lt;/code&gt; then your installation was successful. The number you get back is the version of Node. If you get something like &apos;not recognized&apos;, there was some error in the installation. Try reinstalling.&lt;/p&gt;
&lt;p&gt;NodeJS comes with NPM (Node Package Manger) with which you can download NPM packages. They are simply JavaScript libraries. Once again in your command line, type&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;--version&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You should get back a version number. Great! We now have all the requirements fulfilled.&lt;/p&gt;
&lt;h3 id=&quot;3-project-setup&quot;&gt;3. Project Setup&lt;/h3&gt;
&lt;p&gt;Hold your horses folks. Let&apos;s set up our project first. Few more minutes and then we&apos;ll get into coding - I promise !&lt;/p&gt;
&lt;p&gt;Create a folder to store all your bot files. Inside that folder you should have the config.js file we created earlier. Create another file called &lt;code class=&quot;language-text&quot;&gt;bot.js&lt;/code&gt; - this is the file where we&apos;ll be writing all of logic.&lt;/p&gt;
&lt;p&gt;Well, every NodeJS project requires a &lt;code class=&quot;language-text&quot;&gt;package.json&lt;/code&gt; file. This file will contain all the metadata of our project like the project name, project version, description, license and most importantly the dependencies. Dependencies are the node modules that we use in our program. You can manually create this file but there&apos;s a much better way. On your command line navigate to the project folder and then type the following command&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; init &lt;span class=&quot;token parameter variable&quot;&gt;-f&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This command creates the package.json file. You folder should have 3 files by now&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;config.js&lt;/li&gt;
&lt;li&gt;bot.js&lt;/li&gt;
&lt;li&gt;package.json&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;4-install-twit-module&quot;&gt;4. Install Twit Module&lt;/h3&gt;
&lt;p&gt;To communicate with the twitter server we&apos;ll use a NPM package called &lt;code class=&quot;language-text&quot;&gt;Twit&lt;/code&gt;. This is the only package we&apos;ll need. On your terminal run the following command&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;--save&lt;/span&gt; twit&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This will install the Twit package. If you check your package.json file you should see &quot;twit&quot; in your dependencies.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;json&quot;&gt;&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;your-project-name&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;version&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;1.0.0&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;description&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;main&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;index.js&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;dependencies&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;twit&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;^2.2.9&quot;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// twit module&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Every time you install a package it&apos;ll automatically be added to your package.json file.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;It&apos;s very important that you are on the project folder on your command line while running these commands&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;5-code&quot;&gt;5. Code&lt;/h3&gt;
&lt;p&gt;It&apos;s time to write some code! Open the bot.js file and copy these lines.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Import NPM package&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; Twit &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;twit&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Import Config File&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; config &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;./config&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The first line of our code imports the Twit package and assigns it to the &lt;code class=&quot;language-text&quot;&gt;Twit&lt;/code&gt; variable. Similarly the second line of code imports the config.js file on our Folder. Make sure you have added all the required consumer keys and access tokens on the config.js file.&lt;/p&gt;
&lt;p&gt;We now create a Twit instance.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Create a Twit Instance&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; Bot &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Twit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;config&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The variable &lt;code class=&quot;language-text&quot;&gt;Bot&lt;/code&gt; holds the &lt;code class=&quot;language-text&quot;&gt;Twit&lt;/code&gt; instance. &lt;strong&gt;Bot&lt;/strong&gt; has a function called &lt;code class=&quot;language-text&quot;&gt;post()&lt;/code&gt; which enables us to make a tweet. This post function takes 3 different arguments&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;method&lt;/li&gt;
&lt;li&gt;input&lt;/li&gt;
&lt;li&gt;callback function&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// tweet &apos;hello world!&apos;&lt;/span&gt;
Bot&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;post&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;statuses/update&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Hello World&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;err&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; data&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Successfully Tweeted&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Let&apos;s breakdown and understand this code.&lt;/p&gt;
&lt;h4 id=&quot;a-the-first-argument-&quot;&gt;a. The first argument: –&lt;/h4&gt;
&lt;p&gt;&apos;statuses/update&apos; means we want to update the status. There are other various methods like &apos;media/upload&apos; to upload a media, &apos;favorites/create&apos; to favorite a tweet, &apos;direct_messages/new&apos; to send direct messages, and many more. Read more about Twitter API here.&lt;/p&gt;
&lt;h4 id=&quot;b-the-second-argument-&quot;&gt;b. The second argument: –&lt;/h4&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;{ status: &apos;hello world!&apos; }&lt;/code&gt; is a JavaScript object with a property &apos;status&apos; and a value of &apos;hello world!&apos;. This means we want to make a tweet &apos;hello world&apos;. To make any other tweets just edit the &apos;hello world!&apos; part like this { status: &apos;Best bot ever&apos; } , { status: &apos;I love Twitter Bots&apos; } …&lt;/p&gt;
&lt;h4 id=&quot;c-the-third-argument-&quot;&gt;c. The Third Argument:-&lt;/h4&gt;
&lt;p&gt;This argument is a function or more specifically a callback function.&lt;/p&gt;
&lt;p&gt;So now what our function does is updates the status &apos;hello world!&apos; right? As soon as the post function makes the tweet or if there occurs any error while tweeting, this callback function is invoked!&lt;/p&gt;
&lt;p&gt;Inside this function we have three variables &apos;error&apos;, &apos;data&apos; and &apos;response&apos;. If any error occurs while tweeting, this error variable will contain the information of the error, if everything goes right then we&apos;ll get a response.&lt;/p&gt;
&lt;p&gt;Now your bot.js file should look something like this&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; Twit &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;twit&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; config &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;./config&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; Bot &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Twit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;config&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

Bot&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;post&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;statuses/update&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Hello World&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;err&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; data&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Successfully Tweeted&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Great! With these lines of code we can already make a tweet. Open up your command line and navigate to your project folder. Now run the command&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;node&lt;/span&gt; bot.js&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This should make a tweet! Go check your bot&apos;s twitter account.&lt;/p&gt;
&lt;p&gt;It&apos;s tedious to write that long string of function to make a tweet. Let&apos;s wrap that Twit.post function in our own custom function.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; Twit &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;twit&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; config &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;./config&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; Bot &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Twit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;config&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;makeTweet&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token parameter&quot;&gt;tweet&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  Bot&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;post&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;statuses/update&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; tweet &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;err&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; data&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Tweet Made Successfully&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;makeTweet&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;I am tweeting from my command line and it&apos;s awesome&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now everytime we need to make a tweet we can just call the makeTweet() function and pass in the tweet like this&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token function&quot;&gt;makeTweet&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;I am tweeting from my command line and it&apos;s awesome&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is great but what&apos;s the fun if we need to run a command everytime we need to make a tweet? Let&apos;s automate the process so that our bot will make a tweet in certain time interval. We can achieve this by using the setInterval() function in JavaScript that runs a task in a certain set of intervals. Add this line of code at the bottom&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token function&quot;&gt;setInterval&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;makeTweet&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;60000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This code runs the makeTweet() function every 60 seconds ( 60,000 milliseconds). If you run the bot from your command line the bot will tweet a random number every minute.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Do not spam and post every few seconds or so. Twitter will block your app!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 id=&quot;streaming-tweets&quot;&gt;Streaming Tweets&lt;/h4&gt;
&lt;p&gt;Alright so we have made a bot that can post tweets. But that&apos;s not enough. We will step up our game by streaming realtime tweets! For example, we can track any words like &apos;Donald Trump&apos; so that whenever someone makes a tweet with the word &apos;Donald Trump&apos; anywhere in the tweet, our bot will grab that tweet in realtime. We can track twitter accounts, words, hashtags, etc with this method.&lt;/p&gt;
&lt;p&gt;Lets create a &lt;strong&gt;trackTweet&lt;/strong&gt; function. This function takes a parameter, that we name &lt;strong&gt;keyword&lt;/strong&gt;, which stores the word we want to track. Once someone makes a tweet with that keyword, we&apos;ll program our bot to print the tweet in the command line. Let&apos;s track &apos;trump&apos;.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; Twit &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;twit&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; config &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;./config&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; Bot &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Twit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;config&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;makeTweet&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token parameter&quot;&gt;tweet&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  Bot&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;post&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;statuses/update&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; tweet &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;err&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; data&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Tweet Made Successfully&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Lets not call this function right now&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// setInterval(makeTweet, 60 * 1000, Math.random() * 20)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;trackTweet&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token parameter&quot;&gt;keyword&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; stream &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Bot&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;stream&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;statuses/filter&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;track&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; keyword &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  stream&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;tweet&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;tweet&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;tweet&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;text&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;trackTweet&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;trump&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The last line calls the function and the bot will start tracking every tweets with &apos;trump&apos;&lt;/p&gt;
&lt;h4 id=&quot;track-tweets-and-favorite-the-tweet&quot;&gt;Track tweets and favorite the tweet&lt;/h4&gt;
&lt;p&gt;We&apos;re not done yet! Currently the &lt;strong&gt;trackTweet&lt;/strong&gt; function track tweets and print it on the command line. Let&apos;s modify it so that we can not only track tweets but also &lt;em&gt;favorite&lt;/em&gt; the ones we like.&lt;/p&gt;
&lt;p&gt;We&apos;ll create a &lt;strong&gt;favoriteTweet&lt;/strong&gt; function that will favorite tweets we pass to it. Then inside our &lt;strong&gt;trackTweet&lt;/strong&gt; function we&apos;ll use this function to favorite tweets we like.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; Twit &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;twit&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; config &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;./config&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; Bot &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Twit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;config&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;makeTweet&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token parameter&quot;&gt;tweet&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  Bot&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;post&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;statuses/update&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; tweet &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;err&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; data&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Tweet Made Successfully&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;favoriteTweet&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token parameter&quot;&gt;tweet_id&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  Bot&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;post&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;favorites/create&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; tweet_id &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;err&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; data&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Successfully favorited Tweet!&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;trackTweet&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token parameter&quot;&gt;keyword&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; stream &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Bot&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;stream&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;statuses/filter&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;track&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; keyword &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  stream&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;tweet&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;tweet&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;tweet&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;text&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;favoriteTweet&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;tweet&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;id_str&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;trackTweet&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;nepal&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// setInterval(makeTweet, 60 * 1000, Math.random() * 20)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Do you see some resemblance in the &lt;code class=&quot;language-text&quot;&gt;favoriteTweet()&lt;/code&gt; function we just created? It is almost identical to the &lt;code class=&quot;language-text&quot;&gt;makeTweet()&lt;/code&gt; function. The only difference is the parameter passed to them.&lt;/p&gt;
&lt;p&gt;Go to the &lt;a href=&quot;https://developer.twitter.com/en/docs/api-reference-index&quot;&gt;Twitter API Documentation&lt;/a&gt; and try to make a function that follows a twitter user. &lt;strong&gt;Please&lt;/strong&gt; take your time and try to figure this on your own because once you learn to read the documentation you can add plenty more features that twitter provides.&lt;/p&gt;
&lt;p&gt;The code must look something like this.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Pass it the username and your bot will follow the user.&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;followUser&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token parameter&quot;&gt;username&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  Bot&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;post&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;friendships/create&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;screen_name&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; username &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;err&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; data&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Couldn&apos;t Follow!&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Followed!&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; username&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We have created a twitter bot that tracks a keyword and favorites the tweet if it finds one. I know it&apos;s not the most exciting bot. I tried to focus this tutorial mainly for beginners. To summarize this tutorial, We have learnt to&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Track realtime tweets&lt;/li&gt;
&lt;li&gt;Make tweets&lt;/li&gt;
&lt;li&gt;Follow users&lt;/li&gt;
&lt;li&gt;Favorite tweets&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;There&apos;s still so much more to explore! Visit the &lt;a href=&quot;https://developer.twitter.com/en/docs/api-reference-index&quot;&gt;Twitter API Documentation&lt;/a&gt; and try adding more features.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;6-deploy-on-heroku&quot;&gt;6. Deploy on Heroku&lt;/h3&gt;
&lt;p&gt;I know you must be thinking &quot;Wait a minute, do I have to keep my computer running for this bot to function?&quot;. I have a good news for you - &lt;strong&gt;NO, you can actually run your bot on the cloud&lt;/strong&gt;. One cloud platform that I can vouch for is &lt;code class=&quot;language-text&quot;&gt;Heroku&lt;/code&gt; &lt;em&gt;(mainly because it is very easy to setup and there&apos;s a free package that doesn&apos;t require credit card)&lt;/em&gt;. The free package, of course, has limitations. A very limited compute-time is provided to you but that should be more than enough for this tutorial.&lt;/p&gt;
&lt;h4 id=&quot;a-create-a-heroku-account&quot;&gt;A. Create a Heroku account&lt;/h4&gt;
&lt;p&gt;Create an account &lt;a href=&quot;https://www.heroku.com/&quot;&gt;here&lt;/a&gt;. If you create a free account then you can host up to 5 different applications. Once you create a new account create a new app. Now there&apos;s a whole bunch of things we need to do here. Basically there are 3 different ways we can add our code on heroku&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Through Heroku Command Line (&lt;em&gt;Preffered and the programmer&apos;s way&lt;/em&gt;)&lt;/li&gt;
&lt;li&gt;Github (&lt;em&gt;Easy way&lt;/em&gt;)&lt;/li&gt;
&lt;li&gt;Dropbox (&lt;em&gt;Easy way&lt;/em&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I would recommend the first way although it&apos;s a bit harder to get at first. However you can just follow along by using the syntax I provide here.&lt;/p&gt;
&lt;h4 id=&quot;b-heroku-command-line-interface-cli-and-git&quot;&gt;B. Heroku Command Line Interface (CLI) and GIT:&lt;/h4&gt;
&lt;p&gt;Download Heroku Command Line from &lt;a href=&quot;https://devcenter.heroku.com/articles/heroku-cli&quot;&gt;here&lt;/a&gt;. We need to download one more thing and that&apos;s &lt;code class=&quot;language-text&quot;&gt;git&lt;/code&gt; – a CLI for GitHub. Download git &lt;a href=&quot;https://git-scm.com/downloads&quot;&gt;here&lt;/a&gt;. Run those two installation files. If you have any trouble installing look for tutorials online, there are plenty.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1200px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/d938de288954d791beee2cbf7e06ba81/8698d/heroku_deploy.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 41.66666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAAAsTAAALEwEAmpwYAAAA0klEQVR42oVRAY4DIQjc//+1t+0qoLAuN2Cb9JLWM5kQBcYZ2LSbMzUXbq5qfl2Xx4koIs7MbngfY77/dzaR5rVSkulbYxASi1di5IO4Z7519Y7Yn/Ud9/McWR/Yvv0USY7PoN7QEFAb3u0E2V+oTUTNkpCgrpTq0noq06eycBGT+YQl4f2oftsPP2C5kIBYgbA9IW/gbql2QThgl3K+ZpZzsrAGha/4aVFLhaHuZy++P6o/CpaDxVBAFFExYyhrE5TKlwo95zZtai7jtZxvOMfwX4LVdrIf9VGNAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;heroku deploy&quot;
        title=&quot;&quot;
        src=&quot;/static/d938de288954d791beee2cbf7e06ba81/c1b63/heroku_deploy.png&quot;
        srcset=&quot;/static/d938de288954d791beee2cbf7e06ba81/5a46d/heroku_deploy.png 300w,
/static/d938de288954d791beee2cbf7e06ba81/0a47e/heroku_deploy.png 600w,
/static/d938de288954d791beee2cbf7e06ba81/c1b63/heroku_deploy.png 1200w,
/static/d938de288954d791beee2cbf7e06ba81/8698d/heroku_deploy.png 1239w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;em&gt;Deploy on Heroku&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;By now you should have Heroku CLI and GIT installed. To check if you have successfully installed those two application open your command line and type&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;heroku &lt;span class=&quot;token parameter variable&quot;&gt;--verion&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If you get a reply something like this&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;heroku-cli/6.14.22-f598c4a &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;windows-x64&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; node-v8.4.0&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;then the app was installed successfully. Likewise type&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;--version&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;and you should see the git version. Please proceed to rest of the tutorial only if you have installed Heroku CLI &amp;#x26; Git.&lt;/p&gt;
&lt;h3 id=&quot;c-creating-a-procfile&quot;&gt;C. Creating a Procfile&lt;/h3&gt;
&lt;p&gt;Heroku requires a special file called &lt;code class=&quot;language-text&quot;&gt;Procfile&lt;/code&gt;. &lt;em&gt;If you&apos;re hosting your bot on any other hosting service then this file is not require&lt;/em&gt;. This file does not have any extension like .js or .txt, but only a name &apos;Procfile&apos;. So in your Project folder, create a new file and name it as Procfile. Inside this file, write&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;worker: &lt;span class=&quot;token function&quot;&gt;node&lt;/span&gt; bot.js&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;and save it. That&apos;s all we need to do with Procfile.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;This Procfile tells heroku to run &lt;code class=&quot;language-text&quot;&gt;node bot.js&lt;/code&gt; command just like you did in your command line. The &lt;code class=&quot;language-text&quot;&gt;worker&lt;/code&gt; is a type of a thing called dyno in heroku which I better not talk about right now.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 id=&quot;d-creating-a-new-app-in-heroku&quot;&gt;D. Creating a New App in Heroku&lt;/h4&gt;
&lt;p&gt;On your terminal, type heroku login. Type your Heroku email and password and log in. Now, to create a new app type the following command&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;heroku create &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;your_app_name&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Replace &lt;code class=&quot;language-text&quot;&gt;&amp;lt;you_app_name&gt;&lt;/code&gt; with your app name. The app name should be in lowercase. We&apos;re done. That&apos;s how easy it is to create an app in heroku. All we need to do now is upload our code to our Heroku app.&lt;/p&gt;
&lt;p&gt;Login to your heroku account and you&apos;ll see a list of all your apps. Click on the app you created just now and then go to the &lt;code class=&quot;language-text&quot;&gt;Deploy&lt;/code&gt; tab section. If you scroll down you&apos;ll see this :&lt;/p&gt;
&lt;p&gt;As I mentioned earlier, there are various methods to deploy your code on heroku. We are using the Heroku CLI because its cooler than using GUI 😀 .&lt;/p&gt;
&lt;h4 id=&quot;e-creating-a-git-repository-and-uploading-our-twitter-bot-code&quot;&gt;E. Creating a Git Repository and Uploading our Twitter Bot code:&lt;/h4&gt;
&lt;p&gt;We first need to create a Git Repository of our bot and only then we can upload (&lt;em&gt;push&lt;/em&gt;) it to Heroku. Open command line and navigate to your project file and type&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; init&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This command initializes an empty git repository. Now we must add all the files in our project to the repository. To do so use the following two commands&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;.&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; commit &lt;span class=&quot;token parameter variable&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;first commit&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Great! Now before we upload our code, we first need to tell where to actually upload the code. We can do that by using the command below&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;heroku remote:set &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;your app name&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now the final step is to upload(push) the code. Use the following command&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; push heroku master&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4 id=&quot;f-final-step--turning-on-worker-dyno&quot;&gt;F. Final Step – Turning on Worker Dyno&lt;/h4&gt;
&lt;p&gt;There&apos;s one last thing we need to do. Go to your heroku app page on your browser. On the &lt;strong&gt;&apos;Resources&apos;&lt;/strong&gt; tab you should see your dynos.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1200px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/01efa9e968d145bb6ec2cef120969b1d/afa26/heroku_dyno.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 20%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAYAAACOXx+WAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAgUlEQVR42o2QOw7CQAxE9/4n4wyp6BABGqTY6+/gDUGiIBEjvcLW2Bq7uTtUDZ0VTILMxF/6+FQBIuTaSjQzw7JQwWDu6KKQL0Y9jOvADnK943yacLs80bwWcheY+XuwiNjY6iMND0mFmh/QurJFBEZK9zi87hdDZgGqRVavCw+8AL/sO9a1Gu/nAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;Heroku Dynos&quot;
        title=&quot;&quot;
        src=&quot;/static/01efa9e968d145bb6ec2cef120969b1d/c1b63/heroku_dyno.png&quot;
        srcset=&quot;/static/01efa9e968d145bb6ec2cef120969b1d/5a46d/heroku_dyno.png 300w,
/static/01efa9e968d145bb6ec2cef120969b1d/0a47e/heroku_dyno.png 600w,
/static/01efa9e968d145bb6ec2cef120969b1d/c1b63/heroku_dyno.png 1200w,
/static/01efa9e968d145bb6ec2cef120969b1d/afa26/heroku_dyno.png 1258w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;em&gt;Heroku Dynos&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;We need to turn on the worker dyno to start our bot. Click on the edit button and disable the web dyno and turn on worker dyno. This is where the Procfile comes into play! Without the Procfile, we wouldn&apos;t have this option to turn on worker dyno.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;If you&apos;ve read this far I hope you enjoyed it :)&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Seive's Algorithm To Calculate The Sum Of First Million Prime Numbers]]></title><description><![CDATA[Fastest algorithm to calculate Sum of all prime numbers less than one million.]]></description><link>https://www.adityathebe.com/sum-of-first-million-prime-numbers/</link><guid isPermaLink="false">https://www.adityathebe.com/sum-of-first-million-prime-numbers/</guid><pubDate>Fri, 16 Mar 2018 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;If you&apos;re a programmer there&apos;s a good chance that you have, at least once, written a prime detection function. This problem seems easy enough for anyone who knows what a prime number is and in fact it is ! But many of us approach it the wrong way. The most obvious way would be to make a function that classifies a number as prime or composite and then another function that loops through all the numbers say upto a million and then checks each number with the classifier function. There&apos;s nothing wrong with this but depending on the prime classifier function, calculating sum of all prime numbers upto 1 million can take anywhere from 1 second to 10 minutes ! Let me write a prime classifier function first ...&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;isPrimeNumber&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token parameter&quot;&gt;num&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;num &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; num&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;num &lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now to get the sum we loop over all numbers upto 1 million&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; sum &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1000000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;isPrimeNumber&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; sum &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; i&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Lets see what&apos;s wrong with this approach. To classify a prime number say &lt;strong&gt;11&lt;/strong&gt;, we divide it by every numbers starting from 2 upto 10. To classify &lt;strong&gt;13&lt;/strong&gt; we repeat the same process, divide it by every numbers starting from 2 to 12. You can see where this is going. As the number increases, each classification will take more time than the previous one. In CS term the Big O of this approach is O(n&lt;sup&gt;2&lt;/sup&gt;) which is really really bad for an algorithm.&lt;/p&gt;
&lt;h3 id=&quot;optimization&quot;&gt;Optimization&lt;/h3&gt;
&lt;p&gt;We can optimize this by not classifying even numbers, except &lt;em&gt;2&lt;/em&gt;, since they are for sure not prime. By increasing the counter up by &lt;strong&gt;2&lt;/strong&gt; in the two &lt;em&gt;for&lt;/em&gt; loops we can ignore all the even numbers. That would decrease the processing time by half. But that&apos;s still way off from being a good algorithm.&lt;/p&gt;
&lt;p&gt;We can further optimize by taking divisors upto the square root of &lt;em&gt;num&lt;/em&gt;. In our &lt;em&gt;for&lt;/em&gt; loop in &lt;em&gt;checkPrime&lt;/em&gt; function the loop should only continue up to &lt;em&gt;√num&lt;/em&gt;. We have now significantly decreased the amount of divisors but this is still not good for large value of N.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;primality-test&quot;&gt;Primality Test&lt;/h2&gt;
&lt;p&gt;There&apos;s another much better way to classify a number as prime - the &lt;strong&gt;&quot;Primality Test Algorithm&quot;&lt;/strong&gt;. This algorithm does not give prime factors but only state whether the input number is prime or not. Hence there&apos;s much less computation to do.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;primality&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token parameter&quot;&gt;num&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;num &lt;span class=&quot;token operator&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;num &lt;span class=&quot;token operator&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;num &lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; num &lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;i &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;&amp;lt;=&lt;/span&gt; num&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;num &lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; num &lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;i &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    i &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I used both the algorithms to classify the 50 millionth prime number &lt;strong&gt;982,451,653&lt;/strong&gt; and the result was:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# first Algorithm: 2952.744ms&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# primality: 0.527ms&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Similary, I used those two algorithms to get the sum of all primes below 1 million and this was the result&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;runtime&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1000000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;isPrimeNumber&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    sum &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; i&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;timeEnd&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;runtime&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# First algorithm : 705403.287ms // About 11 minutes&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# Using Primality algorithm : 117.574ms&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Wot !! That&apos;s a massive performance gain if you ask me. Primality Test is in fact considered to be the fastest prime detection algorithm. But wait there&apos;s another even better algorithm for this type of prime calculations. This next algorithm gets the same result in just 50ms.&lt;/p&gt;
&lt;h2 id=&quot;sieves-algorithm&quot;&gt;Sieve&apos;s Algorithm&lt;/h2&gt;
&lt;p&gt;The &lt;strong&gt;Sieve of Eratosthenes&lt;/strong&gt; is a simple, ancient algorithm to find all the prime numbers that are less than a given number. This algorithm cannot directly classify a number &lt;strong&gt;X&lt;/strong&gt; as prime or composite but will generate list of all prime numbers that are less than &lt;strong&gt;X&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://upload.wikimedia.org/wikipedia/commons/b/b9/Sieve_of_Eratosthenes_animation.gif&quot; alt=&quot;Sieve&amp;#x27;s Algorithm&quot;&gt;&lt;em&gt;Sieve&apos;s Algorithm&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Here&apos;s how it works. Let&apos;s say we need to get all the prime numbers upto a number &lt;strong&gt;N&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 1:&lt;/strong&gt; We generate an array of numbers starting from 2 to N-1. So now we have N-2 elements in the array.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 2:&lt;/strong&gt; Then all the elements of the array are set to boolean value &lt;strong&gt;TRUE&lt;/strong&gt;. True means they are prime (&lt;em&gt;yet&lt;/em&gt;). But as we proceed we&apos;ll have many False values. It&apos;s analogous to how we filter out unwanted particles using a sieve. At first all of them are in the sieve machine (set to True) and then at last only the required particles (prime numbers) are present.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 826px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/88eb15f5eb4dc2ed2479eae144558c7a/1c58d/sieve.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 56.333333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAALABQDASIAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAMEBv/EABYBAQEBAAAAAAAAAAAAAAAAAAQCA//aAAwDAQACEAMQAAABZBbFmjQDSz//xAAcEAACAgIDAAAAAAAAAAAAAAABAwACBBESITP/2gAIAQEAAQUCesl1lxB5Jy/Qncr1X//EABcRAQADAAAAAAAAAAAAAAAAAAEQERL/2gAIAQMBAT8BwtMf/8QAFxEAAwEAAAAAAAAAAAAAAAAAEBESIf/aAAgBAgEBPwGlg//EABoQAAICAwAAAAAAAAAAAAAAAAABIVECEBH/2gAIAQEABj8C7Y5kxbrUiP/EABwQAQACAgMBAAAAAAAAAAAAAAEAIRExYXGRwf/aAAgBAQABPyFh0HkxmXwi7ZRnK1ZcbDaAEaCf/9oADAMBAAIAAwAAABDs3//EABgRAQEAAwAAAAAAAAAAAAAAAAEAESEx/9oACAEDAQE/EAuXhO2//8QAFhEBAQEAAAAAAAAAAAAAAAAAAAEx/9oACAECAQE/ENCP/8QAHxABAAIBAwUAAAAAAAAAAAAAAQARITFBUWGBoeHw/9oACAEBAAE/EGfgRdiymfuJp6bRy9w9qYs3TF+JZdqABVD0No3ZsykMeggdp//Z&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;Sieving&quot;
        title=&quot;&quot;
        src=&quot;/static/88eb15f5eb4dc2ed2479eae144558c7a/1c58d/sieve.jpg&quot;
        srcset=&quot;/static/88eb15f5eb4dc2ed2479eae144558c7a/f93b5/sieve.jpg 300w,
/static/88eb15f5eb4dc2ed2479eae144558c7a/b4294/sieve.jpg 600w,
/static/88eb15f5eb4dc2ed2479eae144558c7a/1c58d/sieve.jpg 826w&quot;
        sizes=&quot;(max-width: 826px) 100vw, 826px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;em&gt;Source: &lt;a href=&quot;http://www.tigtagcarolina.com&quot;&gt;www.tigtagcarolina.com&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 3:&lt;/strong&gt; Now starting from the 2nd index of the array to the last, we remove the multiples of the number. But first we need to check if the current number ( &lt;em&gt;or index of array&lt;/em&gt; ) is &lt;em&gt;TRUE&lt;/em&gt; of false. If the value is &lt;em&gt;TRUE&lt;/em&gt;, we calculate its multiple and if it&apos;s false we don&apos;t.&lt;/p&gt;
&lt;p&gt;So what do we do once we find the multiples? We set the boolean value of that index to &lt;strong&gt;FALSE&lt;/strong&gt;. Don&apos;t worry if this sounds confusing right now ( &lt;em&gt;I&apos;m not very good at explaining&lt;/em&gt; ) but this example will clear up everything - I promise!&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Example&lt;/em&gt;: We start with 2nd index of the array (&lt;em&gt;everytime&lt;/em&gt;). Its value in the array is &lt;em&gt;TRUE&lt;/em&gt;. Hence we proceed to calculate its multiples i.e. 4, 6, 8, 10, 12, ... in the array and set them to false. Then we get to 3. Again, the value in the 3rd index is &lt;em&gt;TRUE&lt;/em&gt; and so we proceed in a similar manner setting all the multiple of 3 i.e. 9, 12, 15, 18, ... to false. Now comes 4. But remember the 4th index is already set to false since it was one of the multiples of 2. So we do not need to find its multiples. We keep proceeding in this manner until the end.&lt;/p&gt;
&lt;p&gt;Notice that I didn&apos;t include 6 in the multiples of 3. It so happens that, for a number n we can start counting its multiple from n^2. Example: for n = 5, we do not need to look for 10, 15, 20. These numbers are already cut out by previous numbers and excluding them will save a tiny bit of processing time.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 4:&lt;/strong&gt; Now we have an array with mixed values of True and False. True indicates that the number is a prime and false indicates the number isn&apos;t prime. We loop through the array and add the index value whose value is set to True. And finally we will have the sum of all required Primes.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Eratosthenes algorithm to find all primes under n&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;eratosthenes&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token parameter&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; array &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; output &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; upperLimit &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sqrt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;n&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// We need to make an array from 2 to (n - 1)&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// For easy indexing we add extra two elements 0, 1 hence the length = n&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; n&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    array&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// Remove multiples of primes starting from 2, 3, 5,...&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;&amp;lt;=&lt;/span&gt; upperLimit&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;array&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; j &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; i&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; j &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; n&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; j &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; i&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        array&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;j&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// All array[i] set to true are primes&lt;/span&gt;
  sum &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; n&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;array&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      sum &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; i&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; sum&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;downside-of-sieves-algorithm&quot;&gt;Downside of Sieve&apos;s Algorithm&lt;/h3&gt;
&lt;p&gt;You must have probably guessed the problem with this algorithm. Yes, it&apos;s the memory consumption! For N = 1million we need an array of size 1million! In Node for large values of N, we see the classic javascript error - &quot; &lt;strong&gt;heap out of memory&lt;/strong&gt; &quot;. But Node can easily handle upto N = 50 million.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;--- JS stacktrace ---&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;

&lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; JS stack trace &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;

FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;hr&gt;
&lt;p&gt;If you&apos;ve read this far I hope you enjoyed it :)&lt;/p&gt;</content:encoded></item><item><title><![CDATA[The Code behind @KuNotifier - A Twitter bot for Kathmandu University]]></title><description><![CDATA[A twitter bot for Kathmandu University that tweets college notices on Twitter. Built with Node Js]]></description><link>https://www.adityathebe.com/kathmandu-university-twitter-bot/</link><guid isPermaLink="false">https://www.adityathebe.com/kathmandu-university-twitter-bot/</guid><pubDate>Tue, 07 Nov 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;The last time Kathmandu University updated its &lt;a href=&quot;http://ku.edu.np&quot;&gt;official website&apos;s&lt;/a&gt; layout was almost around 5 years ago. The old-fashioned website doesn&apos;t facilitate email subscription due to which students tend to miss out on important news and notices.&lt;/p&gt;
&lt;p&gt;This time of year is a start to a new semester and every students (not the freshmans) in the college are waiting for their end semester results. The only way they can get notified about their results is by visiting the website or through friends. I have seen people who refresh the exam section page atleast a couple of dozen times a day! This is a very inconvinient and inefficient way since it takes time and if you&apos;re on mobile - an unnecessary data cost.&lt;/p&gt;
&lt;p&gt;As a programmer I couldn&apos;t bear this and so I decided to build a bot that would notify me on every new notice published on the site.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Disclaimer: I didn&apos;t intend to make this bot for the public but soley for my own purpose. I am not responsible if the bot fails to deliver any news.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;deciding-on-how-to-get-notified&quot;&gt;Deciding on how to get notified&lt;/h3&gt;
&lt;p&gt;I use a gmail chrome extension that notifies me instantly whenever I get new emails and since I am always on my browser I decided that the bot notifies me through email. This didn&apos;t go as planned due to Google&apos;s security system. It was because the bot was running on a server in United states which raised suspicion everytime the bot tried to connect with gmail&apos;s smtp server. This wasn&apos;t a huge issue to solve but I didn&apos;t bother to look for the solution.&lt;/p&gt;
&lt;p&gt;So the obvious next way to notify was through social medias - Twitter and Facebook. In this way, not only me, but any student can take the benefit of the bot.&lt;/p&gt;
&lt;p&gt;The bot is currently running on Twitter &lt;a href=&quot;https://twitter.com/KuNotifier&quot;&gt;@KuNotifier&lt;/a&gt; and on Facebok &lt;a href=&quot;https://m.me/botlimbu&quot;&gt;@botlimbu&lt;/a&gt;. I have been running the Facebook Messenger bot for few months for learning purposes. It doesn&apos;t make facebook posts but message users directly who are subscribed to it. To subscribe, go to &lt;a href=&quot;https://m.me/botlimbu&quot;&gt;https://m.me/botlimbu&lt;/a&gt; and on the persistence menu click on the &lt;strong&gt;&quot;Subscribe&quot;&lt;/strong&gt; option.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/OyHBQzh.png&quot; alt=&quot;Subscribe on Facebook&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;summarizing-the-process&quot;&gt;&lt;strong&gt;Summarizing the process&lt;/strong&gt;&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;KU fortunately provides RSS feeds for its /exam and /news subdomains. The bot checks these two RSS feed every 20 minutes.&lt;/li&gt;
&lt;li&gt;The result from the RSS is checked against a firebase database. If any new notice is found, tweet it and update the datbase&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This is basically what the bot does ...&lt;/p&gt;
&lt;h3 id=&quot;code&quot;&gt;&lt;strong&gt;Code&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;The bot is written in JavaScript and runs on a NodeJS environment.&lt;/p&gt;
&lt;p&gt;The bot bascially has two main functions. One to get the RSS feed and the other to check for new notices in the feed.&lt;/p&gt;
&lt;h4 id=&quot;1-reading-the-rss-feed&quot;&gt;1. Reading the RSS Feed&lt;/h4&gt;
&lt;p&gt;In order to read and parse the RSS feeds, I used the NPM module called - &quot;rss-parser&quot;. The function that gets the rss feed is named getResult. I prefer using ES6 and hence you&apos;ll find the arrow functions.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; parser &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;rss-parser&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; examFeed &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;http://www.ku.edu.np/exam/?feed=rss2&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; newsFeed &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;http://www.ku.edu.np/news/rss.php?blogId=1&amp;amp;profile=rss20&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;getResult&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token parameter&quot;&gt;callback&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  parser&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;parseURL&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;examFeed&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;err&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; examData&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    parser&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;parseURL&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;newsFeed&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;err&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; newsData&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; items &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; examData&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;feed&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;entries&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;concat&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;newsData&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;feed&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;entries&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The data we get back is an object with all the feeds in an array in its feed.entries property. The two arrays from the exam and news feed is concatenated using the &lt;em&gt;concat&lt;/em&gt; function in JavaScript. The concatenated array is stored in a variable named &lt;strong&gt;&quot;items&quot;&lt;/strong&gt;. Now the elements in these array must be sorted according to the date from latest to oldest.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Sorting the array based on isoDate of each element&lt;/span&gt;
items &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; items&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sort&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;a&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; b&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;b&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;isoDate&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;isoDate&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Great! Now just to keep things pretty I have also modified the pubDate format and added a new category property to each element of the array. This is the final code for our getResult function.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;getResult&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token parameter&quot;&gt;callback&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  parser&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;parseURL&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;examFeed&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;err&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; examData&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    parser&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;parseURL&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;newsFeed&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;err&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; newsData&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; items &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; examData&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;feed&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;entries&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;concat&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;newsData&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;feed&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;entries&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

      items &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; items
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sort&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;a&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; b&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;b&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;isoDate&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;isoDate&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;item&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
          item&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;pubDate &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; item&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;pubDate
            &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos; &apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;slice&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos; &apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
          &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; item&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;item&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
          item&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;category &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; item&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;link
            &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;splice&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;21&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toUpperCase&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
          &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; item&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;slice&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

      &lt;span class=&quot;token function&quot;&gt;callback&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;items&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4 id=&quot;2-checking-against-the-database-to-look-for-new-notices&quot;&gt;2. Checking against the database to look for new notices&lt;/h4&gt;
&lt;p&gt;Next I have a checkResult function that fetches data from firebase database, and compares it with the latest data fetched by getResult function. If theres any new notice, this function triggers a notification.&lt;/p&gt;
&lt;p&gt;Let&apos;s break it down.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;checkResult&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Checking New Notice&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;getResult&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;res&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; err&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    db&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;once&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;value&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token parameter&quot;&gt;notice&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token comment&quot;&gt;// Two Arrays, one from RSS and other from Database&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; DB_Results &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;objToArray&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;notice&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; feed_Results &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;el&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; el&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;title&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The above function uses the getResult function to get latest feed from the RSS source. After that, it fetches data from the firebase database using the db.on method. The data received from the datbase is stored in a &lt;strong&gt;notice&lt;/strong&gt; variable. This data is an object. To convert this object into array I create a new function objToArray.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;objToArray&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; arr &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; key &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; obj&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    arr&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;obj&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;key&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; arr&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Using this &lt;strong&gt;&lt;em&gt;objToArray&lt;/em&gt;&lt;/strong&gt; function I convert the &lt;strong&gt;notice&lt;/strong&gt; ojbect to arrays;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Two Arrays, one from RSS and other from Database&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; DB_Results &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;objToArray&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;notice&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To make things simpler I created a new array &lt;strong&gt;fed_Results&lt;/strong&gt; to store only the title of each post.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; feed_Results &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;el&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; el&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;title&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Great! Now we have two arrays that are identical in structure. Because of this we can easily compare them and see if any element of the array (post) differs. If there is any difference then we trigger a notification for that particular post.&lt;/p&gt;
&lt;p&gt;Here&apos;s the full code for the &lt;strong&gt;&lt;em&gt;checkResult&lt;/em&gt;&lt;/strong&gt; function.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;checkResult&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Checking New Notice&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;getResult&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;res&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; err&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    db&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;once&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;value&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token parameter&quot;&gt;notice&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token comment&quot;&gt;// Two Arrays, one from RSS and other from Database&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; DB_Results &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;objToArray&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;notice&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; feed_Results &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;el&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; el&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;title&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

      &lt;span class=&quot;token comment&quot;&gt;// Compare Those Two Arrays&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;JSON&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;stringify&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;DB_Results&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!==&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;JSON&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;stringify&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;feed_Results&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// Find all New Indices that don&apos;t match&lt;/span&gt;
        res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forEach&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;elm&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; index&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;DB_Results&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;indexOf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;elm&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;title&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token comment&quot;&gt;// Tweet the new indices&lt;/span&gt;
            &lt;span class=&quot;token function&quot;&gt;shortenUrl&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;elm&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;link&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;url&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
              &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; status &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;statusMaker&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;elm&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; url&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
              &lt;span class=&quot;token function&quot;&gt;makeTweet&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Bot&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; status&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
              &lt;span class=&quot;token function&quot;&gt;sendFBMsg&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;status&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
          &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// Update Database&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;clearAndStore&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;feed_Results&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is it! Now I use a setTimeout method to run the checkResult function every 20 minutes&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token function&quot;&gt;setInterval&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;checkResult&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1000&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;hr&gt;
&lt;h3 id=&quot;source-code&quot;&gt;&lt;strong&gt;Source Code&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Read the full source code &lt;a href=&quot;https://github.com/adityathebe/kuNotifier&quot;&gt;here&lt;/a&gt;&lt;/p&gt;</content:encoded></item></channel></rss>