<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
	<title>Mostly Bugless</title>
	<subtitle>Ramblings on life, sofware and everything else</subtitle>
	
	<link href="https://mostlybugless.com/feed/feed.xml" rel="self" />
	<link href="https://mostlybugless.com/" />
	<updated>2023-01-31T00:00:00Z</updated>
	<id>https://mostlybugless.com/</id>
	<author>
		<name>Daniel Materowski</name>
		<email>daniel@mostlybugless.com</email>
	</author>
	
	<entry>
		<title>World Data Visualization Prize entry</title>
		<link href="https://mostlybugless.com/posts/2023-012-worldsummit/" />
		<updated>2023-01-31T00:00:00Z</updated>
		<id>https://mostlybugless.com/posts/2023-012-worldsummit/</id>
		<content type="html">&lt;h2 id=&quot;world-data-visualization-prize&quot; tabindex=&quot;-1&quot;&gt;World Data Visualization Prize &lt;a class=&quot;direct-link&quot; href=&quot;https://mostlybugless.com/posts/2023-012-worldsummit/#world-data-visualization-prize&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Timing, as they say, is everything. Just as I dusted off my website (not a moment too soon, I assure you), I stumbled upon the&lt;a href=&quot;https://www.worldgovernmentsummit.org/awards/world-data-visualization-prize&quot;&gt;World Data Visualization Prize&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Now, considering I had less than two weeks to the deadline, a full-time job, and the monumental task of keeping my offspring alive (kudos to my wife, the real MVP here, for holding down the fort), I wasn&#39;t exactly betting on a win. But getting onto the longlist and indulging some of my long-neglected ideas? More than satisfying.&lt;/p&gt;
&lt;h2 id=&quot;the-big-idea-predicting-the-unpredictable&quot; tabindex=&quot;-1&quot;&gt;The Big Idea: Predicting the Unpredictable &lt;a class=&quot;direct-link&quot; href=&quot;https://mostlybugless.com/posts/2023-012-worldsummit/#the-big-idea-predicting-the-unpredictable&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I maintain a lengthy backlog of ideas, oddball thoughts, and existential scares. Writing these down is essentially my brain’s delete button. One recurring theme? Predicting the future, or more precisely - visualizing it.&lt;/p&gt;
&lt;p&gt;In a world teeming with technological revolutions, shifting geopolitical landscapes, and the occasional black-swan event (*cough* &lt;em&gt;covid&lt;/em&gt; *cough*), trying to foresee the future might seem, well, ludicrous. But certain things, like demographic trends and CO2 levels, aren’t going to change overnight. And fortunately or not, that AI/Robotics genie isn&#39;t going back in the bottle anytime soon.&lt;/p&gt;
&lt;p&gt;Experts have been pondering these topics for years. So, while predicting the year 2100 might be a bit of a reach, summarizing the next 20-30 years seems like a fair shot. And let&#39;s be real, my real motivation? Understanding just how dicey my son&#39;s future might be, and pondering the hard questions he&#39;s bound to throw my way when he&#39;s a teenager.&lt;/p&gt;
&lt;p&gt;And guess what? One of the competition categories was pretty much dedicated to this very topic.&lt;/p&gt;
&lt;h2 id=&quot;future-of-frontiers&quot; tabindex=&quot;-1&quot;&gt;Future of Frontiers &lt;a class=&quot;direct-link&quot; href=&quot;https://mostlybugless.com/posts/2023-012-worldsummit/#future-of-frontiers&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I&#39;ve posted my visualization on this site. It&#39;s not a technological marvel by any stretch (do yourself a favor and avoid peeking at the code — I committed some unspeakable programming sins to meet the deadline), but it did accomplish a few key things:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Satisfied my itch to test OpenAI ChatGPT APIs in a practical setting (a topic worth its own blog post)&lt;/li&gt;
&lt;li&gt;Visualized expert predictions contextualized by age, giving me the personalized forecast I wanted&lt;/li&gt;
&lt;li&gt;Dabbled in fediverse integration, though, in hindsight, this was more of a distraction than anything else.&lt;/li&gt;
&lt;li&gt;Reminded me why I steer clear of front-end work for years — it still doesn’t play nice with Firefox (seriously, I was just trying to make a table!)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Seeing what the experts at WGS think about the future was fun, scary, and deeply interesting. Give it a spin via the link below, or check out the recorded GIFs in this article for a quick overview. (Note: not optimized for mobile and doesn’t work on Firefox)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://mostlybugless.com/apps/worldsummit/&quot;&gt;Link (doesnt work on mobile or non-Chromium browsers)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://mostlybugless.com/apps/worldsummit/?cat=Artificial%20intelligence&amp;amp;inn=Commercial%20AI&amp;amp;pred=2030&quot;&gt;Deeplink to sample entry&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;snapshots&quot; tabindex=&quot;-1&quot;&gt;Snapshots &lt;a class=&quot;direct-link&quot; href=&quot;https://mostlybugless.com/posts/2023-012-worldsummit/#snapshots&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id=&quot;contextualize-predictions-with-your-or-anybody-else-s-age&quot; tabindex=&quot;-1&quot;&gt;Contextualize predictions with your (or anybody else&#39;s) age &lt;a class=&quot;direct-link&quot; href=&quot;https://mostlybugless.com/posts/2023-012-worldsummit/#contextualize-predictions-with-your-or-anybody-else-s-age&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;img class=&quot;content-image pure-img&quot; src=&quot;https://mostlybugless.com/img/posts/2023-012/start.gif&quot; /&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;browse-and-explore-future&quot; tabindex=&quot;-1&quot;&gt;Browse and explore future &lt;a class=&quot;direct-link&quot; href=&quot;https://mostlybugless.com/posts/2023-012-worldsummit/#browse-and-explore-future&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;img class=&quot;content-image pure-img&quot; src=&quot;https://mostlybugless.com/img/posts/2023-012/browse%201.gif&quot; /&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;img class=&quot;content-image pure-img&quot; src=&quot;https://mostlybugless.com/img/posts/2023-012/browse%202.gif&quot; /&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;search-for-specific-topics&quot; tabindex=&quot;-1&quot;&gt;Search for specific topics &lt;a class=&quot;direct-link&quot; href=&quot;https://mostlybugless.com/posts/2023-012-worldsummit/#search-for-specific-topics&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;img class=&quot;content-image pure-img&quot; src=&quot;https://mostlybugless.com/img/posts/2023-012/search.gif&quot; /&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;learn-more-find-more-connections&quot; tabindex=&quot;-1&quot;&gt;Learn more, find more connections &lt;a class=&quot;direct-link&quot; href=&quot;https://mostlybugless.com/posts/2023-012-worldsummit/#learn-more-find-more-connections&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;img class=&quot;content-image pure-img&quot; src=&quot;https://mostlybugless.com/img/posts/2023-012/details.gif&quot; /&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;get-smart-answers-to-your-questions-using-llm-supported-chat&quot; tabindex=&quot;-1&quot;&gt;Get smart answers to your questions using LLM-supported chat &lt;a class=&quot;direct-link&quot; href=&quot;https://mostlybugless.com/posts/2023-012-worldsummit/#get-smart-answers-to-your-questions-using-llm-supported-chat&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;⚠️ The chat is already disabled to control costs.&lt;/li&gt;
&lt;li&gt;
&lt;img class=&quot;content-image pure-img&quot; src=&quot;https://mostlybugless.com/img/posts/2023-012/chat.gif&quot; /&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;use-social-media-and-fediverse&quot; tabindex=&quot;-1&quot;&gt;Use social media and fediverse &lt;a class=&quot;direct-link&quot; href=&quot;https://mostlybugless.com/posts/2023-012-worldsummit/#use-social-media-and-fediverse&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;img class=&quot;content-image pure-img&quot; src=&quot;https://mostlybugless.com/img/posts/2023-012/social.gif&quot; /&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;following-links-are-used-to-showcase-webmentions-functionality&quot; tabindex=&quot;-1&quot;&gt;$ Following links are used to showcase webmentions functionality &lt;a class=&quot;direct-link&quot; href=&quot;https://mostlybugless.com/posts/2023-012-worldsummit/#following-links-are-used-to-showcase-webmentions-functionality&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://mostlybugless.com/apps/worldsummit/?cat=Artificial%20intelligence&amp;amp;inn=Commercial%20AI&amp;amp;pred=2030&quot;&gt;Hiring AI&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://mostlybugless.com/apps/worldsummit/?cat=Social%20technology&amp;amp;inn=Smart%20Cities&amp;amp;pred=2050&quot;&gt;Smart City&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://mostlybugless.com/apps/worldsummit/?cat=Governance&amp;amp;inn=Triple%20Bottom%20Line%20&amp;amp;pred=2040&quot;&gt;Triple Sector Democracy&lt;/a&gt;&lt;/p&gt;

		</content>
	</entry>
	
	<entry>
		<title>Hello (Again) World</title>
		<link href="https://mostlybugless.com/posts/2023-011-hello-again/" />
		<updated>2023-01-31T00:00:00Z</updated>
		<id>https://mostlybugless.com/posts/2023-011-hello-again/</id>
		<content type="html">&lt;p&gt;😁&lt;/p&gt;
&lt;p&gt;After a lengthy hiatus, I have decided to bring my blog back to life.&lt;/p&gt;
&lt;p&gt;In its original form, I crafted a custom blogging engine from scratch using F#.
It was a thrilling side project and deliberately overengineered solution. However as life and professional commitments took precedence, the project lost its place in my list of priorities. What ultimately sealed the fate of my initial site was the excessive hosting costs. I kept the domain name, as I was attached to it already, and seems I was right to expect I will come back to write here once again.&lt;/p&gt;
&lt;p&gt;Now, I&#39;ve chosen to build a static site with Eleventy. Diving back into front-end/full-stack development after years spent focusing on data platforms has been both nostalgic and entertaining. But I have to admit - first and foremost frustrating. Surprisingly little has changed - frameworks evolved, some new took the web dev community by storm. But javascript is still a horrible language, project setup and framework choice are experiences that probably costed me few milimetrs of my remaining hairline. And don&#39;t get me started about styling and browsers.&lt;/p&gt;
&lt;p&gt;With that said, please bear with me as there are still several issues in the new version, particularly in the CSS department.&lt;/p&gt;
&lt;p&gt;If you&#39;re interested in subscribing to updates, I&#39;m experimenting with a more personal approach than traditional mailing list managers. Drop me an email, and I&#39;ll periodically share new posts and other updates with you - or just use the RSS feed.&lt;/p&gt;

		</content>
	</entry>
	
	<entry>
		<title>The softer side of IT - public speaking</title>
		<link href="https://mostlybugless.com/posts/2019-010-public-speaking/" />
		<updated>2019-09-05T00:00:00Z</updated>
		<id>https://mostlybugless.com/posts/2019-010-public-speaking/</id>
		<content type="html">&lt;h2 id=&quot;the-case-for-public-speaking&quot; tabindex=&quot;-1&quot;&gt;The case for public speaking &lt;a class=&quot;direct-link&quot; href=&quot;https://mostlybugless.com/posts/2019-010-public-speaking/#the-case-for-public-speaking&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;This year, I’ve run workshops, seminars, and participated in more presentations than a PowerPoint at a business convention.&lt;/p&gt;
&lt;p&gt;I have a secret, though. No one believes it at first. Not only am I an introvert, but my presentation skills have all the natural talent of a brick.&lt;/p&gt;
&lt;p&gt;Learning public speaking was one of the best decisions I made early in my career, and today I hope to convince you to do the same. But first, let’s clear one thing up:&lt;/p&gt;
&lt;h2 id=&quot;public-speaking-is-not-normal&quot; tabindex=&quot;-1&quot;&gt;Public speaking is not normal &lt;a class=&quot;direct-link&quot; href=&quot;https://mostlybugless.com/posts/2019-010-public-speaking/#public-speaking-is-not-normal&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;You’ve probably heard that people fear public speaking more than death. Poor science reporting and incompetent journalism aside, there’s a kernel of truth in there worth exploring. If your ancestor was being stared down by the whole tribe, their body would have kicked into overdrive — because either a saber-toothed tiger was behind them or they were about to get thrown out for solitary doom. Neither of which bode well for a future beyond next Tuesday.&lt;/p&gt;
&lt;p&gt;Let&#39;s be clear: &lt;strong&gt;being afraid of public speaking is absolutely normal&lt;/strong&gt;. If you’re not, you either have the experience of a seasoned pro or somehow throughout schools, family gatherings and work meetings you kept the blissful ignorance of someone who&#39;s never had to do it.&lt;/p&gt;
&lt;h2 id=&quot;public-speaking-matters&quot; tabindex=&quot;-1&quot;&gt;Public speaking matters &lt;a class=&quot;direct-link&quot; href=&quot;https://mostlybugless.com/posts/2019-010-public-speaking/#public-speaking-matters&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;For those of us who find solace in the glow of a dual-monitor setup, working on soft skills can be about as appealing as a root canal. Why spend time practicing public speaking when you could be optimizing your gnarly Spark performance bottleneck or setting up a PI-cluster for distributed machine learning?&lt;/p&gt;
&lt;p&gt;Well, because unless you&#39;re the very last IT professional on Earth, you need to communicate. Think about it:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Convince stakeholders vs. bore them into a coma.&lt;/li&gt;
&lt;li&gt;Inspire your teammates vs. make them regret ever logging on.&lt;/li&gt;
&lt;li&gt;Excite your group about upcoming changes vs send them straight to LinkedIn.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Your brilliant ideas are only as good as your ability to convey them.&lt;/strong&gt; This is not just idle chit-chat; it&#39;s a fundamental career skill.&lt;/p&gt;
&lt;p&gt;Don&#39;t believe me? Listen to this gem from Warren Buffett, who ranks communication training as his most valuable degree:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;They gave us this book of speeches—keynote speech, election speech, lieutenant governor&#39;s speech—and we were supposed to deliver these things every week. The way it works is that you learn to get out of yourself. I mean, why should you be able to talk alone with somebody five minutes before and then freeze in front of a group? So they teach you the psychological tricks to overcome this. Some of it is just practice—just doing it and practicing. We really helped each other through. And it worked. That&#39;s the most important degree that I have.&lt;/p&gt;&lt;footer&gt;&lt;cite&gt;Warren Buffett in The Snowball: Warren Buffett and the Business of Life &lt;/cite&gt;&lt;/footer&gt;&lt;/blockquote&gt;
&lt;p&gt;Warren Buffett, a man who could buy small countries with his pocket change, claims that communication skills &lt;a href=&quot;https://youtu.be/og4tto-Lg_Q?t=1756&quot;&gt;can increase your personal value by 50%&lt;/a&gt;. And who am I to argue with the Oracle of Omaha?&lt;/p&gt;
&lt;h2 id=&quot;it-s-just-a-skill&quot; tabindex=&quot;-1&quot;&gt;It&#39;s just a skill &lt;a class=&quot;direct-link&quot; href=&quot;https://mostlybugless.com/posts/2019-010-public-speaking/#it-s-just-a-skill&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Imagine deciding to learn the saxophone. If your first attempt was in front of a packed Wembley Stadium, it would likely be memorable for all the wrong reasons.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://mostlybugless.com/img/legacy/articles/publicspeaking/saxophone-1.png&quot; alt=&quot;Poor musician performance&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Neither the audience, you, nor your unfortunate manager would be thrilled.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://mostlybugless.com/img/legacy/articles/publicspeaking/saxophone-2.png&quot; alt=&quot;Musician taken off stage&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Although if you spent 30 hours learning, you could probably perform a simple tune for your friends. &lt;strong&gt;Start filling your skill bar&lt;/strong&gt; — you want it maxed out before any career-defining performances.&lt;/p&gt;
&lt;p&gt;Opportunities for public speaking, whether in front of large audiences or during tough small-group meetings, often coincide with crucial career moments. Interviews, pitches, team addresses, and tech talks are all opportunities to shine — or bomb. If you had one shot, one opportunity, would you capture it, or just let it slip? &lt;sub&gt;&lt;em&gt;Sorry, I couldn&#39;t resist&lt;/em&gt; &lt;/sub&gt;&lt;/p&gt;
&lt;p&gt;So how do you make sure you&#39;re ready when the spotlight hits?&lt;/p&gt;
&lt;p&gt;Start small. Give presentations to your team and solicit feedback. Or check out your &lt;a href=&quot;https://www.toastmasters.org/find-a-club&quot;&gt;local Toastmasters club&lt;/a&gt;. Sign up for a class. Record yourself prepping for that tech talk and practice* like your dream job depends on it — because it just might.&lt;/p&gt;
&lt;p&gt;Yes, some folks are naturally gifted. Extroverts might have a smoother ride since they practice early, but it doesn’t matter. If you’re willing to put in the hours, you can learn anything. I recorded my first presentation when I started actively learning public speaking. Two years later, watching it was just painful. Cringing hard, I hit ‘delete’ with no regrets.&lt;/p&gt;
&lt;p&gt;Buffett was right. It’s one of the most vital skills you can develop.&lt;/p&gt;
&lt;p&gt;[2024 Addendum]
Five years later, I can definitively confirm and double down on everything I wrote here. I attribute much of my career success to the ability to communicate effectively, and presenting in front of large and/or demanding audiences is a skill that I use almost daily.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;* There is some nuance to how you practice effectively. That’s why my core advice is to join a club or find a mentor as a first step. For instance, repeating your entire presentation from beginning to end over and over is likely to not only waste your time but also make your delivery worse.&lt;/p&gt;

		</content>
	</entry>
	
	<entry>
		<title>The softer side of IT - effective learning</title>
		<link href="https://mostlybugless.com/posts/2019-009-effective-learning/" />
		<updated>2019-06-18T00:00:00Z</updated>
		<id>https://mostlybugless.com/posts/2019-009-effective-learning/</id>
		<content type="html">&lt;h2 id=&quot;effective-learning&quot; tabindex=&quot;-1&quot;&gt;Effective learning &lt;a class=&quot;direct-link&quot; href=&quot;https://mostlybugless.com/posts/2019-009-effective-learning/#effective-learning&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In the ever-changing IT ocean, you must keep swimming to stay in your current place. Frameworks change, practices develop, and paradigms shift - a good developer is a learning machine, no matter if they are working with machine learning or javascript.&lt;/p&gt;
&lt;p&gt;I&#39;d have to caveat that with few words on unchanging principles and that most of the things we are discussing as novelty have been done 40 years ago, but that&#39;s worth another post. But even if you optimize for the right knowledge and avoid trying to remember API details of a tool that will be gone in two years - there is still enough of both constant and constantly changing but essential topics that will last you a lifetime of learning.&lt;/p&gt;
&lt;p&gt;And thus, one of the key issues I have with our education system, especially the academia (and as far as I can tell, this is not an isolated issue here), is that they absolutely fail to teach about softer aspects of technical roles - even effective learning.&lt;/p&gt;
&lt;h2 id=&quot;spaced-repetition&quot; tabindex=&quot;-1&quot;&gt;Spaced repetition &lt;a class=&quot;direct-link&quot; href=&quot;https://mostlybugless.com/posts/2019-009-effective-learning/#spaced-repetition&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Spaced repetition is, as far as I could find, the best system we have for retaining knowledge. And one that&#39;s quite well researched. Long story short, &lt;strong&gt;if you are tested right after you start forgetting, the rate at which your memories decay will slow down&lt;/strong&gt;. So from forgetting 60% of the content in 1 hour&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://mostlybugless.com/img/legacy/articles/effectivelearning/forgetting-curve.png&quot; alt=&quot;Basic forgetting curve&quot; /&gt;&lt;/p&gt;
&lt;p&gt;You can go to&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://mostlybugless.com/img/legacy/articles/effectivelearning/forgetting-curve-repetition.png&quot; alt=&quot;Forgetting curve with single repetition&quot; /&gt;&lt;/p&gt;
&lt;p&gt;and&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://mostlybugless.com/img/legacy/articles/effectivelearning/forgetting-curve-spaced-repetition.png&quot; alt=&quot;Spaced repetition curves&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Finally managing to retain whatever nugget of wisdom you were trying to memorize.&lt;/p&gt;
&lt;p&gt;The fact that you need to learn how to learn is a pretty Big Thing. We are what we remember - you can&#39;t be a mathematician without remembering the basic formulas. Now a trick question: do you remember all points of OWASP Top 10? Of software craftsmanship manifesto? Or even the Agile Manifesto? In contrast to what happened with manual multiplication and calculators, &lt;strong&gt;We can&#39;t outsource things that are supposed to drive our behavior&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;I&#39;m not going to waste mine or your time to scratch up a good introduction to spaced repetition, while a fantastic 20-minute starter &lt;a href=&quot;https://ncase.me/remember/&quot;&gt;like this already exists&lt;/a&gt;, and you can find further details on making great flash cards &lt;a href=&quot;https://www.supermemo.com/en/archives1990-2015/articles/20rules&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;However, let&#39;s explore today the issue of turning this theoretical approach into material results. And let&#39;s face it, consistent 10-30 minutes per day of intensive, inconvenient practice is an impossible plan for many, if not most people - me included.&lt;/p&gt;
&lt;h2 id=&quot;willpower&quot; tabindex=&quot;-1&quot;&gt;Willpower &lt;a class=&quot;direct-link&quot; href=&quot;https://mostlybugless.com/posts/2019-009-effective-learning/#willpower&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I heard about spaced repetition and started using Anki years ago. I&#39;m not going to lie - even though the promise of gaining a severe edge in the knowledge economy is alluring, I&#39;ve been &lt;strong&gt;consistently failing&lt;/strong&gt; to follow up on regular repetition (or even adding new cards to the set).&lt;/p&gt;
&lt;p&gt;Willpower is a funny thing.&lt;/p&gt;
&lt;p&gt;In the meantime, I tried multiple habit-building techniques or apps, from &#39;best in productivity&#39;, through notebooks, reminders, and wall-mounted scorecards, to social commitments.&lt;/p&gt;
&lt;p&gt;Yes, it did have ~some~ results. No, I&#39;m not happy with them.&lt;/p&gt;
&lt;h2 id=&quot;tiny-habits&quot; tabindex=&quot;-1&quot;&gt;Tiny habits &lt;a class=&quot;direct-link&quot; href=&quot;https://mostlybugless.com/posts/2019-009-effective-learning/#tiny-habits&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;A few months ago, I stumbled upon a Tiny habits program by BJ Fogg. The basic idea about Tiny Habits is that the behaviors you try to implement are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;done at least once per day&lt;/li&gt;
&lt;li&gt;take &amp;lt; 30 seconds&lt;/li&gt;
&lt;li&gt;require little effort&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And are triggered by your existing automatic actions (brushing teeth, setting an alarm clock, opening a fridge, etc.)&lt;/p&gt;
&lt;p&gt;In short - &lt;strong&gt;habit-forming done right&lt;/strong&gt;. There are many important details, including making the process fun and focusing on experimentation, but once again, there is no point in me taking the stage. Just sign up for &lt;a href=&quot;https://www.tinyhabits.com/join&quot;&gt;a free 5-day course&lt;/a&gt; and let yourself be amazed.&lt;/p&gt;
&lt;h2 id=&quot;unexpected-synergy&quot; tabindex=&quot;-1&quot;&gt;Unexpected synergy &lt;a class=&quot;direct-link&quot; href=&quot;https://mostlybugless.com/posts/2019-009-effective-learning/#unexpected-synergy&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Tiny Habits are currently my number 1 recommendation for making lasting life changes. However, making a habit of daily spaced repetitions is a whole another level of improvement. Hopefully, you will find this combination of a memorization technique with a habit-building system as useful as I and my significant other did!&lt;/p&gt;
&lt;p&gt;For reference, I&#39;m using &lt;a href=&quot;https://apps.ankiweb.net/&quot;&gt;Anki + Anki Droid&lt;/a&gt; , with most of the flashcards added on desktop and repetitions done on mobile each morning and evening.&lt;/p&gt;
&lt;p&gt;If you are interested in soft skills topics, take a look on my previous post &lt;a href=&quot;https://mostlybugless.com/posts/2018-007-tm-overview&quot;&gt;Overview of time management&lt;/a&gt; and in any case feel free to &lt;a href=&quot;https://mostlybugless.com/posts/2019-009-effective-learning/#comments&quot;&gt;comment&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&quot;links-summary&quot; tabindex=&quot;-1&quot;&gt;Links summary &lt;a class=&quot;direct-link&quot; href=&quot;https://mostlybugless.com/posts/2019-009-effective-learning/#links-summary&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://ncase.me/remember/&quot;&gt;The best introduction to practical spaced repetition&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.supermemo.com/en/archives1990-2015/articles/20rules&quot;&gt;Guidelines for making great cards&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.tinyhabits.com/&quot;&gt;Tiny habits&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

		</content>
	</entry>
	
	<entry>
		<title>Mental models in software development</title>
		<link href="https://mostlybugless.com/posts/2018-008-mental-models/" />
		<updated>2018-12-31T00:00:00Z</updated>
		<id>https://mostlybugless.com/posts/2018-008-mental-models/</id>
		<content type="html">&lt;p&gt;&lt;img src=&quot;https://mostlybugless.com/img/legacy/articles/mentalmodels/mental_models_feature_image.jpg&quot; alt=&quot;Mental models feature image&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Software development is an amazingly complex enterprise. On the one hand, we have the inherent complexity of getting pieces of silicon to do our bidding and 50 levels of hardware, networks, systems, and frameworks to coordinate. On the other - humans. And those come with relationships, ambitions, visions, and fears.&lt;/p&gt;
&lt;p&gt;To get things done reliably, as an industry, we came up with a host of patterns and ideas, big and small. DRY, KISS, Clean Code, Clean Architecture, Design Patterns, TDD, Agile, Software Craftsmanship... and so on and so forth. There is, however, one useful perspective that&#39;s even one level higher - let me introduce you to Mental Models.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A mental model is simply a representation of how something works. We cannot keep all of the details of the world in our brains, so we use models to simplify the complex into understandable and organizable chunks.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://fs.blog/mental-models/&quot;&gt;FarnamStreet&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;At first sight, it doesn&#39;t seem to be an extremely revolutionary observation. Yes, we keep a simplified version of reality in our minds; tell me something I didn&#39;t know.&lt;/p&gt;
&lt;p&gt;I find the lens of mental models to be an extremely handy tool. The overall framework, as defined on Farnam Street (which you can see linked around my previous posts quite often), seems obvious - find the big cross-domain concepts, understand them and use them daily. The catch comes in work required since this is pretty much a life-long process.&lt;/p&gt;
&lt;p&gt;So why even bother? I feel we tend to get overfocused and lost in specific topics or trending approaches in IT. When discussing microservices, DevOps, agile, or SCRUM, you can feel the peer pressure and FOMO. Far too many teams follow along and drive their agenda with hot blog posts or the most recent Gartner materials.&lt;/p&gt;
&lt;p&gt;Looking at this from the perspective of mental models is a chance to take a step back and evaluate whatever we are doing from one level higher - hopefully noticing the forest surrounding the current tree in front of us. And as a side bonus, you have a well maintained toolbox of cross-domain tools to apply when needed.&lt;/p&gt;
&lt;p&gt;Few relevant examples that stand out for me:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;TDD, A/B testing, monitoring, code reviews, and retrospectives - all fall under the general model of &lt;strong&gt;Feedback&lt;/strong&gt;. Looking at those from the perspective of the feedback loop and control engineering principles around it, what would you do differently? Is the feedback loop working for you? Is the information timely and accurate?&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Second Order Effects&lt;/strong&gt; - a lot of the things we do can have positive first-order effects (we shipped without postponing a deadline) and negative or deadly further consequences (code became a mess, and we are now moving at a snail&#39;s pace). Having this model embedded in your thought process makes you more likely to notice the problem before it materializes and gives you plenty of ammunition to push back or at least plan mitigation of negative consequences down the line.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I&#39;ve seen it argued that it&#39;s just sensible analysis and planning, but I find that having a common language and model to use in tradeoff discussion is extremely important. Asking explicitly &amp;quot;&lt;strong&gt;What will be next order effects of this decision?&lt;/strong&gt;&amp;quot; usually yields different answers than &amp;quot;What will be the consequences?&amp;quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Antifragility&lt;/strong&gt; - is the system we are building &lt;em&gt;fragile&lt;/em&gt; (fails with little push), &lt;em&gt;robust&lt;/em&gt; (can tolerate a lot), or does our process make it better with each failure (&lt;em&gt;antifragile&lt;/em&gt;)? How can we use the practices we are considering to get closer to antifragility?&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The cited FS guide is an excellent starting point with a broad overview of 109 mental models split into different areas (e.g., Human Nature, Physics, and Numeracy).&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://fs.blog/mental-models/&quot;&gt;Check it out here&lt;/a&gt;&lt;/p&gt;

		</content>
	</entry>
	
	<entry>
		<title>Time Management Knowledge Pill</title>
		<link href="https://mostlybugless.com/posts/2018-007-tm-overview/" />
		<updated>2018-09-14T00:00:00Z</updated>
		<id>https://mostlybugless.com/posts/2018-007-tm-overview/</id>
		<content type="html">&lt;p style=&quot;background:yellow; font-size:x-small; color:red&quot;&gt; This post is migrated from v1 of this site - there might be couple issues left around formatting or links. Since 2018 also my understanding of time management has become much more nuanced and I would either caveat or outright disagree with some of the content. Consider yourself warned. &lt;/p&gt;
&lt;p&gt;Reactions to time management/self-improvement topics vary, but especially among the more skeptical cultures (like Poland) and communities (programmers), you can get some flak just by mentioning them. And I&#39;d dare to say there is some substance behind allergic reactions I have sometimes seen - a lot of the accusations against coaching, Time Management and general self-help industries are not coming from thin air.&lt;/p&gt;
&lt;p&gt;Still, unless you are completely satisfied with how your life is going right now, some of the proven techniques and
grounded in science ideas can help. At least a little bit. My goal here is not to persuade you to anything, nor
promise you life-changing results. However, I hope to show you what I stumbled upon in the last few years and what I&#39;m convinced has at least some merit to it.&lt;/p&gt;
&lt;p&gt;Keep in mind that none of the below concepts are deeply explained. &lt;strong&gt;There are whole books dedicated to every single one of them&lt;/strong&gt;, thus I only aim to to gather my thoughts in a roughly sensible manner. And if any of below inspires you to dig deeper, that would be just a bonus.&lt;/p&gt;
  &lt;section&gt;
    &lt;h2 id=&quot;table&quot;&gt;Table of contents&lt;/h2&gt;
    &lt;ol&gt;
      &lt;li&gt;&lt;a href=&quot;https://mostlybugless.com/posts/2018-007-tm-overview/#intro&quot;&gt;Introduction&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://mostlybugless.com/posts/2018-007-tm-overview/#table&quot;&gt;This table&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://mostlybugless.com/posts/2018-007-tm-overview/#tenets&quot;&gt;Core Tenets&lt;/a&gt;
        &lt;ol&gt;
          &lt;li&gt;&lt;a href=&quot;https://mostlybugless.com/posts/2018-007-tm-overview/#tenets-no-tm&quot;&gt;There is no such thing as time management&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;https://mostlybugless.com/posts/2018-007-tm-overview/#tenets-tm-skill&quot;&gt;Time management is a skill&lt;/a&gt;&lt;/li&gt;
        &lt;/ol&gt;
      &lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://mostlybugless.com/posts/2018-007-tm-overview/#topics&quot;&gt;Main topics&lt;/a&gt;
        &lt;ol&gt;
          &lt;li&gt;&lt;a href=&quot;https://mostlybugless.com/posts/2018-007-tm-overview/#topics-energy&quot;&gt;Energy&lt;/a&gt;
            &lt;ol&gt;
              &lt;li&gt;&lt;a href=&quot;https://mostlybugless.com/posts/2018-007-tm-overview/#topics-energy-sleep&quot;&gt;Sleep&lt;/a&gt;&lt;/li&gt;
              &lt;li&gt;&lt;a href=&quot;https://mostlybugless.com/posts/2018-007-tm-overview/#topics-energy-exercise&quot;&gt;Exercise&lt;/a&gt;&lt;/li&gt;
              &lt;li&gt;&lt;a href=&quot;https://mostlybugless.com/posts/2018-007-tm-overview/#topics-energy-food&quot;&gt;Food&lt;/a&gt;&lt;/li&gt;
              &lt;li&gt;&lt;a href=&quot;https://mostlybugless.com/posts/2018-007-tm-overview/#topics-energy-managing&quot;&gt;Managing energy&lt;/a&gt;&lt;/li&gt;
            &lt;/ol&gt;
          &lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;https://mostlybugless.com/posts/2018-007-tm-overview/#topics-habits&quot;&gt;Habits&lt;/a&gt;
            &lt;ol&gt;
              &lt;li&gt;&lt;a href=&quot;https://mostlybugless.com/posts/2018-007-tm-overview/#topics-habits-overcoming&quot;&gt;Overcoming bad habits&lt;/a&gt;&lt;/li&gt;
              &lt;li&gt;&lt;a href=&quot;https://mostlybugless.com/posts/2018-007-tm-overview/#topics-habits-making&quot;&gt;Making new habits&lt;/a&gt;&lt;/li&gt;
              &lt;li&gt;&lt;a href=&quot;https://mostlybugless.com/posts/2018-007-tm-overview/#topics-habits-keystone&quot;&gt;Keystone habit&lt;/a&gt;&lt;/li&gt;
              &lt;li&gt;&lt;a href=&quot;https://mostlybugless.com/posts/2018-007-tm-overview/#topics-habits-chaining&quot;&gt;Habit chaining&lt;/a&gt;&lt;/li&gt;
              &lt;li&gt;&lt;a href=&quot;https://mostlybugless.com/posts/2018-007-tm-overview/#topics-habits-addictions&quot;&gt;Bad habit or an addiction?&lt;/a&gt;&lt;/li&gt;
            &lt;/ol&gt;
          &lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;https://mostlybugless.com/posts/2018-007-tm-overview/#topics-mindsets&quot;&gt;Mindsets&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;https://mostlybugless.com/posts/2018-007-tm-overview/#topics-meaning&quot;&gt;Meaning&lt;/a&gt;
            &lt;ol&gt;
              &lt;li&gt;&lt;a href=&quot;https://mostlybugless.com/posts/2018-007-tm-overview/#topics-meaning-flow&quot;&gt;Flow&lt;/a&gt;&lt;/li&gt;
              &lt;li&gt;&lt;a href=&quot;https://mostlybugless.com/posts/2018-007-tm-overview/#topics-meaning-eisenhower&quot;&gt;The Eisenhower Method&lt;/a&gt;&lt;/li&gt;
              &lt;li&gt;&lt;a href=&quot;https://mostlybugless.com/posts/2018-007-tm-overview/#topics-meaning-busy&quot;&gt;Being busy vs being productive&lt;/a&gt;&lt;/li&gt;
            &lt;/ol&gt;
          &lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;https://mostlybugless.com/posts/2018-007-tm-overview/#topics-feedback&quot;&gt;Feedback and planning&lt;/a&gt;
            &lt;ol&gt;
              &lt;li&gt;&lt;a href=&quot;https://mostlybugless.com/posts/2018-007-tm-overview/#topics-feedback-state&quot;&gt;Current state and Quantification&lt;/a&gt;&lt;/li&gt;
              &lt;li&gt;&lt;a href=&quot;https://mostlybugless.com/posts/2018-007-tm-overview/#topics-feedback-goals&quot;&gt;Goals&lt;/a&gt;
                &lt;ol&gt;
                  &lt;li&gt;&lt;a href=&quot;https://mostlybugless.com/posts/2018-007-tm-overview/#topics-feedback-goals-okr&quot;&gt;Objectives and key results (OKR) &lt;/a&gt;&lt;/li&gt;
                &lt;/ol&gt;
              &lt;/li&gt;
              &lt;li&gt;&lt;a href=&quot;https://mostlybugless.com/posts/2018-007-tm-overview/#topics-feedback-systems&quot;&gt;Systems&lt;/a&gt;&lt;/li&gt;
            &lt;/ol&gt;
          &lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;https://mostlybugless.com/posts/2018-007-tm-overview/#topics-irrationality&quot;&gt;Irrationality&lt;/a&gt;
            &lt;ol&gt;
              &lt;li&gt;&lt;a href=&quot;https://mostlybugless.com/posts/2018-007-tm-overview/#topics-irrationality-procrastination&quot;&gt;Procrastination&lt;/a&gt;&lt;/li&gt;
            &lt;/ol&gt;
          &lt;/li&gt;
        &lt;/ol&gt;
      &lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://mostlybugless.com/posts/2018-007-tm-overview/#tactics&quot;&gt;Base tactics&lt;/a&gt;
        &lt;ol&gt;
          &lt;li&gt;&lt;a href=&quot;https://mostlybugless.com/posts/2018-007-tm-overview/#tactics-pomodoros&quot;&gt;Pomodoros&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;https://mostlybugless.com/posts/2018-007-tm-overview/#tactics-blocking&quot;&gt;Time blocking&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;https://mostlybugless.com/posts/2018-007-tm-overview/#tactics-environment&quot;&gt;Environment control&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;https://mostlybugless.com/posts/2018-007-tm-overview/#tactics-planning&quot;&gt;Regular planning&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;https://mostlybugless.com/posts/2018-007-tm-overview/#tactics-tactics-buffers&quot;&gt;Buffers&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;https://mostlybugless.com/posts/2018-007-tm-overview/#tactics-todo&quot;&gt;To-do lists&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;https://mostlybugless.com/posts/2018-007-tm-overview/#tactics-gtd&quot;&gt;Getting things done&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;https://mostlybugless.com/posts/2018-007-tm-overview/#tactics-ulysses&quot;&gt;Ulysses contracts&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;https://mostlybugless.com/posts/2018-007-tm-overview/#tactics-automation&quot;&gt;Checklists and automation&lt;/a&gt;&lt;/li&gt;
        &lt;/ol&gt;
      &lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://mostlybugless.com/posts/2018-007-tm-overview/#myths&quot;&gt;Main myths&lt;/a&gt;
        &lt;ol&gt;
          &lt;li&gt;&lt;a href=&quot;https://mostlybugless.com/posts/2018-007-tm-overview/#myths-visualization&quot;&gt;Visualization / self-affirmation&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;https://mostlybugless.com/posts/2018-007-tm-overview/#myths-working&quot;&gt;Working more&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;https://mostlybugless.com/posts/2018-007-tm-overview/#myths-singletrick&quot;&gt;There is a single trick, 10 step guide, or a blog post that will change your
              life&lt;/a&gt;&lt;/li&gt;
        &lt;/ol&gt;
      &lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://mostlybugless.com/posts/2018-007-tm-overview/#minor&quot;&gt;Minor concepts&lt;/a&gt;
        &lt;ol&gt;
          &lt;li&gt;&lt;a href=&quot;https://mostlybugless.com/posts/2018-007-tm-overview/#minor-resistance&quot;&gt;Resistance&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;https://mostlybugless.com/posts/2018-007-tm-overview/#minor-essentialism&quot;&gt;Essentialism&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;https://mostlybugless.com/posts/2018-007-tm-overview/#minor-pareto&quot;&gt;Pareto principle&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;https://mostlybugless.com/posts/2018-007-tm-overview/#minor-fktit&quot;&gt;F*ck it effect&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;https://mostlybugless.com/posts/2018-007-tm-overview/#minor-inbox&quot;&gt;Inbox 0&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;https://mostlybugless.com/posts/2018-007-tm-overview/#minor-barbell&quot;&gt;Barbell strategy&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;https://mostlybugless.com/posts/2018-007-tm-overview/#minor-vianegativa&quot;&gt;Via negativa&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;https://mostlybugless.com/posts/2018-007-tm-overview/#minor-antifragile&quot;&gt;Antifragility&lt;/a&gt;&lt;/li&gt;
        &lt;/ol&gt;
      &lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://mostlybugless.com/posts/2018-007-tm-overview/#toolset&quot;&gt;Toolset&lt;/a&gt;
        &lt;ol&gt;
          &lt;li&gt;&lt;a href=&quot;https://mostlybugless.com/posts/2018-007-tm-overview/#toolset-calendar&quot;&gt;Calendar&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;https://mostlybugless.com/posts/2018-007-tm-overview/#toolset-todo&quot;&gt;Todo list&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;https://mostlybugless.com/posts/2018-007-tm-overview/#toolset-other&quot;&gt;Other&lt;/a&gt;&lt;/li&gt;
        &lt;/ol&gt;
      &lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://mostlybugless.com/posts/2018-007-tm-overview/#summary&quot;&gt;Other notes and wrap-up&lt;/a&gt;&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/section&gt;
  &lt;section&gt;
    &lt;h2 id=&quot;tenets&quot;&gt;Core Tenets&lt;/h2&gt;
    &lt;h3 id=&quot;tenets-no-tm&quot;&gt;There is no such thing as time management&lt;/h3&gt;
    &lt;p&gt;Time moves in one direction and disregarding experiments with sublight velocities no one has ever affected the
      way it works. What we can manage is ourselves - our actions, attitudes, and emotions. Thinking in terms of
      managing time as moving blocks of seconds between buckets of activities skips the beautiful complexity of our
      messy brains and their evolutionary legacy.&lt;/p&gt;
    &lt;p&gt;Another critical point here is that time is the ultimate constant - everyone, you and me, have the same 24 hours of a day. While the external forces and their personal history make each person&#39;s challenges unique, the allocation of those 24 short hours is the only control we have - and the only way to make a difference.&lt;/p&gt;&lt;a href=&quot;https://waitbutwhy.com/2016/10/100-blocks-day.html&quot; class=&quot;url-standalone&quot; target=&quot;_blank&quot;&gt;100 blocks a day&lt;/a&gt;&lt;a href=&quot;https://waitbutwhy.com/2014/05/life-weeks.html&quot; class=&quot;url-standalone&quot; target=&quot;_blank&quot;&gt;52 weeks a year&lt;/a&gt;
    &lt;h3 id=&quot;tenets-tm-skill&quot;&gt;Time management is a skill&lt;/h3&gt;
    &lt;p&gt;And skills take time to acquire.&lt;/p&gt;
    &lt;ul&gt;
      &lt;li&gt;You can&#39;t expect to be good at any of the techniques the first time you try them&lt;/li&gt;
      &lt;li&gt;Failure is part of learning&lt;/li&gt;
      &lt;li&gt;Theory without practice is useless&lt;/li&gt;
      &lt;li&gt;Repetition is not learning (deliberate practice is a separate skill/concept)&lt;/li&gt;
      &lt;li&gt;Working on more than one substantial change at a time is a guarantee of failure&lt;/li&gt;
    &lt;/ul&gt;
&lt;p&gt;No matter if you subscribe to Gladwell&#39;s estimate of 10000 hours of practice to mastery, or Tim Ferriss&#39;s 6
months, one of the key ideas to remember is that time management is a little bit like cooking. If you keep your ego in check, have good sources or mentors and keep experimenting you can quite quickly get to the point of having solid basics.&lt;/p&gt;
  &lt;/section&gt;
  &lt;section&gt;
    &lt;h2 id=&quot;topics&quot;&gt;Main topics&lt;/h2&gt;
    &lt;section&gt;
      &lt;h3 id=&quot;topics-energy&quot;&gt;Energy&lt;/h3&gt;
      &lt;p&gt;No amount of methods or programs are going to make a visible impact on your life if any of the physical pillars
        are off:&lt;/p&gt;
      &lt;h4 id=&quot;topics-energy-sleep&quot;&gt;Sleep&lt;/h4&gt;
      &lt;p&gt;One of the most annoying scientific facts is that you need 8 hours of sleep. Sleeping only 6 hours per day in
        the long term leads to a permanent decrease in performance equivalent to not sleeping for 2 previous nights, but
        - here is the twist - without any awareness that you are effectively sleep-deprived and ineffective. Yes, I’ve
        personally tested this.&lt;/p&gt;&lt;img class=&quot;content-image pure-img&quot; src=&quot;https://mostlybugless.com/img/legacy/articles/timemanagement/sleep.png&quot; alt=&quot;Bed with a sleeping man&quot; /&gt;
      &lt;p&gt;Keep in mind that our bodies love routine and there is no way you can feel fresh if your wake-up time is
        scattered between 5 am and 11. Also, watch out for blue light, screens and late evening coffee. I use &lt;a href=&quot;https://justgetflux.com/&quot; target=&quot;_blank&quot;&gt;f.lux&lt;/a&gt; for years
        already, but modern devices seem to be getting screen color control as a basic system feature.&lt;/p&gt;
      &lt;p&gt;On a side note, when you wake up in December and it&#39;s still pitch dark outside at 7 a.m. don&#39;t expect to be
        productive in the morning. Hooking up your lights with an automatic dimmer does wonders for your sleep cycle if
        you can get them to slowly brighten up before your alarm clock and gradually dim before you go to bed. I use a
        small set of &lt;a href=&quot;https://www2.meethue.com/&quot; target=&quot;_blank&quot;&gt;Philips Hue&lt;/a&gt; smart bulbs but in a hindsight I would look for a cheaper option - they are
        great but not on the price/value ratio while there are many new competing products.&lt;/p&gt;&lt;a href=&quot;https://www.ncbi.nlm.nih.gov/pubmed/12683469&quot; class=&quot;url-standalone&quot; target=&quot;_blank&quot;&gt;Paper on long-term sleep deprivation&lt;/a&gt;&lt;a href=&quot;https://www.amazon.com/Why-We-Sleep-Unlocking-Dreams/dp/1501144316&quot; class=&quot;url-standalone&quot; target=&quot;_blank&quot;&gt;Matthew Walker, Why We Sleep: Unlocking the Power of Sleep and Dreams&lt;/a&gt;
      &lt;h4 id=&quot;topics-energy-exercise&quot;&gt;Exercise&lt;/h4&gt;
      &lt;p&gt;Regular exercise is hard. It takes time. It takes motivation. And lots of people look at time management to
        help them with establishing a fitness routine, as I do, and maybe you. Egg and a chicken.&lt;/p&gt;&lt;img class=&quot;content-image pure-img&quot; src=&quot;https://mostlybugless.com/img/legacy/articles/timemanagement/gym.png&quot; alt=&quot;Drawing of a gym workout&quot; /&gt;
      &lt;p&gt;Exercise not only helps with avoiding death from any of the cheerful consequences of white-collar
        chair-sitting. It&#39;s non-negotiable for getting maximum performance of your brain.&lt;/p&gt;
      &lt;p&gt;Move.&lt;/p&gt;&lt;a href=&quot;https://www.amazon.com/Spark-Revolutionary-Science-Exercise-Brain/dp/0316113514&quot; class=&quot;url-standalone&quot; target=&quot;_blank&quot;&gt;Eric Hagerman, Spark&lt;/a&gt;&lt;a href=&quot;https://www.amazon.com/How-Fail-Almost-Everything-Still/dp/1591847745&quot; class=&quot;url-standalone&quot; target=&quot;_blank&quot;&gt;Scott Adams, How to Fail at Almost Everything and Still Win Big&lt;/a&gt;
      &lt;h4 id=&quot;topics-energy-food&quot;&gt;Food&lt;/h4&gt;&lt;img class=&quot;content-image pure-img&quot; src=&quot;https://mostlybugless.com/img/legacy/articles/timemanagement/food.png&quot; alt=&quot;Vegetable and a bottle&quot; /&gt;
      &lt;p&gt;Diet is a controversial topic. No matter which particular approach you mention, someone will throw a bunch of
        research papers and hateful words in your direction. But what we eat defines how we feel physically. A right
        diet that doesn&#39;t make you sleepy throughout the day, nor hate yourself and the person who invented tofu, is a
        long way to having a high-quality life. &lt;/p&gt;
      &lt;p&gt;Question, learn and experiment.&lt;/p&gt;&lt;a href=&quot;https://www.amazon.com/How-Not-Die-Discover-scientifically-ebook/dp/B0114MO6IE&quot; class=&quot;url-standalone&quot; target=&quot;_blank&quot;&gt;Michael Greger, How Not To Die&lt;/a&gt;&lt;a href=&quot;https://www.amazon.com/How-Fail-Almost-Everything-Still/dp/1591847745&quot; class=&quot;url-standalone&quot; target=&quot;_blank&quot;&gt;Scott Adams, How to Fail at Almost Everything and Still Win Big&lt;/a&gt;
      &lt;h4 id=&quot;topics-energy-managing&quot;&gt;Managing energy&lt;/h4&gt;&lt;img class=&quot;content-image pure-img&quot; src=&quot;https://mostlybugless.com/img/legacy/articles/timemanagement/energy.png&quot; alt=&quot;Lightning bolt icon&quot; /&gt;
      &lt;p&gt;Your energy levels are also affected by time of day, environment and people. Are you most effective in the
        mornings? Is your brain offline after lunch? Do the people you talk to make you happy and motivated? Does the
        clutter on your desk make you depressed? Do you have enough of the D3 vitamin?&lt;/p&gt;
      &lt;p&gt;Trying to solve complex problems when your body is focused on digesting is not going to be efficient.
        Organizing emails when your brain is sparking with power is just a pure waste. Measure, plan and experiment.&lt;/p&gt;
    &lt;/section&gt;
    &lt;section&gt;
      &lt;h3 id=&quot;topics-habits&quot;&gt;Habits&lt;/h3&gt;
      &lt;p&gt;We are creatures of habit, and most of our decisions are automatic. The science behind this topic is solid, and
        its insights are essential to help tune your life.&lt;/p&gt;&lt;img class=&quot;content-image pure-img&quot; src=&quot;https://mostlybugless.com/img/legacy/articles/peakhabit/habit_loop.png&quot; alt=&quot;Habit loop&quot; /&gt;
      &lt;section&gt;
        &lt;h4 id=&quot;topics-habits-overcoming&quot;&gt;Overcoming bad habits&lt;/h4&gt;
        &lt;ul&gt;
          &lt;li&gt;Why do you want to change this habit?&lt;/li&gt;
          &lt;li&gt;What is the trigger? What is the reward?&lt;/li&gt;
          &lt;li&gt;Replace the habit with a new one leaving same trigger and same reward.&lt;/li&gt;
        &lt;/ul&gt;
        &lt;p&gt;While trying to remove the trigger rarely works - good luck removing &#39;feeling stressed&#39; - when working on
          replacing the routine it&#39;s useful to lock yourself out of the bad alternative. For digital habits, there are
          blocker applications that cut you off from websites, and many routers have this option.&lt;/p&gt;
        &lt;p&gt;Technically-able can also edit the /etc/hosts file or write their own scripts that blow up your system if you
          &#39;accidentally&#39; get lost in &#39;one more turn&#39; mode. That&#39;s my personal approach right now, but I tried the popular
          blockers before, and they did also work.&lt;/p&gt;
        &lt;h4 id=&quot;topics-habits-making&quot;&gt;Making new habits&lt;/h4&gt;
        &lt;ul&gt;
          &lt;li&gt;Decompose your goal into a smallest possible action - Tidying bedroom -&amp;gt; making a bed -&amp;gt; spread out
            the bedding&lt;/li&gt;
          &lt;li&gt;Decide on the trigger - I woke up&lt;/li&gt;
          &lt;li&gt;Setup a reminder - sign, place, notification (physical is better than digital)&lt;/li&gt;
          &lt;li&gt;Dependingly on a habit, you may need between 3 weeks and a 2/3s of a year&lt;/li&gt;
          &lt;li&gt;It&#39;s impossible to build more than one habit at a time&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/section&gt;
      &lt;p&gt;As a physical pattern in your brain emerges you will switch to autopilot. And exercising, planning, reading,
        healthy eating, or whatever floats your boat - will be completely effortless. Having no need to force yourself
        in any of the routines you always wanted to have sounds good, right? In fact, if you skip for whatever temporary
        reason, you are going to feel quite weird.&lt;/p&gt;&lt;img class=&quot;content-image pure-img&quot; src=&quot;https://mostlybugless.com/img/legacy/articles/timemanagement/brainshabit.png&quot; alt=&quot;Brain pattern icon&quot; /&gt;
      &lt;p&gt;On a side note, willpower is a separate topic. We can train willpower just like a muscle and people use it to
        do incredible things. But in everyday life habits eat willpower for breakfast.&lt;/p&gt;
      &lt;h4 id=&quot;topics-habits-keystone&quot;&gt;Keystone habit&lt;/h4&gt;
      &lt;p&gt;Some of the practices have disproportionate effects on overall life quality. Removing a single worst lousy
        habit can completely change your direction, like getting back 2 hours of time a day that would be allocated to
        passive social media browsing. Getting a habit of regular exercising makes you feel better and more energetic.
      &lt;/p&gt;
      &lt;p&gt;Also, see the &lt;a href=&quot;https://mostlybugless.com/posts/2018-007-tm-overview/#minor-pareto&quot;&gt;Pareto principle&lt;/a&gt; (20/80).&lt;/p&gt;
      &lt;h4 id=&quot;topics-habits-chaining&quot;&gt;Habit chaining&lt;/h4&gt;
      &lt;p&gt;It&#39;s easier to add additional loops on top of existing ones.&lt;/p&gt;&lt;a href=&quot;https://www.amazon.com/Power-Habit-What-Life-Business/dp/B007EJSMC8&quot; class=&quot;url-standalone&quot; target=&quot;_blank&quot;&gt;Charles Duhigg, The Power of Habit&lt;/a&gt;
      &lt;h4 id=&quot;topics-habits-addictions&quot;&gt;Bad habit or an addiction?&lt;/h4&gt;
      &lt;p&gt;That&#39;s a question you can ask your psychologist. Some of the most common bad habits are on the verge of
        addiction, like excessive Facebook browsing, Netflix binging and drinking 1 liter of coke a day. It&#39;s a serious
        civilizational problem - technology is breaking our brains.&lt;/p&gt;&lt;img class=&quot;content-image pure-img&quot; src=&quot;https://mostlybugless.com/img/legacy/articles/timemanagement/techdrug.png&quot; alt=&quot;Mobile phone with needle inside&quot; /&gt;&lt;a href=&quot;https://www.amazon.com/Shallows-What-Internet-Doing-Brains/dp/0393339750&quot; class=&quot;url-standalone&quot; target=&quot;_blank&quot;&gt;Nicholas Carr, The Shallows&lt;/a&gt;
    &lt;/section&gt;
    &lt;section&gt;
      &lt;h3 id=&quot;topics-mindsets&quot;&gt;Mindsets&lt;/h3&gt;&lt;img class=&quot;content-image pure-img&quot; src=&quot;https://mostlybugless.com/img/legacy/articles/timemanagement/mindset.png&quot; alt=&quot;Mind-bulb icon&quot; /&gt;
      &lt;p&gt;Our mindsets are kind of mental habits - they ways we think, worry and generally talk to ourselves are rarely
        conscious. We can take control over them though.&lt;/p&gt;
      &lt;p&gt;If your mind hates you and talks to you in pathological patterns (&quot;You did it again, idiot.&quot;, &quot;Why does this
        happen to me always?&quot; ), there is a need for change. Also, being able to shut down your mental chatter when
        falling asleep is a superpower. &lt;/p&gt;&lt;a href=&quot;https://www.amazon.com/Mindfulness-English-Bhante-Henepola-Gunaratana/dp/0861719069&quot; class=&quot;url-standalone&quot; target=&quot;_blank&quot;&gt;Bhante Henepola Gunaratana, Mindfulness in Plain English&lt;/a&gt;&lt;a href=&quot;https://www.amazon.com/Guide-Rational-Living-Albert-Ellis/dp/0879800429/&quot; class=&quot;url-standalone&quot; target=&quot;_blank&quot;&gt;Albert Ellis, A Guide to Rational Living&lt;/a&gt;&lt;a href=&quot;https://www.amazon.com/Change-Your-Questions-Life-Institute/dp/1576756009&quot; class=&quot;url-standalone&quot; target=&quot;_blank&quot;&gt;Marilee Adams, Change Your Questions, Change Your Life&lt;/a&gt;
    &lt;/section&gt;
    &lt;section&gt;
      &lt;h3 id=&quot;topics-meaning&quot;&gt;Meaning&lt;/h3&gt;
      &lt;blockquote&gt;
        &lt;p&gt;Whatever your dreams are, start taking them very, very seriously.&lt;/p&gt;
        &lt;footer&gt;&lt;cite&gt;Barbara Sher&lt;/cite&gt;&lt;/footer&gt;
      &lt;/blockquote&gt;
      &lt;p&gt;The first association to time management is probably a to-do list or a calendar. But those are only tactical
        measures that can make you more efficient in your current efforts. If you are working on wrong things at work,
        or overall pursuing an unfulfilling career, you need to go back to the strategic layer.&lt;/p&gt;&lt;img class=&quot;content-image pure-img&quot; src=&quot;https://mostlybugless.com/img/legacy/articles/timemanagement/heart.png&quot; alt=&quot;Heart icon&quot; /&gt;
      &lt;p&gt;We need a purpose in things we do - no amount of to-do lists is going to compete with a single vision and some
        determination. Understanding your own values and what you really want to get out of life is really hard and
        takes deliberate effort. Every action has to have a &#39;why.&#39; Preferably - a written down one.&lt;/p&gt;&lt;a href=&quot;https://www.ted.com/talks/dan_ariely_what_makes_us_feel_good_about_our_work&quot; class=&quot;url-standalone&quot; target=&quot;_blank&quot;&gt;Dan Ariely, TED talk: What makes us feel good about our work&lt;/a&gt;&lt;a href=&quot;https://www.amazon.com/8th-Habit-Effectiveness-Greatness/dp/0743287932&quot; class=&quot;url-standalone&quot; target=&quot;_blank&quot;&gt;Stephen R. Covey, The 8th Habit&lt;/a&gt;&lt;a href=&quot;https://www.amazon.com/Art-Non-Conformity-Rules-Change-Perigee/dp/0399536108/&quot; class=&quot;url-standalone&quot; target=&quot;_blank&quot;&gt;Chris Guillebeau, The Art of Non-Conformity&lt;/a&gt;&lt;a href=&quot;https://www.amazon.com/Drive-Surprising-Truth-About-Motivates/dp/1594484805/&quot; class=&quot;url-standalone&quot; target=&quot;_blank&quot;&gt;Daniel H. Pink, Drive&lt;/a&gt;
      &lt;p&gt;Another important aspect is the base limitation of things we can do within the 24 hours of a day. Fun fact:
        initially, the word priority had no plural form! Choosing &#39;the one&#39; thing is an art itself.&lt;/p&gt;&lt;a href=&quot;https://www.amazon.com/Essentialism-Disciplined-Pursuit-Greg-McKeown/dp/0804137382&quot; class=&quot;url-standalone&quot; target=&quot;_blank&quot;&gt;Greg McKeown, Essentialism&lt;/a&gt;
      &lt;section&gt;
        &lt;h4 id=&quot;topics-meaning-flow&quot;&gt;Flow&lt;/h4&gt;
        &lt;p&gt;Flow is a state when you are completely immersed in an activity. When all your worries are gone and 4 hours
          feel like 14 minutes, that&#39;s flow. And that&#39;s when we create the best work we can. &lt;/p&gt;&lt;img class=&quot;content-image pure-img&quot; src=&quot;https://mostlybugless.com/img/legacy/articles/timemanagement/fire.png&quot; alt=&quot;Fire icon&quot; /&gt;
        &lt;p&gt;To get into the flow, you need a meaningful task that is right on the edge of your skill level.&lt;/p&gt;&lt;a href=&quot;https://www.amazon.com/Flow-Psychology-Experience-Perennial-Classics/dp/0061339202&quot; class=&quot;url-standalone&quot; target=&quot;_blank&quot;&gt;Mihaly Csikszentmihalyi, Flow&lt;/a&gt;
      &lt;/section&gt;
      &lt;section&gt;
        &lt;h4 id=&quot;topics-meaning-eisenhower&quot;&gt;The Eisenhower Method&lt;/h4&gt;
        &lt;p&gt;A core distinction between what&#39;s urgent and what is important.&lt;/p&gt;&lt;img class=&quot;content-image pure-img&quot; src=&quot;https://mostlybugless.com/img/legacy/articles/timemanagement/MerrillCoveyMatrix.png&quot; alt=&quot;Eisenhower matrix&quot; /&gt;&lt;a href=&quot;https://www.amazon.com/7-Habits-Highly-Effective-People/dp/1416502491&quot; class=&quot;url-standalone&quot; target=&quot;_blank&quot;&gt;7 Habits of Highly Effective People&lt;/a&gt;
      &lt;/section&gt;
      &lt;section&gt;
        &lt;h4 id=&quot;topics-meaning-busy&quot;&gt;Being busy vs being productive&lt;/h4&gt;
        &lt;p&gt;We live in a culture that promotes busyness. People are proud when they work around the clock and are
          constantly hooked to a stream of news, posts and notifications. No great work was ever created when switching
          between email, slack and the piece itself.&lt;/p&gt;
        &lt;p&gt;Long story short, multitasking doesn&#39;t work. As well as cramming your schedule to 105%.&lt;/p&gt;&lt;a href=&quot;https://www.apa.org/research/action/multitask.aspx&quot; class=&quot;url-standalone&quot; target=&quot;_blank&quot;&gt;American Psychological Association summary of multitasking
          research&lt;/a&gt;&lt;a href=&quot;https://www.amazon.com/Essentialism-Disciplined-Pursuit-Greg-McKeown/dp/0804137382&quot; class=&quot;url-standalone&quot; target=&quot;_blank&quot;&gt;Greg McKeown, Essentialism&lt;/a&gt;
      &lt;/section&gt;
    &lt;/section&gt;
    &lt;section&gt;
      &lt;h3 id=&quot;topics-feedback&quot;&gt;Feedback and planning&lt;/h3&gt;
      &lt;p&gt;To risk a cliche, if you improve 1% per day for 365 days, you are going to improve by 3778% in a year. 1.01^365
        = 37.78&lt;/p&gt;
      &lt;p&gt;&lt;b&gt;Hundreds of different systems and ideas can help you to be more effective. Some will work for you, some
          won&#39;t, but will for others. Some will, but not today. And some are just bonkers. &lt;/b&gt; As long as you keep an
        attitude of constant experimentation, you can work out a satisfying routine that moves you toward the impact you
        want to have on the world - however big or small your vision is.&lt;/p&gt;&lt;a href=&quot;https://youtu.be/5WX9UEYZsR8?t=437&quot; class=&quot;url-standalone&quot; target=&quot;_blank&quot;&gt;Jordan Peterson, How to set goals the smart way&lt;/a&gt;
      &lt;section&gt;
        &lt;h4 id=&quot;topics-feedback-state&quot;&gt;Current state and Quantification&lt;/h4&gt;
        &lt;p&gt;What are you spending your time on? What makes you feel good? What drains your motivation?&lt;/p&gt;&lt;img class=&quot;content-image pure-img&quot; src=&quot;https://mostlybugless.com/img/legacy/articles/timemanagement/measure.png&quot; alt=&quot;Pad with markings&quot; /&gt;
        &lt;p&gt;Without understanding where you are now, you can&#39;t plot the route to achievement. Consider:&lt;/p&gt;
        &lt;ul&gt;
          &lt;li&gt;life audit - writing down every single thing you do for 2-3 days; also useful for understanding your
            energy levels in a day&lt;/li&gt;
          &lt;li&gt;time logging - &lt;a href=&quot;https://toggl.com/&quot; target=&quot;_blank&quot;&gt;toggl&lt;/a&gt; enables you to consistently log your productive (and unproductive if you choose
            to do so) time split into different buckets&lt;/li&gt;
          &lt;li&gt;automatic logging - some tools, like &lt;a href=&quot;https://www.rescuetime.com/&quot; target=&quot;_blank&quot;&gt;RT&lt;/a&gt;
            record everything you do on your device / in your browser and report the results&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/section&gt;
      &lt;section&gt;
        &lt;h4 id=&quot;topics-feedback-goals&quot;&gt;Goals&lt;/h4&gt;&lt;img class=&quot;content-image pure-img&quot; src=&quot;https://mostlybugless.com/img/legacy/articles/timemanagement/goal.png&quot; alt=&quot;Peak with a flag&quot; /&gt;
        &lt;p&gt;Goals are necessary, and there is a whole science behind goal creation (also a very profitable industry). The
          minimum pattern of SMART means that goals should be:&lt;/p&gt;
        &lt;ul&gt;
          &lt;li&gt;Specific&lt;/li&gt;
          &lt;li&gt;Measurable&lt;/li&gt;
          &lt;li&gt;Achievable&lt;/li&gt;
          &lt;li&gt;Relevant&lt;/li&gt;
          &lt;li&gt;Time-bound&lt;/li&gt;
        &lt;/ul&gt;
        &lt;h5 id=&quot;topics-feedback-goals-okr&quot;&gt;Objectives and key results (OKR)&lt;/h5&gt;
        &lt;p&gt;OKRs are a state-of-the-art practice for goal-setting, especially prevalent in successful companies:&lt;/p&gt;&lt;a href=&quot;https://www.amazon.com/Measure-What-Matters-Google-Foundation/dp/0525536221&quot; class=&quot;url-standalone&quot; target=&quot;_blank&quot;&gt;John Doerr, Measure What Matters&lt;/a&gt;
      &lt;/section&gt;
      &lt;section&gt;
        &lt;h4 id=&quot;topics-feedback-systems&quot;&gt;Systems&lt;/h4&gt;&lt;img class=&quot;content-image pure-img&quot; src=&quot;https://mostlybugless.com/img/legacy/articles/timemanagement/system.png&quot; alt=&quot;Infinity loop&quot; /&gt;
        &lt;p&gt;Goals do not work. Anyone who has made a New Year&#39;s resolutions can attest to that. The alternative approach
          is to create systems that push you in the right direction every day. So, instead of having a goal of writing a
          book this year, make a system of writing 150 words every day. And decide when, where and how you will be
          writing them.&lt;/p&gt;
        &lt;p&gt;Consider systems as goals done well with supporting latticework of habits and environment design. &lt;/p&gt;
        &lt;div&gt;
          &lt;div class=&quot;pure-u-1 pure-u-md-1-2&quot;&gt;
            &lt;h5 id=&quot;topics-feedback-systems-goals&quot;&gt;Goals&lt;/h5&gt;
            &lt;ul&gt;
              &lt;li&gt;Single point of achievement - constant state of pre-success failure&lt;/li&gt;
              &lt;li&gt;Delayed gratifications&lt;/li&gt;
              &lt;li&gt;Large and uncertain - cause anxiety&lt;/li&gt;
            &lt;/ul&gt;
          &lt;/div&gt;
          &lt;div class=&quot;pure-u-1 pure-u-md-1-2&quot;&gt;
            &lt;h5 id=&quot;topics-feedback-systems-systems&quot;&gt;Systems&lt;/h5&gt;
            &lt;ul&gt;
              &lt;li&gt;Everyday progress - feeling good every time you apply the system &lt;/li&gt;
              &lt;li&gt;Continuous gratification&lt;/li&gt;
              &lt;li&gt;Small and manageable&lt;/li&gt;
            &lt;/ul&gt;
          &lt;/div&gt;
        &lt;/div&gt;
      &lt;/section&gt;&lt;a href=&quot;https://www.amazon.com/How-Fail-Almost-Everything-Still/dp/1591847745&quot; class=&quot;url-standalone&quot; target=&quot;_blank&quot;&gt;Scott Adams, How to Fail at Almost Everything and Still Win Big&lt;/a&gt;
    &lt;/section&gt;
    &lt;section&gt;
      &lt;h3 id=&quot;topics-irrationality&quot;&gt;Irrationality&lt;/h3&gt;
      &lt;p&gt;Contrary to how economists would like the world to work, people for most purposes are inherently crazy. We fail
        our goals, skip diets and predictably make horrible decisions. On the bright side, there is a lot of research on
        human irrationality already done. Understanding central insights in this area helps to prioritize your next
        summer body over half a liter of a milkshake.&lt;/p&gt;&lt;img class=&quot;content-image pure-img&quot; src=&quot;https://mostlybugless.com/img/legacy/articles/timemanagement/irrational.png&quot; alt=&quot;Facepalm&quot; /&gt;
      &lt;p&gt;The &lt;s&gt;official&lt;/s&gt; Wikipedia&#39;s list of biases is really, really long. Consider starting with the books. Some
        of the obvious-yet-enlightening ones include&lt;/p&gt;
      &lt;ul&gt;
        &lt;li&gt;&lt;b&gt;Hyperbolic discounting&lt;/b&gt; - discounting reward in time, overvaluing short-term gains&lt;/li&gt;
        &lt;li&gt;&lt;b&gt;Optimism bias/planning fallacy&lt;/b&gt; - we are consistently bad at estimating anything. &lt;/li&gt;
      &lt;/ul&gt;&lt;a href=&quot;https://www.amazon.com/Predictably-Irrational-Revised-Expanded-Decisions/dp/0061353248&quot; class=&quot;url-standalone&quot; target=&quot;_blank&quot;&gt;Dan Ariely, Predictably Irrational&lt;/a&gt;&lt;a href=&quot;https://www.amazon.com/Thinking-Fast-Slow-Daniel-Kahneman/dp/0374533555&quot; class=&quot;url-standalone&quot; target=&quot;_blank&quot;&gt;Daniel Kahneman, Thinking, Fast and Slow&lt;/a&gt;&lt;a href=&quot;https://www.clearerthinking.org/tools-and-mini-courses&quot; class=&quot;url-standalone&quot; target=&quot;_blank&quot;&gt;Tools and minicourses on getting your decision making under control,
        ClearerThinking.org&lt;/a&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/List_of_cognitive_biases&quot; class=&quot;url-standalone&quot; target=&quot;_blank&quot;&gt;List of cognitive biases&lt;/a&gt;
      &lt;section&gt;
        &lt;h4 id=&quot;topics-irrationality-procrastination&quot;&gt;Procrastination&lt;/h4&gt;
        &lt;p&gt;Procrastination is a chronic avoidance of tasks, whether self or externally imposed. It&#39;s closely connected
          to some of our biases (especially Hyperbolic discounting). Long story short, ambitious, uncertain and
          important goals cause mental resistance. You can break down those problems with good systems that turn massive
          undertakings into a small, manageable series of steps.&lt;/p&gt;
        &lt;section&gt;
          &lt;p&gt;Procrastination is also often a second-degree effect of&lt;/p&gt;
          &lt;ul&gt;
            &lt;li&gt;lack of vision&lt;/li&gt;
            &lt;li&gt;overcommitment (lack of prioritization)&lt;/li&gt;
            &lt;li&gt;deeply ingrained bad habits&lt;/li&gt;
          &lt;/ul&gt;
        &lt;/section&gt;
        &lt;p&gt;If you find yourself procrastinating consider shrinking the task to a smallest possible bit - &#39;I will open a
          notebook.&#39; Pomodoros also help. And a small technique suggested by R. Wiseman: making a deal with yourself
          that you are going to work &#39;just for a few minutes&#39; instead of making a deal that you will browse Facebook
          &#39;just for a few minutes&#39;, which we both know just doesn&#39;t work.&lt;/p&gt;&lt;a href=&quot;https://www.amazon.com/59-Seconds-Change-Under-Minute/dp/0307474860/&quot; class=&quot;url-standalone&quot; target=&quot;_blank&quot;&gt;Richard Wiseman, 59 Seconds&lt;/a&gt;
      &lt;/section&gt;
    &lt;/section&gt;
  &lt;/section&gt;
  &lt;section&gt;
    &lt;h2 id=&quot;tactics&quot;&gt;Base tactics&lt;/h2&gt;
    &lt;h3 id=&quot;tactics-pomodoros&quot;&gt;Pomodoros&lt;/h3&gt;&lt;img class=&quot;content-image pure-img&quot; src=&quot;https://mostlybugless.com/img/legacy/articles/timemanagement/timer.png&quot; alt=&quot;Timer&quot; /&gt;
    &lt;p&gt;Breaking your work into 25-minute long high-intensity, full-focus intervals with breaks between.&lt;/p&gt;&lt;a href=&quot;https://francescocirillo.com/pages/pomodoro-technique&quot; class=&quot;url-standalone&quot; target=&quot;_blank&quot;&gt;Pomodoro technique&lt;/a&gt;
    &lt;h3 id=&quot;tactics-blocking&quot;&gt;Time blocking&lt;/h3&gt;&lt;img class=&quot;content-image pure-img&quot; src=&quot;https://mostlybugless.com/img/legacy/articles/timemanagement/schedule.png&quot; alt=&quot;Blocks of schedule&quot; /&gt;
    &lt;p&gt;Building your schedule on large blocks of focused time. 9-11 deep work, 11-12 bureaucracy and emails, meetings
      13-15, etc. Ideally planned tasks should correspond to natural cycles of your physical energy. &lt;/p&gt;
    &lt;p&gt;Hint: never plan more than 80% of your time. Buffers are crucial.&lt;/p&gt;
    &lt;h3 id=&quot;tactics-environment&quot;&gt;Environment control&lt;/h3&gt;&lt;img class=&quot;content-image pure-img&quot; src=&quot;https://mostlybugless.com/img/legacy/articles/timemanagement/silence.png&quot; alt=&quot;Man with gagged mouth&quot; /&gt;
    &lt;p&gt;There is no such thing as multitasking. Any kind of creative work requires focus, and there is no way you can get
      into the flow when you get interruptions every 10 minutes.&lt;/p&gt;
    &lt;p&gt;Turn off notifications and work in a silent environment. Or at least get a reasonable pair of headphones and use
      &lt;a href=&quot;https://mostlybugless.com/web/20211022103148/http://mostlybugless.com/articles/mynoise&quot; target=&quot;_blank&quot;&gt;white noise&lt;/a&gt; to drown
      out noises made by those pesky humans.&lt;/p&gt;
    &lt;h3 id=&quot;tactics-planning&quot;&gt;Regular planning&lt;/h3&gt;&lt;img class=&quot;content-image pure-img&quot; src=&quot;https://mostlybugless.com/img/legacy/articles/timemanagement/planning.png&quot; alt=&quot;Agenda drawing&quot; /&gt;
    &lt;p&gt;You need to spend time to save time. 30 minutes on Sunday for a week planning session does wonders, as well as a
      quick daily check on the most important thing to achieve the next day.&lt;/p&gt;
    &lt;h3 id=&quot;tactics-buffers&quot;&gt;Buffers&lt;/h3&gt;&lt;img class=&quot;content-image pure-img&quot; src=&quot;https://mostlybugless.com/img/legacy/articles/timemanagement/bufferoverlow.png&quot; alt=&quot;Overflowing buffer&quot; /&gt;
    &lt;p&gt;Since we are naturally horrible at estimating (which also explains a lot of the IT industry), creating large
      buffers for tasks is a valid technique to avoid failure. Historical data solves this problem also. If a small size
      post takes me 6 hours, I can expect next one to not deviate too much. However, if I&#39;m estimating a new work - a
      large post with heavy research - and I come up with 15 hours top-down, it&#39;s safe to look at the 30+ hour range.
    &lt;/p&gt;&lt;a href=&quot;http://programs.clearerthinking.org/planning_fallacy.html&quot; class=&quot;url-standalone&quot; target=&quot;_blank&quot;&gt;50 minute mini-course on improving your planning from
      ClearerThinking.org&lt;/a&gt;
    &lt;h3 id=&quot;tactics-todo&quot;&gt;To-do lists&lt;/h3&gt;&lt;img class=&quot;content-image pure-img&quot; src=&quot;https://mostlybugless.com/img/legacy/articles/timemanagement/todo.png&quot; alt=&quot;To-do list&quot; /&gt;
    &lt;p&gt;We can hold at best 2-3 things in our brains. To not get lost in the sea of bills, calls and life goals it&#39;s
      essential to have a log of things left to do. Creating effective to-do lists is a vast topic. Some pointers:&lt;/p&gt;
    &lt;ul&gt;
      &lt;li&gt;Tasks should be as small as possible, whole projects are not tasks and therefore not for to-do lists&lt;/li&gt;
      &lt;li&gt;Visit everyday&lt;/li&gt;
      &lt;li&gt;Have separate lists based on time - today, this week and future is a common choice&lt;/li&gt;
    &lt;/ul&gt;
    &lt;p&gt;Don&#39;t forget to get things done.&lt;/p&gt;
    &lt;h3 id=&quot;tactics-gtd&quot;&gt;Getting things done&lt;/h3&gt;&lt;img class=&quot;content-image pure-img&quot; src=&quot;https://mostlybugless.com/img/legacy/articles/timemanagement/gtd.png&quot; alt=&quot;Multiple lists&quot; /&gt;
    &lt;p&gt;Complex, overhyped system enabling you to do wrong things very efficiently. Based on to-do lists. Sarcasm aside,
      it&#39;s really great and lets you take back control over large amounts of tasks in all areas of your life.&lt;/p&gt;&lt;a href=&quot;https://www.amazon.com/Getting-Things-Done-Stress-Free-Productivity/dp/0142000280&quot; class=&quot;url-standalone&quot; target=&quot;_blank&quot;&gt;David Allen, Getting things done&lt;/a&gt;
    &lt;h3 id=&quot;tactics-ulysses&quot;&gt;Ulysses contracts&lt;/h3&gt;&lt;img class=&quot;content-image pure-img&quot; src=&quot;https://mostlybugless.com/img/legacy/articles/timemanagement/handsbound.png&quot; alt=&quot;Bound hands drawing&quot; /&gt;
    &lt;p&gt;Making early commitments that prevent your future you from making bad decisions. Uninstalling time-wasting apps,
      blocking infinite-scrolling websites on your router, inviting friends over so you have to clean up your flat, etc.
      Creating artificial deadlines and getting accountability partners who reward and punish you also fall into this
      category.&lt;/p&gt;
    &lt;h3 id=&quot;tactics-automation&quot;&gt;Checklists and automation&lt;/h3&gt;&lt;img class=&quot;content-image pure-img&quot; src=&quot;https://mostlybugless.com/img/legacy/articles/timemanagement/robot.png&quot; alt=&quot;Robot&quot; /&gt;
    &lt;p&gt;Checklists are the first step to automation. You shouldn&#39;t be spending computational cycles of your brain on what
      to take for next trip, nor which groceries to buy at the beginning of a week. On the other hand, a lot of our
      tasks can be automated or outsourced - paying bills, doing the dishes, checking your daily set of blogs for new
      posts.&lt;/p&gt;
  &lt;/section&gt;
  &lt;section&gt;
    &lt;h2 id=&quot;myths&quot;&gt;Main myths&lt;/h2&gt;
    &lt;h3 id=&quot;myths-visualization&quot;&gt;Visualization / self-affirmation&lt;/h3&gt;&lt;img class=&quot;content-image pure-img&quot; src=&quot;https://mostlybugless.com/img/legacy/articles/timemanagement/magic.png&quot; alt=&quot;Drawing of head with a magic wand&quot; /&gt;
    &lt;p&gt;Thinking about your best future successful self does not work - at best, possibly it&#39;s even harmful. There may be
      some merit to thinking about concrete steps of your journey and visualizing yourself doing the work required
      though.&lt;/p&gt;&lt;a href=&quot;https://www.amazon.com/59-Seconds-Change-Under-Minute/dp/0307474860/&quot; class=&quot;url-standalone&quot; target=&quot;_blank&quot;&gt;Richard Wiseman, 59 Seconds&lt;/a&gt;
    &lt;h3 id=&quot;myths-working&quot;&gt;Working more&lt;/h3&gt;&lt;img class=&quot;content-image pure-img&quot; src=&quot;https://mostlybugless.com/img/legacy/articles/timemanagement/gears.png&quot; alt=&quot;Gears&quot; /&gt;
    &lt;p&gt;Overtime and generally pushing yourself over the limits doesn&#39;t work besides single occurings with significant
      rest periods afterward. Life is a marathon, not a sprint.&lt;/p&gt;
    &lt;h3 id=&quot;myths-singletrick&quot;&gt;There is a single trick, 10 step guide, or a blog post that will change your life&lt;/h3&gt;
    &lt;img class=&quot;content-image pure-img&quot; src=&quot;https://mostlybugless.com/img/legacy/articles/timemanagement/unicorn.png&quot; alt=&quot;Unicorn drawing&quot; /&gt;
    &lt;p&gt;Making yourself more productive means fighting against 30, or however old you are, years of reinforcing
      experience and 7 million years of evolutionary history. Getting better is hard. And easy answers usually are
      either incomplete or completely wrong.&lt;/p&gt;
  &lt;/section&gt;
  &lt;section&gt;
    &lt;h2 id=&quot;minor&quot;&gt;Minor concepts&lt;/h2&gt;
    &lt;h3 id=&quot;minor-resistance&quot;&gt;Resistance&lt;/h3&gt;&lt;img class=&quot;content-image pure-img&quot; src=&quot;https://mostlybugless.com/img/legacy/articles/timemanagement/cosmos.png&quot; alt=&quot;Galaxy drawing&quot; /&gt;
    &lt;p&gt;Procrastination as a physical force of nature.&lt;/p&gt;&lt;a href=&quot;https://www.amazon.com/War-Art-Steven-Pressfield-ebook/dp/B007A4SDCG&quot; class=&quot;url-standalone&quot; target=&quot;_blank&quot;&gt;Steven Pressfield, The War of Art&lt;/a&gt;
    &lt;h3 id=&quot;minor-essentialism&quot;&gt;Essentialism&lt;/h3&gt;&lt;img class=&quot;content-image pure-img&quot; src=&quot;https://mostlybugless.com/img/legacy/articles/timemanagement/aim.png&quot; alt=&quot;Bullseye drawing&quot; /&gt;
    &lt;p&gt;Stop doing everything, start doing essential things.&lt;/p&gt;&lt;a href=&quot;https://www.amazon.com/Essentialism-Disciplined-Pursuit-Greg-McKeown/dp/0804137382&quot; class=&quot;url-standalone&quot; target=&quot;_blank&quot;&gt;Greg McKeown, Essentialism&lt;/a&gt;
    &lt;h3 id=&quot;minor-pareto&quot;&gt;Pareto principle&lt;/h3&gt;&lt;img class=&quot;content-image pure-img&quot; src=&quot;https://mostlybugless.com/img/legacy/articles/timemanagement/piechart.png&quot; alt=&quot;Piechart drawing&quot; /&gt;
    &lt;p&gt;20% of work gives you 80% of results&lt;/p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=5WX9UEYZsR8&quot; class=&quot;url-standalone&quot; target=&quot;_blank&quot;&gt;Jordan Peterson, How to set goals the smart way&lt;/a&gt;
    &lt;h3 id=&quot;minor-fktit&quot;&gt;F*ck it effect&lt;/h3&gt;&lt;img class=&quot;content-image pure-img&quot; src=&quot;https://mostlybugless.com/img/legacy/articles/timemanagement/drink.png&quot; alt=&quot;Drawing of a drink&quot; /&gt;
    &lt;p&gt;I ate one piece of pie so I might just as well finish whole. Having contingency plans and non-hostile mindset
      (&#39;what can i do better next time?&#39; instead of &#39;I&#39;m a failure&#39; helps).&lt;/p&gt;
    &lt;h3 id=&quot;minor-inbox&quot;&gt;Inbox 0&lt;/h3&gt;&lt;img class=&quot;content-image pure-img&quot; src=&quot;https://mostlybugless.com/img/legacy/articles/timemanagement/inbox.png&quot; alt=&quot;Drawing of an inbox&quot; /&gt;
    &lt;p&gt;Keeping your email inbox completely empty by making quick, radical decisions. When poorly applied leads to an
      explosion of meaningless emails in your team/organization. When applied correctly helps you remain sane and
      productive. &lt;/p&gt;
    &lt;h3 id=&quot;minor-barbell&quot;&gt;Barbell strategy&lt;/h3&gt;&lt;img class=&quot;content-image pure-img&quot; src=&quot;https://mostlybugless.com/img/legacy/articles/timemanagement/barbell.png&quot; alt=&quot;Barbell drawing&quot; /&gt;
    &lt;p&gt;Mediocrity kills, results are on the extremes. Sharp focus with good rest afterward is an order of magnitude more
      effective than messing about the whole day. &lt;/p&gt;&lt;a href=&quot;https://www.amazon.com/gp/product/B0083DJWGO&quot; class=&quot;url-standalone&quot; target=&quot;_blank&quot;&gt;Nassim Taleb, Antifragile&lt;/a&gt;
    &lt;h3 id=&quot;minor-vianegativa&quot;&gt;Via negativa&lt;/h3&gt;&lt;img class=&quot;content-image pure-img&quot; src=&quot;https://mostlybugless.com/img/legacy/articles/timemanagement/stopsign.png&quot; alt=&quot;No entry sign&quot; /&gt;
    &lt;p&gt;Inversion of planning. What I absolutely must not do if I want to have a fulfilling life. &lt;/p&gt;&lt;a href=&quot;https://www.amazon.com/gp/product/B0083DJWGO&quot; class=&quot;url-standalone&quot; target=&quot;_blank&quot;&gt;Nassim Taleb, Antifragile&lt;/a&gt;
    &lt;h3 id=&quot;minor-antifragile&quot;&gt;Antifragility&lt;/h3&gt;&lt;img class=&quot;content-image pure-img&quot; src=&quot;https://mostlybugless.com/img/legacy/articles/timemanagement/fist.png&quot; alt=&quot;Fist&quot; /&gt;
    &lt;p&gt;Improvement in face of failures and stressors. Applies both to systems (chaos engineering) and humans.&lt;/p&gt;&lt;a href=&quot;https://www.amazon.com/gp/product/B0083DJWGO&quot; class=&quot;url-standalone&quot; target=&quot;_blank&quot;&gt;Nassim Taleb, Antifragile&lt;/a&gt;
  &lt;/section&gt;
  &lt;section&gt;
    &lt;h2 id=&quot;toolset&quot;&gt;Toolset&lt;/h2&gt;
    &lt;p&gt;Minimal version:&lt;/p&gt;
    &lt;h3 id=&quot;toolset-calendar&quot;&gt;Calendar&lt;/h3&gt;
    &lt;p&gt;There is really no magic here, as long as you can plan your schedule it works. It&#39;s a little easier to create
      recurring events and time-blocks on digital calendars, but they are easier to ignore and disconnect physical
      sensations from the act of planning.&lt;/p&gt;
    &lt;h3 id=&quot;toolset-todo&quot;&gt;Todo list&lt;/h3&gt;
    &lt;p&gt;Mentioned above.&lt;/p&gt;&lt;a href=&quot;https://trello.com/&quot; class=&quot;url-standalone&quot; target=&quot;_blank&quot;&gt;Try Trello&lt;/a&gt;
    &lt;p&gt;Or any other app from the hundreds you can find.&lt;/p&gt;
    &lt;h3 id=&quot;toolset-other&quot;&gt;Additional&lt;/h3&gt;
    &lt;p&gt;You can also try&lt;/p&gt;
    &lt;ul&gt;
      &lt;li&gt;Time loggers&lt;/li&gt;
      &lt;li&gt;Website blockers&lt;/li&gt;
      &lt;li&gt;Habit builders (I prefer physical ones to digital, but there is obviously an app for that)&lt;/li&gt;
      &lt;li&gt;Decision journals&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/section&gt;
  &lt;section&gt;
    &lt;h2 id=&quot;summary&quot;&gt;Other notes and wrap-up&lt;/h2&gt;
    &lt;p&gt;Besides external links above, some of general references and inspiration for this post include:&lt;/p&gt;&lt;a href=&quot;https://www.amazon.com/7-Habits-Highly-Effective-People/dp/1416502491&quot; class=&quot;url-standalone&quot; target=&quot;_blank&quot;&gt;7 Habits of Highly Effective People&lt;/a&gt;&lt;a href=&quot;https://fs.blog/&quot; class=&quot;url-standalone&quot; target=&quot;_blank&quot;&gt;Farnam
      Street&lt;/a&gt;
    &lt;p&gt;Also it&#39;s worth mentioning countless time-management and related trainings (including those delivered by me over the years), attended courses and lengthy discussion with a whole lot of smart people, including a quite terrific
      course by Piotrek from &lt;a href=&quot;https://produktywni.pl/&quot; target=&quot;_blank&quot;&gt;produktywni.pl&lt;/a&gt; that I attended literally yesterday.&lt;/p&gt;
    &lt;p&gt;Yes, there is a lot of things you can try, and the amount of information might seem overwheling. No, don&#39;t panic. Start small!
  &lt;/p&gt;&lt;/section&gt;

		</content>
	</entry>
	
	<entry>
		<title>Peak Bad Habit</title>
		<link href="https://mostlybugless.com/posts/2018-006-bad-habit/" />
		<updated>2018-08-05T00:00:00Z</updated>
		<id>https://mostlybugless.com/posts/2018-006-bad-habit/</id>
		<content type="html">&lt;p&gt;We have spent the past decade under the sign of habit-forming technologies. Scroll down - get a dopamine hit. Your tweet was seen by another 100 people - one more. Binged an entire season of a new series? - oops.&lt;/p&gt;
&lt;p&gt;The most significant successes that come to mind - Facebook, Twitter, Instagram, Netflix, Youtube - all base their achievements in creating a &lt;strong&gt;habitual interaction with their products&lt;/strong&gt;. Habits themselves aren&#39;t inherently bad, of course. We base our existence on countless automatic patterns. However, is spending hours a day scrolling through neverending (and mostly never-valuable) content good for your health?&lt;/p&gt;
&lt;p&gt;(The obvious and already well established answer is &lt;em&gt;no&lt;/em&gt;)&lt;/p&gt;
&lt;p&gt;Our operating system is easy to hijack. For human 1.0, all you need is a red blob popping up on the notification bar or an auto-play turned on by default.&lt;/p&gt;
&lt;h2 id=&quot;habits&quot; tabindex=&quot;-1&quot;&gt;Habits &lt;a class=&quot;direct-link&quot; href=&quot;https://mostlybugless.com/posts/2018-006-bad-habit/#habits&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;All habit-forming requires is a cue, routine, and reward.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://mostlybugless.com/img/legacy/articles/peakhabit/habit_loop.png&quot; alt=&quot;Habit loop&quot; /&gt;&lt;/p&gt;
&lt;p&gt;As your brain figures out the connection between them, you get locked into an automatic pattern. That worked great for our ancestors, who were more concerned with staying alive than watching cat videos. And not so great for us &lt;strong&gt;when thousands of people work daily to get us hooked on their products&lt;/strong&gt; with the same mechanisms.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://mostlybugless.com/img/legacy/articles/peakhabit/habit_loop_sample.png&quot; alt=&quot;Habit loop with media example&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The worst and best thing about habits is that we do them automatically. Life would be pretty dull if I had to decide which pocket to put my wallet in consciously. But when opening your laptop triggers a direct pathway to an infinite-scrolling website, we have a tremendous problem.&lt;/p&gt;
&lt;p&gt;(You can read more about habits in the excellent &amp;quot;The power of habit&amp;quot; by Charles Duhigg)&lt;/p&gt;
&lt;h2 id=&quot;apple-and-google-to-the-rescue&quot; tabindex=&quot;-1&quot;&gt;Apple and Google to the rescue? &lt;a class=&quot;direct-link&quot; href=&quot;https://mostlybugless.com/posts/2018-006-bad-habit/#apple-and-google-to-the-rescue&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Both &lt;a href=&quot;https://www.cnbc.com/2018/06/12/ios-12-screen-time-hands-on-preview.html&quot;&gt;Apple&lt;/a&gt; and &lt;a href=&quot;https://www.cnbc.com/2018/05/09/google-fighting-smartphone-addiction-with-android-p-digital-wellness.html&quot;&gt;Google&lt;/a&gt; recently revealed upcoming features for iOS and Android which aim at helping users manage their interactions with phones. Usage statistics, blocking apps by the time of day, limiting notifications, etc.&lt;/p&gt;
&lt;p&gt;While those are far from revolutionary and don&#39;t seem to deliver much over &#39;just turning your goddamn phone off,&#39; they prove there is enough pressure on digital wellbeing that companies which earn on screen time are willing to help users limit it. That&#39;s a good sign! Maybe movements like &lt;a href=&quot;http://humanetech.com/&quot;&gt;Time Well Spent&lt;/a&gt; and a rising tide of articles and books (The Shallows comes to mind) will slowly move us towards a more conscious future?&lt;/p&gt;
&lt;h2 id=&quot;a-low-tech-alternative&quot; tabindex=&quot;-1&quot;&gt;A low-tech alternative &lt;a class=&quot;direct-link&quot; href=&quot;https://mostlybugless.com/posts/2018-006-bad-habit/#a-low-tech-alternative&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Time tracking isn&#39;t a new idea. Many apps and companies offer precisely that already. I wasn&#39;t delighted with the ones I tried before, mainly due to a tiny little issue I have with running borderline spyware on my devices.&lt;/p&gt;
&lt;p&gt;So yes, getting statistics of my screen usage from built-in system functionality sounds &lt;strong&gt;amazing&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;But before that makes its way to my phone, there is a straightforward exercise that I run from time to time which helps me notice unwanted patterns in my life:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Print out a &lt;a href=&quot;https://mostlybugless.com/img/legacy/articles/peakhabit/time_log.pdf&quot;&gt;time log&lt;/a&gt; for two days&lt;/li&gt;
&lt;li&gt;Every 15 minutes, write down what you were doing&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;After two days:&lt;/p&gt;
&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;Be surprised&lt;/li&gt;
&lt;li&gt;Ask yourself is this consistent with your self-perception - and what you want to change&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;It works wonders for me, and a few &lt;del&gt; guinea pigs &lt;/del&gt; people I &lt;del&gt;forced&lt;/del&gt; kindly motivated to try it - without depending on a tech giant to solve my problems.&lt;/p&gt;
&lt;p&gt;There seems to be also a whole movement and a book by Laura Vanderkam (&amp;quot;168 hours&amp;quot;) based on radical time tracking, but I haven&#39;t yet gotten around to digging deeper into it.&lt;/p&gt;
&lt;h2 id=&quot;peak-bad-habit&quot; tabindex=&quot;-1&quot;&gt;Peak bad habit &lt;a class=&quot;direct-link&quot; href=&quot;https://mostlybugless.com/posts/2018-006-bad-habit/#peak-bad-habit&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I wonder if we will see more news about digital monopolies taking action to limit their habit-forming impact. If the social pendulum swings back from digitized life back to reality, we all would be better off. But in a world where competition for our attention is a zero-sum game for tech giants, there are good reasons to remain skeptical, even in the face of the first good signs.&lt;/p&gt;
&lt;p&gt;Still, there is always the personal choice to pull the plug on any service you know you spend too much time on.&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;He is free who lives as he wishes to live; who is neither subject to compulsion nor to hindrance, nor to force; whose movements to action are not impeded, whose desires attain their purpose, and who does not fall into that which he would avoid.&lt;/p&gt;&lt;footer&gt;&lt;cite&gt;Discourses by Epictetus&lt;/cite&gt;&lt;/footer&gt;&lt;/blockquote&gt;

		</content>
	</entry>
	
	<entry>
		<title>Post-authenticity society</title>
		<link href="https://mostlybugless.com/posts/2018-005-post-authenticity/" />
		<updated>2018-07-29T00:00:00Z</updated>
		<id>https://mostlybugless.com/posts/2018-005-post-authenticity/</id>
		<content type="html">&lt;p&gt;I&#39;m only 3 books into the series, but The Culture by Iain M. Banks is one of the best pieces of sci-fi I recently read. 30 years ago Mr. Banks in one of the books made a casual remark about authenticity in a society where any kind of proof can be faked with technology. Keep in mind that his vision is one of the most optimistic scenarios for technological advancement where artificial intelligence coexists with mere humans in an utopian society.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;(...) Anybody could make up anything they wanted; sound, moving pictures, smell, touch . . . there were machines that did just that. You could order them from a store and effectively paint whatever pictures-still or moving-you wanted, and with sufficient time and patience you could make it look as realistic as the real thing, recorded with an ordinary camera. You could simply make up any film sequence you wanted.  &lt;br /&gt;&lt;br /&gt;
Some people used such machines just for fun or revenge, making up stories where appalling or just funny things happened to their enemies or their friends. Where nothing could be authenticated, blackmail became both pointless and impossible; in a society like the Culture, where next to nothing was forbidden, and both money and individual power had virtually ceased to exist, it was doubly irrelevant.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;footer&gt;&lt;cite&gt;The Player of Games by Iain M. Banks&lt;/cite&gt;&lt;/footer&gt;
&lt;p&gt;The funny thing is, we are kind of &lt;a href=&quot;https://www.youtube.com/watch?v=cQ54GDm1eL0&quot; traget=&quot;_blank&quot;&gt;getting there&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;You have most likely heard about &#39;deep fakes&#39; before. The term blew up in the news when everyone started using machine learning to substitute faces in videos. Political satire, revenge pornography, and Nicolas Cage as the main character of every movie - humans applying &lt;del&gt;artificial intelligence&lt;/del&gt; &lt;ins&gt;any new technology&lt;/ins&gt; at its finest.&lt;/p&gt;
&lt;p&gt;At the same time, there are startups that aim to perfect voice imitation. &lt;a href=&quot;https://mostlybugless.com/posts/2018-005-post-authenticity/lyrebird.ai&quot; target=&quot;_blank&quot;&gt;Lyrebird&lt;/a&gt; lets you create a model of your own voice. They made the news with fake samples for Trump, Clinton, and Obama early last year. Their demo is already taken down, but you can hear the samples on a &lt;a href=&quot;https://techcrunch.com/2017/04/25/lyrebird-is-a-voice-mimic-for-the-fake-news-era/&quot; target=&quot;_blank&quot;&gt;TechCrunch article&lt;/a&gt;. Far from perfect, but a significant step. &lt;/p&gt;
&lt;img class=&quot;content-image pure-img&quot; src=&quot;https://mostlybugless.com/img/legacy/articles/postauthenticity/censure_sample.jpg&quot; alt=&quot;Sample of photo censure&quot; /&gt;
&lt;p&gt;It was &lt;strong&gt;always&lt;/strong&gt; possible to alter images, as the classic example above proves. Photoshop just made it much more accessible. The same with videos - with enough resources you can fake any kind of evidence.&lt;/p&gt;
&lt;p&gt;We are however far from an utopia where money and power do not matter, like the society of Culture in Bank&#39;s fiction. So what can we trust today? And who can we trust tomorrow?&lt;/p&gt;

		</content>
	</entry>
	
	<entry>
		<title>Pumping up your productivity with..noise?</title>
		<link href="https://mostlybugless.com/posts/2018-004-mynoise/" />
		<updated>2018-07-22T00:00:00Z</updated>
		<id>https://mostlybugless.com/posts/2018-004-mynoise/</id>
		<content type="html">&lt;h2 id=&quot;noising-up-your-productivity&quot; tabindex=&quot;-1&quot;&gt;Noising up your productivity &lt;a class=&quot;direct-link&quot; href=&quot;https://mostlybugless.com/posts/2018-004-mynoise/#noising-up-your-productivity&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Open space offices are kind of an antipattern. You can find relevant articles and studies easily. &lt;strong&gt;Quiet: The Power of Introverts in a World That Can&#39;t Stop Talking&lt;/strong&gt; by Susan Cain can be a good starting point:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Open-plan offices have been found to reduce productivity and impair memory. They&#39;re associated with high staff turnover. They make people sick, hostile, unmotivated, and insecure.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This post is not about bashing open-space. The world outside of the office is not much better at promoting focus and deep work. Significant others, neighbors, cars, trains, birds, animals, generally humans and non-humans tend to make noise. Optimizing your environment for focus is hard and sometimes outside of our circle of control. This post is about doing damage control where we can.&lt;/p&gt;
&lt;h2 id=&quot;spacing-out&quot; tabindex=&quot;-1&quot;&gt;Spacing out &lt;a class=&quot;direct-link&quot; href=&quot;https://mostlybugless.com/posts/2018-004-mynoise/#spacing-out&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Headphones - the international sign of a focused developer. Some buy 900$ active noise-canceling headphones, some just blast 80&#39;s power metal full volume. I&#39;m not that keen on expensive tech gadgets, and music tends to grab by attention, which is just substituting one distraction for another.&lt;/p&gt;
&lt;p&gt;A few years ago though, the Interstellar movie (yes, Interstellar came out 4 years ago!) inspired me to take a look at nature noises. Remember how they used to listen to a thunderstorm with crickets on the spaceship? So that&#39;s how I found...&lt;/p&gt;
&lt;h2 id=&quot;mynoise-net&quot; tabindex=&quot;-1&quot;&gt;&lt;a href=&quot;https://mynoise.net/&quot; target=&quot;_blank&quot;&gt;MyNoise.net&lt;/a&gt; &lt;a class=&quot;direct-link&quot; href=&quot;https://mostlybugless.com/posts/2018-004-mynoise/#mynoise-net&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;tl;dr:&lt;/strong&gt; check out that site, use it to nullify distractions, better than any &#39;programming playlist&#39;.&lt;/p&gt;
&lt;p&gt;On mynoise you can find noise generators that let you relax, meditate, sleep or not go mad during a 23 year long solitary recluse in a spaceship. Moreover, some of them are marked as noise-canceling - put on your headphones and hear what happens when someone talks next to you. White noise is the secret sauce that drowns the world outside of your headphones.&lt;/p&gt;
&lt;h2 id=&quot;white-noise&quot; tabindex=&quot;-1&quot;&gt;White noise &lt;a class=&quot;direct-link&quot; href=&quot;https://mostlybugless.com/posts/2018-004-mynoise/#white-noise&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If you look up white noise, you are most likely going to find thousands of videos and applications designed to help babies sleep. Instead of running a hair drier or vacuum for 6 hours you can just play it on your computer, pretty convenient I guess. But what is white noise?&lt;/p&gt;
&lt;p&gt;In the simplest terms, white noise is a random signal with equal intensity at different frequencies. If you look at the power spectrum of synthetic white noise you can see something like this:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://mostlybugless.com/img/legacy/articles/mynoise/white_noise_spectrum.png&quot; alt=&quot;White noise spectrum&quot; /&gt;&amp;gt;&lt;/p&gt;
&lt;p&gt;If we merge it with a human speech the result is not always perfect; if you listen carefully, you can still understand some of the words. However it&#39;s usually good enough to prevent distractions. Consider someone talking directly in front of you:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://mostlybugless.com/img/legacy/articles/mynoise/human_speech.png&quot; alt=&quot;Human speech&quot; /&gt;&amp;gt;&lt;img src=&quot;https://mostlybugless.com/img/legacy/articles/mynoise/human_speech_spectrogram.png&quot; alt=&quot;Human speech spectrogram&quot; /&gt;&amp;gt;&lt;/p&gt;
&lt;p&gt;And the same with applied white noise:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://mostlybugless.com/img/legacy/articles/mynoise/human_with_noise.png&quot; alt=&quot;Human speech with applied white noise&quot; /&gt;&amp;gt;&lt;img src=&quot;https://mostlybugless.com/img/legacy/articles/mynoise/human_with_noise_spectogram.png&quot; alt=&quot;Spectrogram of human speech with white noise&quot; /&gt;&amp;gt;&lt;/p&gt;
&lt;p&gt;If the voice was generated two meters away - it would be utterly indescribable.&lt;/p&gt;
&lt;p&gt;The topic is quite complicated, but the key takeaway is that white noise is excellent in masking other sounds. Moreover, some of the natural sounds are very close to white noise in the audible spectrum - rain, waterfalls, hair dryers.&lt;/p&gt;
&lt;p&gt;I&#39;ve been using &lt;a href=&quot;http://mynoise.net/&quot;&gt;mynoise.net&lt;/a&gt; for years already. Listening to actual synthetic white noise isn&#39;t my favourite way to use it, but natural noises that are &#39;close enough&#39; are great for my focus - they helped me work or think even in the most annoying conditions. My favorite?&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://mynoise.net/NoiseMachines/tropicalRainNoiseGenerator.php&quot; target=&quot;_blank&quot;&gt;Tropical rain, &lt;/a&gt;
&lt;a href=&quot;https://mynoise.net/NoiseMachines/windSeaRainNoiseGenerator.php&quot; target=&quot;_blank&quot;&gt;Irish Coast,&lt;/a&gt; and
&lt;a href=&quot;https://mynoise.net/NoiseMachines/cafeRestaurantNoiseGenerator.php&quot; target=&quot;_blank&quot;&gt;Cafe Restaurant&lt;/a&gt;&lt;/p&gt;

		</content>
	</entry>
	
	<entry>
		<title>Chatbots - should I call LUIS?</title>
		<link href="https://mostlybugless.com/posts/2018-003-call-luis/" />
		<updated>2018-07-05T00:00:00Z</updated>
		<id>https://mostlybugless.com/posts/2018-003-call-luis/</id>
		<content type="html">&lt;h2 id=&quot;radical-changes-in-microsoft-botframework-v4&quot; tabindex=&quot;-1&quot;&gt;Radical changes in Microsoft BotFramework v4 &lt;a class=&quot;direct-link&quot; href=&quot;https://mostlybugless.com/posts/2018-003-call-luis/#radical-changes-in-microsoft-botframework-v4&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Microsoft stack for bots lets you quickly build smart and functional bots. It&#39;s great, check it out, build your own ~friends~ virtual assistants. Architecture can be boiled down to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Bot Service&lt;/strong&gt; - a connector that abstracts any channel (Skype, slack, etc.)&lt;/li&gt;
&lt;li&gt;REST-ful app that you develop with &lt;strong&gt;BotFramework SDK&lt;/strong&gt; that is called by Bot Service with every message&lt;/li&gt;
&lt;li&gt;Any additional services that provide &amp;quot;intelligence&amp;quot; to your bot (LUIS, QnA, Azure Search..)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&quot;https://www.luis.ai/&quot; target=&quot;_blank&quot;&gt;LUIS&lt;/a&gt;, part of that offering - Language Understanding service - enables you to easily detect what the user wants. If you want to know that user asks to &amp;quot;BookFlight&amp;quot; (intent) and you expect people to say something like:&lt;/p&gt;
&lt;pre class=&quot;language-txt&quot;&gt;&lt;code class=&quot;language-txt&quot;&gt;    Book flight to [place] on [date]&lt;br /&gt;    &lt;br /&gt;    I want to go to [place] on [date]&lt;br /&gt;    &lt;br /&gt;    On [date] I want to fly to [place]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Congratulations, you have just pretty much written down a LUIS model.&lt;/p&gt;
&lt;p&gt;Now, if you are interested in BotFramework you may have noticed that in SDK v3 the default behavior is to send every user query to LUIS. All samples related to intelligence use middleware that hijacks the flow if an intent is found in user answer.&lt;/p&gt;
&lt;h2 id=&quot;should-we-call-luis-on-every-single-message&quot; tabindex=&quot;-1&quot;&gt;Should we call LUIS on every single message? &lt;a class=&quot;direct-link&quot; href=&quot;https://mostlybugless.com/posts/2018-003-call-luis/#should-we-call-luis-on-every-single-message&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The short answer: &lt;strong&gt;no&lt;/strong&gt;. And that&#39;s also direction SDK v4 has recently taken, but before that let&#39;s consider two situations:&lt;/p&gt;
&lt;div class=&quot;chat-wrapper&quot;&gt;
&lt;div class=&quot;chat-bubble-left&quot;&gt;
    &lt;p&gt;Where do you want to pick up your order?&lt;/p&gt;&lt;ol&gt;&lt;li&gt;At our restaurant&lt;/li&gt;&lt;li&gt;At your office&lt;/li&gt;&lt;li&gt;At your home&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;div class=&quot;chat-bubble-right&quot;&gt;&lt;p&gt;home&lt;/p&gt;&lt;/div&gt;&lt;div class=&quot;chat-bubble-left&quot;&gt;&lt;p&gt;What&#39;s your home address?&lt;/p&gt;&lt;/div&gt;&lt;div class=&quot;chat-bubble-right&quot;&gt;&lt;p&gt;Home Street 1145&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Asking LUIS by default wouldn&#39;t provide any value. And on the other side we would dent our LUIS calls quota (50 calls / sec / service, chargable) and possibly get sensitive user data in endpoint logs!&lt;/p&gt;
&lt;h2 id=&quot;sdk-v4-changes&quot; tabindex=&quot;-1&quot;&gt;SDK v4 - changes &lt;a class=&quot;direct-link&quot; href=&quot;https://mostlybugless.com/posts/2018-003-call-luis/#sdk-v4-changes&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;BotFramework SDK v3 is the current production-quality release. V4 is in preview and changes rapidly, but if you look at the docs and samples you can still see LUIS middlewares used everywhere.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://mostlybugless.com/img/legacy/articles/luis/commit.png&quot; alt=&quot;Commit screenshot&quot; /&gt;&amp;gt;&lt;/p&gt;
&lt;p&gt;Well. 27.06, pretty much a week ago, all middleware for LUIS and QnA was removed from master branch. The idea is that we as developers must own the decision when to call LUIS. &lt;strong&gt;And that&#39;s great!&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&quot;luis-and-input&quot; tabindex=&quot;-1&quot;&gt;LUIS and input &lt;a class=&quot;direct-link&quot; href=&quot;https://mostlybugless.com/posts/2018-003-call-luis/#luis-and-input&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In contrast to previous samples, let&#39;s consider:&lt;/p&gt;
&lt;div class=&quot;chat-wrapper&quot;&gt;&lt;div class=&quot;chat-bubble-left&quot;&gt;&lt;p&gt;What&#39;s your street address?&lt;/p&gt;&lt;/div&gt;&lt;div class=&quot;chat-bubble-right&quot;&gt;&lt;p&gt;Wait, why do you need my address?&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;In that case the user obviously (for me and my fellow humans such as you, my dear reader) wants to do something different, but at the level of input to an app - we don&#39;t really know that. Should we call LUIS just in case?&lt;/p&gt;
&lt;h2 id=&quot;the-pragmatic-reality&quot; tabindex=&quot;-1&quot;&gt;The pragmatic reality &lt;a class=&quot;direct-link&quot; href=&quot;https://mostlybugless.com/posts/2018-003-call-luis/#the-pragmatic-reality&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;One of the most important (and far too often not used at all or poorly implemented) patterns in user experience is the ~undo~ functionality. However, as hard as it&#39;s to implement sensibly in conversational interfaces, we can at least rely on double confirmations&lt;/p&gt;
&lt;div class=&quot;chat-wrapper&quot;&gt;
    &lt;div class=&quot;chat-bubble-left&quot;&gt;&lt;p&gt;We will send your package to &quot;Wait, why do you need my address&quot;. Is that correct&lt;/p&gt;
    &lt;/div&gt;
    &lt;div class=&quot;chat-bubble-right&quot;&gt;&lt;p&gt;no, go back!&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Confirmation might be the right place to call LUIS, or even better - try checking the answer with rule-based, &amp;quot;less-intelligent&amp;quot; parser.&lt;/p&gt;
&lt;p&gt;Building chatbots is a very different kind of challenge that any traditional UI. There are hundreds of weird edge cases like that and at the end we are still nowhere near pretending to create human-level experience with chatbots. But if we as creators don&#39;t overpromise - users turn a blind eye for some minor blunders in our &amp;quot;intelligent&amp;quot; applications. And get some real problems solved behind the scenes which is the only thing that counts in the end.&lt;/p&gt;
&lt;p&gt;Still, some brave souls that use preview version of BotFramework SDK may be in for a surprise after next release.&lt;/p&gt;

		</content>
	</entry>
	
	<entry>
		<title>Automated page rendering revisited - Puppeteer edition</title>
		<link href="https://mostlybugless.com/posts/2018-002-puppeteer/" />
		<updated>2018-05-18T00:00:00Z</updated>
		<id>https://mostlybugless.com/posts/2018-002-puppeteer/</id>
		<content type="html">&lt;h2 id=&quot;the-king-is-dead-long-live-the-king&quot; tabindex=&quot;-1&quot;&gt;The king is dead, long live the king &lt;a class=&quot;direct-link&quot; href=&quot;https://mostlybugless.com/posts/2018-002-puppeteer/#the-king-is-dead-long-live-the-king&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;PhantomJS - default headless browser used by many automatic testing solutions - is dead. The only information about that fact can be found in &lt;a href=&quot;https://github.com/ariya/phantomjs/issues/15344&quot; target=&quot;_blank&quot;&gt;one of 1823 open issues in git repository&lt;/a&gt;. Don&#39;t blame yourself if you didn&#39;t notice. Hopefully you haven&#39;t recently started a new project using it or &lt;strong&gt;spent few days writing an extensive &lt;a href=&quot;https://mostlybugless.com/posts/2018-001-phantomjs&quot;&gt;post&lt;/a&gt;&lt;/strong&gt; detailing workarounds for some interesting edge-case uses.&lt;/p&gt;
&lt;p&gt;[EDIT: &lt;a href=&quot;http://phantomjs.org/&quot;&gt;http://phantomjs.org/&lt;/a&gt; is already updated with this information]&lt;/p&gt;
&lt;p&gt;However, it deserves a moment of silence. PhantomJS had a good run, helped solve real development issues and even large brands like Netflix, LinkedIn and Twitter mentioned using it. Who knows how many critical bugs were caught thanks to it?&lt;/p&gt;
&lt;p&gt;In the meantime, somewhen last year, Chrome shipped version 59 supporting headless browsing. There is not much to discuss - it&#39;s hard to ask for stabler engine than chromium.&lt;/p&gt;
&lt;h2 id=&quot;controlling-your-puppets&quot; tabindex=&quot;-1&quot;&gt;Controlling your puppets &lt;a class=&quot;direct-link&quot; href=&quot;https://mostlybugless.com/posts/2018-002-puppeteer/#controlling-your-puppets&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Google ships a framework for controlling Chrome/Chromium under a well chosen name of &lt;a href=&quot;https://developers.google.com/web/tools/puppeteer/&quot; target=&quot;_blank&quot;&gt;puppeteer&lt;/a&gt;. I have to admit I&#39;m having a blast exploring its API and that&#39;s why today we are going to redo some of the functionalities from my previous post.&lt;/p&gt;
&lt;p&gt;Puppeteer has also been featured on Google I/O &#39;18, you can watch &lt;a href=&quot;https://www.youtube.com/watch?v=lhZOFUY1weo&quot; target=&quot;_blank&quot;&gt;the session here&lt;/a&gt; and &lt;a href=&quot;https://github.com/GoogleChromeLabs/puppeteer-examples&quot; target=&quot;_blank&quot;&gt; see the samples here&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;typing-your-types&quot; tabindex=&quot;-1&quot;&gt;Typing your types &lt;a class=&quot;direct-link&quot; href=&quot;https://mostlybugless.com/posts/2018-002-puppeteer/#typing-your-types&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;This time we are not bound by PhantomJS engine so we can create a regular Node.js app. I&#39;ll be using TypeScript - if you haven&#39;t used it before, it&#39;s a less-bad JavaScript that gets transpiled to JavaScript but pretty much looks the same like JavaScript. Sarcasm aside, it really helps with whole classes of issues and has a very low starting barrier for anyone proficient in JS and object-oriented paradigm.&lt;/p&gt;
&lt;p&gt;I won&#39;t be going into details of TypeScript here - samples below barely use any significant features and you should be able to read it just like JavaScript.&lt;/p&gt;
&lt;h2 id=&quot;simple-rendering&quot; tabindex=&quot;-1&quot;&gt;Simple rendering &lt;a class=&quot;direct-link&quot; href=&quot;https://mostlybugless.com/posts/2018-002-puppeteer/#simple-rendering&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;pre class=&quot;language-ts&quot;&gt;&lt;code class=&quot;language-ts&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; puppeteer &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;puppeteer&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;async&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;run&lt;/span&gt;&lt;span class=&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 builtin&quot;&gt;Promise&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; browser &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; puppeteer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;launch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&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; page &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; browser&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;newPage&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&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; page&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;goto&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;https://mostlybugless.com&#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;br /&gt;   &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; page&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;screenshot&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; path&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;mb.png&#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;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;   &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; browser&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;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 function&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&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;Easy!&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://mostlybugless.com/img/legacy/articles/puppeteer/initial-render.png&quot; alt=&quot;Initial rendering of a webpage&quot; /&gt;&lt;/p&gt;
&lt;h2 id=&quot;viewport-and-emulation&quot; tabindex=&quot;-1&quot;&gt;Viewport and emulation &lt;a class=&quot;direct-link&quot; href=&quot;https://mostlybugless.com/posts/2018-002-puppeteer/#viewport-and-emulation&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Our end-goal is to verify if a website looks good on most common devices. We can easily set viewport of a page with&lt;/p&gt;
&lt;pre class=&quot;language-ts&quot;&gt;&lt;code class=&quot;language-ts&quot;&gt;page&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setViewport&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;viewport&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Besides width and height, it supports &lt;a href=&quot;https://github.com/GoogleChrome/puppeteer/blob/v1.3.0/docs/api.md#pagesetviewportviewport&quot; target=&quot;_blank&quot;&gt;additional settings&lt;/a&gt; which I&#39;m going to ignore&lt;/p&gt;
&lt;p&gt;But one thing to keep in mind is that puppeteer provides&lt;/p&gt;
&lt;pre class=&quot;language-ts&quot;&gt;&lt;code class=&quot;language-ts&quot;&gt;page&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;emulate&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/GoogleChrome/puppeteer/blob/v1.3.0/docs/api.md#pageemulateoptions&quot; target=&quot;_blank&quot;&gt;which&lt;/a&gt; you can use as a shorthand to emulate any of the already &lt;a href=&quot;https://github.com/GoogleChrome/puppeteer/blob/master/DeviceDescriptors.js&quot; target=&quot;_blank&quot;&gt;defined devices&lt;/a&gt;. Fun!&lt;/p&gt;
&lt;p&gt;Single line sanity check:&lt;/p&gt;
&lt;pre class=&quot;language-ts&quot;&gt;&lt;code class=&quot;language-ts&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; page&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setViewport&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&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;1366&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; height&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;768&lt;/span&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;h2 id=&quot;scrolling&quot; tabindex=&quot;-1&quot;&gt;Scrolling &lt;a class=&quot;direct-link&quot; href=&quot;https://mostlybugless.com/posts/2018-002-puppeteer/#scrolling&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In the previous post I committed some serious crimes against code to create gifs of page scrolling. With full node support this time we could easily integrate one of the more reasonable gif-rendering packages and call it a day, but one issue bothered me - you can&#39;t stop a gif. That&#39;s nice that you can notice an issue in the middle of a page, but if it&#39;s gone in next 200 ms, that&#39;s not a great user experience.&lt;/p&gt;
&lt;p&gt;Now, puppeteer doesn&#39;t (yet) have a direct api to scroll, which is a shame. Still, since we can run anything directly on the page itself..&lt;/p&gt;
&lt;pre class=&quot;language-ts&quot;&gt;&lt;code class=&quot;language-ts&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; stepPoints &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; page&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;evaluate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;document.body.scrollHeight&#39;&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 function&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;scrollHeight &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 builtin&quot;&gt;console&lt;/span&gt;&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;scrollHeight&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; adjustedHeight &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; scrollHeight &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; step&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; lastScrollHeigthToRender &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; adjustedHeight &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; adjustedHeight &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;br /&gt;           &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; stepCount &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;ceil&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;lastScrollHeigthToRender &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; step&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;span class=&quot;token function&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;stepCount&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;stepNo &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; stepNo &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; step&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;br /&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;let&lt;/span&gt; point &lt;span class=&quot;token keyword&quot;&gt;of&lt;/span&gt; stepPoints&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; path &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 string&quot;&gt;mb-&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;point&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;.png&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;br /&gt;       &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; page&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;evaluate&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;window.scrollTo(0, &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;point&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 keyword&quot;&gt;await&lt;/span&gt; page&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;screenshot&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; path &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token 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;/code&gt;&lt;/pre&gt;
&lt;p&gt;With this adjustment, we got&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://mostlybugless.com/img/legacy/articles/puppeteer/scrolling.png&quot; alt=&quot;Page with scrolling&quot; /&gt;&lt;/p&gt;
&lt;h2 id=&quot;summary&quot; tabindex=&quot;-1&quot;&gt;Summary &lt;a class=&quot;direct-link&quot; href=&quot;https://mostlybugless.com/posts/2018-002-puppeteer/#summary&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Puppeteer is a powerful framework and it&#39;s only starting to get attention. I expect to see many interesting use cases in coming months. Also, if you haven&#39;t yet tried TypeScript - give it a chance. It will be worth it.&lt;/p&gt;
&lt;p&gt;This time I&#39;m not going to completely automate the rendering as in the previous post, but maybe I&#39;ll come back to this topic. In the meantime you can get a good start with above code. Enjoy your puppets!&lt;/p&gt;

		</content>
	</entry>
	
	<entry>
		<title>PhantomJS for automatic responsive page rendering</title>
		<link href="https://mostlybugless.com/posts/2018-001-phantomjs/" />
		<updated>2018-04-05T00:00:00Z</updated>
		<id>https://mostlybugless.com/posts/2018-001-phantomjs/</id>
		<content type="html">&lt;blockquote&gt;
&lt;p&gt;PhantomJS is a headless WebKit scriptable with a JavaScript API&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;While you might&#39;ve already used PhantomJS as a part of a test automation stack, it&#39;s also a powerful standalone tool you can use for fun and profit. My experiment today:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How can I automatically check my website on multiple screen sizes?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;There are some great tools out there that you can try, but if you are running low-budget (like a personal blog) or feel
an insatiable urge to overengineer a simple problem, feel free to follow along. We are going to end up with a report
that will look like &lt;a href=&quot;https://mostlybugless.com/img/legacy/articles/phantomjs/mb/report.html&quot;&gt;this&lt;/a&gt;.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Download &lt;a href=&quot;http://phantomjs.org/&quot; target=&quot;_blank&quot;&gt;PhanthomJS&lt;/a&gt; , I&#39;ll be running
phantomjs-2.1.1-windows.&lt;/li&gt;
&lt;li&gt;Though there is sadly no support for ES6, the API is really reasonable and well documented. Let&#39;s start with a sanity
check and just render our webpage. Create a file &lt;strong&gt;render.js&lt;/strong&gt;, which will load the webpage module and save it to png
file:&lt;/li&gt;
&lt;/ol&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; page &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;webpage&#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;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;page&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;&#39;https://mostlybugless.com/&#39;&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 punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    page&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;render&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;mb.png&#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;    phantom&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;exit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&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;&lt;a href=&quot;http://phantomjs.org/screen-capture.html&quot; target=&quot;_blank&quot;&gt;Link to screen capture API docs&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;You can run it with:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;phantomjs&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;exe render&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;js&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;https://mostlybugless.com/img/legacy/articles/phantomjs/page-screenshot-1.png&quot;&gt;Resulting image&lt;/a&gt; will
contain full-lenght page with minimum-width render. Not quite what we wanted, but ~it&#39;s something~.
3. We can configure our script to change the viewport with:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;page&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;viewportSize &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;width&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1024&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;height&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;768&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;Aaand &lt;a href=&quot;https://mostlybugless.com/img/legacy/articles/phantomjs/page-screenshot-2.png&quot;&gt;that&lt;/a&gt; doesn&#39;t look
like 1024x768. Viewport is the size of actual headless browser but rendering in default saves full page length. Let&#39;s
fix that by letting PhantomJS know which part of the page we want to clip when taking screenshot.&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;page&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;clipRect &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;top&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1024&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;768&lt;/span&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;In some cases we may want to render full lenght of page, but as you can see on this very blog, we wouldn&#39;t get actual
user experience for fixed position elements. Altogether we are now at:&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; page &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;webpage&#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;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;page&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;&#39;https://mostlybugless.com/&#39;&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 punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    page&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;viewportSize &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;width&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1024&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;height&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;768&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;    page&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;clipRect &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;top&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;token literal-property property&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;token literal-property property&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1024&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;height&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;768&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;    page&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;render&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;mb.png&#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;    phantom&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;exit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&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;&lt;img src=&quot;https://mostlybugless.com/img/legacy/articles/phantomjs/page-screenshot-3.png&quot; alt=&quot;Created screenshot&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Tremendous success! We have covered the basic screen capture guide from PhantomJS documentation. We could easily
for-loop it here and call it a day. Build package that you downloaded should even contains an example script by Salih
Sagdilek - &lt;strong&gt;responsive-screenshot.js&lt;/strong&gt;, which pretty much does that.&lt;/p&gt;
&lt;p&gt;Let&#39;s go a little bit deeper&lt;/p&gt;
&lt;h2 id=&quot;rendering-page-with-scrolling&quot; tabindex=&quot;-1&quot;&gt;Rendering page with scrolling &lt;a class=&quot;direct-link&quot; href=&quot;https://mostlybugless.com/posts/2018-001-phantomjs/#rendering-page-with-scrolling&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;PhantomJS API allows us to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Evaluate any function in the context of opened webpage&lt;/li&gt;
&lt;/ul&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; actualHeight &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; page&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;evaluate&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 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; document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;body&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;scrollHeight&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;ul&gt;
&lt;li&gt;Scroll page to a desired position&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;page&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;scrollPosition &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;top&lt;/span&gt;&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 punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token literal-property property&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;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;By combining those two features with simple math we can automatically save screenshots of a virtual full-page scroll to
bottom.&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; page &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;webpage&#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;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;page&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;&#39;https://mostlybugless.com/&#39;&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 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; viewPort &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;width&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1024&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;height&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;768&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;    page&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;viewportSize &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; viewPort&lt;br /&gt;    page&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;clipRect &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;top&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;token literal-property property&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;token literal-property property&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; viewPort&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;width&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;token literal-property property&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; viewPort&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;height&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; actualHeight &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; page&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;evaluate&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 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; document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;body&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;scrollHeight&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;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; step &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 punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; stepCount &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;actualHeight &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; viewPort&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 operator&quot;&gt;/&lt;/span&gt; step&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;1&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;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; stepCount&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;br /&gt;        page&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;scrollPosition &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;top&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;min&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; step&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; actualHeight &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; viewPort&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 literal-property property&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;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;        page&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;render&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;mb&#39;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;.png&#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;br /&gt;&lt;br /&gt;    phantom&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;exit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&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;&lt;img src=&quot;https://mostlybugless.com/img/legacy/articles/phantomjs/scrolling-screenshots.png&quot; alt=&quot;Screenshot with scrolling&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Now that we have got a series of pictures, how about&lt;/p&gt;
&lt;h2 id=&quot;making-a-page-interaction-gif-animation-automatically&quot; tabindex=&quot;-1&quot;&gt;Making a page interaction gif animation automatically &lt;a class=&quot;direct-link&quot; href=&quot;https://mostlybugless.com/posts/2018-001-phantomjs/#making-a-page-interaction-gif-animation-automatically&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If it was ever created, it will be rewritten in javascript at some point. It&#39;s true for git clients, web servers and video-processing frameworks - for better or worse. But in the latter we are interested. There is a small gif-creating library from yahoo we are going to use:&lt;/p&gt;
&lt;p&gt;v&lt;a href=&quot;https://github.com/yahoo/gifshot&quot; target=&quot;_blank&quot;&gt;gifshot&lt;/a&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;var&lt;/span&gt; page &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;webpage&#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;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;var&lt;/span&gt; gifshot &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;./gifshot.js&#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 keyword&quot;&gt;var&lt;/span&gt; fs &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;fs&#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;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; webserver &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;webserver&#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 keyword&quot;&gt;var&lt;/span&gt; server &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; webserver&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;var&lt;/span&gt; service &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; server&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;listen&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;8083&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;request&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; response&lt;/span&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;    response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;statusCode &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 punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setHeader&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;Access-Control-Allow-Origin&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;*&#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;    response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setHeader&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;Content-Type&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;image/png&#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;    response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setEncoding&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;binary&#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 keyword&quot;&gt;var&lt;/span&gt; path &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; request&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;url&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;substring&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token 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;&#39;request &#39;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; path&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; file &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; fs&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;path&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;rb&#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 keyword&quot;&gt;var&lt;/span&gt; data &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; file&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&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;    file&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;data&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;    response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;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;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; GifReadyMessage &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;[Injected] Gif Ready&#39;&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;&lt;span class=&quot;token string&quot;&gt;&#39;server started &#39;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; service&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;page&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;&#39;http://localhost:54359/&#39;&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;status&lt;/span&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;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;status&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    page&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;onConsoleMessage&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;msg&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; lineNum&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; sourceId&lt;/span&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;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;CONSOLE: &#39;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; msg &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39; (from line #&#39;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; lineNum &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39; in &#92;&quot;&#39;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; sourceId &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;&#92;&quot;)&#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 function&quot;&gt;handlePageConsoleMessage&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;msg&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; page&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;    page&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;onError &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; logError&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; width &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1024&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; height &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;768&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; gifDownScale &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 keyword&quot;&gt;var&lt;/span&gt; gifFrameDuration &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 10 = 1 second&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; scrollingPixelStep &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 punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; fileNamePrefix &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;mb&#39;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; files &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;renderPage&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;page&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; width&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; height&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; scrollingPixelStep&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; fileNamePrefix&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;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;rendered&#39;&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; injectsuccess &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; page&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;injectJs&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;./gifshot.js&#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;    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;&#39;injecting gifshot success&#39;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; injectsuccess&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; imagesToUse &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; files&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;f&lt;/span&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 string&quot;&gt;&#39;http://localhost:8083/&#39;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; f&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;    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;imagesToUse&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    page&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;evaluate&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;width&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; height&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; frameDuration&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; downscale&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; images&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; readyMessage&lt;/span&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;        gifshot&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createGIF&lt;/span&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;&#39;images&#39;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; images&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;token string-property property&quot;&gt;&#39;frameDuration&#39;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; frameDuration&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;token string-property property&quot;&gt;&#39;gifWidth&#39;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; width &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; downscale&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;token string-property property&quot;&gt;&#39;gifHeight&#39;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; height &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; downscale&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 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;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;obj&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;error&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;                _injected_tempGifStorage &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; obj&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;image&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;readyMessage&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;                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 constant&quot;&gt;JSON&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;stringify&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;obj&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&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;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; width&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; height&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; gifFrameDuration&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; gifDownScale&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; imagesToUse&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; GifReadyMessage&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 punctuation&quot;&gt;}&lt;/span&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;handlePageConsoleMessage&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;msg&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; page&lt;/span&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;msg &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; GifReadyMessage&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; gif &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; page&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;evaluate&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 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; _injected_tempGifStorage&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;var&lt;/span&gt; path &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;output.gif&#39;&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;&#39;Saving image&#39;&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; gifContent &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; gif&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;replace&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token regex&quot;&gt;&lt;span class=&quot;token regex-delimiter&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token regex-source language-regex&quot;&gt;^data:image&#92;/gif;base64,&lt;/span&gt;&lt;span class=&quot;token regex-delimiter&quot;&gt;/&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;&#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;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;        fs&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;atob&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;gifContent&lt;span class=&quot;token punctuation&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;wb&#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;        phantom&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;exit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&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;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;renderPage&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;page&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; width&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; height&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; scrollingStep&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; prefix&lt;/span&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;    page&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;viewportSize &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;width&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; width&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;token literal-property property&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; height&lt;br /&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;    page&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;clipRect &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;top&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;token literal-property property&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;token literal-property property&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; width&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;token literal-property property&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; height&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; actualHeight &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; page&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;evaluate&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 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; document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;body&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;scrollHeight&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;var&lt;/span&gt; step &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; scrollingStep&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; stepCount &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;actualHeight &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; height&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; step&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;1&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; files &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;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; stepCount&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;br /&gt;&lt;br /&gt;        page&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;scrollPosition &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;top&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;min&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; step&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; actualHeight &lt;span class=&quot;token operator&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 literal-property property&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;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; fileName &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; prefix &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;_&#39;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; width &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;x&#39;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; height &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;_&#39;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;.png&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;        page&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;render&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;fileName&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;        files&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;fileName&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;&#39;rendered &#39;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; fileName&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;return&lt;/span&gt; files&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;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;logError&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;msg&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; trace&lt;/span&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; msgStack &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;ERROR: &#39;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; msg&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;trace &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; trace&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;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;        msgStack&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;TRACE:&#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;        trace&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forEach&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token 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;t&lt;/span&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;            msgStack&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39; -&gt; &#39;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; t&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;file &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;: &#39;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; t&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;line &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;t&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;function &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39; (in function &#92;&quot;&#39;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; t&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;function&lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;&#92;&quot;)&#39;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;&#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;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;br /&gt;    console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;msgStack&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;&#39;&#92;n&#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;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;Oops, that escalated quickly. Combining quirks of a headless browser, gif-rendering javascript library that
abuses DOM to achieve its goals, local files and, worst of all, javascript, was less then pleasurable. Taking it piece
by piece, we:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Set up a webserver that serves static files from the script directory&lt;/li&gt;
&lt;li&gt;Render page just like before&lt;/li&gt;
&lt;li&gt;Inject gifshot into the context of a webpage&lt;/li&gt;
&lt;li&gt;Request gifshot to create animation of locally saved renders and notify us through console.log-ing&lt;/li&gt;
&lt;li&gt;Read the result and save locally in a hook to opened page console message&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;So, this ~maybe~ is a ~little bit~ hacky solution. I created this abomination for various reasons that came up, but
mostly this is because gifshot uses DOM to do its magic and in this situation - access to locally saved pictures.
Asynchronisity of gif creation and sandboxing between PhantomJS context and opened webpage did not help.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://mostlybugless.com/img/legacy/articles/phantomjs/animated-page-rendering.gif&quot; alt=&quot;Final page
rendering&quot; /&gt;But
it works! We are now automatically generating a gif of a full-page scrolling.&lt;/p&gt;
&lt;p&gt;Now, we are pretty much one for-loop from doing a cross-spectrum responsiveness checkup. But first,&lt;/p&gt;
&lt;h2 id=&quot;which-screen-resolutions-to-test&quot; tabindex=&quot;-1&quot;&gt;Which screen resolutions to test? &lt;a class=&quot;direct-link&quot; href=&quot;https://mostlybugless.com/posts/2018-001-phantomjs/#which-screen-resolutions-to-test&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;According to &lt;a href=&quot;http://gs.statcounter.com/screen-resolution-stats#monthly-201702-201802&quot; target=&quot;_blank&quot;&gt;statcounter&lt;/a&gt;
80% of market share is covered by 20 screen sizes. We will as such apply the Pareto principle.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://mostlybugless.com/img/legacy/articles/phantomjs/screen-sizes-marketshare-chart.png&quot; alt=&quot;Screen sizes market
share&quot; /&gt;
20 is still a pretty large number, but I will reduce some of them since height usually doesn&#39;t matter that much for
overflowing content and some of them are &amp;quot;close enough&amp;quot;. If your styling will break it will be either at smallest
screens, largest screens, or right next to your breakpoints. I&#39;m assuming the typical bootstrapesque 768/992/1200, so a
following set seems pretty reasonable:&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; screenSizes &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;br /&gt;        &lt;span class=&quot;token literal-property property&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1024&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;height&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;768&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;width&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1280&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;height&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;720&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;width&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1366&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;height&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;768&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;width&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1600&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;height&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;900&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;width&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1920&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;height&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1080&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;width&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;320&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;height&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;534&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;width&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;375&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;height&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;667&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;width&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;540&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;height&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;960&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;width&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;720&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;height&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1280&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;width&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;768&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;height&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1024&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;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;final-solution&quot; tabindex=&quot;-1&quot;&gt;Final solution &lt;a class=&quot;direct-link&quot; href=&quot;https://mostlybugless.com/posts/2018-001-phantomjs/#final-solution&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;There is nothing interesting in looping over an array, nor doing minor parametrization or using again previous hack for passing data through a sandboxed page. However final version contains automatic report creation and folder handling which make it much more usable.&lt;/p&gt;
&lt;p&gt;There is always a lot more that I could improve, performance and code quality, file cleanup. But I&#39;m calling it
Pareto-done for now. You can find the script &lt;a href=&quot;https://gist.github.com/dmaterowski/c511f8d3bf12c206393a88b5c9bfc8b8&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt; and &lt;a href=&quot;https://mostlybugless.com/img/legacy/articles/phantomjs/mb/report.html&quot;&gt;sample report here&lt;/a&gt;, enjoy!&lt;/p&gt;
&lt;h2 id=&quot;notes-and-issues&quot; tabindex=&quot;-1&quot;&gt;Notes and issues &lt;a class=&quot;direct-link&quot; href=&quot;https://mostlybugless.com/posts/2018-001-phantomjs/#notes-and-issues&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;PhantomJS is supposed to support ES6 from version 2.5, we are stuck now with the bad parts of JS.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PhantomJS is dead&lt;/strong&gt;, project is no longer maintained. It will still be used for long time as it lies on the foundation of many testing setups, but don&#39;t count on issues being fixed. Take a look at  &lt;a href=&quot;https://developers.google.com/web/updates/2017/04/headless-chrome&quot; target=&quot;_blank&quot;&gt;headless Chrome&lt;/a&gt; and &lt;a href=&quot;https://developers.google.com/web/tools/puppeteer/&quot; target=&quot;_blank&quot;&gt;Puppeteer&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PhantomJS has bugs&lt;/strong&gt;. Quite a lot of them actually. So before you cry wolf, make sure you are not seeing an issue with media query parsing.&lt;/li&gt;
&lt;li&gt;Transparent background will be transparent on renders, and thus on gif, leading to really weird results. I can&#39;t imagine right now a valid case where your page&#39;s body would have transparent background, so just set it explicitly if it&#39;s not and you encounter problems.&lt;/li&gt;
&lt;/ul&gt;

		</content>
	</entry>
</feed>