<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-US"><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://briceshatzer.com/blog/feed.xml" rel="self" type="application/atom+xml" /><link href="https://briceshatzer.com/blog/" rel="alternate" type="text/html" hreflang="en-US" /><updated>2026-09-25T03:08:33-05:00</updated><id>https://briceshatzer.com/blog/feed.xml</id><title type="html">BriceShatzer.com/blog</title><subtitle>The professional blog of Brice Shatzer, a Chicago-based Iowan that, until recently, was working on the software that powers some of the internet&apos;s favorite sites. Opinions here are my own.
</subtitle><author><name>Brice Shatzer</name><email>brice.shatzer@gmail.com</email><uri>https://briceshatzer.com</uri></author><entry><title type="html">Think Twice: High-Stakes Change Control at PayPal</title><link href="https://briceshatzer.com/blog/2024-02-22-PayPal-ThinkTwice" rel="alternate" type="text/html" title="Think Twice: High-Stakes Change Control at PayPal" /><published>2024-02-22T11:00:00-06:00</published><updated>2024-02-22T11:00:00-06:00</updated><id>https://briceshatzer.com/blog/PayPal-ThinkTwice</id><content type="html" xml:base="https://briceshatzer.com/blog/2024-02-22-PayPal-ThinkTwice"><![CDATA[<p>PayPal experienced 971 seconds (16:11) of ATB (availability to the business) downtime, leading to over 350,000 failed transactions and $400k in lost revenue. The root cause was determined to be a faulty software change with the extended length of the outage being caused by inadequate rollback planning. In response, they launched a mandatory, recurring training program for software engineers called “Think Twice”. Below are my notes from that program.</p>

<hr />

<h2 id="change-control">Change Control</h2>

<p><strong>Failed changes are the largest contributor to downtown with undocumented changes causing 10x the impact of documented changes.</strong></p>

<p><strong>safe</strong> - doesn’t break anything<br />
<strong>effective</strong> - does what it says its intend to do<br />
<strong>follows policy</strong> - documented, has approvals &amp; isolation procedures</p>

<p>Keys needed for successful change control</p>
<ul>
  <li>Visibility</li>
  <li>Planning &amp; scheduling</li>
  <li>Defined standards that are followed</li>
  <li>Continuous delivery architecture that provides: predictability, scalability, repeatability, transparency</li>
</ul>

<h2 id="change-approver">Change Approver</h2>
<p>This is the person that reviews all of the actual code changes &amp; accompanying document<br />
<strong>They are ultimately on the hook for any issues that occurring during or resulting from the change</strong></p>
<ul>
  <li>Evaluate it</li>
  <li>ID dependencies &amp; risks</li>
  <li>Confirm everyone can make the change and roll it back</li>
  <li>Make sure it will be safe effective and follow policy</li>
</ul>

<h2 id="change-planning--execution">Change Planning &amp; Execution</h2>
<ul>
  <li><strong>Should I be doing this?</strong>
    <ul>
      <li>Know reason, risk, &amp; intended outcome</li>
      <li>Filed a “Change Request”</li>
      <li>I am rested &amp; able</li>
      <li>Know the sequence of events that need to occur</li>
    </ul>
  </li>
  <li><strong>Am I qualified to do this?</strong>
    <ul>
      <li>Do I know how?</li>
      <li>Do I have visibility/access to all the systems required to monitor the process</li>
      <li>Is the dev environment good? Did any issues occur when the changes were made in this environment?</li>
      <li>Are the requisite tech resources available for support?</li>
    </ul>
  </li>
  <li><strong>Can I control my changes?</strong>
    <ul>
      <li>Have plan for making the change</li>
      <li>Documentation on verification &amp; rollback process</li>
      <li>Know the risks</li>
      <li>Know potential issues</li>
    </ul>
  </li>
  <li><strong>Do I have a valid execution, rollback, and validation plan?</strong>
    <ul>
      <li>Know all contingencies</li>
      <li>In contact with external teams that may need to assist (like SRE)</li>
      <li>Have talked to all stakeholders</li>
      <li>Done a walkthrough</li>
      <li>Have written testing &amp; validation plan</li>
      <li>Ensured that any potential rollback would actually roll everything back</li>
    </ul>
  </li>
  <li><strong>Does my plan isolate the changes?</strong><br />
<em>these steps are fairly specific to the infrastructure of PayPal, but the ideas are still valid</em>
    <ul>
      <li>push to a single node &gt; then pool &gt; then availability zone</li>
      <li>let the change “burn-in” and validate site health prior to applying the change to additional zones</li>
    </ul>
  </li>
  <li><strong>Is everything documented and approved?</strong>
    <ul>
      <li>“Change Request” is completely filled out<br />
<em>i.e.: Jira/Trello/etc. thing you’re using to document your work is completed &amp; accurate</em></li>
      <li>Risk level assignment is correct and has been approved by proper level:
        <ul>
          <li>low: manager</li>
          <li>medium: manager + director</li>
          <li>high: manager + director + senior director and/or VP of site ops</li>
        </ul>
      </li>
    </ul>
  </li>
  <li><strong>Is it scheduled to minimize impact?</strong>
    <ul>
      <li>not between 9am - 3pm PT</li>
      <li>communicate w/ partners &amp; stakeholders about SLA around returning availability</li>
    </ul>
  </li>
</ul>

<h2 id="change-validation">Change Validation</h2>
<ul>
  <li>Validation testing is present, valid, &amp; successful</li>
  <li>wait 15 minutes prior to running validation testing</li>
</ul>]]></content><author><name>Brice Shatzer</name><email>brice.shatzer@gmail.com</email><uri>https://briceshatzer.com</uri></author><category term="development" /><category term="testing" /><category term="javascript" /><category term="PayPal" /><category term="CI/CD" /><summary type="html"><![CDATA[PayPal experienced 971 seconds of downtime, leading to over 350,000 failed transactions and $400k in lost revenue. In response, they launched a mandatory, recurring training program for software engineers called Think Twice.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://briceshatzer.com/blog/assets/face.png" /><media:content medium="image" url="https://briceshatzer.com/blog/assets/face.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Basic Video Overview of Webdriver.IO</title><link href="https://briceshatzer.com/blog/2022-03-11-Basic-Video-Overview-of-WebdriverIO" rel="alternate" type="text/html" title="Basic Video Overview of Webdriver.IO" /><published>2022-03-11T11:00:00-06:00</published><updated>2022-03-11T11:00:00-06:00</updated><id>https://briceshatzer.com/blog/Basic-Video-Overview-of-WebdriverIO</id><content type="html" xml:base="https://briceshatzer.com/blog/2022-03-11-Basic-Video-Overview-of-WebdriverIO"><![CDATA[<style>
.videoWrapper {
  position: relative;
  padding-bottom: 56.25%; /* 16:9 */  
  padding-top: 25px;
  height: 0;
}

.videoWrapper iframe {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 601px;
}
</style>

<p>
A basic video overview providing a general walk-through of <a href="https://webdriver.io/" target="_blank" rel="noreferrer">Webdriver.IO</a> and it's implementation in Grainger's Next.js/React Starter Kit. <em>For best viewing experience either <a href="https://support.google.com/youtube/answer/91449?hl=en" target="_blank" rel="noreferrer">select a better video quality</a> or view on YouTube <a href="https://youtu.be/XqEKPNov2JA" target="_blank" rel="noreferrer">directly</a>.</em>
</p>

<div class="videoWrapper">
<iframe width="1024" height="601" src="https://www.youtube.com/embed/XqEKPNov2JA" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe>
</div>]]></content><author><name>Brice Shatzer</name><email>brice.shatzer@gmail.com</email><uri>https://briceshatzer.com</uri></author><category term="development" /><category term="testing" /><category term="javascript" /><category term="Webdriver" /><category term="WebdriverIO" /><category term="e2e" /><category term="Grainger" /><category term="Next.js" /><category term="React" /><summary type="html"><![CDATA[A basic video overview providing a general walk-through of Webdriver.IO and it's implementation in Grainger's Next.js/React Starter Kit.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://briceshatzer.com/blog/assets/face.png" /><media:content medium="image" url="https://briceshatzer.com/blog/assets/face.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Clever Sites For Developers</title><link href="https://briceshatzer.com/blog/2021-02-05-Clever-Sites" rel="alternate" type="text/html" title="Clever Sites For Developers" /><published>2021-02-05T11:00:00-06:00</published><updated>2021-02-05T11:00:00-06:00</updated><id>https://briceshatzer.com/blog/Clever-Sites</id><content type="html" xml:base="https://briceshatzer.com/blog/2021-02-05-Clever-Sites"><![CDATA[<style>
	h2:not(.post-title) {text-align: center;}
	h2:not(.post-title):before,
	h2:not(.post-title):after {
		margin: 0 1rem;
		border:0.75px solid #69B5C3;
		display:inline-block;
		content:' ';
    	vertical-align: middle;
    	width: 20%;
	}
	img[alt="Boxy SVG editor"]{max-width: 720px;}
</style>

<!-- 

Things to update this with: 

video editor - https://opencut.app/
PDF editor - https://www.stirling.com/
CSV viewer - https://csv-viewer-online.github.io/
office suite - https://www.onlyoffice.com/
image compresser - https://squoosh.app/


--->

<p>A small collection of sites/services/resources that I’ve found useful throughout my career in web dev.
There are tools for <a href="#visual--design-things">visual/design</a>, <a href="#programmer--coding-things">coding</a>, <a href="#audiovideo-things">audio/video</a> and <a href="#routing--devops-sort-of-things">DevOps &amp; routing</a>.</p>

<h2 id="visual--design-things">Visual &amp; Design Things</h2>

<h3 id="pixlr-photoshop-for-free-on-the-internet"><a href="https://pixlr.com/e/">Pixlr</a>: Photoshop for free on the internet</h3>
<p>Pixlr is free, runs in the browser, and accomplishes 80% to 90% of the stuff that most people would ever want to do in Photoshop. It’s got layers, masking, transforms, clone stamping…literally all the things. An alternative is <a href="https://www.photopea.com/">Photopea</a>, which provides a lot of the same tools, but also allows you to open native file types like <code class="language-plaintext highlighter-rouge">.psd</code> &amp; <code class="language-plaintext highlighter-rouge">.ai</code>.</p>

<p><img src="/blog/assets/post-files/2021-02-05-Clever-Sites/pixlr.jpg" alt="Pixlr editor" /></p>

<h3 id="boxy-svg-free-online-svg-editor"><a href="https://boxy-svg.com/">Boxy SVG</a>: Free online SVG editor</h3>
<p>Boxy SVG is a free, easy to use, and pretty robust SVG editor. You do have to create an account to export or save anything, but it does allow you to generate alternative file types (png,jpg,etc). It also includes a really neat generator feature that allows you to create valid barcodes &amp; QR codes, jigsaw puzzle templates, parliament charts, or printing marks.</p>

<p><img src="/blog/assets/post-files/2021-02-05-Clever-Sites/boxysvg.svg" alt="Boxy SVG editor" /></p>

<h3 id="and-if-you-plan-on-putting-svgs-on-the-internet-you-need-to-use-omg-svg">…and if you plan on putting SVGs on the internet you need to use <a href="https://jakearchibald.github.io/svgomg/">OMG-SVG</a></h3>
<p>If you look at the code behind SVGs that are created using design tools like Photoshop or Illustrator (or even <a href="#boxy-svg-free-online-svg-editor">Boxy SVG</a>), it’s kind of a mess. Meaningless metadate, repeating styles, unneccesarily specific coordinate values, and more all conspire to bloat a file to multiple times larger than it needs to be.</p>

<p>That’s where OMG-SVG comes in. Created by the always entertaining <a href="https://www.youtube.com/playlist?list=PLNYkxOF6rcIAKIQFsNbV0JDws_G_bnNo9">Jake Archibald</a>, it takes the SVG optimizer tool <a href="https://github.com/jakearchibald/svgomg">SVGO</a>, that would normally run as part of <a href="https://github.com/svg/svgo#other-ways-to-use-svgo">build/deploy process or toolchain</a> and turns it into a web app with a simple user interface. It works really well and is completely <a href="https://github.com/jakearchibald/svgomg">open-source</a>.</p>

<p>It’s worth noting that if you’re trying to <a href="https://www.sanity.io/guides/import-svg-files-in-react#c125367dce7c">include an SVGs directly in JSX</a>, TypeScript doesn’t like you using the the style attribute <a href="https://i.imgur.com/frvYR1v.png" target="_blank" rel="noopener">apparently</a>? OMG-SVG allows you to convert those styles to their appropriate attribute values, making them JSX safe.</p>

<h3 id="easily-make-diagrams-w-excalidraw">Easily Make Diagrams w/ <a href="https://excalidraw.com/">Excalidraw</a></h3>
<p>Excalidraw lets you easily make “white-board” style diagrams that look great. It’s completely free, <a href="https://github.com/excalidraw/excalidraw">open-source</a>, and even has a community of folks making libraries of shapes &amp; objects that you can use as well.</p>

<p><img src="/blog/assets/post-files/2021-02-05-Clever-Sites/excalidraw.jpeg" alt="Excalidraw in action" /></p>

<h3 id="pretty-code-snippet-images-w-carbon">Pretty Code Snippet Images w/ <a href="https://carbon.now.sh/">Carbon</a></h3>
<p>Carbon lets you create great looking code snippet images for use in things like a presentation slide or blog post.
It gives you a ton of syntax highlighting/color scheme options and is a way easier alternative than trying to mess with your editor and the snipping tool.
<img src="/blog/assets/post-files/2021-02-05-Clever-Sites/carbon.png" alt="Carbon code snippet" /></p>

<h3 id="aspect-ratio-calculator"><a href="http://andrew.hedges.name/experiments/aspect_ratio/">Aspect Ratio Calculator</a></h3>
<p>Allows you to calculate the missing value of an image based on its original aspect ratio when resizing it. It’s incredibly rudimentary but has been something I’ve used consistently for nearly a decade.
<img src="/blog/assets/post-files/2021-02-05-Clever-Sites/ARC.png" alt="The Aspect Ratio Calculator" /></p>

<h2 id="programmer--coding-things">Programmer &amp; Coding Things</h2>

<h3 id="macos-setup-guide"><a href="https://sourabhbajaj.com/mac-setup/">MacOS Setup Guide</a></h3>
<p>This has been my go-to guide for setting up a Mac machine for development work for the past 5 years. It covers everything from basic stuff like installing <a href="https://brew.sh/">Homebrew</a> &amp; <a href="https://iterm2.com/">iTerm</a> to more involved topics like Ruby &amp; Node version management with <code class="language-plaintext highlighter-rouge">rvm/nvm</code>. More than anything else it’s a good general checklist to prevent you from running into a road blocks down the road because you forgot to install something basic you needed.
<img src="/blog/assets/post-files/2021-02-05-Clever-Sites/macos-setup.png" alt="MacOS Setup Guide" /></p>

<h3 id="the-book-of-secret-knowledge"><a href="https://github.com/trimstray/the-book-of-secret-knowledge">The Book of Secret Knowledge</a></h3>
<p>This repository is a collection of various materials and tools for developers. It contains inspiring lists, manuals, cheatsheets, blogs, hacks, one-liners, cli/web tools, and more. It’s an open-source project so new items are being added to it regularly.</p>

<p><a href="https://github.com/trimstray/the-book-of-secret-knowledge"><img src="/blog/assets/post-files/2021-02-05-Clever-Sites/the-book-of-secret-knowledge.png" alt="The Book of Secret Knowledge" /></a></p>

<h3 id="regexr"><a href="https://regexr.com/">Regexr</a></h3>
<p>When I was first starting out, I asked one of the other developers I was working with what programing language I should learn. His response, “It doesn’t matter, just get really good at regular expression. They all do that.” Regexr lets you visualize what your expression is matching and capturing while you’re constructing it, in addition to providing a cheatsheet and common patterns.
<img src="/blog/assets/post-files/2021-02-05-Clever-Sites/regexr.png" alt="Regexr.com" /></p>

<h3 id="online-javascript-beautifier---beautifierio">Online JavaScript Beautifier - <a href="https://beautifier.io/">beautifier.io</a></h3>
<p>Basically the “pretty print” <a href="https://developers.google.com/web/tools/chrome-devtools/javascript/pretty-print">button from Chrome Dev Tools</a> attached to a text box. While this functionality is built into most IDEs, I still find myself regularly throwing in a string of minified JSON or HTML into the site.</p>

<p><img src="/blog/assets/post-files/2021-02-05-Clever-Sites/beautifierIO.gif" alt="beautifier.io in action" /></p>

<h3 id="jshint"><a href="https://jshint.com/">JSHint</a></h3>
<p>The linting/hinting that most of use know and love from our favorite IDEs, but in the browser. This is great for when you’re working on a project that has bad/wrong/broken <a href="https://eslint.org/docs/user-guide/configuring/configuration-files#using-configuration-files">eslint config file</a>. It allows you easily toggle through different rule sets &amp; environment assumptions.</p>

<p><img src="/blog/assets/post-files/2021-02-05-Clever-Sites/jshint.gif" alt="JSHint in action" /></p>

<!-- 

May need to add "Dan's Tools" 

### [CSS Font Stack](https://www.cssfontstack.com/)
This site has been around for...
![CSS Fonts - Arial](/blog/assets/post-files/2021-02-05-Clever-Sites/FontStack.png)
-->

<h3 id="browserhacks"><a href="http://browserhacks.com/">BrowserHacks</a></h3>
<p>Y’all remember conditional comments?</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&lt;!--[if IE 6]&gt; Internet Explorer 6 &lt;![endif]--&gt;
&lt;!--[if IE 7]&gt; Internet Explorer 7 &lt;![endif]--&gt;
&lt;!--[if IE 8]&gt; Internet Explorer 8 &lt;![endif]--&gt;
&lt;!--[if IE 9]&gt; Internet Explorer 9 &lt;![endif]--&gt;
</code></pre></div></div>

<p>In <em>“the before times”</em>  there were often instances where we would need target changes or functionality for different or older versions of browsers. This site has an exhaustive list of all those sorts of tricks. Thankfully, I haven’t needed to use this site much in recent years, although I do still run into the occasional issue around detecting and implementing something specifically for safari because <a href="https://threadreaderapp.com/thread/1191026394421026816.html">Apple hates the internet</a>.</p>

<h3 id="microsoft-virtual-machines"><a href="https://developer.microsoft.com/en-us/microsoft-edge/tools/vms/">Microsoft Virtual Machines</a></h3>
<p>If you ever need to test something on a windows machine, Microsoft has made a complete array of virtual machines available for free.
They run on pretty much every platform (VirtualBox, Vagrant, VMware, etc. ) and they go all the way back to IE8 running on Windows 7.</p>

<h2 id="audiovideo-things">Audio/Video Things</h2>

<h3 id="webcam-test"><a href="https://webcamtests.com/">Webcam Test</a></h3>
<p>I use this daily while working from home before every meeting to make sure that things I’d rather not share aren’t inadvertently in frame of the camera.
<img src="/blog/assets/post-files/2021-02-05-Clever-Sites/webcamtest.png" alt="Webcam Test " /></p>

<h3 id="online-audio-editors">Online Audio Editors</h3>
<p><a href="https://audiotrimmer.com/#">AudioTrimmer</a> lets you easily trim &amp; cut files, while <a href="https://29a.ch/timestretch/">TimeStrech Player</a> lets you do interesting stuff like adjust speed/pitch/speed and create loops.</p>

<p><img src="/blog/assets/post-files/2021-02-05-Clever-Sites/timestretch.png" alt="TimeStrech Player" /></p>

<h2 id="routing--devops-sort-of-things">Routing &amp; DevOps sort of things</h2>

<h3 id="httpxipio"><a href="http://xip.io/">http://xip.io/</a></h3>

<p>xip.io is a magic domain name that provides wildcard DNS for any IP address. Say your LAN IP address is 10.0.0.1, using xip.io:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>          10.0.0.1.xip.io   resolves to   10.0.0.1
      www.10.0.0.1.xip.io   resolves to   10.0.0.1
</code></pre></div></div>
<p>Why? This sort of <a href="https://stackoverflow.com/a/37370422/1608016">explains some reasons why</a> you might want to do this.</p>

<h3 id="cors-anywhere"><a href="https://github.com/Rob--W/cors-anywhere">CORS Anywhere</a></h3>
<p>It’s a live endpoint that allows you to proxy a request to a URL which doesn’t have CORS enabled. I’ve used it when debugging an issues on projects that relied on calls to a URL where CORS was enabled, but not necessarily for that particular environment in which I was currently working.</p>

<p>Endpoint - <a href="https://cors-anywhere.herokuapp.com/">https://cors-anywhere.herokuapp.com/</a>
<a href="https://github.com/Rob--W/cors-anywhere/">Github Repo</a>
<a href="https://robwu.nl/cors-anywhere.html">Example Application</a></p>

<h3 id="bundlephobia"><a href="https://bundlephobia.com/">Bundlephobia</a></h3>
<p>Allows you to see the impact of including a dependency in your javascript either by looking up individual packages or by uploading and scanning your <code class="language-plaintext highlighter-rouge">package.json</code> file.</p>

<p><img src="/blog/assets/post-files/2021-02-05-Clever-Sites/bundlephobia.gif" alt="Bundlephobia in action" /></p>]]></content><author><name>Brice Shatzer</name><email>brice.shatzer@gmail.com</email><uri>https://briceshatzer.com</uri></author><category term="development" /><category term="front-end" /><category term="javascript" /><category term="css" /><category term="design" /><summary type="html"><![CDATA[A collection of sites I've found useful over the course of my career.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://briceshatzer.com/blog/assets/face.png" /><media:content medium="image" url="https://briceshatzer.com/blog/assets/face.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Notes from CascadiaJS 2020</title><link href="https://briceshatzer.com/blog/2020-09-02-Notes-from-CascadiaJS-2020" rel="alternate" type="text/html" title="Notes from CascadiaJS 2020" /><published>2020-09-02T12:00:00-05:00</published><updated>2020-09-02T12:00:00-05:00</updated><id>https://briceshatzer.com/blog/Notes-from-CascadiaJS-2020</id><content type="html" xml:base="https://briceshatzer.com/blog/2020-09-02-Notes-from-CascadiaJS-2020"><![CDATA[<style>
    #video-time-stamps-for-every-talk+p,#video-time-stamps-for-every-talk+p+p {
        line-height: 1.75;
        padding-left:1em;
    }
    #video-time-stamps-for-every-talk+p strong,#video-time-stamps-for-every-talk+p+p strong {
        margin-left: -1em;
    } 
</style>

<p>Some of my favorite talks, highlights, and things I found interesting from <a href="https://2020.cascadiajs.com/">CascadiaJS 2020</a>. Additionally, links to all of the talks can be found at the bottom of this post.</p>

<p><strong>Day 1 Highlights</strong></p>

<ul>
  <li>
    <p><a href="https://youtu.be/Zsw637CCejI?t=5252">Modal Windows for Everyone</a> shared some great ideas around implementing modals that I hadn’t really thought about previously like “trapping focus” within the modal, hooking CSS to aria-attributes to force their usage by future maintainers, and wiring scrims in an accessible way. This was probably my favorite talk of the conference.</p>
  </li>
  <li>
    <p><a href="https://youtu.be/Zsw637CCejI?t=9619">I18N | L10N - The Principals for a more Accessible Web</a> talked about internalization &amp; localization, but my big take-away from this talk was the last 5 minutes where he went through the <code class="language-plaintext highlighter-rouge">Intl</code> object which gives you a bunch of <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl">internationalization utility methods</a> like: <br />
<code class="language-plaintext highlighter-rouge">.DateTimeFormat</code> with (dateStyle,timeStyle,formatRange), <br />
<code class="language-plaintext highlighter-rouge">.RelativeTimeFormat</code>,<br />
<code class="language-plaintext highlighter-rouge">.ListFormat</code>,<br />
&amp; <code class="language-plaintext highlighter-rouge">.DisplayNames</code><br />
and <code class="language-plaintext highlighter-rouge">Temporal</code> which is in the <a href="https://tc39.es/proposal-temporal/docs/">process of joining the language</a> and lets you do stuff that you historically needed to use libraries like Moment.js/Day.js.</p>
  </li>
  <li>
    <p><a href="https://youtu.be/Zsw637CCejI?t=11263">Understanding Accessibility as a Concept</a> talked about accessibility broadly and shared some tools around testing accessibility that I hadn’t heard of before like <a href="https://wave.webaim.org/">WAVE Web Accessibility Evaluation Tool</a> &amp; the <a href="https://marketplace.visualstudio.com/items?itemName=MaxvanderSchee.web-accessibility">Web Accessibility VS Code Extension</a>.</p>
  </li>
  <li>
    <p><a href="https://youtu.be/Zsw637CCejI?t=17992">Memory Leaks and the Havoc They Wreak</a> gave a general overview of memory leaks in JS and how to start going about debugging them.</p>
  </li>
</ul>

<p><strong>Day 2 Highlights</strong></p>

<ul>
  <li>
    <p><a href="https://youtu.be/YMJ3pAX_0_U?t=5409">The Zen of Git</a> walks through what is happening under the hood when you use git and what the various commands are doing behind the scenes.</p>
  </li>
  <li>
    <p><a href="https://youtu.be/YMJ3pAX_0_U?t=6943">Musical Creativity in the Browser</a> was a really neat talk about connecting instruments to the internet using the <a href="https://www.w3.org/TR/webmidi/">Web Midi API</a></p>
  </li>
  <li>
    <p><a href="https://youtu.be/YMJ3pAX_0_U?t=9549">Complex Geometry in HTML!</a> - The talk itself was fairly in the weeds, but the demos were really really cool.<br />
  ・3D game written entirely in vanilla JS, HTML &amp; CSS ( <a href="https://pantel.is/projects/css3d/">play it</a> | <a href="https://github.com/pkalogiros/css3d-game">github</a> )<br />
  ・a really cool <a href="https://codepen.io/pantelisk/pen/QWyzjBm">Mario Cart demo</a></p>
  </li>
</ul>

<hr />

<h2 id="video-time-stamps-for-every-talk">Video time stamps for every talk</h2>

<p><strong>Day 1</strong> - <a href="https://youtu.be/Zsw637CCejI">Video</a><br />
<a href="https://youtu.be/Zsw637CCejI?t=3031">Opening Message About Racial Justice</a> - Claudius Mbemba<br />
<a href="https://youtu.be/Zsw637CCejI?t=3287">Mo’Problems, Mo’Nads</a> - Kyle “Getify” Simpson <br />
<a href="https://youtu.be/Zsw637CCejI?t=5252">Modal Windows for Everyone</a> - James Steinbach<br />
<a href="https://youtu.be/Zsw637CCejI?t=8273">The Past, Present, and Future of Favicons</a> - Tiger Oakes<br />
<a href="https://youtu.be/Zsw637CCejI?t=9619">I18N | L10N - The Principals for a more Accessible Web</a> - Romulo Cintra<br />
<a href="https://youtu.be/Zsw637CCejI?t=11263">Understanding Accessibility as a Concept</a> - Jemima Abu<br />
<a href="https://youtu.be/Zsw637CCejI?t=17992">Memory Leaks and the Havoc They Wreak</a> - Will Klein<br />
<a href="https://youtu.be/Zsw637CCejI?t=19123">Saving Data to the DWeb: A Primer and a Practical Perspective</a> - Kelsey Breseman<br />
<a href="https://youtu.be/Zsw637CCejI?t=20659">Human Centered On-Call Practices</a> - Najla Elmachtoub<br />
<a href="https://youtu.be/Zsw637CCejI?t=24205">Developing Your Community Brand</a> - Joel Hooks<br />
<a href="https://youtu.be/Zsw637CCejI?t=25764">The ACID/BASE Conundrum</a> - Sangeetha KP<br />
<a href="https://youtu.be/Zsw637CCejI?t=26519">The Operating System of You</a> - Shawn Wang</p>

<p><strong>Day 2</strong> - <a href="https://youtu.be/YMJ3pAX_0_U">Video</a> <br />
<a href="https://youtu.be/YMJ3pAX_0_U?t=3750">How I learned to Stop Worrying and Let the Robot Publish to NPM</a> - Evan Tahler<br />
<a href="https://youtu.be/YMJ3pAX_0_U?t=5409">The Zen of Git</a> - Tianyu Pu<br />
<a href="https://youtu.be/YMJ3pAX_0_U?t=6943">Musical Creativity in the Browser</a> - Scott Ammon<br />
<a href="https://youtu.be/YMJ3pAX_0_U?t=9549">Complex Geometry in HTML! A story of Constrained Creativity</a> - Pantelis Kalogiros<br />
<a href="https://youtu.be/YMJ3pAX_0_U?t=11224">SVG, Canvas, and WebGL: The Power, The Beauty, &amp; The Cost</a> - Amber Hoak<br />
<a href="https://youtu.be/YMJ3pAX_0_U?t=12757">Building Better Communities with Mental Health Support</a> - Rahat Chowdhury<br />
<a href="https://youtu.be/YMJ3pAX_0_U?t=19936">You Might Not Need a Build Step</a> - Kristofer Joseph<br />
<a href="https://youtu.be/YMJ3pAX_0_U?t=21392">My Assistant Misty</a> - April Speight<br />
<a href="https://youtu.be/YMJ3pAX_0_U?t=23079">Relax, it’s IoTea Time!</a> - Myriam E Walden-Duarte<br />
<a href="https://youtu.be/YMJ3pAX_0_U?t=26051">How I Graduated from React to Vanilla JavaScript</a> - Dan McKeon<br />
<a href="https://youtu.be/YMJ3pAX_0_U?t=27338">Oh Sweet, Gif</a> - Rachelle Rathbone<br />
<a href="https://youtu.be/YMJ3pAX_0_U?t=28278">Snowpack, Webpack and the Third Age of JavaScript</a> - Fred K Schott</p>

<!-- 

CascadiaJS 

[Day 1 Stream Video](https://youtu.be/Zsw637CCejI) | [Day 2 Stream Video](https://youtu.be/YMJ3pAX_0_U) 

https://youtu.be/Zsw637CCejI?t=24203

-->]]></content><author><name>Brice Shatzer</name><email>brice.shatzer@gmail.com</email><uri>https://briceshatzer.com</uri></author><category term="development" /><category term="CascadiaJS" /><category term="javascript" /><category term="conference" /><summary type="html"><![CDATA[Some of my favorite talks, highlights, and things I found interesting from CascadiaJS 2020, along with a collection of links to all of the talks that took place.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://briceshatzer.com/blog/assets/face.png" /><media:content medium="image" url="https://briceshatzer.com/blog/assets/face.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Kinja Custom Header Case Study</title><link href="https://briceshatzer.com/blog/2020-03-20-Kinja-Custom-Header-Case-Study" rel="alternate" type="text/html" title="Kinja Custom Header Case Study" /><published>2020-03-20T12:00:00-05:00</published><updated>2020-03-20T12:00:00-05:00</updated><id>https://briceshatzer.com/blog/Kinja-Custom-Header-Case-Study</id><content type="html" xml:base="https://briceshatzer.com/blog/2020-03-20-Kinja-Custom-Header-Case-Study"><![CDATA[<picture style="text-align: center; display: block;">
    <img src="/blog/assets/post-files/2020-03-20-Kinja-Custom-Header-Case-Study/custom-header.gif" alt="Animated demo of the custom header in use"  />
</picture>
<p>
    "All of the sites look the same", had been a consistent refrain that the product team has heard from both the editorial staff and readers throughout the life of Kinja, and only intensified when the brands of Onion, Inc. <a href="https://product.kinja.com/the-onion-is-now-publishing-on-kinja-1819619421" rel="noreferrer">migrated on to the platform</a>.
</p>
<p>
    With that in mind, we set about creating a new way for the different sites to be able to express their own unique and creative brand identities without having to rely on time from the product team. The ability to completely customize headers on any different category, story type, vertical (sub-site) page is available from within Kinja's internal management UI, <a href="https://changelog.kinja.com/added-ability-to-customize-curation-module-1840391541" rel="noreferrer">which all site editors</a> have access to.  
</p>
<p>
    Some great examples of the editorial staff taking full advantage of the project can be found on the Gizmodo sub-sites like <a href="https://paleofuture.gizmodo.com/" rel="noreferrer">Paleofuture</a>, <a href="https://io9.gizmodo.com/" rel="noreferrer">io9</a>, & <a href="https://earther.gizmodo.com/" rel="noreferrer">Earther</a>; and the various sections of The A.V. Club:  <a href="https://film.avclub.com/" rel="noreferrer">Film</a>, <a href="https://tv.avclub.com/" rel="noreferrer">T.V.</a>, <a href="https://music.avclub.com/" rel="noreferrer">Music</a>, <a href="https://games.avclub.com/" rel="noreferrer">Games</a>, & <a href="https://aux.avclub.com/" rel="noreferrer">AUX</a>.
</p>
<p> 
    I was singularly responsible for defining, overseeing, and implementing all the technical aspects of this product including:
</p>
  <ul style="margin-top:-1em">
    <li>
        Designing an iterative and incremental <a href="https://gist.github.com/BriceShatzer/bdd91a7d423d23b0f349b33ac34f9184#file-custom-header-plan-md" rel="noreferrer">development plan</a> for the project
    </li>
    <li>Defining the API endpoint <a href="https://gist.github.com/BriceShatzer/bdd91a7d423d23b0f349b33ac34f9184#file-schema-json" rel="noreferrer">schema</a></li>
    <li>
        Creating <a href="https://docs.google.com/presentation/d/1Qt3uQsgsR0_9ZD0iyPL5mFcu_VGqp7AbJoq5b51x69k/edit?usp=sharing" rel="noreferrer">robust documentation</a> for use by staff across all parts of the business
    </li>
</ul>
<br />

<p style="text-align:center;display:block;"> Feel free to <a href="https://github.com/BriceShatzer/kinja-custom-header-files" rel="noreferrer">explore the code</a>, or play around with it in <a href="https://gawkermedia.github.io/kinja-components/?path=/story/4-components-custom-header--custom-header">StoryBook</a> <br />
    <a href="https://gawkermedia.github.io/kinja-components/?path=/story/4-components-custom-header--custom-header">
        <img src="/blog/assets/post-files/2020-03-20-Kinja-Custom-Header-Case-Study/StoryBook.png" alt="Interactive version available via Storybook" /> 
    </a>
</p>]]></content><author><name>Brice Shatzer</name><email>brice.shatzer@gmail.com</email><uri>https://briceshatzer.com</uri></author><category term="portfolio" /><category term="Kinja" /><category term="feature" /><summary type="html"><![CDATA[The process creating a product feature that helps brands differentiate their unique identity and voice across a shared publishing platform.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://briceshatzer.com/blog/assets/face.png" /><media:content medium="image" url="https://briceshatzer.com/blog/assets/face.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Look Ma, I’m on the Internet!</title><link href="https://briceshatzer.com/blog/2020-02-03-Look-Ma-I'm-on-the-Internet" rel="alternate" type="text/html" title="Look Ma, I’m on the Internet!" /><published>2020-02-03T11:00:00-06:00</published><updated>2020-02-03T11:00:00-06:00</updated><id>https://briceshatzer.com/blog/Look-Ma-I&apos;m-on-the-Internet</id><content type="html" xml:base="https://briceshatzer.com/blog/2020-02-03-Look-Ma-I&apos;m-on-the-Internet"><![CDATA[<style>
  .story {
    display: flex;
    justify-content: center;
    flex-direction: column;
    padding: 1rem 0 2rem;
  }
  .story img,
  .story iframe {
    align-self: center;
    width: 100%;
    max-width: 720px;
  }
  .story a {
    text-align: center;
  }
  .story p {
    text-indent: 2rem;
    margin-top: 0;
    margin-bottom: 0;
  }
  li {padding-bottom:0.25em;}
  li.title {
    list-style: none;
    text-indent: -1em;

  }
</style>

<div class="story">
  <h2 class="size-h3">
    <a href="https://www.theonion.com/c/the-topical" target="_blank" rel="noopener">The Topical</a>&nbsp; - &nbsp;<i>a daily podcast from The Onion and Onion Public Radio</i>
  </h2>

  <ul>
    <li class="title">I've been the voice of:</li>
    <li>Bill Wright, CEO of Wright's Logging & Tree Services and Member of The American Loggers Council, in the second story of <a href="https://www.theonion.com/walmart-prevents-gun-violence-at-walmart-1841385147" target="_blank" rel="noopener">"Walmart Prevents Gun Violence At Walmart"</a>
    </li>
    <li>Tim Jones, recruiting cordinator for the Boy Scouts of America in the second story of <a href="https://www.theonion.com/a-new-democratic-frontrunner-emerges-in-iowa-1841429219" target="_blank" rel="noopener">"A New Democratic Frontrunner Emerges In Iowa"</a>
    </li>
  </ul>
  
    <iframe src="https://open.spotify.com/embed/playlist/776u0NxMAoxbB6slzUIofh" width="300" height="180" frameborder="0" allowtransparency="true" allow="encrypted-media"></iframe>
  
</div>

<div class="story">
  <h2 class="size-h3">
    <a href="https://theonion.com/well-i-could-do-that-says-art-museum-attendee-viewin-1841159893" target="_blank" rel="noopener">
    ‘Well, I Could Do That’ Says Art Museum Attendee Viewing Security Guard On Lunch Break
  </a> - <i>1/22/2020</i>
  </h2>
  <a href="https://theonion.com/well-i-could-do-that-says-art-museum-attendee-viewin-1841159893" target="_blank" rel="noopener">
    <img src="/blog/assets/post-files/2020-01-24-My-meteoric-rise-to-satirical-fame-continues/museum_article_crop.png" alt="The Onion homepage with an article about a museum guard eating a sandwich."  />
  </a>
</div>

<div class="story">
  <h2 class="size-h3">
    <a href="https://theonion.com/new-employee-confused-by-office-espresso-machine-just-r-1835002974" target="_blank" rel="noopener">
    New Employee Confused By Office Espresso Machine Just Returns To Desk With Mug Of Hot Water
    </a> - <i>5/24/2019</i>
  </h2>
  <a href="https://theonion.com/new-employee-confused-by-office-espresso-machine-just-r-1835002974" target="_blank" rel="noopener">
    <img src="/blog/assets/post-files/2020-01-24-My-meteoric-rise-to-satirical-fame-continues/espresso_article.png" alt="An article about a man confused by an expresso machine."  />
  </a>
</div>

<div class="story">
  <h2 class="size-h3">
    <a href="https://theonion.com/quick-scan-of-room-confirms-area-man-once-again-sweatie-1820294035" target="_blank" rel="noopener">
    Quick Scan Of Room Confirms Area Man Once Again Sweatiest Person Present
    </a> - <i>11/09/2017</i>
  </h2>
  <a href="https://theonion.com/quick-scan-of-room-confirms-area-man-once-again-sweatie-1820294035" target="_blank" rel="noopener">
    <img src="/blog/assets/post-files/2020-01-24-My-meteoric-rise-to-satirical-fame-continues/quick-scan-of-room_article_crop.jpg" alt="The Onion homepage with an article about a sweaty office worker." />
  </a>
</div>

<div class="story">
  <h2 class="size-h3">
    <a href="https://www.facebook.com/watch/?v=10156753381304497" target="_blank" rel="noopener">
    Breaking: 9 Sneezes In A Fucking Row
    </a> - <i>11/09/2017</i>
  </h2>
  <p>Video I'm in for ½ a second.</p>
  <a href="https://www.facebook.com/watch/?v=10156753381304497" target="_blank" rel="noopener">
    <img src="/blog/assets/post-files/2020-01-24-My-meteoric-rise-to-satirical-fame-continues/9-sneezes.gif" alt="A looping image of confused office worker."  />
  </a>
</div>


<!--
### [‘Well, I Could Do That’ Says Art Museum Attendee Viewing Security Guard On Lunch Break](https://local.theonion.com/well-i-could-do-that-says-art-museum-attendee-viewin-1841159893) - *1/22/20*
![museum gaurd](/blog/assets/post-files/2020-01-24-My-meteoric-rise-to-satirical-fame-continues/museum.jpg)


###  [New Employee Confused By Office Espresso Machine Just Returns To Desk With Mug Of Hot Water](https://local.theonion.com/new-employee-confused-by-office-espresso-machine-just-r-1835002974)
*(5/24/19)*
![New Employee](/blog/assets/post-files/2020-01-24-My-meteoric-rise-to-satirical-fame-continues/espresso.jpg)

### [Quick Scan Of Room Confirms Area Man Once Again Sweatiest Person Present](https://local.theonion.com/quick-scan-of-room-confirms-area-man-once-again-sweatie-1820294035)
![Sweatiest Person](/blog/assets/post-files/2020-01-24-My-meteoric-rise-to-satirical-fame-continues/quick-scan.jpg)



### [Breaking: 9 Sneezes In A Fucking Row](https://www.facebook.com/watch/?v=10156753381304497) *(7/10/18)*
[![9 Sneezes loop](/blog/assets/post-files/2020-01-24-My-meteoric-rise-to-satirical-fame-continues/9-sneezes.gif)](https://www.facebook.com/watch/?v=10156753381304497)

-->]]></content><author><name>Brice Shatzer</name><email>brice.shatzer@gmail.com</email><uri>https://briceshatzer.com</uri></author><category term="TheOnion" /><category term="Onion" /><category term="articles" /><category term="satire" /><summary type="html"><![CDATA[Cataloging my meteoric rise to satirical fame and fortune...]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://briceshatzer.com/blog/assets/face.png" /><media:content medium="image" url="https://briceshatzer.com/blog/assets/face.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Check a File’s Size With This Simple Command-line Function</title><link href="https://briceshatzer.com/blog/2019-04-25-curling-for-size" rel="alternate" type="text/html" title="Check a File’s Size With This Simple Command-line Function" /><published>2019-04-25T12:00:00-05:00</published><updated>2019-04-25T12:00:00-05:00</updated><id>https://briceshatzer.com/blog/curling-for-size</id><content type="html" xml:base="https://briceshatzer.com/blog/2019-04-25-curling-for-size"><![CDATA[<p>I recently had a project dealing with image compression/hosting and I wanted a way to check the size of a hosted file that was quicker than digging into the <a href="https://developers.google.com/web/tools/chrome-devtools/network/">network panel</a> or opening <a href="https://www.getpostman.com/">Postman</a> each time.</p>

<p>So, I wrote a simple function that I’ve added to my <a href="https://github.com/BriceShatzer/my-stuff/blob/master/onion-gmg/.zshrc">.bashrc file</a> to do exactly that.</p>

<p>Basically it is just a simple wrapper around <a href="https://curl.haxx.se/">curl</a> that:</p>
<ol>
  <li>Uses <code class="language-plaintext highlighter-rouge">curl -I</code> to fetch the header of a user provided URL</li>
  <li>Checks to make sure the header returned useful information</li>
  <li>Takes that useful header information and formats it in a way that is easy to understand.</li>
</ol>

<h2 class="size-h3" id="code">Code</h2>
<div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">function </span>curl-size <span class="o">{</span>
  <span class="k">if</span> <span class="o">[[</span> <span class="nt">-z</span> <span class="nv">$1</span> <span class="o">]]</span><span class="p">;</span> <span class="k">then
    </span><span class="nb">printf</span> <span class="s1">'%s\n'</span> <span class="s2">"Please provide a URL"</span>
  <span class="k">else
    </span><span class="nb">local </span><span class="nv">response</span><span class="o">=</span><span class="si">$(</span>curl <span class="nt">-sI</span> <span class="s2">"</span><span class="nv">$1</span><span class="s2">"</span> | <span class="nb">tr</span> <span class="nt">-d</span> <span class="s1">'\r'</span> <span class="si">)</span>
    <span class="nb">local </span><span class="nv">statusCode</span><span class="o">=</span><span class="si">$(</span><span class="nb">echo</span> <span class="nv">$response</span> | <span class="nb">awk</span> <span class="s1">'/^HTTP/ {print}'</span><span class="si">)</span>
    <span class="nb">local </span><span class="nv">byteLength</span><span class="o">=</span><span class="si">$(</span><span class="nb">echo</span> <span class="nv">$response</span> | <span class="nb">awk</span> <span class="s1">'/[cC]ontent-[lL]ength/ {print $2}'</span><span class="si">)</span>
    <span class="k">if</span> <span class="o">[[</span> <span class="nt">-z</span> <span class="nv">$response</span> <span class="o">]]</span><span class="p">;</span> <span class="k">then
      </span><span class="nb">printf</span> <span class="s1">'%s\n'</span> <span class="s2">"Please provide a valid URL"</span>
    <span class="k">else
      </span><span class="nb">local </span><span class="nv">disposition</span><span class="o">=</span>UNKNOWN

      <span class="k">if</span> <span class="o">[[</span> <span class="nv">$statusCode</span> <span class="o">=</span> <span class="k">*</span><span class="s2">"200"</span><span class="k">*</span> <span class="o">]]</span><span class="p">;</span> <span class="k">then
        </span><span class="nv">disposition</span><span class="o">=</span>OK
      <span class="k">elif</span> <span class="o">[[</span> <span class="nv">$statusCode</span> <span class="o">=</span> <span class="k">*</span><span class="s2">" 30"</span><span class="k">*</span> <span class="o">]]</span><span class="p">;</span> <span class="k">then
        </span><span class="nv">disposition</span><span class="o">=</span>REDIRECT
        <span class="nb">local </span><span class="nv">newLocation</span><span class="o">=</span><span class="si">$(</span><span class="nb">echo</span> <span class="nv">$response</span> | <span class="nb">awk</span> <span class="s1">'/^[lL]ocation:/ {print $2}'</span><span class="si">)</span>
        print <span class="nv">$statusCode</span>
      <span class="k">else
        </span><span class="nv">disposition</span><span class="o">=</span>OTHER
      <span class="k">fi

      function </span>_doMath <span class="o">{</span>
        <span class="nv">divisor</span><span class="o">=</span><span class="nv">$1</span>
        print <span class="s2">"scale=3;</span><span class="nv">$byteLength</span><span class="s2">/</span><span class="nv">$divisor</span><span class="s2">"</span> | bc <span class="nt">-l</span>
      <span class="o">}</span>

      <span class="k">if</span> <span class="o">[[</span> <span class="nv">$disposition</span> <span class="o">==</span> REDIRECT <span class="o">]]</span><span class="p">;</span> <span class="k">then
        </span><span class="nb">printf</span> <span class="s1">'redirecting to %s\n'</span> <span class="nv">$newLocation</span>
        curl-size <span class="si">$(</span><span class="nb">echo</span> <span class="nv">$newLocation</span><span class="si">)</span>
      <span class="k">elif</span> <span class="o">[[</span> <span class="nv">$disposition</span> <span class="o">==</span> OTHER <span class="o">]]</span><span class="p">;</span> <span class="k">then
         </span>print <span class="nv">$statusCode</span>
      <span class="k">else
        </span><span class="nb">local </span><span class="nv">value</span><span class="o">=</span><span class="s2">""</span>
        <span class="nb">local </span><span class="nv">unit</span><span class="o">=</span><span class="s2">""</span>
        <span class="k">if</span> <span class="o">[[</span> <span class="nt">-z</span> <span class="nv">$byteLength</span> <span class="o">||</span> <span class="o">(</span><span class="nv">$byteLength</span> <span class="o">==</span> <span class="s2">"0"</span><span class="o">)</span> <span class="o">]]</span><span class="p">;</span> <span class="k">then
          </span><span class="nv">unit</span><span class="o">=</span><span class="s2">"Please provide a valid URL"</span>
        <span class="k">elif</span> <span class="o">((</span><span class="nv">$byteLength</span><span class="o">&gt;</span>1000000000<span class="o">))</span><span class="p">;</span><span class="k">then</span> <span class="c">#1*10^9</span>
          <span class="nv">value</span><span class="o">=</span><span class="si">$(</span>_doMath 1000000000<span class="si">)</span>
          <span class="nv">unit</span><span class="o">=</span><span class="s2">"gb"</span>
        <span class="k">elif</span> <span class="o">((</span><span class="nv">$byteLength</span><span class="o">&gt;</span>1000000<span class="o">))</span><span class="p">;</span><span class="k">then</span> <span class="c">#1*10^6</span>
          <span class="nv">value</span><span class="o">=</span><span class="si">$(</span>_doMath 1000000<span class="si">)</span>
          <span class="nv">unit</span><span class="o">=</span><span class="s2">"mb"</span>
        <span class="k">elif</span> <span class="o">((</span><span class="nv">$byteLength</span><span class="o">&gt;</span>1000<span class="o">))</span><span class="p">;</span><span class="k">then
          </span><span class="nv">value</span><span class="o">=</span><span class="si">$(</span>_doMath 1000<span class="si">)</span>
          <span class="nv">unit</span><span class="o">=</span><span class="s2">"kb"</span>
        <span class="k">else
          </span><span class="nv">value</span><span class="o">=</span><span class="s2">"</span><span class="nv">$byteLength</span><span class="s2">"</span>
          <span class="nv">unit</span><span class="o">=</span><span class="s2">"bytes"</span>
        <span class="k">fi
        
        </span><span class="nb">printf</span> <span class="s1">'%s\n'</span> <span class="s2">"</span><span class="si">$(</span><span class="nb">printf</span> <span class="s1">'%s\n'</span> <span class="s2">"</span><span class="nv">$value</span><span class="s2">"</span> | <span class="nb">grep</span> <span class="nt">-o</span> <span class="s1">'.*[1-9]'</span><span class="si">)</span><span class="s2"> </span><span class="nv">$unit</span><span class="s2">"</span>
      <span class="k">fi
    fi
  fi</span>
<span class="o">}</span>
</code></pre></div></div>

<h2 class="size-h3" id="in-use">In Use</h2>
<p>Using it for it’s original purpose…
<img src="/blog/assets/post-files/2019-04-25-curling-for-size/curl-size-image.png" alt="curl-sizing an image" /></p>

<p>It even handles URLs that return non-200 status codes…<br />
<img src="/blog/assets/post-files/2019-04-25-curling-for-size/curl-size-non200.png" alt="curl-size returning a 301" /></p>]]></content><author><name>Brice Shatzer</name><email>brice.shatzer@gmail.com</email><uri>https://briceshatzer.com</uri></author><category term="development" /><category term="bash" /><category term="curl" /><category term="command-line" /><summary type="html"><![CDATA[A simple function to put in your .bashrc file to quickly get the size of files via curl]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://briceshatzer.com/blog/assets/face.png" /><media:content medium="image" url="https://briceshatzer.com/blog/assets/face.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Amazon is Worth $800 Billion &amp;amp; Apparently I Have to Write Their Documentation</title><link href="https://briceshatzer.com/blog/2018-07-09-params-for-amazon-native-shopping-ads" rel="alternate" type="text/html" title="Amazon is Worth $800 Billion &amp;amp; Apparently I Have to Write Their Documentation" /><published>2018-07-09T12:00:00-05:00</published><updated>2018-07-09T12:00:00-05:00</updated><id>https://briceshatzer.com/blog/params-for-amazon-native-shopping-ads</id><content type="html" xml:base="https://briceshatzer.com/blog/2018-07-09-params-for-amazon-native-shopping-ads"><![CDATA[<p><em>This post covers how to define/interact with <a href="https://affiliate-program.amazon.com/help/node/topic/G202102890">Amazon Native Shopping Ads</a> in a programmatic manner and assumes you already have a basic understanding of what they are and how they work.</em></p>

<p><em>Useful links from this post:</em></p>
<ul>
  <li><em><a href="#the-official-parameters-for-native-shopping-ads">“Official Ad Code Parameters”</a></em></li>
  <li><em><a href="https://gist.github.com/BriceShatzer/f2a884a38f023d08024b369479926bd7">All 137 values that onejs is looking for on the global scope</a></em></li>
  <li><em><a href="https://gist.github.com/BriceShatzer/419fed1a315362c2e60a1f128ed02fa1">Amazon’s onejs file unminified</a></em></li>
</ul>

<h2 id="background--the-problem-at-hand">Background &amp; the problem at hand…</h2>

<p><a href="https://affiliate-program.amazon.com/help/node/topic/G202096040">Amazon Native Shopping Ads</a> can be controlled by setting specific values on the global scope prior to loading the <a href="https://z-na.amazon-adsystem.com/widgets/onejs">onejs</a> script which is responsible for creating the ad. 
You can <a href="/blog/assets/post-files/2018-07-09-params-for-amazon-native-shopping-ads/copy-ad-code.png">see this</a> when using the <a href="https://affiliate-program.amazon.com/home/ads/adcode/custom">“Create Custom Ads” tool</a>. If you play around with some of the advance settings, you’ll notice that providing different parameters changes how the ad looks &amp; behaves.</p>

<p>One of these ads had been implemented previously and I was now tasked with getting it to look &amp; behave a particular way. The pattern the widget used of setting certain values prior to loading seemed straight forward enough, so I set to work. First, I tried looking for <a href="https://affiliate-program.amazon.com/resource-center/">documentation</a> around what parameters could actually be set and what they do.
<a href="https://engagedforums.com/discussions/Amazoncom_Associates/Discussions/List_of_available_amzn_assoc__values_for_Native_Ads/am-associhelp/50474.1?redirCnt=2&amp;dbg=6&amp;nav=messages">As far as I can tell</a>, that information doesn’t exist publicly and the info that is available is basically just <a href="https://engagedforums.com/discussions/Amazoncom_Associates/Discussions/List_of_available_amzn_assoc__values_for_Native_Ads/am-associhelp/50474.1?redirCnt=2&amp;dbg=6&amp;nav=messages">forum users throwing things against the wall and seeing what sticks</a>.</p>

<p>My next thought was to <a href="https://gist.github.com/BriceShatzer/419fed1a315362c2e60a1f128ed02fa1">unminifiying the one.js</a> that is actually responsible for constructing the ad and pulling out all of the values that it looks for.</p>

<p>Many of the naming conventions they use rely on a lot of acronyms and/or are generic enough that they don’t give good enough context clues as to what they actually do, but it did provide me with a list of <a href="https://gist.github.com/BriceShatzer/f2a884a38f023d08024b369479926bd7">137 values</a> to start to play around with. This let me start to control some fairly rudimentary thing like:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>amzn_assoc_widget_padding = "12";
amzn_assoc_text_style = "font-size: 17px;font-weight: normal;";
</code></pre></div></div>

<p>Having been working at <a href="/blog/assets/post-files/2018-07-09-params-for-amazon-native-shopping-ads/peak-efficiency.svg">peak efficiency</a> with our counterparts at Amazon up to this point while trying to implement this ad unit, I specifically asked if they had any documentation around those 137 values that they could share. Eventually we received…</p>

<h2 id="the-official-parameters-for-native-shopping-ads"><a href="https://youtu.be/OFr74zI1LBM">The Official Parameters for Native Shopping Ads</a></h2>
<p>The tables below cover all the possible ad code parameters used for Native Shopping Ads.
This information was provided by an Amazon Account Manager &amp; PM that my team was working with to implement these sorts of ads.</p>

<table>
  <thead>
    <tr>
      <th>Parameter Name</th>
      <th style="text-align: left">Sample Value(s)</th>
      <th style="text-align: left">Description</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>amzn_assoc_ad_type</td>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">"smart"</code></td>
      <td style="text-align: left">Required. Ad type of smart is used for NSA.</td>
    </tr>
    <tr>
      <td>amzn_assoc_region</td>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">"US"</code></td>
      <td style="text-align: left">Required. Region - currently only US.</td>
    </tr>
    <tr>
      <td>amzn_assoc_marketplace</td>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">"amazon"</code></td>
      <td style="text-align: left">Required. Currently only amazon.</td>
    </tr>
    <tr>
      <td>amzn_assoc_linkid</td>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">"4e5a800706eeb232402189e87baaff82"</code></td>
      <td style="text-align: left">Required. Link id is unique every time ad code is generated from AC.</td>
    </tr>
    <tr>
      <td>amzn_assoc_placement</td>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">"adunit0"</code></td>
      <td style="text-align: left">Not used currently, but is a required field. This free form text field could be a useful attribute for optimization of ad selection and ranking.”</td>
    </tr>
    <tr>
      <td>amzn_assoc_tracking_id</td>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">refaiz-20"</code></td>
      <td style="text-align: left">Required. Tracking ID of the associate - used for tagging Amazon retail session of the customer with the publisher who referred.”</td>
    </tr>
    <tr>
      <td>amzn_assoc_debug</td>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">true</code></td>
      <td style="text-align: left">Enable debug mode.</td>
    </tr>
    <tr>
      <td>amzn_assoc_aax_src_id</td>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">308</code></td>
      <td style="text-align: left">Force to a particular AAX source id like 308 or 330. Used in production for certain head publishers like CNET, where we might not want certain bidders to bid.</td>
    </tr>
    <tr>
      <td>amzn_assoc_title</td>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">"Shop Related Products</code></td>
      <td style="text-align: left">Title of the ad unit. Note that this might not be available for certain design types (Card format). By default Strip format does not have a title as it is intended for in content placement.</td>
    </tr>
    <tr>
      <td>amzn_assoc_header_style</td>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">"font-size: 18px; font-weight: bold;"</code></td>
      <td style="text-align: left">Customize CSS style of the header (title).</td>
    </tr>
    <tr>
      <td>amzn_assoc_link_style</td>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">"font-size: 15px !important; color: #373737; line-height: 18px;"</code></td>
      <td style="text-align: left">Customize CSS style of the product titles.</td>
    </tr>
    <tr>
      <td>amzn_assoc_link_hover_style</td>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">"text-decoration: underline;"</code></td>
      <td style="text-align: left">Customize CSS hover style of the product titles.</td>
    </tr>
    <tr>
      <td>amzn_assoc_text_style</td>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">"font-size: 17px;font-weight: normal;"</code></td>
      <td style="text-align: left">Customize CSS style of Price.</td>
    </tr>
    <tr>
      <td>amzn_assoc_ad_mode</td>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">"auto"</code><small> - Recommendation Ads </small><br /><code class="language-plaintext highlighter-rouge">"search"</code><small> - Search Ads</small><br /><code class="language-plaintext highlighter-rouge">"manual"</code><small> - Custom Ads</small></td>
      <td style="text-align: left">Required. Specify type of NSA.</td>
    </tr>
    <tr>
      <td>amzn_assoc_asins</td>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">"B075D4SL1T,B01NBTSVDN,B01MT5EV2B"</code></td>
      <td style="text-align: left">Required for Custom Ads to specify ASINs to render.</td>
    </tr>
    <tr>
      <td>amzn_assoc_random_permute</td>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">"true"</code></td>
      <td style="text-align: left">Used for shuffling order or ASINs provided for Custom ads.</td>
    </tr>
    <tr>
      <td>amzn_assoc_render_full_page</td>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">"true"</code></td>
      <td style="text-align: left">Enabling this parameter will cause the ad markup to contain a full HTML page - including the <code class="language-plaintext highlighter-rouge">&lt;html&gt;</code> <code class="language-plaintext highlighter-rouge">&lt;body&gt;</code> tags, meant to be rendered inside an iFrame.</td>
    </tr>
    <tr>
      <td>amzn_assoc_default_search_phrase</td>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">"Harry Potter"</code></td>
      <td style="text-align: left">Required for Search Ads.</td>
    </tr>
    <tr>
      <td>amzn_assoc_default_category</td>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">"All"</code><br /><code class="language-plaintext highlighter-rouge">"Wireless"</code><br /><code class="language-plaintext highlighter-rouge">"Apparel"</code></td>
      <td style="text-align: left">Required for Search Ads to restrict search results to specific category.</td>
    </tr>
    <tr>
      <td>amzn_assoc_fallback_mode</td>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">{"type": "search","value": "Harry Potter"}</code></td>
      <td style="text-align: left">Fallback search keywords used for Auto ads to show in case there are no recommendations for the page.</td>
    </tr>
    <tr>
      <td>amzn_assoc_url</td>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">"http://groomandstyle.com/top-5-best-home-teeth-whitening-kit- reviews/"</code></td>
      <td style="text-align: left">Load recommendations as if the ad is loading from specified URL.</td>
    </tr>
    <tr>
      <td>amzn_assoc_axf_exp_name<br />amzn_assoc_axf_treatment</td>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">amzn_assoc_axf_exp_name="NSA_Borders_4081"</code>;<br /><code class="language-plaintext highlighter-rouge">amzn_assoc_axf_treatment="T1"</code>;</td>
      <td style="text-align: left">These 2 params are used together to force a particular experiment.</td>
    </tr>
    <tr>
      <td>amzn_assoc_design</td>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">""</code><small> - (not specified) Default. We serve Grid format by default, but it could be replaced by card format in special cases (only one recommendation).</small><br /><code class="language-plaintext highlighter-rouge">"standard_grid"</code><small> - Force Grid format.</small><br /><code class="language-plaintext highlighter-rouge">"enhanced_links"</code><small> - Card format.</small><br /><code class="language-plaintext highlighter-rouge">"text_links"</code><small> - List format.</small><br /><code class="language-plaintext highlighter-rouge">"in_content"</code><small> - Strip format.</small></td>
      <td style="text-align: left">Used to specify NSA variant.</td>
    </tr>
  </tbody>
</table>

<h3 id="grid-format">Grid Format</h3>
<p>Parameters specific to the Grid format.</p>

<table>
  <thead>
    <tr>
      <th>Parameter Name</th>
      <th style="text-align: left">Sample Value(s)</th>
      <th style="text-align: left">Description</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>amzn_assoc_width</td>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">"200"</code></td>
      <td style="text-align: left">Restrict the width of the ad unit (in pixels). Number of cards rendered depends on this width. AC restricts this input between 130-600.</td>
    </tr>
    <tr>
      <td>amzn_assoc_height</td>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">"700"</code></td>
      <td style="text-align: left">Height restriction - this value is used only to decide the number of rows displayed and does not control the height of the cards! AC restricts this input between 400-2000.</td>
    </tr>
    <tr>
      <td>amzn_assoc_size</td>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">"autox700"</code></td>
      <td style="text-align: left">A combination of the above parameters. Provided as widthxheight.</td>
    </tr>
    <tr>
      <td>amzn_assoc_search_bar</td>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">"true"</code></td>
      <td style="text-align: left">Enable/disable the search bar.</td>
    </tr>
    <tr>
      <td>amzn_assoc_search_bar_position</td>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">"bottom"</code>, <code class="language-plaintext highlighter-rouge">"top"</code></td>
      <td style="text-align: left">Position of the search bar.</td>
    </tr>
    <tr>
      <td>amzn_assoc_disable_borders</td>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">"true"</code></td>
      <td style="text-align: left">Enable/disable borders around the NSA cards. Default value for this parameter is “false” for Recommendation ads and “true” for Search and Custom ad formats.</td>
    </tr>
    <tr>
      <td>amzn_assoc_attributes</td>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">"false"</code></td>
      <td style="text-align: left">Enable/disable attributes like pricing, prime, star rating etc. If disabled, only title and image of the products will be shown.</td>
    </tr>
    <tr>
      <td>amzn_assoc_carousel</td>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">"true"</code></td>
      <td style="text-align: left">Enable/disable carousel. Enough ASINs should be available for the carousel to show up.</td>
    </tr>
    <tr>
      <td>amzn_assoc_feedback_enable</td>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">"true"</code>, “false”</td>
      <td style="text-align: left">Enable/disable Ad Feedback feature. Is true by default for Recommendation ads.</td>
    </tr>
    <tr>
      <td>amzn_assoc_rows</td>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">"1"</code></td>
      <td style="text-align: left">Number of rows to be shown. Max value possible: 5</td>
    </tr>
    <tr>
      <td>amzn_assoc_max_ads_in_a_row</td>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">"4"</code></td>
      <td style="text-align: left">Max number of cards to be shown per row. Default value is 4. Max value possible: 5</td>
    </tr>
    <tr>
      <td>amzn_assoc_list_price</td>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">"false"</code></td>
      <td style="text-align: left">Show/hide strike out price.</td>
    </tr>
    <tr>
      <td>amzn_assoc_prime</td>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">"false"</code></td>
      <td style="text-align: left">Show/hide Prime logo for Prime eligible ASINs.</td>
    </tr>
    <tr>
      <td>amzn_assoc_prime_position</td>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">"inline_price"</code>, <code class="language-plaintext highlighter-rouge">"bottom"</code></td>
      <td style="text-align: left">Customize position of the prime logo. By default is “inline_price”. “bottom” will push the prime logo to the bottom of the card in a new row.</td>
    </tr>
    <tr>
      <td>amzn_assoc_widget_padding</td>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">"13"</code></td>
      <td style="text-align: left">Padding around the ad unit. Default is 0.</td>
    </tr>
    <tr>
      <td>amzn_assoc_strike_text_style</td>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">"display: inline-block;font- size: 13px;color: #9B9B9B;"</code></td>
      <td style="text-align: left">Customize CSS style of strikeout price.</td>
    </tr>
    <tr>
      <td>amzn_assoc_brand_text_link</td>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">"false"</code></td>
      <td style="text-align: left">By default, “Ads by Amazon” links to homepage of NSA in the affiliate portal. Setting this param to “false” will remove this link.</td>
    </tr>
    <tr>
      <td>amzn_assoc_brand_position</td>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">"top"</code>, <code class="language-plaintext highlighter-rouge">"bottom"</code></td>
      <td style="text-align: left">Position of “Ads by Amazon”. By default is “bottom”.</td>
    </tr>
    <tr>
      <td>amzn_assoc_large_rating</td>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">"true"</code></td>
      <td style="text-align: left">Makes the star ratings larger in size.</td>
    </tr>
    <tr>
      <td>amzn_assoc_rating_position</td>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">"above_price"</code>, <code class="language-plaintext highlighter-rouge">"below_price"</code></td>
      <td style="text-align: left">Position of the star rating. By default, is “below_price”.</td>
    </tr>
    <tr>
      <td>amzn_assoc_max_title_height</td>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">"55"</code></td>
      <td style="text-align: left">Maximum height of the product titles container. Default value is 47.</td>
    </tr>
  </tbody>
</table>

<h3 id="strip-format">Strip Format</h3>
<p>Parameters specific to the Grid format.</p>

<table>
  <thead>
    <tr>
      <th>Parameter Name</th>
      <th style="text-align: left">Sample Value(s)</th>
      <th style="text-align: left">Description</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>amzn_assoc_enable_swipe_on_mobile</td>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">"false"</code></td>
      <td style="text-align: left">Enable/disable carousel swipe mode on mobile. By default is “true”.</td>
    </tr>
  </tbody>
</table>

<h2 id="closing-thoughts">Closing thoughts</h2>

<p>If you’re going provide a technical service that will <em>explicitly</em> generate revenue for you, perhaps it might be a good idea to provide some public facing documentation.</p>

<!-- 
     It's mind blowing that this sort of documentation isn't available anywhere inside Amazon's labyrinth of a resource center. 

You can use the [editor on GitHub](https://github.com/BriceShatzer/blog/edit/master/index.md) to maintain and preview the content for your website in Markdown files.

Whenever you commit to this repository, GitHub Pages will run [Jekyll](https://jekyllrb.com/) to rebuild the pages in your site, from the content in your Markdown files.

### Markdown

Markdown is a lightweight and easy-to-use syntax for styling your writing. It includes conventions for

```markdown
Syntax highlighted code block

# Header 1
## Header 2
### Header 3

- Bulleted
- List

1. Numbered
2. List

**Bold** and _Italic_ and `Code` text

[Link](url) and ![Image](src)
```

For more details see [GitHub Flavored Markdown](https://guides.github.com/features/mastering-markdown/).

### Jekyll Themes

Your Pages site will use the layout and styles from the Jekyll theme you have selected in your [repository settings](https://github.com/BriceShatzer/blog/settings). The name of this theme is saved in the Jekyll `_config.yml` configuration file.

### Support or Contact

Having trouble with Pages? Check out our [documentation](https://help.github.com/categories/github-pages-basics/) or [contact support](https://github.com/contact) and we’ll help you sort it out.
-->]]></content><author><name>Brice Shatzer</name><email>brice.shatzer@gmail.com</email><uri>https://briceshatzer.com</uri></author><category term="development" /><category term="Amazon" /><category term="ads" /><category term="publishing" /><summary type="html"><![CDATA[The documentation that should exist on the parameters that can be set for the Amazon Affiliate Native Shopping Ads.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://briceshatzer.com/blog/assets/face.png" /><media:content medium="image" url="https://briceshatzer.com/blog/assets/face.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">JWPlayer Event Reference</title><link href="https://briceshatzer.com/blog/2018-06-25-JWPlayer-Event-Reference" rel="alternate" type="text/html" title="JWPlayer Event Reference" /><published>2018-06-25T13:51:30-05:00</published><updated>2018-06-25T13:51:30-05:00</updated><id>https://briceshatzer.com/blog/JWPlayer-Event-Reference</id><content type="html" xml:base="https://briceshatzer.com/blog/2018-06-25-JWPlayer-Event-Reference"><![CDATA[<p>A reference to all the events that can potentially fire when using JWPlayer 8.<br />
Full documentation can be found <a href="https://developer.jwplayer.com/jw-player/docs/javascript-api-reference/">here</a></p>

<ul>
  <li>
    <p><code class="language-plaintext highlighter-rouge">all</code></p>
  </li>
  <li><strong><a href="https://developer.jwplayer.com/jw-player/docs/javascript-api-reference/#jwplayeronready">Setup</a></strong>
    <ul>
      <li><code class="language-plaintext highlighter-rouge">ready</code></li>
      <li><code class="language-plaintext highlighter-rouge">setupError</code></li>
      <li><code class="language-plaintext highlighter-rouge">remove</code></li>
    </ul>
  </li>
  <li><strong><a href="https://developer.jwplayer.com/jw-player/docs/javascript-api-reference/#jwplayeronviewable">Viewability</a></strong>
    <ul>
      <li><code class="language-plaintext highlighter-rouge">viewable</code></li>
    </ul>
  </li>
  <li><strong><a href="https://developer.jwplayer.com/jw-player/docs/javascript-api-reference/#jwplayeronplaylist">Playlist</a></strong>
    <ul>
      <li><code class="language-plaintext highlighter-rouge">playlist</code></li>
      <li><code class="language-plaintext highlighter-rouge">playlistItem</code></li>
      <li><code class="language-plaintext highlighter-rouge">playlistComplete</code></li>
    </ul>
  </li>
  <li><strong><a href="https://developer.jwplayer.com/jw-player/docs/javascript-api-reference/#jwplayeronbufferchange">Buffer</a></strong>
    <ul>
      <li><code class="language-plaintext highlighter-rouge">bufferChange</code></li>
    </ul>
  </li>
  <li><strong><a href="https://developer.jwplayer.com/jw-player/docs/javascript-api-reference/#jwplayeronautostartnotallowed">Playback</a></strong>
    <ul>
      <li><code class="language-plaintext highlighter-rouge">autostartNotAllowed</code></li>
      <li><code class="language-plaintext highlighter-rouge">play</code></li>
      <li><code class="language-plaintext highlighter-rouge">pause</code></li>
      <li><code class="language-plaintext highlighter-rouge">playAttemptFailed</code></li>
      <li><code class="language-plaintext highlighter-rouge">buffer</code></li>
      <li><code class="language-plaintext highlighter-rouge">idle</code></li>
      <li><code class="language-plaintext highlighter-rouge">complete</code></li>
      <li><code class="language-plaintext highlighter-rouge">firstFrame</code></li>
      <li><code class="language-plaintext highlighter-rouge">error</code></li>
      <li><code class="language-plaintext highlighter-rouge">playbackRateChanged</code></li>
    </ul>
  </li>
  <li><strong><a href="https://developer.jwplayer.com/jw-player/docs/javascript-api-reference/#jwplayeronseek">Seek</a></strong>
    <ul>
      <li><code class="language-plaintext highlighter-rouge">seek</code></li>
      <li><code class="language-plaintext highlighter-rouge">seeked</code></li>
      <li><code class="language-plaintext highlighter-rouge">time</code></li>
    </ul>
  </li>
  <li><strong><a href="https://developer.jwplayer.com/jw-player/docs/javascript-api-reference/#jwplayeronmute">Volume</a></strong>
    <ul>
      <li><code class="language-plaintext highlighter-rouge">mute</code></li>
      <li><code class="language-plaintext highlighter-rouge">volume</code></li>
    </ul>
  </li>
  <li><strong><a href="https://developer.jwplayer.com/jw-player/docs/javascript-api-reference/#jwplayeronfullscreen">Resize</a></strong>
    <ul>
      <li><code class="language-plaintext highlighter-rouge">fullscreen</code></li>
      <li><code class="language-plaintext highlighter-rouge">resize</code></li>
    </ul>
  </li>
  <li><strong><a href="https://developer.jwplayer.com/jw-player/docs/javascript-api-reference/#jwplayeronlevels">Quality</a></strong>
    <ul>
      <li><code class="language-plaintext highlighter-rouge">levels</code></li>
      <li><code class="language-plaintext highlighter-rouge">levelsChanged</code></li>
      <li><code class="language-plaintext highlighter-rouge">visualQuality</code></li>
    </ul>
  </li>
  <li><strong><a href="https://developer.jwplayer.com/jw-player/docs/javascript-api-reference/#jwplayeronaudiotracks">Audio Tracks</a></strong>
    <ul>
      <li><code class="language-plaintext highlighter-rouge">audioTracks</code></li>
      <li><code class="language-plaintext highlighter-rouge">audioTracksChanged</code></li>
    </ul>
  </li>
  <li><strong><a href="https://developer.jwplayer.com/jw-player/docs/javascript-api-reference/#jwplayeroncaptionslist">Captions</a></strong>
    <ul>
      <li><code class="language-plaintext highlighter-rouge">captionsList</code></li>
      <li><code class="language-plaintext highlighter-rouge">captionsChanged</code></li>
    </ul>
  </li>
  <li><strong><a href="https://developer.jwplayer.com/jw-player/docs/javascript-api-reference/#jwplayeroncontrols">Controls</a></strong>
    <ul>
      <li><code class="language-plaintext highlighter-rouge">controls</code></li>
      <li><code class="language-plaintext highlighter-rouge">displayClick</code></li>
    </ul>
  </li>
  <li><strong><a href="https://developer.jwplayer.com/jw-player/docs/javascript-api-reference/#jwplayeronadblock">Advertising</a></strong>
    <ul>
      <li><code class="language-plaintext highlighter-rouge">adBlock</code></li>
      <li><code class="language-plaintext highlighter-rouge">beforePlay</code></li>
      <li><code class="language-plaintext highlighter-rouge">beforeComplete</code></li>
      <li><code class="language-plaintext highlighter-rouge">adBidRequest</code></li>
      <li><code class="language-plaintext highlighter-rouge">adBidResponse</code></li>
      <li><code class="language-plaintext highlighter-rouge">adClick</code></li>
      <li><code class="language-plaintext highlighter-rouge">adCompanions</code></li>
      <li><code class="language-plaintext highlighter-rouge">adComplete</code></li>
      <li><code class="language-plaintext highlighter-rouge">adSkipped</code></li>
      <li><code class="language-plaintext highlighter-rouge">adError</code></li>
      <li><code class="language-plaintext highlighter-rouge">adRequest</code></li>
      <li><code class="language-plaintext highlighter-rouge">adStarted</code></li>
      <li><code class="language-plaintext highlighter-rouge">adImpression</code></li>
      <li><code class="language-plaintext highlighter-rouge">adPlay</code></li>
      <li><code class="language-plaintext highlighter-rouge">adPause</code></li>
      <li><code class="language-plaintext highlighter-rouge">adTime</code></li>
      <li><code class="language-plaintext highlighter-rouge">adBreakStart</code></li>
      <li><code class="language-plaintext highlighter-rouge">adBreakEnd</code></li>
      <li><code class="language-plaintext highlighter-rouge">adManager</code></li>
      <li><code class="language-plaintext highlighter-rouge">adMeta</code></li>
      <li><code class="language-plaintext highlighter-rouge">adSchedule</code></li>
    </ul>
  </li>
  <li><strong><a href="https://developer.jwplayer.com/jw-player/docs/javascript-api-reference/#metadata">Metadata</a></strong>
    <ul>
      <li><code class="language-plaintext highlighter-rouge">meta</code></li>
    </ul>
  </li>
  <li><strong><a href="https://developer.jwplayer.com/jw-player/docs/javascript-api-reference/#sharingpluginonopen">Sharing</a></strong>
    <ul>
      <li><code class="language-plaintext highlighter-rouge">sharingPlugin.on('open')</code></li>
      <li><code class="language-plaintext highlighter-rouge">sharingPlugin.on('close')</code></li>
      <li><code class="language-plaintext highlighter-rouge">sharingPlugin.on('click')</code></li>
    </ul>
  </li>
  <li><strong><a href="https://developer.jwplayer.com/jw-player/docs/javascript-api-reference/#relatedpluginonopen">Related</a></strong>
    <ul>
      <li><code class="language-plaintext highlighter-rouge">relatedPlugin.on('open')</code></li>
      <li><code class="language-plaintext highlighter-rouge">relatedPlugin.on('close')</code></li>
      <li><code class="language-plaintext highlighter-rouge">relatedPlugin.on('play')</code></li>
    </ul>
  </li>
</ul>]]></content><author><name>Brice Shatzer</name><email>brice.shatzer@gmail.com</email><uri>https://briceshatzer.com</uri></author><category term="development" /><category term="javascript" /><category term="JWPlayer" /><summary type="html"><![CDATA[A reference to all the events that can potentially fire when using JWPlayer 8.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://briceshatzer.com/blog/assets/face.png" /><media:content medium="image" url="https://briceshatzer.com/blog/assets/face.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Dictating Markup Structure via Styling/SASS</title><link href="https://briceshatzer.com/blog/2017-06-13-Dictating-Markup-Structure-via-Styling-SASS" rel="alternate" type="text/html" title="Dictating Markup Structure via Styling/SASS" /><published>2017-06-13T12:00:00-05:00</published><updated>2017-06-13T12:00:00-05:00</updated><id>https://briceshatzer.com/blog/Dictating-Markup-Structure-via-Styling-SASS</id><content type="html" xml:base="https://briceshatzer.com/blog/2017-06-13-Dictating-Markup-Structure-via-Styling-SASS"><![CDATA[<p>This is a response I gave to a <a href="https://stackoverflow.com/questions/44533365/thoughts-on-a-mixin-requiring-a-specific-html-structure/44534118">Stack Overflow question</a> 
that was soliciting opinions about using a sass mixin that requires a particular markup structure and the idea of extending it via arguments to make it a more flexible.</p>

<p>I figured my the topic is interesting enough to share my (perhaps overly verbose) 
answer to the world outside of a Stack Overflow question with 0 up-votes.</p>

<p>Check out some of the other questions I’ve asked &amp; answered over at <a href="https://stackoverflow.com/users/1608016/brice">Stack Overflow</a>.</p>

<hr />

<p><em>TL;DR: <strong>With gratuitous code-commenting</strong>, I think dictating the structure in the styling is fine. Also, having your mixin accept arguments makes it more flexible to use, but exponentially more complex to build/maintain. Really think hard if you’re ok with that tradeoff.</em></p>

<p>The nice thing about working in any sort of environment/language that will ultimately be compiled or minified before it gets to production, is that it allows you to be incredibly verbose with your code comments. At best, they can be an incredibly helpful insights into how stuff works. At worst, they are easily ignorable and get stripped when compiling for production anyways, so there really isn’t a cost. SASS is no exception.</p>

<p>With that preface in mind…<br />
I have done something similar in the past where we were using <a href="http://sass-lang.com/documentation/file.SASS_REFERENCE.html#placeholder_selectors_">placeholder selectors</a> as a base style for a particular family of elements that would each get extended with their own unique styles given the situation. The structure of the markup that those elements needed to use, along with how to write and an extended style was all included within that particular SASS include. It ended up looking something like:</p>

<div class="language-scss highlighter-rouge"><div class="highlight"><pre class="highlight"><code>    <span class="nv">%full-width-story-block</span> <span class="p">{</span>
    <span class="cm">/* Can be included with article.story-block elements which need to occupy their container's full width.
       See "Usage" section after the style definitions for notes &amp; examples. */</span>

      <span class="nl">flex-basis</span><span class="p">:</span> <span class="m">100%</span><span class="p">;</span>
      <span class="nl">display</span><span class="p">:</span> <span class="n">flex</span><span class="p">;</span>

      <span class="k">&amp;</span> <span class="o">&gt;</span> <span class="o">*</span> <span class="p">{</span>
        <span class="k">@include</span> <span class="nd">make-col</span><span class="p">(</span><span class="m">6</span><span class="p">);</span>
        <span class="nl">display</span><span class="p">:</span> <span class="n">flex</span><span class="p">;</span>
        <span class="nl">flex-direction</span><span class="p">:</span> <span class="n">column</span><span class="p">;</span>
        <span class="nl">justify-content</span><span class="p">:</span> <span class="nb">center</span><span class="p">;</span>
        <span class="nl">align-content</span><span class="p">:</span> <span class="nb">center</span><span class="p">;</span>
      <span class="p">}</span>
      <span class="k">&amp;</span> <span class="o">&gt;</span> <span class="nt">div</span> <span class="p">{</span>
        <span class="nl">padding-left</span><span class="p">:</span> <span class="nv">$story-block-spacing</span><span class="o">*</span><span class="m">2</span><span class="p">;</span>
      <span class="p">}</span>
      <span class="k">&amp;</span> <span class="o">&gt;</span> <span class="nt">a</span> <span class="p">{</span> <span class="nl">display</span><span class="p">:</span> <span class="nb">block</span><span class="p">;</span> <span class="p">}</span>
      <span class="k">@include</span> <span class="nd">media-breakpoint-up</span><span class="p">(</span><span class="n">md</span><span class="p">)</span> <span class="p">{</span>
        <span class="nt">h3</span> <span class="p">{</span> <span class="nl">padding-top</span><span class="p">:</span> <span class="m">0</span><span class="p">;</span> <span class="p">}</span>
      <span class="p">}</span>

      <span class="k">@include</span> <span class="nd">media-breakpoint-down</span><span class="p">(</span><span class="n">sm</span><span class="p">)</span> <span class="p">{</span>
        <span class="nl">flex-wrap</span><span class="p">:</span> <span class="n">wrap</span><span class="p">;</span>

        <span class="k">&amp;</span> <span class="o">&gt;</span> <span class="nt">div</span> <span class="p">{</span><span class="nl">padding-left</span><span class="p">:</span><span class="m">0</span><span class="p">;}</span>
        <span class="k">&amp;</span> <span class="o">&gt;</span> <span class="o">*</span> <span class="p">{</span>
          <span class="k">@include</span> <span class="nd">make-col</span><span class="p">(</span><span class="m">12</span><span class="p">);</span>
        <span class="p">}</span>
      <span class="p">}</span>

    <span class="cm">/*  Usage :
        + Ensure that the element is rendered on the page in the following pattern:
          (note the div containing everything but the 1st anchor/image tags.
           This is generally not included when story-block elements are used in "Content Walls")

            &lt;article id="post-4321" class="story-block"&gt;
                &lt;a href="/link/to/post"&gt; &lt;img src="story-pic.jpg" /&gt; &lt;/a&gt;
                &lt;div&gt;
                  &lt;h3&gt; &lt;a href="/link/to/post"&gt;Story Title&lt;/a&gt; &lt;/h3&gt;
                  &lt;p&gt;A short excerpt from the article...&lt;/p&gt;
                  &lt;div class="save-article"&gt;
                    &lt;a class="save-to-pocket" href="/pocket/url"/&gt; &lt;svg&gt;...&lt;/svg&gt;&lt;/a&gt;
                    &lt;a class="save-to-instapaper" href="/instapaper/url"/&gt; &lt;svg&gt;...&lt;/svg&gt;&lt;/a&gt;
                  &lt;/div&gt;
                &lt;/div&gt;
            &lt;/article&gt;

        + Extend the styling to the element container:
              .container-needing-full-width-story-block {
                  .story-block { @extend %full-width-story-block; }
              }
    */</span>
    <span class="p">}</span>
</code></pre></div></div>

<p>The big thing was communicating that the info was there and being consistent in the implementation. There were a couple of different families of components that shared that sort of structure, and they each had their required markup structures and process of extension laid out in the code comments in a similar manner. This made it easy for other dev to come along and start using &amp; extending the structures we had already spent time setting up.</p>

<p>Also, the fact that all of this documentation (for a lack of a better word) existed within the codebase itself means that all this knowledge would be ported around with the project files by default. So in 2 years when a fix or update needs to be applied, as long as we have the code-base, we’re not trying to track down some obscure internal knowledge-base/wiki article or the devs who originally built it.</p>

<p>All of that being said, I would caution you on writing something that would accept arguments. In theory it does allow for more flexibility in the structure of markup, but that flexibility comes at the cost of increased complexity in building and maintaining that mixin. I’ve seen/built things like that which had good intentions, but ultimately ended becoming very “switch case”-ey, with each usage of the mixin elsewhere in the project requiring changes to the mixin itself to handle that particular situation’s idiosyncrasies. Just something to think about…</p>]]></content><author><name>Brice Shatzer</name><email>brice.shatzer@gmail.com</email><uri>https://briceshatzer.com</uri></author><category term="development" /><category term="sass" /><category term="best-practices" /><category term="documentation" /><summary type="html"><![CDATA[A response to a Stack Overflow question about sass mixins that require a particular markup structure and the idea of extending them via arguments to make it a more flexible.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://briceshatzer.com/blog/assets/face.png" /><media:content medium="image" url="https://briceshatzer.com/blog/assets/face.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry></feed>