<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="https://www.w3.org/2005/Atom">
	<title>Kushagra Gour- Creativity freak!</title>
	<subtitle>Kushagra Gour- Creativity freak!</subtitle>
	<link href="https://kushagra.dev/feed/feed.xml" rel="self"/>
	<link href="https://kushagra.dev"/>
	<updated>2026-05-06T00:00:00+00:00</updated>
	<id>https://kushagra.dev/feed/feed.xml</id>
	<author>
		<name>Kushagra Gour</name>
	</author>
	
	<entry>
		<title>Vibe-coding on Mac mini from anywhere</title>
		<link href="https://kushagra.dev/blog/vibecoding-on-mac-mini-from-anywhere/"/>
		<updated>2026-05-06T00:00:00+00:00</updated>
		<id>https://kushagra.dev/blog/vibecoding-on-mac-mini-from-anywhere/</id>
		<content type="html">&lt;p&gt;&lt;img src=&quot;https://kushagra.dev/images/og/og-vibecoding-on-macmini.png&quot; alt=&quot;Vibecoding on Mac mini from anywhere&quot;&gt;&lt;/p&gt;
&lt;p&gt;This post is about me wanting to use my Mac mini whenever I’m away from it. This use case started with me wanting to work from another room. Since all my work (and in-progress) is on the Mac mini (and it is not movable), I wanted to keep working on the same machine. (PS: yes I know there is GIT). And working these days means just prompting, so even a reliable SSH connection works. So here is how I did it.&lt;/p&gt;
&lt;h3 id=&quot;step-1%3A-enable-remote-login-(ssh)-on-your-mac-mini&quot;&gt;Step 1: Enable Remote Login (SSH) on your Mac mini &lt;a class=&quot;bookmark&quot; href=&quot;#step-1%3A-enable-remote-login-(ssh)-on-your-mac-mini&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;You need to enable remote SSH on your Mac mini. Open &lt;strong&gt;System Settings → General → Sharing&lt;/strong&gt; and turn on &lt;strong&gt;Remote Login&lt;/strong&gt;. That’s it — your Mac mini is now accepting SSH connections on the local network.&lt;/p&gt;
&lt;h3 id=&quot;step-2%3A-make-ssh-work-outside-your-home-wi%E2%80%91fi-(use-tailscale)&quot;&gt;Step 2: Make SSH work outside your home Wi‑Fi (use Tailscale) &lt;a class=&quot;bookmark&quot; href=&quot;#step-2%3A-make-ssh-work-outside-your-home-wi%E2%80%91fi-(use-tailscale)&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;You still won’t be able to SSH into your Mac mini if you are away from your location, meaning you are not on the home Wi‑Fi. You basically need a public IP for your Mac mini. That’s where &lt;a href=&quot;https://tailscale.com/&quot;&gt;Tailscale&lt;/a&gt; comes in.&lt;/p&gt;
&lt;p&gt;Tailscale gives you a secure private network where you can put all your devices: your Mac mini, your laptop, maybe your phone. Then each device can talk to the others over that private network — as if they were all sitting on the same Wi‑Fi, no matter where in the world they actually are.&lt;/p&gt;
&lt;p&gt;Install Tailscale on both your Mac mini and your client device (laptop, phone), sign in with the same account on both, and you’re done. You’ll get a stable hostname/IP for your Mac mini that works from anywhere.&lt;/p&gt;
&lt;h3 id=&quot;step-3%3A-prevent-the-mac-mini-from-sleeping-(so-it-stays-reachable)&quot;&gt;Step 3: Prevent the Mac mini from sleeping (so it stays reachable) &lt;a class=&quot;bookmark&quot; href=&quot;#step-3%3A-prevent-the-mac-mini-from-sleeping-(so-it-stays-reachable)&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Cool, so now you can SSH to your Mac mini from anywhere in the world.&lt;/p&gt;
&lt;p&gt;The issue is that most of us have a sleep timeout set on a Mac mini. This means that after a while the display turns off, then after some time the hard disk turns off, and the system goes to sleep.&lt;/p&gt;
&lt;p&gt;When that happens, your SSH connection breaks and your Mac mini won’t be accessible anymore. You won’t be able to set up a new SSH connection either.&lt;/p&gt;
&lt;p&gt;So we need to do one more thing to prevent it from sleeping. Run this command on your Mac mini:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;sudo&lt;/span&gt; pmset &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; disablesleep &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This makes sure your Mac mini does not sleep even after the display turns off. After some time the display will turn off, but don’t worry — at this point it will still be SSH-able.&lt;/p&gt;
&lt;p&gt;Just make sure you don’t put your Mac mini to sleep explicitly (Eg. from Apple menu &amp;gt; Sleep). In that case, it won’t be accessible.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;strong&gt;One important thing: don’t run this command on your laptop.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Laptops can be inside bags while they are on. If they don’t go to sleep when the lid is closed, ventilation can be blocked and the laptop can heat up.&lt;/p&gt;
&lt;p&gt;This also applies to your Mac mini if it’s not properly ventilated or kept in a cool area. If so, avoid this.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;step-4%3A-keep-work-running-even-if-your-client-device-sleeps-(use-tmux)&quot;&gt;Step 4: Keep work running even if your client device sleeps (use tmux) &lt;a class=&quot;bookmark&quot; href=&quot;#step-4%3A-keep-work-running-even-if-your-client-device-sleeps-(use-tmux)&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Now you can SSH to your Mac mini from anywhere in the world and your Mac mini won’t sleep. It will always be accessible over SSH.&lt;/p&gt;
&lt;p&gt;But what about the machine you are SSH-ing from?&lt;/p&gt;
&lt;p&gt;In my case, it was my MacBook Air. I can SSH into my Mac mini and then open Claude Code, give it a prompt, and the thing starts running.&lt;/p&gt;
&lt;p&gt;Now let’s say I have to go somewhere and I close the lid of my MacBook Air. That will put the MacBook Air to sleep after some time, and then the SSH connection will terminate. That means the Claude Code run would also stop midway, and your work will be lost.&lt;/p&gt;
&lt;p&gt;We need to do one final thing: when you SSH to your Mac mini, you should use the terminal through &lt;strong&gt;tmux&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;tmux is a terminal multiplexer that also has state persistence. If you run a session through tmux, anything that is going on will keep running even if the SSH connection closes.&lt;/p&gt;
&lt;p&gt;That gives you two benefits:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Your MacBook Air, or whatever client device you are using, can go to sleep at any time. You can just walk away or shut down your client device, and your Mac mini will keep running Claude Code (or whatever you’re running) even if the SSH connection terminates. Next time you SSH back in, you just attach to the tmux session and pick up exactly where you left off.&lt;/li&gt;
&lt;li&gt;A tmux session can also have multiple panes, just like you have in terminals like iTerm and Ghostty. To work on any project, you can maintain a tmux session per project which probably would have multiple panes for say, claude code, your server, vim etc etc. As soon as you attach to a particular session, all the panes related to that project — which you had opened last time — open up in one go. This is so cool to get in that working state very quickly. Also applies if you are working on a single machine too.&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;PS: Credit to this tip goes to &lt;a href=&quot;https://x.com/ayysoni&quot;&gt;Ayush Soni&lt;/a&gt; who suggested this at the IndieHacking Retreat when I refused to close my laptop lid! 😆&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;That’s it. Three small pieces — SSH, Tailscale, and tmux — and your Mac mini quietly becomes a Vibe-coding machine you can use from anywhere, with work that survives sleeps and disconnects on either end.&lt;/p&gt;
&lt;h3 id=&quot;bonus-update%3A-try-zellij-instead-of-tmux&quot;&gt;Bonus update: try Zellij instead of tmux &lt;a class=&quot;bookmark&quot; href=&quot;#bonus-update%3A-try-zellij-instead-of-tmux&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;tmux is actually painful to use sometimes. I don’t like its default keyboard shortcuts. You can’t easily copy things from there. Even when you get it working, it works only half the time. No good mouse support either.&lt;/p&gt;
&lt;p&gt;Ayush recently suggested a newer terminal multiplexer called &lt;a href=&quot;https://zellij.dev/&quot;&gt;Zellij&lt;/a&gt;. I gave it a quick spin and am liking it. So try that too.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>AI and my direction</title>
		<link href="https://kushagra.dev/blog/ai-and-my-direction/"/>
		<updated>2026-02-16T00:00:00+00:00</updated>
		<id>https://kushagra.dev/blog/ai-and-my-direction/</id>
		<content type="html">&lt;p&gt;For the past five or six months, I’ve been thinking deeply about the recent changes happening in the world of AI — what it means for how we work today, and what the future might look like.&lt;/p&gt;
&lt;p&gt;PS: If you haven’t paused to reflect on this shift yet, you might be missing something important.&lt;/p&gt;
&lt;p&gt;During this time, I’ve been re-evaluating my own style of work and how I can better leverage AI, while also thinking about what my future could look like. I had been meaning to write about these thoughts for months, and finally got inspired to put them into words after &lt;a href=&quot;https://x.com/mattshumer_/status/2021256989876109403&quot;&gt;reading this post&lt;/a&gt; by Matt Shumer.&lt;/p&gt;
&lt;p&gt;This article is essentially a collection of those reflections.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;ai-anxiety&quot;&gt;AI Anxiety &lt;a class=&quot;bookmark&quot; href=&quot;#ai-anxiety&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Let’s begin with a term I recently saw somewhere on the socials — &lt;strong&gt;AI anxiety&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;It’s obvious why people feel anxious about AI. When something is being developed that can potentially do exactly what you do for a living — and possibly do it better — fear is a natural reaction. Interestingly, I don’t personally feel that anxiety, and I spent some time asking myself why.&lt;/p&gt;
&lt;p&gt;I think it comes down to how I define who I am. I don’t see myself strictly as a developer or tied to a single profession. I see myself as a &lt;strong&gt;Builder&lt;/strong&gt; — someone who currently builds software, but isn’t limited to it. I equally enjoy creating art pieces, designing in-person experiences, woodworking, making music, and many other forms of creation.&lt;/p&gt;
&lt;p&gt;Even if software development eventually becomes something AI can fully handle, it wouldn’t feel like the end of what I do. I would simply build something else. And that feels completely fine.&lt;/p&gt;
&lt;p&gt;In a way, passions should be diversified just like an investment portfolio. You don’t want a single failed investment to collapse your entire portfolio, and similarly, you don’t want one skill or passion becoming obsolete to bring down your entire career.&lt;/p&gt;
&lt;p&gt;Diversify.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;a-paradigm-shift%3A-personal-software&quot;&gt;A Paradigm Shift: Personal Software &lt;a class=&quot;bookmark&quot; href=&quot;#a-paradigm-shift%3A-personal-software&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Software is what I spend most of my time building, and a major shift is already underway.&lt;/p&gt;
&lt;p&gt;We are writing significantly less code today. With the latest AI models, in many cases you can avoid writing code entirely. You can simply describe the software you want in a few sentences, and the model can generate a working implementation. And this capability is improving every day.&lt;/p&gt;
&lt;p&gt;This leads to an important question:&lt;br&gt;
&lt;strong&gt;If everyone can create software for themselves, will people continue buying software made by others?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I suspect the answer is increasingly no.&lt;/p&gt;
&lt;p&gt;Soon, individuals may be able to simply describe what they need and receive polished, robust software tailored specifically to them. One common counter-argument is that people will still value “taste” — beautiful design and thoughtful craftsmanship created by humans.&lt;/p&gt;
&lt;p&gt;But from what I’ve seen, AI models are already beginning to demonstrate what we traditionally call taste. And given the exponential pace of progress in AI, it may not be long before AI closely replicates the aesthetic judgment we associate with human designers today.&lt;/p&gt;
&lt;p&gt;What I believe will happen is this: powerful AI systems will build highly reliable personal software for each individual. Software will become so trustworthy and personalized that traditional visual interfaces may become less important. Instead of navigating apps, you might simply speak or write what you want done and receive the result — likely through a simple conversational interface.&lt;/p&gt;
&lt;p&gt;And when the interface itself starts disappearing, the importance of visual taste may diminish as well.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;what-will-matter%3A-experiences-and-human-interaction&quot;&gt;What Will Matter: Experiences and Human Interaction &lt;a class=&quot;bookmark&quot; href=&quot;#what-will-matter%3A-experiences-and-human-interaction&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If software becomes personal and infinitely customizable, does that mean people will stop building software for others?&lt;/p&gt;
&lt;p&gt;I don’t think so.&lt;/p&gt;
&lt;p&gt;There will still be software that people use together — software that cannot be reduced to simple CRUD functionality. These will be &lt;strong&gt;shared experiences&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Even if AI can build perfectly tailored software for an individual, it cannot easily recreate the experience of thousands of people participating together in something meaningful. As the world becomes increasingly digital and potentially more isolated, people will seek experiences they can share with others — both online and in person.&lt;/p&gt;
&lt;p&gt;Human interaction itself becomes the value.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;cssbattle&quot;&gt;CSSBattle &lt;a class=&quot;bookmark&quot; href=&quot;#cssbattle&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;This belief strongly connects to CSSBattle.&lt;/p&gt;
&lt;p&gt;CSSBattle isn’t special because of its technology or gameplay mechanics alone. It is what it is because of its players. The real value comes from the experience of competing in real time alongside other human developers.&lt;/p&gt;
&lt;p&gt;Earlier, I mentioned a future where people may not need to write code manually anymore. Yet I believe there will always be passionate programmers — people like me — who can get work done with AI but still feel something missing when they no longer write code by hand. Not because they can’t, but because the future simply doesn’t require it.&lt;/p&gt;
&lt;p&gt;When that happens, CSSBattle can become a place where developers come to chill, write code, compete with other humans, and enjoy the craft itself.&lt;/p&gt;
&lt;p&gt;That’s why I believe CSSBattle will be incredibly valuable in the future. I’m very bullish on it, and I’m not giving up on it anytime soon.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;physical-products-and-experiences&quot;&gt;Physical Products and Experiences &lt;a class=&quot;bookmark&quot; href=&quot;#physical-products-and-experiences&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;This year, my direction isn’t limited to CSSBattle or software alone.&lt;/p&gt;
&lt;p&gt;I want to move more deeply into physical products and real-world experiences. My plans include organizing in-person CSSBattle conferences, building a clothing line inspired by ancient Vedic heritage, and creating a calm, serene café of my own — among other ideas.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion &lt;a class=&quot;bookmark&quot; href=&quot;#conclusion&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To summarize: I’m genuinely excited about the future and the possibilities that AI has unlocked.&lt;/p&gt;
&lt;p&gt;Rather than seeing AI as something that replaces what we do, I see it as something that reshapes where we direct our creativity and energy.&lt;/p&gt;
&lt;p&gt;And I look forward to seeing you at one of the experiences I launch soon.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Getting started with Chrome&#39;s Inbuilt AI</title>
		<link href="https://kushagra.dev/blog/chrome-inbuilt-ai-getting-started/"/>
		<updated>2025-04-14T00:00:00+00:00</updated>
		<id>https://kushagra.dev/blog/chrome-inbuilt-ai-getting-started/</id>
		<content type="html">&lt;p&gt;I recently wanted to tinker with Chrome&#39;s in-built AI, that uses the Gemini nano LLM. Though there are several articles/videos around getting started with it, I am still writing this guide post because most of them are dated now. Because the in-built AI is an experimental feature, it is undergoing very rapid iterations and so within a few months, all the information out there becomes old and invalid - even the official docs.&lt;/p&gt;
&lt;p&gt;So if you want to get started with the in-built AI on Chrome (on Apr 14, 2025), follow along!&lt;/p&gt;
&lt;h2 id=&quot;browser-version&quot;&gt;Browser version &lt;a class=&quot;bookmark&quot; href=&quot;#browser-version&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In-built AI isn&#39;t limited to dev/carany channel anymore. You can try it on stable Chrome too.&lt;/p&gt;
&lt;h2 id=&quot;the-experimental-flags&quot;&gt;The experimental flags &lt;a class=&quot;bookmark&quot; href=&quot;#the-experimental-flags&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Switch on the following 2 experimental flags from &lt;code&gt;chrome://flags&lt;/code&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;chrome://flags/#optimization-guide-on-device-model&quot;&gt;Enables optimization guide on device&lt;/a&gt; - Set it to Enable BypassPerPerfRequirement&amp;quot;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;chrome://flags/#prompt-api-for-gemini-nano&quot;&gt;Prompt API for Gemini Nano&lt;/a&gt; - Set it to &amp;quot;Enabled&amp;quot;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;And now relaunch your Chrome.&lt;/p&gt;
&lt;h2 id=&quot;downloading-the-model&quot;&gt;Downloading the model &lt;a class=&quot;bookmark&quot; href=&quot;#downloading-the-model&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If the model is downloaded or downloading, you would see &amp;quot;Optimization Guide On Device Model&amp;quot; listed on &lt;a href=&quot;chrome://components/&quot;&gt;chrome://components/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;For me the model, didn&#39;t download automatically, so I saw nothing there. In that case, first check if the LLM is available to you or not. Open the developer tools, go to Console and run:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; ai&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;languageModel&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;availability&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It should return &amp;quot;downloadable&amp;quot;. If yes, run the following:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ai&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;languageModel&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token function&quot;&gt;monitor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;    m&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addEventListener&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;downloadprogress&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;      console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;Downloaded &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;e&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;loaded &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; e&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;total&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This basically triggers the model to download on your machine and also adds a listener to the progress event of this process - so that you know when it has finished downloading.&lt;/p&gt;
&lt;p&gt;Note: Even during download, if you visit &lt;a href=&quot;chrome://components/&quot;&gt;chrome://components/&lt;/a&gt;, you should now see &amp;quot;Optimization Guide On Device Model&amp;quot; listed.&lt;/p&gt;
&lt;h2 id=&quot;using-ai&quot;&gt;Using AI &lt;a class=&quot;bookmark&quot; href=&quot;#using-ai&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Once the LLM has downloaded, you can verify it by running the following in the developer console:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; ai&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;languageModel&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;availability&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and it should return &amp;quot;available&amp;quot;! ✅&lt;/p&gt;
&lt;p&gt;Now, run a small example to test out the new AI:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; _ai &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ai&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;languageModel&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; _ai&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;prompt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;a small poem in 100 chars about dog&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;figure&gt;
    &lt;img src=&quot;https://kushagra.dev/images/2025/chromeai-example.png&quot; alt=&quot;&quot;&gt;
    &lt;figcaption&gt;Running a small example to test Chrome AI.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;That is it! Have fun!&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Mistake - Making an async function sync</title>
		<link href="https://kushagra.dev/blog/mistake-removing-async-function/"/>
		<updated>2024-06-06T00:00:00+00:00</updated>
		<id>https://kushagra.dev/blog/mistake-removing-async-function/</id>
		<content type="html">&lt;p&gt;I recently migrated Firebase to the latest version in &lt;a href=&quot;https://webmaker.app/&quot;&gt;WebMaker&lt;/a&gt; app. As part of the migration the way database instance is retrieved changed from asynchronous to synchronous. Earlier, I had a function to get the db instance, like so:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; dbPromise&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// a promise that gets defined somewhere&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getDb&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; dbPromise&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// resolved to a dbInstance&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And then wherever I wanted to do some operation in the DB, this is how would use the above &lt;code&gt;getDb&lt;/code&gt; function:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;doSomethingWithDb&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; db &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getDb&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getDoc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;doc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;db&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;colId/userId&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then I did the migration to latest Firebase which removed the async part in getting the db instance. So it was time to make a few things synchronous. To keep changes minimal, I made the &lt;code&gt;getDb&lt;/code&gt; function return the &lt;code&gt;dbInstance&lt;/code&gt; directly, instead of a promise:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getDb&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; dbInstance&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And since I wasn&#39;t returning any promise now, I could use the &lt;code&gt;db&lt;/code&gt; without an &lt;code&gt;await&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;doSomethingWithDb&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; db &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getDb&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getDoc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;doc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;db&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;colId/userId&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But this didn&#39;t work! I got error from Firebase about wrong database instance being passed to it. But I was passing the same thing which I got from promise resolution earlier, being returned directly from &lt;code&gt;getDb&lt;/code&gt; now. Oh wait...I spotted the mistake I made. It doesn&#39;t matter what you return from an &lt;code&gt;async&lt;/code&gt; function, it always returns a promise. I had missed removing the &lt;code&gt;async&lt;/code&gt; keyword from the &lt;code&gt;getDb&lt;/code&gt; function and so it was still returning a promise. The fix was simple - changing the &lt;code&gt;getDb&lt;/code&gt; to:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getDb&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; dbInstance&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And that fixed it!&lt;/p&gt;
&lt;p&gt;I’ll see you again with my next mistake! 👋🙂&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Google maps street view hack</title>
		<link href="https://kushagra.dev/blog/google-map-street-view-hack/"/>
		<updated>2024-05-23T00:00:00+00:00</updated>
		<id>https://kushagra.dev/blog/google-map-street-view-hack/</id>
		<content type="html">&lt;p&gt;I want to share a Google maps hack I executed recently. I think it was a super fun one! 😄 So story goes like...there is a mobile/laptop repair store in a market around 8kms far from my place. My brother had given a laptop for repair there but accidently misplaced the receipt that store gave and hence their contact number. Now he wanted to contact that store to get an update and doesn&#39;t have their contact number anymore! What do we do? Let the hacking beging! 😎&lt;/p&gt;
&lt;h2 id=&quot;chapter-1&quot;&gt;Chapter 1 &lt;a class=&quot;bookmark&quot; href=&quot;#chapter-1&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Obviously I opened Google maps first to search for mobile and computer repair stores in that area. I know the exact geolocation of that store. So I could localize my search. Now, remember that we don&#39;t even know the name of that store 😅 Since I didn&#39;t know the name of the store, I couldn&#39;t search it by name. So I checked out all stores that came in my search, checked their pictures to identify.&lt;br&gt;
Unfortunately, that store isn&#39;t listed on Google and hence no luck in the search!&lt;/p&gt;
&lt;h1 id=&quot;chapter-2&quot;&gt;Chapter 2 &lt;a class=&quot;bookmark&quot; href=&quot;#chapter-2&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;While wandering in Google maps, the street view icon caught my attention. I had played with the street view before one or two times but never for any use case. In fact, when I tried it this time I actually realized it worked pretty good in my location (Uttar Pradesh, India) too!&lt;br&gt;
As soon as I entered the street view, I realized I can just walk down the street to that shop! Good thing is that in India, almost every shop has their contact number on their signboard. Ray of hope! ⛅ And so I started walking happily (and digitally) in the market streets to reach that shop and there it was. But wait! That particular shop doesn&#39;t have their contact number on their sign board...what!!!&lt;/p&gt;
&lt;figure&gt;
    &lt;img src=&quot;https://kushagra.dev/images/2024/googlemap-hack-1.png&quot; alt=&quot;&quot;&gt;
    &lt;figcaption&gt;The target shop with its signboard and name on it.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;But, their name was on the signboard. Ah...at least some information.&lt;/p&gt;
&lt;h1 id=&quot;chapter-3&quot;&gt;Chapter 3 &lt;a class=&quot;bookmark&quot; href=&quot;#chapter-3&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;The next immediate thing I did was to google the name of the store. And weird enough, the store was listed on Google. Not sure why it didn&#39;t shop in the map search earlier. But this was of no use because they had not put their contact number in the google listing. 🤦🏼‍♂️&lt;/p&gt;
&lt;h1 id=&quot;chapter-4&quot;&gt;Chapter 4 &lt;a class=&quot;bookmark&quot; href=&quot;#chapter-4&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;I was clueless now. I didn&#39;t want to drive down the market just to ask the store for an update! Then I started thinking if I know someone there who could fetch me the store&#39;s contact number. At one point I was even thinking of asking in my society&#39;s whatsapp group if anyone is going to that market...and ask them a favour! 😆&lt;/p&gt;
&lt;p&gt;Just then it clicked me - why not ask another shop besides it to get my store&#39;s number?? Yeah, why not! Most people would say no, but someone might just agree. To maximise my success chances here I felt that only a small roadside &lt;em&gt;thela&lt;/em&gt; (mobile/portable shop) person could be helpful here. Someone who is nearby to that store and also mobile n humble enough to do me a favour. I remembered there are a lot of such mobile street-side tempered-glass shops. They could be my saviour!&lt;/p&gt;
&lt;p&gt;So I went inside the street view again, started walking down the street from the target store...in search for that tempered-glass &lt;em&gt;thela&lt;/em&gt;. And there it was - I had found one! This wasn&#39;t enough though. That &lt;em&gt;thela&lt;/em&gt; had to satisfy either of the following 2 conditions for me to contact it. Either:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;have itself listed on google&lt;/li&gt;
&lt;li&gt;or have a signboard and its phone number on the signboard&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It wasn&#39;t listed on Google...as expected. Fortunately, it had a small signboard and...its phone number written on it too! WOhoo! First hundle cleared! 🏁&lt;/p&gt;
&lt;p&gt;This is that shop:&lt;/p&gt;
&lt;figure&gt;
    &lt;img src=&quot;https://kushagra.dev/images/2024/googlemap-hack-2.png&quot; alt=&quot;&quot;&gt;
    &lt;figcaption&gt;The small tempered-glass *thela* near the target store.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&quot;final-chapter&quot;&gt;Final chapter &lt;a class=&quot;bookmark&quot; href=&quot;#final-chapter&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The final step was to contact this shop person, ask him for a favour and hope that he agrees to it 🤞🏼. I called the shop, explained my situation and requested him to get that store&#39;s number. I even said I am ready to pay him for his time...but he humbly said no to it. 🙂 He said I am just setting my shop for the day and will get the number in half an hour. I waited impatiently like a child waiting for exam results 😅.&lt;/p&gt;
&lt;p&gt;And almost after half an hour, I got a whatsapp message from the shop guy - he had sent me a number! 🥳 Jackpot!&lt;/p&gt;
&lt;p&gt;I am so happy with this hack I pulled off sitting on my couch at home. Made me wonder (yet again) how technology has enabled us so much! This was fun and hope you had fun reading it too! Until next time. 👋🏼&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>My first Woodwork</title>
		<link href="https://kushagra.dev/blog/my-first-woodwork/"/>
		<updated>2024-03-18T00:00:00+00:00</updated>
		<id>https://kushagra.dev/blog/my-first-woodwork/</id>
		<content type="html">&lt;p&gt;Sometime back I wrote a post on this &lt;a href=&quot;https://kushagra.dev/blog/todo-after-financial-freedom/&quot;&gt;blog about things I want to do once I gain financial freedom&lt;/a&gt;. One of those things was opening a Wood workshop. Today, I am pleased to report that I have finished my first wood working project! This is what I made:&lt;/p&gt;
&lt;figure&gt;
    &lt;img src=&quot;https://kushagra.dev/images/2024/woodshelf-finished.jpg&quot; alt=&quot;&quot;&gt;
    &lt;figcaption&gt;The finished rope hanging solid wood shelf&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;For those who are interested about how I made this, read on!&lt;/p&gt;
&lt;h2 id=&quot;backstory&quot;&gt;Backstory &lt;a class=&quot;bookmark&quot; href=&quot;#backstory&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;My wife recently started trying her hands on handicraft gifts. Her table soon got occupied with multiple accessories, tools and what not - leaving her very little space to do actual work. I wanted to solve this for her and thanks to my deep interest in woodworking, I decided to build the solution myself! 😎 And so started this fun journey of BYOS (Build your own shelf)!&lt;/p&gt;
&lt;h2 id=&quot;type-of-shelf&quot;&gt;Type of shelf &lt;a class=&quot;bookmark&quot; href=&quot;#type-of-shelf&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I first wanted to decide what kind of shelf to build. I saw a bunch of videos on YouTube and searched Amazon to understand different kind of shelves out there - mainly in terms of how they attach to the wall. Some hang, some get screwed, some need brackets etc etc&lt;br&gt;
Based on difficulty level and resources required, I decided on the following:&lt;/p&gt;
&lt;figure&gt;
    &lt;img src=&quot;https://kushagra.dev/images/2024/woodshelf-target.jpg&quot; alt=&quot;A wooden shelf on 2 brackets&quot;&gt;
    &lt;figcaption&gt;The design I decided to build&lt;/figcaption&gt;
&lt;/figure&gt;
I liked this design for a few reasons:
&lt;ol&gt;
&lt;li&gt;It was very easy on the wooden plank side (nothing required there) apart from a slight groove at the bottom for keeping brackets in place.&lt;/li&gt;
&lt;li&gt;Wooden plank can be easily replaced with a longer one in future.&lt;/li&gt;
&lt;li&gt;Brackets are easy to hand on wall&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;PS: This wooden shelf is available on around INR 500, for 2 shelves. But its not solid wood.&lt;/p&gt;
&lt;h2 id=&quot;the-wooden-plank&quot;&gt;The wooden plank &lt;a class=&quot;bookmark&quot; href=&quot;#the-wooden-plank&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Immediately after, I starting searching for a solid wood plank. I checked out some online stores, but they had too expensive ones. So I thought about checking with some local wood workers near my place. But before I could do that, I had a chance to visit our gaushala (farmhouse) recently. And it couldn&#39;t have been a more fortunate visit - I found a good and old plank of solid wood there! I was so excited to get it - it was of perfect length for building 2 shelves! 🤩&lt;/p&gt;
&lt;figure&gt;
    &lt;img src=&quot;https://kushagra.dev/images/2024/woodshelf-plank.jpg&quot; alt=&quot;A wooden plank of very old wood&quot;&gt;
    &lt;figcaption&gt;The old wood plank I found at our gaushala&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&quot;getting-the-plank-ready&quot;&gt;Getting the plank ready &lt;a class=&quot;bookmark&quot; href=&quot;#getting-the-plank-ready&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The plank had to shaped down first to remove old paint and make it flat. There is a local furniture shop here from which we have got quite some things made in the past. I decided that I would go there and request the owner to let me work in their workshop. I would just use their tools and nothing else. Worst case I thought if they didn&#39;t agree to it, I would just ask them to do it for a price.&lt;/p&gt;
&lt;p&gt;So on a fine weekend, I put the plank in my car and went to that furniture shop, asked the owner and he agreed! At their workshop I found the carpenter who had also built an almirah for us recently. I had a little chat with him and he showed me the tools there.&lt;/p&gt;
&lt;p&gt;I got down to the first part - removing old nails from the wood. Some nails got removed, but some just broke and left part inside. The carpenter there helped me with this. Next was the smoothing the plank. This is done using a tool called &lt;strong&gt;Hand Plane&lt;/strong&gt; (&lt;em&gt;Randa&lt;/em&gt;). It was my first time using this tool. Fun fact, there was just one Hand plane in the workshop. So the carpenter kept asking me for it, for his own work. And everytime he used it, I watched him carefully and learnt something new about how to use that tool. Still it took me good 1.5 hours to smooth one side of the plank and the sides. I left the other side because it was anyways going to be hidden from view.&lt;/p&gt;
&lt;figure&gt;
    &lt;img src=&quot;https://kushagra.dev/images/2024/woodshelf-plane.jpg&quot; alt=&quot;Me smoothing the plank with a hand plane in the workshop&quot;&gt;
    &lt;figcaption&gt;Smoothing the plank with a Hand plane (&lt;em&gt;Randa&lt;/em&gt;)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;I was so amazed to see fresh wood coming out every minute during this process...felt like magic! Once the wood was smooth enough, I got it cut into 2 pieces - one for each shelf. Here is the end result of this phase:&lt;/p&gt;
&lt;figure&gt;
    &lt;img src=&quot;https://kushagra.dev/images/2024/woodshelf-smooth.jpg&quot; alt=&quot;2 pieces of smoothened wooden plank&quot;&gt;
    &lt;figcaption&gt;Ultra-smooth 2 planks ready!&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&quot;some-more-finishing&quot;&gt;Some more finishing &lt;a class=&quot;bookmark&quot; href=&quot;#some-more-finishing&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;While I was leaving that workshop with my two wooden planks, I saw one of the carpenters sanding some wood. I had seen this thing in woodworking videos. Sanding is basically smoothening the wood some more with hand sand paper (or machine). I asked what kinda sand paper it was...he said it was No. 80. So while my wayback home, I got some materials:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;2 Sand papers of No. 80&lt;/li&gt;
&lt;li&gt;A Teak finish wood polish&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;After some sanding, polish and then some more sanding, I got this:&lt;/p&gt;
&lt;figure&gt;
    &lt;img src=&quot;https://kushagra.dev/images/2024/woodshelf-polished.jpg&quot; alt=&quot;Polished planks with polish bottle and brush&quot;&gt;
    &lt;figcaption&gt;Sanded and polished 😍&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&quot;the-brackets&quot;&gt;The brackets &lt;a class=&quot;bookmark&quot; href=&quot;#the-brackets&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;According to the design, I needed 4 metal brackets. I asked a local Iron fabricator to make such brackets but he asked me 200 rupees for one such bracket i.e. 800 for 4 - much more than the full cost of shelves on Amazon! 😅 So that way didn&#39;t work. I started thinking alternative to metal brackets and the next best thing was - Rope.&lt;/p&gt;
&lt;p&gt;One way was to simply replace the bracket with rope but that would still need the grooves made on the wood - to keep the rope from slipping off the plank. Moreover, I wasn&#39;t sure if the plank would now stay horizontal on that flexible shaky rope. So I changed a bit. Instead of rope going around the wood, I decided to drill holes on 4 sides of the plank and hang the plank though rope, with rope itself handing on wall hooks.&lt;/p&gt;
&lt;figure&gt;
    &lt;img src=&quot;https://kushagra.dev/images/2024/woodshelf-drill.jpg&quot; alt=&quot;Wooden plank with my Bosch Drill kit&quot;&gt;
    &lt;figcaption&gt;Drilling work begins&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;4 holes and some rope-tying later, the shelf was ready to be hanged! I liked this way as it allows to easily asjust the plank&#39;s alignment through the rope knots.&lt;/p&gt;
&lt;figure&gt;
    &lt;img src=&quot;https://kushagra.dev/images/2024/woodshelf-ready.jpg&quot; alt=&quot;Shelf ready with rope tied on both sides&quot;&gt;
    &lt;figcaption&gt;Shelves ready with ropes tied on both sides&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Now all that was required was to hang the shelves at the spot! So I drilled some holes in the wall, inserted some hooks and voila!&lt;/p&gt;
&lt;figure&gt;
    &lt;img src=&quot;https://kushagra.dev/images/2024/woodshelf-finished.jpg&quot; alt=&quot;The finished shelf hanging on the wall with items kept on it&quot;&gt;
    &lt;figcaption&gt;The finished shelf!&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
    &lt;img src=&quot;https://kushagra.dev/images/2024/woodshelf-finished2.jpg&quot; alt=&quot;&quot;&gt;
    &lt;figcaption&gt;The finished shelf, from the side&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;I am so happy I could start on my dream and also with what I could build in my first try! 😃 I hope to continue to build more whenever I get a chance. Thanks for reading 👋🏼&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Mistake - forgot to deploy indexes</title>
		<link href="https://kushagra.dev/blog/mistake-forgot-to-deploy-indexes/"/>
		<updated>2023-10-08T00:00:00+00:00</updated>
		<id>https://kushagra.dev/blog/mistake-forgot-to-deploy-indexes/</id>
		<content type="html">&lt;p&gt;Now that we have a staging environment for &lt;a href=&quot;https://cssbattle.dev/&quot;&gt;CSSBattle&lt;/a&gt;, we develop all features there i.e. local frontend is connected to staging project on Firebase. This feature involved a firestore security change. I tested the whole thing on local and then deployed it to production. Since it involved a security rule change, I made the same change on the production project too. And then, it broke on production!&lt;br&gt;
I couldn&#39;t figure out why it was not working. There was nothing wrong in the production data too! Finally I had to ask one of our users for any error that might be showing in their developer console. And there it was - there was a missing index on Firestore. The feature also required a new index to be created in Firestore, which I did in the staging project but forgot to create on production.&lt;/p&gt;
&lt;h2 id=&quot;learnings-and-fixes&quot;&gt;Learnings and fixes &lt;a class=&quot;bookmark&quot; href=&quot;#learnings-and-fixes&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;I still make changes to Firestore security rules and indexes manually from the web UI. Firebase has a nice way to have all the configs in source files and deploy them from the command line. Had I used the source files method 1) I would have seen the diff in the PR 2) Automated the deployment of rules and indexes from command line.&lt;/li&gt;
&lt;li&gt;I had to ask a user for the error in console 🤦🏼‍♂️ This actually reminded me that we have Sentry on the frontend but since I haven&#39;t made use of it ever I totally forgot about it! Need to be more active there.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;See you in my next mistake!&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>CSS-only 3D card</title>
		<link href="https://kushagra.dev/blog/css-only-3d-card/"/>
		<updated>2023-09-03T00:00:00+00:00</updated>
		<id>https://kushagra.dev/blog/css-only-3d-card/</id>
		<content type="html">&lt;p&gt;In this post we&#39;ll build a 3D card with just CSS. Yes, just CSS! This is sort of an extension to my last post - &lt;a href=&quot;https://kushagra.dev/blog/scroll-based-3d-cards/&quot;&gt;&amp;quot;Scroll-based 3d cards&amp;quot;&lt;/a&gt;. So if you haven&#39;t read that already, I recommend you read that first.&lt;/p&gt;
&lt;p&gt;Few more things about what we are building here. It will be a 3d card that can be rotated and viewed by same gesture as if you are scrolling the page - horizontally and vertically. This used scroll-linked animations feature in CSS, which as of writing this article is only supported in Chrome &amp;amp; Edge. &lt;a href=&quot;#final-demo-%F0%9F%A5%B3&quot;&gt;See the final demo&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;1.-get-the-card&quot;&gt;1. Get the Card &lt;a class=&quot;bookmark&quot; href=&quot;#1.-get-the-card&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;card-wrap&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;card&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;.card-wrap&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;display&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; grid&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;place-content&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; center&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;inset&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 0&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;transform-style&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; preserve-3d&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;perspective&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 800px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token selector&quot;&gt;.card&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;border-radius&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 1.5rem&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 80vh&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;aspect-ratio&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 9 / 16&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;background&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token url&quot;&gt;&lt;span class=&quot;token function&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string url&quot;&gt;&quot;https://cdn.midjourney.com/f87ef132-b7e1-40a4-9e7c-0bf90e7e7724/0_3.png&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;background-size&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; cover&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;box-shadow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 50px 50px 30px &lt;span class=&quot;token function&quot;&gt;rgba&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;0&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 0&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 0&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 0.3&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;transform&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;rotateX&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;10deg&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;rotateY&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;10deg&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Few things about the code above:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;.card-wrap&lt;/code&gt; solves 2 purposes here - acts as a container to center our card. And also to give a 3D perspective to our card.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.card&lt;/code&gt; is a usual card which takes 80% of viewport height and has 16:9 aspect ratio. It has a cool background image which I generated through Midjourney for this demo.&lt;/li&gt;
&lt;li&gt;For now the card has a static shadow and rotation which we&#39;ll make dynamic as we go!&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Here is what we get:&lt;/p&gt;
&lt;p&gt;&lt;div class=&quot;demo-frame&quot; style=&quot;--height:600px&quot;&gt; &lt;iframe srcDoc=&quot;&lt;div class=&amp;quot;card-wrap&amp;quot;&gt;&lt;div class=&amp;quot;card&amp;quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;style&gt;.card-wrap {display: grid;place-content: center;inset: 0;transform-style: preserve-3d;perspective: 800px;}.card {border-radius: 1.5rem;height: 80vh;aspect-ratio: 9 / 16;background: url(&amp;quot;https://cdn.midjourney.com/f87ef132-b7e1-40a4-9e7c-0bf90e7e7724/0_3.png&amp;quot;);background-size: cover;box-shadow: 50px 50px 30px rgba(0, 0, 0, 0.3);transform: rotateX(10deg) rotateY(10deg);}&lt;/style&gt;&quot;&gt;&lt;/iframe&gt; &lt;/div&gt;&lt;/p&gt;
&lt;h2 id=&quot;2.-bring-in-some-scroll&quot;&gt;2. Bring in some scroll &lt;a class=&quot;bookmark&quot; href=&quot;#2.-bring-in-some-scroll&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;This is an interesting illusion! As I mentioned before, we&#39;ll enable card rotation through scroll. Which means if you have double finger scroll gesture on your track pad, you can very intuitively use it to explore the card from all angles. But, how do we get scroll on the page,...there is nothing overflowing from our page? For that, we&#39;ll create a dummy invisble element which is so big that it overflows out of our viewport.&lt;/p&gt;
&lt;p&gt;This creates another issue that our card will also glide along with the scroll. But we don&#39;t want that. So what we do is make &lt;code&gt;.card-wrap&lt;/code&gt; fixed positioned. Now you get this nice illusion where you are scrolling on the page technically but nothing scrolls.&lt;/p&gt;
&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;dummy&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;card-wrap&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;card&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;.card-wrap&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; fixed&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;display&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; grid&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;place-content&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; center&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;inset&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 0&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;transform-style&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; preserve-3d&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;perspective&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 800px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token selector&quot;&gt;.dummy&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 150vw&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 150vh&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;Our dummy element is set to be 150% (i.e. 1.5 times) of our viewport. You can increase/decrease it based on how much do you want user to scroll to see the effect.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.card-wrap&lt;/code&gt; is now fixed positioned so as to be independent from the page scroll.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Notice that now our page has scrolls.&lt;/p&gt;
&lt;p&gt;&lt;div class=&quot;demo-frame&quot; style=&quot;--height:600px&quot;&gt; &lt;iframe srcDoc=&quot;&lt;div class=&amp;quot;dummy&amp;quot;&gt;&lt;/div&gt;&lt;div class=&amp;quot;card-wrap&amp;quot;&gt;&lt;div class=&amp;quot;card&amp;quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;style&gt;.card-wrap {position: fixed;display: grid;place-content: center;inset: 0;transform-style: preserve-3d;perspective: 800px;}.dummy {width: 150vw;height: 150vh;}.card {border-radius: 1.5rem;height: 80vh;aspect-ratio: 9 / 16;background: url(&amp;quot;https://cdn.midjourney.com/f87ef132-b7e1-40a4-9e7c-0bf90e7e7724/0_3.png&amp;quot;);background-size: cover;box-shadow: 50px 50px 30px rgba(0, 0, 0, 0.3);transform: rotateX(10deg) rotateY(10deg);}&lt;/style&gt;&quot;&gt;&lt;/iframe&gt; &lt;/div&gt;&lt;/p&gt;
&lt;h2 id=&quot;3.-rotate-card-as-we-scroll&quot;&gt;3. Rotate card as we scroll &lt;a class=&quot;bookmark&quot; href=&quot;#3.-rotate-card-as-we-scroll&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;It&#39;s time to use some scroll-linked animation to rotate our card. Again, to get a recap, you can &lt;a href=&quot;https://kushagra.dev/blog/scroll-based-3d-cards/&quot;&gt;go through my previous post about scroll-linked animations&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;We&#39;ll have the card rotated from &lt;code&gt;-10deg&lt;/code&gt; to &lt;code&gt;10deg&lt;/code&gt; on x and y axes as we scroll, similar to how we did in the 3d card carousel.&lt;/p&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;:root&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;--rotation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 10deg&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token selector&quot;&gt;.card&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;animation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; rotate-x linear&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; rotate-y linear&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;animation-timeline&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;scroll&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;root inline&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;scroll&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;root block&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token atrule&quot;&gt;&lt;span class=&quot;token rule&quot;&gt;@keyframes&lt;/span&gt; rotate-x&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token selector&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token property&quot;&gt;transform&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;rotateX&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--rotation&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token selector&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token property&quot;&gt;transform&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;rotateX&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;calc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--rotation&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; * -1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token atrule&quot;&gt;&lt;span class=&quot;token rule&quot;&gt;@keyframes&lt;/span&gt; rotate-y&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token selector&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token property&quot;&gt;transform&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;rotateX&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;calc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--rotation&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; * -1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token selector&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token property&quot;&gt;transform&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;rotateX&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--rotation&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;rotate-x&lt;/code&gt; &amp;amp; &lt;code&gt;rotate-y&lt;/code&gt; are 2 animations that rotate from -10deg to 10deg respectively.&lt;/li&gt;
&lt;li&gt;We add 2 animations on the card. Note how we also assign 2 different animation timelines because we want to attach the &lt;code&gt;rotate-x&lt;/code&gt; animation with y-direction scroll and &lt;code&gt;rotate-y&lt;/code&gt; animation with x-direction scroll.&lt;/li&gt;
&lt;li&gt;Another thing different from the previous blog post is that we are not creating a named scroll here. Another shortcut to attach animation timeline to scroll is using the &lt;code&gt;scroll&lt;/code&gt; function. &lt;code&gt;root&lt;/code&gt; inside &lt;code&gt;scroll&lt;/code&gt; simply means we are referring to document&#39;s root scroll.&lt;/li&gt;
&lt;li&gt;Notice how x rotation goes from positive to negative while y rotation is opposite? This is just to make the rotation direction consistent with the scroll direction.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Except that this doesn&#39;t work as expected! Try for yourself and observe how it behaves:&lt;/p&gt;
&lt;p&gt;&lt;div class=&quot;demo-frame&quot; style=&quot;--height:600px&quot;&gt; &lt;iframe srcDoc=&quot;&lt;div class=&amp;quot;dummy&amp;quot;&gt;&lt;/div&gt;&lt;div class=&amp;quot;card-wrap&amp;quot;&gt;&lt;div class=&amp;quot;card&amp;quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;style&gt;:root {--rotation: 10deg;}.card-wrap {position: fixed;display: grid;place-content: center;inset: 0;transform-style: preserve-3d;perspective: 800px;}.dummy {width: 150vw;height: 150vh;}.card {border-radius: 1.5rem;height: 80vh;aspect-ratio: 9 / 16;background: url(&amp;quot;https://cdn.midjourney.com/f87ef132-b7e1-40a4-9e7c-0bf90e7e7724/0_3.png&amp;quot;);background-size: cover;box-shadow: 50px 50px 30px rgba(0, 0, 0, 0.3);animation: rotate-x linear, rotate-y linear;animation-timeline: scroll(root inline), scroll(root block);}@keyframes rotate-x {from {transform: rotateX(var(--rotation));}to {transform: rotateX(calc(var(--rotation) * -1));}}@keyframes rotate-y {from {transform: rotateX(calc(var(--rotation) * -1));}to {transform: rotateX(var(--rotation));}}&lt;/style&gt;&quot;&gt;&lt;/iframe&gt; &lt;/div&gt;&lt;/p&gt;
&lt;p&gt;The card rotates nicely as you scroll vertically. But horizontal scroll doesn&#39;t affect the card&#39;s rotation. Do you see what&#39;s wrong? Hint: It&#39;s the 2 keyframe animations.&lt;/p&gt;
&lt;p&gt;The issue is - both animations modify the &lt;code&gt;transform&lt;/code&gt; property of the card. So one overrides other. Since &lt;code&gt;rotate-y&lt;/code&gt; is set after &lt;code&gt;rotate-x&lt;/code&gt; on the card in the &lt;code&gt;animation&lt;/code&gt; property, vertical scroll works. Let&#39;s fix this issue next.&lt;/p&gt;
&lt;h2 id=&quot;4.-making-both-rotations-work&quot;&gt;4. Making both rotations work &lt;a class=&quot;bookmark&quot; href=&quot;#4.-making-both-rotations-work&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;It&#39;s clear that our animations can&#39;t simply work on the &lt;code&gt;transform&lt;/code&gt; property since one overrides other. One solution here is to have each animation only work on a particular axis rotation. But there are no &lt;code&gt;rotateX&lt;/code&gt; or &lt;code&gt;rotateY&lt;/code&gt; properties in CSS. Custom properties to the rescue! When the property we want isn&#39;t there, we can create our own custom properties.&lt;/p&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;.card&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;transform&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;rotateX&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--ry&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;rotateY&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--rx&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;animation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; rotate-x linear&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; rotate-y linear&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;animation-timeline&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;scroll&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;root inline&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;scroll&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;root block&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token atrule&quot;&gt;&lt;span class=&quot;token rule&quot;&gt;@property&lt;/span&gt; --rx&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;syntax&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&amp;lt;angle&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;initial-value&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 0deg&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;inherits&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; false&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token atrule&quot;&gt;&lt;span class=&quot;token rule&quot;&gt;@property&lt;/span&gt; --ry&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;syntax&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&amp;lt;angle&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;initial-value&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 0deg&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;inherits&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; false&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token atrule&quot;&gt;&lt;span class=&quot;token rule&quot;&gt;@keyframes&lt;/span&gt; rotate-x&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token selector&quot;&gt;0%&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token property&quot;&gt;--rx&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--rotation&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token selector&quot;&gt;100%&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token property&quot;&gt;--rx&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;calc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--rotation&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; * -1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token atrule&quot;&gt;&lt;span class=&quot;token rule&quot;&gt;@keyframes&lt;/span&gt; rotate-y&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token selector&quot;&gt;0%&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token property&quot;&gt;--ry&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;calc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--rotation&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; * -1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token selector&quot;&gt;100%&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token property&quot;&gt;--ry&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--rotation&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Our keyframe animations now modify &lt;code&gt;--rx&lt;/code&gt; and &lt;code&gt;--ry&lt;/code&gt; custom properties now.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Custom properties by default are non-animatable. Unless we define what kind of value they can contain, through the &lt;code&gt;@property&lt;/code&gt; rule. We define our custom properties to be of type &lt;code&gt;&amp;lt;angle&amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Our card uses the 2 custom properties as &lt;code&gt;transform: rotateX(var(--ry)) rotateY(var(--rx))&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;div class=&quot;demo-frame&quot; style=&quot;--height:600px&quot;&gt; &lt;iframe srcDoc=&quot;&lt;div class=&amp;quot;dummy&amp;quot;&gt;&lt;/div&gt;&lt;div class=&amp;quot;card-wrap&amp;quot;&gt;&lt;div class=&amp;quot;card&amp;quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;style&gt;:root {--rotation: 10deg;}.card-wrap {position: fixed;display: grid;place-content: center;inset: 0;transform-style: preserve-3d;perspective: 800px;}.dummy {width: 150vw;height: 150vh;}.card {border-radius: 1.5rem;height: 80vh;aspect-ratio: 9 / 16;background: url(&amp;quot;https://cdn.midjourney.com/f87ef132-b7e1-40a4-9e7c-0bf90e7e7724/0_3.png&amp;quot;);background-size: cover;box-shadow: 50px 50px 30px rgba(0, 0, 0, 0.3);transform: rotateX(var(--ry)) rotateY(var(--rx));animation: rotate-x linear, rotate-y linear;animation-timeline: scroll(root inline), scroll(root block);}@property --rx {syntax: &amp;quot;&lt;angle&gt;&amp;quot;;initial-value: 0deg;inherits: false;}@property --ry {syntax: &amp;quot;&lt;angle&gt;&amp;quot;;initial-value: 0deg;inherits: false;}@keyframes rotate-x {0% {--rx: var(--rotation);}100% {--rx: calc(var(--rotation) * -1);}}@keyframes rotate-y {0% {--ry: calc(var(--rotation) * -1);}100% {--ry: var(--rotation);}}&lt;/style&gt;&quot;&gt;&lt;/iframe&gt; &lt;/div&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;5.-make-shadows-dynamic&quot;&gt;5. Make shadows dynamic &lt;a class=&quot;bookmark&quot; href=&quot;#5.-make-shadows-dynamic&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;:root&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;--shadow-length&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 50px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token selector&quot;&gt;.card&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;box-shadow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--shadow-x&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--shadow-y&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; 30px &lt;span class=&quot;token function&quot;&gt;rgba&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;0&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 0&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 0&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 0.3&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;transform&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;rotateX&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--ry&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;rotateY&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--rx&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;animation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; rotate-x linear&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; rotate-y linear&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; shadow-x linear&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; shadow-y linear&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;animation-timeline&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;scroll&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;root inline&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;scroll&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;root block&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;scroll&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;br&gt;      root inline&lt;br&gt;    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;scroll&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;root block&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token comment&quot;&gt;/* other animations */&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token atrule&quot;&gt;&lt;span class=&quot;token rule&quot;&gt;@property&lt;/span&gt; --shadow-x&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;syntax&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&amp;lt;length&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;initial-value&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 0px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;inherits&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; false&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token atrule&quot;&gt;&lt;span class=&quot;token rule&quot;&gt;@keyframes&lt;/span&gt; shadow-x&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token selector&quot;&gt;0%&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token property&quot;&gt;--shadow-x&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;calc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;-1 * &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--shadow-length&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token selector&quot;&gt;100%&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token property&quot;&gt;--shadow-x&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--shadow-length&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token atrule&quot;&gt;&lt;span class=&quot;token rule&quot;&gt;@property&lt;/span&gt; --shadow-y&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;syntax&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&amp;lt;length&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;initial-value&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 0px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;inherits&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; false&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token atrule&quot;&gt;&lt;span class=&quot;token rule&quot;&gt;@keyframes&lt;/span&gt; shadow-y&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token selector&quot;&gt;0%&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token property&quot;&gt;--shadow-y&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;calc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;-1 * &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--shadow-length&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token selector&quot;&gt;100%&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token property&quot;&gt;--shadow-y&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--shadow-length&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;More or less similar to how we added rotation on both axes, we add 2 shadow animations for x and y direction. Our card is looking pretty 3D now:&lt;/p&gt;
&lt;p&gt;&lt;div class=&quot;demo-frame&quot; style=&quot;--height:600px&quot;&gt; &lt;iframe srcDoc=&quot;&lt;div class=&amp;quot;dummy&amp;quot;&gt;&lt;/div&gt;&lt;div class=&amp;quot;card-wrap&amp;quot;&gt;&lt;div class=&amp;quot;card&amp;quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;style&gt;:root {--rotation: 10deg;--shadow-length: 50px;}.card-wrap {position: fixed;display: grid;place-content: center;inset: 0;transform-style: preserve-3d;perspective: 800px;}.dummy {width: 150vw;height: 150vh;}.card {border-radius: 1.5rem;height: 80vh;aspect-ratio: 9 / 16;background: url(&amp;quot;https://cdn.midjourney.com/f87ef132-b7e1-40a4-9e7c-0bf90e7e7724/0_3.png&amp;quot;);background-size: cover;box-shadow: var(--shadow-x) var(--shadow-y) 30px rgba(0, 0, 0, 0.3);transform: rotateX(var(--ry)) rotateY(var(--rx));animation: rotate-x linear, rotate-y linear, shadow-x linear, shadow-y linear;animation-timeline: scroll(root inline), scroll(root block),scroll(root inline), scroll(root block);}@property --rx {syntax: &amp;quot;&lt;angle&gt;&amp;quot;;initial-value: 0deg;inherits: false;}@property --ry {syntax: &amp;quot;&lt;angle&gt;&amp;quot;;initial-value: 0deg;inherits: false;}@keyframes rotate-x {0% {--rx: var(--rotation);}100% {--rx: calc(var(--rotation) * -1);}}@keyframes rotate-y {0% {--ry: calc(var(--rotation) * -1);}100% {--ry: var(--rotation);}}@property --shadow-x {syntax: &amp;quot;&lt;length&gt;&amp;quot;;initial-value: 0px;inherits: false;}@keyframes shadow-x {0% {--shadow-x: calc(-1 * var(--shadow-length));}100% {--shadow-x: var(--shadow-length);}}@property --shadow-y {syntax: &amp;quot;&lt;length&gt;&amp;quot;;initial-value: 0px;inherits: false;}@keyframes shadow-y {0% {--shadow-y: calc(-1 * var(--shadow-length));}100% {--shadow-y: var(--shadow-length);}}&lt;/style&gt;&quot;&gt;&lt;/iframe&gt; &lt;/div&gt;&lt;/p&gt;
&lt;h2 id=&quot;6.-icing---shine-%E2%9C%A8&quot;&gt;6. Icing - Shine ✨ &lt;a class=&quot;bookmark&quot; href=&quot;#6.-icing---shine-%E2%9C%A8&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;There is one final effect we can add to make our card real 3D - a shine! We create the shine through a &lt;code&gt;radial-gradient&lt;/code&gt; over the card&#39;s current background image. We also move that shine across the card as it rotates.&lt;/p&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;.card&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  ...&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;background&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;radial-gradient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;br&gt;      circle at &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--shine-x&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--shine-y&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;      #fffa 40px&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;      #0000&lt;br&gt;    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token url&quot;&gt;&lt;span class=&quot;token function&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string url&quot;&gt;&quot;https://cdn.midjourney.com/f87ef132-b7e1-40a4-9e7c-0bf90e7e7724/0_3.png&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  ...&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;animation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; rotate-y linear&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; shadow-y linear&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; rotate-x linear&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; shadow-x linear&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;    anim-shine-x linear&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; anim-shine-y linear&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;animation-timeline&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;scroll&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;root&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;scroll&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;root&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;scroll&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;root inline&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;scroll&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;root inline&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token function&quot;&gt;scroll&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;root inline&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;scroll&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;root&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token comment&quot;&gt;/* other animations */&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token atrule&quot;&gt;&lt;span class=&quot;token rule&quot;&gt;@property&lt;/span&gt; --shine-x&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;syntax&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&amp;lt;percentage&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;initial-value&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 0%&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;inherits&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; false&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token atrule&quot;&gt;&lt;span class=&quot;token rule&quot;&gt;@property&lt;/span&gt; --shine-y&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;syntax&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&amp;lt;percentage&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;initial-value&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 0%&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;inherits&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; false&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token atrule&quot;&gt;&lt;span class=&quot;token rule&quot;&gt;@keyframes&lt;/span&gt; anim-shine-x&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token selector&quot;&gt;0%&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token property&quot;&gt;--shine-x&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 0%&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token selector&quot;&gt;100%&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token property&quot;&gt;--shine-x&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 100%&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token atrule&quot;&gt;&lt;span class=&quot;token rule&quot;&gt;@keyframes&lt;/span&gt; anim-shine-y&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token selector&quot;&gt;0%&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token property&quot;&gt;--shine-y&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 100%&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token selector&quot;&gt;100%&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token property&quot;&gt;--shine-y&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 0%&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The shine is a circle created with &lt;code&gt;radial-gradient&lt;/code&gt; from transparent white to complete transparent and whose center keeps on moving through the custom variables.&lt;/p&gt;
&lt;h3 id=&quot;final-demo-%F0%9F%A5%B3&quot;&gt;Final demo 🥳 &lt;a class=&quot;bookmark&quot; href=&quot;#final-demo-%F0%9F%A5%B3&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;div class=&quot;demo-frame&quot; style=&quot;--height:600px&quot;&gt; &lt;iframe srcDoc=&quot;&lt;div class=&amp;quot;dummy&amp;quot;&gt;&lt;/div&gt;&lt;div class=&amp;quot;card-wrap&amp;quot;&gt;&lt;div class=&amp;quot;card&amp;quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;style&gt;:root {--rotation: 10deg;--shadow-length: 50px;}::-webkit-scrollbar,::-webkit-scrollbar-thumb,::-webkit-scrollbar-track,::-webkit-scrollbar-corner {/*background: transparent;*/}.card-wrap {position: fixed;display: grid;place-content: center;inset: 0;transform-style: preserve-3d;perspective: 800px;}.card {border-radius: 1.5rem;height: 80vh;aspect-ratio: 9 / 16;background: radial-gradient(circle at var(--shine-x) var(--shine-y),#fffa 40px,#0000),url(&amp;quot;https://cdn.midjourney.com/f87ef132-b7e1-40a4-9e7c-0bf90e7e7724/0_3.png&amp;quot;);background-size: cover;box-shadow: var(--shadow-x) var(--shadow-y) 30px rgba(0, 0, 0, 0.3);transform: rotateX(var(--ry)) rotateY(var(--rx));animation: rotate-y linear, shadow-y linear, rotate-x linear,shadow-x linear, anim-shine-x linear, anim-shine-y linear;animation-timeline: scroll(root), scroll(root), scroll(root inline),scroll(root inline), scroll(root inline), scroll(root);}.dummy {width: 150vw;height: 150vh;}@property --rx {syntax: &amp;quot;&lt;angle&gt;&amp;quot;;initial-value: 0deg;inherits: false;}@property --ry {syntax: &amp;quot;&lt;angle&gt;&amp;quot;;initial-value: 0deg;inherits: false;}@keyframes rotate-x {0% {--rx: var(--rotation);}100% {--rx: calc(var(--rotation) * -1);}}@keyframes rotate-y {0% {--ry: calc(var(--rotation) * -1);}100% {--ry: var(--rotation);}}@property --shadow-y {syntax: &amp;quot;&lt;length&gt;&amp;quot;;initial-value: 0px;inherits: false;}@keyframes shadow-y {0% {--shadow-y: calc(-1 * var(--shadow-length));}100% {--shadow-y: var(--shadow-length);}}@property --shadow-x {syntax: &amp;quot;&lt;length&gt;&amp;quot;;initial-value: 0px;inherits: false;}@keyframes shadow-x {0% {--shadow-x: var(--shadow-length);}100% {--shadow-x: calc(-1 * var(--shadow-length));}}@property --shine-x {syntax: &amp;quot;&lt;percentage&gt;&amp;quot;;initial-value: 0%;inherits: false;}@property --shine-y {syntax: &amp;quot;&lt;percentage&gt;&amp;quot;;initial-value: 0%;inherits: false;}@keyframes anim-shine-x {0% {--shine-x: 0%;}100% {--shine-x: 100%;}}@keyframes anim-shine-y {0% {--shine-y: 100%;}100% {--shine-y: 0%;}}&lt;/style&gt;&quot;&gt;&lt;/iframe&gt; &lt;/div&gt;&lt;/p&gt;
&lt;div class=&quot;d-f jc-c&quot;&gt;
&lt;a href=&quot;https://webmaker.app/app/?html=%3Cdiv%20class%3D%22dummy%22%3E%3C%2Fdiv%3E%0A%3Cdiv%20class%3D%22card-wrap%22%3E%0A%20%20%3Cdiv%20class%3D%22card%22%3E%3C%2Fdiv%3E%0A%3C%2Fdiv%3E&amp;css=%3Aroot%20%7B--rotation%3A%2010deg%3B--shadow-length%3A%2050px%3B%7D.card-wrap%20%7Bposition%3A%20fixed%3Bdisplay%3A%20grid%3Bplace-content%3A%20center%3Binset%3A%200%3Btransform-style%3A%20preserve-3d%3Bperspective%3A%20800px%3B%7D.card%20%7Bborder-radius%3A%201.5rem%3Bheight%3A%2080vh%3Baspect-ratio%3A%209%20%2F%2016%3Bbackground%3A%20radial-gradient(circle%20at%20var(--shine-x)%20var(--shine-y)%2C%23fffa%2040px%2C%230000)%2Curl(%22https%3A%2F%2Fcdn.midjourney.com%2Ff87ef132-b7e1-40a4-9e7c-0bf90e7e7724%2F0_3.png%22)%3Bbackground-size%3A%20cover%3Bbox-shadow%3A%20var(--shadow-x)%20var(--shadow-y)%2030px%20rgba(0%2C%200%2C%200%2C%200.3)%3Btransform%3A%20rotateX(var(--ry))%20rotateY(var(--rx))%3Banimation%3A%20rotate-y%20linear%2C%20shadow-y%20linear%2C%20rotate-x%20linear%2Cshadow-x%20linear%2C%20anim-shine-x%20linear%2C%20anim-shine-y%20linear%3Banimation-timeline%3A%20scroll(root)%2C%20scroll(root)%2C%20scroll(root%20inline)%2Cscroll(root%20inline)%2C%20scroll(root%20inline)%2C%20scroll(root)%3B%7D.dummy%20%7Bwidth%3A%20150vw%3Bheight%3A%20150vh%3B%7D%40property%20--rx%20%7Bsyntax%3A%20%22%3Cangle%3E%22%3Binitial-value%3A%200deg%3Binherits%3A%20false%3B%7D%40property%20--ry%20%7Bsyntax%3A%20%22%3Cangle%3E%22%3Binitial-value%3A%200deg%3Binherits%3A%20false%3B%7D%40keyframes%20rotate-x%20%7B0%25%20%7B--rx%3A%20var(--rotation)%3B%7D100%25%20%7B--rx%3A%20calc(var(--rotation)%20*%20-1)%3B%7D%7D%40keyframes%20rotate-y%20%7B0%25%20%7B--ry%3A%20calc(var(--rotation)%20*%20-1)%3B%7D100%25%20%7B--ry%3A%20var(--rotation)%3B%7D%7D%40property%20--shadow-y%20%7Bsyntax%3A%20%22%3Clength%3E%22%3Binitial-value%3A%200px%3Binherits%3A%20false%3B%7D%40keyframes%20shadow-y%20%7B0%25%20%7B--shadow-y%3A%20calc(-1%20*%20var(--shadow-length))%3B%7D100%25%20%7B--shadow-y%3A%20var(--shadow-length)%3B%7D%7D%40property%20--shadow-x%20%7Bsyntax%3A%20%22%3Clength%3E%22%3Binitial-value%3A%200px%3Binherits%3A%20false%3B%7D%40keyframes%20shadow-x%20%7B0%25%20%7B--shadow-x%3A%20var(--shadow-length)%3B%7D100%25%20%7B--shadow-x%3A%20calc(-1%20*%20var(--shadow-length))%3B%7D%7D%40property%20--shine-x%20%7Bsyntax%3A%20%22%3Cpercentage%3E%22%3Binitial-value%3A%200%25%3Binherits%3A%20false%3B%7D%40property%20--shine-y%20%7Bsyntax%3A%20%22%3Cpercentage%3E%22%3Binitial-value%3A%200%25%3Binherits%3A%20false%3B%7D%40keyframes%20anim-shine-x%20%7B0%25%20%7B--shine-x%3A%200%25%3B%7D100%25%20%7B--shine-x%3A%20100%25%3B%7D%7D%40keyframes%20anim-shine-y%20%7B0%25%20%7B--shine-y%3A%20100%25%3B%7D100%25%20%7B--shine-y%3A%200%25%3B%7D%7D&quot;&gt;See demo with code in Web Maker&lt;/a&gt;
&lt;/div&gt;
&lt;p&gt;This illusion works best on a mobile where scrolling is much more easy and intuitive. One improvement that can be done for mobile (or for trackpad supported devices) is hiding the scrollbars, which makes the whole effect more seamless.&lt;/p&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;::-webkit-scrollbar,&lt;br&gt;::-webkit-scrollbar-thumb,&lt;br&gt;::-webkit-scrollbar-track,&lt;br&gt;::-webkit-scrollbar-corner&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;background&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; transparent&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you enjoyed reading this, do share!&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Scroll-based 3D card carousel</title>
		<link href="https://kushagra.dev/blog/scroll-based-3d-cards/"/>
		<updated>2023-08-15T00:00:00+00:00</updated>
		<id>https://kushagra.dev/blog/scroll-based-3d-cards/</id>
		<content type="html">&lt;p&gt;In this blog post I&#39;ll show how we can simulate cards with 3D depth based on scrolling using the newly arrived scroll-based animations.&lt;/p&gt;
&lt;p&gt;We’ll be creating a carousel of cards that change inclination while scrolling. The cards will seem to have a 3D depth i.e we’ll be able to see either of left or right sides of the card based on the carousel’s inclination while scrolling. &lt;a href=&quot;#final-demo-%F0%9F%A5%B3&quot;&gt;See the final effect we’ll create&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;1.-place-the-cards&quot;&gt;1. Place the cards &lt;a class=&quot;bookmark&quot; href=&quot;#1.-place-the-cards&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;carousel-wrap&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;carousel&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;card&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token special-attr&quot;&gt;&lt;span class=&quot;token attr-name&quot;&gt;style&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token value css language-css&quot;&gt;&lt;span class=&quot;token property&quot;&gt;--height&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 7ex&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Card 1&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;card&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token special-attr&quot;&gt;&lt;span class=&quot;token attr-name&quot;&gt;style&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token value css language-css&quot;&gt;&lt;span class=&quot;token property&quot;&gt;--height&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 9ex&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Card 2&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;card&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token special-attr&quot;&gt;&lt;span class=&quot;token attr-name&quot;&gt;style&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token value css language-css&quot;&gt;&lt;span class=&quot;token property&quot;&gt;--height&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 10ex&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Card 3&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;card&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token special-attr&quot;&gt;&lt;span class=&quot;token attr-name&quot;&gt;style&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token value css language-css&quot;&gt;&lt;span class=&quot;token property&quot;&gt;--height&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 6ex&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Card 4&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;card&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token special-attr&quot;&gt;&lt;span class=&quot;token attr-name&quot;&gt;style&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token value css language-css&quot;&gt;&lt;span class=&quot;token property&quot;&gt;--height&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 12ex&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Card 5&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;.carousel&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;display&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; flex&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;padding&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 1rem&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;overflow-x&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; scroll&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token selector&quot;&gt;.card&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;flex-shrink&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 0&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 28ch&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--height&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;margin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 1rem&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;padding&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 1rem&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;border-radius&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 0.5rem&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;background&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; #f7f1f2&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;text-align&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; center&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;font-family&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; sans-serif&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;border&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 2px solid #222&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;box-shadow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; -10px 5px 0px 2px &lt;span class=&quot;token function&quot;&gt;rgba&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;0&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 0&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 0&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 0.75&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Few things about the code above:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;carousel-wrap&lt;/code&gt; doesn’t do anything for now 🤷🏻‍♂️. We’ll use it later.&lt;/li&gt;
&lt;li&gt;Cards are given different heights, just for for visual enhancement, through a custom property called &lt;code&gt;--height&lt;/code&gt;. Interestingly, the unit of these heights are &lt;code&gt;ex&lt;/code&gt; which is height of the letter &lt;code&gt;x&lt;/code&gt; in the current font...something you might want to use to approximate a set number of lines in an element.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.carousel&lt;/code&gt; is a flex container.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.card&lt;/code&gt; is given a &lt;code&gt;flex-shrink: 0&lt;/code&gt; so that the cards don’t shrink because of limited width of the parent. And instead take the given width and overflow the parent.&lt;/li&gt;
&lt;li&gt;We give the cards a box-shadow to create an illusion of a depth on the cards. The left side shadow gives the impression of the visible left side of our 3D cards.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Here is what we get:&lt;/p&gt;
&lt;p&gt;&lt;div class=&quot;demo-frame&quot; style=&quot;--height:22ex&quot;&gt; &lt;iframe srcDoc=&quot;&lt;div class=&amp;quot;carousel-wrap&amp;quot;&gt;&lt;div class=&amp;quot;carousel&amp;quot;&gt;&lt;div class=&amp;quot;card&amp;quot; style=&amp;quot;--height: 7ex&amp;quot;&gt;Card 1&lt;/div&gt;&lt;div class=&amp;quot;card&amp;quot; style=&amp;quot;--height: 9ex&amp;quot;&gt;Card 2&lt;/div&gt;&lt;div class=&amp;quot;card&amp;quot; style=&amp;quot;--height: 10ex&amp;quot;&gt;Card 3&lt;/div&gt;&lt;div class=&amp;quot;card&amp;quot; style=&amp;quot;--height: 6ex&amp;quot;&gt;Card 4&lt;/div&gt;&lt;div class=&amp;quot;card&amp;quot; style=&amp;quot;--height: 12ex&amp;quot;&gt;Card 5&lt;/div&gt;	&lt;/div&gt;&lt;/div&gt;&lt;style&gt;.carousel {display: flex;padding: 1rem;overflow-x: scroll;}.card {flex-shrink: 0;width: 28ch;height: var(--height);margin: 1rem;padding: 1rem;border-radius: 0.5rem;background: #f7f1f2;text-align: center;font-family: sans-serif;border: 2px solid #222;box-shadow: -10px 5px 0px 2px rgba(0, 0, 0, 0.75);}&lt;/style&gt;&quot;&gt;&lt;/iframe&gt; &lt;/div&gt;&lt;/p&gt;
&lt;h3 id=&quot;2.-scroll-based-inclination---give-a-timeline-name-for-x-direction-scrolling&quot;&gt;2. Scroll-based inclination - give a timeline name for x-direction scrolling &lt;a class=&quot;bookmark&quot; href=&quot;#2.-scroll-based-inclination---give-a-timeline-name-for-x-direction-scrolling&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Now the fun part starts. The overflowing set of cards create a scroll in their parent. We&#39;ll make this scroll the basis of our cool effect on the cards. First effect is inclining the set of cards from left-to-right when scrolling. We&#39;ll start by making use of the newly available &lt;code&gt;scroll-timeline&lt;/code&gt; property to associate the x-direction scroll (&lt;code&gt;inline&lt;/code&gt;) of the carousel to a name.&lt;/p&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;.carousel&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;scroll-timeline&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; --carousel-scroll inline&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;--carousel-scroll&lt;/code&gt; is called the timeline-name and is associated with x-direction scroll of the element &lt;code&gt;.carousel&lt;/code&gt; .&lt;/p&gt;
&lt;h3 id=&quot;3.-create-animation-to-rotate&quot;&gt;3. Create animation to rotate &lt;a class=&quot;bookmark&quot; href=&quot;#3.-create-animation-to-rotate&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Scroll-based animation allows us to attach any animation to a scroll timeline i.e. the animation would progress as the scroll progresses. So let’s define an animation for rotating our carousel along y-axis and attach it will the scroll timeline we created above.&lt;/p&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token atrule&quot;&gt;&lt;span class=&quot;token rule&quot;&gt;@keyframes&lt;/span&gt; anim-rotate&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token selector&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token property&quot;&gt;transform&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;rotateY&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;8deg&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token selector&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token property&quot;&gt;transform&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;rotateY&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;-8deg&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token selector&quot;&gt;.carousel-wrap&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;perspective&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 600px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token selector&quot;&gt;.carousel&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  ...&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;scroll-timeline&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; --carousel-scroll inline&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;animation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; anim-rotate auto linear&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;animation-timeline&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; --carousel-scroll&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;anim-rotate&lt;/code&gt; is an animation that rotates the carousel along y-axis from &lt;code&gt;8deg&lt;/code&gt; to &lt;code&gt;-8deg&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;We attach the animation to the scroll timeline using the &lt;code&gt;animation-timeline&lt;/code&gt; property.&lt;/li&gt;
&lt;li&gt;We now need the &lt;code&gt;.carousel-wrap&lt;/code&gt; element to create a 3d perspective of &lt;code&gt;600px&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Scroll inside the carousel now and see it tilting from one side to another as you scroll! Voila!&lt;/p&gt;
&lt;p&gt;&lt;div class=&quot;demo-frame&quot; style=&quot;--height:22ex&quot;&gt; &lt;iframe srcDoc=&quot;&lt;div class=&amp;quot;carousel-wrap&amp;quot;&gt;&lt;div class=&amp;quot;carousel&amp;quot;&gt;&lt;div class=&amp;quot;card&amp;quot; style=&amp;quot;--height: 7ex&amp;quot;&gt;Card 1&lt;/div&gt;&lt;div class=&amp;quot;card&amp;quot; style=&amp;quot;--height: 9ex&amp;quot;&gt;Card 2&lt;/div&gt;&lt;div class=&amp;quot;card&amp;quot; style=&amp;quot;--height: 10ex&amp;quot;&gt;Card 3&lt;/div&gt;&lt;div class=&amp;quot;card&amp;quot; style=&amp;quot;--height: 6ex&amp;quot;&gt;Card 4&lt;/div&gt;&lt;div class=&amp;quot;card&amp;quot; style=&amp;quot;--height: 12ex&amp;quot;&gt;Card 5&lt;/div&gt;	&lt;/div&gt;&lt;/div&gt;&lt;style&gt;@keyframes anim-rotate {from {transform: rotateY(8deg);}to {transform: rotateY(-8deg);}}.carousel-wrap {perspective: 600px;}.carousel {display: flex;padding: 1rem;overflow-x: scroll;scroll-timeline: --carousel-scroll inline;animation: anim-rotate auto linear;animation-timeline: --carousel-scroll;}.card {flex-shrink: 0;width: 28ch;height: var(--height);margin: 1rem;padding: 1rem;border-radius: 0.5rem;background: #f7f1f2;text-align: center;font-family: sans-serif;border: 2px solid #222;box-shadow: -10px 5px 0px 2px rgba(0, 0, 0, 0.75);}&lt;/style&gt;&quot;&gt;&lt;/iframe&gt; &lt;/div&gt;&lt;/p&gt;
&lt;p&gt;But if you scroll and reach the last card, the depth looks incorrect - with that tilt we should be seeing the right side (depth) of the cards, not left. Let’s make it dynamic!&lt;/p&gt;
&lt;h3 id=&quot;5.-parametrize-the-shadow&#39;s-x-offset-and-animate-on-scroll&quot;&gt;5. Parametrize the shadow&#39;s x offset and animate on scroll &lt;a class=&quot;bookmark&quot; href=&quot;#5.-parametrize-the-shadow&#39;s-x-offset-and-animate-on-scroll&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token atrule&quot;&gt;&lt;span class=&quot;token rule&quot;&gt;@keyframes&lt;/span&gt; anim-shadow&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token selector&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token property&quot;&gt;--shadow-x&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; -10px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token selector&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token property&quot;&gt;--shadow-x&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 10px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token selector&quot;&gt;.card&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  ...&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;box-shadow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--shadow-x&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; 5px 0px 2px &lt;span class=&quot;token function&quot;&gt;rgba&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;0&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 0&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 0&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 0.75&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;animation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; anim-shadow auto linear&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;animation-timeline&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; --carousel-scroll&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;We create a animation for the card’s box-shadow. The animation basically animates a custom property called &lt;code&gt;--shadow-x&lt;/code&gt; from &lt;code&gt;-10px&lt;/code&gt; to &lt;code&gt;10px&lt;/code&gt; - which represents the x-offset in our &lt;code&gt;box-shadow&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;We make the x-offset dynamic in our &lt;code&gt;box-shadow&lt;/code&gt; by using the &lt;code&gt;--shadow-x&lt;/code&gt; custom property.&lt;/li&gt;
&lt;li&gt;As before, we set the animation on the card and attach it to the &lt;code&gt;--carousel-scroll&lt;/code&gt; scroll timeline.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Try scrolling inside the carousel and you’ll notice something strange - The box-shadow doesn’t animates! Instead, half way through the scroll, the box-shadow’s x-offset changes abruptly from &lt;code&gt;-10px&lt;/code&gt; to &lt;code&gt;10px&lt;/code&gt; (Notice in the center card). That’s not what we want…we want the shadow to animate smoothly as we scroll.&lt;/p&gt;
&lt;p&gt;&lt;div class=&quot;demo-frame&quot; style=&quot;--height:22ex&quot;&gt; &lt;iframe srcDoc=&quot;&lt;div class=&amp;quot;carousel-wrap&amp;quot;&gt;&lt;div class=&amp;quot;carousel&amp;quot;&gt;&lt;div class=&amp;quot;card&amp;quot; style=&amp;quot;--height: 7ex&amp;quot;&gt;Card 1&lt;/div&gt;&lt;div class=&amp;quot;card&amp;quot; style=&amp;quot;--height: 9ex&amp;quot;&gt;Card 2&lt;/div&gt;&lt;div class=&amp;quot;card&amp;quot; style=&amp;quot;--height: 10ex&amp;quot;&gt;Card 3&lt;/div&gt;&lt;div class=&amp;quot;card&amp;quot; style=&amp;quot;--height: 6ex&amp;quot;&gt;Card 4&lt;/div&gt;&lt;div class=&amp;quot;card&amp;quot; style=&amp;quot;--height: 12ex&amp;quot;&gt;Card 5&lt;/div&gt;	&lt;/div&gt;&lt;/div&gt;&lt;style&gt;@keyframes anim-rotate {from {transform: rotateY(8deg);}to {transform: rotateY(-8deg);}}@keyframes anim-shadow {from {--shadow-x: -10px;}to {--shadow-x: 10px;}}.carousel-wrap {perspective: 600px;}.carousel {display: flex;padding: 1rem;overflow-x: scroll;scroll-timeline: --carousel-scroll inline;animation: anim-rotate auto linear;animation-timeline: --carousel-scroll;}.card {flex-shrink: 0;width: 28ch;height: var(--height);margin: 1rem;padding: 1rem;border-radius: 0.5rem;background: #f7f1f2;text-align: center;font-family: sans-serif;border: 2px solid #222;box-shadow: var(--shadow-x) 5px 0px 2px rgba(0, 0, 0, 0.75);animation: anim-shadow auto linear;	animation-timeline: --carousel-scroll;}&lt;/style&gt;&quot;&gt;&lt;/iframe&gt; &lt;/div&gt;&lt;/p&gt;
&lt;h3 id=&quot;6.-fixing-the-animation&quot;&gt;6. Fixing the animation &lt;a class=&quot;bookmark&quot; href=&quot;#6.-fixing-the-animation&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Even though the offsets in the &lt;code&gt;box-shadow&lt;/code&gt; value are animatable, they don’t animate for us. It&#39;s because of the custom property being used for the x-offset. The browser doesn’t know about our custom property and hence doesn’t animate it. We need to give some extra information about our custom property to the browser for it figure out how to animate the property.&lt;/p&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token atrule&quot;&gt;&lt;span class=&quot;token rule&quot;&gt;@property&lt;/span&gt; --shadow-x&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;syntax&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&amp;lt;length&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;inherits&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; false&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;initial-value&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 0px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token atrule&quot;&gt;&lt;span class=&quot;token rule&quot;&gt;@keyframes&lt;/span&gt; anim-shadow&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token selector&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token property&quot;&gt;--shadow-x&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; -10px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token selector&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token property&quot;&gt;--shadow-x&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 10px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token selector&quot;&gt;.card&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  ...&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;box-shadow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--shadow-x&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; 5px 0px 2px &lt;span class=&quot;token function&quot;&gt;rgba&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;0&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 0&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 0&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 0.75&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;animation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; anim-shadow auto linear&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;	&lt;span class=&quot;token property&quot;&gt;animation-timeline&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; --carousel-scroll&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With the &lt;code&gt;@property&lt;/code&gt; declaration we are telling the browser to treat &lt;code&gt;--shadow-x&lt;/code&gt; as a &lt;code&gt;length&lt;/code&gt; type value (like &lt;code&gt;width&lt;/code&gt; is). And there we go, now the shadow offset animates perfectly!!&lt;/p&gt;
&lt;p&gt;Now you have your nice pseudo 3D cards! 🥳&lt;/p&gt;
&lt;h3 id=&quot;final-demo-%F0%9F%A5%B3&quot;&gt;Final demo 🥳 &lt;a class=&quot;bookmark&quot; href=&quot;#final-demo-%F0%9F%A5%B3&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;div class=&quot;demo-frame&quot; style=&quot;--height:22ex&quot;&gt; &lt;iframe srcDoc=&quot;&lt;div class=&amp;quot;carousel-wrap&amp;quot;&gt;&lt;div class=&amp;quot;carousel&amp;quot;&gt;&lt;div class=&amp;quot;card&amp;quot; style=&amp;quot;--height: 7ex&amp;quot;&gt;Card 1&lt;/div&gt;&lt;div class=&amp;quot;card&amp;quot; style=&amp;quot;--height: 9ex&amp;quot;&gt;Card 2&lt;/div&gt;&lt;div class=&amp;quot;card&amp;quot; style=&amp;quot;--height: 10ex&amp;quot;&gt;Card 3&lt;/div&gt;&lt;div class=&amp;quot;card&amp;quot; style=&amp;quot;--height: 6ex&amp;quot;&gt;Card 4&lt;/div&gt;&lt;div class=&amp;quot;card&amp;quot; style=&amp;quot;--height: 12ex&amp;quot;&gt;Card 5&lt;/div&gt;	&lt;/div&gt;&lt;/div&gt;&lt;style&gt;@keyframes anim-rotate {from {transform: rotateY(8deg);}to {transform: rotateY(-8deg);}}@property --shadow-x {syntax: &amp;quot;&lt;length&gt;&amp;quot;;inherits: false;initial-value: 0px;}@keyframes anim-shadow {from {--shadow-x: -10px;}to {--shadow-x: 10px;}}.carousel-wrap {perspective: 600px;}.carousel {display: flex;padding: 1rem;overflow-x: scroll;scroll-timeline: --carousel-scroll inline;animation: anim-rotate auto linear;animation-timeline: --carousel-scroll;}.card {flex-shrink: 0;width: 28ch;height: var(--height);margin: 1rem;padding: 1rem;border-radius: 0.5rem;background: #f7f1f2;text-align: center;font-family: sans-serif;border: 2px solid #222;box-shadow: var(--shadow-x) 5px 0px 2px rgba(0, 0, 0, 0.75);animation: anim-shadow auto linear;	animation-timeline: --carousel-scroll;}&lt;/style&gt;&quot;&gt;&lt;/iframe&gt; &lt;/div&gt;&lt;/p&gt;
&lt;p&gt;If you enjoyed reading this, do share!&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>How to learn &amp; master CSS</title>
		<link href="https://kushagra.dev/blog/how-to-learn-master-css/"/>
		<updated>2023-07-31T00:00:00+00:00</updated>
		<id>https://kushagra.dev/blog/how-to-learn-master-css/</id>
		<content type="html">&lt;p&gt;Cascading Style Sheets (CSS) is an essential technology used in web development to style and layout web pages. CSS is not like other programming languages because of its unique core concepts and hence learning CSS can be challenging, especially for beginners. In this blog post, I attempt to outline how one can learn and master CSS.&lt;/p&gt;
&lt;p&gt;Learning CSS can be broken down into 2 things: &lt;strong&gt;Learning&lt;/strong&gt; and &lt;strong&gt;Practice&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&quot;learning&quot;&gt;Learning &lt;a class=&quot;bookmark&quot; href=&quot;#learning&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;You need to learn 2 things in CSS: The core concepts &amp;amp; property-values.&lt;/p&gt;
&lt;h3 id=&quot;learning-core-concepts&quot;&gt;Learning Core Concepts &lt;a class=&quot;bookmark&quot; href=&quot;#learning-core-concepts&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;This involves understanding the CSS specific concepts, theoretically. Things like cascade, z-index, box model, selectors etc&lt;/p&gt;
&lt;p&gt;The resources I recommend for this are:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://web.dev/learn/css&quot;&gt;web.dev guide&lt;/a&gt; - Super nice articles explaining each of the concepts in CSS. Must read!&lt;/li&gt;
&lt;li&gt;CSSBattles’s &lt;a href=&quot;https://cssbattle.dev/learn&quot;&gt;Learn CSS course&lt;/a&gt; - they just have a beginner course for now but it&#39;s a unique interactive game-like experience to understand the basics of CSS, while not feeling daunted with just reading long articles.&lt;/li&gt;
&lt;li&gt;Josh Comeau&#39;s &lt;a href=&quot;https://css-for-js.dev/&quot;&gt;CSS for JavaScript developers&lt;/a&gt; course. This man is a wizard in CSS and teaching - an extraordinary combination that makes his course excellent for learning CSS.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;learning-about-properties-and-values&quot;&gt;Learning about Properties and Values &lt;a class=&quot;bookmark&quot; href=&quot;#learning-about-properties-and-values&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The only resource I recommend here is the MDN docs. To learn properties and values, you should read the MDN docs on various properties. MDN docs provide an in-depth explanation of each property, including its syntax, possible values, interactive examples and browser support. As a routine, you can visit the MDN pages of the first 2-3 properties you use daily…its fun!&lt;/p&gt;
&lt;h2 id=&quot;practice&quot;&gt;Practice &lt;a class=&quot;bookmark&quot; href=&quot;#practice&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Once you get a basic knowledge about the core concepts and properties, practice is of utmost importance to turn your acquired knowledge into skills. Here are the 2 directions I recommend practicing CSS in:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Page layouts by building pages&lt;/strong&gt; - this is an excellent way to practice what you have learned. It will give you real-world experience in applying CSS concepts and properties to create practical layouts and structures. You can start with building static webpages - grab a design from Dribbble/Behance and turn into HTML &amp;amp; CSS. Then move onto building simple apps like a landing page or a portfolio website.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Properties-values in CSSBattle&lt;/strong&gt; - &lt;a href=&quot;https://cssbattle.dev/&quot;&gt;CSSBattle&lt;/a&gt; is a game where you play each level by replicating a given image as close as possible in just CSS in minimum number of characters (also called as code-golfing). Now writing minimum CSS may sound very impractical and it is! But you don&#39;t need to do code-golfing and can just focus on the matching the image part. Now even that might sound impractical, and yes that is! But suprisingly that gives you a very good practice in CSS properties and also helps develop your creative thinking when you come up with different approaches to replicate each level&#39;s image. There are so many levels on CSSBattle that doing them regularly will force you to experiment with each property and explore it in the process! I have personally learned a lot of properties here like clip-path, radial-gradient and much more.&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&quot;info-box&quot;&gt;
Disclaimer: I recommend CSSBattle in this post wich I have created. As biased as it may sound, I don&#39;t recommend it because I am the creator. It has been my first-hand experience learning a lot on that platform, accompanied by testimonials from a lot of other players.
&lt;/div&gt;
&lt;h2 id=&quot;final-tool&quot;&gt;Final tool &lt;a class=&quot;bookmark&quot; href=&quot;#final-tool&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In the end, the thing that will give the final sharpness to your CSS sword is - &lt;a href=&quot;https://drafts.csswg.org/&quot;&gt;&amp;quot;The Specifications&amp;quot;&lt;/a&gt;! Specifications are the written documentation on each feature of CSS, by the people who build CSS! It covers every topic in-depth - upto details which then are also used by all the browsers to implement those CSS features. Reading these specifications give you the extra bit of understanding into why every features works the way it does.&lt;/p&gt;
&lt;p&gt;Remember that learning and practicing are not sequential phases, they go hand-in-hand. Never stop learning as CSS language keeps evolving and so should your skills. And with time and practice, you can become a CSS master. Happy CSS-ing! 👋&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Logging query docs in Firebase Firestore</title>
		<link href="https://kushagra.dev/blog/firebase-query-logs/"/>
		<updated>2023-04-25T00:00:00+00:00</updated>
		<id>https://kushagra.dev/blog/firebase-query-logs/</id>
		<content type="html">&lt;p&gt;Firebase is one of my favourite and most useful tools! It’s one of the reasons Frontend developers like me are able to launch end-to-end products! No matter how much I praise Firebase, there is one distinct thing about it that always bothers me - it&#39;s peculiar way of fetching data and related error reporting. In a usual REST API system, you can easily inspect network calls, see the response and debug things. In Firebase, calls are not that trivial for queries you run. Its not straightforward to inspect them in the network tab of devtools.&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&quot;https://kushagra.dev/images/2023/firebase-network-response.png&quot;&gt;
&lt;figcaption&gt;Response of network call made by Firebase Firestore&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;But for this post I’ll like to focus on its error reporting. It’s not very unusual to hit an error like &lt;code&gt;Query.where() called with invalid data&lt;/code&gt;] which occurs when a &lt;code&gt;where&lt;/code&gt; clause is passed &lt;code&gt;undefined&lt;/code&gt; compare value. This error results from some query in your code, but it won’t tell you which one. Even if you put a debugger on the calling point of this error, the stack trace is so massive and convoluted that I am not even sure if you can reach the actual query from there. So how do you debug which query is resulting this such an error in Firebase?&lt;/p&gt;
&lt;div class=&quot;info-box&quot;&gt;
Note: This post is all related to Firebase v9 and it&#39;s Firestore database.
&lt;/div&gt;
&lt;h2 id=&quot;solution&quot;&gt;Solution &lt;a class=&quot;bookmark&quot; href=&quot;#solution&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;First thing we need is to know what queries are being made from your app. As there is no corresponding network call for each request, we can’t use the network tools for this. The only way left then is to put some log statements at all places where queries are made! What?? All places? Yes, there can be too many such places. Moreover, these log statements can’t be all same - each log statement will have to log some distinct pieces of information to be useful - eg. what doc or what collection is being queried.&lt;/p&gt;
&lt;p&gt;What we can do is put our logging at some central place which we know gets called for all queries. Yes! We’ll monkey-patch Firebase API for this.&lt;/p&gt;
&lt;p&gt;2 ways to read/write documents in Firebase (Firestore) are through the &lt;code&gt;doc&lt;/code&gt; and &lt;code&gt;collection&lt;/code&gt; functions on the Firestore&#39;s DB instance. These are the functions we’ll patch, like so:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; db &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; firebase&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;firestore&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;DEBUG_MODE&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; _doc &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; db&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;doc&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; _collection &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; db&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;collection&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  db&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;doc&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;args&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;    console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;doc()&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; args&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;_doc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;apply&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;db&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; args&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  db&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;collection&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;args&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;    console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;collection()&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; args&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;_collection&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;apply&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;db&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; args&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We set &lt;code&gt;db.doc&lt;/code&gt; and &lt;code&gt;db.collection&lt;/code&gt; to our own functions which first log the received arguments and then call the original functions from within. Now we see what all queries were made in the console:&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&quot;https://kushagra.dev/images/2023/firebase-query-logs.png&quot;&gt;
&lt;figcaption&gt;Query logs in devtools console&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;This isn’t a complete solution though. First, it won’t tell the additional info from &lt;code&gt;where&lt;/code&gt;, &lt;code&gt;orderBy&lt;/code&gt; etc. You’ll need to figure out from the &lt;code&gt;doc/collection&lt;/code&gt; argument, the place of the actual call, put a &lt;code&gt;debugger&lt;/code&gt; point and then see the other information at that instance. Still this works as a good starting point for me as now I can at least see what all queries are being made in the app and I can spot abnormalities from there.&lt;/p&gt;
&lt;p&gt;I’ll probably keep refining the patch here to make it more informative. Let me know how you debug such instances in Firebase.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Mistake - deployed to wrong firebase project</title>
		<link href="https://kushagra.dev/blog/mistake-deployed-wrong-firebase-project/"/>
		<updated>2023-04-09T00:00:00+00:00</updated>
		<id>https://kushagra.dev/blog/mistake-deployed-wrong-firebase-project/</id>
		<content type="html">&lt;p&gt;Hello, we meet so soon after my last mistake. 😄 Yesterday I was deploying &lt;a href=&quot;https://cssbattle.dev/&quot;&gt;CSSBattle&#39;s&lt;/a&gt; backend because new targets were to be unlocked and it did happen fine. Soon after, players started reporting that submissions are acting weirdly. There was an error in the submission call but the target scores were recorded correctly. Also, for the 2 new targets, the high score was not being added to the battle score!&lt;/p&gt;
&lt;p&gt;This happened for the first time…I couldn’t really see why this should happen. The gcloud logs showed an error while recalculating the battle score - which happens after saving the target score. So that made sense, the call worked partially till saving the target score but failed while recalculating the battle score.&lt;/p&gt;
&lt;h2 id=&quot;the-bug&quot;&gt;The bug &lt;a class=&quot;bookmark&quot; href=&quot;#the-bug&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The error looked like the code I had deployed never got deployed - strange! There is one thing peculiar about that code though - it was from a yarn monorepo package outside the Firebase package. And because of how Firebase works, it&#39;s deployed in a little hacky manner. 🤷🏻 So I thought maybe that got messed up and I re-deployed. But even that didn’t fix anything.&lt;/p&gt;
&lt;p&gt;Just then I remembered - we had &lt;a href=&quot;https://x.com/cssmonk/status/1637825848223969281?s=20&quot;&gt;introduced a staging environment on Firebase&lt;/a&gt;! I quickly went into the terminal to check which project did I deploy to…and yes, I had deployed to the staging environment (which I was working on before deployment). 🤦🏻‍♂️&lt;/p&gt;
&lt;h2 id=&quot;solution&quot;&gt;Solution &lt;a class=&quot;bookmark&quot; href=&quot;#solution&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;That was pretty simple — I switched to the production environment with &lt;code&gt;firebase use &amp;lt;projectID&amp;gt;&lt;/code&gt; and re-deployed!&lt;/p&gt;
&lt;p&gt;But that is not actually the solution to the problem. I can make the same mistake again in the future. It’s very easy to miss which Firebase project/environment is set in the terminal. I still have to solve this for us, but I have a few ideas:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I could add the Firebase project name in my terminal prompt. That way it always shows without explicit checking. But still, I could miss seeing my prompt.&lt;figure&gt;
&lt;img src=&quot;https://kushagra.dev/images/2023/terminal-prompt.png&quot;&gt;
&lt;figcaption&gt;My terminal prompt&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;I use a shell script that internally does Firebase deployment. I could make that script print out loud something like “DEPLOYING TO X PROJECT”…in s big font! So that as soon as deployment starts, I clearly see where I am deploying.&lt;/li&gt;
&lt;li&gt;(Added on 12th April &#39;23) Right now I use a single npm command &lt;code&gt;npm run deploy&lt;/code&gt; to deploy. I could break that command into &lt;code&gt;npm run deploy:staging&lt;/code&gt; and &lt;code&gt;npm run deploy:prod&lt;/code&gt; to make it very explicit where I am deploying! And inside those commands I can set the right project with &lt;code&gt;firebase use&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I think I’ll go with 2nd one and see how it goes. Do you have a better solution to this? Let me know on &lt;a href=&quot;https://x.com/cssmonk&quot;&gt;Twitter&lt;/a&gt; or &lt;a href=&quot;https://www.linkedin.com/in/chinchang/&quot;&gt;LinkedIn&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;See you in my next mistake!&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Mistake - comparison with optional chaining</title>
		<link href="https://kushagra.dev/blog/mistake-optional-chaining-comparison/"/>
		<updated>2023-04-07T00:00:00+00:00</updated>
		<id>https://kushagra.dev/blog/mistake-optional-chaining-comparison/</id>
		<content type="html">&lt;p&gt;I broke &lt;a href=&quot;https://cssbattle.dev/&quot;&gt;CSSBattle’s&lt;/a&gt; leaderboard recently because of an interesting bug. We had a piece of code, whose simplified version looked something like this:&lt;/p&gt;
&lt;pre class=&quot;language-jsx&quot;&gt;&lt;code class=&quot;language-jsx&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; isMore &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; a&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;score &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; b&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;score&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This got recently changed so that score was now inside a key called &lt;code&gt;overall&lt;/code&gt; and also, the &lt;code&gt;overall&lt;/code&gt; key was optional - could be there or not. Also, in the old scenario &lt;code&gt;score&lt;/code&gt; was always guaranteed to be there. But in the new structure, because &lt;code&gt;original&lt;/code&gt; key itself isn’t guaranteed, hence the &lt;code&gt;score&lt;/code&gt; key too. So very conveniently I changed the above comparison to access &lt;code&gt;score&lt;/code&gt; from &lt;code&gt;overall&lt;/code&gt; key through an optional chaining operator so that I don&#39;t get an error if &lt;code&gt;overall&lt;/code&gt; key doesn’t exist:&lt;/p&gt;
&lt;pre class=&quot;language-jsx&quot;&gt;&lt;code class=&quot;language-jsx&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; isMore &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; a&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;overall&lt;span class=&quot;token operator&quot;&gt;?.&lt;/span&gt;score &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; b&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;overall&lt;span class=&quot;token operator&quot;&gt;?.&lt;/span&gt;score&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Everything seemed to be working with the change…until I noticed that the comparison was returning faulty results in some cases.&lt;/p&gt;
&lt;h2 id=&quot;the-bug&quot;&gt;The Bug &lt;a class=&quot;bookmark&quot; href=&quot;#the-bug&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Here’s what happened. Assume in the original code, we have &lt;code&gt;a.score&lt;/code&gt; as 40 and &lt;code&gt;b.score&lt;/code&gt; as 0. With those values, &lt;code&gt;isMore&lt;/code&gt; would come out to be &lt;code&gt;true&lt;/code&gt; - which is correct. But what if now, &lt;code&gt;a.original.score&lt;/code&gt; is 40, but &lt;code&gt;b.orginal&lt;/code&gt; doesn’t exist. We expect &lt;code&gt;isMore&lt;/code&gt; to be still &lt;code&gt;true&lt;/code&gt; because 40 is more than &lt;em&gt;nothing&lt;/em&gt;, right? But that doesn’t happen - &lt;code&gt;isMore&lt;/code&gt; is &lt;code&gt;false&lt;/code&gt; in the new case. Let’s see why.&lt;/p&gt;
&lt;p&gt;Putting values in our expression, we get:&lt;/p&gt;
&lt;pre class=&quot;language-jsx&quot;&gt;&lt;code class=&quot;language-jsx&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; isMore &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;40&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;undefined&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// evaluates to false&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note: right side of the &lt;code&gt;&amp;gt;&lt;/code&gt; operator would evaluate to &lt;code&gt;undefined&lt;/code&gt; because of the optional chaining operator on a key which doesn’t exists. And &lt;code&gt;40&lt;/code&gt; , though we expect to be more than something which doesn’t exists, is actually not more than &lt;code&gt;undefined&lt;/code&gt; !&lt;/p&gt;
&lt;p&gt;That makes sense too (now at least 😛). I say the value “doesn’t exists” a lot of times above, but &lt;code&gt;undefined&lt;/code&gt; doesn’t mean “doesn’t exist”, it means the value isn’t defined. In JS, the closest to “doesn’t exists” would be &lt;code&gt;null&lt;/code&gt;. And as should be expected, &lt;code&gt;40 &amp;gt; null&lt;/code&gt; actually is &lt;code&gt;true&lt;/code&gt;!&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&quot;https://kushagra.dev/images/2023/optional-chaining-comparison.png&quot;&gt;
&lt;figcaption&gt;Comparison with undefined gives false and null gives true, shown in devtools&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&quot;solution&quot;&gt;Solution &lt;a class=&quot;bookmark&quot; href=&quot;#solution&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I patched the above expression to have &lt;code&gt;0&lt;/code&gt; as default value when &lt;code&gt;original&lt;/code&gt; key doesn’t exist:&lt;/p&gt;
&lt;pre class=&quot;language-jsx&quot;&gt;&lt;code class=&quot;language-jsx&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; isMore &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;overall&lt;span class=&quot;token operator&quot;&gt;?.&lt;/span&gt;score &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;b&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;overall&lt;span class=&quot;token operator&quot;&gt;?.&lt;/span&gt;score &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, we won’t have &lt;code&gt;undefined&lt;/code&gt; ever so numeric comparisons work correctly. Fixed!&lt;/p&gt;
&lt;p&gt;I’ll see you again with my next mistake! 👋🙂&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>New journey - is it a bad decision?</title>
		<link href="https://kushagra.dev/blog/new-journey/"/>
		<updated>2023-03-24T00:00:00+00:00</updated>
		<id>https://kushagra.dev/blog/new-journey/</id>
		<content type="html">&lt;p&gt;I finally get to write this post! First, some news recap - I recently quit my super-awesome job to work full-time on my product, &lt;a href=&quot;https://cssbattle.dev/&quot;&gt;CSSBattle&lt;/a&gt;. That&#39;s not it! We got blessed with baby boy exactly around the same time 😃 I know… that 2 news coming together triggers surprise, but more so - a lot of questions. Let me come to them.&lt;/p&gt;
&lt;h2 id=&quot;why-quit%3F&quot;&gt;Why Quit? &lt;a class=&quot;bookmark&quot; href=&quot;#why-quit%3F&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Let me start by talking about why I quit my job. People generally quit their job either because they are not enjoying their current work, not growing professionally or are getting a better salary somewhere else. I was enjoying my job though - great team and good work &amp;amp; money. But if you know me, you know how much I love doing side projects. One such side project I started with a &lt;a href=&quot;https://twitter.com/kushsolitary&quot;&gt;friend&lt;/a&gt; 3 years back is &lt;a href=&quot;https://twitter.com/css_battle&quot;&gt;CSSBattle&lt;/a&gt;. Over time it has grown a lot organically, to be one of the biggest platforms to learn and practice CSS. It gets us decent revenue without putting in too much development or marketing efforts regularly. What that means is that it has a huge huge scope to become even bigger. There is so much we want to build there. This whole idea of taking it to the next level is too exciting! And I believe unless I devote myself 100% to it, unlocking its 100% potential won’t be possible.&lt;/p&gt;
&lt;p&gt;But what about job and financial stability? That is another reason why people tend to stick with what they are doing. To be clear, this is not an ad-hoc decision I have taken. I have made sure I have a well-buffered runway to give me enough time to give 100% to CSSBattle and not worry about finances. And just in case I run out of money sooner than expected, I have confidence that I can again get back to a good job whenever I want. So there is essentially no risk on that front.&lt;/p&gt;
&lt;h2 id=&quot;but-why-now%3F&quot;&gt;But why now? &lt;a class=&quot;bookmark&quot; href=&quot;#but-why-now%3F&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;You never know when there pops another product that builds on top of yours. This doesn’t mean I am scared of competition or don’t want one. I have confidence that nobody can build this thing better than us! But competition would be bad if that becomes a reason for me to quit my job one day in haste. You can’t compete with a product being worked full-time on while you take yours as a side project. I wanted me to control my decision, not a competition that comes in the future.&lt;/p&gt;
&lt;p&gt;Moreover, each person I have talked to about CSSBattle and shared our vision with has only shared astonishment on where this has come and that gives me reassurance on what this can become! PS: I am lucky to have such friends around me who constantly motivate you to live your passion and are ready to support you in any way required! I am thankful to them 🙏🏼. And when I know where we can take CSSBattle, there is no point in delaying it further.&lt;/p&gt;
&lt;h2 id=&quot;but-going-indie%2C-with-a-kid%3F&quot;&gt;But going indie, with a kid? &lt;a class=&quot;bookmark&quot; href=&quot;#but-going-indie%2C-with-a-kid%3F&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I know, it is damn hard to run your own thing with a little kid! It is challenging! But one of the basic principles I go by is - “If you are comfortable, you can’t progress”. I realized it had been a while since I became uncomfortable again. Just that reason was enough for me to take the leap.&lt;/p&gt;
&lt;p&gt;I know it&#39;s going to be challenging, it’s a problem I’ll have to solve. And I am a problem solver in the first place, that’s what I have been doing my whole career. So a problem can’t be a reason for me to not do what I want to do because it’s what I do - solve problems. Anyways, there will always be an excuse for not quitting, if you don&#39;t want to. This challenge is new for me, it’s exciting and am looking forward to solving it! 😄&lt;/p&gt;
&lt;h2 id=&quot;did-i-take-a-bad-decision-or-a-good-one-at-the-wrong-time%3F&quot;&gt;Did I take a bad decision or a good one at the wrong time? &lt;a class=&quot;bookmark&quot; href=&quot;#did-i-take-a-bad-decision-or-a-good-one-at-the-wrong-time%3F&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I don’t think so! I know my decision involves a lot of risks &amp;amp; challenges. But whenever I have such risks, the only question I ask is what can possibly go wrong? And here the answer is — nothing much really! The worst that can happen is I run out of money - then I take a job again. Or I might not have enough time for CSSBattle - fine, it might a little more time to get where we want. But I know my efforts will definitely be more than what I would have had with a full-time job. I know one year down the line I won’t repent for not giving it my best shot or delaying further!&lt;/p&gt;
&lt;h2 id=&quot;how%E2%80%99s-it-going%3F&quot;&gt;How’s it going? &lt;a class=&quot;bookmark&quot; href=&quot;#how%E2%80%99s-it-going%3F&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Well, it has been 24 days since I started this new journey. With a newborn, it’s very difficult to get time for yourself (for every feed, baby needs a burping of 10-15 mins and baby takes feed every 2-3 hours or so. That’s 2 hours gone in just burping - crazyy!) 😅. But I got more time this week to build things compared to last week — so that’s all I want — improvement! I know I’ll get there.&lt;/p&gt;
&lt;p&gt;We (the “Kushagras”) have already started shipping things on CSSBattle and working on other exciting stuff we had in the pipeline. I am super pumped and excited to build and figure out what the future holds for CSSBattle!&lt;/p&gt;
&lt;p&gt;We are not hiring nor looking for investments, so that means we can 100% focus on building and shipping! 🚀😄&lt;/p&gt;
&lt;p&gt;I hope this post gives some perspective to those who have been sitting on their dreams and waiting for the right time. Trust in yourself, believe in your abilities, and take action toward your dreams. It may not be easy, but it will be worth it in the end. Remember, life is too short to settle for anything less than what truly makes you happy.&lt;/p&gt;
&lt;p&gt;Peace!&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>My TODO after gaining financial freedom</title>
		<link href="https://kushagra.dev/blog/todo-after-financial-freedom/"/>
		<updated>2022-11-08T00:00:00+00:00</updated>
		<id>https://kushagra.dev/blog/todo-after-financial-freedom/</id>
		<content type="html">&lt;p&gt;Lot of times you go somewhere and see someone doing something, you feel you want to do it, at least try it out. I have a similar list of things that I want to try out. You could say I should be doing these things even now if I like them...and I mostly do. But there are somethings that need more of your time and can&#39;t be done alongside a day job - the below mentioned things are those. Things that I did like to try for a month or so. Hence, I wan&#39;t to do them after I have gained financial freedom.&lt;/p&gt;
&lt;h2 id=&quot;financial-freedom&quot;&gt;Financial Freedom &lt;a class=&quot;bookmark&quot; href=&quot;#financial-freedom&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;There are many definitions out there for the term &amp;quot;Financial Freedom&amp;quot;. So let me first clear what it means for me. For me financial freedom is when I don&#39;t have to work anymore for money. I&#39;ll have enough for my needs and wants.&lt;/p&gt;
&lt;h2 id=&quot;my-todo-list&quot;&gt;My TODO List &lt;a class=&quot;bookmark&quot; href=&quot;#my-todo-list&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Cab Driver&lt;/strong&gt; - I want to be a cab driver for sometime. I like driving. I feel I like helping people reach their destination 😅 I might also choose to be a cab driver in a tech-savvy place like Bangalore where I could converse with my passengers and discuss tech with them, may be solve a problem or two for them - B.Tech Cab-wala? 😄&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;At a restaurant counter&lt;/strong&gt; - I want to be at the pay counter of McDonalds or a similar place where I can take food orders, provide money change to customers and get them their food.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Weekly sessions to teach programming&lt;/strong&gt; - I want to sit with kids and tell them about my experiences around programming (whatever I can remember and write by then). Guide them on how to be a good programmer and a product builder.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Fast food joint&lt;/strong&gt; - I want to open a fast food joint...probably just a small counter under a big umbrella with some seating. Something I can take places and serve food. I specifically want to serve sandwiches &amp;amp; burgers and some drinks alongside.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Do customer support&lt;/strong&gt; - I want to join a good company as a customer support representative for them. Customer support people are the people who interact with the customers the most and are make or break for any company. I have always fancied talking to customers and solving their problems. I already do some of it, but I want to do it full-time and really take it to the next level.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Play music in cafes&lt;/strong&gt; - Ever since I saw people do live performances in restaurants, I have wanted to do this! I want to play piano at restaurants...and if they give, have dinner there every time I play for them. 😃&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Live portraits at fairs&lt;/strong&gt; - I like drawing. I want to draw live at fairs &amp;amp; children parties and entertain folks.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Wood workshop&lt;/strong&gt; - I want to get a formal training in wood working and then open my own workshop to build custom furnitures for my customers.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;side-projects%3F&quot;&gt;Side Projects? &lt;a class=&quot;bookmark&quot; href=&quot;#side-projects%3F&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Just to be clear - I haven&#39;t mentioned &amp;quot;Side Projects&amp;quot; in my list above, doesn&#39;t mean it&#39;s not on my list. It&#39;s love for me, I don&#39;t think I can ever stop building products. I&#39;ll keep doing them, on my side, forever! ♥️&lt;/p&gt;
&lt;p&gt;Do you have a similar list? Share with me on &lt;a href=&quot;https://x.com/cssmonk/status/1589827525626466304&quot;&gt;this Twitter post&lt;/a&gt;.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Hint.css is free again!</title>
		<link href="https://kushagra.dev/blog/hint-css-is-free/"/>
		<updated>2020-04-30T00:00:00+00:00</updated>
		<id>https://kushagra.dev/blog/hint-css-is-free/</id>
		<content type="html">&lt;h2 id=&quot;tl%3Bdr&quot;&gt;TL;DR &lt;a class=&quot;bookmark&quot; href=&quot;#tl%3Bdr&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://kushagra.dev/lab/hint/&quot;&gt;&lt;strong&gt;Hint.css&lt;/strong&gt;&lt;/a&gt; is FREE again after being a paid product for nearly 3.5 years! 🥳&lt;/p&gt;
&lt;h2 id=&quot;back-story&quot;&gt;Back Story &lt;a class=&quot;bookmark&quot; href=&quot;#back-story&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://kushagra.dev/lab/hint/&quot;&gt;Hint.css&lt;/a&gt; is a CSS library I built back in 2013. It is a CSS-only solution to create tooltips. After it launched, it quickly gained a lot of traction, thousands of &lt;a href=&quot;https://github.com/chinchang/hint&quot;&gt;stars on Github&lt;/a&gt;, was featured twice (🥶) on the &lt;a href=&quot;https://news.ycombinator.com/item?id=5164029&quot;&gt;homepage of&lt;/a&gt; &lt;a href=&quot;https://news.ycombinator.com/item?id=11011420&quot;&gt;HackerNews&lt;/a&gt;, &lt;a href=&quot;https://www.producthunt.com/posts/hint-css-2-0&quot;&gt;featured on ProductHunt&lt;/a&gt; and mentioned on countless websites. It was launched under the MIT license and was free to use, no matter how you used it.&lt;/p&gt;
&lt;p&gt;In 2016 I decided to monetize it. I came across a resource aggregation website called Uplabs which had also started its own marketplace. It was still free for personal projects. But if you did use it in a commercial project, a license had to be purchased. I decided to monetize it for a number of reasons:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It was a very popular tooltip library&lt;/li&gt;
&lt;li&gt;I had never monetized any of my product before. I wanted to try it out.&lt;/li&gt;
&lt;li&gt;Who doesn&#39;t want a few bucks from a side-project! 😬&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;and-today&quot;&gt;And Today &lt;a class=&quot;bookmark&quot; href=&quot;#and-today&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;After a period of 3.5 years, I have finally decided to make it free again! Here is why I have made this decision:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It has not been getting too many sales recently. There is a life of every product on a marketplace.&lt;/li&gt;
&lt;li&gt;I think it has earned me enough, considering it was a few hours project! (and some days of maintenance) 😃&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;the-fun-part&quot;&gt;The Fun Part &lt;a class=&quot;bookmark&quot; href=&quot;#the-fun-part&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Okay, now the interesting part. How much did it earn me!! I have experimented a lot over the years with its pricing. I don&#39;t have an exact count of the number of sales (Uplabs doesn&#39;t give that). But till date, Hint.css has made &lt;strong&gt;$1902.88&lt;/strong&gt; in sales! I think it is pretty good considering the library is just a few lines of CSS I wrote. 😎&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://kushagra.dev/images/2020/uplabs-earning.png&quot; alt=&quot;earnings&quot;&gt;&lt;/p&gt;
&lt;h2 id=&quot;few-learnings&quot;&gt;Few Learnings &lt;a class=&quot;bookmark&quot; href=&quot;#few-learnings&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Experiment with pricing. It&#39;s difficult to guess what something is worth. I didn&#39;t expect people to purchased Hint.css for as much as $70!&lt;/li&gt;
&lt;li&gt;Side projects can teach you a lot of things. Hint.css taught me open-source maintenance and product monetization.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I am really proud of this sweet little experiment of mine. 🤩 And now that Hint.css is free again, go and use it to add some quick tooltips to your websites. Ciao!&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Terminal commands for daily use</title>
		<link href="https://kushagra.dev/blog/terminal-commands-for-daily-use/"/>
		<updated>2019-10-11T00:00:00+00:00</updated>
		<id>https://kushagra.dev/blog/terminal-commands-for-daily-use/</id>
		<content type="html">&lt;p&gt;This post is a compilation of the most used commands I use in my terminal daily. A reason to share this compilation is to give a quick introduction to how a few very common regular tasks can be done through commands in a terminal. I find running commands in the terminal a lot faster than otherwise doing through the GUI and hence makes me more productive. If you feel you are better without them, that is completely fine too. But I suggest everyone should try them to see what works best for you.&lt;/p&gt;
&lt;p&gt;There are 2 bonus tips at the end of this post to give you that extra productivity boost. Do read till the end.&lt;/p&gt;
&lt;h2 id=&quot;list-all-files-with-human-readable-filesizes&quot;&gt;List all files with human-readable filesizes &lt;a class=&quot;bookmark&quot; href=&quot;#list-all-files-with-human-readable-filesizes&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;ls&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-lah&lt;/span&gt; some/folder/path&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;l&lt;/code&gt; - lists the files &lt;strong&gt;l&lt;/strong&gt;ong format.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;a&lt;/code&gt; - lists &lt;strong&gt;a&lt;/strong&gt;ll the files.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;h&lt;/code&gt; - lists filesize in more &lt;strong&gt;h&lt;/strong&gt;uman-readable way.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Tip: you can list files of the current folder with &lt;code&gt;ls .&lt;/code&gt;&lt;/p&gt;
&lt;h2 id=&quot;switch-directory&quot;&gt;Switch directory &lt;a class=&quot;bookmark&quot; href=&quot;#switch-directory&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;cd&lt;/span&gt; some/folder/path&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;create-a-new-file&quot;&gt;Create a new file &lt;a class=&quot;bookmark&quot; href=&quot;#create-a-new-file&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;touch&lt;/span&gt; fileName.js&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Creates an empty file with the name &lt;code&gt;fileName.js&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;create-a-new-folder&quot;&gt;Create a new folder &lt;a class=&quot;bookmark&quot; href=&quot;#create-a-new-folder&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;mkdir&lt;/span&gt; new-folder-name&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;copy-a-file&quot;&gt;Copy a file &lt;a class=&quot;bookmark&quot; href=&quot;#copy-a-file&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;cp&lt;/span&gt; copyFrom.js copyTo.js&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;rename-a-file&quot;&gt;Rename a file &lt;a class=&quot;bookmark&quot; href=&quot;#rename-a-file&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;mv&lt;/span&gt; oldFile.js newFile.js&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;open-a-file-in-visual-studio-code-(vscode)&quot;&gt;Open a file in Visual Studio Code (VSCode) &lt;a class=&quot;bookmark&quot; href=&quot;#open-a-file-in-visual-studio-code-(vscode)&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;code fileName.css&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is really useful. If you are not aware, VSCode can be added as a shell command too. Here is &lt;a href=&quot;https://code.visualstudio.com/docs/setup/mac#_launching-from-the-command-line&quot;&gt;how to add VSCode as shell command&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;git-commands&quot;&gt;Git commands &lt;a class=&quot;bookmark&quot; href=&quot;#git-commands&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I am going to club these into one section.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;git status&lt;/code&gt; - Check the status of the repository in the current directory&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git checkout master&lt;/code&gt; - Switch to &lt;code&gt;master&lt;/code&gt; branch&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git pull --rebase origin &amp;lt;branch_name&amp;gt;&lt;/code&gt; - Pull remote changes from a branch called &lt;code&gt;branch_name&lt;/code&gt; and apply my unpushed changes over those pulled changes&lt;/li&gt;
&lt;li&gt;`git commit -m &amp;quot;my message here&amp;quot; - Commit changes&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git push origin &amp;lt;branch_name&amp;gt;&lt;/code&gt; - Push changes of branch &lt;code&gt;branch_name&lt;/code&gt; to remote&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;open-any-file-(max-osx-only)&quot;&gt;Open any file (Max OSX only) &lt;a class=&quot;bookmark&quot; href=&quot;#open-any-file-(max-osx-only)&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;open&lt;/span&gt; /some/path/filename.ext&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This basically works like double-clicking a file in the GUI file explorer. It opens the file in the default program set for that type of file. Super useful!&lt;/p&gt;
&lt;p&gt;&lt;code&gt;open&lt;/code&gt; is a Mac OSX command, but I am sure every OS has something similar.&lt;/p&gt;
&lt;h2 id=&quot;bonus-tips&quot;&gt;Bonus Tips &lt;a class=&quot;bookmark&quot; href=&quot;#bonus-tips&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id=&quot;quickly-accessing-your-terminal&quot;&gt;Quickly accessing your terminal &lt;a class=&quot;bookmark&quot; href=&quot;#quickly-accessing-your-terminal&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;When you start using your terminal for little quick things like mentioned above, it becomes all the more necessary that you are able to do them fast enough without any overhead. And so it makes sense to do some tweaks to make your terminal accessible as quickly as possible.&lt;/p&gt;
&lt;p&gt;For that, you can do 2 things.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;First, set your terminal to show as an overlay on the screen i.e. on top of whatever window you have open in front of you. In case you have spaces (also referred as workspaces) enabled on your machine, showing as overlay prevents unnecessary context switch in changing spaces (because you&#39;ll switch to whatever space the terminal window is in) and also removes the time delay it would take to switch spaces. Overlay terminal shows instantly.&lt;/li&gt;
&lt;li&gt;Next, set a hotkey on your terminal. That enables you to show up your terminal with a quick keyboard shortcut.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Most terminals (I have tested on Hyper and iTerm) let you do the above things natively or through some plugin.&lt;/p&gt;
&lt;h3 id=&quot;aliases&quot;&gt;Aliases &lt;a class=&quot;bookmark&quot; href=&quot;#aliases&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;With time, you&#39;ll realise that you use a few commands more frequently than others. For these commands, you can set &lt;a href=&quot;http://www.peachpit.com/articles/article.aspx?p=31442&amp;amp;seqNum=5&quot;&gt;aliases&lt;/a&gt;. Aliases are short names given to commands so that you don&#39;t have to type the complete command again and again. Whatever shell you are using, they allow setting aliases. You can find how to set aliases in your shell by searching &amp;quot;How to set aliases in &amp;lt;your_shell_name&amp;gt;&amp;quot;. By default, most operating systems give your &lt;code&gt;bash&lt;/code&gt; shell.&lt;/p&gt;
&lt;p&gt;Also, here is a good article on &lt;a href=&quot;https://www.thegeekdiary.com/examples-of-creating-command-alias-in-different-shells/&quot;&gt;setting aliases in few different shells&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Hope this post proves useful to you and give you some extra productivity boost! Ciao!&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Strong vs Em</title>
		<link href="https://kushagra.dev/blog/strong-vs-em/"/>
		<updated>2019-08-25T00:00:00+00:00</updated>
		<id>https://kushagra.dev/blog/strong-vs-em/</id>
		<content type="html">&lt;p&gt;&lt;code&gt;&amp;lt;strong&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;em&amp;gt;&lt;/code&gt; are two of the most basic tags that we learn when we start learning HTML. I am sure you must have used both these tags multiple times. I have too. But somewhere at the back of my mind I always had that slight confusion about which cases each should be used. In fact about which places one tag shouldn&#39;t be used. So I finally decided to look up the specifications to clear that doubt once and for all. And I must admit, the specification does a great job at explaining the purpose of each.&lt;/p&gt;
&lt;p&gt;If you also face that slight confusion about using &lt;code&gt;&amp;lt;strong&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;em&amp;gt;&lt;/code&gt; tags, you are at the right place. This article tries to re-express the learnings I got by reading the &lt;cite&gt;W3C specification&lt;/cite&gt;.&lt;/p&gt;
&lt;h2 id=&quot;tl%3Bdr&quot;&gt;TL;DR &lt;a class=&quot;bookmark&quot; href=&quot;#tl%3Bdr&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;div class=&quot;info-box&quot;&gt;
If it&#39;s just visual importance, you want &lt;code&gt;strong&lt;/code&gt;. If it alters the sentence meaning, use &lt;code&gt;em&lt;/code&gt;.
&lt;/div&gt;
&lt;h2 id=&quot;the-%3Cstrong%3E-tag&quot;&gt;The &lt;code&gt;&amp;lt;strong&amp;gt;&lt;/code&gt; tag &lt;a class=&quot;bookmark&quot; href=&quot;#the-%3Cstrong%3E-tag&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Firstly, to quote the &lt;cite&gt;&lt;a href=&quot;https://www.w3.org/TR/html50/text-level-semantics.html#the-strong-element&quot;&gt;W3C specification&lt;/a&gt;&lt;/cite&gt;&lt;/p&gt;
&lt;blockquote&gt;
The strong element represents strong importance, seriousness, or urgency for its contents.
&lt;/blockquote&gt;
&lt;p&gt;Let&#39;s try to understand those 3 use cases.&lt;/p&gt;
&lt;h3 id=&quot;importance&quot;&gt;Importance &lt;a class=&quot;bookmark&quot; href=&quot;#importance&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Importance can be thought of like &amp;quot;hierarchy&amp;quot;. For example, say you are describing certain items in different paragraphs. You will probably start the paragraph by putting the item name in &lt;code&gt;strong&lt;/code&gt; tags, like so:&lt;/p&gt;
&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;strong&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Item X&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;strong&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;: This paragraph is all about describing Item X, it&#39;s&lt;br&gt;  properties and behaviour.&lt;br&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;strong&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Item Y&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;strong&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;: This paragraph is all about describing Item Y, it&#39;s&lt;br&gt;  properties and behaviour.&lt;br&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;They are acting similar to headings, visually. I compare importance with hierarchy because if someone needs to quickly scan all such items described in the paragraphs, they can just glance at the &lt;code&gt;strong&lt;/code&gt; texts which also appear bold (and hence seemingly higher up the hierarchy).&lt;/p&gt;
&lt;h3 id=&quot;seriousness&quot;&gt;Seriousness &lt;a class=&quot;bookmark&quot; href=&quot;#seriousness&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;A classic example of this is when you need to show a warning or error. You could simply show a sentence describing the whole warning but there could be a chance that user ignores reading the whole text, and thus the warning. To make it more evident that the particular text is conveying a warning, we can wrap it in &lt;code&gt;strong&lt;/code&gt; tags. Again, the bold appearance of the &lt;code&gt;strong&lt;/code&gt; tag helps us convey that this is not just another text. It&#39;s something serious and needs to be seen.&lt;/p&gt;
&lt;p&gt;A simple example:&lt;/p&gt;
&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;strong&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Warning: You data will lost in 35 seconds&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;strong&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;which renders as:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Warning: You data will be lost in 35 seconds&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id=&quot;urgency&quot;&gt;Urgency &lt;a class=&quot;bookmark&quot; href=&quot;#urgency&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;This use case is something I have encountered quite a lot, especially while writing emails. Say you are writing a long paragraph and there are certain things that you want the reader to read first and foremost. Those things can be wrapped in &lt;code&gt;strong&lt;/code&gt; tags.&lt;/p&gt;
&lt;p&gt;Again, the whole premise is that the person reading your long text doesn&#39;t have the time to read all the text and even if they do, there might be certain important pieces of text that are intended to be read first and act urgently. The &lt;code&gt;strong&lt;/code&gt; tag helps us achieve that.&lt;/p&gt;
&lt;p&gt;I know all the 3 use cases seem similar and overlapping each other. That is true. But overall they do help to construct a good set of intentions where you would use the &lt;code&gt;strong&lt;/code&gt; tag.&lt;/p&gt;
&lt;h2 id=&quot;the-%3Cem%3E-tag&quot;&gt;The &lt;code&gt;&amp;lt;em&amp;gt;&lt;/code&gt; tag &lt;a class=&quot;bookmark&quot; href=&quot;#the-%3Cem%3E-tag&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;em&lt;/code&gt; tag reads as &lt;code&gt;emphasis&lt;/code&gt; but it certainly isn&#39;t just that. In fact, it&#39;s that word &lt;em&gt;emphasis&lt;/em&gt; that has confused a lot of us in thinking that it is similar to the &lt;code&gt;strong&lt;/code&gt; tag, which is also used to emphasize the importance of something. And it is not!&lt;/p&gt;
&lt;p&gt;Again, to quote the &lt;cite&gt;&lt;a href=&quot;https://www.w3.org/TR/html50/text-level-semantics.html#the-em-element&quot;&gt;W3C specification&lt;/a&gt;&lt;/cite&gt;:&lt;/p&gt;
&lt;blockquote&gt;
The em element represents stress emphasis of its contents.
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Stress emphasis&lt;/strong&gt; is the important thing to note here. It actually has to do with how you speak a particular piece of text.&lt;br&gt;
Let me explain the gist of &lt;code&gt;em&lt;/code&gt; tag with a gif:&lt;/p&gt;
&lt;img src=&quot;https://kushagra.dev/blog/strong-vs-em/&quot; class=&quot;visually-hidden&quot; alt=&quot;A person making air quotes while text shows on then screen: Get the &amp;quot;Laundry&amp;quot; (with quotes around the word - &amp;quot;laundry&amp;quot;)&quot;&gt;
&lt;iframe tabindex=&quot;-1&quot; aria-hidden=&quot;true&quot; src=&quot;https://giphy.com/embed/31P5RGyIVBhMMfw0F7&quot; width=&quot;480&quot; height=&quot;270&quot; frameBorder=&quot;0&quot; class=&quot;giphy-embed&quot; allowFullScreen=&quot;&quot;&gt;&lt;/iframe&gt;&lt;p&gt;&lt;a href=&quot;https://giphy.com/&quot;&gt;via GIPHY&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I am sure you have seen people doing this quote gesture while speaking a particular word or phrase in a long sentence. Imagine they hadn&#39;t done that gesture while speaking that word/phrase. Would you have got the same meaning out of that speaker? No. Because the specific stress that the speaker put on that particular part of the sentence, changed their intended meaning.&lt;/p&gt;
&lt;p&gt;This is exactly what the &lt;code&gt;em&lt;/code&gt; tag helps you do while writing. You can wrap certain parts of sentences to simulate the same stress as you would while speaking.&lt;/p&gt;
&lt;p&gt;To make it more clear, I would like to show you the exact example from the &lt;cite&gt;W3C specification&lt;/cite&gt; because I think it does the job perfectly in explaining what &lt;code&gt;em&lt;/code&gt; tag does.&lt;/p&gt;
&lt;blockquote&gt;
These examples show how changing the stress emphasis changes the meaning. First, a general statement of fact, with no stress:
&lt;p&gt;&lt;code&gt;&amp;lt;p&amp;gt;Cats are cute animals.&amp;lt;/p&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;By emphasizing the first word, the statement implies that the kind of animal under discussion is in question (maybe someone is asserting that dogs are cute):&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;p&amp;gt;&amp;lt;em&amp;gt;Cats&amp;lt;/em&amp;gt; are cute animals.&amp;lt;/p&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Moving the stress to the verb, one highlights that the truth of the entire sentence is in question (maybe someone is saying cats are not cute):&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;p&amp;gt;Cats &amp;lt;em&amp;gt;are&amp;lt;/em&amp;gt; cute animals.&amp;lt;/p&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;By moving it to the adjective, the exact nature of the cats is reasserted (maybe someone suggested cats were mean animals):&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;p&amp;gt;Cats are &amp;lt;em&amp;gt;cute&amp;lt;/em&amp;gt; animals.&amp;lt;/p&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Similarly, if someone asserted that cats were vegetables, someone correcting this might emphasize the last word:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;p&amp;gt;Cats are cute &amp;lt;em&amp;gt;animals&amp;lt;/em&amp;gt;.&amp;lt;/p&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;By emphasizing the entire sentence, it becomes clear that the speaker is fighting hard to get the point across. This kind of stress emphasis also typically affects the punctuation, hence the exclamation mark here.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;p&amp;gt;&amp;lt;em&amp;gt;Cats are cute animals!&amp;lt;/em&amp;gt;&amp;lt;/p&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Anger mixed with emphasizing the cuteness could lead to markup such as:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Cats are &lt;em&gt;cute&lt;/em&gt; animals!&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Hope these examples make it all clear.&lt;/p&gt;
&lt;h2 id=&quot;screen-reader-accessibility&quot;&gt;Screen reader accessibility &lt;a class=&quot;bookmark&quot; href=&quot;#screen-reader-accessibility&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;strong&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;em&amp;gt;&lt;/code&gt; are not just meant to convey semantics visually, but they are also supposed to convey the same meaning to screen reader users too, ideally through a change of voice.&lt;/p&gt;
&lt;p&gt;From what I could test, VoiceOver doesn&#39;t seem to differentiate normal text from the emphasized text. Also, there seems to be no recent studies on the Web for other screen readers like JAWS and NVDA. Hence, I am not covering this topic in much details. I would appreciate if someone can share studies on this matter, which I can update here.&lt;/p&gt;
&lt;p&gt;Nevertheless, screen readers are continuously improving and our correct use of the tags will only help users eventually.&lt;/p&gt;
&lt;p&gt;Also, it&#39;s worth noting that accessibility isn&#39;t always about screen readers. The visual difference that comes with &lt;code&gt;strong&lt;/code&gt;/&lt;code&gt;em&lt;/code&gt; tag is great for increasing reading comprehension and helping with cognitive disabilities like dyslexia.&lt;/p&gt;
&lt;h2 id=&quot;summary&quot;&gt;Summary &lt;a class=&quot;bookmark&quot; href=&quot;#summary&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Next time you get confused which tag to use out of &lt;code&gt;strong&lt;/code&gt; and &lt;code&gt;em&lt;/code&gt;, think about this: What&#39;s your intention - is it just visual importance or do you want to stress over something to communicate better by changing the meaning of the sentence (like you would have stressed while speaking)?&lt;/p&gt;
&lt;p&gt;If it&#39;s just visual importance, you want &lt;code&gt;strong&lt;/code&gt;. If it alters the sentence meaning, use &lt;code&gt;em&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;what-about-b-and-i-tags%3F&quot;&gt;What about &lt;code&gt;b&lt;/code&gt; and &lt;code&gt;i&lt;/code&gt; tags? &lt;a class=&quot;bookmark&quot; href=&quot;#what-about-b-and-i-tags%3F&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;There is also a common confusion while choosing between &lt;code&gt;strong&lt;/code&gt;/&lt;code&gt;b&lt;/code&gt; and &lt;code&gt;em&lt;/code&gt;/&lt;code&gt;i&lt;/code&gt;. Visually they look exactly the same as their counterparts. Then what&#39;s the difference?&lt;/p&gt;
&lt;p&gt;The difference lies in semantics. &lt;code&gt;strong&lt;/code&gt; and &lt;code&gt;em&lt;/code&gt; bring in some additional context or meaning wherever used. On the other hand, &lt;code&gt;b&lt;/code&gt; and &lt;code&gt;i&lt;/code&gt; are just for styling and visually differentiating some part of the sentence from the rest. You can consider &lt;code&gt;b&lt;/code&gt; tag the same as a &lt;code&gt;span&lt;/code&gt; with a CSS of &lt;code&gt;font-weight: bold&lt;/code&gt; applied on it. Similarly, &lt;code&gt;i&lt;/code&gt; can be thought of as a &lt;code&gt;span&lt;/code&gt; with CSS of &lt;code&gt;font-style: italics&lt;/code&gt; applied on it.&lt;/p&gt;
&lt;p&gt;So if you want to communicate importance, urgency or seriousness, use &lt;code&gt;strong&lt;/code&gt;. If you just need to draw attention without any importance, use &lt;code&gt;b&lt;/code&gt; or rather just use CSS &lt;code&gt;font-weight&lt;/code&gt;. Similarly, if you want put stress on something, use &lt;code&gt;em&lt;/code&gt;. If it&#39;s just about highlighting a different type of text, such as a word in another language, then use &lt;code&gt;&amp;lt;i&amp;gt;&lt;/code&gt; or just CSS &lt;code&gt;font-style&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.w3.org/TR/html50/text-level-semantics.html#the-b-element&quot;&gt;Read more about &lt;code&gt;b&lt;/code&gt; tag&lt;/a&gt;&lt;br&gt;
&lt;a href=&quot;https://www.w3.org/TR/html50/text-level-semantics.html#the-i-element&quot;&gt;Read more about &lt;code&gt;i&lt;/code&gt; tag&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;That is all for this post. Hope this helps understand these common tags better.&lt;/p&gt;
&lt;hr class=&quot;post__divider&quot;&gt;
&lt;p&gt;Special thanks to &lt;a href=&quot;https://twitter.com/jitendravyas&quot;&gt;Jitendra Vyas&lt;/a&gt;, &lt;a href=&quot;https://twitter.com/stommepoes&quot;&gt;@stommepoes&lt;/a&gt;, and the lovely members of &lt;a href=&quot;https://web-a11y.slack.com/&quot;&gt;Slack Web Accessibility group&lt;/a&gt; for reviewing this post.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Case Study: Accessibility Report for Managers - Part 2</title>
		<link href="https://kushagra.dev/blog/case-study-accessibility-report-for-managers-p2/"/>
		<updated>2019-08-08T00:00:00+00:00</updated>
		<id>https://kushagra.dev/blog/case-study-accessibility-report-for-managers-p2/</id>
		<content type="html">&lt;div class=&quot;info-box&quot;&gt;
&lt;p&gt;
This is a two part case-study of why and how I created my recent side-project - &lt;a href=&quot;https://a11yformanagers.now.sh/&quot;&gt;Accessibility Report for Managers&lt;/a&gt;.&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;Part 1 - &lt;a href=&quot;https://kushagra.dev/blog/case-study-accessibility-report-for-managers-p1/&quot;&gt;Idea &amp; Frontend&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Part 2 - Backend &amp; Deployment&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;p&gt;In the &lt;a href=&quot;https://kushagra.dev/blog/case-study-accessibility-report-for-managers-p1/&quot;&gt;previous chapter&lt;/a&gt;, I took you through why I made &lt;a href=&quot;https://a11yformanagers.now.sh/&quot;&gt;&lt;strong&gt;Accessibility Report for Managers&lt;/strong&gt;&lt;/a&gt; and the rationale behind it. Also, we saw how different parts of the frontend are created. In this chapter, I’ll take you into how the app works behind the scene - The Backend and how the complete app is deployed. Let’s dive in.&lt;/p&gt;
&lt;h2 id=&quot;backend&quot;&gt;Backend &lt;a class=&quot;bookmark&quot; href=&quot;#backend&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id=&quot;the-monorepo&quot;&gt;The Monorepo &lt;a class=&quot;bookmark&quot; href=&quot;#the-monorepo&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Before getting into the backend, I would highlight the folder structure of this app. I use a Monorepo structure - which means the frontend and backend, both reside in the same repo as side-by-side folders. And as a general &lt;a href=&quot;https://github.com/lerna/lerna&quot;&gt;Lerna&lt;/a&gt; convention, I place them &lt;a href=&quot;https://github.com/chinchang/a11y-for-managers/tree/master/packages&quot;&gt;inside a &amp;quot;packages&amp;quot; folder&lt;/a&gt;. The frontend is in the &lt;code&gt;/packages/app&lt;/code&gt; folder and backend in &lt;code&gt;/packages/api&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: I am not using Lerna, just following its packages folder convention.&lt;/p&gt;
&lt;h3 id=&quot;getting-the-actual-accessibility-issues&quot;&gt;Getting the actual Accessibility issues &lt;a class=&quot;bookmark&quot; href=&quot;#getting-the-actual-accessibility-issues&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The whole basis of this app is first getting the real Accessibility issues on a particular website which we can later highlight by turning into fake feedbacks. For this, I wanted a library that could detect most Accessibility issues on a website, with easy setup and API. Out of the many, I chose to use &lt;a href=&quot;https://pa11y.org/&quot;&gt;pa11y&lt;/a&gt;. &lt;strong&gt;pa11y&lt;/strong&gt; is an open-source Node.js library to find Accessibility issues on a webpage. Perfect for my case.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;pa11y&lt;/strong&gt; can run its tests on an actual Chrome browser or you can provide it a Puppeteer instance, which is basically headless Chrome. This part of the backend resides in a script: &lt;a href=&quot;https://github.com/chinchang/a11y-for-managers/blob/master/packages/api/generate.js&quot;&gt;&lt;code&gt;packages/api/generate.js&lt;/code&gt;&lt;/a&gt;. Input for this endpoint is just the URL of the webpage that we want to run the Accessibility tests on. This input is passed to the endpoint as a query parameter. We’ll later see how this script gets served as an API on a URL endpoint. &lt;code&gt;generate.js&lt;/code&gt; just runs pa11y over the passed webpage URL and sends pa11y’s test results in the response.&lt;/p&gt;
&lt;p&gt;You might be thinking where does &lt;strong&gt;pa11y&lt;/strong&gt; get Chrome browser from. The complete backend is deployed on a serverless environment (I’ll cover this in more depth when we get to the deployment part). So I do not actually have a server that I control and can install Chrome browser on. This is where &lt;code&gt;chrome-aws-lambda&lt;/code&gt; comes in. Consider it as a stripped-down Chrome browser specifically tailored for serverless environments (particularly AWS and Google Cloud).&lt;/p&gt;
&lt;p&gt;Now that we have got the actual issues on a webpage, we pass them to the frontend as a JSON response. And we saw in the last chapter how these get processed and turned into fake feedbacks.&lt;/p&gt;
&lt;h3 id=&quot;showing-the-affected-page-element&quot;&gt;Showing the affected page element &lt;a class=&quot;bookmark&quot; href=&quot;#showing-the-affected-page-element&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;If you try the app on a URL, you’ll notice that in each feedback tweet it also shows the image of the affected element on that page.&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&quot;https://kushagra.dev/images/2019/a11yformanagers-tweet.png&quot;&gt;
&lt;figcaption&gt;Tweet screenshot of a fake user complaining about color contrast user&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;How does it do that?&lt;/p&gt;
&lt;p&gt;Remember the result object we get from pa11y?&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token literal-property property&quot;&gt;code&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;WCAG2AA.Principle2.Guideline2_4.2_4_1.H64.1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token literal-property property&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Iframe element requires a non-empty title attribute that identifies the frame.&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token literal-property property&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;error&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token literal-property property&quot;&gt;selector&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;#77c8c1c1-74e9-4d61-be2e-c1e39ffe02a0&quot;&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It also gives us the CSS selector of the page element that the Accessibility is found on. Now that we have the selector, how do we take an image of it? Enter &lt;a href=&quot;https://pptr.dev/&quot;&gt;Puppeteer&lt;/a&gt;.&lt;/p&gt;
&lt;p class=&quot;info-box&quot;&gt;
Puppeteer is a high-level API to control a Chrome or Chromium browser (and now Firefox also). It runs the browser in headless mode by default - meaning the core of the browser runs without all the UI and visual stuff. Hence it is faster than running a normal browser instance.
&lt;/p&gt;
&lt;p&gt;Out of the several wonderful API options, there is one to grab a screenshot of any element on a URL. Now that we know this, it is time to create another API endpoint to generate the image for the affected page elements. As you can guess, this endpoint will require 2 things as input: a page URL and the CSS selector of the element. And it all happens inside &lt;a href=&quot;https://github.com/chinchang/a11y-for-managers/blob/master/packages/api/image.js&quot;&gt;packages/api/image.js&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Few things to note in this script:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;We are decoding the passed CSS selector before using it, like so:&lt;br&gt;
&lt;code&gt;const selector = decodeURIComponent(queryData.selector);&lt;/code&gt;&lt;br&gt;
The &lt;a href=&quot;https://github.com/chinchang/a11y-for-managers/blob/master/packages/api/image.js#L8&quot;&gt;CSS selector is encoded&lt;/a&gt; on the frontend before sending as query parameter because it can contain URL-unsafe characters like &lt;code&gt;#&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;This is a little different from a traditional API endpoint which you call asynchronously to get a JSON response. Firstly, it doesn’t send a JSON response. Note the following &lt;a href=&quot;https://github.com/chinchang/a11y-for-managers/blob/2dd19118445c538e5e8c1a2755821ce327953eb3/packages/api/image.js#L13&quot;&gt;line in the script&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;res.setHeader(&amp;quot;Content-Type&amp;quot;, image/png);&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;We are setting the &lt;code&gt;Content-Type&lt;/code&gt; header for our response as &lt;code&gt;image/png&lt;/code&gt;. i.e. we are telling the browser to expect a PNG image from us. This is the same header value you’ll see in a usual PNG image. And how do you usually use a PNG image? In an &lt;code&gt;&amp;lt;image&amp;gt;&lt;/code&gt; tag. That’s right, our API endpoint is designed such that it can be used in an &lt;code&gt;&amp;lt;image&amp;gt;&lt;/code&gt; tag inside the &lt;code&gt;src&lt;/code&gt; attribute. For example: if the endpoint is available on &lt;em&gt;&lt;a href=&quot;https://app.com/api/image&quot;&gt;https://app.com/api/image&lt;/a&gt;&lt;/em&gt; and we want to generate screenshot image of an element on page &lt;a href=&quot;https://targetpage.com/&quot;&gt;https://targetpage.com&lt;/a&gt; having CSS selector as &lt;code&gt;.avatar&lt;/code&gt;, we can do it like so:&lt;/p&gt;
&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;image&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token attr-name&quot;&gt;src&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;https://app.com/api/image?url=https%3A%2F%2Ftargetpage.com&amp;amp;selector=.avatar&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;image&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And our captured screenshot would show up in the image tag!&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Also, just like the pa11y script, I use &lt;code&gt;chrome-aws-lamda&lt;/code&gt; as the Chrome instance because it is light-weight. And instead of &lt;code&gt;uppeteer&lt;/code&gt; module, I use &lt;code&gt;puppeteer-core&lt;/code&gt; for the same reason that it’s very minimal and light-weight. All these file size optimizations are necessary to take into account when you go with serverless architecture because you get a very limited amount of resources to run your code on. Of course, you can pay more and get on better resource plans, but you get my point.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That completes our backend - a set of 2 URL endpoints. One to get the issues on a webpage and second to generate a screenshot of any image on a webpage.&lt;/p&gt;
&lt;h2 id=&quot;deployment&quot;&gt;Deployment &lt;a class=&quot;bookmark&quot; href=&quot;#deployment&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I decided to try &lt;a href=&quot;https://zeit.co/now&quot;&gt;Zeit’s Now&lt;/a&gt; for this app. It let’s you deploy static files on a custom domain and also supports running many server-side languages in a serverless environment. No server management hassles, nothing. Absolutely a treat to deploy things on it.&lt;br&gt;
I have 2 components of my app that will get deployed on &lt;em&gt;Now -&lt;/em&gt; the frontend app and the backend APIs. How each component gets deployed on &lt;em&gt;Now&lt;/em&gt; is defined in a file called &lt;code&gt;now.json&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Frontend configuration&lt;/strong&gt;&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token string-property property&quot;&gt;&quot;version&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token string-property property&quot;&gt;&quot;builds&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;br&gt;        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;          &lt;span class=&quot;token string-property property&quot;&gt;&quot;src&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;packages/app/package.json&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;          &lt;span class=&quot;token string-property property&quot;&gt;&quot;use&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;@now/static-build&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;          &lt;span class=&quot;token string-property property&quot;&gt;&quot;config&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;            &lt;span class=&quot;token string-property property&quot;&gt;&quot;distDir&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;build&quot;&lt;/span&gt;&lt;br&gt;          &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token string-property property&quot;&gt;&quot;routes&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;br&gt;        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;          &lt;span class=&quot;token string-property property&quot;&gt;&quot;src&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;^/(.*)&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;          &lt;span class=&quot;token string-property property&quot;&gt;&quot;dest&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;/packages/app/$1&quot;&lt;/span&gt;&lt;br&gt;        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notice a single entry in the &lt;code&gt;build&lt;/code&gt; array. Its the configuration to deploy our frontend. What we are telling &lt;strong&gt;Now&lt;/strong&gt; is:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;the path of our app (particularly the &lt;code&gt;package.json&lt;/code&gt; file)&lt;/li&gt;
&lt;li&gt;that it needs to build the app first, by specifying the &lt;code&gt;@now/static-build&lt;/code&gt; builder&lt;/li&gt;
&lt;li&gt;path to our final build folder, which is &lt;code&gt;build&lt;/code&gt; in our case.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;You also have the ability to define redirects in &lt;code&gt;now.json&lt;/code&gt; which is a very powerful tool to create app routes, APIs, proxies and much more. Using the same, we define a route which tells &lt;em&gt;Now&lt;/em&gt; to redirect every request to our just deployed frontend app. A very important thing to note here is the &lt;code&gt;dest&lt;/code&gt; path we give in our route: &lt;code&gt;/packages/app/$1&lt;/code&gt;. &lt;em&gt;Now&lt;/em&gt; takes the contents of the &lt;code&gt;distDir&lt;/code&gt; we provided in our build config, and makes it available inside the folder that is being built. So in our case here, the final build artifacts are available inside &lt;code&gt;/packages/app&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Backend configuration&lt;/strong&gt;&lt;br&gt;
Just like put an entry in the &lt;code&gt;builds&lt;/code&gt; array for our frontend app, we’ll put an entry for each of our API endpoint. First, our issue generation script: &lt;code&gt;generate.js&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token string-property property&quot;&gt;&quot;version&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token string-property property&quot;&gt;&quot;builds&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;br&gt;        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;          &lt;span class=&quot;token string-property property&quot;&gt;&quot;src&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;packages/app/package.json&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;          &lt;span class=&quot;token string-property property&quot;&gt;&quot;use&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;@now/static-build&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;          &lt;span class=&quot;token string-property property&quot;&gt;&quot;config&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;            &lt;span class=&quot;token string-property property&quot;&gt;&quot;distDir&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;build&quot;&lt;/span&gt;&lt;br&gt;          &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;          &lt;span class=&quot;token string-property property&quot;&gt;&quot;src&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;packages/api/generate.js&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;          &lt;span class=&quot;token string-property property&quot;&gt;&quot;use&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;@now/node&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;          &lt;span class=&quot;token string-property property&quot;&gt;&quot;config&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token string-property property&quot;&gt;&quot;maxLambdaSize&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;40mb&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token string-property property&quot;&gt;&quot;routes&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;br&gt;        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;          &lt;span class=&quot;token string-property property&quot;&gt;&quot;src&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;^/api/generate.*&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;          &lt;span class=&quot;token string-property property&quot;&gt;&quot;dest&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;/packages/api/generate.js&quot;&lt;/span&gt;&lt;br&gt;        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;          &lt;span class=&quot;token string-property property&quot;&gt;&quot;src&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;^/(.*)&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;          &lt;span class=&quot;token string-property property&quot;&gt;&quot;dest&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;/packages/app/$1&quot;&lt;/span&gt;&lt;br&gt;        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Same as before, we tell is the script to run, we tell it to use &lt;code&gt;Node.js&lt;/code&gt; for it and finally some serverless environment config to limit the memory available to our code.&lt;/p&gt;
&lt;p class=&quot;info-box&quot;&gt;
The total of 40mb memory size is why we need things like &#39;chrome-aws-lambda&#39; and &#39;puppeteer-core&#39; which provide us the absolute minimal version of their respective capabilities. Thus making them faster and lighter to run.
&lt;/p&gt;
&lt;p&gt;And then, we add a route to redirect any request on &lt;code&gt;/api/generate.*&lt;/code&gt; to our &lt;code&gt;generate.js&lt;/code&gt; script. Done!&lt;/p&gt;
&lt;p&gt;Build config for the &lt;code&gt;image.js&lt;/code&gt; script is similar and this is how our final &lt;code&gt;now.json&lt;/code&gt; looks like:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token string-property property&quot;&gt;&quot;version&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token string-property property&quot;&gt;&quot;builds&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;br&gt;        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;          &lt;span class=&quot;token string-property property&quot;&gt;&quot;src&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;packages/app/package.json&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;          &lt;span class=&quot;token string-property property&quot;&gt;&quot;use&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;@now/static-build&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;          &lt;span class=&quot;token string-property property&quot;&gt;&quot;config&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;            &lt;span class=&quot;token string-property property&quot;&gt;&quot;distDir&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;build&quot;&lt;/span&gt;&lt;br&gt;          &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;          &lt;span class=&quot;token string-property property&quot;&gt;&quot;src&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;packages/api/generate.js&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;          &lt;span class=&quot;token string-property property&quot;&gt;&quot;use&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;@now/node&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;          &lt;span class=&quot;token string-property property&quot;&gt;&quot;config&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token string-property property&quot;&gt;&quot;maxLambdaSize&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;40mb&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;          &lt;span class=&quot;token string-property property&quot;&gt;&quot;src&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;packages/api/image.js&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;          &lt;span class=&quot;token string-property property&quot;&gt;&quot;use&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;@now/node&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;          &lt;span class=&quot;token string-property property&quot;&gt;&quot;config&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token string-property property&quot;&gt;&quot;maxLambdaSize&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;40mb&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token string-property property&quot;&gt;&quot;routes&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;br&gt;        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;          &lt;span class=&quot;token string-property property&quot;&gt;&quot;src&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;^/api/generate.*&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;          &lt;span class=&quot;token string-property property&quot;&gt;&quot;dest&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;/packages/api/generate.js&quot;&lt;/span&gt;&lt;br&gt;        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;          &lt;span class=&quot;token string-property property&quot;&gt;&quot;src&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;^/api/image.*&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;          &lt;span class=&quot;token string-property property&quot;&gt;&quot;dest&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;/packages/api/image.js&quot;&lt;/span&gt;&lt;br&gt;        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;          &lt;span class=&quot;token string-property property&quot;&gt;&quot;src&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;^/(.*)&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;          &lt;span class=&quot;token string-property property&quot;&gt;&quot;dest&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;/packages/app/$1&quot;&lt;/span&gt;&lt;br&gt;        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Whatever matches with the first 2 API routes, gets redirected to the respective scripts. Rest all requests get served from the app folder.&lt;/p&gt;
&lt;p&gt;By default, your website gets served on a &lt;code&gt;now.sh&lt;/code&gt; subdomain but you have the option to add a custom domain if you want.&lt;/p&gt;
&lt;p&gt;And here is the final product → &lt;a href=&quot;https://a11yformanagers.now.sh/&quot;&gt;https://a11yformanagers.now.sh/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Remember, this app is open-source on Github → &lt;a href=&quot;https://github.com/chinchang/a11y-for-managers&quot;&gt;https://github.com/chinchang/a11y-for-managers&lt;/a&gt;&lt;br&gt;
So if you want to get your hands dirty in open-source by making your first contribution, this app is perfect way to do it. Presently it has support to show only only few accessibility issues as tweets. You can add support for more types of Accessibility issues. And &lt;a href=&quot;https://x.com/cssmonk&quot;&gt;reach out to me&lt;/a&gt; for any help.&lt;/p&gt;
&lt;p&gt;Hope you had fun reading and learnt a few new things along the way.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Case Study: Accessibility Report for Managers - Part 1</title>
		<link href="https://kushagra.dev/blog/case-study-accessibility-report-for-managers-p1/"/>
		<updated>2019-08-08T00:00:00+00:00</updated>
		<id>https://kushagra.dev/blog/case-study-accessibility-report-for-managers-p1/</id>
		<content type="html">&lt;div class=&quot;info-box&quot;&gt;
&lt;p&gt;
This is a two part case-study of why and how I created my recent side-project - &lt;a href=&quot;https://a11yformanagers.now.sh/&quot;&gt;Accessibility Report for Managers&lt;/a&gt;.&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;Part 1 - Idea &amp; Frontend&lt;/li&gt;
  &lt;li&gt;Part 2 - &lt;a href=&quot;https://kushagra.dev/blog/case-study-accessibility-report-for-managers-p2/&quot;&gt;Backend &amp; Deployment&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;p&gt;Accessibility is a very important aspect of any product. If your product isn’t accessible to every possible user, then you are simply losing out on potential users. Over the past few years, I have grown to care more and more about accessibility in every work I do, not just web development, but everything. With that also comes the disappointment to see all these websites out that that break even the basic accessibility rules.&lt;/p&gt;
&lt;p&gt;Lack of knowledge is certainly the reason for poor accessibility in websites. But it isn’t always just the lack of knowledge of developers. I feel there are times when developers do want to take time out to improve the accessibility in their work as they slowly learn new and new things, but they are not always given the freedom to do so. Again, it’s the lack of knowledge and empathy, but in a different set of people who manage these developers. That is why Accessibility, and for that matter, any part of a website, is not just a developer’s job. It needs to be a company value that starts from the early stage of idea conceptualisation, to design, development, product management, marketing, and beyond.&lt;/p&gt;
&lt;h2 id=&quot;the-idea-behind-%E2%80%9Caccessibility-report-for-managers%E2%80%9D&quot;&gt;The Idea behind “Accessibility Report for Managers” &lt;a class=&quot;bookmark&quot; href=&quot;#the-idea-behind-%E2%80%9Caccessibility-report-for-managers%E2%80%9D&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The most common argument we get to hear from people who are tried to convinced about focusing on Accessibility is:&lt;/p&gt;
&lt;blockquote&gt;
Hey, do we really have those kinds of users? Has anyone ever complained about our website not being accessible?
&lt;div&gt;- A Manager&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;This gave me an idea - why not make an app that gives these people what they want - real feedback from actual users. But then I thought, the primary aim here is “real feedback”, not “actual users” 😉 This led to the whole concept for “Accessibility Report For Managers” - website where you can enter any website URL and generate a report full of dummy feedbacks about actual Accessibility issues on that website, by dummy users 🙂 You take this report to your manager who was asking for real customer feedback all this time, and voila!&lt;/p&gt;
&lt;p class=&quot;info-box&quot;&gt;
&lt;strong&gt;Disclaimer&lt;/strong&gt;: The idea here is not at all to diminish the importance of actual accessibility testing and feedback submitted by real users. That is at most important. This app is just a fun attempt to bring a different perspective to look at real accessibility issues.
&lt;/p&gt;
&lt;h2 id=&quot;the-real-value&quot;&gt;The Real value &lt;a class=&quot;bookmark&quot; href=&quot;#the-real-value&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Okay, fun part aside. &lt;strong&gt;Accessibility Report for Managers&lt;/strong&gt; isn’t just a funny impractical website to generate these fake feedback. I realised it serves a more practical purpose. This app basically gives you a very different, a customer oriented, view of the Accessibility issues present on your website. Compare this to reading a story and actually seeing/hearing the same story in a movie. Similarly, a textual list of issues generated from a linter would not create the same amount of empathy inside the reader that probably a tweet from a disappointed user showing a screenshot of something broken on the website would do.&lt;/p&gt;
&lt;p&gt;For example, compare these two:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Linter&lt;/strong&gt;: Color contrast not sufficient. It should be at least 4.5:1.&lt;br&gt;
&lt;strong&gt;User Feedback&lt;/strong&gt;: Hey web admin, I was browsing through your website to get some work done but at some places, it’s really hard for me to read the text, probably due to poor colour contrast.&lt;/p&gt;
&lt;p&gt;I hope you can see the huge difference between the two. I feel the latter gives a very understandable view of the same issue.&lt;/p&gt;
&lt;h2 id=&quot;tl%3Bdr%3A-creating-the-app&quot;&gt;TL;DR: Creating the App &lt;a class=&quot;bookmark&quot; href=&quot;#tl%3Bdr%3A-creating-the-app&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;This app, though seemingly small, has quite a few components behind the scenes. And the best part, as a frontend developer I could write it all in JavaScript and run without actually setting up or managing a server. These things really excite me and this article series is an attempt to share the whole process of creating such an app with all the latest tech out there. Let’s begin with the tech stack used in the app.&lt;/p&gt;
&lt;p&gt;Note: The app is &lt;a href=&quot;https://github.com/chinchang/a11y-for-managers/&quot;&gt;open-source on Github&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;component-1---the-frontend&quot;&gt;Component 1 - The Frontend &lt;a class=&quot;bookmark&quot; href=&quot;#component-1---the-frontend&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;I chose &lt;a href=&quot;https://preactjs.com/&quot;&gt;Preact&lt;/a&gt; to write this app’s frontend. Preact is an extremely lightweight (just 3KB gzipped) alternative to React with almost the same API. It’s perfect for a scenario where you have such a small app and you don’t wanna overload it with some framework’s footprint.&lt;br&gt;
I used Preact’s &lt;code&gt;preact-cli&lt;/code&gt; which does a basic scaffolding for a Preact Progressive Web App. There is no other dependency on Frontend apart from Preact.&lt;/p&gt;
&lt;p&gt;The CSS is written the old-fashioned way - a single CSS file.&lt;/p&gt;
&lt;h3 id=&quot;component-2---the-backend&quot;&gt;Component 2 - The Backend &lt;a class=&quot;bookmark&quot; href=&quot;#component-2---the-backend&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The backend is basically a set of serverless functions which creates 2 endpoints for the frontend. Again, they are all written in JavaScript (NodeJS).&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;There is one API endpoint to get the actual issues on a given page which uses the &lt;a href=&quot;https://github.com/pa11y/pa11y&quot;&gt;pa11y&lt;/a&gt; package to extract out all the issues.&lt;/li&gt;
&lt;li&gt;The second API endpoint is to get the screenshot of affected areas. This is done using &lt;a href=&quot;https://pptr.dev/&quot;&gt;Puppeteer&lt;/a&gt; to get screenshot of specific elements on the page.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;component-3---deployment&quot;&gt;Component 3 - Deployment &lt;a class=&quot;bookmark&quot; href=&quot;#component-3---deployment&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Both, the frontend and the backend, are hosted on Zeit Now. It simply involves writing the deployment configuration for your components and everything gets deployed with a single command without managing any server!&lt;/p&gt;
&lt;h2 id=&quot;the-frontend&quot;&gt;The Frontend &lt;a class=&quot;bookmark&quot; href=&quot;#the-frontend&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: Till we get to the Backend, assume that we have a backend API. We can send any URL to the API and it returns us a list of Accessibility issues.&lt;/p&gt;
&lt;h3 id=&quot;the-framework&quot;&gt;The framework &lt;a class=&quot;bookmark&quot; href=&quot;#the-framework&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;I love React. But if the project I am working on is not too demanding in terms of features and I am the only one working on it, I prefer to use &lt;a href=&quot;https://preactjs.com/&quot;&gt;Preact&lt;/a&gt; - which is a 3KB alternative to React. It almost feels like I am shipping a vanilla JS app while getting the same ease as with React.&lt;/p&gt;
&lt;p&gt;Preact also has a CLI that scaffolds a basic progressive app.&lt;/p&gt;
&lt;h3 id=&quot;creating-fake-tweets---content&quot;&gt;Creating fake tweets - Content &lt;a class=&quot;bookmark&quot; href=&quot;#creating-fake-tweets---content&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;As I mentioned, our API gives us a list of Accessibility issues (found through &lt;a href=&quot;https://github.com/pa11y/pa11y&quot;&gt;pa11y&lt;/a&gt;). First of all, we need to turn these into tweets. Each issue in the list is of the following structure:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token literal-property property&quot;&gt;code&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;WCAG2AA.Principle2.Guideline2_4.2_4_1.H64.1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token literal-property property&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Iframe element requires a non-empty title attribute that identifies the frame.&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token literal-property property&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;error&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token literal-property property&quot;&gt;selector&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;#77c8c1c1-74e9-4d61-be2e-c1e39ffe02a0&quot;&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;code&lt;/code&gt; is a unique identifier for a particular Accessibility guideline that wasn’t followed, explained in brief in the &lt;code&gt;message&lt;/code&gt; value. The main gist of this app is to turn the technical guideline into seemingly real feedback from a real user. That is why I need to convert that into a tweet. And the same tweet always for a particular issue type would look unreal and boring. So I maintain 3-4 different tweets for each issue type and pick one out randomly. Like so:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; supportedRules &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token constant&quot;&gt;INSUFFICIENT_CONTRAST&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;WCAG2AA.Principle1.Guideline1_4.1_4_3.G18.Fail&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token constant&quot;&gt;MISSING_LABEL_ON_FORM_CONTROL&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;WCAG2AA.Principle1.Guideline1_3.1_3_1.F68&quot;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;generateFeedback&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;issue&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; url&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token keyword&quot;&gt;switch&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;issue&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;code&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; supportedRules&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;MISSING_LABEL_ON_FORM_CONTROL&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;        &lt;span class=&quot;token literal-property property&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;br&gt;          &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;Dear Web Developer, I cannot see and browse the web using a screen reader. And websites like &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;url&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt; on which you don&#39;t label your form elements are completely unusable to people like me. #fixtheweb #a11y&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;          &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;Oh God! It&#39;s a disaster browsing websites where the developer simply didn&#39;t care to put a label on form controls!! Encountered one such site -&gt; &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;url&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt; #accessibility.&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;br&gt;        &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; supportedRules&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;INSUFFICIENT_CONTRAST&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;        &lt;span class=&quot;token literal-property property&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;br&gt;          &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;Hello! I was browsing through your website &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;url&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt; and facing issues with reading few texts. I guess it could get a lil&#39; better for people like me if the text color had some more contrast with the background.&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;          &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;It&#39;s such a difficult task to read websites these days. Eg. Missing text contrast here -&gt; &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;url&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt; Someone please fix the web. #accessibility&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;br&gt;        &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;What&#39;s happening here is, I have made enums for the supported Accessibility guideline codes to make it more clear while referencing them. Then there is the &lt;code&gt;generateFeedback&lt;/code&gt; function which does a &lt;code&gt;switch&lt;/code&gt; on the accessibility issue &lt;code&gt;code&lt;/code&gt; and returns a random feedback from a list of feedbacks corresponding to that issue.&lt;/p&gt;
&lt;p&gt;One more thing to note here is that I pass the URL of the website, whose report is being generated, to the &lt;code&gt;generateFeedback&lt;/code&gt; function. This passed argument gets used in the &lt;code&gt;${url}&lt;/code&gt; placeholder within the feedback strings, which are actually &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals&quot;&gt;template literals&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;creating-fake-tweets---fake-users&quot;&gt;Creating fake tweets - Fake users &lt;a class=&quot;bookmark&quot; href=&quot;#creating-fake-tweets---fake-users&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;This one is interesting! Next, we need some fake users to show within our feedback tweets. I searched a lot for services which would give me random user data and finally settled on &lt;a href=&quot;https://randomuser.me/&quot;&gt;https://randomuser.me&lt;/a&gt;. It’s free, fast and gave me the data I wanted (eg. name, photo etc). It has an API with all sorts of options, but the one that is of our interest here is the &lt;code&gt;results&lt;/code&gt; option. You can pass a count in &lt;code&gt;results&lt;/code&gt; parameter and the API will return that number of fake users to you. Sweet right!&lt;/p&gt;
&lt;p&gt;So the whole report generation process till now is as follows:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;I get a list of issues from the API&lt;/li&gt;
&lt;li&gt;The issue list is converted into fake feedback tweets (only the issues which are supported)&lt;/li&gt;
&lt;li&gt;As per the number of feedbacks we generate, we fetch those number of fake user from &lt;a href=&quot;https://randomuser.me/&quot;&gt;https://randomuser.me&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;creating-fake-tweets---twitter-handles&quot;&gt;Creating fake tweets - Twitter handles &lt;a class=&quot;bookmark&quot; href=&quot;#creating-fake-tweets---twitter-handles&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;To complete our fake feedback tweet, we need to show the twitter handles (username) of our fake users. Now we could just create random strings out of numbers and alphabets, but that would again look unreal. And what&#39;s the fun in making unreal stuff! So here is what I do instead:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;For each user, we have the user’s full name.&lt;/li&gt;
&lt;li&gt;I extract some part of the user’s first name (&lt;strong&gt;F&lt;/strong&gt;) and some part of their last name (&lt;strong&gt;L&lt;/strong&gt;).&lt;/li&gt;
&lt;li&gt;Then with a 50% probability, I concat &lt;strong&gt;F&lt;/strong&gt; and &lt;strong&gt;L&lt;/strong&gt; with an underscore. The other 50% times, I concat them straightaway. Because people generally contact their first and last names to create their handles.&lt;/li&gt;
&lt;li&gt;Next, with a 30% probability, I append some digits (maximum 3) after the result of Step 3. Why? Because not everyone in the Twitter-verse gets their handle of choice. They append random numbers to make it unique :)&lt;/li&gt;
&lt;li&gt;The result is appended to a “@” character.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;And we have the handle ready! If you are wondering how do we do something with X% probability, it can be done easily by checking the result of &lt;code&gt;Math.random()&lt;/code&gt;.&lt;br&gt;
For example: To run a code with 70% probability, we could use &lt;code&gt;Math.random() &amp;gt; 0.3&lt;/code&gt;. This condition means we want the number returned by &lt;code&gt;Math.random()&lt;/code&gt; to be greater than 0.3. And &lt;code&gt;Math.random()&lt;/code&gt; return from 0 to 1. So basically we are checking that the returned number should be between 0.3 and 0.1. This translates to having a 70% chance:&lt;/p&gt;
&lt;p&gt;0 - 0.3 → 30% probably outcomes&lt;br&gt;
0.3 - 1 → 70% probably outcomes&lt;/p&gt;
&lt;p&gt;Here is how the complete function looks like:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getHandleFromName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;fname&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; lname&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token comment&quot;&gt;// Concatenating extracts from first and last name, with _ maybe?&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; handle &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;fname&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;substr&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; fname&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;length &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;    Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.5&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;_&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;lname&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;substr&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; lname&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;length &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;br&gt;  &lt;span class=&quot;token comment&quot;&gt;// Add some digits?&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.7&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;    handle &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;handle&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;999&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;br&gt;  &lt;span class=&quot;token comment&quot;&gt;// Append to @&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;handle&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;creating-fake-tweets---final-items&quot;&gt;Creating fake tweets - Final items &lt;a class=&quot;bookmark&quot; href=&quot;#creating-fake-tweets---final-items&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;To all the above data, we add random “like” count and tweet date. One more thing that the tweet shows is the image of the element on the website that failed the Accessibility guideline. Remember the issue structure that we get from the API? It had a key called &lt;code&gt;selector&lt;/code&gt; is the CSS selector of the corresponding element. I created another API to which I pass the CSS selector and website URL and it returns me the screenshot of that element. More on that later.&lt;/p&gt;
&lt;p&gt;And combining all the fake data, we generate this beautiful fake feedback tweet:&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&quot;https://kushagra.dev/images/2019/a11yformanagers-tweet.png&quot;&gt;
&lt;figcaption&gt;Tweet screenshot of a fake user complaining about color contrast user&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;That is it for this article. In &lt;a href=&quot;https://kushagra.dev/blog/case-study-accessibility-report-for-managers-p2/&quot;&gt;the next article&lt;/a&gt;, we’ll go through the app’s backend and how its deployed.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>How I saved 100KB with React.lazy</title>
		<link href="https://kushagra.dev/blog/how-i-saved-100kbs-with-react-lazy/"/>
		<updated>2019-07-05T00:00:00+00:00</updated>
		<id>https://kushagra.dev/blog/how-i-saved-100kbs-with-react-lazy/</id>
		<content type="html">&lt;p&gt;This post is about how I was able to reduce my homepage JavaScript by more around 100Kb.&lt;/p&gt;
&lt;div&gt;
&lt;strong&gt;TL;DR&lt;/strong&gt;: Use &lt;a rel=&quot;external&quot; href=&quot;https://reactjs.org/docs/code-splitting.html#reactlazy&quot;&gt;&lt;code&gt;React.lazy&lt;/code&gt;&lt;/a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https://reactjs.org/docs/code-splitting.html#suspense&quot;&gt;&lt;code&gt;React.Suspense&lt;/code&gt;&lt;/a&gt; to lazy load your non-critical dependencies
&lt;/div&gt;
&lt;p&gt;I have a React app bootstrapped from &lt;a href=&quot;https://github.com/facebook/create-react-app&quot;&gt;create-react-app&lt;/a&gt;. One of the page (just a React Component) in that app uses &lt;a href=&quot;https://codemirror.net/&quot;&gt;CodeMirror&lt;/a&gt; (a code editor). The app uses &lt;a href=&quot;https://reacttraining.com/react-router/&quot;&gt;react-router&lt;/a&gt; for routing. And so this page component, just like all other pages, is imported in the main &lt;code&gt;App&lt;/code&gt; component to provide to the router.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;App.js&lt;/strong&gt;&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; Home &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;./Home&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; Page2 &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;./Page2&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;App&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Router&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Route path&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;/&quot;&lt;/span&gt; component&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;Home&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Route path&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;/page2&quot;&lt;/span&gt; component&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;Page2&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Router&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Page2.js&lt;/strong&gt;&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; CodeMirror &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;react-codemirror&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;App&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;CodeMirror &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;div&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;Note&lt;/em&gt;: &lt;code&gt;react-codemirror&lt;/code&gt; actually does a named export. But for simplicity, I am assuming a default export.&lt;/p&gt;
&lt;p&gt;This situation leads to &lt;code&gt;Page2.js&lt;/code&gt; being a synchronous dependency to render &lt;code&gt;App.js&lt;/code&gt;. And &lt;code&gt;Page2.js&lt;/code&gt; in turn depends on &lt;code&gt;react-codemirror&lt;/code&gt;. So indirectly, &lt;code&gt;react-codemirror&lt;/code&gt; becomes a synchronous dependency to render &lt;code&gt;App.js&lt;/code&gt;. This basically means whatever page we visit, &lt;code&gt;react-codemirror&lt;/code&gt; will be fetched and parsed before the page renders. Even if Codemirror is not even being used on that page! Let&#39;s fix this.&lt;/p&gt;
&lt;h2 id=&quot;solution&quot;&gt;Solution &lt;a class=&quot;bookmark&quot; href=&quot;#solution&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The solution is pretty neat and easy. React recently introduced a new API: &lt;a href=&quot;https://reactjs.org/docs/code-splitting.html#reactlazy&quot;&gt;&lt;code&gt;React.lazy&lt;/code&gt;&lt;/a&gt;. And an accompanying component called &lt;a href=&quot;https://reactjs.org/docs/code-splitting.html#suspense&quot;&gt;&lt;code&gt;Suspense&lt;/code&gt;&lt;/a&gt;. Here is how we use them to fix our problem.&lt;/p&gt;
&lt;h2 id=&quot;step-1%3A-make-the-import-lazy&quot;&gt;Step 1: Make the import lazy &lt;a class=&quot;bookmark&quot; href=&quot;#step-1%3A-make-the-import-lazy&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;Page2.js&lt;/code&gt; imports &lt;code&gt;react-codemirror&lt;/code&gt;. Ideally we want that &lt;code&gt;Page2.js&lt;/code&gt; should load &lt;code&gt;react-codemirror&lt;/code&gt; asynchronously when Page2 is actually visited.&lt;/p&gt;
&lt;p&gt;This is our current &lt;code&gt;Page2.js&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; CodeMirror &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;react-codemirror&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;App&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;CodeMirror &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;div&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Using the &lt;code&gt;React.lazy&lt;/code&gt; API, we can make the import lazy. Like so:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; React &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;react&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; CodeMirror &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; React&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;lazy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;react-codemirror&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;App&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;CodeMirror &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;div&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And this just starts working out of the box! No more change required in the way &lt;code&gt;CodeMirror&lt;/code&gt; component is used. What you&#39;ll notice now is initially when you are on homepage, CodeMirror doesn&#39;t load. When you visit &lt;em&gt;/page2/&lt;/em&gt;, you see blank area where CodeMirror was to be rendered, for a short duration while CodeMirror loads asynchronously. And then when it has finished loading, &lt;code&gt;CodeMirror&lt;/code&gt; component renders.&lt;/p&gt;
&lt;p&gt;While CodeMirror is being fetched, there is just blank space where CodeMirror editor should have been present. That is not such a good experience as user is left without any information about that blank space. That is where &lt;code&gt;React.Suspense&lt;/code&gt; component comes into action.&lt;/p&gt;
&lt;h2 id=&quot;step-2%3A-improve-the-blank-space-context&quot;&gt;Step 2: Improve the blank space context &lt;a class=&quot;bookmark&quot; href=&quot;#step-2%3A-improve-the-blank-space-context&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Here is all we need to do to make the experience better:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; React&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; Suspense &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;react&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; CodeMirror &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; React&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;lazy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;react-codemirror&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;App&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Suspense fallback&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Loading editor...&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;br&gt;        &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;CodeMirror &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Suspense&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;div&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We wrap the asynchronous/lazy components with a &lt;code&gt;Suspense&lt;/code&gt; tag and give it a &lt;code&gt;fallback&lt;/code&gt; which should show instead of blank space. That is it!&lt;/p&gt;
&lt;h2 id=&quot;bonus-tip&quot;&gt;Bonus tip &lt;a class=&quot;bookmark&quot; href=&quot;#bonus-tip&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;There is one special requirement for using &lt;code&gt;React.lazy&lt;/code&gt; which you need to be aware of. It only works with component that have default &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/web/javascript/reference/statements/export&quot;&gt;export&lt;/a&gt;. So components with named exports can&#39;t be lazily imported with it. But you might have components with named exports, what to do then? There is a small trick. Let&#39;s assume our &lt;code&gt;Page2.js&lt;/code&gt; file exported &lt;code&gt;Page2&lt;/code&gt; component so that it was initially imported as &lt;code&gt;import {CodeMirror} from &#39;react-codemirror&#39;&lt;/code&gt;. In that case, we can use &lt;code&gt;React.lazy&lt;/code&gt; on it as follows:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; React&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; Suspense &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;react&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; CodeMirror &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;lazy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;mark class=&quot;highlight-line highlight-line-active&quot;&gt;  &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;react-codemirror&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; module&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;CodeMirror &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/mark&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;App&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Suspense fallback&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Loading editor...&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;        &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;CodeMirror &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Suspense&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;div&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;What we did here is once we import the named module, inside the &lt;code&gt;then&lt;/code&gt; callback we turn it into a seemingly default exported module - an object with the module available on &lt;code&gt;default&lt;/code&gt; key.&lt;/p&gt;
&lt;p&gt;That&#39;s all folks! Go shave off some unnecessary bytes of your pages. If you have any questions or comments, ask me on Twitter &lt;a href=&quot;https://x.com/cssmonk&quot;&gt;@chinchang457&lt;/a&gt; (DMs are open).&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>An interactive and practical introduction to Web Accessibility</title>
		<link href="https://kushagra.dev/blog/introduction-to-web-accessibility/"/>
		<updated>2019-07-02T00:00:00+00:00</updated>
		<id>https://kushagra.dev/blog/introduction-to-web-accessibility/</id>
		<content type="html">&lt;p&gt;Ever since I understood the importance of Accessibility, I have always tried putting a conscious effort to share whatever I keep learning. So that everyone can start caring about at least the basics of Accessibility while making websites.&lt;/p&gt;
&lt;p&gt;Nothing brings you closer to reality than actually facing it. This is the premise of my latest attempt to spread awareness about Web Accessibility. Presenting, &lt;a href=&quot;https://introtoaccessibility.com/&quot;&gt;introtoaccessibility.com&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This project is a series of chapters, in the form of a quiz. Each chapter shows you something or ask you to do something and then asks you a question. The chapters are basically extreme cases of unusable user experience designed such that they are inaccessible even to abled users.&lt;/p&gt;
&lt;p&gt;Each chapter makes you experience a particular Accessibility issue. It then tells you how that issue affects various users on the Internet, why it affects them and what you can do to prevent it.&lt;/p&gt;
&lt;p&gt;My intention with this project is that it can be the first step to introduce Web Accessibility to anyone and everyone who work with websites. No matter if they are developers, designers or marketers! I hope I can arouse empathy that each one of us requires to make the Web a better place for everyone.&lt;/p&gt;
&lt;p&gt;Please do share with anyone and everyone you know who works with websites -&amp;gt; &lt;a href=&quot;https://introtoaccessibility.com/&quot;&gt;introtoaccessibility.com&lt;/a&gt;&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Restrict specific fields updation in Firestore</title>
		<link href="https://kushagra.dev/blog/ensure-missing-fields-in-firestore-security-rules/"/>
		<updated>2019-06-15T00:00:00+00:00</updated>
		<id>https://kushagra.dev/blog/ensure-missing-fields-in-firestore-security-rules/</id>
		<content type="html">&lt;p&gt;Let&#39;s say you have a &lt;code&gt;users&lt;/code&gt; collection and each document in that collection contains the public information about a user. Something like this:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;users&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token literal-property property&quot;&gt;user_id_1&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token literal-property property&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;John Doe&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token literal-property property&quot;&gt;country&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Thailand&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token literal-property property&quot;&gt;website&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;https://example.com&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token literal-property property&quot;&gt;username&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;j_deo&quot;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And of course, since this is user&#39;s information, the users will have editing rights to their corresponding document. This can be guaranteed by the following security rule:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;match &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;users&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;userId&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  allow write&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; userId &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; request&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;auth&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;uid&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;All good till now. Here is a thing to note: Should all the fields in the above document be allowed to be written by its user? Think about the &lt;code&gt;username&lt;/code&gt; field. Username of a person is a unique value in an app, generally. Meaning, if there exists a user with username &amp;quot;ramesh&amp;quot;, there can&#39;t be (at least shouldn&#39;t be) another user with the same username &amp;quot;ramesh&amp;quot;. How would you ensure that in Firestore, you ask? Well, that could be another blog post, but in summary, you&#39;ll have a cloud function endpoint to change username instead of directly hitting Firestore to update the username. And inside the function, you can have logic to check if there is username conflict and take appropriate actions.&lt;/p&gt;
&lt;p&gt;This is the half solution for ensuring the username doesn&#39;t conflict. Remember that our above-mentioned security rule for any document in &lt;code&gt;users&lt;/code&gt; collection doesn&#39;t stop anyone from updating the &lt;code&gt;username&lt;/code&gt; field. So now we need to somehow ensure that the user cannot update their username in the document.&lt;/p&gt;
&lt;h2 id=&quot;resource-%26-request&quot;&gt;resource &amp;amp; request &lt;a class=&quot;bookmark&quot; href=&quot;#resource-%26-request&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;For that, we need to know about these 2 variables: &lt;code&gt;resource.data&lt;/code&gt; and &lt;code&gt;request.resource.data&lt;/code&gt;. These are available to use while writing the Firestore security rules.&lt;/p&gt;
&lt;h3 id=&quot;resource.data&quot;&gt;resource.data &lt;a class=&quot;bookmark&quot; href=&quot;#resource.data&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;This is simple. It&#39;s your document&#39;s current state, before the write. More precisely, it is a map with your current document&#39;s keys.&lt;/p&gt;
&lt;h3 id=&quot;request.resource.data&quot;&gt;request.resource.data &lt;a class=&quot;bookmark&quot; href=&quot;#request.resource.data&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;This one is tricky. Let&#39;s say you send an &lt;code&gt;update&lt;/code&gt; request to update your document&#39;s &lt;code&gt;name&lt;/code&gt; field, like so:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;db&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;collection&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;users/user_id_1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;update&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token literal-property property&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Something else&quot;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You would expect &lt;code&gt;request.resource.data&lt;/code&gt; to be &lt;code&gt;{ name: &#39;Something else&#39; }&lt;/code&gt;, which is simply the data we are sending in the request. But it is not!&lt;/p&gt;
&lt;p&gt;&lt;code&gt;request.resource.data&lt;/code&gt; is your document&#39;s future state i.e. after the write. So in this case, if the write succeeds, our document would become something like this:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token literal-property property&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Something else&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token literal-property property&quot;&gt;country&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Thailand&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token literal-property property&quot;&gt;website&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;https://example.com&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token literal-property property&quot;&gt;username&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;j_deo&quot;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is exactly what &lt;code&gt;request.resource.data&lt;/code&gt; is - A map with all your future document&#39;s keys.&lt;/p&gt;
&lt;h3 id=&quot;back-to-ensuring-the-missing-field&quot;&gt;Back to ensuring the missing field &lt;a class=&quot;bookmark&quot; href=&quot;#back-to-ensuring-the-missing-field&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Once you understand what &lt;code&gt;resource.data&lt;/code&gt; and &lt;code&gt;request.resource.data&lt;/code&gt; are, you soon realize why we cannot simply check that &lt;code&gt;username&lt;/code&gt; should be &lt;code&gt;undefined&lt;/code&gt; in our &lt;code&gt;request.resource.data&lt;/code&gt;. Because &lt;code&gt;request.resource.data&lt;/code&gt; is not the object you send. But it is the object that your document will become if the write happens, and in that object &lt;code&gt;username&lt;/code&gt; still lives. So what do we do now?&lt;/p&gt;
&lt;p&gt;Let&#39;s take a small example:&lt;/p&gt;
&lt;p&gt;Current document:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// resource.data&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token literal-property property&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;John Doe&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token literal-property property&quot;&gt;username&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;j_deo&quot;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And we send an update request like so: &lt;code&gt;db.collection(&#39;users/user_id_1&#39;).update({ name: &#39;John Doe - the great&#39; })&lt;/code&gt;. Here is what our future document will look like, i.e. our &lt;code&gt;request.resource.data&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// request.resource.data&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token literal-property property&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;John Doe - the great&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token literal-property property&quot;&gt;username&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;j_deo&quot;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you compare the current and future state, you&#39;ll notice that the username remains same when we don&#39;t send the &lt;code&gt;username&lt;/code&gt; field. That means to validate the user not sending the &lt;code&gt;username&lt;/code&gt; field, we can check for the &lt;code&gt;username&lt;/code&gt; being the same in before and after states with the following security rule:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;match &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;users&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;userId&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  allow write&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; userId &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; request&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;auth&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;uid&lt;br&gt;    &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; resource&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;username &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; request&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;resource&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;username&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Are we done? No, one more small thing. There could be a scenario where the &lt;code&gt;username&lt;/code&gt; field doesn&#39;t exist in the current document. In that case, the above security rule errors out (it probably shouldn&#39;t, but it does) with a strange error &lt;code&gt;Property username is undefined on object&lt;/code&gt;! To bypass this error, we can simply check for the field &lt;code&gt;username&lt;/code&gt; to be absent in future state (&lt;code&gt;request.resource.data&lt;/code&gt;). Because if there was no &lt;code&gt;username&lt;/code&gt; initially and we don&#39;t update it, it won&#39;t be present in the future state too. Here is how we do that:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;match &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;users&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;userId&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  allow write&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; userId &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; request&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;auth&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;uid&lt;br&gt;    &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;username&#39;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; request&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;resource&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; resource&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;username &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; request&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;resource&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;username&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;bonus-refactor&quot;&gt;Bonus refactor &lt;a class=&quot;bookmark&quot; href=&quot;#bonus-refactor&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;You might probably have more such fields that need to be restricted for writing. Repeating above conditions for all such fields can make the rules difficult to read. We can abstract the logic in a function to make it manageable:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;notUpdating&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;field&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;field &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; request&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;resource&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; resource&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;field&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; request&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;resource&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;field&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;br&gt;match &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;users&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;userId&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  allow write&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; userId &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; request&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;auth&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;uid&lt;br&gt;    &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;notUpdating&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;username&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;notUpdating&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;isAdmin&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Neat, right?&lt;/p&gt;
&lt;p&gt;That&#39;s all folks. If you have any questions or comments, reply in the comments or ask on Twitter &lt;a href=&quot;https://x.com/cssmonk&quot;&gt;@chinchang457&lt;/a&gt; (DMs are open).&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Introducing CSSBattle — the first CSS code-golfing game</title>
		<link href="https://kushagra.dev/"/>
		<updated>2019-04-17T00:00:00+00:00</updated>
		<id>https://kushagra.dev/</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>Undefined: The Third Boolean Value</title>
		<link href="https://kushagra.dev/"/>
		<updated>2019-04-05T00:00:00+00:00</updated>
		<id>https://kushagra.dev/</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>Side Project - my not so &#39;side&#39; project</title>
		<link href="https://kushagra.dev/blog/side-project-app/"/>
		<updated>2019-02-25T00:00:00+00:00</updated>
		<id>https://kushagra.dev/blog/side-project-app/</id>
		<content type="html">&lt;p&gt;A few months back I left my job to go full-time as an Independent Product Maker. And today I am here to present my latest product:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://sideproject.app/&quot;&gt;&lt;strong&gt;Side Project&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://sideproject.app/&quot;&gt;&lt;img src=&quot;https://sideproject.app/images/social.png&quot; alt=&quot;Side Project banner&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;quot;Side Project&amp;quot; aims to be a one-stop website to get new ideas for your side projects and resources to build it whether you want to choose a frontend framework, payment processor and what not. On top of that you also get a continuously improving &lt;a href=&quot;https://sideproject.app/checklist&quot;&gt;Launch Checklist&lt;/a&gt; with important things to take care of while launching.&lt;/p&gt;
&lt;p&gt;It doesn&#39;t stop there, this is also my first paid product. Besides all the free things mentioned above, you can also buy a Side Project pack which allows you to fork the Launch checklist separately for your individual side projects. Plus, you can completely customize the checklist to suit your project. You can get &lt;strong&gt;5 Side Projects for just $3&lt;/strong&gt;! And to celebrate the launch you can get a &lt;strong&gt;50% discount using the coupon &amp;quot;launch&amp;quot;&lt;/strong&gt;. So what are you waiting for? &lt;a href=&quot;https://sideproject.app/login&quot;&gt;Try it now&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;With this product I have experimented with a lot of stuff like Serverless functions, Netlify, Eleventy, Preact, Gumroad, payments, security, Accessibility, Product design and lots of other things. I&#39;ll probably write separate posts on that. It was fun build this mini product. If you have questions on how it was built or the tech behind it, feel free to comment or &lt;a href=&quot;https://x.com/cssmonk&quot;&gt;ask on twitter&lt;/a&gt;.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Things I Don&#39;t Know as of 2018</title>
		<link href="https://kushagra.dev/blog/things-i-dont-know-as-of-2018/"/>
		<updated>2018-12-29T00:00:00+00:00</updated>
		<id>https://kushagra.dev/blog/things-i-dont-know-as-of-2018/</id>
		<content type="html">&lt;p&gt;This post is inspired by &lt;a href=&quot;https://overreacted.io/things-i-dont-know-as-of-2018/&quot;&gt;Dan Abramov&#39;s post&lt;/a&gt; where he lists out, yes, things he doesn&#39;t know as of 2018. On top of Dan&#39;s reasons, I am also writing this post to myself get clarity on the things I don&#39;t fully understand and things I want to learn next year. So here goes...&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;CSS Grid&lt;/strong&gt; - I know I know, Grids are the best. Hard to believe, but I haven&#39;t used CSS Grids even once in any project yet. I have tinkered with them, but haven&#39;t got any practical need to use them over Flexbox.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Accessibility&lt;/strong&gt; - I started focusing a lot on Web Accessibility (a11y) in 2017, thanks to my friend &lt;a href=&quot;https://twitter.com/jitendravyas&quot;&gt;Jitendra Vyas&lt;/a&gt;. I take care about &lt;abbr title=&quot;Accessibility&quot;&gt;a11y&lt;/abbr&gt; in whatever I develop now. But the domain is very huge and there are many aspect I still need to learn about &lt;abbr title=&quot;Accessibility&quot;&gt;a11y&lt;/abbr&gt; (inspect me :)).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Responsive web design&lt;/strong&gt; (RWD) - I feel I lack the right approach towards &lt;abbr title=&quot;Responsive web design&quot;&gt;RWD&lt;/abbr&gt;. Whatever I implement still feels hacky and not-robust to me.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Docker performance&lt;/strong&gt; - I started with Docker in late 2017 and have worked quite a bit. But the end results have been intolerably slow as far as performance is concerned. I still have to learn the internals of containers to have usable architectures over Docker.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Backend&lt;/strong&gt; - I am a frontend developer and though I have worked a few times over backend code, I still am afraid to write one from scratch or maintain backend code. That is also the reason why my app &lt;a href=&quot;https://webmakerapp.com/&quot;&gt;Web Maker&lt;/a&gt; is completely serverless till date - hosted on Github pages and running serverless functions wherever required.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;React patterns&lt;/strong&gt; - I have tried React over 2-3 projects now. In fact I re-wrote &lt;a href=&quot;https://webmakerapp.com/&quot;&gt;Web Maker&lt;/a&gt; completely in &lt;a href=&quot;https://preactjs.com/&quot;&gt;Preact&lt;/a&gt; (lighter React) &lt;a href=&quot;https://medium.com/web-maker/web-maker-is-now-in-preact-85af98be8683&quot;&gt;this year&lt;/a&gt;. But I feel my code could be much more concise and manageable if I know the many patterns out there.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Typing without looking at the keyboard&lt;/strong&gt; - I still can&#39;t type correctly without looking at the keyboard for even a minute 😅 Moreover, I got a new keyboard and my type speed has severely downgraded!&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SEO&lt;/strong&gt; - Hardly know anything (maybe a point or two) in this space.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now some non-tech things:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Being productive&lt;/strong&gt; - I feel I have started procrastinating more and more 😛 Even more since I quit my job to become an indie developer. I need to get back on track soon and start shipping and learning.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Playing chords on Piano&lt;/strong&gt; - I am able to figure out chords for a lot of music, but still not close to 100%.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Go to post something on twitter and get back without checking out my timeline&lt;/strong&gt; - self-explanatory 😔.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;todo-2019&quot;&gt;TODO 2019 &lt;a class=&quot;bookmark&quot; href=&quot;#todo-2019&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Finally here are few things I want to do in 2019:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Release 4 products that earn me money.&lt;/li&gt;
&lt;li&gt;Deep dive more into Web Accessibility.&lt;/li&gt;
&lt;li&gt;Launch the educational website I have been wanting to start (for years!).&lt;/li&gt;
&lt;li&gt;Get my left hand to play without seeing on Piano. More practice required.&lt;/li&gt;
&lt;li&gt;Draw more.&lt;/li&gt;
&lt;li&gt;Stay like a kid :)&lt;/li&gt;
&lt;/ul&gt;
</content>
	</entry>
	
	<entry>
		<title>A CSS Approach to Trap Focus Inside of an Element</title>
		<link href="https://kushagra.dev/"/>
		<updated>2018-03-27T00:00:00+00:00</updated>
		<id>https://kushagra.dev/</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>Creating Vue.js Component Instances Programmatically</title>
		<link href="https://kushagra.dev/blog/creating-vue-js-component-instances-programmatically/"/>
		<updated>2018-01-23T00:00:00+00:00</updated>
		<id>https://kushagra.dev/blog/creating-vue-js-component-instances-programmatically/</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>How to write better CSS in teams with ACSS — A dynamic Atomic CSS library</title>
		<link href="https://kushagra.dev/blog/acss-a-dynamic-atomic-css-library/"/>
		<updated>2018-01-04T00:00:00+00:00</updated>
		<id>https://kushagra.dev/blog/acss-a-dynamic-atomic-css-library/</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>Web Maker — How I built a fast, offline front-end playground</title>
		<link href="https://kushagra.dev/blog/web-maker-how-i-built-a-fast-offline-front-end-playground/"/>
		<updated>2017-08-01T00:00:00+00:00</updated>
		<id>https://kushagra.dev/blog/web-maker-how-i-built-a-fast-offline-front-end-playground/</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>Overriding new tab page in Chrome extension, conditionally!</title>
		<link href="https://kushagra.dev/blog/conditional-newtab-override-chrome-extension/"/>
		<updated>2017-07-26T00:00:00+00:00</updated>
		<id>https://kushagra.dev/blog/conditional-newtab-override-chrome-extension/</id>
		<content type="html">&lt;p&gt;If you use Chrome extensions like Momentum, Panda etc you know that Chrome extensions have the ability to override your new tab pages i.e. the page you see when you open a new tab in the browser. They do this through the &lt;a href=&quot;https://developer.chrome.com/extensions/override&quot;&gt;&lt;em&gt;Override Pages&lt;/em&gt;&lt;/a&gt; API, by doing so in the manifest file:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token string-property property&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;My extension&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;&lt;br&gt;&lt;br&gt;  &lt;span class=&quot;token string-property property&quot;&gt;&quot;chrome_url_overrides&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token string-property property&quot;&gt;&quot;newtab&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;theNewPage.html&quot;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Issue with such extensions is that you can use only one such extension, because if you have multiple extensions with each one trying to override the new tab page, only one of them can finally override. Also, these extensions don&#39;t provide any configurable setting to make the overriding of new tab optional. But, there is a very simple trick to make new tab overriding conditional which I use in &lt;a href=&quot;https://webmakerapp.com/&quot;&gt;Web Maker&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;First, you don&#39;t do anything in the extension&#39;s manifest as mentioned above. Then you can have a background page that listens for a new tab creation event. Whenever a new tab is created and the new tab&#39;s URL is &lt;code&gt;chrome://newtab/&lt;/code&gt;, we can do our condition checking and replace the URL accordingly. Heres how you do that:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;chrome&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tabs&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;onCreated&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addListener&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;tab&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;tab&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;url &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;chrome://newtab/&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;shouldReplaceNewTabSetting &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;      chrome&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tabs&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;update&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;tab&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;id&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;        &lt;span class=&quot;token literal-property property&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; chrome&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;extension&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getURL&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;theNewPage.html&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There you go - conditional new tab page replacement! You can also see the actual &lt;a href=&quot;https://github.com/chinchang/web-maker/blob/master/src/eventPage.js#L13&quot;&gt;code I use in Web Maker here&lt;/a&gt;.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Web Maker: Forking and Fonts</title>
		<link href="https://kushagra.dev/blog/web-maker-fork-templates/"/>
		<updated>2017-05-31T00:00:00+00:00</updated>
		<id>https://kushagra.dev/blog/web-maker-fork-templates/</id>
		<content type="html">&lt;p&gt;I recently released v2.7.0 of &lt;a href=&quot;https://webmakerapp.com/&quot;&gt;Web Maker&lt;/a&gt; with 2 super useful features - Forking &amp;amp; Customizable fonts. Here is a bit about them.&lt;/p&gt;
&lt;h2 id=&quot;forking&quot;&gt;Forking &lt;a class=&quot;bookmark&quot; href=&quot;#forking&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Forking basically allows you to create a duplicate of any of your existing creation. This sounds like a small feature, but its usefulness is enormous. Forking any creation gives you the power to define templates. Say, your creations are mostly based on &lt;code&gt;three.js&lt;/code&gt; and a &lt;code&gt;three.js&lt;/code&gt; work requires a bit of same starter code always. With Forking now in Web maker, you do this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Create a new creation.&lt;/li&gt;
&lt;li&gt;Add &lt;code&gt;three.js&lt;/code&gt; from &lt;em&gt;Add Library&lt;/em&gt; option.&lt;/li&gt;
&lt;li&gt;Add the required base code for creating a new &lt;code&gt;three.js&lt;/code&gt; work.&lt;/li&gt;
&lt;li&gt;Change your creation&#39;s title to: &lt;em&gt;Template: three.js starter&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Thats it. Now you have created a readymade template for starting any &lt;code&gt;three.js&lt;/code&gt; work in future. How do you use it? Simply:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Click on the &lt;em&gt;Open&lt;/em&gt; button.&lt;/li&gt;
&lt;li&gt;Type in &lt;code&gt;template&lt;/code&gt; to search across all saved templates (remember you named your template so).&lt;/li&gt;
&lt;li&gt;Hit the &lt;strong&gt;Fork&lt;/strong&gt; button on the the desired template. And done!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And all this user experience is completely accessible through just keyboard too!&lt;/p&gt;
&lt;figure&gt;
    &lt;img src=&quot;https://kushagra.dev/images/2017/webmaker-fork.gif&quot; alt=&quot;Web Maker Fork&quot;&gt;
    &lt;caption&gt;Web Maker&#39;s Fork feature&lt;/caption&gt;
&lt;/figure&gt;
&lt;h2 id=&quot;fonts!&quot;&gt;Fonts! &lt;a class=&quot;bookmark&quot; href=&quot;#fonts!&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Customizable fonts are something that developers always dig. And with the new generation fonts with ligatures, it has become more exciting to use them. With this new release, you now get 4 awesome fonts with ligatures (except Inconsolata) - Fira Code (now default), FixedSys, Monoid and Inconsolata. Big thanks to the developers of these fonts! If you want to see some other font as well, let me know in comments or on &lt;a href=&quot;https://twitter.com/webmakerapp&quot;&gt;twitter&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I personally like the game-y feel of the &lt;em&gt;FixedSys&lt;/em&gt; font. Now coding feels like playing a game :)&lt;/p&gt;
&lt;figure&gt;
    &lt;img src=&quot;https://kushagra.dev/images/2017/webmaker-fixedsys.png&quot; alt=&quot;Web Maker FixedSys font&quot;&gt;
    &lt;caption&gt;FixedSys font in Web Maker&lt;/caption&gt;
&lt;/figure&gt;
&lt;p&gt;Hope it hear from you all about these new features. If you find them useful, tweet out your love to &lt;a href=&quot;https://twitter.com/webmakerapp&quot;&gt;@webmakerapp&lt;/a&gt;. Oh, by the way, Web Maker has a &lt;a href=&quot;https://gitter.im/web-maker-app/Lobby&quot;&gt;chat lobby on Gitter&lt;/a&gt;. Join there if you need any help or want to say Hi. Cheers!&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Web Maker: Console is here!</title>
		<link href="https://kushagra.dev/blog/web-maker-console-is-here/"/>
		<updated>2017-05-18T00:00:00+00:00</updated>
		<id>https://kushagra.dev/blog/web-maker-console-is-here/</id>
		<content type="html">&lt;p&gt;I have an awesome news to share with all the &lt;a href=&quot;https://webmakerapp.com/&quot;&gt;Web Maker&lt;/a&gt; users out there. The most &lt;a href=&quot;https://github.com/chinchang/web-maker/issues/56&quot;&gt;requested feature&lt;/a&gt; has finally landed in version 2.6 - The &amp;quot;Console&amp;quot;. Yes, you heard it right, you now have an inbuilt Console right inside the Web Maker interface.&lt;/p&gt;
&lt;h2 id=&quot;what-exactly-is-a-console%2C-you-ask%3F&quot;&gt;What exactly is a Console, you ask? &lt;a class=&quot;bookmark&quot; href=&quot;#what-exactly-is-a-console%2C-you-ask%3F&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If you have developed for browsers, you have most probably used the developer console that every browser provides. Wherein you can see your logs, errors etc. The Console in Web Maker is a similar thing, though it might not be that advanced...yet. You can do most basic things you do in the browser&#39;s developer console, without actually opening it! This is how it looks:&lt;/p&gt;
&lt;figure&gt;
    &lt;img src=&quot;https://kushagra.dev/images/webmaker-console.gif&quot; alt=&quot;Web Maker Console&quot;&gt;
    &lt;caption&gt;Web Maker&#39;s inbuilt Console&lt;/caption&gt;
&lt;/figure&gt;
&lt;h2 id=&quot;how-is-a-console-useful%3F&quot;&gt;How is a Console useful? &lt;a class=&quot;bookmark&quot; href=&quot;#how-is-a-console-useful%3F&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Having a Console right there, makes your much more productive and efficient in multiple ways. First of all, you won&#39;t have to open the browser&#39;s developer console in most cases...we all know how it can be slow at times.&lt;/p&gt;
&lt;p&gt;You often use various log functions in your code, like &lt;code&gt;console.log&lt;/code&gt;, &lt;code&gt;console.error&lt;/code&gt; etc. All these logs show up in the inbuilt Console. Moreover, if there is any runtime error in your JavaScript code, it would show up too in the Console, thus making your debugging very quick and easy.&lt;/p&gt;
&lt;p&gt;Apart from this, you can also evaluate any custom JavaScript code in your preview&#39;s context right from the Console. Just type it in the console input and press Enter.&lt;/p&gt;
&lt;p&gt;I had real fun developing Console into Web Maker. Hope it makes you more productive. If you loved this new feature, tweet out your love to &lt;a href=&quot;https://twitter.com/webmakerapp&quot;&gt;@webmakerapp&lt;/a&gt;. Cheers!&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Web Maker, an Offline, Browser-based CodePen Alternative</title>
		<link href="https://kushagra.dev/blog/web-maker-offline-web-playground/"/>
		<updated>2017-02-15T00:00:00+00:00</updated>
		<id>https://kushagra.dev/blog/web-maker-offline-web-playground/</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>Web Maker: Preventing Infinite Loops</title>
		<link href="https://kushagra.dev/blog/web-maker-infinite-loop-prevention/"/>
		<updated>2017-02-10T00:00:00+00:00</updated>
		<id>https://kushagra.dev/blog/web-maker-infinite-loop-prevention/</id>
		<content type="html">&lt;h2 id=&quot;the-problem&quot;&gt;The Problem &lt;a class=&quot;bookmark&quot; href=&quot;#the-problem&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;When you write JavaScript in &lt;a href=&quot;https://kushagragour.in/lab/web-maker&quot;&gt;Web Maker&lt;/a&gt;, it renders that JavaScript inside the preview window in realtime. What this means is in case you using any loop structure in your code, there will probably be a point when you mid way defining your loop variables, conditions, variant etc. And at that point if Web Maker renders your JavaScript, it would result in an infinite loop. Lets see with an example. Suppose I want to write a for loop to iterate 10 times, I&#39;ll start with&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;cursor_here&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note that my cursor would be where it says &lt;code&gt;[cursor_here]&lt;/code&gt; and I am still defining my loop and going to write &lt;code&gt;i++&lt;/code&gt; there. But as we render in realtime, this incomplete code would get executed in preview, resulting in an infinite loop.&lt;/p&gt;
&lt;p&gt;Therefore we need a way to prevent such intermediate incomplete loops from running infinitely and choking the browser.&lt;/p&gt;
&lt;h2 id=&quot;solution&quot;&gt;Solution &lt;a class=&quot;bookmark&quot; href=&quot;#solution&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;There is a &lt;a href=&quot;http://mca.nowgray.com/2017/01/can-runtime-environment-detect-infinite.html&quot;&gt;lot of discussion on the Web&lt;/a&gt; regarding how difficult it is to detect an infinite loop in runtime, simply because any runtime cannot actually diffrentiate between a normal loop and one that is going to run infinitely. There are some analyzers that try to solve this issue but static analysis can only do so much.&lt;/p&gt;
&lt;p&gt;The approach Web Maker takes to solve this is by keeping a check on the time spent inside a loop. To be specific, I check if the loop isn&#39;t taking more than 1 second. Otherwise its marked as an infinite loop. To be able to keep track of this time, we need to have a time check inside the loop and hence this requires changing the actual loop code, also called as &lt;a href=&quot;https://en.wikipedia.org/wiki/Instrumentation_(computer_programming)&quot;&gt;Code Instrumentation&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;So if we have a code like this:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After our instrumentation, it should change to:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; startTime &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Date&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Date&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; startTime &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token keyword&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To analyze a piece of code, we need a JavaScript parser. I used &lt;a href=&quot;http://esprima.org/&quot;&gt;Esprima&lt;/a&gt; for that. Lets see how we can use Esprima to instrument our code.&lt;/p&gt;
&lt;h3 id=&quot;detecting-a-loop&quot;&gt;Detecting a loop &lt;a class=&quot;bookmark&quot; href=&quot;#detecting-a-loop&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Esprima converts a string of JavaScript code into an &lt;a href=&quot;https://en.wikipedia.org/wiki/Abstract_syntax_tree&quot;&gt;Abstract Syntax Tree&lt;/a&gt; (AST), which is basically a tree like structure representing the code snippet.&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;instrumentCode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;code&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; ast &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; esprima&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;code&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To get a sense of what an AST looks like, lets run esprima on the following code:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; foo &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is what we&#39;ll get:&lt;/p&gt;
&lt;figure&gt;
    &lt;img src=&quot;https://kushagra.dev/images/ast.png&quot; alt=&quot;Esprima Abstract Syntax Tree&quot;&gt;
    &lt;caption&gt;Esprima&#39;s Abstract Syntax Tree&lt;/caption&gt;
&lt;/figure&gt;
&lt;p&gt;Notice how the return AST is a repeating nested array structure (&lt;code&gt;body&lt;/code&gt; inside &lt;code&gt;body&lt;/code&gt;), with each identifiable unit as an instance of some class. Eg. &lt;code&gt;VariableDeclaration&lt;/code&gt;, &lt;code&gt;ForStatement&lt;/code&gt; etc. This is something we can easily traverse using recursion, like so:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;processAst&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;ast&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; currentElement&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token comment&quot;&gt;// If this ins&#39;t actual body, recurse with the body&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;Array&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;isArray&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;astBody&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token function&quot;&gt;processAst&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;astBody&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;body&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token comment&quot;&gt;// Traverse the body&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ast&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;length&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i&lt;span class=&quot;token operator&quot;&gt;--&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; currentElement &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ast&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;br&gt;    &lt;span class=&quot;token comment&quot;&gt;// Process `currentElement` here&lt;/span&gt;&lt;br&gt;&lt;br&gt;    &lt;span class=&quot;token comment&quot;&gt;// Recurse on inner body&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;currentElement&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;body&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token function&quot;&gt;processAst&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;currentElement&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;body&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;instrumentCode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;code&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; ast &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; esprima&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;code&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token function&quot;&gt;processAst&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ast&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With the above code in place, we&#39;ll keep getting different syntax structures in &lt;code&gt;currentElement&lt;/code&gt;. Next, we check them and inject the actual loop protection code.&lt;/p&gt;
&lt;h3 id=&quot;injecting-the-loop-protection-checks&quot;&gt;Injecting the loop protection checks &lt;a class=&quot;bookmark&quot; href=&quot;#injecting-the-loop-protection-checks&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;We are concerned when &lt;code&gt;currentElement&lt;/code&gt; is a &lt;code&gt;for&lt;/code&gt;, &lt;code&gt;while&lt;/code&gt; or &lt;code&gt;do-while&lt;/code&gt; loop. This can be checked by simply testing &lt;code&gt;currentElement.type&lt;/code&gt;. Lets add that.&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;processAst&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;ast&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; currentElement&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token comment&quot;&gt;// If this ins&#39;t actual body, recurse with the body&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;Array&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;isArray&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;astBody&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token function&quot;&gt;processAst&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;astBody&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;body&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token comment&quot;&gt;// Traverse the body&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ast&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;length&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i&lt;span class=&quot;token operator&quot;&gt;--&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; currentElement &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ast&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;br&gt;    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;currentElement &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; currentElement&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;type &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;ForStatement&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt;&lt;br&gt;      currentElement&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;type &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;WhileStatement&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt;&lt;br&gt;      currentElement&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;type &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;DoWhileStatement&quot;&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token comment&quot;&gt;// We got a loop!&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token comment&quot;&gt;// Recurse on inner body&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;currentElement&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;body&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token function&quot;&gt;processAst&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;currentElement&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;body&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next we need two of our statements to be injected in AST syntax. For that we can again use esprima. Once we covert the statements into AST objects, its just a matter of adding them to the right &lt;code&gt;body&lt;/code&gt; in our AST.&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;currentElement &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; currentElement&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;type &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;ForStatement&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt;&lt;br&gt;  currentElement&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;type &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;WhileStatement&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt;&lt;br&gt;  currentElement&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;type &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;DoWhileStatement&quot;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; ast1 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; esprima&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;var myvar = Date.now();&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; ast2 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; esprima&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token string&quot;&gt;&quot;while(a){if (Date.now() - myvar &gt; 1000) { break;}}&quot;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; insertionBlocks &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token literal-property property&quot;&gt;before&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ast1&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;body&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token literal-property property&quot;&gt;inside&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ast2&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;body&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;body&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;body&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notice, that we have assigned the current time in &lt;code&gt;myVar&lt;/code&gt;. Now there could be multiple loops (even nested) in a single code snippet and they all need to be handled with their unique variables. So we replace the variable names in our insertion blocks with a 3 digit random string:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;currentElement &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; currentElement&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;type &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;ForStatement&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt;&lt;br&gt;  currentElement&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;type &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;WhileStatement&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt;&lt;br&gt;  currentElement&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;type &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;DoWhileStatement&quot;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; ast1 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; esprima&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;var myvar = Date.now();&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; ast2 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; esprima&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token string&quot;&gt;&quot;while(a){if (Date.now() - myvar &gt; 1000) { break;}}&quot;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; insertionBlocks &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token literal-property property&quot;&gt;before&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ast1&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;body&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token literal-property property&quot;&gt;inside&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ast2&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;body&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;body&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;body&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  randomVariableName &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;_&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;generateRandomId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  insertionBLocks&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;before&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;declarations&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;id&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; insertionBLocks&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;inside&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;test&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;left&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;right&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; randomVariableName&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;All that is left now is to insert the insertion blocks at right places:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;currentElement &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; currentElement&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;type &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;ForStatement&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt;&lt;br&gt;  currentElement&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;type &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;WhileStatement&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt;&lt;br&gt;  currentElement&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;type &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;DoWhileStatement&quot;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; ast1 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; esprima&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;var myvar = Date.now();&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; ast2 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; esprima&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token string&quot;&gt;&quot;while(a){if (Date.now() - myvar &gt; 1000) { break;}}&quot;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; insertionBlocks &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token literal-property property&quot;&gt;before&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ast1&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;body&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token literal-property property&quot;&gt;inside&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ast2&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;body&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;body&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;body&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  randomVariableName &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;_&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;generateRandomId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  insertionBLocks&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;before&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;declarations&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;id&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; insertionBLocks&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;inside&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;test&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;left&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;right&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; randomVariableName&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;br&gt;  &lt;span class=&quot;token comment&quot;&gt;// Insert time variable assignment as first child in the body array.&lt;/span&gt;&lt;br&gt;  ast&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;splice&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; insertionBLocks&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;before&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;br&gt;  &lt;span class=&quot;token comment&quot;&gt;// If the loop&#39;s body is a single statement, then convert it into a block statement&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token comment&quot;&gt;// so that we can insert our conditional break inside it.&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;Array&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;isArray&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;el&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;body&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;    currentElement&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;body &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token literal-property property&quot;&gt;body&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;el&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;body&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token literal-property property&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;BlockStatement&quot;&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;br&gt;  &lt;span class=&quot;token comment&quot;&gt;// Insert the `If` Statement check&lt;/span&gt;&lt;br&gt;  currentElement&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;body&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;body&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;unshift&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;insertionBLocks&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;inside&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And we are done.&lt;/p&gt;
&lt;p&gt;You can also see the actual Web Maker &lt;a href=&quot;https://github.com/chinchang/web-maker/blob/master/src/utils.js&quot;&gt;source code for this logic&lt;/a&gt;.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>HTML5 mode without server-side code</title>
		<link href="https://kushagra.dev/blog/html5mode-without-server/"/>
		<updated>2016-07-09T00:00:00+00:00</updated>
		<id>https://kushagra.dev/blog/html5mode-without-server/</id>
		<content type="html">&lt;h2 id=&quot;issue&quot;&gt;Issue &lt;a class=&quot;bookmark&quot; href=&quot;#issue&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If you ever worked on a Single Page App (SPA), you would know that the URLs in the app either work using hash(#) or without hash - also called as &lt;em&gt;HTML5 mode&lt;/em&gt; in most frameworks. For &lt;em&gt;HTML5 mode&lt;/em&gt; to work though, you need to write server-side rewrite code to always serve &lt;code&gt;index.html&lt;/code&gt; for every page requested.&lt;/p&gt;
&lt;p&gt;Eg. &lt;code&gt;www.yourapp.com/product/13&lt;/code&gt; or &lt;code&gt;www.yourapp.com/user/setting&lt;/code&gt; should all respond with &lt;code&gt;index.html&lt;/code&gt; because in SPAs, there are no separate html files that can directly/independently render in the browser, except &lt;code&gt;index.html&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;But what if you could get the HTML5 mode working without any server-side code?&lt;/p&gt;
&lt;h2 id=&quot;the-trick&quot;&gt;The Trick &lt;a class=&quot;bookmark&quot; href=&quot;#the-trick&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I read this trick on &lt;a href=&quot;https://coderwall.com/p/kfomwa/angularjs-html5mode-on-github-pages&quot;&gt;Coderwall&lt;/a&gt; sometime back and decided to give it a shot. The trick is simple, if you do not have proper rewrite rules on the server, requesting a URL like &lt;code&gt;www.yourapp.com/user/13&lt;/code&gt; would try fetching a resource on the path &lt;code&gt;user/13/&lt;/code&gt;, which isn&#39;t actually present. So your app would send in a &lt;code&gt;404.html&lt;/code&gt; in this case. But we want it to respond with index.html. What if we make &lt;code&gt;404.html&lt;/code&gt; same as &lt;code&gt;index.html&lt;/code&gt;?? 😎&lt;/p&gt;
&lt;p&gt;For this demo, I have implemented a basic SPA using &lt;a href=&quot;http://vuejs.org/&quot;&gt;Vue.js&lt;/a&gt; as the JavaScript framework and deployed it on Github pages.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://kushagragour.in/vuejs-html5mode&quot; class=&quot;button&quot;&gt;Demo&lt;/a&gt;&lt;br&gt;
&lt;a href=&quot;https://github.com/chinchang/vuejs-html5mode&quot; class=&quot;button&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The main thing to notice there is if you refresh the app on a path other than &lt;code&gt;https://kushagragour.in/vuejs-html5mode/&lt;/code&gt;, you would see a 404 in the network panel.&lt;/p&gt;
&lt;h2 id=&quot;things-to-keep-in-mind&quot;&gt;Things to keep in mind &lt;a class=&quot;bookmark&quot; href=&quot;#things-to-keep-in-mind&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;First, you would have a 404 from the server when a user lands on any path other than the root. No big deal, just that there would be a red entry in the network panel.&lt;/p&gt;
&lt;p&gt;Second, and more importantly, you are using your 404 page to make an &lt;code&gt;index.html&lt;/code&gt; clone. That means that you no more have a real 404 page to show to your users. One way I think of to fix this is by having a script in &lt;code&gt;404.html&lt;/code&gt; that validates the current URL for valid URL and if its not, renders the 404 stuff instead of usual &lt;code&gt;index.html&lt;/code&gt; contents.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Using background color in currentColor</title>
		<link href="https://kushagra.dev/blog/backgroundcolor-in-currentcolor/"/>
		<updated>2016-01-31T00:00:00+00:00</updated>
		<id>https://kushagra.dev/blog/backgroundcolor-in-currentcolor/</id>
		<content type="html">&lt;p&gt;I had the following situation recently - I have a container with some background color and it needs to have an arrow coming out from inside of the same background color. I implemented the arrow using &lt;code&gt;:after&lt;/code&gt; pseudo element. Something like this:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://kushagra.dev/images/2016/currentcolor-propagation.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;.container&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;display&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; inline-block&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;padding&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 30px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;background-color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; indianred&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; relative&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class=&quot;token comment&quot;&gt;/* Arrow */&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token selector&quot;&gt;.container:after&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;display&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; block&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; absolute&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 100%&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;top&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;calc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;50% - 10px&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;border&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 10px solid transparent&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;border-left-color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; indianred&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now this code works, but the container could be multi-colored and also the arrow can show either right or left for any container. With above implementation, for each different container, we&#39;ll have to change the border color as well like so:&lt;/p&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;/* Modifier for a container having left arrow */&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token selector&quot;&gt;.container--inverted:after&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; auto&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;right&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 100%&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;border-left-color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; transparent &lt;span class=&quot;token important&quot;&gt;!important&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class=&quot;token comment&quot;&gt;/* New container */&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token selector&quot;&gt;.container--2&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;background-color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; skyblue&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class=&quot;token comment&quot;&gt;/* Arrow */&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token selector&quot;&gt;.container--2:after&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;border-left-color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; skyblue&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token selector&quot;&gt;.container--2.container--inverted:after&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;border-right-color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; skyblue&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Bad Demo:&lt;/strong&gt;&lt;/p&gt;
&lt;p data-height=&quot;268&quot; data-theme-id=&quot;0&quot; data-slug-hash=&quot;rxKrag&quot; data-default-tab=&quot;result&quot; data-user=&quot;chinchang&quot; data-preview=&quot;true&quot; class=&quot;codepen&quot;&gt;See the Pen &lt;a href=&quot;http://codepen.io/chinchang/pen/rxKrag/&quot;&gt;BjVPNJ&lt;/a&gt; by Kushagra Gour (&lt;a href=&quot;http://codepen.io/chinchang&quot;&gt;@chinchang&lt;/a&gt;) on &lt;a href=&quot;http://codepen.io/&quot;&gt;CodePen&lt;/a&gt;.&lt;/p&gt;
&lt;script async=&quot;&quot; src=&quot;https://assets.codepen.io/assets/embed/ei.js&quot;&gt;&lt;/script&gt;
&lt;h3 id=&quot;issues&quot;&gt;Issues &lt;a class=&quot;bookmark&quot; href=&quot;#issues&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;This code has 2 visible issues:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Not DRY&lt;/strong&gt; - Every new container has to define the color of its arrow by specifying the border color and that too 2 times, one for left and right each. So in total we&#39;ll need to write a single color value 3 times for every container...too much repeatition.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Coupling&lt;/strong&gt; - The container styling needs to be aware of the arrow implementation, whether its using border trick or something else. Changing the arrow implementation in future will require changing it for every container.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;solution&quot;&gt;Solution &lt;a class=&quot;bookmark&quot; href=&quot;#solution&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;One thing that might come to your mind to prevent these issues is &lt;code&gt;currentColor&lt;/code&gt;. Close enough, just that &lt;code&gt;currentColor&lt;/code&gt; refers to the &lt;code&gt;color&lt;/code&gt; property and not &lt;code&gt;background-color&lt;/code&gt;. Bummer!&lt;/p&gt;
&lt;p&gt;To overcome this limitation I came up with a trick I call &lt;code&gt;currentColor propagation&lt;/code&gt; :) The trick is basically to propagate &lt;code&gt;background-color&lt;/code&gt; to &lt;code&gt;color&lt;/code&gt; property of the arrow and then use &lt;code&gt;currentColor&lt;/code&gt; for coloring arrows! That solves both our issues:&lt;/p&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;.container&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token comment&quot;&gt;/* Other styles here */&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;background-color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; indianred&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token selector&quot;&gt;.container:after&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token comment&quot;&gt;/* Other styles here */&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; indianred&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;border-left-color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; currentColor&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token selector&quot;&gt;.container--inverted:after&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;border-left-color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; transparent&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;border-right-color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; currentColor&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class=&quot;token comment&quot;&gt;/* Modifiers can just be like so */&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token selector&quot;&gt;.container--2&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;background-color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; skyblue&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token comment&quot;&gt;/* Arrow */&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token selector&quot;&gt;.container--2:after&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; skyblue&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Yes, we need still need to mention color 2 times for each new container, but still better than 3 times. More importantly, all the arrow related code is just at one place and not duplicated for each container. Plus we don&#39;t have to use that dirty &lt;code&gt;!important&lt;/code&gt; and have much less code.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Improved Demo:&lt;/strong&gt;&lt;/p&gt;
&lt;p data-height=&quot;268&quot; data-theme-id=&quot;0&quot; data-slug-hash=&quot;BjVPNJ&quot; data-default-tab=&quot;result&quot; data-user=&quot;chinchang&quot; data-preview=&quot;true&quot; class=&quot;codepen&quot;&gt;See the Pen &lt;a href=&quot;http://codepen.io/chinchang/pen/BjVPNJ/&quot;&gt;BjVPNJ&lt;/a&gt; by Kushagra Gour (&lt;a href=&quot;http://codepen.io/chinchang&quot;&gt;@chinchang&lt;/a&gt;) on &lt;a href=&quot;http://codepen.io/&quot;&gt;CodePen&lt;/a&gt;.&lt;/p&gt;
&lt;script async=&quot;&quot; src=&quot;https://assets.codepen.io/assets/embed/ei.js&quot;&gt;&lt;/script&gt;
&lt;p&gt;Thats it for this article. Hope it will help you sometime :)&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>2015 - Year in review</title>
		<link href="https://kushagra.dev/blog/2015-year-in-review/"/>
		<updated>2015-12-31T00:00:00+00:00</updated>
		<id>https://kushagra.dev/blog/2015-year-in-review/</id>
		<content type="html">&lt;p&gt;Another year passed and its review time :) But this time instead of reviewing the year month wise, I&#39;ll do it in few categories.&lt;/p&gt;
&lt;h2 id=&quot;tech&quot;&gt;Tech &lt;a class=&quot;bookmark&quot; href=&quot;#tech&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;This has to be the first category for review as this is what I love to do the most.&lt;/p&gt;
&lt;figure&gt;
	&lt;h3&gt;Perfaudit&lt;/h3&gt;
	&lt;img src=&quot;https://kushagra.dev/images/2015/perfaudit.png&quot; alt=&quot;&quot;&gt;
	&lt;figcaption&gt;&lt;a href=&quot;https://perfaudit.com/&quot;&gt;PerfAudit&lt;/a&gt; was this year&#39;s first side project that I did with my colleague &lt;a href=&quot;https://twitter.com/Apoorv_Saxena&quot;&gt;Apoorv&lt;/a&gt;. We did case-studies for some awesome websites, helped people make their sites faster and got lot of appreciation. It was fun.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
	&lt;h3&gt;cta.js&lt;/h3&gt;
	&lt;img src=&quot;https://kushagra.dev/images/2015/ctajs.png&quot; alt=&quot;&quot;&gt;
	&lt;figcaption&gt;&lt;a href=&quot;http://kushagragour.in/lab/ctajs/&quot;&gt;Cta.js&lt;/a&gt; is a JS library I wrote inspired from &lt;a href=&quot;https://twitter.com/aerotwist&quot;&gt;Paul Lewis&#39;&lt;/a&gt; technique to performantly transition DOM elements.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
	&lt;h3&gt;konsole.table, super-search &amp; screenlog.js&lt;/h3&gt;
	&lt;figcaption&gt;
	3 more JS shorties I did. &lt;a href=&quot;https://www.npmjs.com/package/konsole.table&quot;&gt;konsole.table&lt;/a&gt; was my first npm module which provides `console.table` in node environment. And &lt;a href=&quot;https://github.com/chinchang/super-search&quot;&gt;super-search&lt;/a&gt; is a JS library to enable search feature in any blog/website having an RSS feed.
	&lt;br&gt;
	&lt;a href=&quot;https://github.com/chinchang/screenlog.js&quot;&gt;screenlog.js&lt;/a&gt; makes it possible to use `console` statements without opening the console in your browser.
	&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
	&lt;h3&gt;Prototyp&lt;/h3&gt;
	&lt;img src=&quot;https://kushagra.dev/images/2015/prototyp.png&quot; alt=&quot;&quot;&gt;
	&lt;figcaption&gt;Then I did one of my most &quot;useful&quot; app of the year :P I had started playing with Framer.js and was really impressed with what one can do with it very easily. But the editor for it is paid and just available for mac. So I decided to build a web app over Framer.js which is free and works across platforms.
	&lt;br&gt;
	I would say this is by far the closest I have come to creating a product :) Hope to make it more usable in coming time
	&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
	&lt;h3&gt;Kalu&lt;/h3&gt;
	&lt;figcaption&gt;
	&lt;a href=&quot;https://kushagra.dev/lab/kalu/&quot;&gt;Kalu&lt;/a&gt; was a calculator concept I implemented using codemirror editor. It aims at making long inter-linked calculation easy.
	&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
	&lt;h3&gt;Word Blast Game&lt;/h3&gt;
	&lt;img src=&quot;https://kushagra.dev/images/2015/wordblast.jpg&quot; alt=&quot;&quot;&gt;
	&lt;figcaption&gt;The &lt;a href=&quot;http://js13kgames.com/entries/word-blast&quot;&gt;only game&lt;/a&gt; I did this year was for JS13KGames compo. Wanted to make more games though.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
	&lt;h3&gt;lollipop.css&lt;/h3&gt;
	&lt;img src=&quot;https://kushagra.dev/images/2015/lollipopcss.png&quot; alt=&quot;&quot;&gt;
	&lt;figcaption&gt;&lt;a href=&quot;https://kushagra.dev/lab/lollipop.css/&quot;&gt;A self-learning experiment&lt;/a&gt; to implement Android Lollipop animations in pure CSS.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
	&lt;h3&gt;&lt;a href=&quot;http://kushagragour.in/code-blast-codemirror/demo/index.html&quot;&gt;Code Blast plugin for Codemirror&lt;/a&gt;&lt;/h3&gt;
	&lt;video src=&quot;https://kushagra.dev/images/2015/codeblast.mp4&quot; autoplay=&quot;&quot; loop=&quot;&quot; alt=&quot;&quot;&gt;&lt;/video&gt;
	&lt;figcaption&gt;A hack trigerred by someone&#39;s &lt;a href=&quot;https://twitter.com/JoelBesada/status/670343885655293952&quot;&gt;hack&lt;/a&gt;. Too much of fun :P&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&quot;art&quot;&gt;Art &lt;a class=&quot;bookmark&quot; href=&quot;#art&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;figure&gt;
	&lt;h3&gt;INKtober&lt;/h3&gt;
	&lt;img src=&quot;https://kushagra.dev/images/2015/inktober.jpg&quot; alt=&quot;&quot;&gt;
	&lt;figcaption&gt;
	INKtober is a challenge where people draw something on every day of October. This was my first and although I couldn&#39;t draw all 31 days, I managed to pull off quite a few and had a very happy time doing it. Heres a summary of it but checkout all of them on my &lt;a href=&quot;http://draw.kushagragour.in/tagged/inktober&quot;&gt;art blog&lt;/a&gt;.
	&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
	&lt;h3&gt;Bematlab&lt;/h3&gt;
	&lt;img src=&quot;https://kushagra.dev/images/2015/bematlab.jpg&quot; alt=&quot;&quot;&gt;
	&lt;figcaption&gt;
	I started &lt;a href=&quot;https://www.facebook.com/bematlab&quot;&gt;Bematlab&lt;/a&gt; last year and this year I added content whenever I got time and ideas. Drawing is fun! Ideas are rare! Heres one of my favourite from this year.
	&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&quot;music&quot;&gt;Music &lt;a class=&quot;bookmark&quot; href=&quot;#music&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Not much here. I practiced beatboxing and playing flute occasionally. Also released a small &lt;a href=&quot;https://soundcloud.com/kushagra-gour/resham-firiri-bansuri-n-beatbox&quot;&gt;beatbox+flute piece&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;sports&quot;&gt;Sports &lt;a class=&quot;bookmark&quot; href=&quot;#sports&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;figure&gt;
	&lt;h3&gt;Football with office pals&lt;/h3&gt;
	&lt;figcaption&gt;
	We made an unofficial WingifyFC at Wingify :) We have started playing on Sat/Sun, then shifted to Wed/Fridays, then just fridays and then stopped in the end :P We&#39;ll definitely start it again and also have a tournament coming up this January :)
	&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
	&lt;h3&gt;Won TT doubles tournament&lt;/h3&gt;
	&lt;img src=&quot;https://kushagra.dev/images/2015/tt.png&quot; alt=&quot;&quot; height=&quot;300&quot;&gt;
	&lt;figcaption&gt;
	A TT double tournament was organized at Wingify. I and &lt;a href=&quot;https://twitter.com/s0ftvar&quot;&gt;Varun&lt;/a&gt; won that :)
	&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
	&lt;h3&gt;Marathon&lt;/h3&gt;
	&lt;img src=&quot;https://kushagra.dev/images/2015/marathon.jpg&quot; alt=&quot;&quot;&gt;
	&lt;figcaption&gt;
		I ran a 7KM marathon...in Leh, Ladakh with my friend Manpreet :)
	&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&quot;conferences&quot;&gt;Conferences &lt;a class=&quot;bookmark&quot; href=&quot;#conferences&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Attended MetaRefresh conference in Bangalore where we (wingify) were a sponsor and Apoorv gave a talk. It was all fine until...there was a Karnataka-bandh and we had to stay for hours on Bangalore airport :(&lt;/p&gt;
&lt;h2 id=&quot;travel&quot;&gt;Travel &lt;a class=&quot;bookmark&quot; href=&quot;#travel&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;figure&gt;
	&lt;h3&gt;Chamba, Himachal&lt;/h3&gt;
	&lt;img src=&quot;https://kushagra.dev/images/2015/chamba.jpg&quot; alt=&quot;&quot;&gt;
	&lt;figcaption&gt;
		An awesome trip to Chamba/Khajjiar/Dalhousie with Kamal, Ajay, Hariom and Gillz (Vivek). First time in Himachal :) &lt;a href=&quot;http://travel.kushagragour.in/tagged/chamba&quot;&gt;More pics&lt;/a&gt;.
	&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
	&lt;h3&gt;Kasol, Himachal&lt;/h3&gt;
	&lt;img src=&quot;https://kushagra.dev/images/2015/kasol.png&quot; alt=&quot;&quot;&gt;
	&lt;figcaption&gt;
		Full Wingify Engineering team outing.
	&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
	&lt;h3&gt;Leh, Ladakh&lt;/h3&gt;
	&lt;img src=&quot;https://kushagra.dev/images/2015/ladakh1.jpg&quot; alt=&quot;&quot;&gt;
	&lt;img src=&quot;https://kushagra.dev/images/2015/ladakh2.jpg&quot; alt=&quot;&quot;&gt;
	&lt;figcaption&gt;
		No words to speak about this trip. Beautiful mountains, clean roads and absolute silence. You have to be there to experience it. And I must say, the food is just top class in Leh! &lt;a href=&quot;http://travel.kushagragour.in/tagged/ladakh&quot;&gt;More pics&lt;/a&gt;.
	&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
	&lt;h3&gt;Jim Corbett, Uttarakhand&lt;/h3&gt;
	&lt;img src=&quot;https://kushagra.dev/images/2015/corbett1.jpg&quot; alt=&quot;&quot;&gt;
	&lt;figcaption&gt;
		Full Wingify Engineering team outing, again :) We saw no tiger, infact no animal. Just chilled at the resort. We are playing mafia in above still.
	&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
	&lt;h3&gt;Laangkawi, Malaysia&lt;/h3&gt;
	&lt;img src=&quot;https://kushagra.dev/images/2015/malaysia1.jpg&quot; alt=&quot;&quot;&gt;
	&lt;img src=&quot;https://kushagra.dev/images/2015/malaysia2.jpg&quot; alt=&quot;&quot;&gt;
	&lt;figcaption&gt;
		Wingify&#39;s year end trip with 100+ people :) It was amazing to see 100+ wingifians fill up the complete airport, plane, then the resort, beaches! Did para-sailing for first time. Last trip of year, absolute fun.
	&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&quot;work&quot;&gt;Work &lt;a class=&quot;bookmark&quot; href=&quot;#work&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;figure&gt;
	&lt;h3&gt;First time campus recruitment&lt;/h3&gt;
	&lt;img src=&quot;https://kushagra.dev/images/2015/dce1.png&quot; alt=&quot;&quot;&gt;
	&lt;img src=&quot;https://kushagra.dev/images/2015/dce2.png&quot; alt=&quot;&quot;&gt;
	&lt;figcaption&gt;
		After 4 years out of college, I was in a campus (DTU) for recruiting engineers. Good first time experience :P
	&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h3 id=&quot;focusing-on-dx-along-with-ux&quot;&gt;Focusing on DX along with UX &lt;a class=&quot;bookmark&quot; href=&quot;#focusing-on-dx-along-with-ux&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;This year I shifted my partial focus from User experience (UX) to Developer experience (DX, self-invented term). DX means I work towards making life of developers easy in every aspect, whether its writing code or releasing it. That involves things like automating stuff and is a refreshing change for me.&lt;/p&gt;
&lt;h3 id=&quot;bsp&quot;&gt;BSP &lt;a class=&quot;bookmark&quot; href=&quot;#bsp&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;We organized our first Bug squashing party at office. Quite a success I would say.&lt;/p&gt;
&lt;h3 id=&quot;new-office&quot;&gt;New office &lt;a class=&quot;bookmark&quot; href=&quot;#new-office&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Our product team at Wingify moved to a new office. New environment, new vibes, less distraction.&lt;/p&gt;
&lt;h3 id=&quot;hackathon&quot;&gt;Hackathon &lt;a class=&quot;bookmark&quot; href=&quot;#hackathon&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;I made an app called &lt;a href=&quot;http://chennainerd.2015.nodeknockout.com/&quot;&gt;&lt;strong&gt;Gamjeong&lt;/strong&gt;&lt;/a&gt; along with &lt;a href=&quot;https://twitter.com/dheerajhere&quot;&gt;Dheeraj&lt;/a&gt; at a hackathon we had at Wingify. It send you push notifications for tweets that match the keyword and sentiment you say.&lt;/p&gt;
&lt;h2 id=&quot;misc&quot;&gt;Misc &lt;a class=&quot;bookmark&quot; href=&quot;#misc&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;figure&gt;
	&lt;h3&gt;Rubiks Cube&lt;/h3&gt;
	&lt;iframe width=&quot;420&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/hVr-DeIR7TY&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;
	&lt;figcaption&gt;
		Beginning this year, I started solving rubiks cube. Apart from getting down from 5 minutes/solve to 50 seconds/solve, best thing was perseverance. I kept practicing it the whole year...probably because its too handly and I keep playing with it in buses, trains, boring weddings and where not :)
	&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
	&lt;h3&gt;Started Cardistry&lt;/h3&gt;
	&lt;img src=&quot;https://kushagra.dev/images/2015/cardistry.jpg&quot;&gt;
	&lt;figcaption&gt;
		A month back I also started &lt;a href=&quot;http://www.theory11.com/media/4545-what-is-cardistry&quot;&gt;Cardistry&lt;/a&gt; and some basic sleight of hands tricks with cards. Its very interesting and exciting. Will post my first video on cardistry soon :)
	&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
	&lt;h3&gt;New Car&lt;/h3&gt;
	&lt;img src=&quot;https://kushagra.dev/images/2015/ciaz.jpg&quot;&gt;
	&lt;figcaption&gt;
		Got a new car for my Dad :)
	&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
	&lt;h3&gt;More gaming&lt;/h3&gt;
	&lt;figcaption&gt;
		Bought a PS3 and have started playing games again after a long gap. Good to be back!
	&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h3 id=&quot;summary&quot;&gt;Summary &lt;a class=&quot;bookmark&quot; href=&quot;#summary&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;I created a lot of open source stuff, travelled a lot (by my standards). As far as art and music is concerned, I wanted to do more.&lt;/p&gt;
&lt;h3 id=&quot;for-2016-(in-no-order)&quot;&gt;For 2016 (in no order) &lt;a class=&quot;bookmark&quot; href=&quot;#for-2016-(in-no-order)&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Create and release more amazing stuff, as usual. More on product side instead of small libraries.&lt;/li&gt;
&lt;li&gt;Draw more often&lt;/li&gt;
&lt;li&gt;Release some music pieces&lt;/li&gt;
&lt;li&gt;Start a tech podcast&lt;/li&gt;
&lt;li&gt;Travel to more places&lt;/li&gt;
&lt;li&gt;Work towards making someone&#39;s life better&lt;/li&gt;
&lt;li&gt;Help bro with &lt;a href=&quot;https://prakriti.care/&quot;&gt;Prakriti&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
	</entry>
	
	<entry>
		<title>Adding search in your jekyll blog</title>
		<link href="https://kushagra.dev/blog/search-in-jekyll-blog/"/>
		<updated>2015-06-08T00:00:00+00:00</updated>
		<id>https://kushagra.dev/blog/search-in-jekyll-blog/</id>
		<content type="html">&lt;p&gt;I recently implemented search on this website (made in Jekyll). Its a complete client-side search and hence very quick and easy to use. To try it out, press the &#39;/&#39; or ESC key and type something.&lt;/p&gt;
&lt;p&gt;There are not too many articles out there on implementing a functional post search on a Jekyll blog, so I thought of writing about it. The following method described works over your blog&#39;s RSS feeds. So make sure you have your RSS feed URL ready. If you have a jekyll/octopress blog, chances are you already have a &lt;code&gt;feed.xml&lt;/code&gt; in your root folder. If not, &lt;a href=&quot;http://joelglovier.com/writing/rss-for-jekyll/&quot;&gt;read here&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;tl%3Bdr&quot;&gt;tl;dr &lt;a class=&quot;bookmark&quot; href=&quot;#tl%3Bdr&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/chinchang/super-search/&quot;&gt;&lt;strong&gt;super-search&lt;/strong&gt;&lt;/a&gt; - A library to easily add search on your jekyll or any other blog.&lt;/p&gt;
&lt;p&gt;Lets start implementing the search.&lt;/p&gt;
&lt;h3 id=&quot;fetching-the-rss-feeds.&quot;&gt;Fetching the RSS feeds. &lt;a class=&quot;bookmark&quot; href=&quot;#fetching-the-rss-feeds.&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;First thing we need to do is fetch the RSS feed XML. This is simple with &lt;code&gt;XMLHttpRequest&lt;/code&gt;. We fetch the XML and create a DOM out of it for parsing later.&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; xmlhttp &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;XMLHttpRequest&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;xmlhttp&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;GET&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;/feed.xml&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;xmlhttp&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;onreadystatechange&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;xmlhttp&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;readyState &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;xmlhttp&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;status &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;200&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; xmlhttp&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;status &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;304&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;br&gt;  &lt;span class=&quot;token comment&quot;&gt;// Create a DOM out of the XML string.&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; node &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DOMParser&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;parseFromString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;xmlhttp&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;responseText&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;text/xml&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  node &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; node&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;children&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  posts &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;xmlToJson&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;node&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;channel&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;item&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;xmlhttp&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;parsing-xml-feeds-into-json&quot;&gt;Parsing XML feeds into JSON &lt;a class=&quot;bookmark&quot; href=&quot;#parsing-xml-feeds-into-json&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;This can be done by traversing the XML tree and creating a JavaScript object as we go. I used &lt;a href=&quot;http://davidwalsh.name/convert-xml-json&quot;&gt;David Walsh&#39;s&lt;/a&gt; &lt;code&gt;xmlToJson&lt;/code&gt; function with some modifications to make it more suitable:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;
function xmlToJson(xml) {
	// Create the return object
	var obj = {};
	if (xml.nodeType == 3) { // text
		obj = xml.nodeValue;
	}

	// do children
	// If just one text node inside
	if (xml.hasChildNodes() &amp;&amp; xml.childNodes.length === 1 &amp;&amp; xml.childNodes[0].nodeType === 3) {
		obj = xml.childNodes[0].nodeValue;
	}
	else if (xml.hasChildNodes()) {
		for(var i = 0; i &lt; xml.childNodes.length; i++) {
			var item = xml.childNodes.item(i);
			var nodeName = item.nodeName;
			if (typeof(obj[nodeName]) == &quot;undefined&quot;) {
				obj[nodeName] = xmlToJson(item);
			} else {
				if (typeof(obj[nodeName].push) == &quot;undefined&quot;) {
					var old = obj[nodeName];
					obj[nodeName] = [];
					obj[nodeName].push(old);
				}
				obj[nodeName].push(xmlToJson(item));
			}
		}
	}
	return obj;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now you get a simple to use JavaScript object to search upon.&lt;/p&gt;
&lt;h3 id=&quot;matching-the-input-with-post-data&quot;&gt;Matching the input with post data &lt;a class=&quot;bookmark&quot; href=&quot;#matching-the-input-with-post-data&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Now all that remains is taking user input and matching it with the parsed posts we have. In my implementation, matching posts are ones which contain the input string in their title or full content.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;
document.querySelector(&#39;#your-search-input&#39;).addEventListener(&#39;input&#39;, onInputChange);

function onInputChange(e) {
	var currentInputValue = e.target.value,
		date;

	// We ignore input of less than 3 characters in length.
	if (!currentInputValue || currentInputValue.length &lt; 3) {
		return;
	}

	// Filter out all posts that have entered string in their
	// title or description.
	var matchingPosts = posts.filter(function (post) {
		if (post.title.indexOf(currentInputValue) !== -1 || post.description.indexOf(currentInputValue) !== -1) {
			return true;
		}
	});

	document.querySelector(&#39;#your-results-container&#39;).innerHTML = matchingPosts.map(function (post) {
		date = new Date(post.pubDate);
		return &#39;&lt;li&gt;&lt;a href=&quot;https://kushagra.dev/blog/search-in-jekyll-blog/&#39;%20+%20post.link%20+%20&#39;&quot;&gt;&#39; + post.title + &#39;&lt;span class=&quot;search__result-date&quot;&gt;&#39; + date.toUTCString().replace(/.*(&#92;d{2})&#92;s+(&#92;w{3})&#92;s+(&#92;d{4}).*/,&#39;$2 $1, $3&#39;) + &#39;&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#39;;
	}).join(&#39;&#39;);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And done! You have a quick search system in your blog.&lt;/p&gt;
&lt;h3 id=&quot;thats-not-all!&quot;&gt;Thats not all! &lt;a class=&quot;bookmark&quot; href=&quot;#thats-not-all!&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;I am releasing a library which implements the search system described above and even much more addons. Presenting &lt;a href=&quot;https://github.com/chinchang/super-search/&quot;&gt;&lt;strong&gt;super-search&lt;/strong&gt;&lt;/a&gt;, an easy to add search system for your blog. It works equally good with any blog having RSS feed file.&lt;/p&gt;
&lt;p&gt;Simply add the JS and CSS files to your blog:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-markup&quot;&gt;
&amp;lt;script src=&quot;super-search.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;link rel=&quot;stylesheet&quot; href=&quot;super-search.css&quot;&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And initiate the library at the end of your page (before closing BODY tag):&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;
superSearch();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now enjoy a fast search system on your blog. &lt;a href=&quot;https://github.com/chinchang/super-search/&quot;&gt;Read more about it here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Until next time!&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Journey with Rubik&#39;s Cube</title>
		<link href="https://kushagra.dev/blog/journey-with-rubik-cube/"/>
		<updated>2015-04-04T00:00:00+00:00</updated>
		<id>https://kushagra.dev/blog/journey-with-rubik-cube/</id>
		<content type="html">&lt;p&gt;Yes, I started playing with Rubik&#39;s cube recently. I have had rubik&#39;s cube (very cheap one though) since I was 14, but it was just time-pass then. I didn&#39;t know how to solve it. It was just one-sided play (if you get what I mean) as I could figure how to solve only one side completely. But this January my cousin came to our place for his vacations and he brought along a rubik&#39;s cube (probably just like me back then). As anyone would do now-a-days to know how something is done, I google-d too. And a lot of videos on how to solve rubik&#39;s cube showed up. Me and my cousin together learned how to solve the cube with the very basic method and have been practicing since then. I am writing this post to document the approach I have taken to learn whatever I know on solving a 3x3x3 rubik&#39;s cube. Lets start.&lt;/p&gt;
&lt;h3 id=&quot;learning-beginner&#39;s-method&quot;&gt;Learning Beginner&#39;s method &lt;a class=&quot;bookmark&quot; href=&quot;#learning-beginner&#39;s-method&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;My very first step was a &lt;a href=&quot;https://www.youtube.com/watch?v=MaltgJGz-dU&quot;&gt;youtube video&lt;/a&gt; explaining the most basic method for solving a 3x3x3 rubik&#39;s cube, also called as &amp;quot;Beginner&#39;s method&amp;quot;.&lt;/p&gt;
&lt;p&gt;It requires you to know very few algorithms (5 to be exact) and is obviously a little slower compared to other methods. Once I had all the 5 algorithms by heart, I was able to solve a 3x3x3 cube in around 10 minutes on average. Remember this was with a very okayish cube.&lt;/p&gt;
&lt;p&gt;&lt;a&gt;&lt;strong&gt;Average Time: ~ 10 minutes&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&quot;getting-a-new-cube&quot;&gt;Getting a new cube &lt;a class=&quot;bookmark&quot; href=&quot;#getting-a-new-cube&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;As soon as my cousin left, I ordered a new cube online. It was a Taxton T-3 stickerless speedcube. It was damn smooth and I could just turn it the whole day. My solve times on that cube improved a lot, got almost 2x faster!&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://kushagra.dev/images/2015/taxton.jpg&quot; alt=&quot;Taxton speedcube&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;a&gt;&lt;strong&gt;Average Time: ~ 5:20 minutes&lt;/strong&gt;&lt;a&gt;&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&quot;getting-faster-with-finger-tricks&quot;&gt;Getting faster with finger tricks &lt;a class=&quot;bookmark&quot; href=&quot;#getting-faster-with-finger-tricks&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;I kept seeing videos of rubik&#39;s cube championships and various tips and tricks on solving the cube faster. Soon it became clear that to lower my solve time I had 2 options:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Learn a faster method of solving (Fridrich method)&lt;/li&gt;
&lt;li&gt;Get faster with what I already knew&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Upon a quick glance at the Fridrich method, I realized it was better not to take it at that time :P It has huge number of algorithms that one needs to learn to execute it perfectly. All rubik&#39;s cube champions use this method, in pure or derivative form. So I went with the second option, also called as finger tricks in puzzle world.&lt;/p&gt;
&lt;p&gt;Finger tricks basically refers to using your fingers to turn the cube instead of using complete hand (which is slower). Also it emphasizes on smooth transitions from one algorithm to another without wasting much time in getting ready to execute the next one. This is how those sub-20 second guyz are able to turn the cube layers sooooo fast! So I got down to this, practicing each algorithm individually I knew whenever I got time - in bus, train, office, home...everywhere. I actually did not do even a single solve for about 2 weeks, just practice individual algorithms and developing my own finger turn-style. And then I did a timed solve just to show a colleague I could also solve the cube apart from just turning it seemingly ad-hoc - I did it in 2:40 minutes that day!&lt;/p&gt;
&lt;p&gt;&lt;a&gt;&lt;strong&gt;Average Time: ~ 3 minutes&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&quot;move-to-fridrich-method%3F&quot;&gt;Move to Fridrich Method? &lt;a class=&quot;bookmark&quot; href=&quot;#move-to-fridrich-method%3F&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Getting down to 3 minutes on average, I started feeling that I was not able to go lower than that. Also honestly I was getting a little bored with doing those algorithms over and over and over again. So I decided on giving Fridrich method a shot. Fridrich method involves large no. of algorithms which can be divided into categories:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;to solve 1st and 2nd layer - F2L&lt;/li&gt;
&lt;li&gt;to solve 3rd layer - PLL and OLL&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Approaching step by step, I decided to learn F2L (first two layers) first. F2L basically aims at solving the first 2 layers together as opposed to solving then one after other in beginner&#39;s method. Plan was to get F2L perfect for first 2 layers and use the already know algorithms for the 3rd layer. So I started learning and practicing F2L algorithms. There being too many of them, I felt friction in learning them :P So I looked for easier ways to perform F2L. There are quite a few &lt;a href=&quot;https://www.youtube.com/watch?v=2ewy0eOg2Do&quot;&gt;nice tutorials on easier F2L&lt;/a&gt; method which is also called as &lt;a href=&quot;https://www.youtube.com/watch?v=jGeTtD4tB5w&quot;&gt;intuitive F2L&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I practiced it for a week, but the results were not very impressive. I hardly got any better with F2L. I realized it was not a flaw with the method itself, but the time I devoted to it. It demands much much more time to get better with it.&lt;br&gt;
It was at this time when I saw a video on youtube where a guy could do a 3x3x3 solve in under &lt;a href=&quot;https://www.youtube.com/watch?v=qLki-254ZKA&quot;&gt;20 seconds with beginner&#39;s method&lt;/a&gt;! The trick was simple - faster turns. So I decided to do away with F2L and focus back on my finger tricks.&lt;/p&gt;
&lt;p&gt;&lt;a&gt;&lt;strong&gt;Average Time: ~ 3 minutes&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&quot;more-practice---cross-and-3rd-layer-algorithms&quot;&gt;More practice - cross and 3rd layer algorithms &lt;a class=&quot;bookmark&quot; href=&quot;#more-practice---cross-and-3rd-layer-algorithms&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;I focused for a while on improving my cross times and 3rd layer algorithms. Meanwhile I also came to know about a technique called look-ahead that advanced level solvers use to avoid time spent in figuring out the next move. I realized it was a very essential technique to get faster considering that my most of the time was spent in actually rotating the cube to see what to execute next. But this comes only with time and practice. I tried practicing look-aheads for 2nd layer.&lt;/p&gt;
&lt;p&gt;I bought another cube so that I didn&#39;t have to scramble after every solve during solve sprints :P It is a Shengshou 3x3x3 sticker cube. Much better than the taxton T-3. I love its turn sound!&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://kushagra.dev/images/2015/shenshou.jpg&quot; alt=&quot;Shenshou speedcube&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;a&gt;&lt;strong&gt;Average Time: ~ 100 seconds&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&quot;these-days...&quot;&gt;These days... &lt;a class=&quot;bookmark&quot; href=&quot;#these-days...&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;I have been focusing more on improving the individual steps rather than complete solves lately.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Faster cross&lt;/li&gt;
&lt;li&gt;2nd and 3rd layer algorithms&lt;/li&gt;
&lt;li&gt;2nd layer look-ahead&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here is a sample solve in 76 seconds:&lt;/p&gt;
&lt;iframe width=&quot;420&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/hVr-DeIR7TY&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;
&lt;p&gt;My aim is to get atleast sub-60 seconds with just beginner&#39;s method before I move onto learning more advanced techniques. Wish me luck. Looking forward to hear your rubik&#39;s cube experiences.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>2014 - Year in review</title>
		<link href="https://kushagra.dev/blog/2014-year-in-review/"/>
		<updated>2014-12-31T00:00:00+00:00</updated>
		<id>https://kushagra.dev/blog/2014-year-in-review/</id>
		<content type="html">&lt;p&gt;Guess what...it has been an year since I last wrote a post here! Time has passed by pretty quickly (as always) this year. This post is just a written log of things that &lt;code&gt;(did_happen &amp;amp;&amp;amp; I_remember)&lt;/code&gt; this year. Lets begin.&lt;/p&gt;
&lt;h3 id=&quot;january&quot;&gt;January &lt;a class=&quot;bookmark&quot; href=&quot;#january&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;2014 began with a bang. I published this year&#39;s first (and last too) blog post on &lt;a href=&quot;http://kushagragour.in/blog/2014/01/build-git-learn-git/&quot;&gt;learning GIT by implementing it in JavaScript&lt;/a&gt;. The post received a lot of appreciation on &lt;a href=&quot;https://news.ycombinator.com/item?id=7089380&quot;&gt;Hackernews&lt;/a&gt;. In short, people loved it. I had one or two further parts for this article, though I never couldn&#39;t take out time to finish them. 2015, may be :)&lt;/p&gt;
&lt;h3 id=&quot;april&quot;&gt;April &lt;a class=&quot;bookmark&quot; href=&quot;#april&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Nothing major here, but I had some &lt;a href=&quot;https://www.facebook.com/bhaisaab.baagi/media_set?set=a.310731669079177.1073741831.100004270386636&amp;amp;type=1&quot;&gt;really good 3-4 days&lt;/a&gt; with my awesome engineering team at Wingify. We were in the middle of our product&#39;s revamp and it had taken a lot of time already. Our engineering team was a little stressed out along with being excited. So we decided to leave our office for a few days and marched out to &#39;The Westin Sohna Resor&#39;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://kushagra.dev/images/2014/westin1.jpg&quot; alt=&quot;&quot;&gt;&lt;br&gt;
&lt;img src=&quot;https://kushagra.dev/images/2014/westin2.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;All techie ppl inside one huge villa at such an awesome place writing code till 6 in the morning and pool games in the evening...crazy time it was.&lt;/p&gt;
&lt;h3 id=&quot;june&quot;&gt;June &lt;a class=&quot;bookmark&quot; href=&quot;#june&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;One of the biggest acheivement this year. Months and months of effort by our engineering team at Wingify - &lt;a href=&quot;http://app.vwo.com/&quot;&gt;VWO 3.0&lt;/a&gt; finally released on June 25th. It was really a festive environment at the office. Everyone was super relaxed and extremely happy with what a bunch of cool engineers had created.&lt;/p&gt;
&lt;p&gt;I also released my first ever music piece in June. It was a &lt;a href=&quot;https://soundcloud.com/kushagra-gour/billie-jean-beatboxed&quot;&gt;beatbox on MJ&#39;s Billie Jean&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;july&quot;&gt;July &lt;a class=&quot;bookmark&quot; href=&quot;#july&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Our cow, Bahula, gave a cute baby boy this month. We named him &#39;Krishna&#39; as he was dark in color. But with time his name got reduced to just &#39;Kalu&#39; :D Yeah, that is what we call him now :)&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://kushagra.dev/images/2014/kalu.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;september&quot;&gt;September &lt;a class=&quot;bookmark&quot; href=&quot;#september&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Our complete engineering team went on a trip to the beautiful land of Nepal.. That place is amazing I must say. We did a small trek there and went on a bicycle sprint in Pokhra. Super fun-filled 4 days.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://kushagra.dev/images/2014/nepal1.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;Wingify sponsored JSFoo this year which is a JavaScript conference in Banglore, India. So a bunch of people from engineering went there to setup a booth for 2 days. It was my first time attending a conference from sponsor point of view. It was nice altogether. I also gave a small hiring pitch on stage there in &#39;Hindi&#39; which received an applause from the audience :P&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://kushagra.dev/images/2014/jsfoo.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;november&quot;&gt;November &lt;a class=&quot;bookmark&quot; href=&quot;#november&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;November was kickass! I spoke at a conference for the first time. And guess which conference it was - &lt;a href=&quot;http://2014.cssconf.asia/#speakers&quot;&gt;CSS Conf Asia&lt;/a&gt;! It was really a great experience to be speaking on CSS, at such a big conference, in front of such awesome people and along with such great co-speakers. &lt;a href=&quot;https://www.youtube.com/watch?v=FYcu-wWrNqo&quot;&gt;My talk&lt;/a&gt; went better than expected. People applauded and people laughed - that is all I wanted. Though I couldn&#39;t interact face to face much there :p I guess I&#39;m a digital geek.&lt;/p&gt;
&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/FYcu-wWrNqo&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;
![](/images/2014/cssconf2.jpg)
&lt;p&gt;Plus I went to Universal Studios, Singapore. The most amazing thing there was the transformers ride...can&#39;t explain it in words. Had lots of fun with my friends - Himanshu and Kushagra.&lt;/p&gt;
&lt;p&gt;I also started maintaining a travelouge in this trip: &lt;a href=&quot;http://travel.kushagragour.in/&quot;&gt;http://travel.kushagragour.in/&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&quot;december&quot;&gt;December &lt;a class=&quot;bookmark&quot; href=&quot;#december&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;On December&#39;s first day I finally started my Facebook page - &lt;a href=&quot;https://www.facebook.com/bematlab&quot;&gt;&lt;strong&gt;&amp;quot;Bematlab&amp;quot;&lt;/strong&gt;&lt;/a&gt;. A place where I do what I love - draw &amp;amp; crack PJs, together :D Here is a latest comic from there:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://kushagra.dev/images/2014/bematlab.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;I also released my &lt;a href=&quot;https://soundcloud.com/kushagra-gour/teri-yaaden-beatbox-jam&quot;&gt;second beatbox piece&lt;/a&gt;, this time a jam with a friend.&lt;/p&gt;
&lt;p&gt;In the end was Wingify&#39;s year end outing! We went to Krabi, Thailand. Water-water everywhere. Had nice time there.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://kushagra.dev/images/2014/krabi1.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;summary&quot;&gt;Summary &lt;a class=&quot;bookmark&quot; href=&quot;#summary&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;This year I travelled, drew stuff, attended a conference, spoke at a conference, created music, bought lots of toys, collected more flutes, worked on lots of side projects (couldn&#39;t release any though), spent more time with family and friend, learnt stuff. &lt;a href=&quot;https://github.com/chinchang/hint.css&quot;&gt;Hint.css&lt;/a&gt; reached 3000 stars on github.&lt;/p&gt;
&lt;h3 id=&quot;for-2015-(in-no-order)&quot;&gt;For 2015 (in no order) &lt;a class=&quot;bookmark&quot; href=&quot;#for-2015-(in-no-order)&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Create and release more amazing stuff&lt;/li&gt;
&lt;li&gt;Take &#39;Bematlab&#39; to next level&lt;/li&gt;
&lt;li&gt;Draw more&lt;/li&gt;
&lt;li&gt;Get better at Beatboxing&lt;/li&gt;
&lt;li&gt;Collaborate more with other artists and programmers&lt;/li&gt;
&lt;li&gt;Travel to more places&lt;/li&gt;
&lt;li&gt;Learn something new everyday&lt;/li&gt;
&lt;/ul&gt;
</content>
	</entry>
	
	<entry>
		<title>Build GIT - Learn GIT (P1)</title>
		<link href="https://kushagra.dev/blog/build-git-learn-git/"/>
		<updated>2014-01-20T00:00:00+00:00</updated>
		<id>https://kushagra.dev/blog/build-git-learn-git/</id>
		<content type="html">&lt;p&gt;If you are reading this post, you probably are using Git or want to use Git. I am a big fan of Git and also &lt;a href=&quot;https://teropa.info/blog/2013/11/03/make-your-own-angular-part-1-scopes-and-digest.html&quot;&gt;those posts&lt;/a&gt; where people &lt;a href=&quot;https://modernjavascript.blogspot.in/2013/08/promisesa-understanding-by-doing.html&quot;&gt;implement some piece of an existing technology&lt;/a&gt; in order to understand how their work in the core. Point being that if you have implemented something, you obviously know how it works, right? This is one such post written to spread my love for Git. &lt;strong&gt;Yes, we&#39;ll implement Git!&lt;/strong&gt;...in JavaScript.&lt;/p&gt;
&lt;p&gt;This part implements basics of the following concepts:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Repository.&lt;/li&gt;
&lt;li&gt;Commit.&lt;/li&gt;
&lt;li&gt;Commit chaining.&lt;/li&gt;
&lt;li&gt;Branch.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;All the code written is available in a Github repo:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/chinchang/build-git-learn-git/&quot; class=&quot;button button-big&quot;&gt;Github Repo&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;what-is-git%3F&quot;&gt;What is Git? &lt;a class=&quot;bookmark&quot; href=&quot;#what-is-git%3F&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;There is a very simple definition of Git at &lt;a href=&quot;https://www.kernel.org/pub/software/scm/git/docs/user-manual.html#repositories-and-branches&quot;&gt;kernel.org&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
Git is best thought of as a tool for storing the history of a collection of files.
&lt;div&gt;- &lt;a href=&quot;https://www.kernel.org/pub/software/scm/git/docs/user-manual.html#repositories-and-branches&quot;&gt;kernel.org&lt;/a&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;Yeah, that is essentially why one uses Git...to maintain a history of changes in a project.&lt;/p&gt;
&lt;h2 id=&quot;repository-(repo)&quot;&gt;Repository (repo) &lt;a class=&quot;bookmark&quot; href=&quot;#repository-(repo)&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;When you want to use Git in your project, you create something called a &lt;strong&gt;Repository&lt;/strong&gt;. Now we could refer the &lt;a href=&quot;https://www.kernel.org/pub/software/scm/git/docs/gitglossary.html&quot;&gt;Git documentation&lt;/a&gt; which defines a repo as follows:&lt;/p&gt;
&lt;blockquote&gt;
A collection of refs together with an object database containing all objects which are reachable from the refs, possibly accompanied by meta data from one or more porcelains. A repository can share an object database with other repositories via alternates mechanism.
&lt;div&gt;- &lt;a href=&quot;https://www.kernel.org/pub/software/scm/git/docs/gitglossary.html&quot;&gt;kernel.org&lt;/a&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;Well, that is too much to grasp, isn&#39;t it? And that is not what we are here for. So lets make things simple.&lt;br&gt;
Consider a Git repository as a collection of everything related to Git. So when you make a project folder a Git repo, Git basically creates some of its internal stuff there and encapsulates them into it. Having said that, lets make a simple class called &lt;code&gt;Git&lt;/code&gt; which will basically represent a repo.&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Git&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; name&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Repo name&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Great! Now making a repo simply requires us to instantiate the &lt;code&gt;Git&lt;/code&gt; class passing in the name of the repo:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; repo &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Git&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;my-repo&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class=&quot;token comment&quot;&gt;// Actual command:&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token comment&quot;&gt;// &gt; git init&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;commit&quot;&gt;Commit &lt;a class=&quot;bookmark&quot; href=&quot;#commit&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Next concept one needs to know about is a &lt;strong&gt;Commit&lt;/strong&gt;. In very simple terms, a commit is a snapshot of your project&#39;s contents. It is these commits which when chained together form the history of your project.&lt;/p&gt;
&lt;p&gt;From the looks of it, a simple &lt;code&gt;Commit&lt;/code&gt; class would have and &lt;em&gt;id&lt;/em&gt; to reference it and a &lt;em&gt;change&lt;/em&gt; containing the snapshot of change made. Understanding how a change is actually stored is beyond the scope of this implementation. So lets drop the &lt;em&gt;change&lt;/em&gt; part and assume that every commit has the change with it:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Commit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;id &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; id&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token comment&quot;&gt;// Assume that &#39;this&#39; has a &#39;change&#39; property too.&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In Git, when you commit after making some changes, you can give it a message which describes the change you are commiting. This is called the &lt;em&gt;commit message&lt;/em&gt; which we&#39;ll add to our &lt;code&gt;Commit&lt;/code&gt; class:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Commit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;id&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; message&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;  &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;id &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; id&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;mark class=&quot;highlight-line highlight-line-active&quot;&gt;  &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;message &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; message&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/mark&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Lets add the ability on our &lt;code&gt;Git&lt;/code&gt; class to create a commit or commit (verb):&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;Git&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;prototype&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;commit&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; commit &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Commit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; commit&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We add a function called &lt;code&gt;commit&lt;/code&gt; on the &lt;code&gt;Git&lt;/code&gt; prototype. It accepts a string message, creates a new &lt;strong&gt;Commit&lt;/strong&gt; instance and returns it. Note that we are not passing in anything yet in the &lt;code&gt;Commit&lt;/code&gt; constructor. We need an id to give to the new commit. We&#39;ll make the &lt;code&gt;Git&lt;/code&gt; class keep track of the commit ids by keeping a counter called &lt;code&gt;lastCommitId&lt;/code&gt; with it:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Git&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;lastCommitId &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note: In actual Git, commit id is a 40-hexdigit number also called as &amp;quot;SHA-1 id&amp;quot;. But for keeping things simple we are using integers here.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;commit&lt;/code&gt; function can now pass a new id (incremented) along with the message in the constructor:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;Git&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;prototype&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;commit&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;mark class=&quot;highlight-line highlight-line-active&quot;&gt;  &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; commit &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Commit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;lastCommitId&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; message&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/mark&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; commit&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We can now commit anytime like so:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;repo&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;commit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Make commit work&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class=&quot;token comment&quot;&gt;// Actual command:&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token comment&quot;&gt;// &gt; git commit -m &quot;Make commit work&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;match-your-code&quot;&gt;Match your code &lt;a class=&quot;bookmark&quot; href=&quot;#match-your-code&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;At this point you should have your implementation that looks like &lt;a href=&quot;https://github.com/chinchang/build-git-learn-git/blob/ffb353b30e5eee92190e42a989c14ca0a74bb65a/git-part1.js&quot;&gt;the one here&lt;/a&gt;. I have wrapped the whole code in an Immediately invoking function expression (IIFE) and exposed the &lt;code&gt;Git&lt;/code&gt; class manually to keep global space clean.&lt;/p&gt;
&lt;h2 id=&quot;commit-history---chaining-the-commits&quot;&gt;Commit history - chaining the commits &lt;a class=&quot;bookmark&quot; href=&quot;#commit-history---chaining-the-commits&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Git has a command called &lt;code&gt;log&lt;/code&gt; which shows the commit history in reverse chronological order, i.e. first the lastest commit followed by previous ones.&lt;/p&gt;
&lt;p&gt;Lets implement this &lt;code&gt;log&lt;/code&gt; command as a method on our &lt;code&gt;Git&lt;/code&gt; class. Our log function will return an array of commits in reverse chronological order.&lt;/p&gt;
&lt;p&gt;Here is a simple test which should pass for our log function:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Git.log() test&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; repo &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Git&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;test&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;repo&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;commit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Initial commit&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;repo&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;commit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Change 1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; log &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; repo&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;assert&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;log&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;length &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Should have 2 commits.&lt;/span&gt;&lt;br&gt;console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;assert&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;log&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; log&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;id &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Commit 1 should be first.&lt;/span&gt;&lt;br&gt;console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;assert&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;log&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; log&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;id &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// And then Commit 0.&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Onto the implementation.&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;Git&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;prototype&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;log&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; history &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// array of commits in reverse order.&lt;/span&gt;&lt;br&gt;&lt;br&gt;  &lt;span class=&quot;token comment&quot;&gt;// 1. Start from last commit&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token comment&quot;&gt;// 2. Go back tracing to the first commit&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token comment&quot;&gt;// 3. Push in `history`&lt;/span&gt;&lt;br&gt;&lt;br&gt;  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; history&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;log&lt;/code&gt; function has only pseudo code right now in form of comments which tell us the logic of the function. To implement such logic 2 requirements arise:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;We need to know the last commit.&lt;/li&gt;
&lt;li&gt;Every commit should somehow know which commit was made before it.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;We have a failing test case right now:&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;webmaker-embed&quot; href=&quot;https://kushagra.dev/js/bglg-1.js&quot;&gt;Build Git - Learn Git (part 1)&lt;/a&gt;&lt;/p&gt;
&lt;script src=&quot;https://kushagra.dev/js/webmaker-embed.js&quot;&gt;&lt;/script&gt;
&lt;p&gt;Lets take up the first requirement: Knowing the last commit.&lt;/p&gt;
&lt;p&gt;Git has something called a &lt;strong&gt;HEAD&lt;/strong&gt;. In actual Git it is simply a pointer to your current branch. But since we have not covered branches yet, we&#39;ll relax the definition here...temporarily.&lt;/p&gt;
&lt;p&gt;What we&#39;ll do is add a property called &lt;code&gt;HEAD&lt;/code&gt; in the &lt;code&gt;Git&lt;/code&gt; class which will reference the last commit&#39;s &lt;code&gt;Commit&lt;/code&gt; object:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Git&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;  &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; name&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Repo name&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;  &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;lastCommitId &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Keep track of last commit id.&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;mark class=&quot;highlight-line highlight-line-active&quot;&gt;  &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;HEAD&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Reference to last Commit.&lt;/span&gt;&lt;/mark&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;HEAD&lt;/code&gt; will be updated everytime a commit is made i.e. in the &lt;code&gt;commit()&lt;/code&gt; function.&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;Git&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;prototype&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;commit&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;  &lt;span class=&quot;token comment&quot;&gt;// Increment last commit id and pass into new commit.&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;  &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; commit &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Commit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;lastCommitId&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; message&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;  &lt;span class=&quot;token comment&quot;&gt;// Update HEAD and current branch.&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;mark class=&quot;highlight-line highlight-line-active&quot;&gt;  &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;HEAD&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; commit&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/mark&gt;&lt;br&gt;&lt;mark class=&quot;highlight-line highlight-line-active&quot;&gt;&lt;/mark&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; commit&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Simple! Now we always know which was the last commit made.&lt;/p&gt;
&lt;p&gt;Getting on the 2nd requirement: Every commit should somehow know which commit was made before it. This brings up the concept of &lt;strong&gt;parent&lt;/strong&gt; in Git. Commits in Git are kept together in form a data structure called &lt;a href=&quot;https://en.wikipedia.org/wiki/Linked_list&quot;&gt;&lt;strong&gt;Linked Lists&lt;/strong&gt;&lt;/a&gt;. Simply put, in a Linked List every item stores with itself a pointer to its parent item. This is done so that from every item, we can reach its parent item and keep following the pointers to get an ordered list. This diagram from Wikipedia will will make more sense:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://upload.wikimedia.org/wikipedia/commons/6/6d/Singly-linked-list.svg&quot; alt=&quot;Linked list&quot;&gt;&lt;/p&gt;
&lt;p&gt;For this, we add a property called &lt;code&gt;parent&lt;/code&gt; in the &lt;code&gt;Commit&lt;/code&gt; class which will reference its parent commit object:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Commit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;id&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; parent&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; message&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;  &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;id &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; id&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;mark class=&quot;highlight-line highlight-line-active&quot;&gt;  &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;parent &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; parent&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/mark&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;  &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;message &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; message&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The parent commit also needs to be passed into the &lt;code&gt;Commit&lt;/code&gt; constructor. If you think, for a new commit what is the parent/previous commit? Yes, the current commit or the &lt;code&gt;HEAD&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;Git&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;prototype&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;commit&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;	&lt;span class=&quot;token comment&quot;&gt;// Increment last commit id and pass into new commit.&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;mark class=&quot;highlight-line highlight-line-active&quot;&gt;	&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; commit &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Commit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;lastCommitId&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;HEAD&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; message&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/mark&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Having our requirements in place, lets implement the &lt;code&gt;log()&lt;/code&gt; function:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;Git&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;prototype&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;log&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token comment&quot;&gt;// Start from HEAD&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; commit &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;HEAD&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;    history &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;br&gt;  &lt;span class=&quot;token keyword&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;commit&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;    history&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;commit&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token comment&quot;&gt;// Keep following the parent&lt;/span&gt;&lt;br&gt;    commit &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; commit&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;parent&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;br&gt;  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; history&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class=&quot;token comment&quot;&gt;// Can be used as repo.log();&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token comment&quot;&gt;// Actual command:&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token comment&quot;&gt;// &gt; git log&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Our test should pass now:&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;webmaker-embed&quot; href=&quot;https://kushagra.dev/js/bglg-2.js&quot;&gt;Build Git - Learn Git (part 1)&lt;/a&gt;&lt;/p&gt;
&lt;script src=&quot;https://kushagra.dev/js/webmaker-embed.js&quot;&gt;&lt;/script&gt;
&lt;h2 id=&quot;match-your-code-2&quot;&gt;Match your code &lt;a class=&quot;bookmark&quot; href=&quot;#match-your-code-2&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;At this point our code looks &lt;a href=&quot;https://github.com/chinchang/build-git-learn-git/blob/116871ab54376e489af538fa1ba1a7e04359e704/git-part1.js&quot;&gt;like this&lt;/a&gt;.&lt;br&gt;
Next up is Branches!&lt;/p&gt;
&lt;h2 id=&quot;branches&quot;&gt;Branches &lt;a class=&quot;bookmark&quot; href=&quot;#branches&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Hurray, we have reached at the most interesting &amp;amp; powerful feature of Git: Branches. So what is a Branch and what is it used for?&lt;/p&gt;
&lt;p&gt;Imagine this scenario, you are working on a project making commits now and then. At some point may be you or one of your teammate wants to experiment something on your current work, say a different algorithm. You could surely keep making those experimental commits, but remember this was your experiment and hence not guaranteed to be kept in the main project. This way you polluted your main project.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Branches to the rescue&lt;/strong&gt;. What you need to do here is branch out from your current line of commits so that the commits you make do not pollute the main line of development.&lt;/p&gt;
&lt;p&gt;To quote the definition at &lt;a href=&quot;http://kernel.org/&quot;&gt;kernel.org&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
A &quot;branch&quot; is an active line of development. The most recent commit on a branch is referred to as the tip of that branch. The tip of the branch is referenced by a branch head, which moves forward as additional development is done on the branch. A single git repository can track an arbitrary number of branches
&lt;/blockquote&gt;
&lt;p&gt;Lets understand what a branch is. A branch is nothing but a mere pointer to some commit. Seriously, that is it. That is what makes branches in Git so lightweight and use-n-throw type. You may say &lt;code&gt;HEAD&lt;/code&gt; was exactly this. You are right. The only difference being that &lt;code&gt;HEAD&lt;/code&gt; is just one (because at a given time you are only on a single commit) but branches can be many, each pointing to a commit.&lt;/p&gt;
&lt;p&gt;The &lt;strong&gt;&#39;master&#39; branch&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Each Git repo when initialized comes with a default branch called &lt;em&gt;master&lt;/em&gt;. Lets understand branches through some diagrams from &lt;a href=&quot;https://git-scm.com/book/en/Git-Branching-What-a-Branch-Is&quot;&gt;git-scm.com&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;You create a new repository and make some commits:&lt;br&gt;
&lt;img src=&quot;https://git-scm.com/figures/18333fig0303-tn.png&quot; alt=&quot;Just master&quot;&gt;&lt;/p&gt;
&lt;p&gt;Then you create a new branch called &lt;em&gt;testing&lt;/em&gt;:&lt;br&gt;
&lt;img src=&quot;https://git-scm.com/figures/18333fig0304-tn.png&quot; alt=&quot;New branch &#39;testing&#39;&quot;&gt;&lt;/p&gt;
&lt;p&gt;Nothing much, just a new pointer called &lt;em&gt;testing&lt;/em&gt; to the lastest commit.&lt;br&gt;
How does Git know which branch you are on? Here comes the &lt;code&gt;HEAD&lt;/code&gt;. &lt;code&gt;HEAD&lt;/code&gt; points to the current branch:&lt;br&gt;
&lt;img src=&quot;https://git-scm.com/figures/18333fig0306-tn.png&quot; alt=&quot;HEAD pointing &#39;testing&#39;&quot;&gt;&lt;/p&gt;
&lt;p&gt;Now comes interesting part. Being on &lt;em&gt;testing&lt;/em&gt; branch you make a commit. Notice what happens:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://git-scm.com/figures/18333fig0307-tn.png&quot; alt=&quot;&#39;testing&#39; moves&quot;&gt;&lt;/p&gt;
&lt;p&gt;From now on, the &lt;em&gt;testing&lt;/em&gt; branch/pointer only moves and not &lt;em&gt;master&lt;/em&gt;. Looking at the above diagram and keeping our &lt;code&gt;log()&lt;/code&gt; algorithm in mind, lets see what history would each branch return.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;testing branch&lt;/em&gt;: Currently we are on &lt;em&gt;testing&lt;/em&gt; branch. Moving backwards from &lt;code&gt;HEAD&lt;/code&gt;(commit &lt;em&gt;c2b9e&lt;/em&gt;) and tracking the visible linkages, we get the history as:&lt;br&gt;
|c2b9e| -&amp;gt; |f30ab| -&amp;gt; |34ac2| -&amp;gt; |98ca9|&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;master branch&lt;/em&gt;: If we switch to &lt;em&gt;master&lt;/em&gt; branch, we would have a state as follows:&lt;br&gt;
&lt;img src=&quot;https://git-scm.com/figures/18333fig0308-tn.png&quot; alt=&quot;Back to master&quot;&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now tracing back from &lt;code&gt;HEAD&lt;/code&gt; gives us the history as:&lt;br&gt;
|f30ab| -&amp;gt; |34ac2| -&amp;gt; |98ca9|&lt;/p&gt;
&lt;p&gt;You see what we acheived? We were able to make some experimental changes/commits without polluting the main branch (master) history using branches. Isn&#39;t that cool!!!&lt;/p&gt;
&lt;p&gt;Enough said, lets code. First lets make a new class for a branch. A branch, as we saw, has a name and a reference to some commit:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Branch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;name&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; commit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; name&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;commit &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; commit&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;By default, Git gives you a branch called &lt;em&gt;master&lt;/em&gt;. Lets create one:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Git&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;  &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; name&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Repo name&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;  &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;lastCommitId &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Keep track of last commit id.&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;  &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;HEAD&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Reference to last Commit.&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;mark class=&quot;highlight-line highlight-line-active&quot;&gt;  &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; master &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Branch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;master&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// null is passed as we don&#39;t have any commit yet.&lt;/span&gt;&lt;/mark&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Remember we changed the meaning of &lt;code&gt;HEAD&lt;/code&gt; in the beginning as we were still to cover branches? Its time we make it do what its meant for i.e. reference the current branch (&lt;em&gt;master&lt;/em&gt; when repo is created):&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Git&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;  &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; name&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Repo name&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;  &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;lastCommitId &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Keep track of last commit id.&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;  &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; master &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Branch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;master&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// null is passed as we don&#39;t have any commit yet.&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;mark class=&quot;highlight-line highlight-line-active&quot;&gt;  &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;HEAD&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; master&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// HEAD points to current branch.&lt;/span&gt;&lt;/mark&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This will require certain changes in the &lt;code&gt;commit()&lt;/code&gt; function as &lt;code&gt;HEAD&lt;/code&gt; is no longer referencing a &lt;code&gt;Commit&lt;/code&gt; but a &lt;code&gt;Branch&lt;/code&gt; now:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;Git&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;prototype&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;commit&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;  &lt;span class=&quot;token comment&quot;&gt;// Increment last commit id and pass into new commit.&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;  &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; commit &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Commit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;lastCommitId&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;HEAD&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;commit&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; message&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;mark class=&quot;highlight-line highlight-line-active&quot;&gt;&lt;/mark&gt;&lt;br&gt;&lt;mark class=&quot;highlight-line highlight-line-active&quot;&gt;  &lt;span class=&quot;token comment&quot;&gt;// Update the current branch pointer to new commit.&lt;/span&gt;&lt;/mark&gt;&lt;br&gt;&lt;mark class=&quot;highlight-line highlight-line-active&quot;&gt;  &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;HEAD&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;commit &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; commit&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/mark&gt;&lt;br&gt;&lt;mark class=&quot;highlight-line highlight-line-active&quot;&gt;&lt;/mark&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; commit&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And a minor change in &lt;code&gt;log&lt;/code&gt; function. We start from &lt;code&gt;HEAD.commit&lt;/code&gt; now:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;Git&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;prototype&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;log&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;mark class=&quot;highlight-line highlight-line-active&quot;&gt;	&lt;span class=&quot;token comment&quot;&gt;// Start from HEAD commit&lt;/span&gt;&lt;/mark&gt;&lt;br&gt;&lt;mark class=&quot;highlight-line highlight-line-active&quot;&gt;	&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; commit &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;HEAD&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;commit&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;/mark&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Everything works as before. To really verify what we deduced in theory by calculating history of those 2 branches above, we need one final method on our &lt;code&gt;Git&lt;/code&gt; class: &lt;strong&gt;checkout&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;To begin with, consider &lt;em&gt;checkout&lt;/em&gt; as switching branches. By default we are on &lt;em&gt;master&lt;/em&gt; branch. If I do something like &lt;code&gt;repo.checkout(&#39;testing&#39;)&lt;/code&gt;, I should jump to &lt;em&gt;testing&lt;/em&gt; branch...provided it is already created. But if its not created already, a new branch with that name should be created. Lets write a test for this method.&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Git.checkout() test&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; repo &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Git&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;test&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;repo&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;commit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Initial commit&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;br&gt;console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;assert&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;repo&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;HEAD&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;master&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Should be on master branch.&lt;/span&gt;&lt;br&gt;repo&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;checkout&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;testing&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;assert&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;repo&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;HEAD&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;testing&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Should be on new testing branch.&lt;/span&gt;&lt;br&gt;repo&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;checkout&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;master&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;assert&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;repo&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;HEAD&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;master&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Should be on master branch.&lt;/span&gt;&lt;br&gt;repo&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;checkout&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;testing&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;assert&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;repo&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;HEAD&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;testing&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Should be on testing branch again.&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This test fails right now as we don&#39;t have a &lt;code&gt;checkout&lt;/code&gt; method yet. Lets write one:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;Git&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;prototype&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;checkout&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;branchName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token comment&quot;&gt;// Check if a branch already exists with name = branchName&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The comment in above code requires that the repo maintains a list of all created branches. So we put a property called &lt;code&gt;branches&lt;/code&gt; on &lt;code&gt;Git&lt;/code&gt; class with initially having only &lt;em&gt;master&lt;/em&gt; in it:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Git&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;  &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; name&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Repo name&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;  &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;lastCommitId &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Keep track of last commit id.&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;mark class=&quot;highlight-line highlight-line-active&quot;&gt;  &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;branches &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// List of all branches.&lt;/span&gt;&lt;/mark&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;  &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; master &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Branch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;master&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// No commit yet, so null is passed.&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;mark class=&quot;highlight-line highlight-line-active&quot;&gt;  &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;branches&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;master&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Store master branch.&lt;/span&gt;&lt;/mark&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;  &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;HEAD&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; master&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// HEAD points to current branch.&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Continuing with the &lt;code&gt;checkout&lt;/code&gt; function now. Taking first case when we find an existing branch, all we need to do is point the &lt;code&gt;HEAD&lt;/code&gt;, the current branch pointer, to that existing branch:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;Git&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;prototype&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;checkout&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;branchName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token comment&quot;&gt;// Loop through all branches and see if we have a branch&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token comment&quot;&gt;// called `branchName`.&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;branches&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;length&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i&lt;span class=&quot;token operator&quot;&gt;--&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;branches&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; branchName&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token comment&quot;&gt;// We found an existing branch&lt;/span&gt;&lt;br&gt;      console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Switched to existing branch: &quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; branchName&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;HEAD&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;branches&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;br&gt;  &lt;span class=&quot;token comment&quot;&gt;// We reach here when no matching branch is found.&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I returned &lt;code&gt;this&lt;/code&gt; from that method so that methods can be chanined. Next, incase we don&#39;t find a branch with the passed name, we create one just like we did for &lt;em&gt;master&lt;/em&gt;:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;Git&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;prototype&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;checkout&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;branchName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;  &lt;span class=&quot;token comment&quot;&gt;// Loop through all branches and see if we have a branch&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;  &lt;span class=&quot;token comment&quot;&gt;// called `branchName`.&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;  &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;branches&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;length&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i&lt;span class=&quot;token operator&quot;&gt;--&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;branches&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; branchName&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;      &lt;span class=&quot;token comment&quot;&gt;// We found an existing branch&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;      console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Switched to existing branch: &quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; branchName&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;      &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;HEAD&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;branches&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;mark class=&quot;highlight-line highlight-line-active&quot;&gt;  &lt;span class=&quot;token comment&quot;&gt;// If branch was not found, create a new one.&lt;/span&gt;&lt;/mark&gt;&lt;br&gt;&lt;mark class=&quot;highlight-line highlight-line-active&quot;&gt;  &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; newBranch &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Branch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;branchName&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;HEAD&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;commit&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/mark&gt;&lt;br&gt;&lt;mark class=&quot;highlight-line highlight-line-active&quot;&gt;  &lt;span class=&quot;token comment&quot;&gt;// Store branch.&lt;/span&gt;&lt;/mark&gt;&lt;br&gt;&lt;mark class=&quot;highlight-line highlight-line-active&quot;&gt;  &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;branches&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;newBranch&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/mark&gt;&lt;br&gt;&lt;mark class=&quot;highlight-line highlight-line-active&quot;&gt;  &lt;span class=&quot;token comment&quot;&gt;// Update HEAD&lt;/span&gt;&lt;/mark&gt;&lt;br&gt;&lt;mark class=&quot;highlight-line highlight-line-active&quot;&gt;  &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;HEAD&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; newBranch&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/mark&gt;&lt;br&gt;&lt;mark class=&quot;highlight-line highlight-line-active&quot;&gt;&lt;/mark&gt;&lt;br&gt;&lt;mark class=&quot;highlight-line highlight-line-active&quot;&gt;  console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Switched to new branch: &quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; branchName&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/mark&gt;&lt;br&gt;&lt;mark class=&quot;highlight-line highlight-line-active&quot;&gt;  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/mark&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Actual command:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// &gt; git checkout existing-branch&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// &gt; git checkout -b new-branch&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Eureka! Now our &lt;code&gt;checkout&lt;/code&gt; tests pass :)&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;webmaker-embed&quot; href=&quot;https://kushagra.dev/js/bglg-3.js&quot;&gt;Build Git - Learn Git (part 1)&lt;/a&gt;&lt;/p&gt;
&lt;script src=&quot;https://kushagra.dev/js/webmaker-embed.js&quot;&gt;&lt;/script&gt;
&lt;p&gt;Now the grand moment for which we created the &lt;code&gt;checkout&lt;/code&gt; function. Verifying the awesomeness of branches through the theory we saw earlier. We&#39;ll write one final test to verify the same:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;3. Branches test&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; repo &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Git&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;test&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;repo&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;commit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Initial commit&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;repo&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;commit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Change 1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class=&quot;token comment&quot;&gt;// Maps the array of commits into a string of commit ids.&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token comment&quot;&gt;// For [C2, C1,C3], it returns &quot;2-1-0&quot;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;historyToIdMapper&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;history&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; ids &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; history&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;commit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; commit&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;id&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; ids&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;-&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;br&gt;console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;assert&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;historyToIdMapper&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;repo&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;1-0&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Should show 2 commits.&lt;/span&gt;&lt;br&gt;&lt;br&gt;repo&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;checkout&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;testing&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;repo&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;commit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Change 3&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;br&gt;console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;assert&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;historyToIdMapper&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;repo&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;2-1-0&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Should show 3 commits.&lt;/span&gt;&lt;br&gt;&lt;br&gt;repo&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;checkout&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;master&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;assert&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;historyToIdMapper&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;repo&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;1-0&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Should show 2 commits. Master unpolluted.&lt;/span&gt;&lt;br&gt;&lt;br&gt;repo&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;commit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Change 3&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;assert&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;historyToIdMapper&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;repo&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;3-1-0&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Continue on master with 4th commit.&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This test basically represents the diagrams we saw earlier explaining the working of branches. Lets see if our implementation is inline with the theory:&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;webmaker-embed&quot; href=&quot;https://kushagra.dev/js/bglg-4.js&quot;&gt;Build Git - Learn Git (part 1)&lt;/a&gt;&lt;/p&gt;
&lt;script src=&quot;https://kushagra.dev/js/webmaker-embed.js&quot;&gt;&lt;/script&gt;
&lt;p&gt;Wonderful! Our implementation is right. The final code for this part can be found in GIT repo: &lt;code&gt;git-part1.js&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/chinchang/build-git-learn-git/&quot; class=&quot;button button-big&quot;&gt;Github Repo&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;whats-next%3F&quot;&gt;Whats next? &lt;a class=&quot;bookmark&quot; href=&quot;#whats-next%3F&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Next I plan to implement concepts like merging (Fast-forward and 3-way-merge) and rebasing of branches.&lt;/p&gt;
&lt;p&gt;I had a lot of fun writing this and hope you enjoyed it too. If you did, share the Git love with others.&lt;/p&gt;
&lt;p&gt;Till next time, bbye.&lt;/p&gt;
&lt;h2 id=&quot;references&quot;&gt;References &lt;a class=&quot;bookmark&quot; href=&quot;#references&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://git-scm.com/book/en/&quot;&gt;https://git-scm.com/book/en/&lt;/a&gt; (Where I learned Git from)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.kernel.org/pub/software/scm/git/docs/gitglossary.html&quot;&gt;https://www.kernel.org/pub/software/scm/git/docs/gitglossary.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;Update: Join the &lt;a href=&quot;https://news.ycombinator.com/item?id=7089380&quot;&gt;discussion on HN&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Creating a 3D Cube Image Gallery</title>
		<link href="https://kushagra.dev/blog/creating-a-3d-cube-image-gallery/"/>
		<updated>2013-08-06T00:00:00+00:00</updated>
		<id>https://kushagra.dev/blog/creating-a-3d-cube-image-gallery/</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>Getting started with Chart.js</title>
		<link href="https://kushagra.dev/blog/getting-started-with-chartjs/"/>
		<updated>2013-06-02T00:00:00+00:00</updated>
		<id>https://kushagra.dev/blog/getting-started-with-chartjs/</id>
		<content type="html">&lt;p&gt;I had been recording data from Alexa since &lt;a href=&quot;https://kushagra.dev/lab/hint/&quot;&gt;Hint.css&lt;/a&gt; went live just to track its popularity and reach. Nothing too complex, just maintained a JSON file and added new object in an array for each data point. I had been thinking if I could visualize this data, just for fun. Did try &lt;a href=&quot;http://d3js.org/&quot;&gt;d3.js&lt;/a&gt;. Though its a really awesome library for data visualization and all, it surely has some learning curve before you can have something out of it.&lt;/p&gt;
&lt;p&gt;Then today I thought, lets try &lt;a href=&quot;http://www.chartjs.org/&quot;&gt;chart.js&lt;/a&gt; which had been on HN sometime back. And I must say, its so easy to get started with it and that is probably the reason I am writing this post for anyone who wants to do some chart work really really quick.&lt;/p&gt;
&lt;p&gt;Here is what I did.&lt;/p&gt;
&lt;p&gt;This is the sample of data I had which I wanted to visualize:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token literal-property property&quot;&gt;date&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;15-12-2012&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token literal-property property&quot;&gt;rank&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1896594&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token string-property property&quot;&gt;&quot;sites-linking&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;50&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token literal-property property&quot;&gt;date&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;17-12-2012&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token literal-property property&quot;&gt;rank&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1895639&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token string-property property&quot;&gt;&quot;sites-linking&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;50&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token literal-property property&quot;&gt;date&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;09-02-2013&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token literal-property property&quot;&gt;rank&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;413592&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token string-property property&quot;&gt;&quot;sites-linking&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;47&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token literal-property property&quot;&gt;date&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;12-02-2013&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token literal-property property&quot;&gt;rank&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;327643&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token string-property property&quot;&gt;&quot;sites-linking&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;55&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token literal-property property&quot;&gt;date&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;14-02-2013&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token literal-property property&quot;&gt;rank&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;313141&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token string-property property&quot;&gt;&quot;sites-linking&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;55&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token literal-property property&quot;&gt;date&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;15-02-2013&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token literal-property property&quot;&gt;rank&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;292197&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token string-property property&quot;&gt;&quot;sites-linking&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;55&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token literal-property property&quot;&gt;date&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;25-02-2013&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token literal-property property&quot;&gt;rank&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;242294&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token string-property property&quot;&gt;&quot;sites-linking&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;88&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token literal-property property&quot;&gt;date&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;26-02-2013&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token literal-property property&quot;&gt;rank&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;234704&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token string-property property&quot;&gt;&quot;sites-linking&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;88&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token literal-property property&quot;&gt;date&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;02-03-2013&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token literal-property property&quot;&gt;rank&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;213869&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token string-property property&quot;&gt;&quot;sites-linking&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;First thing I did was clone the &lt;a href=&quot;https://github.com/nnnick/Chart.js&quot;&gt;github repo for Chart.js&lt;/a&gt;:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; clone git://github.com/nnnick/Chart.js.git&lt;br&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;cd&lt;/span&gt; Chart.js&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the repo, you&#39;ll find a &lt;code&gt;samples/&lt;/code&gt; folder which has some examples of using Chart.js. I needed a line chart, so I opened &lt;code&gt;samples/line.html&lt;/code&gt; in Sublime and started reading the code. It was such little code which created a sweet little line graph with subtle animations.&lt;/p&gt;
&lt;p&gt;This was the old JS there:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; lineChartData &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token literal-property property&quot;&gt;labels&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;January&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;February&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;March&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;April&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;May&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;June&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;July&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token literal-property property&quot;&gt;datasets&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token literal-property property&quot;&gt;fillColor&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;rgba(220,220,220,0.5)&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token literal-property property&quot;&gt;strokeColor&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;rgba(220,220,220,1)&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token literal-property property&quot;&gt;pointColor&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;rgba(220,220,220,1)&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token literal-property property&quot;&gt;pointStrokeColor&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;#fff&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token literal-property property&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;65&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;59&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;90&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;81&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;56&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;55&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;40&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token literal-property property&quot;&gt;fillColor&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;rgba(151,187,205,0.5)&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token literal-property property&quot;&gt;strokeColor&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;rgba(151,187,205,1)&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token literal-property property&quot;&gt;pointColor&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;rgba(151,187,205,1)&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token literal-property property&quot;&gt;pointStrokeColor&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;#fff&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token literal-property property&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;28&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;48&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;40&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;19&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;96&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;27&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; myLine &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Chart&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getElementById&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;canvas&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getContext&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;2d&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Line&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;br&gt;  lineChartData&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next what I did was get my data into that script. So I simply made a variable and assigned my object to it. Also to begin with, I removed one of the data set entry from the array so I can visualize just the &lt;code&gt;rank&lt;/code&gt; key:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; myData &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token literal-property property&quot;&gt;date&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;15-12-2012&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token literal-property property&quot;&gt;rank&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1896594&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token string-property property&quot;&gt;&quot;sites-linking&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;50&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token literal-property property&quot;&gt;date&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;17-12-2012&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token literal-property property&quot;&gt;rank&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1895639&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token string-property property&quot;&gt;&quot;sites-linking&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;50&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token literal-property property&quot;&gt;date&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;09-02-2013&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token literal-property property&quot;&gt;rank&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;413592&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token string-property property&quot;&gt;&quot;sites-linking&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;47&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token literal-property property&quot;&gt;date&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;12-02-2013&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token literal-property property&quot;&gt;rank&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;327643&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token string-property property&quot;&gt;&quot;sites-linking&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;55&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token literal-property property&quot;&gt;date&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;14-02-2013&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token literal-property property&quot;&gt;rank&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;313141&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token string-property property&quot;&gt;&quot;sites-linking&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;55&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token literal-property property&quot;&gt;date&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;15-02-2013&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token literal-property property&quot;&gt;rank&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;292197&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token string-property property&quot;&gt;&quot;sites-linking&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;55&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token literal-property property&quot;&gt;date&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;25-02-2013&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token literal-property property&quot;&gt;rank&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;242294&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token string-property property&quot;&gt;&quot;sites-linking&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;88&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token literal-property property&quot;&gt;date&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;26-02-2013&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token literal-property property&quot;&gt;rank&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;234704&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token string-property property&quot;&gt;&quot;sites-linking&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;88&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token literal-property property&quot;&gt;date&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;02-03-2013&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token literal-property property&quot;&gt;rank&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;213869&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token string-property property&quot;&gt;&quot;sites-linking&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;  lineChartData &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token literal-property property&quot;&gt;labels&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;January&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;February&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;March&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;April&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;May&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;June&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;July&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token literal-property property&quot;&gt;datasets&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;        &lt;span class=&quot;token literal-property property&quot;&gt;fillColor&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;rgba(220,220,220,0.5)&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;        &lt;span class=&quot;token literal-property property&quot;&gt;strokeColor&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;rgba(220,220,220,1)&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;        &lt;span class=&quot;token literal-property property&quot;&gt;pointColor&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;rgba(220,220,220,1)&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;        &lt;span class=&quot;token literal-property property&quot;&gt;pointStrokeColor&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;#fff&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;        &lt;span class=&quot;token literal-property property&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;65&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;59&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;90&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;81&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;56&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;55&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;40&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you note in the above code where &lt;code&gt;lineChartData&lt;/code&gt; is being created, values corresponding to the data we want to visualize are arrays. To be specific, its the &lt;code&gt;label&lt;/code&gt; and &lt;code&gt;data&lt;/code&gt; keys in that object. So we need to convert our data into arrays which could be assigned to those 2 keys.&lt;/p&gt;
&lt;p&gt;For that I made a small function called &lt;code&gt;mapProperty&lt;/code&gt; (inspired from Emberjs) which basically maps the array with only the passed property values.&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;prototype&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;mapProperty&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;property&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; obj&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;property&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class=&quot;token comment&quot;&gt;// Example: myData.mapProperty(&#39;rank&#39;) to get an array of all ranks&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now all I had to do is use the above function to map my data on appropriate key and assign in the &lt;code&gt;lineChartData&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;lineChartData &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token literal-property property&quot;&gt;labels&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; myData&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;mapProperty&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;date&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token literal-property property&quot;&gt;datasets&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token literal-property property&quot;&gt;fillColor&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;rgba(220,220,220,0.5)&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token literal-property property&quot;&gt;strokeColor&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;rgba(220,220,220,1)&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token literal-property property&quot;&gt;pointColor&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;rgba(220,220,220,1)&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token literal-property property&quot;&gt;pointStrokeColor&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;#fff&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token literal-property property&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; myData&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;mapProperty&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;rank&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I refreshed the page in browser and voila! My data was converted into a beautiful chart. Wasn&#39;t that dead simple?&lt;/p&gt;
&lt;img src=&quot;https://kushagra.dev/images/2013/rank-chart.png&quot; alt=&quot;Alexa rank visualized&quot; title=&quot;Alexa rank chart&quot;&gt;
&lt;p&gt;I added another dataset entry for the &lt;code&gt;sites-linking&lt;/code&gt;, but &lt;code&gt;rank&lt;/code&gt; values being much larger than &lt;code&gt;sites-linking&lt;/code&gt; key, it made the &lt;code&gt;sites-linking&lt;/code&gt; line almost invisible.&lt;/p&gt;
&lt;p&gt;To sum up,&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Good&lt;/strong&gt;: easy to use, fast, nice animations, multiple chart types&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Bad&lt;/strong&gt;: no tooltips, no interactivity&lt;/p&gt;
&lt;p&gt;Its still a new library and has a long way to go. It has been receiving contributions from Open Source developers and I think it will evolve into a cool visualization library soon.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/nnnick/Chart.js&quot;&gt;Hack it here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Cheers :)&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Year&#39;s first side project- Hint.css</title>
		<link href="https://kushagra.dev/blog/years-first-side-project-hint/"/>
		<updated>2013-02-17T00:00:00+00:00</updated>
		<id>https://kushagra.dev/blog/years-first-side-project-hint/</id>
		<content type="html">&lt;p&gt;Hey everyone!&lt;/p&gt;
&lt;p&gt;It has been around a month and a half since we jumped into 2013. And this is my first post of the year. I released a side project called &lt;a href=&quot;http://kushagragour.in/lab/hint/&quot;&gt;&lt;strong&gt;Hint.css&lt;/strong&gt;&lt;/a&gt; some days back on Hacker News and this post is primarily about what it is, how it works and what all I learned while creating it.&lt;/p&gt;
&lt;p&gt;First I would like to mention how nicely it was received and appreciated by the community. Here are some stats for the same:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;I &lt;a href=&quot;http://news.ycombinator.com/item?id=5164029&quot;&gt;released it on Hacker News&lt;/a&gt; on 4th Feb 2013 where it attained #1 ranking just after half an hour or so. Cool eh? BTW, this was the first time my submission got to #1 :) It got &lt;strong&gt;224 upvotes&lt;/strong&gt;. Thank you!&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;As a result of the above, the project page around 20K+ unique views. Heres an image showing some realtime stats after ~3 hours of release (&lt;em&gt;Note: The realtime count did went above 300, but come on...I was not in a state to take a screenshot then :P&lt;/em&gt;):&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;img src=&quot;https://kushagra.dev/images/2013/hint-realtime-stats.png&quot; alt=&quot;Hint GA realtime stats&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The &lt;a href=&quot;https://github.com/chinchang/hint.css/&quot;&gt;github repo&lt;/a&gt; has been starred and forked 1.4K+ and 100+ times respectively.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Also the repo is still in the &lt;a href=&quot;https://github.com/explore/month&quot;&gt;list of most trending repos&lt;/a&gt; on github.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So all in all, the launch was beyond expectations and really good.&lt;/p&gt;
&lt;p&gt;###About hint.css&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;hint.css&lt;/strong&gt; is a library written in SASS to create simple tooltips. So basically it uses only HTML and CSS to create tooltips for your lovely websites. Yes you heard that right, no JavaScript required. &lt;a href=&quot;http://kushagragour.in/lab/hint/&quot;&gt;Learn more&lt;/a&gt; about how to use it.&lt;/p&gt;
&lt;p&gt;The library uses the &lt;a href=&quot;https://gist.github.com/necolas/1309546&quot;&gt;BEM naming convention&lt;/a&gt; by &lt;a href=&quot;http://nicolasgallagher.com/about-html-semantics-front-end-architecture/&quot;&gt;Nicolas Gallagher&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;###How does it work&lt;br&gt;
The library uses 4 basic concepts to create the tooltips without a line of JavaScript or any extra markup:&lt;/p&gt;
&lt;p&gt;####1. Pseudo elements&lt;br&gt;
Pseudo elements are a gift for web developers which open numerous possibilities for creating amazing stuff. &lt;strong&gt;Hint.css&lt;/strong&gt; makes use of these pseudo elements (&lt;code&gt;::before&lt;/code&gt; and &lt;code&gt;::after&lt;/code&gt; elements) to create the actual tooltip.&lt;/p&gt;
&lt;p&gt;This has the advantage that you do not have to add any extra markup on your page. But it has a downside too. As the tooltip is created using pseudo elements, its not possible to use them for any other purpose on the element you put tooltip on.&lt;/p&gt;
&lt;p&gt;####2. data-_ attributes&lt;br&gt;
The tooltips need to be told what text to show. How do we provide this text? &lt;a href=&quot;http://www.w3.org/TR/2011/WD-html5-20110525/elements.html#embedding-custom-non-visible-data-with-the-data-attributes&quot;&gt;&lt;code&gt;data-_ &lt;/code&gt;&lt;/a&gt; attributes to the rescue. They let you put custom data on any element using attributes. So &lt;strong&gt;hint.css&lt;/strong&gt; expects you to define an attribute called &lt;code&gt;data-hint&lt;/code&gt; on the element which needs a tooltip:&lt;/p&gt;
&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;Out of the many, &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;span&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;data-hint&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;Tooltip text&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;this&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;span&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt; word needs a&lt;br&gt;tooltip.&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;####3. attr function for content&lt;br&gt;
Now the most important part on which &lt;strong&gt;hint.css&lt;/strong&gt; is based on. You may have heard about the &lt;code&gt;content&lt;/code&gt; property of pseudo elements. As is clear from the name, it lets you specify content of the pseudo element.&lt;/p&gt;
&lt;p&gt;What was really great for me was the &lt;strong&gt;attr&lt;/strong&gt; function which gives you the power of grabbing the value of any attribute on the element and set it as the pseudo element&#39;s content. Isn&#39;t that really neat? So the meat of the library is this one line:&lt;/p&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token property&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;attr&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;data-hint&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And you are DONE!&lt;/p&gt;
&lt;p&gt;####4. CSS3 transitions&lt;br&gt;
Finally to add some eye candy, the tooltips are loaded with subtle fade &amp;amp; translate effect using &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/CSS/Tutorials/Using_CSS_transitions&quot;&gt;CSS3 Transitions&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;One thing to note here is that Transitions on pseudo elements work only in Firefox presently. But do not worry guyz...thanks to Elliott Sprehn, &lt;a href=&quot;https://bugs.webkit.org/show_bug.cgi?id=92591&quot;&gt;the feature&lt;/a&gt; has arrived in Google Chrome 26 dev version and it&#39;s not too far when we&#39;ll all have it in the stable one too :)&lt;/p&gt;
&lt;p&gt;###What I learned&lt;/p&gt;
&lt;p&gt;If you are passionate about creating cool new stuff, you surely understand the importance of developing small side projects, something you can own completely. It teaches you a hell lot of things...not only about the tech side but about managing stuff from planning to releasing to maintaining a small product. You should probably read this &lt;a href=&quot;http://sachagreif.com/the-side-project-project/&quot;&gt;awesome post on creating side projects&lt;/a&gt; by &lt;a href=&quot;http://sachagreif.com/&quot;&gt;Sacha Grief&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;While making &lt;strong&gt;hint.css&lt;/strong&gt; I too learned many things which I would like to share here.&lt;/p&gt;
&lt;p&gt;####SASS&lt;/p&gt;
&lt;p&gt;This was the first time I tried &lt;a href=&quot;http://sass-lang.com/&quot;&gt;SASS&lt;/a&gt;. SASS is basically a CSS preprocessor...meaning it provides you some great features (like variables, mixins etc) to write your CSS in a more efficient way.&lt;/p&gt;
&lt;p&gt;I had never felt the need of using a preprocessor ever. And same was with &lt;strong&gt;hint&lt;/strong&gt; also. If you happen to see the &lt;a href=&quot;http://codepen.io/chinchang/pen/lICaq&quot;&gt;original demo of &lt;strong&gt;hint.css&lt;/strong&gt;&lt;/a&gt; I released, it was written in CSS. Even when I started writing the actual library I was using plain CSS but then things started getting very repetitive and unmanageable.&lt;/p&gt;
&lt;p&gt;Adding any new type of tooltip required to change certain properties on all four tooltip positions (top, bottom, left and right) which I had to write again and again. Also at times, inconsistencies occurred with respect to color values and other static numbers used at different places. And hence I was forced to look into a preprocessor that could make me write smarter code.&lt;/p&gt;
&lt;p&gt;Basically its the &lt;em&gt;mixins&lt;/em&gt; (check out &lt;a href=&quot;https://github.com/chinchang/hint.css/blob/master/src/hint-color-types.scss&quot;&gt;src/color-types.scss&lt;/a&gt; for example) and &lt;em&gt;variables&lt;/em&gt; that made the whole library very easy to extend and consistent everywhere.&lt;/p&gt;
&lt;p&gt;####Grunt&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://gruntjs.com/&quot;&gt;Grunt&lt;/a&gt; is a build tool basically made for JavaScript projects. I helps you create a build flow using variety of tasks it supports like concatenation, minification etc. As I started using SASS for &lt;strong&gt;Hint&lt;/strong&gt; it made sense to incorporate a build tool in my workflow and having a little experience of using Grunt in my previous game projects, I thought why not try it on a CSS project.&lt;/p&gt;
&lt;p&gt;It has worked quite well till now. I had to install some extra tasks for &lt;a href=&quot;https://github.com/sindresorhus/grunt-sass&quot;&gt;SASS compilation&lt;/a&gt; and &lt;a href=&quot;https://npmjs.org/package/grunt-contrib-mincss&quot;&gt;CSS minification&lt;/a&gt; as they don&#39;t come bundled by default with Grunt and now I simply run &lt;code&gt;grunt watch&lt;/code&gt; and all building happens silently in the background as I develop.&lt;/p&gt;
&lt;p&gt;####Release preparation&lt;/p&gt;
&lt;p&gt;This one is a tough and I would say a phase which needs more consideration and effort than the actual development itself.&lt;br&gt;
Coding the library hardly took a day or two but rest of the work took around 300% of the already spent time and that includes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Writing README for the repo&lt;/li&gt;
&lt;li&gt;Creating a project page with demo, usage explanation etc&lt;/li&gt;
&lt;li&gt;Writing a blog post about the project&lt;/li&gt;
&lt;li&gt;Making sure I did not miss anything&lt;/li&gt;
&lt;li&gt;Finally releasing!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;During this I became better at writing (I only love writing code though) and managing multiple tasks.&lt;/p&gt;
&lt;p&gt;####More CSS knowledge&lt;br&gt;
Last but not the least, as I was working on a CSS library I came to know more about it as mentioned earlier. CSS is really beautiful :)&lt;/p&gt;
&lt;p&gt;###In the end&lt;/p&gt;
&lt;p&gt;Finally &lt;strong&gt;Hint.css&lt;/strong&gt; was released as an Open Source project on Github. But it didn&#39;t stop there. People have been liking it and started using and &lt;a href=&quot;https://github.com/chinchang/hint.css/pulls&quot;&gt;contributing to it&lt;/a&gt; which marks the beginning of the final phase of a software: Maintenance. To keep a library fresh you need to constantly keep it up to date with latest technology, keep adding new features your users want, fix bugs that get reported regularly. And all this in very organized and planned manner so that the user&#39;s know exactly what changed when, whats coming up etc. In short, everyone should be able to track the project without difficulties.&lt;/p&gt;
&lt;p&gt;Doing all this is fun. I am getting to know GIT better and better now that I have started using branches, merging etc a lot. I only hope I don&#39;t face the &lt;a href=&quot;http://fat.github.com/slides-os-guilt/&quot;&gt;Cute Puppy Syndrome&lt;/a&gt; (a term coined by &lt;a href=&quot;https://twitter.com/fat&quot;&gt;@fat&lt;/a&gt;) in future :P&lt;/p&gt;
&lt;p&gt;Talking about issues, one thing that I have been &lt;a href=&quot;https://github.com/chinchang/hint.css/issues/12&quot;&gt;hearing a lot from people&lt;/a&gt; is that BEM naming convention is kind of an overkill, specifically in &lt;strong&gt;Hint&lt;/strong&gt;. For example people prefer &lt;code&gt;hint-top&lt;/code&gt; class over &lt;code&gt;hint--top&lt;/code&gt;. I am still thinking over this if BEM was at all necessary or is really an overkill in my library. Though I would really appreciate if BEM masters could really comment on this.&lt;/p&gt;
&lt;p&gt;Would love to hear your comments, suggestion or anything you feel like saying about my work, this post...anything.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://kushagragour.in/lab/hint/&quot; class=&quot;button button-big&quot;&gt;Take me to Hint.css&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;P.S. Discussion on &lt;a href=&quot;http://news.ycombinator.com/item?id=5164029&quot;&gt;Hacker News&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Cheers!&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>[Tutorial] Win8 HTML5 app development- II</title>
		<link href="https://kushagra.dev/blog/win8-html5-dev-part2/"/>
		<updated>2012-12-02T00:00:00+00:00</updated>
		<id>https://kushagra.dev/blog/win8-html5-dev-part2/</id>
		<content type="html">&lt;p&gt;Finally I got the opportunity to write the second part of the tutorial series on HTML5 game development for Windows 8.&lt;br&gt;
The first part &lt;a href=&quot;https://kushagra.dev/blog/2012/09/win8-html5-dev-part1/&quot;&gt;can be read here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Okay, so lets see what are we going to do today.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;First we&#39;ll port my game &lt;a href=&quot;http://kushagragour.in/Bouncy_HTML5/&quot;&gt;Bouncy&lt;/a&gt; to a Visual Studio 2012 project&lt;/li&gt;
&lt;li&gt;Add a paddle below he ball which will be controlled by &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/windows/apps/windows.devices.sensors.inclinometer&quot; trget=&quot;_blank&quot;&gt;Inclinometer&lt;/a&gt; sensor&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Lets begin!&lt;/p&gt;
&lt;p&gt;###PART 2: Writing your first sensor enabled Windows Store game###&lt;/p&gt;
&lt;p&gt;To begin with the porting, we need the game source first which we&#39;ll fetch by cloning the &lt;a href=&quot;https://github.com/chinchang/Bouncy_HTML5&quot;&gt;game repository on github&lt;/a&gt;. I am using terminal to do so but you could use any possible way to clone it. If you are using the terminal too, run the following command:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; clone git@github.com:chinchang/Bouncy_HTML5.git&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After you clone the repo, you should have a directory called &lt;strong&gt;Bouncy_HTML5&lt;/strong&gt; on your system containing 4 files out which we require &lt;code&gt;index.html&lt;/code&gt; and &lt;code&gt;game.js&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;####Porting game to Visual Studio:####&lt;/p&gt;
&lt;p&gt;Now lets fire up Visual Studio 2012. Once you have it running create a new project and select the &lt;strong&gt;Javascript &amp;gt; Windows Metro style &amp;gt; Blank App&lt;/strong&gt; template for your project.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://kushagra.dev/images/html5-sensor-tut-ss1.png&quot;&gt;&lt;img src=&quot;https://kushagra.dev/images/html5-sensor-tut-ss1.png&quot; alt=&quot;Blank App&quot; title=&quot;Select a Blank App&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This will create a basic setup for an Windows Store HTML5 app ready to run on Window 8. You can check out the files that are created by the template for you in the right solution panel:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://kushagra.dev/images/html5-sensor-tut-ss2.png&quot;&gt;&lt;img src=&quot;https://kushagra.dev/images/html5-sensor-tut-ss2.png&quot; alt=&quot;Solution panel&quot; title=&quot;Solution panel&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Our next step is to integrate our 2 files into the project. So basically first we integrate the markup (&lt;code&gt;index.html&lt;/code&gt;) and then the JavaScript (&lt;code&gt;game.js&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;Open the &lt;code&gt;default.html&lt;/code&gt; file present in your Visual Studio project and delete all the HTML present inside the &lt;code&gt;BODY&lt;/code&gt; tag.&lt;/p&gt;
&lt;p&gt;Now open up &lt;code&gt;Bouncy_HTML5/index.html&lt;/code&gt; in your favourite text-editor (BTW, I use the awesome &lt;a href=&quot;http://www.sublimetext.com/&quot;&gt;Sublime Text 2&lt;/a&gt;).&lt;br&gt;
From there you only need to copy 2 lines (Yeah, just 2. Rest is all the extra stuff on the page) into &lt;code&gt;default.html&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Copy the following line:&lt;/p&gt;
&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;canvas&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;c&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token attr-name&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;640&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token attr-name&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;480&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token special-attr&quot;&gt;&lt;span class=&quot;token attr-name&quot;&gt;style&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt; border: 1px solid #AAA;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;canvas&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and paste it inside the &lt;code&gt;BODY&lt;/code&gt; tag.&lt;/p&gt;
&lt;p&gt;Now back in the &lt;code&gt;index.html&lt;/code&gt; file copy the following:&lt;/p&gt;
&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;script&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;text/javascript&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;src&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;game.js&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token script&quot;&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and paste it where other &lt;code&gt;SCRIPT&lt;/code&gt; tags are present in &lt;code&gt;default.html&lt;/code&gt;. One thing you need to change here is the script path as our JavaScript file will now go in a sub-folder named &lt;strong&gt;js&lt;/strong&gt;. Change the line to:&lt;/p&gt;
&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;script&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;text/javascript&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;src&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;/js/game.js&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token script&quot;&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We are done with our HTML. Over to Javascript, developer.&lt;/p&gt;
&lt;p&gt;Next we&#39;ll add &lt;code&gt;Bouncy_HTML5/game.js&lt;/code&gt; to our project. Right-click on the &lt;strong&gt;js&lt;/strong&gt; folder in the solution pane. Select &lt;strong&gt;Add &amp;gt; Existing Item&lt;/strong&gt; then browse to &lt;code&gt;Bouncy_HTML5/game.js&lt;/code&gt; and click Add as shown below:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://kushagra.dev/images/html5-sensor-tut-ss3.png&quot;&gt;&lt;img src=&quot;https://kushagra.dev/images/html5-sensor-tut-ss3.png&quot; alt=&quot;Add file to project&quot; title=&quot;Add file to project&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Congratz, that file has now become part of your project. Now you can close the text editor and you have nothing to do with the Bouncy_HTML5 folder. You can delete it if you wish.&lt;/p&gt;
&lt;p&gt;If you try to run the project by pressing F5, the game will run just fine. But we&#39;ll make a small tweak here.&lt;/p&gt;
&lt;p&gt;If you happen to notice in &lt;code&gt;game.js&lt;/code&gt;, we call a function called &lt;code&gt;init()&lt;/code&gt; on window load event (Line 193). But in our new project we don&#39;t explicitly need to listen to window load event. In &lt;code&gt;default.js&lt;/code&gt; file that was created with the project you&#39;ll see a code that looks like this around Line 13:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// TODO: This application has been newly launched. Initialize&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token comment&quot;&gt;// your application here.&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is essentially a position where we can execute any of our initialization code. But the issue here is that the &lt;code&gt;init()&lt;/code&gt; function is inside an anonymous function and hence not available to outer world. It has to be first put in global scope to be able to call from &lt;code&gt;default.js&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Back in &lt;code&gt;game.js&lt;/code&gt;, modify the following line:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addEventListener&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;load&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; init&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;to&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// create a global game object&lt;/span&gt;&lt;br&gt;window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;game &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;game &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class=&quot;token comment&quot;&gt;// set a reference to init function&lt;/span&gt;&lt;br&gt;window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;game&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;init &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; init&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So now the function is accessible in global scope using &lt;code&gt;window.game.init()&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Switch back to &lt;code&gt;default.js&lt;/code&gt; and call the &lt;code&gt;init()&lt;/code&gt; function at the place we saw earlier. Your &lt;code&gt;onactivated&lt;/code&gt; function should look like this now:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;onactivated&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;args&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;detail&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;kind &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; activation&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ActivationKind&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;launch&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;br&gt;      args&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;detail&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;previousExecutionState &lt;span class=&quot;token operator&quot;&gt;!==&lt;/span&gt;&lt;br&gt;      activation&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ApplicationExecutionState&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;terminated&lt;br&gt;    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token comment&quot;&gt;// TODO: This application has been newly launched. Initialize&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token comment&quot;&gt;// your application here.&lt;/span&gt;&lt;br&gt;      window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;game&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token comment&quot;&gt;// TODO: This application has been reactivated from suspension.&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token comment&quot;&gt;// Restore application state here.&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;    args&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setPromise&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;WinJS&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;UI&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;processAll&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To verify your change, run the game by pressing F5 and it should work as before.&lt;/p&gt;
&lt;p&gt;####Adding the paddle:####&lt;br&gt;
Now that our game is completely ported we&#39;ll add paddle to it which will use the &lt;strong&gt;Inclinometer&lt;/strong&gt; sensor to move.&lt;/p&gt;
&lt;p&gt;As this tutorial doesn&#39;t focus on game development, rather using sensors for Windows Store game, we&#39;ll not dive into the code to implement the paddle. Simply download the new &lt;code&gt;game-with-paddle.js&lt;/code&gt; file and replace the &lt;code&gt;game.js&lt;/code&gt; code with its code:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://kushagra.dev/uploads/2012/game-with-paddle.js&quot; target=&quot;_blank&quot; class=&quot;button button-big&quot;&gt;Download new game.js&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Run your project and you should see a paddle on the screen and the balls bouncing on it. Lets make our paddle move, shall we?&lt;/p&gt;
&lt;p&gt;####Enabling Inclinometer to move paddle:####&lt;br&gt;
All the sensors in Windows Runtime (WinRT) are available under the namespace &lt;code&gt;Windows.Devices.Sensors&lt;/code&gt;. The class we need to use is &lt;code&gt;Windows.Devices.Sensors.Inclinometer&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;In &lt;code&gt;game.js&lt;/code&gt;, modify the following line:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; ball1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; ball2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; paddle&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;to&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; ball1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;  ball2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;  paddle&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;  sensor&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;  max_roll &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;which creates a new variable to reference our sensor.&lt;/p&gt;
&lt;p&gt;Next, in the &lt;code&gt;init()&lt;/code&gt; function, put the following lines:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// get the reference to the Inclinometer sensor&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  sensor &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Windows&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Devices&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Sensors&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Inclinometer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getDefault&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;e&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;You don&#39;t have sensor support&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;At this point we have initialized the Inclinometer. Now we need to read it to make the paddle move. Modify the paddle&#39;s &lt;code&gt;update()&lt;/code&gt; function to following:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;Paddle&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;prototype&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;update&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;dt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;sensor&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; reading &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; sensor&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getCurrentReading&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;reading&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;x &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;canvas&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;width &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; reading&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;rollDegrees &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; max_roll&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;All we do above is read the sensor&#39;s present reading (we are using the device roll amount here) and position the paddle according to it.&lt;/p&gt;
&lt;p&gt;Run your project now and try tilting your Windows 8 device. Voila! You can now control the paddle using the device&#39;s Inclinometer sensor (if one exists). You can download the Visual Studio project at the following link:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://kushagra.dev/uploads/2012/bouncy-sensor.zip&quot; target=&quot;_blank&quot; class=&quot;button button-big&quot;&gt;Download Project&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;We are done with our first sensor enabled game ready to be put up on the Windows Store. If I find some more interesting stuff about Windows Store app development, I&#39;ll share it in my next post :) Till then, here is a screenshot of the game in action:&lt;/p&gt;
&lt;img src=&quot;https://kushagra.dev/images/html5-sensor-tut-ss4.png&quot; alt=&quot;Game in action&quot;&gt;
&lt;p&gt;So go now and make your games sensor enabled and rule the world!&lt;/p&gt;
&lt;p&gt;Cheers!&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>[Tutorial] Win8 HTML5 app development- I</title>
		<link href="https://kushagra.dev/blog/win8-html5-dev-part1/"/>
		<updated>2012-09-22T00:00:00+00:00</updated>
		<id>https://kushagra.dev/blog/win8-html5-dev-part1/</id>
		<content type="html">&lt;p&gt;Hola!&lt;/p&gt;
&lt;p&gt;I recently received a prototype of the next generation Ultrabook device from Intel to support my Windows 8 app developments which had Windows 8 Release Preview installed.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://kushagra.dev/images/ubook.png&quot;&gt;&lt;img src=&quot;https://kushagra.dev/images/ubook.jpg&quot; alt=&quot;Ultrabook&quot; title=&quot;Next-gen ultrabook&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Excited about the new capabilities the device offers, I thought of starting by porting one my previous games to Windows 8. I started looking on forums, communities etc to get some &#39;getting started&#39; guides on developing HTML5 apps for Windows 8 RT which is specifically for touch device like tablets. Unfortunately, there isn&#39;t much information for beginners...or may be I couldn&#39;t find some. But anyways, the only option that was left was to explore stuff on my own.&lt;/p&gt;
&lt;p&gt;This tutorial series is basically a documentation about my experience of the process of porting one of my HTML5 games (&lt;a href=&quot;https://github.com/chinchang/Bouncy_HTML5&quot;&gt;HTML5 Bouncy&lt;/a&gt;) to Windows 8 and use its accelerometer capability to add some extra control.&lt;br&gt;
The tutorial series isn&#39;t pre-decided as to how long it would be as the app is still under development. I&#39;ll share my experience here as and when there is some progress.&lt;/p&gt;
&lt;p&gt;###PART 1: Getting the dev environment ready###&lt;/p&gt;
&lt;p&gt;Okay, so to develop apps for Windows 8 we need Microsoft Visual 2012 which supports Metro style apps. So I headed over to the &lt;a href=&quot;http://www.microsoft.com/visualstudio/eng/downloads&quot;&gt;Visual Studio download page&lt;/a&gt; as prescribed &lt;a href=&quot;http://software.intel.com/en-us/blogs/2012/07/13/getting-started-with-ultrabook-development&quot;&gt;by few&lt;/a&gt; &lt;a href=&quot;http://blogs.msdn.com/b/jennifer/archive/2012/06/19/developing-a-windows-8-metro-app-part-2-getting-started.aspx&quot;&gt;articles&lt;/a&gt; I read.&lt;/p&gt;
&lt;p&gt;Then I downloaded &lt;strong&gt;Visual Studio Express 2012 for Windows 8&lt;/strong&gt; from there. But upon installing, it gave a weird error:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Windows 8 Release Preview does not have the required .NET framework 4.5.50709&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Well, that was annoying as I expected my windows 8 to come bundled with all the dependencies. My next step was to obviously search the Microsoft website for the required .NET updates. I even found some updates to .NET but each one on installation gave the message that &lt;strong&gt;&lt;em&gt;I already had the same .NET version installed&lt;/em&gt;&lt;/strong&gt;. That was more weird.&lt;/p&gt;
&lt;p&gt;After some googling about the issue, I hit a &lt;a href=&quot;http://stackoverflow.com/questions/12389297/unable-to-install-visual-studio-professional-2012-on-windows-8-cp-and-also-not-o&quot;&gt;Stackoverflow page&lt;/a&gt; that had the information I wanted. So it turns out that Visual Studio cannot be installed on Windows 8 Release Preview due to some restrictions by Microsoft. It can be installed only on Windows 8 RTM. Besides this, if you want to have Visual Studio 2012 for Win 8 RP, you can do so using Visual Studio 2012 Release Candidate. God bless Microsoft!&lt;/p&gt;
&lt;p&gt;So basically I had 2 options now to choose from:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Get Windows 8 RTM&lt;/li&gt;
&lt;li&gt;Get Visual Studio 2012 RC&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And obviously I picked the latter as whose gonna download and install Window 8 :) Finally &lt;a href=&quot;http://www.microsoft.com/en-us/download/details.aspx?id=29915&quot;&gt;downloaded Visual Studio 2012 RC&lt;/a&gt; and it installed without any issues on my Ultrabook device. A moment of rejoice!&lt;/p&gt;
&lt;p&gt;And there I had in front of my eyes, the beautiful new UI of Micorsoft Visual Studio 2012 inspired by the Metro view :D It was simply neat and clean.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://kushagra.dev/images/vs2012_start_screen.png&quot;&gt;&lt;img src=&quot;https://kushagra.dev/images/vs2012_start_screen.png&quot; alt=&quot;Visual Studio 2012&quot; title=&quot;Visual Studio 2012 start screen&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Just to try out things, I made a new Javascript Blank Project which provides you with a &lt;code&gt;default.html&lt;/code&gt;, &lt;code&gt;default.js&lt;/code&gt; and &lt;code&gt;default.css&lt;/code&gt; files with some basic setup code. I added some code to make a simple Hello World app:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;HTML&lt;/strong&gt;&lt;/p&gt;
&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;hello-world&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Hello World!&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;CSS&lt;/strong&gt;&lt;/p&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;#hello-world&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;text-align&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; center&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;font-size&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 220px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;margin-top&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 300px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And I have my first hello world HTML5 window 8 app ready :)&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://kushagra.dev/images/helloworld_win8.png&quot;&gt;&lt;img src=&quot;https://kushagra.dev/images/helloworld_win8.png&quot; alt=&quot;Hello World&quot; title=&quot;Hello World!&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;###Whats up next?###&lt;br&gt;
It seems the dev environment is setup now. Next, this is what I am going to do:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Port &lt;a href=&quot;https://github.com/chinchang/Bouncy_HTML5&quot;&gt;HTML5 Bouncy&lt;/a&gt; to Visual Studio (shouldn&#39;t be much of pain)&lt;/li&gt;
&lt;li&gt;Explore how to use device accelerometer with Javascript&lt;/li&gt;
&lt;li&gt;Add some features to the game to exploit accelerometer capabilities&lt;/li&gt;
&lt;li&gt;May be something more...&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Hope this series is useful to someone starting Windows 8 app development for the next generation Ultrabooks.&lt;/p&gt;
&lt;p&gt;Till the next part, cya!&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Rotating earth using pure CSS</title>
		<link href="https://kushagra.dev/blog/rotating-earth-using-css/"/>
		<updated>2012-09-16T00:00:00+00:00</updated>
		<id>https://kushagra.dev/blog/rotating-earth-using-css/</id>
		<content type="html">&lt;p&gt;Recently after seeing a pen on &lt;a target=&quot;_blank&quot; href=&quot;http://www.codepen.io/&quot;&gt;codepen&lt;/a&gt; by &lt;a href=&quot;http://codepen.io/jackrugile/pen/sadvF&quot;&gt;Jack Rugile&lt;/a&gt; and a creation on &lt;a href=&quot;http://www.cssdeck.com/&quot;&gt;CSSDeck&lt;/a&gt; by &lt;a href=&quot;http://cssdeck.com/labs/animated-map-icon&quot;&gt;Tim Holman&lt;/a&gt;, I thought why not use the two concepts to come up with something interesting. An illusion of a 3D rotating planet using just CSS. And so I &lt;a href=&quot;http://codepen.io/chinchang/pen/ygHBc&quot;&gt;hacked down a pen&lt;/a&gt; (this does a little more than mentioned, not nicely enough though).&lt;/p&gt;
&lt;div class=&quot;talign-center&quot;&gt;
	&lt;a href=&quot;http://codepen.io/chinchang/pen/xCkus&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;https://kushagra.dev/images/css-rotating-earth.jpeg&quot; alt=&quot;Rotating earth in CSS&quot; width=&quot;200&quot; height=&quot;200&quot;&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;p&gt;I thought may be I should share the little CSS tricks being used in this CSS stuff to create the illusion. And here I am with a short walkthrough. Lets begin.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://codepen.io/chinchang/pen/xCkus&quot; target=&quot;_blank&quot; class=&quot;button button-big&quot;&gt;Demo&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This demo uses a single &lt;code&gt;div&lt;/code&gt; tag for the HTML. So lets start by creating a &lt;code&gt;div&lt;/code&gt; tag with an ID &lt;code&gt;earth&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;earth&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Thats it. Our markup is done. Time for some CSS now. Lets break this part into numbered steps.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;STEP 1&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;Lets give our earth some dimensions. Give it a &lt;code&gt;width&lt;/code&gt; and &lt;code&gt;height&lt;/code&gt; of 100 pixels. Also give a temporary &lt;code&gt;background&lt;/code&gt; of blue color just to know what it is becoming.&lt;/p&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;#earth&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 100px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 100px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;background&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; blue&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;STEP 2&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;Earth isn&#39;t all that square for sure. Lets make it a perfect circle by giving it a &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/CSS/border-radius&quot;&gt;&lt;code&gt;border-radius&lt;/code&gt;&lt;/a&gt; of 50%.&lt;/p&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;#earth&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 100px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 100px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;background&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; blue&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;border-radius&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 50%&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;STEP 3&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;Much better now. But still doesn&#39;t looks like our earth. Yeah, you&#39;re right...we need a texture. Lets pick an earth texture to put on our present blue circle. I have selected &lt;a href=&quot;http://www.noirextreme.com/digital/Earth-Color4096.jpg&quot;&gt;this image&lt;/a&gt; here for this tutorial (you could use any of your choice). Set the image as the background of our &lt;code&gt;div&lt;/code&gt; instead of the blue color we have.&lt;/p&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;#earth&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 100px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 100px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;background&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token url&quot;&gt;&lt;span class=&quot;token function&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;http://www.noirextreme.com/digital/Earth-Color4096.jpg&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;border-radius&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 50%&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Step 4&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;Ahh, all we see is a blue color still. Why? Well that is because the texture we are using is quite big for a 100x100 earth. We need to scale down the background a bit. Lets try giving it a &lt;code&gt;background-size&lt;/code&gt; of something according to our dimensions. I find 210 pixels to be a fit here.&lt;/p&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;#earth&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 100px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 100px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;background&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token url&quot;&gt;&lt;span class=&quot;token function&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;http://www.noirextreme.com/digital/Earth-Color4096.jpg&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;border-radius&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 50%&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;background-size&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 210px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Step 5&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;Seems better. But our earth still looks all flat. Time to give it some 3D feel by adding some lighting. For this we use &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/CSS/box-shadow&quot;&gt;&lt;code&gt;box-shadow&lt;/code&gt;&lt;/a&gt; CSS property. Give it an inner blackish shadow from left.&lt;/p&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;#earth&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 100px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 100px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;background&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token url&quot;&gt;&lt;span class=&quot;token function&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;http://www.noirextreme.com/digital/Earth-Color4096.jpg&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;border-radius&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 50%&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;background-size&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 210px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;box-shadow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; inset 16px 0 40px 3px black&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To make it more realistic, add another white shadow from right side, a subtle one with some opacity.&lt;/p&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;#earth&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 100px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 100px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;background&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token url&quot;&gt;&lt;span class=&quot;token function&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;http://www.noirextreme.com/digital/Earth-Color4096.jpg&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;border-radius&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 50%&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;background-size&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 210px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;box-shadow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; inset 16px 0 40px 3px &lt;span class=&quot;token function&quot;&gt;rgb&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;0&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 0&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 0&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; inset -3px 0 6px 2px &lt;span class=&quot;token function&quot;&gt;rgba&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;255&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 255&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 255&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 0.2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Step 6&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;Now that looks like our earth. One final thing we will do is...rotate it. How? &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/CSS/Using_CSS_animations&quot;&gt;CSS Animations&lt;/a&gt; to the rescue. We first need to define our own animation keyframes which essentially means telling which CSS property will change to what value and at what time. But wait! What CSS property can we use to make a rotation animation?&lt;/p&gt;
&lt;p&gt;Well, the rotation illusion is actually created by simply scrolling the background image horizontally which is by default tiled both horizontally and vertically. Hence we make use of &lt;code&gt;background-position-x&lt;/code&gt; CSS to do so. Add the following CSS to define the animation keyframes which we call &lt;code&gt;rotate&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token atrule&quot;&gt;&lt;span class=&quot;token rule&quot;&gt;@keyframes&lt;/span&gt; rotate&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token selector&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token property&quot;&gt;background-position-x&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 0px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token selector&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token property&quot;&gt;background-position-x&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 210px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So here we are defining our animation to change the &lt;code&gt;background-position&lt;/code&gt; &lt;code&gt;from&lt;/code&gt; 0px when animation cycle starts &lt;code&gt;to&lt;/code&gt; 210px when cycle ends. Why we chose 210px for the final value? Remember that is the size we set for our background-image. So for a seamless scrolling we shift the background image equal to its width.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 7&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;Nothing happens though because we have not yet used the above defined animation. To use it, we set the &lt;code&gt;animation-name&lt;/code&gt; CSS property to our animation name (rotate).&lt;/p&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;#earth&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 100px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 100px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;background&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token url&quot;&gt;&lt;span class=&quot;token function&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;http://www.noirextreme.com/digital/Earth-Color4096.jpg&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;border-radius&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 50%&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;background-size&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 210px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;box-shadow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; inset 16px 0 40px 3px &lt;span class=&quot;token function&quot;&gt;rgb&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;0&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 0&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 0&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; inset -3px 0 6px 2px &lt;span class=&quot;token function&quot;&gt;rgba&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;255&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 255&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 255&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 0.2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;animation-name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; rotate&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then we define the time it should take for one animation cycle using &lt;code&gt;animation-duration&lt;/code&gt; property. Set a value of 4 seconds for the same.&lt;/p&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;#earth&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 100px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 100px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;background&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token url&quot;&gt;&lt;span class=&quot;token function&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;http://www.noirextreme.com/digital/Earth-Color4096.jpg&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;border-radius&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 50%&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;background-size&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 210px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;box-shadow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; inset 16px 0 40px 3px &lt;span class=&quot;token function&quot;&gt;rgb&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;0&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 0&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 0&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; inset -3px 0 6px 2px &lt;span class=&quot;token function&quot;&gt;rgba&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;255&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 255&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 255&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 0.2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;animation-name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; rotate&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;animation-duration&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 4s&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notice here how the animation plays just once and stops. We must tell the animation to play in an infinte loop using the &lt;code&gt;animation-iteration-count&lt;/code&gt; property.&lt;/p&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;#earth&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 100px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 100px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;background&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token url&quot;&gt;&lt;span class=&quot;token function&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;http://www.noirextreme.com/digital/Earth-Color4096.jpg&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;border-radius&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 50%&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;background-size&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 210px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;box-shadow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; inset 16px 0 40px 3px &lt;span class=&quot;token function&quot;&gt;rgb&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;0&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 0&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 0&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; inset -3px 0 6px 2px &lt;span class=&quot;token function&quot;&gt;rgba&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;255&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 255&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 255&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 0.2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;animation-name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; rotate&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;animation-duration&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 4s&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;animation-iteration-count&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; infinite&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;One final adjustment to make the animation smooth, set the &lt;code&gt;animation-timing-function&lt;/code&gt; to &lt;code&gt;linear&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;#earth&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 100px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 100px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;background&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token url&quot;&gt;&lt;span class=&quot;token function&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;http://www.noirextreme.com/digital/Earth-Color4096.jpg&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;border-radius&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 50%&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;background-size&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 210px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;box-shadow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; inset 16px 0 40px 3px &lt;span class=&quot;token function&quot;&gt;rgb&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;0&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 0&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 0&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; inset -3px 0 6px 2px &lt;span class=&quot;token function&quot;&gt;rgba&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;255&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 255&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 255&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 0.2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;animation-name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; rotate&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;animation-duration&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 4s&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;animation-iteration-count&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; infinite&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token property&quot;&gt;animation-timing-function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; linear&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And we are done! You may give the body a black background to get a feel of space. Also you can make different planets by just changing the background texture. So go and make some cool CSS planets.&lt;/p&gt;
&lt;p&gt;Finally, some light discussion about the demo &lt;a href=&quot;http://news.ycombinator.com/item?id=4498860&quot;&gt;on Hacker News&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Earth image credits: &lt;a href=&quot;http://www.noirextreme.com/earth&quot;&gt;http://www.noirextreme.com/earth&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Cheers!&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>I complete an year at Wingify</title>
		<link href="https://kushagra.dev/blog/one-year-at-wingify/"/>
		<updated>2012-08-25T00:00:00+00:00</updated>
		<id>https://kushagra.dev/blog/one-year-at-wingify/</id>
		<content type="html">&lt;p&gt;Today is quite a big day for me. Last year on this very date, I joined my first job at a startup called &lt;strong&gt;&lt;a href=&quot;http://www.wingify.com/&quot;&gt;Wingify&lt;/a&gt;&lt;/strong&gt; which was not much known name to me at that time. And today I complete an year working at Wingify and immensely proud and privileged of having been part of a bunch of talented geeks!&lt;/p&gt;
&lt;p&gt;&lt;strong id=&quot;one-year&quot;&gt;1&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Writing this post, lots of memories of the past year strike my mind (whatever my short-term memory can recall). I still remember that day when I was about to join some other company in Bangalore and was all set to leave on Sunday. And two days before that I came to know about a startup called Wingify in New Delhi and that it was hiring. I was called for an interview the next day at Wingify&#39;s one room office back then, where I had the geekiest (and longest) interview of my life :P But seriously it was so much fun talking and discussing stuff at that 3 hour long interview which was taken by the geeky CTO of Wingify, &lt;a href=&quot;https://www.facebook.com/sparshgupta&quot;&gt;Sparsh Gupta&lt;/a&gt; (btw, our cool CEO, &lt;a href=&quot;http://paraschopra.com/&quot;&gt;Paras Chopra&lt;/a&gt;, was out for holidays at that time). Irrespective of my selection, I was happy to have talked to some awesome people that day. But thankfully I was selected for the job that very day (night to be precise) and there, I was saved from the employee exploitation machine I was going into :P We were just 7 people then.&lt;/p&gt;
&lt;p&gt;Since then, it has been a journey filled with lots of learning, making awesome stuff and wonderful parties :)&lt;br&gt;
Being a startup I have got the opportunity to work in various domains here which has really helped me grow, learn new things and become better at whatever I do. Here, I have created frontends, backends, &lt;a href=&quot;http://team.wingify.com/our-christmas-logo&quot;&gt;doodles&lt;/a&gt;, christmas cards (this was a &lt;a href=&quot;http://team.wingify.com/greeting-card-day-at-wingify-office&quot;&gt;tough job&lt;/a&gt; for our team) and what not. And the most important thing which sets Wingify apart from the rest is the creative freedom and casual environment it provides to the team which lets us create better and better product for our customers.&lt;/p&gt;
&lt;p&gt;Talking about the past year, one thing that I can&#39;t forget is the &lt;a href=&quot;http://team.wingify.com/thailand-trip-pictures&quot;&gt;crazy trip to Thailand&lt;/a&gt; that we had on Christmas.&lt;/p&gt;
&lt;img src=&quot;https://kushagra.dev/images/team-at-thailand.jpg&quot; title=&quot;Team in Thailand&quot;&gt;
&lt;p&gt;It was a wonderful experience going out with the team and I thank Wingify for that. There are a lot of short stories of that trip but lets not discuss them here :)&lt;/p&gt;
&lt;p&gt;All in all, I feel really fortunate to be a part of Wingify and to be able to work with some freaky hackers here building a &lt;a href=&quot;http://visualwebsiteoptimizer.com/&quot;&gt;world class product&lt;/a&gt; that our customers love. Its altogether a different feeling to be in a small team (we are 10 people now) and share huge achievements together (we recently hit 1500+ signups and shifting to a better &amp;amp; bigger office soon). Hope to make more neat and wonderful stuff here.&lt;/p&gt;
&lt;p&gt;And hey, we are always looking out for great talent out there. So if you think you have got it, &lt;a href=&quot;http://visualwebsiteoptimizer.com/careers.php&quot;&gt;reach out to us&lt;/a&gt; and be a part of this place called &lt;strong&gt;Wingify&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;EDIT: And as an icing on the cake, I received a &lt;a href=&quot;https://www.facebook.com/photo.php?fbid=4551440628203&quot; target=&quot;_blank&quot;&gt;touch ultrabook&lt;/a&gt; from Intel today :D Yuhooo!!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Thanks Wingify!&lt;/strong&gt;&lt;/p&gt;
&lt;style type=&quot;text/css&quot;&gt;
#one-year { display: inline-block; font-size: 120px; margin-left: 70px; text-shadow: 0 1px 1px #6E7231, 0 2px 1px #6E7231, 0 3px 1px #6E7231, 0 4px 1px #6E7231, 0 5px 1px #6E7231, 0 6px 1px #6E7231, 0 6px 1px rgba(0, 0, 0, 0.9), 0 6px 13px rgba(0, 0, 0, 0.4); -webkit-transition: 300ms margin-left; -moz-transition: 300ms margin-left; }
#one-year:before { content: &#39;year&#39;; font-size: 25px; position: relative; left: 133px; bottom: 60px; }
#one-year:after { content: &#39;@ Wingify&#39;; font-size: 40px; position: relative; left: 10px; bottom: 20px; }
#one-year:hover { margin-left: 80px; }
&lt;/style&gt;
</content>
	</entry>
	
	<entry>
		<title>Hello World!</title>
		<link href="https://kushagra.dev/blog/hello-world/"/>
		<updated>2012-07-28T00:00:00+00:00</updated>
		<id>https://kushagra.dev/blog/hello-world/</id>
		<content type="html">&lt;p&gt;Hey!&lt;/p&gt;
&lt;p&gt;As a custom, I write my first post on my new blog (powered by Jekyll and Github).&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; str &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Hello World!&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;br&gt;console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;str&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I&#39;ll be soon writing a post about my experience with switching from wordpress to really awesome Jekyll.&lt;/p&gt;
&lt;p&gt;Stay tuned.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>New web experiments!</title>
		<link href="https://kushagra.dev/blog/new-web-experiments/"/>
		<updated>2012-07-01T04:30:37+00:00</updated>
		<id>https://kushagra.dev/blog/new-web-experiments/</id>
		<content type="html">&lt;p&gt;Hey everyone!&lt;/p&gt;
&lt;p&gt;This is my post after a long long time. Well, I am here to introduce 2 recent experimental web stuff I developed just to get the hang of HTML5, CSS3 and coffeescript and I must tell you that working with these super-awesome web technologies has been a great experience. They open a whole new world of possibilities where imagination can create mind-blowing things.&lt;/p&gt;
&lt;h2 id=&quot;iso-blocks&quot;&gt;&lt;a href=&quot;https://kushagra.dev/lab/isoblocks/&quot;&gt;ISO-BLOCKS&lt;/a&gt; &lt;a class=&quot;bookmark&quot; href=&quot;#iso-blocks&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://kushagra.dev/images/ISO-BLOCKS-An-eye-candy-CSS3-isometric-text-library..png&quot;&gt;&lt;img src=&quot;https://kushagra.dev/images/ISO-BLOCKS-An-eye-candy-CSS3-isometric-text-library.-300x148.png&quot; alt=&quot;&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The first one of them is actually a small library used to create cool looking isometric text in the browser using CSS3 &lt;em&gt;&lt;a href=&quot;https://developer.mozilla.org/en/CSS/CSS_transitions/&quot;&gt;transitions&lt;/a&gt;&lt;/em&gt; and &lt;em&gt;&lt;a href=&quot;https://developer.mozilla.org/en/CSS/transform&quot;&gt;transforms&lt;/a&gt;&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://kushagra.dev/lab/isoblocks/&quot;&gt;Try out ISO-BLOCKS&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;picssel-art&quot;&gt;&lt;a href=&quot;https://kushagra.dev/lab/picssel-art/&quot;&gt;piCSSel-art&lt;/a&gt; &lt;a class=&quot;bookmark&quot; href=&quot;#picssel-art&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://kushagra.dev/images/picssel-ss.png&quot;&gt;&lt;img src=&quot;https://kushagra.dev/images/picssel-ss-244x300.png&quot; alt=&quot;&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This is a recent thing I have been working on. The inspiration behind this was the space invader made &lt;a href=&quot;http://css-tricks.com/examples/ShapesOfCSS/&quot;&gt;here&lt;/a&gt; using CSS &lt;em&gt;&lt;a href=&quot;https://developer.mozilla.org/en/CSS/box-shadow&quot;&gt;box-shadow&lt;/a&gt;&lt;/em&gt; seeing which I though of recreating my complete site with zero images using only CSS pixel art. And so &lt;strong&gt;piCSSel-art&lt;/strong&gt; was born.&lt;/p&gt;
&lt;p&gt;Having the app done, I&#39;ll can now start working on my new website design which is gonna be hell lot of fun with this.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://kushagra.dev/lab/picssel-art/&quot;&gt;Try out piCSSel-art&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Both the above experiments are in the open-source world for anyone who wants to tinker with them. So fork and play with them.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ISO-BLOCKS&lt;/strong&gt;: &lt;a href=&quot;https://github.com/chinchang/IsoBlocks&quot;&gt;https://github.com/chinchang/IsoBlocks&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;piCSSel-art&lt;/strong&gt;: &lt;a href=&quot;https://github.com/chinchang/picssel-art&quot;&gt;https://github.com/chinchang/picssel-art&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Let me know your thoughts, comments, suggestions on them.&lt;/p&gt;
&lt;p&gt;Cheers!&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Ludum Dare 23!</title>
		<link href="https://kushagra.dev/blog/ludum-dare-23/"/>
		<updated>2012-04-30T01:16:08+00:00</updated>
		<id>https://kushagra.dev/blog/ludum-dare-23/</id>
		<content type="html">&lt;p&gt;Hey everyone!&lt;/p&gt;
&lt;p&gt;Last weekend was just super awesome...it was &lt;strong&gt;&lt;a href=&quot;http://www.ludumdare.com/compo/&quot;&gt;Ludum Dare&lt;/a&gt;&lt;/strong&gt; 23 - The ultimate 48 hour compo. The theme was &#39;Tiny World&#39; and I was in this time (my 2nd LD). I chose to make a game on flash platform using the &lt;strong&gt;&lt;a href=&quot;http://www.flashpunk.com/&quot;&gt;Flashpunk&lt;/a&gt;&lt;/strong&gt; game library. The game is called &lt;em&gt;SAVE ME&lt;/em&gt; in which you control a cute alien which is attacked by some evil species. You can jump on planets and even hop from one planet to another collecting the game power-ups.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://kushagra.dev/images/ld23_ss1.png&quot;&gt;&lt;img src=&quot;https://kushagra.dev/images/ld23_ss1.png&quot; width=&quot;220&quot;&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href=&quot;https://kushagra.dev/images/ld23_ss1.png&quot;&gt;&lt;img src=&quot;https://kushagra.dev/images/ld23_ss2.png&quot; width=&quot;220&quot;&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href=&quot;https://kushagra.dev/images/ld23_ss1.png&quot;&gt;&lt;img src=&quot;https://kushagra.dev/images/ld23_ss3.png&quot; width=&quot;220&quot;&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href=&quot;https://kushagra.dev/images/ld23_ss1.png&quot;&gt;&lt;img src=&quot;https://kushagra.dev/images/ld23_ss4.png&quot; width=&quot;220&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Some points about this LD for me were:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Gave more time and priority to gameplay.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Drew quite a lot pixel art for the first time (it was fun).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Tried some new game mechanics.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Integrated almost all game elements (sounds really matter).&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;play-and-rate-my-entry.&quot;&gt;&lt;strong&gt;&lt;a href=&quot;http://www.ludumdare.com/compo/ludum-dare-23/?action=preview&amp;amp;uid=4201&quot;&gt;Play and rate&lt;/a&gt;&lt;/strong&gt; my entry. &lt;a class=&quot;bookmark&quot; href=&quot;#play-and-rate-my-entry.&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Now that the compo is over, I have played around 60 entries out which here are my best picks (in no order):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;**&lt;a href=&quot;http://www.ludumdare.com/compo/ludum-dare-23/?action=preview&amp;amp;uid=2982&quot;&gt;Memento XII - deepnight&lt;/a&gt;: **As always, this entry by deepnight has mind blowing graphics. The pixel art is really good and gives a very nice feel to the game. Though being a &lt;em&gt;point and click adventure&lt;/em&gt; type, I was not that a fan of the gameplay.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;http://www.ludumdare.com/compo/ludum-dare-23/?action=preview&amp;amp;uid=528&quot;&gt;Astro Break - hulahulahest&lt;/a&gt;&lt;/strong&gt;: This was a really well made contra style game. I loved the sprites and the whole idea of having a shoot&#39;emup on a lil planet was greet. A game to play for powerups!&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;http://www.ludumdare.com/compo/ludum-dare-23/?action=preview&amp;amp;uid=11306&quot;&gt;Soul Searchin&#39; - MaximSchoemaker&lt;/a&gt;&lt;/strong&gt;: A 100% into the the theme entry. A very well executed idea where the player can be shrunk and grown to clear levels inside levels...A nice level design too.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;**&lt;a href=&quot;http://www.ludumdare.com/compo/ludum-dare-23/?action=preview&amp;amp;uid=19&quot;&gt;Nook - PoV&lt;/a&gt;: **Another shrink/grow type jam entry which wonderful graphics and animation. The game is fun to play and effects are neat.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So go ahead, play them, rate them and be cool :)&lt;/p&gt;
&lt;p&gt;If you wanna check out my game&#39;s source, it can be found on &lt;strong&gt;&lt;a href=&quot;https://github.com/chinchang/LD23&quot;&gt;github&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Till next time, cya!&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Copter clone- open source on github</title>
		<link href="https://kushagra.dev/blog/copter-clone-open-source-on-github/"/>
		<updated>2012-01-01T20:06:20+00:00</updated>
		<id>https://kushagra.dev/blog/copter-clone-open-source-on-github/</id>
		<content type="html">&lt;p&gt;Hey everyone&lt;/p&gt;
&lt;h1 id=&quot;happy-new-year-to-all!&quot;&gt;&lt;strong&gt;HAPPY NEW YEAR TO ALL!&lt;/strong&gt; &lt;a class=&quot;bookmark&quot; href=&quot;#happy-new-year-to-all!&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;It has been an awesome year in 2011, with many things happening as expected and many unexpectedly. But overall...superb.&lt;/p&gt;
&lt;p&gt;The first news of 2012 from my side is that I have put one of my alpha games on github. Its basically a clone of the very famous copter game by seethru. You can fork the game &lt;strong&gt;&lt;a href=&quot;https://github.com/chinchang/Copter&quot;&gt;HERE&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/chinchang/Copter&quot;&gt;&lt;img src=&quot;https://kushagra.dev/images/copter-300x207.png&quot; alt=&quot;&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;So fork it, hack it and enjoy.&lt;br&gt;
May this new year bring more n more joy to all.&lt;/p&gt;
&lt;p&gt;Cheers!&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Fun at Nasscom GDC BYOG 2011!</title>
		<link href="https://kushagra.dev/blog/fun-at-nasscom-gdc-byog/"/>
		<updated>2011-11-15T01:24:51+00:00</updated>
		<id>https://kushagra.dev/blog/fun-at-nasscom-gdc-byog/</id>
		<content type="html">&lt;p&gt;Hey fellow developers!&lt;/p&gt;
&lt;p&gt;It has been a long time since I wrote my last post. Well, I have got a reason for this one :)&lt;/p&gt;
&lt;p&gt;Four days back, Nasscom organized its third &lt;strong&gt;&lt;a href=&quot;http://ngdc.nasscom.in/&quot;&gt;Game Developers Conference&lt;/a&gt;&lt;/strong&gt; in Pune. What was different this time was the BYOG event conducted by the Indie Game Development India community. Yes, you heard that right a &lt;strong&gt;&lt;a href=&quot;http://ingd.in/byog/nasscom-2011&quot;&gt;Build Your Own Game&lt;/a&gt;&lt;/strong&gt; wherein a game was to be developed in 48 hours...savvy!&lt;/p&gt;
&lt;p&gt;Unfortunately, I could not attend the awesome event this year. Nevertheless, I took part in the BYOG remotely. And what I came up with in this jam was &lt;strong&gt;&lt;a href=&quot;http://ingd.in/project/fun-forces&quot;&gt;Fun With Force&lt;/a&gt;&lt;/strong&gt;. The theme of my game was &#39;physics&#39;. Its a very simple prototype but I&#39;m happy with the result. And yes...it won the 3rd prize in the jam :D&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://kushagra.dev/games/fun-with-force/&quot;&gt;&lt;img src=&quot;https://kushagra.dev/images/fun_with_force.png&quot; alt=&quot;Fun with force&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://kushagra.dev/games/fun-with-force/&quot; target=&quot;_blank&quot; class=&quot;button button-big&quot;&gt;Play&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Let the developer (me) know your comments and suggestions.&lt;/p&gt;
&lt;p&gt;More updates on my games coming soon.&lt;br&gt;
&lt;strong&gt;Cheers!&lt;/strong&gt;&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>AS3 Motion Tracker on github</title>
		<link href="https://kushagra.dev/blog/as3-motion-tracker-on-github/"/>
		<updated>2011-06-13T18:37:47+00:00</updated>
		<id>https://kushagra.dev/blog/as3-motion-tracker-on-github/</id>
		<content type="html">&lt;p&gt;Hiya everyone !&lt;/p&gt;
&lt;p&gt;I have been working on motion tracking since my &lt;a href=&quot;http://kushagragour.in/blog/2011/06/a-supercool-night-with-motion-tracking/&quot;&gt;last blog post&lt;/a&gt; on experiment with Justin Windle&#39;s motion tracker. Inspired by all the fascinating stuff, I started writing my own motion tracker in Actionscript 3.0 which is finally done and up on &lt;a href=&quot;https://github.com/&quot;&gt;Github&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Though it tracks motion nicely it still needs to be improved to track smoothly and more accurately. I&#39;ll be also working on integrating gesture recognition with it.&lt;/p&gt;
&lt;h1 id=&quot;project-source&quot;&gt;&lt;strong&gt;&lt;a href=&quot;https://github.com/chinchang/AS3-Motion-Tracker&quot;&gt;PROJECT SOURCE&lt;/a&gt;&lt;/strong&gt; &lt;a class=&quot;bookmark&quot; href=&quot;#project-source&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Download it. Play with it. Improve it.&lt;/p&gt;
&lt;p&gt;Cheers !&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>A supercool night with MOTION TRACKING</title>
		<link href="https://kushagra.dev/blog/a-supercool-night-with-motion-tracking/"/>
		<updated>2011-06-04T09:09:13+00:00</updated>
		<id>https://kushagra.dev/blog/a-supercool-night-with-motion-tracking/</id>
		<content type="html">&lt;p&gt;Hellooo everyone !&lt;/p&gt;
&lt;p&gt;Last night while surfing on the web and reading flash stuff I came across &lt;a href=&quot;http://blog.soulwire.co.uk/&quot;&gt;&lt;strong&gt;Justin Windle&#39;s blog&lt;/strong&gt;&lt;/a&gt;. He has done such awesome flash work...was really amazed to see it. And one of them is his motion tracking API. As soon as I read about it and saw the demo, I could not stop myself and immediately downloaded it to explore more. I made a small game out of it. This is what I came up with :&lt;/p&gt;
&lt;object data=&quot;https://kushagra.dev/uploads/2011/motionpong.swf&quot; type=&quot;application/x-shockwave-flash&quot; width=&quot;530&quot; height=&quot;300&quot;&gt;
&lt;/object&gt;
&lt;p&gt;&lt;strong&gt;(Move your hand left-right to move the platform.)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The motion tracking algorithm is itself very basic but gives amazing results with little tweaking. One restriction though, you should have only one object moving on the screen (hand, head etc) to properly get it tracked to play the game. More about the API &lt;strong&gt;&lt;a href=&quot;http://blog.soulwire.co.uk/code/actionscript-3/webcam-motion-detection-tracking&quot;&gt;can be read here&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Its actually really cool to make your very own motion sensing game and play it :) I am surely going to explore it more and develop some good stuff with it, soon.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://kushagra.dev/uploads/2011/motion_pong.rar&quot; target=&quot;_blank&quot; class=&quot;button button-big&quot;&gt;Download Source&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Cheers&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>[Creating a LAN] Wireless LAN using ad-hoc network</title>
		<link href="https://kushagra.dev/blog/creating-a-lan-wireless-lan-using-ad-hoc-network/"/>
		<updated>2011-05-28T01:21:59+00:00</updated>
		<id>https://kushagra.dev/blog/creating-a-lan-wireless-lan-using-ad-hoc-network/</id>
		<content type="html">&lt;p&gt;This is the second part of the &lt;strong&gt;CREATING A LAN series - Wireless LAN&lt;/strong&gt;.&lt;br&gt;
You can read the tutorial on Wired LAN &lt;a href=&quot;https://kushagra.dev/blog/2011/05/creating-a-lan-wired-lan-using-crossover-cable/&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Windows 7 gives you an option to form a wireless ad-hoc network without much configuration in few minutes.&lt;br&gt;
Now some real stuff.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Requirements for this tutorial :&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Upto 9 Computer machines having wifi.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Windows 7 OS (Windows Vista will also work)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;(&lt;strong&gt;NOTE&lt;/strong&gt; : The tutorial visuals shown here are of Win 7, though it would work just fine on Windows Vista also.)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;STEP 1 :&lt;/strong&gt;&lt;br&gt;
On any one machine (which you want to create the network on), open the control Panel and go over to &lt;strong&gt;View network status and tasks&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://kushagra.dev/images/wlan_1.png&quot;&gt;&lt;img src=&quot;https://kushagra.dev/images/wlan_1-300x208.png&quot; alt=&quot;&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;STEP 2 :&lt;/strong&gt;&lt;br&gt;
Now click on &lt;strong&gt;Set up a new connection or network&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://kushagra.dev/images/wlan_2.png&quot;&gt;&lt;img src=&quot;https://kushagra.dev/images/wlan_2-300x139.png&quot; alt=&quot;&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;STEP 3 :&lt;/strong&gt;&lt;br&gt;
From the available options, select &lt;strong&gt;Set up a wireless ad hoc (computer-to-computer) network&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://kushagra.dev/images/wlan_3.png&quot;&gt;&lt;img src=&quot;https://kushagra.dev/images/wlan_3-300x189.png&quot; alt=&quot;&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;STEP 4 :&lt;/strong&gt;&lt;br&gt;
Now you need to enter a &lt;strong&gt;Network name&lt;/strong&gt; and a &lt;strong&gt;Security key&lt;/strong&gt; for the new network. Anything of your choice.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://kushagra.dev/images/wlan_4.png&quot;&gt;&lt;img src=&quot;https://kushagra.dev/images/wlan_4-300x209.png&quot; alt=&quot;&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Thats all you need to do to create a wireless network. Now its time to start it up and let others join.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;STEP 5 :&lt;/strong&gt;&lt;br&gt;
(&lt;strong&gt;NOTE&lt;/strong&gt; : Make sure WIFI on the machine is turned on before this step.)&lt;/p&gt;
&lt;p&gt;On the same machine, click the network icon in the system tray. You will see the network name you just created in the list.&lt;br&gt;
Click it to connect to it.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://kushagra.dev/images/wlan_5.png&quot;&gt;&lt;img src=&quot;https://kushagra.dev/images/wlan_5-255x300.png&quot; alt=&quot;&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;On succesfull connection, you would see &lt;strong&gt;Waiting for users&lt;/strong&gt; instead of Connect button.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://kushagra.dev/images/wlan_6.png&quot;&gt;&lt;img src=&quot;https://kushagra.dev/images/wlan_6-284x300.png&quot; alt=&quot;&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;STEP 6 :&lt;/strong&gt;&lt;br&gt;
Now move on to other machines which you want to add to the network. Switch on their WIFI. Click on the network icon in the system tray and find the network we created in the previous step (&lt;strong&gt;test&lt;/strong&gt; in our case). Click it and connect. It will ask for the security key which&lt;br&gt;
is the same as we entered while creating the network.&lt;/p&gt;
&lt;p&gt;If all goes well, you will now be connected to the network successfully.&lt;/p&gt;
&lt;p&gt;Now you can enjoy your favourite lan games with more than 2 machines connected wirelessly.&lt;/p&gt;
&lt;p&gt;Have fun.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>[Creating a LAN] Wired LAN using crossover cable</title>
		<link href="https://kushagra.dev/blog/creating-a-lan-wired-lan-using-crossover-cable/"/>
		<updated>2011-05-18T23:49:05+00:00</updated>
		<id>https://kushagra.dev/blog/creating-a-lan-wired-lan-using-crossover-cable/</id>
		<content type="html">&lt;p&gt;Ever wanted to connect your PCs to form a LAN and play your favourite multiplayer game ?If you got stuck creating a LAN, then this tutorial will guide you through. So all you have to do is just follow the steps and you&#39;ll be on a LAN in no time.&lt;/p&gt;
&lt;p&gt;The tutorial is in 2 parts : &lt;strong&gt;&lt;a href=&quot;http://kushagragour.in/blog/2011/05/creating-a-lan-wired-lan-using-crossover-cable/&quot;&gt;WIRED&lt;/a&gt;&lt;/strong&gt; and &lt;strong&gt;WIRELESS&lt;/strong&gt;.&lt;br&gt;
This one will show how to create a wired LAN using just a crossover cable.&lt;/p&gt;
&lt;p&gt;So lets get going !&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Requirements for this tutorial :&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;2 Computer machines having lan card.&lt;/li&gt;
&lt;li&gt;1 &lt;a href=&quot;http://en.wikipedia.org/wiki/Ethernet_crossover_cable&quot;&gt;Crossover cable&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;(&lt;strong&gt;NOTE&lt;/strong&gt; : The visuals shown here are of Win 7, though it would work just fine on any Windows.)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;STEP 1 :&lt;/strong&gt;&lt;br&gt;
Connect the 2 machines with the crossover cable.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;STEP 2 :&lt;/strong&gt;&lt;br&gt;
On first machine, Open the control Panel and go over to &lt;strong&gt;View network status and tasks&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://kushagra.dev/images/lan_1-300x208.png&quot;&gt;&lt;img src=&quot;https://kushagra.dev/images/lan_1-300x208.png&quot; alt=&quot;&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;STEP 3 :&lt;/strong&gt;&lt;br&gt;
Now click on &lt;strong&gt;Change adapter settings&lt;/strong&gt; in the left panel.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://kushagra.dev/images/lan_2-300x202.png&quot;&gt;&lt;img src=&quot;https://kushagra.dev/images/lan_2-300x202.png&quot; alt=&quot;&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;STEP 4 :&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Select the &lt;strong&gt;Local Area Connection&lt;/strong&gt; adapter, right-click on it and select &lt;strong&gt;Properties&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://kushagra.dev/images/lan_3.png&quot;&gt;&lt;img src=&quot;https://kushagra.dev/images/lan_3-300x198.png&quot; alt=&quot;&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;STEP 5 :&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Now we need to edit some IPv4 properties of the connection. Click on &lt;strong&gt;Properties&lt;/strong&gt; with &lt;strong&gt;Internet Protocol Version 4 (TCP/IPv4)&lt;/strong&gt; selected in the list.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://kushagra.dev/images/lan_4.png&quot;&gt;&lt;img src=&quot;https://kushagra.dev/images/lan_4-300x219.png&quot; alt=&quot;&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;STEP 6 :&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Change the IP addresses to those shown in the picture below and click &lt;strong&gt;OK&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://kushagra.dev/images/lan_5.png&quot;&gt;&lt;img src=&quot;https://kushagra.dev/images/lan_5-300x229.png&quot; alt=&quot;&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;STEP 7 :&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Follow the same steps on the second machine and change its IP addresses as shown in the picture.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://kushagra.dev/images/lan_6.png&quot;&gt;&lt;img src=&quot;https://kushagra.dev/images/lan_6-300x249.png&quot; alt=&quot;&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This is it ! Your both machines are now connected in a LAN.&lt;/p&gt;
&lt;p&gt;You can also set some additional sharing options. For that:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;STEP 8 :&lt;/strong&gt;&lt;br&gt;
Click on &lt;strong&gt;Change advanced sharing options&lt;/strong&gt; in the &lt;strong&gt;Network and Sharing Center&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://kushagra.dev/images/lan_7.png&quot;&gt;&lt;img src=&quot;https://kushagra.dev/images/lan_7-300x227.png&quot; alt=&quot;&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Here you can find several sharing options which you can set according to your preferences.&lt;/p&gt;
&lt;p&gt;One disadvantage of using a crossover cable to form a LAN is that only 2 machines can be connected together. If you want to go over 2, you will need a switch.&lt;/p&gt;
&lt;p&gt;In next tutorial, I shall demonstrate how to form a wireless ad-hoc network using wi-fi which enables more than 2 machines to be connected.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Stay tuned :)&lt;/strong&gt;&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Caricature 3: Hasta la vista, baby !</title>
		<link href="https://kushagra.dev/blog/caricature-1-hasta-la-vista-baby/"/>
		<updated>2011-05-17T15:28:08+00:00</updated>
		<id>https://kushagra.dev/blog/caricature-1-hasta-la-vista-baby/</id>
		<content type="html">&lt;p&gt;One more...&lt;/p&gt;
&lt;img src=&quot;https://kushagra.dev/images/arnoldyy.png&quot; alt=&quot;Arnold&quot; title=&quot;terminator&quot;&gt;
&lt;p&gt;(Made in Flash Professional)&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Caricature 2 - Pride of India</title>
		<link href="https://kushagra.dev/blog/caricature-2-pride-of-india/"/>
		<updated>2011-05-17T14:58:07+00:00</updated>
		<id>https://kushagra.dev/blog/caricature-2-pride-of-india/</id>
		<content type="html">&lt;p&gt;Helos all !&lt;/p&gt;
&lt;p&gt;Here is one more caricature of a person who has made India proud.&lt;/p&gt;
&lt;img src=&quot;https://kushagra.dev/images/amitabh1.png&quot; alt=&quot;Amitabh Bachchan&quot; title=&quot;Hainnnnnnnnnnn!&quot;&gt;
&lt;p&gt;&lt;strong&gt;Who is he ?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;(Made in Flash Professional)&lt;/p&gt;
</content>
	</entry>
</feed>