<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>The Leaky Cauldron Blog</title><description>A Brew of Awesomeness with a Pinch of Magic. The Leaky Cauldron Blog is the personal blog of Vaibhav Sharma. Topics include coding, movies, music, books, dinosaurs or anything under the sun and beyond.</description><link>https://theleakycauldronblog.com</link><item><title>How is Kingdom Two Crowns So Addictive?!</title><link>https://theleakycauldronblog.com/articles/kingdom-two-crowns-is-addictive</link><guid isPermaLink="true">https://theleakycauldronblog.com/articles/kingdom-two-crowns-is-addictive</guid><description>&lt;img alt=&quot;How is Kingdom Two Crowns So Addictive?!&quot; src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Fimg2.Clh0lPWQ.jpg&amp;w=1280&amp;h=800&amp;dpl=699bfef0c4120e00087ee35a&quot; /&gt; A love letter to a game with just one button, a slow horse, and some wooden walls that somehow hijacked five hours of my life.</description><pubDate>Fri, 13 Feb 2026 06:40:00 GMT</pubDate><content:encoded>&lt;p&gt;No, seriously. How?&lt;/p&gt;
&lt;p&gt;You’re telling me traveling from place to place on horseback, stopping only here and there to hold &lt;strong&gt;A&lt;/strong&gt; to deposit some coins is somehow addictive and that I just played 5 hours of this shit? Now I have brain fog. I don’t know why I didn’t take a bath today. Or yesterday? I don’t even want to go out anymore. Or talk to anyone.&lt;/p&gt;
&lt;p&gt;Who designs a game like that?&lt;/p&gt;
&lt;p&gt;It takes so long to get to each place too. A whole in-game day even to go from the left edge of this camp-turned-kingdom to the right. You don’t wanna give me some kinda button to boost this retarded donkey? Maybe just one button if you time it right and boom! Suddenly lord huffs-a-lot gets some pepper up his ass.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Fimg1.7r6ruwTM.jpg&amp;amp;w=1280&amp;amp;h=800&amp;amp;dpl=699bfef0c4120e00087ee35a&quot; alt=&quot;kingdom-2-crowns-night&quot; title=&quot;kingdom-2-crowns-night&quot; /&gt;&lt;/p&gt;
&lt;p&gt;I don’t even know why I want to get where I’m going, faster. It’s just so I can press and hold &lt;strong&gt;A&lt;/strong&gt; so some stacks of wood turn into stone walls, and then when I have more money, the stone walls turn to rock walls, oh look there’s a mound of mud there, that can be another stack of wood, and if I get enough money I can turn it into a stone wall and…&lt;/p&gt;
&lt;p&gt;&lt;em&gt;What the hell is wrong with me? Why?&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Can’t you add some action for god’s sake. Let me have some more buttons at least? I like pressing buttons. I’m good at it. I’m pressing them now. &lt;strong&gt;&lt;em&gt;Tap. Tap. Tap&lt;/em&gt;.&lt;/strong&gt; (&lt;em&gt;Is this meta humor?&lt;/em&gt;)&lt;/p&gt;
&lt;p&gt;I don’t know. I really don’t. The art looks pretty I guess. The little builders look cute with their hammers somehow cutting down trees so I can add a mill to my little continent spanning empire.&lt;/p&gt;
&lt;p&gt;And what’s with that water reflection? It’s so calm and beautiful. Every wave has this parallax effect in motion that I just can’t ignore how serene it makes me feel.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Fimg0.CAKzlmob.jpg&amp;amp;w=1280&amp;amp;h=800&amp;amp;dpl=699bfef0c4120e00087ee35a&quot; alt=&quot;kingdom-2-crowns-fog&quot; title=&quot;kingdom-2-crowns-fog&quot; /&gt;&lt;/p&gt;
&lt;p&gt;I mean I get that I don’t sound serene right now. Senile more like.&lt;/p&gt;
&lt;p&gt;I don’t even know why it’s bothering me so much. It’s a cozy game. You’re supposed to relax and expand. Like me on my birthday.&lt;/p&gt;
&lt;p&gt;I don’t like feeling happy, game! So don’t try your little tricks.&lt;/p&gt;
&lt;p&gt;Demand more of me. Make me do more things. Make me press buttons in order, in time, in the correct place, I want to feel like I matter. But you are just treating me like…&lt;/p&gt;
&lt;p&gt;Like I am a king.&lt;/p&gt;
</content:encoded><author>Eklavya Mishra</author></item><item><title>Stop Letting Me Retry Your Horror Game</title><link>https://theleakycauldronblog.com/articles/retrying-kills-horror-games</link><guid isPermaLink="true">https://theleakycauldronblog.com/articles/retrying-kills-horror-games</guid><description>&lt;img alt=&quot;Stop Letting Me Retry Your Horror Game&quot; src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Fgabriel-h73jxsqwecc-unsplash.CZm3PJmQ.png&amp;w=1536&amp;h=1024&amp;dpl=699bfef0c4120e00087ee35a&quot; /&gt; A rant about why retrying kills horror in video games, why fear doesn’t survive repetition, and why some encounters should be allowed to fail, permanently.</description><pubDate>Fri, 06 Feb 2026 13:20:00 GMT</pubDate><content:encoded>&lt;p&gt;So, horror in video games right? Here’s something I’ve been thinking about for a while: why are we still allowing gamers to play through a horror section again once they’ve failed?&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Well it’s a game, Klad(my gamer tag is &lt;strong&gt;Kladspear&lt;/strong&gt;). You are supposed to retry until you get how to beat it. Permadeath is for the masochists.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;And yeah I mean I’d say so as well but specifically with horror you gotta agree the thrill of that first encounter goes away pretty quick on repeated exposure.&lt;/p&gt;
&lt;p&gt;Of course, that’s true for almost every other kind of encounter as well. Let’s say comedy, if the cutscene of a tough encounter starts with a joke, it could be funny as hell but after hearing it 5 times...&lt;/p&gt;
&lt;p&gt;Repetition especially in a particularly tough encounter destroys the atmosphere that we were led with. Watching the same cutscene over and over again, going for that health pack on the side every time because you know you’ll need it in the 2nd phase, I mean I get it. That’s what we are here for, the gameplay.&lt;/p&gt;
&lt;p&gt;The ability to make different choices or planning ahead this time, that’s our hook. That’s where our agency is. And the more options (read viable options) we have, the better the game is.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Resident Evil 7&lt;/strong&gt;&lt;/em&gt;’s first boss fight against Jack Baker, even though that first shock of “&lt;em&gt;I’m supposed to deal with this guy&lt;/em&gt;” may subside on multiple attempts but … I am free to move, to explore, find weapons, map out the area in my head for quick getaways. I have strategies to try. It doesn’t feel repetitive. And it’s one of my favorite boss fights in any horror game.&lt;/p&gt;
&lt;p&gt;But the problem comes with games which are light on gameplay. The story or atmosphere focused ones. There are those of us who enjoy being put into situations like these. However, not having a proper combat system or enough options means I’m basically doing the same thing every time. Which you may call a bad game and you may as well be right.&lt;/p&gt;
&lt;p&gt;So, is the solution just to make horror games easier?&lt;/p&gt;
&lt;p&gt;Well, maybe. But let’s not forget it’s a game. And game difficulty is already a huge topic of discussion I’m not looking to get into right now.&lt;/p&gt;
&lt;p&gt;No, what I’m thinking is, I just don’t think I should be allowed to replay that encounter.&lt;/p&gt;
&lt;p&gt;I can hear you in my head: &lt;em&gt;“So, what are you saying, skip the encounter?”&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Well, kinda. Or, make the death/loss canon.&lt;/p&gt;
&lt;p&gt;Yes, that fight happened. Yes, now you have lost your left hand permanently. And hence, you can’t reload anymore.&lt;/p&gt;
&lt;p&gt;Now that option is treading into the game difficulty waters again so I’m just putting it there for the sake of options. If you’ve got a good combat system I think it can be done.&lt;/p&gt;
&lt;p&gt;But what about my dear ol’ walking simulators with run and hide mechanics?&lt;/p&gt;
&lt;p&gt;In those cases yes, for the love of all lovecraftian horror, skip that encounter. You are killing the atmosphere, game! I’ve seen the makeup that dude puts on, I’ve seen the eyelashes. I know on which corners its path-finding breaks. I’m not afraid anymore. I know I’m dealing with a moron.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;But Klad, skipping content is a cardinal sin. How can we possibly…&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Blah blah blah. Skip it. Skip the damn thing already. It spooked me, and I wasn’t ready. The job is done. Now I don’t know what to expect. I’m on my toes. The game is willing to screw with me and not give me a chance to retry. Isn’t that crazy? Shock in a horror game? Color me white.&lt;/p&gt;
&lt;p&gt;Skipped content is scary. Losing a vital resource or an NPC you care about permanently because of your own poor planning/ability is scary. The feeling of loss is real and personal. Isn’t that what games should aspire to be?&lt;/p&gt;
&lt;p&gt;Alright enough with the sermonizing.&lt;/p&gt;
&lt;p&gt;Look, I know this option has its own issues. For one, it really reduces the effective length of a game and I know some people hate that. All I know is, being able to retry is killing the atmosphere. Revealing cracks that shouldn’t be visible and putting far too much stress on systems that were not designed with replayability in mind.&lt;/p&gt;
&lt;p&gt;And that’s just not how you do horror.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;You get all that &lt;strong&gt;Call of Cthulhu&lt;/strong&gt;?&lt;/em&gt;&lt;/p&gt;
</content:encoded><author>Eklavya Mishra</author></item><item><title>Civilization, Myth, and Savagery: Reading Lord of the Flies</title><link>https://theleakycauldronblog.com/articles/lord-of-the-flies</link><guid isPermaLink="true">https://theleakycauldronblog.com/articles/lord-of-the-flies</guid><description>&lt;img alt=&quot;Civilization, Myth, and Savagery: Reading Lord of the Flies&quot; src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Flordoftheflies.D3-4wJ7x.png&amp;w=1536&amp;h=1024&amp;dpl=699bfef0c4120e00087ee35a&quot; /&gt; On a deserted island, Golding’s “Lord of the Flies” explores the collapse of civilization, questioning whether savagery is humanity’s fate or if culture and cooperation can prevail.</description><pubDate>Sat, 06 Sep 2025 08:38:00 GMT</pubDate><content:encoded>&lt;p&gt;After reading &lt;em&gt;Lord of the Flies&lt;/em&gt;, it’s tempting to accept William Golding’s grim hypothesis — that without the rules of civilization, children (and by extension, humans) descend into savagery. The novel unsettles precisely because it pokes at a myth Western societies have long told themselves: that schooling and tradition civilize us.&lt;/p&gt;
&lt;h2&gt;Golding&apos;s Background&lt;/h2&gt;
&lt;p&gt;Golding won the &lt;a href=&quot;https://www.nobelprize.org/prizes/literature/1983/press-release/&quot;&gt;Nobel Prize for Literature in 1983&lt;/a&gt;, and commentators never fail to note how profoundly he was shaped by war. He had served as a naval officer in World War II, witnessing the D-Day landings and the horrific destructiveness of modern conflict. These experiences stripped him of youthful optimism about human goodness.&lt;/p&gt;
&lt;p&gt;Seen in that light, &lt;em&gt;Lord of the Flies&lt;/em&gt; is a &lt;strong&gt;multi-faceted allegory&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;political allegory&lt;/strong&gt;, dramatizing the fragility of democracy.&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;psychological allegory&lt;/strong&gt;, mapping Freudian drives (id, ego, superego) onto its characters.&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;religious allegory&lt;/strong&gt;, with Simon’s Christ-like martyrdom.&lt;/li&gt;
&lt;li&gt;And most centrally, an allegory of &lt;strong&gt;war itself&lt;/strong&gt; — showing how quickly human beings turn to violence when stripped of external order.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Golding was also, in many ways, offering a fictional argument in line with &lt;strong&gt;Thomas Hobbes’s &lt;em&gt;Leviathan&lt;/em&gt;&lt;/strong&gt; (1651), which famously argued that in the “state of nature” life is “solitary, poor, nasty, brutish, and short.”&lt;/p&gt;
&lt;h2&gt;The Eton–Waterloo Myth&lt;/h2&gt;
&lt;p&gt;Take the famous line:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;The Battle of Waterloo was won on the playing fields of Eton.&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Supposedly uttered by the Duke of Wellington (though almost certainly apocryphal), it became shorthand for the idea that elite British schools instilled discipline, teamwork, and leadership through games.&lt;/p&gt;
&lt;p&gt;This was myth-making at its finest:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;False cause fallacy&lt;/strong&gt; – Wars are won by logistics, strategy, and manpower, not cricket.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Exclusivity bias&lt;/strong&gt; – Most soldiers at Waterloo weren’t Etonians; the victory was collective, not aristocratic.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Propaganda&lt;/strong&gt; – The line justified elite dominance by pretending privilege produced virtue.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In short, the “playing fields” weren’t about education; they were about producing obedient officers and administrators. Schools functioned less like centers of learning, more like &lt;strong&gt;factories of hierarchy&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;Golding’s Rebuttal&lt;/h2&gt;
&lt;p&gt;Golding’s boys are straight out of that British school culture. If the Eton myth were true, they should have embodied resilience and teamwork. Instead, stripped of adult authority, the structure collapses: rivalry, fear, and violence take over.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Lord of the Flies&lt;/em&gt; reads like a direct contradiction of the Waterloo slogan. Where the myth glorifies discipline and leadership, Golding reveals how thin that veneer really is. The training doesn’t hold; savagery lurks beneath.&lt;/p&gt;
&lt;p&gt;Golding’s argument is more than narrative pessimism — it’s a literary counterattack against a cherished national story. The “playing fields” didn’t save Europe from tyranny; they masked the same impulses that fueled fascism and war.&lt;/p&gt;
&lt;h2&gt;The Tongan Counterexample&lt;/h2&gt;
&lt;p&gt;Critics often point to the 1965 case of six Tongan boys, aged 13–16, who survived over a year on a deserted island. Unlike Golding’s children, they cooperated — building gardens, sharing food, and caring for the injured until rescue.&lt;/p&gt;
&lt;p&gt;At first glance, this real-world story undermines Golding’s thesis. Yet comparing the two is a &lt;strong&gt;false equivalence&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Golding’s boys were younger, strangers, and written as products of a competitive, individualistic culture.&lt;/li&gt;
&lt;li&gt;The Tongans were older, already friends, and grounded in collectivist Polynesian values.&lt;/li&gt;
&lt;li&gt;Different ages, different cultures, different contexts.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The Tongans show that cooperation is possible — but it’s shaped by culture and bonds of trust. Golding wasn’t denying cooperation exists; he was warning how easily fragile social systems can unravel when they lack those supports.&lt;/p&gt;
&lt;p&gt;This aligns with more optimistic views of humanity, such as &lt;strong&gt;Jean-Jacques Rousseau’s idea&lt;/strong&gt; that humans are born good and corrupted by society — and with modern works like &lt;strong&gt;Rutger Bregman’s &lt;em&gt;Humankind: A Hopeful History&lt;/em&gt; (2020)&lt;/strong&gt;, which argues that cooperation is our default instinct.&lt;/p&gt;
&lt;h2&gt;Schools as Factories&lt;/h2&gt;
&lt;p&gt;Put together, these stories highlight the real role of schools in the industrial and imperial age. They were less about nurturing curiosity and more about producing soldiers, workers, and administrators. Bells, uniforms, rigid schedules — all echoes of the factory floor.&lt;/p&gt;
&lt;p&gt;The Eton myth celebrates this as a virtue. Golding exposes its fragility. The Tongans remind us that cooperation and resilience can emerge — but only where culture and relationships make it possible.&lt;/p&gt;
&lt;p&gt;In a sense, Golding was writing not just against the Eton myth, but against the very assumption that discipline alone equals civilization. He suggests instead that civilization is precarious, requiring constant moral choice, not just training.&lt;/p&gt;
&lt;p&gt;Modern psychology reinforces this point. The infamous &lt;strong&gt;Stanford Prison Experiment (1971)&lt;/strong&gt; by Philip Zimbardo showed how quickly ordinary people can adopt cruelty when authority structures collapse or shift. Like Golding’s novel, it suggested that savagery is never far below the surface.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Golding’s pessimism wasn’t universal, but it was pointed: the stories elites tell about civilization are often myths designed to preserve power. Whether through slogans like “Waterloo was won at Eton” or the sanitized image of schooling, the underlying assumption is the same — discipline equals virtue.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Lord of the Flies&lt;/em&gt; forces us to ask:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;What happens when those myths are stripped away?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;What happens when humans devolve?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Golding leaves us with a haunting possibility: without culture, compassion, and constant vigilance, civilization is only a mask.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Can humanity rise above savagery at its most desperate times?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
</content:encoded><author>Rishabh Chakrabarti</author></item><item><title>Chhupa Sa Kuch — छुपा-सा कुछ</title><link>https://theleakycauldronblog.com/articles/chhupa-sa-kuch-vyom</link><guid isPermaLink="true">https://theleakycauldronblog.com/articles/chhupa-sa-kuch-vyom</guid><description>&lt;img alt=&quot;Chhupa Sa Kuch — छुपा-सा कुछ&quot; src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Fchhupa-sa-kuch-vyom-erik-odiin.H-XO_exV.jpg&amp;w=1920&amp;h=1280&amp;dpl=699bfef0c4120e00087ee35a&quot; /&gt; Amidst life&apos;s trials and tribulations, this poem reflects on the silent struggles and the quest for understanding in a world that seems indifferent.</description><pubDate>Fri, 20 Jun 2025 12:30:00 GMT</pubDate><content:encoded>&lt;p&gt;A haunting exploration of life&apos;s trial, loneliness and the search for connection by author &lt;strong&gt;&lt;a href=&quot;https://theleakycauldronblog.com/search?q=vyom&quot;&gt;Vyom&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;छुपा-सा कुछ — Vyom&lt;/h2&gt;
&lt;p&gt;क्या लिखूं कि जीवन में कठिनाई है,&lt;/p&gt;
&lt;p&gt;ये भी लिख लूं तो फिर पढ़ाऊं किसको?&lt;/p&gt;
&lt;p&gt;सोचता हूँ — चीखें सुनाऊँ जो मुँह से निकल ही नहीं रहीं,&lt;/p&gt;
&lt;p&gt;या एक ग़ज़ल बनाऊँ… और बहलाऊँ सबको।&lt;/p&gt;
&lt;p&gt;&amp;lt;br&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;br&amp;gt;&lt;/p&gt;
&lt;p&gt;सब कुछ टूट रहा है, और मैं ईंटें समेट रहा हूँ,&lt;/p&gt;
&lt;p&gt;इन्हें जोड़ दूँ, एक महल बनाऊँ — पर उसमें ठहराऊँ किसको?&lt;/p&gt;
&lt;p&gt;&amp;lt;br&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;br&amp;gt;&lt;/p&gt;
&lt;p&gt;एक वक़्त था जब पाना था बहुत कुछ,&lt;/p&gt;
&lt;p&gt;अब कुछ पाया है — पर वो दिखाऊँ किसको?&lt;/p&gt;
&lt;p&gt;&amp;lt;br&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;br&amp;gt;&lt;/p&gt;
&lt;p&gt;मुँह मोड़ लिया है हर किसी ने, पर खुदगर्ज़ भी हैं सब,&lt;/p&gt;
&lt;p&gt;जिन्हें बुलाऊँ, वो आ भी जाएंगे — पर अब मैं बुलाऊँ किसको?&lt;/p&gt;
&lt;p&gt;&amp;lt;br&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;br&amp;gt;&lt;/p&gt;
&lt;p&gt;अब मन नहीं करता अपनी किस्मत से लड़ने का…&lt;/p&gt;
&lt;p&gt;बात बस इतनी सी है — पर ये बतलाऊँ किसको?&lt;/p&gt;
</content:encoded><author>Vyom</author></item><item><title>Flowers Too Late</title><link>https://theleakycauldronblog.com/articles/flowers-too-late-neha-ramrakhyani</link><guid isPermaLink="true">https://theleakycauldronblog.com/articles/flowers-too-late-neha-ramrakhyani</guid><description>&lt;img alt=&quot;Flowers Too Late&quot; src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Fstarry-night.CQqU3aM8.jpg&amp;w=1920&amp;h=1200&amp;dpl=699bfef0c4120e00087ee35a&quot; /&gt; A poignant reflection on the unrecognized struggles of artists, the value of art, and the legacy of creativity in a world that often fails to listen.</description><pubDate>Sun, 16 Mar 2025 12:30:00 GMT</pubDate><content:encoded>&lt;p&gt;A heartfelt tribute to the unseen artists, their struggles, and the enduring power of art to heal and console.&lt;/p&gt;
&lt;h2&gt;Flowers Too Late — Neha Ramrakhyani&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Art is to console those who are broken by life. — Vincent Van Gogh&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I&apos;ve often found myself thinking and writing about art.&lt;/p&gt;
&lt;p&gt;Can we ever concise its gravity in words?&lt;/p&gt;
&lt;p&gt;Can we ever capture its depth in colors?&lt;/p&gt;
&lt;p&gt;Art is everything, everywhere and everyone,&lt;/p&gt;
&lt;p&gt;Yet it&apos;s nothing at all if not valued.&lt;/p&gt;
&lt;p&gt;So many artists die unrecognized, unappreciated.&lt;/p&gt;
&lt;p&gt;And we don&apos;t just lose life when we lose an artist,&lt;/p&gt;
&lt;p&gt;We lose a perspective, a vision, a story, we lose art.&lt;/p&gt;
&lt;p&gt;We lose what could have been a way of living, a masterpiece in making,&lt;/p&gt;
&lt;p&gt;We lose a voice that had courage to speak but fell on deaf ears.&lt;/p&gt;
&lt;p&gt;What good is it when you honor him by putting flowers on his grave,&lt;/p&gt;
&lt;p&gt;When all his life you made him feel like he had done nothing but failed.&lt;/p&gt;
&lt;p&gt;&amp;lt;br /&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;br /&amp;gt;&lt;/p&gt;
&lt;p&gt;When actually it was you who had failed,&lt;/p&gt;
&lt;p&gt;To recognize the greatness in the numbered days he persisted,&lt;/p&gt;
&lt;p&gt;While he struggled to find a single companion that would stay.&lt;/p&gt;
&lt;p&gt;I often feel that artists perceive things differently, a tad too deeply, a little more intensely.&lt;/p&gt;
&lt;p&gt;Perhaps that&apos;s their greatness and also their tragedy.&lt;/p&gt;
&lt;p&gt;And I feel everyone is capable of feeling the same way,&lt;/p&gt;
&lt;p&gt;And they surely would, if there was a job for it that would pay.&lt;/p&gt;
&lt;p&gt;I wonder what will happen to me and my words,&lt;/p&gt;
&lt;p&gt;Will my voice be heard or will flowers be put on my grave?&lt;/p&gt;
&lt;p&gt;Vincent says art is to console those who are broken by life,&lt;/p&gt;
&lt;p&gt;I say, art is to heal the artists who refuse to be broken by life.&lt;/p&gt;
</content:encoded><author>Neha Ramrakhyani</author></item><item><title>Optimization Strategies and Best Practices in React Native</title><link>https://theleakycauldronblog.com/articles/optimizing-performance-react-native</link><guid isPermaLink="true">https://theleakycauldronblog.com/articles/optimizing-performance-react-native</guid><description>&lt;img alt=&quot;Optimization Strategies and Best Practices in React Native&quot; src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Frob-hampson-react-native-optimization.-xVawtr5.jpg&amp;w=1920&amp;h=1280&amp;dpl=699bfef0c4120e00087ee35a&quot; /&gt; By implementing these optimization strategies, you can significantly improve your React Native app’s speed, memory usage, and responsiveness.</description><pubDate>Tue, 25 Feb 2025 12:30:00 GMT</pubDate><content:encoded>&lt;p&gt;React Native enables developers to build cross-platform apps efficiently, but achieving optimal performance requires careful tuning. Without optimizations, React Native apps can suffer from slow rendering, memory leaks, and sluggish UI interactions, especially on lower-end devices.&lt;/p&gt;
&lt;p&gt;In this guide, we’ll explore key performance bottlenecks and proven strategies to optimize your React Native app for a smoother user experience.&lt;/p&gt;
&lt;h2&gt;Optimizing Rendering Performance&lt;/h2&gt;
&lt;h3&gt;Avoid Unnecessary Re-Renders with &lt;code&gt;memo&lt;/code&gt; and &lt;code&gt;useCallback&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;By default, React components &lt;strong&gt;re-render&lt;/strong&gt; when their parent re-renders, which can cause performance bottlenecks.&lt;/p&gt;
&lt;p&gt;Use &lt;code&gt;React.memo&lt;/code&gt; to prevent unnecessary re-renders:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import React, { memo } from &apos;react&apos;;

const ExpensiveComponent = memo(({ data }) =&amp;gt; {
  console.log(&apos;Rendered&apos;);
  return &amp;lt;Text&amp;gt;{data}&amp;lt;/Text&amp;gt;;
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Use &lt;code&gt;useCallback&lt;/code&gt; to avoid regenerating functions in child components:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const handlePress = useCallback(() =&amp;gt; {
  console.log(&apos;Button clicked&apos;);
}, []);
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Use &lt;code&gt;FlatList&lt;/code&gt; Instead of &lt;code&gt;ScrollView&lt;/code&gt; for Large Lists:&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;ScrollView&lt;/code&gt; renders &lt;strong&gt;all items at once&lt;/strong&gt;, causing memory and performance issues for long lists. Instead, use &lt;code&gt;FlatList&lt;/code&gt; for efficient lazy loading.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;FlatList
  data={items}
  renderItem={({ item }) =&amp;gt; &amp;lt;ItemComponent item={item} /&amp;gt;}
  keyExtractor={(item) =&amp;gt; item.id}
/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Use &lt;code&gt;useEffect&lt;/code&gt; and &lt;code&gt;useMemo&lt;/code&gt; Wisely&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Minimize unnecessary computations&lt;/strong&gt; inside components with useMemo:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const computedValue = useMemo(() =&amp;gt; expensiveCalculation(data), [data]);
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Only re-run side effects when needed&lt;/strong&gt; using useEffect with dependency arrays:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;useEffect(() =&amp;gt; {
  fetchData();
}, []); // Runs only once
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Reducing JavaScript Thread Load&lt;/h2&gt;
&lt;h3&gt;Optimize JavaScript Execution with &lt;code&gt;InteractionManager&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;If you have heavy computations, move them to the background using &lt;code&gt;InteractionManager.runAfterInteractions&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import { InteractionManager } from &apos;react-native&apos;;

useEffect(() =&amp;gt; {
  InteractionManager.runAfterInteractions(() =&amp;gt; {
    expensiveOperation();
  });
}, []);
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Improving UI Performance&lt;/h2&gt;
&lt;h3&gt;Enable Hermes for Faster Startup Times&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/facebook/hermes/blob/main/README.md&quot;&gt;Hermes&lt;/a&gt; is an optimized JavaScript engine that improves execution speed and memory usage.&lt;/p&gt;
&lt;p&gt;On Android, enable Hermes in &lt;code&gt;android/app/build.gradle&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;project.ext.react = [
  enableHermes: true  // Set to true
]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For iOS, turn the &lt;code&gt;hermes_enabled&lt;/code&gt; flag to true in &lt;code&gt;ios/Podfile&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;use_react_native!(
  :path =&amp;gt; config[:reactNativePath],
  # to enable hermes on iOS, change `false` to `true` and
then install pods
  :hermes_enabled =&amp;gt; true
)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Use Native Driver for Animations&lt;/h3&gt;
&lt;p&gt;React Native’s &lt;strong&gt;JS-based animations&lt;/strong&gt; block the JS thread, causing lag. Enable the &lt;strong&gt;native driver&lt;/strong&gt; to shift animations to the UI thread. You can use the native driver by specifying &lt;code&gt;useNativeDriver: true&lt;/code&gt; in your animation configuration.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Animated.timing(animatedValue, {
  toValue: 1,
  duration: 500,
  useNativeDriver: true, // Moves animations to native thread
}).start();
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Memory Management and Avoiding Leaks&lt;/h2&gt;
&lt;h3&gt;Remove Unmounted Listeners&lt;/h3&gt;
&lt;p&gt;Unremoved listeners cause memory leaks. Clean up listeners in &lt;code&gt;useEffect&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;useEffect(() =&amp;gt; {
  const subscription = eventEmitter.addListener(&apos;event&apos;, callback);
  return () =&amp;gt; subscription.remove(); // Cleanup
}, []);
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Optimizing Network and Data Fetching&lt;/h2&gt;
&lt;h3&gt;Use Pagination Instead of Fetching Everything at Once&lt;/h3&gt;
&lt;p&gt;If fetching large datasets, implement pagination:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const fetchMoreData = () =&amp;gt; {
  fetch(`https://api.example.com/data?page=${nextPage}`)
    .then((res) =&amp;gt; res.json())
    .then((newData) =&amp;gt; setData([...data, ...newData]));
};

&amp;lt;FlatList
  data={data}
  onEndReached={fetchMoreData}
  onEndReachedThreshold={0.5}
/&amp;gt;;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Use &lt;code&gt;tanstack/react-query&lt;/code&gt; for Caching and Background Fetching&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://tanstack.com/query/latest&quot;&gt;tanstack/react-query&lt;/a&gt; efficiently caches data and refetches in the background, improving perceived speed.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import React from &apos;react&apos;
import { useIsFocused } from &apos;@react-navigation/native&apos;
import { useQuery } from &apos;@tanstack/react-query&apos;
import { Text } from &apos;react-native&apos;

function MyComponent() {
  const isFocused = useIsFocused()

  const { dataUpdatedAt } = useQuery({
    queryKey: [&apos;key&apos;],
    queryFn: () =&amp;gt; fetch(...),
    subscribed: isFocused,
  })

  return &amp;lt;Text&amp;gt;DataUpdatedAt: {dataUpdatedAt}&amp;lt;/Text&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Bundle Size Optimization&lt;/h2&gt;
&lt;h3&gt;Enable Code Splitting and Dynamic Imports&lt;/h3&gt;
&lt;p&gt;Reduce initial bundle size by &lt;strong&gt;lazy-loading&lt;/strong&gt; components:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const HeavyComponent = React.lazy(() =&amp;gt; import(&apos;./HeavyComponent&apos;));

&amp;lt;Suspense fallback={&amp;lt;Loader /&amp;gt;}&amp;gt;
  &amp;lt;HeavyComponent /&amp;gt;
&amp;lt;/Suspense&amp;gt;;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Reduce Package Bloat&lt;/h3&gt;
&lt;p&gt;Audit and remove unnecessary libraries:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;npx depcheck
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Replace large libraries with lighter alternatives:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;moment.js&lt;/code&gt; → &lt;code&gt;date-fns&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;lodash&lt;/code&gt; → native JS functions (&lt;a href=&quot;https://github.com/you-dont-need/You-Dont-Need-Lodash-Underscore&quot;&gt;You Don&apos;t Need Lodash&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Debugging Performance Bottlenecks&lt;/h2&gt;
&lt;h3&gt;Use React Native Performance Monitors&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Enable &lt;strong&gt;Perf Monitor&lt;/strong&gt;: &lt;code&gt;Cmd + M&lt;/code&gt; (Android) or &lt;code&gt;Cmd + D&lt;/code&gt; (iOS)&lt;/li&gt;
&lt;li&gt;Profile your app with &lt;a href=&quot;https://fbflipper.com/docs/features/react-native/&quot;&gt;Flipper&lt;/a&gt; and &lt;a href=&quot;https://reactnative.dev/docs/react-native-devtools&quot;&gt;React Native DevTools&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Check JS Frame Rate&lt;/h3&gt;
&lt;p&gt;Use the &lt;a href=&quot;https://reactnative.dev/docs/performance&quot;&gt;FPS monitor&lt;/a&gt; to check frame drops.&lt;/p&gt;
&lt;p&gt;By following these best practices, your React Native app will run smoothly and efficiently, ensuring a better user experience across devices.&lt;/p&gt;
</content:encoded><author>Vaibhav Sharma</author></item><item><title>React and WebAssembly: Unlocking High-Performance Apps</title><link>https://theleakycauldronblog.com/articles/react-and-webassembly-unlocking-high-performance-apps</link><guid isPermaLink="true">https://theleakycauldronblog.com/articles/react-and-webassembly-unlocking-high-performance-apps</guid><description>&lt;img alt=&quot;React and WebAssembly: Unlocking High-Performance Apps&quot; src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Ffrancesco-ungaro-rust-reactjs-webassembly.C9vRVcQy.jpg&amp;w=1920&amp;h=1280&amp;dpl=699bfef0c4120e00087ee35a&quot; /&gt; In this post, we’ll explore what WebAssembly is, why you’d want to use it with React, and how to get started.</description><pubDate>Sun, 09 Feb 2025 12:30:00 GMT</pubDate><content:encoded>&lt;p&gt;Web performance is more important than ever. With applications becoming more complex, developers are constantly looking for ways to optimize performance. One of the most exciting advancements in web development is &lt;strong&gt;WebAssembly (WASM)&lt;/strong&gt; — a low-level, binary instruction format that runs in the browser at near-native speed. When combined with &lt;strong&gt;React&lt;/strong&gt;, WebAssembly opens up new possibilities for building high-performance web applications.&lt;/p&gt;
&lt;h2&gt;🚀 What is WebAssembly (WASM)?&lt;/h2&gt;
&lt;p&gt;WebAssembly (WASM) is a &lt;strong&gt;portable binary format&lt;/strong&gt; that allows code written in languages like &lt;strong&gt;C&lt;/strong&gt;, &lt;strong&gt;C++&lt;/strong&gt;, &lt;strong&gt;Rust&lt;/strong&gt;, and others to run in the browser at native speed. It was designed to complement JavaScript, enabling performance-critical parts of your application to be written in more efficient languages while still integrating seamlessly with the web ecosystem.&lt;/p&gt;
&lt;h3&gt;Key Features of WebAssembly&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;High Performance:&lt;/strong&gt; Near-native execution speed.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Portability:&lt;/strong&gt; Runs on all major browsers and platforms.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Interoperability:&lt;/strong&gt; Works alongside JavaScript.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Security:&lt;/strong&gt; Sandboxed environment for safe execution.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Why Use WebAssembly with React?&lt;/h2&gt;
&lt;p&gt;React is already a performant library for building user interfaces, but for CPU-intensive tasks, such as real-time data processing, image manipulation, or 3D rendering, JavaScript may hit its limits. This is where WebAssembly shines.&lt;/p&gt;
&lt;h3&gt;Use Cases for React + WebAssembly&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Real-time Data Visualization:&lt;/strong&gt; Handling large datasets or complex calculations without blocking the UI.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Multimedia Processing:&lt;/strong&gt; Image, audio, and video manipulation.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Gaming and 3D Graphics:&lt;/strong&gt; Powering graphics-heavy applications using WebGL.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cryptography and Compression:&lt;/strong&gt; High-performance encryption, compression, and decompression in the browser.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Machine Learning:&lt;/strong&gt; Running inference for trained ML models in the browser.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Setting Up WebAssembly with React&lt;/h2&gt;
&lt;p&gt;Let’s walk through a simple example of integrating WebAssembly in a React app. For this demo, we’ll use &lt;strong&gt;Rust&lt;/strong&gt; to write a WebAssembly module.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 1: Install Rust and &lt;code&gt;wasm-pack&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;First, install Rust and the &lt;code&gt;wasm-pack&lt;/code&gt; tool, which helps compile Rust into WebAssembly.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;curl --proto &apos;=https&apos; --tlsv1.2 -sSf https://sh.rustup.rs | sh  
cargo install wasm-pack
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Step 2: Create a Rust Library&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Create a new Rust project and add a function to calculate the Fibonacci sequence (a CPU-heavy task).Create a new Rust project and add a function to calculate the Fibonacci sequence (a CPU-heavy task).&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// src/lib.rs
#[no_mangle]
pub fn fibonacci(n: u32) -&amp;gt; u32 {
    match n {
        0 =&amp;gt; 0,
        1 =&amp;gt; 1,
        _ =&amp;gt; fibonacci(n - 1) + fibonacci(n - 2),
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Step 3: Compile to WebAssembly&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Use &lt;code&gt;wasm-pack&lt;/code&gt; to compile the Rust project to WebAssembly.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;wasm-pack build --target web
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Step 4: Integrate WebAssembly in React&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In your React app, import and use the generated WebAssembly module.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import React, { useState } from &apos;react&apos;;

function App() {
  const [fibResult, setFibResult] = useState&amp;lt;number | null&amp;gt;(null);

  const calculateFibonacci = async (n: number) =&amp;gt; {
    const wasm = await import(&apos;./wasm_module&apos;);  // Import your Wasm module
    const result = wasm.fibonacci(n);
    setFibResult(result);
  };

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;h1&amp;gt;React + WebAssembly Example&amp;lt;/h1&amp;gt;
      &amp;lt;input
        type=&quot;number&quot;
        placeholder=&quot;Enter a number&quot;
        onChange={(e) =&amp;gt; calculateFibonacci(Number(e.target.value))}
      /&amp;gt;
      {fibResult !== null &amp;amp;&amp;amp; &amp;lt;p&amp;gt;Fibonacci Result: {fibResult}&amp;lt;/p&amp;gt;}
    &amp;lt;/div&amp;gt;
  );
}

export default App;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Performance Gains: What to Expect&lt;/h2&gt;
&lt;p&gt;By offloading computationally intensive tasks to WebAssembly, you can reduce UI blocking and improve the responsiveness of your React app. However, WebAssembly isn’t always the best solution for every problem. Use it when &lt;strong&gt;raw performance is essential&lt;/strong&gt;, and stick to JavaScript for simpler tasks to avoid unnecessary complexity.&lt;/p&gt;
&lt;h2&gt;Best Practices for React and WebAssembly Integration&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Benchmark First:&lt;/strong&gt; Ensure that the performance gains justify the added complexity.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Avoid Over-Optimization:&lt;/strong&gt; Not everything needs to be written in WebAssembly. Use it where it makes the most impact.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Memory Management:&lt;/strong&gt; Be mindful of WebAssembly’s memory model. Share data between JavaScript and WASM efficiently.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Error Handling:&lt;/strong&gt; WASM debugging can be tricky. Use tools like &lt;code&gt;wasm-bindgen&lt;/code&gt; and &lt;code&gt;console.error&lt;/code&gt; for better error tracking.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;The Future of React and WebAssembly&lt;/h2&gt;
&lt;p&gt;As WebAssembly continues to evolve (with features like garbage collection and threading on the horizon), it’s poised to play a significant role in the future of web development. When combined with React, it opens up new doors for high-performance, interactive web applications that were previously impossible to build with pure JavaScript. Tools like &lt;strong&gt;Figma&lt;/strong&gt;, &lt;strong&gt;AutoDesk&lt;/strong&gt; and &lt;strong&gt;Tensorflow.js&lt;/strong&gt; already leverage WASM, and list is just gonna keep growing.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Want to go deeper?&lt;/strong&gt; Let me know if you’d like a follow-up post on optimizing WebAssembly memory or integrating WebAssembly with other frameworks like &lt;strong&gt;Next.js&lt;/strong&gt;!&lt;/p&gt;
</content:encoded><author>Vaibhav Sharma</author></item><item><title>In Bruges — Harry Potter Edition</title><link>https://theleakycauldronblog.com/articles/in-bruges-harry-potter-edition</link><guid isPermaLink="true">https://theleakycauldronblog.com/articles/in-bruges-harry-potter-edition</guid><description>&lt;img alt=&quot;In Bruges — Harry Potter Edition&quot; src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Fin-bruges.B1hdjg-k.jpg&amp;w=1440&amp;h=810&amp;dpl=699bfef0c4120e00087ee35a&quot; /&gt; This &quot;magical&quot; version of In Bruges definitely adds a Harry Potter twist to it, but the dark humor and poetic themes remain.</description><pubDate>Mon, 03 Feb 2025 12:30:00 GMT</pubDate><content:encoded>&lt;p&gt;I was watching In Bruges, and I thoroughly enjoyed the movie. However, the number of actors who have appeared in both In Bruges and the Harry Potter franchise gave me a magical perspective on the movie...&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Warning: Spoilers&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Gellert Grindelwald&lt;/strong&gt; and &lt;strong&gt;Alastor “Mad-Eye” Moody&lt;/strong&gt; are two wizards — er, hitmen — hiding out in the fairytale (well, technically Muggle) city of Bruges after a job gone horribly wrong. They’ve been sent there by their ruthless boss, &lt;strong&gt;Lord Voldemort&lt;/strong&gt; (who is coincidentally named &lt;em&gt;Harry&lt;/em&gt; in the movie), to lay low.&lt;/p&gt;
&lt;p&gt;Grindelwald, young and brash, absolutely hates Bruges. The medieval charm, the canals, the gothic architecture — it’s all wasted on him. He complains non-stop to Moody, who, being older and more experienced, actually enjoys the city’s history and culture. But Grindelwald is impatient, restless, and haunted by their last job.&lt;/p&gt;
&lt;p&gt;Through a series of wanderings, Grindelwald meets &lt;strong&gt;Fleur Delacour&lt;/strong&gt;, a beautiful and mysterious woman involved in the local film industry. He’s immediately drawn to her and starts pursuing a romance. Meanwhile, Moody takes a more measured approach to their exile, sightseeing and reflecting on their predicament.&lt;/p&gt;
&lt;p&gt;As it turns out, Grindelwald and Moody were sent to Bruges because, on their last job, Grindelwald accidentally killed a child while assassinating &lt;strong&gt;Aberforth Dumbledore&lt;/strong&gt;. This weighs heavily on Moody’s conscience, though Grindelwald tries to push the guilt away with drinking and partying. Their boss, Voldemort, is not pleased with the botched mission.&lt;/p&gt;
&lt;p&gt;Things take a turn when Voldemort calls Moody, revealing his true intention: Grindelwald must die for his mistake. Moody, who has grown fond of his reckless young partner, struggles with this command. He tries to persuade Grindelwald to leave Bruges, but Grindelwald, too wrapped up in his misadventures (which include a run-in with a racist house elf, Jimmy), doesn’t take him seriously.&lt;/p&gt;
&lt;p&gt;Eventually, Voldemort himself arrives in Bruges, bringing chaos with him. Grindelwald, realizing he’s been marked for death, attempts to flee, but a series of violent encounters lead to a final showdown in the city’s picturesque streets.&lt;/p&gt;
&lt;p&gt;As &lt;em&gt;Avada Kedavara&lt;/em&gt; — er, bullets — fly, Moody sacrifices himself to give Grindelwald a chance to escape, but Voldemort is relentless. In the end, Grindelwald, gravely wounded, is left contemplating his fate. Will he survive? Does he even want to, given the weight of his sins? As the screen fades to black, he wonders if Bruges — beautiful, quiet Bruges — is his own personal purgatory.&lt;/p&gt;
</content:encoded><author>Vaibhav Sharma</author></item><item><title>Critical Analysis of Union Budget 2025</title><link>https://theleakycauldronblog.com/articles/critical-analysis-union-budget-2025</link><guid isPermaLink="true">https://theleakycauldronblog.com/articles/critical-analysis-union-budget-2025</guid><description>&lt;img alt=&quot;Critical Analysis of Union Budget 2025&quot; src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Fishant-mishra-union-budget-2025.DW-nZcwx.jpg&amp;w=1920&amp;h=1323&amp;dpl=699bfef0c4120e00087ee35a&quot; /&gt; The Union Budget 2025 is growth-focused, investor-friendly, and pro-reform, but execution bottlenecks, fiscal risks, and global economic uncertainties could impact its success.</description><pubDate>Sat, 01 Feb 2025 12:30:00 GMT</pubDate><content:encoded>&lt;p&gt;The Union Budget 2025 presents a mix of ambitious reforms, fiscal prudence, and sector-specific incentives. While it introduces significant tax reliefs, infrastructure expansion, and targeted employment generation, there are concerns regarding fiscal consolidation, implementation challenges, and potential economic implications. Let&apos;s take a look at the budget’s major aspects.&lt;/p&gt;
&lt;h2&gt;Taxation &amp;amp; Fiscal Consolidation&lt;/h2&gt;
&lt;h3&gt;Positives:&lt;/h3&gt;
&lt;p&gt;✅ &lt;strong&gt;Income Tax Relief –&lt;/strong&gt; Raising the income tax exemption limit to ₹12 lakh is a significant move that boosts disposable income and encourages consumption. It also simplifies tax filing for middle-class taxpayers.&lt;/p&gt;
&lt;p&gt;✅ &lt;strong&gt;Simplification of TDS/TCS –&lt;/strong&gt; Reducing compliance burden will encourage investment and ease financial transactions.&lt;/p&gt;
&lt;h3&gt;Concerns:&lt;/h3&gt;
&lt;p&gt;❌ &lt;strong&gt;Fiscal Deficit Concerns –&lt;/strong&gt; While the government aims to reduce fiscal deficit to 4.4% of GDP (from 4.8%), its ambitious expenditure on welfare schemes and infrastructure raises concerns about how revenue shortfalls will be covered. More details on deficit financing are needed.&lt;/p&gt;
&lt;p&gt;❌ &lt;strong&gt;New Tax Code Uncertainty –&lt;/strong&gt; The budget proposes a new tax law next week, creating uncertainty about potential long-term tax regime changes. Businesses and investors may delay decisions until further clarity emerges.&lt;/p&gt;
&lt;h2&gt;Agriculture &amp;amp; Rural Development&lt;/h2&gt;
&lt;h3&gt;Positives:&lt;/h3&gt;
&lt;p&gt;✅ &lt;strong&gt;Dhan Dhanya Yojana &amp;amp; Credit Expansion –&lt;/strong&gt; Enhancing the Kisan Credit Card limit to ₹5 lakh will improve access to credit for farmers and boost agricultural productivity. The six-year pulses mission will help reduce import dependency.&lt;/p&gt;
&lt;p&gt;✅ &lt;strong&gt;Expansion of Agro-Based Sectors –&lt;/strong&gt; Establishing a Makhana Board in Bihar and increased government purchase of pulses ensure price stability for farmers.&lt;/p&gt;
&lt;h3&gt;Concerns:&lt;/h3&gt;
&lt;p&gt;❌ &lt;strong&gt;No Major Structural Reforms –&lt;/strong&gt; While subsidies and credit expansion are beneficial, there is no significant land reform policy or market-linked agricultural pricing mechanism, which are critical for long-term growth.&lt;/p&gt;
&lt;p&gt;❌ &lt;strong&gt;MSP &amp;amp; Procurement Uncertainty –&lt;/strong&gt; The budget lacks clarity on whether the government will increase Minimum Support Prices (MSP) or sustain large-scale procurement programs.&lt;/p&gt;
&lt;h2&gt;Infrastructure &amp;amp; Urban Development&lt;/h2&gt;
&lt;h3&gt;Positives:&lt;/h3&gt;
&lt;p&gt;✅ &lt;strong&gt;₹11.11 Lakh Crore Capex Allocation –&lt;/strong&gt; This is a continuation of the government’s infrastructure-driven growth strategy, expected to boost sectors like cement, steel, and construction.&lt;/p&gt;
&lt;p&gt;✅ &lt;strong&gt;Urban Challenge Fund (₹1 Lakh Crore) –&lt;/strong&gt; Encouraging states to revamp cities and water sanitation through competitive grants is an innovative governance approach.&lt;/p&gt;
&lt;h3&gt;Concerns:&lt;/h3&gt;
&lt;p&gt;❌ &lt;strong&gt;Execution Bottlenecks –&lt;/strong&gt; Infrastructure projects in India often face delays due to land acquisition issues, environmental clearances, and bureaucratic red tape. The budget does not specify how these hurdles will be addressed.&lt;/p&gt;
&lt;p&gt;❌ &lt;strong&gt;Dependence on States –&lt;/strong&gt; Many urban reforms (e.g., affordable housing, transport) require state-level cooperation. With differing political alignments, implementation may be slow.&lt;/p&gt;
&lt;h2&gt;Financial Sector Reforms&lt;/h2&gt;
&lt;h3&gt;Positives:&lt;/h3&gt;
&lt;p&gt;✅ &lt;strong&gt;100% FDI in Insurance –&lt;/strong&gt; This reform is expected to bring global players into India’s insurance market, increasing competition and expanding coverage.&lt;/p&gt;
&lt;p&gt;✅ &lt;strong&gt;MSME Credit Support –&lt;/strong&gt; Enhancing credit guarantees for small businesses (₹5 lakh limit on micro-enterprise credit cards) will improve liquidity and boost entrepreneurship.&lt;/p&gt;
&lt;h3&gt;Concerns:&lt;/h3&gt;
&lt;p&gt;❌ &lt;strong&gt;Banking Sector Risks –&lt;/strong&gt; While increased credit guarantees help businesses, they also increase the risk of NPAs (Non-Performing Assets) if borrowers fail to repay. India’s banking sector already struggles with bad loans.&lt;/p&gt;
&lt;p&gt;❌ &lt;strong&gt;Lack of Direct Support for NBFCs –&lt;/strong&gt; Many Non-Banking Financial Companies (NBFCs) play a key role in credit distribution, but the budget does not offer specific relief or funding for them.&lt;/p&gt;
&lt;h2&gt;Energy &amp;amp; Sustainability&lt;/h2&gt;
&lt;h3&gt;Positives:&lt;/h3&gt;
&lt;p&gt;✅ &lt;strong&gt;100 GW Nuclear Energy Plan –&lt;/strong&gt; This ambitious target will help India reduce coal dependency and transition to cleaner energy.&lt;/p&gt;
&lt;p&gt;✅ &lt;strong&gt;Exemptions for EV &amp;amp; Battery Sector –&lt;/strong&gt; Removing import duties on lithium-ion batteries will reduce costs for electric vehicle (EV) manufacturers, making EVs more affordable.&lt;/p&gt;
&lt;h3&gt;Concerns:&lt;/h3&gt;
&lt;p&gt;❌ &lt;strong&gt;Delayed Renewable Energy Transition –&lt;/strong&gt; The focus on nuclear energy over solar and wind raises concerns, as nuclear projects take decades to implement, whereas solar &amp;amp; wind can be scaled faster.&lt;/p&gt;
&lt;p&gt;❌ &lt;strong&gt;Lack of Carbon Taxation –&lt;/strong&gt; Despite global emphasis on carbon credits and emission reduction, the budget does not introduce incentives for green financing or carbon pricing.&lt;/p&gt;
&lt;h2&gt;Employment &amp;amp; Skill Development&lt;/h2&gt;
&lt;h3&gt;Positives:&lt;/h3&gt;
&lt;p&gt;✅ &lt;strong&gt;22 Lakh Jobs in Leather &amp;amp; Footwear –&lt;/strong&gt; This initiative will boost exports and create employment in labor-intensive manufacturing.&lt;/p&gt;
&lt;p&gt;✅ &lt;strong&gt;AI Research &amp;amp; Digital Education –&lt;/strong&gt; Allocating ₹500 crore for AI in education is a forward-thinking move, helping India compete in global AI advancements.&lt;/p&gt;
&lt;h3&gt;Concerns:&lt;/h3&gt;
&lt;p&gt;❌ &lt;strong&gt;Unclear Job Creation Strategy –&lt;/strong&gt; The budget mentions job creation but does not provide a structured employment generation roadmap. India needs 90 lakh jobs annually to absorb its workforce, but these initiatives may not be enough.&lt;/p&gt;
&lt;p&gt;❌ &lt;strong&gt;Limited Focus on Women’s Employment –&lt;/strong&gt; While there is a special scheme for women from backward classes, there is no large-scale initiative for urban working women or gender wage parity.&lt;/p&gt;
&lt;h2&gt;Fiscal Discipline &amp;amp; Debt Management&lt;/h2&gt;
&lt;h3&gt;Positives:&lt;/h3&gt;
&lt;p&gt;✅ &lt;strong&gt;Lower Fiscal Deficit Target –&lt;/strong&gt; Reducing fiscal deficit to 4.4% of GDP signals the government’s intent to maintain economic discipline.&lt;/p&gt;
&lt;h3&gt;Concerns:&lt;/h3&gt;
&lt;p&gt;❌ &lt;strong&gt;Borrowing Dependency –&lt;/strong&gt; The government plans to borrow ₹11.5 trillion, raising concerns about rising interest payments and debt sustainability.&lt;/p&gt;
&lt;p&gt;❌ &lt;strong&gt;Revenue Assumptions May Be Optimistic –&lt;/strong&gt; The budget assumes high tax collections and disinvestment targets, but global economic uncertainties (geopolitical tensions, slowing growth) may impact revenue.&lt;/p&gt;
&lt;h2&gt;Final Verdict: A Balanced but Risky Budget&lt;/h2&gt;
&lt;h3&gt;✅ Strengths&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Pro-Growth &amp;amp; Investment-Oriented:&lt;/strong&gt; Focus on infrastructure, MSME credit, and nuclear energy will drive long-term growth.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Taxpayer-Friendly:&lt;/strong&gt; Raising tax exemption limits will boost disposable income.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Sector-Specific Support:&lt;/strong&gt; Agriculture, rural development, and manufacturing sectors receive targeted incentives.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;❌ Weaknesses&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Fiscal Risks:&lt;/strong&gt; Revenue assumptions are optimistic, and high government borrowing raises concerns.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Execution Challenges:&lt;/strong&gt; Many reforms require state cooperation &amp;amp; bureaucratic efficiency.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Limited Social Sector Reforms:&lt;/strong&gt; Health, women’s employment, and education need stronger policy interventions.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Rating: 7.5/10&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;*Disclaimer:&lt;/strong&gt; &lt;em&gt;Views expressed are author&apos;s personal and based on initial interpretation and understanding of budget before further addendums and explanations given by the government&lt;/em&gt;&lt;/p&gt;
</content:encoded><author>CA Sumeet Agarwal</author></item><item><title>Piranesi by Susanna Clarke  —  Identity, Power, and Beauty</title><link>https://theleakycauldronblog.com/articles/piranesi-susanna-clarke-review</link><guid isPermaLink="true">https://theleakycauldronblog.com/articles/piranesi-susanna-clarke-review</guid><description>&lt;img alt=&quot;Piranesi by Susanna Clarke  —  Identity, Power, and Beauty&quot; src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Fdan-asaki-labyrinth.IQmKOjAZ.jpg&amp;w=1920&amp;h=1285&amp;dpl=699bfef0c4120e00087ee35a&quot; /&gt; Piranesi by Susanna Clarke explores themes of identity, power, and perception. Piranesi’s journey of self-discovery and reconciliation leaves a lasting emotional impact.</description><pubDate>Tue, 28 Jan 2025 12:30:00 GMT</pubDate><content:encoded>&lt;p&gt;When I first picked up Piranesi by Susanna Clarke, I wasn’t quite sure what to expect. What I found was a deeply moving exploration of identity, power, and our perceptions of the world. It’s a book that felt like it was written to be felt as much as it was to be read.&lt;/p&gt;
&lt;h2&gt;The Two Kinds of People&lt;/h2&gt;
&lt;p&gt;One of the most striking themes in Piranesi is the contrast between two kinds of people. There are those who are content with what they have, open to new experiences, and able to find joy in life’s small gifts. Then there are those endlessly chasing power and control, never satisfied, always wanting more.&lt;/p&gt;
&lt;p&gt;Piranesi embodies the former: resourceful, grateful, and kind. His acceptance of the House and his life within it is deeply tied to his trauma and isolation, yet he doesn’t succumb to bitterness. Instead, he thrives in his own way, finding beauty and meaning in his existence.&lt;/p&gt;
&lt;p&gt;The Other, by contrast, epitomizes the latter. Despite having access to so much — luxuries and knowledge — the Other is unsatisfied, always taking and giving nothing in return. I couldn’t help but envy the Other for the things he had, even as I shared Piranesi’s growing realization that something wasn’t right.&lt;/p&gt;
&lt;h2&gt;The Cruelty of Betrayal&lt;/h2&gt;
&lt;p&gt;One of the most gut-wrenching parts of the book is the betrayal that Piranesi experiences at the hands of the Other. To discover that someone you trusted has not only lied to you but also used you as a pawn for their own selfish ends is devastating.&lt;/p&gt;
&lt;p&gt;What makes this betrayal even crueler is the bitter irony of the name “Piranesi.” The name comes from Giovanni Battista Piranesi, an artist known for his surreal depictions of endless, prison-like spaces. By calling him this, the Other reduces Matthew’s existence to a mockery, trapping him in a world of his own ignorance and pain.&lt;/p&gt;
&lt;p&gt;This revelation dug deep. The overwhelming scenarios of revenge and retribution that flood Piranesi’s mind — followed by his breaking down and falling asleep — perfectly capture the weight of this betrayal. And yet, even in his pain, Piranesi finds the strength to reconcile with himself and extend forgiveness, making him an extraordinary character.&lt;/p&gt;
&lt;h2&gt;Unreliable Narrators Done Right&lt;/h2&gt;
&lt;p&gt;At first, I was frustrated by some inconsistencies in Piranesi’s knowledge. How could someone who seemed native to the House know about chess, minotaurs, and other worldly concepts? It felt like sloppy world-building at first.&lt;/p&gt;
&lt;p&gt;But then, the journal entries switched from using standard months and years to made-up dates. That was my first clue that something had changed — that something much deeper was at play. Suddenly, those inconsistencies became breadcrumbs leading me toward the truth.&lt;/p&gt;
&lt;p&gt;I’m often skeptical of unreliable narrators; they can feel like a lazy way to add twists. But Clarke does it so beautifully here. Every revelation felt earned, and I found myself equally excited and nervous as I pieced things together alongside Piranesi. The Other’s role in the story — friend? foe? something in between? — was handled with such nuance that by the end, I felt like I truly knew him, even though I didn’t trust him.&lt;/p&gt;
&lt;h2&gt;Echoes of Narnia&lt;/h2&gt;
&lt;p&gt;The novel’s references to C.S. Lewis’s Chronicles of Narnia were a delightful surprise. When Piranesi mentions dreaming of “a faun standing in a snowy forest and speaking to a female child,” it’s almost certainly a nod to Lucy Pevensie’s meeting with Mr. Tumnus in The Lion, the Witch, and the Wardrobe. This subtle allusion adds another layer to the book’s themes of alternate worlds, liminal spaces, and the tension between wonder and danger. Much like Narnia, Piranesi’s world is both enchanting and treacherous, inviting readers to lose themselves while urging caution.&lt;/p&gt;
&lt;h2&gt;A Cast That Feels Real&lt;/h2&gt;
&lt;p&gt;Despite being a relatively short book, Piranesi features characters who feel startlingly real. Even the “villains” like Ketterley are written in a way that makes them deeply human — evil in a familiar, unsettling way. It’s a testament to Clarke’s skill that she can create such vivid, believable characters with only snippets of backstory.&lt;/p&gt;
&lt;p&gt;Raphael, in particular, stood out for her gentleness and contrast to Ketterley. Her courage and grace in dealing with Piranesi and the House were beautiful to witness. The way she approached Piranesi — with patience and respect — was a much-needed balm after the cruelty of the Other.&lt;/p&gt;
&lt;h2&gt;Identity and Reconciliation&lt;/h2&gt;
&lt;p&gt;One of the most powerful aspects of the book is its exploration of identity. As Piranesi learns more about his past, the lines between who he was (Matthew) and who he is (Piranesi) blur. By the end, he reconciles these identities to become someone new — a blend of the two, but also entirely himself.&lt;/p&gt;
&lt;p&gt;This theme is reinforced in small but poignant ways, like Piranesi’s continued kindness toward Ritter, despite everything. His ability to forgive, to show compassion even in the face of betrayal, is a testament to his character and the journey he’s undergone.&lt;/p&gt;
&lt;h2&gt;Perspective Shifts&lt;/h2&gt;
&lt;p&gt;Some moments in the book hit hard — like the revelation about the bones. At first, Piranesi sees them as friends, residents of the House. But when Raphael reveals the truth, they become something entirely different: victims, murdered by Ketterley. This shift in perspective is gut-wrenching, not just for Piranesi but for the reader as well.&lt;/p&gt;
&lt;p&gt;Another poignant moment comes when Piranesi realizes the House needed someone to appreciate its beauty. It’s a subtle but profound realization, one that mirrors the way this book itself feels like it needs to be appreciated by multiple perspectives. Like the House, Piranesi is richer when shared and discussed.&lt;/p&gt;
&lt;h2&gt;Freedom vs. Captivity&lt;/h2&gt;
&lt;p&gt;One of the book’s recurring questions is whether we’re trapped or free. For Piranesi, the House is both a prison and a sanctuary. The idea that freedom is a matter of perception is explored so delicately, leaving the reader to ponder: How much of our own sense of freedom is shaped by our mindset?&lt;/p&gt;
&lt;h2&gt;Emotionally Resonant Prose&lt;/h2&gt;
&lt;p&gt;More than anything, this book made me feel. I felt Piranesi’s sorrow, shame, joy, and pain as if they were my own. The writing is evocative and poetic, feeling almost like a classic novel, yet it carries a modern sensibility that makes it accessible.&lt;/p&gt;
&lt;p&gt;Moments like Piranesi breaking down after realizing the Other’s betrayal, or crying on Raphael’s shoulder, were so raw and human that I couldn’t help but ache for him. The book’s ability to connect on such a deep emotional level is its greatest strength.&lt;/p&gt;
&lt;h2&gt;Final Thoughts&lt;/h2&gt;
&lt;p&gt;Piranesi is a masterpiece. It combines the wonder of magic, the intrigue of cults and charismatic leaders, and the quiet beauty of liminal spaces into a deeply philosophical exploration of identity and freedom.&lt;/p&gt;
&lt;p&gt;Few books have left me feeling as connected to a character as this one. It’s not just a book; it’s an experience — one that deserves to be shared, discussed, and cherished.&lt;/p&gt;
&lt;p&gt;If you haven’t read it yet, I can’t recommend it enough.&lt;/p&gt;
</content:encoded><author>Vaibhav Sharma</author></item><item><title>The Financial Bubble: How Stock Market Frenzy Is Impacting India’s Economic Balance (2014–2023)</title><link>https://theleakycauldronblog.com/articles/indian-financial-bubble-stock-market-frenzy</link><guid isPermaLink="true">https://theleakycauldronblog.com/articles/indian-financial-bubble-stock-market-frenzy</guid><description>&lt;img alt=&quot;The Financial Bubble: How Stock Market Frenzy Is Impacting India’s Economic Balance (2014–2023)&quot; src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Fstock-market-tyler-prahm.DyrVrfsq.jpg&amp;w=1920&amp;h=1440&amp;dpl=699bfef0c4120e00087ee35a&quot; /&gt; India’s economy, driven by government spending and liquidity, might have seen a disproportionate rise in stock market capitalization compared to private consumption.</description><pubDate>Mon, 13 Jan 2025 12:30:00 GMT</pubDate><content:encoded>&lt;p&gt;India’s economy over the past decade has been characterized by robust government expenditure, surging stock markets, and stagnating private consumption. From 2014 to 2023, the market capitalization of listed companies on Indian exchanges grew by 259.1%, while private consumption—India’s largest GDP component—grew only by 51.4%. During the same period, bank deposit growth slowed significantly, as retail investors increasingly diverted funds to the stock market in search of higher returns. This article evaluates how government expenditure and excess liquidity are indirectly being funneled into equity markets, creating a risky financial bubble that threatens long-term economic stability.&lt;/p&gt;
&lt;h2&gt;Government Expenditure and Its Indirect Link to Stock Markets&lt;/h2&gt;
&lt;p&gt;Government expenditure grew significantly from ₹16.6 trillion in 2014 to an estimated ₹45.0 trillion in 2023, driven by infrastructure investments, fiscal stimulus, and large-scale disinvestments. However, a portion of this liquidity has bypassed the real economy and found its way into financial markets.&lt;/p&gt;
&lt;h3&gt;Key Drivers Linking Government Spending to Stock Markets&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Disinvestment Proceeds:&lt;/strong&gt; Government disinvestment programs raised ₹2.7 trillion between 2014 and 2023, much of which boosted the equity market. For example, the LIC IPO (2022) and stakes in PSUs were absorbed by institutional and retail investors, adding to market momentum.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Liquidity Injection:&lt;/strong&gt; Post-2016 demonetization and subsequent fiscal stimuli provided excess liquidity, which investors reallocated into equities.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;strong&gt;Government Expenditure Growth (2014–2023)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;src/assets/media/screenshot-2025-01-13-at-8.41.40%E2%80%AFpm.jpg&quot; alt=&quot;Government Expenditure Growth (2014–2023)&quot; title=&quot;Government Expenditure Growth (2014–2023)&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Source: Union Budget, Ministry of Finance, GoI&lt;/em&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Rising Market Capitalization vs. Private Consumption Growth&lt;/h2&gt;
&lt;p&gt;While government spending boosted financial assets, its effect on private consumption—a more critical growth driver—has been muted.&lt;/p&gt;
&lt;h3&gt;Diverging Trends in Market Capitalization and Consumption&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Stock Market Boom:&lt;/strong&gt; From ₹75.3 trillion in 2014, India’s market capitalization surged to ₹271.4 trillion in 2023, fueled by institutional inflows, retail participation, and speculative investments.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Consumption Stagnation:&lt;/strong&gt; In contrast, private consumption grew at a subdued pace, from ₹106 trillion in 2014 to ₹160.5 trillion in 2023, indicating weak demand in the broader economy.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;strong&gt;Cumulative Growth Comparison (2014–2023)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;src/assets/media/screenshot-2025-01-13-at-8.41.58%E2%80%AFpm.jpg&quot; alt=&quot;Cumulative Growth Comparison (2014–2023)&quot; title=&quot;Cumulative Growth Comparison (2014–2023)&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Source: NSE, MOSPI&lt;/em&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;blockquote&gt;
&lt;p&gt;Conclusion from Data&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The sharp rise in market capitalization is driven more by speculative inflows than real earnings growth or economic output.&lt;/li&gt;
&lt;li&gt;Consumption’s tepid growth reflects insufficient job creation, stagnant wages, and wealth concentration in financial markets.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Declining Bank Deposits Amid Market Frenzy&lt;/h2&gt;
&lt;p&gt;The sharp rise in stock market participation has come at the expense of bank deposits. With real deposit rates falling, investors are increasingly chasing equity-linked returns, reducing the banking system’s ability to fund long-term credit needs.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;strong&gt;Bank Deposit Growth (2014–2023)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;src/assets/media/screenshot-2025-01-13-at-8.42.26%E2%80%AFpm.jpg&quot; alt=&quot;Bank Deposit Growth (2014–2023)&quot; title=&quot;Bank Deposit Growth (2014–2023)&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Source: RBI Annual Reports&lt;/em&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;blockquote&gt;
&lt;p&gt;Deposit growth has significantly lagged behind the stock market, raising concerns about the sustainability of credit growth in the banking system.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;The Role of Domestic Institutional and Retail Investors&lt;/h2&gt;
&lt;p&gt;Domestic Institutional Investors (DIIs) and retail investors have played a pivotal role in driving stock market valuations, leveraging lower interest rates and excess liquidity.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;strong&gt;Equity Investment Trends&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;src/assets/media/screenshot-2025-01-13-at-8.42.49%E2%80%AFpm.jpg&quot; alt=&quot;Equity Investment Trends (2014-2023)&quot; title=&quot;Equity Investment Trends (2014-2023)&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Source: NSE, SEBI&lt;/em&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Retail Involvement:&lt;/strong&gt; Platforms like &lt;em&gt;Zerodha&lt;/em&gt; and &lt;em&gt;Paytm Money&lt;/em&gt; have democratized equity participation, encouraging speculative investments.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;The Risks of Stock Market Frenzy&lt;/h2&gt;
&lt;h3&gt;Wealth Concentration&lt;/h3&gt;
&lt;p&gt;The stock market boom has disproportionately benefited the wealthy, exacerbating income inequality. According to &lt;a href=&quot;https://www.oxfamindia.org/knowledgehub/workingpaper/survival-richest-india-story&quot;&gt;Oxfam’s 2023 report&lt;/a&gt;, the richest 1% of Indians own 40% of national wealth.&lt;/p&gt;
&lt;h3&gt;Speculative Bubble Risks&lt;/h3&gt;
&lt;p&gt;Valuations in certain sectors have reached unsustainable levels, risking a financial correction that could destabilize investor confidence and consumption further.&lt;/p&gt;
&lt;h3&gt;Insufficient Job Creation&lt;/h3&gt;
&lt;p&gt;High market capitalization growth has not translated into commensurate job creation, as companies prioritize capital efficiency over expansion.&lt;/p&gt;
&lt;h2&gt;Policy Recommendations&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Reallocate Expenditure:&lt;/strong&gt; Direct more government spending toward rural welfare, job creation, and demand-driven schemes.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Improve Financial Literacy:&lt;/strong&gt; Curb speculative retail investments by ensuring investors are aware of risks.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Revive Banking:&lt;/strong&gt; Encourage higher deposit rates to improve banking liquidity and credit capacity.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;India’s market frenzy, driven by liquidity and speculative inflows, presents systemic risks that policymakers must address. Without aligning financial market growth with consumption and employment, the economy may face a potential bubble that threatens long-term stability.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Hold on for the next part...&lt;/em&gt;&lt;/p&gt;
</content:encoded><author>CA Sumeet Agarwal</author></item><item><title>How to sync Child Transforms of a GameObject with PUN2 in Unity3D</title><link>https://theleakycauldronblog.com/articles/sync-child-transforms-unity3d-pun2</link><guid isPermaLink="true">https://theleakycauldronblog.com/articles/sync-child-transforms-unity3d-pun2</guid><description>&lt;img alt=&quot;How to sync Child Transforms of a GameObject with PUN2 in Unity3D&quot; src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Fsync-child-transforms-unity3d-pun2-lorenzo-herrera.JQW2vV9s.jpg&amp;w=2400&amp;h=1600&amp;dpl=699bfef0c4120e00087ee35a&quot; /&gt; Learn how to sync child transforms using Photon Unity Networking 2 (PUN2) for smooth, optimized multiplayer game experiences.</description><pubDate>Fri, 21 Jun 2024 12:30:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;strong&gt;Photon Unity Networking v2 (&lt;a href=&quot;https://www.photonengine.com/pun&quot;&gt;PUN2&lt;/a&gt;)&lt;/strong&gt;  is the &lt;code&gt;networking package&lt;/code&gt; you end up using when you realize the &lt;a href=&quot;https://unity.com&quot;&gt;Unity3D&lt;/a&gt; project you’re working on will need:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;WebGL&lt;/strong&gt; build&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Voice Chat&lt;/strong&gt; support&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The alternative, &lt;strong&gt;&lt;a href=&quot;https://docs-multiplayer.unity3d.com/netcode/current/about/&quot;&gt;Netcode&lt;/a&gt;&lt;/strong&gt; for &lt;code&gt;GameObjects&lt;/code&gt;, the networking package provided by &lt;strong&gt;Unity3D&lt;/strong&gt; itself, is a decent solution for sure (according to me, having worked on it for only a week). But the voice service provided by Unity - &lt;strong&gt;Vivox&lt;/strong&gt; doesn’t support voice over &lt;strong&gt;WebGL&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;The point is, &lt;strong&gt;PUN2&lt;/strong&gt; exists and its voice service works over &lt;strong&gt;WebGL&lt;/strong&gt;! Can you read the excitement in my words? That’s me with 5 years of &lt;strong&gt;&lt;a href=&quot;https://theleakycauldronblog.com/tags/gamedev&quot;&gt;Game Dev&lt;/a&gt;&lt;/strong&gt; experience now. I’ve heard it’s only gonna get better.&lt;/p&gt;
&lt;p&gt;Anyway, you probably know how to set up a &lt;code&gt;prefab&lt;/code&gt; which will be instantiated over the internet.&lt;/p&gt;
&lt;p&gt;Or if you don’t - that’s fine. I’ll explain. I’ll skip the steps about importing &lt;strong&gt;PUN2&lt;/strong&gt; and the &lt;strong&gt;App ID&lt;/strong&gt; setup. You can find that stuff anywhere.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Have a prefab in your &lt;code&gt;Resources&lt;/code&gt; folder.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add a &lt;code&gt;PhotonView&lt;/code&gt; component to your prefab’s root. Let’s assume it’s a basic &lt;em&gt;Cube&lt;/em&gt;. We don’t care about syncing animations for now.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Now add a &lt;code&gt;PhotonTransformView&lt;/code&gt; component to your alongside the &lt;code&gt;PhotonView&lt;/code&gt; (i.e., on the same root). This component will be responsible for syncing our &lt;code&gt;Transform&lt;/code&gt; over the network.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add this code to instantiate your &lt;code&gt;prefab&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;PhotonNetwork.Instantiate(prefabPath, Vector3.zero, Quaternion.identity);
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Here &lt;code&gt;prefabPath&lt;/code&gt; would be the path to your prefab in the &lt;code&gt;Resources&lt;/code&gt; folder. And the &lt;code&gt;Vector3&lt;/code&gt; and &lt;code&gt;Quaternion&lt;/code&gt; are your position and rotation respectively.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;And that’s it. Your &lt;em&gt;&lt;strong&gt;Cube&lt;/strong&gt;&lt;/em&gt; (assuming it has a script updating its position/rotation) will reflect the changes to the other players.&lt;/p&gt;
&lt;p&gt;There’s a catch here of course.&lt;/p&gt;
&lt;p&gt;Say, there’s a &lt;em&gt;&lt;strong&gt;Cube&lt;/strong&gt;&lt;/em&gt; with a script that rotates the &lt;em&gt;&lt;strong&gt;Cube&lt;/strong&gt;&lt;/em&gt; along the &lt;code&gt;Y-axis&lt;/code&gt;, and there&apos;s a child of this &lt;em&gt;&lt;strong&gt;Cube&lt;/strong&gt;&lt;/em&gt;, a &lt;em&gt;&lt;strong&gt;Capsule&lt;/strong&gt;&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Now, it&apos;s fair to assume that the &lt;em&gt;&lt;strong&gt;Capsule’s&lt;/strong&gt;&lt;/em&gt; movement should also be reflected to other players over the network.&lt;/p&gt;
&lt;p&gt;But of course, that doesn&apos;t work. SMH.&lt;/p&gt;
&lt;p&gt;So, what do we do?&lt;/p&gt;
&lt;p&gt;Now I’ll pay a little lip-service to the idea of adding another &lt;code&gt;PhotonView&lt;/code&gt; and another &lt;code&gt;PhotonTransformView&lt;/code&gt; to the child (&lt;em&gt;&lt;strong&gt;Capsule&lt;/strong&gt;&lt;/em&gt; in our case). But I could never get that solution to work. Maybe it’s supposed to, maybe it’s not.&lt;/p&gt;
&lt;p&gt;Either way, I have a different solution.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;PhotonTransformView&lt;/code&gt; implements an interface called &lt;code&gt;IPunObservable&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class PhotonTransformView : MonoBehaviour, IPunObservable
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That’s what you wanna inherit from if you wanna share data over the&lt;code&gt;network stream&lt;/code&gt;. This gives you the method — &lt;code&gt;OnPhotonSerializeView&lt;/code&gt;, which gets called every time there is a change in the &lt;code&gt;stream&lt;/code&gt;. This &lt;code&gt;method&lt;/code&gt; also provides us with the &lt;code&gt;stream object&lt;/code&gt; itself.&lt;/p&gt;
&lt;p&gt;All we need to do is check if the stream is currently &lt;code&gt;reading&lt;/code&gt; or &lt;code&gt;writing&lt;/code&gt;, which is the equivalent of sending/receiving data.&lt;/p&gt;
&lt;p&gt;One thing to note here is that the &lt;em&gt;&lt;strong&gt;order&lt;/strong&gt;&lt;/em&gt; in which the data is &lt;em&gt;&lt;strong&gt;received&lt;/strong&gt;&lt;/em&gt; is the &lt;em&gt;&lt;strong&gt;same order&lt;/strong&gt;&lt;/em&gt; in which it is &lt;em&gt;&lt;strong&gt;sent&lt;/strong&gt;&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;So here’s the gist of the idea — we handle the syncing ourselves.&lt;/p&gt;
&lt;p&gt;Here’s a &lt;em&gt;bad&lt;/em&gt; way of doing this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;using Photon.Pun;
using UnityEngine;

public class ChildTransformSync : MonoBehaviourPun, IPunObservable
{
	[SerializeField] private Transform childTransform;

	public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
	{
    	if (stream.IsWriting)
    	{
        	// Send the current position and rotation to other players
        	stream.SendNext(childTransform.localPosition);
        	stream.SendNext(childTransform.localRotation);
    	}
    	else
    	{
        	// Receive the position and rotation from other players
        	childTransform.localPosition= (Vector3)stream.ReceiveNext();
        	childTransform.localRotation= (Quaternion)stream.ReceiveNext();
    	}
	}
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;All you gotta do with this component is:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Attach it to the &lt;em&gt;&lt;strong&gt;Capsule&lt;/strong&gt;&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Add it to the &lt;code&gt;Observed Components&lt;/code&gt; list in your parent’s (&lt;em&gt;&lt;strong&gt;Cube&lt;/strong&gt;&lt;/em&gt;) &lt;code&gt;PhotonView&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Here are my issues with this script:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;I gotta add this &lt;code&gt;component&lt;/code&gt; to every &lt;code&gt;child&lt;/code&gt; I need. And make sure they are observed by the parent’s &lt;code&gt;PhotonView&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;I’m sending the &lt;code&gt;position&lt;/code&gt; for this &lt;em&gt;&lt;strong&gt;Capsule&lt;/strong&gt;&lt;/em&gt; over &lt;code&gt;stream&lt;/code&gt; — an object which is never going to move. Only rotate. That too, only in the &lt;code&gt;Y-axis&lt;/code&gt;. Why should I clog up the stream?&lt;/li&gt;
&lt;li&gt;There is no &lt;code&gt;interpolation&lt;/code&gt; for these sync ups. So, the &lt;em&gt;movement/rotation&lt;/em&gt; is gonna snap all over the place.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Let’s first handle the first problem. The code handles the syncing for one child, so let&apos;s &lt;em&gt;&lt;strong&gt;DRY&lt;/strong&gt;&lt;/em&gt; it up so that it syncs up all the &lt;code&gt;Transforms&lt;/code&gt; we want.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;using UnityEngine;
using Photon.Pun;

public class TransformSync: MonoBehaviourPun, IPunObservable
{
	[SerializeField] private Transform[] transforms; // Array of transforms to sync

	public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
	{
    	if (stream.IsWriting)
    	{
        	// Send data to others
        	foreach (var t in transforms)
        	{
            	if (t != null)
            	{
                	stream.SendNext(t.position);
                	stream.SendNext(t.rotation);
                	stream.SendNext(t.localScale);
            	}
        	}
    	}
    	else
    	{
        	// Receive data
        	foreach (var t in transforms)
        	{
            	if (t != null)
            	{
                	t.position = (Vector3)stream.ReceiveNext();
                	t.rotation = (Quaternion)stream.ReceiveNext();
                	t.localScale = (Vector3)stream.ReceiveNext();
            	}
        	}
    	}
	}
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, let&apos;s take care of the &lt;code&gt;interpolation&lt;/code&gt;, by making a &lt;code&gt;struct&lt;/code&gt; to hold the data we get from the stream:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[System.Serializable]
public struct TransformData
{
    public Vector3 position;
    public Quaternion rotation;
    public Vector3 scale;

    public TransformData(Vector3 pos, Quaternion rot, Vector3 scl)
    {
   	 position = pos;
   	 rotation = rot;
   	 scale = scl;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, let’s use an &lt;code&gt;array&lt;/code&gt; of these &lt;code&gt;structs&lt;/code&gt; to hold the received data from the stream instead of setting it right when it’s received.&lt;br /&gt;
&lt;br /&gt;
We’ll also ensure that this &lt;code&gt;array&lt;/code&gt; is populated at the start with the initial positions of these &lt;code&gt;transforms&lt;/code&gt;. We don’t want any goof-ups. Since, we are dealing with &lt;code&gt;structs&lt;/code&gt; here, not &lt;code&gt;classes&lt;/code&gt;, &lt;code&gt;struct&lt;/code&gt; references(when they are not initialized in code) take up &lt;code&gt;default values&lt;/code&gt; which can screw up our calculations.&lt;/p&gt;
&lt;p&gt;Once we have the data — we can &lt;code&gt;lerp&lt;/code&gt; to the network positions, instead of snapping to them.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;using UnityEngine;
using Photon.Pun;

public class TransformsSync : MonoBehaviourPun, IPunObservable
{
    [SerializeField] private Transform[] transforms; // Array of transforms to sync
    [SerializeField] private float interpolationSpeed = 10f; // Speed of interpolation

    private TransformData[] _targetTransformData; // Target transform data to interpolate towards

    void Start()
    {
   	 _targetTransformData = new TransformData[transforms.Length];
   	 for (int i = 0; i &amp;lt; transforms.Length; i++)
   	 {
   		 if (transforms[i] != null)
   		 {
   			 _targetTransformData[i] = new TransformData(transforms[i].position, transforms[i].rotation, transforms[i].localScale);
   		 }
   	 }
    }

    void Update()
    {
   	 if (!photonView.IsMine)
   	 {
   		 for (int i = 0; i &amp;lt; transforms.Length; i++)
   		 {
   			 if (transforms[i] != null)
   			 {
   				 transforms[i].position = Vector3.Lerp(transforms[i].position, _targetTransformData[i].position, Time.deltaTime * interpolationSpeed);
   				 transforms[i].rotation = Quaternion.Lerp(transforms[i].rotation, _targetTransformData[i].rotation, Time.deltaTime * interpolationSpeed);
   				 transforms[i].localScale = Vector3.Lerp(transforms[i].localScale, _targetTransformData[i].scale, Time.deltaTime * interpolationSpeed);
   			 }
   		 }
   	 }
    }

    public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
    {
   	 if (stream.IsWriting)
   	 {
   		 // Send data to others
   		 foreach (var childTransform in transforms)
   		 {
   			 if (childTransform != null)
   			 {
   				 stream.SendNext(childTransform.position);
   				 stream.SendNext(childTransform.rotation);
   				 stream.SendNext(childTransform.localScale);
   			 }
   		 }
   	 }
   	 else
   	 {
   		 // Receive data and update target transform data
   		 for (int i = 0; i &amp;lt; transforms.Length; i++)
   		 {
   			 if (transforms[i] != null)
   			 {
   				 _targetTransformData[i].position = (Vector3)stream.ReceiveNext();
   				 _targetTransformData[i].rotation = (Quaternion)stream.ReceiveNext();
   				 _targetTransformData[i].scale = (Vector3)stream.ReceiveNext();
   			 }
   		 }
   	 }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You might&apos;ve noticed a check in the &lt;code&gt;Update method&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private void Update()
{
	if (!photonView.IsMine)
	{
    	...
	}
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This ensures our &lt;code&gt;interpolation&lt;/code&gt; will only occur for objects belonging to other clients. Of course, we’d be handling our &lt;em&gt;&lt;strong&gt;Capsule&lt;/strong&gt;&lt;/em&gt; rotation ourselves so our calculated rotations will be perfectly accurate already.&lt;/p&gt;
&lt;p&gt;So &lt;code&gt;interpolation&lt;/code&gt; is resolved. Now, all we need to do is:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Attach this script to the &lt;code&gt;prefab root&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Fill the &lt;code&gt;transforms&lt;/code&gt; list with the &lt;code&gt;Transform&lt;/code&gt; components we want to sync up.&lt;/li&gt;
&lt;li&gt;Get rid of any &lt;code&gt;PhotonTransformView&lt;/code&gt; components — we don’t need help.&lt;/li&gt;
&lt;li&gt;Add this component to the &lt;code&gt;Observed Components&lt;/code&gt; list in our &lt;code&gt;PhotonView&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Now, &lt;em&gt;technically&lt;/em&gt; we have achieved, what we set out to do. You can even stop reading at this point. But, let’s see if we can handle limiting the data &lt;em&gt;sent/received&lt;/em&gt; over &lt;code&gt;stream&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Why? Because we are &lt;em&gt;&lt;strong&gt;programmers&lt;/strong&gt;&lt;/em&gt; and we &lt;em&gt;&lt;strong&gt;love optimizing things&lt;/strong&gt;&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Let’s first create another &lt;code&gt;struct&lt;/code&gt; called &lt;code&gt;TransformSyncSettings&lt;/code&gt;. This will determine which values we want to sync up. It will consist of 3 &lt;code&gt;bools&lt;/code&gt; — &lt;em&gt;&lt;strong&gt;x, y &amp;amp; z&lt;/strong&gt;&lt;/em&gt;. Each determining the &lt;code&gt;axis&lt;/code&gt; we want to sync.&lt;/p&gt;
&lt;p&gt;This structure makes sense for &lt;em&gt;position&lt;/em&gt; and &lt;em&gt;scale&lt;/em&gt; but for rotations we should have an additional &lt;code&gt;w&lt;/code&gt; parameter as they are &lt;code&gt;Quaternions&lt;/code&gt; - though let’s stick with &lt;code&gt;Euler angles&lt;/code&gt; for now.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[System.Serializable]
public struct SyncSettings
{
	public bool x, y, z;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let’s get rid of the &lt;code&gt;TransformData&lt;/code&gt; class and rename it to &lt;code&gt;TransformSyncData&lt;/code&gt;. It sounds cleaner.&lt;/p&gt;
&lt;p&gt;This &lt;code&gt;struct&lt;/code&gt; will hold a &lt;code&gt;Transform&lt;/code&gt; reference, also a &lt;code&gt;SyncSettings&lt;/code&gt; references for &lt;em&gt;position&lt;/em&gt;, &lt;em&gt;rotation&lt;/em&gt; and &lt;em&gt;scale&lt;/em&gt;, and the &lt;code&gt;3 Vectors&lt;/code&gt;(&lt;code&gt;NonSerialized&lt;/code&gt;) which will hold on to the network target positions for &lt;code&gt;interpolation&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[System.Serializable]
public struct TransformSyncData
{
	public UnityEngine.Transform transform;
	public SyncSettings positionSync;
	public SyncSettings rotationSync;
	public SyncSettings scaleSync;

	[HideInInspector] public Vector3 targetPosition;
	[HideInInspector] public Vector3 targetRotation;
	[HideInInspector] public Vector3 targetScale;

	public TransformSyncData(UnityEngine.Transform transform)
	{
    	this.transform = transform;
    	positionSync = new SyncSettings { x = true, y = true, z = true };
    	rotationSync = new SyncSettings { x = true, y = true, z = true };
    	scaleSync = new SyncSettings { x = true, y = true, z = true };
    	targetPosition = transform.position;
    	targetRotation = transform.rotation.eulerAngles;
    	targetScale = transform.localScale;
	}
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, in our &lt;code&gt;TransformsSync&lt;/code&gt; class, let’s adjust the &lt;code&gt;Start&lt;/code&gt; method so we correctly initialize the positions of our synced transforms. We’ll also update the old &lt;code&gt;TransformData&lt;/code&gt; array reference to be of the &lt;code&gt;TransformSyncData&lt;/code&gt; type.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[Header(&quot;Transform Sync&quot;)]
[SerializeField]
private TransformSyncData[] transformsToSync;

private void Start()
{
	for (int i = 0; i &amp;lt; transformsToSync.Length; i++)
	{
    	if (transformsToSync[i].transform == null) continue;

    	transformsToSync[i].targetPosition = transformsToSync[i].transform.position;
    	transformsToSync[i].targetRotation = transformsToSync[i].transform.rotation.eulerAngles;
    	transformsToSync[i].targetScale = transformsToSync[i].transform.localScale;
	}
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, let’s take a look at our &lt;code&gt;OnPhotonSerializeView&lt;/code&gt; code.&lt;/p&gt;
&lt;p&gt;We wanna make use of our &lt;code&gt;SyncSettings&lt;/code&gt; and only &lt;em&gt;send/receive&lt;/em&gt; data which is explicitly defined to be sent through the &lt;code&gt;inspector&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This is how we’ll handle the sending:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;for (int i = 0; i &amp;lt; transformsToSync.Length; i++)
{
	if (transformsToSync[i].transform == null) continue;
	// Write only the necessary values based on sync settings

	if (transformsToSync[i].positionSync.x)
    	stream.SendNext(transformsToSync[i].transform.position.x);
	if (transformsToSync[i].positionSync.y)
    	stream.SendNext(transformsToSync[i].transform.position.y);
	if (transformsToSync[i].positionSync.z)
    	stream.SendNext(transformsToSync[i].transform.position.z);

	if (transformsToSync[i].rotationSync.x)
    	stream.SendNext(transformsToSync[i].transform.eulerAngles.x);
	if (transformsToSync[i].rotationSync.y)
    	stream.SendNext(transformsToSync[i].transform.eulerAngles.y);
	if (transformsToSync[i].rotationSync.z)
    	stream.SendNext(transformsToSync[i].transform.eulerAngles.z);

	if (transformsToSync[i].scaleSync.x)
    	stream.SendNext(transformsToSync[i].transform.localScale.x);
	if (transformsToSync[i].scaleSync.y)
    	stream.SendNext(transformsToSync[i].transform.localScale.y);
	if (transformsToSync[i].scaleSync.z)
    	stream.SendNext(transformsToSync[i].transform.localScale.z);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And this, is how we’ll read that data:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;for (int i = 0; i &amp;lt; transformsToSync.Length; i++)
{
	if (transformsToSync[i].transform == null) continue;

	// Read only the necessary values based on sync settings
	Vector3 receivedPosition = new Vector3(
    	transformsToSync[i].positionSync.x
        	? (float)stream.ReceiveNext()
        	: transformsToSync[i].transform.position.x,
    	transformsToSync[i].positionSync.y
        	? (float)stream.ReceiveNext()
        	: transformsToSync[i].transform.position.y,
    	transformsToSync[i].positionSync.z
        	? (float)stream.ReceiveNext()
        	: transformsToSync[i].transform.position.z
	);

	transformsToSync[i].targetPosition = receivedPosition;

	Vector3 receivedRotation = new Vector3(
    	transformsToSync[i].rotationSync.x
        	? (float)stream.ReceiveNext()
        	: transformsToSync[i].transform.eulerAngles.x,
    	transformsToSync[i].rotationSync.y
        	? (float)stream.ReceiveNext()
        	: transformsToSync[i].transform.eulerAngles.y,
    	transformsToSync[i].rotationSync.z
        	? (float)stream.ReceiveNext()
        	: transformsToSync[i].transform.eulerAngles.z
	);
	transformsToSync[i].targetRotation = receivedRotation;

	Vector3 receivedScale = new Vector3(
    	transformsToSync[i].scaleSync.x
        	? (float)stream.ReceiveNext()
        	: transformsToSync[i].transform.localScale.x,
    	transformsToSync[i].scaleSync.y
        	? (float)stream.ReceiveNext()
        	: transformsToSync[i].transform.localScale.y,
    	transformsToSync[i].scaleSync.z
        	? (float)stream.ReceiveNext()
        	: transformsToSync[i].transform.localScale.z
	);

	transformsToSync[i].targetScale = receivedScale;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Moving on to &lt;code&gt;interpolation&lt;/code&gt;, we want to make sure we only interpolate the values which we have explicitly stated to be &lt;em&gt;sent/received&lt;/em&gt; making use of the &lt;code&gt;SyncSettings&lt;/code&gt; bools.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;for (int i = 0; i &amp;lt; transformsToSync.Length; i++)
{
	if (transformsToSync[i].transform == null) continue;

	TransformSyncData data = transformsToSync[i];

	Vector3 currentPos = data.transform.position;
	Vector3 currentRot = data.transform.eulerAngles;
	Vector3 currentScale = data.transform.localScale;

	float t = Time.deltaTime * PhotonNetwork.SerializationRate;

	// Interpolate position if required
	if (data.positionSync.x)
	{
    	currentPos.x = Mathf.Lerp(currentPos.x, data.targetPosition.x, t);
	}

	if (data.positionSync.y)
	{
    	currentPos.y = Mathf.Lerp(currentPos.y, data.targetPosition.y, t);
	}

	if (data.positionSync.z)
	{
    	currentPos.z = Mathf.Lerp(currentPos.z, data.targetPosition.z, t);
	}

	// Interpolate rotation if required
	if (data.rotationSync.x)
	{
    	currentRot.x = Mathf.LerpAngle(currentRot.x, data.targetRotation.x, t);
	}

	if (data.rotationSync.y)
	{
    	currentRot.y = Mathf.LerpAngle(currentRot.y, data.targetRotation.y, t);
	}

	if (data.rotationSync.z)
	{
    	currentRot.z = Mathf.LerpAngle(currentRot.z, data.targetRotation.z, t);
	}

	// Interpolate scale if required
	if (data.scaleSync.x)
	{
    	currentScale.x = Mathf.Lerp(currentScale.x, data.targetScale.x, t);
	}

	if (data.scaleSync.y)
	{
    	currentScale.y = Mathf.Lerp(currentScale.y, data.targetScale.y, t);
	}

	if (data.scaleSync.z)
	{
    	currentScale.z = Mathf.Lerp(currentScale.z, data.targetScale.z, t);
	}

	// Update transform
	data.transform.position = currentPos;
	data.transform.eulerAngles = currentRot;
	data.transform.localScale = currentScale;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You’ll notice I’ve gotten rid of the &lt;code&gt;interpolationSpeed&lt;/code&gt; factor here, instead opting for &lt;code&gt;PhotonNetwork.SerializationRate&lt;/code&gt;. I took that cue from the original &lt;code&gt;PhotonTransformView&lt;/code&gt; class.&lt;/p&gt;
&lt;p&gt;Can I explain more about it? No, I can’t.&lt;/p&gt;
&lt;p&gt;Now, in the inspector add the &lt;em&gt;&lt;strong&gt;Cube&lt;/strong&gt;&lt;/em&gt; and the &lt;em&gt;&lt;strong&gt;Capsule&lt;/strong&gt;&lt;/em&gt; to the &lt;code&gt;transformsToSync&lt;/code&gt; list. And, adjust the &lt;code&gt;SyncSettings&lt;/code&gt; booleans to your heart’s content.&lt;/p&gt;
&lt;p&gt;Finally, at long last, we are done. Really done! 100% absolutely ....&lt;/p&gt;
&lt;p&gt;Yeah, there’s an issue.&lt;/p&gt;
&lt;p&gt;If you run a build with this code you’ll notice that if the &lt;strong&gt;Host’s &lt;em&gt;Capsule&lt;/em&gt;&lt;/strong&gt; rotated somewhat before a &lt;strong&gt;Client&lt;/strong&gt; joined — the joining &lt;strong&gt;Client&lt;/strong&gt; would only see the &lt;em&gt;default rotation&lt;/em&gt; set in the &lt;code&gt;prefab&lt;/code&gt; itself. Any &lt;em&gt;updates&lt;/em&gt; to the rotation afterwards will &lt;em&gt;reflect perfectly&lt;/em&gt; on the client but that initial situation is an &lt;em&gt;issue&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Riddle me this: which got called first &lt;code&gt;Update&lt;/code&gt; or &lt;code&gt;OnPhotonSerializeView&lt;/code&gt;?&lt;/p&gt;
&lt;p&gt;That’s right. It’s &lt;em&gt;unclear&lt;/em&gt;. On some machines, maybe &lt;code&gt;Update&lt;/code&gt; got called first, on others, maybe it was &lt;code&gt;OnPhotonSerializeView&lt;/code&gt;. They are not linked; one is never guaranteed to be called after the other.&lt;/p&gt;
&lt;p&gt;So let’s be &lt;strong&gt;responsible programmers&lt;/strong&gt; and handle that initial situation. All we gotta do is make sure our updates, i.e., our &lt;code&gt;interpolation&lt;/code&gt;, only happens once we have started receiving data over the network.&lt;/p&gt;
&lt;p&gt;I’m sure you can figure out how to do that... 😉&lt;/p&gt;
</content:encoded><author>Eklavya Mishra</author></item><item><title>Top 10 LoFi 🌌 - beats to distract you from study/work</title><link>https://theleakycauldronblog.com/articles/top-10-lofi-tracks</link><guid isPermaLink="true">https://theleakycauldronblog.com/articles/top-10-lofi-tracks</guid><description>&lt;img alt=&quot;Top 10 LoFi 🌌 - beats to distract you from study/work&quot; src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Flofigirl.Dy6f3FHI.png&amp;w=1920&amp;h=1080&amp;dpl=699bfef0c4120e00087ee35a&quot; /&gt; My Top 10 LoFi Beats that are so good that they distract me from work/study and make me vibe hard and transport my imagination to far off places.</description><pubDate>Sat, 11 May 2024 12:30:00 GMT</pubDate><content:encoded>&lt;p&gt;Just like a lot of people around the world I too rely on &lt;a href=&quot;https://www.youtube.com/@LofiGirl&quot;&gt;LoFi Girl&lt;/a&gt; to help boost my productivity. “Lo-fi&quot; is short for &quot;low-fidelity&quot; music which embraces the imperfections of low-quality music production. It acts as an ambient sound just like white noise, and helps you provide a rhythm without being distracting. Here&apos;s the YouTube channel &quot;Answer in Progress&quot; explaining the science behind LoFi.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://youtu.be/OeFujF6LdAM&quot;&gt;https://youtu.be/OeFujF6LdAM&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;But the thing with music is that sometimes it&apos;s just so damn good that you can&apos;t help putting everything aside and just vibing to it, as they conjure beautiful scenarios in your head, that you may or even may not have experienced. I have made a list of my 10 favourite LoFi tracks and tried to put to words the emotions and imagination they inspire in me.&lt;/p&gt;
&lt;h2&gt;10. dontcry - Redbone&lt;/h2&gt;
&lt;p&gt;I had no idea that a chill song like Redbone could get even more chill, but this LoFi rendition of Redbone by Childish Gambino proves otherwise. Best served with a side of hot coco and rain on the glass window.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://youtu.be/4E3eDnbtAT8&quot;&gt;https://youtu.be/4E3eDnbtAT8&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;9. bits &amp;amp; hits - The Slopes of Blessure&lt;/h2&gt;
&lt;p&gt;Masterfully created LoFi version of &lt;a href=&quot;https://www.youtube.com/watch?v=824CHpd7Ax8&quot;&gt;The Slopes of Blessure&lt;/a&gt; from The Witcher 3: Wild Hunt [Blood and Wine] Game OST, perfect beats to slay supernatural beasts/play Gwent to.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://youtu.be/8EyX2o7gH8k&quot;&gt;https://youtu.be/8EyX2o7gH8k&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;8. GentleBeatz - One With The Wind&lt;/h2&gt;
&lt;p&gt;With a base sampled from &lt;a href=&quot;https://youtu.be/geZ_5Ri7ANg&quot;&gt;EDEN - rock + roll&lt;/a&gt; this LoFi track goes beyond the original, and when the music intensifies at 1 minute 28 seconds, it makes you feel the quote &quot;I know that a life without love is no life at all&quot; sampled at the beginning [from &lt;a href=&quot;https://en.wikipedia.org/wiki/Ever_After&quot;&gt;Ever After(1998)&lt;/a&gt;].&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://youtu.be/6kVUDvZ1oGg&quot;&gt;https://youtu.be/6kVUDvZ1oGg&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;7. Kinissue &amp;amp; Raimu - Bliss&lt;/h2&gt;
&lt;p&gt;With a healthy dose of eastern flute, this fusion beat will transport your mind, straight to tranquillity, away from the bustling life of a metropolitan city.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://youtu.be/2l7Mmn_WUwU&quot;&gt;https://youtu.be/2l7Mmn_WUwU&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;6. Kupla - Lavender&lt;/h2&gt;
&lt;p&gt;One of the most beautiful LoFi tracks I have ever heard, it&apos;s as if the medley of instruments plays on my heartstrings themselves, while i sit at the edge of a small pier on the lake on a breezy spring day.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://youtu.be/4jit_SPagrI&quot;&gt;https://youtu.be/4jit_SPagrI&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;5.  WYS - The Bad Party&lt;/h2&gt;
&lt;p&gt;Playing this hauntingly melancholic track on a loop is perfect for those sombre moments in life, when you stay up till early morning in winters, staring out the window, contemplating.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://youtu.be/3hHoJo7ZNGg&quot;&gt;https://youtu.be/3hHoJo7ZNGg&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;4. nymano x Pandrezz - Evening Routine&lt;/h2&gt;
&lt;p&gt;This beautiful shimmering lo-fi track is the music equivalent of taking an evening walk with your crush on streets reflecting neon signs of the big city in the puddles left on the wet pavement after a storm, with a pleasant petrichor still lingering in the air. The warm, wistful melody perfectly captures that feeling of romantic anticipation and the soft glow of new love against the twinkling city lights.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://youtu.be/6IlPJ_mBxLQ&quot;&gt;https://youtu.be/6IlPJ_mBxLQ&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;3. Bamf - Lost in Kyoto&lt;/h2&gt;
&lt;p&gt;I have been following the artist Bamf since he had less than 50 subs on his YouTube. I can proudly say he&apos;s one of my most rewarding discoveries, he not only makes the music, he adds beautiful little &lt;a href=&quot;https://waneella.tumblr.com&quot;&gt;8-bit GIFs&lt;/a&gt; enhancing the aesthetics of his music. And though I love all his tracks, this one takes the cake for my favourite.&lt;/p&gt;
&lt;p&gt;It captures the &lt;a href=&quot;https://www.dictionaryofobscuresorrows.com/post/27720773573/kenopsia&quot;&gt;kenopsia&lt;/a&gt; of walking down a quiet canal road at late night/early morning, while the mists make eerie shapes as they scatter light on the path illuminated by halogen street lights. An atmospheric track that bottles the surreal solitude of being the sole soul awake in the pre-dawn stillness.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://youtu.be/nD9-F_FU9PA&quot;&gt;https://youtu.be/nD9-F_FU9PA&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;2. Plant Guy - Towards The Mountain&lt;/h2&gt;
&lt;p&gt;This serene yet melancholic track conjures up imagery of sitting in an autumn countryside pasture, watching cows lazily grazing under the golden sun. However, there&apos;s an underlying sense of the impending harsh winter, carried through the nippy October winds, hinting at the transient nature of this peaceful seasonal moment.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://youtu.be/57PcFq4uZ2s&quot;&gt;https://youtu.be/57PcFq4uZ2s&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;1. sweetbn_ - rowflip&lt;/h2&gt;
&lt;p&gt;This LoFi track is pure perfection, from the entrancing music to the masterfully edited video. Clips from the film &lt;a href=&quot;https://en.wikipedia.org/wiki/Eternal_Sunshine_of_the_Spotless_Mind&quot;&gt;Eternal Sunshine of the Spotless Mind&lt;/a&gt; are seamlessly woven together, made even more poignant by sampling a line from the movie itself. The result captures the bittersweet nostalgia of a faded relationship with heartbreaking accuracy. As the melancholic melody washes over you, it kindles hope for the future, like finding solace in a cozy cafe over a cup of pourover, while processing the end of one chapter and the potential start of another.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://youtu.be/U-9rYC8RPu8&quot;&gt;https://youtu.be/U-9rYC8RPu8&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;So these were my top 10, did I miss any, what did you think about it, let me know in the comments down below!&lt;/p&gt;
</content:encoded><author>Vaibhav Sharma</author></item><item><title>Dear Friends: Politics</title><link>https://theleakycauldronblog.com/articles/dear-friends-politics</link><guid isPermaLink="true">https://theleakycauldronblog.com/articles/dear-friends-politics</guid><description>&lt;img alt=&quot;Dear Friends: Politics&quot; src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Fdear-friends-politics-brian-wertheim.DXNkcMj2.jpg&amp;w=2400&amp;h=1435&amp;dpl=699bfef0c4120e00087ee35a&quot; /&gt; A letter to my friends on why I believe we should take a centrist approach rather than align to ideological leanings and political parties.</description><pubDate>Mon, 06 May 2024 12:30:00 GMT</pubDate><content:encoded>&lt;p&gt;Do you think any politician deserves our blind loyalty? I don&apos;t believe even our closest family or friends warrant that level of devotion. As humans, we are deeply flawed, and our understanding of someone&apos;s true motivations is greatly diminished in parasocial relationships, such as those with celebrities, influencers, or politicians. In my opinion, we need not defend every policy decision made by our preferred party, nor should we oppose every action taken by the opposing party.&lt;/p&gt;
&lt;p&gt;While I would like to see people behave with more compassion, kindness, and selflessness, I believe we should approach political allegiances rationally and objectively. Rather than aligning ourselves rigidly with a specific ideology, we ought to evaluate each individual step or policy a party takes based on its potential benefits or detriments to society and ourselves. Our voices should be raised in support or opposition accordingly, disassociated from partisan loyalties.&lt;/p&gt;
&lt;p&gt;The greatest advantage of this centrist approach is that it prevents others from exploiting our egos and conditioning us to blindly defend every action taken by &quot;our&quot; party. We avoid the trap of grasping at straws to justify misguided policies, and conversely, we remain open to acknowledging positive steps taken by the opposition, rather than reflexively opposing them due to partisan prejudice. As the adage goes,&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Don&apos;t throw the baby out with the bathwater.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;We must accept that no policy will ever please everyone.&lt;/p&gt;
&lt;p&gt;Political parties derive much of their strength from unity, making them more resilient to hypocrisy and doublespeak by attributing such failings to a few &quot;bad apples.&quot; This deflection becomes far more difficult on an individual level; the moment we begin parroting or defending a party&apos;s contradictions, we have surrendered our autonomy to their programming. Likewise, alienating loved ones over their support for an opposing party is to surrender our personal unity – our greatest source of strength.&lt;/p&gt;
&lt;p&gt;It is reasonable to distance ourselves from toxic individuals or those engaged in heinous activities. However, cutting ties with others solely over their political affiliations seems misguided and counterproductive. We must acknowledge that, for better or worse, others will never share our precise intellectual and emotional perspectives. Our priorities will inevitably diverge to some degree, no matter how reasoned our arguments are.&lt;/p&gt;
&lt;p&gt;While we can endeavour to broaden others&apos; considerations, we will never convince everyone of our viewpoint. Alienating and dehumanizing loved ones through tribalism merely enables politicians to &quot;divide and rule&quot; according to their interests, not ours. History has shown the peril of such divisions; we must resist them at all costs.&lt;/p&gt;
</content:encoded><author>Vaibhav Sharma</author></item><item><title>Tress of the Emerald Sea — A Very Cosmere Fairy Tale</title><link>https://theleakycauldronblog.com/articles/tress-of-the-emerald-sea-review</link><guid isPermaLink="true">https://theleakycauldronblog.com/articles/tress-of-the-emerald-sea-review</guid><description>&lt;img alt=&quot;Tress of the Emerald Sea — A Very Cosmere Fairy Tale&quot; src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Fsippingsaltytea.CIXDtXCs.jpg&amp;w=1354&amp;h=773&amp;dpl=699bfef0c4120e00087ee35a&quot; /&gt; Dive into a conversational journey through Brandon Sanderson’s “Tress of the Emerald Sea.” Discover a fairy-tale world where spores float, dragons soar, and a window washer named Tress shows us the power of thoughtfulness.</description><pubDate>Mon, 08 Apr 2024 12:30:00 GMT</pubDate><content:encoded>&lt;p&gt;So, diving into &lt;em&gt;“Tress of the Emerald Sea”&lt;/em&gt; was like stepping into a different Sanderson universe, right? It’s got this light, fairy-tale vibe that’s not what you’d expect after books like &lt;a href=&quot;https://theleakycauldronblog.com/articles/mistborn-the-final-empire-review/&quot;&gt;Mistborn&lt;/a&gt; or &lt;a href=&quot;https://theleakycauldronblog.com/articles/warbreaker-brandon-sanderson-review/&quot;&gt;Warbreaker&lt;/a&gt;. And Tress, she’s not your typical hero with crazy powers. She’s just super practical and thoughtful, which totally makes sense since she’s used to chilling on her own while washing windows.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Warning: May Contain Mild Spoilers&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I totally loved how Sanderson showed us Tress’s uniqueness without making her “the chosen one.” And her dad! Instead of the usual unsupportive parent angle, we get this beautiful moment that really shows why Tress is so full of love and empathy.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;It might seem that the person who can feel for others is doomed in life. Isn’t one person’s pain enough? Why must a person like Tress feel for two, or more? Yet I’ve found that the people who are the happiest are the ones who learn best how to feel. It takes practice, you know. Effort. And those who (late in life) have been feeling for two, three, or a thousand different people…well, turns out they’ve had a leg up on everyone else all along.&lt;/p&gt;
&lt;p&gt;Empathy is an emotional loss leader. It pays for itself eventually.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It’s refreshing to see a character like Tress who’s confident and self-assured. We’re so used to seeing characters who have to overcome self-doubt, but Tress? She grows without losing herself, and she’s never arrogant because she’s always thinking of others.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Like a firm handshake in human form.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The world-building blew my mind! The spores, the seas, and the whole sciencey feel to it? Genius. And the Crow’s Song? Gave me major “One Piece” vibes. Captain Crow was basically Pirate Alvida in my head, no joke.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Tress would have made an excellent philosopher. In fact, she had already determined that philosophy wasn’t as valuable as she’d assumed — something that takes most great philosophers at least three decades to realize.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;For someone new to the Cosmere, seeing Hoid in all his glory was super exciting. It’s tough to dodge spoilers, but man, the theories are flying! And the Dougs, Fort’s quest for his “HUNT,” and the twist with Ulaam being a Kandra? Mind. Blown.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;That stupid shapeshifter was enjoying this. I swear, they’ve all been getting weirder ever since Sazed released them.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Okay, the Tosher story might not be everyone’s cup of tea, but hey, variety is the spice of life, right? And the tension with the spores, the sorceress showdown, and that gut-punch with Pakson’s death? Classic Sanderson, keeping us on our toes.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Heroism is often the seemingly spontaneous result of a lifetime of preparation.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I was rooting for Tress to take over the kitchen from the start, and when it finally happened, it felt like a key piece of her journey. And that dragon encounter? Handled with finesse. Plus, the whole Midnight’s Essence thing? As someone with Thalassophobia, that was intense.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Indeed, the path to a life without empathy is a long and painful one, full of bartered humanity sold at a steep discount.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The Phallic Tower being the Sorceress’s spaceship, the “Laptop,” “Tablet,” “Screens,” and “Hacking” stuff? I’m betting they’ll pop up again, maybe in &lt;em&gt;&lt;strong&gt;Mistborn Era 3 - Ghostbloods&lt;/strong&gt;&lt;/em&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Don’t wake me up unless Death himself has shown up, nails in his eyes.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If I had to nitpick, Riian’s motivation was a bit fuzzy, which isn’t like Sanderson at all. But the coolest part? I didn’t hate a single character, not even the baddies. And yes, not to forget the Cosmere Cat! I’m dying to know if they’re different like &lt;a href=&quot;https://starwars.fandom.com/wiki/Loth-cat&quot;&gt;Loth cats&lt;/a&gt; or just regular Earth kitties.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Memories have a way of changing on us. Souring or sweetening over time—like a brew we drink, then recreate later by taste, only getting the ingredients mostly right. You can’t taste a memory without tainting it with who you have become.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So, that’s my take on “Tress of the Emerald Sea.” It’s a book that’s as fun as it is deep, and it’s got that Sanderson magic that makes you think, laugh, and gasp all the way through. What about you? What did you think?&lt;/p&gt;
</content:encoded><author>Vaibhav Sharma</author></item><item><title>Warbreaker by Brandon Sanderson — Another Cosmere Gem</title><link>https://theleakycauldronblog.com/articles/warbreaker-brandon-sanderson-review</link><guid isPermaLink="true">https://theleakycauldronblog.com/articles/warbreaker-brandon-sanderson-review</guid><description>&lt;img alt=&quot;Warbreaker by Brandon Sanderson — Another Cosmere Gem&quot; src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Fwarbreaker-brandon-sanderson-bill-williams.BTPjpCrF.jpg&amp;w=1920&amp;h=1080&amp;dpl=699bfef0c4120e00087ee35a&quot; /&gt; A review of Warbreaker by Brandon Sanderson, a tale of twists, tears, and tantalizing characters. One of the best Cosmere Novellas.</description><pubDate>Sun, 24 Mar 2024 12:30:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;strong&gt;Mistborn &lt;a href=&quot;https://theleakycauldronblog.com/articles/mistborn-the-final-empire-review/&quot;&gt;The Final Empire&lt;/a&gt;&lt;/strong&gt; was my introduction to &lt;em&gt;Brandon Sanderson&lt;/em&gt;&apos;s work. And, while it was great, it was a YA Novel at its core, despite having very mature characterizations. Which meant it felt like I would have appreciated it better when I was younger. So, when I started &lt;strong&gt;&lt;a href=&quot;https://theleakycauldronblog.com/articles/mistborn-the-well-of-ascension-review&quot;&gt;The Well of Ascension&lt;/a&gt;&lt;/strong&gt; I didn&apos;t expect it to grow so fast into something more than a mere YA Novel, the &lt;em&gt;Sanderlanche&lt;/em&gt; at the end was mind blowing. And then &lt;strong&gt;&lt;a href=&quot;https://theleakycauldronblog.com/articles/mistborn-the-hero-of-ages-review&quot;&gt;The Hero of Ages&lt;/a&gt;&lt;/strong&gt; quickly and unsurprisingly became one of the best fantasy books I had ever read! But I had no idea how much I would like Warbreaker when I was getting into it, since I had not heard much, if at all, about this book. The book was not token YA at all, rather, it got into mature in themes like sex, metal health, poverty and torture (though none of it is explicit in nature). I believe if the humor lands for you, you&apos;ll love this book.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Warning: May Contain Mild Spoilers!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Warbreaker captivated me from the very start with its impeccably paced narrative, striking a perfect balance between suspense and excitement. While the build-up maintained a steady rhythm, it never once felt tedious or drawn-out, keeping me thoroughly engaged throughout.&lt;/p&gt;
&lt;p&gt;One of the unexpected delights of Warbreaker was its humor, which consistently brought a smile to my face. The clever wit infused into the dialogue made for delightful reading, adding depth to the characters and the world they inhabit.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;You see, the great thing about madness is that it&apos;s all in your head.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Speaking of characters, Warbreaker boasts a cast that is both diverse and compelling. Each character&apos;s motivations are intricately woven into the narrative, making even the so-called &quot;evil&quot; ones strangely endearing. The twists and turns, particularly surrounding characters like Denth and Tonk Fah, kept me on the edge of my seat, with Brandon Sanderson expertly leading readers down unexpected paths.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I like words. And I always learn a few new ones when Father gets angry. I shouldn&apos;t neglect my education, now should I?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;While the character development was masterfully executed, there were moments of disappointment, such as the underutilization of Parlin(who was a nod to &lt;a href=&quot;https://en.wikipedia.org/wiki/Link_(The_Legend_of_Zelda)&quot;&gt;Link&lt;/a&gt;, from &lt;a href=&quot;https://en.wikipedia.org/wiki/The_Legend_of_Zelda&quot;&gt;The Legend of Zelda Franchise&lt;/a&gt;) and the seemingly forgettable nature of his demise. This aspect left me feeling somewhat disillusioned with certain characters, particularly Vivenna.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;To Parlin&apos;s mind, nothing showed affection like a hunk of something dead and bleeding on the table.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;However, the dynamic between Siri and Susebron provided a welcome respite, their interactions brimming with charm and depth. Despite this, I couldn&apos;t shake the feeling that Susebron&apos;s potential remained largely untapped, leaving me yearning for more exploration of his character.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&apos;That is sarcasm,&apos; Susebron said. &apos;She is quite fond of it.&apos;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Every scene featuring Lightsong added a layer of brilliance to the narrative, his wit and charisma elevating the story to new heights. His ultimate sacrifice was a poignant moment that left me with goosebumps and tears in my eyes, a testament to the depth of his character and the impact of his actions.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;My life to yours. My breath become yours.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Despite its many strengths, Warbreaker is not without its flaws. The ending, in particular, felt rushed, with an excessive amount of exposition crammed into the final chapters. While the revelations were captivating, I couldn&apos;t help but wish for a more gradual unfolding of events, allowing readers the opportunity to piece together the puzzle themselves.&lt;/p&gt;
&lt;p&gt;Overall, Warbreaker is a captivating tale filled with richly drawn characters and intricate plot twists. While it may not be perfect, its strengths far outweigh its weaknesses, cementing its place as a must-read for fans of epic fantasy.&lt;/p&gt;
</content:encoded><author>Vaibhav Sharma</author></item><item><title>Use Cloudflare Zaraz to implement Disqus performantly</title><link>https://theleakycauldronblog.com/articles/use-cloudflare-zaraz-implement-disqus</link><guid isPermaLink="true">https://theleakycauldronblog.com/articles/use-cloudflare-zaraz-implement-disqus</guid><description>&lt;img alt=&quot;Use Cloudflare Zaraz to implement Disqus performantly&quot; src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Fdisqus-comments-zaraz-catherine-heath.7_oOehyh.jpg&amp;w=4240&amp;h=2384&amp;dpl=699bfef0c4120e00087ee35a&quot; /&gt; Use Cloudflare Zaraz to implement Disqus performantly by offloading resource-intensive third-party scripts to a web worker freeing up your main thread for your code.</description><pubDate>Thu, 14 Mar 2024 12:30:00 GMT</pubDate><content:encoded>&lt;p&gt;Using Third-Party Embeddings is always taxing on the performance metrics, but none(in my opinion) are as bad as Disqus, or as I call it — The Necessary Evil. It has a million errors &amp;amp; warnings, outdated APIs and is overall a mess! It&apos;s so bad that I wonder if Disqus has dropped their entire dev team! I have seen people employ multiple strategies to combat this issue, like clicking to load comments, separate pages for comments, web worker loaders etc.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Web worker loader offloads resource-intensive third-party scripts to a web worker freeing up your main thread for your code.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Out of all these, I found web worker strategies to be the most natural user experience. There are a few web worker providers like &lt;a href=&quot;https://partytown.builder.io&quot;&gt;Partytown&lt;/a&gt; and &lt;a href=&quot;https://www.cloudflare.com/application-services/products/zaraz/&quot;&gt;Cloudflare Zaraz&lt;/a&gt; that are mostly preferred.&lt;/p&gt;
&lt;h2&gt;Prerequisite&lt;/h2&gt;
&lt;p&gt;This tutorial assumes you already have Cloudflare DNS setup for your Website or Cloudflare is your DNS Provider.&lt;/p&gt;
&lt;h2&gt;Why did I choose Zaraz over Partytown?&lt;/h2&gt;
&lt;p&gt;My blog is built with &lt;a href=&quot;https://www.gatsbyjs.com&quot;&gt;Gatsby JS&lt;/a&gt;, which has native support for Partytown. So, you must be wondering why I went with Zaraz, let me tell you, I didn&apos;t, at least not at first. I first attempted to implement it with the &lt;a href=&quot;https://www.gatsbyjs.com/docs/reference/built-in-components/gatsby-script/&quot;&gt;Gatsby Script API off-main-thread strategy&lt;/a&gt;, which is a fancy wrapper on Partytown. But that didn&apos;t work out because it was built for &lt;em&gt;Gatsby Cloud&lt;/em&gt; primarily, and even though Netlify claims, it supports the redirections required to make it work,(via &lt;code&gt;gatsby-adapter-netlify&lt;/code&gt;), I couldn&apos;t make it work. And not for the lack of trying, as I wasn&apos;t the only one who found this task nearly impossible, given the forum posts, I encountered. This naturally left me with the only available option — Cloudflare Zaraz.&lt;/p&gt;
&lt;h2&gt;Embedding Disqus&lt;/h2&gt;
&lt;p&gt;Embedding Disqus has three steps:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Create a &lt;code&gt;&amp;lt;div/&amp;gt;&lt;/code&gt; with id &lt;code&gt;&quot;disqus_thread&quot;&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Implement a config loading function.&lt;/li&gt;
&lt;li&gt;Insert the Disqus embedding JS.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;div id=&quot;disqus_thread&quot;&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;script&amp;gt;
    /**
    *  RECOMMENDED CONFIGURATION VARIABLES: EDIT AND UNCOMMENT THE SECTION BELOW TO INSERT DYNAMIC VALUES FROM YOUR PLATFORM OR CMS.
    *  LEARN WHY DEFINING THESE VARIABLES IS IMPORTANT: https://disqus.com/admin/universalcode/#configuration-variables    */
    /*
    var disqus_config = function () {
    this.page.url = PAGE_URL;  // Replace PAGE_URL with your page&apos;s canonical URL variable
    this.page.identifier = PAGE_IDENTIFIER; // Replace PAGE_IDENTIFIER with your page&apos;s unique identifier variable
    };
    */
    (function() { // DON&apos;T EDIT BELOW THIS LINE
    var d = document, s = d.createElement(&apos;script&apos;);
    s.src = &apos;https://EXAMPLE.disqus.com/embed.js&apos;;
    s.setAttribute(&apos;data-timestamp&apos;, +new Date());
    (d.head || d.body).appendChild(s);
    })();
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Frontend Code&lt;/h3&gt;
&lt;p&gt;The first step is easy enough - just add a &lt;code&gt;div&lt;/code&gt; to the page where you want the comments. Next, add the &lt;code&gt;disqus_config&lt;/code&gt; script to the page where you want the comments, and replace the variables, since I&apos;m using Gatsby, I&apos;ll be using Gatsby&apos;s Script API, and pass the page &lt;code&gt;URL&lt;/code&gt;, &lt;code&gt;identifier&lt;/code&gt; and title to it, and push it to production.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import {Script, ScriptStrategy} from &apos;gatsby&apos;
.
.
.
&amp;lt;&amp;gt;
      &amp;lt;div id=&quot;disqus_thread&quot; className=&quot;p-3 md:px-0 md:py-5&quot; /&amp;gt;

      &amp;lt;Script
        id={id}
        strategy={ScriptStrategy.postHydrate}
        dangerouslySetInnerHTML={{
          __html: `var disqus_config = function () {
            this.page.url = &quot;${url}&quot;;
            this.page.identifier = &quot;${id}&quot;; 
            this.page.title = &quot;${title}&quot;;
          };`,
        }}
      /&amp;gt;

      &amp;lt;noscript&amp;gt;
        &amp;lt;div className=&quot;p-3 md:px-0 md:py-5&quot;&amp;gt;
          Please enable JavaScript to view the{&apos; &apos;}
          &amp;lt;a href=&quot;https://disqus.com/?ref_noscript&quot;&amp;gt;
            comments powered by Disqus.
          &amp;lt;/a&amp;gt;
        &amp;lt;/div&amp;gt;
      &amp;lt;/noscript&amp;gt;
&amp;lt;/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Implementing Disqus Script with Cloudflare Zaraz&lt;/h3&gt;
&lt;p&gt;Go to your project, and then, in the left side panel, click on Zaraz.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;src/assets/media/screenshot-2024-03-14-at-11.17.48%E2%80%AFam.jpg&quot; alt=&quot;Cloudflare Zaraz in left side panel&quot; title=&quot;Cloudflare Zaraz in left side panel&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The way Zaraz works is you have to create a &lt;code&gt;trigger&lt;/code&gt; and attach that trigger to the code you want to insert into your website. There are a few templates, but Disqus is not one of them, so we&apos;ll use a &lt;code&gt;Custom HTML Tool&lt;/code&gt; to insert it. So click on Custom HTML.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;src/assets/media/screenshot-2024-03-14-at-11.26.21%E2%80%AFam.jpg&quot; alt=&quot;Custom HTML Tool&quot; title=&quot;Custom HTML Tool&quot; /&gt;&lt;/p&gt;
&lt;p&gt;You&apos;ll be asked for a few permissions, grant them, and give it a name.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;src/assets/media/screenshot-2024-03-14-at-11.26.38%E2%80%AFam.jpg&quot; alt=&quot;Confirm permission&quot; title=&quot;Confirm permission&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;src/assets/media/screenshot-2024-03-14-at-11.26.45%E2%80%AFam.jpg&quot; alt=&quot;Execute JS permission&quot; title=&quot;Execute JS permission&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;src/assets/media/screenshot-2024-03-14-at-11.27.02%E2%80%AFam.jpg&quot; alt=&quot;Name the tool&quot; title=&quot;Name the tool&quot; /&gt;&lt;/p&gt;
&lt;p&gt;While Zaraz provides a default trigger i.e. &lt;code&gt;Pageview&lt;/code&gt;, which loads on every page view, we don&apos;t want to load Disqus scripts on every page, so we&apos;ll create a new Trigger by going to &lt;em&gt;Triggers&lt;/em&gt; tab and clicking on Create a trigger. We&apos;ll add two rules to this trigger —&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;first, that&apos;ll identify the page to load the script on, by checking if the URL contains &lt;code&gt;/blog/&lt;/code&gt; (although you can use whatever identifying pattern you want)&lt;/li&gt;
&lt;li&gt;and second, that&apos;ll check if the user has scrolled enough that we should begin loading the comments, I have used a scroll depth of 50%, you can choose your own. Though I&apos;d recommend at least 10%, or else it sometimes doesn&apos;t work.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;src/assets/media/screenshot-2024-03-14-at-11.17.13%E2%80%AFam.jpg&quot; alt=&quot;Create Trigger&quot; title=&quot;Create Trigger&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Then we go to the Third-Party Tools tab and click on Disqus &amp;gt; Edit and add the Trigger &lt;code&gt;Blog view&lt;/code&gt; and the Disqus &lt;code&gt;embed.js&lt;/code&gt; to it.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;src/assets/media/screenshot-2024-03-16-at-8.13.39%E2%80%AFpm.jpg&quot; alt=&quot;Third-party tool&quot; title=&quot;Third-party tool&quot; /&gt;&lt;/p&gt;
&lt;p&gt;This should load Disqus comments on your website using Zaraz.&lt;/p&gt;
</content:encoded><author>Vaibhav Sharma</author></item><item><title>Diving into The Cosmere Part III: The Hero of Ages Review</title><link>https://theleakycauldronblog.com/articles/mistborn-the-hero-of-ages-review</link><guid isPermaLink="true">https://theleakycauldronblog.com/articles/mistborn-the-hero-of-ages-review</guid><description>&lt;img alt=&quot;Diving into The Cosmere Part III: The Hero of Ages Review&quot; src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Fhero-of-ages-review-izabela-kraus.CORE1Avg.jpg&amp;w=6000&amp;h=4000&amp;dpl=699bfef0c4120e00087ee35a&quot; /&gt; Review for the final book in the Mistborn Trilogy, The Hero of Ages by Brandon Sanderson, as he brings us to the wrap of Era 1.</description><pubDate>Mon, 04 Mar 2024 12:30:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;strong&gt;Warning: May Contain Mild Spoilers!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The last two books were very interesting but I went into this with an irrational fear — what if the ending is not good enough especially for the high bar it had set in past two books, because i have seen multiple times when something starts great but ends up being a dud in the ending. But thankfully it was exactly that — an irrational fear.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Fmistborn-the-hero-of-ages.Du66bRNi.jpg&amp;amp;w=658&amp;amp;h=1000&amp;amp;dpl=699bfef0c4120e00087ee35a&quot; alt=&quot;mistborn-the-hero-of-ages&quot; title=&quot;Mistborn: The Hero of Ages&quot; /&gt;&lt;/p&gt;
&lt;p&gt;As I embarked on the final leg of the Mistborn journey with &quot;Hero of Ages,&quot; I was greeted by a familiar yet evolved world — one where Emperor Elend teetered on the edge of becoming a new Lord Ruler, a testament to the complexity of power and its seductive allure.&lt;/p&gt;
&lt;p&gt;Despite hearing murmurs about Elend&apos;s sudden transformation into an overpowering figure, I found his evolution to be both believable and compelling. Tindwyl&apos;s influence in last book and his newfound Mistborn abilities played pivotal roles in shaping him into the formidable emperor he became. Yet, amidst his power, Elend&apos;s internal struggles humanized him, adding depth to his character and heightening the poignancy of his relationship with Vin.&lt;/p&gt;
&lt;p&gt;The impact of loss reverberated through the narrative, as the deaths of crew members weighed heavily on their comrades. Each character&apos;s journey was marked by grief and growth, underscoring the human element at the heart of the story.&lt;/p&gt;
&lt;p&gt;Sazed&apos;s portrayal of depression was both well-written and realistic, yet at times, it felt overly focused and slowed the pace of the narrative. However, amidst the darkness, Spook&apos;s thrilling storyline provided a welcome respite, feeling like a mini-novel within the larger tapestry of the tale.&lt;/p&gt;
&lt;p&gt;TenSoon&apos;s arc and the exploration of Kandra culture added depth to the world-building, presenting them as distinct entities rather than mere shapeshifters. The nuanced portrayal of characters gaining respect for the fallen Lord Ruler without redeeming his actions struck a delicate balance, adding layers of complexity to the narrative.&lt;/p&gt;
&lt;p&gt;Yomen emerged as a worthy adversary, his respectful demeanor adding depth to the conflict that ensued. The divine entities of Ruin and Preservation were masterfully crafted, their lore steeped in meaning and intervention tempered by limitation.&lt;/p&gt;
&lt;p&gt;The final stand of Elend and Vin brought tears to my eyes, a testament to the emotional resonance of their journey. And amidst the chaos, Sazed emerged as the true hero of ages, his ascension to godhood a culmination of a beautifully crafted arc.&lt;/p&gt;
&lt;p&gt;In the end, &quot;Hero of Ages&quot; delivered a worthy conclusion to the Mistborn trilogy — one filled with grandeur, emotion, and unexpected twists. It was a journey that defied expectations, leaving me awestruck by the sheer brilliance of Brandon Sanderson&apos;s storytelling prowess.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Mistborn Era 1 Reviews&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://theleakycauldronblog.com/articles/mistborn-the-final-empire-review/&quot;&gt;The Final Empire Review&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://theleakycauldronblog.com/articles/mistborn-the-well-of-ascension-review/&quot;&gt;The Well of Ascension Review&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
</content:encoded><author>Vaibhav Sharma</author></item><item><title>Diving into The Cosmere Part II: The Well of Ascension Review</title><link>https://theleakycauldronblog.com/articles/mistborn-the-well-of-ascension-review</link><guid isPermaLink="true">https://theleakycauldronblog.com/articles/mistborn-the-well-of-ascension-review</guid><description>&lt;img alt=&quot;Diving into The Cosmere Part II: The Well of Ascension Review&quot; src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Fwell-of-ascension-review-hasan-almasi.C4qx51Xm.jpg&amp;w=5184&amp;h=3456&amp;dpl=699bfef0c4120e00087ee35a&quot; /&gt; Review for the book The Well of Ascension by Brandon Sanderson, the second book in the Era 1 of Mistborn series</description><pubDate>Sat, 02 Mar 2024 12:30:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;strong&gt;Warning: May Contain Mild Spoilers!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;As I made it clear in my previous review, I really loved the first book in the Mistborn Era 1, though it left me with lingering questions about the ominous warning of &lt;em&gt;Lord Ruler&lt;/em&gt;. So, I started the Book 2 immediately.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Fmistborn-the-well-of-ascension.9S6Be-4a.jpg&amp;amp;w=660&amp;amp;h=1000&amp;amp;dpl=699bfef0c4120e00087ee35a&quot; alt=&quot;mistborn-the-well-of-ascension&quot; title=&quot;Mistborn: The Well of Ascension&quot; /&gt;&lt;/p&gt;
&lt;p&gt;And the journey continued in &quot;Well of Ascension,&quot; where the aftermath of revolution laid bare the complexities of power and the turmoil it leaves in its wake.&lt;/p&gt;
&lt;p&gt;The initial chapters painted a vivid picture of the instability and power vacuum created by the revolution — a stark reminder of the consequences of upheaval and change. The impact of Kelsier&apos;s death reverberated through the narrative, affecting each member of the crew in profoundly different ways. The deification of Kelsier felt hauntingly realistic, showcasing how legends are born from the ashes of tragedy.&lt;/p&gt;
&lt;p&gt;Enter Straff, a brilliantly crafted antagonist whose portrayal felt eerily reminiscent of real-world figures rather than typical fantasy villains. His presence added a layer of depth to the narrative, challenging the traditional notions of good and evil.&lt;/p&gt;
&lt;p&gt;However, not all characters resonated equally. Zane&apos;s inclusion felt forced, and the attempted love triangle seemed out of place, particularly given Vin&apos;s established character. Yet, amidst these missteps, Vin&apos;s struggles with anxiety were portrayed with raw authenticity, adding a layer of depth to her character that felt relatable on a personal level.&lt;/p&gt;
&lt;p&gt;Elend&apos;s journey from idealism to pragmatism struck a chord with me, mirroring the struggles many face when thrust into positions of power. His development was nuanced and realistic, offering insights that resonated deeply with my own experiences.&lt;/p&gt;
&lt;p&gt;The politicking in the middle of the book admittedly bogged down the pace, but amidst the quagmire of political maneuvering, characters like Tindwyl shone brightly. Her role in shaping Elend&apos;s leadership and her subtle yet powerful relationship with Sazed added layers of depth to the narrative, enriching the story in unexpected ways.&lt;/p&gt;
&lt;p&gt;The ending of &quot;The Well of Ascension&quot; surpassed its predecessor in every way. Each death and victory stirred my emotions, while the twists sent chills down my spine. Sazed and TenSoon emerged as new favorites, their character arcs adding richness and depth to the narrative.&lt;/p&gt;
&lt;p&gt;Yet, despite its strengths, the uneven pacing remained a notable flaw. The journey truly found its stride in Part 5 of the book, with the payoffs making the earlier struggles worthwhile.&lt;/p&gt;
&lt;p&gt;In hindsight, &quot;The Well of Ascension&quot; was a testament to Brandon Sanderson&apos;s ability to weave intricate tales of power and personal struggle. It was a journey marked by highs and lows, triumphs and tragedies — a journey that left me eagerly anticipating the next installment in the Mistborn series.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Mistborn Era 1 Reviews&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://theleakycauldronblog.com/articles/mistborn-the-final-empire-review&quot;&gt;The Final Emire Review&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://theleakycauldronblog.com/articles/mistborn-the-hero-of-ages-review&quot;&gt;The Hero of Ages Review&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
</content:encoded><author>Vaibhav Sharma</author></item><item><title>Diving into The Cosmere Part I: Mistborn The Final Empire Review</title><link>https://theleakycauldronblog.com/articles/mistborn-the-final-empire-review</link><guid isPermaLink="true">https://theleakycauldronblog.com/articles/mistborn-the-final-empire-review</guid><description>&lt;img alt=&quot;Diving into The Cosmere Part I: Mistborn The Final Empire Review&quot; src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Fthe-final-empire-review-cederic-vandenberghe.DoghTK7N.jpg&amp;w=5935&amp;h=3962&amp;dpl=699bfef0c4120e00087ee35a&quot; /&gt; This is my review of diving into the fantastic world of Brandon Sanderson&apos;s Cosmere, with Mistborn The Final Empire.</description><pubDate>Mon, 26 Feb 2024 12:30:00 GMT</pubDate><content:encoded>&lt;p&gt;Although I love Harry Potter and Lord of the Rings I&apos;m not much of a Fantasy reader; I mostly stick to Sci-Fi books. And though, I had heard a lot about Brandon Sanderson, the sheer number of pages per book and the number of books had made me avoid getting into Cosmere for the longest time. Then somehow I stumbled upon &quot;that Wired article&quot; (&apos;Brandon Sanderson is your God&apos; not gonna provide a link to that hit piece and increase its engagement) insulting Brandon Sanderson, and after reading it, instead of the intended effect, he rather came off as a great guy. So, I decided to dive into Cosmere by following his very own 2024 reading guide.&lt;/p&gt;
&lt;p&gt;https://youtu.be/0mC8dsQJK7w&lt;/p&gt;
&lt;h2&gt;Brandon Sanderson&apos;s 2024 Cosmere Reading Order&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;The Final Empire&lt;/li&gt;
&lt;li&gt;The Well of Ascension&lt;/li&gt;
&lt;li&gt;The Hero of Ages&lt;/li&gt;
&lt;li&gt;Warbreaker&lt;/li&gt;
&lt;li&gt;Tress of the Emerald Sea&lt;/li&gt;
&lt;li&gt;The Way of Kings&lt;/li&gt;
&lt;li&gt;The Alloy of Law&lt;/li&gt;
&lt;li&gt;Words of Radiance&lt;/li&gt;
&lt;li&gt;Shadows of Self&lt;/li&gt;
&lt;li&gt;Edgedancer&lt;/li&gt;
&lt;li&gt;The Bands of Mourning&lt;/li&gt;
&lt;li&gt;Oathbringer&lt;/li&gt;
&lt;li&gt;The Lost Metal&lt;/li&gt;
&lt;li&gt;Dawnshard&lt;/li&gt;
&lt;li&gt;Rhythm of War&lt;/li&gt;
&lt;li&gt;Elantris&lt;/li&gt;
&lt;li&gt;Yumi and The Nightmare Painter&lt;/li&gt;
&lt;li&gt;The Sunlit Man&lt;/li&gt;
&lt;li&gt;Wind and Truth&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Warning: May Contain Mild Spoilers!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Entering the world of Mistborn through &quot;The Final Empire&quot; was akin to stepping into a realm where shadows danced with intrigue and despair. At first, the pace felt slow, but the intricate setup of this grim, dark world gradually drew me in, weaving a web of curiosity that I couldn&apos;t escape.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Fmistborn-the-final-empire.DxTKI1R2.jpg&amp;amp;w=660&amp;amp;h=1000&amp;amp;dpl=699bfef0c4120e00087ee35a&quot; alt=&quot;mistborn-the-final-empire&quot; title=&quot;Mistborn: The Final Empire&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The introduction of Kelsier, a troublemaker with layers of complexity, was a highlight. Initially, I saw him as a rebel without a cause, but as the layers of his character peeled away, I found myself captivated by his depth and determination. He became a character I couldn&apos;t help but admire.&lt;/p&gt;
&lt;p&gt;Vin, too, struck a chord with me. Her portrayal as someone scarred by an abusive childhood resonated deeply, adding a layer of realism to her character that made her journey all the more compelling.&lt;/p&gt;
&lt;p&gt;What truly stood out, however, was the dynamic ensemble of characters that comprised the crew. Each member possessed a distinct personality, and as I journeyed alongside them, I found myself becoming intimately familiar with their quirks and motivations. It was as though I could predict their reactions in any given situation — a testament to the author&apos;s skill in crafting relatable characters.&lt;/p&gt;
&lt;p&gt;The magic system introduced in &quot;The Final Empire&quot; is unparalleled in its complexity and ingenuity. The way each aspect of magic is intricately woven into the fabric of the trilogy as a whole is nothing short of masterful. It adds layers of depth to the story, enriching the world-building and driving the plot forward in unexpected ways.&lt;/p&gt;
&lt;p&gt;The portrayal of nobles and skaa felt incredibly realistic, highlighting the stark divide between the privileged and the oppressed. Their contrasting perspectives and prejudices added another layer of complexity to an already richly textured narrative.&lt;/p&gt;
&lt;p&gt;Encountering Hoid, a character often spoken of in memes, was a delightfully unexpected surprise — a nod to the interconnectedness of the Cosmere universe.&lt;/p&gt;
&lt;p&gt;The inquisitors and the Lord Ruler himself instilled a sense of dread and foreboding, adding a chilling element to the story that sent shivers down my spine.&lt;/p&gt;
&lt;p&gt;While the ending of &quot;The Final Empire&quot; felt satisfying, I couldn&apos;t shake the feeling that Vin bordered on Mary Sue territory. However, as I delved further into the trilogy, I came to appreciate the deliberate nature of her character arc. It was a subtle nuance that might have been difficult to grasp initially but added depth upon reflection.&lt;/p&gt;
&lt;p&gt;And then there&apos;s Sazed — an unsung hero whose quiet strength and unwavering loyalty stole my heart.&lt;/p&gt;
&lt;p&gt;In hindsight, &quot;The Final Empire&quot; was almost perfect, with its only flaw being a slight dip in pacing in the middle. But even that minor hiccup couldn&apos;t detract from the overall brilliance of Brandon Sanderson&apos;s storytelling. It was a journey that left me eager to delve deeper into the world of Mistborn, eager to uncover its secrets and unravel its mysteries.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Mistborn Era 1 Reviews&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://theleakycauldronblog.com/articles/mistborn-the-well-of-ascension-review&quot;&gt;The Well of Ascension Review&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://theleakycauldronblog.com/articles/mistborn-the-hero-of-ages-review&quot;&gt;The Hero of Ages Review&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
</content:encoded><author>Vaibhav Sharma</author></item><item><title>Healing After Heartbreak: A Guide to Moving Forward</title><link>https://theleakycauldronblog.com/articles/healing-after-heartbreak-healthily</link><guid isPermaLink="true">https://theleakycauldronblog.com/articles/healing-after-heartbreak-healthily</guid><description>&lt;img alt=&quot;Healing After Heartbreak: A Guide to Moving Forward&quot; src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Fcontent-pixie-2v5pjggqyts-unsplash.BK0IEoP6.jpg&amp;w=6000&amp;h=4000&amp;dpl=699bfef0c4120e00087ee35a&quot; /&gt; Discover advice for overcoming heartbreak, finding hope, and embracing a better future. You&apos;re not alone on this journey. Deal with it properly and move forward in a healthy manner.</description><pubDate>Sun, 06 Aug 2023 12:30:00 GMT</pubDate><content:encoded>&lt;p&gt;I know it&apos;s tough. I know you&apos;re going through a lot.&lt;/p&gt;
&lt;p&gt;BUT&lt;/p&gt;
&lt;p&gt;I sincerely believe that sharing these points can help someone. I won&apos;t bore anyone with a lot of details about my past and my relationship but you can take my word for it that it was tight (but it also had its ups and downs). I didn&apos;t breakup, she did. She cheated on me and long distance + COVID + family issues were huge factors.&lt;/p&gt;
&lt;h2&gt;Succint Points&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;No contact and kill the hope (it&apos;s gone, you have to accept it)&lt;/li&gt;
&lt;li&gt;There&apos;s tradeoffs - maybe they will go on with their life with different issues in a different relationship and maybe you will go on with your life with different issues in a different relationship. The bottom line is there&apos;s always someone out there with a different set of tradeoffs that might interlock better with your criterion&lt;/li&gt;
&lt;li&gt;Time is not of essence, the moments are. Someone can make you feel the same stuff in 2 months that a person can make you feel in 4 years&lt;/li&gt;
&lt;li&gt;Forgive them, don&apos;t go into the revenge mindset. Thinking about anything vengeful, thinking about karma and how karma will take its revenge and stuff is also futile. Indifference is the key&lt;/li&gt;
&lt;li&gt;Don&apos;t be ashamed of therapy - it helps make you feel better (especially if you&apos;ve been cheated on). They will help validate some of the feelings you have and push you to not victimize yourself&lt;/li&gt;
&lt;li&gt;Having a really good support system - Friends, family, girlfriends anyone who can make you feel better. For me it was mainly my new girlfriend, friends and then family (in descending order of helpfulness)&lt;/li&gt;
&lt;li&gt;Delete those photos, delete those chats, delete the memories that take you back. Take that bitter pill because it&apos;ll help you a hell lot&lt;/li&gt;
&lt;li&gt;Take that vacation, seeing the same set of faces can fuck you up. For me, it was taking a trip back to my parents&apos; place and I met my current gf there&lt;/li&gt;
&lt;li&gt;Time will heal you and make it better. Shit happens. Shit happens to everyone. You are not alone. Never ever think that&lt;/li&gt;
&lt;li&gt;Insta reels about breakups and stuff can help, but ...... eh&lt;/li&gt;
&lt;li&gt;Learn something new - I learnt bike riding. Helped out a lot. I went on treks. I just said yes to all outings&lt;/li&gt;
&lt;li&gt;It always helps to understand that there&apos;s worse that could&apos;ve happened. I could&apos;ve been married and then found out that she is a cheater. I&apos;m happy that I failed faster. Thank your lucky stars that it ended. Even if it&apos;s your fault, believe that whatever has happened, has happened for the good&lt;/li&gt;
&lt;li&gt;Rebound or no rebound doesn&apos;t matter. Don&apos;t start a new relationship with any agenda. Just let it flow and believe that it&apos;ll be different. Don&apos;t go looking for patterns that match with your ex. Let it be fresh - like you&apos;re going through a different journey altogether&lt;/li&gt;
&lt;li&gt;Don&apos;t try to victimize yourself, don&apos;t get addicted to the sadness. Don&apos;t think that you need to be in mourning for a certain period of time. Your life doesn&apos;t have to be that same old depressing movie. At a certain point, you need to snap out of it and make space for something better&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;All in all I would say one thing to end this already long post. Try and cope up with it healthily. Try to not let it affect your present. I know it&apos;s a lot of philosophy, it may/may not help you, but I am telling you with complete confidence that there&apos;s nothing to be ashamed of. There&apos;s nothing to be afraid of and you are not alone. Have faith that your future is going to be better. There&apos;s plenty of fish in the sea.&lt;/p&gt;
</content:encoded><author>Rishabh Chakrabarti</author></item><item><title>Upgrading My Blog to Gatsby v5 with TypeScript and Tailwind CSS</title><link>https://theleakycauldronblog.com/articles/upgrading-blog-gatsby-typescript-tailwindcss</link><guid isPermaLink="true">https://theleakycauldronblog.com/articles/upgrading-blog-gatsby-typescript-tailwindcss</guid><description>&lt;img alt=&quot;Upgrading My Blog to Gatsby v5 with TypeScript and Tailwind CSS&quot; src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Fandrew-neel-upgrading-blog-gatsby-typescript-tailwindcss.a-ef_web.jpg&amp;w=6000&amp;h=4000&amp;dpl=699bfef0c4120e00087ee35a&quot; /&gt; Discover the journey of upgrading my blog to Gatsby v5 with TypeScript. Enhanced performance, new features, and improved design await!</description><pubDate>Tue, 01 Aug 2023 12:30:00 GMT</pubDate><content:encoded>&lt;p&gt;When I first started this blog, I was among the early adopters of &lt;a href=&quot;https://www.gatsbyjs.com/docs&quot;&gt;Gatsby JS&lt;/a&gt;, a static site generator that allowed me to create blazing-fast websites with React and GraphQL. However, in those early days, Gatsby was still evolving, and the plugin ecosystem was not as mature and stable as it is today. As each new release brought improvements, it also brought its fair share of challenges. Nonetheless, I persevered, learning from issues that arose and helping others in the process.&lt;/p&gt;
&lt;p&gt;By the time I released version 2 of my website using Gatsby 3, the platform had significantly matured, and it offered more stability and features. However, one crucial aspect was missing - TypeScript support. It was time to address this limitation and make my codebase more robust.&lt;/p&gt;
&lt;h2&gt;The Journey Begins: Moving to TypeScript and Tailwind CSS&lt;/h2&gt;
&lt;p&gt;I decided to embark on a journey to upgrade my blog to Gatsby v5 and integrate TypeScript support. But before that, I needed to address some design aspects of the blog. My existing CSS toolkit, Tachyons, served me well, but it seemed to have been abandoned. Tailwind CSS, which had gained tremendous popularity, offered similar benefits without complex setup requirements.&lt;/p&gt;
&lt;p&gt;To eliminate bloat and unnecessary dependencies, I decided to rewrite my codebase from scratch, retaining only the Markdown pages from the previous version. I started by generating a new Gatsby project with TypeScript, Tailwind CSS, and Netlify CMS. This fresh foundation would set the stage for a cleaner and more efficient blog.&lt;/p&gt;
&lt;h2&gt;Revamping Styling with &lt;code&gt;shadcn/ui&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;To maintain consistency in styling and ensure future extensibility, I sought out a suitable component system. After exploring various options, I settled on &lt;a href=&quot;https://ui.shadcn.com&quot;&gt;&lt;code&gt;shadcn/ui&lt;/code&gt;&lt;/a&gt;, a flexible framework that generates component files, allowing for infinite customization possibilities. This choice provided the perfect balance of convenience and control, saving me the trouble of designing a new component system from scratch.&lt;/p&gt;
&lt;h2&gt;Improving User Experience: Pagination and Search Functionality&lt;/h2&gt;
&lt;p&gt;Before diving into styling, I prioritized implementing pagination. The plugin I previously used for this feature, &lt;code&gt;gatsby-paginate&lt;/code&gt;, had been abandoned. Instead of relying on outdated code, I decided to write my pagination functionality from scratch, providing a tailored solution that better suited my needs.&lt;/p&gt;
&lt;p&gt;Moreover, the search functionality on my blog required enhancement. With the previous &lt;code&gt;@gatsby-contrib/gatsby-plugin-elasticlunr-search&lt;/code&gt; plugin now abandoned, I integrated &lt;code&gt;Lunr&lt;/code&gt; search using &lt;code&gt;gatsby-plugin-local-search&lt;/code&gt;, a powerful JavaScript-based search engine. This upgrade improved the search experience for my readers and ensured they could easily find the content they were looking for.&lt;/p&gt;
&lt;h2&gt;Removing Excess Features and Embracing New Ones&lt;/h2&gt;
&lt;p&gt;As part of this migration process, I reevaluated the features present on my blog. I decided to remove certain elements that were either outdated or posed more problems than benefits. Among the features I discarded were:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Site-wide branding with &lt;code&gt;config.js&lt;/code&gt;:&lt;/strong&gt; To maintain branding consistency across the site i was using a config.js file but removed that in favor of &lt;code&gt;react-i18next&lt;/code&gt; as it was a dual purpose solution.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Embedding support for various services:&lt;/strong&gt; I streamlined the embedded content to avoid clutter and improve loading times.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Offline support:&lt;/strong&gt; While it sounded good on paper, I found that offline support created more issues than it resolved, so I decided to drop it.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cookie consent:&lt;/strong&gt; The previous cookie consent implementation was unreliable, so I removed it in favor of a better user experience.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Web Vitals tracking:&lt;/strong&gt; Cloudflare&apos;s Real User Monitoring (RUM) already handled this aspect efficiently.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Google Tag Manager (GTM):&lt;/strong&gt; I wanted to implement it using &lt;code&gt;partytown&lt;/code&gt; support that Gatsby Script API provides, so I experimented with off-main-thread strategies for GTM integration, but turns out the redirects didn&apos;t work on netlify, so removed it in favor of &lt;em&gt;Cloudflare Zaraz&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Newsletter form:&lt;/strong&gt; Simplified my approach by removing the newsletter form, reducing maintenance overhead.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Introducing New Features and Enhancements&lt;/h2&gt;
&lt;p&gt;Amidst the removal of unnecessary features, I also introduced some exciting new additions to my blog:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Site-wide branding using &lt;code&gt;react-i18next&lt;/code&gt;:&lt;/strong&gt; This allowed me to make a base to provide multilingual support in future while still acting as a one stop config hub.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Automatic Dark mode:&lt;/strong&gt; Catering to the growing trend and preferences for dark mode, I incorporated this feature to give users more control over their reading experience.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cloudflare &lt;em&gt;Zaraz&lt;/em&gt;:&lt;/strong&gt; By integrating &lt;em&gt;&lt;a href=&quot;https://www.cloudflare.com/application-services/products/zaraz/&quot;&gt;Zaraz&lt;/a&gt;&lt;/em&gt;, I gained more granular control over tracking and analytics on my blog, without blocking main thread.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Contact form using &lt;code&gt;react-hook-form&lt;/code&gt; and validation with &lt;code&gt;zod&lt;/code&gt;:&lt;/strong&gt; To ensure a smoother experience for users interacting with the contact form, I migrated from &lt;code&gt;Formik&lt;/code&gt; to &lt;code&gt;react-hook-form&lt;/code&gt;, and for validation, I switched from &lt;code&gt;yup&lt;/code&gt; to &lt;code&gt;zod&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Licensing changes:&lt;/strong&gt; I made licensing more explicit, separating licenses for posts, the code within them, and the Gatsby website. Thanks &lt;a href=&quot;https://twitter.com/dan_abramov&quot;&gt;@dan_abramov&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Typescript and GraphQL type generation:&lt;/strong&gt; Adding TypeScript support allowed for better code maintenance and provided improved type safety. Additionally, GraphQL type generation further enhanced the development workflow.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Optimization and Bloat Removal&lt;/h2&gt;
&lt;p&gt;One of the primary goals of this migration was to optimize performance and eliminate bloat. I meticulously reviewed each part of the website, optimizing queries, removing unused packages, and employing best practices to enhance loading times and overall user experience.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;The journey of moving my blog to Gatsby v5 with TypeScript was both challenging and rewarding. By adopting the latest features and shedding unnecessary baggage, I was able to create a more efficient, better-performing, and future-proof blog. Embracing TypeScript and enhancing the design with Tailwind CSS streamlined the development process, making it more enjoyable and maintainable.&lt;/p&gt;
&lt;p&gt;As the web continues to evolve, so will my blog. I look forward to exploring new technologies, optimizing performance, and delivering valuable content to my readers while staying true to the core principles of simplicity and efficiency. So, welcome to the new and improved blog - fast, functional, and ready to engage!&lt;/p&gt;
</content:encoded><author>Vaibhav Sharma</author></item><item><title>Why Mario 64 speedrun record cannot be broken</title><link>https://theleakycauldronblog.com/articles/mario-64-unbreakable-speedrun-cosmic-fluke</link><guid isPermaLink="true">https://theleakycauldronblog.com/articles/mario-64-unbreakable-speedrun-cosmic-fluke</guid><description>&lt;img alt=&quot;Why Mario 64 speedrun record cannot be broken&quot; src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Fclaudio-luiz-castro-mario-64-unbreakable-speedrun-record.CPwIkxT0.jpg&amp;w=5184&amp;h=3456&amp;dpl=699bfef0c4120e00087ee35a&quot; /&gt; Unbreakable Glory: The Cosmic Fluke Behind Mario 64&apos;s Unbeatable Speedrun Record</description><pubDate>Sat, 29 Jul 2023 12:30:00 GMT</pubDate><content:encoded>&lt;p&gt;Speed-running is the act of playing a game to complete it as fast as possible, usually with the help of sequence breaking and glitches. Among the myriad retro games that have captured the hearts of gamers, &lt;a href=&quot;https://en.wikipedia.org/wiki/Super_Mario_64&quot;&gt;&lt;strong&gt;Super Mario 64&lt;/strong&gt;&lt;/a&gt; stands as a timeless classic with a speedrun record that seems destined to remain unbroken. In this blog post, we delve into the fascinating story of how a cosmic fluke forever altered the course of Mario 64&apos;s speed-running history.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://www.twitch.tv/dota_teabag&quot;&gt;DOTA_Teabag&lt;/a&gt;&lt;/strong&gt;, a prominent figure in the speedrunning community, embarked on a quest to break Mario 64&apos;s speedrun record. Little did he know that fate had something extraordinary in store for him. While live streaming his run on &lt;a href=&quot;https://www.twitch.tv/&quot;&gt;Twitch&lt;/a&gt;, an unimaginable glitch transported Mario to a higher part of the level. This unprecedented occurrence meant that DOTA_Teabag had inadvertently set an unbreakable speedrun record for the beloved game.&lt;/p&gt;
&lt;p&gt;What caused this freakish glitch that altered Mario&apos;s trajectory and bestowed him with an unattainable advantage? The answer lies in a phenomenon originating from the depths of outer space: cosmic rays. Cosmic rays are high-energy particles, primarily protons and atomic nuclei, that zoom through the universe at incredible speeds.&lt;/p&gt;
&lt;p&gt;Mario 64, like all computer-based systems, relies on binary code, with data represented by sequences of 0s and 1s. Even the tiniest alteration to this binary data can lead to significant changes in the program&apos;s behaviour, known as &quot;&lt;a href=&quot;https://en.wikipedia.org/wiki/RAM_parity&quot;&gt;bit flipping&lt;/a&gt;&quot;. Herein lies the crux of the matter—when a cosmic ray collides with a computer&apos;s memory, it can cause a single-bit change, leading to unexpected results.&lt;/p&gt;
&lt;p&gt;In DOTA_Teabag&apos;s case, an elusive cosmic ray struck the computer at just the right moment and the perfect location, causing a single-bit change to Mario&apos;s height value. This unforeseen alteration launched the Italian plumber skyward through the level, bypassing obstacles and achieving an unparalleled speedrun time.&lt;/p&gt;
&lt;p&gt;The chances of such an event occurring are astronomically low, making DOTA_Teabag&apos;s achievement nearly impossible to replicate intentionally. The alignment of celestial forces, the precise timing of the cosmic ray, and the exact location it hit the computer all converged to create the unbeatable speedrun record.&lt;/p&gt;
&lt;p&gt;The captivating world of speedrunning is filled with tales of triumphs and failures, pushing the boundaries of what seems humanly possible. Within this realm, Mario 64&apos;s unbreakable speedrun record stands as a testament to the unforeseeable power of cosmic rays and the intricacies of binary code. DOTA_Teabag&apos;s journey unwittingly intertwined with celestial forces, forever solidifying his place in gaming folklore. As the speedrunning community continues to strive for perfection, the tale of Mario 64&apos;s cosmic glitch serves as a reminder that, at times, the universe itself can intervene in the pursuit of gaming greatness.&lt;/p&gt;
</content:encoded><author>Vaibhav Sharma</author></item><item><title>Migrating From WebStorm to VS Code</title><link>https://theleakycauldronblog.com/articles/migrating-from-webstorm-to-vscode</link><guid isPermaLink="true">https://theleakycauldronblog.com/articles/migrating-from-webstorm-to-vscode</guid><description>&lt;img alt=&quot;Migrating From WebStorm to VS Code&quot; src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Fjuanjo-jaramillo-vscode-webstorm.DaaYmJ1q.jpg&amp;w=5184&amp;h=3456&amp;dpl=699bfef0c4120e00087ee35a&quot; /&gt; Join my journey as I switch from WebStorm to VS Code! Discover the reasons behind the switch, how I overcame challenges, and embraced VS Code&apos;s lightness and extensibility.</description><pubDate>Mon, 24 Jul 2023 12:30:00 GMT</pubDate><content:encoded>&lt;p&gt;As we all know, all the cool devs have to have a few things - No Social Life, VS Code and crippling coffee addiction. I figured the only thing left for me to become a cool dev like rest of you guys, was to use VS Code. But let&apos;s take a step back and talk about why I hadn&apos;t jumped on the VS Code train...yet!&lt;/p&gt;
&lt;h2&gt;Why I use WebStorm(and other JetBrains IDEs)&lt;/h2&gt;
&lt;p&gt;Back in my uni days, as a fresh-faced coder diving into Android development, I was stuck with Eclipse - and let&apos;s just say it was a total mess. But then, like a shining beacon, Android Studio came along and saved the day. That was my first taste of JetBrains IDEs, and man, was I hooked! As I ventured into Python, PyCharm became my go-to. The best part? My college email ID got me free access to all their products - score! So when it was time to tackle React, I naturally landed on WebStorm, and it&apos;s been my ride-or-die ever since.&lt;/p&gt;
&lt;h2&gt;What I like about WebStorm(and other JetBrains IDEs)&lt;/h2&gt;
&lt;p&gt;Let me tell you, the code completion, auto import, and code refactoring in WebStorm are straight-up unmatched! The auto-format feature (&lt;code&gt;⌘ + ⌥ + L&lt;/code&gt;) and the import optimization (&lt;code&gt;^ + ⌥ + O&lt;/code&gt;) are gifts from the coding gods! Every time I fired up the IDE, it showered me with useful tips and best practices, making me a better coder by the day. Learning new stuff, whether it&apos;s React or TypeScript, felt like a breeze. And Git? Oh boy, WebStorm made it feel like child&apos;s play. No wonder I never looked at other editors like &lt;code&gt;Atom&lt;/code&gt; or &lt;code&gt;VS Code&lt;/code&gt; when they launched - if it ain&apos;t broke, don&apos;t fix it, right?&lt;/p&gt;
&lt;h2&gt;Why I Decided to Give VS Code a Shot&lt;/h2&gt;
&lt;p&gt;Recently my M2 MacBook Air&apos;s screen started to show horizontal lines(seems like they haven&apos;t fixed the display hinge issues plaguing the MacBooks since 2016), fortunately, it was fixed under warranty, but unfortunately, it meant that I had no (properly working) machine for a week, so I had to borrow my brother&apos;s gaming laptop to work. And since I didn&apos;t want to install too much gunk on my brother&apos;s laptop I decided to keep things light and installed just the basics - Docker, Node JS, and VS Code. Surprisingly, even with resource-intensive projects like Docker and  Next JS, VS Code&apos;s memory usage was significantly lower than WebStorm&apos;s. This, combined with the allure of trying something new, sparked my interest in making the switch. Armed with the Gryffindor spirit, I embarked on the journey of learning VS Code, integrating Tailwind CSS, and transitioning my Gatsby code to TypeScript, embracing challenges head-on.&lt;/p&gt;
&lt;h2&gt;The Roadblocks I Faced&lt;/h2&gt;
&lt;p&gt;The first big problem was of course keybindings, which was expected as I had been using WebStorm for almost a decade, and the unreliable code completion, lack of advanced refactoring, auto-formatting, and snippets were also huge hurdles. And let&apos;s not forget Git support - decent, but not as smooth as WebStorm&apos;s. But the biggest problem was debugging with &lt;code&gt;launch.json&lt;/code&gt;. Let me explain, WebStorm has a way of detecting &lt;code&gt;npm&lt;/code&gt; scripts, chaining them, choice of using &lt;code&gt;yarn&lt;/code&gt; or &lt;code&gt;npm&lt;/code&gt;. Whereas the auto-configuration of VS Code was severely lacking, and I really didn’t wanna learn what seemed like a substantial set of commands to write &lt;code&gt;launch.json&lt;/code&gt;. What’s worse is that when I generate &lt;code&gt;launch.json&lt;/code&gt; the comments say to learn about the command with &lt;code&gt;IntelliCode&lt;/code&gt; but the problem with &lt;code&gt;IntelliCode&lt;/code&gt; is that it doesn’t always trigger for some reason.&lt;/p&gt;
&lt;h2&gt;How I Tackled the Challenges&lt;/h2&gt;
&lt;p&gt;TL;DR: Extensions, lots of extensions...&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://media.giphy.com/media/ZUVPTMpehuqkH8HH2h/giphy.gif&quot; alt=&quot;guns-lots-of-guns&quot; title=&quot;Guns, Lots of Guns&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The first big hurdle, keybindings, was easy to overcome, there’s an extension for it, IntelliJ IDEA Keybindings. Actually, most hurdles were easy to overcome using extensions, almost every problem I could think of had an extension that solved it(mostly) -&lt;code&gt;IntelliCode&lt;/code&gt;, &lt;code&gt;Auto Rename Tags&lt;/code&gt;, &lt;code&gt;JS Codeformer, ES7+ React/Redux/React-Native snippets&lt;/code&gt; etc Adding the keybindings along with &lt;code&gt;ESLint&lt;/code&gt;, &lt;code&gt;Prettier&lt;/code&gt;, made auto format accessible. And Git Lens enhanced the Git support and made it relatively powerful.&lt;/p&gt;
&lt;h3&gt;Debugging with &lt;code&gt;launch.json&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;Okay, I won&apos;t lie - no magical auto-configuration here. But the community had my back! Shoutout to fellow devs who shared their launch.json setups for Vite, Next JS, and Gatsby. With a little tweaking, I was back on track.&lt;/p&gt;
&lt;h4&gt;Next JS&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;launch.json&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
    &quot;version&quot;: &quot;0.2.0&quot;,
    &quot;configurations&quot;: [
        {
            &quot;name&quot;: &quot;Dev&quot;,
            &quot;type&quot;: &quot;node&quot;,
            &quot;request&quot;: &quot;launch&quot;,
            &quot;runtimeExecutable&quot;: &quot;yarn&quot;,
            &quot;runtimeArgs&quot;: [
                &quot;run&quot;,
                &quot;dev&quot;
            ],
            &quot;cwd&quot;: &quot;${workspaceFolder}&quot;,
            &quot;serverReadyAction&quot;: {
                &quot;pattern&quot;: &quot;🚀 started server on .+, url: (https?://.+)&quot;,
                &quot;uriFormat&quot;: &quot;%s&quot;,
                &quot;action&quot;: &quot;debugWithChrome&quot;
            },
            &quot;preLaunchTask&quot;: &quot;devTasks&quot;
        },
        {
            &quot;name&quot;: &quot;Build&quot;,
            &quot;type&quot;: &quot;node&quot;,
            &quot;request&quot;: &quot;launch&quot;,
            &quot;runtimeExecutable&quot;: &quot;yarn&quot;,
            &quot;runtimeArgs&quot;: [
                &quot;run&quot;,
                &quot;build&quot;
            ],
            &quot;cwd&quot;: &quot;${workspaceFolder}&quot;,
            &quot;preLaunchTask&quot;: &quot;devTasks&quot;
        },
        {
            &quot;name&quot;: &quot;Start&quot;,
            &quot;type&quot;: &quot;node&quot;,
            &quot;request&quot;: &quot;launch&quot;,
            &quot;runtimeExecutable&quot;: &quot;yarn&quot;,
            &quot;runtimeArgs&quot;: [
                &quot;run&quot;,
                &quot;start&quot;
            ],
            &quot;cwd&quot;: &quot;${workspaceFolder}&quot;,
            &quot;serverReadyAction&quot;: {
                &quot;pattern&quot;: &quot;🚀 started server on .+, url: (https?://.+)&quot;,
                &quot;uriFormat&quot;: &quot;%s&quot;,
                &quot;action&quot;: &quot;debugWithChrome&quot;
            },
            &quot;preLaunchTask&quot;: &quot;startTasks&quot;
        },
    ],
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;tasks.json&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
    &quot;version&quot;: &quot;2.0.0&quot;,
    &quot;tasks&quot;: [
        {
            &quot;label&quot;: &quot;clean&quot;,
            &quot;type&quot;: &quot;shell&quot;,
            &quot;command&quot;: &quot;yarn run clean&quot;,
            &quot;group&quot;: {
                &quot;kind&quot;: &quot;build&quot;,
                &quot;isDefault&quot;: true
            }
        },
        {
            &quot;label&quot;: &quot;lint&quot;,
            &quot;type&quot;: &quot;shell&quot;,
            &quot;command&quot;: &quot;yarn run lint&quot;,
            &quot;group&quot;: {
                &quot;kind&quot;: &quot;build&quot;,
                &quot;isDefault&quot;: true
            }
        },
        {
            &quot;label&quot;: &quot;build&quot;,
            &quot;type&quot;: &quot;shell&quot;,
            &quot;command&quot;: &quot;yarn run build&quot;,
            &quot;group&quot;: {
                &quot;kind&quot;: &quot;build&quot;,
                &quot;isDefault&quot;: true
            }
        },
        {
            &quot;label&quot;: &quot;devTasks&quot;,
            &quot;dependsOrder&quot;: &quot;sequence&quot;,
            &quot;dependsOn&quot;: [
                &quot;clean&quot;,
                &quot;lint&quot;
            ],
            &quot;group&quot;: {
                &quot;kind&quot;: &quot;build&quot;,
                &quot;isDefault&quot;: true
            }
        },
        {
            &quot;label&quot;: &quot;startTasks&quot;,
            &quot;dependsOrder&quot;: &quot;sequence&quot;,
            &quot;dependsOn&quot;: [
                &quot;clean&quot;,
                &quot;lint&quot;,
                &quot;build&quot;
            ],
            &quot;group&quot;: {
                &quot;kind&quot;: &quot;build&quot;,
                &quot;isDefault&quot;: true
            }
        },
    ]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Gatsby JS&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;launch.json&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
    &quot;version&quot;: &quot;0.2.0&quot;,
    &quot;configurations&quot;: [
        {
            &quot;name&quot;: &quot;Gatsby Develop&quot;,
            &quot;type&quot;: &quot;node&quot;,
            &quot;request&quot;: &quot;launch&quot;,
            &quot;program&quot;: &quot;${workspaceRoot}/node_modules/.bin/gatsby&quot;,
            &quot;args&quot;: [
                &quot;develop&quot;
            ],
            &quot;env&quot;: {
                &quot;PARCEL_WORKERS&quot;: &quot;0&quot;,
                &quot;GATSBY_CPU_COUNT&quot;: &quot;1&quot;,
            },
            &quot;runtimeArgs&quot;: [
                &quot;--nolazy&quot;
            ],
            &quot;console&quot;: &quot;integratedTerminal&quot;
        },
        {
            &quot;name&quot;: &quot;Gatsby Build&quot;,
            &quot;type&quot;: &quot;node&quot;,
            &quot;request&quot;: &quot;launch&quot;,
            &quot;program&quot;: &quot;${workspaceRoot}/node_modules/.bin/gatsby&quot;,
            &quot;args&quot;: [
                &quot;build&quot;
            ],
            &quot;env&quot;: {
                &quot;PARCEL_WORKERS&quot;: &quot;0&quot;,
                &quot;GATSBY_CPU_COUNT&quot;: &quot;1&quot;,
            },
            &quot;runtimeArgs&quot;: [
                &quot;--nolazy&quot;
            ],
            &quot;console&quot;: &quot;integratedTerminal&quot;,
        },
        {
            &quot;name&quot;: &quot;Gatsby Serve&quot;,
            &quot;type&quot;: &quot;node&quot;,
            &quot;request&quot;: &quot;launch&quot;,
            &quot;program&quot;: &quot;${workspaceRoot}/node_modules/.bin/gatsby&quot;,
            &quot;args&quot;: [
                &quot;build&quot;
            ],
            &quot;env&quot;: {
                &quot;PARCEL_WORKERS&quot;: &quot;0&quot;,
                &quot;GATSBY_CPU_COUNT&quot;: &quot;1&quot;,
            },
            &quot;runtimeArgs&quot;: [
                &quot;--nolazy&quot;
            ],
            &quot;console&quot;: &quot;integratedTerminal&quot;,
            &quot;preLaunchTask&quot;: &quot;clean&quot;,
            &quot;postDebugTask&quot;: &quot;serve&quot;
        },
    ]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;tasks.json&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
    &quot;version&quot;: &quot;2.0.0&quot;,
    &quot;tasks&quot;: [
        {
            &quot;label&quot;: &quot;clean&quot;,
            &quot;type&quot;: &quot;shell&quot;,
            &quot;command&quot;: &quot;yarn run clean&quot;,
            &quot;group&quot;: {
                &quot;kind&quot;: &quot;build&quot;,
                &quot;isDefault&quot;: true
            }
        },
        {
            &quot;label&quot;: &quot;lint&quot;,
            &quot;type&quot;: &quot;shell&quot;,
            &quot;command&quot;: &quot;yarn run lint&quot;,
            &quot;group&quot;: {
                &quot;kind&quot;: &quot;build&quot;,
                &quot;isDefault&quot;: true
            }
        },
        {
            &quot;label&quot;: &quot;serve&quot;,
            &quot;type&quot;: &quot;shell&quot;,
            &quot;command&quot;: &quot;yarn run serve&quot;,
            &quot;group&quot;: {
                &quot;kind&quot;: &quot;build&quot;,
                &quot;isDefault&quot;: true
            }
        },
    ]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Vite&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;launch.json&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
    &quot;version&quot;: &quot;0.2.0&quot;,
    &quot;configurations&quot;: [
        {
            &quot;name&quot;: &quot;Develop&quot;,
            &quot;type&quot;: &quot;node&quot;,
            &quot;request&quot;: &quot;launch&quot;,
            &quot;runtimeExecutable&quot;: &quot;yarn&quot;,
            &quot;runtimeArgs&quot;: [
                &quot;run&quot;,
                &quot;dev&quot;
            ],
            &quot;cwd&quot;: &quot;${workspaceFolder}&quot;,
            &quot;console&quot;: &quot;integratedTerminal&quot;,
            &quot;sourceMaps&quot;: true,
            &quot;outFiles&quot;: [
                &quot;${workspaceFolder}/dist/**/*.js&quot;
            ],
            &quot;smartStep&quot;: true,
            &quot;skipFiles&quot;: [
                &quot;${workspaceFolder}/node_modules/**/*.js&quot;,
                &quot;&amp;lt;node_internals&amp;gt;/**/*.js&quot;
            ]
        },
        {
            &quot;name&quot;: &quot;Build&quot;,
            &quot;type&quot;: &quot;node&quot;,
            &quot;request&quot;: &quot;launch&quot;,
            &quot;runtimeExecutable&quot;: &quot;node&quot;,
            &quot;runtimeArgs&quot;: [
                &quot;${workspaceFolder}/node_modules/vite/bin/vite.js&quot;,
                &quot;build&quot;,
                &quot;--mode&quot;,
                &quot;development&quot;
            ],
            &quot;cwd&quot;: &quot;${workspaceFolder}&quot;,
            &quot;console&quot;: &quot;integratedTerminal&quot;,
            &quot;sourceMaps&quot;: true,
            &quot;outFiles&quot;: [
                &quot;${workspaceFolder}/dist/**/*.js&quot;
            ],
            &quot;smartStep&quot;: true,
            &quot;skipFiles&quot;: [
                &quot;${workspaceFolder}/node_modules/**/*.js&quot;,
                &quot;&amp;lt;node_internals&amp;gt;/**/*.js&quot;
            ]
        }
    ]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Final Verdict&lt;/h2&gt;
&lt;h3&gt;Was it worth it?&lt;/h3&gt;
&lt;p&gt;The transition to VS Code has been rewarding. I appreciate its lightness and extensibility, and though I occasionally miss WebStorm&apos;s features out of habit, I don&apos;t find myself lacking. As for neural networks and ML projects, I&apos;m yet to explore VS Code&apos;s capabilities fully and see if it can replace my beloved PyCharm.&lt;/p&gt;
&lt;h3&gt;Will I stay&lt;/h3&gt;
&lt;p&gt;Indeed, I plan to stick with VS Code. While JetBrains Fleet was an option, the free, battle-tested, and well-supported VS Code was a more natural fit for my needs. Although &lt;code&gt;launch.json&lt;/code&gt; remains a concern, the overall experience has been positive, making the switch well worth it.&lt;/p&gt;
</content:encoded><author>Vaibhav Sharma</author></item><item><title>Fahrenheit 451: An Alternate Perspective</title><link>https://theleakycauldronblog.com/articles/fahrenheit-451-alternate-perspective</link><guid isPermaLink="true">https://theleakycauldronblog.com/articles/fahrenheit-451-alternate-perspective</guid><description>&lt;img alt=&quot;Fahrenheit 451: An Alternate Perspective&quot; src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Ffred-kearney-fahrenheit-451-alternative-perspective.DDA-oO6u.jpg&amp;w=3270&amp;h=1817&amp;dpl=699bfef0c4120e00087ee35a&quot; /&gt; Fahrenheit 451 is no doubt a great read but what bugs me is that the book pretends to be about book burning and censorship but is actually mostly about shitting on new technologies at its core. But why?</description><pubDate>Sat, 18 Sep 2021 12:30:00 GMT</pubDate><content:encoded>&lt;p&gt;Yesterday I finished reading the book &lt;strong&gt;Fahrenheit 451&lt;/strong&gt;, oh wait did I say finished reading, more like, completed listening to the audiobook narrated by &lt;em&gt;Tim Robbins&lt;/em&gt;. Yes, I’m a &lt;em&gt;Neil DeGrasse Tyson&lt;/em&gt; certified badass who listens, instead of reads, a book that is all about the dangers of abandoning reading literature.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Fneiltysonbadass.BjCEb3cl.png&amp;amp;w=769&amp;amp;h=595&amp;amp;dpl=699bfef0c4120e00087ee35a&quot; alt=&quot;neil-degrasse-tyson-badass-meme&quot; title=&quot;neil-degrasse-tyson-badass-meme&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Fahrenheit 451 (or 232.778C in non retard units) is the temperature at which paper is said to self ignite, which is central to the story. The book is about a fireman, &lt;em&gt;Guy Montag&lt;/em&gt;, and set in a dystopian future where houses are fireproof. So, the firemen get repurposed to burn illegal books instead, to maintain social stability. Until he meets an eccentric girl, &lt;em&gt;Clarisse&lt;/em&gt;, who teaches him the joys of being a weirdo. The book emphasises on the dangers of censorship, consumption of mass media over books. It argues that doing so will leave us half dead half alive in our essence, just like the mechanised dog that hunts criminals, the mechanised snake that pumps stomach and &lt;em&gt;Mildred Montag&lt;/em&gt; (Guy Montag&apos;s wife) who’s your average millennial/gen-z kid buried in her iPad and AirPods. The book is very unsettling at times, is overall peppered with great ideas and makes us question whether the media most of us consume now, is just superficial. Also, the book predicted earphones, interactive media, ATMs etc. with eerie accuracy. It&apos;s no doubt a great read but what bugs me is that the book pretends to be about book burning and censorship but is actually mostly about shitting on new technologies at its core. But why?&lt;/p&gt;
&lt;p&gt;Ray Bradbury, since childhood, was obsessed with books but didn’t have the means to attend college after his high school ended. So, he took what he had and made the most of it by spending as much time as he could at the &lt;em&gt;Los Angeles Public Library&lt;/em&gt;. He used to be pissed that the library didn’t stock science fiction novels like those of &lt;em&gt;H.G. Wells&lt;/em&gt;, as they were deemed not literary enough. That and learning about the destruction of the &lt;em&gt;Library of Alexandria&lt;/em&gt; made a great impression on little Ray. Also, his early life saw the Golden Age of Radio. And then, during the &lt;em&gt;McCarthy&lt;/em&gt; era, the government started interfering with artists and creative kinds, all the while the world was transitioning to the Golden Age of Television, leading to the creation of the book Fahrenheit 451 on a typewriter that cost 20 cents an hour to rent.&lt;/p&gt;
&lt;p&gt;Now forgive me for my ignorance but, I never found Tim Robbins to be significant enough to recognise by name, even though I have seen &lt;em&gt;Shawshank Redemption&lt;/em&gt;. That and the fact that his voice seemed awfully similar to &lt;em&gt;Norm McDonald&lt;/em&gt;’s, made it more hilarious than the author intended it. It certainly didn’t help on how fuckin preachy and on the nose the writing itself was at times. The writing was clearly influenced by George Orwell but lacked the subtlety and complexity of his work. It read like a fanfiction of 1984 about kids these days, which is ironic since George Orwell famously once said ―&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Every generation imagines itself to be more intelligent than the one that went before it, and wiser than the one that comes after it.&lt;/p&gt;
&lt;p&gt;― George Orwell&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Fuckin’ teenagers with their Radio and TV!&lt;/p&gt;
&lt;p&gt;Generational labels get created to provide an order to our generally messy history and explain the concerned disappointment with the youth. This hate/disappointment for the youth is timeless with examples dating as far back as times of Aristotle, 4th century BC. And as is the tradition there’s always a relevant &lt;a href=&quot;https://xkcd.com/1227/&quot;&gt;XKCD comic&lt;/a&gt; for any situation. This inaccurate, exaggerated and sensational characterisation of young people is called &lt;strong&gt;Ephebiphobia&lt;/strong&gt;. But the sentiments of distaste and/or fear of the social culture associated with young people is perhaps better described by the term &lt;em&gt;Juvenoia&lt;/em&gt;. Perhaps, fuelled by the way our memories are notoriously affected by emotions of the time, making them less than reliable. But surely things are way worse than they were back in the good ol’ days, right? There’s no depth beneath the superficial stimulation of modern media, right?&lt;/p&gt;
&lt;p&gt;Popular science author and media theorist Steven Johnson argues that entertainment can now be made for all sorts of audiences to scratch all sorts of itches, with high rewatch value, encouraging discussion in online forums thus adding an intellectual level of depth that was never possible before. The complex web of names, relationships and events that people today have to keep straight in their heads to be socially aware consumers of mass media is impressive by historical standards. The time Ray Bradbury wrote his now-famous book about the dangers of mass media, it didn’t even have that much mass anyways. The steep rise in the consumption of mass media and interactive video games grew so much during the 90s that writer and media theorist &lt;em&gt;Douglas Rushkoff&lt;/em&gt; coined the term &lt;em&gt;Screenagers&lt;/em&gt;. Last year, Netflix took interactive storytelling to new levels with its production ― &lt;strong&gt;Black Mirror: Bandersnatch&lt;/strong&gt;. But what if books were invented after interactive storytelling options like the internet, video games and choose-your-own-ending movies?&lt;/p&gt;
&lt;p&gt;That’s exactly what was explored by Steven Johnson in his book ― &lt;em&gt;&lt;strong&gt;Everything Bad is Good for You&lt;/strong&gt;&lt;/em&gt;. He imagines a world where kids everywhere are starting to read these new trendy things ― books, causing the concerned parents and teachers to argue the following ―&lt;/p&gt;
&lt;p&gt;&quot;Perhaps, the most dangerous property of these books is the fact that they follow a fixed linear path. You can&apos;t control their narratives in any fashion. You simply sit back and have the story dictated to you. For those of us raised on interactive narratives, this property may seem astonishing. Why would anyone want to embark on an adventure utterly choreographed by another person? But today&apos;s generation embarks on such adventures millions of times a day. Reading is not an active participatory process, it&apos;s a submissive one. The book readers of the younger generation are learning to follow the plot instead of learning to lead.&quot;&lt;/p&gt;
&lt;p&gt;What if narcissistic selfies, memes and woke-ness are the most human things to do that we have yet discovered? After all, if historical trends are any indication then it’s pretty evident that we have only progressed as humans ― crimes committed by young people have decreased, academic proficiency has increased, hate comments have decreased etc. Then why is it that &lt;em&gt;Juvenoia&lt;/em&gt; still persists? I mean it makes sense biologically ― after all, parents were a genetic success for the species, they produced a future generation, so, it makes sense for them to have a bias towards the way they were raised. Maybe worrying about the future generation might have been natural selection as well, just like walking or breathing. But whatever may be the reason, whether we apply memories of our good ol&apos; days fairly and rationally or not, the thing that breeds greatness isn’t a particular method, but time. The same H. G. Well’s books that were not considered literary enough in Bradbury’s times are now considered some of the greatest pieces of sci-fi literature ever produced. So when it comes to cheap laughs and superficial pop songs, I’m reminded of renowned Spanish essayist, Miguel de Unamuno, who once put it as ―&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;More often I have seen a cat reason than laugh or weep. Perhaps it weeps or laughs inwardly. But then perhaps, also inwardly, a crab resolves equations of the second degree.&quot;&lt;/p&gt;
&lt;p&gt;― Miguel de Unamuno&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;That being said, I’d still recommend everyone to at least once read the book Fahrenheit 451, because beyond all the hate I spewed about technophobia in this article, it truly is a great story, we can all learn from it. Once immersed the reader will truly feel every emotion and dilemma that the protagonist faces, and perhaps a few more that weren’t put to words.&lt;/p&gt;
</content:encoded><author>Vaibhav Sharma</author></item><item><title>Basic Serverless Typeahead Search with Cloudflare Workers</title><link>https://theleakycauldronblog.com/articles/serverless-typeahead-search-cloudflare-workers</link><guid isPermaLink="true">https://theleakycauldronblog.com/articles/serverless-typeahead-search-cloudflare-workers</guid><description>&lt;img alt=&quot;Basic Serverless Typeahead Search with Cloudflare Workers&quot; src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Fmichael-rivera-serverless-typeahead-search.B_3zdcZr.jpg&amp;w=6000&amp;h=4000&amp;dpl=699bfef0c4120e00087ee35a&quot; /&gt; Use Cloudflare Workers and React to make a Basic Typeahead Search for Pokedex.</description><pubDate>Fri, 12 Mar 2021 12:30:00 GMT</pubDate><content:encoded>&lt;p&gt;Typeahead search progressively searches and filters as the user types his/her query. It’s also called &lt;strong&gt;predictive search&lt;/strong&gt;, &lt;strong&gt;incremental search&lt;/strong&gt; or &lt;strong&gt;search-as-you-type&lt;/strong&gt; and is an important feature of most search engines. In this tutorial, we’ll learn to make a very basic version of a &lt;em&gt;Pokémon&lt;/em&gt; Typeahead Search using &lt;strong&gt;Cloudflare Workers&lt;/strong&gt; and &lt;strong&gt;React&lt;/strong&gt;. Cloudflare provides generous &lt;strong&gt;100,000&lt;/strong&gt; requests per day in its free plan, making it perfect for an API like this.&lt;/p&gt;
&lt;h2&gt;Setup Cloudflare&lt;/h2&gt;
&lt;p&gt;We begin by signing up for a Cloudflare Workers account at &lt;a href=&quot;https://workers.cloudflare.com&quot;&gt;workers.cloudflare.com&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Fcloudflare-workers-homepage.WHPmLZrR.png&amp;amp;w=1874&amp;amp;h=1202&amp;amp;dpl=699bfef0c4120e00087ee35a&quot; alt=&quot;cloudflare-workers-homepage&quot; title=&quot;cloudflare-workers-homepage&quot; /&gt;&lt;/p&gt;
&lt;p&gt;In the onboarding screen, select a unique subdomain for our workers.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Fsetting-up-custom-subdomain.BrpHVRmp.jpg&amp;amp;w=1874&amp;amp;h=1202&amp;amp;dpl=699bfef0c4120e00087ee35a&quot; alt=&quot;setting-up-custom-subdomain&quot; title=&quot;setting-up-custom-subdomain&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;Installing Wrangler&lt;/h2&gt;
&lt;p&gt;To get the most out of Cloudflare Workers we need to install Wrangler CLI using &lt;code&gt;yarn&lt;/code&gt; or &lt;code&gt;npm&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;yarn global add @cloudflare/wrangler
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next we login to our Cloudflare Account with Wrangler CLI&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;wrangler login
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Fwrangler-login-terminal.BjbVv7Ua.png&amp;amp;w=1924&amp;amp;h=1274&amp;amp;dpl=699bfef0c4120e00087ee35a&quot; alt=&quot;wrangler-login-terminal&quot; title=&quot;wrangler-login-terminal&quot; /&gt;&lt;/p&gt;
&lt;p&gt;This will open up a page on your browser where you can authorise the wrangler.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Fwrangler-login-browser.CU83l4Lz.jpg&amp;amp;w=1874&amp;amp;h=706&amp;amp;dpl=699bfef0c4120e00087ee35a&quot; alt=&quot;wrangler-login-browser&quot; title=&quot;wrangler-login-browser&quot; /&gt;&lt;/p&gt;
&lt;p&gt;If it doesn’t work, you can manually log in using the config command and following the prompted instructions.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;wrangler config
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Setup A Worker Project&lt;/h2&gt;
&lt;p&gt;Wrangler CLI lets you set up a Cloudflare Worker project easily, as well as allows you to use Templates.&lt;/p&gt;
&lt;p&gt;We’ll be using the TypeScript template for our project. To set it up just use the following command.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;wrangler generate search-api https://github.com/cloudflare/worker-typescript-template
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, navigate to the project and open it using your favourite IDE and we can start writing the serverless code.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Fwrangler-generate-template.DWVAAolh.jpg&amp;amp;w=1700&amp;amp;h=1049&amp;amp;dpl=699bfef0c4120e00087ee35a&quot; alt=&quot;wrangler-generate-template&quot; title=&quot;wrangler-generate-template&quot; /&gt;&lt;/p&gt;
&lt;p&gt;But, before we begin to write our API, we need to add our &lt;code&gt;accound_id&lt;/code&gt; in the project’s &lt;code&gt;wrangler.toml&lt;/code&gt; file, as prompted while generating the project.&lt;/p&gt;
&lt;h2&gt;Writing the API&lt;/h2&gt;
&lt;p&gt;For our search to work there needs to be an index where our data is stored, here we’ll be using a &lt;a href=&quot;https://raw.githubusercontent.com/v4iv/pokedex/master/search/search-index.json&quot;&gt;JSON File&lt;/a&gt; of all the &lt;em&gt;Pokémons&lt;/em&gt; and their ID, that I generated using &lt;a href=&quot;https://pokeapi.co&quot;&gt;PokeAPI&lt;/a&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[
  {
    &quot;name&quot;: &quot;bulbasaur&quot;,
    &quot;id&quot;: 1
  },
  {
    &quot;name&quot;: &quot;ivysaur&quot;,
    &quot;id&quot;: 2
  },
  {
    &quot;name&quot;: &quot;venusaur&quot;,
    &quot;id&quot;: 3
  },
  {
    &quot;name&quot;: &quot;charmander&quot;,
    &quot;id&quot;: 4
  },
  .
  .
  .
  {
    &quot;name&quot;: &quot;eternatus-eternamax&quot;,
    &quot;id&quot;: 10217
  },
  {
    &quot;name&quot;: &quot;urshifu-single-strike-gmax&quot;,
    &quot;id&quot;: 10218
  },
  {
    &quot;name&quot;: &quot;urshifu-rapid-strike-gmax&quot;,
    &quot;id&quot;: 10219
  },
  {
    &quot;name&quot;: &quot;toxtricity-low-key-gmax&quot;,
    &quot;id&quot;: 10220
  }
]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can download and add it to the project’s &lt;code&gt;src&lt;/code&gt; folder as &lt;code&gt;pokedex.json&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;But we can’t directly import a JSON module to our typescript file, for that we need to add the following to the project’s &lt;code&gt;tsconfig.json&lt;/code&gt; file.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&quot;resolveJsonModule&quot;: true,
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now let’s open our &lt;code&gt;handler.ts&lt;/code&gt; file and start writing our API. We begin by importing our Pokémon Index file.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import pokedex from “./pokedex.json”
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, we get the &lt;code&gt;pathname&lt;/code&gt; and &lt;code&gt;query-string parameter&lt;/code&gt; from the &lt;code&gt;Request&lt;/code&gt; object.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const {pathname, searchParams} = new URL(request.url)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then we check if the &lt;code&gt;pathname&lt;/code&gt; is correct, else we respond with a &lt;code&gt;404 error&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;if (pathname === “/search”) {

} else return new Response(&quot;&quot;, {
   status: 404,
   statusText: &quot;Path Not Found!&quot;
   headers: {
       &apos;Access-Control-Allow-Origin&apos;: &apos;*&apos;,
       &apos;Access-Control-Allow-Methods&apos;: &apos;GET&apos;,
   },
})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And if the path is correct, we extract the exact query params we need to process our search:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const query = searchParams.get(“q”)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, we write the filter for the Pokémons according to our query.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const d = pokedex.filter(
   (pokemon) =&amp;gt;
       pokemon.name.toString().toLowerCase().includes(query.toLowerCase()) ||
       pokemon.id.toString().toLowerCase().includes(query.toLowerCase()),
)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally, we return the &lt;code&gt;stringified&lt;/code&gt; results in our &lt;code&gt;Response&lt;/code&gt; object along with CORS headers.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;return new Response(JSON.stringify(d), {
   headers: {
       &apos;Access-Control-Allow-Origin&apos;: &apos;*&apos;,
       &apos;Access-Control-Allow-Methods&apos;: &apos;GET&apos;,
   },
})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Completed code should look like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import pokedex from &apos;./pokedex.json&apos;


export async function handleRequest(request: Request): Promise&amp;lt;Response&amp;gt; {
 const { searchParams, pathname } = new URL(request.url)
 
 if (pathname === &apos;/search&apos;) {
   const query = searchParams.get(&apos;q&apos;) || &apos;&apos;
   
   const d = pokedex.filter(
     (pokemon) =&amp;gt;
       pokemon.name.toString().toLowerCase().includes(query.toLowerCase()) ||
       pokemon.id.toString().toLowerCase().includes(query.toLowerCase()),
   )

   return new Response(JSON.stringify(d), {
     headers: {
       &apos;Access-Control-Allow-Origin&apos;: &apos;*&apos;,
       &apos;Access-Control-Allow-Methods&apos;: &apos;GET&apos;,
     },
   })
 } else return new Response(&apos;&apos;, {
     status: 404,
     statusText: &apos;Path Not Found!&apos;,
     headers: {
       &apos;Access-Control-Allow-Origin&apos;: &apos;*&apos;,
       &apos;Access-Control-Allow-Methods&apos;: &apos;GET&apos;,
     },
   })
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Debugging and Publishing&lt;/h2&gt;
&lt;p&gt;Since this project is made with TypeScript we cannot directly run or publish it, for that we need a bundler like Webpack, which is preconfigured in the template we used.&lt;/p&gt;
&lt;p&gt;To debug locally, we need to first run the dev script to compile the typescript.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;yarn run dev
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then, we run the wrangler dev command.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;wrangler dev
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This should run the script on our localhost, where we can test it out by entering the following URL in our browser.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://127.0.0.1:8787/search?q=pika&quot;&gt;http://127.0.0.1:8787/search?q=pika&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Which should return a list of all the entries for Pikachu in our index.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[
  {&quot;name&quot;:&quot;pikachu&quot;,&quot;id&quot;:25},
  {&quot;name&quot;:&quot;pikachu-rock-star&quot;,&quot;id&quot;:10080},
  {&quot;name&quot;:&quot;pikachu-belle&quot;,&quot;id&quot;:10081},
  {&quot;name&quot;:&quot;pikachu-pop-star&quot;,&quot;id&quot;:10082},
  {&quot;name&quot;:&quot;pikachu-phd&quot;,&quot;id&quot;:10083},
  {&quot;name&quot;:&quot;pikachu-libre&quot;,&quot;id&quot;:10084},
  {&quot;name&quot;:&quot;pikachu-cosplay&quot;,&quot;id&quot;:10085},
  {&quot;name&quot;:&quot;pikachu-original-cap&quot;,&quot;id&quot;:10094},
  {&quot;name&quot;:&quot;pikachu-hoenn-cap&quot;,&quot;id&quot;:10095},
  {&quot;name&quot;:&quot;pikachu-sinnoh-cap&quot;,&quot;id&quot;:10096},
  {&quot;name&quot;:&quot;pikachu-unova-cap&quot;,&quot;id&quot;:10097},
  {&quot;name&quot;:&quot;pikachu-kalos-cap&quot;,&quot;id&quot;:10098},
  {&quot;name&quot;:&quot;pikachu-alola-cap&quot;,&quot;id&quot;:10099},
  {&quot;name&quot;:&quot;pikachu-partner-cap&quot;,&quot;id&quot;:10148},
  {&quot;name&quot;:&quot;pikachu-gmax&quot;,&quot;id&quot;:10190}
]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Once satisfied, we can build and publish it to our account using Wrangler CLI.&lt;/p&gt;
&lt;p&gt;To build in production mode, run the build script.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;yarn run build
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then, run the publish command.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;wrangler publish
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally, the backend part of this project is complete and we can access the live API from the browser, it should be something like this.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;https://search-api.&amp;lt;your-subdomain&amp;gt;.workers.dev/search?q=pika
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Frontend&lt;/h2&gt;
&lt;p&gt;Although the API we made earlier is front-end agnostic, I’ll be bootstrapping the web app using Create React App.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;yarn create react-app search-app --template typescript
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We’ll begin by removing &lt;code&gt;App.css&lt;/code&gt;, &lt;code&gt;App.test.ts&lt;/code&gt;, &lt;code&gt;index.css&lt;/code&gt; and &lt;code&gt;logo.svg&lt;/code&gt; (don’t forget to remove the &lt;code&gt;index.css&lt;/code&gt; import from &lt;code&gt;index.tsx&lt;/code&gt; file).&lt;/p&gt;
&lt;p&gt;To demonstrate the API I&apos;ll be using &lt;a href=&quot;https://gestalt.netlify.app&quot;&gt;Gestalt&lt;/a&gt;, a React Component Library by &lt;a href=&quot;https://pinterest.com&quot;&gt;Pinterest&lt;/a&gt; and Axios to fetch the data from the API, let&apos;s add it to our project.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;yarn add axios @types/gestalt@19.2.0 gestalt@19.2.2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, we add the Gestalt CSS file to our &lt;code&gt;index.tsx&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;...
import &quot;gestalt/dist/gestalt.css&quot;
...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then in the &lt;code&gt;App.tsx&lt;/code&gt; file, we delete the pre-existing code, make it a fresh &lt;code&gt;React Function Component&lt;/code&gt; and add the following code for our Search Field.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import React from &apos;react&apos;;
import {Box, Container, SearchField} from &quot;gestalt&quot;;

const App: React.FC = () =&amp;gt; {
   return (
       &amp;lt;&amp;gt;
           &amp;lt;Container&amp;gt;
               &amp;lt;Box flex=&quot;grow&quot;&amp;gt;
                   &amp;lt;SearchField
                       accessibilityLabel=&quot;Search&quot;
                       placeholder=&quot;Search&quot;
                       id=&quot;search&quot;
                       onChange={({value}) =&amp;gt; console.log(value)}
                   /&amp;gt;
               &amp;lt;/Box&amp;gt;
           &amp;lt;/Container&amp;gt;
       &amp;lt;/&amp;gt;
   );
};

export default App;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, we begin to build our search function by importing &lt;code&gt;axios&lt;/code&gt; and &lt;code&gt;useState&lt;/code&gt;, &lt;code&gt;useCallback&lt;/code&gt; Hooks and adding the search function to the &lt;code&gt;onChange&lt;/code&gt; attribute of Search Field.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import React, {useCallback, useState} from &apos;react&apos;;
import {Box, Container, SearchField} from &quot;gestalt&quot;;
import axios from &quot;axios&quot;;


const App: React.FC = () =&amp;gt; {
   const [results, setResults] = useState([])

   const search = useCallback((query) =&amp;gt; {
       axios
           .get(`${process.env.REACT_APP_SEARCH_API}/search?q=${query}`)
           .then(res =&amp;gt; {
               const pokemons = res.data
               setResults(pokemons)
           })
           .catch(err =&amp;gt; {
               console.error(err)

               setResults([])
           })
   }, [])

   return (
       &amp;lt;&amp;gt;
           &amp;lt;Container&amp;gt;
               &amp;lt;Box flex=&quot;grow&quot;&amp;gt;
                   &amp;lt;SearchField
                       accessibilityLabel=&quot;Search&quot;
                       placeholder=&quot;Search&quot;
                       id=&quot;search&quot;
                       onChange={({value}) =&amp;gt; search(value)}
                   /&amp;gt;
               &amp;lt;/Box&amp;gt;
           &amp;lt;/Container&amp;gt;
       &amp;lt;/&amp;gt;
   );
};

export default App;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note that we are using an environment variable for our API, that’s just for ease but you can hard code the API if you like.&lt;/p&gt;
&lt;p&gt;Finally, we write the code to display our results.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import React, {useCallback, useState} from &apos;react&apos;;
import {Avatar, Box, Container, SearchField, Text} from &quot;gestalt&quot;;
import axios from &quot;axios&quot;;


interface IPokemon {
   id: number,
   name: string
}

const App: React.FC = () =&amp;gt; {
   const [results, setResults] = useState([])

   const search = useCallback((query) =&amp;gt; {
       axios
           .get(`${process.env.REACT_APP_SEARCH_API}/search?q=${query}`)
           .then(res =&amp;gt; {
               setResults(res.data)
           })
           .catch(err =&amp;gt; {
               console.error(err)

               setResults([])
           })
   }, [])

   return (
       &amp;lt;&amp;gt;
           &amp;lt;Container&amp;gt;
               &amp;lt;Box flex=&quot;grow&quot;&amp;gt;
                   &amp;lt;SearchField
                       accessibilityLabel=&quot;Search&quot;
                       placeholder=&quot;Search&quot;
                       id=&quot;search&quot;
                       onChange={({value}) =&amp;gt; search(value)}
                   /&amp;gt;
               &amp;lt;/Box&amp;gt;

               {results.length
                   ? &amp;lt;Box paddingY={2}&amp;gt;
                       {results.map((pokemon: IPokemon) =&amp;gt; {
                           const pokemonName = pokemon.name
                           const pokemonImage = `https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/${pokemon.id}.png`

                           return &amp;lt;Box key={pokemon.id} borderStyle=&quot;sm&quot; marginBottom={2} rounding=&quot;pill&quot; padding={2}
                                       alignItems=&quot;center&quot; display=&quot;flex&quot;&amp;gt;
                               &amp;lt;Box paddingX={2}&amp;gt;
                                   &amp;lt;Avatar
                                       name={pokemonName}
                                       src={pokemonImage}
                                       size=&quot;xs&quot;
                                   /&amp;gt;
                               &amp;lt;/Box&amp;gt;
                         
                               &amp;lt;Box paddingX={2} flex=&quot;grow&quot;&amp;gt;
                                   &amp;lt;Text color=&quot;darkGray&quot; weight=&quot;bold&quot;&amp;gt;
                                       {pokemonName.toUpperCase()}
                                   &amp;lt;/Text&amp;gt;
                               &amp;lt;/Box&amp;gt;
                           &amp;lt;/Box&amp;gt;
                       })}
                   &amp;lt;/Box&amp;gt;
                   : null}
           &amp;lt;/Container&amp;gt;
       &amp;lt;/&amp;gt;
   );
};

export default App;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The results should look something like this.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Ffinal-product.eFzO88Se.png&amp;amp;w=2126&amp;amp;h=788&amp;amp;dpl=699bfef0c4120e00087ee35a&quot; alt=&quot;typeahead-search-final&quot; title=&quot;typeahead-search-final&quot; /&gt;&lt;/p&gt;
&lt;p&gt;We can deploy the react app with Cloudflare Pages or with Cloudflare Workers as well.&lt;/p&gt;
</content:encoded><author>Vaibhav Sharma</author></item><item><title>The Monk Who Accidentally Saved India</title><link>https://theleakycauldronblog.com/articles/kesavananda-bharati-vs-kerala</link><guid isPermaLink="true">https://theleakycauldronblog.com/articles/kesavananda-bharati-vs-kerala</guid><description>&lt;img alt=&quot;The Monk Who Accidentally Saved India&quot; src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Fmanyu-varma-kesavanada-bharati-vs-kerala.CSWMRZp3.jpg&amp;w=6000&amp;h=4000&amp;dpl=699bfef0c4120e00087ee35a&quot; /&gt; Find out how an unwitting saviour rescued Indian Democracy from becoming a totalitarian Regime, the story of Kesavananda Bharati vs The State of Kerala.</description><pubDate>Tue, 26 Jan 2021 12:30:00 GMT</pubDate><content:encoded>&lt;p&gt;Today is the &lt;em&gt;71st Republic Day of India&lt;/em&gt; as on this day, year 1950, &lt;em&gt;The Constitution of India&lt;/em&gt; came into force. But in this long journey, there came a time when India almost came to the brink of becoming a totalitarian regime. And then, came an unwitting, unlikely saviour, who rescued the Indian Democracy, a Monk, &lt;em&gt;Swami Kesavananda Bharati&lt;/em&gt;. In 1973, 13 Judges assembled to deliver the verdict on the most important case of Indian History, &lt;em&gt;&lt;strong&gt;Kesavananda Bharati vs The State of Kerala&lt;/strong&gt;&lt;/em&gt;, which enforced the &lt;em&gt;Basic Structure Doctrine&lt;/em&gt;. Last year, on September 6th, he crossed this realm of existence and I wanted to commemorate his legacy on this historic day.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Kesavananda Bharati vs The State of Kerala&lt;/em&gt; was the culmination of a series of serious clashes between The Judiciary and The Indira Gandhi Government. It all started in 1967 when the Indira Gandhi government received the first blow after, The Supreme Court of India, gave a verdict in the &lt;em&gt;Golak Nath case&lt;/em&gt; that parliament could not amend &lt;em&gt;Fundamental Rights&lt;/em&gt;. Two years later, Indira Gandhi government received a second blow when her decision to nationalise the private banks of India was struck down by the Supreme Court. And finally, a year later in 1970, Indira Gandhi’s decision of abolishing &lt;em&gt;Privy Purse&lt;/em&gt; was again struck down by the Supreme Court. Being out-powered by The Judiciary, in three separate rulings, all of them argued by lawyer &lt;em&gt;Nanabhoy Palkhiwala&lt;/em&gt;, Indira Gandhi was determined to cut the Indian Courts to sizes. So, she introduced a series of constitutional amendments that nullified the &lt;em&gt;Golak Nath&lt;/em&gt;, &lt;em&gt;Bank Nationalisation&lt;/em&gt; and &lt;em&gt;Privy Purse&lt;/em&gt; judgements. These amendments gave the Parliament unlimited powers to alter or even abolish any Fundamental Rights promised by The Constitution.&lt;/p&gt;
&lt;p&gt;Enter &lt;em&gt;Swami Kesavananda Bharati&lt;/em&gt;, the &lt;em&gt;Shankaracharya&lt;/em&gt;(Head Monk) of the Hindu monastery called &lt;em&gt;Edneer Mattha&lt;/em&gt; in Kerala. In February 1970, he filed a petition to challenge the Kerala Government’s attempt to impose restrictions on the management of the Monastery property, under two land reform acts. Nanabhoy Palkhiwala took this as an opportunity and convinced Swamiji to file this petition under &lt;em&gt;&lt;strong&gt;Article 26&lt;/strong&gt;&lt;/em&gt;, &lt;em&gt;The Right to Manage Religious Property without Government Interference&lt;/em&gt;. Thus began the legal battle that quickly took on serious political overtones. The case was heard for 68 days by the largest ever Constitutional Bench of 13 Judges. The amount of effort that was put for this case was breathtaking with hundreds of cases cited and provisions of the Constitution of more than 50 countries compared!&lt;/p&gt;
&lt;p&gt;The Judicial Bench was split right down the middle at &lt;strong&gt;6:6&lt;/strong&gt; until the 13th judge, &lt;em&gt;Justice H. R. Khanna&lt;/em&gt; added his support to &lt;em&gt;Basic Structure Doctrine&lt;/em&gt;. Thus Indian Democracy was saved by a wafer-thin margin of &lt;strong&gt;7:6&lt;/strong&gt; majority. And while Swami Kesavananda Bharati, received no relief in the case, the judgement introduced the Basic Structure Doctrine, which introduced a major Check to the power of The Parliament to make drastic changes to the core values of The Indian Constitution, like &lt;em&gt;secularism&lt;/em&gt; and &lt;em&gt;federalism&lt;/em&gt;. Now this all may sound very dramatic and movie-like but it happened. Though unfortunately, it didn’t end there...&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Indira Gandhi&lt;/em&gt; didn’t take kindly this verdict, and she promoted &lt;em&gt;Justice A. N. Ray&lt;/em&gt;, who was the most vocal among the dissenters in the bench, to the Chief Justice of India, superseding three senior Judges, which was unprecedented in Indian Legal History. And by the time the infamous &lt;em&gt;&lt;strong&gt;Emergency of 1975&lt;/strong&gt;&lt;/em&gt; was declared, 8 new judges had been appointed to The Supreme Court. What preceded was a &lt;em&gt;(not-so)shocking&lt;/em&gt; attempt by Chief Justice Ray to review the Kesavanada Bharati decision, setting up a 13 Judge Bench. Again Nanabhoy Palkhiwala gave, what is now regarded as, one of the finest advocacy hearings in the history of India. But, as we say in India &lt;em&gt;&lt;strong&gt;“Satyamev Jayate”&lt;/strong&gt;&lt;/em&gt; (&lt;em&gt;Truth Alone Triumphs&lt;/em&gt;) the Bench was dissolved within 2 days, as it was discovered that no one had filed a review petition.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Few amazing things about this cornerstone case are:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Though it was a landmark case, Swami Kesavanada Bharati lost his case as The Supreme Court upheld the land reform laws.&lt;/li&gt;
&lt;li&gt;Bangladesh adopted the Basic Structure Doctrine by expressly relying on the reasoning in the Kesavananda Bharati case.&lt;/li&gt;
&lt;li&gt;Swami Kesavananda Bharati never met Nanabhoy Palkhiwala in person, and was rather surprised to see his name in the newspapers every day. He even wondered why his case was taking so long!&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;p&gt;Thanks to Kesavananda Bharati, Nanabhoy Palkhiwala, the seven judges as this decision thwarted many attempts on Indian Democracy, making India reach this milestone — &lt;strong&gt;The 71st year of being a Republic.&lt;/strong&gt;&lt;/p&gt;
</content:encoded><author>Vaibhav Sharma</author></item><item><title>Authenticated Serverless CRUD with Netlify Functions and FaunaDB Part 3</title><link>https://theleakycauldronblog.com/articles/authenticated-serverless-crud-netlify-functions-faunadb-part-3</link><guid isPermaLink="true">https://theleakycauldronblog.com/articles/authenticated-serverless-crud-netlify-functions-faunadb-part-3</guid><description>&lt;img alt=&quot;Authenticated Serverless CRUD with Netlify Functions and FaunaDB Part 3&quot; src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Fmarcel-friedrich-authenticated-serverless-crud-netlify-faunadb-part-3.BqT7BWyZ.jpg&amp;w=4032&amp;h=2729&amp;dpl=699bfef0c4120e00087ee35a&quot; /&gt; Leverage FaunaDB and Netlify Functions to create authenticated Serverless CRUD APIs with generous free tier.</description><pubDate>Fri, 22 Jan 2021 12:30:00 GMT</pubDate><content:encoded>&lt;p&gt;In the last parts, we have built a foundation of a Netlify Functions serverless project and set up our Fauna DB Collections, Indexes and Roles. We have also written two APIs, Sign Up and Sign In. And if you have followed the last parts, your project folder should look like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;.
├── node_modules/
├── db/
│   └──  bootstrap.js
├── functions/
│      ├-- sign-in.js
│      ├-- sign-up.js
│      └──  hello-world.js   
├-- netlify.toml
├-- package.json
└── yarn.lock
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this part, we’ll finally be writing the CRUD APIs. Oh, I hope you have saved the &lt;code&gt;User ID&lt;/code&gt; and the &lt;code&gt;Secret Token&lt;/code&gt; returned after signing in. If not, go ahead sign in again and save the new ones, as we’ll be needing them.&lt;/p&gt;
&lt;h2&gt;Create My Cat&lt;/h2&gt;
&lt;p&gt;The big idea is to use the &lt;code&gt;secret token&lt;/code&gt; we saved earlier as a &lt;code&gt;bearer token&lt;/code&gt; and on the server-side, we use it as a regular FaunaDB access token, to initialise the Fauna Client and run queries. In this particular case a query to create a cat.&lt;/p&gt;
&lt;p&gt;First, we create a file called &lt;code&gt;create-my-cat.js&lt;/code&gt; in our functions folder:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cd functions/ &amp;amp;&amp;amp; touch create-my-cat.js
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then, we take the &lt;code&gt;authorisation header&lt;/code&gt; and retrieve the bearer token to initialise our Fauna Client.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const faunadb = require(&apos;faunadb&apos;)

const q = faunadb.query

module.exports.handler = async (event, context, callback) =&amp;gt; {
    const payload = JSON.parse(event.body)
    let authorisation = event.headers.authorization
    authorisation = authorisation.split(&quot; &quot;)
    const token = authorisation[1]

    const client = new faunadb.Client({
        secret: token
    })
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally, we write the query to create an entry of a cat, from the payload, we also save a reference to the user who created the entry.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    try {
        const response = await client.query(
            q.Create(
                q.Collection(&apos;cat_breeds&apos;), {
                    data: {
                        name: payload.name,
                        image: payload.image,
                        breed: payload.breed,
                        userRef: q.Ref(q.Collection(&apos;users&apos;), payload.user_id)
                    }
                }
            )
        )

        callback(null, {
         statusCode: 200,
         headers: {
             /* Required for CORS support to work */
             &quot;Access-Control-Allow-Origin&quot;: &quot;*&quot;,
             &quot;Access-Control-Allow-Headers&quot;: &quot;*&quot;,
             &quot;Access-Control-Allow-Methods&quot;: &quot;POST, OPTIONS&quot;,
         },
         body: JSON.stringify(response),
      })
    } catch (err) {
        console.error(err)

        callback(null, {
         statusCode: 400,
         headers: {
             /* Required for CORS support to work */
             &quot;Access-Control-Allow-Origin&quot;: &quot;*&quot;,
             &quot;Access-Control-Allow-Headers&quot;: &quot;*&quot;,
             &quot;Access-Control-Allow-Methods&quot;: &quot;POST, OPTIONS&quot;,
         },
         body: JSON.stringify({error: err}),
      });
    }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To test the API run the dev server:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;yarn run dev
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then, authenticate the user we created earlier, using a &lt;code&gt;POST&lt;/code&gt; request to:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://localhost:8888/api/create-my-cat&quot;&gt;http://localhost:8888/api/create-my-cat&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;With the following payload:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;user_id&quot;: &quot;285249298598199809&quot;,
  &quot;name&quot;: &quot;mr snugglepants&quot;,
  &quot;image&quot;: &quot;https://example.com/cat_1.jpg&quot;,
  &quot;breed&quot;: &quot;maine coon&quot;
} 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And, the authorisation header:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;authorization&quot;: &quot;Bearer fnED_83xz1ACAAPy2UP8gAYBHFYA7Xw0l-0EDv_oWF4fj28gX9I&quot;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Make sure to make a few entries before proceeding to the next step.&lt;/p&gt;
&lt;h2&gt;Retrieve My Cats&lt;/h2&gt;
&lt;p&gt;Retrieving the cats is similar, but we’ll be using the Index we created in the last part - &lt;code&gt;cats_by_users&lt;/code&gt;. We’ll also be using a FaunaDB Lambda function, which will process the list of cat ids retrieved from the Index to their entire document.&lt;/p&gt;
&lt;p&gt;First, create a file &lt;code&gt;retrieve-my-cats.js&lt;/code&gt; in the functions folder:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;touch retrieve-my-cats.js
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then, write the following code in the file:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const faunadb = require(&apos;faunadb&apos;)

const q = faunadb.query

module.exports.handler = async (event, context, callback) =&amp;gt; {
    const payload = JSON.parse(event.body)
    let authorisation = event.headers.authorization
    authorisation = authorisation.split(&quot; &quot;)
    const token = authorisation[1]
    const user_id = payload.user_id

    const client = new faunadb.Client({
        secret: token
    })
    
     try {
        const response = await client.query(
            q.Map(
                q.Paginate(
                    q.Match(
                        q.Index(&apos;cats_by_users&apos;),
                        q.Ref(q.Collection(&quot;users&quot;), user_id)
                    )
                ),
                q.Lambda(&apos;catBreedsRef&apos;, q.Get(q.Var(&quot;catBreedsRef&quot;)))
            )
        )

        callback(null, {
         statusCode: 200,
         headers: {
             /* Required for CORS support to work */
             &quot;Access-Control-Allow-Origin&quot;: &quot;*&quot;,
             &quot;Access-Control-Allow-Headers&quot;: &quot;*&quot;,
             &quot;Access-Control-Allow-Methods&quot;: &quot;POST, OPTIONS&quot;,
         },
         body: JSON.stringify(response),
      })
    } catch (err) {
        console.error(err)

        callback(null, {
         statusCode: 400,
         headers: {
             /* Required for CORS support to work */
             &quot;Access-Control-Allow-Origin&quot;: &quot;*&quot;,
             &quot;Access-Control-Allow-Headers&quot;: &quot;*&quot;,
             &quot;Access-Control-Allow-Methods&quot;: &quot;POST, OPTIONS&quot;,
         },
         body: JSON.stringify({error: err}),
      });
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To test the API, restart the dev server. Then, make a &lt;code&gt;POST&lt;/code&gt; request to the API, with the following payload. (Don’t forget the Authorisation Token in the Header)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;user_id&quot;: &quot;285249298598199809&quot;,
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For the next part, make sure to save one of the &lt;strong&gt;Cat’s ID&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;Update My Cat&lt;/h2&gt;
&lt;p&gt;For updating data we’ll use the Cat ID we saved earlier.&lt;/p&gt;
&lt;p&gt;First, create a file &lt;code&gt;update-my-cat.js&lt;/code&gt; in the functions folder&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;touch update-my-cat.js
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, write the following code in the file.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const faunadb = require(&apos;faunadb&apos;)

const q = faunadb.query

module.exports.handler = async (event, context, callback) =&amp;gt; {
    const payload = JSON.parse(event.body)
    let authorisation = event.headers.authorization
    authorisation = authorisation.split(&quot; &quot;)
    const token = authorisation[1]
    const cat_id = payload.cat_id
    const data = payload.data

    const client = new faunadb.Client({
        secret: token
    })
    
     try {
        const response = await client.query(
            q.Replace(
                q.Ref(q.Collection(&apos;cat_breeds&apos;), cat_id),
                {
                    data: data
                })
        )

        callback(null, {
         statusCode: 200,
         headers: {
             /* Required for CORS support to work */
             &quot;Access-Control-Allow-Origin&quot;: &quot;*&quot;,
             &quot;Access-Control-Allow-Headers&quot;: &quot;*&quot;,
             &quot;Access-Control-Allow-Methods&quot;: &quot;PUT, OPTIONS&quot;,
         },
         body: JSON.stringify(response),
      })
    } catch (err) {
        console.error(err)

        callback(null, {
         statusCode: 400,
         headers: {
             /* Required for CORS support to work */
             &quot;Access-Control-Allow-Origin&quot;: &quot;*&quot;,
             &quot;Access-Control-Allow-Headers&quot;: &quot;*&quot;,
             &quot;Access-Control-Allow-Methods&quot;: &quot;PUT, OPTIONS&quot;,
         },
         body: JSON.stringify({error: err}),
      });
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then, to test the API, restart the dev server and make a &lt;code&gt;PUT&lt;/code&gt; request to the API, with changes in the payload. (Don’t forget the Authorisation Token in the Header)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;cat_id&quot;: &quot;288175339623940608&quot;,
  &quot;data&quot;: {
    &quot;breed&quot;: &quot;tabby&quot;
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Delete My Cat&lt;/h2&gt;
&lt;p&gt;Just like in the last script we’ll use the Cat ID we saved earlier.&lt;/p&gt;
&lt;p&gt;First, create a file &lt;code&gt;delete-my-cat.js&lt;/code&gt; in the functions folder&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;touch delete-my-cat.js
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then, write the following code in the file.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const faunadb = require(&apos;faunadb&apos;)

const q = faunadb.query

module.exports.handler = async (event, context, callback) =&amp;gt; {
    const payload = JSON.parse(event.body)
    let authorisation = event.headers.authorization
    authorisation = authorisation.split(&quot; &quot;)
    const token = authorisation[1]
    const cat_id = payload.cat_id


    const client = new faunadb.Client({
        secret: token
    })
    
     try {
        const response = await client.query(
            q.Delete(
                q.Ref(q.Collection(&apos;cat_breeds&apos;), cat_id))
        )

        callback(null, {
         statusCode: 200,
         headers: {
             /* Required for CORS support to work */
             &quot;Access-Control-Allow-Origin&quot;: &quot;*&quot;,
             &quot;Access-Control-Allow-Headers&quot;: &quot;*&quot;,
             &quot;Access-Control-Allow-Methods&quot;: &quot;DELETE, OPTIONS&quot;,
         },
         body: JSON.stringify(response),
      })
    } catch (err) {
        console.error(err)

        callback(null, {
         statusCode: 400,
         headers: {
             /* Required for CORS support to work */
             &quot;Access-Control-Allow-Origin&quot;: &quot;*&quot;,
             &quot;Access-Control-Allow-Headers&quot;: &quot;*&quot;,
             &quot;Access-Control-Allow-Methods&quot;: &quot;DELETE, OPTIONS&quot;,
         },
         body: JSON.stringify({error: err}),
      });
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then, to test the API, restart the dev server and make a &lt;code&gt;DELETE&lt;/code&gt; request to the API. (Don’t forget the Authorisation Token in the Header)&lt;/p&gt;
&lt;p&gt;That’s it for this tutorial series on making serverless authenticated CRUD with Netlify Functions and Fauna DB. Hope, you make something awesome.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Links&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Link to Part 1:&lt;/strong&gt; &lt;a href=&quot;https://theleakycauldronblog.com/articles/authenticated-serverless-crud-netlify-functions-faunadb-part-1&quot;&gt;Authenticated Serverless CRUD with Netlify Functions and FaunaDB Part 1&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Link to Part 2:&lt;/strong&gt; &lt;a href=&quot;https://theleakycauldronblog.com/articles/authenticated-serverless-crud-netlify-functions-faunadb-part-2&quot;&gt;Authenticated Serverless CRUD with Netlify Functions and FaunaDB Part 2&lt;/a&gt;&lt;/p&gt;
</content:encoded><author>Vaibhav Sharma</author></item><item><title>Authenticated Serverless CRUD with Netlify Functions and FaunaDB Part 2</title><link>https://theleakycauldronblog.com/articles/authenticated-serverless-crud-netlify-functions-faunadb-part-2</link><guid isPermaLink="true">https://theleakycauldronblog.com/articles/authenticated-serverless-crud-netlify-functions-faunadb-part-2</guid><description>&lt;img alt=&quot;Authenticated Serverless CRUD with Netlify Functions and FaunaDB Part 2&quot; src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Fga-authenticated-serverless-crud-netlify-faunadb-part-2.Bj12nHiV.jpg&amp;w=5184&amp;h=3212&amp;dpl=699bfef0c4120e00087ee35a&quot; /&gt; Leverage FaunaDB and Netlify Functions to create authenticated Serverless CRUD APIs with generous free tier.</description><pubDate>Tue, 19 Jan 2021 12:30:00 GMT</pubDate><content:encoded>&lt;p&gt;In the last part, we set up our &lt;em&gt;FaunaDB&lt;/em&gt; account, generated a database access secret and set up our &lt;em&gt;Netlify Functions&lt;/em&gt; project. We also made a serverless API that returns &lt;em&gt;“Hello, World!”&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Link to Part 1: &lt;a href=&quot;https://theleakycauldronblog.com/articles/authenticated-serverless-crud-netlify-functions-faunadb-part-1&quot;&gt;Authenticated Serverless CRUD with Netlify Functions and FaunaDB Part 1&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;If everything was set up properly according to the last tutorial the project folder should look like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;.
├── node_modules/
├── functions
│      └──  hello-world.js   
├-- netlify.toml
├-- package.json
└── yarn.lock
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this part, we will first, programmatically set up our database &lt;code&gt;Collections&lt;/code&gt;, &lt;code&gt;Indexes&lt;/code&gt; and &lt;code&gt;Roles&lt;/code&gt;. Then, we’ll set up the user sign-up and sign-in APIs.&lt;/p&gt;
&lt;h2&gt;Bootstrap Fauna Database&lt;/h2&gt;
&lt;p&gt;For our Cats project, we’ll need two tables or “&lt;code&gt;Collections&lt;/code&gt;” — &lt;code&gt;users&lt;/code&gt; and &lt;code&gt;cat_breeds&lt;/code&gt;. And while we can make our Collections, Indexes and Roles using the Fauna Cloud Console GUI, setting it up programmatically allows us to keep the settings as a template which can be deployed locally as well.&lt;/p&gt;
&lt;p&gt;First, install &lt;code&gt;dotenv&lt;/code&gt; package&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;yarn add dotenv
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, create a folder &lt;code&gt;db&lt;/code&gt; at the project root:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mkdir db 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then in the &lt;code&gt;db&lt;/code&gt; folder create a file &lt;code&gt;bootstrap.js&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cd db &amp;amp;&amp;amp; touch bootstrap.js
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the &lt;code&gt;bootstrap.js&lt;/code&gt; file, we’ll first import &lt;code&gt;dotenv&lt;/code&gt; and &lt;code&gt;faunadb&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;require(&apos;dotenv&apos;).config()
const faunadb = require(&apos;faunadb&apos;)


console.log(&apos;Creating FaunaDB database...&apos;)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Creating Collections&lt;/h3&gt;
&lt;p&gt;First, we write a function to create our Collections, in that function we initiate the Fauna &lt;code&gt;query&lt;/code&gt; and Fauna &lt;code&gt;client&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const createCollections = key =&amp;gt; {
  const q = faunadb.query


  const client = new faunadb.Client({
    secret: key
  })

}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now we have to write the queries to create Collections in our &lt;code&gt;createCollections&lt;/code&gt; function:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Users Collection
client.query(
   q.CreateCollection({name: &apos;users&apos;})
)
   .then(ret =&amp;gt; console.log(&apos;Success: %s&apos;, ret))
   .catch(err =&amp;gt; console.error(&apos;Error: %s&apos;, err))



// CatBreeds Collection
client.query(
   q.CreateCollection({name: ‘cat_breeds’})
)
   .then(ret =&amp;gt; console.log(&apos;Success: %s&apos;, ret))
   .catch(err =&amp;gt; console.error(&apos;Error: %s&apos;, err))
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Creating Indexes&lt;/h3&gt;
&lt;p&gt;Indexes are used to quickly locate data without having to search every individual document (or row of data) in the database. We’ll create an index to look up users by email so that we can sign them in and another to get the cats.&lt;/p&gt;
&lt;p&gt;In the &lt;code&gt;bootstrap.js&lt;/code&gt; file add another function, &lt;code&gt;createIndexes&lt;/code&gt; and initialise the Fauna query and client.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const createIndexes = key =&amp;gt; {
  const q = faunadb.query


  const client = new faunadb.Client({
    secret: key
  })
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, we need to write the query to create our indexes, in our &lt;code&gt;createIndexes&lt;/code&gt; function.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Users by Email Index
client.query(
   q.CreateIndex({
       name: &apos;users_by_email&apos;,
       permissions: {read: &quot;public&quot;},
       source: q.Collection(&quot;users&quot;),
       terms: [{field: [&quot;data&quot;, &quot;email&quot;]}],
       unique: true,
   })
)
   .then(ret =&amp;gt; console.log(&apos;Success: %s&apos;, ret))
   .catch(err =&amp;gt; console.error(&apos;Error: %s&apos;, err))


// Cat Breeds by Users Index
client.query(
   q.CreateIndex({
       name: &apos;cats_by_users&apos;,
       source: [q.Collection(&quot;cat_breeds&quot;)],
       terms: [{field: [&quot;data&quot;, &quot;userRef&quot;]}],
   })
)
   .then(ret =&amp;gt; console.log(&apos;Success: %s&apos;, ret))
   .catch(err =&amp;gt; console.error(&apos;Error: %s&apos;, err))
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Create Roles&lt;/h3&gt;
&lt;p&gt;User-defined roles provide configurable, domain-specific security rules. They are the core schema for attribute-based access control. For example, you can create roles like Staff, Customers etc. Here we’ll be creating a role for our users so that they all can access the Cat Breeds table and the &lt;code&gt;cats_by_users&lt;/code&gt; index.&lt;/p&gt;
&lt;p&gt;As before, create a function, name it &lt;code&gt;createRoles&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const createRoles = key =&amp;gt; {
  const q = faunadb.query


  const client = new faunadb.Client({
    secret: key
  })
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And then, write the queries for the role, &lt;code&gt;cat_whisperers&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;client.query(q.CreateRole({
   name: &quot;cat_whisperers&quot;,
   membership: [
       {
           resource: q.Collection(&quot;users&quot;),
       }
   ],
   privileges: [
       {
           resource: q.Collection(&quot;cat_breeds&quot;),
           actions: {
               read: true,
               write: true,
               create: true,
               delete: true,
               history_read: false,
               history_write: false,
               unrestricted_read: false
           }
       },
       {
           resource: q.Index(&quot;cats_by_users&quot;),
           actions: {
               unrestricted_read: false,
               read: true
           }
       },
   ],

}))
   .then(ret =&amp;gt; console.log(&apos;Success: %s&apos;, ret))
   .catch(err =&amp;gt; console.error(&apos;Error: %s&apos;, err))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We don’t need to add permission for our other index because that is already public.&lt;/p&gt;
&lt;h3&gt;Running the Bootstrap Script&lt;/h3&gt;
&lt;p&gt;Before we run the script we need to call the above functions after checking if the environment has &lt;code&gt;FAUNADB_SECRET&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;if (!process.env.FAUNADB_SECRET) {
   console.error(&apos;FaunaDB Secret Key not found!&apos;)
} else {
   createCollections(process.env.FAUNADB_SECRET)
   createIndexes(process.env.FAUNADB_SECRET)
   createRoles(process.env.FAUNADB_SECRET)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, we can finally run it!&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;node ./db/bootstrap.js
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can go to Fauna Cloud Console and verify if everything was created as desired. After doing that, we can finally start writing our APIs.&lt;/p&gt;
&lt;h2&gt;Sign Up&lt;/h2&gt;
&lt;p&gt;This is a simple one, first, we initialise Fauna &lt;code&gt;Client&lt;/code&gt; and &lt;code&gt;Query&lt;/code&gt; with &lt;code&gt;FAUNADB_SECRET&lt;/code&gt;. And then write an FQL query to create a user.&lt;/p&gt;
&lt;p&gt;Create a file &lt;code&gt;sign-up.js&lt;/code&gt; in the &lt;code&gt;functions&lt;/code&gt; folder:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cd functions &amp;amp;&amp;amp; touch sign-up.js
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then add the following code to the file. This function will take user data and store it to users collection as well as utilise Fauna native &lt;code&gt;credentials&lt;/code&gt; storage to safely store the password in a hashed format:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const faunadb = require(&apos;faunadb&apos;)


const q = faunadb.query
const client = new faunadb.Client({
   secret: process.env.FAUNADB_SECRET
})



module.exports.handler = async (event, context, callback) =&amp;gt; {
   let payload = JSON.parse(event.body)
   
   // user_data part of payload can contain all that you want to store about the user but it must contain email for our login to work
   let user_data = payload.user_data

   const password = payload.password



   try {
       const user = await client.query(
           q.Create(
               q.Collection(&apos;users&apos;), {
                   credentials: {
                       password: password
                   },
                   data: user_data
               }
           )
       )


       const response = user.data


       callback(null, {
       statusCode: 200,
       headers: {
         /* Required for CORS support to work */
         &quot;Access-Control-Allow-Origin&quot;: &quot;*&quot;,
         &quot;Access-Control-Allow-Methods&quot;: &quot;POST, OPTIONS&quot;,
      },
      body: JSON.stringify(response),
    })
   } catch (err) {
       console.error(err)

       callback(null, {
         statusCode: 500,
         headers: {
           /* Required for CORS support to work */
           &quot;Access-Control-Allow-Origin&quot;: &quot;*&quot;,
           &quot;Access-Control-Allow-Methods&quot;: &quot;POST, OPTIONS&quot;,
        },
        body: JSON.stringify({error: err}),
      })
   }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To test the API run the netlify dev server.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;yarn run dev
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then, make a user using a &lt;code&gt;POST&lt;/code&gt; request to:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://localhost:8888/api/sign-up&quot;&gt;http://localhost:8888/api/sign-up&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;With the following payload:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;password&quot;: &quot;abc123&quot;,
  &quot;user_data&quot;: {
    &quot;name&quot;: &quot;foo bar&quot;,
    &quot;email&quot;: &quot;foo@bar.com&quot;
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That should successfully create a user with email: &lt;a href=&quot;foo@bar.com&quot;&gt;foo@bar.com&lt;/a&gt; &amp;amp; password: abc123.&lt;/p&gt;
&lt;h2&gt;Sign In&lt;/h2&gt;
&lt;p&gt;To sign in we’ll use Fauna’s native &lt;code&gt;Login&lt;/code&gt; function. This will take the password in the incoming payload and convert it to the hash format and try to match it against the stored hash. We’ll be using the &lt;code&gt;users_by_email&lt;/code&gt; Index that we created earlier to identify the user.&lt;/p&gt;
&lt;p&gt;First, we need to create a file, let’s name it &lt;code&gt;sign-in.js&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;touch sign-in.js
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then add the following code to the file:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const faunadb = require(&apos;faunadb&apos;)


const q = faunadb.query
const client = new faunadb.Client({
   secret: process.env.FAUNADB_SECRET
})



module.exports.handler = async (event, context, callback) =&amp;gt; {
   let payload = JSON.parse(event.body)

   const email = payload.email

   const password = payload.password


   try {
       const response = await client.query(
           q.Login(
               q.Match(q.Index(&apos;users_by_email&apos;), email),
               {password: password}
           )
       )


       callback(null, {
         statusCode: 200,
         headers: {
             /* Required for CORS support to work */
             &quot;Access-Control-Allow-Origin&quot;: &quot;*&quot;,
             &quot;Access-Control-Allow-Headers&quot;: &quot;*&quot;,
             &quot;Access-Control-Allow-Methods&quot;: &quot;POST, OPTIONS&quot;,
         },
         body: JSON.stringify(response),
      })
   } catch (err) {
       console.error(err)
     
       callback(null, {
         statusCode: 400,
         headers: {
             /* Required for CORS support to work */
             &quot;Access-Control-Allow-Origin&quot;: &quot;*&quot;,
             &quot;Access-Control-Allow-Headers&quot;: &quot;*&quot;,
             &quot;Access-Control-Allow-Methods&quot;: &quot;POST, OPTIONS&quot;,
         },
         body: JSON.stringify({error: err}),
      })
   }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally, to test the API run the dev server:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;yarn run dev
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then, authenticate the user we created earlier, using a &lt;code&gt;POST&lt;/code&gt; request to:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://localhost:8888/api/sign-in&quot;&gt;http://localhost:8888/api/sign-in&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;With the following payload:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;email&quot;: &quot;foo@bar.com&quot;,
  &quot;password&quot;: &quot;abc123&quot;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This should give you a response like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
   &quot;ref&quot;: {
       &quot;@ref&quot;: {
           &quot;id&quot;: &quot;288175339623940608&quot;,
           &quot;collection&quot;: {
               &quot;@ref&quot;: {
                   &quot;id&quot;: &quot;tokens&quot;
               }
           }
       }
   },
   &quot;ts&quot;: 1611084270140000,
   &quot;instance&quot;: {
       &quot;@ref&quot;: {
           &quot;id&quot;: &quot;285249298598199809&quot;,
           &quot;collection&quot;: {
               &quot;@ref&quot;: {
                   &quot;id&quot;: &quot;users&quot;,
                   &quot;collection&quot;: {
                       &quot;@ref&quot;: {
                           &quot;id&quot;: &quot;collections&quot;
                       }
                   }
               }
           }
       }
   },
   &quot;secret&quot;: &quot;fnED_83xz1ACAAPy2UP8gAYBHFYA7Xw0l-0EDv_oWF4fj28gX9I&quot;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Save the &lt;code&gt;secret&lt;/code&gt;, we’ll be using it while making authenticated CRUD requests. We’ll also be needing user id, it’s in the response: &lt;code&gt;instance =&amp;gt; @ref =&amp;gt; id&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;That’s it for this part, In the next part, we’ll finally be writing the code for authenticated CRUD requests.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Links&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Link to Part 1:&lt;/strong&gt; &lt;a href=&quot;https://theleakycauldronblog.com/articles/authenticated-serverless-crud-netlify-functions-faunadb-part-1&quot;&gt;Authenticated Serverless CRUD with Netlify Functions and FaunaDB Part 1&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Link to Part 3:&lt;/strong&gt; &lt;a href=&quot;https://theleakycauldronblog.com/articles/authenticated-serverless-crud-netlify-functions-faunadb-part-3&quot;&gt;Authenticated Serverless CRUD with Netlify Functions and FaunaDB Part 3&lt;/a&gt;&lt;/p&gt;
</content:encoded><author>Vaibhav Sharma</author></item><item><title>Authenticated Serverless CRUD with Netlify Functions and FaunaDB Part 1</title><link>https://theleakycauldronblog.com/articles/authenticated-serverless-crud-netlify-functions-faunadb-part-1</link><guid isPermaLink="true">https://theleakycauldronblog.com/articles/authenticated-serverless-crud-netlify-functions-faunadb-part-1</guid><description>&lt;img alt=&quot;Authenticated Serverless CRUD with Netlify Functions and FaunaDB Part 1&quot; src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Fchris-barbalis-serverless-netlify-faunadb.Dh5WUapG.jpg&amp;w=5648&amp;h=3936&amp;dpl=699bfef0c4120e00087ee35a&quot; /&gt; Leverage FaunaDB and Netlify Functions to create authenticated Serverless CRUD APIs with generous free tier.</description><pubDate>Mon, 18 Jan 2021 12:30:00 GMT</pubDate><content:encoded>&lt;p&gt;Last month, one of my best friends decided he wanted to fulfil his lifelong dream of opening a restaurant. So while we were discussing how to go about doing that I suggested to him to try cloud kitchen first, as we realised we didn’t want to risk investing too much, in uncertain times like this. Since we wanted to invest as little as we can get away with, I decided to try the generous free tier of &lt;em&gt;Netlify Functions&lt;/em&gt; and &lt;em&gt;Fauna DB&lt;/em&gt;. Having worked extensively with &lt;em&gt;AWS Lambda&lt;/em&gt; Serverless Functions I was itching to try Netlify Functions, as I thought it’ll be right up my alley. But I was sceptical about FaunaDB especially since I’m not comfortable with the hassle, that is, setting up &lt;em&gt;GraphQL&lt;/em&gt; and I was conflicted about learning Fauna’s native query language &lt;em&gt;FQL&lt;/em&gt;. But after quickly skimming through docs I decided to try FQL. And, while I did run into some trouble, I finally got a hang of it and decided that I’d write an article on setting up Authenticated CRUD APIs using the two.&lt;/p&gt;
&lt;h2&gt;What We’ll Be Building&lt;/h2&gt;
&lt;p&gt;We’ll be building a Sign-Up API, a Sign In API and Authenticated CRUD APIs for our Cats database. &lt;s&gt;Before we begin, make sure you have the &lt;code&gt;netlify-dev&lt;/code&gt; package installed globally on your machine.&lt;/s&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;netlify-dev&lt;/code&gt; has been deprecated please check out &lt;a href=&quot;https://docs.netlify.com/cli/get-started/&quot;&gt;&lt;code&gt;netlify-cli&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;yarn global add netlify-cli
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;NOTE: This write-up assumes that you have some familiarity with serverless functions. This article will not teach you FQL in detail, but merely show you how you can leverage FaunaDB and Netlify Functions to create authenticated serverless APIs. I use &lt;code&gt;yarn&lt;/code&gt;, but you can use &lt;code&gt;npm&lt;/code&gt; as well.&lt;/p&gt;
&lt;h2&gt;Setup Fauna&lt;/h2&gt;
&lt;p&gt;We begin by signing up for a free Fauna DB account (I love the fact that neither Fauna nor Netlify needs a credit card to sign up).&lt;/p&gt;
&lt;p&gt;After that, we have to create a new database, in Fauna Cloud Console:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Click on “&lt;em&gt;New Database&lt;/em&gt;”&lt;/li&gt;
&lt;li&gt;Enter a name for the database, I’ll go with “&lt;em&gt;Cats&lt;/em&gt;”&lt;/li&gt;
&lt;li&gt;Click “&lt;em&gt;Save&lt;/em&gt;”&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Next, we need to generate a database access key secret:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Click on “&lt;em&gt;Security&lt;/em&gt;” in the Left Navigation&lt;/li&gt;
&lt;li&gt;Click on “&lt;em&gt;New Key&lt;/em&gt;”&lt;/li&gt;
&lt;li&gt;Select Database “&lt;em&gt;Cats&lt;/em&gt;” and Role “&lt;em&gt;Admin&lt;/em&gt;”&lt;/li&gt;
&lt;li&gt;Enter a key name, I’ll go with “&lt;em&gt;API&lt;/em&gt;”&lt;/li&gt;
&lt;li&gt;Click “&lt;em&gt;Save&lt;/em&gt;”&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;You’ll get a long alphanumeric key, copy it and save it, as you’ll not get to see it again. We’ll need it later.&lt;/p&gt;
&lt;h2&gt;Setup Netlify Functions Project&lt;/h2&gt;
&lt;p&gt;Now for the serverless part, we need to first create an empty node project.&lt;/p&gt;
&lt;p&gt;Create a directory called cats.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mkdir cats &amp;amp;&amp;amp; cd cats/
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then,  initialise with &lt;code&gt;yarn init&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;yarn init 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now install the following package:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;yarn add faunadb
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then in your &lt;code&gt;package.json&lt;/code&gt; add the following script:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;“scripts”: {
  “dev”: “netlify dev”
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;s&gt;&lt;code&gt;netlify-dev&lt;/code&gt;&lt;/s&gt; &lt;code&gt;netlify-cli&lt;/code&gt; package allows us to emulate the netlify production environment on our local machine. It also injects variables saved in a &lt;code&gt;.env&lt;/code&gt; file into the environment, bringing us to the next step.&lt;/p&gt;
&lt;p&gt;Create a file &lt;code&gt;.env&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;touch .env
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this file add the Fauna DB access secret that we had generated earlier, as follows:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;FAUNADB_SECRET=”your-fauna-db-access-key”
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, we finally get to the functions part.&lt;/p&gt;
&lt;p&gt;Create a folder called &lt;code&gt;functions&lt;/code&gt; in your project root, you can set it to whatever you like but I prefer the &lt;code&gt;functions&lt;/code&gt; convention:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mkdir functions &amp;amp;&amp;amp; cd functions/
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the functions directory, we create our first serverless function &lt;code&gt;hello-world.js&lt;/code&gt; to test if everything works so far.&lt;/p&gt;
&lt;p&gt;Create a file called &lt;code&gt;hello-world.js&lt;/code&gt;, in the functions folder. Remember the file name will be the &lt;code&gt;slug&lt;/code&gt; for accessing our function API.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;touch hello-world.js
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Inside &lt;code&gt;hello-world.js&lt;/code&gt; we will write a generic AWS Lambda function, since Netlify Functions is just a wrapper on AWS Lambda:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;module.exports.handler = (event, context, callback) =&amp;gt; {
  // &quot;event&quot; has information about the path, body, headers, etc. of the request
  console.log(&apos;event&apos;, event)

  // &quot;context&quot; has information about the lambda environment and user details
  console.log(&apos;context&apos;, context)

  // The &quot;callback&quot; ends the execution of the function and returns a response back to the caller
  return callback(null, {
    statusCode: 200,
    body: JSON.stringify({
      data: &apos;Hello, World!&apos;
    })
  })
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We are not done yet, as netlify still doesn’t know where our functions are stored. For that, we need to specify our functions folder in &lt;code&gt;netlify.toml&lt;/code&gt; file.&lt;/p&gt;
&lt;p&gt;Create a file called &lt;code&gt;netlify.toml&lt;/code&gt; in the project root:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cd .. &amp;amp;&amp;amp; touch netlify.toml
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In &lt;code&gt;netlify.toml&lt;/code&gt;, specify functions directory&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[build]
  functions = &quot;functions&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally, it’s time to test if everything works. First, we run our &lt;code&gt;netlify dev&lt;/code&gt; environment then we can test our API using &lt;code&gt;Postman&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;yarn run dev
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The dev server will probably start at &lt;a href=&quot;http://localhost:8888/&quot;&gt;http://localhost:8888&lt;/a&gt; and we can access our API at:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://localhost:8888/.netlify/functions/hello-world&quot;&gt;http://localhost:8888/.netlify/functions/hello-world&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;It should give the following output:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Hello, World!
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;One final thing, before we proceed, let&apos;s make our API URL a bit more pretty, as &lt;code&gt;/.netlify/functions/&lt;/code&gt; doesn’t look aesthetic enough for production. To do that we need to add redirect instructions in our &lt;code&gt;netlify.toml&lt;/code&gt; file.&lt;/p&gt;
&lt;p&gt;Add the following to our &lt;code&gt;netlify.toml&lt;/code&gt; file:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[[redirects]]
  from = &quot;/api/*&quot;
  to = &quot;/.netlify/functions/:splat&quot;
  status = 200
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Great now let&apos;s try to access our pretty URL:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://localhost:8888/api/hello-world&quot;&gt;http://localhost:8888/api/hello-world&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Hopefully, we still get the same output as before.&lt;/p&gt;
&lt;p&gt;In the next parts we&apos;ll create our Fauna DB Collections, Indexes and Roles, as well as write the CRUD APIs.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Links&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Link to Part 2:&lt;/strong&gt; &lt;a href=&quot;https://theleakycauldronblog.com/articles/authenticated-serverless-crud-netlify-functions-faunadb-part-2&quot;&gt;Authenticated Serverless CRUD with Netlify Functions and FaunaDB Part 2&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Link to Part 3:&lt;/strong&gt; &lt;a href=&quot;https://theleakycauldronblog.com/articles/authenticated-serverless-crud-netlify-functions-faunadb-part-3&quot;&gt;Authenticated Serverless CRUD with Netlify Functions and FaunaDB Part 3&lt;/a&gt;&lt;/p&gt;
</content:encoded><author>Vaibhav Sharma</author></item><item><title>The Ghost in our Shell</title><link>https://theleakycauldronblog.com/articles/hard-problem-of-consciousness</link><guid isPermaLink="true">https://theleakycauldronblog.com/articles/hard-problem-of-consciousness</guid><description>&lt;img alt=&quot;The Ghost in our Shell&quot; src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Fthe-ghost-in-the-shell.BY0W2KA0.jpg&amp;w=2000&amp;h=1333&amp;dpl=699bfef0c4120e00087ee35a&quot; /&gt; Embark on a journey to understand the question of what makes us, us, as we try to unravel the problem of explaining why any physical state is conscious rather than non-conscious.</description><pubDate>Sat, 16 Jan 2021 12:30:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;em&gt;Portuguese Man-o-War&lt;/em&gt;, also known as bluebottle and floating terror is a weird marine organism that is actually not an organism. It’s a bunch of genetically distinct organisms with distinct nervous systems working together to form another organism. Although it’s commonly found on beaches (which leads to the closing of the beach because of their venomous tentacles) we know very little about them. Not because of lack of interest, but because of lack of making sense! Scientists still can’t figure out if they are a group of colonial organisms or a single organism made of specialized tissues (like we are). They have a weird overlap of both of these but we don’t know how much. They are named after 18th-century sailing warships that they roughly resemble.&lt;/p&gt;
&lt;p&gt;Speaking of ships, let&apos;s imagine a ship that has its parts replaced every year until all of the parts get replaced, is it the same ship? Now let’s imagine a new ship made out of all the replaced parts of the previously mentioned ship, which ship is THE ship? This is the famous thought experiment called, &lt;em&gt;Ship of Theseus&lt;/em&gt;. It tries to understand what makes us … well, us!&lt;/p&gt;
&lt;p&gt;So what DOES make us, US? Memories and experiences? What if we lose all our memories, are we still, us? If not, what if we get back all the memories that we lost? And even if we don’t lose our memories, our brain cannot accurately remember everything anyways, our memories have gaps, and our brain fills those gaps by false/made-up memories to maintain a sense of continuity, and these gaps only keep increasing with time. And then there’s the fact that our memories are highly unreliable, biased by the emotions of the moment, mental state and other psychological factors. So is it our body? All the bones in our body get replaced every 10 years, all the cells get replaced every 7 years and 98% of atoms in our body get replaced every year. Where do these particles come from and where do they go?!&lt;/p&gt;
&lt;p&gt;Joni Mitchell in her ethereal song Woodstock, sang:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;We are Stardust…&lt;/p&gt;
&lt;p&gt;― Joni Mitchell&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Turns out she was right! Everything we are and everything in our entire universe originated from Stardust! The stardust finds its way into plants and from there into the nutrients we need for everything. And it continually floats through us today, connecting us to the universe, rebuilding us over and over again throughout our lifetime. Until our soul or whatever, this body, a shell for, decides that it’s time to leave.&lt;/p&gt;
&lt;p&gt;And, while, all stars are beautiful, isn’t our star, the Sun, especially beautiful? The different shades of sky at dusk, fondle our emotions in a way that cannot be accurately put to words.&lt;/p&gt;
&lt;p&gt;It makes us question how our universe has the exact right values for various fundamental constants that guide the particles that make everything, and more importantly how these particles came together on this very planet to form the first cells which then merged together to form simple bio-robots which eventually came to form the complex creatures that can enjoy the sunsets.&lt;/p&gt;
&lt;p&gt;How does our brain turn a certain range of wavelengths of the electromagnetic spectrum to the perceived beauty of a sunset? There’s no known combination of words in any known language that can spontaneously reproduce the redness of sky in someone else’s mind. We cannot explain colours to someone who is blind and has never seen colours in their life, or describe a taste, smell etc. Philosophers call these raw ineffable feelings, &lt;em&gt;&lt;strong&gt;Qualia&lt;/strong&gt;&lt;/em&gt;, and our inability to describe these internal qualia, &lt;em&gt;&lt;strong&gt;Explanatory Gap&lt;/strong&gt;&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Some philosophers like Daniel Dennett believe that our inability to express our internal qualia might be a failure of our language, not necessarily because they will always be impossible to share. Given millions and billions of words used in just the right way, it may be possible to adequately describe a colour such that a blind person could see it for the first time. And that might bring us one step closer to the answer to what is &lt;em&gt;The Ghost in our Shell&lt;/em&gt;, the hard problem of consciousness.&lt;/p&gt;
&lt;p&gt;As Pierre Teilhard de Chardin once said:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;We are not human beings having a spiritual experience. We are spiritual beings having a human experience.&lt;/p&gt;
&lt;p&gt;― Pierre Teilhard de Chardin&lt;/p&gt;
&lt;/blockquote&gt;
</content:encoded><author>Vaibhav Sharma</author></item><item><title>Can Psychedelics Lift the Veil on Consciousness?</title><link>https://theleakycauldronblog.com/articles/psychedelics-consciousness-iit</link><guid isPermaLink="true">https://theleakycauldronblog.com/articles/psychedelics-consciousness-iit</guid><description>&lt;img alt=&quot;Can Psychedelics Lift the Veil on Consciousness?&quot; src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Fdima-pechurin-psychedelic-consciousness-iit.Bug7aYDE.jpg&amp;w=3000&amp;h=2000&amp;dpl=699bfef0c4120e00087ee35a&quot; /&gt; Psychedelic down-regulates the part of brain that controls our ego letting us truly see what it means to be one with the universe, and may hold the answer to the panpsychic world of integrated information theory.</description><pubDate>Fri, 25 Dec 2020 12:30:00 GMT</pubDate><content:encoded>&lt;p&gt;Psychedelics are mysterious compounds and science doesn’t really understand how they work. Partly, because research on them was banned and partly because their effects extend to alter the state of consciousness itself. Their primary effect is to trigger non-ordinary states of consciousness, which is colloquially referred to as &lt;em&gt;Psychedelic Experience&lt;/em&gt; or &lt;em&gt;Trips&lt;/em&gt;. These non-ordinary states of consciousness are often compared to the state of consciousness experienced in meditation and near-death experience. What we do understand about psychedelics is that these compounds trigger the &lt;strong&gt;5-HT2A&lt;/strong&gt; serotonin receptors, which modulate the sensory perception and cognition in our brain. This is because the shape of these compounds resembles serotonin, so much so, that some compounds fit the &lt;strong&gt;5-HT2A&lt;/strong&gt; receptors better than serotonin itself! However, what is not known is how exactly the compounds manipulate the receptor to induce changes in perception and cognition.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Robin Carhart-Harris&lt;/em&gt;, and his team — &lt;em&gt;The Psychedelic Research Club&lt;/em&gt; from &lt;em&gt;The Imperial College, London&lt;/em&gt;, study the effect of psychedelics on the human brain using F-MRI machines. What they discovered is that rather than &lt;em&gt;just&lt;/em&gt; exciting parts of the brain, a part of the brain network was actually down-regulated. This part is called the &lt;em&gt;Default Mode Network&lt;/em&gt;, it’s a tightly linked set of structures connecting the prefrontal cortex to the posterior cingulate cortex and some other centres of emotions and memory. The Default Mode Network has been associated with things like self-reflection, the theory of mind, the ability to impute mental states to others and the ability to shift through the mental states through time, creating a strong sense of identity. Basically, it’s the part that deals with our Ego.&lt;/p&gt;
&lt;p&gt;Ego is that part of our psyche that helps us form a distinct sense of self. This is the part that identifies the boundaries of us and other things. The Default Mode Network seems to regulate that part. In the hierarchy of the brain, the Default Mode Network sits on top and orchestrates and regulates every other part. It takes all our experiences and actions and adds the perspective of self-identity to it. Psychedelics take this part out of the equation thus giving a sense of ego dissolution also popularly known as &lt;em&gt;Ego Death&lt;/em&gt;. So when this ego dissolution occurs the other parts of the brain that don’t usually interact with each other start doing so. Thus producing effects like synesthesia and the ability to see music. As ego subsides and the boundary of self-identity thins, we also experience being one with the universe.&lt;/p&gt;
&lt;p&gt;Being one with the universe, as many of you may be familiar, is an important part of many eastern philosophies like &lt;em&gt;Hinduism&lt;/em&gt; and &lt;em&gt;Buddhism&lt;/em&gt;. A lot of eastern meditation is focused on getting in touch with Brahman, or rather making oneself realise that &lt;em&gt;Atman&lt;/em&gt;(self) is &lt;em&gt;Brahman&lt;/em&gt;(universe). In some schools of thoughts of Hinduism, such as &lt;em&gt;Advaita Vedanta&lt;/em&gt;, Brahman is identical to the Atman, is everywhere and inside each living being, and there is connected spiritual oneness in all existence. This realisation sounds very if not completely identical to the experience provided by psychedelics. It seems like the experience provided by psychedelic is an unevolved version of the complex interpretations of Advaita philosophy. Advaita Vedanta school of thought assumes, among other things, that there exists a state of consciousness where we are connected to all other consciousness of this universe, a form of panpsychism.&lt;/p&gt;
&lt;p&gt;So does that mean that consciousness extends to all matter and not just things with brains? &lt;em&gt;Guilio Tononi&lt;/em&gt;, a neuroscientist, proposed an ambitious theory to explain consciousness called the &lt;em&gt;Integrated Information Theory&lt;/em&gt; (IIT). This theory suggests that panpsychism might not be so far-fetched after all. The core identity of IIT suggests that —&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The quantity and quality of an “&lt;em&gt;experience&lt;/em&gt;” are an intrinsic, maximally irreducible property of a complex of mechanisms in a state — the property of informing or shaping the space of possibilities (past and future states) in a particular way, just as it is considered to be intrinsic to a mass to bend space-time around it.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;IIT claims that a system is conscious if it possesses a property called &lt;strong&gt;Φ&lt;/strong&gt;, or &lt;strong&gt;phi&lt;/strong&gt;. &lt;em&gt;Phi&lt;/em&gt; is the measure of a system&apos;s “integrated information”. What that implies is that various systems can have various levels of consciousness which is their intrinsic property.&lt;/p&gt;
&lt;p&gt;While this theory is a developing one and has yet to iron out its kinks, it provides an interesting perspective to the term &quot;&lt;em&gt;consciousness&lt;/em&gt;&quot; and the theory of panpsychism. And Psychedelics are one of the easiest ways to experience this. But while doing drugs is easy and meditation is hard, some swear by the fact that a higher level of this experience can be achieved by meditation than by psychedelics. So, if not much, these psychedelic compounds can definitely serve as an advertisement to all that can be achieved through meditation.&lt;/p&gt;
</content:encoded><author>Vaibhav Sharma</author></item><item><title>Hate in the Time of Corona</title><link>https://theleakycauldronblog.com/articles/hate-in-the-time-of-corona</link><guid isPermaLink="true">https://theleakycauldronblog.com/articles/hate-in-the-time-of-corona</guid><description>&lt;img alt=&quot;Hate in the Time of Corona&quot; src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Fbram-hate-in-the-time-of-corona.ChUy1F6L.jpg&amp;w=6000&amp;h=4000&amp;dpl=699bfef0c4120e00087ee35a&quot; /&gt; Discover how fear drives humanity, which was once the gift that helped us evolve but has now backfired leading us to hate and how we need compassion to counter this situation.</description><pubDate>Tue, 20 Oct 2020 12:30:00 GMT</pubDate><content:encoded>&lt;p&gt;Have you ever met someone and felt from the bottom of your heart that you want to spend your entire life... without them? Usually, I feel that way when I find some bell-end justifying their hate and asserting their flawed ideas as if it’s common fuckin&apos; sense, that too with an air of threat that anyone who disagrees or tries to be neutral is not worth existing. FYI, I know calling someone a Stupid Cunt has never in the history of the world changed their mind, no matter what logical and sensible argument we precede it with. But this write-up isn’t meant to change anyone’s mind or to justify why the title is ripped from the modern classic &lt;a href=&quot;https://en.wikipedia.org/wiki/Love_in_the_Time_of_Cholera&quot;&gt;Love In The Time of Cholera&lt;/a&gt;. No this... this is a motherfuckin&apos; RANT! A release that was long overdue, due to my particular strategy of dealing with stupid people.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Never Underestimate the Power of Stupid People in Large Groups&lt;/p&gt;
&lt;p&gt;— George Carlin&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Stupid cunts are very dangerous to the community, to democracy and to people&apos;s mental health and well being. Add the power to broadcast unregulated shit at the speed of light, things go south real fast. My way of dealing with stupid people is to always avoid arguing with them, but being a stupid prick myself (&lt;em&gt;although of a tad different kind&lt;/em&gt;) I sometimes inadvertently find myself in the middle of an argument with such people. If I find myself trapped before it is too late, my go-to strategy is always to come out as a naive idiot because a naive idiot isn’t a threat. And since most stupidity is driven by fear, even the smartest of people are susceptible to it.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Fear is the path to the dark side…fear leads to anger… anger leads to hate… hate leads to suffering.&lt;/p&gt;
&lt;p&gt;— Master Yoda&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Fear is a unique thing, some evolutionary scientists argue that if it weren’t for fear, we wouldn’t have evolved as much as we did. It’s not hard to see that if we weren’t afraid of starvation we’d never develop agriculture and if we weren’t afraid of natural calamities we wouldn’t develop shelters and if we weren’t afraid of our survival as a group we’d never develop language and if we weren’t afraid of the death of our thoughts and ideas, we wouldn’t develop writing and so on... According to science, this “&lt;em&gt;gift&lt;/em&gt;” of fear comes from our evolutionary will to live and spread our DNA. But what I have observed reading history is that our obsession with immortality is not so bio-mechanical in nature.
&lt;br /&gt;
&lt;br /&gt;
History is a witness to the fact that humans can kill or die for their ideologies. The need to control other people’s thoughts and the fear of other people’s ideologies prevailing is what strengthens a society. But every once in a while, when times like 2020 arrives where the uncertainty of our lives just keeps piling up, the ultimate fear creeps in. The fear of lack of control. Though we have never in the history of this universe truly been in control and we are just insignificant shit stains ignored by any intergalactic society that might be out there, the sudden realisation of how fragile our lives are and how meaningless our existence is — makes us very, &lt;em&gt;VERY&lt;/em&gt; angry. So, we try to find something to scream, shout and blame our fears on to feel better and more in control. We want to see someone screwed for making us afraid. This leads to outrageous claims like coronavirus was made in the lab, our religion is in danger, Illuminati is making our biscuits fall in tea etc. But life isn’t curated, we aren’t kids anymore and there’s no grand plan! Everyone is as lost and stupid as everyone else. And we&apos;ll probably bomb ourselves to extinction.
&lt;br /&gt;
&lt;br /&gt;
This thought crept up the other day when I found a book that I had read in my high school days — &lt;strong&gt;Arthur C. Clarke’s July 20, 2019: A Day in the Life of the 21st Century&lt;/strong&gt;. At first, it gave me an undeserved sense of accomplishment that I was living in the future, then a haunting thought arose, Is anyone making sure we don’t kill ourselves, are we gonna be able to see the fuckin&apos; 22nd Century? Or as the &lt;em&gt;Fermi Paradox&lt;/em&gt; puts it, will our civilisation pass the Great Filter? After all, it has just been a bit over 70 years, since humans detonated the first atomic bomb! A weapon that was just first in the long list of cruel options that we now have, to end our entire civilisation very efficiently. After the USA nuked Hiroshima and Nagasaki, in his speech Emperor Hirohito of Imperial Japan said —&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The enemy has begun to employ a new and most cruel bomb, the power of which to do damage is, indeed, incalculable, taking the toll of many innocent lives. Should we continue to fight, not only would it result in an ultimate collapse and obliteration of the Japanese nation, but also it would lead to the total extinction of human civilisation.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;And ever since then, there have been at least a thousand instances that, we know of for sure, when we accidentally fucked up and almost brought our entire planet to the brink of nuclear annihilation. And it’s without a doubt that we’ll screw up in the future as well with a thousand times the efficiency we did in the past. So, it is not too much of a stretch to imagine that a bioweapon that was created in the lab got out.&lt;/p&gt;
&lt;p&gt;Or is it?&lt;/p&gt;
&lt;p&gt;In Philosophy, A &lt;em&gt;Razor&lt;/em&gt; is a principle or a rule that allows one to “&lt;em&gt;Shave Off&lt;/em&gt;”(eliminate) unlikely speculations and explanations for a certain event/phenomenon. One such Razor is &lt;em&gt;Hanlon’s Razor&lt;/em&gt; which states —&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Never attribute to malice that which can be adequately explained by stupidity.&lt;/p&gt;
&lt;p&gt;— Hanlon’s Razor&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;What that means is that our need to blame someone or something evil that’s responsible for our misery and suffering usually overlooks a simple explanation that should be prioritised i.e. — more often than not, things happen without reason, life doesn’t always make sense, every single human makes mistakes and bad incidents usually don&apos;t have malice in its roots. That being said, the fear, anger and hate we feel is also a normal part of being human. And these feelings wouldn’t have mattered much if we hadn’t taken a fuckin&apos; shortcut to evolution — &lt;em&gt;Technology&lt;/em&gt;.
&lt;br /&gt;
&lt;br /&gt;
With the advent of Social Media, we can take these fears and spread them like viruses. Hence the term ‘&lt;em&gt;Going Viral&lt;/em&gt;’. Speaking of which, a study in 2009 — ‘&lt;a href=&quot;https://papers.ssrn.com/sol3/papers.cfm?abstract_id=1528077&quot;&gt;What makes Online Content Viral?&lt;/a&gt;’ showed that anger is the ultimate virus, eliminating the mental firewall of logic, it compels us to share the shit that makes us angry! Proof that we share a common ancestor with shit flinging monkeys. And it doesn’t just end there, to make other people understand the pain and anger we felt and to increase its impact we start tweaking the truth — a photoshop here, an eliminated context there, who cares? The more people discuss it, the more life expectancy of these anger viruses further increases thus creating an us-versus-them divide between people. And once this happens, it’s only a matter of time before cherry-picking begins — skewing perspectives, destroying harmony, driven by anger, all we can see is how ‘they’ are wrong &amp;amp; ‘we’ are innocent … and we lived hatefully ever after! Bringing us a full circle back to the stupid cunts I mentioned at the beginning. You see?!! How the very thing that made us the superior species over Neanderthals, backfired on us, you see, right?!!!!!
&lt;br /&gt;
&lt;br /&gt;
But Neanderthals, despite their popular image of being archetypical brutish and stupid ‘&lt;em&gt;cave men’&lt;/em&gt;, used to survive many years with severe handicaps, evidence that they were cared for and loved by someone. They had bigger bodies and larger brains than Sapiens, yet we prevailed, reason being, we had a more advanced language. Our tongue which helped us to express better that we care and love, helped us form a bigger and stronger society. If that’s not enough evidence that compassion is in our DNA then I don’t fuckin&apos; know what is! We’ll never be correct 100% of the time, but what we can do is delay our judgement to make our paradigms more accurate, use &lt;em&gt;Occam’s Razor&lt;/em&gt; to eliminate and avoid unnecessary or improbable assumptions.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Of two explanations that account for all the facts, the one that makes the least assumptions is more likely to be correct.&lt;/p&gt;
&lt;p&gt;— Occam’s Razor&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;But most importantly WE CAN BE KIND! And if anyone says otherwise they can GO FUCK THEMSELVES!
&lt;br /&gt;
&lt;br /&gt;
With Love,&lt;br /&gt;
Vaibhav&lt;/p&gt;
</content:encoded><author>Vaibhav Sharma</author></item><item><title>Raat — रात</title><link>https://theleakycauldronblog.com/articles/raat</link><guid isPermaLink="true">https://theleakycauldronblog.com/articles/raat</guid><description>&lt;img alt=&quot;Raat — रात&quot; src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Ftodd-diemer-raat-vyom.rvZGR61p.jpg&amp;w=4270&amp;h=2530&amp;dpl=699bfef0c4120e00087ee35a&quot; /&gt; अजीब थी वो रात पर आखिर रात ही थी ना। रातों की किस्मत होती है सवेरे से मात खाना। — व्योम</description><pubDate>Thu, 15 Oct 2020 12:30:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;em&gt;Another great poem by my friend who writes under the pen-name ”&lt;strong&gt;Vyom&lt;/strong&gt;”.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;एक अजीब सा माहौल था उस रात।&lt;br /&gt;
चाँद नहीं था आसमान में, पर तारे चांदनी को इठला रहे थे।&lt;br /&gt;
बादलों का दूर - दूर तक निशान नहीं था, पर तूफान का आना लगभग तय था।&lt;br /&gt;
हवाएँ खेल तो रही थी पत्तों के संग, पर उस रात एक खामोशी थी खेल में।&lt;br /&gt;
जंगलों की गुर्राहट शहरों तक सुनाई दे रही थी।&lt;br /&gt;
उस रात पक्षी घोंसलों में नहीं थे, शायद उन्हें तूफान का आभास था।&lt;br /&gt;
सहर शमशान सा सांत था।&lt;/p&gt;
&lt;p&gt;गाड़ियाँ तो चल रही थी पर कहीं हॉर्न की आवाज़ नहीं थी, मानो सब कायदे से हो रहा हो, मानो जैसे हर कोई ख़ौफ़ में हो।&lt;br /&gt;
ख़ौफ़, जो देर हो जाने के ख़ौफ़ से बड़ा था।&lt;br /&gt;
अजीब थी वो रात पर आखिर रात ही थी ना।&lt;br /&gt;
रातों की किस्मत होती है सवेरे से मात खाना।&lt;br /&gt;
लोग जानते थे कि सुबह आयेगी।&lt;/p&gt;
&lt;p&gt;जब फिर सब तरीके से होगा पर उन तरीकों को कोई व्यक्ति विशेष तय नहीं करेगा।&lt;br /&gt;
जब हवा, समुद्र या रोशनी पर किसी की पाबंदी नहीं होगी।&lt;br /&gt;
जब हंसी की गूंज तभी आयेगी जब उसकी वजह होगी और आँसू भी बिन वजह नहीं बहेंगे।&lt;br /&gt;
तब तक जरूरी है इस रात में जागना और दूसरों को सोने ना देना ताकि उस नए सूरज की किरणों से कोई अनजान ना रह जाए।।&lt;/p&gt;
&lt;p&gt;— &lt;em&gt;&lt;strong&gt;व्योम&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
</content:encoded><author>Vyom</author></item><item><title>Interstellar, King Muchukunda and Time Dilation</title><link>https://theleakycauldronblog.com/articles/interstellar-muchukunda-time-dilation</link><guid isPermaLink="true">https://theleakycauldronblog.com/articles/interstellar-muchukunda-time-dilation</guid><description>&lt;img alt=&quot;Interstellar, King Muchukunda and Time Dilation&quot; src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Fking-muchukunda.BCMmqTiA.jpg&amp;w=1848&amp;h=1351&amp;dpl=699bfef0c4120e00087ee35a&quot; /&gt; Time Dilation was an important part of both Ancient Hindu Scriptures and the movie Interstellar, did the Ancient Indians really know about it and its limitation, read to find out.</description><pubDate>Sat, 10 Oct 2020 12:30:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Christopher_Nolan&quot;&gt;Christopher Nolan&lt;/a&gt; is without a doubt one of the best directors of our time. He takes incredibly complex subjects, mixes it with an equally complex story and beautiful cinematography and makes it accessible to regular people with a topping of great music. One of his most popular films is the sci-fi — &lt;a href=&quot;https://en.wikipedia.org/wiki/Interstellar_(film)&quot;&gt;Interstellar&lt;/a&gt;, which deals with the topics of Black Hole, Wormhole, Parallel Dimension and Time Dilation.&lt;/p&gt;
&lt;p&gt;Interstellar is a story set in a dystopian future where humanity is on the verge of destruction due to crop blights and dust storms. The film follows five astronauts who travel through a wormhole(which was placed by unknown beings near Saturn) to different planets to find a suitable home to rehabilitate human beings. One such planet, that the protagonists of the film travel to, is — Miller’s Planet which is near a black hole, Gargantua. And due to its proximity to Gargantua, there’s severe gravitational time dilation, so much so that one hour on Miller’s Planet was equal to seven years on Earth! Interstellar was the first movie dealing with Time Dilation but not the first piece of fiction, but I’m getting ahead of myself, let’s first understand what exactly is Time Dilation.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Time_dilation&quot;&gt;Time dilation&lt;/a&gt; is the relative difference in time elapsed measured by two clocks due to their relative velocity to each other or due to gravitational potential difference. What that basically means is that even after compensating for the &lt;a href=&quot;https://en.wikipedia.org/wiki/Doppler_effect&quot;&gt;Doppler Effect&lt;/a&gt; (the varying signal delays between two clocks, one observer and one moving), the observer will measure that the moving clock is ticking slower than his/her own clock which is at rest in his/her own frame of reference. And the other way time dilates is that a clock near a massive body will record less elapsed time than one situated away from that massive body. The latter one is so apparent that it is even observable near pyramids, and in satellites that are in orbit! Though this is not a new concept and has been predicted since the turn of the 20th Century by various scientists and authors like — &lt;a href=&quot;http://www.bourbaphy.fr/darrigol2.pdf&quot;&gt;Poincare&lt;/a&gt; and &lt;a href=&quot;https://archive.org/details/alberteinsteinss0000mill&quot;&gt;Einstein&lt;/a&gt;, evidence suggests that it may even be older than that.&lt;/p&gt;
&lt;p&gt;Hindu scriptures talk about &lt;a href=&quot;https://en.wikipedia.org/wiki/Loka&quot;&gt;14 Lokas&lt;/a&gt; or Dimensions — Brahma Loka being on the top and Paatala Loka (something like hell but not exactly)being the bottom-most. Earth is situated in Bhu Loka which is the 7th dimension and Swarga (something akin to Heaven but not exactly) or Indra Loka is the 5th one. One of the features of these dimensions is that time runs at different speeds. One such legend about time dilation in Hindu scriptures is that of &lt;a href=&quot;https://en.wikipedia.org/wiki/Muchukunda&quot;&gt;King Muchukunda&lt;/a&gt;. King Muchukunda was from &lt;a href=&quot;https://en.wikipedia.org/wiki/Ikshvaku&quot;&gt;Ikshvaku&lt;/a&gt; Dynasty and an ancestor of &lt;a href=&quot;https://en.wikipedia.org/wiki/Rama&quot;&gt;Lord Rama&lt;/a&gt; (the seventh avatar of &lt;a href=&quot;https://en.wikipedia.org/wiki/Vishnu&quot;&gt;Lord Vishnu&lt;/a&gt; and a major Hindu Deity). His story is found in &lt;a href=&quot;https://en.wikipedia.org/wiki/Vishnu_Purana&quot;&gt;Vishnu Purana&lt;/a&gt;, which is believed to have been written around 700-300 BCE. He was a brilliant war strategist and an accomplished General. So much so, that when &lt;a href=&quot;https://en.wikipedia.org/wiki/Deva_(Hinduism)&quot;&gt;Devas&lt;/a&gt; (Deities) were outnumbered and on the verge of defeat in a battle against &lt;a href=&quot;https://en.wikipedia.org/wiki/Asura&quot;&gt;Asuras&lt;/a&gt;(~Demons, although not all Asuras were evil) due to lack of a formidable commander, they sought help from Muchukunda, who was just a human. They asked for him to join them and help them in their fight against Asuras in Indra Loka. The fight was long and bloody, he got so caught up in the war that he didn’t even get to sleep. He protected them from Asuras until they got &lt;a href=&quot;https://en.wikipedia.org/wiki/Kartikeya&quot;&gt;Kartikeya&lt;/a&gt; the son of &lt;a href=&quot;https://en.wikipedia.org/wiki/Shiva&quot;&gt;Lord Shiva&lt;/a&gt; as their commander. For his services &lt;a href=&quot;https://en.wikipedia.org/wiki/Indra&quot;&gt;Indra&lt;/a&gt;, the king of Devas thanked him and said —&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“O king, we, the Devas are indebted to you for the help and protection which you have given us, by sacrificing your own family life. Here in heaven, one second equals one year of the earth and you had fought with asuras for one year of heaven. Since it has been a long time, there is no sign of your kingdom and family because it has been destroyed over time. We are indebted to you, so ask for any boon except Moksha (liberation from rebirth cycle) because Moksha is beyond our capabilities”.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Muchukunda asked to return to his family and kingdom, to which Indra, apologetically informed, that Time runs differently in Indra Loka and that the year spent here was equivalent to many centuries on earth. His entire dynasty had ended and so had his kingdom. Saddened and depressed he asked for a boon of sleep that wouldn’t end until he wanted it to, to compensate for all the sleepless nights he had spent fighting. He also asked that whoever disturbs his sleep, would burn to ashes. These events happened before the events of &lt;a href=&quot;https://en.wikipedia.org/wiki/Ramayana&quot;&gt;Ramayana&lt;/a&gt;, and just like all good sequels, this was an important callback event in the times of &lt;a href=&quot;https://en.wikipedia.org/wiki/Mahabharata&quot;&gt;Mahabharata&lt;/a&gt;. When &lt;a href=&quot;https://en.wikipedia.org/wiki/Yona&quot;&gt;Yavana&lt;/a&gt;(Greek) warrior &lt;a href=&quot;https://en.wikipedia.org/wiki/Kalayavana&quot;&gt;Kalayavana&lt;/a&gt; invaded India, he was invincible and was said to have gotten a boon from Lord Shiva that no weapons could defeat him. &lt;a href=&quot;https://en.wikipedia.org/wiki/Krishna&quot;&gt;Lord Krishna&lt;/a&gt;, being an avatar of Lord Vishnu, knew about Muchukunda’s boon and used it to defeat Kalayavana.&lt;/p&gt;
&lt;p&gt;This, while being the most striking incidence of Time Dilation used in Hindu Scriptures surprisingly isn’t the only one! Some other legends that I could find were — &lt;a href=&quot;https://en.wikipedia.org/wiki/Revati&quot;&gt;Princess Revati&lt;/a&gt; who travelled to Brahma Loka and &lt;a href=&quot;https://en.wikipedia.org/wiki/Indradyumna&quot;&gt;King Indradyumna&lt;/a&gt; who commissioned &lt;a href=&quot;https://en.wikipedia.org/wiki/Jagannath&quot;&gt;The Jagannath Icon of Puri&lt;/a&gt;, who also travelled to Brahma Loka. Does that mean Hindus knew about the concept of Time Dilation since ancient times? Hard to say, and I say that because on the one hand, India has always had a rich culture of Science and Mathematics since ancient times, on the other hand, Time Dilation has been used by a lot of modern writers as it technically allows forward Time Travel, since our current understanding of Space-Time doesn’t allow us to travel back in time. And what&apos;s interesting is that we have yet to come across a Hindu scripture that mentions Backward Time Travel as well! The Indians believed that time is cyclic in nature rather than linear (&lt;a href=&quot;https://en.wikipedia.org/wiki/Closed_timelike_curve&quot;&gt;Closed Timelike Curve&lt;/a&gt;), there even was a Sage who was gifted to be beyond time and could see &lt;a href=&quot;https://en.wikipedia.org/wiki/World_line&quot;&gt;multiple outcomes for the same events&lt;/a&gt; (&lt;a href=&quot;https://en.wikipedia.org/wiki/Kakbhushundi&quot;&gt;Sage Kakbhushundi&lt;/a&gt; — the OG &lt;a href=&quot;https://en.wikipedia.org/wiki/Avengers:_Infinity_War#:~:text=Strange%20uses%20the%20Time%20Stone%20to%20view%20millions%20of%20possible%20futures,%20seeing%20only%20one%20in%20which%20Thanos%20loses&quot;&gt;Dr Strange&lt;/a&gt;), but &lt;strong&gt;not even one mention of backward time travel&lt;/strong&gt;! A trivial concept in fiction and a hell lot easier to imagine a time travel story than a time dilation story, especially, given that, this is supposed to be &quot;Mythology&quot;, why bother with such an arbitrary omission. Did the ancient Indians know about this limitation, if yes, then how?! This certainly, is something significant to think about. But I guess it&apos;ll always remain a mystery as a lot of ancient knowledge that India had, was destroyed in numerous invasions that it was subjected to throughout history.&lt;/p&gt;
</content:encoded><author>Vaibhav Sharma</author></item><item><title>Is MSG bad for you?</title><link>https://theleakycauldronblog.com/articles/is-msg-bad-for-you</link><guid isPermaLink="true">https://theleakycauldronblog.com/articles/is-msg-bad-for-you</guid><description>&lt;img alt=&quot;Is MSG bad for you?&quot; src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Funcle-roger-msg.CEdjDvHl.jpg&amp;w=2880&amp;h=1616&amp;dpl=699bfef0c4120e00087ee35a&quot; /&gt; Find out if MSG is really bad for you, if not, where does the controversy come from and what is the Scientific Consensus.</description><pubDate>Mon, 21 Sep 2020 12:30:00 GMT</pubDate><content:encoded>&lt;p&gt;Recently &lt;a href=&quot;https://www.youtube.com/watch?v=53me-ICi_f8&quot;&gt;a video&lt;/a&gt; by Sino-Malaysian comedian Nigel Ng went viral where his alter-ego Uncle Roger ruthelessly roasts an Anglo-Indian girl Hersha Patel, for her “Egg Fried Rice” cooking methods. But in a wholesome turn of events, they became friends, and he made &lt;a href=&quot;https://www.youtube.com/watch?v=d9Zg_I5a96Y&quot;&gt;another video&lt;/a&gt; about taking her to London’s Chinatown for shopping authentic Chinese ingredients. In this video, Nigel or rather Uncle Roger confesses his love for ... MSG. This leads to a minor argument between Uncle Roger and Aunty Hersha on whether MSG is bad for health.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In Asian culture, if taste good no need science&lt;/p&gt;
&lt;p&gt;— Uncle Roger&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Being a big fan of MSG and having faced similar criticism, I decided to finally write a post presenting why MSG is infamous.&lt;/p&gt;
&lt;h2&gt;What is MSG?&lt;/h2&gt;
&lt;p&gt;Monosodium Glutamate or MSG is the sodium salt of Glutamic Acid. Popularly known by its &lt;a href=&quot;https://en.wikipedia.org/wiki/Generic_trademark&quot;&gt;genericised&lt;/a&gt; name Aji no Moto (Aji means Taste, Moto means Essence, no is a preposition, so aji no moto stands for The Essence of Taste), is a compound that provides umami flavour. &lt;a href=&quot;https://en.wikipedia.org/wiki/Umami&quot;&gt;Umami&lt;/a&gt; or Savoury is one of the 5 basic tastes that humans have receptors for, along with — Sweet, Sour, Salty and Bitter. Umami receptors typically respond to glutamate and nucleotides. Despite its widespread notoriety, glutamates are naturally found in a lot of foods like meat broths, fermented food, tomatoes, mushrooms, seaweeds and are even &lt;a href=&quot;https://www.sciencedaily.com/releases/2009/10/091009092344.htm#:~:text=Even%20in%20breast%20milk&amp;amp;text=The%20most%20abundant%20amino%20acid,Taiwan%2C%22%20the%20researcher%20concludes.&quot;&gt;claimed to be present in breast milk&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Origins&lt;/h2&gt;
&lt;p&gt;MSG, although sometimes called Chinese Salt in India(and elsewhere) due to the popularity of Chinese food and use of MSG in them, actually has its origin in Japan. Kikunae Ikeda of Tokyo Imperial University realised that Dashi, a Japanese broth of Dried Tuna (&lt;a href=&quot;https://en.wikipedia.org/wiki/Katsuobushi&quot;&gt;Katsuobushi&lt;/a&gt;) and Seaweed (&lt;a href=&quot;https://en.wikipedia.org/wiki/Kombu&quot;&gt;Kombu&lt;/a&gt;), has a unique taste that he cannot classify as any of the then recognised taste — sweet, salty, sour or bitter. In 1908, he isolated sodium glutamate from Kombu as a flavouring ingredient by aqueous extraction and crystallization of glutamic acid. He called his patented creation Monosodium Glutamate and proposed the flavour it provided as Umami (Japanese for — pleasant savoury taste). In 1909, the Suzuki brothers started commercial production under the iconic name ‘&lt;a href=&quot;https://www.ajinomoto.com/&quot;&gt;Ajin-no-moto&lt;/a&gt;’. But, it wasn’t till 1985 that the &lt;a href=&quot;https://www.srut.org/english/about-en/&quot;&gt;scientific community accepted&lt;/a&gt; Umami as the flavour of glutamates and nucleotides.&lt;/p&gt;
&lt;h2&gt;Fall from Grace&lt;/h2&gt;
&lt;p&gt;Ever since it started being sold, MSG has enjoyed widespread popularity and acceptance in various East Asian cuisines. It all changed when the fire nation attacked...err I meant when a &lt;a href=&quot;https://ir.uiowa.edu/poroi/vol12/iss2/7/&quot;&gt;letter&lt;/a&gt; was penned to the &lt;a href=&quot;https://www.nejm.org/&quot;&gt;New England Journal of Medicine&lt;/a&gt;. In this letter, Dr Robert Ho Man Kwok coined the term “Chinese Restaurant Syndrome” which was a collective term for a bunch of &lt;em&gt;“symptoms“&lt;/em&gt; he believed, were caused by MSG. Dr Kwok believed that every time he visited a Chinese restaurant he experienced - numbness of the neck, arms, and back with headache, dizziness, excessive sweating and palpitations. This publication was met with a lot of ridicule, satire within the medical community, as this wasn’t an &lt;a href=&quot;https://news.colgate.edu/magazine/2019/02/06/the-strange-case-of-dr-ho-man-kwok/&quot;&gt;isolated comical letter&lt;/a&gt; to NEJM. What’s to be noted here is that this observation was not scientific in any stretch of the word and was totally anecdotal.&lt;/p&gt;
&lt;p&gt;Interestingly, in 2018, renowned surgeon Dr Howard Steel claimed to have written the above letter under a pseudonym for a bet. But according to a &lt;a href=&quot;https://www.thisamericanlife.org/668/the-long-fuse&quot;&gt;This American Life&lt;/a&gt; interview, they discovered that a real Dr Kwok existed and his descendants claim that he did, in fact, write the letter. This was followed by an NYTimes article that was published six weeks after the NEJM letter was published. This article took the letter at face value without further investigating/verifying whether the said letter was credible science. Though we cannot be sure, whether the letter written by Dr Kwok was an inside joke of the scientific community or if he did truly believe that there exists such syndrome.&lt;/p&gt;
&lt;p&gt;There was another significant paper that affected the public perception of MSG, titled - &lt;a href=&quot;https://www.sciencedirect.com/science/article/abs/pii/S0896841107001400&quot;&gt;Monosodium glutamate (MSG): A villain and promoter of liver inflammation and dysplasia&lt;/a&gt; that claimed that MSG causes cancer in rats. The methodology involved here though is questionable at best - injecting an abnormally high concentration of MSG directly into the bloodstreams of mice. Since digestive intake is not the same as a subcutaneous injection, we have to take the observations of this paper with a grain of Chinese Salt (sorry 😜).&lt;/p&gt;
&lt;h2&gt;Scientific Consensus&lt;/h2&gt;
&lt;p&gt;MSG is regarded as &lt;a href=&quot;https://web.archive.org/web/20070521071111/http://www.cfsan.fda.gov/~dms/opascogd.html&quot;&gt;fairly safe&lt;/a&gt; for consumption by the FDA of the USA. European Union, while yet to publish a NOAEL(No Observable Adverse Effect Level) for glutamate flavouring, considers that a daily intake of MSG of 6 grams per kilogram of body weight (6 g/kg/day) &lt;a href=&quot;https://doi.org/10.1038/sj.ejcn.1602526&quot;&gt;is safe&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;As &lt;a href=&quot;https://en.wikipedia.org/wiki/Glutamate_flavoring#cite_note-freeman-20&quot;&gt;no association&lt;/a&gt; between MSG consumption and &lt;a href=&quot;https://doi.org/10.1016%2F0041-008X%2871%2990129-3&quot;&gt;the claimed symptoms&lt;/a&gt; have been successfully demonstrated under &lt;a href=&quot;https://doi.org/10.1016%2F0278-6915%2893%2990012-N&quot;&gt;rigorous testing conditions&lt;/a&gt;, the general scientific consensus on MSG is that it’s safe to eat.&lt;/p&gt;
&lt;h2&gt;Redefine CRS Campaign&lt;/h2&gt;
&lt;p&gt;While researching for this article I came across a recent campaign - &lt;a href=&quot;https://www.whyusemsg.com/chinese-restaurant-syndrome/&quot;&gt;#RedefineCRS&lt;/a&gt; by Ajinomoto Co. Inc. This campaign aimed to redefine the entry for Chinese Restaurant Syndrome in Merriam-Webster dictionary, on the grounds of it being dated and somewhat offensive. While I didn’t find the origin of the bias towards MSG had any racial roots, I can certainly see how it can be offensive. Though I assure you this isn’t a sponsored article, nor was it written for the &lt;a href=&quot;https://www.whyusemsg.com/chinese-restaurant-syndrome/&quot;&gt;#RedefineCRS&lt;/a&gt; campaign.&lt;/p&gt;
</content:encoded><author>Vaibhav Sharma</author></item><item><title>Is “Always”, really Snape’s best line?</title><link>https://theleakycauldronblog.com/articles/is-always-really-snape-best-line</link><guid isPermaLink="true">https://theleakycauldronblog.com/articles/is-always-really-snape-best-line</guid><description>&lt;img alt=&quot;Is “Always”, really Snape’s best line?&quot; src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Fartem-maltsev-always-snape.CiWVAMHo.jpg&amp;w=4512&amp;h=3012&amp;dpl=699bfef0c4120e00087ee35a&quot; /&gt; After a lot of digging, I think I&apos;m finally convinced that I have found out the best line that Snape has ever uttered. So here I am writing to convince you of the same.</description><pubDate>Thu, 27 Aug 2020 12:30:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;em&gt;Check out this amazing article on Severus Snape by my friend &lt;strong&gt;&lt;a href=&quot;mailto:hermionelovegood@gmail.com&quot;&gt;Hermione Lovegood&lt;/a&gt;&lt;/strong&gt;. For more of her writings check out her blog - &lt;strong&gt;&lt;a href=&quot;https://dailyquibbler.com&quot;&gt;The Daily Quibbler&lt;/a&gt;&lt;/strong&gt;, where she analyzes various books and movies from an unusual point of view. The idea behind the name, as you can see is also derived from our beloved &apos;Harry Potter&apos;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Maybe, few of the most used quotes of all time, from the Harry Potter series is - &lt;em&gt;&quot;&lt;strong&gt;After all this time?&lt;/strong&gt;&quot;&lt;/em&gt; and, it’s apt retort - &lt;em&gt;&quot;&lt;strong&gt;Always&lt;/strong&gt;&quot;&lt;/em&gt;. Deep down, we all know that Severus Snape can beat many great lovers of the fictional world. So, for us &lt;em&gt;Potterheads&lt;/em&gt;, &lt;em&gt;&quot;After all this time&quot;&lt;/em&gt; and &lt;em&gt;&quot;Always&quot;&lt;/em&gt; replaced the magic words - &lt;em&gt;&apos;&lt;strong&gt;I love you&lt;/strong&gt;&apos;&lt;/em&gt;. Because these, more than anything else, reveal the potion master&apos;s heart before our eyes, the heart that was capable of loving forever, loving ceaselessly, loving despite all the hatred he got.&lt;/p&gt;
&lt;p&gt;Or do they?&lt;/p&gt;
&lt;p&gt;Ever since I first read The Deathly Hallows, I was convinced that these are not the best words to reflect Snape’s heart. So, I began searching, analysing, re-reading the books. And, after a lot of digging, I think I&apos;m finally convinced that I have found out the best line that Snape has ever uttered. So here I am writing to convince you of the same.&lt;/p&gt;
&lt;p&gt;Love might not necessarily change a person, but it certainly has the potential to. For instance, it did so to a person whose early life was wrecked by lack of care, excess of bitter treatment, abandonment, and who, despite having better paths, overlooked them drowned in resentment, and could not help himself from descending deep into the dark arts. But at the same time, love cannot change a person who does not know its meaning.&lt;/p&gt;
&lt;p&gt;There&apos;s hardly any doubt that despite having a soul, as beautiful as, the wild white flower that blooms in the deepest parts of the forest, he was never the one to open its doors. But then, love came from the overwhelming power of opening those very doors. But when I talk about someone loving Severus Snape, so deeply, that it kindled a thousand untouched candles in every dark passage of his soul, mind, and life, I’m not referring to Lily Evans, but the extraordinary &lt;em&gt;&lt;strong&gt;Albus Percival Wulfric Brian Dumbledore&lt;/strong&gt;&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;It&apos;s well known that Snape kept on protecting Harry and fighting the battle against Voldemort, out of his undying love for Lily. But, according to me, that&apos;s only partially correct. His love for Lily was indeed eternal, but that was definitely not the most important factor behind Snape’s unshaken resolution. With time, the former Death Eater turned into a man who did not need any promise to drive him on the path of goodness. Snape indeed vowed to protect Harry because he didn&apos;t want Lily&apos;s sacrifice to go in vain. But later, his motive became broader and more enlightened. His character development over the years supports this argument. There are three, very clear examples of this progress.&lt;/p&gt;
&lt;p&gt;First, in &lt;em&gt;The Deathly Hallows&lt;/em&gt;, we find out that during The Battle of Seven Potters, Snape attempts to protect one of his so-called &quot;&lt;em&gt;enemies&lt;/em&gt;&quot;, Lupin (although the curse made George, &apos;&lt;em&gt;saint-like&lt;/em&gt;&apos; instead). The mere fact that he buried his childhood enmity against A Marauder and tried to save him, risking his cover, alone, is enough indication of his transformation. Remember, he had no debt to repay this time, like he had when he protected Harry from Quirrell. He saved Lupin for no reason other than the impulse of saving an innocent man. Thus, we realise that his acclimation to killing and murder was long eliminated.&lt;/p&gt;
&lt;p&gt;Directly linked with this, is the second example, which we will observe through this excerpt -&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;’Don’t be so shocked, Severus. How many men and women have you watched die?’&lt;/p&gt;
&lt;p&gt;‘Lately, only those whom I could not save’ said Snape.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Is it not in sharp contrast with the man, who once, only cared about Lily, and was unmoved by the fact that an infant will also be killed?&lt;/p&gt;
&lt;p&gt;And the final nail in the coffin, from ‘&lt;em&gt;The Prince’s Tale&lt;/em&gt;’ — &lt;em&gt;The Deathly Hallows&lt;/em&gt; -&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;‘Headmaster! They are camping in the Forest of Dean! The Mudblood –‘&lt;/p&gt;
&lt;p&gt;‘Do not use that word!’&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It is such an amazing situational irony that Snape(&lt;em&gt;the then Headmaster&lt;/em&gt;), who, in his anger, himself used this insulting word on Lily- his love, couldn’t even endure it from a Death Eater anymore.&lt;/p&gt;
&lt;p&gt;These examples indubitably clarify that there was more to it than just his love for Lily that went into making Severus Snape, the character we have come to admire. But how were these changes possible? As we have already established, that while his unrequited love and remorse did set him on the path of goodness, that alone wasn&apos;t enough to change him altogether. What actually turned him into an overall good, sensible, and an empathetic person is his association with Albus Dumbledore.&lt;/p&gt;
&lt;p&gt;Yes, that’s right, Albus Dumbledore’s presence worked as a true &lt;em&gt;Philosopher’s Stone&lt;/em&gt; for Snape. This “&lt;em&gt;greatest wizard of all time&lt;/em&gt;” loved the desolate man. In a world where Snape received nothing but distrust, disrespect, and dishonour, Dumbledore was the only person who knew the real Severus. Dumbledore was the only person to acknowledge the goodness within him. And Snape was grateful. Yes, he was grateful to the one person who believed him in the whole world. And naturally, it was very important to him to keep the Headmaster&apos;s trust. Being a gifted &lt;em&gt;&lt;a href=&quot;https://www.hp-lexicon.org/thing/occlumens/&quot;&gt;Occlumens&lt;/a&gt;&lt;/em&gt;, he didn’t show it often, but we catch a few glimpses of his heart sometimes. For example, when Mad-Eye Moody(&lt;em&gt;disguised Crouch Jr, to be precise&lt;/em&gt;) questions Dumbledore’s trust over Snape, the hooked nose man instantly became defensive –&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;‘Dumbledore happens to trust me,’ said Snape through clenched teeth. ‘I refuse to believe that he gave you orders to search my office!’&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Apart from this extract, there are few words uttered by Snape, which clearly, uncloaks how much it meant for him to let Dumbledore know about the effort he put in his reform. And thus comes the words which I think are more significant than &apos;&lt;em&gt;After all this time&lt;/em&gt;&apos; and &apos;&lt;em&gt;Always&lt;/em&gt;&apos;. When Dumbledore gave Snape the task of killing him, he told us that he cared for the soul of Draco. And at that very moment, maybe being unable to restrain himself anymore, Snape asked him –&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;‘And my soul, Dumbledore? Mine?’&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;These words speak more than anything about &apos;&lt;em&gt;the bravest man&lt;/em&gt;&apos; we know. It speaks of how he had been ceaselessly working to refine his soul from the moment Dumbledore offered an enlightened world for him. They reveal how Snape, at last, got a person in his life whom he could touch with all the unromantic feelings possible between two closed persons. It speaks of the pain of Severus Snape, as well as the love within him. While his love for Lily set him on the right path, the love of Dumbledore was his constant companion on this path.&lt;/p&gt;
</content:encoded><author>Hermione Lovegood</author></item><item><title>WARNING: Images that can break your brain — McCollough Effect</title><link>https://theleakycauldronblog.com/articles/mccollough-effect</link><guid isPermaLink="true">https://theleakycauldronblog.com/articles/mccollough-effect</guid><description>&lt;img alt=&quot;WARNING: Images that can break your brain — McCollough Effect&quot; src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Fdavid-clode-mccollough-effect.nm01mXZ0.jpg&amp;w=4392&amp;h=3090&amp;dpl=699bfef0c4120e00087ee35a&quot; /&gt; What if I told you there exists a scary SCARY thing that can enter your head through your eyes and breaks your brain for a very long time?! This scary phenomenon is called the McCollough Effect.</description><pubDate>Mon, 24 Aug 2020 12:30:00 GMT</pubDate><content:encoded>&lt;p&gt;Earworm or Sticky Music Syndrome refers to the phenomenon when a catchy piece of music continually repeats through a person’s mind after it’s no longer playing. It’s an annoyance mostly, but to be honest I sometimes use it to play music in my head while commuting, when I forget my earphones at home.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;We are told to remember the idea, not the man, because a man can fail. He can be caught, he can be killed and forgotten, but 400 years later, an idea can still change the world.&lt;/p&gt;
&lt;p&gt;\—V for Vendetta&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;But what if I told you there exists a scary SCARY thing that can enter your head through your eyes and can break your brain for a very long time?! This scary phenomenon is called the &lt;strong&gt;&lt;a href=&quot;http://people.brandeis.edu/~sekuler/SensoryProcessesMaterial/McColloughArticle1965.pdf&quot;&gt;McCollough Effect&lt;/a&gt;&lt;/strong&gt;. Now you may ask what exactly is this &lt;em&gt;McCollough Effect&lt;/em&gt; and how does it work? The answer is there exists a set of images that when exposed to can literally break how your brain works! And the scariest part is that its effects can last &lt;a href=&quot;https://doi.apa.org/doiLanding?doi=10.1037%2F0096-1523.1.4.323&quot;&gt;up to 3 months&lt;/a&gt;! But, before we proceed, I must warn you that this isn’t a joke, this is a real phenomenon with no absolute guarantee on how long the effects can last. So please, do not try this. And I’m fully aware that the internet is not really known for people following safety warnings, but guys, this is a truly terrifying phenomenon and shouldn’t be taken lightly.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://lh4.googleusercontent.com/CF-fJB0SgfchuR74WPP8VovaPbhLyYNbSoNg9yR1tW7UiM_JzkcOlI6Cl9PK7mQos1VHYrNuZc-VuBVLtwXPvMcbHNFxhQ72o2F6nOcdhE7QlxlU5_UBpBXDuwNrt08_8wq6M7UL&quot; alt=&quot;McCollough Effect Induction Image 1&quot; title=&quot;McCollough Effect Induction Image 1&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://lh6.googleusercontent.com/rcLWHB5AXVvOZBcg0huINYaVGT5vqEu4Oy4RZNf4EGCq3iGAjWsD87fgsvfafwyaOd7tvl07m1UkKIta6W0nhzemPWO8T_cfSlHB7qPhCZ7MTVaapKcDQ_wAXoXMzod6GDwrmLIe&quot; alt=&quot;McCollough Effect Induction Image 2&quot; title=&quot;McCollough Effect Induction Image 2&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;Induction Images&lt;/h2&gt;
&lt;p&gt;Coming back to the effect. As you can see, there exists a set of two oppositely coloured images with oppositely oriented black bars in them. The subject has to merely stare at them for a certain amount of time, called induction, for this phenomena to occur. After a successful induction, when the subject is exposed to test images which are black and white sets of oppositely oriented bars, they see opposite colours between the white spaces of corresponding induction images. So, for example, if the horizontal induction image had red colour between the bars and the vertical induction image had green, the subject will see green between the horizontal bars and red between vertical bars in test images. This phenomenon is not just limited to these particular induction and test images, as it also occurred with people who worked long periods on old computer monitors that displayed green texts on black background. These people reported seeing pink colour between the letters of black texts on a white background of books with the same spatial frequency between the alphabets, as the monitors.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://lh3.googleusercontent.com/6_oEQb67vihz0NNHl1tOwcVDLDarfDpC8lLFuuVCa7fjBgGtH-bHVKDkWHLZjTPpgEuiG9U85kz9HS9cy29FEcAmuYXk1xfnFdXyK9C21OclNkXLgqFzQgffu6JHODC_tyZEJZr7&quot; alt=&quot;McCollough Effect Test Images&quot; title=&quot;McCollough Effect Test Images&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;Test Images&lt;/h2&gt;
&lt;p&gt;As to why this happens, there is a flurry of research papers that try to explain this phenomenon from various standpoints. Some say it’s because of classical conditioning, others attribute it to neurological reasons, but the explanations are highly debated with no conclusive evidence to one particular explanation. And this lack of a conclusive explanation makes it particularly dangerous, as the term of effect varies from person to person, and can even become permanent. So once again try it at your own risk.&lt;/p&gt;
</content:encoded><author>Vaibhav Sharma</author></item><item><title>Apne Apne Bhagwaan — अपने अपने भगवान</title><link>https://theleakycauldronblog.com/articles/apne-apne-bhagwaan</link><guid isPermaLink="true">https://theleakycauldronblog.com/articles/apne-apne-bhagwaan</guid><description>&lt;img alt=&quot;Apne Apne Bhagwaan — अपने अपने भगवान&quot; src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Fben-white-apne-apne-bhagwaan.BxdPdmDz.jpg&amp;w=6016&amp;h=4016&amp;dpl=699bfef0c4120e00087ee35a&quot; /&gt; राम तू, क़ुरान तू, नानक साहब का ज्ञान तू, सच्ची समझ जो आ जाये,   तो परमेश्वर रूपी इंसान तू! — व्योम</description><pubDate>Sun, 16 Aug 2020 12:30:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;em&gt;A powerful poem by my friend who writes under the pen-name &quot;&lt;strong&gt;Vyom&lt;/strong&gt;&quot;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;अजीब सा माहौल है, &lt;br /&gt;
मानो सब गोल मोल है &lt;br /&gt;
कोई इधर, कोई उधर, &lt;br /&gt;
सब के सब है तीतर बितर&lt;/p&gt;
&lt;p&gt;कोई है मग्न यहाँ राम में, &lt;br /&gt;
किसी की जान है क़ुरान में &lt;br /&gt;
कोई भगवे में हो रहा है लीन, &lt;br /&gt;
तो कोई हरा भरा है रात दिन&lt;/p&gt;
&lt;p&gt;कोई मांगता रहे रिहाई, &lt;br /&gt;
की खतरे में हैं सारे भाई &lt;br /&gt;
कहीं डर का माहौल है, &lt;br /&gt;
कहीं खुल रही अब पोल है&lt;/p&gt;
&lt;p&gt;कोई चीख़ता - चिल्लाता यहाँ &lt;br /&gt;
कोई बम से उड़ाता यहाँ &lt;br /&gt;
कोई मस्जिद को है तोड़ रहा &lt;br /&gt;
कोई मंदिर का ईंटा जोड़ रहा&lt;/p&gt;
&lt;p&gt;अजीब सख्त वक्त है &lt;br /&gt;
गिर रहा हर तख्त है &lt;br /&gt;
हर खून मानो सो रहा &lt;br /&gt;
है काल मानो रो रहा&lt;/p&gt;
&lt;p&gt;हर शख़्स किसी से लड़ रहा &lt;br /&gt;
खुदा भी अब तो डर रहा &lt;br /&gt;
इनसानियत ही है खुदा &lt;br /&gt;
खुदा से ना कोई जुदा &lt;br /&gt;
संभल जा तू अब मान जा &lt;br /&gt;
इस बात को अब जान जा&lt;/p&gt;
&lt;p&gt;ये बात भी ना सच्चा हो &lt;br /&gt;
सिर्फ खुदा का बंदा अच्छा हो &lt;br /&gt;
सिर्फ राम नाम का ही बोल रहे &lt;br /&gt;
इन बातों का फिर क्या मोल रहे?&lt;/p&gt;
&lt;p&gt;हर बात को है जानता, &lt;br /&gt;
वो सबको ही तो मानता &lt;br /&gt;
इनसानियत बनाई जिसने, तू उसे ही बचा रहा! &lt;br /&gt;
दुनिया बनाई जिसने , तू उसे दुनिया दिखा रहा!&lt;/p&gt;
&lt;p&gt;दया रखो, धर्म करो &lt;br /&gt;
ये पाठ जो है बोलता &lt;br /&gt;
दंगे करवाके, हिंसा अपना के &lt;br /&gt;
उनके मूल्यों को है तू तोलता!&lt;/p&gt;
&lt;p&gt;राम तू, क़ुरान तू, &lt;br /&gt;
नानक साहब का ज्ञान तू &lt;br /&gt;
सच्ची समझ जो आ जाये, &lt;br /&gt;
तो परमेश्वर रूपी इंसान तू!&lt;/p&gt;
&lt;p&gt;— &lt;em&gt;&lt;strong&gt;व्योम&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
</content:encoded><author>Vyom</author></item><item><title>The Interesting World of Bees</title><link>https://theleakycauldronblog.com/articles/the-interesting-world-of-bees</link><guid isPermaLink="true">https://theleakycauldronblog.com/articles/the-interesting-world-of-bees</guid><description>&lt;img alt=&quot;The Interesting World of Bees&quot; src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Fboris-smokrovic-the-interesting-world-of-bees.CC2UB-zf.jpg&amp;w=3615&amp;h=2410&amp;dpl=699bfef0c4120e00087ee35a&quot; /&gt; Take a look at the interesting life of bees. Bees pollinate about 80% of the world&apos;s plants including 90 different food crops. That’s about ~ 1/3 of all the agricultural food crops!</description><pubDate>Fri, 24 Apr 2020 12:30:00 GMT</pubDate><content:encoded>&lt;p&gt;Bees are one of the most fascinating creatures in the world. In the alleys of the internet there’s a popular meme that gets passed around - “&lt;em&gt;According to Albert Einstein if honey bees were to disappear from the earth, humans would be dead within four years&lt;/em&gt;”. While there’s no evidence that Einstein said so, or that the apocalyptic prophecy mentioned would occur, what’s true though is that it’ll certainly cause mass starvation. Bees pollinate about 80% of the world&apos;s plants including 90 different food crops. That’s about one third or one-fourth of all the agricultural food crops! Not only are they very helpful, but their life is also very very interesting.&lt;/p&gt;
&lt;p&gt;It all begins when worker bees decide to raise a new queen. They pick a few eggs and build a peanut-shaped ‘&lt;em&gt;&lt;strong&gt;Queen Cell&lt;/strong&gt;&lt;/em&gt;’ around them. These special eggs hang in the hexagonal honeycomb. But the journey to royalty isn’t easy. The first to emerge kills all the other candidates before they can reach adulthood. If multiple queens hatch simultaneously, they’ll fight to death. And only one comes out as a victor. This is pretty much the only time the queen uses their stinger.&lt;/p&gt;
&lt;p&gt;These queens-to-be candidates are the only one fed the ‘&lt;em&gt;&lt;strong&gt;Royal Jelly&lt;/strong&gt;&lt;/em&gt;’, a substance secreted by the workers, their entire life, even in adulthood. This ‘&lt;em&gt;&lt;strong&gt;Royal Jelly&lt;/strong&gt;&lt;/em&gt;’ helps them reach sexual maturity with active ovaries. The competition and pressure are so high that they mature ~ 25% faster than normal workers. The Queen’s only job is to lay eggs. But, her pheromones also help keep the hive healthy.&lt;/p&gt;
&lt;p&gt;She mates once at the beginning of her life, then lays more than a thousand eggs a day during summer for up to five years. But not all eggs get fertilised. The fertilised eggs they lay become female worker bees, and the non-fertilised eggs become male drones. The female fertilised eggs are fed ‘&lt;em&gt;&lt;strong&gt;Royal Jelly&lt;/strong&gt;&lt;/em&gt;’ for the first two days, then switched to a diet of pollen and honey. This change in diet causes hormonal changes that prevent worker bees from attaining sexual maturity. They make up about 85% of the population and they are the ones who do all the important tasks like nectar collection, taking care of eggs, males and the queen etc keeping the hive running smoothly&lt;/p&gt;
&lt;p&gt;The unfertilised eggs that become male make up about 15% of the total population of the hive. This interesting distinction in the sex of male drone bees, means they have only half the chromosomes of their sisters. And no father! These drones are mostly useless, can’t even feed themselves. They have only one goal in life -- To try and mate with a virgin queen from another hive. If they succeed, they die, if not they get killed, or evicted before the winter arrives.&lt;/p&gt;
</content:encoded><author>Vaibhav Sharma</author></item><item><title>Mushroom Stroganoff with Smetana (Sour Cream) Recipe</title><link>https://theleakycauldronblog.com/articles/mushroom-stroganoff-with-smetana-sour-cream-recipe</link><guid isPermaLink="true">https://theleakycauldronblog.com/articles/mushroom-stroganoff-with-smetana-sour-cream-recipe</guid><description>&lt;img alt=&quot;Mushroom Stroganoff with Smetana (Sour Cream) Recipe&quot; src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Fmushroom-stroganoff-with-sour-cream.C78mdMUF.jpg&amp;w=4000&amp;h=2272&amp;dpl=699bfef0c4120e00087ee35a&quot; /&gt; A vegetarian twist to a classic Russian dish. This is an easy and tasty recipe to enjoy with Rice or Buttered Noodles.</description><pubDate>Mon, 23 Mar 2020 12:30:00 GMT</pubDate><content:encoded>&lt;p&gt;Mushroom Stroganoff is a Russian dish of sautéed pieces of Mushroom served in a sauce with &lt;a href=&quot;https://en.wikipedia.org/wiki/Smetana_(dairy_product)&quot;&gt;smetana&lt;/a&gt; (&lt;a href=&quot;https://en.wikipedia.org/wiki/Sour_cream&quot;&gt;sour cream&lt;/a&gt;). Best enjoyed with &lt;em&gt;rice&lt;/em&gt; and a side of &lt;em&gt;sautéed vegetables&lt;/em&gt;. It can be made in ~ 1 hour.&lt;/p&gt;
&lt;h2&gt;Ingredients&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;200g &lt;strong&gt;Button Mushrooms&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;1 medium &lt;strong&gt;Onion&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;3 &lt;strong&gt;Green Chillies&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;1 tablespoon &lt;strong&gt;All Purpose Wheat Flour&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;½ cup &lt;strong&gt;Sour Cream&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;3 tablespoon &lt;strong&gt;Butter&lt;/strong&gt; (or &lt;strong&gt;Olive Oil&lt;/strong&gt;)&lt;/li&gt;
&lt;li&gt;½ teaspoon &lt;strong&gt;Ginger Garlic Paste&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;½ teaspoon &lt;strong&gt;Italian Herb Mix&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;¼ teaspoon &lt;strong&gt;Black Pepper&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;½ teaspoon &lt;strong&gt;Salt&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Preparations&lt;/h2&gt;
&lt;h3&gt;Vegetables&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Cut the mushrooms in long, ¼ centimetre thick strips, along the stem.&lt;/li&gt;
&lt;li&gt;Mince onion and green chillies.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Mushroom Broth&lt;/h3&gt;
&lt;p&gt;Before we begin we first need to prepare &lt;em&gt;Mushroom Broth&lt;/em&gt;.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Heat a tablespoon of butter in a non stick pan and let it sizzle.&lt;/li&gt;
&lt;li&gt;Add the chopped mushrooms.&lt;/li&gt;
&lt;li&gt;Stir it till the mushroom starts releasing water.&lt;/li&gt;
&lt;li&gt;Cook till they are beginning to get brownish.&lt;/li&gt;
&lt;li&gt;Add water, let it boil for a minute.&lt;/li&gt;
&lt;li&gt;Separate the mushrooms and the broth using a strainer.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Steps to Make&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Sprinkle the mushrooms with salt, pepper and herbs. Set it aside.&lt;/li&gt;
&lt;li&gt;Melt a tablespoon of butter in a non stick pan.&lt;/li&gt;
&lt;li&gt;Add a tablespoon of flour, cook it for 2 minutes, stirring constantly.&lt;/li&gt;
&lt;li&gt;Gradually add the mushroom broth while stirring, cook it till it becomes smooth and thick. Set the prepared broth sauce aside.&lt;/li&gt;
&lt;li&gt;Heat up another tablespoon of butter, add the minced onions and green chillies. Cook till the onions begin to get brown.&lt;/li&gt;
&lt;li&gt;Add garlic ginger paste and mix well.&lt;/li&gt;
&lt;li&gt;Quickly add mushrooms, and cook till they are brown.&lt;/li&gt;
&lt;li&gt;Add the thickened broth sauce we prepared earlier, cover and cook for 10 minutes on low. Stirring every few minutes.&lt;/li&gt;
&lt;li&gt;Stir in the sour cream, cook it up but don’t let it boil.&lt;/li&gt;
&lt;li&gt;Garnish it with Herbs and Enjoy.&lt;/li&gt;
&lt;/ol&gt;
</content:encoded><author>Vaibhav Sharma</author></item><item><title>Pro Mode of our Brain – Awareness</title><link>https://theleakycauldronblog.com/articles/pro-mode-of-our-brain-awareness</link><guid isPermaLink="true">https://theleakycauldronblog.com/articles/pro-mode-of-our-brain-awareness</guid><description>&lt;img alt=&quot;Pro Mode of our Brain – Awareness&quot; src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Fben-white-thinking-and-awareness.Bl-K0RlV.jpg&amp;w=6016&amp;h=4016&amp;dpl=699bfef0c4120e00087ee35a&quot; /&gt; My dealings with my awareness, and how it changed my life. I learnt that just like a DSLR has an &apos;Auto&apos; Mode and a &apos;Pro&apos; Mode we also have two types of settings of our brain.</description><pubDate>Sat, 12 Oct 2019 12:30:00 GMT</pubDate><content:encoded>&lt;p&gt;We all have done embarrassing things, taken bad decisions and primarily - said some bad things in the haze of the moment. Things that still traumatise us every time their thoughts cross our heads. We often ask ourselves - &apos;What was I thinking?!&apos;. We can&apos;t seem to fathom, how we didn&apos;t consider certain information while taking a certain decision, despite knowing it in the back of our heads. And maybe it&apos;s a bias, but I feel that for some reason I tend to do it more than average people. It could be anything from murmuring to myself while in a crowded metro or making faces while eating alone, to blurting out inappropriate and or hurtful things. It&apos;s so bad that I&apos;m scared every time I let myself zone out, as I don&apos;t totally trust myself in &apos;Auto&apos; Mode.&lt;/p&gt;
&lt;p&gt;Yes, that&apos;s right, just like a DSLR Camera has an &lt;code&gt;&apos;Auto&apos; Mode&lt;/code&gt; and a &lt;code&gt;&apos;Pro&apos; Mode&lt;/code&gt;, I believe that we also have two types of modes in our brain. Take this for an example, if I ask you what&apos;s 2 + 2 - 1 you can answer it without thinking. &lt;em&gt;Quick Mafs amirite!&lt;/em&gt; I mean of course we do think, but it&apos;s almost as if the answer comes to us as a reflex. It&apos;s not the same as if I ask you to calculate what&apos;s 15 times 23 in your head. Most people can multiply two digits number in their head, given enough patience. But, the mental effort required, compared to a simple 2 + 2 - 1 would be vastly different. Musicians and athletes call this muscle memory, even though the memory technically still is stored in our brain.&lt;/p&gt;
&lt;p&gt;In psychology, one way to model how our brains work is to imagine that it&apos;s made up of two systems, psychologists call it System 1 and System 2, or as I like to call it Auto Mode and Pro Mode. Basically what that means is that Pro Mode is your conscious part, and the part, that you think you are as an individual and Auto mode is your subconscious part. Pro Mode of our brain is slow and uncomfortable, it takes effort to operate, but it&apos;s careful, and can catch and fix errors. Auto Mode is fast and can process huge amounts of data with relatively very minimal effort, but is prone to error. Not just that, with practice and deliberate effort we can improve our auto mode, to do complex things with ease just like simple things that it already does. But the motive behind this article isn&apos;t to improve Auto Mode. This is about my dealings with getting control over the Pro Mode. To be able to engage it with ease without having to feel resistance and discomfort.&lt;/p&gt;
&lt;p&gt;My incredibly buggy Auto mode and inability to fully control my Pro Mode made me fascinated with elegant solutions, quick wits and when people did critical thinking in impromptu situations. It shaped my belief in such a way that for me truly great things are usually simple solutions to seemingly unknown problems that affect our every day. Social networks, for example, were born out of the need for humans to be social. Many people believe that it was social networks that destroyed the culture of actually interacting with people instead of keeping in touch online. Whereas the truth is as we developed more and more our work-life started becoming more demanding, we had less time to do what is an integral part of being human, socialising. We just found a solution to this cultural shift in the shape of social networks. The reason those people have this perspective is simply that, a cultural shift was a problem that they didn&apos;t realize humans had. This fascination and love for the elegant conscious decisions grew into what would become my life goal -- to make something that would not only reach the entire world but also help it. And, I realized that to achieve that goal I would have to &apos;fix&apos; my Auto Mode and get more in control of my Pro Mode.&lt;/p&gt;
&lt;p&gt;But before I could do that, I would have to go through a painful process of realising that to become what I wish to see myself as and to achieve what I wish to do in life I would have to switch to Pro Mode. That came to me when someone very close to me started being emotionally abusive towards me casually. Having known that person for a long time I knew that, malice couldn&apos;t have been the cause. All I could complain about was that they were hurtful, without ever being able to fully explain how. To explain it clearly and rather make them realise, I started by trying to understand what they were doing to me and more importantly, why and why couldn&apos;t they stop? The first part of that question only required me to document how they made me feel bad/hurt. However, to find the answer to the second part I had to dig through my history to find and remember similar events to try to understand the mindset. I realised that that person was doing these things in Auto Mode, and couldn&apos;t stop because of the giant ego that their Pro Mode came with. When I figured out I have in fact done similar things in Auto Mode in the past, I had to fix that about myself. If one thing I do not like about being human is how hypocritical our lives are. Both knowingly and unknowingly.&lt;/p&gt;
&lt;p&gt;But the silver lining to this experience was that I realized a few important things, first the reason of the goal in my life and the path towards achieving it, second, that it is possible to learn to process complex thoughts, and take aware actions in the same way we can walk upright and maintain our balance without thinking, You must be thinking that &quot;Vaibhav you are comparing apples to oranges!&quot;. The mental effort required differs by a vast difference between processing complex thoughts and walking. What you may not realize is how many complex calculations the brain does to just maintain balance standing still upright, let alone walking. If you have watched videos of some people abusing weird looking robots, you may be familiar with their creators, Boston Dynamics. The scientist working for Boston Dynamics would perhaps best tell you how complex these simple actions are. In fact, it&apos;s so complex to mimic human-like walking that we still haven&apos;t been fully able to do so. And since we all know that walking is an acquired behaviour in humans, something that we have to learn, not only that we learn to do a lot of things which become our second or first nature, which is very complex at their core.&lt;/p&gt;
&lt;p&gt;So I began trying to become more &apos;aware&apos; and to take more and more control of my actions in life. I began by simple things, like trying to feel and remember every bite of my meal, remembering the faces in commute, and of course, being more considerate while speaking something, etc. I was resolute about getting 100% of my life in my own control. Ironically assuming that, Auto Mode is just a bug in my system entirely and not something that evolution planned before putting in our system. The hard reality came crashing to me when I realized that I am after all a mere mortal, that no matter how aware I become I&apos;m still prone to making mistakes. And, being aware of trivial mistakes that I make - hurts more, takes longer to get over, and takes up precious space in RAM. This made me realize the importance and purpose of the Auto Mode. There&apos;s a reason why scientists and critical thinkers are generally sad. The good news is that this means that Auto Mode is just smart memory management by nature and that being able to do things in Auto Mode freed up my head for something more resource-heavy. From then on it was easy to make a connection to the fact that we get the best of our ideas while we are in the toilet, in the shower or while taking a walk, basically mundane things. Leaving us alone with our thoughts, freeing up our Pro Mode.&lt;/p&gt;
&lt;p&gt;Don&apos;t get me wrong the purpose of the article isn&apos;t to say that we should all be on Pro Mode all the time. Rather, from my experience, I found that while Pro Mode is a good thing there&apos;s a reason Auto Mode exists. You can&apos;t be wasting an hour to select what would be an appropriate attire to wear, or which toothbrush to buy. There are definitely times where Auto Mode is the appropriate mental state, we evolved it for a reason after all. It makes us more efficient and intuitive. It’s the getting over the discomfort in engaging our Pro Mode that’s important. The key is to identify where your priorities lie and that you are not lulled into the false comfort of cognitive ease that our Auto Mode provides hindering our path to success. Also, it&apos;s always nice to be considerate.&lt;/p&gt;
</content:encoded><author>Vaibhav Sharma</author></item><item><title>The Egg by Andy Weir in Hindi</title><link>https://theleakycauldronblog.com/articles/the-egg-by-andy-weir-in-hindi</link><guid isPermaLink="true">https://theleakycauldronblog.com/articles/the-egg-by-andy-weir-in-hindi</guid><description>&lt;img alt=&quot;The Egg by Andy Weir in Hindi&quot; src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Fparent-child-omar-lopez.B7YwtdxQ.jpg&amp;w=5472&amp;h=3648&amp;dpl=699bfef0c4120e00087ee35a&quot; /&gt; This is a Hindi translation of popular short story &apos;The Egg&apos; by Andy Weir. Translated by Vaibhav Sharma.</description><pubDate>Sun, 08 Sep 2019 12:30:00 GMT</pubDate><content:encoded>&lt;p&gt;This is my attempt at Hindi translation of popular short story &lt;a href=&quot;http://www.galactanet.com/oneoff/theegg_mod.html&quot;&gt;The Egg by Andy Weir&lt;/a&gt; (author of The Martian, Artemis). Written with the permission of Andy Weir.&lt;/p&gt;
&lt;h2&gt;द एग (एक अंडा) - ऐंडी वीयर&lt;/h2&gt;
&lt;p&gt;तुम घर जा रहे थे, जब तुम मर गए।&lt;/p&gt;
&lt;p&gt;यह एक कार दुर्घटना थी। विशेष रूप से उल्लेखनीय कुछ भी नहीं, लेकिन फिर भी घातक। तुम अपने पीछे एक पत्नी और दो बच्चे छोड़ गए। यह एक दर्दनाक मौत थी। डॉक्टरों ने तुम्हें बचाने की पूरी कोशिश की, लेकिन कोई फायदा नहीं हुआ। तुम्हारा शरीर इतना खराब हो चुका था कि यही बेहतर था, विश्वास करो।&lt;/p&gt;
&lt;p&gt;और तब तुम मुझसे मिले।&lt;/p&gt;
&lt;p&gt;&quot;क्या ... क्या हुआ?&quot; तुमने पूछा &quot;मैं कहाँ हूँ?&quot;&lt;/p&gt;
&lt;p&gt;&quot;तुम मर गए&quot;, मैंने कहा, सीधी बात। शब्द टटोलने में कोई फायदा नहीं है।&lt;/p&gt;
&lt;p&gt;&quot;वहाँ एक ... एक ट्रक था और वह फिसल रहा था ...&quot;&lt;/p&gt;
&lt;p&gt;&quot;हाँ&quot;, मैंने कहा।&lt;/p&gt;
&lt;p&gt;&quot;... मैं मर गया?&quot;&lt;/p&gt;
&lt;p&gt;&quot;हाँ। लेकिन इसके बारे में चिंता मत करो। हर कोई मर जाता है”, मैंने कहा।&lt;/p&gt;
&lt;p&gt;तुमने चारों ओर देखा। कुछ भी नहीं था। सिर्फ तुम और मैं। &quot;यह जगह क्या है?&quot;, &quot;क्या यह मरणोत्तर जीवन है?&quot;&lt;/p&gt;
&lt;p&gt;&quot;हाँ भी और नही भी&quot;, मैंने कहा।&lt;/p&gt;
&lt;p&gt;&quot;क्या आप भगवान हैं?&quot;, तुमने पूछा।&lt;/p&gt;
&lt;p&gt;&quot;हाँ,&quot; मैंने जवाब दिया। &quot;मैं भगवान हूं।&quot;&lt;/p&gt;
&lt;p&gt;&quot;मेरे बच्चे ... मेरी पत्नी&quot;, तुमने कहा।&lt;/p&gt;
&lt;p&gt;&quot;उनके बारे में क्या?&quot;&lt;/p&gt;
&lt;p&gt;&quot;वे सब ठीक हो जाएंगे?&quot;&lt;/p&gt;
&lt;p&gt;&quot;मुझे यह देखना पसंद है&quot;, मैंने कहा। “तुम मर गए और तुम्हारी मुख्य चिंता तुम्हारे परिवार के लिए है। यह अच्छा है। ”&lt;/p&gt;
&lt;p&gt;तुमने मुझे मोह से देखा। तुम्हारे लिए, मैं भगवान की तरह नहीं दिख रहा था। मैं बस किसी इंसान की तरह लग रहा था। या संभवतः एक महिला। कोई अस्पष्ट अधिकारिक व्यक्ति, हो सकता है। सर्वशक्तिमान से अधिक एक स्कूल शिक्षक लग रहा था।&lt;/p&gt;
&lt;p&gt;&quot;चिंता मत करो&quot;, मैंने कहा। &quot;वे ठीक हो जाएंगे, तुम्हारे बच्चे तुम्हें निष्कलंक याद करेंगे। उनके पास तुम्हारे लिए उपेक्षा बढ़ाने का समय नहीं था, तुम्हारी पत्नी बाहर से रोएगी, लेकिन अंदर से राहत पाएगी। निष्पक्षता से कहूं तो, तुम्हारी शादी टूट रही थी। यदि यह कोई सांत्वना है, तो वह राहत महसूस करने के लिए बहुत दोषी महसूस करेगी।&quot;&lt;/p&gt;
&lt;p&gt;&quot;अच्छा,&quot; तुमने कहा। &quot;तो अब आगे क्या? क्या मैं स्वर्ग या नरक या कुछ और... जाऊँगा? ”&lt;/p&gt;
&lt;p&gt;&quot;नहीं&quot;, मैंने कहा। &quot;तुम पुनर्जन्म लोगे।&quot;&lt;/p&gt;
&lt;p&gt;&quot;अच्छा&quot;, तुमने कहा। &quot;तो हिंदू सही थे&quot;,&lt;/p&gt;
&lt;p&gt;&quot;सभी धर्म अपने तरीके से सही हैं&quot;, मैंने कहा। &quot;मेरे साथ चलो।&quot;&lt;/p&gt;
&lt;p&gt;हम शून्य में आगे बढ़े। &quot;हम कहा जा रहे है?&quot;&lt;/p&gt;
&lt;p&gt;&quot;विशेष रूप से, कहीं नहीं&quot;, मैंने कहा। &quot;जब हम बात करते हैं, तो चलना अच्छा लगता है।&quot;&lt;/p&gt;
&lt;p&gt;&quot;तो फायदा क्या हुआ?&quot; &quot;जब मुझे पुनर्जन्म मिलेगा, तो मैं सिर्फ एक खाली स्लेट हो जाऊँगा, है ना? एक बच्चा। इसलिए मेरे सभी अनुभव और इस जीवन में मैंने जो कुछ भी किया वह कोई मायने नहीं रखता था।&quot;&lt;/p&gt;
&lt;p&gt;&quot;ऐसा नहीं है!&quot; मैंने कहा। “तुम अपने भीतर अपने सभी पिछले जन्मों का ज्ञान और अनुभव रखते हो। तुम उन्हें अभी याद नहीं कर सकते। ”&lt;/p&gt;
&lt;p&gt;मैने रुक कर, तुम्हारे कंधे पर हाथ रखा। &quot;तुम्हारी आत्मा, तुम्हारी संभवतः कल्पना से अधिक शानदार, सुंदर, और विशाल है। एक मानव मन में केवल वही छोटा अंश हो सकता है जो वह हैं। जैसे यह देखने के लिए कि पानी गर्म है या ठंडा, तुम पानी में अपनी उंगली डालते हो। वैसे ही तुमने अपना एक छोटा हिस्सा, भौतिक अस्तित्व में डाल देते हो, और जब तुम इसे वापस लाते हो, तो तुम्हारे पास पहले से अधिक अनुभव प्राप्त हो जाता है।&lt;/p&gt;
&lt;p&gt;&quot;तुम पिछले 48 वर्षों से एक मानव में हो, इसलिए तुमने अभी तक इसे नहीं फैलाया है और अपनी शेष चेतना को महसूस नहीं किया है। यदि हम लंबे समय तक यहां रहते हैं, तो तुम्हें सब कुछ याद आने लगेगा। लेकिन प्रत्येक जीवन के बीच ऐसा करने का कोई मतलब नहीं है।”&lt;/p&gt;
&lt;p&gt;&quot;मैंने कितनी बार पुनर्जन्म लिया हैं, फिर?&quot;&lt;/p&gt;
&lt;p&gt;“ओह बहुत सारे। करोडों से भी ज़्यादा। विभिन्न जीवों के बहुत सारे जन्म।”, मैंने कहा। &quot;इस बार, तुम 540 ई। में एक चीनी किसान लड़की होगे।&quot;&lt;/p&gt;
&lt;p&gt;&quot;रुको, क्या?&quot; तुम हकलाए। &quot;क्या आप मुझे समय में वापस भेज रहे हैं?&quot;&lt;/p&gt;
&lt;p&gt;“कह सकते हो। समय, जैसा कि तुम इसे समझते हो, केवल तुम्हारे ब्रह्मांड में मौजूद है। जहां मैं आता हूं वहां चीजें अलग होती हैं। ”&lt;/p&gt;
&lt;p&gt;&quot;आप जहां से आते हैं?&quot; तुमने पूछा।&lt;/p&gt;
&lt;p&gt;&quot;हाँ&quot;, मैंने समझाया &quot;मैं भी कहीं से आता हूं। कहीं और। और मेरे जैसे और भी हैं। मैं जानता हूं कि तुम जानना चाहते हो कि वहां क्या है, लेकिन ईमानदारी से कहूं तो तुम समझ नहीं पाओगे।”&lt;/p&gt;
&lt;p&gt;&quot;ऐसा क्या&quot;, तुमने थोड़ा निराश होकर कहा। &quot;लेकिन रुकें। यदि मैं समय में अन्य स्थानों में पुनर्जन्म लेता हूं, तो मैं किसी वक्त में खुद से बातचीत कर सकता था ”&lt;/p&gt;
&lt;p&gt;&quot;ज़रूर। अनेक बार होता भी है। लेकिन, दोनों को, केवल अपने स्वयं के जीवन के बारे में पता होता है इस वजह से वो दोनों  यह जान भी नहीं पाते हैं। &quot;&lt;/p&gt;
&lt;p&gt;&quot;इन सब का मतलब क्या है?&quot;&lt;/p&gt;
&lt;p&gt;&quot;सच में जानना चाहते हो?&quot; मैंने पूछा। &quot;सच में? तुम मुझसे जीवन का अर्थ पूछ रहे हो? क्या यह थोड़ा घिसा-पिटा नहीं है? ”&lt;/p&gt;
&lt;p&gt;&quot;यह एक उचित सवाल है&quot;, तुम कायम रहे।&lt;/p&gt;
&lt;p&gt;मैंने तुम्हारी आँखों में देखा। &quot;जीवन का अर्थ, जिस कारण से मैंने इस पूरे ब्रह्मांड को बनाया है, वह यह है की ताकि तुम परिपक्व हो जाओ।&quot;&lt;/p&gt;
&lt;p&gt;“आप का मतलब है मानव जाति? आप चाहते हैं कि हम परिपक्व हों। ”&lt;/p&gt;
&lt;p&gt;&quot;नहीं, सिर्फ तुम, मैंने यह पूरा ब्रह्मांड सिर्फ तुम्हारे लिए बनाया है। प्रत्येक नए जीवन के साथ तुम बड़े होते हो और परिपक्व होते हो और एक बड़ी और महान बुद्धि बन जाते हो। &quot;&lt;/p&gt;
&lt;p&gt;&quot;सिर्फ मैं? बाकी सब के बारे में क्या? ”&lt;/p&gt;
&lt;p&gt;&quot;कोई और नहीं है&quot;, मैंने कहा। &quot;इस ब्रह्मांड में, सिर्फ तुम और मैं हैं।&quot;&lt;/p&gt;
&lt;p&gt;तुमने मुझे घूर कर देखा। &quot;लेकिन पृथ्वी पर सभी लोग ...&quot;&lt;/p&gt;
&lt;p&gt;“सब तुम। तुम्हारे विभिन्न अवतार”&lt;/p&gt;
&lt;p&gt;&quot;रुकिए। मैं सब हूँ! &quot;&lt;/p&gt;
&lt;p&gt;&quot;अब तुम इसे समझ रहे हो&quot;, मैंने पीठ पर एक बधाई वाली थपकी के साथ कहा।&lt;/p&gt;
&lt;p&gt;&quot;मैं हर वह इंसान हूँ जो कभी रहता था?&quot;&lt;/p&gt;
&lt;p&gt;&quot;या जो कभी जीएगा, हाँ।&quot;&lt;/p&gt;
&lt;p&gt;&quot;मैं महात्मा गाँधी हूँ?&quot;&lt;/p&gt;
&lt;p&gt;&quot;और नाथूराम गोडसे भी&quot;, मैंने कहा।&lt;/p&gt;
&lt;p&gt;&quot;मैं हिटलर हूं?&quot;&lt;/p&gt;
&lt;p&gt;&quot;और उसके मारे गए लाखों लोग भी हो।&quot;&lt;/p&gt;
&lt;p&gt;&quot;मैं यीशु हूँ!&quot;&lt;/p&gt;
&lt;p&gt;&quot;और तुम उसके पीछे चलने वाले सभी लोग भी हो।&quot;&lt;/p&gt;
&lt;p&gt;तुम चुप हो गए।&lt;/p&gt;
&lt;p&gt;&quot;हर बार जब तुम किसी को पीड़ित करते थे&quot;, मैंने कहा, &quot;तुम खुद को पीड़ित कर रहे थे।&quot; तुम्हारे द्वारा किया गया दया का हर कार्य, आपने स्वयं से किया गया है। किसी भी इंसान द्वारा अनुभव किए गए हर खुश और दुख की घड़ी, तुम्हारे द्वारा अनुभव की जाएगी।”&lt;/p&gt;
&lt;p&gt;तुमने लंबे समय तक सोचा।&lt;/p&gt;
&lt;p&gt;&quot;क्यों?&quot; तुमने मुझसे पूछा। &quot;यह सब क्यों?&quot;&lt;/p&gt;
&lt;p&gt;&quot;क्योंकि किसी दिन, तुम मेरी तरह बन जाओगे। क्योंकि यही तुम्हारी सच्चाई है, तुम मेरी तरह हो। तुम मेरे बच्चे हो&quot;&lt;/p&gt;
&lt;p&gt;&quot;क्...क्या&quot;, तुमने अविश्वसनीयता के साथ कहा। &quot;आपका मतलब है, कि मैं भगवान हूँ?&quot;&lt;/p&gt;
&lt;p&gt;&quot;नहीं। अभी नहीं। अभी तुम एक भ्रूण हो, तुम अभी भी बढ़ रहे हो एक बार जब तुम, हर समय में, हर जीवन जी लोगे, तब तुम पैदा होने के लिए तैयार हो गए होगे। ”&lt;/p&gt;
&lt;p&gt;&quot;तो पूरा ब्रह्मांड&quot;, तुमने कहा, &quot;एक ...&quot;&lt;/p&gt;
&lt;p&gt;&quot;एक अंडा है।&quot; मैंने जवाब दिया। &quot;अब तुम्हारे अगले जीवन के लिए आगे बढ़ने का समय आ गया है।&quot;&lt;/p&gt;
&lt;p&gt;और मैंने तुम्हें अपने रास्ते पर भेज दिया।&lt;/p&gt;
</content:encoded><author>Andy Weir</author></item><item><title>5 Classy-ish French Insults</title><link>https://theleakycauldronblog.com/articles/classy-french-insults</link><guid isPermaLink="true">https://theleakycauldronblog.com/articles/classy-french-insults</guid><description>&lt;img alt=&quot;5 Classy-ish French Insults&quot; src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Fmarkus-clemens-classy-french-insult.DPZvz6Ag.jpg&amp;w=6000&amp;h=4000&amp;dpl=699bfef0c4120e00087ee35a&quot; /&gt; Learn few of the most classy french insults, and sound like a true Gentleman.</description><pubDate>Sun, 01 Sep 2019 12:30:00 GMT</pubDate><content:encoded>&lt;p&gt;The lockdown due to the pandemic has been rough. Everyone’s trying to find a productive hobby to make the most of it. And me being no different, tried to learn &lt;em&gt;Le Français&lt;/em&gt;. While learning a language is rewarding in itself, it gets a bit tedious after a while. After a while, you start understanding that the bookish language you learn is mostly useless IRL conversations. To my immense surprise, I learnt that the native speakers don’t exactly use &lt;em&gt;“J’ai une baguette et un croissant”&lt;/em&gt;, all that much.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Pardon my French.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So, I decided that I need to change my strategy and learn some actually useful lines. And where better to start than from insults. Here are some of my favourite, classy-ish french insults that I found most interesting.&lt;/p&gt;
&lt;h2&gt;Et mon cul, c&apos;est du poulet?&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Literally - And is my ass made of chicken?!&lt;/strong&gt; This hilarious line isn’t really an insult per se, instead used as a sarcastic retort when someone is trying to bullshit you.&lt;/p&gt;
&lt;h2&gt;Si les cons volaient, tu serais chef d&apos;escadrille&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Literally - If the idiots flew, you would be a squadron leader!&lt;/strong&gt; Now, this is a proper insult, grand and extravagant, just what you expect from the French. It’s used to call someone - The Idiot-in-Charge.&lt;/p&gt;
&lt;h2&gt;Va te faire cuire un oeuf&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Literally - Go make yourself an egg!&lt;/strong&gt; When a French person tells you to go make yourself an egg, it means they are annoyed at you. It’s the French way to say &lt;em&gt;Fuck Off&lt;/em&gt; or &lt;em&gt;Sod Off&lt;/em&gt;! The origin of this is said to be the old common domestic argument - &lt;em&gt;‘When a husband would criticise his wife’s cooking, she’d ask him to cook himself.’&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;Intellectuellement, il vit au dessus de ses moyens&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Literally - Intellectually, he lives beyond his means.&lt;/strong&gt; Popularly used by famous Haitian-Canadian novelist and journalist &lt;a href=&quot;https://en.wikipedia.org/wiki/Dany_Laferri%C3%A8re&quot;&gt;Danny Laferrière&lt;/a&gt;. This is a perfect insult for someone exhibiting &lt;a href=&quot;https://en.wikipedia.org/wiki/Dunning%E2%80%93Kruger_effect&quot;&gt;The Dunning-Kruger Effect&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Il a été bercé trop près du mur&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Literally - He was rocked too close to the wall.&lt;/strong&gt; This hilarious insult is my personal favourite. It’s used to subtly imply that one has mental damage due to being accidentally rocked against a wall when they were an infant. The subtlety of this insult is what makes this so funny. I literally laughed for 5 minutes straight when I first read it.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Which one was your favourite, do you have any that I missed? Do let me know in the comments below.&lt;/em&gt;&lt;/p&gt;
</content:encoded><author>Vaibhav Sharma</author></item><item><title>Fit Bounds of a Polyline and Marker with react-google-maps</title><link>https://theleakycauldronblog.com/articles/fit-bounds-of-a-polyline-and-marker-with-react-google-maps</link><guid isPermaLink="true">https://theleakycauldronblog.com/articles/fit-bounds-of-a-polyline-and-marker-with-react-google-maps</guid><description>&lt;img alt=&quot;Fit Bounds of a Polyline and Marker with react-google-maps&quot; src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Freact-google-maps.KtyqFKv6.jpg&amp;w=1280&amp;h=853&amp;dpl=699bfef0c4120e00087ee35a&quot; /&gt; Use React Google Maps and fit bounds &amp; zoom of a Polyline and Marker together for a better UI experience.</description><pubDate>Tue, 16 Jul 2019 12:30:00 GMT</pubDate><content:encoded>&lt;p&gt;When we started working on a Live Flight Tracker for my company, we chose to use &lt;a href=&quot;https://github.com/tomchentw/react-google-maps&quot;&gt;react-google-maps&lt;/a&gt; as our library. Since it&apos;s the most popular one, with over 4K stars on Github. I did have some experience with it but that was nowhere enough for the problem I was about to face. Especially, with very inadequate documentation and not enough examples showing the usage of the library.&lt;/p&gt;
&lt;p&gt;What we were trying to accomplish was to trace the flight path, and show the current position of the said flight. In theory, the first part was simple enough to do with a simple &lt;code&gt;Polyline&lt;/code&gt;, so was the second part with a simple &lt;code&gt;Marker&lt;/code&gt;. But there was a third part to it — to display both, the Polyline &amp;amp; the Marker in the same bounding box of the visible map with an appropriate amount of zoom. This should have been easy as well given that we knew that there&apos;s a helper function provided by Google Maps that helps us calculate bounding box. But implementing it in the context of &lt;code&gt;react-google-maps&lt;/code&gt; wasn&apos;t as simple due to lack of examples online. So, after I was done, I decided to save &quot;noobs&quot; like me from the trouble I faced.&lt;/p&gt;
&lt;h2&gt;Writing the Map Component&lt;/h2&gt;
&lt;p&gt;First, we begin by making the Map Component that will display our Polyline &amp;amp; Marker, which is simple enough, but let me show anyways so that we are on the same page.&lt;/p&gt;
&lt;p&gt;We begin by initializing our Google Maps in our Component which is wrapped in &lt;code&gt;withScriptjs&lt;/code&gt; &amp;amp; &lt;code&gt;withGoogleMap&lt;/code&gt; HOCs.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import React, { Component } from &apos;react&apos;
import { withScriptjs, withGoogleMap, GoogleMap, Polyline, Marker } from &apos;react-google-maps&apos;

export const CustomMapComponent: React.ComponentClass&amp;lt;any&amp;gt; = withScriptjs(withGoogleMap((props) =&amp;gt;
  &amp;lt;GoogleMap
    defaultCenter={props.defaultCenter}
    defaultZoom={3}
    options={{
      streetViewControl: false,
      mapTypeId: &apos;satellite&apos;,
    }}
  &amp;gt;

  &amp;lt;/GoogleMap&amp;gt;
))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then we add Polyline that will trace the flight path. We pass an array of &lt;code&gt;lat&lt;/code&gt; &amp;amp; &lt;code&gt;lng&lt;/code&gt; to the path prop.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;...

  &amp;lt;GoogleMap
    defaultCenter={props.defaultCenter}
    defaultZoom={3}
    options={{
      streetViewControl: false,
      mapTypeId: &apos;satellite&apos;,
    }}
  &amp;gt;
    &amp;lt;Polyline
      path={props.path}
      options={{
        geodesic: true,
        strokeColor: &apos;#669DF6&apos;,
        strokeOpacity: 1.0,
        strokeWeight: 2,
      }}
    /&amp;gt;
  &amp;lt;/GoogleMap&amp;gt;

...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, we add Marker to show the current position of our aircraft. We pass the current position object made up of &lt;code&gt;lat&lt;/code&gt; &amp;amp; &lt;code&gt;lng&lt;/code&gt; to it, which in our case is just the last position in our path array.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;...

  &amp;lt;GoogleMap
    defaultCenter={props.defaultCenter}
    defaultZoom={3}
    options={{
      streetViewControl: false,
      mapTypeId: &apos;satellite&apos;,
    }}
  &amp;gt;
    &amp;lt;Polyline
      path={props.path}
      options={{
        geodesic: true,
        strokeColor: &apos;#669DF6&apos;,
        strokeOpacity: 1.0,
        strokeWeight: 2,
      }}
    /&amp;gt;
    &amp;lt;Marker
      position={props.currentPosition}
      defaultIcon={
        { url: &apos;/static/images/flight-marker.png&apos;, scaledSize: { height: 16, width: 16 }, anchor: new google.maps.Point(8, 8) }}
    /&amp;gt;
  &amp;lt;/GoogleMap&amp;gt;

...
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Using the Map Component&lt;/h2&gt;
&lt;p&gt;Using it is simple enough just import the above component, pass it the required props one of them being your Google Maps API key URL.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;class FlightPathTracker Component&amp;lt;any, any&amp;gt; {
  componentDidMount(): void {
    ...
  }

  render() {
    const {path, defaultCenter, currentPosition} = this.props
    return(
          &amp;lt;CustomMapComponent
            {/* add all the other required props */}
            ...
            {/* add all the other required props */}
            googleMapURL={`https://maps.googleapis.com/maps/api/js?key=${process.env.GOOGLE_MAP_API_KEY}`}
            defaultCenter={defaultCenter}
            path={path}
            currentPosition={currentPosition}
          /&amp;gt;
    )
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Just go ahead and run it and check to see if everything is working. You&apos;ll see that when the map mounts the viewport zooms and fits the Marker as the default. But our objective is to fit the Marker as well as the Polyline.&lt;/p&gt;
&lt;h2&gt;Setting the Bounding Box for both Polyline &amp;amp; Marker&lt;/h2&gt;
&lt;p&gt;Now comes the tricky part, to set bounds we first let the map we created above mount, then we get a &lt;code&gt;ref&lt;/code&gt; from our map component, we pass it to a mounted map handler method, where we set the bounds. We begin by adding the handler function as a prop to the &lt;code&gt;ref&lt;/code&gt; of our map component.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;...

  &amp;lt;GoogleMap
    defaultCenter={props.defaultCenter}
    defaultZoom={3}
    options={{
      streetViewControl: false,
      mapTypeId: &apos;satellite&apos;,
    }}
    ref={props.onMapMounted}
  &amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, we write the &lt;code&gt;handleMapMounted&lt;/code&gt; method, where we first initialize Google&apos;s &lt;code&gt;LatLngBounds()&lt;/code&gt; object. Then we for each position in the path array we extend that object. And, finally, we pass that object to our map.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;...

class FlightPathTracker Component&amp;lt;any, any&amp;gt; {
  ...

  handleMapMounted = (map) =&amp;gt; {
    const { path } = this.props
    
    this._map = map
    if (map) {
      const bounds = new google.maps.LatLngBounds()

      path.map(position =&amp;gt; {
        bounds.extend(position)
      })
      
      this._map.fitBounds(bounds)
   
    }
  }

...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally, we pass this method to the &lt;code&gt;CustomMapComponent&lt;/code&gt; as a prop and voila.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;...

          &amp;lt;CustomMapComponent
            {/* add all the other required props */}
            ...
            {/* add all the other required props */}
            googleMapURL={`https://maps.googleapis.com/maps/api/js?key=${process.env.GOOGLE_MAP_API_KEY}`}
            defaultCenter={defaultCenter}
            path={path}
            currentPosition={currentPosition}
            onMapMounted={this.handleMapMounted}
          /&amp;gt;

...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now run your app to see if everything is working and we are done.&lt;/p&gt;
</content:encoded><author>Vaibhav Sharma</author></item><item><title>Formik and Yup with Netlify Forms for React Apps</title><link>https://theleakycauldronblog.com/articles/formik-and-yup-with-netlify-forms-for-react-apps</link><guid isPermaLink="true">https://theleakycauldronblog.com/articles/formik-and-yup-with-netlify-forms-for-react-apps</guid><description>&lt;img alt=&quot;Formik and Yup with Netlify Forms for React Apps&quot; src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Fformik-netlify-forms-react-yup.BIU1swXp.jpg&amp;w=4032&amp;h=2688&amp;dpl=699bfef0c4120e00087ee35a&quot; /&gt; Use Formik and Yup to make robust forms in conjunction with Netlify Forms. Best part, no backend required! With a generous 100 submissions per month, it&apos;s more than enough for most hobby websites.</description><pubDate>Sun, 16 Jun 2019 12:30:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;https://www.netlify.com/docs/form-handling/&quot;&gt;Netlify Forms&lt;/a&gt; is yet another amazing service provided by &lt;a href=&quot;https://www.netlify.com/&quot;&gt;Netlify&lt;/a&gt; with a generous free tier. For those who don&apos;t know, it allows you to set up a form and take submissions without needing a backend. The form data is not only stored in your dashboard, but you can also directly get a notification on any email address! Sounds interesting right?! As we start implementing you&apos;ll find out just how easy it is to set up if you know basics of React. Although I should mention it&apos;s not just a React only feature, you can set it up with basic HTML as well!&lt;/p&gt;
&lt;h2&gt;Setting Up Formik Form&lt;/h2&gt;
&lt;p&gt;We&apos;re gonna first install &lt;a href=&quot;https://jaredpalmer.com/formik/&quot;&gt;Formik&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;yarn add formik
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then we create a Function Component called &lt;code&gt;ContactForm.js&lt;/code&gt;, in it, we&apos;ll begin by setting up &lt;a href=&quot;https://jaredpalmer.com/formik/&quot;&gt;Formik&lt;/a&gt; and it&apos;s required props - initialValues, onSubmit &amp;amp; render).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ContactForm.js:&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import React from &apos;react&apos;
import { Formik, Field } from &apos;formik&apos;

const ContactForm = () =&amp;gt; {
  return (
    &amp;lt;Formik
      initialValues={{ name: &apos;&apos;, email: &apos;&apos;, message: &apos;&apos; }}
      onSubmit={values =&amp;gt; console.log(values)}
      render={({
        isSubmitting,
        handleSubmit,
        handleReset,
      }) =&amp;gt; (
        &amp;lt;form className=&apos;form&apos;
          name=&apos;contact&apos;
          onSubmit={handleSubmit}
          onReset={handleReset}
          data-netlify=&apos;true&apos;
          data-netlify-honeypot=&apos;bot-field&apos;
        &amp;gt;
          &amp;lt;div className=&apos;field&apos;&amp;gt;
            &amp;lt;label htmlFor=&apos;name&apos; className=&apos;label&apos;&amp;gt;Name&amp;lt;/label&amp;gt;
            &amp;lt;Field
              className=&apos;input&apos;
              type=&apos;text&apos;
              name=&apos;name&apos;
            /&amp;gt;
          &amp;lt;/div&amp;gt;
          &amp;lt;div className=&apos;field&apos;&amp;gt;
            &amp;lt;label htmlFor=&apos;email&apos; className=&apos;label&apos;&amp;gt;Email&amp;lt;/label&amp;gt;
            &amp;lt;Field
              className=&apos;input&apos;
              type=&apos;text&apos;
              name=&apos;email&apos;
            /&amp;gt;
          &amp;lt;/div&amp;gt;
          &amp;lt;div className=&apos;field&apos;&amp;gt;
            &amp;lt;label htmlFor=&apos;message&apos; className=&apos;label&apos;&amp;gt;Message&amp;lt;/label&amp;gt;
            &amp;lt;Field
              className=&apos;input-textarea&apos;
              name=&apos;message&apos;
              component=&apos;textarea&apos;
              rows=&apos;6&apos;
            /&amp;gt;
          &amp;lt;/div&amp;gt;
          &amp;lt;div className=&apos;buttons&apos;&amp;gt;
            &amp;lt;input type=&apos;reset&apos; value=&apos;Clear&apos;
              className=&apos;button&apos; /&amp;gt;
            &amp;lt;input name=&apos;submit&apos; type=&apos;submit&apos; disabled={isSubmitting} value=&apos;Send Message&apos;
              className=&apos;button&apos; /&amp;gt;
          &amp;lt;/div&amp;gt;
        &amp;lt;/form&amp;gt;
      )}
    /&amp;gt;
  )
}

export default ContactForm
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You might&apos;ve noticed that we have also added a flag for Send Message Button to be disabled while submitting. This is to prevent unwanted behaviour.&lt;/p&gt;
&lt;p&gt;This is a basic Contact form with fields for Name, Email &amp;amp; Message. Next, we set up validation using Yup.&lt;/p&gt;
&lt;h2&gt;Creating a Validation Schema for Contact Form&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/jquense/yup&quot;&gt;Yup&lt;/a&gt; is a form validation library and has tight integration with &lt;a href=&quot;https://jaredpalmer.com/formik/&quot;&gt;Formik&lt;/a&gt;. &lt;a href=&quot;https://github.com/jquense/yup&quot;&gt;Yup&lt;/a&gt; helps us define schema like &lt;a href=&quot;https://github.com/hapijs/joi&quot;&gt;Joi&lt;/a&gt; and validate against it. Add it to your project:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;yarn add yup
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Create a file called validationSchema.js and create a schema as shown below:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;validationSchema.js:&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import * as Yup from &apos;yup&apos;

const validationSchema = Yup.object().shape({
  name: Yup.string()
    .min(2, &apos;Too Short!&apos;)
    .max(50, &apos;Too Long!&apos;)
    .required(&apos;Name is Required!&apos;),
  email: Yup.string()
    .email(&apos;Enter a Valid Email!&apos;)
    .required(&apos;Email is Required!&apos;),
  message: Yup.string()
    .required(&apos;Message is Required!&apos;),
})

export default validationSchema
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Import the above file and add it to formik&apos;s &lt;code&gt;validationSchema&lt;/code&gt; prop.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ContactForm.js:&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import React from &apos;react&apos;
import { Formik, Field } from &apos;formik&apos;
import validationSchema from &apos;./validationSchema&apos;

const ContactForm = () =&amp;gt; {
  return (
    &amp;lt;Formik
      initialValues={{ name: &apos;&apos;, email: &apos;&apos;, message: &apos;&apos; }}
      validationSchema={validationSchema}
      onSubmit={values =&amp;gt; console.log(values)}
    ...
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Writing form On Submit method&lt;/h2&gt;
&lt;p&gt;In on Submit function of &lt;a href=&quot;https://jaredpalmer.com/formik/&quot;&gt;Formik&lt;/a&gt; Component, we&apos;ll replace &lt;code&gt;console.log&lt;/code&gt; with a &lt;code&gt;application/x-www-form-urlencoded&lt;/code&gt; fetch request. But before we do that we need to make an uri component encoder (you can use third-party library if you like).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ContactForm.js:&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;...
import validationSchema from &apos;./validationSchema&apos;

const encode = (data) =&amp;gt; {
  return Object.keys(data)
    .map(key =&amp;gt; encodeURIComponent(key) + &apos;=&apos; + encodeURIComponent(data[key]))
    .join(&apos;&amp;amp;&apos;)
}

const ContactForm = () =&amp;gt; {
...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now we write the onSubmit method, the fetch request has to be made to home path ie &lt;code&gt;/&lt;/code&gt;. We also called setSubmitting method, which will be used to change the state of isSubmitting flag.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ContactForm.js:&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;...
onSubmit={(values, { setSubmitting }) =&amp;gt; {
        fetch(&quot;/&quot;, {                                 
          method: &apos;POST&apos;,
          headers: { &apos;Content-Type&apos;: &apos;application/x-www-form-urlencoded&apos; },
          body: encode({
            &apos;form-name&apos;: &apos;contact&apos;,
            ...values,
          }),
        })
          .then(() =&amp;gt; {
            alert(&apos;Success!&apos;)
            setSubmitting(false)
          })
          .catch(error =&amp;gt; {
            alert(&apos;Error: Please Try Again!&apos;)                            
            setSubmitting(false)
          })
      }}
...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you are using Gatsby JS, especially &lt;code&gt;gatsby-plugin-offline&lt;/code&gt; then you&apos;ll need to add &lt;code&gt;?no-cache=1&lt;/code&gt; along with &lt;code&gt;/&lt;/code&gt; or it won&apos;t work.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ContactForm.js:&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;...
fetch(&quot;/?no-cache=1&quot;, {   
...
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Displaying Validation Errors to User&lt;/h2&gt;
&lt;p&gt;To display the validation errors we need to use two params from &lt;code&gt;render&lt;/code&gt; method &lt;code&gt;touched&lt;/code&gt; &amp;amp; &lt;code&gt;errors&lt;/code&gt;. &lt;code&gt;touched&lt;/code&gt; object tells us if the user has touched the field, and &lt;code&gt;errors&lt;/code&gt; object tell us the errors. We are gonna display the errors if the user has touched the field and there&apos;s an error for that field.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ContactForm.js:&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;...
      render={({
        touched,
        errors,
        isSubmitting,
        handleSubmit,
        handleReset,
      }) =&amp;gt; (
        &amp;lt;form className=&apos;form&apos;
          name=&apos;contact&apos;
          onSubmit={handleSubmit}
          onReset={handleReset}
          data-netlify=&apos;true&apos;
          data-netlify-honeypot=&apos;bot-field&apos;
        &amp;gt;
          &amp;lt;div className=&apos;field&apos;&amp;gt;
            &amp;lt;label htmlFor=&apos;name&apos; className=&apos;label&apos;&amp;gt;Name&amp;lt;/label&amp;gt;
            &amp;lt;Field
              className=&apos;input&apos;
              type=&apos;text&apos;
              name=&apos;name&apos;
            /&amp;gt;
           {touched.name &amp;amp;&amp;amp; errors.name &amp;amp;&amp;amp; &amp;lt;p className=&apos;danger&apos;&amp;gt;{errors.name}&amp;lt;/p&amp;gt;}
          &amp;lt;/div&amp;gt;
          &amp;lt;div className=&apos;field&apos;&amp;gt;
            &amp;lt;label htmlFor=&apos;email&apos; className=&apos;label&apos;&amp;gt;Email&amp;lt;/label&amp;gt;
            &amp;lt;Field
              className=&apos;input&apos;
              type=&apos;text&apos;
              name=&apos;email&apos;
            /&amp;gt;
           {touched.email &amp;amp;&amp;amp; errors.email &amp;amp;&amp;amp; &amp;lt;p className=&apos;danger&apos;&amp;gt;{errors.email}&amp;lt;/p&amp;gt;}
          &amp;lt;/div&amp;gt;
          &amp;lt;div className=&apos;field&apos;&amp;gt;
            &amp;lt;label htmlFor=&apos;message&apos; className=&apos;label&apos;&amp;gt;Message&amp;lt;/label&amp;gt;
            &amp;lt;Field
              className=&apos;input-textarea&apos;
              name=&apos;message&apos;
              component=&apos;textarea&apos;
              rows=&apos;6&apos;
            /&amp;gt;
           {touched.message &amp;amp;&amp;amp; errors.message &amp;amp;&amp;amp; &amp;lt;p className=&apos;danger&apos;&amp;gt;{errors.message}&amp;lt;/p&amp;gt;}
          &amp;lt;/div&amp;gt;
          &amp;lt;div className=&apos;buttons&apos;&amp;gt;
            &amp;lt;input type=&apos;reset&apos; value=&apos;Clear&apos;
              className=&apos;button&apos; /&amp;gt;
            &amp;lt;input name=&apos;submit&apos; type=&apos;submit&apos; disabled={isSubmitting} value=&apos;Send Message&apos;
              className=&apos;button&apos; /&amp;gt;
          &amp;lt;/div&amp;gt;
        &amp;lt;/form&amp;gt;
      )}
    /&amp;gt;
...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And with this, we are finally done. Now according to our validation Schema:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&apos;Name&apos;, &apos;Email&apos; &amp;amp; &apos;Message&apos; are required fields.&lt;/li&gt;
&lt;li&gt;&apos;Name&apos; should be minimum 2 characters and maximum 50 characters.&lt;/li&gt;
&lt;li&gt;&apos;Email&apos; field should have a valid email.&lt;/li&gt;
&lt;li&gt;And &apos;Message&apos; field cannot be empty.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I hope this helps you, happy coding.&lt;/p&gt;
</content:encoded><author>Vaibhav Sharma</author></item><item><title>Creamy MushRome Mushroom Recipe</title><link>https://theleakycauldronblog.com/articles/creamy-mushrome-mushroom-recipe</link><guid isPermaLink="true">https://theleakycauldronblog.com/articles/creamy-mushrome-mushroom-recipe</guid><description>&lt;img alt=&quot;Creamy MushRome Mushroom Recipe&quot; src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Fmushrome.DcNifO-a.jpg&amp;w=4608&amp;h=2592&amp;dpl=699bfef0c4120e00087ee35a&quot; /&gt; Taste the creamy mildly spicy deliciousness of this mushroom recipe, that cooks fast and leaves you craving for more.</description><pubDate>Sat, 23 Mar 2019 12:30:00 GMT</pubDate><content:encoded>&lt;p&gt;This dish is something of my experiment, but extremely tasty. Best enjoyed with &lt;strong&gt;Garlic Naan&lt;/strong&gt; or &lt;strong&gt;Rice&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;Ingredients&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;250g Button Mushrooms&lt;/li&gt;
&lt;li&gt;4 Green Chillies&lt;/li&gt;
&lt;li&gt;1 Red Bell Pepper / Capsicum&lt;/li&gt;
&lt;li&gt;1 Green Bell Pepper / Capsicum&lt;/li&gt;
&lt;li&gt;1 Yellow Bell Pepper / Capsicum&lt;/li&gt;
&lt;li&gt;2 Medium Sized Onions&lt;/li&gt;
&lt;li&gt;Butter&lt;/li&gt;
&lt;li&gt;Cream&lt;/li&gt;
&lt;li&gt;Garlic Paste&lt;/li&gt;
&lt;li&gt;Oregano-Garlic Powder Mix&lt;/li&gt;
&lt;li&gt;Red Chilli Sauce&lt;/li&gt;
&lt;li&gt;Cardamom Powder&lt;/li&gt;
&lt;li&gt;Garam Masala&lt;/li&gt;
&lt;li&gt;Salt&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Preparation&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Chop mushrooms in quarters&lt;/li&gt;
&lt;li&gt;Finely chop 2 green chillies And Slit other 2 in half for garnishing&lt;/li&gt;
&lt;li&gt;Cut thin slices of Bell Peppers&lt;/li&gt;
&lt;li&gt;Slice onions in a ring shape&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Cooking Steps&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Melt butter in a non-stick pan, add garlic paste, chopped green chillies, onions and bell peppers. Saute them till onions turn pink&lt;/li&gt;
&lt;li&gt;Add mushrooms and cook them till they turn golden brown&lt;/li&gt;
&lt;li&gt;Sprinkle garam masala, oregano-garlic powder liberally and add a pinch of cardamom powder to enhance fragrance of our dish&lt;/li&gt;
&lt;li&gt;Add 2 Spoons of red chilli sauce, enough to coat all the mushrooms&lt;/li&gt;
&lt;li&gt;Pour 4-5 tablespoons of cream and keep stirring to mix everything well&lt;/li&gt;
&lt;li&gt;Cook for 15-20 mins, make sure to keep stirring, and that&apos;s it.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;TIP&lt;/strong&gt;: Add Bhuna-Masala in step one to make it even spicier, if it wasn&apos;t enough kick for you!&lt;/p&gt;
</content:encoded><author>Vaibhav Sharma</author></item><item><title>Setting up i18n with TypeScript in Next JS Project</title><link>https://theleakycauldronblog.com/articles/setting-up-i18n-with-typescript-in-next-js-project</link><guid isPermaLink="true">https://theleakycauldronblog.com/articles/setting-up-i18n-with-typescript-in-next-js-project</guid><description>&lt;img alt=&quot;Setting up i18n with TypeScript in Next JS Project&quot; src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Fi18n-typescript-nextjs.itGMyVYI.jpg&amp;w=6000&amp;h=4000&amp;dpl=699bfef0c4120e00087ee35a&quot; /&gt; Leverage the power of TypeScript with Next JS and make your project i18n ready. Use the plugin next-i18next with your TypeScript Next JS project.</description><pubDate>Sun, 10 Mar 2019 12:30:00 GMT</pubDate><content:encoded>&lt;p&gt;As I was starting a new &lt;a href=&quot;https://nextjs.org&quot;&gt;NextJS&lt;/a&gt; project, I planned to do it in &lt;a href=&quot;https://www.typescriptlang.org&quot;&gt;TypeScript&lt;/a&gt;. Since I don&apos;t know TypeScript, my initial plan was to learn as I go. Comes the time I had to set up i18n using &lt;a href=&quot;https://github.com/isaachinman/next-i18next&quot;&gt;&lt;code&gt;next-i18next&lt;/code&gt;&lt;/a&gt; plugin, and it was a bit problematic as there was no example for it on the official &lt;a href=&quot;https://github.com/isaachinman/next-i18next&quot;&gt;&lt;code&gt;next-i18next&lt;/code&gt;&lt;/a&gt; repository. After I successfully learnt how to do it, I did make a PR for typescript example on the original repo but this is in case it doesn&apos;t get accepted.&lt;/p&gt;
&lt;p&gt;Setting up &lt;a href=&quot;https://github.com/isaachinman/next-i18next&quot;&gt;next-i18next&lt;/a&gt; in a TS Next app, has 3 parts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Setting Up TypeScript Next App&lt;/li&gt;
&lt;li&gt;Adding Custom Server&lt;/li&gt;
&lt;li&gt;Implementing &lt;code&gt;next-i18next&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Today we&apos;ll set up a simple Next app which will have two pages and an option to change the language.&lt;/p&gt;
&lt;h2&gt;Setting Up TypeScript Next App&lt;/h2&gt;
&lt;p&gt;We&apos;ll start from a blank folder simple-typescript-i18n which we initialise with&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;yarn init
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then we add the following dependencies&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;yarn add @zeit/next-typescript next react react-dom
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;we&apos;ll also need some dev dependencies, let&apos;s add them&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;yarn add @types/next @types/react @types/react-dom typescript --dev
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now we add our two pages&lt;/p&gt;
&lt;p&gt;&lt;code&gt;pages/index.tsx&lt;/code&gt; :&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import React from &apos;react&apos;
import Link from &apos;next/link&apos;

const HomePage: React.FunctionComponent&amp;lt;any&amp;gt; = () =&amp;gt; (
    &amp;lt;div&amp;gt;
        &amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;
        &amp;lt;Link href=&apos;/second-page&apos;&amp;gt;&amp;lt;button type=&apos;button&apos;&amp;gt;Goto Second Page&amp;lt;/button&amp;gt;&amp;lt;/Link&amp;gt;
    &amp;lt;div&amp;gt;
)

export default HomePage
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and&lt;/p&gt;
&lt;p&gt;&lt;code&gt;pages/second-page.tsx&lt;/code&gt; :&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import React from &apos;react&apos;
import Link from &apos;next/link&apos;

const SecondPage: React.FunctionComponent&amp;lt;any&amp;gt; = () =&amp;gt; (
    &amp;lt;div&amp;gt;
        &amp;lt;h1&amp;gt;Welcome To Second Page&amp;lt;/h1&amp;gt;
        &amp;lt;Link href=&apos;/&apos;&amp;gt;&amp;lt;button type=&apos;button&apos;&amp;gt;Go Back&amp;lt;/button&amp;gt;&amp;lt;/Link&amp;gt;
    &amp;lt;/div&amp;gt;
)

export default SecondPage
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then we create the following files in the root folder&lt;/p&gt;
&lt;p&gt;&lt;code&gt;.babelrc&lt;/code&gt; :&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;presets&quot;: [
    &quot;next/babel&quot;,
    &quot;@zeit/next-typescript/babel&quot;
  ]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;next.config.js&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const withTypescript = require(&apos;@zeit/next-typescript&apos;)

module.exports = withTypescript()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;tsconfig.json&lt;/code&gt; :&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;compileOnSave&quot;: false,
  &quot;compilerOptions&quot;: {
    &quot;target&quot;: &quot;esnext&quot;,
    &quot;module&quot;: &quot;esnext&quot;,
    &quot;jsx&quot;: &quot;preserve&quot;,
    &quot;allowJs&quot;: true,
    &quot;moduleResolution&quot;: &quot;node&quot;,
    &quot;allowSyntheticDefaultImports&quot;: true,
    &quot;noUnusedLocals&quot;: true,
    &quot;noUnusedParameters&quot;: true,
    &quot;removeComments&quot;: false,
    &quot;preserveConstEnums&quot;: true,
    &quot;sourceMap&quot;: true,
    &quot;skipLibCheck&quot;: true,
    &quot;baseUrl&quot;: &quot;.&quot;,
    &quot;typeRoots&quot;: [
      &quot;./node_modules/@types&quot;
    ],
    &quot;lib&quot;: [
      &quot;dom&quot;,
      &quot;es2015&quot;,
      &quot;es2016&quot;
    ]
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;to begin our project all we need to do is set up scripts in &lt;code&gt;package.json&lt;/code&gt;, add the following lines to your &lt;code&gt;package.json&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;scripts&quot;: {
    &quot;dev&quot;: &quot;next&quot;,
    &quot;build&quot;: &quot;next build&quot;,
    &quot;start&quot;: &quot;next start&quot;,
    &quot;type-check&quot;: &quot;tsc&quot;
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Go ahead and give it a run to check if everything is okay&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;yarn dev
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;visit &lt;a href=&quot;http://localhost:3000&quot;&gt;http://localhost:3000&lt;/a&gt; from your browser.&lt;/p&gt;
&lt;h2&gt;Adding Custom Server&lt;/h2&gt;
&lt;p&gt;To add next-i18next it&apos;s necessary to have a custom server running, for that we&apos;ll need to add the following package&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;yarn add express
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;yarn add nodemon ts-node --dev
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;after doing that we need to create our custom server, in the root directory create a folder called server, in that, create a file called &lt;code&gt;index.ts&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;server/index.ts&lt;/code&gt; :&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const express = require(&apos;express&apos;)
const next = require(&apos;next&apos;)

const port = process.env.PORT || 3000
const app = next({ dev: process.env.NODE_ENV !== &apos;production&apos; })
const handle = app.getRequestHandler();

(async () =&amp;gt; {
  await app.prepare()
  const server = express()

  // handle nextjs routing
  server.get(&apos;*&apos;, (req, res) =&amp;gt; handle(req, res))

  await server.listen(port)
  console.log(`🚀 Ready on http://localhost:${port}`) // eslint-disable-line no-console
})()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and then a &lt;code&gt;tsconfig.server.json&lt;/code&gt; file in the root directory&lt;/p&gt;
&lt;p&gt;&lt;code&gt;tsconfig.server.json&lt;/code&gt; :&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;extends&quot;: &quot;./tsconfig.json&quot;,
  &quot;compilerOptions&quot;: {
    &quot;module&quot;: &quot;commonjs&quot;,
    &quot;outDir&quot;: &quot;.build&quot;,
    &quot;target&quot;: &quot;es2017&quot;,
    &quot;lib&quot;: [
      &quot;es2017&quot;
    ]
  },
  &quot;include&quot;: [
    &quot;next.config.js&quot;,
    &quot;server/**/*.ts&quot;,
  ]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;now all we need to do some changes in our &lt;code&gt;npm&lt;/code&gt; scripts, refactor the following lines in &lt;code&gt;package.json&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&quot;scripts&quot;: {
    &quot;dev&quot;: &quot;nodemon --exec ts-node --project tsconfig.server.json server&quot;,
    &quot;build&quot;: &quot;next build &amp;amp;&amp;amp; tsc --project tsconfig.server.json&quot;,
    &quot;start&quot;: &quot;NODE_ENV=production node .build/server&quot;,
    &quot;type-check&quot;: &quot;tsc&quot;
  },
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;give it a spin, to see if everything is working all right.&lt;/p&gt;
&lt;h2&gt;Implementing next-i18next&lt;/h2&gt;
&lt;p&gt;All that&apos;s left now is to add i18next, to do that we begin by adding the following package&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;yarn add next-i18next
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, we add a file &lt;code&gt;i18n.ts&lt;/code&gt; to our root&lt;/p&gt;
&lt;p&gt;&lt;code&gt;i18n.ts&lt;/code&gt; :&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const NextI18Next = require(&apos;next-i18next/dist/commonjs&apos;).default

module.exports = new NextI18Next({
  defaultLanguage: &apos;en&apos;,
  otherLanguages: [&apos;hi&apos;],
  localeSubpaths: &apos;foreign&apos;, // locale subpaths for url could be none, foreign or all
})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;now we add the i18next middleware to our server as well i18n configuration&lt;/p&gt;
&lt;p&gt;&lt;code&gt;server/index.ts&lt;/code&gt; :&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const express = require(&apos;express&apos;)
const next = require(&apos;next&apos;)
const nextI18NextMiddleware = require(&apos;next-i18next/middleware&apos;)

const nextI18next = require(&apos;../i18n&apos;)

const port = process.env.PORT || 3000
const app = next({ dev: process.env.NODE_ENV !== &apos;production&apos; })
const handle = app.getRequestHandler();

(async () =&amp;gt; {
  await app.prepare()
  const server = express()

  // use the next-i18next middleware with our i18n configuration
  try {
    server.use(nextI18NextMiddleware(nextI18next))
  } catch (e) {
    throw (e)
  }

  // handle nextjs routing
  server.get(&apos;*&apos;, (req, res) =&amp;gt; handle(req, res))

  await server.listen(port)
  console.log(`🚀 Ready on http://localhost:${port}`) // eslint-disable-line no-console
})()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then, we add &lt;code&gt;appWithTranslation&lt;/code&gt; HOC to a custom &lt;code&gt;_app.tsx&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;pages/_app.tsx&lt;/code&gt; :&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import React from &apos;react&apos;
import App, { Container } from &apos;next/app&apos;
import { appWithTranslation } from &apos;../i18n&apos;

class MyApp extends App {
  render() {
    const { Component, pageProps } = this.props
    return (
      &amp;lt;Container&amp;gt;
        &amp;lt;Component {...pageProps} /&amp;gt;
      &amp;lt;/Container&amp;gt;
    )
  }
}

export default appWithTranslation(MyApp)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, we add some translations, to do that we need to create a folder called static in our root, then add a folder called locales in static then add folders named with language codes in locales and add common.json files to them. In our case, we&apos;ll be adding english as default and Hindi as the other language&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;.
├── pages
│   ├-- _app.tsx
│   ├-- index.tsx
│   └-- second-page.tsx
├── static
│   └-- locales
│       ├-- en
│       │   └-- common.json
│       └-- hi
│           └-- common.json
├-- server
│   └-- index.ts
├-- .babelrc
├-- i18n.ts
├-- next.config.js
├-- package.json
├-- tsconfig.json
├-- tsconfig.server.json
└── yarn.lock
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Add translations to &lt;code&gt;common.json&lt;/code&gt; files&lt;/p&gt;
&lt;p&gt;&lt;code&gt;static/locales/en/common.json&lt;/code&gt; :&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
    &quot;hello-world&quot;: &quot;Hello, World!&quot;,
    &quot;goto-second-page&quot;: &quot;Goto Second Page&quot;,
    &quot;change-language&quot;: &quot;Change Language&quot;,
    &quot;welcome&quot;: &quot;Welcome To Second Page&quot;,
    &quot;go-back&quot;: &quot;Go Back&quot;,
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;static/locales/hi/common.json&lt;/code&gt; :&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
    &quot;hello-world&quot;: &quot;नमस्ते, विश्व!&quot;,
    &quot;goto-second-page&quot;: &quot;दूसरे पेज पर जाएं&quot;,
    &quot;change-language&quot;: &quot;भाषा बदलें&quot;,
    &quot;welcome&quot;: &quot;दूसरे पेज पर आपका स्वागत है&quot;,
    &quot;go-back&quot;: &quot;वापस जाएं&quot;,
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;then we refactor our two pages to include translation HOC, namespaces, and translation function, also add a button to change the language.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;pages/index.tsx&lt;/code&gt; :&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import React from &apos;react&apos;
import { i18n, Link, withNamespaces } from &apos;../i18n&apos; // We replace next/link with the one provide by next-i18next, this helps with locale subpaths

const HomePage: React.FunctionComponent&amp;lt;any&amp;gt; = ({ t }) =&amp;gt; (
    &amp;lt;div&amp;gt;
        &amp;lt;h1&amp;gt;{t(&apos;hello-world&apos;)}&amp;lt;/h1&amp;gt;
        &amp;lt;button type=&apos;button&apos; onClick={() =&amp;gt; i18n.changeLanguage(i18n.language === &apos;en&apos; ? &apos;hi&apos; : &apos;en&apos;)}&amp;gt;{t(&apos;change-language&apos;)}&amp;lt;/button&amp;gt;
        &amp;lt;Link href=&apos;/second-page&apos;&amp;gt;&amp;lt;button type=&apos;button&apos;&amp;gt;{t(&apos;goto-second-page&apos;)}&amp;lt;/button&amp;gt;&amp;lt;/Link&amp;gt;
    &amp;lt;div&amp;gt;
)

HomePage.getInitialProps = () =&amp;gt; ({
  namespacesRequired: [&apos;common&apos;],
})

export default withNamespaces(&apos;common&apos;)(HomePage)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and&lt;/p&gt;
&lt;p&gt;&lt;code&gt;pages/second-page.tsx&lt;/code&gt; :&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import React from &apos;react&apos;
import { withNamespaces, Link } from &apos;../i18n&apos;

const SecondPage: React.FunctionComponent&amp;lt;any&amp;gt; = ({ t }) =&amp;gt; (
    &amp;lt;div&amp;gt;
        &amp;lt;h1&amp;gt;{t(&apos;welcome&apos;)}&amp;lt;/h1&amp;gt;
        &amp;lt;Link href=&apos;/&apos;&amp;gt;&amp;lt;button type=&apos;button&apos;&amp;gt;{t(&apos;go-back&apos;)}&amp;lt;/button&amp;gt;&amp;lt;/Link&amp;gt;
    &amp;lt;/div&amp;gt;
)

export default withNamespaces(&apos;common&apos;)(SecondPage)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;now all we have to do is make minor changes to our &lt;code&gt;tsconfig.server.json&lt;/code&gt; to include our i18n compiled file as it is in our build folder&lt;/p&gt;
&lt;p&gt;&lt;code&gt;tsconfig.server.json&lt;/code&gt; :&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;extends&quot;: &quot;./tsconfig.json&quot;,
  &quot;compilerOptions&quot;: {
    &quot;module&quot;: &quot;commonjs&quot;,
    &quot;outDir&quot;: &quot;.build&quot;,
    &quot;target&quot;: &quot;es2017&quot;,
    &quot;lib&quot;: [
      &quot;es2017&quot;
    ]
  },
  &quot;include&quot;: [
    &quot;i18n.ts&quot;,
    &quot;next.config.js&quot;,
    &quot;server/**/*.ts&quot;,
  ]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That&apos;s it we are done now you can go ahead and try to run, to see if everything is working.&lt;/p&gt;
&lt;p&gt;And that&apos;s how you set up &lt;a href=&quot;https://github.com/isaachinman/next-i18next&quot;&gt;next-i18next&lt;/a&gt; with typescript in &lt;a href=&quot;https://nextjs.org&quot;&gt;Next JS&lt;/a&gt; app.&lt;/p&gt;
</content:encoded><author>Vaibhav Sharma</author></item><item><title>Problems with &apos;gatsby-image&apos; and their workarounds</title><link>https://theleakycauldronblog.com/articles/problems-with-gatsby-image-and-their-workarounds</link><guid isPermaLink="true">https://theleakycauldronblog.com/articles/problems-with-gatsby-image-and-their-workarounds</guid><description>&lt;img alt=&quot;Problems with &apos;gatsby-image&apos; and their workarounds&quot; src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Fgatsby-image-workarounds.BAo43jpl.jpeg&amp;w=1952&amp;h=1299&amp;dpl=699bfef0c4120e00087ee35a&quot; /&gt; Gatsby Image is a very powerful package with drool worthy features. It makes it very easy to implement, Medium like progressive image loading among other things. But it has its fair share of problems. Here are some of them along with workarounds.</description><pubDate>Wed, 19 Dec 2018 12:30:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;https://www.gatsbyjs.org/packages/gatsby-image/&quot;&gt;gatsby-image&lt;/a&gt; is a very powerful package with drool-worthy features. It makes it very easy to implement, Medium like progressive image loading. It can do a bunch of other stuff but that&apos;s the fancy stuff that we won&apos;t be going into. But I decided to not use it for this website, mostly because it doesn&apos;t play well with &lt;a href=&quot;https://www.netlifycms.org&quot;&gt;Netlify CMS&lt;/a&gt;. And, I was quite happy with the site&apos;s performance as it didn&apos;t have many images.&lt;/p&gt;
&lt;p&gt;The article list was all words, no thumbnails and since all the images were within the article, it worked just fine.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Fscreenshot-2019-09-07-at-4.01.21-pm.CZjHsWSi.png&amp;amp;w=2644&amp;amp;h=1354&amp;amp;dpl=699bfef0c4120e00087ee35a&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;This all changed when I decided to ditch &lt;a href=&quot;https://bulma.io&quot;&gt;Bulma&lt;/a&gt; for &lt;a href=&quot;https://tachyons.io&quot;&gt;Tachyons&lt;/a&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;With New Framework Comes New Design&lt;/p&gt;
&lt;p&gt;- Anonymous (Probably LOL)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In the new design, I was working the article list had a small thumbnail along with the title and excerpt.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Fscreenshot-2018-12-19-at-11.19.21-pm.CNZTDMo9.png&amp;amp;w=1646&amp;amp;h=528&amp;amp;dpl=699bfef0c4120e00087ee35a&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Without the optimisation magic of &lt;a href=&quot;https://www.gatsbyjs.org/packages/gatsby-image/&quot;&gt;gatsby-image&lt;/a&gt; each page size would be touching 5MB. Begrudgingly, I decided to use &lt;a href=&quot;https://www.gatsbyjs.org/packages/gatsby-image/&quot;&gt;gatsby-image&lt;/a&gt;. I did what anyone would do, installed the package and peer dependencies. And as instructed added the relevant config. That&apos;s when the problem began! Everything started breaking. And I&apos;m ashamed that it took me a lot more time than I&apos;m willing to admit, to solve them. Well everyone has bad days.&lt;/p&gt;
&lt;h2&gt;Things to be careful about while configuring gatsby-image&lt;/h2&gt;
&lt;p&gt;First, you need &lt;code&gt;gatsby-remark-relative-images&lt;/code&gt; to convert image src(s) in markdown to be relative to their node&apos;s parent directory. So that &lt;code&gt;gatsby-remark-images&lt;/code&gt; can match images outside the node folder. This is especially important if you are working with &lt;a href=&quot;https://www.netlifycms.org&quot;&gt;Netlify CMS&lt;/a&gt;. Also, don&apos;t forget to add fmImagesToRelative to &lt;em&gt;gatsby-node.js&lt;/em&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const {fmImagesToRelative} = require(&apos;gatsby-remark-relative-images&apos;)

exports.onCreateNode = ({node, actions, getNode}) =&amp;gt; {
  const {createNodeField} = actions
  fmImagesToRelative(node)

  if (node.internal.type === `MarkdownRemark`) {
    const value = createFilePath({node, getNode})
    createNodeField({
      name: `slug`,
      node,
      value,
    })
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Second, The &apos;&lt;strong&gt;gatsby-source-filesystem&lt;/strong&gt;&apos; media folder must be included before the other plugins, especially &lt;a href=&quot;https://www.netlifycms.org&quot;&gt;Netlfiy CMS&lt;/a&gt;. That&apos;s something that has been mentioned in &lt;strong&gt;gatsby-transformer-remark&lt;/strong&gt;&apos;s README.md. Not only that, it&apos;ll be best if you include &apos;&lt;strong&gt;gatsby-transformer-sharp&lt;/strong&gt;&apos; &apos;&lt;strong&gt;gatsby-plugin-sharp&apos;&lt;/strong&gt; and &apos;&lt;strong&gt;gatsby-transformer-remark&lt;/strong&gt;&apos; before any other plugin in &lt;em&gt;gatsby-config.js&lt;/em&gt;. Not doing this might lead to the following error.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Field &quot;image&quot; must not have a selection since type &quot;String&quot; has no subfields
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Third, once you are done configuring you cannot just query an image without parameters. I suggest &lt;strong&gt;publicURL&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Fourth, GIFs and SVGs are not processed by &lt;a href=&quot;https://www.gatsbyjs.org/packages/gatsby-image/&quot;&gt;gatsby-image&lt;/a&gt;. So always include &lt;strong&gt;publicURL&lt;/strong&gt; in the parameters as an alternate.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;export const imageQuery = graphql`
       image {
            childImageSharp {
                fluid(maxWidth: 1075, quality: 72) {
                    ...GatsbyImageSharpFluid
                }
            }
            publicURL
        }`
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;        {!!image &amp;amp;&amp;amp; !!image.childImageSharp
          ? &amp;lt;Img fluid={image.childImageSharp.fluid}
                 alt={title}
            /&amp;gt;
          : &amp;lt;img src={image.publicURL}
                 alt={title} 
           /&amp;gt;
        }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally, sometimes the build can fail just because &lt;strong&gt;node_modules/&lt;/strong&gt; needs to be rebuilt. So, if you see nothing else working try removing &lt;strong&gt;node_modules/&lt;/strong&gt; and reinstalling packages.&lt;/p&gt;
&lt;h2&gt;gatsby-image and gatsby-paginate don&apos;t go well together&lt;/h2&gt;
&lt;p&gt;While implementing Article List I ran into an error that disturbed me for hours. Let me preface by explaining how &lt;a&gt;gatsby-paginate&lt;/a&gt; works. We plugin Gatsby Paginate&apos;s &lt;code&gt;createPaginatedPages&lt;/code&gt; function in &lt;em&gt;gatsby-node.js&lt;/em&gt;. It takes the &lt;code&gt;createPages&lt;/code&gt; method and takes results of the query to create a paginated list of posts.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;return graphql(`
    {
      allMarkdownRemark(sort: { order: DESC, fields: [frontmatter___date] }) {
        edges {
          node {
            excerpt(pruneLength: 250)
            id
            fields {
              slug
            }
            frontmatter {
              title
              tags
              date(formatString: &quot;MMMM DD, YYYY&quot;)
              templateKey
            }
          }
        }
      }
    }
  `)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So, if I had to display a thumbnail on my article list I just add that query. Simple enough right? Wrong! You add an image to the query, and you run into the first problem, it needs to have parameters. That&apos;s okay, you need to apply &lt;code&gt;...GatsbyImageSharpFluid&lt;/code&gt; anyways, but wait! This throws an error, one that drove me crazy and made me write this article.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;return graphql(`
    {
      allMarkdownRemark(sort: { order: DESC, fields: [frontmatter___date] }) {
        edges {
          node {
            excerpt(pruneLength: 250)
            id
            fields {
              slug
            }
            frontmatter {
              image
              title
              tags
              date(formatString: &quot;MMMM DD, YYYY&quot;)
              templateKey
            }
          }
        }
      }
    }
  `)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Error: unknown fragment ...GatsbyImageSharpFluid
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is an annoying problem because the reason it states is very confusing! &lt;strong&gt;GatsbyImageSharpFluid&lt;/strong&gt; is a fragment and I know that for sure. After searching for hours I find out an interesting thing.&lt;/p&gt;
&lt;p&gt;The query in &lt;em&gt;gatsby-node.js&lt;/em&gt; is only the path and stuff you put in context, which you can use in your page/template to retrieve the data you need. What this means is it&apos;s only creating pages, the query there isn&apos;t really supposed to be passing data down apart from a kind of reference which you can use in the page to make a query for the specific kind of data that page needs. Hence, it doesn&apos;t recognise &lt;strong&gt;GatsbyImageSharpFluid&lt;/strong&gt; as a valid fragment.&lt;/p&gt;
&lt;p&gt;Which brings us to workaround. After looking online I found that I&apos;m not the only one to run into this Catch 22. Various people found various workarounds, with varying results. After failing to get any of them working for me, it struck me. A workaround that&apos;ll work for everyone, not ideal but universal. All you gotta do is pass the required fields of fluid to it manually. And to add the base64 placeholder image, top it off with &lt;strong&gt;base64&lt;/strong&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;return graphql(`
    {
      allMarkdownRemark(sort: { order: DESC, fields: [frontmatter___date] }) {
        edges {
          node {
            excerpt(pruneLength: 250)
            id
            fields {
              slug
            }
            frontmatter {
              image {
                childImageSharp{
                  fluid (maxWidth:500, quality:50){
                    src
                    srcSet
                    aspectRatio
                    sizes
                    base64
                  }
                }
                publicURL
              }
              title
              tags
              date(formatString: &quot;MMMM DD, YYYY&quot;)
              templateKey
            }
          }
        }
      }
    }
  `)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Ooooorrrrr, you could simply use one of the other plugins for pagination.&lt;/p&gt;
&lt;p&gt;Neither &lt;a href=&quot;https://www.gatsbyjs.org/packages/gatsby-image/&quot;&gt;gatsby-image&lt;/a&gt;, nor &lt;a&gt;gatsby-paginate&lt;/a&gt;, are ideal packages. But the utility they provide is without question, very helpful. As the Gatsby community grows, we&apos;ll have perfect solutions. But till then I just hope we keep sharing the problems we run into and how we overcome them.&lt;/p&gt;
</content:encoded><author>Vaibhav Sharma</author></item><item><title>Self hosting Google Fonts for better caching</title><link>https://theleakycauldronblog.com/articles/self-hosting-google-fonts-for-better-caching</link><guid isPermaLink="true">https://theleakycauldronblog.com/articles/self-hosting-google-fonts-for-better-caching</guid><description>&lt;img alt=&quot;Self hosting Google Fonts for better caching&quot; src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Fself_hosted_google_fonts.D2pfxV6D.jpg&amp;w=4608&amp;h=2592&amp;dpl=699bfef0c4120e00087ee35a&quot; /&gt; Self host google fonts to better leverage the browser caching provided by starter kit like create-react-app and Gatsby.</description><pubDate>Wed, 05 Dec 2018 12:30:00 GMT</pubDate><content:encoded>&lt;p&gt;Just a month ago a college fresher came to me showing her newly made React app, bootstrapped using &lt;code&gt;create-react-app&lt;/code&gt;. As we got into discussing performance, she told me that everything was almost 100 on &lt;a href=&quot;https://gtmetrix.com/&quot;&gt;gtmetrix.com&lt;/a&gt; except for &lt;strong&gt;Browser Caching&lt;/strong&gt;. That was because of &lt;em&gt;Google Analytics&lt;/em&gt; and &lt;em&gt;Google Fonts&lt;/em&gt;. And, it&apos;s not just about browser caching, a lot of times &lt;em&gt;Google Fonts&lt;/em&gt; have files that will probably be of no use to us. For example, extra language support. Although not much can be done about &lt;em&gt;Google Analytics&lt;/em&gt;, I told her a little hack that will make the &lt;em&gt;&apos;Google Fonts&apos;&lt;/em&gt; problem disappear very easily. Since starter kits like &lt;code&gt;create-react-app&lt;/code&gt; and &lt;em&gt;Gatsby JS&lt;/em&gt; provide support for caching and service workers, we&apos;re better off self-hosting.&lt;/p&gt;
&lt;p&gt;For this tutorial, we&apos;ll be assuming the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;This is a &lt;code&gt;create-react-app&lt;/code&gt; project&lt;/li&gt;
&lt;li&gt;We need to include Montserrat font from &lt;em&gt;Google Fonts&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Let&apos;s begin, by selecting the font on &lt;a href=&quot;https://fonts.google.com&quot;&gt;https://fonts.google.com&lt;/a&gt; for us that will be &lt;em&gt;Montserrat&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Fscreenshot-2018-12-05-at-9.58.11-pm.BDAm_Sv8.png&amp;amp;w=2696&amp;amp;h=1842&amp;amp;dpl=699bfef0c4120e00087ee35a&quot; alt=&quot;self-hosting-google-fonts-1&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Next, we copy the URL in the &lt;code&gt;href&lt;/code&gt; attribute of the example code. Open the URL from your browser and you&apos;ll see a CSS file, with the code to include the font-face.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Fscreenshot-2018-12-05-at-9.59.21-pm.Dp4Sk8mL.png&amp;amp;w=2696&amp;amp;h=1842&amp;amp;dpl=699bfef0c4120e00087ee35a&quot; alt=&quot;self-hosted-google-fonts-2&quot; /&gt;&lt;/p&gt;
&lt;p&gt;We see here that there are quite a few font files that the API pulled. Let&apos;s say for this article that we don&apos;t need the Vietnamese support. So, we just copy the Latin and Cyrillic parts of the stylesheet. In the code, we see, there&apos;s a URL for the font file. We download the fonts using that URL and keep them in a local project folder. Now, all we need to do is replace the URL from the cloud-hosted to the relative address of the locally stored file.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;src: local(&apos;Montserrat Regular&apos;), local(&apos;Montserrat-Regular&apos;), url(https://fonts.gstatic.com/s/montserrat/v12/JTUSjIg1_i6t8kCHKm459WlhyyTh89Y.woff2) format(&apos;woff2&apos;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;to&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;src: local(&apos;Montserrat Regular&apos;), local(&apos;Montserrat-Regular&apos;), url(../fonts/JTUSjIg1_i6t8kCHKm459WlhyyTh89Y.woff2) format(&apos;woff2&apos;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;create-react-app&lt;/code&gt; allows us to directly import CSS files, we just import our stylesheet in the javascript.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;...
import &apos;./styles.css&apos;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And, that&apos;s all we need to do, &lt;code&gt;create-react-app&lt;/code&gt; automatically takes care of caching and service worker. This works for other libraries like &lt;em&gt;Gatsby JS&lt;/em&gt; as well.
That&apos;s all for this article.&lt;/p&gt;
</content:encoded><author>Vaibhav Sharma</author></item><item><title>Quirks of migrating the blog to Gatsby v2</title><link>https://theleakycauldronblog.com/articles/quirks-of-migrating-the-blog-to-gatsby-v2</link><guid isPermaLink="true">https://theleakycauldronblog.com/articles/quirks-of-migrating-the-blog-to-gatsby-v2</guid><description>&lt;img alt=&quot;Quirks of migrating the blog to Gatsby v2&quot; src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2F1y8lnpji8cr11.BA2e1m3r.jpg&amp;w=2081&amp;h=1511&amp;dpl=699bfef0c4120e00087ee35a&quot; /&gt; Dealing with the struggles and features of migrating to Gatsby v2. From handling broken dependencies to dealing with unexpected broken features to utilising new features of Gatsby v2.</description><pubDate>Mon, 03 Dec 2018 12:30:00 GMT</pubDate><content:encoded>&lt;p&gt;When the Gatsby v2 dropped I was like do I really need this, my website is already faster than anything on Gatsby v1? But then I remembered I made this website more so because I wanted to try Gatsby than anything else. Finally, I took time out to do it last weekend.&lt;/p&gt;
&lt;h2&gt;Journey Begins - Updating Dependencies&lt;/h2&gt;
&lt;p&gt;Upgrading &lt;code&gt;npm&lt;/code&gt; packages broke so much because a lot of them now require &lt;em&gt;peerDependencies&lt;/em&gt; which were earlier part of the package itself. And some packages had dependencies included in them. This task had one upside to it - I cleaned up a lot of packages that weren&apos;t that useful and wanted to remove but never got time to. This also got me thinking about including new packages and features that I wanted to, most of all - ElasticLunr Search. The real struggles soon follow.&lt;/p&gt;
&lt;h2&gt;I See Red - Warnings and Deprecations&lt;/h2&gt;
&lt;p&gt;With new release, comes lots of deprecations:&lt;/p&gt;
&lt;h3&gt;Link is now included in gatsby package&lt;/h3&gt;
&lt;p&gt;Although migration from &lt;code&gt;react-router&lt;/code&gt; to &lt;code&gt;reach/router&lt;/code&gt; was a great decision, it meant manually updating the imports in a lot of files. Nevertheless, a good decision as I felt there was a lot of inconsistency with &lt;code&gt;react-router&lt;/code&gt; especially in terms of gatsby, even though it was a more familiar package to work with due to my experience with React.&lt;/p&gt;
&lt;h3&gt;Global graphql is now deprecated&lt;/h3&gt;
&lt;p&gt;This one was more of a surprise to me as it made not much sense, but still meant a lot of refactoring. What I thought would make it easy was Webstorm auto-import but that didn&apos;t go quite well for me, had to do it manually. Only to find out that there is a codemod package to help it!&lt;/p&gt;
&lt;h3&gt;Renaming parameters&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;boundActionCreators&lt;/code&gt; and &lt;code&gt;pathContext&lt;/code&gt; were retired to make way for &lt;code&gt;actions&lt;/code&gt; and &lt;code&gt;pageContext&lt;/code&gt;. This was easy enough to do with Webstorm. Phew!&lt;/p&gt;
&lt;h2&gt;Removing inline styles from &lt;code&gt;html.js&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;Although Gatsby v2 doc states that we should stay away from html.js but, my project is set up in a way that I didn&apos;t/couldn&apos;t stay away from it(thanks &lt;code&gt;Bulma&lt;/code&gt;). And this also meant additional refactoring.&lt;/p&gt;
&lt;h3&gt;Adding the support for Layout&lt;/h3&gt;
&lt;p&gt;This one had me most wary, I was like this cannot go well on the first try, but voila it did. But wait a second, there was a problem that I didn&apos;t know yet.&lt;/p&gt;
&lt;h2&gt;Problems Begin - Solving Breaking Changes&lt;/h2&gt;
&lt;p&gt;Just when I was thinking this going all too well, I encountered my first glitch - The Netlify CMS isn&apos;t accessible anymore.&lt;/p&gt;
&lt;h3&gt;&lt;code&gt;gatsby-plugin-layout&lt;/code&gt; breaks Netlify CMS Admin Page&lt;/h3&gt;
&lt;p&gt;This was a particularly nasty problem because it looks like &lt;code&gt;gatsby-plugin-layout&lt;/code&gt; is trying to put the layout on the admin page and you don&apos;t see any way to fix it! ...but, it doesn&apos;t have much to do with it. After googling for hours and asking random devs online, I remembered I had another project where it didn&apos;t break the admin page. Solution? All you need to do is that you need to put &lt;code&gt;gatsby-plugin-layout&lt;/code&gt; before &lt;code&gt;gatsby-plugin-netlify-cms&lt;/code&gt; in &lt;code&gt;gatsby-config.js&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;Netlify CMS Preview Pane stops working&lt;/h3&gt;
&lt;p&gt;This one although was easy to figure out using Console errors, was still surprising because it made no sense why it had worked before and if it did, it made no sense that it is now broken! The problem was that the tags needed an error check:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; {tags &amp;amp;&amp;amp; tags.length ? (...) : null}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Luckily this is where my problems ended with the migrations. Now, it was time for improving the blog, by adding search functionality.&lt;/p&gt;
&lt;h2&gt;Improvement Begins - Adding Search Functionality&lt;/h2&gt;
&lt;p&gt;I know this doesn&apos;t seem like much of a reason to include it in this blog, but I included this because I wanted to discuss how freakin&apos; StaticQuery is! It was always in the plans to include a Search Box, and had planned to use &lt;code&gt;@andrew-codes/gatsby-plugin-elasticlunr-search&lt;/code&gt; since I had no plans to use Algolia. I could still use &lt;code&gt;andrew-codes&lt;/code&gt; version but i decided to use the forked version by &lt;code&gt;gatsby-contrib&lt;/code&gt;, because I wanted to try out StaticQuery. And let me tell ya, it&apos;s a damn cool feature!&lt;/p&gt;
&lt;p&gt;And with that migration was finally complete! It was not too bad, for javascript ecosystem. And the effort was worth the result.&lt;/p&gt;
</content:encoded><author>Vaibhav Sharma</author></item><item><title>Implement Rich Snippet Schema with Google Tag Manager</title><link>https://theleakycauldronblog.com/articles/implement-rich-snippet-schema-with-google-tag-manager</link><guid isPermaLink="true">https://theleakycauldronblog.com/articles/implement-rich-snippet-schema-with-google-tag-manager</guid><description>&lt;img alt=&quot;Implement Rich Snippet Schema with Google Tag Manager&quot; src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Fstructured_data_gtm.DIFCO39Y.jpg&amp;w=6702&amp;h=4468&amp;dpl=699bfef0c4120e00087ee35a&quot; /&gt; Leverage Google Tag Manager Custom HTML Tag to implement Schema.org JSON-LD Schema for Rich Snippets.</description><pubDate>Sat, 16 Jun 2018 12:30:00 GMT</pubDate><content:encoded>&lt;p&gt;Rich Snippets Schema, while may not help in improving SERP Ranking, it does help in better CTR(Click Through Rate). And this is the new frontier in Digital Marketing/SEO. With the onset of various AI Assistants like &lt;em&gt;Google Assistant&lt;/em&gt;, &lt;em&gt;Siri&lt;/em&gt;, &lt;em&gt;Cortana&lt;/em&gt;, etc and them affecting sales, It has become very important that the search engines understand your content better. To make them understand the content better, a lot of search giants got together and developed a content markup system. This is Project &lt;strong&gt;&lt;em&gt;Schema.org&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;There are various encodings you can use to markup your data, like &lt;code&gt;Microdata&lt;/code&gt;, &lt;code&gt;JSON-LD&lt;/code&gt;, &lt;code&gt;RDFa&lt;/code&gt;. But out of these the popular choices are &lt;code&gt;Microdata&lt;/code&gt; and &lt;code&gt;JSON-LD&lt;/code&gt;. &lt;code&gt;Microdata&lt;/code&gt; is very much like &lt;code&gt;XML&lt;/code&gt; whereas &lt;code&gt;JSON-LD&lt;/code&gt; is more like &lt;code&gt;JSON&lt;/code&gt;. Google prefers &lt;code&gt;JSON-LD&lt;/code&gt; and plans to phase out &lt;code&gt;Microdata&lt;/code&gt;. But &lt;code&gt;Microdata&lt;/code&gt; is still a big part of Bing and Yahoo.&lt;/p&gt;
&lt;p&gt;Although there are various ways you can implement these Schemas, the one that has been gaining a lot of traction recently is using &lt;em&gt;Google Tag Manager&lt;/em&gt;. While you can simply put your JSON-LD schema Tag in a Custom HTML field and expect it to work, and for some people it has, if you go to &lt;a href=&quot;https://search.google.com/structured-data/testing-tool/&quot;&gt;Structured Data Testing Tool&lt;/a&gt; you&apos;ll find out that the schema isn&apos;t visible. That&apos;s either because the Structured Data Testing Tool cannot render the schema, or GTM doesn&apos;t allow us to do so.&lt;/p&gt;
&lt;p&gt;This made us think and we found a simple workaround for this problem. What we do essentially is, store schema data as &lt;code&gt;JSON&lt;/code&gt; in a variable, and create a &lt;code&gt;&amp;lt;script type=&quot;application/ld+json&quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;/code&gt; tag using JavaScript.&lt;/p&gt;
&lt;p&gt;Let&apos;s say this is our &lt;code&gt;JSON-LD&lt;/code&gt; Schema&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;script type=&quot;application/ld+json&quot;&amp;gt;
{
  &quot;@context&quot;: &quot;http://schema.org/&quot;,
  &quot;@type&quot;: &quot;Review&quot;,
  &quot;url&quot;: &quot;https://www.example.com/lorem-services/&quot;,
  &quot;name&quot;: &quot;Example Lorem Service Review&quot;,
  &quot;reviewBody&quot;: &quot;Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Sed posuere consectetur est at lobortis. Cras mattis consectetur purus sit amet fermentum.&quot;,
  &quot;datePublished&quot;: &quot;2017-06-27&quot;,
  &quot;itemReviewed&quot;: {
    &quot;@type&quot;: &quot;Service&quot;,
    &quot;name&quot;: &quot;Lorem Service&quot;
  },
  &quot;author&quot;: {
    &quot;@type&quot;: &quot;Person&quot;,
    &quot;name&quot;: &quot;John Smith&quot;
  },
  &quot;reviewRating&quot;: {
    &quot;@type&quot;: &quot;Rating&quot;,
    &quot;worstRating&quot;: &quot;1&quot;,
    &quot;ratingValue&quot;: &quot;5&quot;,
    &quot;bestRating&quot;: &quot;5&quot;
  }
}
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;First, we create a Custom HTML Tag in Google Tag Manager. In that tag, we create a JavaScript &lt;code&gt;document function&lt;/code&gt; within a Script Tag. In that &lt;code&gt;function&lt;/code&gt;, we create a variable called &lt;code&gt;jsonld&lt;/code&gt;, which stores our &lt;code&gt;JSON-LD&lt;/code&gt; data.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;script&amp;gt;
(function () {
    var jsonld = {
        &quot;@context&quot;: &quot;http://schema.org/&quot;,
        &quot;@type&quot;: &quot;Review&quot;,
        &quot;url&quot;: &quot;https://www.example.com/lorem-services/&quot;,
        &quot;name&quot;: &quot;Example Lorem Service Review&quot;,
        &quot;reviewBody&quot;: &quot;Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Sed posuere consectetur est at lobortis. Cras mattis consectetur purus sit amet fermentum.&quot;,
        &quot;datePublished&quot;: &quot;2017-06-27&quot;,
        &quot;itemReviewed&quot;: {
            &quot;@type&quot;: &quot;Service&quot;,
            &quot;name&quot;: &quot;Lorem Service&quot;
        },
        &quot;author&quot;: {
            &quot;@type&quot;: &quot;Person&quot;,
            &quot;name&quot;: &quot;John Smith&quot;
        },
        &quot;reviewRating&quot;: {
            &quot;@type&quot;: &quot;Rating&quot;,
            &quot;worstRating&quot;: &quot;1&quot;,
            &quot;ratingValue&quot;: &quot;5&quot;,
            &quot;bestRating&quot;: &quot;5&quot;
        }
    };
})(document);
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then we initialise the Script element, set the type as &lt;code&gt;&quot;application/ld+json&quot;&lt;/code&gt;, and put the &lt;code&gt;jsonld&lt;/code&gt; variable data in the  &lt;code&gt;Inner HTML&lt;/code&gt;. After that, all that&apos;s left is to append the script to document Head.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;script&amp;gt;
(function () {
    var jsonld = {
        &quot;@context&quot;: &quot;http://schema.org/&quot;,
        &quot;@type&quot;: &quot;Review&quot;,
        &quot;url&quot;: &quot;https://www.example.com/lorem-services/&quot;,
        &quot;name&quot;: &quot;Example Lorem Service Review&quot;,
        &quot;reviewBody&quot;: &quot;Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Sed posuere consectetur est at lobortis. Cras mattis consectetur purus sit amet fermentum.&quot;,
        &quot;datePublished&quot;: &quot;2017-06-27&quot;,
        &quot;itemReviewed&quot;: {
            &quot;@type&quot;: &quot;Service&quot;,
            &quot;name&quot;: &quot;Lorem Service&quot;
        },
        &quot;author&quot;: {
            &quot;@type&quot;: &quot;Person&quot;,
            &quot;name&quot;: &quot;John Smith&quot;
        },
        &quot;reviewRating&quot;: {
            &quot;@type&quot;: &quot;Rating&quot;,
            &quot;worstRating&quot;: &quot;1&quot;,
            &quot;ratingValue&quot;: &quot;5&quot;,
            &quot;bestRating&quot;: &quot;5&quot;
        }
    };
    var script = document.createElement(&apos;script&apos;);
    script.type = &apos;application/ld+json&apos;;
    script.innerHTML = JSON.stringify( jsonld );
    document.getElementsByTagName(&apos;head&apos;)[0].appendChild(script);
})(document);
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Oh and don&apos;t forget to check the box that says &lt;em&gt;Support &lt;code&gt;document.write&lt;/code&gt;&lt;/em&gt;.
Since we are done with the coding part, all that is left is to set the trigger, which can be done easily by creating a new trigger and setting the required path, depending on if you want it to trigger on specific pages or all pages.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;TIP:&lt;/strong&gt; You can set custom variables in GTM that&apos;ll pull the data according to &lt;code&gt;CSS selectors&lt;/code&gt;, this can be used to make an automated template schema, for pages like blog posts.&lt;/p&gt;
</content:encoded><author>Vaibhav Sharma</author></item><item><title>Sending Mass Mail from Google Sheet using Scripts</title><link>https://theleakycauldronblog.com/articles/sending-mass-mail-from-google-sheet-using-scripts</link><guid isPermaLink="true">https://theleakycauldronblog.com/articles/sending-mass-mail-from-google-sheet-using-scripts</guid><description>&lt;img alt=&quot;Sending Mass Mail from Google Sheet using Scripts&quot; src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Fmass_mail_google_script.n273RGwx.jpg&amp;w=6016&amp;h=4016&amp;dpl=699bfef0c4120e00087ee35a&quot; /&gt; Leverage the power of Google Script to run email campaigns, right from your Google Sheet.</description><pubDate>Mon, 04 Jun 2018 12:30:00 GMT</pubDate><content:encoded>&lt;p&gt;ver find yourself with a big spreadsheet full of names and emails and you have to send personalized emails to all of them? We did. We had a spreadsheet full of candidates for hiring and:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;We had to first send them a mail asking if they are interested.&lt;/li&gt;
&lt;li&gt;If they replied positively we had to send them an assignment.&lt;/li&gt;
&lt;li&gt;If they hadn&apos;t replied with the completed assignment, we had to send them reminder mail.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So what we did first was, add three columns:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Send First Email&lt;/li&gt;
&lt;li&gt;Send Assignment&lt;/li&gt;
&lt;li&gt;Send Reminder&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These columns containing the word &quot;Send&quot; if the candidate has to be mailed, and &quot;Sent&quot; once the mail has been sent. So basically our script goes through, the sheet, picks up the candidate name, and email, uses name variable to create a personalized message, send it to their email(if the Send First Email contains the keyword &quot;Send&quot;) and after sending replaces the keyword with &quot;Sent&quot;.&lt;/p&gt;
&lt;h2&gt;Step One: Structure of Our Sheet&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Fsheet_structure.C4V85fgh.png&amp;amp;w=631&amp;amp;h=88&amp;amp;dpl=699bfef0c4120e00087ee35a&quot; alt=&quot;google sheet sturcture&quot; /&gt;&lt;/p&gt;
&lt;p&gt;This is our example table, for the customized message we&apos;ll pick up, the first name from &lt;code&gt;column B&lt;/code&gt;, the last name from &lt;code&gt;column C&lt;/code&gt;, etc. You can add more details accordingly.&lt;/p&gt;
&lt;h2&gt;Step Two: Script for Mass Mail&lt;/h2&gt;
&lt;p&gt;Google Script uses plain JavaScript with some built-in APIs. First, we write the function that&apos;ll send the mail. To Write the Script click on &lt;code&gt;Tools &amp;gt; Script Editor&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function sendMassMail() {

  // Get Active Sheet
  var sheet = SpreadsheetApp.getActiveSheet(); 

  // Sender Name will Appear to the Recipient
  var senderName = &quot;Vaibhav | The Leaky Cauldron Blog&quot;;

  // Get all Data.
  var dataRange = sheet.getDataRange(); 
  var data = dataRange.getValues(); 

  var count = 0;

  // Parse Through Data
  for (i in data) { 
    count += 1;
    var rowData = data[i]; 

    // Array Starts with 0, eg. - column B is 1
    var first_name = rowData[1]; 
    var last_name = rowData[2];
    var emailAddress = rowData[3]; 
    var confirmSend = rowData[4]; 

    // Set a Custom Subject
    var subject = first_name + &apos; | Graphic Designer Role at The Leaky Cauldron Blog&apos;;

    // Verify if the mail has to be sent
    if (confirmSend === &quot;Send&quot;) { 
      try { 

        // Use MailApp API to send Email.
        MailApp.sendEmail({ 
          to: emailAddress, 
          subject: subject, 
          // Write Custom HTML Message
          htmlBody: &apos;&amp;lt;div&amp;gt;Hi &apos; + first_name + last_name + &apos;&amp;lt;/div&amp;gt;&apos;, 
          name: senderName 
        }); 

        // Set the value of Mail Status to Sent if Sent.
        // getRange(row, column). column starts from 1.
        sheet.getRange(count, 5).setValue(&quot;Sent&quot;);

        // Log if the Mail was sent successfully
        Logger.log(&quot;Email: %s&quot;, emailAddress); 

      } catch(e) { 

        // Set the value of Mail Status to Failed if Failed.
        sheet.getRange(count, 5).setValue(&quot;Failed&quot;);

        // Log if there was some error
        Logger.log(e); 

      } 
    } else { 
      continue; 
    } 
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Don&apos;t forget to Save the Project.&lt;/p&gt;
&lt;h2&gt;Step Three: Add the Function To Main Menu&lt;/h2&gt;
&lt;p&gt;Below the &lt;code&gt;sendMassMail()&lt;/code&gt; write a function called &lt;code&gt;onOpen()&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function onOpen() {
  var sheet = SpreadsheetApp.getActiveSpreadsheet();
  var entries = [{

    // Set a Name for Function
    name : &quot;Send Mass Mail&quot;,
    functionName : &quot;sendMassMail&quot;

  }];

  // Add a Menu and name it
  sheet.addMenu(&quot;Email&quot;, entries);

};
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Save and reload the sheet, you&apos;ll see a menu called &lt;code&gt;Email&lt;/code&gt;, and within it, an option called &lt;code&gt;Send Mass Mail&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;That&apos;s it just click on the option to run the script and send mass mail. One more, thing you&apos;ll have to approve the script to use your Gmail.&lt;/p&gt;
&lt;p&gt;Link to Example Sheet - &lt;a href=&quot;https://docs.google.com/spreadsheets/d/1OeRL8bFaAYuwAQXdy_wV1WKmGap_gcQ3jFOzrbKVEuo/edit?usp=sharing&quot;&gt;Mass Mail&lt;/a&gt;&lt;/p&gt;
</content:encoded><author>Vaibhav Sharma</author></item><item><title>Writing Authenticated Route Component in React Redux</title><link>https://theleakycauldronblog.com/articles/writing-authenticated-route-component-in-react-redux</link><guid isPermaLink="true">https://theleakycauldronblog.com/articles/writing-authenticated-route-component-in-react-redux</guid><description>&lt;img alt=&quot;Writing Authenticated Route Component in React Redux&quot; src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Freact_redux_authenticated_routes.BTXU3hkk.jpg&amp;w=5598&amp;h=3657&amp;dpl=699bfef0c4120e00087ee35a&quot; /&gt; Writing Authenticated Routes which will redirect to signin page if the user is not authenticated and once signed in it&apos;ll redirect back to the same page.</description><pubDate>Sat, 02 Jun 2018 12:30:00 GMT</pubDate><content:encoded>&lt;p&gt;How to write an Authenticated Route component which will redirect to Sign In Page if a user isn&apos;t authenticated and once authentication is complete, it&apos;ll redirect them back to the same page, this is a problem most new React developers face. Today we learn to do just that.&lt;/p&gt;
&lt;p&gt;But before we begin, lets clear out some assumptions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;This is not a beginner react-redux authentication tutorial, we assume you already have an authentication mechanism set up.&lt;/li&gt;
&lt;li&gt;The Redux association is just to get the &quot;authenticated&quot;(bool) state, and you can use any state management you like.&lt;/li&gt;
&lt;li&gt;We are using React Router v4&lt;/li&gt;
&lt;li&gt;You may need to modify it according to your project.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now that, that&apos;s out of the way lets begin by creating the most important part, the &lt;code&gt;AuthenticatedRoute&lt;/code&gt; component.&lt;/p&gt;
&lt;h2&gt;Creating AuthenticatedRoute Component&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;AuthenticatedRoute&lt;/code&gt; component is a component which takes the props of &lt;code&gt;Route&lt;/code&gt; and an additional boolean prop, &lt;code&gt;authenticated&lt;/code&gt;, which determines if the Component is to be rendered or the user needs to be redirected.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import React from &quot;react&quot;;
import {Route, Redirect} from &quot;react-router-dom&quot;;

export default function AuthenticatedRoute({
                                               component: Component,
                                               authenticated,
                                               ...rest
                                           }) {
    return (
        &amp;lt;Route
            {...rest}
            render={props =&amp;gt;
                authenticated === true ? (
                    &amp;lt;Component {...props} {...rest} /&amp;gt;
                ) : (
                    &amp;lt;Redirect to={`/signin?redirectTo=${props.match.path}`}/&amp;gt;
                )
            }
        /&amp;gt;
    );
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It also stores the actual path as a parameter in the sign in path &lt;code&gt;/signin?redirectTo=&amp;lt;path&amp;gt;&lt;/code&gt; so that when the user signs in it&apos;ll redirect to that path.&lt;/p&gt;
&lt;h2&gt;Redirecting to the URL Param after Sign In&lt;/h2&gt;
&lt;p&gt;To redirect to the param that we set, we need to first edit the &lt;code&gt;signinUser(username, password)&lt;/code&gt; action, by adding a third argument, redirect.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;...

export function signinUser(username, password, redirect = &apos;/&apos;){
// Authentication Logic
...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;we set a default value for the third argument so that in case no value is provided it&apos;ll redirect to the home page. Now for the actual redirection.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;export function signinUser(username, password, redirect = &apos;/&apos;){
    return function(dispatch){
        dispatch(authRequest);
            return axios.post(
                ...
            ).then((response) =&amp;gt; {
                dispatch(authSuccess(response));
                // Redirect
                window.location = redirect;
            }).catch(error =&amp;gt; {
                dispatch(authFailure(error));
            });
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Parsing the URL Parameter&lt;/h2&gt;
&lt;p&gt;To get the &lt;code&gt;redirectTo&lt;/code&gt; param&apos;s value from&lt;code&gt;/signin?redirectTo=&amp;lt;path&amp;gt;&lt;/code&gt;, we need to install a package called &lt;code&gt;query-string&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;yarn add query-string
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;or&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;npm install query-string --save
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;now in our Sign In Container, in the function that handles Sign In request, we access the URL param and pass it to &lt;code&gt;signinUser&lt;/code&gt; function.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;...
import queryString from &apos;query-string&apos;;

class SignInContainer extends Component {
    handleSignIn(event) {
        event.preventDefault();
        const redirectTo = queryString.parse(this.props.location.search).redirectTo;
        this.props.actions.signinUser(this.state.data.username, this.state.data.password, redirectTo);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Using AuthenticatedRoute in our Router&lt;/h2&gt;
&lt;p&gt;Now it&apos;s time to use the AuthenticatedRoute Component, it&apos;s very easy to do and works exactly like Route from react-router-dom. It only takes one extra parameter, &lt;code&gt;authenticated&lt;/code&gt;, which is a boolean that determines if the user is authenticated or not.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;...
import AuthenticatedRoute from &apos;./component/AuthenticatedRoute&apos;;

const store = configureStore();
const {sessionReducer: {session: {authenticated}}} = store.getState();

class App extends Component {
render() {
        return (
            &amp;lt;Provider store={store}&amp;gt;
                &amp;lt;Router&amp;gt;
                    &amp;lt;div&amp;gt;
                        &amp;lt;Switch&amp;gt;
                            &amp;lt;Route exact path=&apos;/signin&apos; component={SignInPage}/&amp;gt;
                            &amp;lt;AuthenticatedRoute exact path=&apos;/&apos; 
                                                component={HomePage}
                                                authenticate={authenticated}/&amp;gt;
                            ...
                        &amp;lt;/Switch&amp;gt;
                    &amp;lt;/div&amp;gt;
                &amp;lt;/Router&amp;gt;
            &amp;lt;/Provider&amp;gt;
        );
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And that&apos;s it! We&apos;re all set.&lt;/p&gt;
</content:encoded><author>Vaibhav Sharma</author></item><item><title>Scraping Dynamic Websites (Angular, React etc) with Scrapy and Selenium</title><link>https://theleakycauldronblog.com/articles/scraping-dynamic-single-page-websites-with-scrapy-and-selenium</link><guid isPermaLink="true">https://theleakycauldronblog.com/articles/scraping-dynamic-single-page-websites-with-scrapy-and-selenium</guid><description>&lt;img alt=&quot;Scraping Dynamic Websites (Angular, React etc) with Scrapy and Selenium&quot; src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Fscraping_dynamic_webapps.3X0mUuyt.jpg&amp;w=4000&amp;h=2790&amp;dpl=699bfef0c4120e00087ee35a&quot; /&gt; Scraping websites made with Javascript frameworks like Angular and React is not possible with Scrapy or Beautiful Soup, learn to do so with the added help of Selenium.</description><pubDate>Fri, 04 May 2018 12:30:00 GMT</pubDate><content:encoded>&lt;p&gt;Last week I was assigned a task of scraping some data from a website, regular stuff no big deal. So, I set up a Scrapy Project, write the spider, and run the project sipping tea. What do I get?! A blank CSV file with no data! I try some more, make changes to the selector, and run it again to no avail. Then I notice that the website is made on Angular JS. Neither &lt;code&gt;beautiful_soup&lt;/code&gt; nor &lt;code&gt;Scrapy&lt;/code&gt; can scrape dynamic websites. I look up online and find out that only two frameworks that can do so are: &lt;code&gt;Splash&lt;/code&gt; and &lt;code&gt;Selenium&lt;/code&gt;. I chose &lt;code&gt;Selenium&lt;/code&gt;, mainly for two reasons:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;More Python friendly&lt;/li&gt;
&lt;li&gt;More likely to be useful in future projects.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In brief what we&apos;re about to do is, use the webdriver of a browser with the help of Selenium to render the entire page along with the dynamic parts, then scrape it. But before we begin, I&apos;m gonna assume the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;This is not a scrapy tutorial for beginners, I&apos;ll assume some familiarity&lt;/li&gt;
&lt;li&gt;A dummy page to be scraped, the links that have to be scraped has the class &quot;ng-binding&quot;&lt;/li&gt;
&lt;li&gt;A scrapy project has been set up and a blank spider script is ready, wherein our code goes.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Setting up Geckodriver&lt;/h2&gt;
&lt;p&gt;To begin we need to install, &lt;code&gt;geckodriver&lt;/code&gt;, which is webdriver for Firefox web browser. I&apos;m gonna write the instructions for Linux, you can look up the installation for your specific OS.
First, download the latest edition of geckodriver:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;wget https://github.com/mozilla/geckodriver/releases/download/v0.20.1/geckodriver-v0.20.1-linux64.tar.gz
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Extract the file with:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;tar -xvzf geckodriver*
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Make it executable:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;chmod +x geckodriver
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Make it accessible by command line:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo mv geckodriver /usr/local/bin/
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Writing the Spider&lt;/h2&gt;
&lt;p&gt;In the spider file, let&apos;s assume its name is &lt;code&gt;angular.py&lt;/code&gt; first we need to import the following:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import scrapy
import csv
from selenium import webdriver
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then we need to set up the spider class:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;...

class AngularSpider(scrapy.Spider):
    name = &apos;angular_spider&apos;
    start_urls = [
        &apos;https://www.example.com/?page=1&apos;,
        &apos;https://www.example.com/?page=2&apos;,
    ]    
    # Initalize the webdriver    
    def __init__(self):
        self.driver = webdriver.Firefox()

    
    # Parse through each Start URLs
    def start_requests(self):
        for url in self.start_urls:
            yield scrapy.Request(url=url, callback=self.parse)    
    

   # Parse function: Scrape the webpage and store it
   def parse(self, response):
       pass   
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The real magic happens in the parse function, here we&apos;ll write the selector for the data, and the output in a CSV file:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    ...
    
    # Parse function: Scrape the webpage and store it
    def parse(self, response):
        self.driver.get(response.url)
        # Output filename
        filename = &quot;angular_data.csv&quot;
        with open(filename, &apos;a+&apos;) as f:
            writer = csv.writer(f)
            # Selector for all the names from the link with class &apos;ng-binding&apos;
            names = self.driver.find_elements_by_css_selector(&quot;a.ng-binding&quot;)
            for name in names:
                title = name.text
                writer.writerow([title])
        self.log(&apos;Saved file %s&apos; % filename)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now when you run this using:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;scrapy crawl angular_spider
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You&apos;ll notice a browser opens up and the page is loaded, and when the scraping is complete you can open the CSV file and see the data.&lt;/p&gt;
</content:encoded><author>Vaibhav Sharma</author></item><item><title>Awesome Moments from Avengers: Infinity War</title><link>https://theleakycauldronblog.com/articles/awesome-moments-from-avengers-infinity-war</link><guid isPermaLink="true">https://theleakycauldronblog.com/articles/awesome-moments-from-avengers-infinity-war</guid><description>&lt;img alt=&quot;Awesome Moments from Avengers: Infinity War&quot; src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Favengers_infinity_war.D0Ppfzdo.jpg&amp;w=960&amp;h=540&amp;dpl=699bfef0c4120e00087ee35a&quot; /&gt; Here are some of the most awesome moments from the long-awaited Avenger&apos;s Infinity War.</description><pubDate>Mon, 30 Apr 2018 12:30:00 GMT</pubDate><content:encoded>&lt;p&gt;Friday marked the release of Avengers Infinity War, and I couldn&apos;t miss it for the world. In short, Marvel nailed it, from character chemistry to villain. The film was an emotional roller coaster, with a lot of people claiming to need therapy after it was over. Here are some of the moments I thought were the best (Spoilers, DUH!):&lt;/p&gt;
&lt;h2&gt;``...We have a Hulk!``&lt;/h2&gt;
&lt;p&gt;The classic line from The Avengers! After tasting what Stark meant when he said &quot;We have a Hulk&quot;, finally Loki got to say it.&lt;/p&gt;
&lt;h2&gt;Space Squidward&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Fsquidward.Dr1JU7Fl.jpg&amp;amp;w=496&amp;amp;h=297&amp;amp;dpl=699bfef0c4120e00087ee35a&quot; alt=&quot;Space Squidward&quot; /&gt;&lt;/p&gt;
&lt;p&gt;When Stark called Ebony Maw Squidward from Spongebob, it was a tiny one-liner but I just couldn&apos;t stop myself from laughing like a maniac. I&apos;m sure I&apos;m not the only, right?! right?! right?!&lt;/p&gt;
&lt;h2&gt;``Dude you are embarrassing me in front of the wizards``&lt;/h2&gt;
&lt;p&gt;This sent the entire hall, in a fit of laughter.&lt;/p&gt;
&lt;h2&gt;``The only way to smuggle it was up my ....``&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Feye.CXXMx0-F.jpg&amp;amp;w=384&amp;amp;h=384&amp;amp;dpl=699bfef0c4120e00087ee35a&quot; alt=&quot;Ass Eye&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Oh, Rocket and his obsession with prosthesis! At least Thor got his missing eye thanks to the weird rabbit.&lt;/p&gt;
&lt;h2&gt;Groot makes the handle of Stormbreaker with his Arm&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Fstormbreaker.jpg.C_mrRrWv.png&amp;amp;w=440&amp;amp;h=402&amp;amp;dpl=699bfef0c4120e00087ee35a&quot; alt=&quot;Stormbreaker&quot; /&gt;&lt;/p&gt;
&lt;p&gt;As if Thor getting a new Hammer/Axe wasn&apos;t exciting enough!&lt;/p&gt;
&lt;h2&gt;Thanos&apos; obsession with bubbles&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Fbubbles.B5AB1h0Z.jpg&amp;amp;w=689&amp;amp;h=340&amp;amp;dpl=699bfef0c4120e00087ee35a&quot; alt=&quot;thanos bubbles&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Seems to show a softer side to the Despot. Maybe... IDK&lt;/p&gt;
&lt;h2&gt;Red Skull&apos;s Dementor Makeover&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Fdementor.CK6ol0KO.jpeg&amp;amp;w=1500&amp;amp;h=1000&amp;amp;dpl=699bfef0c4120e00087ee35a&quot; alt=&quot;red_skull_dementor&quot; /&gt;&lt;/p&gt;
&lt;p&gt;This must be going through every Harry Potter fan, Red Skull levitating in that tattered robe was looking very much like a Dementor.&lt;/p&gt;
&lt;h2&gt;Death of Gamora&lt;/h2&gt;
&lt;p&gt;This was heartbreaking in a twisted kind of way. But certainly a powerful scene.&lt;/p&gt;
&lt;h2&gt;Where&apos;s Who&apos;s and Why&apos;s of Gamora&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Fgamora.DsRgpuMM.jpg&amp;amp;w=280&amp;amp;h=281&amp;amp;dpl=699bfef0c4120e00087ee35a&quot; alt=&quot;Gamora&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Guardians of the Galaxy meet Earth&apos;s Mightiest...&lt;/p&gt;
&lt;h2&gt;Kick Names, Take Ass&lt;/h2&gt;
&lt;p&gt;The ditsy half-sister of Star Lord, Mantis is always a delight.&lt;/p&gt;
&lt;h2&gt;Strange surrenders the Time Stone in exchange for Thanos sparing an injured Stark&lt;/h2&gt;
&lt;p&gt;Is it just me or it&apos;s weird that Strange never once used his most powerful weapon, and surrender it way too easily for Stark&apos;s life? He must think Stark is more important than any Stone in the future he saw them win.&lt;/p&gt;
&lt;h2&gt;Bucky-Rocket Interactions&lt;/h2&gt;
&lt;p&gt;Everyone was screaming with excitement when Buck used Rocket as a weapon, oh and of course Rocket wants his arm.&lt;/p&gt;
&lt;h2&gt;Wanda Destroys an Infinity Stone&lt;/h2&gt;
&lt;p&gt;Just goes to show how powerful she is(or rather was).&lt;/p&gt;
&lt;h2&gt;SNAP&lt;/h2&gt;
&lt;p&gt;The dreadful SNAP, killing half the universe, including some of our most beloved character. As if that wasn&apos;t enough, we got to see how much Thanos mourns Gamora.&lt;/p&gt;
&lt;h2&gt;Peter&apos;s Death&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Fpeters_death.CepGx8v4.jpg&amp;amp;w=700&amp;amp;h=541&amp;amp;dpl=699bfef0c4120e00087ee35a&quot; alt=&quot;Peter&apos;s Death&quot; /&gt;&lt;/p&gt;
&lt;p&gt;This one got to me, and I&apos;m sure most of the viewers. It was just too painful to hear him desperately hug Tony. &quot;I&apos;m sorry Mr. Stark...&quot;&lt;/p&gt;
&lt;h2&gt;Mother F&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Fcaptainmarvel.BTKguQUl.jpg&amp;amp;w=324&amp;amp;h=324&amp;amp;dpl=699bfef0c4120e00087ee35a&quot; alt=&quot;Paging Captain Marvel&quot; /&gt;&lt;/p&gt;
&lt;p&gt;This end credit was just appropriate..., Also Captain Marvel!&lt;/p&gt;
</content:encoded><author>Vaibhav Sharma</author></item><item><title>Requesting User details from JWT in Django OAuth Toolkit</title><link>https://theleakycauldronblog.com/articles/requesting-user-details-jwt-django-oauth-toolkit</link><guid isPermaLink="true">https://theleakycauldronblog.com/articles/requesting-user-details-jwt-django-oauth-toolkit</guid><description>&lt;img alt=&quot;Requesting User details from JWT in Django OAuth Toolkit&quot; src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Fuser_info_jwt.Df2hK-4K.jpg&amp;w=5107&amp;h=3391&amp;dpl=699bfef0c4120e00087ee35a&quot; /&gt; Learn to write an API to fetch the details of currently logged in user, using the Authorization Token, in Django Oauth Toolkit</description><pubDate>Mon, 16 Apr 2018 12:30:00 GMT</pubDate><content:encoded>&lt;p&gt;We always require an API to fetch the details of the current user. This API, unfortunately, isn&apos;t provided by default in Django OAuth Toolkit. But worry not, it&apos;s fairly easy to write this API, and that is what we&apos;ll do. But before we begin, let&apos;s clarify some assumptions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;This tutorial is written with Django 2.0 specific commands in mind (eg. Path)&lt;/li&gt;
&lt;li&gt;This is for someone who has Django OAuth Toolkit already up and running in the project.&lt;/li&gt;
&lt;li&gt;This tutorial doesn&apos;t mention imports and will have to be done by developer accordingly.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now that that&apos;s clear, let&apos;s begin.&lt;/p&gt;
&lt;h2&gt;Setting up the Authentication Backend and Middlewares&lt;/h2&gt;
&lt;p&gt;Before we begin writing &lt;code&gt;API View&lt;/code&gt;, make sure to add the following in the &lt;code&gt;settings.py&lt;/code&gt; of the project. First, we add &lt;code&gt;AUTHENTICATION_BACKENDS&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;AUTHENTICATION_BACKENDS = (
    &apos;oauth2_provider.backends.OAuth2Backend&apos;,
    # Not required for DOT, but required for Admin
    &apos;django.contrib.auth.backends.ModelBackend&apos;,
)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then we add relevant &lt;code&gt;MIDDLEWARE&lt;/code&gt; for the OAuth Toolkit:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;MIDDLEWARE = (
    &apos;...&apos;,
    # If you use SessionAuthenticationMiddleware, be sure it appears before OAuth2TokenMiddleware.
    # SessionAuthenticationMiddleware is NOT required for using DOT.
    &apos;django.contrib.auth.middleware.SessionAuthenticationMiddleware&apos;,
    &apos;oauth2_provider.middleware.OAuth2TokenMiddleware&apos;,
    &apos;...&apos;,
)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These steps are essentials for getting &lt;code&gt;request.user&lt;/code&gt; function, which will be required while writing the &lt;code&gt;API View&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;Writing the API&lt;/h2&gt;
&lt;p&gt;In the &lt;code&gt;views.py&lt;/code&gt; we&apos;ll write a &lt;code&gt;generic Retrieve API View&lt;/code&gt; which when called along with the authorization token will return the User details. For that, we&apos;ll first write a &lt;code&gt;serializer&lt;/code&gt; that will define our JSON response.&lt;/p&gt;
&lt;h3&gt;Serializer for the User&lt;/h3&gt;
&lt;p&gt;For our JSON response let&apos;s take id, first name, last name, email, and username. In the &lt;code&gt;serializers.py&lt;/code&gt; file write the following Model Serializer class&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;class UserDetailSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = (&apos;id&apos;, &apos;first_name&apos;, &apos;last_name&apos;, &apos;email&apos;, &apos;username&apos;)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;The Retrieve API View&lt;/h3&gt;
&lt;p&gt;In the &lt;code&gt;views.py&lt;/code&gt; file we&apos;ll write the UserDetail View:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;class UserDetailView(generics.RetrieveAPIView):
    &quot;&quot;&quot;
    Use this endpoint to retrieve user.
    &quot;&quot;&quot;
    # Set the AUTH_USER_MODEL in settings.py file to make it work with custom user models as well.
    model = settings.AUTH_USER_MODEL
    serializer_class = UserDetailSerializer
    # Set the permission class if not already set by default
    permission_classes = [permissions.IsAuthenticated]

    def get_object(self, *args, **kwargs):
        return self.request.user
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;The API Path&lt;/h3&gt;
&lt;p&gt;Now that the tough part is over we&apos;ll write the URL Path for the API. In your &lt;code&gt;urls.py&lt;/code&gt; add the following URL pattern.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;urlpatterns = [
    &apos;...&apos;
    path(&apos;api/me/&apos;, UserDetailView.as_view(), name=&apos;me&apos;),
]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That&apos;s all for the coding part, now when you call the &lt;code&gt;http://localhost:8000/api/me/?format=json&lt;/code&gt; with Authorization Header, you&apos;ll get the ID, First Name, Last Name, Email and Username of the user associated with the JSON Web Token.&lt;/p&gt;
</content:encoded><author>Vaibhav Sharma</author></item><item><title>Writing Tests for Authenticated APIs in Django REST Framework</title><link>https://theleakycauldronblog.com/articles/writing-tests-for-authenticated-apis-in-django-rest-framework</link><guid isPermaLink="true">https://theleakycauldronblog.com/articles/writing-tests-for-authenticated-apis-in-django-rest-framework</guid><description>&lt;img alt=&quot;Writing Tests for Authenticated APIs in Django REST Framework&quot; src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Fauthenticated_api_testing.CM-5gLfC.jpg&amp;w=5184&amp;h=3456&amp;dpl=699bfef0c4120e00087ee35a&quot; /&gt; Learn to write tests for Django OAuth Toolkit Authenticated APIs in Django REST Framework.</description><pubDate>Fri, 13 Apr 2018 12:30:00 GMT</pubDate><content:encoded>&lt;p&gt;If you are new to &lt;a href=&quot;http://www.django-rest-framework.org/&quot;&gt;Django Rest Framework&lt;/a&gt; and &lt;a href=&quot;http://dot.evonove.it/&quot;&gt;Django OAuth Toolkit&lt;/a&gt; and are having trouble writing automated tests for your &lt;code&gt;is_authenticated&lt;/code&gt; APIs, you have come to the right place. The problem arises because for a token to be generated we need to first create an application and then retrieve its &lt;code&gt;client_id&lt;/code&gt; and &lt;code&gt;client_secret&lt;/code&gt; before sending it along with username and password for generating &lt;code&gt;access_token&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Before beginning, though we&apos;re gonna work on the following assumptions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;There&apos;s a model called Books.&lt;/li&gt;
&lt;li&gt;There&apos;s a &lt;code&gt;generic.ListAPIView&lt;/code&gt;, with URL name &lt;code&gt;books:list&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;The permission on the URL is &lt;code&gt;is_authenticated&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now that, that&apos;s out of the way, we can begin the fun part.&lt;/p&gt;
&lt;p&gt;In your &lt;code&gt;tests.py&lt;/code&gt; file we create a class called BookListTest:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;from rest_framework.test import APITestCase




class BookListTest(APITestCase):

    pass
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To begin testing, we need a few things set up first, to do so we use the &lt;code&gt;setUp&lt;/code&gt; method. Here we will, first create a &lt;code&gt;test user&lt;/code&gt;, set up a dummy &lt;code&gt;application&lt;/code&gt;, then create &lt;code&gt;two dummy book entries&lt;/code&gt;, and finally define our &lt;code&gt;fetch url&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;class BookListTest(APITestCase):
    def setUp(self):
        # Create a Test User.
        self.test_user = User.objects.create_user(&apos;test&apos;,&apos;user&apos;,&apos;testuser&apos;, &apos;test@example.com&apos;,&apos;testpassword&apos;)
        # Set Up a Test Application
        self.application = Application(
            name = &quot;Test Application&quot;,
            redirect_uris = &quot;http://localhost&quot;,
            user = self.test_user,
            client_type = Application.CLIENT_CONFIDENTIAL,
            authorization_grant_type = Application.GRANT_AUTHORIZATION_CODE,
        )
        self.application.save()
        # Create Entries in our model to fetch the list of.
        self.foo_book = Book(
            title = &quot;foo&quot;
            author = &quot;bar author&quot;
        )
        self.foo_book.save()
        self.bar_book = Book(
            title = &quot;bar&quot;
            author = &quot;foo author&quot;
        )
        self.bar_book.save()
        # URL to fetch the list of the books.
        self.fetch_url = reverse(&quot;books:list&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Everything we write in the above function is created at the beginning of every Test. Now let&apos;s come to writing the actual test. To do that we&apos;ll need an &lt;code&gt;access_token&lt;/code&gt;, and will have to set the &lt;code&gt;authorization header&lt;/code&gt; with the &lt;code&gt;bearer token&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;class BookListTest(APITestView):
    def setUp(self):
    ...
    def test_list_books(self):
        &quot;&quot;&quot;
        Ensure we can list all the books.
        &quot;&quot;&quot;
        # Create A Token
        tok = AccessToken.objects.create(
            user = self.test_user,
            token = &apos;1234567890&apos;,
            application = self.application,
            scope = &apos;read write&apos;,
            expires = timezone.now() + datetime.timedelta(days=1)
        )
        # Set Authorization Header
        auth_headers = {
            &apos;HTTP_AUTHORIZATION&apos;: &apos;Bearer &apos; + tok.token,
        }
        response = self.client.get(self.fetch_url, format=&apos;json&apos;, **auth_headers)
        # Make assertions
        self.assertEqual(response.status_code, status.HTTP_200_OK)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And that&apos;s it, just run the test. But before you do that, make sure you have required &lt;code&gt;imports&lt;/code&gt;. You will need the following imports:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;User&lt;/code&gt;, &lt;code&gt;Book&lt;/code&gt; Models&lt;/li&gt;
&lt;li&gt;from &lt;code&gt;django.urls&lt;/code&gt;, &lt;code&gt;reverse&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;from &lt;code&gt;django.utils&lt;/code&gt;, &lt;code&gt;timezone&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;from &lt;code&gt;oauth2_provider.models&lt;/code&gt;, &lt;code&gt;Application&lt;/code&gt; and &lt;code&gt;AccessToken&lt;/code&gt; models&lt;/li&gt;
&lt;li&gt;from &lt;code&gt;rest_framework&lt;/code&gt;, &lt;code&gt;status&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;datetime&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;from &lt;code&gt;rest_framework.test&lt;/code&gt;, &lt;code&gt;APITestCase&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Happy Testing.&lt;/p&gt;
</content:encoded><author>Vaibhav Sharma</author></item><item><title>Making a marketing website using Gatsby Starter Business</title><link>https://theleakycauldronblog.com/articles/making-a-marketing-website-using-gatsby-starter-business</link><guid isPermaLink="true">https://theleakycauldronblog.com/articles/making-a-marketing-website-using-gatsby-starter-business</guid><description>&lt;img alt=&quot;Making a marketing website using Gatsby Starter Business&quot; src=&quot;https://theleakycauldronblog.com/.netlify/images?url=_astro%2Fgatsby_marketing_website.D_bu9Imv.jpg&amp;w=5184&amp;h=3456&amp;dpl=699bfef0c4120e00087ee35a&quot; /&gt; Make an SEO friendly website, leveraging Gatsby Starter Business, perfect for your marketing needs like Sitemap, Schemas, OpenGraph, Meta Tags, GTM etc</description><pubDate>Tue, 10 Apr 2018 12:30:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; Updated for &lt;em&gt;&lt;strong&gt;gatsby-starter-business v2.1&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Gatsby JS brought something that everyone was waiting for, a React JS based static site generator, and that too a powerful one. True to their boast that it&apos;s really hard to make a sloppy website with Gatsby, making it amazing for marketing websites.&lt;/p&gt;
&lt;p&gt;When I was writing a website for my company, I found my self wanting a Gatsby starter with the following requirements:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It should be powered by &lt;em&gt;Netlify&lt;/em&gt; CMS.&lt;/li&gt;
&lt;li&gt;It should be SEO friendly.&lt;/li&gt;
&lt;li&gt;It should at least have a home page and blog page.&lt;/li&gt;
&lt;li&gt;It should allow proper styling using some CSS framework like &lt;em&gt;Bootstrap&lt;/em&gt; or &lt;em&gt;Bulma&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;While all these features are available in various starters, none of them was a complete package. So, I decided I&apos;ll make one myself:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/v4iv/gatsby-starter-business&quot;&gt;gatsby-starter-business&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Starting a new Gatsby Project&lt;/h2&gt;
&lt;p&gt;Assuming you already have Gatsby CLI installed, to start a new Gatsby JS Project using Gatsby-Starter-Business, open your terminal and run this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;gatsby new &amp;lt;your_project_name&amp;gt; https://github.com/v4iv/gatsby-starter-business
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This will create a clone of Gatsby Starter Business, with project name you gave earlier.&lt;/p&gt;
&lt;h2&gt;Get Started With Gatsby Starter Business&lt;/h2&gt;
&lt;p&gt;To configure Gatsby Starter Business, open &lt;code&gt;config.js&lt;/code&gt; file. Change the required variables and save it. And push it to a new repository in your Github.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;module.exports = {
  siteTitle: &apos;Gatsby Starter Business&apos;, // Site title.
  siteTitleAlt: &apos;Business&apos;, // Alternative site title for SEO.
  siteLogo: &apos;/icons/icon-512x512.png&apos;, // Logo used for SEO and manifest.
  siteUrl: &apos;https://gatsby-starter-business.netlify.com&apos;, // Domain of your website without pathPrefix.
  // Do not use trailing slash!
  pathPrefix: &apos;/&apos;, // Prefixes all links. For cases when deployed to example.github.io/gatsby-starter-business/.
  siteDescription: &apos;Leverage Gatsby Business Starter for your Business.&apos;, // Website description used for RSS feeds/meta description tag.
  siteRss: &apos;/rss.xml&apos;,
  siteFBAppID: &apos;&apos;, // FB Application ID for using app insights
  googleTagManagerID: &apos;&apos;, // GTM tracking ID.
  disqusShortname: &apos;gatsby-business-starter&apos;, // Disqus shortname.
  userName: &apos;Vaibhav Sharma&apos;,
  userTwitter: &apos;vaibhaved&apos;,
  userLocation: &apos;Delhi NCR, India&apos;,
  userDescription: &apos;&apos;,
  copyright: &apos;Copyright © Gatsby Starter Business 2018. All Rights Reserved.&apos;, // Copyright string for the footer of the website and RSS feed.
  themeColor: &apos;#00d1b2&apos;, // Used for setting manifest and progress theme colors.
  backgroundColor: &apos;#ffffff&apos;, // Used for setting manifest background color.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then from Netlify dashboard create a new site from Github for the same repository, and deploy it.&lt;/p&gt;
&lt;p&gt;Once done go to Netlify settings page, and enable Identity, set registration preference and Git Gateway. Create a user from the identity tab of Netlify and visit &lt;a href=&quot;https://yoursiteaddress/admin/#/&quot;&gt;https://yoursiteaddress/admin/#/&lt;/a&gt; login with your Netlify credentials and you&apos;ll be on the admin page. Now you can easily edit pages or add new blog articles.&lt;/p&gt;
</content:encoded><author>Vaibhav Sharma</author></item></channel></rss>