Files
nexus/sreweekly/articles/175/08-what-does-debugging-a-program-look-like.html
2026-09-12 17:23:01 +08:00

430 lines
26 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html class="no-js" lang="en">
<head>
<meta charset="utf-8">
<title>What does debugging a program look like?</title>
<meta name="author" content="Julia Evans">
<meta name="HandheldFriendly" content="True">
<meta name="MobileOptimized" content="320">
<meta name="description" content="What does debugging a program look like?">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta property="og:title" content='What does debugging a program look like?'>
<meta property="og:type" content="website" />
<meta property="og:url" content="https://jvns.ca/blog/2019/06/23/a-few-debugging-resources/" />
<meta property="og:site_name" content="Julia Evans" />
<link rel="canonical" href="https://jvns.ca/blog/2019/06/23/a-few-debugging-resources/">
<link href="/favicon.ico" rel="icon">
<link href="/stylesheets/screen.css" rel="preload" type="text/css" as="style">
<link href="/stylesheets/screen.css" media="screen, projection" rel="stylesheet" type="text/css">
<link href="/stylesheets/print.css" media="print" rel="stylesheet" type="text/css">
<link href="/atom.xml" rel="alternate" title="Julia Evans" type="application/atom+xml">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.4/dist/katex.min.css" integrity="sha384-vKruj+a13U8yHIkAyGgK1J3ArTLzrFGBbBc0tDp4ad/EyewESeXE/Iv67Aj8gKZ0" crossorigin="anonymous">
<script defer data-domain="jvns.ca" src="https://plausible.io/js/script.js"></script>
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.4/dist/katex.min.js" integrity="sha384-PwRUT/YqbnEjkZO0zZxNqcxACrXe+j766U2amXcgMg5457rve2Y7I6ZJSm2A0mS4" crossorigin="anonymous"></script>
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.4/dist/contrib/auto-render.min.js" integrity="sha384-+VBxd3r6XgURycqtZ117nYw44OOcIax56Z4dCRWbxyPt0Koah1uHoK0o4+/RRE05" crossorigin="anonymous" onload="renderMathInElement(document.body);"></script>
<script defer type="text/javascript">
window.heap=window.heap||[],heap.load=function(e,t){window.heap.appid=e,window.heap.config=t=t||{};var r=document.createElement("script");r.type="text/javascript",r.async=!0,r.src="https://cdn.heapanalytics.com/js/heap-"+e+".js";var a=document.getElementsByTagName("script")[0];a.parentNode.insertBefore(r,a);for(var n=function(e){return function(){heap.push([e].concat(Array.prototype.slice.call(arguments,0)))}},p=["addEventProperties","addUserProperties","clearEventProperties","identify","resetIdentity","removeEventProperty","setEventProperties","track","unsetEventProperty"],o=0;o<p.length;o++)heap[p[o]]=n(p[o])};
heap.load("2242143965");
</script>
</head>
<body>
<div id="skiptocontent">
<a href="#main">Skip to main content</a>
</div>
<div id="wrap">
<header role="banner">
<hgroup>
<h1><a href="/">Julia Evans</a></h1>
</hgroup>
<ul class="header-links">
<li><a href="/about">About</a></li>
<li><a href="/talks">Talks</a></li>
<li><a href="/projects/">Projects</a></li>
<li><a rel="me" href="https://social.jvns.ca/@b0rk">Mastodon</a></li>
<li><a href="https://bsky.app/profile/b0rk.jvns.ca">Bluesky</a></li>
<li><a href="https://github.com/jvns">Github</a></li>
</ul>
</header>
<nav role="navigation" class="header-nav"><ul class="main-navigation">
<li><a href="/categories/favorite/">Favorites</a></li>
<li><a href="/til/">TIL</a></li>
<li><a href="https://wizardzines.com">Zines</a></li>
<li class="subscription" data-subscription="rss"><a href="/atom.xml" rel="subscribe-rss" title="subscribe via RSS">RSS</a></li>
</ul>
</nav>
<div id="main">
<div id="content">
<div>
<article class="hentry" role="article">
<header>
<h1 class="entry-title">What does debugging a program look like?</h1>
<div class="post-tags">
</div>
<p class="meta sans">
<time class="date" datetime="2019-06-23T18:48:35" pubdate data-updated="true">
June 23, 2019
</time>
</p>
</header>
<main>
<p>I was debugging with a friend who&rsquo;s a relatively new programmer yesterday, and showed them a few
debugging tips. Then I was thinking about how to teach debugging this morning, and <a href="https://twitter.com/b0rk/status/1142825259546140673">mentioned on
Twitter</a> that I&rsquo;d never seen a really good
guide to debugging your code. (there are a ton of really great replies by Anne Ogborn to that tweet
if you are interested in debugging tips)</p>
<p>As usual, I got a lot of helpful answers and now I have a few ideas about how to teach debugging
skills / describe the process of debugging.</p>
<h3 id="a-couple-of-debugging-resources" class="post-heading">
<a href="#a-couple-of-debugging-resources">
a couple of debugging resources
</a>
</h3>
<p>I was hoping for more links to debugging books/guides, but here are the 2 recommendations I
got:</p>
<p><strong>&ldquo;Debugging&rdquo; by David Agans</strong>: Several people recommended the book
<a href="http://debuggingrules.com/">Debugging</a>, which looks like a nice and fairly short book that explains
a debugging strategy. I haven&rsquo;t read it yet (though I ordered it to see if I should be recommending
it) and the rules laid out in the book (&ldquo;understand the system&rdquo;, &ldquo;make it fail&rdquo;, &ldquo;quit thinking and
look&rdquo;, &ldquo;divide and conquer&rdquo;, &ldquo;change one thing at a time&rdquo;, &ldquo;keep an audit trail&rdquo;, &ldquo;check the plug&rdquo;,
&ldquo;get a fresh view&rdquo;, and &ldquo;if you didn&rsquo;t fix it, it ain&rsquo;t fixed&rdquo;) seem extremely resaonable :). He
also has a charming <a href="http://debuggingrules.com/?page_id=40">debugging poster</a>.</p>
<p><strong>&ldquo;How to debug&rdquo; by John Regehr</strong>: <a href="https://blog.regehr.org/archives/199">How to Debug</a> is a very
good blog post based on Regehr&rsquo;s experience teaching a university embedded systems course. Lots of
good advice. He also has a <a href="https://blog.regehr.org/archives/849">blog post reviewing 4 books about debugging</a>, including Agans&rsquo; book.</p>
<h3 id="reproduce-your-bug-but-how-do-you-do-that" class="post-heading">
<a href="#reproduce-your-bug-but-how-do-you-do-that">
reproduce your bug (but how do you do that?)
</a>
</h3>
<p>The rest of this post is going to be an attempt to aggregate different ideas about debugging
people tweeted at me.</p>
<p>Somewhat obviously, everybody agrees that being able to consistently reproduce a bug is important if
you want to figure out what&rsquo;s going on. I have an intuitive sense for how to do this but I&rsquo;m not
sure how to <strong>explain</strong> how to go from &ldquo;I saw this bug twice&rdquo; to &ldquo;I can consistently reproduce this
bug on demand on my laptop&rdquo;, and I wonder whether the techniques you use to do this depend on the
domain (backend web dev, frontend, mobile, games, C++ programs, embedded etc).</p>
<h3 id="reproduce-your-bug-quickly" class="post-heading">
<a href="#reproduce-your-bug-quickly">
reproduce your bug <em>quickly</em>
</a>
</h3>
<p>Everybody also agrees that it&rsquo;s extremely useful be able to reproduce the bug quickly (if it takes
you 3 minutes to check if every change helped, iterating is VERY SLOW).</p>
<p>A few suggested approaches:</p>
<ul>
<li>for something that requires clicking on a bunch of things in a browser to reproduce, recording
what you clicked on with <a href="https://www.seleniumhq.org/">Selenium</a> and getting Selenium to replay
the UI interactions (suggested <a href="https://twitter.com/AnnieTheObscure/status/1142843984642899968">here</a>)</li>
<li>writing a unit test that reproduces the bug (if you can). bonus: you can add this to your test
suite later if it makes sense</li>
<li>writing a script / finding a command line incantation that does it (like <code>curl MY_APP.local/whatever</code>)</li>
</ul>
<h3 id="accept-that-it-s-probably-your-code-s-fault" class="post-heading">
<a href="#accept-that-it-s-probably-your-code-s-fault">
accept that it&rsquo;s probably your code&rsquo;s fault
</a>
</h3>
<p>Sometimes I see a problem and I&rsquo;m like &ldquo;oh, library X has a bug&rdquo;, &ldquo;oh, it&rsquo;s DNS&rdquo;, &ldquo;oh, SOME OTHER
THING THAT IS NOT MY CODE is broken&rdquo;. And sometimes it&rsquo;s not my code! But in general between an
established library and my code that I wrote last month, usually it&rsquo;s my code that I wrote last
month that&rsquo;s the problem :).</p>
<h3 id="start-doing-experiments" class="post-heading">
<a href="#start-doing-experiments">
start doing experiments
</a>
</h3>
<p>@act_gardner gave a <a href="https://twitter.com/act_gardner/status/1142838587437830144">nice, short explanation of what you have to do after you reproduce your
bug</a></p>
<blockquote>
<p>I try to encourage people to first fully understand the bug - What&rsquo;s happening? What do you expect
to happen? When does it happen? When does it not happen? Then apply their mental model of the
system to guess at what could be breaking and come up with experiments.</p>
</blockquote>
<blockquote>
<p>Experiments could be changing or removing code, making API calls from a REPL, trying new inputs,
poking at memory values with a debugger or print statements.</p>
</blockquote>
<p>I think the loop here may be:</p>
<ul>
<li>make guess about one aspect about what might be happening (&ldquo;this variable is set to X where it
should be Y&rdquo;, &ldquo;the server is being sent the wrong request&rdquo;, &ldquo;this code is never running at all&rdquo;)</li>
<li>do experiment to check that guess</li>
<li>repeat until you understand what&rsquo;s going on</li>
</ul>
<h3 id="change-one-thing-at-a-time" class="post-heading">
<a href="#change-one-thing-at-a-time">
change one thing at a time
</a>
</h3>
<p>Everybody definitely agrees that it is important to change one thing a time when doing an
experiment to verify an assumption.</p>
<h3 id="check-your-assumptions" class="post-heading">
<a href="#check-your-assumptions">
check your assumptions
</a>
</h3>
<p>A lot of debugging is realizing that something you were <strong>sure</strong> was true (&ldquo;wait this request is
going to the new server, right, not the old one???&rdquo;) is actually&hellip; not true. I made an attempt to
<a href="https://tweets.jvns.ca/b0rk/status/1142812831420768257">list some common incorrect assumptions</a>. Here
are some examples:</p>
<ul>
<li>this variable is set to X (&ldquo;that filename is definitely right&rdquo;)</li>
<li>that variable&rsquo;s value can&rsquo;t possibly have changed between X and Y</li>
<li>this code was doing the right thing before</li>
<li>this function does X</li>
<li>I&rsquo;m editing the right file</li>
<li>there can&rsquo;t be any typos in that line I wrote it is just 1 line of code</li>
<li>the documentation is correct</li>
<li>the code I&rsquo;m looking at is being executed at some point</li>
<li>these two pieces of code execute sequentially and not in parallel</li>
<li>the code does the same thing when compiled in debug / release mode (or with -O2 and without, or&hellip;)</li>
<li>the compiler is not buggy (though this is last on purpose, the compiler is only very rarely to blame :))</li>
</ul>
<h3 id="weird-methods-to-get-information" class="post-heading">
<a href="#weird-methods-to-get-information">
weird methods to get information
</a>
</h3>
<p>There are a lot of normal ways to do experiments to check your assumptions / guesses about what the
code is doing (print out variable values, use a debugger, etc). Sometimes, though, you&rsquo;re in a more
difficult environment where you can&rsquo;t print things out and don&rsquo;t have access to a debugger (or it&rsquo;s
inconvenient to do those things, maybe because there are too many events). Some ways to cope:</p>
<ul>
<li><a href="https://twitter.com/cocoaphony/status/1142847665690030080">adding sounds on mobile</a>: &ldquo;In the
mobile world, I live on this advice. Xcode can play a sound when you hit a breakpoint (and
continue without stopping). I place them certain places in the code, and listen for buzzing Tink
to indicate tight loops or Morse/Pop pairs to catch unbalanced events&rdquo; (also <a href="https://twitter.com/AnnieTheObscure/status/1142842421954244608">this tweet</a>)</li>
<li>there&rsquo;s a very cool talk about <a href="https://qnoid.com/2013/06/08/Sound-Debugging.html">using XCode to play sound for iOS debugging here</a></li>
<li><a href="https://twitter.com/wombatnation/status/1142887843963867136">adding LEDs</a>: &ldquo;When I did embedded
dev ages ago on grids of transputers, we wired up an LED to an unused pin on each chip. It was
surprisingly effective for diagnosing parallelism issues.&rdquo;</li>
<li><a href="https://twitter.com/irvingreid/status/1142887472441040896">string</a>: &ldquo;My networks prof told me
about a hack he saw at Xerox in the early days of Ethernet: a tap in the coax with an amp and
motor and piece of string. The busier the network was, the faster the string twirled.&rdquo;</li>
<li><a href="http://peep.sourceforge.net/intro.html">peep</a> is a &ldquo;network auralizer&rdquo; that translates what&rsquo;s
happening on your system into sounds. I spent 10 minutes trying to get it to compile and failed so
far but it looks very fun and I want to try it!!</li>
</ul>
<p>The point here is that information is the most important thing and you need to do whatever&rsquo;s
necessary to get information.</p>
<h3 id="write-your-code-so-it-s-easier-to-debug" class="post-heading">
<a href="#write-your-code-so-it-s-easier-to-debug">
write your code so it&rsquo;s easier to debug
</a>
</h3>
<p>Another point a few people brought up is that you can improve your program to make it
easier to debug. tef has a nice post about this: <a href="https://programmingisterrible.com/post/173883533613/code-to-debug">Write code that’s easy to delete, and easy to debug too.</a> here. I thought this
was very true:</p>
<blockquote>
<p>Debuggable code isn’t necessarily clean, and code that’s littered with checks or error handling
rarely makes for pleasant reading.</p>
</blockquote>
<p>I think one interpretation of &ldquo;easy to debug&rdquo; is &ldquo;every single time there&rsquo;s an error, the program
reports to you exactly what happened in an easy to understand way&rdquo;. Whenever my program has a
problem and says something like &ldquo;error: failure to connect to SOME_IP port 443: connection timeout&rdquo;
I&rsquo;m like THANK YOU THAT IS THE KIND OF THING I WANTED TO KNOW and I can check if I need to fix a
firewall thing or if I got the wrong IP for some reason or what.</p>
<p>One simple example of this recently: I was making a request to a server I wrote and the
reponse I got was &ldquo;upstream connect error or disconnect/reset before headers&rdquo;. This is an nginx
error which basically in this case boiled down to &ldquo;your program crashed before it sent anything in
response to the request&rdquo;. Figuring out the cause of the crash was pretty easy, but having better
error handling (returning an error instead of crashing) would have saved me a little time
because instead of having to go check the cause of the crash, I could have just read the error
message and figured out what was going on right away.</p>
<h3 id="error-messages-are-better-than-silently-failing" class="post-heading">
<a href="#error-messages-are-better-than-silently-failing">
error messages are better than silently failing
</a>
</h3>
<p>To get closer to the dream of &ldquo;every single time there&rsquo;s an error, the program reports
to you exactly what happened in an easy to understand way&rdquo; you also need to be disciplined about
immediately returning an error message instead of silently writing incorrect data / passing a
nonsense value to another function which will do WHO KNOWS WHAT with it and cause you a gigantic
headache. This means adding code like this:</p>
<pre><code>if UNEXPECTED_THING:
raise &quot;oh no THING happened&quot;
</code></pre>
<p>This isn&rsquo;t easy to get right (it&rsquo;s not always obvious where you should be raising errors!&quot;) but it
really helps a lot.</p>
<h3 id="failure-print-out-a-stack-of-errors-not-just-one-error" class="post-heading">
<a href="#failure-print-out-a-stack-of-errors-not-just-one-error">
failure: print out a stack of errors, not just one error.
</a>
</h3>
<p>Related to returning helpful errors that make it easy to debug: Rust has a really incredible error
handling library <a href="https://github.com/rust-lang-nursery/failure">called failure</a> which basically lets
you return a chain of errors instead of just one error, so you can print out a stack of errors like:</p>
<pre><code>&quot;error starting server process&quot; caused by
&quot;error initializing logging backend&quot; caused by
&quot;connection failure: timeout connecting to 1.2.3.4 port 1234&quot;.
</code></pre>
<p>This is SO MUCH MORE useful than just <code>connection failure: timeout connecting to 1.2.3.4 port 1234</code>
by itself because it tells you the significance of 1.2.3.4 (it&rsquo;s something to do with the logging
backend!). And I think it&rsquo;s also more useful than <code>connection failure: timeout connecting to 1.2.3.4 port 1234</code>
with a stack trace, because it summarizes at a high level the parts that went wrong instead of
making you read all the lines in the stack trace (some of which might not be relevant!).</p>
<p>tools like this in other languages:</p>
<ul>
<li>Go: the idiom to do this seems to be to just concatenate your stack of errors together as a
big string so you get &ldquo;error: thing one: error: thing two : error: thing three&rdquo; which works okay but
is definitely a lot less structured than <code>failure</code>&rsquo;s system</li>
<li>Java: I hear you can give exceptions causes but haven&rsquo;t used that myself</li>
<li>Python 3: you can use <code>raise ... from</code> which sets the <code>__cause__</code> attribute on the exception and then
your exceptions will be separated by <code>The above exception was the direct cause of the following exception:..</code></li>
</ul>
<p>If you know how to do this in other languages I&rsquo;d be interested to hear!</p>
<h3 id="understand-what-the-error-messages-mean" class="post-heading">
<a href="#understand-what-the-error-messages-mean">
understand what the error messages mean
</a>
</h3>
<p>One sub debugging skill that I take for granted a lot of the time is understanding what error
messages mean! I came across this nice graphic explaining <a href="https://pythonforbiologists.com/29-common-beginner-errors-on-one-page/">common Python errors and what they
mean</a>, which breaks down
things like <code>NameError</code>, <code>IOError</code>, etc.</p>
<p>I think a reason interpreting error messages is hard is that understanding a new error message might
mean learning a new concept &ndash; <code>NameError</code> can mean &ldquo;Your code uses a variable outside the scope
where it&rsquo;s defined&rdquo;, but to really understand that you need to understand what variable scope is! I
ran into this a lot when learning Rust &ndash; the Rust compiler would be like &ldquo;you have a weird lifetime
error&rdquo; and I&rsquo;d like be &ldquo;ugh ok Rust I get it I will go actually learn about how lifetimes work
now!&rdquo;.</p>
<p>And a lot of the time error messages are caused by a problem very different from the text of the
message, like how &ldquo;upstream connect error or disconnect/reset before headers&rdquo; might mean &ldquo;julia,
your server crashed!&rdquo;. The skill of understanding what error messages mean is often not transferable
when you switch to a new area (if I started writing a lot of React or something tomorrow, I would
probably have no idea what any of the error messages meant!). So this definitely isn&rsquo;t just an issue
for beginner programmers.</p>
<h3 id="that-s-all-for-now" class="post-heading">
<a href="#that-s-all-for-now">
that&rsquo;s all for now!
</a>
</h3>
<p>I feel like the big thing I&rsquo;m missing when talking about debugging skills is a stronger
understanding of where people get stuck with debugging &ndash; it&rsquo;s easy to say &ldquo;well, you need to
reproduce the problem, then make a more minimal reproduction, then start coming up with guesses and
verifying them, and improve your mental model of the system, and then figure it out, then fix the
problem and hopefully write a test to make it not come back&rdquo;, but &ndash; where are people actually
getting stuck in practice? What are the hardest parts? I have some sense of what the hardest parts
usually are for me but I&rsquo;m still not sure what the hardest parts usually are for someone newer to
debugging their code.</p>
</main>
<footer>
<style type="text/css">
#mc_embed_signup{background:#fff; clear:left; font:14px Helvetica,Arial,sans-serif; display: inline;}
#mc_embed_signup {
display: inline;
}
#mc_embed_signup input.button {
background: #ff5e00;
display: inline;
color: white;
padding: 6px 12px;
}
</style>
<div class="sharing">
<style>
.form-inline {
display:flex; flex-flow: row wrap; justify-content: center;
}
.form-inline input, .form-inline span {
padding: 10px;
}
.form-inline input {
display:inline;
max-width:30%;
margin: 0 10px 0 0;
background-color: #fff;
border: 1px solid #ddd;
border-radius: 5px;
padding: 10px;
}
button {
background-color: #f50;
box-shadow: none;
border: 0;
border-radius: 5px;
color: white;
padding: 5px 10px;
}
@media (max-width: 800px) {
.form-inline input {
margin: 10px 0;
max-width:100% !important;
}
.form-inline {
flex-direction: column;
align-items: stretch;
}
}
</style>
<div align="center">
<form class="form-inline" action="https://app.convertkit.com/forms/1052396/subscriptions" method="post" data-uid="8884355abb" data-format="inline" data-version="5">
<span> Want a weekly digest of this blog?</span>
<input name="email_address" type="text" placeholder="Email address" />
<button type="submit" data-element="submit">Subscribe</button>
</form>
</div>
</div>
<p class="meta">
<a class="basic-alignment left" href="https://jvns.ca/blog/2019/03/26/what-are-monoidal-categories/" title="Previous Post: Why are monoidal categories interesting?">Why are monoidal categories interesting?</a>
<a class="basic-alignment right" href="https://jvns.ca/blog/brag-documents/" title="Next Post: Get your work recognized: write a brag document">Get your work recognized: write a brag document</a>
</p>
</footer>
</article>
</div>
</div>
</div>
<nav role="navigation" class="footer-nav"> <a href="/">Archives</a>
</nav>
<footer role="contentinfo"><span class="credit">&copy; Julia Evans. </span>
<span>If you like this, you may like <a href="https://web.archive.org/web/20181228051203/http://www.uliaea.ca/">Ulia Ea</a> or, more seriously, this list of <a href="https://jvns.ca/blogroll">blogs I love</a> or some <a href="https://jvns.ca/bookshelf">books I've read</a>. <br>
<p class="rc-scout__text"><i class="rc-scout__logo"></i>
You might also like the <a class="rc-scout__link" href="https://www.recurse.com/scout/click?t=546ea46360584b522270b8c3e5d830f8">Recurse Center</a>, my very favorite programming community <a href="/categories/hackerschool/">(my posts about it)</a></p>
</span>
<style class="rc-scout__style" type="text/css">.rc-scout{display:block;padding:0;border:0;margin:0;}.rc-scout__text{display:block;padding:0;border:0;margin:0;height:100%;font-size:100%;}.rc-scout__logo{display:inline-block;padding:0;border:0;margin:0;width:0.85em;height:0.85em;background:no-repeat center url('data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2012%2015%22%3E%3Crect%20x%3D%220%22%20y%3D%220%22%20width%3D%2212%22%20height%3D%2210%22%20fill%3D%22%23000%22%3E%3C%2Frect%3E%3Crect%20x%3D%221%22%20y%3D%221%22%20width%3D%2210%22%20height%3D%228%22%20fill%3D%22%23fff%22%3E%3C%2Frect%3E%3Crect%20x%3D%222%22%20y%3D%222%22%20width%3D%228%22%20height%3D%226%22%20fill%3D%22%23000%22%3E%3C%2Frect%3E%3Crect%20x%3D%222%22%20y%3D%223%22%20width%3D%221%22%20height%3D%221%22%20fill%3D%22%2361ae24%22%3E%3C%2Frect%3E%3Crect%20x%3D%224%22%20y%3D%223%22%20width%3D%221%22%20height%3D%221%22%20fill%3D%22%2361ae24%22%3E%3C%2Frect%3E%3Crect%20x%3D%226%22%20y%3D%223%22%20width%3D%221%22%20height%3D%221%22%20fill%3D%22%2361ae24%22%3E%3C%2Frect%3E%3Crect%20x%3D%223%22%20y%3D%225%22%20width%3D%222%22%20height%3D%221%22%20fill%3D%22%2361ae24%22%3E%3C%2Frect%3E%3Crect%20x%3D%226%22%20y%3D%225%22%20width%3D%222%22%20height%3D%221%22%20fill%3D%22%2361ae24%22%3E%3C%2Frect%3E%3Crect%20x%3D%224%22%20y%3D%229%22%20width%3D%224%22%20height%3D%223%22%20fill%3D%22%23000%22%3E%3C%2Frect%3E%3Crect%20x%3D%221%22%20y%3D%2211%22%20width%3D%2210%22%20height%3D%224%22%20fill%3D%22%23000%22%3E%3C%2Frect%3E%3Crect%20x%3D%220%22%20y%3D%2212%22%20width%3D%2212%22%20height%3D%223%22%20fill%3D%22%23000%22%3E%3C%2Frect%3E%3Crect%20x%3D%222%22%20y%3D%2213%22%20width%3D%221%22%20height%3D%221%22%20fill%3D%22%23fff%22%3E%3C%2Frect%3E%3Crect%20x%3D%223%22%20y%3D%2212%22%20width%3D%221%22%20height%3D%221%22%20fill%3D%22%23fff%22%3E%3C%2Frect%3E%3Crect%20x%3D%224%22%20y%3D%2213%22%20width%3D%221%22%20height%3D%221%22%20fill%3D%22%23fff%22%3E%3C%2Frect%3E%3Crect%20x%3D%225%22%20y%3D%2212%22%20width%3D%221%22%20height%3D%221%22%20fill%3D%22%23fff%22%3E%3C%2Frect%3E%3Crect%20x%3D%226%22%20y%3D%2213%22%20width%3D%221%22%20height%3D%221%22%20fill%3D%22%23fff%22%3E%3C%2Frect%3E%3Crect%20x%3D%227%22%20y%3D%2212%22%20width%3D%221%22%20height%3D%221%22%20fill%3D%22%23fff%22%3E%3C%2Frect%3E%3Crect%20x%3D%228%22%20y%3D%2213%22%20width%3D%221%22%20height%3D%221%22%20fill%3D%22%23fff%22%3E%3C%2Frect%3E%3Crect%20x%3D%229%22%20y%3D%2212%22%20width%3D%221%22%20height%3D%221%22%20fill%3D%22%23fff%22%3E%3C%2Frect%3E%3C%2Fsvg%3E');}.rc-scout__link:link,.rc-scout__link:visited{color:#61ae24;text-decoration:underline;}.rc-scout__link:hover,.rc-scout__link:active{color:#4e8b1d;}</style>
</footer>
<script type="text/rocketscript">
(function(){
var twitterWidgets = document.createElement('script');
twitterWidgets.type = 'text/javascript';
twitterWidgets.async = true;
twitterWidgets.src = 'http://platform.twitter.com/widgets.js';
document.getElementsByTagName('head')[0].appendChild(twitterWidgets);
})();
</script>
</div>
</body>
</html>