<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Nelson Chen's Blog</title><link>https://mindflakes.com/</link><description>Recent content on Nelson Chen's Blog</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><copyright>Copyright Nelson Chen</copyright><lastBuildDate>Wed, 11 Feb 2026 20:10:00 -0800</lastBuildDate><atom:link href="https://mindflakes.com/index.xml" rel="self" type="application/rss+xml"/><item><title>Bambu Lab Store Filament Tracker</title><link>https://mindflakes.com/posts/2026/02/11/bambu-lab-store-filament-tracker/</link><pubDate>Wed, 11 Feb 2026 20:10:00 -0800</pubDate><guid>https://mindflakes.com/posts/2026/02/11/bambu-lab-store-filament-tracker/</guid><description>&lt;p&gt;I&amp;rsquo;ve been running a &lt;a href="https://bambulab.com/"&gt;Bambu Lab&lt;/a&gt; Store filament tracker at &lt;a href="https://bbltracker.com/"&gt;bbltracker.com&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://mindflakes.com/images/bbltracker.com.png" alt="bbltracker dashboard"&gt;&lt;/p&gt;
&lt;p&gt;I recently got into &lt;a href="https://en.wikipedia.org/wiki/3D_printing"&gt;3D printing&lt;/a&gt;. A lot of what I print is practical: last-millimeter adapters, things like &lt;a href="https://en.wikipedia.org/wiki/Robotic_vacuum_cleaner"&gt;robot vacuum&lt;/a&gt; ramps around the house, and other tiny fixes that make daily life less annoying.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://bambulab.com/"&gt;Bambu Lab&lt;/a&gt; released the &lt;a href="https://bambulab.com/en-us/p2s"&gt;P2S&lt;/a&gt;, their flagship midrange printer, and I picked one up after hearing how polished their ecosystem is. People call them the Apple of 3D printers, and I can see why. The hardware is solid, but the software and ecosystem are really what make it shine.&lt;/p&gt;
&lt;p&gt;There is also a bit of a format war around &lt;a href="https://en.wikipedia.org/wiki/Fused_filament_fabrication"&gt;filament&lt;/a&gt;. Bambu sells filament with &lt;a href="https://en.wikipedia.org/wiki/Radio-frequency_identification"&gt;RFID&lt;/a&gt; tags that are not easy for third parties to mimic. The RFID flow makes loading filament easy and automatically applies Bambu-tuned profiles. Some people feel those profiles run too fast, but for my functional prints, they have worked great.&lt;/p&gt;
&lt;h2 id="where-the-frustration-started"&gt;Where the frustration started&lt;/h2&gt;
&lt;p&gt;I like having color options, and color can be functional too. But stock has been rough for a while, even after the holiday season.&lt;/p&gt;
&lt;p&gt;That rough stock situation (and the need for a tracker) is really a symptom of how popular Bambu has gotten, especially over the holidays:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://mindflakes.com/images/bbl-handy-chart.webp" alt="Handy chart showing Bambu popularity spike over the holidays"&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Source: &lt;a href="https://www.reddit.com/r/BambuLab/comments/1r01yoo/comment/o4hrtwx"&gt;Reddit comment&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Then there is the constant bulk-sale mechanic on the &lt;a href="https://us.store.bambulab.com/?skr=yes"&gt;Bambu Lab Store&lt;/a&gt;: buy 4+, get a strong discount, buy more, save more. In practice, that falls apart when the combinations you want are never all in stock at the same time.&lt;/p&gt;
&lt;p&gt;At the time, the store UI also made this harder than it needed to be. Out-of-stock options were not clearly crossed out, so building a cart felt like guesswork.&lt;/p&gt;
&lt;p&gt;That made me angry, but in a constructive way. So I built a tracker.&lt;/p&gt;
&lt;h2 id="what-the-tracker-does"&gt;What the tracker does&lt;/h2&gt;
&lt;p&gt;At a high level, the tracker monitors store inventory over time, keeps historical snapshots, and renders a dashboard so I can quickly answer:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;What is actually in stock right now?&lt;/li&gt;
&lt;li&gt;What appears stable versus constantly draining?&lt;/li&gt;
&lt;li&gt;What was the last major restock spike?&lt;/li&gt;
&lt;li&gt;Are there ETA hints for restocks?&lt;/li&gt;
&lt;li&gt;Is this likely to go out of stock soon?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I started with only the &lt;a href="https://us.store.bambulab.com/?skr=yes"&gt;US store&lt;/a&gt;, then expanded to &lt;a href="https://eu.store.bambulab.com/?skr=yes"&gt;EU&lt;/a&gt;, &lt;a href="https://ca.store.bambulab.com/?skr=yes"&gt;CA&lt;/a&gt;, &lt;a href="https://uk.store.bambulab.com/?skr=yes"&gt;UK&lt;/a&gt;, &lt;a href="https://au.store.bambulab.com/?skr=yes"&gt;AU&lt;/a&gt;, and &lt;a href="https://asia.store.bambulab.com/?skr=yes"&gt;Asia&lt;/a&gt; coverage.&lt;/p&gt;
&lt;p&gt;I also reused a stock-quantity verification trick I had learned while documenting &lt;a href="https://github.com/commaai/openpilot"&gt;openpilot&lt;/a&gt;&amp;rsquo;s &lt;a href="https://github.com/optskug/docs"&gt;Toyota security key journey&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="building-it-fast-and-keeping-it-moving"&gt;Building it fast (and keeping it moving)&lt;/h2&gt;
&lt;p&gt;I used a lot of &lt;a href="https://antigravity.google/"&gt;Google Antigravity&lt;/a&gt; while building this. &lt;a href="https://en.wikipedia.org/wiki/Web_scraping"&gt;Web scraping&lt;/a&gt; is tedious work, and &lt;a href="https://en.wikipedia.org/wiki/Large_language_model"&gt;large language models&lt;/a&gt; helped a lot with iteration speed and the constant tweaks.&lt;/p&gt;
&lt;p&gt;The codebase is not pretty in every corner, but LLMs have made it very workable to maintain and improve continuously.&lt;/p&gt;
&lt;p&gt;Later, I added depletion-rate estimation so the tracker can make a rough guess about when something might go out of stock.&lt;/p&gt;
&lt;h2 id="things-that-happened-after-launch"&gt;Things that happened after launch&lt;/h2&gt;
&lt;p&gt;After I released it and posted it on &lt;a href="https://www.reddit.com/r/BambuLab/"&gt;/r/BambuLab&lt;/a&gt;, a bunch of interesting things happened:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Bambu nerfed the original stock-count hole the tracker used.&lt;/li&gt;
&lt;li&gt;For a while, counts were capped at 200 in the US view, which reduced visibility.&lt;/li&gt;
&lt;li&gt;Later, that cap moved to 400 in the &lt;a href="https://us.store.bambulab.com/?skr=yes"&gt;US store&lt;/a&gt;. Maybe my tracker&amp;rsquo;s utility was actually a factor in that decision? I do see traffic from China, where there is no Bambu Lab Store of the same codebase as far as I can see.&lt;/li&gt;
&lt;li&gt;Bambu improved their UI and added clearer out-of-stock cross-outs.&lt;/li&gt;
&lt;li&gt;I added more quality-of-life indicators, including &amp;ldquo;stable stock,&amp;rdquo; ETA context, and restock-spike visibility.&lt;/li&gt;
&lt;li&gt;I added a &lt;a href="https://gofund.me/b1be0586b"&gt;GoFundMe&lt;/a&gt; and a nice patron funded a custom domain and hosting for the tracker.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="backend-at-a-glance"&gt;Backend at a glance&lt;/h2&gt;
&lt;p&gt;Keeping this online reliably has mostly been a deployment and operations problem:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://cloud.google.com/run"&gt;Google Cloud Run&lt;/a&gt; is heavily used for scheduled jobs, scaling, and reliability.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pages.cloudflare.com/"&gt;Cloudflare Pages&lt;/a&gt; hosts the output and leaves room for future expansion.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you print a lot and buy filament in batches, this has been much better than manually refreshing product pages and hoping for the best.&lt;/p&gt;</description></item><item><title>Surviving a power outage with fiber ONT and PoE setup (Frontier FOX222)</title><link>https://mindflakes.com/posts/2025/07/06/surviving-a-power-outage-with-fiber-ont-and-poe-setup-frontier-fox222/</link><pubDate>Sun, 06 Jul 2025 18:12:00 -0800</pubDate><guid>https://mindflakes.com/posts/2025/07/06/surviving-a-power-outage-with-fiber-ont-and-poe-setup-frontier-fox222/</guid><description>&lt;p&gt;&lt;img src="https://assets.mindflakes.com/fiber-poe/fox222.jpg" alt="fox222"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://assets.mindflakes.com/fiber-poe/CA25U16V2.jpg" alt="power supply"&gt;&lt;/p&gt;
&lt;p&gt;For some reason, it&amp;rsquo;s been a bit hard to find information on how to setup my particular fiber ONT so that it can survive a power outage with a PoE setup.&lt;/p&gt;
&lt;p&gt;While of course, one could power a whole house with solar and batteries, I wanted to find a way to keep my fiber ONT and router powered during a power outage without having to invest in a full home battery system.&lt;/p&gt;
&lt;p&gt;Costco recently &lt;a href="https://slickdeals.net/f/18368635-ecoflow-river-3-plus-wireless-boost-combo-219"&gt;had on sale a small EcoFlow RIVER 3 Plus Portable Power Station&lt;/a&gt;, which I installed into my home network setup with the power station being next to my router.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s been wonderful as an UPS!&lt;/p&gt;
&lt;p&gt;My setup is a bit peculiar as my Frontier FOX222 ONT is a bit far from the power station, but the power station is next to the router and there is an Ethernet cable running from the ONT to the router. The RIVER 3 is also next to the router.&lt;/p&gt;
&lt;p&gt;The only way to provide power to the ONT without also having to plumb AC backed by the power station: A PoE injector on the Ethernet cable between the ONT and the router and a splitter at the ONT end to convert the PoE to 16V DC power for the ONT.&lt;/p&gt;
&lt;p&gt;The FOX222 ONT is powered by a 16V DC power supply. There is an &amp;ldquo;Auxiliary Power Supply&amp;rdquo; port on the side of the power supply. Unfortunately, there is no printed information on what acceptable inputs are acceptable for this port. Nor is there documentation on the power supply itself on acceptable voltages. And size, that took forever and was inconsistent.&lt;/p&gt;
&lt;p&gt;Information is also a bit scattered and/or some people have done permanent modications. Some &lt;a href="https://www.instructables.com/I-211M-L-ONT-Enable-Data-While-on-Battery-Power/"&gt;sources have even said 12V is all you need but this is wrong&lt;/a&gt;! The information may be applicable to a different ONT model.&lt;/p&gt;
&lt;p&gt;Through some trial and error and quite some Amazon returns, I&amp;rsquo;ve have an Amazon checklist of the requirements for what is needed.&lt;/p&gt;
&lt;p&gt;My environment:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Frontier FOX222 Fiber ONT (Optical Network Terminal)&lt;/li&gt;
&lt;li&gt;Cyberpower CA25U16V2 Power Supply&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Requirements:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You need a PoE injector that can provide at least 30W. The power supply itself at the end of the chain is rated for 16V at 1.6A but it is unlikely to use the full 1.6A.
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://amzn.to/3Iubo63"&gt;TRENDnet Gigabit Power Over Ethernet Plus Injector, PoE+ (30W)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;You need a PoE splitter that can provide 16V DC output or something close to it. The FOX222 ONT requires 16V DC input. It will not run with 12V DC input. The 18V DC output is within range and works.
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://amzn.to/4ew8v0C"&gt;LINOVISION 30W Gigabit PoE Splitter to DC 5/9/12/18V Output, Wide Voltage Input&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;The power supply connector has a DIN-like connector on one end. It must be modified so that when there is no AC power, the ONT will still power on and provide data.
&lt;ul&gt;
&lt;li&gt;The modification is easily reversible with a small piece of alumnium foil.&lt;/li&gt;
&lt;li&gt;&lt;img src="https://assets.mindflakes.com/fiber-poe/power-supply-plug-modification.webp" alt="Modification Image"&gt;&lt;/li&gt;
&lt;li&gt;Image from &lt;a href="https://www.instructables.com/I-211M-L-ONT-Enable-Data-While-on-Battery-Power/"&gt;https://www.instructables.com/I-211M-L-ONT-Enable-Data-While-on-Battery-Power/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;If not modified, apparently the ONT will refuse to power on the data port. I did not care to try.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;The &amp;ldquo;Auxiliary plug to the the power supply is a 4.0mm x 1.7mm barrel connector. I don&amp;rsquo;t know why some some sources say it&amp;rsquo;s a 4.5mm x 3.0mm barrel connector. Or &lt;a href="https://www.instructables.com/I-211M-L-ONT-Enable-Data-While-on-Battery-Power/"&gt;have other bizzare sizes such as &amp;ldquo;1.3mm x 3.5mm&amp;rdquo;.&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://amzn.to/4eKLUgX"&gt;4.0mm x 1.7mm barrel connector&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;You&amp;rsquo;re adding some Ethernet cable segments. Some small thin cables is fine.
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://amzn.to/4nyWHyP"&gt;Monoprice&amp;rsquo;s SlimRun cables seem to be excellent. I have a few 1 ft patch cables&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Installation:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Plug the PoE injector into the wall and connect it to the router on the WAN side. Use the short Ethernet cables to add small segments as needed.&lt;/li&gt;
&lt;li&gt;Connect the PoE splitter to the ONT on the other end of the Ethernet cable. Use the short Ethernet cables to add small segments as needed.&lt;/li&gt;
&lt;li&gt;The LINOVISION PoE splitter has a 5.5mm x 2.1mm barrel connector male as an output. Connect it to the PoE adapter&amp;rsquo;s cable with the 4.0mm x 1.7mm barrel connector.&lt;/li&gt;
&lt;li&gt;Plug the 4.0mm x 1.7mm barrel connector into the &amp;ldquo;Auxiliary Power Supply&amp;rdquo; port on the Cyberpower CA25U16V2 power supply.&lt;/li&gt;
&lt;li&gt;Take out the wire between the ONT and the power supply and modify the plug as shown in the image above. This is done by stuffing in a small piece of aluminum foil into the barrel connector. It apparently shorts some pins together to allow the ONT to power on and provide data when there is no AC power.
&lt;ul&gt;
&lt;li&gt;&lt;img src="https://assets.mindflakes.com/fiber-poe/power-supply-plug-modification.webp" alt="Modification Image"&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Unplug the AC cord from the Cyberpower CA25U16V2 power supply.&lt;/li&gt;
&lt;li&gt;Plug in the DC barrel connector into the power supply&amp;rsquo;s &amp;ldquo;Auxiliary Power Supply&amp;rdquo; port.
&lt;ul&gt;
&lt;li&gt;&lt;img src="https://assets.mindflakes.com/fiber-poe/auxilllary_power_supply.jpg" alt="Auxiliary Power Supply"&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;It should power on!&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Do not plug in the AC cord!&lt;/strong&gt; as if you plug it in, the ONT will reboot. This is actually bad. If the AC power goes out, the ONT will reboot. Just leave it powered by the DC power supply exclusively and from the PoE injector.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Setup Image:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;img src="https://assets.mindflakes.com/fiber-poe/setup.jpg" alt="Setup Image"&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Operation:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Leave the AC cord from the power supply unplugged. If you plug it in, power outages will disrupt service. You&amp;rsquo;re welcome to test this yourself once you have the setup working completely on DC power.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Things I don&amp;rsquo;t know:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Does this work the with the FRX523? It&amp;rsquo;s apparently some sort of successor to the FOX222.&lt;/li&gt;
&lt;li&gt;Will there by long term issues with the ONT being powered by a 18V DC power supply?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Comments:&lt;/p&gt;
&lt;p&gt;Questions and suggestions are welcome to &lt;a href="https://bsky.app/profile/mindflakes.com"&gt;https://bsky.app/profile/mindflakes.com&lt;/a&gt; .&lt;/p&gt;
&lt;p&gt;References:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://www.dmdtech.org/2024/11/30/power-your-frontier-and-others-ont-w-poe/"&gt;https://www.dmdtech.org/2024/11/30/power-your-frontier-and-others-ont-w-poe/&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Gave a hint that 16V is an absolute requirement&lt;/li&gt;
&lt;li&gt;Provided a hint to the LINOVision PoE splitter&amp;rsquo;s 18V output being acceptable&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://www.instructables.com/I-211M-L-ONT-Enable-Data-While-on-Battery-Power/"&gt;https://www.instructables.com/I-211M-L-ONT-Enable-Data-While-on-Battery-Power/&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Provided the image above&lt;/li&gt;
&lt;li&gt;Implies that the power supply is happy to take a 12V DC input but this is wrong for the FOX222 ONT, at least.&lt;/li&gt;
&lt;li&gt;Plug size is wrong, it&amp;rsquo;s 4.0mm x 1.7mm!&lt;/li&gt;
&lt;li&gt;Only thing right seems to be the modification of the power supply plug with aluminum foil&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Talky Pet Watcher, a cat watching AI</title><link>https://mindflakes.com/posts/2025/02/01/talky-pet-watcher-a-cat-watching-ai/</link><pubDate>Sat, 01 Feb 2025 06:08:55 +0000</pubDate><guid>https://mindflakes.com/posts/2025/02/01/talky-pet-watcher-a-cat-watching-ai/</guid><description>&lt;p&gt;&lt;img src="https://mindflakes.com/images/talky-pet-watcher.png" alt="Cat Watch"&gt;&lt;/p&gt;
&lt;p&gt;Github Project: &lt;a href="https://github.com/nelsonjchen/talky_pet_watcher/"&gt;talky_pet_watcher&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m allergic to cats 😢. But a friend asked me to watch their cat. My family was more than willing to help but to be safe, I wanted to also monitor the cat to make sure she didn&amp;rsquo;t get into any shenanigans that were too much.&lt;/p&gt;
&lt;p&gt;With some cheap &lt;a href="https://www.tp-link.com/us/home-networking/cloud-camera/"&gt;TP-Link Tapo&lt;/a&gt; cameras, I set up a system to watch the cat remotely and ensure she was safe while I could not be next to her. It&amp;rsquo;s a &lt;a href="https://telegram.org/"&gt;Telegram&lt;/a&gt; bot that also sends me a message whenever the cat is doing something interesting.&lt;/p&gt;
&lt;p&gt;It watches multiple cameras and tries to aggregate the data to provide insights on the cat&amp;rsquo;s behavior.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s the project description:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Talky Pet Watcher is a tool to watch a series of &lt;a href="https://www.onvif.org/"&gt;ONVIF&lt;/a&gt; webcams and their streams. It captures video clips, uploads them to Google AI for processing, and uses a generative model to create captions and identify relevant clips. The results are then delivered to a Telegram channel. This project is designed to help pet owners keep an eye on their pets and share interesting moments with friends.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This was slapped together in a few days, as I only watched the cat for two weeks.&lt;/p&gt;
&lt;p&gt;I was also interested in &lt;a href="https://gemini.google.com/"&gt;Google Gemini&lt;/a&gt; and how cheap they claimed to be for analyzing video. I figured that this would be a good way to test it out.&lt;/p&gt;
&lt;p&gt;What went well:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The system was able to capture interesting moments effectively.&lt;/li&gt;
&lt;li&gt;It was able to concantate multiple camera&amp;rsquo;s POV to provide interesting views.&lt;/li&gt;
&lt;li&gt;The cameras were cheap!&lt;/li&gt;
&lt;li&gt;Putting the results on Telegram was a good way to share the results with the cat&amp;rsquo;s owner and friends.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;What did not go well (and there are many!):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I did not implement history, so the system basically reported the same thing over and over again.&lt;/li&gt;
&lt;li&gt;Getting reliable clips from multiple cameras when motion was detected was iffy due to the TP-Link Tapo camera&amp;rsquo;s iffy web servers. It would stall and halt a lot.&lt;/li&gt;
&lt;li&gt;The Google Gemini AI could only analyze video clips at 1FPS. For an agile kitten, this can sometimes make wrong assumptions about what the cat is doing.&lt;/li&gt;
&lt;li&gt;Implementation wise, &lt;a href="https://bun.sh/"&gt;&lt;code&gt;bun&lt;/code&gt;&lt;/a&gt; was very crashy and I had to restart it a lot.&lt;/li&gt;
&lt;li&gt;The connection to the camera also had to be restarted a lot.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If I had to do it again:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Use something that can pull from a NVR by relative timestamps. There was some Rust NVR but it was too complicated for me to set up in the small amount of time I had.&lt;/li&gt;
&lt;li&gt;Implement a history system and maybe some memory bank system.&lt;/li&gt;
&lt;li&gt;And so so much more! 😅&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>comma three faux touch keyboard</title><link>https://mindflakes.com/posts/2024/12/13/comma-three-faux-touch-keyboard/</link><pubDate>Fri, 13 Dec 2024 22:02:00 -0800</pubDate><guid>https://mindflakes.com/posts/2024/12/13/comma-three-faux-touch-keyboard/</guid><description>&lt;h1 id="-comma-three-faux-touch-keyboard"&gt;🦾 comma three Faux-Touch keyboard&lt;/h1&gt;
&lt;p&gt;&lt;em&gt;Long arms for those of us with short arms from birth or those who can&amp;rsquo;t afford arm extension surgery!&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://github.com/nelsonjchen/c3-touchkey-keyboard/assets/5363/d9617916-2442-4287-b430-709dad173da8" alt="touchkey keyboard demo"&gt;&lt;/p&gt;
&lt;p&gt;Built a faux-touch keyboard for the comma three using a CH552G microcontroller. The keyboard is off the shelf and reprogrammed to emulat a touchscreen.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s a bit of a hack but it certainly beats &lt;a href="https://en.wikipedia.org/wiki/Touchscreen#%22Gorilla_arm%22"&gt;gorilla arm&lt;/a&gt; syndrome while driving.&lt;/p&gt;
&lt;p&gt;For $5 of hardware, it&amp;rsquo;s very hard to beat.&lt;/p&gt;
&lt;p&gt;The journey started in January 2024 and ended in May 2024. Though it, I had to struggle with:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;CH552G programming&lt;/li&gt;
&lt;li&gt;Linux USB HID Touchscreen protocol&lt;/li&gt;
&lt;li&gt;Instructions and documentation&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It&amp;rsquo;s also been through that period of unintended usage. The &lt;a href="https://github.com/FrogAi/FrogPilot"&gt;Frogpilot&lt;/a&gt; project has had users who were surprisingly interested in using it as an alternative for some GM vehicles where there is no ACC button. They use the keyboard to touch the screen where ACC would be.&lt;/p&gt;
&lt;p&gt;Part of the work also meant upstreaming to the the &lt;a href="https://github.com/wagiminator/MCU-Templates"&gt;CH552G community&lt;/a&gt;. While I doubt it&amp;rsquo;ll have any users, it&amp;rsquo;s nice to give back to the community. There is now a touchscreen library for the CH552G.&lt;/p&gt;
&lt;p&gt;The project is open source and can be found at:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/nelsonjchen/c3-faux-touch-keyboard"&gt;https://github.com/nelsonjchen/c3-faux-touch-keyboard&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;There&amp;rsquo;s a nice readme that explains how to build and flash the firmware.&lt;/p&gt;</description></item><item><title>comma three faux touch keyboard</title><link>https://mindflakes.com/projects/c3-faux-touch-keyboard/</link><pubDate>Fri, 13 Dec 2024 00:00:00 +0000</pubDate><guid>https://mindflakes.com/projects/c3-faux-touch-keyboard/</guid><description>&lt;h1 id="-comma-three-faux-touch-keyboard"&gt;🦾 comma three Faux-Touch keyboard&lt;/h1&gt;
&lt;p&gt;&lt;em&gt;Long arms for those of us with short arms from birth or those who can&amp;rsquo;t afford arm extension surgery!&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://github.com/nelsonjchen/c3-touchkey-keyboard/assets/5363/d9617916-2442-4287-b430-709dad173da8" alt="touchkey keyboard demo"&gt;&lt;/p&gt;
&lt;p&gt;Built a faux-touch keyboard for the comma three using a CH552G microcontroller. The keyboard is off the shelf and reprogrammed to emulat a touchscreen.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s a bit of a hack but it certainly beats &lt;a href="https://en.wikipedia.org/wiki/Touchscreen#%22Gorilla_arm%22"&gt;gorilla arm&lt;/a&gt; syndrome while driving.&lt;/p&gt;
&lt;p&gt;For $5 of hardware, it&amp;rsquo;s very hard to beat.&lt;/p&gt;
&lt;p&gt;The journey started in January 2024 and ended in May 2024. Though it, I had to struggle with:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;CH552G programming&lt;/li&gt;
&lt;li&gt;Linux USB HID Touchscreen protocol&lt;/li&gt;
&lt;li&gt;Instructions and documentation&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It&amp;rsquo;s also been through that period of unintended usage. The &lt;a href="https://github.com/FrogAi/FrogPilot"&gt;Frogpilot&lt;/a&gt; project has had users who were surprisingly interested in using it as an alternative for some GM vehicles where there is no ACC button. They use the keyboard to touch the screen where ACC would be.&lt;/p&gt;
&lt;p&gt;Part of the work also meant upstreaming to the the &lt;a href="https://github.com/wagiminator/MCU-Templates"&gt;CH552G community&lt;/a&gt;. While I doubt it&amp;rsquo;ll have any users, it&amp;rsquo;s nice to give back to the community. There is now a touchscreen library for the CH552G.&lt;/p&gt;
&lt;p&gt;The project is open source and can be found at:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/nelsonjchen/c3-faux-touch-keyboard"&gt;https://github.com/nelsonjchen/c3-faux-touch-keyboard&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;There&amp;rsquo;s a nice readme that explains how to build and flash the firmware.&lt;/p&gt;</description></item><item><title>Replicate.com openpilot Replay Clipper</title><link>https://mindflakes.com/posts/2023/10/12/replicate.com-openpilot-replay-clipper/</link><pubDate>Thu, 12 Oct 2023 22:28:00 -0800</pubDate><guid>https://mindflakes.com/posts/2023/10/12/replicate.com-openpilot-replay-clipper/</guid><description>&lt;p&gt;&lt;img src="https://github.com/nelsonjchen/op-replay-clipper/assets/5363/7a9cf016-2012-4acd-90e9-9cdec6bf96c1" alt="Web capture_8-11-2023_9551_replicate com"&gt;&lt;/p&gt;
&lt;p&gt;The replay clipper has been ported to &lt;a href="https://replicate.com"&gt;Replicate.com&lt;/a&gt;!&lt;/p&gt;
&lt;p&gt;&lt;a href="https://replicate.com/nelsonjchen/op-replay-clipper"&gt;https://replicate.com/nelsonjchen/op-replay-clipper&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Along with it comes a slew of upgrades and updates:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;GPU accelerated&lt;/strong&gt; decoding, rendering, and encoding. NVIDIA GPUs are provided to the Replicate environment and greatly speed up the clipper.&lt;/li&gt;
&lt;li&gt;Rapid fast downloading of clips. Instead of relying on &lt;code&gt;replay&lt;/code&gt; to handle downloads sequentially in a non-parallel manner, we use the parfive library to download underlying data in parallel.&lt;/li&gt;
&lt;li&gt;Comma Connect URL Input. No need to mentally calculate the starting time and length. Just copy and paste the URL from Comma Connect.&lt;/li&gt;
&lt;li&gt;Video/UI-less mode. Don&amp;rsquo;t want UI? You can have it.&lt;/li&gt;
&lt;li&gt;360 mode. Render 360 clips&lt;/li&gt;
&lt;li&gt;Forward Upon Wide. Render clips with the forward clip upon the wide clip&lt;/li&gt;
&lt;li&gt;Richer error messages to help pinpoint issues.&lt;/li&gt;
&lt;li&gt;No more having to manage GitHub Codespaces. Replicate handles all the setup and cleanup for you.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Unfortunately, there is a cost. It&amp;rsquo;s a very small cost but technically Replicate.com is not free. Expect to drop a cent per render. Thankfully, you have a lot a trial credits to burn through and the clipper can run on a free-ish tier.&lt;/p&gt;</description></item><item><title>Colorized-Project: A Project-Color restoration.</title><link>https://mindflakes.com/posts/2023/02/01/colorized-project-a-project-color-restoration./</link><pubDate>Wed, 01 Feb 2023 22:28:00 -0800</pubDate><guid>https://mindflakes.com/posts/2023/02/01/colorized-project-a-project-color-restoration./</guid><description>&lt;p&gt;&lt;img src="https://user-images.githubusercontent.com/5363/217070588-7faccad0-890c-49df-a119-a0ad261cb9df.png" alt="screenshot_c235a4a9-429b-4564-bfef-24e4f12bd9a8"&gt;&lt;/p&gt;
&lt;p&gt;GitHub Link: &lt;a href="https://github.com/nelsonjchen/Colorized-Project"&gt;https://github.com/nelsonjchen/Colorized-Project&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;On IntelliJ IDEs, I&amp;rsquo;ve been using &lt;a href="https://github.com/nowtilous/Project-Color"&gt;Project-Color&lt;/a&gt; to set a color for each project. This is useful for me because I have a lot of projects open at once, and it&amp;rsquo;s nice to be able to quickly identify which project is which.&lt;/p&gt;
&lt;p&gt;Unfortunately, Project-Color &lt;a href="https://github.com/nowtilous/Project-Color/issues/"&gt;hasn&amp;rsquo;t been updated in a while&lt;/a&gt;, and it doesn&amp;rsquo;t work with the latest versions of IntelliJ.&lt;/p&gt;
&lt;p&gt;After a few months of using IntelliJ without Project-Color, I decided to try to fix it. I&amp;rsquo;ve released the result as &lt;a href="https://github.com/nelsonjchen/Colorized-Project"&gt;Colorized-Project&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Thre are a few rough edges, but it&amp;rsquo;s mostly functional. I&amp;rsquo;ve been using it for a few weeks now, and it&amp;rsquo;s been working well. I&amp;rsquo;ve also submitted it to the JetBrains plugin repository as well.&lt;/p&gt;
&lt;p&gt;It still needs some polish like a nicer icon, and I&amp;rsquo;d like to add a few more features.&lt;/p&gt;</description></item><item><title>Colorized-Project</title><link>https://mindflakes.com/projects/colorized-project/</link><pubDate>Wed, 01 Feb 2023 00:00:00 +0000</pubDate><guid>https://mindflakes.com/projects/colorized-project/</guid><description>&lt;p&gt;&lt;img src="https://user-images.githubusercontent.com/5363/217070588-7faccad0-890c-49df-a119-a0ad261cb9df.png" alt="screenshot_c235a4a9-429b-4564-bfef-24e4f12bd9a8"&gt;&lt;/p&gt;
&lt;p&gt;GitHub Link: &lt;a href="https://github.com/nelsonjchen/Colorized-Project"&gt;https://github.com/nelsonjchen/Colorized-Project&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Remember your projects by color! Colorize the window somehow to differentiate your open projects. Updated and &lt;a href="https://github.com/nowtilous/Project-Color/issues/"&gt;maintained&lt;/a&gt; fork of Project-Color.&lt;/p&gt;
&lt;p&gt;Working on multiple projects simultaneously with Jetbrains products based on IntelliJ can be difficult, since they all look the same at a glance. This plugin solves that by giving the user the option to colorize each project&amp;rsquo;s window in a noticeable way.&lt;/p&gt;</description></item><item><title>GitHub Wiki SEE: Search Engine Enablement: Year One</title><link>https://mindflakes.com/posts/2022/10/13/github-wiki-see-search-engine-enablement-year-one/</link><pubDate>Thu, 13 Oct 2022 21:04:00 -0800</pubDate><guid>https://mindflakes.com/posts/2022/10/13/github-wiki-see-search-engine-enablement-year-one/</guid><description>&lt;p&gt;It&amp;rsquo;s been near a year since I supercharged &lt;a href="https://github-wiki-see.page"&gt;GitHub Wiki SEE&lt;/a&gt; with dynamically generating sitemaps.&lt;/p&gt;
&lt;p&gt;Since then a few things have changed:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;GitHub has started to permit a select set of wikis to be indexed.&lt;/li&gt;
&lt;li&gt;They have not budged on letting un-publically editable wikis be indexed.&lt;/li&gt;
&lt;li&gt;There is now a star requirement of about 500, and it appears to be steadily decreasing.&lt;/li&gt;
&lt;li&gt;Many projects have reacted by moving or configuring their wikis to indexable platforms.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As a result, traffic to &lt;a href="https://github-wiki-see.page"&gt;GitHub Wiki SEE&lt;/a&gt; has dropped off dramatically.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://user-images.githubusercontent.com/5363/195682137-8f9fad93-2a68-4ca0-9c20-035eeba002a1.png" alt="stats"&gt;&lt;/p&gt;
&lt;p&gt;This is a good thing, as it means that GitHub is moving in the right direction.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m still going to keep the service up, as it&amp;rsquo;s still useful for wikis that are not yet indexed and there are still about 400,000 wikis that aren&amp;rsquo;t indexed.&lt;/p&gt;
&lt;p&gt;Hopefully GitHub will continue to move in the right direction and allow all wikis to be indexed.&lt;/p&gt;</description></item><item><title>openpilot Replay Clipper</title><link>https://mindflakes.com/posts/2022/10/12/openpilot-replay-clipper/</link><pubDate>Wed, 12 Oct 2022 19:42:00 -0800</pubDate><guid>https://mindflakes.com/posts/2022/10/12/openpilot-replay-clipper/</guid><description>&lt;p&gt;End to End Longitudinal Control is currently an &amp;ldquo;extremely alpha&amp;rdquo; feature in &lt;a href="https://github.com/commaai/openpilot"&gt;openpilot&lt;/a&gt; that is the gateway to future functionality such as stopping for traffic lights and stop signs.&lt;/p&gt;
&lt;p&gt;Problem is, it&amp;rsquo;s hard to describe its current deficiencies without a video.&lt;/p&gt;
&lt;p&gt;So I made a tool to help make it easier to share clips of this functionality with a view into what openpilot is seeing, and thinking.&lt;/p&gt;
&lt;video controls&gt;
&lt;source src="https://user-images.githubusercontent.com/5363/188810452-47a479c4-fa9a-4037-9592-c6a47f2e1bb1.mp4
" type="video/mp4"&gt;
&lt;/video&gt;
&lt;p&gt;&lt;a href="https://github.com/nelsonjchen/op-replay-clipper/"&gt;GitHub repository&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s a bit heavy in resource use though. I was thinking of making it into a web service but I simply do not have enough time. So I made instructions for others to run it on services like &lt;a href="https://www.digitalocean.com/"&gt;DigitalOcean&lt;/a&gt;, where it is cheap.&lt;/p&gt;
&lt;p&gt;It is composed of a shell script and a Docker setup that fires up a bunch of processes and then kills them all when done.&lt;/p&gt;
&lt;p&gt;Hopefully this leads to more interesting clips being shared, and more feedback on the models that &lt;a href="https://comma.ai/"&gt;comma.ai&lt;/a&gt; can use.&lt;/p&gt;
&lt;p&gt;I later also ported this to Replicate &lt;a href="https://mindflakes.com/posts/2023/10/12/replicate.com-openpilot-replay-clipper/"&gt;here&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>Datasette-lite sqlite-httpvfs experiment POC with the California Unclaimed Property database</title><link>https://mindflakes.com/posts/2022/10/11/datasette-lite-sqlite-httpvfs-experiment-poc-with-the-california-unclaimed-property-database/</link><pubDate>Tue, 11 Oct 2022 20:36:00 -0800</pubDate><guid>https://mindflakes.com/posts/2022/10/11/datasette-lite-sqlite-httpvfs-experiment-poc-with-the-california-unclaimed-property-database/</guid><description>&lt;p&gt;&lt;img src="https://user-images.githubusercontent.com/5363/195697437-2331acfb-fedd-478f-8596-28d6a1809339.png" alt="screenshot"&gt;&lt;/p&gt;
&lt;p&gt;There&amp;rsquo;s a web browser version of datasette called datasette-lite which runs on Python ported to WASM with Pyodide which can load SQLite databases.
I grafted the enhanced lazyFile implementation from emscripten and then from this implementation to datasette-lite relatively recently as a curious test. Threw in a 18GB CSV from CA&amp;rsquo;s unclaimed property records here&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.sco.ca.gov/upd_download_property_records.html"&gt;https://www.sco.ca.gov/upd_download_property_records.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;into a FTS5 Sqlite Database which came out to about 28GB after processing:&lt;/p&gt;
&lt;p&gt;POC, non-merging Log/Draft PR for the hack:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/simonw/datasette-lite/pull/49"&gt;https://github.com/simonw/datasette-lite/pull/49&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;You can run queries through to datasette-lite if you URL hack into it and just get to the query dialog, browsing is kind of a dud at the moment since datasette runs a count(*) which downloads everything.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://datasette-lite-lab.mindflakes.com/index.html?url=https://datasette-lite-lab.mindflakes.com/sdb/2022-10-02_93eff57de3573985_ca_unclaimed_property.sqlite#/2022-10-02_93eff57de3573985_ca_unclaimed_property?sql=SELECT+*+FROM+records+WHERE+records.owner_name+MATCH+%22Elon+Musk%22+ORDER+BY+CAST%28CURRENT_CASH_BALANCE+AS+FLOAT%29++DESC%3B"&gt;Elon Musk&amp;rsquo;s CA Unclaimed Property&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Still, not bad for a $0.42/mo hostable cached CDN&amp;rsquo;d read-only database. It&amp;rsquo;s on Cloudflare R2, so there&amp;rsquo;s no BW costs.&lt;/p&gt;
&lt;p&gt;Celebrity gawking is one thing, but the real, useful thing that this can do is search by address. If you aren&amp;rsquo;t sure of the names, such as people having multiple names or nicknames, you can search by address and get a list of properties at a location. This is one thing that the &lt;a href="https://ucpi.sco.ca.gov/en/Property/SearchIndex"&gt;California Unclaimed Property site can&amp;rsquo;t do&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I am thinking of making this more proper when R2 introduces lifecycle rules to delete old dumps. I could automate the process of dumping with GitHub Actions but I would like R2 to handle cleanup.&lt;/p&gt;</description></item><item><title>openpilot Replay Cliper</title><link>https://mindflakes.com/projects/openpilot-replay-clipper/</link><pubDate>Sat, 01 Oct 2022 00:00:00 +0000</pubDate><guid>https://mindflakes.com/projects/openpilot-replay-clipper/</guid><description>&lt;p&gt;Replicate: &lt;a href="https://replicate.com/nelsonjchen/op-replay-clipper"&gt;https://replicate.com/nelsonjchen/op-replay-clipper&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/nelsonjchen/op-replay-clipper/"&gt;https://github.com/nelsonjchen/op-replay-clipper/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;📽 Capture short ~30 second route clips with the openpilot UI included, and the route, seconds marker branded into it.&lt;/p&gt;
&lt;p&gt;Designed to try to encourage more interesting clips to be shared, especially with newer functionality such as &amp;ldquo;end to end longitudinal control&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;Originally a bit heavy, so instructions were made for others to run it on services like DigitalOcean/GitHub Codespaces. Since then, the clipper has been ported to Replicate which provides GPUs and a nice WebUI.&lt;/p&gt;
&lt;p&gt;The UI rendering is composed of a shell script and a Docker setup that fires up a bunch of processes and then kills them all when done. On Replicate, it is wrapped by a Python script that handles the UI and non-UI processing of video and downloads.&lt;/p&gt;</description></item><item><title>Released Gargantuan Takeout Rocket</title><link>https://mindflakes.com/posts/2022/04/16/released-gargantuan-takeout-rocket/</link><pubDate>Sat, 16 Apr 2022 21:04:00 -0800</pubDate><guid>https://mindflakes.com/posts/2022/04/16/released-gargantuan-takeout-rocket/</guid><description>&lt;p&gt;Finally released GTR or Gargantuan Takeout Rocket.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/nelsonjchen/gtr"&gt;GitHub repository&lt;/a&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Gargantuan Takeout Rocket (GTR) is a toolkit of guides and software to help you take out your data from &lt;a href="https://takeout.google.com/"&gt;Google Takeout&lt;/a&gt; and put it somewhere else safe easily, periodically, and fast to make it easy to do the right thing of backing up your Google account and related services such as your YouTube account or Google Photos periodically.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;It took a lot of time to research and to workaround the issues I found in &lt;a href="https://azure.microsoft.com/"&gt;Azure&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I also needed to take apart browser extensions and implement my own browser extension to facilitate the transfers.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://workers.cloudflare.com/"&gt;Cloudflare Workers&lt;/a&gt; was also used to work around issues with Azure&amp;rsquo;s API.&lt;/p&gt;
&lt;p&gt;All this combined, I was able to takeout 1.25TB of data in 3 minutes.&lt;/p&gt;
&lt;p&gt;Now I&amp;rsquo;m showing it around on Twitter, Discord, Reddit, and more to users who have used VPSes to backup Google Takeout or have expressed dismay at the lack of options for users who are looking to store archives on the cheap. The response from people who&amp;rsquo;ve opted to stay on Google has been good!&lt;/p&gt;
&lt;p&gt;There is also a project page with additional details &lt;a href="https://mindflakes.com/projects/gtr/"&gt;here&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>Gargantuan Takeout Rocket</title><link>https://mindflakes.com/projects/gtr/</link><pubDate>Sat, 16 Apr 2022 00:00:00 +0000</pubDate><guid>https://mindflakes.com/projects/gtr/</guid><description>&lt;p&gt;&lt;a href="https://github.com/nelsonjchen/gtr"&gt;https://github.com/nelsonjchen/gtr&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Gargantuan Takeout Rocket (GTR) is a toolkit of guides and software to help you take out your data from &lt;a href="https://takeout.google.com/"&gt;Google Takeout&lt;/a&gt; and put it somewhere else safe easily, periodically, and fast to make it easy to do the right thing of backing up your Google account and related services such as your YouTube account or Google Photos periodically.&lt;/p&gt;
&lt;p&gt;Used to do this with a VPS. It was still too slow to backup 1.25TB. TOOK HOURS! Built a Rocket.&lt;/p&gt;
&lt;p&gt;It is comprised of a two major components:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A &amp;ldquo;GTR Proxy&amp;rdquo; Cloudflare Worker that HTTP3-izes the the Azure API and is capable of proxying base64 URLs to Google Takeout URLs.&lt;/li&gt;
&lt;li&gt;A browser extension that coordinates all this and constructs a job plan to execute.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These two components are infinitely scaleable and can be used to backup Google Takeout at breathtaking, unprecedented speeds.&lt;/p&gt;
&lt;p&gt;The GTR repo contains a guide on how to setup all of this.&lt;/p&gt;
&lt;p&gt;A future revision or successor may target S3 or S3-like APIs. In particular, can we target &lt;a href="https://blog.cloudflare.com/introducing-r2-object-storage/"&gt;Cloudflare&amp;rsquo;s R2 when it comes out&lt;/a&gt;?&lt;/p&gt;</description></item><item><title>Cell Shield</title><link>https://mindflakes.com/posts/2021/07/28/cell-shield/</link><pubDate>Wed, 28 Jul 2021 18:47:00 -0800</pubDate><guid>https://mindflakes.com/posts/2021/07/28/cell-shield/</guid><description>&lt;p&gt;I built &lt;a href="https://cellshield.info"&gt;https://cellshield.info&lt;/a&gt; to scratch an itch. Why can&amp;rsquo;t I embed a
spreadsheet cell?&lt;/p&gt;
&lt;p&gt;&lt;a href="https://docs.google.com/spreadsheets/d/1MkUQwY33RY0gJwJtls48mjISBzPgd8noanZee-omezs/edit#gid=0&amp;amp;range=SAShowPost"&gt;
&lt;img src="https://shields.io/endpoint?url=https%3A%2F%2Fcellshield.info%2Fgs%3FspreadSheetId%3D1MkUQwY33RY0gJwJtls48mjISBzPgd8noanZee-omezs%26cellRange%3DC3" alt=""&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;You can click on that badge and see the sheet that is the data backing the
badge.&lt;/p&gt;
&lt;p&gt;It is useful for embedding a cell from an informal database that is a Google
Spreadsheet atop of some README, wiki, forum post, or web page. Spreadsheets are
still how many projects are managed and this can be used to embed a small
preview of important or attention grabbing data.&lt;/p&gt;
&lt;p&gt;It is a simple Go server that uses Google&amp;rsquo;s API to output JSON that
&lt;a href="https://shields.io"&gt;https://shields.io&lt;/a&gt; can read. Mix it in with some simple VueJS generator
front-end to take public spreadsheet URLS and tada.&lt;/p&gt;
&lt;p&gt;I picked to base my implementation on shields.io&amp;rsquo;s as they make really pretty
badges and have a lot of nice documentation and options.&lt;/p&gt;
&lt;p&gt;I run it on Cloud Run to keep the costs low and availability high. It also
utilizes Google&amp;rsquo;s implementation of authorization to get access to the Sheets API.&lt;/p&gt;
&lt;p&gt;The badge generator web UI can also make BBCode for embedding (along with modern
Markdown and so on).&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve already used it for
&lt;a href="https://github.com/commaai/openpilot/wiki/Toyota-Lexus#2021-toyota-ecu-security-key-support-new-steering_lka--more"&gt;this&lt;/a&gt;
and &lt;a href="https://github.com/commaai/comma10k#comma10k"&gt;that&lt;/a&gt;. The former outputs a
running bounty total and the latter is community annotation progress.&lt;/p&gt;
&lt;p&gt;A major Game Boy development contest is using it labels to display the prize
pool amount: &lt;a href="https://itch.io/jam/gbcompo21"&gt;https://itch.io/jam/gbcompo21&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="why-i-built-this"&gt;Why I built this?&lt;/h2&gt;
&lt;p&gt;I built it for the &lt;a href="https://github.com/commaai/comma10k#comma10k"&gt;Comma10K&lt;/a&gt;
annotation project. I contributed the original badge which attempted to use a
script that was used in the repo to analyze the completion progress.
Unfortunately, this kept on diverging from the actual progress because the human
elements kept changing the structure and organization and I had the badge
removed. The only truth is what was on the spreadsheet.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://docs.google.com/spreadsheets/d/1ZKqku0cAyWY0ELY5L2qsKYYYA2AMGbgAn4p53uoT3v8/edit#gid=0"&gt;&lt;img src="https://img.shields.io/endpoint?color=%2328B224&amp;amp;label=Completion%20Status&amp;amp;url=https%3A%2F%2Fcellshield.info%2Fgs%3FspreadSheetId%3D1ZKqku0cAyWY0ELY5L2qsKYYYA2AMGbgAn4p53uoT3v8%26cellRange%3Di1" alt="Completion Status"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="popularity"&gt;Popularity&lt;/h2&gt;
&lt;p&gt;Compared to my other projects, I don&amp;rsquo;t think the popularity will be too good for
this project though. I think it might have a chance to spread via word of mouth
but it&amp;rsquo;s not everyday that a large public collaborative project is born with a
Google Spreadsheet managing it. The name isn&amp;rsquo;t that great either as it probably
conflicts with anti-wireless hysteria. Also, it&amp;rsquo;s not like there&amp;rsquo;s an agreed
upon community of Google Spreadsheet users to share this knowledge with.&lt;/p&gt;
&lt;p&gt;I also shamelessly plugged it here but I think the question asker might be
deceased:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://stackoverflow.com/questions/57962813/how-to-embed-a-single-google-sheets-cells-text-content-into-a-web-page/68505801#68505801"&gt;https://stackoverflow.com/questions/57962813/how-to-embed-a-single-google-sheets-cells-text-content-into-a-web-page/68505801#68505801&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;At least it was viewed 2,000 times over the last two years.&lt;/p&gt;
&lt;h2 id="maintenance"&gt;Maintenance&lt;/h2&gt;
&lt;p&gt;It&amp;rsquo;s on Cloud Run. The cost to keep it running is low as it sometimes isn&amp;rsquo;t even
running and the Sheets V4 API it uses was recently declared
&lt;a href="https://www.protocol.com/enterprise/google-cloud-enterprise-apis"&gt;&amp;ldquo;enterprise-stable&amp;rdquo;&lt;/a&gt;.
Because of this, it will be super easy to maintain and cheap to run. I don&amp;rsquo;t
expect any more than $2 a month.&lt;/p&gt;</description></item><item><title>GitHub Wiki SEE: Search Engine Enablement</title><link>https://mindflakes.com/posts/2021/07/27/github-wiki-see-search-engine-enablement/</link><pubDate>Tue, 27 Jul 2021 18:12:00 -0800</pubDate><guid>https://mindflakes.com/posts/2021/07/27/github-wiki-see-search-engine-enablement/</guid><description>&lt;p&gt;I built this in March, but I figure I&amp;rsquo;ll write about this project better late
than never. I supercharged it in June out of curiosity to see how it would
perform. It&amp;rsquo;s just a ramble. I am not a good writer but I just wanted to write
stuff down.&lt;/p&gt;
&lt;p&gt;TLDR: I mirrored all of GitHub&amp;rsquo;s wiki with my own service to get the content on
Google and other search engines.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;ve used a search engine to search up something that could appear on
GitHub, you are using my service.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github-wiki-see.page/"&gt;https://github-wiki-see.page/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Did you know that GitHub wikis aren&amp;rsquo;t search engine optimized? In fact, GitHub
excluded their own wiki pages from the search results with their
&lt;a href="https://github.com/robots.txt"&gt;robots.txt&lt;/a&gt;.
&lt;a href="https://en.wikipedia.org/wiki/Robots_exclusion_standard"&gt;&amp;ldquo;robots.txt&amp;rdquo; is the mechanism that sites can use to indicate to search engines whether or not to index certain sections of the site&lt;/a&gt;.
If you search on Google or Bing, you won&amp;rsquo;t find any results unless your search
query terms are directly inside the URL.&lt;/p&gt;
&lt;p&gt;The situation with search engines is currently this. For example, if you wanted
to search for information relating to Nissan Leaf support of the openpilot
self-driving car project in their wiki, you could search for &amp;ldquo;nissan leaf
openpilot wiki&amp;rdquo;. Unfortunately, the search results would be empty and would
contain no results. If you searched for &amp;ldquo;nissan openpilot wiki&amp;rdquo;,
&amp;ldquo;&lt;a href="https://github.com/commaai/openpilot/wiki/Nissan%22"&gt;https://github.com/commaai/openpilot/wiki/Nissan&amp;quot;&lt;/a&gt; would show up correctly
because it has all the terms in it. The content of the GitHub wiki page is not
used for returning good results.&lt;/p&gt;
&lt;p&gt;It has been like this for at least 9 years.
&lt;a href="https://github.com/isaacs/github/issues/1683"&gt;GitHub responded that they have declined to remove it from &lt;code&gt;robots.txt&lt;/code&gt; as they believe it can be used for SEO abuse&lt;/a&gt;.
I find this quite unbelievable.
&lt;a href="https://developers.google.com/search/docs/advanced/guidelines/qualify-outbound-links"&gt;The mechanism to prevent this is to utilize &lt;code&gt;rel=&amp;quot;nofollow&amp;quot;&lt;/code&gt; on all user generated &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt; links in the content and with newer guidance suggesting &lt;code&gt;rel=&amp;quot;nofollow ugc&amp;quot;&lt;/code&gt;&lt;/a&gt;.
By removing the content from the index, they have blinded a large portion of the
web&amp;rsquo;s users to the content in GitHub wiki pages.&lt;/p&gt;
&lt;p&gt;Until I made a pull request to
&lt;a href="https://docs.github.com/en/communities/documenting-your-project-with-wikis/about-wikis"&gt;add a notice to their documentation that wikis are not search engine optimized&lt;/a&gt;,
there was absolutely no official documentation or notice about this decision. I
still believe it is not enough as nothing in the main GitHub interface notes
this limitation.&lt;/p&gt;
&lt;p&gt;I believe there are many dedicated users and communities that are not aware of
this issue who are diligently contributing to GitHub wikis. This really
frustrated me. I was one of them. Many others and I contributed a lot to the
[comma.ai openpilot wiki][op_wiki] and it was maddening that their work and my
work were not indexed.&lt;/p&gt;
&lt;p&gt;I noticed that a lot of technical questions had Stack Overflow mirrors rank
highly and yet they weren&amp;rsquo;t Stack Overflow.&lt;/p&gt;
&lt;p&gt;So what I did was this: I made a proxy site without a &lt;code&gt;robots.txt&lt;/code&gt; that would
mirror GitHub wiki content to a site that did not have a restrictive robots.txt.
I put it up at &lt;a href="https://github-wiki-see.rs"&gt;https://github-wiki-see.rs&lt;/a&gt;. I called it GitHub Wiki SEE for
GitHub Wiki Search Engine Enablement. It&amp;rsquo;s kind of a twisted wording of SEO as I
see it as enabling and not even &amp;ldquo;optimizing&amp;rdquo;.&lt;/p&gt;
&lt;h2 id="whats-the-technology-behind-it"&gt;What&amp;rsquo;s the technology behind it?&lt;/h2&gt;
&lt;p&gt;The current iteration is a &lt;a href="https://github.com/actix/actix-web"&gt;Rust Actix Web&lt;/a&gt; application. It parses
the URL and makes requests out to GitHub to get the content. It then scrapes the
content for relevant HTML and reformats it to be more easily crawl-able. It then
serves the content to the search engine and users who come in from a search
engine with a link to the project page and reasoning at the bottom as a static
pinned element. Users aren&amp;rsquo;t meant to read that page and are only meant to
browse to the original GitHub page.&lt;/p&gt;
&lt;p&gt;With these choices, I could meet these requirements:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Hosted it on Google Cloud Run just in case it doesn&amp;rsquo;t become popular.&lt;/li&gt;
&lt;li&gt;Made it easy to deploy.&lt;/li&gt;
&lt;li&gt;Made it cheap.&lt;/li&gt;
&lt;li&gt;Made it small to run on Cloud Run.&lt;/li&gt;
&lt;li&gt;Made it low maintenance.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Another considering was that it needed to not get rate limited by GitHub. To do
this, I made the server return an error and quit itself on Cloud Run if it
detected a rate limiting response to cycle to a new server with a new client IP
address. Unfortunately, this limited the number of requests each server could
handle at a time to a minimum of one.&lt;/p&gt;
&lt;h2 id="supercharging-it"&gt;Supercharging it&lt;/h2&gt;
&lt;p&gt;I originally built the project in March. I monitored the
&lt;a href="https://search.google.com/search-console/about"&gt;Google Search Console&lt;/a&gt; like a hawk to see how the openpilot stuff I had
contributed to was responding to the proxy setup. Admittedly, it got a few users
to click through here and there and I was pretty happy. For a month or two, I
was pretty satisfied. However, I kept on thinking about the
&lt;a href="https://github.com/isaacs/github/issues/1683"&gt;rest of the users who lamented this situation&lt;/a&gt;. While some did take
my offer to post a link somewhere on their blog, README, or tweet, the adoption
wasn&amp;rsquo;t as much as I had hoped.&lt;/p&gt;
&lt;p&gt;I had learned about &lt;a href="https://www.gharchive.org/"&gt;GH Archive&lt;/a&gt; which is a project that archived
every event of GitHub since about 2012. I also learned that the project also
mirrors its archive on &lt;a href="https://cloud.google.com/bigquery/"&gt;BigQuery&lt;/a&gt;. BigQuery allows you to search large
datasets with SQL. Using BigQuery, I was able to determine that about 2,500
GitHub Wiki pages get edited every day. In a week, about 17,000. A month? 66,000
pages. My furor at the blocking of indexing increased.&lt;/p&gt;
&lt;p&gt;I decided to throw $45 at the issue and run a big mega-query and queried all of
GH Archive. Over the lifetime of GH Archive, 4 million pages were edited. I
dumped this into a queue and processed it with Google Cloud Functions to run the
&lt;code&gt;HEAD&lt;/code&gt; query on all the pages in the list and re-exported it to BigQuery. 2
million pages were still there.&lt;/p&gt;
&lt;p&gt;You can find the results of this in these public tables on &lt;a href="https://cloud.google.com/bigquery/"&gt;BigQuery&lt;/a&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;github-wiki-see:show.checked_touched_wiki_pages_upto_202106&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Checked with &lt;code&gt;HEAD&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;github-wiki-see:show.touched_wiki_pages_upto_202106&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;With this &lt;code&gt;checked_touched_wiki_pages_upto_202106&lt;/code&gt; table, I generated 50MB of
compressed XML sitemaps for the GitHub Wiki SEE pages. I called them seed
sitemaps. The source for this can be found
&lt;a href="https://github.com/nelsonjchen/github-wiki-see-rs-sitemaps"&gt;in the sitemap generator repo&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;BigQuery is expensive, so I made another sitemap series for continuous updates.
An earlier version used BigQuery, but the new version runs a daily GitHub
Actions job that downloads the last week of events from GH Archive, processes
them for unique Wiki URLs and exports them to a sitemap. This handles any
ongoing GitHub Wiki changes. The source for this can also be found
&lt;a href="https://github.com/nelsonjchen/github-wiki-see-rs-sitemaps"&gt;in the sitemap generator repo&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="the-results"&gt;The results&lt;/h2&gt;
&lt;p&gt;I am getting thousands of clicks and millions of impressions every day. GitHub
Wiki SEE results are never at the top and average a position of about 29 or the
third page. The mirrored may not rank high and I don&amp;rsquo;t care as the original
content was never going to rank high anyway so the content appearing at all in
the search results of thousands of users even if it was sort of deep satisfies
me.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;All in all, a pretty fun project. I am really happy with the results.&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;My contributions to the openpilot wiki are now indexed.&lt;/li&gt;
&lt;li&gt;Everyone else&amp;rsquo;s contributions to their wikis are now indexed as well.&lt;/li&gt;
&lt;li&gt;I learned a few things or two about writing a Rust web app.&lt;/li&gt;
&lt;li&gt;I learned a lot about SEO&lt;/li&gt;
&lt;li&gt;I feel I&amp;rsquo;ve helped a lot of people who need to find a diamond in the rough and
the diamond isn&amp;rsquo;t in the URL.&lt;/li&gt;
&lt;li&gt;I feel a little warm that I have a high traffic site.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I have no intention of putting ads on the site. It costs me about $25 a month to
run but for the high traffic it gets, the peace of mind I&amp;rsquo;ve acquired, and the
good feelings of helping everybody searching Google, it is worth it.&lt;/p&gt;
&lt;p&gt;I did add decommissioning steps. If it comes to it, I&amp;rsquo;ll make the site just
directly redirect but after GitHub takes Wikis off their &lt;code&gt;robots.txt&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="things-i-learned"&gt;Things I Learned&lt;/h2&gt;
&lt;p&gt;This is a grab-bag of stuff I learned along the way.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sitemaps are a great way to get search engine traffic to your site.&lt;/li&gt;
&lt;li&gt;Large, multi-million page sitemaps can take many months to process. Consider
yourself lucky if it parses 50,000 URLs a day.
&lt;ul&gt;
&lt;li&gt;The Google Search Console saying &amp;ldquo;failed to retrieve&amp;rdquo; is a lie. It means to
say &amp;ldquo;processing&amp;rdquo; but this is apparently a long standing stupid bug.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;GoogleBot is much more aggressive than Bing.
&lt;ul&gt;
&lt;li&gt;Google&amp;rsquo;s Index of my proxy site is probably a lot larger than Bing&amp;rsquo;s by a
magnitude or two. For every 30, 40, or even 100 GoogleBot requests, I get
one Bing request.&lt;/li&gt;
&lt;li&gt;This is important for serving DuckDuckGo users as it is their index.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;The Rust Tokio situation is a bit of a pain as I am stuck on a version of
Tokio that is needed for stable Actix-Web. As a result, I cannot use modern
Tokio stuff that modern Rust crates or libraries use. I may port it to Rocket
or something in the future.&lt;/li&gt;
&lt;li&gt;A lot of people search for certification answers and test answers on GitHub
Wikis.&lt;/li&gt;
&lt;li&gt;GitHub Wikis and GitHub are no exception to Rule 34.&lt;/li&gt;
&lt;li&gt;Cloud Run is great for getting many IP addresses to use and to swap out if any
die. The outgoing IP address is extremely ephemeral and changing it is a
simple matter of simply exiting if a rate limit is detected.
&lt;ul&gt;
&lt;li&gt;This might not always work. Just exit again if so.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;GCP&amp;rsquo;s UI is nicer for manual use compared to AWS.&lt;/li&gt;
&lt;li&gt;The built-in logging capabilities and sink of GCP products are also really
nice. I can easily re-export and/or stream logs to BigQuery or to a Pub Sub
topic for later analysis. I can also just use the viewer on the UI to see what
is going on.&lt;/li&gt;
&lt;li&gt;I get fairly free monitoring and graphing from the GCP ecosystem. The default
graphs are very useful.&lt;/li&gt;
&lt;li&gt;Rust web apps are really expensive to compile on Google Cloud Build. I had to
use 32-core machines to get it to compile in underneath the default timeout of
10 minutes. I eventually sped it up and made it cheaper to build by building
on a pre-built image along with a smaller instance but it is still quite
expensive.&lt;/li&gt;
&lt;li&gt;The traffic from the aggressive GoogleBot is impressively large. Thankfully, I
do not have to pay the bandwidth costs.&lt;/li&gt;
&lt;li&gt;My sloppy use of the HTML Parser may be causing errors but RAM is fairly
generous. It&amp;rsquo;s Rust too so I don&amp;rsquo;t really have to worry that much about
garbage collection or anything similar.&lt;/li&gt;
&lt;li&gt;Google actually follows links it sees in the pages. When I started, it did
not. Maybe it does it only on more popular pages.&lt;/li&gt;
&lt;li&gt;The Rust code is really sloppy, but it still works.&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>GitHub Wiki SEE</title><link>https://mindflakes.com/projects/github-wiki-see/</link><pubDate>Thu, 01 Apr 2021 00:00:00 +0000</pubDate><guid>https://mindflakes.com/projects/github-wiki-see/</guid><description>&lt;p&gt;&lt;a href="https://github-wiki-see.page/"&gt;https://github-wiki-see.page/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A project to get GitHub Wikis indexed by Google Search.&lt;/p&gt;
&lt;p&gt;Explanation is right on the front page.&lt;/p&gt;
&lt;p&gt;If a search engine can&amp;rsquo;t see it, it may as well be invisible.&lt;/p&gt;
&lt;p&gt;Long-term project involving Rust, BigQuery, Cloudflare Workers, and lots of random hosting.&lt;/p&gt;
&lt;p&gt;Probably one more the more visited sites on the internet and a continous effort to keep costs low.&lt;/p&gt;
&lt;p&gt;Has caused GitHub to revisit their policy on a limited subset of Wikis meeting some criteria.&lt;/p&gt;
&lt;p&gt;Will continue until all Wikis are indexed even if they are publically editable or don&amp;rsquo;t meet some star count criteria.&lt;/p&gt;
&lt;p&gt;Personally, I just got really dismayed all this documentation I was doing on a Wiki wasn&amp;rsquo;t visible to Google. Then I realized it was a good idea to make it visible. Then I realized others don&amp;rsquo;t realize it was invisible at all. This was a problem.&lt;/p&gt;</description></item><item><title>The short lived life of Breakout Bots for Zoom Meetings</title><link>https://mindflakes.com/posts/2020/09/12/the-short-lived-life-of-breakout-bots-for-zoom-meetings/</link><pubDate>Sat, 12 Sep 2020 19:42:00 -0800</pubDate><guid>https://mindflakes.com/posts/2020/09/12/the-short-lived-life-of-breakout-bots-for-zoom-meetings/</guid><description>&lt;p&gt;With the pandemic happening, it&amp;rsquo;s been tough for many organizations to adapt. We&amp;rsquo;re all supposed to be together! One way organizations have been staying together is by using Zoom Meetings.&lt;/p&gt;
&lt;p&gt;At work, we&amp;rsquo;ve been using a knock-off reseller version called RingCentral Meetings. From looking at their competitors, Zoom has pulled out all the stops to make their meeting experience the most efficient, resiliant, rather cheapest, and reliable experience.&lt;/p&gt;
&lt;p&gt;One of these features is &amp;ldquo;Breakout Rooms&amp;rdquo;. With breakout rooms, users can subdivide their meetings to make mini-meetings from a bigger meeting. For most of the year, there has been an odd restriction on Breakout Meetings though.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;You cannot go to another breakout room as an attendee without the host reassigning you unless you are a Host or a Co-Host.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Obviously, this can result in a lot of load upon the poor user who is desginated the host. Even the Co-Hosts can&amp;rsquo;t assign users to another breakout room.&lt;/p&gt;
&lt;p&gt;So I made a bot:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/nelsonjchen/BreakoutRoomsBotForZoomMeetings"&gt;https://github.com/nelsonjchen/BreakoutRoomsBotForZoomMeetings&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://user-images.githubusercontent.com/5363/92406673-79d2e080-f0ed-11ea-9953-5b7704811d1c.gif" alt="the bot rename in action"&gt;&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s quite a hack, but it basically controls a web client that is a Host and assigns users based on chat commands and on attendees renaming themselves.&lt;/p&gt;
&lt;p&gt;Last night, I just finished finally optimizing the bot. It should be able to handle hundreds of users and piles of chat commands.&lt;/p&gt;
&lt;p&gt;This morning I learned that Zoom will add native support for switching:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.reddit.com/r/Zoom/comments/irkm82/selfselect_breakout_room/"&gt;https://www.reddit.com/r/Zoom/comments/irkm82/selfselect_breakout_room/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;It was fun, but as brief as the bot existed, the main purposes are numbered. Maybe someone can reuse the code to make other Zoom Meeting add-on/bots?&lt;/p&gt;
&lt;h2 id="technical-and-learnings"&gt;Technical and Learnings&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;I knew about this issue for many months but I never made a bot because there wasn&amp;rsquo;t an API. I waited until I was very disatisified with the situation and then made the bot. I should have just done it, without the API.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Thankfully, by doing this quickly, I only really spent like a week of time on this total. With some of the tooling I used, I didn&amp;rsquo;t have to spend too long debugging the issues.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The original implementation of this tool was a copy and paste into Chrome&amp;rsquo;s Console. This is a much worse experience for users than a Chrome extension. &lt;a href="https://github.com/khusmann"&gt;Kyle Husmann&lt;/a&gt; contributed a fork that extensionized the bot and it is totally something I&amp;rsquo;ll be stealing for future hacks like this.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Zoom got to where they are by doing things their competitors did not and rather quickly. This feature/feedback response is great and is why they&amp;rsquo;ve been crushing. I feel this is a feature that would have taken their competitors possibly a year to implement. At this time, Microsoft Teams is also looking to implement Breakout Rooms.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Zoom&amp;rsquo;s web client uses React+Redux. They also use the Redux-Thunk middleware. They do stick some side-effects in places where things shouldn&amp;rsquo;t but whatever, it works. It did make integration very hard if not impossible at this layer for my bot. However, subscribing to state changes was and is very reliable.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://rxjs-dev.firebaseapp.com/"&gt;RxJS&lt;/a&gt; is a nice implementation of the Reactive Pattern with Observables and stuff like with RX.NET. Without this, I could not fit the bot in so few lines of code with the reliability and usability that it currently has.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;With &lt;a href="https://rxjs-dev.firebaseapp.com/"&gt;RxJS&lt;/a&gt; and Redux&amp;rsquo;s store, I was able to subscribe to internal Redux state changes and transform them into streams of events. For example, the bot transform the streams of renames and chat message requests into a common structure that it then merges to be processed by later operators. Lots of code is shared and I&amp;rsquo;m able to rearrange and transform at will.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The local override functionality is great if you want to inject Redux Web Tools into an existing minified application. If you beautify the code, you can inject dev tools too. Here&amp;rsquo;s the line of code I replaced to inject Redux Dev Tools into Zoom&amp;rsquo;s web client.&lt;/p&gt;
&lt;p&gt;Previous:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;, &lt;span style="color:#a6e22e"&gt;s&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Object(&lt;span style="color:#a6e22e"&gt;r&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;compose&lt;/span&gt;)(Object(&lt;span style="color:#a6e22e"&gt;r&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;applyMiddleware&lt;/span&gt;)(&lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;));
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;After:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;, &lt;span style="color:#a6e22e"&gt;s&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; window.&lt;span style="color:#a6e22e"&gt;__REDUX_DEVTOOLS_EXTENSION_COMPOSE__&lt;/span&gt;(Object(&lt;span style="color:#a6e22e"&gt;r&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;applyMiddleware&lt;/span&gt;)(&lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;));
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This was super helpful in seeing how the Redux state changes when performing actions in a nice GUI.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://github.com/farzher/fuzzysort"&gt;fuzzysort&lt;/a&gt; is great! I&amp;rsquo;m quite surprised at how unsurprising the results can be when looking up rooms by a partial or cut up name.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The underlying websocket connection is available globally as &lt;code&gt;commandSocket&lt;/code&gt;. If you observe the commands, they are just JSON and you can inject your own commands to control the meeting programatically.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Since Breakout Room status is sent back via WebSocket, the UI will automatically update. I did not have to go through the Redux store to update the Breakout Room UI.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;UI Automation of Breakout Room UI: ~100ms vs webSocket command: 2ms. Wow!&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Chat messages are encrypted and decrypted client-side before going out on the Websocket interface. This probably doesn&amp;rsquo;t stop Zoom from reading the chat messages since they are the ones who gave you the keys. I could have reimplemented the encryption in the bot but after running some replay attacks, the UI did not update. Without the UI updating, I didn&amp;rsquo;t feel it was safe for the host to not know what the bot sent out on their behalf.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Even if I had implemented the chat message encryption, the existing UI automation of chat messages hovered around 30ms. The profiler also showed that the overhead of automation wasn&amp;rsquo;t that much and much of the chat message encryption contributed to the 30ms. It wouldn&amp;rsquo;t have been much of a performance win if I implemented it myself.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Possible Security-ish Issue&lt;/strong&gt; - Since it isn&amp;rsquo;t an acceptable bounty issue, and hosts can simply disable chat, I will disclose is possible to DOS the native client by simply spamming chat. If there is too much text, the native clients will lock up and require a restart. Native clients don&amp;rsquo;t drop old chat logs. Web clients don&amp;rsquo;t have this issue as they will drop old chat automatically. Last but not least, it is possible for the Host to disable chat in many ways to alleviate such an attack. I wasn&amp;rsquo;t sure if to let my load_test bot out there or not because of this but after reflection, I think it&amp;rsquo;s OK.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://rxjs-dev.firebaseapp.com/"&gt;RxJS&lt;/a&gt; is MVP. Or rather the Reactive stuff is MVP. If you can get it into a stream, it&amp;rsquo;s super powerful. Best yet, you can reuse your experience from other ecosystems. I was previously using Rx.NET for some stuff at work. I&amp;rsquo;ll be definitely looking at using the Python version of this in the future.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Though it did seem the differing Reactive stuff have different operators. The baselines are still great though and you can always port operators from one to another implementation.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Rx is really helped if you can use TypeScript. Unfortuntately, I never got to this stage.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That said, this was fun! Now onward to the next thing.&lt;/p&gt;</description></item><item><title>Reverse RDP into Windows on GitHub Actions</title><link>https://mindflakes.com/posts/2019/12/07/reverse-rdp-into-windows-on-github-actions/</link><pubDate>Sat, 07 Dec 2019 17:24:55 +0000</pubDate><guid>https://mindflakes.com/posts/2019/12/07/reverse-rdp-into-windows-on-github-actions/</guid><description>&lt;p&gt;Ever wonder what the Desktop of the Windows Runners on GitHub Actions looks like?&lt;/p&gt;
&lt;p&gt;Or perhaps you&amp;rsquo;re missing the ability to &lt;a href="https://www.appveyor.com/docs/how-to/rdp-to-build-worker/"&gt;RDP into build agents like on Appveyor&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I wrote some steps that use ngrok to make a reverse tunnel possible. I also turned on RDP if it wasn&amp;rsquo;t on already and set a password.&lt;/p&gt;
&lt;p&gt;Take a look here!&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/nelsonjchen/reverse-rdp-windows-github-actions"&gt;https://github.com/nelsonjchen/reverse-rdp-windows-github-actions&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://mindflakes.com/images/reverse-rdp-desktop.png" alt="GitHub Actions Desktop"&gt;&lt;/p&gt;</description></item><item><title>Stop Sims 2 Purple Soup or Pink Flashing Crashes on Windows 10 and Modern Hardware with D9VK</title><link>https://mindflakes.com/posts/2019/10/02/stop-sims-2-purple-soup-or-pink-flashing-crashes-on-windows-10-and-modern-hardware-with-d9vk/</link><pubDate>Wed, 02 Oct 2019 06:08:55 +0000</pubDate><guid>https://mindflakes.com/posts/2019/10/02/stop-sims-2-purple-soup-or-pink-flashing-crashes-on-windows-10-and-modern-hardware-with-d9vk/</guid><description>&lt;p&gt;Wrote a guide on how to fix the Purple Soup or Pink Flashing Crashes for
The Sims 2 on Windows 10 1903+ on powerful gaming computers. It&amp;rsquo;s great to make
this accessible again to gamers with powerful gaming computers.&lt;/p&gt;
&lt;p&gt;Guide Link: &lt;a href="https://docs.google.com/document/d/19JMr-FQSU3AlF7Kyvcrr7awTiHBDQSUNLG6qfaI6rOs/edit#"&gt;https://docs.google.com/document/d/19JMr-FQSU3AlF7Kyvcrr7awTiHBDQSUNLG6qfaI6rOs/edit#&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;General idea: Replace Microsoft DirectX 9 with D9VK.&lt;/p&gt;
&lt;p&gt;D9VK is actually actively developed and fixes bugs. It also translates graphics
to a stack that is more open and stable.&lt;/p&gt;
&lt;p&gt;So this:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://mindflakes.com/images/sims2-purple-soup.jpg" alt="sims 2 purple soup"&gt;&lt;/p&gt;
&lt;p&gt;Turns to this:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://mindflakes.com/images/thesims2_d9vk_rtx2080_win101903.jpg" alt="Fixed and proof of running"&gt;&lt;/p&gt;</description></item><item><title>Fast and lightweight headless Qt Installer from Qt Mirrors: aqtinstall</title><link>https://mindflakes.com/posts/2019/06/02/fast-and-lightweight-headless-qt-installer-from-qt-mirrors-aqtinstall/</link><pubDate>Sun, 02 Jun 2019 22:02:00 -0800</pubDate><guid>https://mindflakes.com/posts/2019/06/02/fast-and-lightweight-headless-qt-installer-from-qt-mirrors-aqtinstall/</guid><description>&lt;p&gt;As part of my work on the &lt;a href="https://github.com/debauchee/barrier/"&gt;Barrier project&lt;/a&gt;, we needed a way to build it with the [Qt installer]from an online CI/CD service. On some platforms, such as &lt;a href="https://www.appveyor.com/docs/windows-images-software/"&gt;Appveyor, Qt may be preinstalled&lt;/a&gt;. But on some other platforms such as &lt;a href="https://azure.microsoft.com/en-us/services/devops/pipelines/"&gt;Azure Pipelines&lt;/a&gt;, Qt may not be pre-installed. Nor on Travis. Nor on CircleCI. For Linux and macOS, there is a saving grace. The Qt libraries can be installed headlessly from their operating system repositories such as &lt;code&gt;apt&lt;/code&gt; or &lt;code&gt;brew&lt;/code&gt;. But this luxury does not exist as well on Windows. While Chocolatey does offer some Qt packages, they tend to ancient or non-official.&lt;/p&gt;
&lt;p&gt;There is a toolkit called &lt;a href="https://github.com/hasboeuf/cuteci"&gt;CuteCI&lt;/a&gt; that let you use the Qt Installer and script the GUI headlessly. It&amp;rsquo;s janky and big though. Additionally, to pin versions, you must download 3 to 5 GB of Qt Installer to install a pinned version of Qt.&lt;/p&gt;
&lt;p&gt;So, I found this: &lt;a href="https://lnj.gitlab.io/post/qli-installer/"&gt;https://lnj.gitlab.io/post/qli-installer/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Apparently it&amp;rsquo;s possible to mimic the Qt Installer from a Python script.&lt;/p&gt;
&lt;p&gt;To save it from possible bit-rot, &lt;a href="https://github.com/nelsonjchen/qli-installer"&gt;I forked it to GitHub&lt;/a&gt;. I added parallel downloading, Windows support, and a CI system. I pushed Azure-Pipelines and each commit could cause 100 jobs to run. Across all the various platforms. Azure Pipelines did not break a sweat.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/hasboeuf/cuteci"&gt;CuteCI&lt;/a&gt; is still extremely useful if you must use the official installer with official support. But the speeds with &lt;a href="https://github.com/nelsonjchen/qli-installer"&gt;my fork&lt;/a&gt; were insane. It would normally take many minutes to install Qt with CuteCI. My QLI-Installer fork? 10 or 20 seconds.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;But it turns out there&amp;rsquo;s an even better installer than mine!&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/miurahr/aqtinstall/"&gt;https://github.com/miurahr/aqtinstall/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;aqtinstall&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Classy reusable Python structure&lt;/li&gt;
&lt;li&gt;On PyPi. You can do &lt;code&gt;pip install aqtinstall&lt;/code&gt; and install &lt;code&gt;aqtinstall&lt;/code&gt; for immediate use.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is also another fork of &lt;code&gt;qli-installer&lt;/code&gt;. The CI system was a in a bit of a sorry state though. So I contributed matrix generated jobs to test &lt;code&gt;aqtinstall&lt;/code&gt; across Mac, Windows, and Linux. @miurahr was able to dial down the installation and testing madness too and ramp it up in some places. Actual Qt applications are built to test if &lt;code&gt;aqtinstall&lt;/code&gt; work. Additionally, there was the insight that mobile platforms generally always require the latest Qt version.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;So, if you want a fast and lightweight headless Qt installer that installs from Qt Mirrors and is continually tested, use &lt;code&gt;aqtinstall&lt;/code&gt;!&lt;/strong&gt;&lt;/p&gt;</description></item><item><title>Non-encumbered Windows Bonjour SDK DLLs and Libs</title><link>https://mindflakes.com/posts/2019/06/01/non-encumbered-windows-bonjour-sdk-dlls-and-libs/</link><pubDate>Sat, 01 Jun 2019 19:15:00 -0800</pubDate><guid>https://mindflakes.com/posts/2019/06/01/non-encumbered-windows-bonjour-sdk-dlls-and-libs/</guid><description>&lt;p&gt;This was one of those adventures where you find a problem and it snowballs from there.&lt;/p&gt;
&lt;p&gt;As part of my work on the &lt;a href="https://github.com/debauchee/barrier/"&gt;Barrier project&lt;/a&gt;, we needed a way to build it with the &lt;a href="https://developer.apple.com/bonjour/"&gt;Bonjour SDK&lt;/a&gt; from an online CI/CD service. &lt;a href="https://en.wikipedia.org/wiki/Bonjour_(software)"&gt;Bonjour&lt;/a&gt; is used by Barrier to discover other barrier hosts on the same network. On Windows, the SDK files are needed. Other platforms natively come with the library or similar APIs already preinstalled.&lt;/p&gt;
&lt;p&gt;But there&amp;rsquo;s an issue. The SDK is behind a login wall on Apple&amp;rsquo;s site. Rehosting it might be possible but it might violate some agreement within the installer. Luckily, the sources are open and are under very permissive licenses.&lt;/p&gt;
&lt;p&gt;To save some work, I reused the XBMC project&amp;rsquo;s fork and made &lt;a href="https://github.com/nelsonjchen/mDNSResponder"&gt;my fork of the SDK&lt;/a&gt;. I didn&amp;rsquo;t change any of XBMC&amp;rsquo;s changes, if any. I added a CI system to build the necessary libraries in the same manner that Apple did.&lt;/p&gt;
&lt;p&gt;So, if you need a free, Cloud CI system accessible Apple Windows Bonjour SDK, look at the releases in &lt;a href="https://github.com/nelsonjchen/mDNSResponder"&gt;my repo&lt;/a&gt;! The library files are there and users can fork my build to build the stubs their own way as well.&lt;/p&gt;</description></item><item><title>Barrier CI System WIP</title><link>https://mindflakes.com/posts/2019/05/30/barrier-ci-system-wip/</link><pubDate>Thu, 30 May 2019 22:02:00 -0800</pubDate><guid>https://mindflakes.com/posts/2019/05/30/barrier-ci-system-wip/</guid><description>&lt;p&gt;This was one of those adventures where you find a problem and it snowballs from there.&lt;/p&gt;
&lt;p&gt;I wanted to use &lt;a href="https://github.com/debauchee/barrier/"&gt;barrier&lt;/a&gt; which is a tool for sharing mouses between computers. It is a fork of Synergy, which had gone commercial.&lt;/p&gt;
&lt;p&gt;So, I noticed on their &lt;a href="https://github.com/debauchee/barrier/"&gt;GitHub repo&lt;/a&gt; that the builds for various platforms was inconsistent. OK, maybe I can help fix their CI systems.&lt;/p&gt;
&lt;p&gt;More worringly, there was some Appveyor CI system configured. It was not configured with the &lt;code&gt;appveyor.yml&lt;/code&gt; method and the build process was non-transparent. It was also failing.&lt;/p&gt;
&lt;p&gt;My current CI system of choice for open source projects is &lt;a href="https://azure.microsoft.com/en-us/services/devops/pipelines/"&gt;Microsoft&amp;rsquo;s Azure Pipelines&lt;/a&gt;. For open source projects on GitHub, they&amp;rsquo;ll provide 10 parallel jobs of &lt;em&gt;Mac&lt;/em&gt;, Linux, and &lt;em&gt;Windows&lt;/em&gt;. &lt;em&gt;Mac&lt;/em&gt; and &lt;em&gt;Windows&lt;/em&gt; usually only show up as premium options or are severely rate-limited. As far as I can tell, whatever cluster Microsoft has created for their service, it&amp;rsquo;s really not limited by capacity.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/debauchee/barrier/issues/293"&gt;The good news is that they were fans of it and I was able to move them.&lt;/a&gt; It&amp;rsquo;s still a work in progress. The work done here has draw in some general &amp;ldquo;improve the ecosystem&amp;rdquo; enhancements which I will elaborate on in future posts.&lt;/p&gt;</description></item><item><title>An Android Accessibility Service for Eventbrite Organizers: PassShout</title><link>https://mindflakes.com/posts/2019/03/15/an-android-accessibility-service-for-eventbrite-organizers-passshout/</link><pubDate>Fri, 15 Mar 2019 19:15:00 -0800</pubDate><guid>https://mindflakes.com/posts/2019/03/15/an-android-accessibility-service-for-eventbrite-organizers-passshout/</guid><description>&lt;p&gt;The Scene:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It&amp;rsquo;s Saturday. And it&amp;rsquo;s like so many people have free time on that date.&lt;/li&gt;
&lt;li&gt;You&amp;rsquo;re manning a convention center ticket check-in booth.&lt;/li&gt;
&lt;li&gt;Your eyesight just isn&amp;rsquo;t the best. After looking at hundreds, if not
thousands of them, it can be a blur.&lt;/li&gt;
&lt;li&gt;You&amp;rsquo;re using Android.&lt;/li&gt;
&lt;li&gt;There&amp;rsquo;s a long line and people have &lt;em&gt;different&lt;/em&gt; pass or ticket types,
sometimes even if they are in the same group.&lt;/li&gt;
&lt;li&gt;You&amp;rsquo;re processing thousands of people.&lt;/li&gt;
&lt;li&gt;You might not even have a table.&lt;/li&gt;
&lt;li&gt;You&amp;rsquo;re using Eventbrite Organizer.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I have a tool for you! It&amp;rsquo;s called &lt;a href="https://github.com/nelsonjchen/PassShout/"&gt;PassShout&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In addition to a chime, it&amp;rsquo;ll read out loud the pass/ticket type.&lt;/p&gt;
&lt;p&gt;This greatly reduces operational mistakes. PassShout is part of an
implementation of a method in occupational safety called
&lt;a href="https://en.wikipedia.org/wiki/Pointing_and_calling"&gt;Pointing and Calling&lt;/a&gt;. &lt;a href="https://en.wikipedia.org/wiki/Pointing_and_calling"&gt;PAC&lt;/a&gt; has been
&lt;a href="https://www.atlasobscura.com/articles/pointing-and-calling-japan-trains"&gt;adopted widely thoughout Asia and the NYC Metro&lt;/a&gt; to
reduce incidents on trains systems. By calling out the type, things move
faster and mistakes are reduced.&lt;/p&gt;
&lt;h2 id="implementation"&gt;Implementation&lt;/h2&gt;
&lt;p&gt;This is the first Android app I&amp;rsquo;ve written in Kotlin. It&amp;rsquo;s amazing what the
Android Accessibility API offers for third party programs to make things
more accessible. Unfortunately, there does not seem to be an equivalent
for iOS.&lt;/p&gt;
&lt;p&gt;Kotlin is really easy to read and write. I can see how it&amp;rsquo;s not Scala and
is closer to a usable modern Java. It&amp;rsquo;s basically the Swift of Android.&lt;/p&gt;</description></item><item><title>NC QEMU</title><link>https://mindflakes.com/projects/nc-qemu/</link><pubDate>Tue, 25 Dec 2018 00:00:00 +0000</pubDate><guid>https://mindflakes.com/projects/nc-qemu/</guid><description>&lt;p&gt;&lt;a href="https://dev.azure.com/nelsonjchen/NC%20QEMU/_build/latest?definitionId=6?branchName=master"&gt;&lt;img src="https://dev.azure.com/nelsonjchen/NC%20QEMU/_apis/build/status/nelsonjchen.nc-qemu?branchName=master" alt="Build Status"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="links"&gt;Links&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Azure Pipelines Build View: &lt;a href="https://dev.azure.com/nelsonjchen/NC%20QEMU/_build"&gt;https://dev.azure.com/nelsonjchen/NC%20QEMU/_build&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;GitHub Repo: &lt;a href="https://github.com/nelsonjchen/nc-qemu/"&gt;https://github.com/nelsonjchen/nc-qemu/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Releases Download Link: &lt;a href="https://github.com/nelsonjchen/nc-qemu/releases"&gt;https://github.com/nelsonjchen/nc-qemu/releases&lt;/a&gt;&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Is this outdated and not matching the latest release of QEMU? Contact me.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="changes"&gt;Changes&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Azure Pipeline to build &lt;code&gt;x86_x64&lt;/code&gt; target QEMU in MSYS2 on Windows&lt;/li&gt;
&lt;li&gt;Upgraded to Capstone with fixes that allow building in MSYS2.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="about"&gt;About&lt;/h2&gt;
&lt;p&gt;&amp;ldquo;NC QEMU&amp;rdquo; is a very lightly augmented and experimental fork of QEMU to build on
Azure Pipelines and with &lt;a href="https://docs.microsoft.com/en-us/virtualization/api/"&gt;Windows Hypervisor Platform (WHPX)&lt;/a&gt; support for
users who care the most about running the &lt;code&gt;x86_64&lt;/code&gt; target fast. This build only
cares about the &lt;code&gt;x86_64&lt;/code&gt; target and other targets are not built.&lt;/p&gt;
&lt;p&gt;The output is a zip file with some DLLs and &lt;code&gt;qemu-system-x86_64.exe&lt;/code&gt;. This QEMU
distribution can be run from a folder by itself. Alternatively,
&lt;code&gt;qemu-system-x86_64.exe&lt;/code&gt; can be dropped into &lt;a href="https://qemu.weilnetz.de/"&gt;QEMU for Window&lt;/a&gt;&amp;rsquo;s
installation directory at &lt;code&gt;C:\Program Files\qemu&lt;/code&gt;, replacing the existing
version. &lt;em&gt;Some features like USB network redirection might be missing though&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;The pipeline provides a differently compiled QEMU compared to &lt;a href="https://qemu.weilnetz.de/"&gt;QEMU for
Windows&lt;/a&gt;&amp;rsquo;s own &lt;a href="https://qemu.weilnetz.de/doc/BUILD.txt"&gt;build instructions&lt;/a&gt; which are
cross-compiled on Linux. Notably, NC QEMU is built on a Microsoft-provided copy
of Windows in MSYS2 with access to the Windows SDK headers for WHPX distributed
by Microsoft. The &lt;a href="https://mingw-w64.org/doku.php"&gt;MingW64 Toolkit&lt;/a&gt; which QEMU for Windows is built
with has unfortunately currently not reproduced the WHPX headers in a free
software manner. Users who want a QEMU for Windows with WHPX support but aren&amp;rsquo;t
licensed nor want to accept the terms of installing the Windows 10 SDK are out
of luck.&lt;/p&gt;
&lt;p&gt;Another benefit is that this project provides a declaratively made and
executable pipeline that builds QEMU for Windows. Fork, setup an Azure Pipeline,
and adjust if needed. This can be considered a bit &amp;ldquo;executable documentation&amp;rdquo;
for building a QEMU x86_64 target of this nature. The build logs are public and
can be used as reference. For users having trouble building or configuring their
systems to build QEMU, this reproducible setup can be quite useful.&lt;/p&gt;
&lt;h2 id="why-qemuwhpx-for-x86_64"&gt;Why QEMU+WHPX for &lt;code&gt;x86_64&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;Absolutely not exhaustive:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Acceleration is great. You can reach near-native speeds with acceleration.&lt;/li&gt;
&lt;li&gt;WHPX is native to the OS. No foreign kernel drivers/modules/extensions needed.&lt;/li&gt;
&lt;li&gt;It&amp;rsquo;s great for users who don&amp;rsquo;t have access to &lt;a href="https://software.intel.com/en-us/articles/intel-hardware-accelerated-execution-manager-intel-haxm"&gt;Intel&amp;rsquo;s HAX&lt;/a&gt; because they
either want Hyper-V and/or AMD support. With AMD CPUs being multi-core bargain
monsters, developers and power users on AMD are becoming more numerous.&lt;/li&gt;
&lt;li&gt;QEMU+WHPX boots Windows ISOs. &lt;a href="https://github.com/intel/haxm/issues/20"&gt;HAX currently does not.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;QEMU is easier to hack on, script, and developed by many organizations, not
one. WHPX support was &lt;em&gt;contributed by Microsoft&lt;/em&gt; but is probably most useful for
Google&amp;rsquo;s QEMU-based Android emulators!&lt;/li&gt;
&lt;li&gt;Users hacking on or working with QEMU in Windows can bring their work to Linux
KVM accelerated systems easier. And vice-versa.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="packer-whpx-workaround"&gt;Packer WHPX workaround&lt;/h2&gt;
&lt;p&gt;The executables provided here do work for &lt;a href="https://www.packer.io/docs/builders/qemu.html"&gt;Packer&lt;/a&gt;. Simply add the
directory &lt;code&gt;with qemu-system-x86_64.exe&lt;/code&gt; to the &lt;code&gt;PATH&lt;/code&gt;. Packer does not currently
recognize &lt;code&gt;whpx&lt;/code&gt; as a valid argument for the &lt;code&gt;acceleration&lt;/code&gt; key. The workaround
is to add it to &lt;code&gt;qemu-args&lt;/code&gt; as a manual argument.&lt;/p&gt;
&lt;p&gt;Additionally, the &lt;code&gt;cpu&lt;/code&gt; argument of QEMU does not support &lt;code&gt;cpu=host&lt;/code&gt; for &lt;code&gt;whpx&lt;/code&gt;.
Specify something supported manually.&lt;/p&gt;
&lt;h2 id="references"&gt;References&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Orbital (PS4 Emulator) Build instructions:
&lt;a href="https://github.com/AlexAltea/orbital/wiki/Building"&gt;https://github.com/AlexAltea/orbital/wiki/Building&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Gooey and PyInstaller for easy to write, distribute, and use scripts!</title><link>https://mindflakes.com/posts/2018/12/15/gooey-and-pyinstaller-for-easy-to-write-distribute-and-use-scripts/</link><pubDate>Sat, 15 Dec 2018 20:36:00 -0800</pubDate><guid>https://mindflakes.com/posts/2018/12/15/gooey-and-pyinstaller-for-easy-to-write-distribute-and-use-scripts/</guid><description>&lt;p&gt;What is:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Easy to write&lt;/li&gt;
&lt;li&gt;Easy to distribute and portable&lt;/li&gt;
&lt;li&gt;Super Powerful&lt;/li&gt;
&lt;li&gt;Cross Platform&lt;/li&gt;
&lt;li&gt;Puts computer novices and professionals on the same level?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I think it&amp;rsquo;s a combination of &lt;a href="https://github.com/chriskiehl/Gooey"&gt;Gooey&lt;/a&gt; and &lt;a href="https://github.com/pyinstaller/pyinstaller"&gt;PyInstaller&lt;/a&gt;. If
you put those two together, you get all those above.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It&amp;rsquo;s Python, so it&amp;rsquo;s easy to write. There are so many guides online and a wide
assortment of libraries. Most importantly, you get libraries that have a
strong eye towards ergonomics. Python is a wonderful beginner&amp;rsquo;s language that
some people even call an executable psuedolanguage.&lt;/li&gt;
&lt;li&gt;PyInstaller bundles applications into a single folder or exe so it&amp;rsquo;s easy to
distribute.&lt;/li&gt;
&lt;li&gt;You get the full force of Python&amp;rsquo;s language and its ecosystem behind you.&lt;/li&gt;
&lt;li&gt;Python is cross platform, but Gooey&amp;rsquo;s GUI is also as well. Don&amp;rsquo;t be expecting
to make &amp;ldquo;Destiny&amp;rdquo;-style GUIs with it. But do be expecting a surprising amount
of native-ness.&lt;/li&gt;
&lt;li&gt;While PyInstaller does package the application up into a portable Python
script, the existing command line invokation is still left for professionals.
Simply add &lt;code&gt;--ignore-gooey&lt;/code&gt; to the list of arguments. Now it&amp;rsquo;s just a plain
old script.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The &lt;a href="https://github.com/nelsonjchen/gooey-pyinstaller-demo"&gt;Gooey PyInstaller Demo&lt;/a&gt; was presented at a DesertPy meetup in August
of 2018. It&amp;rsquo;s a project showing the development of a simple argument parsing
script all the way up to a portable GUI. &lt;del&gt;Future improvements to the demo include
some CI scripts and configurations.&lt;/del&gt; &lt;em&gt;This was completed on 2018-12-15&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Demo Project Link: &lt;a href="https://github.com/nelsonjchen/gooey-pyinstaller-demo"&gt;https://github.com/nelsonjchen/gooey-pyinstaller-demo&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Switched to Hugo</title><link>https://mindflakes.com/posts/2015/11/29/switched-to-hugo/</link><pubDate>Sun, 29 Nov 2015 00:37:59 -0800</pubDate><guid>https://mindflakes.com/posts/2015/11/29/switched-to-hugo/</guid><description>&lt;p&gt;&lt;em&gt;Wow&lt;/em&gt;! I think it has been nearly two years since I last updated this blog.
I have decided to change the blog a bit and port it over to &lt;a href="http://hugo.spf13.com"&gt;hugo&lt;/a&gt; which is
a static site generator written in Go. It is &lt;em&gt;very&lt;/em&gt; fast compared to &lt;a href="http://nanoc.ws/"&gt;nanoc&lt;/a&gt;
which I was using. I do not know if I quite agree that this is just as
customizable as &lt;a href="http://nanoc.ws/"&gt;nanoc&lt;/a&gt; but it is clearly faster. I was not taking too much
advantage of the previous &lt;a href="http://foundation.zurb.com"&gt;Foundation&lt;/a&gt; based flexibility of the &lt;a href="http://nanoc.ws/"&gt;nanoc&lt;/a&gt;
site and I believe it may had become a burden. Also, bitrot was beginning to
seriously set in. Luckily, it is a static site but it does make some tears shed
when you have to pin some really old gems and use a really old version of Ruby
to build and deploy the site. Unless the kernel syscalls change dramatically,
I will probably be able to compile with this version of &lt;a href="http://hugo.spf13.com"&gt;hugo&lt;/a&gt; indefinitely.&lt;/p&gt;
&lt;p&gt;Anyway, the &lt;code&gt;nanoc&lt;/code&gt; versions troubles me no more. I am using a &lt;a href="http://hugo.spf13.com"&gt;hugo&lt;/a&gt; version
of the site now. As an improvement, I have also setup automatic deployment of
my &lt;code&gt;master&lt;/code&gt; branch to Google&amp;rsquo;s storage and configured CloudFlare to provide TLS
and all the goodies that come with that. I guess I could also start using
something like &lt;a href="http://prose.io"&gt;prose.io&lt;/a&gt; to write my posts as well. I doubt I will go that
far! But, it is very nice to know that is possible.&lt;/p&gt;
&lt;p&gt;I am now just using a theme called &lt;a href="https://github.com/enten/hyde-y"&gt;hyde-y&lt;/a&gt; which is off-the-shelf. Of
course, I did customize it a little bit. &lt;a href="http://hugo.spf13.com"&gt;hugo&lt;/a&gt;&amp;rsquo;s overriding system is plain
and simple to use.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Why would anyone want summaries on the front page? Just give the complete
content.&lt;/li&gt;
&lt;li&gt;The titles of the posts on the front page should have the same information.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I addressed all that, and while it was a bit of a hunt, it was fairly clear
what needed to be done.&lt;/p&gt;
&lt;p&gt;I do not think I will go the full mile with customizing &lt;code&gt;hugo&lt;/code&gt; like I did with
&lt;code&gt;nanoc&lt;/code&gt;. The complexity was hurting more than it helped. I guess I have
switched over to being more minimalist since I concieved the original site.
&lt;a href="http://foundation.zurb.com"&gt;Foundation&lt;/a&gt; is great if you need the kitchen sink and everything but it is
really overkill. It was also another maintenance burden with its rather
relentless upgrade schedule. I am taking it slow from here on out.&lt;/p&gt;</description></item><item><title>Running Windows XP using Libvirt inside Ubuntu inside VMWare Fusion</title><link>https://mindflakes.com/posts/2014/01/06/running-windows-xp-using-libvirt-inside-ubuntu-inside-vmware-fusion/</link><pubDate>Mon, 06 Jan 2014 18:09:02 -0700</pubDate><guid>https://mindflakes.com/posts/2014/01/06/running-windows-xp-using-libvirt-inside-ubuntu-inside-vmware-fusion/</guid><description>&lt;p&gt;So I&amp;rsquo;m investigating running Windows XP inside &lt;a href="https://libvirt.org/"&gt;&lt;code&gt;libvirt&lt;/code&gt;&lt;/a&gt; in Ubuntu on my MacBook for continuous integration testing
purposes with &lt;a href="https://www.jenkins.io/"&gt;Jenkins&lt;/a&gt;. I tried for many hours to get it working but Windows would not boot up or it would get stuck
on the &lt;code&gt;NTLDR cannot be found&lt;/code&gt; issue. As it turns out, I did not enable &amp;ldquo;Enable hypervisor applications in this
virtual machine&amp;rdquo;. I was under the assumption that I would not need to check that box as I wrongly assumed &lt;a href="https://www.qemu.org/"&gt;&lt;code&gt;qemu&lt;/code&gt;&lt;/a&gt;
would handle all the needed machine translation and that an error with bootup is not the fault of lacking the ability
to use a CPU feature to emulate something or the disk emulation being borked. With five different ISOs of various
pedigrees, I tried installing Windows XP with &lt;a href="https://virt-manager.org/"&gt;&lt;code&gt;virt-manager&lt;/code&gt;&lt;/a&gt; and all of them failed to bootup with various disk image
formats like &lt;code&gt;qcow2&lt;/code&gt; or &lt;code&gt;raw&lt;/code&gt;. It was only until I checked that checkbox did it then work.&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s my surprise for today. I really wished I checked that checkbox earlier! It determines if your machine can
bootup and only using &lt;code&gt;qemu&lt;/code&gt; without &lt;a href="https://linux-kvm.org/"&gt;&lt;code&gt;kvm&lt;/code&gt;&lt;/a&gt; will not cut it for booting Windows XP inside libvirt inside Ubuntu inside
&lt;a href="https://www.vmware.com/products/desktop-hypervisor/workstation-and-fusion"&gt;VMware Fusion&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>BeamNG DRIVE on Mac OS X with CrossOver</title><link>https://mindflakes.com/posts/2013/08/03/beamng-drive-on-mac-os-x-with-crossover/</link><pubDate>Sat, 03 Aug 2013 16:06:37 -0700</pubDate><guid>https://mindflakes.com/posts/2013/08/03/beamng-drive-on-mac-os-x-with-crossover/</guid><description>&lt;p&gt;&lt;strong&gt;UPDATE&lt;/strong&gt; 2015-11-28: Hey BeamNG forum users. These instructions worked for me way
back when I was using CrossOver. You might be able to get similar or better results
with Wineskin Winery or some other Wine wrapper. And those are &lt;em&gt;free&lt;/em&gt; too!
I don&amp;rsquo;t run BeamNG on my local laptop anymore nowadays but I &lt;a href="(http://lg.io/2015/07/05/revised-and-much-faster-run-your-own-highend-cloud-gaming-service-on-ec2.html)"&gt;Game on Amazon EC2&lt;/a&gt;
and it works fairly well with BeamNG at a very minimal cost.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://mindflakes.com/images/beamng-crossover.jpg" alt="beamng on crossover"&gt;&lt;/p&gt;
&lt;p&gt;Gotta make this quick. This post will change.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s how to get &lt;a href="http://www.beamng.com/drive/"&gt;BeamNG Drive&lt;/a&gt; working in Mac OS X. I&amp;rsquo;m sure there are equivilent instructions for &lt;a href="http://wineskin.urgesoftware.com/tiki-index.php?page=Wineskin%2C+Play+your+favorite+Windows+games+on+Mac+OS+X+without+needing+Microsoft+Windows"&gt;Wineskin&lt;/a&gt;
but I have no time to find out.&lt;/p&gt;
&lt;p&gt;Make a new bottle in Crossover. Make sure it is a Windows Vista bottle. Run the Wine configuration setting inside it
and set the version to Windows 7 in one of the sheets. Enable the Mac Driver so you don&amp;rsquo;t run it through X11.&lt;/p&gt;
&lt;p&gt;Install the Modern DirectX runtime into it. Install BeamNG into it. Mute your speakers. Change the audio options to
use OpenAL for output. Unmute speakers. Enjoy.&lt;/p&gt;
&lt;p&gt;So far this works for the tech demo. I&amp;rsquo;m going to try it on Alpha later.&lt;/p&gt;
&lt;p&gt;UPDATE: It works on Alpha. Yay!&lt;/p&gt;</description></item><item><title>Mount USB devices in Virtualbox-based Vagrant</title><link>https://mindflakes.com/posts/2013/07/24/mount-usb-devices-in-virtualbox-based-vagrant/</link><pubDate>Wed, 24 Jul 2013 17:03:05 -0700</pubDate><guid>https://mindflakes.com/posts/2013/07/24/mount-usb-devices-in-virtualbox-based-vagrant/</guid><description>&lt;p&gt;If you want to mount USB in &lt;a href="http://virtualbox.org"&gt;Virtualbox&lt;/a&gt;, you have to do this &lt;a href="https://gist.github.com/nelsonjchen/c09924feb0830415a1d0#file-solution"&gt;solution&lt;/a&gt;. At
the time of this post, a typical Google search for this would go to a solution
at advocated using the &lt;code&gt;attachusb&lt;/code&gt; command in &lt;code&gt;VboxManage&lt;/code&gt; in the &lt;code&gt;Vagrantfile&lt;/code&gt;
provider customization section. This will not work because the VM is off at the
time of bootup. It looks like the original author of this gist did not repost
his solution back to the thread.&lt;/p&gt;
&lt;p&gt;The solution, in other words, is to use USB filters to automatically connect
devices to your VM. USB filters can be added while the machine is powered off.
They&amp;rsquo;ll be applied upon boot or, in this case, &lt;code&gt;vagrant up&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>My current vagrant setup</title><link>https://mindflakes.com/posts/2013/06/22/my-current-vagrant-setup/</link><pubDate>Sat, 22 Jun 2013 20:09:42 -0700</pubDate><guid>https://mindflakes.com/posts/2013/06/22/my-current-vagrant-setup/</guid><description>&lt;p&gt;I firmly believe that &lt;a href="http://vagrantup.com"&gt;Vagrant&lt;/a&gt; is the quickest way from nothing to a running and preconfigured development
environment on any machine and especially Macs. For me, the &lt;a href="http://docs.vagrantup.com/v2/why-vagrant/"&gt;&amp;lsquo;works on my machine&amp;rsquo; problem&lt;/a&gt; is the biggest reason I
run Vagrant. Day-to-day though, Vagrant is probably the easiest to use UI for &lt;a href="https://www.virtualbox.org/%E2%80%8E"&gt;Virtualbox&lt;/a&gt;. If my work actually
had money to give me for the &lt;a href="http://www.vagrantup.com/vmware"&gt;VMWare plugin&lt;/a&gt;, I believe it would be a better UI for VMWare Fusion as well.&lt;/p&gt;
&lt;h3 id="the-basics"&gt;The Basics&lt;/h3&gt;
&lt;p&gt;This is enough to get started with Vagrant and to reap the rewards.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="https://www.virtualbox.org/%E2%80%8E"&gt;Virtualbox&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.vagrantup.com/vmware"&gt;Vagrant&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;That&amp;rsquo;s great and all, but these are the basics. At the very least, you&amp;rsquo;ll be able to bring up some boxes that don&amp;rsquo;t
require special plugins up.&lt;/p&gt;
&lt;h3 id="frills"&gt;Frills&lt;/h3&gt;
&lt;p&gt;You don&amp;rsquo;t need these but I do! I usually build my &lt;a href="http://www.vagrantup.com/vmware"&gt;Vagrant&lt;/a&gt; boxes with &lt;a href="http://www.opscode.com/chef/"&gt;Opscode Chef&lt;/a&gt;,
a configuration management system. For reference, a Chef cookbook is a series of statements about how a machine
should be setup.&lt;/p&gt;
&lt;p&gt;Most of these frills are plugins. To build the boxes I make, you&amp;rsquo;ll usually have to install or use these.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="http://berkshelf.com/"&gt;Berkshelf&lt;/a&gt; is a dependency resolution manager for Chef. I use Berkshelf as a gem along with the corresponding
&lt;a href="https://github.com/riotgames/vagrant-berkshelf"&gt;vagrant plugin&lt;/a&gt;. With this, when I run &lt;code&gt;berks cookbook &amp;lt;name&amp;gt;&lt;/code&gt;, I can make a Virtual Machine that can be created
and destroyed quickly from scratch for whatever purpose. I could do &lt;code&gt;vagrant init&lt;/code&gt; but &lt;code&gt;berks cookbook&lt;/code&gt; has it beat
by creating a directory structure that&amp;rsquo;s pretty much a Chef cookbook. Even if I don&amp;rsquo;t intend to redistribute said cookbook,
the VM made is perfectly fine for tryout purposes.&lt;/li&gt;
&lt;li&gt;I like using the &lt;a href="https://github.com/opscode/bento"&gt;Opscode Bento&lt;/a&gt; boxes. They are minimal and they have already been uploaded to S3 on Opscode&amp;rsquo;s
dime. In a &lt;code&gt;Vagrantfile&lt;/code&gt;, you can set the box URL for a Vagrant basebox to be downloaded. These boxes are great.&lt;/li&gt;
&lt;li&gt;You can&amp;rsquo;t use the Opscode Bento boxes without the &lt;a href="https://github.com/schisamo/vagrant-omnibus"&gt;Vagrant Omnibus plugin&lt;/a&gt;. Those boxes &lt;em&gt;do not include Chef&lt;/em&gt;
so you must install Chef at runtime.&lt;/li&gt;
&lt;li&gt;Just so you don&amp;rsquo;t get warnings about the Virtualbox additions being out of date,
there&amp;rsquo;s a &lt;a href="https://github.com/opscode/bento"&gt;Vagrant plugin to automatically update the guest additions if needed&lt;/a&gt;. This one is really &lt;em&gt;optional&lt;/em&gt;
and it&amp;rsquo;s use just surpresses that warning you get if you bring up a vagrant box with old guest additions.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="the-future"&gt;The Future&lt;/h3&gt;
&lt;p&gt;In the future, I&amp;rsquo;ll like to be able to test my boxes to make sure they stay working as the things they pull from the
internet change. For this, there&amp;rsquo;s &lt;a href="https://github.com/opscode/test-kitchen"&gt;Test Kitchen&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Unfortunately, it&amp;rsquo;s still really cutting edge. However, there are &lt;a href="https://github.com/opscode/guard-kitchen"&gt;guard plugins&lt;/a&gt; and this &lt;a href="http://starkandwayne.com/articles/2013/05/07/tdd-your-devops-with-test-kitchen/"&gt;Youtube Video and
blog post&lt;/a&gt;. That video is very much a must see for anybody who appreciates TDD.&lt;/p&gt;
&lt;p&gt;Full integration testing on your own laptop is very attractive to me. I keep mine plugged in and I find it disturbing
that the rest of the cores on this MacBook Pro just lie cool.&lt;/p&gt;
&lt;p&gt;And also, maybe if I get some cash, I might drop some money on the VMWare plugin and VMWare Fusion. If I want to
simulate multiple servers at a time and heavier loads, it would make that much faster.&lt;/p&gt;</description></item><item><title>A Windows "QuickStart"</title><link>https://mindflakes.com/posts/2013/05/26/a-windows-quickstart/</link><pubDate>Sun, 26 May 2013 20:33:11 -0700</pubDate><guid>https://mindflakes.com/posts/2013/05/26/a-windows-quickstart/</guid><description>&lt;p&gt;I paid Swish $25 and $8 shipping for &lt;a href="http://www.swish.com/details/devkit/"&gt;this&lt;/a&gt; two months ago. I think I had my
share donated to the Khan Academy.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://mindflakes.com/images/quickstart-box.jpg" alt="The box"&gt;&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s the &amp;ldquo;Windows Quickstart Kit for Mac Developers&amp;rdquo;. It includes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A full Windows 8 Pro license&lt;/li&gt;
&lt;li&gt;A Parallels Desktop license&lt;/li&gt;
&lt;li&gt;A USB Stick with an ISO on it with a real Microsoft Certificate of Authenticity. Genuine Windows!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I&amp;rsquo;m not sure why Microsoft saw fit to spend two months packaging a &amp;ldquo;quickstart&amp;rdquo;. Why Microsoft did not see fit to
provide this quickstart through digital distribution is beyond me. They could have emailed a link to some keys and
ISOs and maybe even let a distributor like Digital River do this. Instead, they saw fit to contract this work out to
a physical media distribution company. It seems with these charity-ware deals that the best way to donate money is to
allocate a large chunk to some physical distributor.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m so stoked to try and develop for Windows Phone. I&amp;rsquo;m going to virtualize Windows 8 and develop a native app for
a platform on which I have no way to run natively. I&amp;rsquo;m also going to jump over some chairs in celebration.&lt;/p&gt;
&lt;p&gt;Nuh uh, virtualization is cheating and is really anti-dogfood. If I have to boot up a RAM hungry OS to RUN the app,
it&amp;rsquo;s a failure. If I have to develop the app inside a virtualized OS, that would be even more of a failure since I
would have to bear with the performance and non-nativeness penalty. There&amp;rsquo;s no way a good app can come out with so
many barriers like that. Google realized that its Eclipse toolkit was a problem and
&lt;a href="http://developer.android.com/sdk/installing/studio.html"&gt;switched&lt;/a&gt;
to IntelliJ IDEA to reduce their barriers and gain an awesome IDE in the meantime. I highly doubt Microsoft will
provide a free cross-platform and light SDK. The technical barriers are just too high. It&amp;rsquo;s totally not like their
Xbox where game developers are used to putting up with shit like that. Mobile developers are in general more finicky
and prefer native tools. I&amp;rsquo;m not sure if this is still the case now but the Android team saw fit at one point to
maintain the Android compilation toolchain for the entire OS &lt;em&gt;on&lt;/em&gt; OS X. You can compile a Linux system on OS X!&lt;/p&gt;
&lt;p&gt;With that said, this cool cardboard box is all that remains. It would be well designed if it never existed. It&amp;rsquo;s way
too late for that though.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s made up of two big pieces. After ripping off the plastic wrapper, there&amp;rsquo;s a windows logo cutout sleeve thing to
keep the box with a flap closed. It&amp;rsquo;s a pretty retail package for something that is only sold online.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://mindflakes.com/images/quickstart-box-two-pieces.jpg" alt="two pieces"&gt;&lt;/p&gt;
&lt;p&gt;When you open the box, you have a welcome card with some very basic instructions on the back on the left and some
coupon card things on the right.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://mindflakes.com/images/quickstart-box-open-box.jpg" alt="open box"&gt;&lt;/p&gt;
&lt;p&gt;Beneath the welcome card is a USB drive. It has a Microsoft certificate of authenticity on it,
so you know its real and has real Microsoft binary bits. There&amp;rsquo;s also a tracking ID on it too. The Microsoft logo is
embedded in plastic on the back and not some cheap printer job. It&amp;rsquo;s certainly done with style to make the USB drive
seem to be actually worth something.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://mindflakes.com/images/quickstart-box-beneath-the-card.jpg" alt="beneath the card"&gt;&lt;/p&gt;
&lt;p&gt;On the USB Drive is just an ISO. There are no other files The drive itself isn&amp;rsquo;t bootable. It is formatted with NTFS
though. At the very least, it&amp;rsquo;s readable on all platforms. It also enumerates as a device of the name Windows 8 Pro
in system profiler. Quite a Matroska doll. I guess having an ISO is easier than mounting a USB drive in a virtual
machine in terms of instructional material.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://mindflakes.com/images/quickstart-box-drive-contents.jpg" alt="drive contents"&gt;&lt;/p&gt;
&lt;p&gt;The cards on the right had keys on them. They&amp;rsquo;re business card sized and feel like them too.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://mindflakes.com/images/quickstart-box-key-cards.jpg" alt="key cards"&gt;&lt;/p&gt;
&lt;p&gt;On the back were some keys. Why they felt the need to kill all these trees and grow soy beans to produce the ink for
printing on said dead tree material to wrap around these numbers is beyond me.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://mindflakes.com/images/quickstart-box-keycodes.jpg" alt="key codes"&gt;&lt;/p&gt;
&lt;p&gt;It took two months for these two alphanumeric strings to get here. The lack of timeliness on delivering these two
codes and an ISO does not look well for Microsoft&amp;rsquo;s Windows efforts at all. It would take 30 minutes to illegally
obtain these materials. 30 minutes is far less than two months. Oh, I almost forgot,
they don&amp;rsquo;t even include Parallels in the package. You will have to go download that from Parallel&amp;rsquo;s site.
What a &amp;ldquo;quickstart&amp;rdquo; indeed.&lt;/p&gt;</description></item><item><title>Here's a compiled version of Keycastr.</title><link>https://mindflakes.com/posts/2013/05/22/heres-a-compiled-version-of-keycastr./</link><pubDate>Wed, 22 May 2013 13:02:12 -0700</pubDate><guid>https://mindflakes.com/posts/2013/05/22/heres-a-compiled-version-of-keycastr./</guid><description>&lt;blockquote&gt;
&lt;p&gt;Update: Keycastr is currently maintained at &lt;a href="https://github.com/keycastr/keycastr"&gt;github.com/keycastr/keycastr&lt;/a&gt;. Please use that repository first.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I just compiled a version of keycastr and put it here since I could not find a precompiled version that&amp;rsquo;s relatively
new. The release artifacts are available here:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/nelsonjchen/keycastr/releases"&gt;Keycastr releases&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Keycastr is used for presentational demos. It&amp;rsquo;s free and the source is here in this &lt;a href="https://github.com/nelsonjchen/keycastr"&gt;GitHub repo&lt;/a&gt;. You will need a
modern version of Xcode to compile it.&lt;/p&gt;
&lt;p&gt;The version that is compiled is by &lt;a href="https://github.com/creemama"&gt;creemama&lt;/a&gt;. I only blindingly updated the settings
with Xcode recommendations. This &amp;ldquo;works for me&amp;rdquo; on OS X 10.8.3.&lt;/p&gt;</description></item><item><title>Boot Camp, Windows 7, and USB Installation Gotchas</title><link>https://mindflakes.com/posts/2013/05/13/boot-camp-windows-7-and-usb-installation-gotchas/</link><pubDate>Mon, 13 May 2013 15:23:28 -0700</pubDate><guid>https://mindflakes.com/posts/2013/05/13/boot-camp-windows-7-and-usb-installation-gotchas/</guid><description>&lt;p&gt;A few days ago, I decided to pull the trigger and install Windows on my Retina
MacBook Pro at a LAN Party. It&amp;rsquo;s a perfectly fine machine with a decent
graphics card and CPU. I started Boot Camp Assistant and followed through with
the instructions to install from the USB drive using the ISO of Windows 7 I had
on my Desktop. &lt;em&gt;If you follow Apple&amp;rsquo;s steps to the letter, your installation of
Windows will never proceed.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;If you do follow the steps, you will most certainly get an error of &amp;ldquo;Setup was
unable to create a new system partition or locate an existing system partition.
&amp;quot; when you select the BootCamp partition that you had just formatted in the
Windows installer on your Mac. This can occur on PCs too but basically the
issue is that the USB drive is initialized as another valid bootable disk. If
you were to Google this, you will find
&lt;a href="http://social.technet.microsoft.com/Forums/en-US/w7itproinstall/thread/9e18e169-f77e-4026-b22f-f602e670d55c/"&gt;solutions&lt;/a&gt;
online that involve yanking out the USB drive and reinserting it before
pressing &amp;ldquo;Install Now&amp;rdquo; on the Windows 7 installation screen. This &amp;ldquo;Install Now&amp;rdquo;
screen is a big centered button that prompts your to install now and the arrow
is set inside a blue circle that&amp;rsquo;s like a gem.&lt;/p&gt;
&lt;p&gt;This is where Apple&amp;rsquo;s helpfulness can get in your way. By default, Boot Camp
Assistant copies the Boot Camp support files to your USB drive. It also adds an
&lt;code&gt;Autounattend.xml&lt;/code&gt; file to the root of your drive to automatically install Boot
Camp support drivers and utilities in Windows. With &lt;code&gt;Autounattend.xml&lt;/code&gt; present,
you will not have the opportunity to yank out and reinsert the USB drive before
continuing. Instead, the setup just proceeds as if that button was pressed.
While this is a good file for disc installations, it causes a massive problem
for USB installation which is most likely to be the case for all new Macs from
now on since they do not include disc drives by default. If you try to ask
Apple to &amp;lsquo;fix&amp;rsquo; this, they will just blame Microsoft which admittedly isn&amp;rsquo;t
blame free either.&lt;/p&gt;
&lt;p&gt;To solve this problem, move or delete &lt;code&gt;Autounattend.xml&lt;/code&gt; on the root of the USB
drive and proceed with the normal steps afterwards . After Windows is done
installing and since &lt;code&gt;Autounattend.xml&lt;/code&gt; was nullified, you will have to run the
Boot Camp support installer from the BootCamp folder on the USB drive.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s a shame Apple&amp;rsquo;s instructions just do not work. The fix required would
probably mean removing &lt;code&gt;Autounattend.xml&lt;/code&gt; functionality for USB Drive
installations. In the meantime, this worked for me.&lt;/p&gt;</description></item><item><title>Reddit Link: LEARN VERSION CONTROL if you are in UCSB CS!</title><link>https://mindflakes.com/posts/2013/05/07/reddit-link-learn-version-control-if-you-are-in-ucsb-cs/</link><pubDate>Tue, 07 May 2013 16:19:28 -0700</pubDate><guid>https://mindflakes.com/posts/2013/05/07/reddit-link-learn-version-control-if-you-are-in-ucsb-cs/</guid><description>&lt;p&gt;Here&amp;rsquo;s a comment I wrote on /r/UCSantaBarbara a month ago. Learning Git is
a very valuable tool for any aspiring or lazy programmer.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.reddit.com/r/UCSantaBarbara/comments/1b93tr/ucsb_cs_faq/"&gt;UCSB CS FAQ comment thread&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;At my current place of somewhat employment, the candidates for our internship
offering job did not know how to use Git. I hope my post will have changed
something.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;re new to Git, &lt;a href="https://git-scm.com/"&gt;git-scm.com&lt;/a&gt; is still a good starting point.&lt;/p&gt;</description></item><item><title>And suddenly, nearly a decade later, a blog appears! Again.</title><link>https://mindflakes.com/posts/2013/04/14/and-suddenly-nearly-a-decade-later-a-blog-appears-again./</link><pubDate>Sun, 14 Apr 2013 22:05:53 -0700</pubDate><guid>https://mindflakes.com/posts/2013/04/14/and-suddenly-nearly-a-decade-later-a-blog-appears-again./</guid><description>&lt;p&gt;I&amp;rsquo;m ashamed to say I&amp;rsquo;ve neglected this domain and site for 9 years. In that
time I&amp;rsquo;ve gone through high school and university in that time. In each period,
I&amp;rsquo;ve attempted &lt;a href="http://web.archive.org/web/*/http://mindflakes.com"&gt;putting up blogs, forums, another blog, and other similar
nonsense&lt;/a&gt;. I did not follow
through with whatever resolutions I may have made to keep the site maintained
or write down the latest results from my last screwing around with my projects.
Basically, for the past 9 years, I don&amp;rsquo;t really have much to show for it other
than being able to rattle off some helpful anecdote from experiences I have
never written down here and there.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Remember kids, the only difference between screwing around and Science is
writing it down.&lt;/p&gt;
&lt;p&gt;&amp;ndash; Adam Savage, &lt;a href="http://www.youtube.com/watch?v=BSUMBBFjxrY"&gt;Video&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I thought I was conducting Science for the past few years; in reality, I&amp;rsquo;ve
only been really screwing around.&lt;/p&gt;
&lt;p&gt;Most of my experiments in the past few years have also ended in spectacular
failures. I never wrote about my failures even during the times I had a blog
available. This is where my fails turned into an epic fail. I recently watched
a &lt;a href="http://www.ted.com/talks/ben_goldacre_battling_bad_science.html"&gt;TED talk&lt;/a&gt;
on this and learned that this phenomenon is called research bias. I should not
have withheld what I had learned from failing. My memory of my failures only
fade away until someone mentioned it and I rattle off some anecdote. This
obviously won&amp;rsquo;t scale and does not do much to help me demonstrate any skills
when I can&amp;rsquo;t even get my foot in the door.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m going to change that with the launch of my new site. I&amp;rsquo;ll be honest here,
this is very much a career move. However, it is also a personal one for reasons
I&amp;rsquo;ve outlined above. I can&amp;rsquo;t let those many hours of screwing around go to
waste! Prospective employers and/or clients love to hire people who do
Science, not screwing around. And I think this site will fix that.&lt;/p&gt;
&lt;p&gt;My new site is designed is designed so much as to be a portfolio and as a blog.
My portfolio is small as I have little to show and my blog has a meager amount
of posts. As a foundation though, the site is solid and is totally ready to
showcase more of my skills.&lt;/p&gt;
&lt;h3 id="because-of-hope"&gt;Because of Hope&lt;/h3&gt;
&lt;p&gt;I started the project to fix up my personal site in September 2012.&lt;/p&gt;
&lt;p&gt;At that time I had heard about this static site generator called &lt;code&gt;nanoc&lt;/code&gt;. I had
taken down previous versions of this site since I could not be bothered to
maintain the PHP beast that is called Wordpress. Also, there was little hope of
me hacking on Wordpress to change its default style to something that better
demonstrates my skills. Stock Wordpress themes just do not exhibit confidence
in web development. Also, learning PHP is just something I&amp;rsquo;me not too
interested in doing. The horror stories of PHP may be FUD, but I&amp;rsquo;ve experienced
and witnessed them myself in a past lifetime. &lt;code&gt;nanoc&lt;/code&gt; answers both of these
problems. I can hack Ruby and static HTML pages on a server do not have moving
parts. &lt;code&gt;nanoc&lt;/code&gt; is written in Ruby and generates static HTML pages for
uploading onto a server. Compared to a beast like Wordpress, it is also very
transparent. The nanoc guys can better explain their kind of product (static
site generators) &lt;a href="http://nanoc.ws/about/#why-static"&gt;here&lt;/a&gt;. I did have
a problem in that I had absolutely no experience with &lt;code&gt;nanoc&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;In September 2012, I answered a request for help from an organization
named Because of Hope at the beginning of my last quarter at UCSB. Because of
Hope is an organization that helps children and women in Uganda through
sustainable methods. Here&amp;rsquo;s the email that was sent to the UCSB Computer
Science jobs list:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;My name is Natalie Lemonnier and I graduated from UCSB in 2011. Since
graduating, two of my friends and I have started a nonprofit here in
Goleta called Because of Hope (BOH) that is working to empower women in
Uganda. I am emailing you because our nonprofit is getting ready to
launch a new Student Sponsorship campaign, which will require making
some changes to our website, and I was wondering if you knew of anyone
(student, faculty or otherwise) who might be interested in helping us
make these changes. I am not sure if websites are your area of focus,
but I just wanted to contact you and see if you could point us in the
direction of someone who might be able to help.&lt;/p&gt;
&lt;p&gt;Originally, our friend built our site from scratch. However, he is no
long working with us and none of us have any web background to make the
necessary changes. I believe that some of the fine-tuning will be
relatively easy, while other issues may be more time intensive.&lt;/p&gt;
&lt;p&gt;However, because we don&amp;rsquo;t have web background, we are not really sure
of the exact time needed to complete the desired changes. If you or
anyone else you know would be interested in volunteering to help us, or
would like to learn more about our situation, we would greatly
appreciate it.&lt;/p&gt;
&lt;p&gt;Because we have only been operational for a year, no one in our
organization currently gets paid, so unfortunately it&amp;rsquo;s not in the
budget to pay someone to help us with our website. But we are hoping to
find someone who would be understanding of our situation and wiling to
help us further our mission! I know UCSB is getting ready to start up,
so please feel free to pass on this information to students you think
would be willing and able to get involved. Please let us know if anyone
comes to mind! Thank you for your time, and please feel free to contact
me via phone if that would be at all more convenient for you! (818)
620-8847. Happy Fall Quarter :)&lt;/p&gt;
&lt;p&gt;(If you would like to learn more about our organization or view our
site, please feel free at &lt;a href="http://www.becauseofhope.org"&gt;http://www.becauseofhope.org&lt;/a&gt;.)&lt;/p&gt;
&lt;p&gt;Best of Wishes,&lt;/p&gt;
&lt;p&gt;Natalie Lemonnier&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So, I needed some experience doing a &lt;code&gt;nanoc&lt;/code&gt; site, something nice to put on my
résumé, and something to satisfy and fulfill the &amp;ldquo;help poor children in Uganda&amp;rdquo;
request in the &lt;code&gt;Vim&lt;/code&gt; text editor. Because of Hope needed someone to maintain
their site. With my résumé as sparse as it is, I called up Natalie and offered
to help.&lt;/p&gt;
&lt;p&gt;I met up with them and took a look at the setup. They had a $20/month VPS to
serve one HTML file. The rest of the &amp;ldquo;pages&amp;rdquo; were actually linked tumblr posts.
I told them upfront I wanted to test out some tools on their problem before
I ran with it on my own personal site. In the meantime, I would maintain their
current handcrafted site and check out any technical details such as the domain
name, Google Apps, or the VPS itself.&lt;/p&gt;
&lt;p&gt;I had &lt;code&gt;nanoc&lt;/code&gt; chosen out, but what about the rest? I checked out the
then-current website&amp;rsquo;s code and it had some custom 980px grid system.
I couldn&amp;rsquo;t be bothered to try and understand it. I did try to understand it
enough to add a donations page that they immediately needed for their upcoming
fundraiser.&lt;/p&gt;
&lt;p&gt;On the bright side, all the mockups that Nikki Day of BOH did were in
Photoshop. They were far more ambitious than what the current site&amp;rsquo;s current
implementation. The custom 980px grid system was not up the the task. In
retrospect, it would have been thrown out anyway. I shudder at what beast
I would have had to slay if the original plans had gone through.&lt;/p&gt;
&lt;p&gt;I chose to use &lt;a href="http://foundation.zurb.com/"&gt;Zurb Foundation&lt;/a&gt;. Zurb Foundation
is a front-end framework that is far more flexible than many other frameworks
out there. This was the the kind of Framework that could handle Nikki&amp;rsquo;s
designs. I would also get free functionality such as drop-down menus, pretty
buttons, photo carousel, and first-class support for SCSS, an extension of CSS.
Zurb Foundation&amp;rsquo;s use of SCSS was very instrumental in adapting the design of
Zurb Foundation for Nikki&amp;rsquo;s designs. Compared to its competitor Twitter
Bootstrap, there is far more control over elements on the page, especially the
buttons. Also, I got a mobile site for free! BOH didn&amp;rsquo;t even ask for it but it
came with it!&lt;/p&gt;
&lt;p&gt;Ever since from that time, I&amp;rsquo;ve been working on BOH&amp;rsquo;s &lt;code&gt;nanoc&lt;/code&gt; site. I learned
how to better compose layouts, the Rules DSL of nanoc, and the whole &lt;code&gt;nanoc&lt;/code&gt;
ecosystem. I was also working with it to integrate Zurb Foundation into the
project.&lt;/p&gt;
&lt;p&gt;Remember that $20/month VPS? It has since been replaced with Amazon S3. I also
tossed in Cloudflare in front. BOH can take on a DDOS attack of the most epic
proportions. Why would anyone attack a non-profit is beyond me but the overkill
just tickles my funny bone. And the cost is free to near pennies! This is
something only a static site can do. As a vote of confidence in S3, &lt;a href="http://blog.apps.npr.org/2013/02/14/app-template-redux.html"&gt;NPR used
S3 for transferring data in its election
app&lt;/a&gt;. I&amp;rsquo;m not
saying that BOH will become as big as the presedential election, but it can
definitely handle that much traffic if need be and certianly more than
a $20/month VPS. Honestly, I&amp;rsquo;m just glad I don&amp;rsquo;t have to manage a Linux server
to achieve this goal. It&amp;rsquo;s really upload and forget.&lt;/p&gt;
&lt;p&gt;Also, in doing &lt;code&gt;nanoc&lt;/code&gt;, I now realize how much of a pain in the ass it is to
update the original site. There was so much copy-paste! How do people do all
these busy work?&lt;/p&gt;
&lt;p&gt;I learned a lot from doing the BOH site and I am continuing to work on it in my
spare time. It&amp;rsquo;s source code is versioned in a Git repository so I can
experiment on it all I want. It&amp;rsquo;s also open source in a &lt;a href="https://github.com/becauseofhope/because-of-hope"&gt;GitHub
repository&lt;/a&gt;. If anybody wants
to peruse it and reuse parts of it, they are more than welcome to do so. I plan
to keep it in sync with anything that is a &lt;code&gt;nanoc&lt;/code&gt; best-practice and update it
with new pages.&lt;/p&gt;
&lt;h3 id="mindflakes"&gt;Mindflakes&lt;/h3&gt;
&lt;p&gt;Okay, so I&amp;rsquo;ve helped a non-profit get their site stuff in shape and beyond.&lt;/p&gt;
&lt;p&gt;What about my personal site?&lt;/p&gt;
&lt;p&gt;Ever since I&amp;rsquo;ve started the BOH site project, I&amp;rsquo;ve probably made 3 false starts
in creating mindflakes.com. I wager I wasn&amp;rsquo;t confident enough in my &lt;code&gt;nanoc&lt;/code&gt;
knowledge in the previous starts. I had given up or I did not have enough time
to really sit down and really start work on my site. Also, I was working part
time at a local company in the area at this time. I came back home so exhausted
from looking through piles of Ruby and Python that I really did not want to put
my finger to the keyboard.&lt;/p&gt;
&lt;p&gt;Maybe the fourth time was the charm? I didn&amp;rsquo;t start the mindflakes
project this time. What I did instead was start an &lt;a href="https://github.com/crazysim/nanoc-foundation-blog"&gt;example/bootstrap
project&lt;/a&gt; for a blog that
used Zurb Foundation and &lt;code&gt;nanoc&lt;/code&gt;. I put some of the best-practices I knew into
there and learned some more best practices from various sources around the web.
I&amp;rsquo;m especially proud that the project is completely tied to Zurb Foundation as its
Javascript is sourced from its gem. There were plenty of Bootstrap examples out
there but I believe that Zurb Foundation better fits with the &lt;code&gt;nanoc&lt;/code&gt;
philosophy in letting power come out in the right places when needed.&lt;/p&gt;
&lt;p&gt;By distilling the framework from the content of my site, I was able to work
away from any pressure in having a nice site to present. Just having a good
framework to build upon is much more gratifying.&lt;/p&gt;
&lt;p&gt;Not only that, I now have a free reusable framework that I may be able to reuse
for client projects that don&amp;rsquo;t involve my site. I don&amp;rsquo;t have to extract magic
or best practice out of my site. I can just rebase anything off of the
framework with the way I like it. I plan to contribute anything I think is
relevant while building my own site back to the framework.&lt;/p&gt;
&lt;p&gt;This is my first long blog post since ever. I wrote this to test out this blog.
As of this post, Mindflakes.com is still very much out-of-the-box even though
I just built the box. I will customize it and make it look pretty enough to
really showcase my work over the next few sessions. I&amp;rsquo;m going to have to decide
what to do about images and what to do with the flexibility that Zurb
Foundation offers me.&lt;/p&gt;
&lt;p&gt;As for what to write, I think I have that settled.&lt;/p&gt;</description></item></channel></rss>