<?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; JavaScript</title>
	<atom:link href="http://blog.mackerron.com/category/javascript/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>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>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>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/javascript/feed/ ) in 0.57463 seconds, on Feb 5th, 2012 at 2:57 am UTC. -->
<!-- This Quick Cache file will automatically expire ( and be re-built automatically ) on Feb 5th, 2012 at 3:57 am UTC -->
