<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>George MacKerron: code blog &#187; Web design</title>
	<atom:link href="http://blog.mackerron.com/category/web-design/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.mackerron.com</link>
	<description>GIS, software development, and other snippets</description>
	<lastBuildDate>Fri, 03 Feb 2012 18:35:21 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>A depthcam? A webkinect? Introducing a new kind of webcam</title>
		<link>http://blog.mackerron.com/2012/02/03/depthcam-webkinect/</link>
		<comments>http://blog.mackerron.com/2012/02/03/depthcam-webkinect/#comments</comments>
		<pubDate>Fri, 03 Feb 2012 18:21:10 +0000</pubDate>
		<dc:creator>George</dc:creator>
				<category><![CDATA[CoffeeScript]]></category>
		<category><![CDATA[WebGL]]></category>
		<category><![CDATA[WebSockets]]></category>

		<guid isPermaLink="false">http://blog.mackerron.com/?p=1005</guid>
		<description><![CDATA[At CASA we&#8217;ve been looking at using a Kinect or three in our forthcoming ANALOGIES (Analogues of Cities) conference + exhibition. We&#8217;ve been inspired in part by Ruairi Glynn&#8216;s amazing work here at UCL, and Martin has been happily experimenting with the OpenKinect bindings for Processing. Meanwhile, I recently got to grips with the excellent [...]]]></description>
			<content:encoded><![CDATA[<p><strong>At <a href="http://www.bartlett.ucl.ac.uk/casa"><span class="caps">CASA</span></a> we&#8217;ve been looking at using a <a href="http://en.wikipedia.org/wiki/Kinect">Kinect</a> or three in our forthcoming <span class="caps">ANALOGIES </span>(Analogues of Cities) conference + exhibition.</strong> </p>

<p>We&#8217;ve been inspired in part by <a href="http://www.ruairiglynn.co.uk/">Ruairi Glynn</a>&#8216;s amazing work here at <span class="caps">UCL, </span>and <a href="http://martinzaltzaustwick.wordpress.com/">Martin</a> has been happily experimenting with the OpenKinect <a href="http://www.shiffman.net/p5/kinect/">bindings</a> for <a href="http://processing.org/">Processing</a>.</p>

<p>Meanwhile, I <a href="http://mackerron.com/snow-mo/">recently got to grips</a> with the excellent <a href="https://github.com/mrdoob/three.js/">Three.js</a>, which makes WebGL &#8212; aka 3D graphics in modern browsers &#8212; as easy as falling off a log. I&#8217;m also a big fan of making things accessible over the web. And so I began to investigate prospects for working with Kinect data in <span class="caps">HTML5.</span></p>

<p>There&#8217;s <a href="https://github.com/doug/depthjs">DepthJS</a>, an extension for Chrome and Safari, but this requires a locally-connected Kinect and isn&#8217;t very clear on Windows support. There&#8217;s also <a href="http://code.google.com/p/intrael/">Intrael</a>, which serves the depth data as <span class="caps">JPEG </span>files and provides some simple scene recognition output as <span class="caps">JSON.</span> But it&#8217;s closed-source and not terribly flexible.</p>


<h2>The depthcam</h2>

<p>So I decided to roll my own. I give you: <a href="http://depthcam.nodester.com/">the depthcam</a>! </p>

<p><a href="http://depthcam.nodester.com/"><img src="http://blog.mackerron.com/wp-content/uploads/2012/02/Screen-Shot-2012-02-03-at-17.45.02.png" alt="Screenshot" style="border: none; position: relative; left: -55px;" /></a></p>

<p><a href="http://depthcam.nodester.com/">Click here</a> or on the screenshot to connect.</p>

<p>It&#8217;s a live-streaming 3D point-cloud, carried over a binary WebSocket. It responds to movement in the scene by panning the (virtual) camera, and you can also pan and zoom around with the mouse.</p>

<p>Currently you&#8217;ll need <a href="http://www.google.com/chrome">Google Chrome</a> to try it, and the number of people who can tune in at once is limited for reasons of bandwidth. If you can&#8217;t connect, or nothing much is happening, try this <a href="http://www.youtube.com/watch?v=GfRPyh7iubQ">short video on YouTube</a> instead.</p>

<p>It might be the future of video-conferencing. It could also be the start of a new wave of web-based movement-powered games.</p>

<p><span id="more-1005"></span></p>

<h2>How it works</h2>

<p>The code is <a href="https://github.com/jawj/websocket-kinect">on GitHub</a>, and is in three parts:</p>


<ol>
<li><strong>A short Python script</strong> wiring up the <a href="http://openkinect.org/wiki/Python_Wrapper">OpenKinect Python wrapper</a> to the <a href="http://www.tavendo.de/autobahn/">Autobahn WebSockets library</a>. Depending on the arguments it&#8217;s run with, this can either serve a web browser directly, or it can push the depth data up to&#8230;</li>
<li><strong>A simple <a href="http://nodejs.org/">node.js</a> server</strong> that gets us round the <span class="caps">UCL </span>firewall. This accepts depth data pushed from the Python script, and broadcasts it onwards (still using binary WebSockets) to any connected web browsers, which are running&#8230;</li>
<li><strong>The web-based client,</strong> written in <a href="http://coffeescript.org/">CoffeeScript</a>. This connects to the node.js server, receives the depth data, and visualises it as a particle system using Three.js and WebGL.</li>
</ol>



<p>The incoming data from the Kinect is pretty heavy, at 18 MB/s (640 &#215; 480 &#215; 2 bytes per pixel x 30Hz). This is more than we can expect to (or afford to!) push over the Internet. So the Python script does some basic video compression to cut this down by several orders of magnitude, to 30 &#8211; 100 KB/s. It follows this three-step recipe:</p>


<ol>
<li><strong>Reduce the amount of data</strong> by down-sampling and quantizing to 160 &#215; 120 &#215; 1 byte per pixel.</li>
<li><strong>Increase the data&#8217;s compressibility.</strong> First, reduce noise &#8212; which also looks bad &#8212; by making each transmitted depth value (i.e. pixel) the median of the values received in the last three frames. Then express each value as its difference from the previous value, with just an occasional absolute-value <a href="http://en.wikipedia.org/wiki/Keyframe#Video_compression">keyframe</a> to allow new viewers to pick up the stream.</li>
<li><strong>Compress the data</strong> using <a href="http://en.wikipedia.org/wiki/Lempel%E2%80%93Ziv%E2%80%93Markov_chain_algorithm"><span class="caps">LZMA</span></a>, which gets better compression ratios than <span class="caps">GZIP </span>or <span class="caps">BZIP2, </span>and decompression times somewhere between the two.</li>
</ol>



<p>Feel free to <a href="https://github.com/jawj/websocket-kinect">fork the code</a> and do something great with it.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.mackerron.com/2012/02/03/depthcam-webkinect/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Overlapping markers on your Google Map? Meet OverlappingMarkerSpiderfier</title>
		<link>http://blog.mackerron.com/2011/06/22/overlapping-marker-spiderfier/</link>
		<comments>http://blog.mackerron.com/2011/06/22/overlapping-marker-spiderfier/#comments</comments>
		<pubDate>Wed, 22 Jun 2011 20:19:25 +0000</pubDate>
		<dc:creator>George</dc:creator>
				<category><![CDATA[CoffeeScript]]></category>
		<category><![CDATA[GIS]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://blog.mackerron.com/?p=553</guid>
		<description><![CDATA[Ever noticed how, in Google Earth, marker pins that overlap each other spring apart gracefully when you click them, so you can pick the one you meant? And ever noticed how, when using the Google Maps API, the exact same thing doesn&#8217;t happen? This code makes Google Maps API version 3 map markers behave in [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Ever noticed how, in Google Earth, marker pins that overlap each other spring apart gracefully when you click them, so you can pick the one you meant?</strong></p>

<p>And ever noticed how, when using the Google Maps <span class="caps">API, </span>the exact same thing <em>doesn&#8217;t</em> happen?</p>

<p>This code makes Google Maps <span class="caps">API </span>version 3 map markers behave in that Google Earth way. Small numbers of markers (up to 8, configurable) spiderfy into a circle. Larger numbers fan out into a (more space-efficient) spiral. </p>

<p><span id="more-553"></span></p>

<p>Try it! (You can reload this page to re-randomise the marker positions).</p>

<p><iframe src="http://jawj.github.com/OverlappingMarkerSpiderfier/demo.html" style="width: 694px; height: 500px; border: 1px solid #444;"></iframe></p>

<p>The code is <span class="caps">MIT </span>licenced, has no dependencies, and is under 3K compiled (from CoffeeScript), minified and gzipped. I wrote it as part of the data download feature for <a href="http://www.mappiness.org.uk">Mappiness</a>.</p>

<p>It&#8217;s on Github, where you can <a href="https://github.com/jawj/OverlappingMarkerSpiderfier">find out more, download or fork the code</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.mackerron.com/2011/06/22/overlapping-marker-spiderfier/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>Cubic splines in JavaScript (via CoffeeScript)</title>
		<link>http://blog.mackerron.com/2011/01/01/javascript-cubic-splines/</link>
		<comments>http://blog.mackerron.com/2011/01/01/javascript-cubic-splines/#comments</comments>
		<pubDate>Sat, 01 Jan 2011 19:36:07 +0000</pubDate>
		<dc:creator>George</dc:creator>
				<category><![CDATA[Canvas]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Web design]]></category>

		<guid isPermaLink="false">http://blog.mackerron.com/?p=466</guid>
		<description><![CDATA[For a recent study two colleagues needed to elicit a cumulative probability distribution function (CDF) from survey respondents. We decided it would be nice to allow respondents to interact with this CDF after providing some key values, and implemented this in the web browser with &#60;canvas&#62; (falling back on FlashCanvas for IE). In the process, [...]]]></description>
			<content:encoded><![CDATA[<p>For a recent study <a href="http://personal.lse.ac.uk/calel/">two</a> <a href="http://www.voxeu.com/index.php?q=node%2F5453">colleagues</a> needed to elicit a cumulative probability distribution function (CDF) from survey respondents.</p>

<p>We decided it would be nice to allow respondents to interact with this <span class="caps">CDF </span>after providing some key values, and implemented this in the web browser with <code>&lt;canvas&gt;</code> (falling back on <a href="http://flashcanvas.net/">FlashCanvas</a> for IE).</p>

<p>In the process, we implemented three kinds of <a href="http://en.wikipedia.org/wiki/Cubic_spline">cubic spline</a> calculation in the ever-wonderful <a href="http://jashkenas.github.com/coffee-script/">CoffeeScript</a>: natural, clamped and (what we actually needed) monotonic cubic splines.</p>

<p>You can play with some examples below: click-and-drag the round handles, or double-click to enter values directly. Feel free to borrow the code (ideally with attribution) if it&#8217;s of use to you.</p>

<p><span id="more-466"></span></p>

<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/prototype/1.6.0.3/prototype.js"></script><script type="text/javascript" src="/wp-content/uploads/2011/01/cubic_spline_min.js"></script><script type="text/javascript" src="/wp-content/uploads/2011/01/cubic_spline_chart.js"></script><div id="page">
<script type="text/javascript">
  ChartMonotonic = new SplineChart();
  ChartNatural   = new SplineChart();
  ChartClamped   = new SplineChart();
</script><!--[if lt IE 9]>
  <script type="text/javascript" src="http://c0021630.cdn1.cloudfiles.rackspacecloud.com/flashcanvas.js"></script><script type="text/javascript">
  ChartMonotonic.ie = true;
  ChartNatural.ie   = true;   
  ChartClamped.ie   = true;
</script><![endif]-->

<div style="height: 1em;"></div>

<h3>Monotonic</h3>

<div style="height: 1em;"></div>

<div id="chart_monotonic" class="cubic_spline" style="width: 575px"><canvas width="575" height="300"></canvas></div>
<script type="text/javascript">
  ChartMonotonic.init('chart_monotonic', 'X', 'Prob(Something ≤ X)', '#f00', -100, 100, function(xs, ys) {
    return new MonotonicCubicSpline(xs, ys);
  });
  ChartMonotonic.point(new Question().answer(0),  0);
  ChartMonotonic.point(new Question().answer(2),  0.25);
  ChartMonotonic.point(new Question().answer(6),  0.5);
  ChartMonotonic.point(new Question().answer(9.6),  0.75);
  ChartMonotonic.point(new Question().answer(10), 1);
</script>

<div style="height: 2em;"></div>

<h3>Natural</h3>

<div style="height: 1em;"></div>

<div id="chart_natural" class="cubic_spline" style="width: 575px;"><canvas width="575" height="300"></canvas></div>
<script type="text/javascript">
  ChartNatural.init('chart_natural', 'X', 'F(x)', '#0f0', -100, 100, function(xs, ys) {
    return new CubicSpline(xs, ys);
  });
  ChartNatural.point(new Question().answer(0),  0);
  ChartNatural.point(new Question().answer(2),  0.25);
  ChartNatural.point(new Question().answer(6),  0.5);
  ChartNatural.point(new Question().answer(9.6),  0.75);
  ChartNatural.point(new Question().answer(10), 1);
</script>

<div style="height: 2em;"></div>

<h3>Clamped (to a slope of 1 at both ends)</h3>

<div style="height: 1em;"></div>

<div id="chart_clamped" class="cubic_spline" style="width: 575px;"><canvas width="575" height="300"></canvas></div>
<script type="text/javascript">
  ChartClamped.init('chart_clamped', 'X', 'F(x)', '#00f', -100, 100, function(xs, ys) {
    return new CubicSpline(xs, ys, 1, 1);
  });
  ChartClamped.point(new Question().answer(0),  0);
  ChartClamped.point(new Question().answer(2),  0.25);
  ChartClamped.point(new Question().answer(6),  0.5);
  ChartClamped.point(new Question().answer(9.6),  0.75);
  ChartClamped.point(new Question().answer(10), 1);
</script>

<div style="height: 4em;"></div>

</div>

<h3>The spline code</h3>


<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> MonotonicCubicSpline
&nbsp;
<span style="color:#008000; font-style:italic;"># by George MacKerron, mackerron.com</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># adapted from: </span>
<span style="color:#008000; font-style:italic;"># http://sourceforge.net/mailarchive/forum.php?thread_name=</span>
<span style="color:#008000; font-style:italic;"># EC90C5C6-C982-4F49-8D46-A64F270C5247%40gmail.com&amp;forum_name=matplotlib-users</span>
<span style="color:#008000; font-style:italic;"># (easier to read at http://old.nabble.com/%22Piecewise-Cubic-Hermite-Interpolating-</span>
<span style="color:#008000; font-style:italic;"># Polynomial%22-in-python-td25204843.html)</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># with help from:</span>
<span style="color:#008000; font-style:italic;"># F N Fritsch &amp; R E Carlson (1980) 'Monotone Piecewise Cubic Interpolation', </span>
<span style="color:#008000; font-style:italic;">#   SIAM Journal of Numerical Analysis 17(2), 238 - 246.</span>
<span style="color:#008000; font-style:italic;"># http://en.wikipedia.org/wiki/Monotone_cubic_interpolation</span>
<span style="color:#008000; font-style:italic;"># http://en.wikipedia.org/wiki/Cubic_Hermite_spline</span>
&nbsp;
  constructor: <span style="color:#006600; font-weight:bold;">&#40;</span>x, y<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">-&gt;</span>
    n = x.<span style="color:#9900CC;">length</span>
    delta = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span>; m = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span>; alpha = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span>; beta = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span>; dist = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span>; tau = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span>
    <span style="color:#9966CC; font-weight:bold;">for</span> i <span style="color:#9966CC; font-weight:bold;">in</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span>...<span style="color:#006600; font-weight:bold;">&#40;</span>n <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#93;</span>
      delta<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#006600; font-weight:bold;">&#40;</span>y<span style="color:#006600; font-weight:bold;">&#91;</span>i <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">-</span> y<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">/</span> <span style="color:#006600; font-weight:bold;">&#40;</span>x<span style="color:#006600; font-weight:bold;">&#91;</span>i <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">-</span> x<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      m<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#006600; font-weight:bold;">&#40;</span>delta<span style="color:#006600; font-weight:bold;">&#91;</span>i <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">+</span> delta<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">/</span> <span style="color:#006666;">2</span> <span style="color:#9966CC; font-weight:bold;">if</span> i <span style="color:#006600; font-weight:bold;">&gt;</span> <span style="color:#006666;">0</span>
    m<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span> = delta<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span>
    m<span style="color:#006600; font-weight:bold;">&#91;</span>n <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span> = delta<span style="color:#006600; font-weight:bold;">&#91;</span>n <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#006666;">2</span><span style="color:#006600; font-weight:bold;">&#93;</span>
    to_fix = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span>
    <span style="color:#9966CC; font-weight:bold;">for</span> i <span style="color:#9966CC; font-weight:bold;">in</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span>...<span style="color:#006600; font-weight:bold;">&#40;</span>n <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#93;</span>
      to_fix.<span style="color:#9900CC;">push</span><span style="color:#006600; font-weight:bold;">&#40;</span>i<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">if</span> delta<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> == <span style="color:#006666;">0</span>
    <span style="color:#9966CC; font-weight:bold;">for</span> i <span style="color:#9966CC; font-weight:bold;">in</span> to_fix
      m<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> = m<span style="color:#006600; font-weight:bold;">&#91;</span>i <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#006666;">0</span>
    <span style="color:#9966CC; font-weight:bold;">for</span> i <span style="color:#9966CC; font-weight:bold;">in</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span>...<span style="color:#006600; font-weight:bold;">&#40;</span>n <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#93;</span>
      alpha<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> = m<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">/</span> delta<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span>
      beta<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span>  = m<span style="color:#006600; font-weight:bold;">&#91;</span>i <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">/</span> delta<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> 
      dist<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span>  = <span style="color:#CC00FF; font-weight:bold;">Math</span>.<span style="color:#9900CC;">pow</span><span style="color:#006600; font-weight:bold;">&#40;</span>alpha<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span>, <span style="color:#006666;">2</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#CC00FF; font-weight:bold;">Math</span>.<span style="color:#9900CC;">pow</span><span style="color:#006600; font-weight:bold;">&#40;</span>beta<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span>, <span style="color:#006666;">2</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      tau<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span>   = <span style="color:#006666;">3</span> <span style="color:#006600; font-weight:bold;">/</span> <span style="color:#CC00FF; font-weight:bold;">Math</span>.<span style="color:#9900CC;">sqrt</span><span style="color:#006600; font-weight:bold;">&#40;</span>dist<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    to_fix = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span>
    <span style="color:#9966CC; font-weight:bold;">for</span> i <span style="color:#9966CC; font-weight:bold;">in</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span>...<span style="color:#006600; font-weight:bold;">&#40;</span>n <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#93;</span>
      to_fix.<span style="color:#9900CC;">push</span><span style="color:#006600; font-weight:bold;">&#40;</span>i<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">if</span> dist<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">&gt;</span> <span style="color:#006666;">9</span>
    <span style="color:#9966CC; font-weight:bold;">for</span> i <span style="color:#9966CC; font-weight:bold;">in</span> to_fix
      m<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span>     = tau<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">*</span> alpha<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">*</span> delta<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span>
      m<span style="color:#006600; font-weight:bold;">&#91;</span>i <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span> = tau<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">*</span> beta<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span>  <span style="color:#006600; font-weight:bold;">*</span> delta<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span>
    <span style="color:#0066ff; font-weight:bold;">@x</span> = x<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span>...<span style="color:#9900CC;">n</span><span style="color:#006600; font-weight:bold;">&#93;</span>  <span style="color:#008000; font-style:italic;"># copy</span>
    <span style="color:#0066ff; font-weight:bold;">@y</span> = y<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span>...<span style="color:#9900CC;">n</span><span style="color:#006600; font-weight:bold;">&#93;</span>  <span style="color:#008000; font-style:italic;"># copy</span>
    <span style="color:#0066ff; font-weight:bold;">@m</span> = m
&nbsp;
  interpolate: <span style="color:#006600; font-weight:bold;">&#40;</span>x<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">-&gt;</span>
    <span style="color:#9966CC; font-weight:bold;">for</span> i <span style="color:#9966CC; font-weight:bold;">in</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#40;</span>@x.<span style="color:#9900CC;">length</span> <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#006666;">2</span><span style="color:#006600; font-weight:bold;">&#41;</span>..<span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span>
      <span style="color:#9966CC; font-weight:bold;">break</span> <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#0066ff; font-weight:bold;">@x</span><span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">&lt;</span>= x
    h = <span style="color:#0066ff; font-weight:bold;">@x</span><span style="color:#006600; font-weight:bold;">&#91;</span>i <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#0066ff; font-weight:bold;">@x</span><span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span>
    t = <span style="color:#006600; font-weight:bold;">&#40;</span>x <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#0066ff; font-weight:bold;">@x</span><span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">/</span> h
    t2 = <span style="color:#CC00FF; font-weight:bold;">Math</span>.<span style="color:#9900CC;">pow</span><span style="color:#006600; font-weight:bold;">&#40;</span>t, <span style="color:#006666;">2</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    t3 = <span style="color:#CC00FF; font-weight:bold;">Math</span>.<span style="color:#9900CC;">pow</span><span style="color:#006600; font-weight:bold;">&#40;</span>t, <span style="color:#006666;">3</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    h00 =  <span style="color:#006666;">2</span> <span style="color:#006600; font-weight:bold;">*</span> t3 <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#006666;">3</span> <span style="color:#006600; font-weight:bold;">*</span> t2 <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#006666;">1</span>
    h10 =      t3 <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#006666;">2</span> <span style="color:#006600; font-weight:bold;">*</span> t2 <span style="color:#006600; font-weight:bold;">+</span> t
    h01 = <span style="color:#006600; font-weight:bold;">-</span><span style="color:#006666;">2</span> <span style="color:#006600; font-weight:bold;">*</span> t3 <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#006666;">3</span> <span style="color:#006600; font-weight:bold;">*</span> t2
    h11 =      t3  <span style="color:#006600; font-weight:bold;">-</span>    t2
    y = h00 <span style="color:#006600; font-weight:bold;">*</span> <span style="color:#0066ff; font-weight:bold;">@y</span><span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">+</span> 
        h10 <span style="color:#006600; font-weight:bold;">*</span> h <span style="color:#006600; font-weight:bold;">*</span> <span style="color:#0066ff; font-weight:bold;">@m</span><span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">+</span> 
        h01 <span style="color:#006600; font-weight:bold;">*</span> <span style="color:#0066ff; font-weight:bold;">@y</span><span style="color:#006600; font-weight:bold;">&#91;</span>i <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">+</span> 
        h11 <span style="color:#006600; font-weight:bold;">*</span> h <span style="color:#006600; font-weight:bold;">*</span> <span style="color:#0066ff; font-weight:bold;">@m</span><span style="color:#006600; font-weight:bold;">&#91;</span>i <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span>
    y
&nbsp;
&nbsp;
<span style="color:#9966CC; font-weight:bold;">class</span> CubicSpline  <span style="color:#008000; font-style:italic;"># natural or clamped</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># by George MacKerron, mackerron.com</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># adapted from:</span>
<span style="color:#008000; font-style:italic;"># http://www.michonline.com/ryan/csc/m510/splinepresent.html</span>
&nbsp;
  constructor: <span style="color:#006600; font-weight:bold;">&#40;</span>x, a, d0, dn<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">-&gt;</span>
    <span style="color:#0000FF; font-weight:bold;">return</span> <span style="color:#9966CC; font-weight:bold;">unless</span> x? <span style="color:#9966CC; font-weight:bold;">and</span> a?
    clamped = d0? <span style="color:#9966CC; font-weight:bold;">and</span> dn?
    n = x.<span style="color:#9900CC;">length</span> <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#006666;">1</span>
    h = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span>; y = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span>; l = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span>; u = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span>; z = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span>; c = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span>; b = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span>; d = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span>; k = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span>; s = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span>
    <span style="color:#9966CC; font-weight:bold;">for</span> i <span style="color:#9966CC; font-weight:bold;">in</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span>...<span style="color:#9900CC;">n</span><span style="color:#006600; font-weight:bold;">&#93;</span>
      h<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> = x<span style="color:#006600; font-weight:bold;">&#91;</span>i <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">-</span> x<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span>
      k<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> = a<span style="color:#006600; font-weight:bold;">&#91;</span>i <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">-</span> a<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span>
      s<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> = k<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">/</span> h<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span>
    <span style="color:#9966CC; font-weight:bold;">if</span> clamped
      y<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#006666;">3</span> <span style="color:#006600; font-weight:bold;">*</span> <span style="color:#006600; font-weight:bold;">&#40;</span>a<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">-</span> a<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">/</span> h<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#006666;">3</span> <span style="color:#006600; font-weight:bold;">*</span> d0
      y<span style="color:#006600; font-weight:bold;">&#91;</span>n<span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#006666;">3</span> <span style="color:#006600; font-weight:bold;">*</span> dn <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#006666;">3</span> <span style="color:#006600; font-weight:bold;">*</span> <span style="color:#006600; font-weight:bold;">&#40;</span>a<span style="color:#006600; font-weight:bold;">&#91;</span>n<span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">-</span> a<span style="color:#006600; font-weight:bold;">&#91;</span>n <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">/</span> h<span style="color:#006600; font-weight:bold;">&#91;</span>n <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span>
    <span style="color:#9966CC; font-weight:bold;">for</span> i <span style="color:#9966CC; font-weight:bold;">in</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">1</span>...<span style="color:#9900CC;">n</span><span style="color:#006600; font-weight:bold;">&#93;</span>
      y<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#006666;">3</span> <span style="color:#006600; font-weight:bold;">/</span> h<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">*</span> <span style="color:#006600; font-weight:bold;">&#40;</span>a<span style="color:#006600; font-weight:bold;">&#91;</span>i <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">-</span> a<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#006666;">3</span> <span style="color:#006600; font-weight:bold;">/</span> h<span style="color:#006600; font-weight:bold;">&#91;</span>i <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">*</span> <span style="color:#006600; font-weight:bold;">&#40;</span>a<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">-</span> a<span style="color:#006600; font-weight:bold;">&#91;</span>i <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">if</span> clamped
      l<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#006666;">2</span> <span style="color:#006600; font-weight:bold;">*</span> h<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span>
      u<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#006666;">0.5</span>
      z<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span> = y<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">/</span> l<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span>
    <span style="color:#9966CC; font-weight:bold;">else</span>
      l<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#006666;">1</span>
      u<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#006666;">0</span>
      z<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#006666;">0</span>
    <span style="color:#9966CC; font-weight:bold;">for</span> i <span style="color:#9966CC; font-weight:bold;">in</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">1</span>...<span style="color:#9900CC;">n</span><span style="color:#006600; font-weight:bold;">&#93;</span>
      l<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#006666;">2</span> <span style="color:#006600; font-weight:bold;">*</span> <span style="color:#006600; font-weight:bold;">&#40;</span>x<span style="color:#006600; font-weight:bold;">&#91;</span>i <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">-</span> x<span style="color:#006600; font-weight:bold;">&#91;</span>i <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">-</span> h<span style="color:#006600; font-weight:bold;">&#91;</span>i <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">*</span> u<span style="color:#006600; font-weight:bold;">&#91;</span>i <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span>
      u<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> = h<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">/</span> l<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span>
      z<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#006600; font-weight:bold;">&#40;</span>y<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">-</span> h<span style="color:#006600; font-weight:bold;">&#91;</span>i <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">*</span> z<span style="color:#006600; font-weight:bold;">&#91;</span>i <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">/</span> l<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span>
    <span style="color:#9966CC; font-weight:bold;">if</span> clamped
      l<span style="color:#006600; font-weight:bold;">&#91;</span>n<span style="color:#006600; font-weight:bold;">&#93;</span> = h<span style="color:#006600; font-weight:bold;">&#91;</span>n <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">*</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">2</span> <span style="color:#006600; font-weight:bold;">-</span> u<span style="color:#006600; font-weight:bold;">&#91;</span>n <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      z<span style="color:#006600; font-weight:bold;">&#91;</span>n<span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#006600; font-weight:bold;">&#40;</span>y<span style="color:#006600; font-weight:bold;">&#91;</span>n<span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">-</span> h<span style="color:#006600; font-weight:bold;">&#91;</span>n <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">*</span> z<span style="color:#006600; font-weight:bold;">&#91;</span>n <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">/</span> l<span style="color:#006600; font-weight:bold;">&#91;</span>n<span style="color:#006600; font-weight:bold;">&#93;</span>
      c<span style="color:#006600; font-weight:bold;">&#91;</span>n<span style="color:#006600; font-weight:bold;">&#93;</span> = z<span style="color:#006600; font-weight:bold;">&#91;</span>n<span style="color:#006600; font-weight:bold;">&#93;</span>
    <span style="color:#9966CC; font-weight:bold;">else</span>
      l<span style="color:#006600; font-weight:bold;">&#91;</span>n<span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#006666;">1</span>
      z<span style="color:#006600; font-weight:bold;">&#91;</span>n<span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#006666;">0</span>
      c<span style="color:#006600; font-weight:bold;">&#91;</span>n<span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#006666;">0</span>
    <span style="color:#9966CC; font-weight:bold;">for</span> i <span style="color:#9966CC; font-weight:bold;">in</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#40;</span>n <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#41;</span>..<span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span>
      c<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> = z<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">-</span> u<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">*</span> c<span style="color:#006600; font-weight:bold;">&#91;</span>i <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span>
      b<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#006600; font-weight:bold;">&#40;</span>a<span style="color:#006600; font-weight:bold;">&#91;</span>i <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">-</span> a<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">/</span> h<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">-</span> h<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">*</span> <span style="color:#006600; font-weight:bold;">&#40;</span>c<span style="color:#006600; font-weight:bold;">&#91;</span>i <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#006666;">2</span> <span style="color:#006600; font-weight:bold;">*</span> c<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">/</span> <span style="color:#006666;">3</span>
      d<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#006600; font-weight:bold;">&#40;</span>c<span style="color:#006600; font-weight:bold;">&#91;</span>i <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">-</span> c<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">/</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">3</span> <span style="color:#006600; font-weight:bold;">*</span> h<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#0066ff; font-weight:bold;">@x</span> = x<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span>..<span style="color:#9900CC;">n</span><span style="color:#006600; font-weight:bold;">&#93;</span>  <span style="color:#008000; font-style:italic;"># copy</span>
    <span style="color:#0066ff; font-weight:bold;">@a</span> = a<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span>...<span style="color:#9900CC;">n</span><span style="color:#006600; font-weight:bold;">&#93;</span>
    <span style="color:#0066ff; font-weight:bold;">@b</span> = b
    <span style="color:#0066ff; font-weight:bold;">@c</span> = c<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span>...<span style="color:#9900CC;">n</span><span style="color:#006600; font-weight:bold;">&#93;</span>
    <span style="color:#0066ff; font-weight:bold;">@d</span> = d
&nbsp;
  derivative: <span style="color:#006600; font-weight:bold;">-&gt;</span>
    s = new this.<span style="color:#9900CC;">constructor</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    s.<span style="color:#9900CC;">x</span> = <span style="color:#0066ff; font-weight:bold;">@x</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span>...@x.<span style="color:#9900CC;">length</span><span style="color:#006600; font-weight:bold;">&#93;</span>  <span style="color:#008000; font-style:italic;"># copy</span>
    s.<span style="color:#9900CC;">a</span> = <span style="color:#0066ff; font-weight:bold;">@b</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span>...@b.<span style="color:#9900CC;">length</span><span style="color:#006600; font-weight:bold;">&#93;</span>  <span style="color:#008000; font-style:italic;"># copy</span>
    s.<span style="color:#9900CC;">b</span> = <span style="color:#006666;">2</span> <span style="color:#006600; font-weight:bold;">*</span> c <span style="color:#9966CC; font-weight:bold;">for</span> c <span style="color:#9966CC; font-weight:bold;">in</span> <span style="color:#0066ff; font-weight:bold;">@c</span>
    s.<span style="color:#9900CC;">c</span> = <span style="color:#006666;">3</span> <span style="color:#006600; font-weight:bold;">*</span> d <span style="color:#9966CC; font-weight:bold;">for</span> d <span style="color:#9966CC; font-weight:bold;">in</span> <span style="color:#0066ff; font-weight:bold;">@d</span>
    s.<span style="color:#9900CC;">d</span> = <span style="color:#006666;">0</span> <span style="color:#9966CC; font-weight:bold;">for</span> x <span style="color:#9966CC; font-weight:bold;">in</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span>...@d.<span style="color:#9900CC;">length</span><span style="color:#006600; font-weight:bold;">&#93;</span>
    s
&nbsp;
  interpolate: <span style="color:#006600; font-weight:bold;">&#40;</span>x<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">-&gt;</span>
    <span style="color:#9966CC; font-weight:bold;">for</span> i <span style="color:#9966CC; font-weight:bold;">in</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#40;</span>@x.<span style="color:#9900CC;">length</span> <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#41;</span>..<span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span>
      <span style="color:#9966CC; font-weight:bold;">break</span> <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#0066ff; font-weight:bold;">@x</span><span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">&lt;</span>= x
    deltaX = x <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#0066ff; font-weight:bold;">@x</span><span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span>
    y = <span style="color:#0066ff; font-weight:bold;">@a</span><span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">+</span> 
        <span style="color:#0066ff; font-weight:bold;">@b</span><span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">*</span> deltaX <span style="color:#006600; font-weight:bold;">+</span> 
        <span style="color:#0066ff; font-weight:bold;">@c</span><span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">*</span> <span style="color:#CC00FF; font-weight:bold;">Math</span>.<span style="color:#9900CC;">pow</span><span style="color:#006600; font-weight:bold;">&#40;</span>deltaX, <span style="color:#006666;">2</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">+</span> 
        <span style="color:#0066ff; font-weight:bold;">@d</span><span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">*</span> <span style="color:#CC00FF; font-weight:bold;">Math</span>.<span style="color:#9900CC;">pow</span><span style="color:#006600; font-weight:bold;">&#40;</span>deltaX, <span style="color:#006666;">3</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    y</pre></div></div>




<p>Download:</p>


<ul>
<li><a href="/wp-content/uploads/2011/01/cubic_spline.coffee.txt">the above CoffeeScript</a></li>
<li><a href="/wp-content/uploads/2011/01/cubic_spline.js">the compiled JavaScript</a></li>
<li><a href="/wp-content/uploads/2011/01/cubic_spline_min.js">the minified compiled JavaScript</a></li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://blog.mackerron.com/2011/01/01/javascript-cubic-splines/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Blocking the weakest passwords</title>
		<link>http://blog.mackerron.com/2010/12/14/death-to-weak-passwords/</link>
		<comments>http://blog.mackerron.com/2010/12/14/death-to-weak-passwords/#comments</comments>
		<pubDate>Tue, 14 Dec 2010 12:24:04 +0000</pubDate>
		<dc:creator>George</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[System admin]]></category>
		<category><![CDATA[Web design]]></category>

		<guid isPermaLink="false">http://blog.mackerron.com/?p=429</guid>
		<description><![CDATA[The recent Gawker passwords leak once again highlights the widespread use of passwords that offer essentially no security. Some years ago, when working on a secure web app for a large organisation &#8212; let&#8217;s call them Secret Testing Ltd &#8212; I was keen that people shouldn&#8217;t choose hopelessly weak passwords. I was particularly concerned by [...]]]></description>
			<content:encoded><![CDATA[<p>The recent <a href="http://gawker.com/5712615/commenting-accounts-compromised-++-change-your-passwords">Gawker passwords leak</a> once again highlights the widespread use of passwords that offer essentially no security.</p>

<p>Some years ago, when working on a secure web app for a large organisation &#8212; let&#8217;s call them Secret Testing Ltd &#8212; I was keen that people shouldn&#8217;t choose hopelessly weak passwords. I was particularly concerned by my sysadmin colleague&#8217;s fondness for passwords of the form &#8216;p/\55w0rd&#8217; or &#8216;S3cr3t-T35t|ng&#8217;.</p>

<p><span id="more-429"></span></p>

<p>I therefore wrote some simple Ruby code to try to catch very weak passwords:</p>


<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> PasswordUtils
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">look_and_sound_alikes</span><span style="color:#006600; font-weight:bold;">&#40;</span>original<span style="color:#006600; font-weight:bold;">&#41;</span>
    look_or_sound_alikes = <span style="color:#006600; font-weight:bold;">&#123;</span> \
      <span style="color:#996600;">'0'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'o'</span><span style="color:#006600; font-weight:bold;">&#93;</span> ,
      <span style="color:#996600;">'1'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'i'</span>, <span style="color:#996600;">'l'</span><span style="color:#006600; font-weight:bold;">&#93;</span>,
      <span style="color:#996600;">'2'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'to'</span>, <span style="color:#996600;">'too'</span><span style="color:#006600; font-weight:bold;">&#93;</span>,
      <span style="color:#996600;">'3'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'e'</span><span style="color:#006600; font-weight:bold;">&#93;</span>,
      <span style="color:#996600;">'4'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'a'</span>, <span style="color:#996600;">'for'</span><span style="color:#006600; font-weight:bold;">&#93;</span>,
      <span style="color:#996600;">'5'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'s'</span><span style="color:#006600; font-weight:bold;">&#93;</span>,
      <span style="color:#996600;">'6'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'g'</span><span style="color:#006600; font-weight:bold;">&#93;</span>,
      <span style="color:#996600;">'8'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'b'</span>, <span style="color:#996600;">'ate'</span><span style="color:#006600; font-weight:bold;">&#93;</span>,
      <span style="color:#996600;">'9'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'g'</span><span style="color:#006600; font-weight:bold;">&#93;</span>,
      <span style="color:#996600;">'i'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'i'</span><span style="color:#006600; font-weight:bold;">&#93;</span>,
      <span style="color:#996600;">'$'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'s'</span><span style="color:#006600; font-weight:bold;">&#93;</span>,
      <span style="color:#996600;">'|'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'i'</span>, <span style="color:#996600;">'l'</span>, <span style="color:#996600;">''</span><span style="color:#006600; font-weight:bold;">&#93;</span>,
      <span style="color:#996600;">'!'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'i'</span>, <span style="color:#996600;">'l'</span>, <span style="color:#996600;">''</span><span style="color:#006600; font-weight:bold;">&#93;</span>,
      <span style="color:#996600;">'@'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'g'</span>, <span style="color:#996600;">'a'</span><span style="color:#006600; font-weight:bold;">&#93;</span>,
      <span style="color:#996600;">'('</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'c'</span><span style="color:#006600; font-weight:bold;">&#93;</span>,
      <span style="color:#996600;">'['</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'c'</span>, <span style="color:#996600;">'e'</span><span style="color:#006600; font-weight:bold;">&#93;</span>,
      <span style="color:#996600;">'{'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'e'</span><span style="color:#006600; font-weight:bold;">&#93;</span>,
      <span style="color:#996600;">'&amp;'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'and'</span><span style="color:#006600; font-weight:bold;">&#93;</span>,
      <span style="color:#996600;">'*'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'star'</span><span style="color:#006600; font-weight:bold;">&#93;</span>,
      <span style="color:#996600;">')'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'d'</span><span style="color:#006600; font-weight:bold;">&#93;</span>,
      <span style="color:#996600;">'^'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'a'</span><span style="color:#006600; font-weight:bold;">&#93;</span>,
      <span style="color:#996600;">'/'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'a'</span>, <span style="color:#996600;">'v'</span><span style="color:#006600; font-weight:bold;">&#93;</span>,
      <span style="color:#996600;">'<span style="color:#000099;">\\</span>'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">''</span><span style="color:#006600; font-weight:bold;">&#93;</span>,
      <span style="color:#996600;">'&lt;'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'k'</span><span style="color:#006600; font-weight:bold;">&#93;</span>
    <span style="color:#006600; font-weight:bold;">&#125;</span> 
    <span style="color:#008000; font-style:italic;"># the penultimate two substitutions catch /\ (A) and \/ (V), albeit without</span>
    <span style="color:#008000; font-style:italic;"># distinguishing them, and the last (in conjunction with the empty options </span>
    <span style="color:#008000; font-style:italic;"># for ! and |) catches !&lt; and |&lt; (K)</span>
    versions = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">''</span><span style="color:#006600; font-weight:bold;">&#93;</span>
    original.<span style="color:#9900CC;">downcase</span>.<span style="color:#9900CC;">each_char</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>c<span style="color:#006600; font-weight:bold;">|</span>
      versions.<span style="color:#9900CC;">collect</span>! <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>v<span style="color:#006600; font-weight:bold;">|</span>
        alikes = look_or_sound_alikes<span style="color:#006600; font-weight:bold;">&#91;</span>c<span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">||</span> <span style="color:#006600; font-weight:bold;">&#91;</span>c<span style="color:#006600; font-weight:bold;">&#93;</span>
        alikes.<span style="color:#9900CC;">collect</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>c1<span style="color:#006600; font-weight:bold;">|</span> v <span style="color:#006600; font-weight:bold;">+</span> c1 <span style="color:#006600; font-weight:bold;">&#125;</span>
      <span style="color:#9966CC; font-weight:bold;">end</span>
      versions.<span style="color:#9900CC;">flatten</span>!
    <span style="color:#9966CC; font-weight:bold;">end</span>
    versions
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">obvious</span>?<span style="color:#006600; font-weight:bold;">&#40;</span>password, custom_banned_list = <span style="color:#996600;">''</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    standard_banned_list = <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">read</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;#{RAILS_ROOT}/config/banned_password_words.txt&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    banned_words = standard_banned_list.<span style="color:#9900CC;">downcase</span>.<span style="color:#CC0066; font-weight:bold;">split</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">/</span>\W<span style="color:#006600; font-weight:bold;">+/</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">+</span> 
      custom_banned_list.<span style="color:#9900CC;">downcase</span>.<span style="color:#CC0066; font-weight:bold;">split</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">/</span>\W<span style="color:#006600; font-weight:bold;">+/</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">delete_if</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>w<span style="color:#006600; font-weight:bold;">|</span> w.<span style="color:#9900CC;">length</span> <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#006666;">4</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
    alike_words = <span style="color:#006600; font-weight:bold;">&#91;</span>password.<span style="color:#9900CC;">downcase</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">+</span> PasswordUtils.<span style="color:#9900CC;">look_and_sound_alikes</span><span style="color:#006600; font-weight:bold;">&#40;</span>password<span style="color:#006600; font-weight:bold;">&#41;</span>
    banned_words.<span style="color:#9900CC;">any</span>? <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>banned_word<span style="color:#006600; font-weight:bold;">|</span>
      alike_words.<span style="color:#9900CC;">any</span>? <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>alike_word<span style="color:#006600; font-weight:bold;">|</span> alike_word.<span style="color:#9966CC; font-weight:bold;">include</span>? banned_word <span style="color:#006600; font-weight:bold;">&#125;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>




<p>The first method of the class undoes some common substitutions:</p>


<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#006600; font-weight:bold;">&gt;</span> PasswordUtils.<span style="color:#9900CC;">look_and_sound_alikes</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'p/<span style="color:#000099;">\5</span>5w0rd'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;password&quot;</span>, <span style="color:#996600;">&quot;pvssword&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span>
<span style="color:#006600; font-weight:bold;">&gt;</span>  PasswordUtils.<span style="color:#9900CC;">look_and_sound_alikes</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'S3cr3t-T35t|ng'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;secret-testing&quot;</span>, <span style="color:#996600;">&quot;secret-testlng&quot;</span>, <span style="color:#996600;">&quot;secret-testng&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span></pre></div></div>




<p>And the second method uses this in conjunction with a list of banned words to check that an entered password isn&#8217;t hopelessly weak.</p>


<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#006600; font-weight:bold;">&gt;</span> PasswordUtils.<span style="color:#9900CC;">obvious</span>?<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'p/<span style="color:#000099;">\5</span>5w0rd'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">true</span>
<span style="color:#006600; font-weight:bold;">&gt;</span>  PasswordUtils.<span style="color:#9900CC;">obvious</span>?<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'S3cr3t-T35t|ng'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">true</span>
<span style="color:#006600; font-weight:bold;">&gt;</span> PasswordUtils.<span style="color:#9900CC;">obvious</span>?<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'gkAsd76!o'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">false</span></pre></div></div>




<p>Obviously, you need a good banned words list &#8212; perhaps starting with some <a href="http://www.buzzfeed.com/gavon/top-25-gawker-passwords">top N passwords lists</a>, and including the name of your company, the web app, and words related to the area of business, local pubs, and so on.</p>

<p>It&#8217;s also a good idea to include custom banned words for individual users. For example:</p>


<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">custom_banned_list = <span style="color:#996600;">&quot;#{first_names} #{surname} #{department} #{organisation} #{email}&quot;</span>
PasswordUtils.<span style="color:#9900CC;">password_obvious</span>?<span style="color:#006600; font-weight:bold;">&#40;</span>password, custom_banned_list<span style="color:#006600; font-weight:bold;">&#41;</span></pre></div></div>




<p>Passing these tests isn&#8217;t a sufficient condition for ruling out a weak password, but it&#8217;s arguably a necessary one, and a good start.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.mackerron.com/2010/12/14/death-to-weak-passwords/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Extended and properly-multi-line Regular Expressions for JavaScript</title>
		<link>http://blog.mackerron.com/2010/08/08/extended-multi-line-js-regexps/</link>
		<comments>http://blog.mackerron.com/2010/08/08/extended-multi-line-js-regexps/#comments</comments>
		<pubDate>Sun, 08 Aug 2010 18:44:46 +0000</pubDate>
		<dc:creator>George</dc:creator>
				<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://blog.mackerron.com/?p=326</guid>
		<description><![CDATA[Perl, Ruby, and some other languages support a readable &#8216;extended&#8217; regular expression syntax, in which literal whitespace is ignored and comments (starting with #) are available. They also support a multi-line mode where the . character matches anything, including a newline. JavaScript does neither of these: it doesn&#8217;t recognise the extended syntax, and its version [...]]]></description>
			<content:encoded><![CDATA[<p>Perl, Ruby, and some other languages support a readable &#8216;extended&#8217; regular expression syntax, in which literal whitespace is ignored and comments (starting with #) are available. They also support a multi-line mode where the . character matches anything, including a newline.</p>

<p>JavaScript does neither of these: it doesn&#8217;t recognise the extended syntax, and its version of multi-line only allows the ^ and $ characters to match the beginnings and ends of lines within a string (it will never allow the . to match a newline).</p>

<p>So I wrote the following function to convert extended and fully-multi-line RegExp source strings to the basic syntax that JavaScript understands.</p>

<p><span id="more-326"></span></p>


<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">function</span> convertRegExpSource<span style="color: #009900;">&#40;</span>source<span style="color: #339933;">,</span> ext<span style="color: #339933;">,</span> multi<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>  <span style="color: #006600; font-style: italic;">// string, boolean, boolean</span>
  <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span> ext <span style="color: #339933;">&amp;&amp;</span> <span style="color: #339933;">!</span> multi<span style="color: #009900;">&#41;</span> <span style="color: #000066; font-weight: bold;">return</span> source<span style="color: #339933;">;</span>
  <span style="color: #003366; font-weight: bold;">var</span> convertedSource <span style="color: #339933;">=</span> <span style="color: #3366CC;">''</span><span style="color: #339933;">,</span> len <span style="color: #339933;">=</span> source.<span style="color: #660066;">length</span><span style="color: #339933;">;</span>
  <span style="color: #003366; font-weight: bold;">var</span> inCharClass <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">,</span> inComment <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">,</span> justBackslashed <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">;</span>
  <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> len<span style="color: #339933;">;</span> i <span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #003366; font-weight: bold;">var</span> c <span style="color: #339933;">=</span> source.<span style="color: #660066;">charAt</span><span style="color: #009900;">&#40;</span>i<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>justBackslashed<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span> inComment<span style="color: #009900;">&#41;</span> convertedSource <span style="color: #339933;">+=</span> c<span style="color: #339933;">;</span>
      justBackslashed <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">;</span>
      <span style="color: #000066; font-weight: bold;">continue</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>c <span style="color: #339933;">==</span> <span style="color: #3366CC;">'<span style="color: #000099; font-weight: bold;">\\</span>'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span> inComment<span style="color: #009900;">&#41;</span> convertedSource <span style="color: #339933;">+=</span> c<span style="color: #339933;">;</span>
      justBackslashed <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">;</span>
      <span style="color: #000066; font-weight: bold;">continue</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>inCharClass<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      convertedSource <span style="color: #339933;">+=</span> c<span style="color: #339933;">;</span>
      <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>c <span style="color: #339933;">==</span> <span style="color: #3366CC;">']'</span><span style="color: #009900;">&#41;</span> inCharClass <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">;</span>
      <span style="color: #000066; font-weight: bold;">continue</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>inComment<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>c <span style="color: #339933;">==</span> <span style="color: #3366CC;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> <span style="color: #339933;">||</span> c <span style="color: #339933;">==</span> <span style="color: #3366CC;">&quot;<span style="color: #000099; font-weight: bold;">\r</span>&quot;</span><span style="color: #009900;">&#41;</span> inComment <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">;</span>
      <span style="color: #000066; font-weight: bold;">continue</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>c <span style="color: #339933;">==</span> <span style="color: #3366CC;">'['</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      convertedSource <span style="color: #339933;">+=</span> c<span style="color: #339933;">;</span>
      inCharClass <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">;</span>
      <span style="color: #000066; font-weight: bold;">continue</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>ext <span style="color: #339933;">&amp;&amp;</span> c <span style="color: #339933;">==</span> <span style="color: #3366CC;">'#'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      inComment <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">;</span>
      <span style="color: #000066; font-weight: bold;">continue</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>multi <span style="color: #339933;">&amp;&amp;</span> c <span style="color: #339933;">==</span> <span style="color: #3366CC;">'.'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      convertedSource <span style="color: #339933;">+=</span> <span style="color: #3366CC;">'[<span style="color: #000099; font-weight: bold;">\\</span>s<span style="color: #000099; font-weight: bold;">\\</span>S]'</span><span style="color: #339933;">;</span>
      <span style="color: #000066; font-weight: bold;">continue</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span> ext <span style="color: #339933;">||</span> <span style="color: #339933;">!</span> c.<span style="color: #660066;">match</span><span style="color: #009900;">&#40;</span><span style="color: #009966; font-style: italic;">/\s/</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> convertedSource <span style="color: #339933;">+=</span> c<span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
  <span style="color: #000066; font-weight: bold;">return</span> convertedSource<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>




<h2>Use it</h2>

<p>The starting example below is the <a href="http://daringfireball.net/2010/07/improved_regex_for_matching_urls">Daring Fireball monster <span class="caps">URL </span>regex</a>.</p>

<h3>Extended RegExp source (editable)</h3>




<script type="text/javascript">
function convertRegExpSource(source, ext, multi) {  // string, boolean, boolean
  if (! ext) if (! multi) return source;
  var convertedSource = '', len = source.length;
  var inCharClass = false, inComment = false, justBackslashed = false;
  for (var i = 0; i < len; i ++) {
    var c = source.charAt(i);
    if (justBackslashed) {
      if (! inComment) convertedSource += c;
      justBackslashed = false;
      continue;
    }
    if (c == '\\') {
      if (! inComment) convertedSource += c;
      justBackslashed = true;
      continue;
    }
    if (inCharClass) {
      convertedSource += c;
      if (c == ']') inCharClass = false;
      continue;
    }
    if (inComment) {
      if (c == "\n" || c == "\r") inComment = false;
      continue;
    }
    if (c == '[') {
      convertedSource += c;
      inCharClass = true;
      continue;
    }
    if (ext) if (c == '#') {
      inComment = true;
      continue;
    }
    if (multi) if (c == '.') {
      convertedSource += '[\\s\\S]';
      continue;
    }
    if (! ext || ! c.match(/\s/)) convertedSource += c;
  }
  return convertedSource;
}

window.onload = function() {
  var t = document.forms[0].elements[0];
  var out = document.forms[1].elements[0];
  var update = function() {
    out.innerHTML = convertRegExpSource(t.value, true, true);
  };
  update();
  t.onkeyup = t.onchange = update;
};
</script>

<form action="#"><p><textarea rows="25" cols="60" style="width: 100%; font-family: monospace;">\b
(                           # Capture 1: entire matched URL
  (?:
    [a-z][\w-]+:                # URL protocol and colon
    (?:
      /{1,3}                        # 1-3 slashes
      |                             #   or
      [a-z0-9%]                     # Single letter or digit or '%'
                                    # (Trying not to match e.g. "URI::Escape")
    )
    |                           #   or
    www\d{0,3}[.]               # "www.", "www1.", "www2." … "www999."
    |                           #   or
    [a-z0-9.\-]+[.][a-z]{2,4}/  # looks like domain name followed by a slash
  )
  (?:                           # One or more:
    [^\s()<>]+                      # Run of non-space, non-()<>
    |                               #   or
    \(([^\s()<>]+|(\([^\s()<>]+\)))*\)  # balanced parens, up to 2 levels
  )+
  (?:                           # End with:
    \(([^\s()<>]+|(\([^\s()<>]+\)))*\)  # balanced parens, up to 2 levels
    |                                   #   or
    [^\s`!()\[\]{};:'".,<>?«»“”‘’]        # not a space or one of these punct chars
  )
)</textarea></p></form>




<h3>Basic RegExp source output</h3>

<form action="#"><p><textarea rows="3" cols="60" style="width: 100%; font-family: monospace;"></textarea></p></form>

<p>Let me know if you find any bugs, or if you know a nicer way to do this (I know nothing about parsing, so there surely is one). </p>

<p>I think I may suggest extended RegExp support as a possible <a href="http://jashkenas.github.com/coffee-script/">CoffeeScript</a> enhancement.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.mackerron.com/2010/08/08/extended-multi-line-js-regexps/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Signing Amazon Product Advertising API calls in Ruby</title>
		<link>http://blog.mackerron.com/2009/08/22/sign-aws-api-in-ruby/</link>
		<comments>http://blog.mackerron.com/2009/08/22/sign-aws-api-in-ruby/#comments</comments>
		<pubDate>Sat, 22 Aug 2009 11:04:23 +0000</pubDate>
		<dc:creator>George</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Web design]]></category>

		<guid isPermaLink="false">http://blog.mackerron.com/?p=182</guid>
		<description><![CDATA[I have a simple site that generates covers for CDs I burn from iTunes purchases and so on (it pre-dates widespread use of JS libraries, and is in much need of prettifying). The site uses Amazon Product Advertising API calls to search and retrieve album cover art and track listings. Since earlier this month, such [...]]]></description>
			<content:encoded><![CDATA[<p>I have <a href="http://mackerron.com/cdcovers/">a simple site</a> that generates covers for CDs I burn from iTunes purchases and so on (it pre-dates widespread use of JS libraries, and is in much need of prettifying). The site uses <a href="https://affiliate-program.amazon.com/gp/advertising/api/detail/main.html">Amazon Product Advertising <span class="caps">API</span></a> calls to search and retrieve album cover art and track listings. Since earlier this month, such <span class="caps">API </span>calls have to be cryptographically signed.</p>

<p>This is somewhat annoying &#8212; the site&#8217;s original design has it communicating independently with Amazon (using Amazon&#8217;s <span class="caps">XSLT API </span>feature to transform their <span class="caps">XML </span>data into <span class="caps">JSON</span>), and that&#8217;s no longer possible with the use of a private key. But it&#8217;s not unfixable. The site now sends its <span class="caps">API </span>call first to my server, which returns a signed version, and then forwards the signed call on to Amazon.</p>

<p>I found most of what I needed for this on <a href="http://chrisroos.co.uk/blog/2009-01-31-implementing-version-2-of-the-amazon-aws-http-request-signature-in-ruby">Chris Roos&#8217; blog</a>, but his version still wasn&#8217;t quite working for me (the two problems I recall are that Ruby&#8217;s <span class="caps">CGI.</span>escape doesn&#8217;t quite follow Amazon&#8217;s requirements, and that times need converting to <span class="caps">GMT</span>).</p>

<p><span id="more-182"></span></p>

<p>Anyway, in case you&#8217;re looking to do the same, here&#8217;s what I ended up with:</p>


<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;">#!/usr/bin/env ruby</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># Note: You need hmac.rb and hmac-sha2.rb from http://deisui.org/~ueno/ruby/hmac.html </span>
<span style="color:#008000; font-style:italic;"># somewhere in your require paths. ruby-hmac is currently broken under Ruby 1.9.</span>
&nbsp;
<span style="color:#006600; font-weight:bold;">%</span>w<span style="color:#006600; font-weight:bold;">&#40;</span>rubygems cgi time hmac<span style="color:#006600; font-weight:bold;">-</span>sha2 base64<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">each</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>lib<span style="color:#006600; font-weight:bold;">|</span> <span style="color:#CC0066; font-weight:bold;">require</span> lib <span style="color:#006600; font-weight:bold;">&#125;</span>
&nbsp;
ACCESS_IDENTIFIER = <span style="color:#996600;">'YOUR_PUBLIC_ID'</span>
SECRET_IDENTIFIER = <span style="color:#996600;">'YOUR_PRIVATE_ID'</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">def</span> aws_escape<span style="color:#006600; font-weight:bold;">&#40;</span>s<span style="color:#006600; font-weight:bold;">&#41;</span>
  s.<span style="color:#CC0066; font-weight:bold;">gsub</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">/</span><span style="color:#006600; font-weight:bold;">&#91;</span>^A<span style="color:#006600; font-weight:bold;">-</span>Za<span style="color:#006600; font-weight:bold;">-</span>z0<span style="color:#006600; font-weight:bold;">-</span><span style="color:#006666;">9</span>_.~<span style="color:#006600; font-weight:bold;">-</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">/</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>c<span style="color:#006600; font-weight:bold;">|</span> <span style="color:#996600;">'%'</span> <span style="color:#006600; font-weight:bold;">+</span> c<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">to_s</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">16</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">upcase</span> <span style="color:#006600; font-weight:bold;">&#125;</span>  
  <span style="color:#008000; font-style:italic;"># for 1.9, you'd replace [0] with .ord -- but ruby-hmac seems broken under 1.9</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
cgi = <span style="color:#CC00FF; font-weight:bold;">CGI</span>.<span style="color:#9900CC;">new</span>
params = cgi.<span style="color:#9900CC;">params</span>.<span style="color:#9900CC;">dup</span>
&nbsp;
amazon_endpoint = params.<span style="color:#9900CC;">delete</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'amazon_endpoint'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
amazon_path = params.<span style="color:#9900CC;">delete</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'amazon_path'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
js_callback = params.<span style="color:#9900CC;">delete</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'js_callback'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
signing_params = <span style="color:#006600; font-weight:bold;">&#123;</span>
  <span style="color:#996600;">'AWSAccessKeyId'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> ACCESS_IDENTIFIER,
  <span style="color:#996600;">'Timestamp'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#CC00FF; font-weight:bold;">Time</span>.<span style="color:#9900CC;">now</span>.<span style="color:#9900CC;">gmtime</span>.<span style="color:#9900CC;">iso8601</span>
<span style="color:#006600; font-weight:bold;">&#125;</span>
&nbsp;
params.<span style="color:#9900CC;">merge</span>!<span style="color:#006600; font-weight:bold;">&#40;</span>signing_params<span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
canonical_querystring = params.<span style="color:#9900CC;">sort</span>.<span style="color:#9900CC;">collect</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>key, value<span style="color:#006600; font-weight:bold;">|</span> 
  <span style="color:#006600; font-weight:bold;">&#91;</span>aws_escape<span style="color:#006600; font-weight:bold;">&#40;</span>key.<span style="color:#9900CC;">to_s</span><span style="color:#006600; font-weight:bold;">&#41;</span>, aws_escape<span style="color:#006600; font-weight:bold;">&#40;</span>value.<span style="color:#9900CC;">to_s</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">join</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'='</span><span style="color:#006600; font-weight:bold;">&#41;</span> 
<span style="color:#9966CC; font-weight:bold;">end</span>.<span style="color:#9900CC;">join</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'&amp;'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
string_to_sign = <span style="color:#996600;">&quot;GET<span style="color:#000099;">\n</span>#{amazon_endpoint}<span style="color:#000099;">\n</span>#{amazon_path}<span style="color:#000099;">\n</span>#{canonical_querystring}&quot;</span>
&nbsp;
hmac = <span style="color:#6666ff; font-weight:bold;">HMAC::SHA256</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>SECRET_IDENTIFIER<span style="color:#006600; font-weight:bold;">&#41;</span>
hmac.<span style="color:#9900CC;">update</span><span style="color:#006600; font-weight:bold;">&#40;</span>string_to_sign<span style="color:#006600; font-weight:bold;">&#41;</span>
signature = <span style="color:#CC00FF; font-weight:bold;">Base64</span>.<span style="color:#9900CC;">encode64</span><span style="color:#006600; font-weight:bold;">&#40;</span>hmac.<span style="color:#9900CC;">digest</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#CC0066; font-weight:bold;">chomp</span>
&nbsp;
params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'Signature'</span><span style="color:#006600; font-weight:bold;">&#93;</span> = signature
querystring = params.<span style="color:#9900CC;">sort</span>.<span style="color:#9900CC;">collect</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>key, value<span style="color:#006600; font-weight:bold;">|</span> 
  <span style="color:#006600; font-weight:bold;">&#91;</span>aws_escape<span style="color:#006600; font-weight:bold;">&#40;</span>key.<span style="color:#9900CC;">to_s</span><span style="color:#006600; font-weight:bold;">&#41;</span>, aws_escape<span style="color:#006600; font-weight:bold;">&#40;</span>value.<span style="color:#9900CC;">to_s</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">join</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'='</span><span style="color:#006600; font-weight:bold;">&#41;</span> 
<span style="color:#9966CC; font-weight:bold;">end</span>.<span style="color:#9900CC;">join</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'&amp;'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
signed_url = <span style="color:#996600;">&quot;http://#{amazon_endpoint}#{amazon_path}?#{querystring}&quot;</span>
&nbsp;
cgi.<span style="color:#9900CC;">out</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'type'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'text/javascript'</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#996600;">&quot;#{js_callback}('#{signed_url}');&quot;</span> <span style="color:#006600; font-weight:bold;">&#125;</span></pre></div></div>




<p>You can test this locally by feeding key/value parameters to <span class="caps">CGI, </span>followed by Ctrl-D. These, for example:</p>



<pre>amazon_endpoint=ecs.amazonaws.com
amazon_path=/onca/xml
js_callback=do_stuff
Service=AWSECommerceService
Version=2009-03-31
Operation=ItemSearch
SearchIndex=Books
Keywords=george+monbiot</pre>]]></content:encoded>
			<wfw:commentRss>http://blog.mackerron.com/2009/08/22/sign-aws-api-in-ruby/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Free Adobe fonts</title>
		<link>http://blog.mackerron.com/2009/05/28/free-adobe-fonts/</link>
		<comments>http://blog.mackerron.com/2009/05/28/free-adobe-fonts/#comments</comments>
		<pubDate>Thu, 28 May 2009 12:17:47 +0000</pubDate>
		<dc:creator>George</dc:creator>
				<category><![CDATA[Mac]]></category>
		<category><![CDATA[Web design]]></category>

		<guid isPermaLink="false">http://blog.mackerron.com/?p=25</guid>
		<description><![CDATA[Quick tip: you can get hold of some of Adobe&#8217;s very nice professional fonts for free when you download the InDesign CS4 trial (and possibly other CS4 apps too). These include: Caslon Pro Chaparral Pro Garamond Pro Minion Pro Myriad Pro If you don&#8217;t want to actually install InDesign, you can get to the fonts [...]]]></description>
			<content:encoded><![CDATA[<p>Quick tip: you can get hold of some of Adobe&#8217;s very nice professional fonts for free when you download the InDesign <span class="caps">CS4 </span>trial (and possibly other <span class="caps">CS4 </span>apps too).</p>

<p>These include:</p>


<ul>
<li>Caslon Pro</li>
<li>Chaparral Pro</li>
<li>Garamond Pro</li>
<li>Minion Pro</li>
<li>Myriad Pro</li>
</ul>



<p>If you don&#8217;t want to actually install InDesign, you can get to the fonts like so (if you&#8217;re a Mac user):</p>


<ul>
<li>Mount (double-click) the downloaded disk image</li>
<li>Mount another disk image found on the newly mounted disk, at Adobe InDesign <span class="caps">CS4</span>/payloads/AdobeFontsAll/AdobeFontsAll.dmg</li>
<li>The fonts are inside /Assets/contents on this second disk</li>
</ul>



<p><strong>Note that these fonts may well be covered by a very restrictive licence: I haven&#8217;t checked.</strong></p>]]></content:encoded>
			<wfw:commentRss>http://blog.mackerron.com/2009/05/28/free-adobe-fonts/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Testing in Internet Explorer for VMWare Fusion users</title>
		<link>http://blog.mackerron.com/2009/05/28/testing-in-ie-for-fusion-users/</link>
		<comments>http://blog.mackerron.com/2009/05/28/testing-in-ie-for-fusion-users/#comments</comments>
		<pubDate>Thu, 28 May 2009 09:25:43 +0000</pubDate>
		<dc:creator>George</dc:creator>
				<category><![CDATA[Mac]]></category>
		<category><![CDATA[Web design]]></category>

		<guid isPermaLink="false">http://blog.mackerron.com/?p=39</guid>
		<description><![CDATA[You might have noticed that Microsoft has lately started making available time-limited Virtual PC images of Windows installations with (separately) Internet Explorer versions 6, 7 and 8. This is brilliant for Mac users who need to test websites in IE, because you get a real installation of each browser in its home environment, with the [...]]]></description>
			<content:encoded><![CDATA[<p>You might have noticed that Microsoft has lately started making available time-limited Virtual PC images of Windows installations with (separately) Internet Explorer versions 6, 7 and 8. </p>

<p>This is brilliant for Mac users who need to test websites in <span class="caps">IE, </span>because you get a real installation of each browser in its home environment, with the right JavaScript engine and working conditional comments, plug-ins, Windows Media Player, and so on. With the alternatives, such as running under Wine or using <a href="http://tredosoft.com/Multiple_IE">Multiple IEs</a> in a single Windows virtual machine, one or more of these things tends to be missing.</p>

<p><span id="more-39"></span></p>

<p>Unfortunately, the images are supplied as self-extracting .exe files, which of course are Windows programs. But happily, the Mac ports of Wine, the open-source Windows emulation software, can run them.</p>


<ul>
<li>Get hold of <a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=21EABB90-958F-4B64-B5F1-73D0A413C8EF&amp;displaylang=en">the self-extracting archives from Microsoft</a>. I find XP+IE6 and XP+IE8 a useful combination.</li>
<li>Install <a href="http://www.kronenberg.org/darwine/">Darwine</a>.</li>
<li>Open /Applications/Darwine/WineHelper, choose File &gt; Open&#8230; and pick one of the .exe files you downloaded in the last step.</li>
<li>Ignore any Darwine messages about needing to install Mozilla, and click Next/Agree/etc. as necessary in the installer to extract the .vhd file. (I understand the free <a href="http://www.virtualbox.org/">VirtualBox</a> will take such a .vhd directly, but I&#8217;ve not tried this myself).</li>
<li>Download <a href="http://www.kju-app.org/">Q</a>. This is a largely useless program for Intel Mac users, since its purpose is to emulate the <span class="caps">CPU </span>you already have. But bear with me: it includes a very handy utility.</li>
<li>Open /Applications/Utilities/Terminal, and paste in the following command, substituting in the correct path to your .vhd file and a path of your choice for the .vmdk file it will be converted to:</li>
</ul>




<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">/</span>Applications<span style="color: #000000; font-weight: bold;">/</span>Q.app<span style="color: #000000; font-weight: bold;">/</span>Contents<span style="color: #000000; font-weight: bold;">/</span>MacOS<span style="color: #000000; font-weight: bold;">/</span>qemu-img convert \
  <span style="color: #660033;">-f</span> vpc <span style="color: #660033;">-O</span> vmdk path_to_old.vhd path_to_new.vmdk</pre></div></div>





<ul>
<li>Nothing will appear to be happening for a few minutes, but don&#8217;t worry. Wait for the prompt to reappear.</li>
<li>Create a new Virtual Machine in Fusion, based on the new .vmdk you just created. Agree to Fusion&#8217;s request to convert the format of the disk.</li>
<li>Before starting up the new machine, remove its <span class="caps">USB </span>controller, sound card and serial port, and disable 3D graphics (this is all optional, but it reduces the number of requests for drivers you&#8217;ll have to deny later).</li>
<li>Start the virtual machine, canceling any requests for driver disks or Windows Update attempts.</li>
<li>Install <span class="caps">VMW</span>are Tools. I find everything works except the mouse, so at this point I choose the custom installation and deselect the mouse driver.</li>
<li>Reboot and you&#8217;re done.</li>
<li>Don&#8217;t forget to move the original .exe and .vhd files to the Trash: they&#8217;re big and completely useless now.</li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://blog.mackerron.com/2009/05/28/testing-in-ie-for-fusion-users/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Getting a Firefox extension&#8217;s directory from within the extension</title>
		<link>http://blog.mackerron.com/2009/05/07/getting-firefox-extension-directory/</link>
		<comments>http://blog.mackerron.com/2009/05/07/getting-firefox-extension-directory/#comments</comments>
		<pubDate>Thu, 07 May 2009 12:23:07 +0000</pubDate>
		<dc:creator>George</dc:creator>
				<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://blog.mackerron.com/?p=8</guid>
		<description><![CDATA[When creating a Firefox extension recently, I was surprised how much pain is involved simply in finding out, from within an extension, where that extension&#8217;s files are installed. You have to create a &#8216;component&#8217;, which entails a fair chunk of unintelligible boilerplate code (well, unintelligible unless you&#8217;re much better acquainted with Firefox&#8217;s innards than developing [...]]]></description>
			<content:encoded><![CDATA[<p>When creating a <a href="http://mackerron.com/zot2bib/">Firefox extension</a> recently, I was surprised how much pain is involved simply in finding out, from within an extension, where that extension&#8217;s files are installed.</p>

<p>You have to create a &#8216;component&#8217;, which entails a fair chunk of unintelligible boilerplate code (well, unintelligible unless you&#8217;re much better acquainted with Firefox&#8217;s innards than developing a basic extension generally requires you to be).</p>

<p>Plenty of places will tell you <em>roughly</em> how to do it. But, after some experimentation, let me show you <em>exactly</em> how.</p>


<ul>
<li>Copy <a href="http://mackerron.com/svn/zot2bib/trunk/components/getExtDir.js">this JavaScript file</a> into your extension&#8217;s /components directory (if that directory doesn&#8217;t exist yet, create it).</li>
<li>Add these lines to your <code>chrome.manifest</code>:</li>
</ul>





<pre style="margin-bottom: 1em;">component {723079F5-F880-40BB-8283-8266DEA93960} components/getExtDir.js
contract @mackerron.com/getExtDir;1 {723079F5-F880-40BB-8283-8266DEA93960}</pre>





<ul>
<li>Use it from elsewhere in your extension like so:</li>
</ul>




<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> own_path <span style="color: #339933;">=</span> Components.<span style="color: #660066;">classes</span><span style="color: #009900;">&#91;</span><span style="color: #3366CC;">&quot;@mackerron.com/getExtDir;1&quot;</span><span style="color: #009900;">&#93;</span>
  .<span style="color: #660066;">createInstance</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">wrappedJSObject</span>.<span style="color: #660066;">getExtDir</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>




<p><strong>Update, August 2011</strong> &#8212; Firefox 3 made this a bit less hairy, and Firefox 4 introduced a small but incompatible change. The updated code above works in Firefox 3 &#8211; 6, and most likely beyond. However, to make knowing your own directory useful (e.g. in order to locate and run an AppleScript there) you may have also to set <code>&lt;em:unpack&gt;true&lt;/em:unpack&gt;</code> in <code>install.rdf</code>. This activates the old <a href="http://blog.mozilla.com/mwu/2010/09/10/extensions-now-installed-packed/">extension unpacking behaviour</a>, which is deprecated because it increases load time.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.mackerron.com/2009/05/07/getting-firefox-extension-directory/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
<!-- This Quick Cache file was built for (  blog.mackerron.com/category/web-design/feed/ ) in 0.92979 seconds, on Feb 5th, 2012 at 2:58 am UTC. -->
<!-- This Quick Cache file will automatically expire ( and be re-built automatically ) on Feb 5th, 2012 at 3:58 am UTC -->
