source: sandbox/expresso-solr/solr/example/work/jetty-0.0.0.0-8983-solr.war-_solr-any-/webapp/js/lib/d3.js @ 7588

Revision 7588, 247.8 KB checked in by adir, 11 years ago (diff)

Ticket #000 - Adicionando a integracao de buscas com Solr na base a ser isnerida na comunidade

Line 
1(function(){if (!Date.now) Date.now = function() {
2  return +new Date;
3};
4try {
5  document.createElement("div").style.setProperty("opacity", 0, "");
6} catch (error) {
7  var d3_style_prototype = CSSStyleDeclaration.prototype,
8      d3_style_setProperty = d3_style_prototype.setProperty;
9  d3_style_prototype.setProperty = function(name, value, priority) {
10    d3_style_setProperty.call(this, name, value + "", priority);
11  };
12}
13d3 = {version: "2.8.1"}; // semver
14function d3_class(ctor, properties) {
15  try {
16    for (var key in properties) {
17      Object.defineProperty(ctor.prototype, key, {
18        value: properties[key],
19        enumerable: false
20      });
21    }
22  } catch (e) {
23    ctor.prototype = properties;
24  }
25}
26var d3_array = d3_arraySlice; // conversion for NodeLists
27
28function d3_arrayCopy(pseudoarray) {
29  var i = -1, n = pseudoarray.length, array = [];
30  while (++i < n) array.push(pseudoarray[i]);
31  return array;
32}
33
34function d3_arraySlice(pseudoarray) {
35  return Array.prototype.slice.call(pseudoarray);
36}
37
38try {
39  d3_array(document.documentElement.childNodes)[0].nodeType;
40} catch(e) {
41  d3_array = d3_arrayCopy;
42}
43
44var d3_arraySubclass = [].__proto__?
45
46// Until ECMAScript supports array subclassing, prototype injection works well.
47function(array, prototype) {
48  array.__proto__ = prototype;
49}:
50
51// And if your browser doesn't support __proto__, we'll use direct extension.
52function(array, prototype) {
53  for (var property in prototype) array[property] = prototype[property];
54};
55d3.map = function(object) {
56  var map = new d3_Map;
57  for (var key in object) map.set(key, object[key]);
58  return map;
59};
60
61function d3_Map() {}
62
63d3_class(d3_Map, {
64  has: function(key) {
65    return d3_map_prefix + key in this;
66  },
67  get: function(key) {
68    return this[d3_map_prefix + key];
69  },
70  set: function(key, value) {
71    return this[d3_map_prefix + key] = value;
72  },
73  remove: function(key) {
74    key = d3_map_prefix + key;
75    return key in this && delete this[key];
76  },
77  keys: function() {
78    var keys = [];
79    this.forEach(function(key) { keys.push(key); });
80    return keys;
81  },
82  values: function() {
83    var values = [];
84    this.forEach(function(key, value) { values.push(value); });
85    return values;
86  },
87  entries: function() {
88    var entries = [];
89    this.forEach(function(key, value) { entries.push({key: key, value: value}); });
90    return entries;
91  },
92  forEach: function(f) {
93    for (var key in this) {
94      if (key.charCodeAt(0) === d3_map_prefixCode) {
95        f.call(this, key.substring(1), this[key]);
96      }
97    }
98  }
99});
100
101var d3_map_prefix = "\0", // prevent collision with built-ins
102    d3_map_prefixCode = d3_map_prefix.charCodeAt(0);
103function d3_this() {
104  return this;
105}
106d3.functor = function(v) {
107  return typeof v === "function" ? v : function() { return v; };
108};
109// Copies a variable number of methods from source to target.
110d3.rebind = function(target, source) {
111  var i = 1, n = arguments.length, method;
112  while (++i < n) target[method = arguments[i]] = d3_rebind(target, source, source[method]);
113  return target;
114};
115
116// Method is assumed to be a standard D3 getter-setter:
117// If passed with no arguments, gets the value.
118// If passed with arguments, sets the value and returns the target.
119function d3_rebind(target, source, method) {
120  return function() {
121    var value = method.apply(source, arguments);
122    return arguments.length ? target : value;
123  };
124}
125d3.ascending = function(a, b) {
126  return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;
127};
128d3.descending = function(a, b) {
129  return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN;
130};
131d3.mean = function(array, f) {
132  var n = array.length,
133      a,
134      m = 0,
135      i = -1,
136      j = 0;
137  if (arguments.length === 1) {
138    while (++i < n) if (d3_number(a = array[i])) m += (a - m) / ++j;
139  } else {
140    while (++i < n) if (d3_number(a = f.call(array, array[i], i))) m += (a - m) / ++j;
141  }
142  return j ? m : undefined;
143};
144d3.median = function(array, f) {
145  if (arguments.length > 1) array = array.map(f);
146  array = array.filter(d3_number);
147  return array.length ? d3.quantile(array.sort(d3.ascending), .5) : undefined;
148};
149d3.min = function(array, f) {
150  var i = -1,
151      n = array.length,
152      a,
153      b;
154  if (arguments.length === 1) {
155    while (++i < n && ((a = array[i]) == null || a != a)) a = undefined;
156    while (++i < n) if ((b = array[i]) != null && a > b) a = b;
157  } else {
158    while (++i < n && ((a = f.call(array, array[i], i)) == null || a != a)) a = undefined;
159    while (++i < n) if ((b = f.call(array, array[i], i)) != null && a > b) a = b;
160  }
161  return a;
162};
163d3.max = function(array, f) {
164  var i = -1,
165      n = array.length,
166      a,
167      b;
168  if (arguments.length === 1) {
169    while (++i < n && ((a = array[i]) == null || a != a)) a = undefined;
170    while (++i < n) if ((b = array[i]) != null && b > a) a = b;
171  } else {
172    while (++i < n && ((a = f.call(array, array[i], i)) == null || a != a)) a = undefined;
173    while (++i < n) if ((b = f.call(array, array[i], i)) != null && b > a) a = b;
174  }
175  return a;
176};
177d3.extent = function(array, f) {
178  var i = -1,
179      n = array.length,
180      a,
181      b,
182      c;
183  if (arguments.length === 1) {
184    while (++i < n && ((a = c = array[i]) == null || a != a)) a = c = undefined;
185    while (++i < n) if ((b = array[i]) != null) {
186      if (a > b) a = b;
187      if (c < b) c = b;
188    }
189  } else {
190    while (++i < n && ((a = c = f.call(array, array[i], i)) == null || a != a)) a = undefined;
191    while (++i < n) if ((b = f.call(array, array[i], i)) != null) {
192      if (a > b) a = b;
193      if (c < b) c = b;
194    }
195  }
196  return [a, c];
197};
198d3.random = {
199  normal: function(mean, deviation) {
200    if (arguments.length < 2) deviation = 1;
201    if (arguments.length < 1) mean = 0;
202    return function() {
203      var x, y, r;
204      do {
205        x = Math.random() * 2 - 1;
206        y = Math.random() * 2 - 1;
207        r = x * x + y * y;
208      } while (!r || r > 1);
209      return mean + deviation * x * Math.sqrt(-2 * Math.log(r) / r);
210    };
211  }
212};
213function d3_number(x) {
214  return x != null && !isNaN(x);
215}
216d3.sum = function(array, f) {
217  var s = 0,
218      n = array.length,
219      a,
220      i = -1;
221
222  if (arguments.length === 1) {
223    while (++i < n) if (!isNaN(a = +array[i])) s += a;
224  } else {
225    while (++i < n) if (!isNaN(a = +f.call(array, array[i], i))) s += a;
226  }
227
228  return s;
229};
230// R-7 per <http://en.wikipedia.org/wiki/Quantile>
231d3.quantile = function(values, p) {
232  var H = (values.length - 1) * p + 1,
233      h = Math.floor(H),
234      v = values[h - 1],
235      e = H - h;
236  return e ? v + e * (values[h] - v) : v;
237};
238d3.transpose = function(matrix) {
239  return d3.zip.apply(d3, matrix);
240};
241d3.zip = function() {
242  if (!(n = arguments.length)) return [];
243  for (var i = -1, m = d3.min(arguments, d3_zipLength), zips = new Array(m); ++i < m;) {
244    for (var j = -1, n, zip = zips[i] = new Array(n); ++j < n;) {
245      zip[j] = arguments[j][i];
246    }
247  }
248  return zips;
249};
250
251function d3_zipLength(d) {
252  return d.length;
253}
254d3.bisector = function(f) {
255  return {
256    left: function(a, x, lo, hi) {
257      if (arguments.length < 3) lo = 0;
258      if (arguments.length < 4) hi = a.length;
259      while (lo < hi) {
260        var mid = lo + hi >> 1;
261        if (f.call(a, a[mid], mid) < x) lo = mid + 1;
262        else hi = mid;
263      }
264      return lo;
265    },
266    right: function(a, x, lo, hi) {
267      if (arguments.length < 3) lo = 0;
268      if (arguments.length < 4) hi = a.length;
269      while (lo < hi) {
270        var mid = lo + hi >> 1;
271        if (x < f.call(a, a[mid], mid)) hi = mid;
272        else lo = mid + 1;
273      }
274      return lo;
275    }
276  };
277};
278
279var d3_bisector = d3.bisector(function(d) { return d; });
280d3.bisectLeft = d3_bisector.left;
281d3.bisect = d3.bisectRight = d3_bisector.right;
282d3.first = function(array, f) {
283  var i = 0,
284      n = array.length,
285      a = array[0],
286      b;
287  if (arguments.length === 1) f = d3.ascending;
288  while (++i < n) {
289    if (f.call(array, a, b = array[i]) > 0) {
290      a = b;
291    }
292  }
293  return a;
294};
295d3.last = function(array, f) {
296  var i = 0,
297      n = array.length,
298      a = array[0],
299      b;
300  if (arguments.length === 1) f = d3.ascending;
301  while (++i < n) {
302    if (f.call(array, a, b = array[i]) <= 0) {
303      a = b;
304    }
305  }
306  return a;
307};
308d3.nest = function() {
309  var nest = {},
310      keys = [],
311      sortKeys = [],
312      sortValues,
313      rollup;
314
315  function map(array, depth) {
316    if (depth >= keys.length) return rollup
317        ? rollup.call(nest, array) : (sortValues
318        ? array.sort(sortValues)
319        : array);
320
321    var i = -1,
322        n = array.length,
323        key = keys[depth++],
324        keyValue,
325        object,
326        valuesByKey = new d3_Map,
327        values,
328        o = {};
329
330    while (++i < n) {
331      if (values = valuesByKey.get(keyValue = key(object = array[i]))) {
332        values.push(object);
333      } else {
334        valuesByKey.set(keyValue, [object]);
335      }
336    }
337
338    valuesByKey.forEach(function(keyValue) {
339      o[keyValue] = map(valuesByKey.get(keyValue), depth);
340    });
341
342    return o;
343  }
344
345  function entries(map, depth) {
346    if (depth >= keys.length) return map;
347
348    var a = [],
349        sortKey = sortKeys[depth++],
350        key;
351
352    for (key in map) {
353      a.push({key: key, values: entries(map[key], depth)});
354    }
355
356    if (sortKey) a.sort(function(a, b) {
357      return sortKey(a.key, b.key);
358    });
359
360    return a;
361  }
362
363  nest.map = function(array) {
364    return map(array, 0);
365  };
366
367  nest.entries = function(array) {
368    return entries(map(array, 0), 0);
369  };
370
371  nest.key = function(d) {
372    keys.push(d);
373    return nest;
374  };
375
376  // Specifies the order for the most-recently specified key.
377  // Note: only applies to entries. Map keys are unordered!
378  nest.sortKeys = function(order) {
379    sortKeys[keys.length - 1] = order;
380    return nest;
381  };
382
383  // Specifies the order for leaf values.
384  // Applies to both maps and entries array.
385  nest.sortValues = function(order) {
386    sortValues = order;
387    return nest;
388  };
389
390  nest.rollup = function(f) {
391    rollup = f;
392    return nest;
393  };
394
395  return nest;
396};
397d3.keys = function(map) {
398  var keys = [];
399  for (var key in map) keys.push(key);
400  return keys;
401};
402d3.values = function(map) {
403  var values = [];
404  for (var key in map) values.push(map[key]);
405  return values;
406};
407d3.entries = function(map) {
408  var entries = [];
409  for (var key in map) entries.push({key: key, value: map[key]});
410  return entries;
411};
412d3.permute = function(array, indexes) {
413  var permutes = [],
414      i = -1,
415      n = indexes.length;
416  while (++i < n) permutes[i] = array[indexes[i]];
417  return permutes;
418};
419d3.merge = function(arrays) {
420  return Array.prototype.concat.apply([], arrays);
421};
422d3.split = function(array, f) {
423  var arrays = [],
424      values = [],
425      value,
426      i = -1,
427      n = array.length;
428  if (arguments.length < 2) f = d3_splitter;
429  while (++i < n) {
430    if (f.call(values, value = array[i], i)) {
431      values = [];
432    } else {
433      if (!values.length) arrays.push(values);
434      values.push(value);
435    }
436  }
437  return arrays;
438};
439
440function d3_splitter(d) {
441  return d == null;
442}
443function d3_collapse(s) {
444  return s.replace(/(^\s+)|(\s+$)/g, "").replace(/\s+/g, " ");
445}
446d3.range = function(start, stop, step) {
447  if (arguments.length < 3) {
448    step = 1;
449    if (arguments.length < 2) {
450      stop = start;
451      start = 0;
452    }
453  }
454  if ((stop - start) / step === Infinity) throw new Error("infinite range");
455  var range = [],
456       k = d3_range_integerScale(Math.abs(step)),
457       i = -1,
458       j;
459  start *= k, stop *= k, step *= k;
460  if (step < 0) while ((j = start + step * ++i) > stop) range.push(j / k);
461  else while ((j = start + step * ++i) < stop) range.push(j / k);
462  return range;
463};
464
465function d3_range_integerScale(x) {
466  var k = 1;
467  while (x * k % 1) k *= 10;
468  return k;
469}
470d3.requote = function(s) {
471  return s.replace(d3_requote_re, "\\$&");
472};
473
474var d3_requote_re = /[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g;
475d3.round = function(x, n) {
476  return n
477      ? Math.round(x * (n = Math.pow(10, n))) / n
478      : Math.round(x);
479};
480d3.xhr = function(url, mime, callback) {
481  var req = new XMLHttpRequest;
482  if (arguments.length < 3) callback = mime, mime = null;
483  else if (mime && req.overrideMimeType) req.overrideMimeType(mime);
484  req.open("GET", url, true);
485  if (mime) req.setRequestHeader("Accept", mime);
486  req.onreadystatechange = function() {
487    if (req.readyState === 4) callback(req.status < 300 ? req : null);
488  };
489  req.send(null);
490};
491d3.text = function(url, mime, callback) {
492  function ready(req) {
493    callback(req && req.responseText);
494  }
495  if (arguments.length < 3) {
496    callback = mime;
497    mime = null;
498  }
499  d3.xhr(url, mime, ready);
500};
501d3.json = function(url, callback) {
502  d3.text(url, "application/json", function(text) {
503    callback(text ? JSON.parse(text) : null);
504  });
505};
506d3.html = function(url, callback) {
507  d3.text(url, "text/html", function(text) {
508    if (text != null) { // Treat empty string as valid HTML.
509      var range = document.createRange();
510      range.selectNode(document.body);
511      text = range.createContextualFragment(text);
512    }
513    callback(text);
514  });
515};
516d3.xml = function(url, mime, callback) {
517  function ready(req) {
518    callback(req && req.responseXML);
519  }
520  if (arguments.length < 3) {
521    callback = mime;
522    mime = null;
523  }
524  d3.xhr(url, mime, ready);
525};
526var d3_nsPrefix = {
527  svg: "http://www.w3.org/2000/svg",
528  xhtml: "http://www.w3.org/1999/xhtml",
529  xlink: "http://www.w3.org/1999/xlink",
530  xml: "http://www.w3.org/XML/1998/namespace",
531  xmlns: "http://www.w3.org/2000/xmlns/"
532};
533
534d3.ns = {
535  prefix: d3_nsPrefix,
536  qualify: function(name) {
537    var i = name.indexOf(":"),
538        prefix = name;
539    if (i >= 0) {
540      prefix = name.substring(0, i);
541      name = name.substring(i + 1);
542    }
543    return d3_nsPrefix.hasOwnProperty(prefix)
544        ? {space: d3_nsPrefix[prefix], local: name}
545        : name;
546  }
547};
548d3.dispatch = function() {
549  var dispatch = new d3_dispatch,
550      i = -1,
551      n = arguments.length;
552  while (++i < n) dispatch[arguments[i]] = d3_dispatch_event(dispatch);
553  return dispatch;
554};
555
556function d3_dispatch() {}
557
558d3_dispatch.prototype.on = function(type, listener) {
559  var i = type.indexOf("."),
560      name = "";
561
562  // Extract optional namespace, e.g., "click.foo"
563  if (i > 0) {
564    name = type.substring(i + 1);
565    type = type.substring(0, i);
566  }
567
568  return arguments.length < 2
569      ? this[type].on(name)
570      : this[type].on(name, listener);
571};
572
573function d3_dispatch_event(dispatch) {
574  var listeners = [],
575      listenerByName = new d3_Map;
576
577  function event() {
578    var z = listeners, // defensive reference
579        i = -1,
580        n = z.length,
581        l;
582    while (++i < n) if (l = z[i].on) l.apply(this, arguments);
583    return dispatch;
584  }
585
586  event.on = function(name, listener) {
587    var l = listenerByName.get(name),
588        i;
589
590    // return the current listener, if any
591    if (arguments.length < 2) return l && l.on;
592
593    // remove the old listener, if any (with copy-on-write)
594    if (l) {
595      l.on = null;
596      listeners = listeners.slice(0, i = listeners.indexOf(l)).concat(listeners.slice(i + 1));
597      listenerByName.remove(name);
598    }
599
600    // add the new listener, if any
601    if (listener) listeners.push(listenerByName.set(name, {on: listener}));
602
603    return dispatch;
604  };
605
606  return event;
607}
608// TODO align
609d3.format = function(specifier) {
610  var match = d3_format_re.exec(specifier),
611      fill = match[1] || " ",
612      sign = match[3] || "",
613      zfill = match[5],
614      width = +match[6],
615      comma = match[7],
616      precision = match[8],
617      type = match[9],
618      scale = 1,
619      suffix = "",
620      integer = false;
621
622  if (precision) precision = +precision.substring(1);
623
624  if (zfill) {
625    fill = "0"; // TODO align = "=";
626    if (comma) width -= Math.floor((width - 1) / 4);
627  }
628
629  switch (type) {
630    case "n": comma = true; type = "g"; break;
631    case "%": scale = 100; suffix = "%"; type = "f"; break;
632    case "p": scale = 100; suffix = "%"; type = "r"; break;
633    case "d": integer = true; precision = 0; break;
634    case "s": scale = -1; type = "r"; break;
635  }
636
637  // If no precision is specified for r, fallback to general notation.
638  if (type == "r" && !precision) type = "g";
639
640  type = d3_format_types.get(type) || d3_format_typeDefault;
641
642  return function(value) {
643
644    // Return the empty string for floats formatted as ints.
645    if (integer && (value % 1)) return "";
646
647    // Convert negative to positive, and record the sign prefix.
648    var negative = (value < 0) && (value = -value) ? "\u2212" : sign;
649
650    // Apply the scale, computing it from the value's exponent for si format.
651    if (scale < 0) {
652      var prefix = d3.formatPrefix(value, precision);
653      value *= prefix.scale;
654      suffix = prefix.symbol;
655    } else {
656      value *= scale;
657    }
658
659    // Convert to the desired precision.
660    value = type(value, precision);
661
662    // If the fill character is 0, the sign and group is applied after the fill.
663    if (zfill) {
664      var length = value.length + negative.length;
665      if (length < width) value = new Array(width - length + 1).join(fill) + value;
666      if (comma) value = d3_format_group(value);
667      value = negative + value;
668    }
669
670    // Otherwise (e.g., space-filling), the sign and group is applied before.
671    else {
672      if (comma) value = d3_format_group(value);
673      value = negative + value;
674      var length = value.length;
675      if (length < width) value = new Array(width - length + 1).join(fill) + value;
676    }
677
678    return value + suffix;
679  };
680};
681
682// [[fill]align][sign][#][0][width][,][.precision][type]
683var d3_format_re = /(?:([^{])?([<>=^]))?([+\- ])?(#)?(0)?([0-9]+)?(,)?(\.[0-9]+)?([a-zA-Z%])?/;
684
685var d3_format_types = d3.map({
686  g: function(x, p) { return x.toPrecision(p); },
687  e: function(x, p) { return x.toExponential(p); },
688  f: function(x, p) { return x.toFixed(p); },
689  r: function(x, p) { return d3.round(x, p = d3_format_precision(x, p)).toFixed(Math.max(0, Math.min(20, p))); }
690});
691
692function d3_format_precision(x, p) {
693  return p - (x ? 1 + Math.floor(Math.log(x + Math.pow(10, 1 + Math.floor(Math.log(x) / Math.LN10) - p)) / Math.LN10) : 1);
694}
695
696function d3_format_typeDefault(x) {
697  return x + "";
698}
699
700// Apply comma grouping for thousands.
701function d3_format_group(value) {
702  var i = value.lastIndexOf("."),
703      f = i >= 0 ? value.substring(i) : (i = value.length, ""),
704      t = [];
705  while (i > 0) t.push(value.substring(i -= 3, i + 3));
706  return t.reverse().join(",") + f;
707}
708var d3_formatPrefixes = ["y","z","a","f","p","n","Ό","m","","k","M","G","T","P","E","Z","Y"].map(d3_formatPrefix);
709
710d3.formatPrefix = function(value, precision) {
711  var i = 0;
712  if (value) {
713    if (value < 0) value *= -1;
714    if (precision) value = d3.round(value, d3_format_precision(value, precision));
715    i = 1 + Math.floor(1e-12 + Math.log(value) / Math.LN10);
716    i = Math.max(-24, Math.min(24, Math.floor((i <= 0 ? i + 1 : i - 1) / 3) * 3));
717  }
718  return d3_formatPrefixes[8 + i / 3];
719};
720
721function d3_formatPrefix(d, i) {
722  return {
723    scale: Math.pow(10, (8 - i) * 3),
724    symbol: d
725  };
726}
727
728/*
729 * TERMS OF USE - EASING EQUATIONS
730 *
731 * Open source under the BSD License.
732 *
733 * Copyright 2001 Robert Penner
734 * All rights reserved.
735 *
736 * Redistribution and use in source and binary forms, with or without
737 * modification, are permitted provided that the following conditions are met:
738 *
739 * - Redistributions of source code must retain the above copyright notice, this
740 *   list of conditions and the following disclaimer.
741 *
742 * - Redistributions in binary form must reproduce the above copyright notice,
743 *   this list of conditions and the following disclaimer in the documentation
744 *   and/or other materials provided with the distribution.
745 *
746 * - Neither the name of the author nor the names of contributors may be used to
747 *   endorse or promote products derived from this software without specific
748 *   prior written permission.
749 *
750 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
751 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
752 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
753 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
754 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
755 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
756 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
757 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
758 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
759 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
760 * POSSIBILITY OF SUCH DAMAGE.
761 */
762
763var d3_ease_quad = d3_ease_poly(2),
764    d3_ease_cubic = d3_ease_poly(3),
765    d3_ease_default = function() { return d3_ease_identity; };
766
767var d3_ease = d3.map({
768  linear: d3_ease_default,
769  poly: d3_ease_poly,
770  quad: function() { return d3_ease_quad; },
771  cubic: function() { return d3_ease_cubic; },
772  sin: function() { return d3_ease_sin; },
773  exp: function() { return d3_ease_exp; },
774  circle: function() { return d3_ease_circle; },
775  elastic: d3_ease_elastic,
776  back: d3_ease_back,
777  bounce: function() { return d3_ease_bounce; }
778});
779
780var d3_ease_mode = d3.map({
781  "in": d3_ease_identity,
782  "out": d3_ease_reverse,
783  "in-out": d3_ease_reflect,
784  "out-in": function(f) { return d3_ease_reflect(d3_ease_reverse(f)); }
785});
786
787d3.ease = function(name) {
788  var i = name.indexOf("-"),
789      t = i >= 0 ? name.substring(0, i) : name,
790      m = i >= 0 ? name.substring(i + 1) : "in";
791  t = d3_ease.get(t) || d3_ease_default;
792  m = d3_ease_mode.get(m) || d3_ease_identity;
793  return d3_ease_clamp(m(t.apply(null, Array.prototype.slice.call(arguments, 1))));
794};
795
796function d3_ease_clamp(f) {
797  return function(t) {
798    return t <= 0 ? 0 : t >= 1 ? 1 : f(t);
799  };
800}
801
802function d3_ease_reverse(f) {
803  return function(t) {
804    return 1 - f(1 - t);
805  };
806}
807
808function d3_ease_reflect(f) {
809  return function(t) {
810    return .5 * (t < .5 ? f(2 * t) : (2 - f(2 - 2 * t)));
811  };
812}
813
814function d3_ease_identity(t) {
815  return t;
816}
817
818function d3_ease_poly(e) {
819  return function(t) {
820    return Math.pow(t, e);
821  };
822}
823
824function d3_ease_sin(t) {
825  return 1 - Math.cos(t * Math.PI / 2);
826}
827
828function d3_ease_exp(t) {
829  return Math.pow(2, 10 * (t - 1));
830}
831
832function d3_ease_circle(t) {
833  return 1 - Math.sqrt(1 - t * t);
834}
835
836function d3_ease_elastic(a, p) {
837  var s;
838  if (arguments.length < 2) p = 0.45;
839  if (arguments.length < 1) { a = 1; s = p / 4; }
840  else s = p / (2 * Math.PI) * Math.asin(1 / a);
841  return function(t) {
842    return 1 + a * Math.pow(2, 10 * -t) * Math.sin((t - s) * 2 * Math.PI / p);
843  };
844}
845
846function d3_ease_back(s) {
847  if (!s) s = 1.70158;
848  return function(t) {
849    return t * t * ((s + 1) * t - s);
850  };
851}
852
853function d3_ease_bounce(t) {
854  return t < 1 / 2.75 ? 7.5625 * t * t
855      : t < 2 / 2.75 ? 7.5625 * (t -= 1.5 / 2.75) * t + .75
856      : t < 2.5 / 2.75 ? 7.5625 * (t -= 2.25 / 2.75) * t + .9375
857      : 7.5625 * (t -= 2.625 / 2.75) * t + .984375;
858}
859d3.event = null;
860
861function d3_eventCancel() {
862  d3.event.stopPropagation();
863  d3.event.preventDefault();
864}
865
866function d3_eventSource() {
867  var e = d3.event, s;
868  while (s = e.sourceEvent) e = s;
869  return e;
870}
871
872// Like d3.dispatch, but for custom events abstracting native UI events. These
873// events have a target component (such as a brush), a target element (such as
874// the svg:g element containing the brush) and the standard arguments `d` (the
875// target element's data) and `i` (the selection index of the target element).
876function d3_eventDispatch(target) {
877  var dispatch = new d3_dispatch,
878      i = 0,
879      n = arguments.length;
880
881  while (++i < n) dispatch[arguments[i]] = d3_dispatch_event(dispatch);
882
883  // Creates a dispatch context for the specified `thiz` (typically, the target
884  // DOM element that received the source event) and `argumentz` (typically, the
885  // data `d` and index `i` of the target element). The returned function can be
886  // used to dispatch an event to any registered listeners; the function takes a
887  // single argument as input, being the event to dispatch. The event must have
888  // a "type" attribute which corresponds to a type registered in the
889  // constructor. This context will automatically populate the "sourceEvent" and
890  // "target" attributes of the event, as well as setting the `d3.event` global
891  // for the duration of the notification.
892  dispatch.of = function(thiz, argumentz) {
893    return function(e1) {
894      try {
895        var e0 =
896        e1.sourceEvent = d3.event;
897        e1.target = target;
898        d3.event = e1;
899        dispatch[e1.type].apply(thiz, argumentz);
900      } finally {
901        d3.event = e0;
902      }
903    };
904  };
905
906  return dispatch;
907}
908d3.interpolate = function(a, b) {
909  var i = d3.interpolators.length, f;
910  while (--i >= 0 && !(f = d3.interpolators[i](a, b)));
911  return f;
912};
913
914d3.interpolateNumber = function(a, b) {
915  b -= a;
916  return function(t) { return a + b * t; };
917};
918
919d3.interpolateRound = function(a, b) {
920  b -= a;
921  return function(t) { return Math.round(a + b * t); };
922};
923
924d3.interpolateString = function(a, b) {
925  var m, // current match
926      i, // current index
927      j, // current index (for coallescing)
928      s0 = 0, // start index of current string prefix
929      s1 = 0, // end index of current string prefix
930      s = [], // string constants and placeholders
931      q = [], // number interpolators
932      n, // q.length
933      o;
934
935  // Reset our regular expression!
936  d3_interpolate_number.lastIndex = 0;
937
938  // Find all numbers in b.
939  for (i = 0; m = d3_interpolate_number.exec(b); ++i) {
940    if (m.index) s.push(b.substring(s0, s1 = m.index));
941    q.push({i: s.length, x: m[0]});
942    s.push(null);
943    s0 = d3_interpolate_number.lastIndex;
944  }
945  if (s0 < b.length) s.push(b.substring(s0));
946
947  // Find all numbers in a.
948  for (i = 0, n = q.length; (m = d3_interpolate_number.exec(a)) && i < n; ++i) {
949    o = q[i];
950    if (o.x == m[0]) { // The numbers match, so coallesce.
951      if (o.i) {
952        if (s[o.i + 1] == null) { // This match is followed by another number.
953          s[o.i - 1] += o.x;
954          s.splice(o.i, 1);
955          for (j = i + 1; j < n; ++j) q[j].i--;
956        } else { // This match is followed by a string, so coallesce twice.
957          s[o.i - 1] += o.x + s[o.i + 1];
958          s.splice(o.i, 2);
959          for (j = i + 1; j < n; ++j) q[j].i -= 2;
960        }
961      } else {
962          if (s[o.i + 1] == null) { // This match is followed by another number.
963          s[o.i] = o.x;
964        } else { // This match is followed by a string, so coallesce twice.
965          s[o.i] = o.x + s[o.i + 1];
966          s.splice(o.i + 1, 1);
967          for (j = i + 1; j < n; ++j) q[j].i--;
968        }
969      }
970      q.splice(i, 1);
971      n--;
972      i--;
973    } else {
974      o.x = d3.interpolateNumber(parseFloat(m[0]), parseFloat(o.x));
975    }
976  }
977
978  // Remove any numbers in b not found in a.
979  while (i < n) {
980    o = q.pop();
981    if (s[o.i + 1] == null) { // This match is followed by another number.
982      s[o.i] = o.x;
983    } else { // This match is followed by a string, so coallesce twice.
984      s[o.i] = o.x + s[o.i + 1];
985      s.splice(o.i + 1, 1);
986    }
987    n--;
988  }
989
990  // Special optimization for only a single match.
991  if (s.length === 1) {
992    return s[0] == null ? q[0].x : function() { return b; };
993  }
994
995  // Otherwise, interpolate each of the numbers and rejoin the string.
996  return function(t) {
997    for (i = 0; i < n; ++i) s[(o = q[i]).i] = o.x(t);
998    return s.join("");
999  };
1000};
1001
1002d3.interpolateTransform = function(a, b) {
1003  var s = [], // string constants and placeholders
1004      q = [], // number interpolators
1005      n,
1006      A = d3.transform(a),
1007      B = d3.transform(b),
1008      ta = A.translate,
1009      tb = B.translate,
1010      ra = A.rotate,
1011      rb = B.rotate,
1012      wa = A.skew,
1013      wb = B.skew,
1014      ka = A.scale,
1015      kb = B.scale;
1016
1017  if (ta[0] != tb[0] || ta[1] != tb[1]) {
1018    s.push("translate(", null, ",", null, ")");
1019    q.push({i: 1, x: d3.interpolateNumber(ta[0], tb[0])}, {i: 3, x: d3.interpolateNumber(ta[1], tb[1])});
1020  } else if (tb[0] || tb[1]) {
1021    s.push("translate(" + tb + ")");
1022  } else {
1023    s.push("");
1024  }
1025
1026  if (ra != rb) {
1027    q.push({i: s.push(s.pop() + "rotate(", null, ")") - 2, x: d3.interpolateNumber(ra, rb)});
1028  } else if (rb) {
1029    s.push(s.pop() + "rotate(" + rb + ")");
1030  }
1031
1032  if (wa != wb) {
1033    q.push({i: s.push(s.pop() + "skewX(", null, ")") - 2, x: d3.interpolateNumber(wa, wb)});
1034  } else if (wb) {
1035    s.push(s.pop() + "skewX(" + wb + ")");
1036  }
1037
1038  if (ka[0] != kb[0] || ka[1] != kb[1]) {
1039    n = s.push(s.pop() + "scale(", null, ",", null, ")");
1040    q.push({i: n - 4, x: d3.interpolateNumber(ka[0], kb[0])}, {i: n - 2, x: d3.interpolateNumber(ka[1], kb[1])});
1041  } else if (kb[0] != 1 || kb[1] != 1) {
1042    s.push(s.pop() + "scale(" + kb + ")");
1043  }
1044
1045  n = q.length;
1046  return function(t) {
1047    var i = -1, o;
1048    while (++i < n) s[(o = q[i]).i] = o.x(t);
1049    return s.join("");
1050  };
1051};
1052
1053d3.interpolateRgb = function(a, b) {
1054  a = d3.rgb(a);
1055  b = d3.rgb(b);
1056  var ar = a.r,
1057      ag = a.g,
1058      ab = a.b,
1059      br = b.r - ar,
1060      bg = b.g - ag,
1061      bb = b.b - ab;
1062  return function(t) {
1063    return "#"
1064        + d3_rgb_hex(Math.round(ar + br * t))
1065        + d3_rgb_hex(Math.round(ag + bg * t))
1066        + d3_rgb_hex(Math.round(ab + bb * t));
1067  };
1068};
1069
1070// interpolates HSL space, but outputs RGB string (for compatibility)
1071d3.interpolateHsl = function(a, b) {
1072  a = d3.hsl(a);
1073  b = d3.hsl(b);
1074  var h0 = a.h,
1075      s0 = a.s,
1076      l0 = a.l,
1077      h1 = b.h - h0,
1078      s1 = b.s - s0,
1079      l1 = b.l - l0;
1080  return function(t) {
1081    return d3_hsl_rgb(h0 + h1 * t, s0 + s1 * t, l0 + l1 * t).toString();
1082  };
1083};
1084
1085d3.interpolateArray = function(a, b) {
1086  var x = [],
1087      c = [],
1088      na = a.length,
1089      nb = b.length,
1090      n0 = Math.min(a.length, b.length),
1091      i;
1092  for (i = 0; i < n0; ++i) x.push(d3.interpolate(a[i], b[i]));
1093  for (; i < na; ++i) c[i] = a[i];
1094  for (; i < nb; ++i) c[i] = b[i];
1095  return function(t) {
1096    for (i = 0; i < n0; ++i) c[i] = x[i](t);
1097    return c;
1098  };
1099};
1100
1101d3.interpolateObject = function(a, b) {
1102  var i = {},
1103      c = {},
1104      k;
1105  for (k in a) {
1106    if (k in b) {
1107      i[k] = d3_interpolateByName(k)(a[k], b[k]);
1108    } else {
1109      c[k] = a[k];
1110    }
1111  }
1112  for (k in b) {
1113    if (!(k in a)) {
1114      c[k] = b[k];
1115    }
1116  }
1117  return function(t) {
1118    for (k in i) c[k] = i[k](t);
1119    return c;
1120  };
1121}
1122
1123var d3_interpolate_number = /[-+]?(?:\d*\.?\d+)(?:[eE][-+]?\d+)?/g;
1124
1125function d3_interpolateByName(n) {
1126  return n == "transform"
1127      ? d3.interpolateTransform
1128      : d3.interpolate;
1129}
1130
1131d3.interpolators = [
1132  d3.interpolateObject,
1133  function(a, b) { return (b instanceof Array) && d3.interpolateArray(a, b); },
1134  function(a, b) { return (typeof a === "string" || typeof b === "string") && d3.interpolateString(a + "", b + ""); },
1135  function(a, b) { return (typeof b === "string" ? d3_rgb_names.has(b) || /^(#|rgb\(|hsl\()/.test(b) : b instanceof d3_Rgb || b instanceof d3_Hsl) && d3.interpolateRgb(a, b); },
1136  function(a, b) { return !isNaN(a = +a) && !isNaN(b = +b) && d3.interpolateNumber(a, b); }
1137];
1138function d3_uninterpolateNumber(a, b) {
1139  b = b - (a = +a) ? 1 / (b - a) : 0;
1140  return function(x) { return (x - a) * b; };
1141}
1142
1143function d3_uninterpolateClamp(a, b) {
1144  b = b - (a = +a) ? 1 / (b - a) : 0;
1145  return function(x) { return Math.max(0, Math.min(1, (x - a) * b)); };
1146}
1147d3.rgb = function(r, g, b) {
1148  return arguments.length === 1
1149      ? (r instanceof d3_Rgb ? d3_rgb(r.r, r.g, r.b)
1150      : d3_rgb_parse("" + r, d3_rgb, d3_hsl_rgb))
1151      : d3_rgb(~~r, ~~g, ~~b);
1152};
1153
1154function d3_rgb(r, g, b) {
1155  return new d3_Rgb(r, g, b);
1156}
1157
1158function d3_Rgb(r, g, b) {
1159  this.r = r;
1160  this.g = g;
1161  this.b = b;
1162}
1163
1164d3_Rgb.prototype.brighter = function(k) {
1165  k = Math.pow(0.7, arguments.length ? k : 1);
1166  var r = this.r,
1167      g = this.g,
1168      b = this.b,
1169      i = 30;
1170  if (!r && !g && !b) return d3_rgb(i, i, i);
1171  if (r && r < i) r = i;
1172  if (g && g < i) g = i;
1173  if (b && b < i) b = i;
1174  return d3_rgb(
1175      Math.min(255, Math.floor(r / k)),
1176      Math.min(255, Math.floor(g / k)),
1177      Math.min(255, Math.floor(b / k)));
1178};
1179
1180d3_Rgb.prototype.darker = function(k) {
1181  k = Math.pow(0.7, arguments.length ? k : 1);
1182  return d3_rgb(
1183      Math.floor(k * this.r),
1184      Math.floor(k * this.g),
1185      Math.floor(k * this.b));
1186};
1187
1188d3_Rgb.prototype.hsl = function() {
1189  return d3_rgb_hsl(this.r, this.g, this.b);
1190};
1191
1192d3_Rgb.prototype.toString = function() {
1193  return "#" + d3_rgb_hex(this.r) + d3_rgb_hex(this.g) + d3_rgb_hex(this.b);
1194};
1195
1196function d3_rgb_hex(v) {
1197  return v < 0x10
1198      ? "0" + Math.max(0, v).toString(16)
1199      : Math.min(255, v).toString(16);
1200}
1201
1202function d3_rgb_parse(format, rgb, hsl) {
1203  var r = 0, // red channel; int in [0, 255]
1204      g = 0, // green channel; int in [0, 255]
1205      b = 0, // blue channel; int in [0, 255]
1206      m1, // CSS color specification match
1207      m2, // CSS color specification type (e.g., rgb)
1208      name;
1209
1210  /* Handle hsl, rgb. */
1211  m1 = /([a-z]+)\((.*)\)/i.exec(format);
1212  if (m1) {
1213    m2 = m1[2].split(",");
1214    switch (m1[1]) {
1215      case "hsl": {
1216        return hsl(
1217          parseFloat(m2[0]), // degrees
1218          parseFloat(m2[1]) / 100, // percentage
1219          parseFloat(m2[2]) / 100 // percentage
1220        );
1221      }
1222      case "rgb": {
1223        return rgb(
1224          d3_rgb_parseNumber(m2[0]),
1225          d3_rgb_parseNumber(m2[1]),
1226          d3_rgb_parseNumber(m2[2])
1227        );
1228      }
1229    }
1230  }
1231
1232  /* Named colors. */
1233  if (name = d3_rgb_names.get(format)) return rgb(name.r, name.g, name.b);
1234
1235  /* Hexadecimal colors: #rgb and #rrggbb. */
1236  if (format != null && format.charAt(0) === "#") {
1237    if (format.length === 4) {
1238      r = format.charAt(1); r += r;
1239      g = format.charAt(2); g += g;
1240      b = format.charAt(3); b += b;
1241    } else if (format.length === 7) {
1242      r = format.substring(1, 3);
1243      g = format.substring(3, 5);
1244      b = format.substring(5, 7);
1245    }
1246    r = parseInt(r, 16);
1247    g = parseInt(g, 16);
1248    b = parseInt(b, 16);
1249  }
1250
1251  return rgb(r, g, b);
1252}
1253
1254function d3_rgb_hsl(r, g, b) {
1255  var min = Math.min(r /= 255, g /= 255, b /= 255),
1256      max = Math.max(r, g, b),
1257      d = max - min,
1258      h,
1259      s,
1260      l = (max + min) / 2;
1261  if (d) {
1262    s = l < .5 ? d / (max + min) : d / (2 - max - min);
1263    if (r == max) h = (g - b) / d + (g < b ? 6 : 0);
1264    else if (g == max) h = (b - r) / d + 2;
1265    else h = (r - g) / d + 4;
1266    h *= 60;
1267  } else {
1268    s = h = 0;
1269  }
1270  return d3_hsl(h, s, l);
1271}
1272
1273function d3_rgb_parseNumber(c) { // either integer or percentage
1274  var f = parseFloat(c);
1275  return c.charAt(c.length - 1) === "%" ? Math.round(f * 2.55) : f;
1276}
1277
1278var d3_rgb_names = d3.map({
1279  aliceblue: "#f0f8ff",
1280  antiquewhite: "#faebd7",
1281  aqua: "#00ffff",
1282  aquamarine: "#7fffd4",
1283  azure: "#f0ffff",
1284  beige: "#f5f5dc",
1285  bisque: "#ffe4c4",
1286  black: "#000000",
1287  blanchedalmond: "#ffebcd",
1288  blue: "#0000ff",
1289  blueviolet: "#8a2be2",
1290  brown: "#a52a2a",
1291  burlywood: "#deb887",
1292  cadetblue: "#5f9ea0",
1293  chartreuse: "#7fff00",
1294  chocolate: "#d2691e",
1295  coral: "#ff7f50",
1296  cornflowerblue: "#6495ed",
1297  cornsilk: "#fff8dc",
1298  crimson: "#dc143c",
1299  cyan: "#00ffff",
1300  darkblue: "#00008b",
1301  darkcyan: "#008b8b",
1302  darkgoldenrod: "#b8860b",
1303  darkgray: "#a9a9a9",
1304  darkgreen: "#006400",
1305  darkgrey: "#a9a9a9",
1306  darkkhaki: "#bdb76b",
1307  darkmagenta: "#8b008b",
1308  darkolivegreen: "#556b2f",
1309  darkorange: "#ff8c00",
1310  darkorchid: "#9932cc",
1311  darkred: "#8b0000",
1312  darksalmon: "#e9967a",
1313  darkseagreen: "#8fbc8f",
1314  darkslateblue: "#483d8b",
1315  darkslategray: "#2f4f4f",
1316  darkslategrey: "#2f4f4f",
1317  darkturquoise: "#00ced1",
1318  darkviolet: "#9400d3",
1319  deeppink: "#ff1493",
1320  deepskyblue: "#00bfff",
1321  dimgray: "#696969",
1322  dimgrey: "#696969",
1323  dodgerblue: "#1e90ff",
1324  firebrick: "#b22222",
1325  floralwhite: "#fffaf0",
1326  forestgreen: "#228b22",
1327  fuchsia: "#ff00ff",
1328  gainsboro: "#dcdcdc",
1329  ghostwhite: "#f8f8ff",
1330  gold: "#ffd700",
1331  goldenrod: "#daa520",
1332  gray: "#808080",
1333  green: "#008000",
1334  greenyellow: "#adff2f",
1335  grey: "#808080",
1336  honeydew: "#f0fff0",
1337  hotpink: "#ff69b4",
1338  indianred: "#cd5c5c",
1339  indigo: "#4b0082",
1340  ivory: "#fffff0",
1341  khaki: "#f0e68c",
1342  lavender: "#e6e6fa",
1343  lavenderblush: "#fff0f5",
1344  lawngreen: "#7cfc00",
1345  lemonchiffon: "#fffacd",
1346  lightblue: "#add8e6",
1347  lightcoral: "#f08080",
1348  lightcyan: "#e0ffff",
1349  lightgoldenrodyellow: "#fafad2",
1350  lightgray: "#d3d3d3",
1351  lightgreen: "#90ee90",
1352  lightgrey: "#d3d3d3",
1353  lightpink: "#ffb6c1",
1354  lightsalmon: "#ffa07a",
1355  lightseagreen: "#20b2aa",
1356  lightskyblue: "#87cefa",
1357  lightslategray: "#778899",
1358  lightslategrey: "#778899",
1359  lightsteelblue: "#b0c4de",
1360  lightyellow: "#ffffe0",
1361  lime: "#00ff00",
1362  limegreen: "#32cd32",
1363  linen: "#faf0e6",
1364  magenta: "#ff00ff",
1365  maroon: "#800000",
1366  mediumaquamarine: "#66cdaa",
1367  mediumblue: "#0000cd",
1368  mediumorchid: "#ba55d3",
1369  mediumpurple: "#9370db",
1370  mediumseagreen: "#3cb371",
1371  mediumslateblue: "#7b68ee",
1372  mediumspringgreen: "#00fa9a",
1373  mediumturquoise: "#48d1cc",
1374  mediumvioletred: "#c71585",
1375  midnightblue: "#191970",
1376  mintcream: "#f5fffa",
1377  mistyrose: "#ffe4e1",
1378  moccasin: "#ffe4b5",
1379  navajowhite: "#ffdead",
1380  navy: "#000080",
1381  oldlace: "#fdf5e6",
1382  olive: "#808000",
1383  olivedrab: "#6b8e23",
1384  orange: "#ffa500",
1385  orangered: "#ff4500",
1386  orchid: "#da70d6",
1387  palegoldenrod: "#eee8aa",
1388  palegreen: "#98fb98",
1389  paleturquoise: "#afeeee",
1390  palevioletred: "#db7093",
1391  papayawhip: "#ffefd5",
1392  peachpuff: "#ffdab9",
1393  peru: "#cd853f",
1394  pink: "#ffc0cb",
1395  plum: "#dda0dd",
1396  powderblue: "#b0e0e6",
1397  purple: "#800080",
1398  red: "#ff0000",
1399  rosybrown: "#bc8f8f",
1400  royalblue: "#4169e1",
1401  saddlebrown: "#8b4513",
1402  salmon: "#fa8072",
1403  sandybrown: "#f4a460",
1404  seagreen: "#2e8b57",
1405  seashell: "#fff5ee",
1406  sienna: "#a0522d",
1407  silver: "#c0c0c0",
1408  skyblue: "#87ceeb",
1409  slateblue: "#6a5acd",
1410  slategray: "#708090",
1411  slategrey: "#708090",
1412  snow: "#fffafa",
1413  springgreen: "#00ff7f",
1414  steelblue: "#4682b4",
1415  tan: "#d2b48c",
1416  teal: "#008080",
1417  thistle: "#d8bfd8",
1418  tomato: "#ff6347",
1419  turquoise: "#40e0d0",
1420  violet: "#ee82ee",
1421  wheat: "#f5deb3",
1422  white: "#ffffff",
1423  whitesmoke: "#f5f5f5",
1424  yellow: "#ffff00",
1425  yellowgreen: "#9acd32"
1426});
1427
1428d3_rgb_names.forEach(function(key, value) {
1429  d3_rgb_names.set(key, d3_rgb_parse(value, d3_rgb, d3_hsl_rgb));
1430});
1431d3.hsl = function(h, s, l) {
1432  return arguments.length === 1
1433      ? (h instanceof d3_Hsl ? d3_hsl(h.h, h.s, h.l)
1434      : d3_rgb_parse("" + h, d3_rgb_hsl, d3_hsl))
1435      : d3_hsl(+h, +s, +l);
1436};
1437
1438function d3_hsl(h, s, l) {
1439  return new d3_Hsl(h, s, l);
1440}
1441
1442function d3_Hsl(h, s, l) {
1443  this.h = h;
1444  this.s = s;
1445  this.l = l;
1446}
1447
1448d3_Hsl.prototype.brighter = function(k) {
1449  k = Math.pow(0.7, arguments.length ? k : 1);
1450  return d3_hsl(this.h, this.s, this.l / k);
1451};
1452
1453d3_Hsl.prototype.darker = function(k) {
1454  k = Math.pow(0.7, arguments.length ? k : 1);
1455  return d3_hsl(this.h, this.s, k * this.l);
1456};
1457
1458d3_Hsl.prototype.rgb = function() {
1459  return d3_hsl_rgb(this.h, this.s, this.l);
1460};
1461
1462d3_Hsl.prototype.toString = function() {
1463  return this.rgb().toString();
1464};
1465
1466function d3_hsl_rgb(h, s, l) {
1467  var m1,
1468      m2;
1469
1470  /* Some simple corrections for h, s and l. */
1471  h = h % 360; if (h < 0) h += 360;
1472  s = s < 0 ? 0 : s > 1 ? 1 : s;
1473  l = l < 0 ? 0 : l > 1 ? 1 : l;
1474
1475  /* From FvD 13.37, CSS Color Module Level 3 */
1476  m2 = l <= .5 ? l * (1 + s) : l + s - l * s;
1477  m1 = 2 * l - m2;
1478
1479  function v(h) {
1480    if (h > 360) h -= 360;
1481    else if (h < 0) h += 360;
1482    if (h < 60) return m1 + (m2 - m1) * h / 60;
1483    if (h < 180) return m2;
1484    if (h < 240) return m1 + (m2 - m1) * (240 - h) / 60;
1485    return m1;
1486  }
1487
1488  function vv(h) {
1489    return Math.round(v(h) * 255);
1490  }
1491
1492  return d3_rgb(vv(h + 120), vv(h), vv(h - 120));
1493}
1494function d3_selection(groups) {
1495  d3_arraySubclass(groups, d3_selectionPrototype);
1496  return groups;
1497}
1498
1499var d3_select = function(s, n) { return n.querySelector(s); },
1500    d3_selectAll = function(s, n) { return n.querySelectorAll(s); },
1501    d3_selectRoot = document.documentElement,
1502    d3_selectMatcher = d3_selectRoot.matchesSelector || d3_selectRoot.webkitMatchesSelector || d3_selectRoot.mozMatchesSelector || d3_selectRoot.msMatchesSelector || d3_selectRoot.oMatchesSelector,
1503    d3_selectMatches = function(n, s) { return d3_selectMatcher.call(n, s); };
1504
1505// Prefer Sizzle, if available.
1506if (typeof Sizzle === "function") {
1507  d3_select = function(s, n) { return Sizzle(s, n)[0]; };
1508  d3_selectAll = function(s, n) { return Sizzle.uniqueSort(Sizzle(s, n)); };
1509  d3_selectMatches = Sizzle.matchesSelector;
1510}
1511
1512var d3_selectionPrototype = [];
1513
1514d3.selection = function() {
1515  return d3_selectionRoot;
1516};
1517
1518d3.selection.prototype = d3_selectionPrototype;
1519d3_selectionPrototype.select = function(selector) {
1520  var subgroups = [],
1521      subgroup,
1522      subnode,
1523      group,
1524      node;
1525
1526  if (typeof selector !== "function") selector = d3_selection_selector(selector);
1527
1528  for (var j = -1, m = this.length; ++j < m;) {
1529    subgroups.push(subgroup = []);
1530    subgroup.parentNode = (group = this[j]).parentNode;
1531    for (var i = -1, n = group.length; ++i < n;) {
1532      if (node = group[i]) {
1533        subgroup.push(subnode = selector.call(node, node.__data__, i));
1534        if (subnode && "__data__" in node) subnode.__data__ = node.__data__;
1535      } else {
1536        subgroup.push(null);
1537      }
1538    }
1539  }
1540
1541  return d3_selection(subgroups);
1542};
1543
1544function d3_selection_selector(selector) {
1545  return function() {
1546    return d3_select(selector, this);
1547  };
1548}
1549d3_selectionPrototype.selectAll = function(selector) {
1550  var subgroups = [],
1551      subgroup,
1552      node;
1553
1554  if (typeof selector !== "function") selector = d3_selection_selectorAll(selector);
1555
1556  for (var j = -1, m = this.length; ++j < m;) {
1557    for (var group = this[j], i = -1, n = group.length; ++i < n;) {
1558      if (node = group[i]) {
1559        subgroups.push(subgroup = d3_array(selector.call(node, node.__data__, i)));
1560        subgroup.parentNode = node;
1561      }
1562    }
1563  }
1564
1565  return d3_selection(subgroups);
1566};
1567
1568function d3_selection_selectorAll(selector) {
1569  return function() {
1570    return d3_selectAll(selector, this);
1571  };
1572}
1573d3_selectionPrototype.attr = function(name, value) {
1574  name = d3.ns.qualify(name);
1575
1576  // If no value is specified, return the first value.
1577  if (arguments.length < 2) {
1578    var node = this.node();
1579    return name.local
1580        ? node.getAttributeNS(name.space, name.local)
1581        : node.getAttribute(name);
1582  }
1583
1584  function attrNull() {
1585    this.removeAttribute(name);
1586  }
1587
1588  function attrNullNS() {
1589    this.removeAttributeNS(name.space, name.local);
1590  }
1591
1592  function attrConstant() {
1593    this.setAttribute(name, value);
1594  }
1595
1596  function attrConstantNS() {
1597    this.setAttributeNS(name.space, name.local, value);
1598  }
1599
1600  function attrFunction() {
1601    var x = value.apply(this, arguments);
1602    if (x == null) this.removeAttribute(name);
1603    else this.setAttribute(name, x);
1604  }
1605
1606  function attrFunctionNS() {
1607    var x = value.apply(this, arguments);
1608    if (x == null) this.removeAttributeNS(name.space, name.local);
1609    else this.setAttributeNS(name.space, name.local, x);
1610  }
1611
1612  return this.each(value == null
1613      ? (name.local ? attrNullNS : attrNull) : (typeof value === "function"
1614      ? (name.local ? attrFunctionNS : attrFunction)
1615      : (name.local ? attrConstantNS : attrConstant)));
1616};
1617d3_selectionPrototype.classed = function(name, value) {
1618  var names = name.split(d3_selection_classedWhitespace),
1619      n = names.length,
1620      i = -1;
1621  if (arguments.length > 1) {
1622    while (++i < n) d3_selection_classed.call(this, names[i], value);
1623    return this;
1624  } else {
1625    while (++i < n) if (!d3_selection_classed.call(this, names[i])) return false;
1626    return true;
1627  }
1628};
1629
1630var d3_selection_classedWhitespace = /\s+/g;
1631
1632function d3_selection_classed(name, value) {
1633  var re = new RegExp("(^|\\s+)" + d3.requote(name) + "(\\s+|$)", "g");
1634
1635  // If no value is specified, return the first value.
1636  if (arguments.length < 2) {
1637    var node = this.node();
1638    if (c = node.classList) return c.contains(name);
1639    var c = node.className;
1640    re.lastIndex = 0;
1641    return re.test(c.baseVal != null ? c.baseVal : c);
1642  }
1643
1644  function classedAdd() {
1645    if (c = this.classList) return c.add(name);
1646    var c = this.className,
1647        cb = c.baseVal != null,
1648        cv = cb ? c.baseVal : c;
1649    re.lastIndex = 0;
1650    if (!re.test(cv)) {
1651      cv = d3_collapse(cv + " " + name);
1652      if (cb) c.baseVal = cv;
1653      else this.className = cv;
1654    }
1655  }
1656
1657  function classedRemove() {
1658    if (c = this.classList) return c.remove(name);
1659    var c = this.className,
1660        cb = c.baseVal != null,
1661        cv = cb ? c.baseVal : c;
1662    cv = d3_collapse(cv.replace(re, " "));
1663    if (cb) c.baseVal = cv;
1664    else this.className = cv;
1665  }
1666
1667  function classedFunction() {
1668    (value.apply(this, arguments)
1669        ? classedAdd
1670        : classedRemove).call(this);
1671  }
1672
1673  return this.each(typeof value === "function"
1674      ? classedFunction : value
1675      ? classedAdd
1676      : classedRemove);
1677}
1678d3_selectionPrototype.style = function(name, value, priority) {
1679  if (arguments.length < 3) priority = "";
1680
1681  // If no value is specified, return the first value.
1682  if (arguments.length < 2) return window
1683      .getComputedStyle(this.node(), null)
1684      .getPropertyValue(name);
1685
1686  function styleNull() {
1687    this.style.removeProperty(name);
1688  }
1689
1690  function styleConstant() {
1691    this.style.setProperty(name, value, priority);
1692  }
1693
1694  function styleFunction() {
1695    var x = value.apply(this, arguments);
1696    if (x == null) this.style.removeProperty(name);
1697    else this.style.setProperty(name, x, priority);
1698  }
1699
1700  return this.each(value == null
1701      ? styleNull : (typeof value === "function"
1702      ? styleFunction : styleConstant));
1703};
1704d3_selectionPrototype.property = function(name, value) {
1705
1706  // If no value is specified, return the first value.
1707  if (arguments.length < 2) return this.node()[name];
1708
1709  function propertyNull() {
1710    delete this[name];
1711  }
1712
1713  function propertyConstant() {
1714    this[name] = value;
1715  }
1716
1717  function propertyFunction() {
1718    var x = value.apply(this, arguments);
1719    if (x == null) delete this[name];
1720    else this[name] = x;
1721  }
1722
1723  return this.each(value == null
1724      ? propertyNull : (typeof value === "function"
1725      ? propertyFunction : propertyConstant));
1726};
1727d3_selectionPrototype.text = function(value) {
1728  return arguments.length < 1
1729      ? this.node().textContent : this.each(typeof value === "function"
1730      ? function() { var v = value.apply(this, arguments); this.textContent = v == null ? "" : v; } : value == null
1731      ? function() { this.textContent = ""; }
1732      : function() { this.textContent = value; });
1733};
1734d3_selectionPrototype.html = function(value) {
1735  return arguments.length < 1
1736      ? this.node().innerHTML : this.each(typeof value === "function"
1737      ? function() { var v = value.apply(this, arguments); this.innerHTML = v == null ? "" : v; } : value == null
1738      ? function() { this.innerHTML = ""; }
1739      : function() { this.innerHTML = value; });
1740};
1741// TODO append(node)?
1742// TODO append(function)?
1743d3_selectionPrototype.append = function(name) {
1744  name = d3.ns.qualify(name);
1745
1746  function append() {
1747    return this.appendChild(document.createElementNS(this.namespaceURI, name));
1748  }
1749
1750  function appendNS() {
1751    return this.appendChild(document.createElementNS(name.space, name.local));
1752  }
1753
1754  return this.select(name.local ? appendNS : append);
1755};
1756// TODO insert(node, function)?
1757// TODO insert(function, string)?
1758// TODO insert(function, function)?
1759d3_selectionPrototype.insert = function(name, before) {
1760  name = d3.ns.qualify(name);
1761
1762  function insert() {
1763    return this.insertBefore(
1764        document.createElementNS(this.namespaceURI, name),
1765        d3_select(before, this));
1766  }
1767
1768  function insertNS() {
1769    return this.insertBefore(
1770        document.createElementNS(name.space, name.local),
1771        d3_select(before, this));
1772  }
1773
1774  return this.select(name.local ? insertNS : insert);
1775};
1776// TODO remove(selector)?
1777// TODO remove(node)?
1778// TODO remove(function)?
1779d3_selectionPrototype.remove = function() {
1780  return this.each(function() {
1781    var parent = this.parentNode;
1782    if (parent) parent.removeChild(this);
1783  });
1784};
1785d3_selectionPrototype.data = function(value, key) {
1786  var i = -1,
1787      n = this.length,
1788      group,
1789      node;
1790
1791  // If no value is specified, return the first value.
1792  if (!arguments.length) {
1793    value = new Array(n = (group = this[0]).length);
1794    while (++i < n) {
1795      if (node = group[i]) {
1796        value[i] = node.__data__;
1797      }
1798    }
1799    return value;
1800  }
1801
1802  function bind(group, groupData) {
1803    var i,
1804        n = group.length,
1805        m = groupData.length,
1806        n0 = Math.min(n, m),
1807        n1 = Math.max(n, m),
1808        updateNodes = [],
1809        enterNodes = [],
1810        exitNodes = [],
1811        node,
1812        nodeData;
1813
1814    if (key) {
1815      var nodeByKeyValue = new d3_Map,
1816          keyValues = [],
1817          keyValue,
1818          j = groupData.length;
1819
1820      for (i = -1; ++i < n;) {
1821        keyValue = key.call(node = group[i], node.__data__, i);
1822        if (nodeByKeyValue.has(keyValue)) {
1823          exitNodes[j++] = node; // duplicate key
1824        } else {
1825          nodeByKeyValue.set(keyValue, node);
1826        }
1827        keyValues.push(keyValue);
1828      }
1829
1830      for (i = -1; ++i < m;) {
1831        keyValue = key.call(groupData, nodeData = groupData[i], i)
1832        if (nodeByKeyValue.has(keyValue)) {
1833          updateNodes[i] = node = nodeByKeyValue.get(keyValue);
1834          node.__data__ = nodeData;
1835          enterNodes[i] = exitNodes[i] = null;
1836        } else {
1837          enterNodes[i] = d3_selection_dataNode(nodeData);
1838          updateNodes[i] = exitNodes[i] = null;
1839        }
1840        nodeByKeyValue.remove(keyValue);
1841      }
1842
1843      for (i = -1; ++i < n;) {
1844        if (nodeByKeyValue.has(keyValues[i])) {
1845          exitNodes[i] = group[i];
1846        }
1847      }
1848    } else {
1849      for (i = -1; ++i < n0;) {
1850        node = group[i];
1851        nodeData = groupData[i];
1852        if (node) {
1853          node.__data__ = nodeData;
1854          updateNodes[i] = node;
1855          enterNodes[i] = exitNodes[i] = null;
1856        } else {
1857          enterNodes[i] = d3_selection_dataNode(nodeData);
1858          updateNodes[i] = exitNodes[i] = null;
1859        }
1860      }
1861      for (; i < m; ++i) {
1862        enterNodes[i] = d3_selection_dataNode(groupData[i]);
1863        updateNodes[i] = exitNodes[i] = null;
1864      }
1865      for (; i < n1; ++i) {
1866        exitNodes[i] = group[i];
1867        enterNodes[i] = updateNodes[i] = null;
1868      }
1869    }
1870
1871    enterNodes.update
1872        = updateNodes;
1873
1874    enterNodes.parentNode
1875        = updateNodes.parentNode
1876        = exitNodes.parentNode
1877        = group.parentNode;
1878
1879    enter.push(enterNodes);
1880    update.push(updateNodes);
1881    exit.push(exitNodes);
1882  }
1883
1884  var enter = d3_selection_enter([]),
1885      update = d3_selection([]),
1886      exit = d3_selection([]);
1887
1888  if (typeof value === "function") {
1889    while (++i < n) {
1890      bind(group = this[i], value.call(group, group.parentNode.__data__, i));
1891    }
1892  } else {
1893    while (++i < n) {
1894      bind(group = this[i], value);
1895    }
1896  }
1897
1898  update.enter = function() { return enter; };
1899  update.exit = function() { return exit; };
1900  return update;
1901};
1902
1903function d3_selection_dataNode(data) {
1904  return {__data__: data};
1905}
1906d3_selectionPrototype.datum =
1907d3_selectionPrototype.map = function(value) {
1908  return arguments.length < 1
1909      ? this.property("__data__")
1910      : this.property("__data__", value);
1911};
1912d3_selectionPrototype.filter = function(filter) {
1913  var subgroups = [],
1914      subgroup,
1915      group,
1916      node;
1917
1918  if (typeof filter !== "function") filter = d3_selection_filter(filter);
1919
1920  for (var j = 0, m = this.length; j < m; j++) {
1921    subgroups.push(subgroup = []);
1922    subgroup.parentNode = (group = this[j]).parentNode;
1923    for (var i = 0, n = group.length; i < n; i++) {
1924      if ((node = group[i]) && filter.call(node, node.__data__, i)) {
1925        subgroup.push(node);
1926      }
1927    }
1928  }
1929
1930  return d3_selection(subgroups);
1931};
1932
1933function d3_selection_filter(selector) {
1934  return function() {
1935    return d3_selectMatches(this, selector);
1936  };
1937}
1938d3_selectionPrototype.order = function() {
1939  for (var j = -1, m = this.length; ++j < m;) {
1940    for (var group = this[j], i = group.length - 1, next = group[i], node; --i >= 0;) {
1941      if (node = group[i]) {
1942        if (next && next !== node.nextSibling) next.parentNode.insertBefore(node, next);
1943        next = node;
1944      }
1945    }
1946  }
1947  return this;
1948};
1949d3_selectionPrototype.sort = function(comparator) {
1950  comparator = d3_selection_sortComparator.apply(this, arguments);
1951  for (var j = -1, m = this.length; ++j < m;) this[j].sort(comparator);
1952  return this.order();
1953};
1954
1955function d3_selection_sortComparator(comparator) {
1956  if (!arguments.length) comparator = d3.ascending;
1957  return function(a, b) {
1958    return comparator(a && a.__data__, b && b.__data__);
1959  };
1960}
1961// type can be namespaced, e.g., "click.foo"
1962// listener can be null for removal
1963d3_selectionPrototype.on = function(type, listener, capture) {
1964  if (arguments.length < 3) capture = false;
1965
1966  // parse the type specifier
1967  var name = "__on" + type, i = type.indexOf(".");
1968  if (i > 0) type = type.substring(0, i);
1969
1970  // if called with only one argument, return the current listener
1971  if (arguments.length < 2) return (i = this.node()[name]) && i._;
1972
1973  // remove the old event listener, and add the new event listener
1974  return this.each(function(d, i) {
1975    var node = this,
1976        o = node[name];
1977
1978    // remove the old listener, if any (using the previously-set capture)
1979    if (o) {
1980      node.removeEventListener(type, o, o.$);
1981      delete node[name];
1982    }
1983
1984    // add the new listener, if any (remembering the capture flag)
1985    if (listener) {
1986      node.addEventListener(type, node[name] = l, l.$ = capture);
1987      l._ = listener; // stash the unwrapped listener for get
1988    }
1989
1990    // wrapped event listener that preserves i
1991    function l(e) {
1992      var o = d3.event; // Events can be reentrant (e.g., focus).
1993      d3.event = e;
1994      try {
1995        listener.call(node, node.__data__, i);
1996      } finally {
1997        d3.event = o;
1998      }
1999    }
2000  });
2001};
2002d3_selectionPrototype.each = function(callback) {
2003  for (var j = -1, m = this.length; ++j < m;) {
2004    for (var group = this[j], i = -1, n = group.length; ++i < n;) {
2005      var node = group[i];
2006      if (node) callback.call(node, node.__data__, i, j);
2007    }
2008  }
2009  return this;
2010};
2011//
2012// Note: assigning to the arguments array simultaneously changes the value of
2013// the corresponding argument!
2014//
2015// TODO The `this` argument probably shouldn't be the first argument to the
2016// callback, anyway, since it's redundant. However, that will require a major
2017// version bump due to backwards compatibility, so I'm not changing it right
2018// away.
2019//
2020d3_selectionPrototype.call = function(callback) {
2021  callback.apply(this, (arguments[0] = this, arguments));
2022  return this;
2023};
2024d3_selectionPrototype.empty = function() {
2025  return !this.node();
2026};
2027d3_selectionPrototype.node = function(callback) {
2028  for (var j = 0, m = this.length; j < m; j++) {
2029    for (var group = this[j], i = 0, n = group.length; i < n; i++) {
2030      var node = group[i];
2031      if (node) return node;
2032    }
2033  }
2034  return null;
2035};
2036d3_selectionPrototype.transition = function() {
2037  var subgroups = [],
2038      subgroup,
2039      node;
2040
2041  for (var j = -1, m = this.length; ++j < m;) {
2042    subgroups.push(subgroup = []);
2043    for (var group = this[j], i = -1, n = group.length; ++i < n;) {
2044      subgroup.push((node = group[i]) ? {node: node, delay: d3_transitionDelay, duration: d3_transitionDuration} : null);
2045    }
2046  }
2047
2048  return d3_transition(subgroups, d3_transitionId || ++d3_transitionNextId, Date.now());
2049};
2050var d3_selectionRoot = d3_selection([[document]]);
2051
2052d3_selectionRoot[0].parentNode = d3_selectRoot;
2053
2054// TODO fast singleton implementation!
2055// TODO select(function)
2056d3.select = function(selector) {
2057  return typeof selector === "string"
2058      ? d3_selectionRoot.select(selector)
2059      : d3_selection([[selector]]); // assume node
2060};
2061
2062// TODO selectAll(function)
2063d3.selectAll = function(selector) {
2064  return typeof selector === "string"
2065      ? d3_selectionRoot.selectAll(selector)
2066      : d3_selection([d3_array(selector)]); // assume node[]
2067};
2068function d3_selection_enter(selection) {
2069  d3_arraySubclass(selection, d3_selection_enterPrototype);
2070  return selection;
2071}
2072
2073var d3_selection_enterPrototype = [];
2074
2075d3.selection.enter = d3_selection_enter;
2076d3.selection.enter.prototype = d3_selection_enterPrototype;
2077
2078d3_selection_enterPrototype.append = d3_selectionPrototype.append;
2079d3_selection_enterPrototype.insert = d3_selectionPrototype.insert;
2080d3_selection_enterPrototype.empty = d3_selectionPrototype.empty;
2081d3_selection_enterPrototype.node = d3_selectionPrototype.node;
2082d3_selection_enterPrototype.select = function(selector) {
2083  var subgroups = [],
2084      subgroup,
2085      subnode,
2086      upgroup,
2087      group,
2088      node;
2089
2090  for (var j = -1, m = this.length; ++j < m;) {
2091    upgroup = (group = this[j]).update;
2092    subgroups.push(subgroup = []);
2093    subgroup.parentNode = group.parentNode;
2094    for (var i = -1, n = group.length; ++i < n;) {
2095      if (node = group[i]) {
2096        subgroup.push(upgroup[i] = subnode = selector.call(group.parentNode, node.__data__, i));
2097        subnode.__data__ = node.__data__;
2098      } else {
2099        subgroup.push(null);
2100      }
2101    }
2102  }
2103
2104  return d3_selection(subgroups);
2105};
2106function d3_transition(groups, id, time) {
2107  d3_arraySubclass(groups, d3_transitionPrototype);
2108
2109  var tweens = new d3_Map,
2110      event = d3.dispatch("start", "end"),
2111      ease = d3_transitionEase;
2112
2113  groups.id = id;
2114
2115  groups.time = time;
2116
2117  groups.tween = function(name, tween) {
2118    if (arguments.length < 2) return tweens.get(name);
2119    if (tween == null) tweens.remove(name);
2120    else tweens.set(name, tween);
2121    return groups;
2122  };
2123
2124  groups.ease = function(value) {
2125    if (!arguments.length) return ease;
2126    ease = typeof value === "function" ? value : d3.ease.apply(d3, arguments);
2127    return groups;
2128  };
2129
2130  groups.each = function(type, listener) {
2131    if (arguments.length < 2) return d3_transition_each.call(groups, type);
2132    event.on(type, listener);
2133    return groups;
2134  };
2135
2136  d3.timer(function(elapsed) {
2137    groups.each(function(d, i, j) {
2138      var tweened = [],
2139          node = this,
2140          delay = groups[j][i].delay,
2141          duration = groups[j][i].duration,
2142          lock = node.__transition__ || (node.__transition__ = {active: 0, count: 0});
2143
2144      ++lock.count;
2145
2146      delay <= elapsed ? start(elapsed) : d3.timer(start, delay, time);
2147
2148      function start(elapsed) {
2149        if (lock.active > id) return stop();
2150        lock.active = id;
2151
2152        tweens.forEach(function(key, value) {
2153          if (tween = value.call(node, d, i)) {
2154            tweened.push(tween);
2155          }
2156        });
2157
2158        event.start.call(node, d, i);
2159        if (!tick(elapsed)) d3.timer(tick, 0, time);
2160        return 1;
2161      }
2162
2163      function tick(elapsed) {
2164        if (lock.active !== id) return stop();
2165
2166        var t = (elapsed - delay) / duration,
2167            e = ease(t),
2168            n = tweened.length;
2169
2170        while (n > 0) {
2171          tweened[--n].call(node, e);
2172        }
2173
2174        if (t >= 1) {
2175          stop();
2176          d3_transitionId = id;
2177          event.end.call(node, d, i);
2178          d3_transitionId = 0;
2179          return 1;
2180        }
2181      }
2182
2183      function stop() {
2184        if (!--lock.count) delete node.__transition__;
2185        return 1;
2186      }
2187    });
2188    return 1;
2189  }, 0, time);
2190
2191  return groups;
2192}
2193
2194var d3_transitionRemove = {};
2195
2196function d3_transitionNull(d, i, a) {
2197  return a != "" && d3_transitionRemove;
2198}
2199
2200function d3_transitionTween(name, b) {
2201  var interpolate = d3_interpolateByName(name);
2202
2203  function transitionFunction(d, i, a) {
2204    var v = b.call(this, d, i);
2205    return v == null
2206        ? a != "" && d3_transitionRemove
2207        : a != v && interpolate(a, v);
2208  }
2209
2210  function transitionString(d, i, a) {
2211    return a != b && interpolate(a, b);
2212  }
2213
2214  return typeof b === "function" ? transitionFunction
2215      : b == null ? d3_transitionNull
2216      : (b += "", transitionString);
2217}
2218
2219var d3_transitionPrototype = [],
2220    d3_transitionNextId = 0,
2221    d3_transitionId = 0,
2222    d3_transitionDefaultDelay = 0,
2223    d3_transitionDefaultDuration = 250,
2224    d3_transitionDefaultEase = d3.ease("cubic-in-out"),
2225    d3_transitionDelay = d3_transitionDefaultDelay,
2226    d3_transitionDuration = d3_transitionDefaultDuration,
2227    d3_transitionEase = d3_transitionDefaultEase;
2228
2229d3_transitionPrototype.call = d3_selectionPrototype.call;
2230
2231d3.transition = function(selection) {
2232  return arguments.length
2233      ? (d3_transitionId ? selection.transition() : selection)
2234      : d3_selectionRoot.transition();
2235};
2236
2237d3.transition.prototype = d3_transitionPrototype;
2238d3_transitionPrototype.select = function(selector) {
2239  var subgroups = [],
2240      subgroup,
2241      subnode,
2242      node;
2243
2244  if (typeof selector !== "function") selector = d3_selection_selector(selector);
2245
2246  for (var j = -1, m = this.length; ++j < m;) {
2247    subgroups.push(subgroup = []);
2248    for (var group = this[j], i = -1, n = group.length; ++i < n;) {
2249      if ((node = group[i]) && (subnode = selector.call(node.node, node.node.__data__, i))) {
2250        if ("__data__" in node.node) subnode.__data__ = node.node.__data__;
2251        subgroup.push({node: subnode, delay: node.delay, duration: node.duration});
2252      } else {
2253        subgroup.push(null);
2254      }
2255    }
2256  }
2257
2258  return d3_transition(subgroups, this.id, this.time).ease(this.ease());
2259};
2260d3_transitionPrototype.selectAll = function(selector) {
2261  var subgroups = [],
2262      subgroup,
2263      subnodes,
2264      node;
2265
2266  if (typeof selector !== "function") selector = d3_selection_selectorAll(selector);
2267
2268  for (var j = -1, m = this.length; ++j < m;) {
2269    for (var group = this[j], i = -1, n = group.length; ++i < n;) {
2270      if (node = group[i]) {
2271        subnodes = selector.call(node.node, node.node.__data__, i);
2272        subgroups.push(subgroup = []);
2273        for (var k = -1, o = subnodes.length; ++k < o;) {
2274          subgroup.push({node: subnodes[k], delay: node.delay, duration: node.duration});
2275        }
2276      }
2277    }
2278  }
2279
2280  return d3_transition(subgroups, this.id, this.time).ease(this.ease());
2281};
2282d3_transitionPrototype.attr = function(name, value) {
2283  return this.attrTween(name, d3_transitionTween(name, value));
2284};
2285
2286d3_transitionPrototype.attrTween = function(nameNS, tween) {
2287  var name = d3.ns.qualify(nameNS);
2288
2289  function attrTween(d, i) {
2290    var f = tween.call(this, d, i, this.getAttribute(name));
2291    return f === d3_transitionRemove
2292        ? (this.removeAttribute(name), null)
2293        : f && function(t) { this.setAttribute(name, f(t)); };
2294  }
2295
2296  function attrTweenNS(d, i) {
2297    var f = tween.call(this, d, i, this.getAttributeNS(name.space, name.local));
2298    return f === d3_transitionRemove
2299        ? (this.removeAttributeNS(name.space, name.local), null)
2300        : f && function(t) { this.setAttributeNS(name.space, name.local, f(t)); };
2301  }
2302
2303  return this.tween("attr." + nameNS, name.local ? attrTweenNS : attrTween);
2304};
2305d3_transitionPrototype.style = function(name, value, priority) {
2306  if (arguments.length < 3) priority = "";
2307  return this.styleTween(name, d3_transitionTween(name, value), priority);
2308};
2309
2310d3_transitionPrototype.styleTween = function(name, tween, priority) {
2311  if (arguments.length < 3) priority = "";
2312  return this.tween("style." + name, function(d, i) {
2313    var f = tween.call(this, d, i, window.getComputedStyle(this, null).getPropertyValue(name));
2314    return f === d3_transitionRemove
2315        ? (this.style.removeProperty(name), null)
2316        : f && function(t) { this.style.setProperty(name, f(t), priority); };
2317  });
2318};
2319d3_transitionPrototype.text = function(value) {
2320  return this.tween("text", function(d, i) {
2321    this.textContent = typeof value === "function"
2322        ? value.call(this, d, i)
2323        : value;
2324  });
2325};
2326d3_transitionPrototype.remove = function() {
2327  return this.each("end.transition", function() {
2328    var p;
2329    if (!this.__transition__ && (p = this.parentNode)) p.removeChild(this);
2330  });
2331};
2332d3_transitionPrototype.delay = function(value) {
2333  var groups = this;
2334  return groups.each(typeof value === "function"
2335      ? function(d, i, j) { groups[j][i].delay = value.apply(this, arguments) | 0; }
2336      : (value = value | 0, function(d, i, j) { groups[j][i].delay = value; }));
2337};
2338d3_transitionPrototype.duration = function(value) {
2339  var groups = this;
2340  return groups.each(typeof value === "function"
2341      ? function(d, i, j) { groups[j][i].duration = Math.max(1, value.apply(this, arguments) | 0); }
2342      : (value = Math.max(1, value | 0), function(d, i, j) { groups[j][i].duration = value; }));
2343};
2344function d3_transition_each(callback) {
2345  var id = d3_transitionId,
2346      ease = d3_transitionEase,
2347      delay = d3_transitionDelay,
2348      duration = d3_transitionDuration;
2349
2350  d3_transitionId = this.id;
2351  d3_transitionEase = this.ease();
2352  for (var j = 0, m = this.length; j < m; j++) {
2353    for (var group = this[j], i = 0, n = group.length; i < n; i++) {
2354      var node = group[i];
2355      if (node) {
2356        d3_transitionDelay = this[j][i].delay;
2357        d3_transitionDuration = this[j][i].duration;
2358        callback.call(node = node.node, node.__data__, i, j);
2359      }
2360    }
2361  }
2362
2363  d3_transitionId = id;
2364  d3_transitionEase = ease;
2365  d3_transitionDelay = delay;
2366  d3_transitionDuration = duration;
2367  return this;
2368}
2369d3_transitionPrototype.transition = function() {
2370  return this.select(d3_this);
2371};
2372var d3_timer_queue = null,
2373    d3_timer_interval, // is an interval (or frame) active?
2374    d3_timer_timeout; // is a timeout active?
2375
2376// The timer will continue to fire until callback returns true.
2377d3.timer = function(callback, delay, then) {
2378  var found = false,
2379      t0,
2380      t1 = d3_timer_queue;
2381
2382  if (arguments.length < 3) {
2383    if (arguments.length < 2) delay = 0;
2384    else if (!isFinite(delay)) return;
2385    then = Date.now();
2386  }
2387
2388  // See if the callback's already in the queue.
2389  while (t1) {
2390    if (t1.callback === callback) {
2391      t1.then = then;
2392      t1.delay = delay;
2393      found = true;
2394      break;
2395    }
2396    t0 = t1;
2397    t1 = t1.next;
2398  }
2399
2400  // Otherwise, add the callback to the queue.
2401  if (!found) d3_timer_queue = {
2402    callback: callback,
2403    then: then,
2404    delay: delay,
2405    next: d3_timer_queue
2406  };
2407
2408  // Start animatin'!
2409  if (!d3_timer_interval) {
2410    d3_timer_timeout = clearTimeout(d3_timer_timeout);
2411    d3_timer_interval = 1;
2412    d3_timer_frame(d3_timer_step);
2413  }
2414}
2415
2416function d3_timer_step() {
2417  var elapsed,
2418      now = Date.now(),
2419      t1 = d3_timer_queue;
2420
2421  while (t1) {
2422    elapsed = now - t1.then;
2423    if (elapsed >= t1.delay) t1.flush = t1.callback(elapsed);
2424    t1 = t1.next;
2425  }
2426
2427  var delay = d3_timer_flush() - now;
2428  if (delay > 24) {
2429    if (isFinite(delay)) {
2430      clearTimeout(d3_timer_timeout);
2431      d3_timer_timeout = setTimeout(d3_timer_step, delay);
2432    }
2433    d3_timer_interval = 0;
2434  } else {
2435    d3_timer_interval = 1;
2436    d3_timer_frame(d3_timer_step);
2437  }
2438}
2439
2440d3.timer.flush = function() {
2441  var elapsed,
2442      now = Date.now(),
2443      t1 = d3_timer_queue;
2444
2445  while (t1) {
2446    elapsed = now - t1.then;
2447    if (!t1.delay) t1.flush = t1.callback(elapsed);
2448    t1 = t1.next;
2449  }
2450
2451  d3_timer_flush();
2452};
2453
2454// Flush after callbacks, to avoid concurrent queue modification.
2455function d3_timer_flush() {
2456  var t0 = null,
2457      t1 = d3_timer_queue,
2458      then = Infinity;
2459  while (t1) {
2460    if (t1.flush) {
2461      t1 = t0 ? t0.next = t1.next : d3_timer_queue = t1.next;
2462    } else {
2463      then = Math.min(then, t1.then + t1.delay);
2464      t1 = (t0 = t1).next;
2465    }
2466  }
2467  return then;
2468}
2469
2470var d3_timer_frame = window.requestAnimationFrame
2471    || window.webkitRequestAnimationFrame
2472    || window.mozRequestAnimationFrame
2473    || window.oRequestAnimationFrame
2474    || window.msRequestAnimationFrame
2475    || function(callback) { setTimeout(callback, 17); };
2476d3.transform = function(string) {
2477  var g = document.createElementNS(d3.ns.prefix.svg, "g"),
2478      identity = {a: 1, b: 0, c: 0, d: 1, e: 0, f: 0};
2479  return (d3.transform = function(string) {
2480    g.setAttribute("transform", string);
2481    var t = g.transform.baseVal.consolidate();
2482    return new d3_transform(t ? t.matrix : identity);
2483  })(string);
2484};
2485
2486// Compute x-scale and normalize the first row.
2487// Compute shear and make second row orthogonal to first.
2488// Compute y-scale and normalize the second row.
2489// Finally, compute the rotation.
2490function d3_transform(m) {
2491  var r0 = [m.a, m.b],
2492      r1 = [m.c, m.d],
2493      kx = d3_transformNormalize(r0),
2494      kz = d3_transformDot(r0, r1),
2495      ky = d3_transformNormalize(d3_transformCombine(r1, r0, -kz)) || 0;
2496  if (r0[0] * r1[1] < r1[0] * r0[1]) {
2497    r0[0] *= -1;
2498    r0[1] *= -1;
2499    kx *= -1;
2500    kz *= -1;
2501  }
2502  this.rotate = (kx ? Math.atan2(r0[1], r0[0]) : Math.atan2(-r1[0], r1[1])) * d3_transformDegrees;
2503  this.translate = [m.e, m.f];
2504  this.scale = [kx, ky];
2505  this.skew = ky ? Math.atan2(kz, ky) * d3_transformDegrees : 0;
2506};
2507
2508d3_transform.prototype.toString = function() {
2509  return "translate(" + this.translate
2510      + ")rotate(" + this.rotate
2511      + ")skewX(" + this.skew
2512      + ")scale(" + this.scale
2513      + ")";
2514};
2515
2516function d3_transformDot(a, b) {
2517  return a[0] * b[0] + a[1] * b[1];
2518}
2519
2520function d3_transformNormalize(a) {
2521  var k = Math.sqrt(d3_transformDot(a, a));
2522  if (k) {
2523    a[0] /= k;
2524    a[1] /= k;
2525  }
2526  return k;
2527}
2528
2529function d3_transformCombine(a, b, k) {
2530  a[0] += k * b[0];
2531  a[1] += k * b[1];
2532  return a;
2533}
2534
2535var d3_transformDegrees = 180 / Math.PI;
2536d3.mouse = function(container) {
2537  return d3_mousePoint(container, d3_eventSource());
2538};
2539
2540// https://bugs.webkit.org/show_bug.cgi?id=44083
2541var d3_mouse_bug44083 = /WebKit/.test(navigator.userAgent) ? -1 : 0;
2542
2543function d3_mousePoint(container, e) {
2544  var svg = container.ownerSVGElement || container;
2545  if (svg.createSVGPoint) {
2546    var point = svg.createSVGPoint();
2547    if ((d3_mouse_bug44083 < 0) && (window.scrollX || window.scrollY)) {
2548      svg = d3.select(document.body)
2549        .append("svg")
2550          .style("position", "absolute")
2551          .style("top", 0)
2552          .style("left", 0);
2553      var ctm = svg[0][0].getScreenCTM();
2554      d3_mouse_bug44083 = !(ctm.f || ctm.e);
2555      svg.remove();
2556    }
2557    if (d3_mouse_bug44083) {
2558      point.x = e.pageX;
2559      point.y = e.pageY;
2560    } else {
2561      point.x = e.clientX;
2562      point.y = e.clientY;
2563    }
2564    point = point.matrixTransform(container.getScreenCTM().inverse());
2565    return [point.x, point.y];
2566  }
2567  var rect = container.getBoundingClientRect();
2568  return [e.clientX - rect.left - container.clientLeft, e.clientY - rect.top - container.clientTop];
2569};
2570d3.touches = function(container, touches) {
2571  if (arguments.length < 2) touches = d3_eventSource().touches;
2572  return touches ? d3_array(touches).map(function(touch) {
2573    var point = d3_mousePoint(container, touch);
2574    point.identifier = touch.identifier;
2575    return point;
2576  }) : [];
2577};
2578function d3_noop() {}
2579d3.scale = {};
2580
2581function d3_scaleExtent(domain) {
2582  var start = domain[0], stop = domain[domain.length - 1];
2583  return start < stop ? [start, stop] : [stop, start];
2584}
2585
2586function d3_scaleRange(scale) {
2587  return scale.rangeExtent ? scale.rangeExtent() : d3_scaleExtent(scale.range());
2588}
2589function d3_scale_nice(domain, nice) {
2590  var i0 = 0,
2591      i1 = domain.length - 1,
2592      x0 = domain[i0],
2593      x1 = domain[i1],
2594      dx;
2595
2596  if (x1 < x0) {
2597    dx = i0; i0 = i1; i1 = dx;
2598    dx = x0; x0 = x1; x1 = dx;
2599  }
2600
2601  if (dx = x1 - x0) {
2602    nice = nice(dx);
2603    domain[i0] = nice.floor(x0);
2604    domain[i1] = nice.ceil(x1);
2605  }
2606
2607  return domain;
2608}
2609
2610function d3_scale_niceDefault() {
2611  return Math;
2612}
2613d3.scale.linear = function() {
2614  return d3_scale_linear([0, 1], [0, 1], d3.interpolate, false);
2615};
2616
2617function d3_scale_linear(domain, range, interpolate, clamp) {
2618  var output,
2619      input;
2620
2621  function rescale() {
2622    var linear = Math.min(domain.length, range.length) > 2 ? d3_scale_polylinear : d3_scale_bilinear,
2623        uninterpolate = clamp ? d3_uninterpolateClamp : d3_uninterpolateNumber;
2624    output = linear(domain, range, uninterpolate, interpolate);
2625    input = linear(range, domain, uninterpolate, d3.interpolate);
2626    return scale;
2627  }
2628
2629  function scale(x) {
2630    return output(x);
2631  }
2632
2633  // Note: requires range is coercible to number!
2634  scale.invert = function(y) {
2635    return input(y);
2636  };
2637
2638  scale.domain = function(x) {
2639    if (!arguments.length) return domain;
2640    domain = x.map(Number);
2641    return rescale();
2642  };
2643
2644  scale.range = function(x) {
2645    if (!arguments.length) return range;
2646    range = x;
2647    return rescale();
2648  };
2649
2650  scale.rangeRound = function(x) {
2651    return scale.range(x).interpolate(d3.interpolateRound);
2652  };
2653
2654  scale.clamp = function(x) {
2655    if (!arguments.length) return clamp;
2656    clamp = x;
2657    return rescale();
2658  };
2659
2660  scale.interpolate = function(x) {
2661    if (!arguments.length) return interpolate;
2662    interpolate = x;
2663    return rescale();
2664  };
2665
2666  scale.ticks = function(m) {
2667    return d3_scale_linearTicks(domain, m);
2668  };
2669
2670  scale.tickFormat = function(m) {
2671    return d3_scale_linearTickFormat(domain, m);
2672  };
2673
2674  scale.nice = function() {
2675    d3_scale_nice(domain, d3_scale_linearNice);
2676    return rescale();
2677  };
2678
2679  scale.copy = function() {
2680    return d3_scale_linear(domain, range, interpolate, clamp);
2681  };
2682
2683  return rescale();
2684}
2685
2686function d3_scale_linearRebind(scale, linear) {
2687  return d3.rebind(scale, linear, "range", "rangeRound", "interpolate", "clamp");
2688}
2689
2690function d3_scale_linearNice(dx) {
2691  dx = Math.pow(10, Math.round(Math.log(dx) / Math.LN10) - 1);
2692  return {
2693    floor: function(x) { return Math.floor(x / dx) * dx; },
2694    ceil: function(x) { return Math.ceil(x / dx) * dx; }
2695  };
2696}
2697
2698function d3_scale_linearTickRange(domain, m) {
2699  var extent = d3_scaleExtent(domain),
2700      span = extent[1] - extent[0],
2701      step = Math.pow(10, Math.floor(Math.log(span / m) / Math.LN10)),
2702      err = m / span * step;
2703
2704  // Filter ticks to get closer to the desired count.
2705  if (err <= .15) step *= 10;
2706  else if (err <= .35) step *= 5;
2707  else if (err <= .75) step *= 2;
2708
2709  // Round start and stop values to step interval.
2710  extent[0] = Math.ceil(extent[0] / step) * step;
2711  extent[1] = Math.floor(extent[1] / step) * step + step * .5; // inclusive
2712  extent[2] = step;
2713  return extent;
2714}
2715
2716function d3_scale_linearTicks(domain, m) {
2717  return d3.range.apply(d3, d3_scale_linearTickRange(domain, m));
2718}
2719
2720function d3_scale_linearTickFormat(domain, m) {
2721  return d3.format(",." + Math.max(0, -Math.floor(Math.log(d3_scale_linearTickRange(domain, m)[2]) / Math.LN10 + .01)) + "f");
2722}
2723function d3_scale_bilinear(domain, range, uninterpolate, interpolate) {
2724  var u = uninterpolate(domain[0], domain[1]),
2725      i = interpolate(range[0], range[1]);
2726  return function(x) {
2727    return i(u(x));
2728  };
2729}
2730function d3_scale_polylinear(domain, range, uninterpolate, interpolate) {
2731  var u = [],
2732      i = [],
2733      j = 0,
2734      k = Math.min(domain.length, range.length) - 1;
2735
2736  // Handle descending domains.
2737  if (domain[k] < domain[0]) {
2738    domain = domain.slice().reverse();
2739    range = range.slice().reverse();
2740  }
2741
2742  while (++j <= k) {
2743    u.push(uninterpolate(domain[j - 1], domain[j]));
2744    i.push(interpolate(range[j - 1], range[j]));
2745  }
2746
2747  return function(x) {
2748    var j = d3.bisect(domain, x, 1, k) - 1;
2749    return i[j](u[j](x));
2750  };
2751}
2752d3.scale.log = function() {
2753  return d3_scale_log(d3.scale.linear(), d3_scale_logp);
2754};
2755
2756function d3_scale_log(linear, log) {
2757  var pow = log.pow;
2758
2759  function scale(x) {
2760    return linear(log(x));
2761  }
2762
2763  scale.invert = function(x) {
2764    return pow(linear.invert(x));
2765  };
2766
2767  scale.domain = function(x) {
2768    if (!arguments.length) return linear.domain().map(pow);
2769    log = x[0] < 0 ? d3_scale_logn : d3_scale_logp;
2770    pow = log.pow;
2771    linear.domain(x.map(log));
2772    return scale;
2773  };
2774
2775  scale.nice = function() {
2776    linear.domain(d3_scale_nice(linear.domain(), d3_scale_niceDefault));
2777    return scale;
2778  };
2779
2780  scale.ticks = function() {
2781    var extent = d3_scaleExtent(linear.domain()),
2782        ticks = [];
2783    if (extent.every(isFinite)) {
2784      var i = Math.floor(extent[0]),
2785          j = Math.ceil(extent[1]),
2786          u = pow(extent[0]),
2787          v = pow(extent[1]);
2788      if (log === d3_scale_logn) {
2789        ticks.push(pow(i));
2790        for (; i++ < j;) for (var k = 9; k > 0; k--) ticks.push(pow(i) * k);
2791      } else {
2792        for (; i < j; i++) for (var k = 1; k < 10; k++) ticks.push(pow(i) * k);
2793        ticks.push(pow(i));
2794      }
2795      for (i = 0; ticks[i] < u; i++) {} // strip small values
2796      for (j = ticks.length; ticks[j - 1] > v; j--) {} // strip big values
2797      ticks = ticks.slice(i, j);
2798    }
2799    return ticks;
2800  };
2801
2802  scale.tickFormat = function(n, format) {
2803    if (arguments.length < 2) format = d3_scale_logFormat;
2804    if (arguments.length < 1) return format;
2805    var k = n / scale.ticks().length,
2806        f = log === d3_scale_logn ? (e = -1e-12, Math.floor) : (e = 1e-12, Math.ceil),
2807        e;
2808    return function(d) {
2809      return d / pow(f(log(d) + e)) < k ? format(d) : "";
2810    };
2811  };
2812
2813  scale.copy = function() {
2814    return d3_scale_log(linear.copy(), log);
2815  };
2816
2817  return d3_scale_linearRebind(scale, linear);
2818}
2819
2820var d3_scale_logFormat = d3.format(".0e");
2821
2822function d3_scale_logp(x) {
2823  return Math.log(x < 0 ? 0 : x) / Math.LN10;
2824}
2825
2826function d3_scale_logn(x) {
2827  return -Math.log(x > 0 ? 0 : -x) / Math.LN10;
2828}
2829
2830d3_scale_logp.pow = function(x) {
2831  return Math.pow(10, x);
2832};
2833
2834d3_scale_logn.pow = function(x) {
2835  return -Math.pow(10, -x);
2836};
2837d3.scale.pow = function() {
2838  return d3_scale_pow(d3.scale.linear(), 1);
2839};
2840
2841function d3_scale_pow(linear, exponent) {
2842  var powp = d3_scale_powPow(exponent),
2843      powb = d3_scale_powPow(1 / exponent);
2844
2845  function scale(x) {
2846    return linear(powp(x));
2847  }
2848
2849  scale.invert = function(x) {
2850    return powb(linear.invert(x));
2851  };
2852
2853  scale.domain = function(x) {
2854    if (!arguments.length) return linear.domain().map(powb);
2855    linear.domain(x.map(powp));
2856    return scale;
2857  };
2858
2859  scale.ticks = function(m) {
2860    return d3_scale_linearTicks(scale.domain(), m);
2861  };
2862
2863  scale.tickFormat = function(m) {
2864    return d3_scale_linearTickFormat(scale.domain(), m);
2865  };
2866
2867  scale.nice = function() {
2868    return scale.domain(d3_scale_nice(scale.domain(), d3_scale_linearNice));
2869  };
2870
2871  scale.exponent = function(x) {
2872    if (!arguments.length) return exponent;
2873    var domain = scale.domain();
2874    powp = d3_scale_powPow(exponent = x);
2875    powb = d3_scale_powPow(1 / exponent);
2876    return scale.domain(domain);
2877  };
2878
2879  scale.copy = function() {
2880    return d3_scale_pow(linear.copy(), exponent);
2881  };
2882
2883  return d3_scale_linearRebind(scale, linear);
2884}
2885
2886function d3_scale_powPow(e) {
2887  return function(x) {
2888    return x < 0 ? -Math.pow(-x, e) : Math.pow(x, e);
2889  };
2890}
2891d3.scale.sqrt = function() {
2892  return d3.scale.pow().exponent(.5);
2893};
2894d3.scale.ordinal = function() {
2895  return d3_scale_ordinal([], {t: "range", x: []});
2896};
2897
2898function d3_scale_ordinal(domain, ranger) {
2899  var index,
2900      range,
2901      rangeBand;
2902
2903  function scale(x) {
2904    return range[((index.get(x) || index.set(x, domain.push(x))) - 1) % range.length];
2905  }
2906
2907  function steps(start, step) {
2908    return d3.range(domain.length).map(function(i) { return start + step * i; });
2909  }
2910
2911  scale.domain = function(x) {
2912    if (!arguments.length) return domain;
2913    domain = [];
2914    index = new d3_Map;
2915    var i = -1, n = x.length, xi;
2916    while (++i < n) if (!index.has(xi = x[i])) index.set(xi, domain.push(xi));
2917    return scale[ranger.t](ranger.x, ranger.p);
2918  };
2919
2920  scale.range = function(x) {
2921    if (!arguments.length) return range;
2922    range = x;
2923    rangeBand = 0;
2924    ranger = {t: "range", x: x};
2925    return scale;
2926  };
2927
2928  scale.rangePoints = function(x, padding) {
2929    if (arguments.length < 2) padding = 0;
2930    var start = x[0],
2931        stop = x[1],
2932        step = (stop - start) / (domain.length - 1 + padding);
2933    range = steps(domain.length < 2 ? (start + stop) / 2 : start + step * padding / 2, step);
2934    rangeBand = 0;
2935    ranger = {t: "rangePoints", x: x, p: padding};
2936    return scale;
2937  };
2938
2939  scale.rangeBands = function(x, padding) {
2940    if (arguments.length < 2) padding = 0;
2941    var reverse = x[1] < x[0],
2942        start = x[reverse - 0],
2943        stop = x[1 - reverse],
2944        step = (stop - start) / (domain.length + padding);
2945    range = steps(start + step * padding, step);
2946    if (reverse) range.reverse();
2947    rangeBand = step * (1 - padding);
2948    ranger = {t: "rangeBands", x: x, p: padding};
2949    return scale;
2950  };
2951
2952  scale.rangeRoundBands = function(x, padding) {
2953    if (arguments.length < 2) padding = 0;
2954    var reverse = x[1] < x[0],
2955        start = x[reverse - 0],
2956        stop = x[1 - reverse],
2957        step = Math.floor((stop - start) / (domain.length + padding)),
2958        error = stop - start - (domain.length - padding) * step;
2959    range = steps(start + Math.round(error / 2), step);
2960    if (reverse) range.reverse();
2961    rangeBand = Math.round(step * (1 - padding));
2962    ranger = {t: "rangeRoundBands", x: x, p: padding};
2963    return scale;
2964  };
2965
2966  scale.rangeBand = function() {
2967    return rangeBand;
2968  };
2969
2970  scale.rangeExtent = function() {
2971    return d3_scaleExtent(ranger.x);
2972  };
2973
2974  scale.copy = function() {
2975    return d3_scale_ordinal(domain, ranger);
2976  };
2977
2978  return scale.domain(domain);
2979}
2980/*
2981 * This product includes color specifications and designs developed by Cynthia
2982 * Brewer (http://colorbrewer.org/). See lib/colorbrewer for more information.
2983 */
2984
2985d3.scale.category10 = function() {
2986  return d3.scale.ordinal().range(d3_category10);
2987};
2988
2989d3.scale.category20 = function() {
2990  return d3.scale.ordinal().range(d3_category20);
2991};
2992
2993d3.scale.category20b = function() {
2994  return d3.scale.ordinal().range(d3_category20b);
2995};
2996
2997d3.scale.category20c = function() {
2998  return d3.scale.ordinal().range(d3_category20c);
2999};
3000
3001var d3_category10 = [
3002  "#1f77b4", "#ff7f0e", "#2ca02c", "#d62728", "#9467bd",
3003  "#8c564b", "#e377c2", "#7f7f7f", "#bcbd22", "#17becf"
3004];
3005
3006var d3_category20 = [
3007  "#1f77b4", "#aec7e8",
3008  "#ff7f0e", "#ffbb78",
3009  "#2ca02c", "#98df8a",
3010  "#d62728", "#ff9896",
3011  "#9467bd", "#c5b0d5",
3012  "#8c564b", "#c49c94",
3013  "#e377c2", "#f7b6d2",
3014  "#7f7f7f", "#c7c7c7",
3015  "#bcbd22", "#dbdb8d",
3016  "#17becf", "#9edae5"
3017];
3018
3019var d3_category20b = [
3020  "#393b79", "#5254a3", "#6b6ecf", "#9c9ede",
3021  "#637939", "#8ca252", "#b5cf6b", "#cedb9c",
3022  "#8c6d31", "#bd9e39", "#e7ba52", "#e7cb94",
3023  "#843c39", "#ad494a", "#d6616b", "#e7969c",
3024  "#7b4173", "#a55194", "#ce6dbd", "#de9ed6"
3025];
3026
3027var d3_category20c = [
3028  "#3182bd", "#6baed6", "#9ecae1", "#c6dbef",
3029  "#e6550d", "#fd8d3c", "#fdae6b", "#fdd0a2",
3030  "#31a354", "#74c476", "#a1d99b", "#c7e9c0",
3031  "#756bb1", "#9e9ac8", "#bcbddc", "#dadaeb",
3032  "#636363", "#969696", "#bdbdbd", "#d9d9d9"
3033];
3034d3.scale.quantile = function() {
3035  return d3_scale_quantile([], []);
3036};
3037
3038function d3_scale_quantile(domain, range) {
3039  var thresholds;
3040
3041  function rescale() {
3042    var k = 0,
3043        n = domain.length,
3044        q = range.length;
3045    thresholds = [];
3046    while (++k < q) thresholds[k - 1] = d3.quantile(domain, k / q);
3047    return scale;
3048  }
3049
3050  function scale(x) {
3051    if (isNaN(x = +x)) return NaN;
3052    return range[d3.bisect(thresholds, x)];
3053  }
3054
3055  scale.domain = function(x) {
3056    if (!arguments.length) return domain;
3057    domain = x.filter(function(d) { return !isNaN(d); }).sort(d3.ascending);
3058    return rescale();
3059  };
3060
3061  scale.range = function(x) {
3062    if (!arguments.length) return range;
3063    range = x;
3064    return rescale();
3065  };
3066
3067  scale.quantiles = function() {
3068    return thresholds;
3069  };
3070
3071  scale.copy = function() {
3072    return d3_scale_quantile(domain, range); // copy on write!
3073  };
3074
3075  return rescale();
3076}
3077d3.scale.quantize = function() {
3078  return d3_scale_quantize(0, 1, [0, 1]);
3079};
3080
3081function d3_scale_quantize(x0, x1, range) {
3082  var kx, i;
3083
3084  function scale(x) {
3085    return range[Math.max(0, Math.min(i, Math.floor(kx * (x - x0))))];
3086  }
3087
3088  function rescale() {
3089    kx = range.length / (x1 - x0);
3090    i = range.length - 1;
3091    return scale;
3092  }
3093
3094  scale.domain = function(x) {
3095    if (!arguments.length) return [x0, x1];
3096    x0 = +x[0];
3097    x1 = +x[x.length - 1];
3098    return rescale();
3099  };
3100
3101  scale.range = function(x) {
3102    if (!arguments.length) return range;
3103    range = x;
3104    return rescale();
3105  };
3106
3107  scale.copy = function() {
3108    return d3_scale_quantize(x0, x1, range); // copy on write
3109  };
3110
3111  return rescale();
3112}
3113d3.scale.identity = function() {
3114  return d3_scale_identity([0, 1]);
3115};
3116
3117function d3_scale_identity(domain) {
3118
3119  function identity(x) { return +x; }
3120
3121  identity.invert = identity;
3122
3123  identity.domain = identity.range = function(x) {
3124    if (!arguments.length) return domain;
3125    domain = x.map(identity);
3126    return identity;
3127  };
3128
3129  identity.ticks = function(m) {
3130    return d3_scale_linearTicks(domain, m);
3131  };
3132
3133  identity.tickFormat = function(m) {
3134    return d3_scale_linearTickFormat(domain, m);
3135  };
3136
3137  identity.copy = function() {
3138    return d3_scale_identity(domain);
3139  };
3140
3141  return identity;
3142}
3143d3.svg = {};
3144d3.svg.arc = function() {
3145  var innerRadius = d3_svg_arcInnerRadius,
3146      outerRadius = d3_svg_arcOuterRadius,
3147      startAngle = d3_svg_arcStartAngle,
3148      endAngle = d3_svg_arcEndAngle;
3149
3150  function arc() {
3151    var r0 = innerRadius.apply(this, arguments),
3152        r1 = outerRadius.apply(this, arguments),
3153        a0 = startAngle.apply(this, arguments) + d3_svg_arcOffset,
3154        a1 = endAngle.apply(this, arguments) + d3_svg_arcOffset,
3155        da = (a1 < a0 && (da = a0, a0 = a1, a1 = da), a1 - a0),
3156        df = da < Math.PI ? "0" : "1",
3157        c0 = Math.cos(a0),
3158        s0 = Math.sin(a0),
3159        c1 = Math.cos(a1),
3160        s1 = Math.sin(a1);
3161    return da >= d3_svg_arcMax
3162      ? (r0
3163      ? "M0," + r1
3164      + "A" + r1 + "," + r1 + " 0 1,1 0," + (-r1)
3165      + "A" + r1 + "," + r1 + " 0 1,1 0," + r1
3166      + "M0," + r0
3167      + "A" + r0 + "," + r0 + " 0 1,0 0," + (-r0)
3168      + "A" + r0 + "," + r0 + " 0 1,0 0," + r0
3169      + "Z"
3170      : "M0," + r1
3171      + "A" + r1 + "," + r1 + " 0 1,1 0," + (-r1)
3172      + "A" + r1 + "," + r1 + " 0 1,1 0," + r1
3173      + "Z")
3174      : (r0
3175      ? "M" + r1 * c0 + "," + r1 * s0
3176      + "A" + r1 + "," + r1 + " 0 " + df + ",1 " + r1 * c1 + "," + r1 * s1
3177      + "L" + r0 * c1 + "," + r0 * s1
3178      + "A" + r0 + "," + r0 + " 0 " + df + ",0 " + r0 * c0 + "," + r0 * s0
3179      + "Z"
3180      : "M" + r1 * c0 + "," + r1 * s0
3181      + "A" + r1 + "," + r1 + " 0 " + df + ",1 " + r1 * c1 + "," + r1 * s1
3182      + "L0,0"
3183      + "Z");
3184  }
3185
3186  arc.innerRadius = function(v) {
3187    if (!arguments.length) return innerRadius;
3188    innerRadius = d3.functor(v);
3189    return arc;
3190  };
3191
3192  arc.outerRadius = function(v) {
3193    if (!arguments.length) return outerRadius;
3194    outerRadius = d3.functor(v);
3195    return arc;
3196  };
3197
3198  arc.startAngle = function(v) {
3199    if (!arguments.length) return startAngle;
3200    startAngle = d3.functor(v);
3201    return arc;
3202  };
3203
3204  arc.endAngle = function(v) {
3205    if (!arguments.length) return endAngle;
3206    endAngle = d3.functor(v);
3207    return arc;
3208  };
3209
3210  arc.centroid = function() {
3211    var r = (innerRadius.apply(this, arguments)
3212        + outerRadius.apply(this, arguments)) / 2,
3213        a = (startAngle.apply(this, arguments)
3214        + endAngle.apply(this, arguments)) / 2 + d3_svg_arcOffset;
3215    return [Math.cos(a) * r, Math.sin(a) * r];
3216  };
3217
3218  return arc;
3219};
3220
3221var d3_svg_arcOffset = -Math.PI / 2,
3222    d3_svg_arcMax = 2 * Math.PI - 1e-6;
3223
3224function d3_svg_arcInnerRadius(d) {
3225  return d.innerRadius;
3226}
3227
3228function d3_svg_arcOuterRadius(d) {
3229  return d.outerRadius;
3230}
3231
3232function d3_svg_arcStartAngle(d) {
3233  return d.startAngle;
3234}
3235
3236function d3_svg_arcEndAngle(d) {
3237  return d.endAngle;
3238}
3239function d3_svg_line(projection) {
3240  var x = d3_svg_lineX,
3241      y = d3_svg_lineY,
3242      interpolate = d3_svg_lineInterpolatorDefault,
3243      interpolator = d3_svg_lineInterpolators.get(interpolate),
3244      tension = .7;
3245
3246  function line(d) {
3247    return d.length < 1 ? null : "M" + interpolator(projection(d3_svg_linePoints(this, d, x, y)), tension);
3248  }
3249
3250  line.x = function(v) {
3251    if (!arguments.length) return x;
3252    x = v;
3253    return line;
3254  };
3255
3256  line.y = function(v) {
3257    if (!arguments.length) return y;
3258    y = v;
3259    return line;
3260  };
3261
3262  line.interpolate = function(v) {
3263    if (!arguments.length) return interpolate;
3264    if (!d3_svg_lineInterpolators.has(v += "")) v = d3_svg_lineInterpolatorDefault;
3265    interpolator = d3_svg_lineInterpolators.get(interpolate = v);
3266    return line;
3267  };
3268
3269  line.tension = function(v) {
3270    if (!arguments.length) return tension;
3271    tension = v;
3272    return line;
3273  };
3274
3275  return line;
3276}
3277
3278d3.svg.line = function() {
3279  return d3_svg_line(Object);
3280};
3281
3282// Converts the specified array of data into an array of points
3283// (x-y tuples), by evaluating the specified `x` and `y` functions on each
3284// data point. The `this` context of the evaluated functions is the specified
3285// "self" object; each function is passed the current datum and index.
3286function d3_svg_linePoints(self, d, x, y) {
3287  var points = [],
3288      i = -1,
3289      n = d.length,
3290      fx = typeof x === "function",
3291      fy = typeof y === "function",
3292      value;
3293  if (fx && fy) {
3294    while (++i < n) points.push([
3295      x.call(self, value = d[i], i),
3296      y.call(self, value, i)
3297    ]);
3298  } else if (fx) {
3299    while (++i < n) points.push([x.call(self, d[i], i), y]);
3300  } else if (fy) {
3301    while (++i < n) points.push([x, y.call(self, d[i], i)]);
3302  } else {
3303    while (++i < n) points.push([x, y]);
3304  }
3305  return points;
3306}
3307
3308// The default `x` property, which references d[0].
3309function d3_svg_lineX(d) {
3310  return d[0];
3311}
3312
3313// The default `y` property, which references d[1].
3314function d3_svg_lineY(d) {
3315  return d[1];
3316}
3317
3318var d3_svg_lineInterpolatorDefault = "linear";
3319
3320// The various interpolators supported by the `line` class.
3321var d3_svg_lineInterpolators = d3.map({
3322  "linear": d3_svg_lineLinear,
3323  "step-before": d3_svg_lineStepBefore,
3324  "step-after": d3_svg_lineStepAfter,
3325  "basis": d3_svg_lineBasis,
3326  "basis-open": d3_svg_lineBasisOpen,
3327  "basis-closed": d3_svg_lineBasisClosed,
3328  "bundle": d3_svg_lineBundle,
3329  "cardinal": d3_svg_lineCardinal,
3330  "cardinal-open": d3_svg_lineCardinalOpen,
3331  "cardinal-closed": d3_svg_lineCardinalClosed,
3332  "monotone": d3_svg_lineMonotone
3333});
3334
3335// Linear interpolation; generates "L" commands.
3336function d3_svg_lineLinear(points) {
3337  var i = 0,
3338      n = points.length,
3339      p = points[0],
3340      path = [p[0], ",", p[1]];
3341  while (++i < n) path.push("L", (p = points[i])[0], ",", p[1]);
3342  return path.join("");
3343}
3344
3345// Step interpolation; generates "H" and "V" commands.
3346function d3_svg_lineStepBefore(points) {
3347  var i = 0,
3348      n = points.length,
3349      p = points[0],
3350      path = [p[0], ",", p[1]];
3351  while (++i < n) path.push("V", (p = points[i])[1], "H", p[0]);
3352  return path.join("");
3353}
3354
3355// Step interpolation; generates "H" and "V" commands.
3356function d3_svg_lineStepAfter(points) {
3357  var i = 0,
3358      n = points.length,
3359      p = points[0],
3360      path = [p[0], ",", p[1]];
3361  while (++i < n) path.push("H", (p = points[i])[0], "V", p[1]);
3362  return path.join("");
3363}
3364
3365// Open cardinal spline interpolation; generates "C" commands.
3366function d3_svg_lineCardinalOpen(points, tension) {
3367  return points.length < 4
3368      ? d3_svg_lineLinear(points)
3369      : points[1] + d3_svg_lineHermite(points.slice(1, points.length - 1),
3370        d3_svg_lineCardinalTangents(points, tension));
3371}
3372
3373// Closed cardinal spline interpolation; generates "C" commands.
3374function d3_svg_lineCardinalClosed(points, tension) {
3375  return points.length < 3
3376      ? d3_svg_lineLinear(points)
3377      : points[0] + d3_svg_lineHermite((points.push(points[0]), points),
3378        d3_svg_lineCardinalTangents([points[points.length - 2]]
3379        .concat(points, [points[1]]), tension));
3380}
3381
3382// Cardinal spline interpolation; generates "C" commands.
3383function d3_svg_lineCardinal(points, tension, closed) {
3384  return points.length < 3
3385      ? d3_svg_lineLinear(points)
3386      : points[0] + d3_svg_lineHermite(points,
3387        d3_svg_lineCardinalTangents(points, tension));
3388}
3389
3390// Hermite spline construction; generates "C" commands.
3391function d3_svg_lineHermite(points, tangents) {
3392  if (tangents.length < 1
3393      || (points.length != tangents.length
3394      && points.length != tangents.length + 2)) {
3395    return d3_svg_lineLinear(points);
3396  }
3397
3398  var quad = points.length != tangents.length,
3399      path = "",
3400      p0 = points[0],
3401      p = points[1],
3402      t0 = tangents[0],
3403      t = t0,
3404      pi = 1;
3405
3406  if (quad) {
3407    path += "Q" + (p[0] - t0[0] * 2 / 3) + "," + (p[1] - t0[1] * 2 / 3)
3408        + "," + p[0] + "," + p[1];
3409    p0 = points[1];
3410    pi = 2;
3411  }
3412
3413  if (tangents.length > 1) {
3414    t = tangents[1];
3415    p = points[pi];
3416    pi++;
3417    path += "C" + (p0[0] + t0[0]) + "," + (p0[1] + t0[1])
3418        + "," + (p[0] - t[0]) + "," + (p[1] - t[1])
3419        + "," + p[0] + "," + p[1];
3420    for (var i = 2; i < tangents.length; i++, pi++) {
3421      p = points[pi];
3422      t = tangents[i];
3423      path += "S" + (p[0] - t[0]) + "," + (p[1] - t[1])
3424          + "," + p[0] + "," + p[1];
3425    }
3426  }
3427
3428  if (quad) {
3429    var lp = points[pi];
3430    path += "Q" + (p[0] + t[0] * 2 / 3) + "," + (p[1] + t[1] * 2 / 3)
3431        + "," + lp[0] + "," + lp[1];
3432  }
3433
3434  return path;
3435}
3436
3437// Generates tangents for a cardinal spline.
3438function d3_svg_lineCardinalTangents(points, tension) {
3439  var tangents = [],
3440      a = (1 - tension) / 2,
3441      p0,
3442      p1 = points[0],
3443      p2 = points[1],
3444      i = 1,
3445      n = points.length;
3446  while (++i < n) {
3447    p0 = p1;
3448    p1 = p2;
3449    p2 = points[i];
3450    tangents.push([a * (p2[0] - p0[0]), a * (p2[1] - p0[1])]);
3451  }
3452  return tangents;
3453}
3454
3455// B-spline interpolation; generates "C" commands.
3456function d3_svg_lineBasis(points) {
3457  if (points.length < 3) return d3_svg_lineLinear(points);
3458  var i = 1,
3459      n = points.length,
3460      pi = points[0],
3461      x0 = pi[0],
3462      y0 = pi[1],
3463      px = [x0, x0, x0, (pi = points[1])[0]],
3464      py = [y0, y0, y0, pi[1]],
3465      path = [x0, ",", y0];
3466  d3_svg_lineBasisBezier(path, px, py);
3467  while (++i < n) {
3468    pi = points[i];
3469    px.shift(); px.push(pi[0]);
3470    py.shift(); py.push(pi[1]);
3471    d3_svg_lineBasisBezier(path, px, py);
3472  }
3473  i = -1;
3474  while (++i < 2) {
3475    px.shift(); px.push(pi[0]);
3476    py.shift(); py.push(pi[1]);
3477    d3_svg_lineBasisBezier(path, px, py);
3478  }
3479  return path.join("");
3480}
3481
3482// Open B-spline interpolation; generates "C" commands.
3483function d3_svg_lineBasisOpen(points) {
3484  if (points.length < 4) return d3_svg_lineLinear(points);
3485  var path = [],
3486      i = -1,
3487      n = points.length,
3488      pi,
3489      px = [0],
3490      py = [0];
3491  while (++i < 3) {
3492    pi = points[i];
3493    px.push(pi[0]);
3494    py.push(pi[1]);
3495  }
3496  path.push(d3_svg_lineDot4(d3_svg_lineBasisBezier3, px)
3497    + "," + d3_svg_lineDot4(d3_svg_lineBasisBezier3, py));
3498  --i; while (++i < n) {
3499    pi = points[i];
3500    px.shift(); px.push(pi[0]);
3501    py.shift(); py.push(pi[1]);
3502    d3_svg_lineBasisBezier(path, px, py);
3503  }
3504  return path.join("");
3505}
3506
3507// Closed B-spline interpolation; generates "C" commands.
3508function d3_svg_lineBasisClosed(points) {
3509  var path,
3510      i = -1,
3511      n = points.length,
3512      m = n + 4,
3513      pi,
3514      px = [],
3515      py = [];
3516  while (++i < 4) {
3517    pi = points[i % n];
3518    px.push(pi[0]);
3519    py.push(pi[1]);
3520  }
3521  path = [
3522    d3_svg_lineDot4(d3_svg_lineBasisBezier3, px), ",",
3523    d3_svg_lineDot4(d3_svg_lineBasisBezier3, py)
3524  ];
3525  --i; while (++i < m) {
3526    pi = points[i % n];
3527    px.shift(); px.push(pi[0]);
3528    py.shift(); py.push(pi[1]);
3529    d3_svg_lineBasisBezier(path, px, py);
3530  }
3531  return path.join("");
3532}
3533
3534function d3_svg_lineBundle(points, tension) {
3535  var n = points.length - 1,
3536      x0 = points[0][0],
3537      y0 = points[0][1],
3538      dx = points[n][0] - x0,
3539      dy = points[n][1] - y0,
3540      i = -1,
3541      p,
3542      t;
3543  while (++i <= n) {
3544    p = points[i];
3545    t = i / n;
3546    p[0] = tension * p[0] + (1 - tension) * (x0 + t * dx);
3547    p[1] = tension * p[1] + (1 - tension) * (y0 + t * dy);
3548  }
3549  return d3_svg_lineBasis(points);
3550}
3551
3552// Returns the dot product of the given four-element vectors.
3553function d3_svg_lineDot4(a, b) {
3554  return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3];
3555}
3556
3557// Matrix to transform basis (b-spline) control points to bezier
3558// control points. Derived from FvD 11.2.8.
3559var d3_svg_lineBasisBezier1 = [0, 2/3, 1/3, 0],
3560    d3_svg_lineBasisBezier2 = [0, 1/3, 2/3, 0],
3561    d3_svg_lineBasisBezier3 = [0, 1/6, 2/3, 1/6];
3562
3563// Pushes a "C" Bézier curve onto the specified path array, given the
3564// two specified four-element arrays which define the control points.
3565function d3_svg_lineBasisBezier(path, x, y) {
3566  path.push(
3567      "C", d3_svg_lineDot4(d3_svg_lineBasisBezier1, x),
3568      ",", d3_svg_lineDot4(d3_svg_lineBasisBezier1, y),
3569      ",", d3_svg_lineDot4(d3_svg_lineBasisBezier2, x),
3570      ",", d3_svg_lineDot4(d3_svg_lineBasisBezier2, y),
3571      ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, x),
3572      ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, y));
3573}
3574
3575// Computes the slope from points p0 to p1.
3576function d3_svg_lineSlope(p0, p1) {
3577  return (p1[1] - p0[1]) / (p1[0] - p0[0]);
3578}
3579
3580// Compute three-point differences for the given points.
3581// http://en.wikipedia.org/wiki/Cubic_Hermite_spline#Finite_difference
3582function d3_svg_lineFiniteDifferences(points) {
3583  var i = 0,
3584      j = points.length - 1,
3585      m = [],
3586      p0 = points[0],
3587      p1 = points[1],
3588      d = m[0] = d3_svg_lineSlope(p0, p1);
3589  while (++i < j) {
3590    m[i] = d + (d = d3_svg_lineSlope(p0 = p1, p1 = points[i + 1]));
3591  }
3592  m[i] = d;
3593  return m;
3594}
3595
3596// Interpolates the given points using Fritsch-Carlson Monotone cubic Hermite
3597// interpolation. Returns an array of tangent vectors. For details, see
3598// http://en.wikipedia.org/wiki/Monotone_cubic_interpolation
3599function d3_svg_lineMonotoneTangents(points) {
3600  var tangents = [],
3601      d,
3602      a,
3603      b,
3604      s,
3605      m = d3_svg_lineFiniteDifferences(points),
3606      i = -1,
3607      j = points.length - 1;
3608
3609  // The first two steps are done by computing finite-differences:
3610  // 1. Compute the slopes of the secant lines between successive points.
3611  // 2. Initialize the tangents at every point as the average of the secants.
3612
3613  // Then, for each segment

3614  while (++i < j) {
3615    d = d3_svg_lineSlope(points[i], points[i + 1]);
3616
3617    // 3. If two successive yk = y{k + 1} are equal (i.e., d is zero), then set
3618    // mk = m{k + 1} = 0 as the spline connecting these points must be flat to
3619    // preserve monotonicity. Ignore step 4 and 5 for those k.
3620
3621    if (Math.abs(d) < 1e-6) {
3622      m[i] = m[i + 1] = 0;
3623    } else {
3624      // 4. Let ak = mk / dk and bk = m{k + 1} / dk.
3625      a = m[i] / d;
3626      b = m[i + 1] / d;
3627
3628      // 5. Prevent overshoot and ensure monotonicity by restricting the
3629      // magnitude of vector <ak, bk> to a circle of radius 3.
3630      s = a * a + b * b;
3631      if (s > 9) {
3632        s = d * 3 / Math.sqrt(s);
3633        m[i] = s * a;
3634        m[i + 1] = s * b;
3635      }
3636    }
3637  }
3638
3639  // Compute the normalized tangent vector from the slopes. Note that if x is
3640  // not monotonic, it's possible that the slope will be infinite, so we protect
3641  // against NaN by setting the coordinate to zero.
3642  i = -1; while (++i <= j) {
3643    s = (points[Math.min(j, i + 1)][0] - points[Math.max(0, i - 1)][0])
3644      / (6 * (1 + m[i] * m[i]));
3645    tangents.push([s || 0, m[i] * s || 0]);
3646  }
3647
3648  return tangents;
3649}
3650
3651function d3_svg_lineMonotone(points) {
3652  return points.length < 3
3653      ? d3_svg_lineLinear(points)
3654      : points[0] +
3655        d3_svg_lineHermite(points, d3_svg_lineMonotoneTangents(points));
3656}
3657d3.svg.line.radial = function() {
3658  var line = d3_svg_line(d3_svg_lineRadial);
3659  line.radius = line.x, delete line.x;
3660  line.angle = line.y, delete line.y;
3661  return line;
3662};
3663
3664function d3_svg_lineRadial(points) {
3665  var point,
3666      i = -1,
3667      n = points.length,
3668      r,
3669      a;
3670  while (++i < n) {
3671    point = points[i];
3672    r = point[0];
3673    a = point[1] + d3_svg_arcOffset;
3674    point[0] = r * Math.cos(a);
3675    point[1] = r * Math.sin(a);
3676  }
3677  return points;
3678}
3679function d3_svg_area(projection) {
3680  var x0 = d3_svg_lineX,
3681      x1 = d3_svg_lineX,
3682      y0 = 0,
3683      y1 = d3_svg_lineY,
3684      interpolate,
3685      i0,
3686      i1,
3687      tension = .7;
3688
3689  function area(d) {
3690    if (d.length < 1) return null;
3691    var points0 = d3_svg_linePoints(this, d, x0, y0),
3692        points1 = d3_svg_linePoints(this, d, x0 === x1 ? d3_svg_areaX(points0) : x1, y0 === y1 ? d3_svg_areaY(points0) : y1);
3693    return "M" + i0(projection(points1), tension)
3694         + "L" + i1(projection(points0.reverse()), tension)
3695         + "Z";
3696  }
3697
3698  area.x = function(x) {
3699    if (!arguments.length) return x1;
3700    x0 = x1 = x;
3701    return area;
3702  };
3703
3704  area.x0 = function(x) {
3705    if (!arguments.length) return x0;
3706    x0 = x;
3707    return area;
3708  };
3709
3710  area.x1 = function(x) {
3711    if (!arguments.length) return x1;
3712    x1 = x;
3713    return area;
3714  };
3715
3716  area.y = function(y) {
3717    if (!arguments.length) return y1;
3718    y0 = y1 = y;
3719    return area;
3720  };
3721
3722  area.y0 = function(y) {
3723    if (!arguments.length) return y0;
3724    y0 = y;
3725    return area;
3726  };
3727
3728  area.y1 = function(y) {
3729    if (!arguments.length) return y1;
3730    y1 = y;
3731    return area;
3732  };
3733
3734  area.interpolate = function(x) {
3735    if (!arguments.length) return interpolate;
3736    if (!d3_svg_lineInterpolators.has(x += "")) x = d3_svg_lineInterpolatorDefault;
3737    i0 = d3_svg_lineInterpolators.get(interpolate = x);
3738    i1 = i0.reverse || i0;
3739    return area;
3740  };
3741
3742  area.tension = function(x) {
3743    if (!arguments.length) return tension;
3744    tension = x;
3745    return area;
3746  };
3747
3748  return area.interpolate("linear");
3749}
3750
3751d3_svg_lineStepBefore.reverse = d3_svg_lineStepAfter;
3752d3_svg_lineStepAfter.reverse = d3_svg_lineStepBefore;
3753
3754d3.svg.area = function() {
3755  return d3_svg_area(Object);
3756};
3757
3758function d3_svg_areaX(points) {
3759  return function(d, i) {
3760    return points[i][0];
3761  };
3762}
3763
3764function d3_svg_areaY(points) {
3765  return function(d, i) {
3766    return points[i][1];
3767  };
3768}
3769d3.svg.area.radial = function() {
3770  var area = d3_svg_area(d3_svg_lineRadial);
3771  area.radius = area.x, delete area.x;
3772  area.innerRadius = area.x0, delete area.x0;
3773  area.outerRadius = area.x1, delete area.x1;
3774  area.angle = area.y, delete area.y;
3775  area.startAngle = area.y0, delete area.y0;
3776  area.endAngle = area.y1, delete area.y1;
3777  return area;
3778};
3779d3.svg.chord = function() {
3780  var source = d3_svg_chordSource,
3781      target = d3_svg_chordTarget,
3782      radius = d3_svg_chordRadius,
3783      startAngle = d3_svg_arcStartAngle,
3784      endAngle = d3_svg_arcEndAngle;
3785
3786  // TODO Allow control point to be customized.
3787
3788  function chord(d, i) {
3789    var s = subgroup(this, source, d, i),
3790        t = subgroup(this, target, d, i);
3791    return "M" + s.p0
3792      + arc(s.r, s.p1, s.a1 - s.a0) + (equals(s, t)
3793      ? curve(s.r, s.p1, s.r, s.p0)
3794      : curve(s.r, s.p1, t.r, t.p0)
3795      + arc(t.r, t.p1, t.a1 - t.a0)
3796      + curve(t.r, t.p1, s.r, s.p0))
3797      + "Z";
3798  }
3799
3800  function subgroup(self, f, d, i) {
3801    var subgroup = f.call(self, d, i),
3802        r = radius.call(self, subgroup, i),
3803        a0 = startAngle.call(self, subgroup, i) + d3_svg_arcOffset,
3804        a1 = endAngle.call(self, subgroup, i) + d3_svg_arcOffset;
3805    return {
3806      r: r,
3807      a0: a0,
3808      a1: a1,
3809      p0: [r * Math.cos(a0), r * Math.sin(a0)],
3810      p1: [r * Math.cos(a1), r * Math.sin(a1)]
3811    };
3812  }
3813
3814  function equals(a, b) {
3815    return a.a0 == b.a0 && a.a1 == b.a1;
3816  }
3817
3818  function arc(r, p, a) {
3819    return "A" + r + "," + r + " 0 " + +(a > Math.PI) + ",1 " + p;
3820  }
3821
3822  function curve(r0, p0, r1, p1) {
3823    return "Q 0,0 " + p1;
3824  }
3825
3826  chord.radius = function(v) {
3827    if (!arguments.length) return radius;
3828    radius = d3.functor(v);
3829    return chord;
3830  };
3831
3832  chord.source = function(v) {
3833    if (!arguments.length) return source;
3834    source = d3.functor(v);
3835    return chord;
3836  };
3837
3838  chord.target = function(v) {
3839    if (!arguments.length) return target;
3840    target = d3.functor(v);
3841    return chord;
3842  };
3843
3844  chord.startAngle = function(v) {
3845    if (!arguments.length) return startAngle;
3846    startAngle = d3.functor(v);
3847    return chord;
3848  };
3849
3850  chord.endAngle = function(v) {
3851    if (!arguments.length) return endAngle;
3852    endAngle = d3.functor(v);
3853    return chord;
3854  };
3855
3856  return chord;
3857};
3858
3859function d3_svg_chordSource(d) {
3860  return d.source;
3861}
3862
3863function d3_svg_chordTarget(d) {
3864  return d.target;
3865}
3866
3867function d3_svg_chordRadius(d) {
3868  return d.radius;
3869}
3870
3871function d3_svg_chordStartAngle(d) {
3872  return d.startAngle;
3873}
3874
3875function d3_svg_chordEndAngle(d) {
3876  return d.endAngle;
3877}
3878d3.svg.diagonal = function() {
3879  var source = d3_svg_chordSource,
3880      target = d3_svg_chordTarget,
3881      projection = d3_svg_diagonalProjection;
3882
3883  function diagonal(d, i) {
3884    var p0 = source.call(this, d, i),
3885        p3 = target.call(this, d, i),
3886        m = (p0.y + p3.y) / 2,
3887        p = [p0, {x: p0.x, y: m}, {x: p3.x, y: m}, p3];
3888    p = p.map(projection);
3889    return "M" + p[0] + "C" + p[1] + " " + p[2] + " " + p[3];
3890  }
3891
3892  diagonal.source = function(x) {
3893    if (!arguments.length) return source;
3894    source = d3.functor(x);
3895    return diagonal;
3896  };
3897
3898  diagonal.target = function(x) {
3899    if (!arguments.length) return target;
3900    target = d3.functor(x);
3901    return diagonal;
3902  };
3903
3904  diagonal.projection = function(x) {
3905    if (!arguments.length) return projection;
3906    projection = x;
3907    return diagonal;
3908  };
3909
3910  return diagonal;
3911};
3912
3913function d3_svg_diagonalProjection(d) {
3914  return [d.x, d.y];
3915}
3916d3.svg.diagonal.radial = function() {
3917  var diagonal = d3.svg.diagonal(),
3918      projection = d3_svg_diagonalProjection,
3919      projection_ = diagonal.projection;
3920
3921  diagonal.projection = function(x) {
3922    return arguments.length
3923        ? projection_(d3_svg_diagonalRadialProjection(projection = x))
3924        : projection;
3925  };
3926
3927  return diagonal;
3928};
3929
3930function d3_svg_diagonalRadialProjection(projection) {
3931  return function() {
3932    var d = projection.apply(this, arguments),
3933        r = d[0],
3934        a = d[1] + d3_svg_arcOffset;
3935    return [r * Math.cos(a), r * Math.sin(a)];
3936  };
3937}
3938d3.svg.mouse = d3.mouse;
3939d3.svg.touches = d3.touches;
3940d3.svg.symbol = function() {
3941  var type = d3_svg_symbolType,
3942      size = d3_svg_symbolSize;
3943
3944  function symbol(d, i) {
3945    return (d3_svg_symbols.get(type.call(this, d, i))
3946        || d3_svg_symbolCircle)
3947        (size.call(this, d, i));
3948  }
3949
3950  symbol.type = function(x) {
3951    if (!arguments.length) return type;
3952    type = d3.functor(x);
3953    return symbol;
3954  };
3955
3956  // size of symbol in square pixels
3957  symbol.size = function(x) {
3958    if (!arguments.length) return size;
3959    size = d3.functor(x);
3960    return symbol;
3961  };
3962
3963  return symbol;
3964};
3965
3966function d3_svg_symbolSize() {
3967  return 64;
3968}
3969
3970function d3_svg_symbolType() {
3971  return "circle";
3972}
3973
3974function d3_svg_symbolCircle(size) {
3975  var r = Math.sqrt(size / Math.PI);
3976  return "M0," + r
3977      + "A" + r + "," + r + " 0 1,1 0," + (-r)
3978      + "A" + r + "," + r + " 0 1,1 0," + r
3979      + "Z";
3980}
3981
3982// TODO cross-diagonal?
3983var d3_svg_symbols = d3.map({
3984  "circle": d3_svg_symbolCircle,
3985  "cross": function(size) {
3986    var r = Math.sqrt(size / 5) / 2;
3987    return "M" + -3 * r + "," + -r
3988        + "H" + -r
3989        + "V" + -3 * r
3990        + "H" + r
3991        + "V" + -r
3992        + "H" + 3 * r
3993        + "V" + r
3994        + "H" + r
3995        + "V" + 3 * r
3996        + "H" + -r
3997        + "V" + r
3998        + "H" + -3 * r
3999        + "Z";
4000  },
4001  "diamond": function(size) {
4002    var ry = Math.sqrt(size / (2 * d3_svg_symbolTan30)),
4003        rx = ry * d3_svg_symbolTan30;
4004    return "M0," + -ry
4005        + "L" + rx + ",0"
4006        + " 0," + ry
4007        + " " + -rx + ",0"
4008        + "Z";
4009  },
4010  "square": function(size) {
4011    var r = Math.sqrt(size) / 2;
4012    return "M" + -r + "," + -r
4013        + "L" + r + "," + -r
4014        + " " + r + "," + r
4015        + " " + -r + "," + r
4016        + "Z";
4017  },
4018  "triangle-down": function(size) {
4019    var rx = Math.sqrt(size / d3_svg_symbolSqrt3),
4020        ry = rx * d3_svg_symbolSqrt3 / 2;
4021    return "M0," + ry
4022        + "L" + rx +"," + -ry
4023        + " " + -rx + "," + -ry
4024        + "Z";
4025  },
4026  "triangle-up": function(size) {
4027    var rx = Math.sqrt(size / d3_svg_symbolSqrt3),
4028        ry = rx * d3_svg_symbolSqrt3 / 2;
4029    return "M0," + -ry
4030        + "L" + rx +"," + ry
4031        + " " + -rx + "," + ry
4032        + "Z";
4033  }
4034});
4035
4036d3.svg.symbolTypes = d3_svg_symbols.keys();
4037
4038var d3_svg_symbolSqrt3 = Math.sqrt(3),
4039    d3_svg_symbolTan30 = Math.tan(30 * Math.PI / 180);
4040d3.svg.axis = function() {
4041  var scale = d3.scale.linear(),
4042      orient = "bottom",
4043      tickMajorSize = 6,
4044      tickMinorSize = 6,
4045      tickEndSize = 6,
4046      tickPadding = 3,
4047      tickArguments_ = [10],
4048      tickValues = null,
4049      tickFormat_,
4050      tickSubdivide = 0;
4051
4052  function axis(g) {
4053    g.each(function() {
4054      var g = d3.select(this);
4055
4056      // Ticks, or domain values for ordinal scales.
4057      var ticks = tickValues == null ? (scale.ticks ? scale.ticks.apply(scale, tickArguments_) : scale.domain()) : tickValues,
4058          tickFormat = tickFormat_ == null ? (scale.tickFormat ? scale.tickFormat.apply(scale, tickArguments_) : String) : tickFormat_;
4059
4060      // Minor ticks.
4061      var subticks = d3_svg_axisSubdivide(scale, ticks, tickSubdivide),
4062          subtick = g.selectAll(".minor").data(subticks, String),
4063          subtickEnter = subtick.enter().insert("line", "g").attr("class", "tick minor").style("opacity", 1e-6),
4064          subtickExit = d3.transition(subtick.exit()).style("opacity", 1e-6).remove(),
4065          subtickUpdate = d3.transition(subtick).style("opacity", 1);
4066
4067      // Major ticks.
4068      var tick = g.selectAll("g").data(ticks, String),
4069          tickEnter = tick.enter().insert("g", "path").style("opacity", 1e-6),
4070          tickExit = d3.transition(tick.exit()).style("opacity", 1e-6).remove(),
4071          tickUpdate = d3.transition(tick).style("opacity", 1),
4072          tickTransform;
4073
4074      // Domain.
4075      var range = d3_scaleRange(scale),
4076          path = g.selectAll(".domain").data([0]),
4077          pathEnter = path.enter().append("path").attr("class", "domain"),
4078          pathUpdate = d3.transition(path);
4079
4080      // Stash a snapshot of the new scale, and retrieve the old snapshot.
4081      var scale1 = scale.copy(),
4082          scale0 = this.__chart__ || scale1;
4083      this.__chart__ = scale1;
4084
4085      tickEnter.append("line").attr("class", "tick");
4086      tickEnter.append("text");
4087      tickUpdate.select("text").text(tickFormat);
4088
4089      switch (orient) {
4090        case "bottom": {
4091          tickTransform = d3_svg_axisX;
4092          subtickEnter.attr("y2", tickMinorSize);
4093          subtickUpdate.attr("x2", 0).attr("y2", tickMinorSize);
4094          tickEnter.select("line").attr("y2", tickMajorSize);
4095          tickEnter.select("text").attr("y", Math.max(tickMajorSize, 0) + tickPadding);
4096          tickUpdate.select("line").attr("x2", 0).attr("y2", tickMajorSize);
4097          tickUpdate.select("text").attr("x", 0).attr("y", Math.max(tickMajorSize, 0) + tickPadding).attr("dy", ".71em").attr("text-anchor", "middle");
4098          pathUpdate.attr("d", "M" + range[0] + "," + tickEndSize + "V0H" + range[1] + "V" + tickEndSize);
4099          break;
4100        }
4101        case "top": {
4102          tickTransform = d3_svg_axisX;
4103          subtickEnter.attr("y2", -tickMinorSize);
4104          subtickUpdate.attr("x2", 0).attr("y2", -tickMinorSize);
4105          tickEnter.select("line").attr("y2", -tickMajorSize);
4106          tickEnter.select("text").attr("y", -(Math.max(tickMajorSize, 0) + tickPadding));
4107          tickUpdate.select("line").attr("x2", 0).attr("y2", -tickMajorSize);
4108          tickUpdate.select("text").attr("x", 0).attr("y", -(Math.max(tickMajorSize, 0) + tickPadding)).attr("dy", "0em").attr("text-anchor", "middle");
4109          pathUpdate.attr("d", "M" + range[0] + "," + -tickEndSize + "V0H" + range[1] + "V" + -tickEndSize);
4110          break;
4111        }
4112        case "left": {
4113          tickTransform = d3_svg_axisY;
4114          subtickEnter.attr("x2", -tickMinorSize);
4115          subtickUpdate.attr("x2", -tickMinorSize).attr("y2", 0);
4116          tickEnter.select("line").attr("x2", -tickMajorSize);
4117          tickEnter.select("text").attr("x", -(Math.max(tickMajorSize, 0) + tickPadding));
4118          tickUpdate.select("line").attr("x2", -tickMajorSize).attr("y2", 0);
4119          tickUpdate.select("text").attr("x", -(Math.max(tickMajorSize, 0) + tickPadding)).attr("y", 0).attr("dy", ".32em").attr("text-anchor", "end");
4120          pathUpdate.attr("d", "M" + -tickEndSize + "," + range[0] + "H0V" + range[1] + "H" + -tickEndSize);
4121          break;
4122        }
4123        case "right": {
4124          tickTransform = d3_svg_axisY;
4125          subtickEnter.attr("x2", tickMinorSize);
4126          subtickUpdate.attr("x2", tickMinorSize).attr("y2", 0);
4127          tickEnter.select("line").attr("x2", tickMajorSize);
4128          tickEnter.select("text").attr("x", Math.max(tickMajorSize, 0) + tickPadding);
4129          tickUpdate.select("line").attr("x2", tickMajorSize).attr("y2", 0);
4130          tickUpdate.select("text").attr("x", Math.max(tickMajorSize, 0) + tickPadding).attr("y", 0).attr("dy", ".32em").attr("text-anchor", "start");
4131          pathUpdate.attr("d", "M" + tickEndSize + "," + range[0] + "H0V" + range[1] + "H" + tickEndSize);
4132          break;
4133        }
4134      }
4135
4136      // For quantitative scales:
4137      // - enter new ticks from the old scale
4138      // - exit old ticks to the new scale
4139      if (scale.ticks) {
4140        tickEnter.call(tickTransform, scale0);
4141        tickUpdate.call(tickTransform, scale1);
4142        tickExit.call(tickTransform, scale1);
4143        subtickEnter.call(tickTransform, scale0);
4144        subtickUpdate.call(tickTransform, scale1);
4145        subtickExit.call(tickTransform, scale1);
4146      }
4147
4148      // For ordinal scales:
4149      // - any entering ticks are undefined in the old scale
4150      // - any exiting ticks are undefined in the new scale
4151      // Therefore, we only need to transition updating ticks.
4152      else {
4153        var dx = scale1.rangeBand() / 2, x = function(d) { return scale1(d) + dx; };
4154        tickEnter.call(tickTransform, x);
4155        tickUpdate.call(tickTransform, x);
4156      }
4157    });
4158  }
4159
4160  axis.scale = function(x) {
4161    if (!arguments.length) return scale;
4162    scale = x;
4163    return axis;
4164  };
4165
4166  axis.orient = function(x) {
4167    if (!arguments.length) return orient;
4168    orient = x;
4169    return axis;
4170  };
4171
4172  axis.ticks = function() {
4173    if (!arguments.length) return tickArguments_;
4174    tickArguments_ = arguments;
4175    return axis;
4176  };
4177
4178  axis.tickValues = function(x) {
4179    if (!arguments.length) return tickValues;
4180    tickValues = x;
4181    return axis;
4182  };
4183
4184  axis.tickFormat = function(x) {
4185    if (!arguments.length) return tickFormat_;
4186    tickFormat_ = x;
4187    return axis;
4188  };
4189
4190  axis.tickSize = function(x, y, z) {
4191    if (!arguments.length) return tickMajorSize;
4192    var n = arguments.length - 1;
4193    tickMajorSize = +x;
4194    tickMinorSize = n > 1 ? +y : tickMajorSize;
4195    tickEndSize = n > 0 ? +arguments[n] : tickMajorSize;
4196    return axis;
4197  };
4198
4199  axis.tickPadding = function(x) {
4200    if (!arguments.length) return tickPadding;
4201    tickPadding = +x;
4202    return axis;
4203  };
4204
4205  axis.tickSubdivide = function(x) {
4206    if (!arguments.length) return tickSubdivide;
4207    tickSubdivide = +x;
4208    return axis;
4209  };
4210
4211  return axis;
4212};
4213
4214function d3_svg_axisX(selection, x) {
4215  selection.attr("transform", function(d) { return "translate(" + x(d) + ",0)"; });
4216}
4217
4218function d3_svg_axisY(selection, y) {
4219  selection.attr("transform", function(d) { return "translate(0," + y(d) + ")"; });
4220}
4221
4222function d3_svg_axisSubdivide(scale, ticks, m) {
4223  subticks = [];
4224  if (m && ticks.length > 1) {
4225    var extent = d3_scaleExtent(scale.domain()),
4226        subticks,
4227        i = -1,
4228        n = ticks.length,
4229        d = (ticks[1] - ticks[0]) / ++m,
4230        j,
4231        v;
4232    while (++i < n) {
4233      for (j = m; --j > 0;) {
4234        if ((v = +ticks[i] - j * d) >= extent[0]) {
4235          subticks.push(v);
4236        }
4237      }
4238    }
4239    for (--i, j = 0; ++j < m && (v = +ticks[i] + j * d) < extent[1];) {
4240      subticks.push(v);
4241    }
4242  }
4243  return subticks;
4244}
4245d3.svg.brush = function() {
4246  var event = d3_eventDispatch(brush, "brushstart", "brush", "brushend"),
4247      x = null, // x-scale, optional
4248      y = null, // y-scale, optional
4249      resizes = d3_svg_brushResizes[0],
4250      extent = [[0, 0], [0, 0]], // [x0, y0], [x1, y1], in pixels (integers)
4251      extentDomain; // the extent in data space, lazily created
4252
4253  function brush(g) {
4254    g.each(function() {
4255      var g = d3.select(this),
4256          bg = g.selectAll(".background").data([0]),
4257          fg = g.selectAll(".extent").data([0]),
4258          tz = g.selectAll(".resize").data(resizes, String),
4259          e;
4260
4261      // Prepare the brush container for events.
4262      g
4263          .style("pointer-events", "all")
4264          .on("mousedown.brush", brushstart)
4265          .on("touchstart.brush", brushstart);
4266
4267      // An invisible, mouseable area for starting a new brush.
4268      bg.enter().append("rect")
4269          .attr("class", "background")
4270          .style("visibility", "hidden")
4271          .style("cursor", "crosshair");
4272
4273      // The visible brush extent; style this as you like!
4274      fg.enter().append("rect")
4275          .attr("class", "extent")
4276          .style("cursor", "move");
4277
4278      // More invisible rects for resizing the extent.
4279      tz.enter().append("g")
4280          .attr("class", function(d) { return "resize " + d; })
4281          .style("cursor", function(d) { return d3_svg_brushCursor[d]; })
4282        .append("rect")
4283          .attr("x", function(d) { return /[ew]$/.test(d) ? -3 : null; })
4284          .attr("y", function(d) { return /^[ns]/.test(d) ? -3 : null; })
4285          .attr("width", 6)
4286          .attr("height", 6)
4287          .style("visibility", "hidden");
4288
4289      // Show or hide the resizers.
4290      tz.style("display", brush.empty() ? "none" : null);
4291
4292      // Remove any superfluous resizers.
4293      tz.exit().remove();
4294
4295      // Initialize the background to fill the defined range.
4296      // If the range isn't defined, you can post-process.
4297      if (x) {
4298        e = d3_scaleRange(x);
4299        bg.attr("x", e[0]).attr("width", e[1] - e[0]);
4300        redrawX(g);
4301      }
4302      if (y) {
4303        e = d3_scaleRange(y);
4304        bg.attr("y", e[0]).attr("height", e[1] - e[0]);
4305        redrawY(g);
4306      }
4307      redraw(g);
4308    });
4309  }
4310
4311  function redraw(g) {
4312    g.selectAll(".resize").attr("transform", function(d) {
4313      return "translate(" + extent[+/e$/.test(d)][0] + "," + extent[+/^s/.test(d)][1] + ")";
4314    });
4315  }
4316
4317  function redrawX(g) {
4318    g.select(".extent").attr("x", extent[0][0]);
4319    g.selectAll(".extent,.n>rect,.s>rect").attr("width", extent[1][0] - extent[0][0]);
4320  }
4321
4322  function redrawY(g) {
4323    g.select(".extent").attr("y", extent[0][1]);
4324    g.selectAll(".extent,.e>rect,.w>rect").attr("height", extent[1][1] - extent[0][1]);
4325  }
4326
4327  function brushstart() {
4328    var target = this,
4329        eventTarget = d3.select(d3.event.target),
4330        event_ = event.of(target, arguments),
4331        g = d3.select(target),
4332        resizing = eventTarget.datum(),
4333        resizingX = !/^(n|s)$/.test(resizing) && x,
4334        resizingY = !/^(e|w)$/.test(resizing) && y,
4335        dragging = eventTarget.classed("extent"),
4336        center,
4337        origin = mouse(),
4338        offset;
4339
4340    var w = d3.select(window)
4341        .on("mousemove.brush", brushmove)
4342        .on("mouseup.brush", brushend)
4343        .on("touchmove.brush", brushmove)
4344        .on("touchend.brush", brushend)
4345        .on("keydown.brush", keydown)
4346        .on("keyup.brush", keyup);
4347
4348    // If the extent was clicked on, drag rather than brush;
4349    // store the point between the mouse and extent origin instead.
4350    if (dragging) {
4351      origin[0] = extent[0][0] - origin[0];
4352      origin[1] = extent[0][1] - origin[1];
4353    }
4354
4355    // If a resizer was clicked on, record which side is to be resized.
4356    // Also, set the origin to the opposite side.
4357    else if (resizing) {
4358      var ex = +/w$/.test(resizing),
4359          ey = +/^n/.test(resizing);
4360      offset = [extent[1 - ex][0] - origin[0], extent[1 - ey][1] - origin[1]];
4361      origin[0] = extent[ex][0];
4362      origin[1] = extent[ey][1];
4363    }
4364
4365    // If the ALT key is down when starting a brush, the center is at the mouse.
4366    else if (d3.event.altKey) center = origin.slice();
4367
4368    // Propagate the active cursor to the body for the drag duration.
4369    g.style("pointer-events", "none").selectAll(".resize").style("display", null);
4370    d3.select("body").style("cursor", eventTarget.style("cursor"));
4371
4372    // Notify listeners.
4373    event_({type: "brushstart"});
4374    brushmove();
4375    d3_eventCancel();
4376
4377    function mouse() {
4378      var touches = d3.event.changedTouches;
4379      return touches ? d3.touches(target, touches)[0] : d3.mouse(target);
4380    }
4381
4382    function keydown() {
4383      if (d3.event.keyCode == 32) {
4384        if (!dragging) {
4385          center = null;
4386          origin[0] -= extent[1][0];
4387          origin[1] -= extent[1][1];
4388          dragging = 2;
4389        }
4390        d3_eventCancel();
4391      }
4392    }
4393
4394    function keyup() {
4395      if (d3.event.keyCode == 32 && dragging == 2) {
4396        origin[0] += extent[1][0];
4397        origin[1] += extent[1][1];
4398        dragging = 0;
4399        d3_eventCancel();
4400      }
4401    }
4402
4403    function brushmove() {
4404      var point = mouse(),
4405          moved = false;
4406
4407      // Preserve the offset for thick resizers.
4408      if (offset) {
4409        point[0] += offset[0];
4410        point[1] += offset[1];
4411      }
4412
4413      if (!dragging) {
4414
4415        // If needed, determine the center from the current extent.
4416        if (d3.event.altKey) {
4417          if (!center) center = [(extent[0][0] + extent[1][0]) / 2, (extent[0][1] + extent[1][1]) / 2];
4418
4419          // Update the origin, for when the ALT key is released.
4420          origin[0] = extent[+(point[0] < center[0])][0];
4421          origin[1] = extent[+(point[1] < center[1])][1];
4422        }
4423
4424        // When the ALT key is released, we clear the center.
4425        else center = null;
4426      }
4427
4428      // Update the brush extent for each dimension.
4429      if (resizingX && move1(point, x, 0)) {
4430        redrawX(g);
4431        moved = true;
4432      }
4433      if (resizingY && move1(point, y, 1)) {
4434        redrawY(g);
4435        moved = true;
4436      }
4437
4438      // Final redraw and notify listeners.
4439      if (moved) {
4440        redraw(g);
4441        event_({type: "brush", mode: dragging ? "move" : "resize"});
4442      }
4443    }
4444
4445    function move1(point, scale, i) {
4446      var range = d3_scaleRange(scale),
4447          r0 = range[0],
4448          r1 = range[1],
4449          position = origin[i],
4450          size = extent[1][i] - extent[0][i],
4451          min,
4452          max;
4453
4454      // When dragging, reduce the range by the extent size and position.
4455      if (dragging) {
4456        r0 -= position;
4457        r1 -= size + position;
4458      }
4459
4460      // Clamp the point so that the extent fits within the range extent.
4461      min = Math.max(r0, Math.min(r1, point[i]));
4462
4463      // Compute the new extent bounds.
4464      if (dragging) {
4465        max = (min += position) + size;
4466      } else {
4467
4468        // If the ALT key is pressed, then preserve the center of the extent.
4469        if (center) position = Math.max(r0, Math.min(r1, 2 * center[i] - min));
4470
4471        // Compute the min and max of the position and point.
4472        if (position < min) {
4473          max = min;
4474          min = position;
4475        } else {
4476          max = position;
4477        }
4478      }
4479
4480      // Update the stored bounds.
4481      if (extent[0][i] !== min || extent[1][i] !== max) {
4482        extentDomain = null;
4483        extent[0][i] = min;
4484        extent[1][i] = max;
4485        return true;
4486      }
4487    }
4488
4489    function brushend() {
4490      brushmove();
4491
4492      // reset the cursor styles
4493      g.style("pointer-events", "all").selectAll(".resize").style("display", brush.empty() ? "none" : null);
4494      d3.select("body").style("cursor", null);
4495
4496      w .on("mousemove.brush", null)
4497        .on("mouseup.brush", null)
4498        .on("touchmove.brush", null)
4499        .on("touchend.brush", null)
4500        .on("keydown.brush", null)
4501        .on("keyup.brush", null);
4502
4503      event_({type: "brushend"});
4504      d3_eventCancel();
4505    }
4506  }
4507
4508  brush.x = function(z) {
4509    if (!arguments.length) return x;
4510    x = z;
4511    resizes = d3_svg_brushResizes[!x << 1 | !y]; // fore!
4512    return brush;
4513  };
4514
4515  brush.y = function(z) {
4516    if (!arguments.length) return y;
4517    y = z;
4518    resizes = d3_svg_brushResizes[!x << 1 | !y]; // fore!
4519    return brush;
4520  };
4521
4522  brush.extent = function(z) {
4523    var x0, x1, y0, y1, t;
4524
4525    // Invert the pixel extent to data-space.
4526    if (!arguments.length) {
4527      z = extentDomain || extent;
4528      if (x) {
4529        x0 = z[0][0], x1 = z[1][0];
4530        if (!extentDomain) {
4531          x0 = extent[0][0], x1 = extent[1][0];
4532          if (x.invert) x0 = x.invert(x0), x1 = x.invert(x1);
4533          if (x1 < x0) t = x0, x0 = x1, x1 = t;
4534        }
4535      }
4536      if (y) {
4537        y0 = z[0][1], y1 = z[1][1];
4538        if (!extentDomain) {
4539          y0 = extent[0][1], y1 = extent[1][1];
4540          if (y.invert) y0 = y.invert(y0), y1 = y.invert(y1);
4541          if (y1 < y0) t = y0, y0 = y1, y1 = t;
4542        }
4543      }
4544      return x && y ? [[x0, y0], [x1, y1]] : x ? [x0, x1] : y && [y0, y1];
4545    }
4546
4547    // Scale the data-space extent to pixels.
4548    extentDomain = [[0, 0], [0, 0]];
4549    if (x) {
4550      x0 = z[0], x1 = z[1];
4551      if (y) x0 = x0[0], x1 = x1[0];
4552      extentDomain[0][0] = x0, extentDomain[1][0] = x1;
4553      if (x.invert) x0 = x(x0), x1 = x(x1);
4554      if (x1 < x0) t = x0, x0 = x1, x1 = t;
4555      extent[0][0] = x0 | 0, extent[1][0] = x1 | 0;
4556    }
4557    if (y) {
4558      y0 = z[0], y1 = z[1];
4559      if (x) y0 = y0[1], y1 = y1[1];
4560      extentDomain[0][1] = y0, extentDomain[1][1] = y1;
4561      if (y.invert) y0 = y(y0), y1 = y(y1);
4562      if (y1 < y0) t = y0, y0 = y1, y1 = t;
4563      extent[0][1] = y0 | 0, extent[1][1] = y1 | 0;
4564    }
4565
4566    return brush;
4567  };
4568
4569  brush.clear = function() {
4570    extentDomain = null;
4571    extent[0][0] =
4572    extent[0][1] =
4573    extent[1][0] =
4574    extent[1][1] = 0;
4575    return brush;
4576  };
4577
4578  brush.empty = function() {
4579    return (x && extent[0][0] === extent[1][0])
4580        || (y && extent[0][1] === extent[1][1]);
4581  };
4582
4583  return d3.rebind(brush, event, "on");
4584};
4585
4586var d3_svg_brushCursor = {
4587  n: "ns-resize",
4588  e: "ew-resize",
4589  s: "ns-resize",
4590  w: "ew-resize",
4591  nw: "nwse-resize",
4592  ne: "nesw-resize",
4593  se: "nwse-resize",
4594  sw: "nesw-resize"
4595};
4596
4597var d3_svg_brushResizes = [
4598  ["n", "e", "s", "w", "nw", "ne", "se", "sw"],
4599  ["e", "w"],
4600  ["n", "s"],
4601  []
4602];
4603d3.behavior = {};
4604// TODO Track touch points by identifier.
4605
4606d3.behavior.drag = function() {
4607  var event = d3_eventDispatch(drag, "drag", "dragstart", "dragend"),
4608      origin = null;
4609
4610  function drag() {
4611    this.on("mousedown.drag", mousedown)
4612        .on("touchstart.drag", mousedown);
4613  }
4614
4615  function mousedown() {
4616    var target = this,
4617        event_ = event.of(target, arguments),
4618        eventTarget = d3.event.target,
4619        offset,
4620        origin_ = point(),
4621        moved = 0;
4622
4623    var w = d3.select(window)
4624        .on("mousemove.drag", dragmove)
4625        .on("touchmove.drag", dragmove)
4626        .on("mouseup.drag", dragend, true)
4627        .on("touchend.drag", dragend, true);
4628
4629    if (origin) {
4630      offset = origin.apply(target, arguments);
4631      offset = [offset.x - origin_[0], offset.y - origin_[1]];
4632    } else {
4633      offset = [0, 0];
4634    }
4635
4636    event_({type: "dragstart"});
4637
4638    function point() {
4639      var p = target.parentNode,
4640          t = d3.event.changedTouches;
4641      return t ? d3.touches(p, t)[0] : d3.mouse(p);
4642    }
4643
4644    function dragmove() {
4645      if (!target.parentNode) return dragend(); // target removed from DOM
4646
4647      var p = point(),
4648          dx = p[0] - origin_[0],
4649          dy = p[1] - origin_[1];
4650
4651      moved |= dx | dy;
4652      origin_ = p;
4653      d3_eventCancel();
4654
4655      event_({type: "drag", x: p[0] + offset[0], y: p[1] + offset[1], dx: dx, dy: dy});
4656    }
4657
4658    function dragend() {
4659      event_({type: "dragend"});
4660
4661      // if moved, prevent the mouseup (and possibly click) from propagating
4662      if (moved) {
4663        d3_eventCancel();
4664        if (d3.event.target === eventTarget) w.on("click.drag", click, true);
4665      }
4666
4667      w .on("mousemove.drag", null)
4668        .on("touchmove.drag", null)
4669        .on("mouseup.drag", null)
4670        .on("touchend.drag", null);
4671    }
4672
4673    // prevent the subsequent click from propagating (e.g., for anchors)
4674    function click() {
4675      d3_eventCancel();
4676      w.on("click.drag", null);
4677    }
4678  }
4679
4680  drag.origin = function(x) {
4681    if (!arguments.length) return origin;
4682    origin = x;
4683    return drag;
4684  };
4685
4686  return d3.rebind(drag, event, "on");
4687};
4688d3.behavior.zoom = function() {
4689  var translate = [0, 0],
4690      translate0, // translate when we started zooming (to avoid drift)
4691      scale = 1,
4692      scale0, // scale when we started touching
4693      scaleExtent = d3_behavior_zoomInfinity,
4694      event = d3_eventDispatch(zoom, "zoom"),
4695      x0,
4696      x1,
4697      y0,
4698      y1,
4699      touchtime; // time of last touchstart (to detect double-tap)
4700
4701  function zoom() {
4702    this
4703        .on("mousedown.zoom", mousedown)
4704        .on("mousewheel.zoom", mousewheel)
4705        .on("mousemove.zoom", mousemove)
4706        .on("DOMMouseScroll.zoom", mousewheel)
4707        .on("dblclick.zoom", dblclick)
4708        .on("touchstart.zoom", touchstart)
4709        .on("touchmove.zoom", touchmove)
4710        .on("touchend.zoom", touchstart);
4711  }
4712
4713  zoom.translate = function(x) {
4714    if (!arguments.length) return translate;
4715    translate = x.map(Number);
4716    return zoom;
4717  };
4718
4719  zoom.scale = function(x) {
4720    if (!arguments.length) return scale;
4721    scale = +x;
4722    return zoom;
4723  };
4724
4725  zoom.scaleExtent = function(x) {
4726    if (!arguments.length) return scaleExtent;
4727    scaleExtent = x == null ? d3_behavior_zoomInfinity : x.map(Number);
4728    return zoom;
4729  };
4730
4731  zoom.x = function(z) {
4732    if (!arguments.length) return x1;
4733    x1 = z;
4734    x0 = z.copy();
4735    return zoom;
4736  };
4737
4738  zoom.y = function(z) {
4739    if (!arguments.length) return y1;
4740    y1 = z;
4741    y0 = z.copy();
4742    return zoom;
4743  };
4744
4745  function location(p) {
4746    return [(p[0] - translate[0]) / scale, (p[1] - translate[1]) / scale];
4747  }
4748
4749  function point(l) {
4750    return [l[0] * scale + translate[0], l[1] * scale + translate[1]];
4751  }
4752
4753  function scaleTo(s) {
4754    scale = Math.max(scaleExtent[0], Math.min(scaleExtent[1], s));
4755  }
4756
4757  function translateTo(p, l) {
4758    l = point(l);
4759    translate[0] += p[0] - l[0];
4760    translate[1] += p[1] - l[1];
4761  }
4762
4763  function dispatch(event) {
4764    if (x1) x1.domain(x0.range().map(function(x) { return (x - translate[0]) / scale; }).map(x0.invert));
4765    if (y1) y1.domain(y0.range().map(function(y) { return (y - translate[1]) / scale; }).map(y0.invert));
4766    d3.event.preventDefault();
4767    event({type: "zoom", scale: scale, translate: translate});
4768  }
4769
4770  function mousedown() {
4771    var target = this,
4772        event_ = event.of(target, arguments),
4773        eventTarget = d3.event.target,
4774        moved = 0,
4775        w = d3.select(window).on("mousemove.zoom", mousemove).on("mouseup.zoom", mouseup),
4776        l = location(d3.mouse(target));
4777
4778    window.focus();
4779    d3_eventCancel();
4780
4781    function mousemove() {
4782      moved = 1;
4783      translateTo(d3.mouse(target), l);
4784      dispatch(event_);
4785    }
4786
4787    function mouseup() {
4788      if (moved) d3_eventCancel();
4789      w.on("mousemove.zoom", null).on("mouseup.zoom", null);
4790      if (moved && d3.event.target === eventTarget) w.on("click.zoom", click);
4791    }
4792
4793    function click() {
4794      d3_eventCancel();
4795      w.on("click.zoom", null);
4796    }
4797  }
4798
4799  function mousewheel() {
4800    if (!translate0) translate0 = location(d3.mouse(this));
4801    scaleTo(Math.pow(2, d3_behavior_zoomDelta() * .002) * scale);
4802    translateTo(d3.mouse(this), translate0);
4803    dispatch(event.of(this, arguments));
4804  }
4805
4806  function mousemove() {
4807    translate0 = null;
4808  }
4809
4810  function dblclick() {
4811    var p = d3.mouse(this), l = location(p);
4812    scaleTo(d3.event.shiftKey ? scale / 2 : scale * 2);
4813    translateTo(p, l);
4814    dispatch(event.of(this, arguments));
4815  }
4816
4817  function touchstart() {
4818    var touches = d3.touches(this),
4819        now = Date.now();
4820
4821    scale0 = scale;
4822    translate0 = {};
4823    touches.forEach(function(t) { translate0[t.identifier] = location(t); });
4824    d3_eventCancel();
4825
4826    if ((touches.length === 1) && (now - touchtime < 500)) { // dbltap
4827      var p = touches[0], l = location(touches[0]);
4828      scaleTo(scale * 2);
4829      translateTo(p, l);
4830      dispatch(event.of(this, arguments));
4831    }
4832    touchtime = now;
4833  }
4834
4835  function touchmove() {
4836    var touches = d3.touches(this),
4837        p0 = touches[0],
4838        l0 = translate0[p0.identifier];
4839    if (p1 = touches[1]) {
4840      var p1, l1 = translate0[p1.identifier];
4841      p0 = [(p0[0] + p1[0]) / 2, (p0[1] + p1[1]) / 2];
4842      l0 = [(l0[0] + l1[0]) / 2, (l0[1] + l1[1]) / 2];
4843      scaleTo(d3.event.scale * scale0);
4844    }
4845    translateTo(p0, l0);
4846    dispatch(event.of(this, arguments));
4847  }
4848
4849  return d3.rebind(zoom, event, "on");
4850};
4851
4852var d3_behavior_zoomDiv, // for interpreting mousewheel events
4853    d3_behavior_zoomInfinity = [0, Infinity]; // default scale extent
4854
4855function d3_behavior_zoomDelta() {
4856
4857  // mousewheel events are totally broken!
4858  // https://bugs.webkit.org/show_bug.cgi?id=40441
4859  // not only that, but Chrome and Safari differ in re. to acceleration!
4860  if (!d3_behavior_zoomDiv) {
4861    d3_behavior_zoomDiv = d3.select("body").append("div")
4862        .style("visibility", "hidden")
4863        .style("top", 0)
4864        .style("height", 0)
4865        .style("width", 0)
4866        .style("overflow-y", "scroll")
4867      .append("div")
4868        .style("height", "2000px")
4869      .node().parentNode;
4870  }
4871
4872  var e = d3.event, delta;
4873  try {
4874    d3_behavior_zoomDiv.scrollTop = 1000;
4875    d3_behavior_zoomDiv.dispatchEvent(e);
4876    delta = 1000 - d3_behavior_zoomDiv.scrollTop;
4877  } catch (error) {
4878    delta = e.wheelDelta || (-e.detail * 5);
4879  }
4880
4881  return delta;
4882}
4883d3.layout = {};
4884// Implements hierarchical edge bundling using Holten's algorithm. For each
4885// input link, a path is computed that travels through the tree, up the parent
4886// hierarchy to the least common ancestor, and then back down to the destination
4887// node. Each path is simply an array of nodes.
4888d3.layout.bundle = function() {
4889  return function(links) {
4890    var paths = [],
4891        i = -1,
4892        n = links.length;
4893    while (++i < n) paths.push(d3_layout_bundlePath(links[i]));
4894    return paths;
4895  };
4896};
4897
4898function d3_layout_bundlePath(link) {
4899  var start = link.source,
4900      end = link.target,
4901      lca = d3_layout_bundleLeastCommonAncestor(start, end),
4902      points = [start];
4903  while (start !== lca) {
4904    start = start.parent;
4905    points.push(start);
4906  }
4907  var k = points.length;
4908  while (end !== lca) {
4909    points.splice(k, 0, end);
4910    end = end.parent;
4911  }
4912  return points;
4913}
4914
4915function d3_layout_bundleAncestors(node) {
4916  var ancestors = [],
4917      parent = node.parent;
4918  while (parent != null) {
4919    ancestors.push(node);
4920    node = parent;
4921    parent = parent.parent;
4922  }
4923  ancestors.push(node);
4924  return ancestors;
4925}
4926
4927function d3_layout_bundleLeastCommonAncestor(a, b) {
4928  if (a === b) return a;
4929  var aNodes = d3_layout_bundleAncestors(a),
4930      bNodes = d3_layout_bundleAncestors(b),
4931      aNode = aNodes.pop(),
4932      bNode = bNodes.pop(),
4933      sharedNode = null;
4934  while (aNode === bNode) {
4935    sharedNode = aNode;
4936    aNode = aNodes.pop();
4937    bNode = bNodes.pop();
4938  }
4939  return sharedNode;
4940}
4941d3.layout.chord = function() {
4942  var chord = {},
4943      chords,
4944      groups,
4945      matrix,
4946      n,
4947      padding = 0,
4948      sortGroups,
4949      sortSubgroups,
4950      sortChords;
4951
4952  function relayout() {
4953    var subgroups = {},
4954        groupSums = [],
4955        groupIndex = d3.range(n),
4956        subgroupIndex = [],
4957        k,
4958        x,
4959        x0,
4960        i,
4961        j;
4962
4963    chords = [];
4964    groups = [];
4965
4966    // Compute the sum.
4967    k = 0, i = -1; while (++i < n) {
4968      x = 0, j = -1; while (++j < n) {
4969        x += matrix[i][j];
4970      }
4971      groupSums.push(x);
4972      subgroupIndex.push(d3.range(n));
4973      k += x;
4974    }
4975
4976    // Sort groups

4977    if (sortGroups) {
4978      groupIndex.sort(function(a, b) {
4979        return sortGroups(groupSums[a], groupSums[b]);
4980      });
4981    }
4982
4983    // Sort subgroups

4984    if (sortSubgroups) {
4985      subgroupIndex.forEach(function(d, i) {
4986        d.sort(function(a, b) {
4987          return sortSubgroups(matrix[i][a], matrix[i][b]);
4988        });
4989      });
4990    }
4991
4992    // Convert the sum to scaling factor for [0, 2pi].
4993    // TODO Allow start and end angle to be specified.
4994    // TODO Allow padding to be specified as percentage?
4995    k = (2 * Math.PI - padding * n) / k;
4996
4997    // Compute the start and end angle for each group and subgroup.
4998    // Note: Opera has a bug reordering object literal properties!
4999    x = 0, i = -1; while (++i < n) {
5000      x0 = x, j = -1; while (++j < n) {
5001        var di = groupIndex[i],
5002            dj = subgroupIndex[di][j],
5003            v = matrix[di][dj],
5004            a0 = x,
5005            a1 = x += v * k;
5006        subgroups[di + "-" + dj] = {
5007          index: di,
5008          subindex: dj,
5009          startAngle: a0,
5010          endAngle: a1,
5011          value: v
5012        };
5013      }
5014      groups.push({
5015        index: di,
5016        startAngle: x0,
5017        endAngle: x,
5018        value: (x - x0) / k
5019      });
5020      x += padding;
5021    }
5022
5023    // Generate chords for each (non-empty) subgroup-subgroup link.
5024    i = -1; while (++i < n) {
5025      j = i - 1; while (++j < n) {
5026        var source = subgroups[i + "-" + j],
5027            target = subgroups[j + "-" + i];
5028        if (source.value || target.value) {
5029          chords.push(source.value < target.value
5030              ? {source: target, target: source}
5031              : {source: source, target: target});
5032        }
5033      }
5034    }
5035
5036    if (sortChords) resort();
5037  }
5038
5039  function resort() {
5040    chords.sort(function(a, b) {
5041      return sortChords(
5042          (a.source.value + a.target.value) / 2,
5043          (b.source.value + b.target.value) / 2);
5044    });
5045  }
5046
5047  chord.matrix = function(x) {
5048    if (!arguments.length) return matrix;
5049    n = (matrix = x) && matrix.length;
5050    chords = groups = null;
5051    return chord;
5052  };
5053
5054  chord.padding = function(x) {
5055    if (!arguments.length) return padding;
5056    padding = x;
5057    chords = groups = null;
5058    return chord;
5059  };
5060
5061  chord.sortGroups = function(x) {
5062    if (!arguments.length) return sortGroups;
5063    sortGroups = x;
5064    chords = groups = null;
5065    return chord;
5066  };
5067
5068  chord.sortSubgroups = function(x) {
5069    if (!arguments.length) return sortSubgroups;
5070    sortSubgroups = x;
5071    chords = null;
5072    return chord;
5073  };
5074
5075  chord.sortChords = function(x) {
5076    if (!arguments.length) return sortChords;
5077    sortChords = x;
5078    if (chords) resort();
5079    return chord;
5080  };
5081
5082  chord.chords = function() {
5083    if (!chords) relayout();
5084    return chords;
5085  };
5086
5087  chord.groups = function() {
5088    if (!groups) relayout();
5089    return groups;
5090  };
5091
5092  return chord;
5093};
5094// A rudimentary force layout using Gauss-Seidel.
5095d3.layout.force = function() {
5096  var force = {},
5097      event = d3.dispatch("start", "tick", "end"),
5098      size = [1, 1],
5099      drag,
5100      alpha,
5101      friction = .9,
5102      linkDistance = d3_layout_forceLinkDistance,
5103      linkStrength = d3_layout_forceLinkStrength,
5104      charge = -30,
5105      gravity = .1,
5106      theta = .8,
5107      interval,
5108      nodes = [],
5109      links = [],
5110      distances,
5111      strengths,
5112      charges;
5113
5114  function repulse(node) {
5115    return function(quad, x1, y1, x2, y2) {
5116      if (quad.point !== node) {
5117        var dx = quad.cx - node.x,
5118            dy = quad.cy - node.y,
5119            dn = 1 / Math.sqrt(dx * dx + dy * dy);
5120
5121        /* Barnes-Hut criterion. */
5122        if ((x2 - x1) * dn < theta) {
5123          var k = quad.charge * dn * dn;
5124          node.px -= dx * k;
5125          node.py -= dy * k;
5126          return true;
5127        }
5128
5129        if (quad.point && isFinite(dn)) {
5130          var k = quad.pointCharge * dn * dn;
5131          node.px -= dx * k;
5132          node.py -= dy * k;
5133        }
5134      }
5135      return !quad.charge;
5136    };
5137  }
5138
5139  force.tick = function() {
5140    // simulated annealing, basically
5141    if ((alpha *= .99) < .005) {
5142      event.end({type: "end", alpha: alpha = 0});
5143      return true;
5144    }
5145
5146    var n = nodes.length,
5147        m = links.length,
5148        q,
5149        i, // current index
5150        o, // current object
5151        s, // current source
5152        t, // current target
5153        l, // current distance
5154        k, // current force
5155        x, // x-distance
5156        y; // y-distance
5157
5158    // gauss-seidel relaxation for links
5159    for (i = 0; i < m; ++i) {
5160      o = links[i];
5161      s = o.source;
5162      t = o.target;
5163      x = t.x - s.x;
5164      y = t.y - s.y;
5165      if (l = (x * x + y * y)) {
5166        l = alpha * strengths[i] * ((l = Math.sqrt(l)) - distances[i]) / l;
5167        x *= l;
5168        y *= l;
5169        t.x -= x * (k = s.weight / (t.weight + s.weight));
5170        t.y -= y * k;
5171        s.x += x * (k = 1 - k);
5172        s.y += y * k;
5173      }
5174    }
5175
5176    // apply gravity forces
5177    if (k = alpha * gravity) {
5178      x = size[0] / 2;
5179      y = size[1] / 2;
5180      i = -1; if (k) while (++i < n) {
5181        o = nodes[i];
5182        o.x += (x - o.x) * k;
5183        o.y += (y - o.y) * k;
5184      }
5185    }
5186
5187    // compute quadtree center of mass and apply charge forces
5188    if (charge) {
5189      d3_layout_forceAccumulate(q = d3.geom.quadtree(nodes), alpha, charges);
5190      i = -1; while (++i < n) {
5191        if (!(o = nodes[i]).fixed) {
5192          q.visit(repulse(o));
5193        }
5194      }
5195    }
5196
5197    // position verlet integration
5198    i = -1; while (++i < n) {
5199      o = nodes[i];
5200      if (o.fixed) {
5201        o.x = o.px;
5202        o.y = o.py;
5203      } else {
5204        o.x -= (o.px - (o.px = o.x)) * friction;
5205        o.y -= (o.py - (o.py = o.y)) * friction;
5206      }
5207    }
5208
5209    event.tick({type: "tick", alpha: alpha});
5210  };
5211
5212  force.nodes = function(x) {
5213    if (!arguments.length) return nodes;
5214    nodes = x;
5215    return force;
5216  };
5217
5218  force.links = function(x) {
5219    if (!arguments.length) return links;
5220    links = x;
5221    return force;
5222  };
5223
5224  force.size = function(x) {
5225    if (!arguments.length) return size;
5226    size = x;
5227    return force;
5228  };
5229
5230  force.linkDistance = function(x) {
5231    if (!arguments.length) return linkDistance;
5232    linkDistance = d3.functor(x);
5233    return force;
5234  };
5235
5236  // For backwards-compatibility.
5237  force.distance = force.linkDistance;
5238
5239  force.linkStrength = function(x) {
5240    if (!arguments.length) return linkStrength;
5241    linkStrength = d3.functor(x);
5242    return force;
5243  };
5244
5245  force.friction = function(x) {
5246    if (!arguments.length) return friction;
5247    friction = x;
5248    return force;
5249  };
5250
5251  force.charge = function(x) {
5252    if (!arguments.length) return charge;
5253    charge = typeof x === "function" ? x : +x;
5254    return force;
5255  };
5256
5257  force.gravity = function(x) {
5258    if (!arguments.length) return gravity;
5259    gravity = x;
5260    return force;
5261  };
5262
5263  force.theta = function(x) {
5264    if (!arguments.length) return theta;
5265    theta = x;
5266    return force;
5267  };
5268
5269  force.alpha = function(x) {
5270    if (!arguments.length) return alpha;
5271
5272    if (alpha) { // if we're already running
5273      if (x > 0) alpha = x; // we might keep it hot
5274      else alpha = 0; // or, next tick will dispatch "end"
5275    } else if (x > 0) { // otherwise, fire it up!
5276      event.start({type: "start", alpha: alpha = x});
5277      d3.timer(force.tick);
5278    }
5279
5280    return force;
5281  };
5282
5283  force.start = function() {
5284    var i,
5285        j,
5286        n = nodes.length,
5287        m = links.length,
5288        w = size[0],
5289        h = size[1],
5290        neighbors,
5291        o;
5292
5293    for (i = 0; i < n; ++i) {
5294      (o = nodes[i]).index = i;
5295      o.weight = 0;
5296    }
5297
5298    distances = [];
5299    strengths = [];
5300    for (i = 0; i < m; ++i) {
5301      o = links[i];
5302      if (typeof o.source == "number") o.source = nodes[o.source];
5303      if (typeof o.target == "number") o.target = nodes[o.target];
5304      distances[i] = linkDistance.call(this, o, i);
5305      strengths[i] = linkStrength.call(this, o, i);
5306      ++o.source.weight;
5307      ++o.target.weight;
5308    }
5309
5310    for (i = 0; i < n; ++i) {
5311      o = nodes[i];
5312      if (isNaN(o.x)) o.x = position("x", w);
5313      if (isNaN(o.y)) o.y = position("y", h);
5314      if (isNaN(o.px)) o.px = o.x;
5315      if (isNaN(o.py)) o.py = o.y;
5316    }
5317
5318    charges = [];
5319    if (typeof charge === "function") {
5320      for (i = 0; i < n; ++i) {
5321        charges[i] = +charge.call(this, nodes[i], i);
5322      }
5323    } else {
5324      for (i = 0; i < n; ++i) {
5325        charges[i] = charge;
5326      }
5327    }
5328
5329    // initialize node position based on first neighbor
5330    function position(dimension, size) {
5331      var neighbors = neighbor(i),
5332          j = -1,
5333          m = neighbors.length,
5334          x;
5335      while (++j < m) if (!isNaN(x = neighbors[j][dimension])) return x;
5336      return Math.random() * size;
5337    }
5338
5339    // initialize neighbors lazily
5340    function neighbor() {
5341      if (!neighbors) {
5342        neighbors = [];
5343        for (j = 0; j < n; ++j) {
5344          neighbors[j] = [];
5345        }
5346        for (j = 0; j < m; ++j) {
5347          var o = links[j];
5348          neighbors[o.source.index].push(o.target);
5349          neighbors[o.target.index].push(o.source);
5350        }
5351      }
5352      return neighbors[i];
5353    }
5354
5355    return force.resume();
5356  };
5357
5358  force.resume = function() {
5359    return force.alpha(.1);
5360  };
5361
5362  force.stop = function() {
5363    return force.alpha(0);
5364  };
5365
5366  // use `node.call(force.drag)` to make nodes draggable
5367  force.drag = function() {
5368    if (!drag) drag = d3.behavior.drag()
5369        .origin(Object)
5370        .on("dragstart", dragstart)
5371        .on("drag", d3_layout_forceDrag)
5372        .on("dragend", d3_layout_forceDragEnd);
5373
5374    this.on("mouseover.force", d3_layout_forceDragOver)
5375        .on("mouseout.force", d3_layout_forceDragOut)
5376        .call(drag);
5377  };
5378
5379  function dragstart(d) {
5380    d3_layout_forceDragOver(d3_layout_forceDragNode = d);
5381    d3_layout_forceDragForce = force;
5382  }
5383
5384  return d3.rebind(force, event, "on");
5385};
5386
5387var d3_layout_forceDragForce,
5388    d3_layout_forceDragNode;
5389
5390function d3_layout_forceDragOver(d) {
5391  d.fixed |= 2;
5392}
5393
5394function d3_layout_forceDragOut(d) {
5395  if (d !== d3_layout_forceDragNode) d.fixed &= 1;
5396}
5397
5398function d3_layout_forceDragEnd() {
5399  d3_layout_forceDragNode.fixed &= 1;
5400  d3_layout_forceDragForce = d3_layout_forceDragNode = null;
5401}
5402
5403function d3_layout_forceDrag() {
5404  d3_layout_forceDragNode.px = d3.event.x;
5405  d3_layout_forceDragNode.py = d3.event.y;
5406  d3_layout_forceDragForce.resume(); // restart annealing
5407}
5408
5409function d3_layout_forceAccumulate(quad, alpha, charges) {
5410  var cx = 0,
5411      cy = 0;
5412  quad.charge = 0;
5413  if (!quad.leaf) {
5414    var nodes = quad.nodes,
5415        n = nodes.length,
5416        i = -1,
5417        c;
5418    while (++i < n) {
5419      c = nodes[i];
5420      if (c == null) continue;
5421      d3_layout_forceAccumulate(c, alpha, charges);
5422      quad.charge += c.charge;
5423      cx += c.charge * c.cx;
5424      cy += c.charge * c.cy;
5425    }
5426  }
5427  if (quad.point) {
5428    // jitter internal nodes that are coincident
5429    if (!quad.leaf) {
5430      quad.point.x += Math.random() - .5;
5431      quad.point.y += Math.random() - .5;
5432    }
5433    var k = alpha * charges[quad.point.index];
5434    quad.charge += quad.pointCharge = k;
5435    cx += k * quad.point.x;
5436    cy += k * quad.point.y;
5437  }
5438  quad.cx = cx / quad.charge;
5439  quad.cy = cy / quad.charge;
5440}
5441
5442function d3_layout_forceLinkDistance(link) {
5443  return 20;
5444}
5445
5446function d3_layout_forceLinkStrength(link) {
5447  return 1;
5448}
5449d3.layout.partition = function() {
5450  var hierarchy = d3.layout.hierarchy(),
5451      size = [1, 1]; // width, height
5452
5453  function position(node, x, dx, dy) {
5454    var children = node.children;
5455    node.x = x;
5456    node.y = node.depth * dy;
5457    node.dx = dx;
5458    node.dy = dy;
5459    if (children && (n = children.length)) {
5460      var i = -1,
5461          n,
5462          c,
5463          d;
5464      dx = node.value ? dx / node.value : 0;
5465      while (++i < n) {
5466        position(c = children[i], x, d = c.value * dx, dy);
5467        x += d;
5468      }
5469    }
5470  }
5471
5472  function depth(node) {
5473    var children = node.children,
5474        d = 0;
5475    if (children && (n = children.length)) {
5476      var i = -1,
5477          n;
5478      while (++i < n) d = Math.max(d, depth(children[i]));
5479    }
5480    return 1 + d;
5481  }
5482
5483  function partition(d, i) {
5484    var nodes = hierarchy.call(this, d, i);
5485    position(nodes[0], 0, size[0], size[1] / depth(nodes[0]));
5486    return nodes;
5487  }
5488
5489  partition.size = function(x) {
5490    if (!arguments.length) return size;
5491    size = x;
5492    return partition;
5493  };
5494
5495  return d3_layout_hierarchyRebind(partition, hierarchy);
5496};
5497d3.layout.pie = function() {
5498  var value = Number,
5499      sort = d3_layout_pieSortByValue,
5500      startAngle = 0,
5501      endAngle = 2 * Math.PI;
5502
5503  function pie(data, i) {
5504
5505    // Compute the numeric values for each data element.
5506    var values = data.map(function(d, i) { return +value.call(pie, d, i); });
5507
5508    // Compute the start angle.
5509    var a = +(typeof startAngle === "function"
5510        ? startAngle.apply(this, arguments)
5511        : startAngle);
5512
5513    // Compute the angular scale factor: from value to radians.
5514    var k = ((typeof endAngle === "function"
5515        ? endAngle.apply(this, arguments)
5516        : endAngle) - startAngle)
5517        / d3.sum(values);
5518
5519    // Optionally sort the data.
5520    var index = d3.range(data.length);
5521    if (sort != null) index.sort(sort === d3_layout_pieSortByValue
5522        ? function(i, j) { return values[j] - values[i]; }
5523        : function(i, j) { return sort(data[i], data[j]); });
5524
5525    // Compute the arcs!
5526    // They are stored in the original data's order.
5527    var arcs = [];
5528    index.forEach(function(i) {
5529      arcs[i] = {
5530        data: data[i],
5531        value: d = values[i],
5532        startAngle: a,
5533        endAngle: a += d * k
5534      };
5535    });
5536    return arcs;
5537  }
5538
5539  /**
5540   * Specifies the value function *x*, which returns a nonnegative numeric value
5541   * for each datum. The default value function is `Number`. The value function
5542   * is passed two arguments: the current datum and the current index.
5543   */
5544  pie.value = function(x) {
5545    if (!arguments.length) return value;
5546    value = x;
5547    return pie;
5548  };
5549
5550  /**
5551   * Specifies a sort comparison operator *x*. The comparator is passed two data
5552   * elements from the data array, a and b; it returns a negative value if a is
5553   * less than b, a positive value if a is greater than b, and zero if a equals
5554   * b.
5555   */
5556  pie.sort = function(x) {
5557    if (!arguments.length) return sort;
5558    sort = x;
5559    return pie;
5560  };
5561
5562  /**
5563   * Specifies the overall start angle of the pie chart. Defaults to 0. The
5564   * start angle can be specified either as a constant or as a function; in the
5565   * case of a function, it is evaluated once per array (as opposed to per
5566   * element).
5567   */
5568  pie.startAngle = function(x) {
5569    if (!arguments.length) return startAngle;
5570    startAngle = x;
5571    return pie;
5572  };
5573
5574  /**
5575   * Specifies the overall end angle of the pie chart. Defaults to 2π. The
5576   * end angle can be specified either as a constant or as a function; in the
5577   * case of a function, it is evaluated once per array (as opposed to per
5578   * element).
5579   */
5580  pie.endAngle = function(x) {
5581    if (!arguments.length) return endAngle;
5582    endAngle = x;
5583    return pie;
5584  };
5585
5586  return pie;
5587};
5588
5589var d3_layout_pieSortByValue = {};
5590// data is two-dimensional array of x,y; we populate y0
5591d3.layout.stack = function() {
5592  var values = Object,
5593      order = d3_layout_stackOrderDefault,
5594      offset = d3_layout_stackOffsetZero,
5595      out = d3_layout_stackOut,
5596      x = d3_layout_stackX,
5597      y = d3_layout_stackY;
5598
5599  function stack(data, index) {
5600
5601    // Convert series to canonical two-dimensional representation.
5602    var series = data.map(function(d, i) {
5603      return values.call(stack, d, i);
5604    });
5605
5606    // Convert each series to canonical [[x,y]] representation.
5607    var points = series.map(function(d, i) {
5608      return d.map(function(v, i) {
5609        return [x.call(stack, v, i), y.call(stack, v, i)];
5610      });
5611    });
5612
5613    // Compute the order of series, and permute them.
5614    var orders = order.call(stack, points, index);
5615    series = d3.permute(series, orders);
5616    points = d3.permute(points, orders);
5617
5618    // Compute the baseline

5619    var offsets = offset.call(stack, points, index);
5620
5621    // And propagate it to other series.
5622    var n = series.length,
5623        m = series[0].length,
5624        i,
5625        j,
5626        o;
5627    for (j = 0; j < m; ++j) {
5628      out.call(stack, series[0][j], o = offsets[j], points[0][j][1]);
5629      for (i = 1; i < n; ++i) {
5630        out.call(stack, series[i][j], o += points[i - 1][j][1], points[i][j][1]);
5631      }
5632    }
5633
5634    return data;
5635  }
5636
5637  stack.values = function(x) {
5638    if (!arguments.length) return values;
5639    values = x;
5640    return stack;
5641  };
5642
5643  stack.order = function(x) {
5644    if (!arguments.length) return order;
5645    order = typeof x === "function" ? x : d3_layout_stackOrders.get(x) || d3_layout_stackOrderDefault;
5646    return stack;
5647  };
5648
5649  stack.offset = function(x) {
5650    if (!arguments.length) return offset;
5651    offset = typeof x === "function" ? x : d3_layout_stackOffsets.get(x) || d3_layout_stackOffsetZero;
5652    return stack;
5653  };
5654
5655  stack.x = function(z) {
5656    if (!arguments.length) return x;
5657    x = z;
5658    return stack;
5659  };
5660
5661  stack.y = function(z) {
5662    if (!arguments.length) return y;
5663    y = z;
5664    return stack;
5665  };
5666
5667  stack.out = function(z) {
5668    if (!arguments.length) return out;
5669    out = z;
5670    return stack;
5671  };
5672
5673  return stack;
5674}
5675
5676function d3_layout_stackX(d) {
5677  return d.x;
5678}
5679
5680function d3_layout_stackY(d) {
5681  return d.y;
5682}
5683
5684function d3_layout_stackOut(d, y0, y) {
5685  d.y0 = y0;
5686  d.y = y;
5687}
5688
5689var d3_layout_stackOrders = d3.map({
5690
5691  "inside-out": function(data) {
5692    var n = data.length,
5693        i,
5694        j,
5695        max = data.map(d3_layout_stackMaxIndex),
5696        sums = data.map(d3_layout_stackReduceSum),
5697        index = d3.range(n).sort(function(a, b) { return max[a] - max[b]; }),
5698        top = 0,
5699        bottom = 0,
5700        tops = [],
5701        bottoms = [];
5702    for (i = 0; i < n; ++i) {
5703      j = index[i];
5704      if (top < bottom) {
5705        top += sums[j];
5706        tops.push(j);
5707      } else {
5708        bottom += sums[j];
5709        bottoms.push(j);
5710      }
5711    }
5712    return bottoms.reverse().concat(tops);
5713  },
5714
5715  "reverse": function(data) {
5716    return d3.range(data.length).reverse();
5717  },
5718
5719  "default": d3_layout_stackOrderDefault
5720
5721});
5722
5723var d3_layout_stackOffsets = d3.map({
5724
5725  "silhouette": function(data) {
5726    var n = data.length,
5727        m = data[0].length,
5728        sums = [],
5729        max = 0,
5730        i,
5731        j,
5732        o,
5733        y0 = [];
5734    for (j = 0; j < m; ++j) {
5735      for (i = 0, o = 0; i < n; i++) o += data[i][j][1];
5736      if (o > max) max = o;
5737      sums.push(o);
5738    }
5739    for (j = 0; j < m; ++j) {
5740      y0[j] = (max - sums[j]) / 2;
5741    }
5742    return y0;
5743  },
5744
5745  "wiggle": function(data) {
5746    var n = data.length,
5747        x = data[0],
5748        m = x.length,
5749        max = 0,
5750        i,
5751        j,
5752        k,
5753        s1,
5754        s2,
5755        s3,
5756        dx,
5757        o,
5758        o0,
5759        y0 = [];
5760    y0[0] = o = o0 = 0;
5761    for (j = 1; j < m; ++j) {
5762      for (i = 0, s1 = 0; i < n; ++i) s1 += data[i][j][1];
5763      for (i = 0, s2 = 0, dx = x[j][0] - x[j - 1][0]; i < n; ++i) {
5764        for (k = 0, s3 = (data[i][j][1] - data[i][j - 1][1]) / (2 * dx); k < i; ++k) {
5765          s3 += (data[k][j][1] - data[k][j - 1][1]) / dx;
5766        }
5767        s2 += s3 * data[i][j][1];
5768      }
5769      y0[j] = o -= s1 ? s2 / s1 * dx : 0;
5770      if (o < o0) o0 = o;
5771    }
5772    for (j = 0; j < m; ++j) y0[j] -= o0;
5773    return y0;
5774  },
5775
5776  "expand": function(data) {
5777    var n = data.length,
5778        m = data[0].length,
5779        k = 1 / n,
5780        i,
5781        j,
5782        o,
5783        y0 = [];
5784    for (j = 0; j < m; ++j) {
5785      for (i = 0, o = 0; i < n; i++) o += data[i][j][1];
5786      if (o) for (i = 0; i < n; i++) data[i][j][1] /= o;
5787      else for (i = 0; i < n; i++) data[i][j][1] = k;
5788    }
5789    for (j = 0; j < m; ++j) y0[j] = 0;
5790    return y0;
5791  },
5792
5793  "zero": d3_layout_stackOffsetZero
5794
5795});
5796
5797function d3_layout_stackOrderDefault(data) {
5798  return d3.range(data.length);
5799}
5800
5801function d3_layout_stackOffsetZero(data) {
5802  var j = -1,
5803      m = data[0].length,
5804      y0 = [];
5805  while (++j < m) y0[j] = 0;
5806  return y0;
5807}
5808
5809function d3_layout_stackMaxIndex(array) {
5810  var i = 1,
5811      j = 0,
5812      v = array[0][1],
5813      k,
5814      n = array.length;
5815  for (; i < n; ++i) {
5816    if ((k = array[i][1]) > v) {
5817      j = i;
5818      v = k;
5819    }
5820  }
5821  return j;
5822}
5823
5824function d3_layout_stackReduceSum(d) {
5825  return d.reduce(d3_layout_stackSum, 0);
5826}
5827
5828function d3_layout_stackSum(p, d) {
5829  return p + d[1];
5830}
5831d3.layout.histogram = function() {
5832  var frequency = true,
5833      valuer = Number,
5834      ranger = d3_layout_histogramRange,
5835      binner = d3_layout_histogramBinSturges;
5836
5837  function histogram(data, i) {
5838    var bins = [],
5839        values = data.map(valuer, this),
5840        range = ranger.call(this, values, i),
5841        thresholds = binner.call(this, range, values, i),
5842        bin,
5843        i = -1,
5844        n = values.length,
5845        m = thresholds.length - 1,
5846        k = frequency ? 1 : 1 / n,
5847        x;
5848
5849    // Initialize the bins.
5850    while (++i < m) {
5851      bin = bins[i] = [];
5852      bin.dx = thresholds[i + 1] - (bin.x = thresholds[i]);
5853      bin.y = 0;
5854    }
5855
5856    // Fill the bins, ignoring values outside the range.
5857    i = -1; while(++i < n) {
5858      x = values[i];
5859      if ((x >= range[0]) && (x <= range[1])) {
5860        bin = bins[d3.bisect(thresholds, x, 1, m) - 1];
5861        bin.y += k;
5862        bin.push(data[i]);
5863      }
5864    }
5865
5866    return bins;
5867  }
5868
5869  // Specifies how to extract a value from the associated data. The default
5870  // value function is `Number`, which is equivalent to the identity function.
5871  histogram.value = function(x) {
5872    if (!arguments.length) return valuer;
5873    valuer = x;
5874    return histogram;
5875  };
5876
5877  // Specifies the range of the histogram. Values outside the specified range
5878  // will be ignored. The argument `x` may be specified either as a two-element
5879  // array representing the minimum and maximum value of the range, or as a
5880  // function that returns the range given the array of values and the current
5881  // index `i`. The default range is the extent (minimum and maximum) of the
5882  // values.
5883  histogram.range = function(x) {
5884    if (!arguments.length) return ranger;
5885    ranger = d3.functor(x);
5886    return histogram;
5887  };
5888
5889  // Specifies how to bin values in the histogram. The argument `x` may be
5890  // specified as a number, in which case the range of values will be split
5891  // uniformly into the given number of bins. Or, `x` may be an array of
5892  // threshold values, defining the bins; the specified array must contain the
5893  // rightmost (upper) value, thus specifying n + 1 values for n bins. Or, `x`
5894  // may be a function which is evaluated, being passed the range, the array of
5895  // values, and the current index `i`, returning an array of thresholds. The
5896  // default bin function will divide the values into uniform bins using
5897  // Sturges' formula.
5898  histogram.bins = function(x) {
5899    if (!arguments.length) return binner;
5900    binner = typeof x === "number"
5901        ? function(range) { return d3_layout_histogramBinFixed(range, x); }
5902        : d3.functor(x);
5903    return histogram;
5904  };
5905
5906  // Specifies whether the histogram's `y` value is a count (frequency) or a
5907  // probability (density). The default value is true.
5908  histogram.frequency = function(x) {
5909    if (!arguments.length) return frequency;
5910    frequency = !!x;
5911    return histogram;
5912  };
5913
5914  return histogram;
5915};
5916
5917function d3_layout_histogramBinSturges(range, values) {
5918  return d3_layout_histogramBinFixed(range, Math.ceil(Math.log(values.length) / Math.LN2 + 1));
5919}
5920
5921function d3_layout_histogramBinFixed(range, n) {
5922  var x = -1,
5923      b = +range[0],
5924      m = (range[1] - b) / n,
5925      f = [];
5926  while (++x <= n) f[x] = m * x + b;
5927  return f;
5928}
5929
5930function d3_layout_histogramRange(values) {
5931  return [d3.min(values), d3.max(values)];
5932}
5933d3.layout.hierarchy = function() {
5934  var sort = d3_layout_hierarchySort,
5935      children = d3_layout_hierarchyChildren,
5936      value = d3_layout_hierarchyValue;
5937
5938  // Recursively compute the node depth and value.
5939  // Also converts the data representation into a standard hierarchy structure.
5940  function recurse(data, depth, nodes) {
5941    var childs = children.call(hierarchy, data, depth),
5942        node = d3_layout_hierarchyInline ? data : {data: data};
5943    node.depth = depth;
5944    nodes.push(node);
5945    if (childs && (n = childs.length)) {
5946      var i = -1,
5947          n,
5948          c = node.children = [],
5949          v = 0,
5950          j = depth + 1;
5951      while (++i < n) {
5952        d = recurse(childs[i], j, nodes);
5953        d.parent = node;
5954        c.push(d);
5955        v += d.value;
5956      }
5957      if (sort) c.sort(sort);
5958      if (value) node.value = v;
5959    } else if (value) {
5960      node.value = +value.call(hierarchy, data, depth) || 0;
5961    }
5962    return node;
5963  }
5964
5965  // Recursively re-evaluates the node value.
5966  function revalue(node, depth) {
5967    var children = node.children,
5968        v = 0;
5969    if (children && (n = children.length)) {
5970      var i = -1,
5971          n,
5972          j = depth + 1;
5973      while (++i < n) v += revalue(children[i], j);
5974    } else if (value) {
5975      v = +value.call(hierarchy, d3_layout_hierarchyInline ? node : node.data, depth) || 0;
5976    }
5977    if (value) node.value = v;
5978    return v;
5979  }
5980
5981  function hierarchy(d) {
5982    var nodes = [];
5983    recurse(d, 0, nodes);
5984    return nodes;
5985  }
5986
5987  hierarchy.sort = function(x) {
5988    if (!arguments.length) return sort;
5989    sort = x;
5990    return hierarchy;
5991  };
5992
5993  hierarchy.children = function(x) {
5994    if (!arguments.length) return children;
5995    children = x;
5996    return hierarchy;
5997  };
5998
5999  hierarchy.value = function(x) {
6000    if (!arguments.length) return value;
6001    value = x;
6002    return hierarchy;
6003  };
6004
6005  // Re-evaluates the `value` property for the specified hierarchy.
6006  hierarchy.revalue = function(root) {
6007    revalue(root, 0);
6008    return root;
6009  };
6010
6011  return hierarchy;
6012};
6013
6014// A method assignment helper for hierarchy subclasses.
6015function d3_layout_hierarchyRebind(object, hierarchy) {
6016  d3.rebind(object, hierarchy, "sort", "children", "value");
6017
6018  // Add an alias for links, for convenience.
6019  object.links = d3_layout_hierarchyLinks;
6020
6021  // If the new API is used, enabling inlining.
6022  object.nodes = function(d) {
6023    d3_layout_hierarchyInline = true;
6024    return (object.nodes = object)(d);
6025  };
6026
6027  return object;
6028}
6029
6030function d3_layout_hierarchyChildren(d) {
6031  return d.children;
6032}
6033
6034function d3_layout_hierarchyValue(d) {
6035  return d.value;
6036}
6037
6038function d3_layout_hierarchySort(a, b) {
6039  return b.value - a.value;
6040}
6041
6042// Returns an array source+target objects for the specified nodes.
6043function d3_layout_hierarchyLinks(nodes) {
6044  return d3.merge(nodes.map(function(parent) {
6045    return (parent.children || []).map(function(child) {
6046      return {source: parent, target: child};
6047    });
6048  }));
6049}
6050
6051// For backwards-compatibility, don't enable inlining by default.
6052var d3_layout_hierarchyInline = false;
6053d3.layout.pack = function() {
6054  var hierarchy = d3.layout.hierarchy().sort(d3_layout_packSort),
6055      size = [1, 1];
6056
6057  function pack(d, i) {
6058    var nodes = hierarchy.call(this, d, i),
6059        root = nodes[0];
6060
6061    // Recursively compute the layout.
6062    root.x = 0;
6063    root.y = 0;
6064    d3_layout_packTree(root);
6065
6066    // Scale the layout to fit the requested size.
6067    var w = size[0],
6068        h = size[1],
6069        k = 1 / Math.max(2 * root.r / w, 2 * root.r / h);
6070    d3_layout_packTransform(root, w / 2, h / 2, k);
6071
6072    return nodes;
6073  }
6074
6075  pack.size = function(x) {
6076    if (!arguments.length) return size;
6077    size = x;
6078    return pack;
6079  };
6080
6081  return d3_layout_hierarchyRebind(pack, hierarchy);
6082};
6083
6084function d3_layout_packSort(a, b) {
6085  return a.value - b.value;
6086}
6087
6088function d3_layout_packInsert(a, b) {
6089  var c = a._pack_next;
6090  a._pack_next = b;
6091  b._pack_prev = a;
6092  b._pack_next = c;
6093  c._pack_prev = b;
6094}
6095
6096function d3_layout_packSplice(a, b) {
6097  a._pack_next = b;
6098  b._pack_prev = a;
6099}
6100
6101function d3_layout_packIntersects(a, b) {
6102  var dx = b.x - a.x,
6103      dy = b.y - a.y,
6104      dr = a.r + b.r;
6105  return dr * dr - dx * dx - dy * dy > .001; // within epsilon
6106}
6107
6108function d3_layout_packCircle(nodes) {
6109  var xMin = Infinity,
6110      xMax = -Infinity,
6111      yMin = Infinity,
6112      yMax = -Infinity,
6113      n = nodes.length,
6114      a, b, c, j, k;
6115
6116  function bound(node) {
6117    xMin = Math.min(node.x - node.r, xMin);
6118    xMax = Math.max(node.x + node.r, xMax);
6119    yMin = Math.min(node.y - node.r, yMin);
6120    yMax = Math.max(node.y + node.r, yMax);
6121  }
6122
6123  // Create node links.
6124  nodes.forEach(d3_layout_packLink);
6125
6126  // Create first node.
6127  a = nodes[0];
6128  a.x = -a.r;
6129  a.y = 0;
6130  bound(a);
6131
6132  // Create second node.
6133  if (n > 1) {
6134    b = nodes[1];
6135    b.x = b.r;
6136    b.y = 0;
6137    bound(b);
6138
6139    // Create third node and build chain.
6140    if (n > 2) {
6141      c = nodes[2];
6142      d3_layout_packPlace(a, b, c);
6143      bound(c);
6144      d3_layout_packInsert(a, c);
6145      a._pack_prev = c;
6146      d3_layout_packInsert(c, b);
6147      b = a._pack_next;
6148
6149      // Now iterate through the rest.
6150      for (var i = 3; i < n; i++) {
6151        d3_layout_packPlace(a, b, c = nodes[i]);
6152
6153        // Search for the closest intersection.
6154        var isect = 0, s1 = 1, s2 = 1;
6155        for (j = b._pack_next; j !== b; j = j._pack_next, s1++) {
6156          if (d3_layout_packIntersects(j, c)) {
6157            isect = 1;
6158            break;
6159          }
6160        }
6161        if (isect == 1) {
6162          for (k = a._pack_prev; k !== j._pack_prev; k = k._pack_prev, s2++) {
6163            if (d3_layout_packIntersects(k, c)) {
6164              break;
6165            }
6166          }
6167        }
6168
6169        // Update node chain.
6170        if (isect) {
6171          if (s1 < s2 || (s1 == s2 && b.r < a.r)) d3_layout_packSplice(a, b = j);
6172          else d3_layout_packSplice(a = k, b);
6173          i--;
6174        } else {
6175          d3_layout_packInsert(a, c);
6176          b = c;
6177          bound(c);
6178        }
6179      }
6180    }
6181  }
6182
6183  // Re-center the circles and return the encompassing radius.
6184  var cx = (xMin + xMax) / 2,
6185      cy = (yMin + yMax) / 2,
6186      cr = 0;
6187  for (var i = 0; i < n; i++) {
6188    var node = nodes[i];
6189    node.x -= cx;
6190    node.y -= cy;
6191    cr = Math.max(cr, node.r + Math.sqrt(node.x * node.x + node.y * node.y));
6192  }
6193
6194  // Remove node links.
6195  nodes.forEach(d3_layout_packUnlink);
6196
6197  return cr;
6198}
6199
6200function d3_layout_packLink(node) {
6201  node._pack_next = node._pack_prev = node;
6202}
6203
6204function d3_layout_packUnlink(node) {
6205  delete node._pack_next;
6206  delete node._pack_prev;
6207}
6208
6209function d3_layout_packTree(node) {
6210  var children = node.children;
6211  if (children && children.length) {
6212    children.forEach(d3_layout_packTree);
6213    node.r = d3_layout_packCircle(children);
6214  } else {
6215    node.r = Math.sqrt(node.value);
6216  }
6217}
6218
6219function d3_layout_packTransform(node, x, y, k) {
6220  var children = node.children;
6221  node.x = (x += k * node.x);
6222  node.y = (y += k * node.y);
6223  node.r *= k;
6224  if (children) {
6225    var i = -1, n = children.length;
6226    while (++i < n) d3_layout_packTransform(children[i], x, y, k);
6227  }
6228}
6229
6230function d3_layout_packPlace(a, b, c) {
6231  var db = a.r + c.r,
6232      dx = b.x - a.x,
6233      dy = b.y - a.y;
6234  if (db && (dx || dy)) {
6235    var da = b.r + c.r,
6236        dc = Math.sqrt(dx * dx + dy * dy),
6237        cos = Math.max(-1, Math.min(1, (db * db + dc * dc - da * da) / (2 * db * dc))),
6238        theta = Math.acos(cos),
6239        x = cos * (db /= dc),
6240        y = Math.sin(theta) * db;
6241    c.x = a.x + x * dx + y * dy;
6242    c.y = a.y + x * dy - y * dx;
6243  } else {
6244    c.x = a.x + db;
6245    c.y = a.y;
6246  }
6247}
6248// Implements a hierarchical layout using the cluster (or dendrogram)
6249// algorithm.
6250d3.layout.cluster = function() {
6251  var hierarchy = d3.layout.hierarchy().sort(null).value(null),
6252      separation = d3_layout_treeSeparation,
6253      size = [1, 1]; // width, height
6254
6255  function cluster(d, i) {
6256    var nodes = hierarchy.call(this, d, i),
6257        root = nodes[0],
6258        previousNode,
6259        x = 0,
6260        kx,
6261        ky;
6262
6263    // First walk, computing the initial x & y values.
6264    d3_layout_treeVisitAfter(root, function(node) {
6265      var children = node.children;
6266      if (children && children.length) {
6267        node.x = d3_layout_clusterX(children);
6268        node.y = d3_layout_clusterY(children);
6269      } else {
6270        node.x = previousNode ? x += separation(node, previousNode) : 0;
6271        node.y = 0;
6272        previousNode = node;
6273      }
6274    });
6275
6276    // Compute the left-most, right-most, and depth-most nodes for extents.
6277    var left = d3_layout_clusterLeft(root),
6278        right = d3_layout_clusterRight(root),
6279        x0 = left.x - separation(left, right) / 2,
6280        x1 = right.x + separation(right, left) / 2;
6281
6282    // Second walk, normalizing x & y to the desired size.
6283    d3_layout_treeVisitAfter(root, function(node) {
6284      node.x = (node.x - x0) / (x1 - x0) * size[0];
6285      node.y = (1 - (root.y ? node.y / root.y : 1)) * size[1];
6286    });
6287
6288    return nodes;
6289  }
6290
6291  cluster.separation = function(x) {
6292    if (!arguments.length) return separation;
6293    separation = x;
6294    return cluster;
6295  };
6296
6297  cluster.size = function(x) {
6298    if (!arguments.length) return size;
6299    size = x;
6300    return cluster;
6301  };
6302
6303  return d3_layout_hierarchyRebind(cluster, hierarchy);
6304};
6305
6306function d3_layout_clusterY(children) {
6307  return 1 + d3.max(children, function(child) {
6308    return child.y;
6309  });
6310}
6311
6312function d3_layout_clusterX(children) {
6313  return children.reduce(function(x, child) {
6314    return x + child.x;
6315  }, 0) / children.length;
6316}
6317
6318function d3_layout_clusterLeft(node) {
6319  var children = node.children;
6320  return children && children.length ? d3_layout_clusterLeft(children[0]) : node;
6321}
6322
6323function d3_layout_clusterRight(node) {
6324  var children = node.children, n;
6325  return children && (n = children.length) ? d3_layout_clusterRight(children[n - 1]) : node;
6326}
6327// Node-link tree diagram using the Reingold-Tilford "tidy" algorithm
6328d3.layout.tree = function() {
6329  var hierarchy = d3.layout.hierarchy().sort(null).value(null),
6330      separation = d3_layout_treeSeparation,
6331      size = [1, 1]; // width, height
6332
6333  function tree(d, i) {
6334    var nodes = hierarchy.call(this, d, i),
6335        root = nodes[0];
6336
6337    function firstWalk(node, previousSibling) {
6338      var children = node.children,
6339          layout = node._tree;
6340      if (children && (n = children.length)) {
6341        var n,
6342            firstChild = children[0],
6343            previousChild,
6344            ancestor = firstChild,
6345            child,
6346            i = -1;
6347        while (++i < n) {
6348          child = children[i];
6349          firstWalk(child, previousChild);
6350          ancestor = apportion(child, previousChild, ancestor);
6351          previousChild = child;
6352        }
6353        d3_layout_treeShift(node);
6354        var midpoint = .5 * (firstChild._tree.prelim + child._tree.prelim);
6355        if (previousSibling) {
6356          layout.prelim = previousSibling._tree.prelim + separation(node, previousSibling);
6357          layout.mod = layout.prelim - midpoint;
6358        } else {
6359          layout.prelim = midpoint;
6360        }
6361      } else {
6362        if (previousSibling) {
6363          layout.prelim = previousSibling._tree.prelim + separation(node, previousSibling);
6364        }
6365      }
6366    }
6367
6368    function secondWalk(node, x) {
6369      node.x = node._tree.prelim + x;
6370      var children = node.children;
6371      if (children && (n = children.length)) {
6372        var i = -1,
6373            n;
6374        x += node._tree.mod;
6375        while (++i < n) {
6376          secondWalk(children[i], x);
6377        }
6378      }
6379    }
6380
6381    function apportion(node, previousSibling, ancestor) {
6382      if (previousSibling) {
6383        var vip = node,
6384            vop = node,
6385            vim = previousSibling,
6386            vom = node.parent.children[0],
6387            sip = vip._tree.mod,
6388            sop = vop._tree.mod,
6389            sim = vim._tree.mod,
6390            som = vom._tree.mod,
6391            shift;
6392        while (vim = d3_layout_treeRight(vim), vip = d3_layout_treeLeft(vip), vim && vip) {
6393          vom = d3_layout_treeLeft(vom);
6394          vop = d3_layout_treeRight(vop);
6395          vop._tree.ancestor = node;
6396          shift = vim._tree.prelim + sim - vip._tree.prelim - sip + separation(vim, vip);
6397          if (shift > 0) {
6398            d3_layout_treeMove(d3_layout_treeAncestor(vim, node, ancestor), node, shift);
6399            sip += shift;
6400            sop += shift;
6401          }
6402          sim += vim._tree.mod;
6403          sip += vip._tree.mod;
6404          som += vom._tree.mod;
6405          sop += vop._tree.mod;
6406        }
6407        if (vim && !d3_layout_treeRight(vop)) {
6408          vop._tree.thread = vim;
6409          vop._tree.mod += sim - sop;
6410        }
6411        if (vip && !d3_layout_treeLeft(vom)) {
6412          vom._tree.thread = vip;
6413          vom._tree.mod += sip - som;
6414          ancestor = node;
6415        }
6416      }
6417      return ancestor;
6418    }
6419
6420    // Initialize temporary layout variables.
6421    d3_layout_treeVisitAfter(root, function(node, previousSibling) {
6422      node._tree = {
6423        ancestor: node,
6424        prelim: 0,
6425        mod: 0,
6426        change: 0,
6427        shift: 0,
6428        number: previousSibling ? previousSibling._tree.number + 1 : 0
6429      };
6430    });
6431
6432    // Compute the layout using Buchheim et al.'s algorithm.
6433    firstWalk(root);
6434    secondWalk(root, -root._tree.prelim);
6435
6436    // Compute the left-most, right-most, and depth-most nodes for extents.
6437    var left = d3_layout_treeSearch(root, d3_layout_treeLeftmost),
6438        right = d3_layout_treeSearch(root, d3_layout_treeRightmost),
6439        deep = d3_layout_treeSearch(root, d3_layout_treeDeepest),
6440        x0 = left.x - separation(left, right) / 2,
6441        x1 = right.x + separation(right, left) / 2,
6442        y1 = deep.depth || 1;
6443
6444    // Clear temporary layout variables; transform x and y.
6445    d3_layout_treeVisitAfter(root, function(node) {
6446      node.x = (node.x - x0) / (x1 - x0) * size[0];
6447      node.y = node.depth / y1 * size[1];
6448      delete node._tree;
6449    });
6450
6451    return nodes;
6452  }
6453
6454  tree.separation = function(x) {
6455    if (!arguments.length) return separation;
6456    separation = x;
6457    return tree;
6458  };
6459
6460  tree.size = function(x) {
6461    if (!arguments.length) return size;
6462    size = x;
6463    return tree;
6464  };
6465
6466  return d3_layout_hierarchyRebind(tree, hierarchy);
6467};
6468
6469function d3_layout_treeSeparation(a, b) {
6470  return a.parent == b.parent ? 1 : 2;
6471}
6472
6473// function d3_layout_treeSeparationRadial(a, b) {
6474//   return (a.parent == b.parent ? 1 : 2) / a.depth;
6475// }
6476
6477function d3_layout_treeLeft(node) {
6478  var children = node.children;
6479  return children && children.length ? children[0] : node._tree.thread;
6480}
6481
6482function d3_layout_treeRight(node) {
6483  var children = node.children,
6484      n;
6485  return children && (n = children.length) ? children[n - 1] : node._tree.thread;
6486}
6487
6488function d3_layout_treeSearch(node, compare) {
6489  var children = node.children;
6490  if (children && (n = children.length)) {
6491    var child,
6492        n,
6493        i = -1;
6494    while (++i < n) {
6495      if (compare(child = d3_layout_treeSearch(children[i], compare), node) > 0) {
6496        node = child;
6497      }
6498    }
6499  }
6500  return node;
6501}
6502
6503function d3_layout_treeRightmost(a, b) {
6504  return a.x - b.x;
6505}
6506
6507function d3_layout_treeLeftmost(a, b) {
6508  return b.x - a.x;
6509}
6510
6511function d3_layout_treeDeepest(a, b) {
6512  return a.depth - b.depth;
6513}
6514
6515function d3_layout_treeVisitAfter(node, callback) {
6516  function visit(node, previousSibling) {
6517    var children = node.children;
6518    if (children && (n = children.length)) {
6519      var child,
6520          previousChild = null,
6521          i = -1,
6522          n;
6523      while (++i < n) {
6524        child = children[i];
6525        visit(child, previousChild);
6526        previousChild = child;
6527      }
6528    }
6529    callback(node, previousSibling);
6530  }
6531  visit(node, null);
6532}
6533
6534function d3_layout_treeShift(node) {
6535  var shift = 0,
6536      change = 0,
6537      children = node.children,
6538      i = children.length,
6539      child;
6540  while (--i >= 0) {
6541    child = children[i]._tree;
6542    child.prelim += shift;
6543    child.mod += shift;
6544    shift += child.shift + (change += child.change);
6545  }
6546}
6547
6548function d3_layout_treeMove(ancestor, node, shift) {
6549  ancestor = ancestor._tree;
6550  node = node._tree;
6551  var change = shift / (node.number - ancestor.number);
6552  ancestor.change += change;
6553  node.change -= change;
6554  node.shift += shift;
6555  node.prelim += shift;
6556  node.mod += shift;
6557}
6558
6559function d3_layout_treeAncestor(vim, node, ancestor) {
6560  return vim._tree.ancestor.parent == node.parent
6561      ? vim._tree.ancestor
6562      : ancestor;
6563}
6564// Squarified Treemaps by Mark Bruls, Kees Huizing, and Jarke J. van Wijk
6565// Modified to support a target aspect ratio by Jeff Heer
6566d3.layout.treemap = function() {
6567  var hierarchy = d3.layout.hierarchy(),
6568      round = Math.round,
6569      size = [1, 1], // width, height
6570      padding = null,
6571      pad = d3_layout_treemapPadNull,
6572      sticky = false,
6573      stickies,
6574      ratio = 0.5 * (1 + Math.sqrt(5)); // golden ratio
6575
6576  // Compute the area for each child based on value & scale.
6577  function scale(children, k) {
6578    var i = -1,
6579        n = children.length,
6580        child,
6581        area;
6582    while (++i < n) {
6583      area = (child = children[i]).value * (k < 0 ? 0 : k);
6584      child.area = isNaN(area) || area <= 0 ? 0 : area;
6585    }
6586  }
6587
6588  // Recursively arranges the specified node's children into squarified rows.
6589  function squarify(node) {
6590    var children = node.children;
6591    if (children && children.length) {
6592      var rect = pad(node),
6593          row = [],
6594          remaining = children.slice(), // copy-on-write
6595          child,
6596          best = Infinity, // the best row score so far
6597          score, // the current row score
6598          u = Math.min(rect.dx, rect.dy), // initial orientation
6599          n;
6600      scale(remaining, rect.dx * rect.dy / node.value);
6601      row.area = 0;
6602      while ((n = remaining.length) > 0) {
6603        row.push(child = remaining[n - 1]);
6604        row.area += child.area;
6605        if ((score = worst(row, u)) <= best) { // continue with this orientation
6606          remaining.pop();
6607          best = score;
6608        } else { // abort, and try a different orientation
6609          row.area -= row.pop().area;
6610          position(row, u, rect, false);
6611          u = Math.min(rect.dx, rect.dy);
6612          row.length = row.area = 0;
6613          best = Infinity;
6614        }
6615      }
6616      if (row.length) {
6617        position(row, u, rect, true);
6618        row.length = row.area = 0;
6619      }
6620      children.forEach(squarify);
6621    }
6622  }
6623
6624  // Recursively resizes the specified node's children into existing rows.
6625  // Preserves the existing layout!
6626  function stickify(node) {
6627    var children = node.children;
6628    if (children && children.length) {
6629      var rect = pad(node),
6630          remaining = children.slice(), // copy-on-write
6631          child,
6632          row = [];
6633      scale(remaining, rect.dx * rect.dy / node.value);
6634      row.area = 0;
6635      while (child = remaining.pop()) {
6636        row.push(child);
6637        row.area += child.area;
6638        if (child.z != null) {
6639          position(row, child.z ? rect.dx : rect.dy, rect, !remaining.length);
6640          row.length = row.area = 0;
6641        }
6642      }
6643      children.forEach(stickify);
6644    }
6645  }
6646
6647  // Computes the score for the specified row, as the worst aspect ratio.
6648  function worst(row, u) {
6649    var s = row.area,
6650        r,
6651        rmax = 0,
6652        rmin = Infinity,
6653        i = -1,
6654        n = row.length;
6655    while (++i < n) {
6656      if (!(r = row[i].area)) continue;
6657      if (r < rmin) rmin = r;
6658      if (r > rmax) rmax = r;
6659    }
6660    s *= s;
6661    u *= u;
6662    return s
6663        ? Math.max((u * rmax * ratio) / s, s / (u * rmin * ratio))
6664        : Infinity;
6665  }
6666
6667  // Positions the specified row of nodes. Modifies `rect`.
6668  function position(row, u, rect, flush) {
6669    var i = -1,
6670        n = row.length,
6671        x = rect.x,
6672        y = rect.y,
6673        v = u ? round(row.area / u) : 0,
6674        o;
6675    if (u == rect.dx) { // horizontal subdivision
6676      if (flush || v > rect.dy) v = rect.dy; // over+underflow
6677      while (++i < n) {
6678        o = row[i];
6679        o.x = x;
6680        o.y = y;
6681        o.dy = v;
6682        x += o.dx = Math.min(rect.x + rect.dx - x, v ? round(o.area / v) : 0);
6683      }
6684      o.z = true;
6685      o.dx += rect.x + rect.dx - x; // rounding error
6686      rect.y += v;
6687      rect.dy -= v;
6688    } else { // vertical subdivision
6689      if (flush || v > rect.dx) v = rect.dx; // over+underflow
6690      while (++i < n) {
6691        o = row[i];
6692        o.x = x;
6693        o.y = y;
6694        o.dx = v;
6695        y += o.dy = Math.min(rect.y + rect.dy - y, v ? round(o.area / v) : 0);
6696      }
6697      o.z = false;
6698      o.dy += rect.y + rect.dy - y; // rounding error
6699      rect.x += v;
6700      rect.dx -= v;
6701    }
6702  }
6703
6704  function treemap(d) {
6705    var nodes = stickies || hierarchy(d),
6706        root = nodes[0];
6707    root.x = 0;
6708    root.y = 0;
6709    root.dx = size[0];
6710    root.dy = size[1];
6711    if (stickies) hierarchy.revalue(root);
6712    scale([root], root.dx * root.dy / root.value);
6713    (stickies ? stickify : squarify)(root);
6714    if (sticky) stickies = nodes;
6715    return nodes;
6716  }
6717
6718  treemap.size = function(x) {
6719    if (!arguments.length) return size;
6720    size = x;
6721    return treemap;
6722  };
6723
6724  treemap.padding = function(x) {
6725    if (!arguments.length) return padding;
6726
6727    function padFunction(node) {
6728      var p = x.call(treemap, node, node.depth);
6729      return p == null
6730          ? d3_layout_treemapPadNull(node)
6731          : d3_layout_treemapPad(node, typeof p === "number" ? [p, p, p, p] : p);
6732    }
6733
6734    function padConstant(node) {
6735      return d3_layout_treemapPad(node, x);
6736    }
6737
6738    var type;
6739    pad = (padding = x) == null ? d3_layout_treemapPadNull
6740        : (type = typeof x) === "function" ? padFunction
6741        : type === "number" ? (x = [x, x, x, x], padConstant)
6742        : padConstant;
6743    return treemap;
6744  };
6745
6746  treemap.round = function(x) {
6747    if (!arguments.length) return round != Number;
6748    round = x ? Math.round : Number;
6749    return treemap;
6750  };
6751
6752  treemap.sticky = function(x) {
6753    if (!arguments.length) return sticky;
6754    sticky = x;
6755    stickies = null;
6756    return treemap;
6757  };
6758
6759  treemap.ratio = function(x) {
6760    if (!arguments.length) return ratio;
6761    ratio = x;
6762    return treemap;
6763  };
6764
6765  return d3_layout_hierarchyRebind(treemap, hierarchy);
6766};
6767
6768function d3_layout_treemapPadNull(node) {
6769  return {x: node.x, y: node.y, dx: node.dx, dy: node.dy};
6770}
6771
6772function d3_layout_treemapPad(node, padding) {
6773  var x = node.x + padding[3],
6774      y = node.y + padding[0],
6775      dx = node.dx - padding[1] - padding[3],
6776      dy = node.dy - padding[0] - padding[2];
6777  if (dx < 0) { x += dx / 2; dx = 0; }
6778  if (dy < 0) { y += dy / 2; dy = 0; }
6779  return {x: x, y: y, dx: dx, dy: dy};
6780}
6781d3.csv = function(url, callback) {
6782  d3.text(url, "text/csv", function(text) {
6783    callback(text && d3.csv.parse(text));
6784  });
6785};
6786d3.csv.parse = function(text) {
6787  var header;
6788  return d3.csv.parseRows(text, function(row, i) {
6789    if (i) {
6790      var o = {}, j = -1, m = header.length;
6791      while (++j < m) o[header[j]] = row[j];
6792      return o;
6793    } else {
6794      header = row;
6795      return null;
6796    }
6797  });
6798};
6799
6800d3.csv.parseRows = function(text, f) {
6801  var EOL = {}, // sentinel value for end-of-line
6802      EOF = {}, // sentinel value for end-of-file
6803      rows = [], // output rows
6804      re = /\r\n|[,\r\n]/g, // field separator regex
6805      n = 0, // the current line number
6806      t, // the current token
6807      eol; // is the current token followed by EOL?
6808
6809  re.lastIndex = 0; // work-around bug in FF 3.6
6810
6811  /** @private Returns the next token. */
6812  function token() {
6813    if (re.lastIndex >= text.length) return EOF; // special case: end of file
6814    if (eol) { eol = false; return EOL; } // special case: end of line
6815
6816    // special case: quotes
6817    var j = re.lastIndex;
6818    if (text.charCodeAt(j) === 34) {
6819      var i = j;
6820      while (i++ < text.length) {
6821        if (text.charCodeAt(i) === 34) {
6822          if (text.charCodeAt(i + 1) !== 34) break;
6823          i++;
6824        }
6825      }
6826      re.lastIndex = i + 2;
6827      var c = text.charCodeAt(i + 1);
6828      if (c === 13) {
6829        eol = true;
6830        if (text.charCodeAt(i + 2) === 10) re.lastIndex++;
6831      } else if (c === 10) {
6832        eol = true;
6833      }
6834      return text.substring(j + 1, i).replace(/""/g, "\"");
6835    }
6836
6837    // common case
6838    var m = re.exec(text);
6839    if (m) {
6840      eol = m[0].charCodeAt(0) !== 44;
6841      return text.substring(j, m.index);
6842    }
6843    re.lastIndex = text.length;
6844    return text.substring(j);
6845  }
6846
6847  while ((t = token()) !== EOF) {
6848    var a = [];
6849    while ((t !== EOL) && (t !== EOF)) {
6850      a.push(t);
6851      t = token();
6852    }
6853    if (f && !(a = f(a, n++))) continue;
6854    rows.push(a);
6855  }
6856
6857  return rows;
6858};
6859d3.csv.format = function(rows) {
6860  return rows.map(d3_csv_formatRow).join("\n");
6861};
6862
6863function d3_csv_formatRow(row) {
6864  return row.map(d3_csv_formatValue).join(",");
6865}
6866
6867function d3_csv_formatValue(text) {
6868  return /[",\n]/.test(text)
6869      ? "\"" + text.replace(/\"/g, "\"\"") + "\""
6870      : text;
6871}
6872d3.geo = {};
6873
6874var d3_geo_radians = Math.PI / 180;
6875// TODO clip input coordinates on opposite hemisphere
6876d3.geo.azimuthal = function() {
6877  var mode = "orthographic", // or stereographic, gnomonic, equidistant or equalarea
6878      origin,
6879      scale = 200,
6880      translate = [480, 250],
6881      x0,
6882      y0,
6883      cy0,
6884      sy0;
6885
6886  function azimuthal(coordinates) {
6887    var x1 = coordinates[0] * d3_geo_radians - x0,
6888        y1 = coordinates[1] * d3_geo_radians,
6889        cx1 = Math.cos(x1),
6890        sx1 = Math.sin(x1),
6891        cy1 = Math.cos(y1),
6892        sy1 = Math.sin(y1),
6893        cc = mode !== "orthographic" ? sy0 * sy1 + cy0 * cy1 * cx1 : null,
6894        c,
6895        k = mode === "stereographic" ? 1 / (1 + cc)
6896          : mode === "gnomonic" ? 1 / cc
6897          : mode === "equidistant" ? (c = Math.acos(cc), c ? c / Math.sin(c) : 0)
6898          : mode === "equalarea" ? Math.sqrt(2 / (1 + cc))
6899          : 1,
6900        x = k * cy1 * sx1,
6901        y = k * (sy0 * cy1 * cx1 - cy0 * sy1);
6902    return [
6903      scale * x + translate[0],
6904      scale * y + translate[1]
6905    ];
6906  }
6907
6908  azimuthal.invert = function(coordinates) {
6909    var x = (coordinates[0] - translate[0]) / scale,
6910        y = (coordinates[1] - translate[1]) / scale,
6911        p = Math.sqrt(x * x + y * y),
6912        c = mode === "stereographic" ? 2 * Math.atan(p)
6913          : mode === "gnomonic" ? Math.atan(p)
6914          : mode === "equidistant" ? p
6915          : mode === "equalarea" ? 2 * Math.asin(.5 * p)
6916          : Math.asin(p),
6917        sc = Math.sin(c),
6918        cc = Math.cos(c);
6919    return [
6920      (x0 + Math.atan2(x * sc, p * cy0 * cc + y * sy0 * sc)) / d3_geo_radians,
6921      Math.asin(cc * sy0 - (p ? (y * sc * cy0) / p : 0)) / d3_geo_radians
6922    ];
6923  };
6924
6925  azimuthal.mode = function(x) {
6926    if (!arguments.length) return mode;
6927    mode = x + "";
6928    return azimuthal;
6929  };
6930
6931  azimuthal.origin = function(x) {
6932    if (!arguments.length) return origin;
6933    origin = x;
6934    x0 = origin[0] * d3_geo_radians;
6935    y0 = origin[1] * d3_geo_radians;
6936    cy0 = Math.cos(y0);
6937    sy0 = Math.sin(y0);
6938    return azimuthal;
6939  };
6940
6941  azimuthal.scale = function(x) {
6942    if (!arguments.length) return scale;
6943    scale = +x;
6944    return azimuthal;
6945  };
6946
6947  azimuthal.translate = function(x) {
6948    if (!arguments.length) return translate;
6949    translate = [+x[0], +x[1]];
6950    return azimuthal;
6951  };
6952
6953  return azimuthal.origin([0, 0]);
6954};
6955// Derived from Tom Carden's Albers implementation for Protovis.
6956// http://gist.github.com/476238
6957// http://mathworld.wolfram.com/AlbersEqual-AreaConicProjection.html
6958
6959d3.geo.albers = function() {
6960  var origin = [-98, 38],
6961      parallels = [29.5, 45.5],
6962      scale = 1000,
6963      translate = [480, 250],
6964      lng0, // d3_geo_radians * origin[0]
6965      n,
6966      C,
6967      p0;
6968
6969  function albers(coordinates) {
6970    var t = n * (d3_geo_radians * coordinates[0] - lng0),
6971        p = Math.sqrt(C - 2 * n * Math.sin(d3_geo_radians * coordinates[1])) / n;
6972    return [
6973      scale * p * Math.sin(t) + translate[0],
6974      scale * (p * Math.cos(t) - p0) + translate[1]
6975    ];
6976  }
6977
6978  albers.invert = function(coordinates) {
6979    var x = (coordinates[0] - translate[0]) / scale,
6980        y = (coordinates[1] - translate[1]) / scale,
6981        p0y = p0 + y,
6982        t = Math.atan2(x, p0y),
6983        p = Math.sqrt(x * x + p0y * p0y);
6984    return [
6985      (lng0 + t / n) / d3_geo_radians,
6986      Math.asin((C - p * p * n * n) / (2 * n)) / d3_geo_radians
6987    ];
6988  };
6989
6990  function reload() {
6991    var phi1 = d3_geo_radians * parallels[0],
6992        phi2 = d3_geo_radians * parallels[1],
6993        lat0 = d3_geo_radians * origin[1],
6994        s = Math.sin(phi1),
6995        c = Math.cos(phi1);
6996    lng0 = d3_geo_radians * origin[0];
6997    n = .5 * (s + Math.sin(phi2));
6998    C = c * c + 2 * n * s;
6999    p0 = Math.sqrt(C - 2 * n * Math.sin(lat0)) / n;
7000    return albers;
7001  }
7002
7003  albers.origin = function(x) {
7004    if (!arguments.length) return origin;
7005    origin = [+x[0], +x[1]];
7006    return reload();
7007  };
7008
7009  albers.parallels = function(x) {
7010    if (!arguments.length) return parallels;
7011    parallels = [+x[0], +x[1]];
7012    return reload();
7013  };
7014
7015  albers.scale = function(x) {
7016    if (!arguments.length) return scale;
7017    scale = +x;
7018    return albers;
7019  };
7020
7021  albers.translate = function(x) {
7022    if (!arguments.length) return translate;
7023    translate = [+x[0], +x[1]];
7024    return albers;
7025  };
7026
7027  return reload();
7028};
7029
7030// A composite projection for the United States, 960x500. The set of standard
7031// parallels for each region comes from USGS, which is published here:
7032// http://egsc.usgs.gov/isb/pubs/MapProjections/projections.html#albers
7033// TODO allow the composite projection to be rescaled?
7034d3.geo.albersUsa = function() {
7035  var lower48 = d3.geo.albers();
7036
7037  var alaska = d3.geo.albers()
7038      .origin([-160, 60])
7039      .parallels([55, 65]);
7040
7041  var hawaii = d3.geo.albers()
7042      .origin([-160, 20])
7043      .parallels([8, 18]);
7044
7045  var puertoRico = d3.geo.albers()
7046      .origin([-60, 10])
7047      .parallels([8, 18]);
7048
7049  function albersUsa(coordinates) {
7050    var lon = coordinates[0],
7051        lat = coordinates[1];
7052    return (lat > 50 ? alaska
7053        : lon < -140 ? hawaii
7054        : lat < 21 ? puertoRico
7055        : lower48)(coordinates);
7056  }
7057
7058  albersUsa.scale = function(x) {
7059    if (!arguments.length) return lower48.scale();
7060    lower48.scale(x);
7061    alaska.scale(x * .6);
7062    hawaii.scale(x);
7063    puertoRico.scale(x * 1.5);
7064    return albersUsa.translate(lower48.translate());
7065  };
7066
7067  albersUsa.translate = function(x) {
7068    if (!arguments.length) return lower48.translate();
7069    var dz = lower48.scale() / 1000,
7070        dx = x[0],
7071        dy = x[1];
7072    lower48.translate(x);
7073    alaska.translate([dx - 400 * dz, dy + 170 * dz]);
7074    hawaii.translate([dx - 190 * dz, dy + 200 * dz]);
7075    puertoRico.translate([dx + 580 * dz, dy + 430 * dz]);
7076    return albersUsa;
7077  };
7078
7079  return albersUsa.scale(lower48.scale());
7080};
7081d3.geo.bonne = function() {
7082  var scale = 200,
7083      translate = [480, 250],
7084      x0, // origin longitude in radians
7085      y0, // origin latitude in radians
7086      y1, // parallel latitude in radians
7087      c1; // cot(y1)
7088
7089  function bonne(coordinates) {
7090    var x = coordinates[0] * d3_geo_radians - x0,
7091        y = coordinates[1] * d3_geo_radians - y0;
7092    if (y1) {
7093      var p = c1 + y1 - y, E = x * Math.cos(y) / p;
7094      x = p * Math.sin(E);
7095      y = p * Math.cos(E) - c1;
7096    } else {
7097      x *= Math.cos(y);
7098      y *= -1;
7099    }
7100    return [
7101      scale * x + translate[0],
7102      scale * y + translate[1]
7103    ];
7104  }
7105
7106  bonne.invert = function(coordinates) {
7107    var x = (coordinates[0] - translate[0]) / scale,
7108        y = (coordinates[1] - translate[1]) / scale;
7109    if (y1) {
7110      var c = c1 + y, p = Math.sqrt(x * x + c * c);
7111      y = c1 + y1 - p;
7112      x = x0 + p * Math.atan2(x, c) / Math.cos(y);
7113    } else {
7114      y *= -1;
7115      x /= Math.cos(y);
7116    }
7117    return [
7118      x / d3_geo_radians,
7119      y / d3_geo_radians
7120    ];
7121  };
7122
7123  // 90° for Werner, 0° for Sinusoidal
7124  bonne.parallel = function(x) {
7125    if (!arguments.length) return y1 / d3_geo_radians;
7126    c1 = 1 / Math.tan(y1 = x * d3_geo_radians);
7127    return bonne;
7128  };
7129
7130  bonne.origin = function(x) {
7131    if (!arguments.length) return [x0 / d3_geo_radians, y0 / d3_geo_radians];
7132    x0 = x[0] * d3_geo_radians;
7133    y0 = x[1] * d3_geo_radians;
7134    return bonne;
7135  };
7136
7137  bonne.scale = function(x) {
7138    if (!arguments.length) return scale;
7139    scale = +x;
7140    return bonne;
7141  };
7142
7143  bonne.translate = function(x) {
7144    if (!arguments.length) return translate;
7145    translate = [+x[0], +x[1]];
7146    return bonne;
7147  };
7148
7149  return bonne.origin([0, 0]).parallel(45);
7150};
7151d3.geo.equirectangular = function() {
7152  var scale = 500,
7153      translate = [480, 250];
7154
7155  function equirectangular(coordinates) {
7156    var x = coordinates[0] / 360,
7157        y = -coordinates[1] / 360;
7158    return [
7159      scale * x + translate[0],
7160      scale * y + translate[1]
7161    ];
7162  }
7163
7164  equirectangular.invert = function(coordinates) {
7165    var x = (coordinates[0] - translate[0]) / scale,
7166        y = (coordinates[1] - translate[1]) / scale;
7167    return [
7168      360 * x,
7169      -360 * y
7170    ];
7171  };
7172
7173  equirectangular.scale = function(x) {
7174    if (!arguments.length) return scale;
7175    scale = +x;
7176    return equirectangular;
7177  };
7178
7179  equirectangular.translate = function(x) {
7180    if (!arguments.length) return translate;
7181    translate = [+x[0], +x[1]];
7182    return equirectangular;
7183  };
7184
7185  return equirectangular;
7186};
7187d3.geo.mercator = function() {
7188  var scale = 500,
7189      translate = [480, 250];
7190
7191  function mercator(coordinates) {
7192    var x = coordinates[0] / 360,
7193        y = -(Math.log(Math.tan(Math.PI / 4 + coordinates[1] * d3_geo_radians / 2)) / d3_geo_radians) / 360;
7194    return [
7195      scale * x + translate[0],
7196      scale * Math.max(-.5, Math.min(.5, y)) + translate[1]
7197    ];
7198  }
7199
7200  mercator.invert = function(coordinates) {
7201    var x = (coordinates[0] - translate[0]) / scale,
7202        y = (coordinates[1] - translate[1]) / scale;
7203    return [
7204      360 * x,
7205      2 * Math.atan(Math.exp(-360 * y * d3_geo_radians)) / d3_geo_radians - 90
7206    ];
7207  };
7208
7209  mercator.scale = function(x) {
7210    if (!arguments.length) return scale;
7211    scale = +x;
7212    return mercator;
7213  };
7214
7215  mercator.translate = function(x) {
7216    if (!arguments.length) return translate;
7217    translate = [+x[0], +x[1]];
7218    return mercator;
7219  };
7220
7221  return mercator;
7222};
7223function d3_geo_type(types, defaultValue) {
7224  return function(object) {
7225    return object && types.hasOwnProperty(object.type) ? types[object.type](object) : defaultValue;
7226  };
7227}
7228/**
7229 * Returns a function that, given a GeoJSON object (e.g., a feature), returns
7230 * the corresponding SVG path. The function can be customized by overriding the
7231 * projection. Point features are mapped to circles with a default radius of
7232 * 4.5px; the radius can be specified either as a constant or a function that
7233 * is evaluated per object.
7234 */
7235d3.geo.path = function() {
7236  var pointRadius = 4.5,
7237      pointCircle = d3_path_circle(pointRadius),
7238      projection = d3.geo.albersUsa();
7239
7240  function path(d, i) {
7241    if (typeof pointRadius === "function") {
7242      pointCircle = d3_path_circle(pointRadius.apply(this, arguments));
7243    }
7244    return pathType(d) || null;
7245  }
7246
7247  function project(coordinates) {
7248    return projection(coordinates).join(",");
7249  }
7250
7251  var pathType = d3_geo_type({
7252
7253    FeatureCollection: function(o) {
7254      var path = [],
7255          features = o.features,
7256          i = -1, // features.index
7257          n = features.length;
7258      while (++i < n) path.push(pathType(features[i].geometry));
7259      return path.join("");
7260    },
7261
7262    Feature: function(o) {
7263      return pathType(o.geometry);
7264    },
7265
7266    Point: function(o) {
7267      return "M" + project(o.coordinates) + pointCircle;
7268    },
7269
7270    MultiPoint: function(o) {
7271      var path = [],
7272          coordinates = o.coordinates,
7273          i = -1, // coordinates.index
7274          n = coordinates.length;
7275      while (++i < n) path.push("M", project(coordinates[i]), pointCircle);
7276      return path.join("");
7277    },
7278
7279    LineString: function(o) {
7280      var path = ["M"],
7281          coordinates = o.coordinates,
7282          i = -1, // coordinates.index
7283          n = coordinates.length;
7284      while (++i < n) path.push(project(coordinates[i]), "L");
7285      path.pop();
7286      return path.join("");
7287    },
7288
7289    MultiLineString: function(o) {
7290      var path = [],
7291          coordinates = o.coordinates,
7292          i = -1, // coordinates.index
7293          n = coordinates.length,
7294          subcoordinates, // coordinates[i]
7295          j, // subcoordinates.index
7296          m; // subcoordinates.length
7297      while (++i < n) {
7298        subcoordinates = coordinates[i];
7299        j = -1;
7300        m = subcoordinates.length;
7301        path.push("M");
7302        while (++j < m) path.push(project(subcoordinates[j]), "L");
7303        path.pop();
7304      }
7305      return path.join("");
7306    },
7307
7308    Polygon: function(o) {
7309      var path = [],
7310          coordinates = o.coordinates,
7311          i = -1, // coordinates.index
7312          n = coordinates.length,
7313          subcoordinates, // coordinates[i]
7314          j, // subcoordinates.index
7315          m; // subcoordinates.length
7316      while (++i < n) {
7317        subcoordinates = coordinates[i];
7318        j = -1;
7319        if ((m = subcoordinates.length - 1) > 0) {
7320          path.push("M");
7321          while (++j < m) path.push(project(subcoordinates[j]), "L");
7322          path[path.length - 1] = "Z";
7323        }
7324      }
7325      return path.join("");
7326    },
7327
7328    MultiPolygon: function(o) {
7329      var path = [],
7330          coordinates = o.coordinates,
7331          i = -1, // coordinates index
7332          n = coordinates.length,
7333          subcoordinates, // coordinates[i]
7334          j, // subcoordinates index
7335          m, // subcoordinates.length
7336          subsubcoordinates, // subcoordinates[j]
7337          k, // subsubcoordinates index
7338          p; // subsubcoordinates.length
7339      while (++i < n) {
7340        subcoordinates = coordinates[i];
7341        j = -1;
7342        m = subcoordinates.length;
7343        while (++j < m) {
7344          subsubcoordinates = subcoordinates[j];
7345          k = -1;
7346          if ((p = subsubcoordinates.length - 1) > 0) {
7347            path.push("M");
7348            while (++k < p) path.push(project(subsubcoordinates[k]), "L");
7349            path[path.length - 1] = "Z";
7350          }
7351        }
7352      }
7353      return path.join("");
7354    },
7355
7356    GeometryCollection: function(o) {
7357      var path = [],
7358          geometries = o.geometries,
7359          i = -1, // geometries index
7360          n = geometries.length;
7361      while (++i < n) path.push(pathType(geometries[i]));
7362      return path.join("");
7363    }
7364
7365  });
7366
7367  var areaType = path.area = d3_geo_type({
7368
7369    FeatureCollection: function(o) {
7370      var area = 0,
7371          features = o.features,
7372          i = -1, // features.index
7373          n = features.length;
7374      while (++i < n) area += areaType(features[i]);
7375      return area;
7376    },
7377
7378    Feature: function(o) {
7379      return areaType(o.geometry);
7380    },
7381
7382    Polygon: function(o) {
7383      return polygonArea(o.coordinates);
7384    },
7385
7386    MultiPolygon: function(o) {
7387      var sum = 0,
7388          coordinates = o.coordinates,
7389          i = -1, // coordinates index
7390          n = coordinates.length;
7391      while (++i < n) sum += polygonArea(coordinates[i]);
7392      return sum;
7393    },
7394
7395    GeometryCollection: function(o) {
7396      var sum = 0,
7397          geometries = o.geometries,
7398          i = -1, // geometries index
7399          n = geometries.length;
7400      while (++i < n) sum += areaType(geometries[i]);
7401      return sum;
7402    }
7403
7404  }, 0);
7405
7406  function polygonArea(coordinates) {
7407    var sum = area(coordinates[0]), // exterior ring
7408        i = 0, // coordinates.index
7409        n = coordinates.length;
7410    while (++i < n) sum -= area(coordinates[i]); // holes
7411    return sum;
7412  }
7413
7414  function polygonCentroid(coordinates) {
7415    var polygon = d3.geom.polygon(coordinates[0].map(projection)), // exterior ring
7416        area = polygon.area(),
7417        centroid = polygon.centroid(area < 0 ? (area *= -1, 1) : -1),
7418        x = centroid[0],
7419        y = centroid[1],
7420        z = area,
7421        i = 0, // coordinates index
7422        n = coordinates.length;
7423    while (++i < n) {
7424      polygon = d3.geom.polygon(coordinates[i].map(projection)); // holes
7425      area = polygon.area();
7426      centroid = polygon.centroid(area < 0 ? (area *= -1, 1) : -1);
7427      x -= centroid[0];
7428      y -= centroid[1];
7429      z -= area;
7430    }
7431    return [x, y, 6 * z]; // weighted centroid
7432  }
7433
7434  var centroidType = path.centroid = d3_geo_type({
7435
7436    // TODO FeatureCollection
7437    // TODO Point
7438    // TODO MultiPoint
7439    // TODO LineString
7440    // TODO MultiLineString
7441    // TODO GeometryCollection
7442
7443    Feature: function(o) {
7444      return centroidType(o.geometry);
7445    },
7446
7447    Polygon: function(o) {
7448      var centroid = polygonCentroid(o.coordinates);
7449      return [centroid[0] / centroid[2], centroid[1] / centroid[2]];
7450    },
7451
7452    MultiPolygon: function(o) {
7453      var area = 0,
7454          coordinates = o.coordinates,
7455          centroid,
7456          x = 0,
7457          y = 0,
7458          z = 0,
7459          i = -1, // coordinates index
7460          n = coordinates.length;
7461      while (++i < n) {
7462        centroid = polygonCentroid(coordinates[i]);
7463        x += centroid[0];
7464        y += centroid[1];
7465        z += centroid[2];
7466      }
7467      return [x / z, y / z];
7468    }
7469
7470  });
7471
7472  function area(coordinates) {
7473    return Math.abs(d3.geom.polygon(coordinates.map(projection)).area());
7474  }
7475
7476  path.projection = function(x) {
7477    projection = x;
7478    return path;
7479  };
7480
7481  path.pointRadius = function(x) {
7482    if (typeof x === "function") pointRadius = x;
7483    else {
7484      pointRadius = +x;
7485      pointCircle = d3_path_circle(pointRadius);
7486    }
7487    return path;
7488  };
7489
7490  return path;
7491};
7492
7493function d3_path_circle(radius) {
7494  return "m0," + radius
7495      + "a" + radius + "," + radius + " 0 1,1 0," + (-2 * radius)
7496      + "a" + radius + "," + radius + " 0 1,1 0," + (+2 * radius)
7497      + "z";
7498}
7499/**
7500 * Given a GeoJSON object, returns the corresponding bounding box. The bounding
7501 * box is represented by a two-dimensional array: [[left, bottom], [right,
7502 * top]], where left is the minimum longitude, bottom is the minimum latitude,
7503 * right is maximum longitude, and top is the maximum latitude.
7504 */
7505d3.geo.bounds = function(feature) {
7506  var left = Infinity,
7507      bottom = Infinity,
7508      right = -Infinity,
7509      top = -Infinity;
7510  d3_geo_bounds(feature, function(x, y) {
7511    if (x < left) left = x;
7512    if (x > right) right = x;
7513    if (y < bottom) bottom = y;
7514    if (y > top) top = y;
7515  });
7516  return [[left, bottom], [right, top]];
7517};
7518
7519function d3_geo_bounds(o, f) {
7520  if (d3_geo_boundsTypes.hasOwnProperty(o.type)) d3_geo_boundsTypes[o.type](o, f);
7521}
7522
7523var d3_geo_boundsTypes = {
7524  Feature: d3_geo_boundsFeature,
7525  FeatureCollection: d3_geo_boundsFeatureCollection,
7526  GeometryCollection: d3_geo_boundsGeometryCollection,
7527  LineString: d3_geo_boundsLineString,
7528  MultiLineString: d3_geo_boundsMultiLineString,
7529  MultiPoint: d3_geo_boundsLineString,
7530  MultiPolygon: d3_geo_boundsMultiPolygon,
7531  Point: d3_geo_boundsPoint,
7532  Polygon: d3_geo_boundsPolygon
7533};
7534
7535function d3_geo_boundsFeature(o, f) {
7536  d3_geo_bounds(o.geometry, f);
7537}
7538
7539function d3_geo_boundsFeatureCollection(o, f) {
7540  for (var a = o.features, i = 0, n = a.length; i < n; i++) {
7541    d3_geo_bounds(a[i].geometry, f);
7542  }
7543}
7544
7545function d3_geo_boundsGeometryCollection(o, f) {
7546  for (var a = o.geometries, i = 0, n = a.length; i < n; i++) {
7547    d3_geo_bounds(a[i], f);
7548  }
7549}
7550
7551function d3_geo_boundsLineString(o, f) {
7552  for (var a = o.coordinates, i = 0, n = a.length; i < n; i++) {
7553    f.apply(null, a[i]);
7554  }
7555}
7556
7557function d3_geo_boundsMultiLineString(o, f) {
7558  for (var a = o.coordinates, i = 0, n = a.length; i < n; i++) {
7559    for (var b = a[i], j = 0, m = b.length; j < m; j++) {
7560      f.apply(null, b[j]);
7561    }
7562  }
7563}
7564
7565function d3_geo_boundsMultiPolygon(o, f) {
7566  for (var a = o.coordinates, i = 0, n = a.length; i < n; i++) {
7567    for (var b = a[i][0], j = 0, m = b.length; j < m; j++) {
7568      f.apply(null, b[j]);
7569    }
7570  }
7571}
7572
7573function d3_geo_boundsPoint(o, f) {
7574  f.apply(null, o.coordinates);
7575}
7576
7577function d3_geo_boundsPolygon(o, f) {
7578  for (var a = o.coordinates[0], i = 0, n = a.length; i < n; i++) {
7579    f.apply(null, a[i]);
7580  }
7581}
7582// TODO breakAtDateLine?
7583
7584d3.geo.circle = function() {
7585  var origin = [0, 0],
7586      degrees = 90 - 1e-2,
7587      radians = degrees * d3_geo_radians,
7588      arc = d3.geo.greatArc().target(Object);
7589
7590  function circle() {
7591    // TODO render a circle as a Polygon
7592  }
7593
7594  function visible(point) {
7595    return arc.distance(point) < radians;
7596  }
7597
7598  circle.clip = function(d) {
7599    arc.source(typeof origin === "function" ? origin.apply(this, arguments) : origin);
7600    return clipType(d);
7601  };
7602
7603  var clipType = d3_geo_type({
7604
7605    FeatureCollection: function(o) {
7606      var features = o.features.map(clipType).filter(Object);
7607      return features && (o = Object.create(o), o.features = features, o);
7608    },
7609
7610    Feature: function(o) {
7611      var geometry = clipType(o.geometry);
7612      return geometry && (o = Object.create(o), o.geometry = geometry, o);
7613    },
7614
7615    Point: function(o) {
7616      return visible(o.coordinates) && o;
7617    },
7618
7619    MultiPoint: function(o) {
7620      var coordinates = o.coordinates.filter(visible);
7621      return coordinates.length && {
7622        type: o.type,
7623        coordinates: coordinates
7624      };
7625    },
7626
7627    LineString: function(o) {
7628      var coordinates = clip(o.coordinates);
7629      return coordinates.length && (o = Object.create(o), o.coordinates = coordinates, o);
7630    },
7631
7632    MultiLineString: function(o) {
7633      var coordinates = o.coordinates.map(clip).filter(function(d) { return d.length; });
7634      return coordinates.length && (o = Object.create(o), o.coordinates = coordinates, o);
7635    },
7636
7637    Polygon: function(o) {
7638      var coordinates = o.coordinates.map(clip);
7639      return coordinates[0].length && (o = Object.create(o), o.coordinates = coordinates, o);
7640    },
7641
7642    MultiPolygon: function(o) {
7643      var coordinates = o.coordinates.map(function(d) { return d.map(clip); }).filter(function(d) { return d[0].length; });
7644      return coordinates.length && (o = Object.create(o), o.coordinates = coordinates, o);
7645    },
7646
7647    GeometryCollection: function(o) {
7648      var geometries = o.geometries.map(clipType).filter(Object);
7649      return geometries.length && (o = Object.create(o), o.geometries = geometries, o);
7650    }
7651
7652  });
7653
7654  function clip(coordinates) {
7655    var i = -1,
7656        n = coordinates.length,
7657        clipped = [],
7658        p0,
7659        p1,
7660        p2,
7661        d0,
7662        d1;
7663
7664    while (++i < n) {
7665      d1 = arc.distance(p2 = coordinates[i]);
7666      if (d1 < radians) {
7667        if (p1) clipped.push(d3_geo_greatArcInterpolate(p1, p2)((d0 - radians) / (d0 - d1)));
7668        clipped.push(p2);
7669        p0 = p1 = null;
7670      } else {
7671        p1 = p2;
7672        if (!p0 && clipped.length) {
7673          clipped.push(d3_geo_greatArcInterpolate(clipped[clipped.length - 1], p1)((radians - d0) / (d1 - d0)));
7674          p0 = p1;
7675        }
7676      }
7677      d0 = d1;
7678    }
7679
7680    if (p1 && clipped.length) {
7681      d1 = arc.distance(p2 = clipped[0]);
7682      clipped.push(d3_geo_greatArcInterpolate(p1, p2)((d0 - radians) / (d0 - d1)));
7683    }
7684
7685    return resample(clipped);
7686  }
7687
7688  // Resample coordinates, creating great arcs between each.
7689  function resample(coordinates) {
7690    var i = 0,
7691        n = coordinates.length,
7692        j,
7693        m,
7694        resampled = n ? [coordinates[0]] : coordinates,
7695        resamples,
7696        origin = arc.source();
7697
7698    while (++i < n) {
7699      resamples = arc.source(coordinates[i - 1])(coordinates[i]).coordinates;
7700      for (j = 0, m = resamples.length; ++j < m;) resampled.push(resamples[j]);
7701    }
7702
7703    arc.source(origin);
7704    return resampled;
7705  }
7706
7707  circle.origin = function(x) {
7708    if (!arguments.length) return origin;
7709    origin = x;
7710    return circle;
7711  };
7712
7713  circle.angle = function(x) {
7714    if (!arguments.length) return degrees;
7715    radians = (degrees = +x) * d3_geo_radians;
7716    return circle;
7717  };
7718
7719  // Precision is specified in degrees.
7720  circle.precision = function(x) {
7721    if (!arguments.length) return arc.precision();
7722    arc.precision(x);
7723    return circle;
7724  };
7725
7726  return circle;
7727}
7728d3.geo.greatArc = function() {
7729  var source = d3_geo_greatArcSource,
7730      target = d3_geo_greatArcTarget,
7731      precision = 6 * d3_geo_radians;
7732
7733  function greatArc() {
7734    var a = typeof source === "function" ? source.apply(this, arguments) : source,
7735        b = typeof target === "function" ? target.apply(this, arguments) : target,
7736        i = d3_geo_greatArcInterpolate(a, b),
7737        dt = precision / i.d,
7738        t = 0,
7739        coordinates = [a];
7740    while ((t += dt) < 1) coordinates.push(i(t));
7741    coordinates.push(b);
7742    return {
7743      type: "LineString",
7744      coordinates: coordinates
7745    };
7746  }
7747
7748  // Length returned in radians; multiply by radius for distance.
7749  greatArc.distance = function() {
7750    var a = typeof source === "function" ? source.apply(this, arguments) : source,
7751        b = typeof target === "function" ? target.apply(this, arguments) : target;
7752     return d3_geo_greatArcInterpolate(a, b).d;
7753  };
7754
7755  greatArc.source = function(x) {
7756    if (!arguments.length) return source;
7757    source = x;
7758    return greatArc;
7759  };
7760
7761  greatArc.target = function(x) {
7762    if (!arguments.length) return target;
7763    target = x;
7764    return greatArc;
7765  };
7766
7767  // Precision is specified in degrees.
7768  greatArc.precision = function(x) {
7769    if (!arguments.length) return precision / d3_geo_radians;
7770    precision = x * d3_geo_radians;
7771    return greatArc;
7772  };
7773
7774  return greatArc;
7775};
7776
7777function d3_geo_greatArcSource(d) {
7778  return d.source;
7779}
7780
7781function d3_geo_greatArcTarget(d) {
7782  return d.target;
7783}
7784
7785function d3_geo_greatArcInterpolate(a, b) {
7786  var x0 = a[0] * d3_geo_radians, cx0 = Math.cos(x0), sx0 = Math.sin(x0),
7787      y0 = a[1] * d3_geo_radians, cy0 = Math.cos(y0), sy0 = Math.sin(y0),
7788      x1 = b[0] * d3_geo_radians, cx1 = Math.cos(x1), sx1 = Math.sin(x1),
7789      y1 = b[1] * d3_geo_radians, cy1 = Math.cos(y1), sy1 = Math.sin(y1),
7790      d = interpolate.d = Math.acos(Math.max(-1, Math.min(1, sy0 * sy1 + cy0 * cy1 * Math.cos(x1 - x0)))),
7791      sd = Math.sin(d);
7792
7793  // From http://williams.best.vwh.net/avform.htm#Intermediate
7794  function interpolate(t) {
7795    var A = Math.sin(d - (t *= d)) / sd,
7796        B = Math.sin(t) / sd,
7797        x = A * cy0 * cx0 + B * cy1 * cx1,
7798        y = A * cy0 * sx0 + B * cy1 * sx1,
7799        z = A * sy0       + B * sy1;
7800    return [
7801      Math.atan2(y, x) / d3_geo_radians,
7802      Math.atan2(z, Math.sqrt(x * x + y * y)) / d3_geo_radians
7803    ];
7804  }
7805
7806  return interpolate;
7807}
7808d3.geo.greatCircle = d3.geo.circle;
7809d3.geom = {};
7810/**
7811 * Computes a contour for a given input grid function using the <a
7812 * href="http://en.wikipedia.org/wiki/Marching_squares">marching
7813 * squares</a> algorithm. Returns the contour polygon as an array of points.
7814 *
7815 * @param grid a two-input function(x, y) that returns true for values
7816 * inside the contour and false for values outside the contour.
7817 * @param start an optional starting point [x, y] on the grid.
7818 * @returns polygon [[x1, y1], [x2, y2], 
]
7819 */
7820d3.geom.contour = function(grid, start) {
7821  var s = start || d3_geom_contourStart(grid), // starting point
7822      c = [],    // contour polygon
7823      x = s[0],  // current x position
7824      y = s[1],  // current y position
7825      dx = 0,    // next x direction
7826      dy = 0,    // next y direction
7827      pdx = NaN, // previous x direction
7828      pdy = NaN, // previous y direction
7829      i = 0;
7830
7831  do {
7832    // determine marching squares index
7833    i = 0;
7834    if (grid(x-1, y-1)) i += 1;
7835    if (grid(x,   y-1)) i += 2;
7836    if (grid(x-1, y  )) i += 4;
7837    if (grid(x,   y  )) i += 8;
7838
7839    // determine next direction
7840    if (i === 6) {
7841      dx = pdy === -1 ? -1 : 1;
7842      dy = 0;
7843    } else if (i === 9) {
7844      dx = 0;
7845      dy = pdx === 1 ? -1 : 1;
7846    } else {
7847      dx = d3_geom_contourDx[i];
7848      dy = d3_geom_contourDy[i];
7849    }
7850
7851    // update contour polygon
7852    if (dx != pdx && dy != pdy) {
7853      c.push([x, y]);
7854      pdx = dx;
7855      pdy = dy;
7856    }
7857
7858    x += dx;
7859    y += dy;
7860  } while (s[0] != x || s[1] != y);
7861
7862  return c;
7863};
7864
7865// lookup tables for marching directions
7866var d3_geom_contourDx = [1, 0, 1, 1,-1, 0,-1, 1,0, 0,0,0,-1, 0,-1,NaN],
7867    d3_geom_contourDy = [0,-1, 0, 0, 0,-1, 0, 0,1,-1,1,1, 0,-1, 0,NaN];
7868
7869function d3_geom_contourStart(grid) {
7870  var x = 0,
7871      y = 0;
7872
7873  // search for a starting point; begin at origin
7874  // and proceed along outward-expanding diagonals
7875  while (true) {
7876    if (grid(x,y)) {
7877      return [x,y];
7878    }
7879    if (x === 0) {
7880      x = y + 1;
7881      y = 0;
7882    } else {
7883      x = x - 1;
7884      y = y + 1;
7885    }
7886  }
7887}
7888/**
7889 * Computes the 2D convex hull of a set of points using Graham's scanning
7890 * algorithm. The algorithm has been implemented as described in Cormen,
7891 * Leiserson, and Rivest's Introduction to Algorithms. The running time of
7892 * this algorithm is O(n log n), where n is the number of input points.
7893 *
7894 * @param vertices [[x1, y1], [x2, y2], 
]
7895 * @returns polygon [[x1, y1], [x2, y2], 
]
7896 */
7897d3.geom.hull = function(vertices) {
7898  if (vertices.length < 3) return [];
7899
7900  var len = vertices.length,
7901      plen = len - 1,
7902      points = [],
7903      stack = [],
7904      i, j, h = 0, x1, y1, x2, y2, u, v, a, sp;
7905
7906  // find the starting ref point: leftmost point with the minimum y coord
7907  for (i=1; i<len; ++i) {
7908    if (vertices[i][1] < vertices[h][1]) {
7909      h = i;
7910    } else if (vertices[i][1] == vertices[h][1]) {
7911      h = (vertices[i][0] < vertices[h][0] ? i : h);
7912    }
7913  }
7914
7915  // calculate polar angles from ref point and sort
7916  for (i=0; i<len; ++i) {
7917    if (i === h) continue;
7918    y1 = vertices[i][1] - vertices[h][1];
7919    x1 = vertices[i][0] - vertices[h][0];
7920    points.push({angle: Math.atan2(y1, x1), index: i});
7921  }
7922  points.sort(function(a, b) { return a.angle - b.angle; });
7923
7924  // toss out duplicate angles
7925  a = points[0].angle;
7926  v = points[0].index;
7927  u = 0;
7928  for (i=1; i<plen; ++i) {
7929    j = points[i].index;
7930    if (a == points[i].angle) {
7931      // keep angle for point most distant from the reference
7932      x1 = vertices[v][0] - vertices[h][0];
7933      y1 = vertices[v][1] - vertices[h][1];
7934      x2 = vertices[j][0] - vertices[h][0];
7935      y2 = vertices[j][1] - vertices[h][1];
7936      if ((x1*x1 + y1*y1) >= (x2*x2 + y2*y2)) {
7937        points[i].index = -1;
7938      } else {
7939        points[u].index = -1;
7940        a = points[i].angle;
7941        u = i;
7942        v = j;
7943      }
7944    } else {
7945      a = points[i].angle;
7946      u = i;
7947      v = j;
7948    }
7949  }
7950
7951  // initialize the stack
7952  stack.push(h);
7953  for (i=0, j=0; i<2; ++j) {
7954    if (points[j].index !== -1) {
7955      stack.push(points[j].index);
7956      i++;
7957    }
7958  }
7959  sp = stack.length;
7960
7961  // do graham's scan
7962  for (; j<plen; ++j) {
7963    if (points[j].index === -1) continue; // skip tossed out points
7964    while (!d3_geom_hullCCW(stack[sp-2], stack[sp-1], points[j].index, vertices)) {
7965      --sp;
7966    }
7967    stack[sp++] = points[j].index;
7968  }
7969
7970  // construct the hull
7971  var poly = [];
7972  for (i=0; i<sp; ++i) {
7973    poly.push(vertices[stack[i]]);
7974  }
7975  return poly;
7976}
7977
7978// are three points in counter-clockwise order?
7979function d3_geom_hullCCW(i1, i2, i3, v) {
7980  var t, a, b, c, d, e, f;
7981  t = v[i1]; a = t[0]; b = t[1];
7982  t = v[i2]; c = t[0]; d = t[1];
7983  t = v[i3]; e = t[0]; f = t[1];
7984  return ((f-b)*(c-a) - (d-b)*(e-a)) > 0;
7985}
7986// Note: requires coordinates to be counterclockwise and convex!
7987d3.geom.polygon = function(coordinates) {
7988
7989  coordinates.area = function() {
7990    var i = 0,
7991        n = coordinates.length,
7992        a = coordinates[n - 1][0] * coordinates[0][1],
7993        b = coordinates[n - 1][1] * coordinates[0][0];
7994    while (++i < n) {
7995      a += coordinates[i - 1][0] * coordinates[i][1];
7996      b += coordinates[i - 1][1] * coordinates[i][0];
7997    }
7998    return (b - a) * .5;
7999  };
8000
8001  coordinates.centroid = function(k) {
8002    var i = -1,
8003        n = coordinates.length,
8004        x = 0,
8005        y = 0,
8006        a,
8007        b = coordinates[n - 1],
8008        c;
8009    if (!arguments.length) k = -1 / (6 * coordinates.area());
8010    while (++i < n) {
8011      a = b;
8012      b = coordinates[i];
8013      c = a[0] * b[1] - b[0] * a[1];
8014      x += (a[0] + b[0]) * c;
8015      y += (a[1] + b[1]) * c;
8016    }
8017    return [x * k, y * k];
8018  };
8019
8020  // The Sutherland-Hodgman clipping algorithm.
8021  coordinates.clip = function(subject) {
8022    var input,
8023        i = -1,
8024        n = coordinates.length,
8025        j,
8026        m,
8027        a = coordinates[n - 1],
8028        b,
8029        c,
8030        d;
8031    while (++i < n) {
8032      input = subject.slice();
8033      subject.length = 0;
8034      b = coordinates[i];
8035      c = input[(m = input.length) - 1];
8036      j = -1;
8037      while (++j < m) {
8038        d = input[j];
8039        if (d3_geom_polygonInside(d, a, b)) {
8040          if (!d3_geom_polygonInside(c, a, b)) {
8041            subject.push(d3_geom_polygonIntersect(c, d, a, b));
8042          }
8043          subject.push(d);
8044        } else if (d3_geom_polygonInside(c, a, b)) {
8045          subject.push(d3_geom_polygonIntersect(c, d, a, b));
8046        }
8047        c = d;
8048      }
8049      a = b;
8050    }
8051    return subject;
8052  };
8053
8054  return coordinates;
8055};
8056
8057function d3_geom_polygonInside(p, a, b) {
8058  return (b[0] - a[0]) * (p[1] - a[1]) < (b[1] - a[1]) * (p[0] - a[0]);
8059}
8060
8061// Intersect two infinite lines cd and ab.
8062function d3_geom_polygonIntersect(c, d, a, b) {
8063  var x1 = c[0], x2 = d[0], x3 = a[0], x4 = b[0],
8064      y1 = c[1], y2 = d[1], y3 = a[1], y4 = b[1],
8065      x13 = x1 - x3,
8066      x21 = x2 - x1,
8067      x43 = x4 - x3,
8068      y13 = y1 - y3,
8069      y21 = y2 - y1,
8070      y43 = y4 - y3,
8071      ua = (x43 * y13 - y43 * x13) / (y43 * x21 - x43 * y21);
8072  return [x1 + ua * x21, y1 + ua * y21];
8073}
8074// Adapted from Nicolas Garcia Belmonte's JIT implementation:
8075// http://blog.thejit.org/2010/02/12/voronoi-tessellation/
8076// http://blog.thejit.org/assets/voronoijs/voronoi.js
8077// See lib/jit/LICENSE for details.
8078
8079// Notes:
8080//
8081// This implementation does not clip the returned polygons, so if you want to
8082// clip them to a particular shape you will need to do that either in SVG or by
8083// post-processing with d3.geom.polygon's clip method.
8084//
8085// If any vertices are coincident or have NaN positions, the behavior of this
8086// method is undefined. Most likely invalid polygons will be returned. You
8087// should filter invalid points, and consolidate coincident points, before
8088// computing the tessellation.
8089
8090/**
8091 * @param vertices [[x1, y1], [x2, y2], 
]
8092 * @returns polygons [[[x1, y1], [x2, y2], 
], 
]
8093 */
8094d3.geom.voronoi = function(vertices) {
8095  var polygons = vertices.map(function() { return []; });
8096
8097  d3_voronoi_tessellate(vertices, function(e) {
8098    var s1,
8099        s2,
8100        x1,
8101        x2,
8102        y1,
8103        y2;
8104    if (e.a === 1 && e.b >= 0) {
8105      s1 = e.ep.r;
8106      s2 = e.ep.l;
8107    } else {
8108      s1 = e.ep.l;
8109      s2 = e.ep.r;
8110    }
8111    if (e.a === 1) {
8112      y1 = s1 ? s1.y : -1e6;
8113      x1 = e.c - e.b * y1;
8114      y2 = s2 ? s2.y : 1e6;
8115      x2 = e.c - e.b * y2;
8116    } else {
8117      x1 = s1 ? s1.x : -1e6;
8118      y1 = e.c - e.a * x1;
8119      x2 = s2 ? s2.x : 1e6;
8120      y2 = e.c - e.a * x2;
8121    }
8122    var v1 = [x1, y1],
8123        v2 = [x2, y2];
8124    polygons[e.region.l.index].push(v1, v2);
8125    polygons[e.region.r.index].push(v1, v2);
8126  });
8127
8128  // Reconnect the polygon segments into counterclockwise loops.
8129  return polygons.map(function(polygon, i) {
8130    var cx = vertices[i][0],
8131        cy = vertices[i][1];
8132    polygon.forEach(function(v) {
8133      v.angle = Math.atan2(v[0] - cx, v[1] - cy);
8134    });
8135    return polygon.sort(function(a, b) {
8136      return a.angle - b.angle;
8137    }).filter(function(d, i) {
8138      return !i || (d.angle - polygon[i - 1].angle > 1e-10);
8139    });
8140  });
8141};
8142
8143var d3_voronoi_opposite = {"l": "r", "r": "l"};
8144
8145function d3_voronoi_tessellate(vertices, callback) {
8146
8147  var Sites = {
8148    list: vertices
8149      .map(function(v, i) {
8150        return {
8151          index: i,
8152          x: v[0],
8153          y: v[1]
8154        };
8155      })
8156      .sort(function(a, b) {
8157        return a.y < b.y ? -1
8158          : a.y > b.y ? 1
8159          : a.x < b.x ? -1
8160          : a.x > b.x ? 1
8161          : 0;
8162      }),
8163    bottomSite: null
8164  };
8165
8166  var EdgeList = {
8167    list: [],
8168    leftEnd: null,
8169    rightEnd: null,
8170
8171    init: function() {
8172      EdgeList.leftEnd = EdgeList.createHalfEdge(null, "l");
8173      EdgeList.rightEnd = EdgeList.createHalfEdge(null, "l");
8174      EdgeList.leftEnd.r = EdgeList.rightEnd;
8175      EdgeList.rightEnd.l = EdgeList.leftEnd;
8176      EdgeList.list.unshift(EdgeList.leftEnd, EdgeList.rightEnd);
8177    },
8178
8179    createHalfEdge: function(edge, side) {
8180      return {
8181        edge: edge,
8182        side: side,
8183        vertex: null,
8184        "l": null,
8185        "r": null
8186      };
8187    },
8188
8189    insert: function(lb, he) {
8190      he.l = lb;
8191      he.r = lb.r;
8192      lb.r.l = he;
8193      lb.r = he;
8194    },
8195
8196    leftBound: function(p) {
8197      var he = EdgeList.leftEnd;
8198      do {
8199        he = he.r;
8200      } while (he != EdgeList.rightEnd && Geom.rightOf(he, p));
8201      he = he.l;
8202      return he;
8203    },
8204
8205    del: function(he) {
8206      he.l.r = he.r;
8207      he.r.l = he.l;
8208      he.edge = null;
8209    },
8210
8211    right: function(he) {
8212      return he.r;
8213    },
8214
8215    left: function(he) {
8216      return he.l;
8217    },
8218
8219    leftRegion: function(he) {
8220      return he.edge == null
8221          ? Sites.bottomSite
8222          : he.edge.region[he.side];
8223    },
8224
8225    rightRegion: function(he) {
8226      return he.edge == null
8227          ? Sites.bottomSite
8228          : he.edge.region[d3_voronoi_opposite[he.side]];
8229    }
8230  };
8231
8232  var Geom = {
8233
8234    bisect: function(s1, s2) {
8235      var newEdge = {
8236        region: {"l": s1, "r": s2},
8237        ep: {"l": null, "r": null}
8238      };
8239
8240      var dx = s2.x - s1.x,
8241          dy = s2.y - s1.y,
8242          adx = dx > 0 ? dx : -dx,
8243          ady = dy > 0 ? dy : -dy;
8244
8245      newEdge.c = s1.x * dx + s1.y * dy
8246          + (dx * dx + dy * dy) * .5;
8247
8248      if (adx > ady) {
8249        newEdge.a = 1;
8250        newEdge.b = dy / dx;
8251        newEdge.c /= dx;
8252      } else {
8253        newEdge.b = 1;
8254        newEdge.a = dx / dy;
8255        newEdge.c /= dy;
8256      }
8257
8258      return newEdge;
8259    },
8260
8261    intersect: function(el1, el2) {
8262      var e1 = el1.edge,
8263          e2 = el2.edge;
8264      if (!e1 || !e2 || (e1.region.r == e2.region.r)) {
8265        return null;
8266      }
8267      var d = (e1.a * e2.b) - (e1.b * e2.a);
8268      if (Math.abs(d) < 1e-10) {
8269        return null;
8270      }
8271      var xint = (e1.c * e2.b - e2.c * e1.b) / d,
8272          yint = (e2.c * e1.a - e1.c * e2.a) / d,
8273          e1r = e1.region.r,
8274          e2r = e2.region.r,
8275          el,
8276          e;
8277      if ((e1r.y < e2r.y) ||
8278         (e1r.y == e2r.y && e1r.x < e2r.x)) {
8279        el = el1;
8280        e = e1;
8281      } else {
8282        el = el2;
8283        e = e2;
8284      }
8285      var rightOfSite = (xint >= e.region.r.x);
8286      if ((rightOfSite && (el.side === "l")) ||
8287        (!rightOfSite && (el.side === "r"))) {
8288        return null;
8289      }
8290      return {
8291        x: xint,
8292        y: yint
8293      };
8294    },
8295
8296    rightOf: function(he, p) {
8297      var e = he.edge,
8298          topsite = e.region.r,
8299          rightOfSite = (p.x > topsite.x);
8300
8301      if (rightOfSite && (he.side === "l")) {
8302        return 1;
8303      }
8304      if (!rightOfSite && (he.side === "r")) {
8305        return 0;
8306      }
8307      if (e.a === 1) {
8308        var dyp = p.y - topsite.y,
8309            dxp = p.x - topsite.x,
8310            fast = 0,
8311            above = 0;
8312
8313        if ((!rightOfSite && (e.b < 0)) ||
8314          (rightOfSite && (e.b >= 0))) {
8315          above = fast = (dyp >= e.b * dxp);
8316        } else {
8317          above = ((p.x + p.y * e.b) > e.c);
8318          if (e.b < 0) {
8319            above = !above;
8320          }
8321          if (!above) {
8322            fast = 1;
8323          }
8324        }
8325        if (!fast) {
8326          var dxs = topsite.x - e.region.l.x;
8327          above = (e.b * (dxp * dxp - dyp * dyp)) <
8328            (dxs * dyp * (1 + 2 * dxp / dxs + e.b * e.b));
8329
8330          if (e.b < 0) {
8331            above = !above;
8332          }
8333        }
8334      } else /* e.b == 1 */ {
8335        var yl = e.c - e.a * p.x,
8336            t1 = p.y - yl,
8337            t2 = p.x - topsite.x,
8338            t3 = yl - topsite.y;
8339
8340        above = (t1 * t1) > (t2 * t2 + t3 * t3);
8341      }
8342      return he.side === "l" ? above : !above;
8343    },
8344
8345    endPoint: function(edge, side, site) {
8346      edge.ep[side] = site;
8347      if (!edge.ep[d3_voronoi_opposite[side]]) return;
8348      callback(edge);
8349    },
8350
8351    distance: function(s, t) {
8352      var dx = s.x - t.x,
8353          dy = s.y - t.y;
8354      return Math.sqrt(dx * dx + dy * dy);
8355    }
8356  };
8357
8358  var EventQueue = {
8359    list: [],
8360
8361    insert: function(he, site, offset) {
8362      he.vertex = site;
8363      he.ystar = site.y + offset;
8364      for (var i=0, list=EventQueue.list, l=list.length; i<l; i++) {
8365        var next = list[i];
8366        if (he.ystar > next.ystar ||
8367          (he.ystar == next.ystar &&
8368          site.x > next.vertex.x)) {
8369          continue;
8370        } else {
8371          break;
8372        }
8373      }
8374      list.splice(i, 0, he);
8375    },
8376
8377    del: function(he) {
8378      for (var i=0, ls=EventQueue.list, l=ls.length; i<l && (ls[i] != he); ++i) {}
8379      ls.splice(i, 1);
8380    },
8381
8382    empty: function() { return EventQueue.list.length === 0; },
8383
8384    nextEvent: function(he) {
8385      for (var i=0, ls=EventQueue.list, l=ls.length; i<l; ++i) {
8386        if (ls[i] == he) return ls[i+1];
8387      }
8388      return null;
8389    },
8390
8391    min: function() {
8392      var elem = EventQueue.list[0];
8393      return {
8394        x: elem.vertex.x,
8395        y: elem.ystar
8396      };
8397    },
8398
8399    extractMin: function() {
8400      return EventQueue.list.shift();
8401    }
8402  };
8403
8404  EdgeList.init();
8405  Sites.bottomSite = Sites.list.shift();
8406
8407  var newSite = Sites.list.shift(), newIntStar;
8408  var lbnd, rbnd, llbnd, rrbnd, bisector;
8409  var bot, top, temp, p, v;
8410  var e, pm;
8411
8412  while (true) {
8413    if (!EventQueue.empty()) {
8414      newIntStar = EventQueue.min();
8415    }
8416    if (newSite && (EventQueue.empty()
8417      || newSite.y < newIntStar.y
8418      || (newSite.y == newIntStar.y
8419      && newSite.x < newIntStar.x))) { //new site is smallest
8420      lbnd = EdgeList.leftBound(newSite);
8421      rbnd = EdgeList.right(lbnd);
8422      bot = EdgeList.rightRegion(lbnd);
8423      e = Geom.bisect(bot, newSite);
8424      bisector = EdgeList.createHalfEdge(e, "l");
8425      EdgeList.insert(lbnd, bisector);
8426      p = Geom.intersect(lbnd, bisector);
8427      if (p) {
8428        EventQueue.del(lbnd);
8429        EventQueue.insert(lbnd, p, Geom.distance(p, newSite));
8430      }
8431      lbnd = bisector;
8432      bisector = EdgeList.createHalfEdge(e, "r");
8433      EdgeList.insert(lbnd, bisector);
8434      p = Geom.intersect(bisector, rbnd);
8435      if (p) {
8436        EventQueue.insert(bisector, p, Geom.distance(p, newSite));
8437      }
8438      newSite = Sites.list.shift();
8439    } else if (!EventQueue.empty()) { //intersection is smallest
8440      lbnd = EventQueue.extractMin();
8441      llbnd = EdgeList.left(lbnd);
8442      rbnd = EdgeList.right(lbnd);
8443      rrbnd = EdgeList.right(rbnd);
8444      bot = EdgeList.leftRegion(lbnd);
8445      top = EdgeList.rightRegion(rbnd);
8446      v = lbnd.vertex;
8447      Geom.endPoint(lbnd.edge, lbnd.side, v);
8448      Geom.endPoint(rbnd.edge, rbnd.side, v);
8449      EdgeList.del(lbnd);
8450      EventQueue.del(rbnd);
8451      EdgeList.del(rbnd);
8452      pm = "l";
8453      if (bot.y > top.y) {
8454        temp = bot;
8455        bot = top;
8456        top = temp;
8457        pm = "r";
8458      }
8459      e = Geom.bisect(bot, top);
8460      bisector = EdgeList.createHalfEdge(e, pm);
8461      EdgeList.insert(llbnd, bisector);
8462      Geom.endPoint(e, d3_voronoi_opposite[pm], v);
8463      p = Geom.intersect(llbnd, bisector);
8464      if (p) {
8465        EventQueue.del(llbnd);
8466        EventQueue.insert(llbnd, p, Geom.distance(p, bot));
8467      }
8468      p = Geom.intersect(bisector, rrbnd);
8469      if (p) {
8470        EventQueue.insert(bisector, p, Geom.distance(p, bot));
8471      }
8472    } else {
8473      break;
8474    }
8475  }//end while
8476
8477  for (lbnd = EdgeList.right(EdgeList.leftEnd);
8478      lbnd != EdgeList.rightEnd;
8479      lbnd = EdgeList.right(lbnd)) {
8480    callback(lbnd.edge);
8481  }
8482}
8483/**
8484* @param vertices [[x1, y1], [x2, y2], 
]
8485* @returns triangles [[[x1, y1], [x2, y2], [x3, y3]], 
]
8486 */
8487d3.geom.delaunay = function(vertices) {
8488  var edges = vertices.map(function() { return []; }),
8489      triangles = [];
8490
8491  // Use the Voronoi tessellation to determine Delaunay edges.
8492  d3_voronoi_tessellate(vertices, function(e) {
8493    edges[e.region.l.index].push(vertices[e.region.r.index]);
8494  });
8495
8496  // Reconnect the edges into counterclockwise triangles.
8497  edges.forEach(function(edge, i) {
8498    var v = vertices[i],
8499        cx = v[0],
8500        cy = v[1];
8501    edge.forEach(function(v) {
8502      v.angle = Math.atan2(v[0] - cx, v[1] - cy);
8503    });
8504    edge.sort(function(a, b) {
8505      return a.angle - b.angle;
8506    });
8507    for (var j = 0, m = edge.length - 1; j < m; j++) {
8508      triangles.push([v, edge[j], edge[j + 1]]);
8509    }
8510  });
8511
8512  return triangles;
8513};
8514// Constructs a new quadtree for the specified array of points. A quadtree is a
8515// two-dimensional recursive spatial subdivision. This implementation uses
8516// square partitions, dividing each square into four equally-sized squares. Each
8517// point exists in a unique node; if multiple points are in the same position,
8518// some points may be stored on internal nodes rather than leaf nodes. Quadtrees
8519// can be used to accelerate various spatial operations, such as the Barnes-Hut
8520// approximation for computing n-body forces, or collision detection.
8521d3.geom.quadtree = function(points, x1, y1, x2, y2) {
8522  var p,
8523      i = -1,
8524      n = points.length;
8525
8526  // Type conversion for deprecated API.
8527  if (n && isNaN(points[0].x)) points = points.map(d3_geom_quadtreePoint);
8528
8529  // Allow bounds to be specified explicitly.
8530  if (arguments.length < 5) {
8531    if (arguments.length === 3) {
8532      y2 = x2 = y1;
8533      y1 = x1;
8534    } else {
8535      x1 = y1 = Infinity;
8536      x2 = y2 = -Infinity;
8537
8538      // Compute bounds.
8539      while (++i < n) {
8540        p = points[i];
8541        if (p.x < x1) x1 = p.x;
8542        if (p.y < y1) y1 = p.y;
8543        if (p.x > x2) x2 = p.x;
8544        if (p.y > y2) y2 = p.y;
8545      }
8546
8547      // Squarify the bounds.
8548      var dx = x2 - x1,
8549          dy = y2 - y1;
8550      if (dx > dy) y2 = y1 + dx;
8551      else x2 = x1 + dy;
8552    }
8553  }
8554
8555  // Recursively inserts the specified point p at the node n or one of its
8556  // descendants. The bounds are defined by [x1, x2] and [y1, y2].
8557  function insert(n, p, x1, y1, x2, y2) {
8558    if (isNaN(p.x) || isNaN(p.y)) return; // ignore invalid points
8559    if (n.leaf) {
8560      var v = n.point;
8561      if (v) {
8562        // If the point at this leaf node is at the same position as the new
8563        // point we are adding, we leave the point associated with the
8564        // internal node while adding the new point to a child node. This
8565        // avoids infinite recursion.
8566        if ((Math.abs(v.x - p.x) + Math.abs(v.y - p.y)) < .01) {
8567          insertChild(n, p, x1, y1, x2, y2);
8568        } else {
8569          n.point = null;
8570          insertChild(n, v, x1, y1, x2, y2);
8571          insertChild(n, p, x1, y1, x2, y2);
8572        }
8573      } else {
8574        n.point = p;
8575      }
8576    } else {
8577      insertChild(n, p, x1, y1, x2, y2);
8578    }
8579  }
8580
8581  // Recursively inserts the specified point p into a descendant of node n. The
8582  // bounds are defined by [x1, x2] and [y1, y2].
8583  function insertChild(n, p, x1, y1, x2, y2) {
8584    // Compute the split point, and the quadrant in which to insert p.
8585    var sx = (x1 + x2) * .5,
8586        sy = (y1 + y2) * .5,
8587        right = p.x >= sx,
8588        bottom = p.y >= sy,
8589        i = (bottom << 1) + right;
8590
8591    // Recursively insert into the child node.
8592    n.leaf = false;
8593    n = n.nodes[i] || (n.nodes[i] = d3_geom_quadtreeNode());
8594
8595    // Update the bounds as we recurse.
8596    if (right) x1 = sx; else x2 = sx;
8597    if (bottom) y1 = sy; else y2 = sy;
8598    insert(n, p, x1, y1, x2, y2);
8599  }
8600
8601  // Create the root node.
8602  var root = d3_geom_quadtreeNode();
8603
8604  root.add = function(p) {
8605    insert(root, p, x1, y1, x2, y2);
8606  };
8607
8608  root.visit = function(f) {
8609    d3_geom_quadtreeVisit(f, root, x1, y1, x2, y2);
8610  };
8611
8612  // Insert all points.
8613  points.forEach(root.add);
8614  return root;
8615};
8616
8617function d3_geom_quadtreeNode() {
8618  return {
8619    leaf: true,
8620    nodes: [],
8621    point: null
8622  };
8623}
8624
8625function d3_geom_quadtreeVisit(f, node, x1, y1, x2, y2) {
8626  if (!f(node, x1, y1, x2, y2)) {
8627    var sx = (x1 + x2) * .5,
8628        sy = (y1 + y2) * .5,
8629        children = node.nodes;
8630    if (children[0]) d3_geom_quadtreeVisit(f, children[0], x1, y1, sx, sy);
8631    if (children[1]) d3_geom_quadtreeVisit(f, children[1], sx, y1, x2, sy);
8632    if (children[2]) d3_geom_quadtreeVisit(f, children[2], x1, sy, sx, y2);
8633    if (children[3]) d3_geom_quadtreeVisit(f, children[3], sx, sy, x2, y2);
8634  }
8635}
8636
8637function d3_geom_quadtreePoint(p) {
8638  return {
8639    x: p[0],
8640    y: p[1]
8641  };
8642}
8643d3.time = {};
8644
8645var d3_time = Date;
8646
8647function d3_time_utc() {
8648  this._ = new Date(arguments.length > 1
8649      ? Date.UTC.apply(this, arguments)
8650      : arguments[0]);
8651}
8652
8653d3_time_utc.prototype = {
8654  getDate: function() { return this._.getUTCDate(); },
8655  getDay: function() { return this._.getUTCDay(); },
8656  getFullYear: function() { return this._.getUTCFullYear(); },
8657  getHours: function() { return this._.getUTCHours(); },
8658  getMilliseconds: function() { return this._.getUTCMilliseconds(); },
8659  getMinutes: function() { return this._.getUTCMinutes(); },
8660  getMonth: function() { return this._.getUTCMonth(); },
8661  getSeconds: function() { return this._.getUTCSeconds(); },
8662  getTime: function() { return this._.getTime(); },
8663  getTimezoneOffset: function() { return 0; },
8664  valueOf: function() { return this._.valueOf(); },
8665  setDate: function() { d3_time_prototype.setUTCDate.apply(this._, arguments); },
8666  setDay: function() { d3_time_prototype.setUTCDay.apply(this._, arguments); },
8667  setFullYear: function() { d3_time_prototype.setUTCFullYear.apply(this._, arguments); },
8668  setHours: function() { d3_time_prototype.setUTCHours.apply(this._, arguments); },
8669  setMilliseconds: function() { d3_time_prototype.setUTCMilliseconds.apply(this._, arguments); },
8670  setMinutes: function() { d3_time_prototype.setUTCMinutes.apply(this._, arguments); },
8671  setMonth: function() { d3_time_prototype.setUTCMonth.apply(this._, arguments); },
8672  setSeconds: function() { d3_time_prototype.setUTCSeconds.apply(this._, arguments); },
8673  setTime: function() { d3_time_prototype.setTime.apply(this._, arguments); }
8674};
8675
8676var d3_time_prototype = Date.prototype;
8677d3.time.format = function(template) {
8678  var n = template.length;
8679
8680  function format(date) {
8681    var string = [],
8682        i = -1,
8683        j = 0,
8684        c,
8685        f;
8686    while (++i < n) {
8687      if (template.charCodeAt(i) == 37) {
8688        string.push(
8689            template.substring(j, i),
8690            (f = d3_time_formats[c = template.charAt(++i)])
8691            ? f(date) : c);
8692        j = i + 1;
8693      }
8694    }
8695    string.push(template.substring(j, i));
8696    return string.join("");
8697  }
8698
8699  format.parse = function(string) {
8700    var d = {y: 1900, m: 0, d: 1, H: 0, M: 0, S: 0, L: 0},
8701        i = d3_time_parse(d, template, string, 0);
8702    if (i != string.length) return null;
8703
8704    // The am-pm flag is 0 for AM, and 1 for PM.
8705    if ("p" in d) d.H = d.H % 12 + d.p * 12;
8706
8707    var date = new d3_time();
8708    date.setFullYear(d.y, d.m, d.d);
8709    date.setHours(d.H, d.M, d.S, d.L);
8710    return date;
8711  };
8712
8713  format.toString = function() {
8714    return template;
8715  };
8716
8717  return format;
8718};
8719
8720function d3_time_parse(date, template, string, j) {
8721  var c,
8722      p,
8723      i = 0,
8724      n = template.length,
8725      m = string.length;
8726  while (i < n) {
8727    if (j >= m) return -1;
8728    c = template.charCodeAt(i++);
8729    if (c == 37) {
8730      p = d3_time_parsers[template.charAt(i++)];
8731      if (!p || ((j = p(date, string, j)) < 0)) return -1;
8732    } else if (c != string.charCodeAt(j++)) {
8733      return -1;
8734    }
8735  }
8736  return j;
8737}
8738
8739var d3_time_zfill2 = d3.format("02d"),
8740    d3_time_zfill3 = d3.format("03d"),
8741    d3_time_zfill4 = d3.format("04d"),
8742    d3_time_sfill2 = d3.format("2d");
8743
8744var d3_time_formats = {
8745  a: function(d) { return d3_time_weekdays[d.getDay()].substring(0, 3); },
8746  A: function(d) { return d3_time_weekdays[d.getDay()]; },
8747  b: function(d) { return d3_time_months[d.getMonth()].substring(0, 3); },
8748  B: function(d) { return d3_time_months[d.getMonth()]; },
8749  c: d3.time.format("%a %b %e %H:%M:%S %Y"),
8750  d: function(d) { return d3_time_zfill2(d.getDate()); },
8751  e: function(d) { return d3_time_sfill2(d.getDate()); },
8752  H: function(d) { return d3_time_zfill2(d.getHours()); },
8753  I: function(d) { return d3_time_zfill2(d.getHours() % 12 || 12); },
8754  j: function(d) { return d3_time_zfill3(1 + d3.time.dayOfYear(d)); },
8755  L: function(d) { return d3_time_zfill3(d.getMilliseconds()); },
8756  m: function(d) { return d3_time_zfill2(d.getMonth() + 1); },
8757  M: function(d) { return d3_time_zfill2(d.getMinutes()); },
8758  p: function(d) { return d.getHours() >= 12 ? "PM" : "AM"; },
8759  S: function(d) { return d3_time_zfill2(d.getSeconds()); },
8760  U: function(d) { return d3_time_zfill2(d3.time.sundayOfYear(d)); },
8761  w: function(d) { return d.getDay(); },
8762  W: function(d) { return d3_time_zfill2(d3.time.mondayOfYear(d)); },
8763  x: d3.time.format("%m/%d/%y"),
8764  X: d3.time.format("%H:%M:%S"),
8765  y: function(d) { return d3_time_zfill2(d.getFullYear() % 100); },
8766  Y: function(d) { return d3_time_zfill4(d.getFullYear() % 10000); },
8767  Z: d3_time_zone,
8768  "%": function(d) { return "%"; }
8769};
8770
8771var d3_time_parsers = {
8772  a: d3_time_parseWeekdayAbbrev,
8773  A: d3_time_parseWeekday,
8774  b: d3_time_parseMonthAbbrev,
8775  B: d3_time_parseMonth,
8776  c: d3_time_parseLocaleFull,
8777  d: d3_time_parseDay,
8778  e: d3_time_parseDay,
8779  H: d3_time_parseHour24,
8780  I: d3_time_parseHour24,
8781  // j: function(d, s, i) { /*TODO day of year [001,366] */ return i; },
8782  L: d3_time_parseMilliseconds,
8783  m: d3_time_parseMonthNumber,
8784  M: d3_time_parseMinutes,
8785  p: d3_time_parseAmPm,
8786  S: d3_time_parseSeconds,
8787  // U: function(d, s, i) { /*TODO week number (sunday) [00,53] */ return i; },
8788  // w: function(d, s, i) { /*TODO weekday [0,6] */ return i; },
8789  // W: function(d, s, i) { /*TODO week number (monday) [00,53] */ return i; },
8790  x: d3_time_parseLocaleDate,
8791  X: d3_time_parseLocaleTime,
8792  y: d3_time_parseYear,
8793  Y: d3_time_parseFullYear
8794  // ,
8795  // Z: function(d, s, i) { /*TODO time zone */ return i; },
8796  // "%": function(d, s, i) { /*TODO literal % */ return i; }
8797};
8798
8799// Note: weekday is validated, but does not set the date.
8800function d3_time_parseWeekdayAbbrev(date, string, i) {
8801  return d3_time_weekdayAbbrevRe.test(string.substring(i, i += 3)) ? i : -1;
8802}
8803
8804// Note: weekday is validated, but does not set the date.
8805function d3_time_parseWeekday(date, string, i) {
8806  d3_time_weekdayRe.lastIndex = 0;
8807  var n = d3_time_weekdayRe.exec(string.substring(i, i + 10));
8808  return n ? i += n[0].length : -1;
8809}
8810
8811var d3_time_weekdayAbbrevRe = /^(?:sun|mon|tue|wed|thu|fri|sat)/i,
8812    d3_time_weekdayRe = /^(?:Sunday|Monday|Tuesday|Wednesday|Thursday|Friday|Saturday)/i;
8813    d3_time_weekdays = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
8814
8815function d3_time_parseMonthAbbrev(date, string, i) {
8816  var n = d3_time_monthAbbrevLookup.get(string.substring(i, i += 3).toLowerCase());
8817  return n == null ? -1 : (date.m = n, i);
8818}
8819
8820var d3_time_monthAbbrevLookup = d3.map({
8821  jan: 0,
8822  feb: 1,
8823  mar: 2,
8824  apr: 3,
8825  may: 4,
8826  jun: 5,
8827  jul: 6,
8828  aug: 7,
8829  sep: 8,
8830  oct: 9,
8831  nov: 10,
8832  dec: 11
8833});
8834
8835function d3_time_parseMonth(date, string, i) {
8836  d3_time_monthRe.lastIndex = 0;
8837  var n = d3_time_monthRe.exec(string.substring(i, i + 12));
8838  return n ? (date.m = d3_time_monthLookup.get(n[0].toLowerCase()), i += n[0].length) : -1;
8839}
8840
8841var d3_time_monthRe = /^(?:January|February|March|April|May|June|July|August|September|October|November|December)/ig;
8842
8843var d3_time_monthLookup = d3.map({
8844  january: 0,
8845  february: 1,
8846  march: 2,
8847  april: 3,
8848  may: 4,
8849  june: 5,
8850  july: 6,
8851  august: 7,
8852  september: 8,
8853  october: 9,
8854  november: 10,
8855  december: 11
8856});
8857
8858var d3_time_months = [
8859  "January",
8860  "February",
8861  "March",
8862  "April",
8863  "May",
8864  "June",
8865  "July",
8866  "August",
8867  "September",
8868  "October",
8869  "November",
8870  "December"
8871];
8872
8873function d3_time_parseLocaleFull(date, string, i) {
8874  return d3_time_parse(date, d3_time_formats.c.toString(), string, i);
8875}
8876
8877function d3_time_parseLocaleDate(date, string, i) {
8878  return d3_time_parse(date, d3_time_formats.x.toString(), string, i);
8879}
8880
8881function d3_time_parseLocaleTime(date, string, i) {
8882  return d3_time_parse(date, d3_time_formats.X.toString(), string, i);
8883}
8884
8885function d3_time_parseFullYear(date, string, i) {
8886  d3_time_numberRe.lastIndex = 0;
8887  var n = d3_time_numberRe.exec(string.substring(i, i + 4));
8888  return n ? (date.y = +n[0], i += n[0].length) : -1;
8889}
8890
8891function d3_time_parseYear(date, string, i) {
8892  d3_time_numberRe.lastIndex = 0;
8893  var n = d3_time_numberRe.exec(string.substring(i, i + 2));
8894  return n ? (date.y = d3_time_century() + +n[0], i += n[0].length) : -1;
8895}
8896
8897function d3_time_century() {
8898  return ~~(new Date().getFullYear() / 1000) * 1000;
8899}
8900
8901function d3_time_parseMonthNumber(date, string, i) {
8902  d3_time_numberRe.lastIndex = 0;
8903  var n = d3_time_numberRe.exec(string.substring(i, i + 2));
8904  return n ? (date.m = n[0] - 1, i += n[0].length) : -1;
8905}
8906
8907function d3_time_parseDay(date, string, i) {
8908  d3_time_numberRe.lastIndex = 0;
8909  var n = d3_time_numberRe.exec(string.substring(i, i + 2));
8910  return n ? (date.d = +n[0], i += n[0].length) : -1;
8911}
8912
8913// Note: we don't validate that the hour is in the range [0,23] or [1,12].
8914function d3_time_parseHour24(date, string, i) {
8915  d3_time_numberRe.lastIndex = 0;
8916  var n = d3_time_numberRe.exec(string.substring(i, i + 2));
8917  return n ? (date.H = +n[0], i += n[0].length) : -1;
8918}
8919
8920function d3_time_parseMinutes(date, string, i) {
8921  d3_time_numberRe.lastIndex = 0;
8922  var n = d3_time_numberRe.exec(string.substring(i, i + 2));
8923  return n ? (date.M = +n[0], i += n[0].length) : -1;
8924}
8925
8926function d3_time_parseSeconds(date, string, i) {
8927  d3_time_numberRe.lastIndex = 0;
8928  var n = d3_time_numberRe.exec(string.substring(i, i + 2));
8929  return n ? (date.S = +n[0], i += n[0].length) : -1;
8930}
8931
8932function d3_time_parseMilliseconds(date, string, i) {
8933  d3_time_numberRe.lastIndex = 0;
8934  var n = d3_time_numberRe.exec(string.substring(i, i + 3));
8935  return n ? (date.L = +n[0], i += n[0].length) : -1;
8936}
8937
8938// Note: we don't look at the next directive.
8939var d3_time_numberRe = /\s*\d+/;
8940
8941function d3_time_parseAmPm(date, string, i) {
8942  var n = d3_time_amPmLookup.get(string.substring(i, i += 2).toLowerCase());
8943  return n == null ? -1 : (date.p = n, i);
8944}
8945
8946var d3_time_amPmLookup = d3.map({
8947  am: 0,
8948  pm: 1
8949});
8950
8951// TODO table of time zone offset names?
8952function d3_time_zone(d) {
8953  var z = d.getTimezoneOffset(),
8954      zs = z > 0 ? "-" : "+",
8955      zh = ~~(Math.abs(z) / 60),
8956      zm = Math.abs(z) % 60;
8957  return zs + d3_time_zfill2(zh) + d3_time_zfill2(zm);
8958}
8959d3.time.format.utc = function(template) {
8960  var local = d3.time.format(template);
8961
8962  function format(date) {
8963    try {
8964      d3_time = d3_time_utc;
8965      var utc = new d3_time();
8966      utc._ = date;
8967      return local(utc);
8968    } finally {
8969      d3_time = Date;
8970    }
8971  }
8972
8973  format.parse = function(string) {
8974    try {
8975      d3_time = d3_time_utc;
8976      var date = local.parse(string);
8977      return date && date._;
8978    } finally {
8979      d3_time = Date;
8980    }
8981  };
8982
8983  format.toString = local.toString;
8984
8985  return format;
8986};
8987var d3_time_formatIso = d3.time.format.utc("%Y-%m-%dT%H:%M:%S.%LZ");
8988
8989d3.time.format.iso = Date.prototype.toISOString ? d3_time_formatIsoNative : d3_time_formatIso;
8990
8991function d3_time_formatIsoNative(date) {
8992  return date.toISOString();
8993}
8994
8995d3_time_formatIsoNative.parse = function(string) {
8996  return new Date(string);
8997};
8998
8999d3_time_formatIsoNative.toString = d3_time_formatIso.toString;
9000function d3_time_interval(local, step, number) {
9001
9002  function round(date) {
9003    var d0 = local(date), d1 = offset(d0, 1);
9004    return date - d0 < d1 - date ? d0 : d1;
9005  }
9006
9007  function ceil(date) {
9008    step(date = local(new d3_time(date - 1)), 1);
9009    return date;
9010  }
9011
9012  function offset(date, k) {
9013    step(date = new d3_time(+date), k);
9014    return date;
9015  }
9016
9017  function range(t0, t1, dt) {
9018    var time = ceil(t0), times = [];
9019    if (dt > 1) {
9020      while (time < t1) {
9021        if (!(number(time) % dt)) times.push(new Date(+time));
9022        step(time, 1);
9023      }
9024    } else {
9025      while (time < t1) times.push(new Date(+time)), step(time, 1);
9026    }
9027    return times;
9028  }
9029
9030  function range_utc(t0, t1, dt) {
9031    try {
9032      d3_time = d3_time_utc;
9033      var utc = new d3_time_utc();
9034      utc._ = t0;
9035      return range(utc, t1, dt);
9036    } finally {
9037      d3_time = Date;
9038    }
9039  }
9040
9041  local.floor = local;
9042  local.round = round;
9043  local.ceil = ceil;
9044  local.offset = offset;
9045  local.range = range;
9046
9047  var utc = local.utc = d3_time_interval_utc(local);
9048  utc.floor = utc;
9049  utc.round = d3_time_interval_utc(round);
9050  utc.ceil = d3_time_interval_utc(ceil);
9051  utc.offset = d3_time_interval_utc(offset);
9052  utc.range = range_utc;
9053
9054  return local;
9055}
9056
9057function d3_time_interval_utc(method) {
9058  return function(date, k) {
9059    try {
9060      d3_time = d3_time_utc;
9061      var utc = new d3_time_utc();
9062      utc._ = date;
9063      return method(utc, k)._;
9064    } finally {
9065      d3_time = Date;
9066    }
9067  };
9068}
9069d3.time.second = d3_time_interval(function(date) {
9070  return new d3_time(Math.floor(date / 1e3) * 1e3);
9071}, function(date, offset) {
9072  date.setTime(date.getTime() + Math.floor(offset) * 1e3); // DST breaks setSeconds
9073}, function(date) {
9074  return date.getSeconds();
9075});
9076
9077d3.time.seconds = d3.time.second.range;
9078d3.time.seconds.utc = d3.time.second.utc.range;
9079d3.time.minute = d3_time_interval(function(date) {
9080  return new d3_time(Math.floor(date / 6e4) * 6e4);
9081}, function(date, offset) {
9082  date.setTime(date.getTime() + Math.floor(offset) * 6e4); // DST breaks setMinutes
9083}, function(date) {
9084  return date.getMinutes();
9085});
9086
9087d3.time.minutes = d3.time.minute.range;
9088d3.time.minutes.utc = d3.time.minute.utc.range;
9089d3.time.hour = d3_time_interval(function(date) {
9090  var timezone = date.getTimezoneOffset() / 60;
9091  return new d3_time((Math.floor(date / 36e5 - timezone) + timezone) * 36e5);
9092}, function(date, offset) {
9093  date.setTime(date.getTime() + Math.floor(offset) * 36e5); // DST breaks setHours
9094}, function(date) {
9095  return date.getHours();
9096});
9097
9098d3.time.hours = d3.time.hour.range;
9099d3.time.hours.utc = d3.time.hour.utc.range;
9100d3.time.day = d3_time_interval(function(date) {
9101  return new d3_time(date.getFullYear(), date.getMonth(), date.getDate());
9102}, function(date, offset) {
9103  date.setDate(date.getDate() + offset);
9104}, function(date) {
9105  return date.getDate() - 1;
9106});
9107
9108d3.time.days = d3.time.day.range;
9109d3.time.days.utc = d3.time.day.utc.range;
9110
9111d3.time.dayOfYear = function(date) {
9112  var year = d3.time.year(date);
9113  return Math.floor((date - year) / 864e5 - (date.getTimezoneOffset() - year.getTimezoneOffset()) / 1440);
9114};
9115d3_time_weekdays.forEach(function(day, i) {
9116  day = day.toLowerCase();
9117  i = 7 - i;
9118
9119  var interval = d3.time[day] = d3_time_interval(function(date) {
9120    (date = d3.time.day(date)).setDate(date.getDate() - (date.getDay() + i) % 7);
9121    return date;
9122  }, function(date, offset) {
9123    date.setDate(date.getDate() + Math.floor(offset) * 7);
9124  }, function(date) {
9125    var day = d3.time.year(date).getDay();
9126    return Math.floor((d3.time.dayOfYear(date) + (day + i) % 7) / 7) - (day !== i);
9127  });
9128
9129  d3.time[day + "s"] = interval.range;
9130  d3.time[day + "s"].utc = interval.utc.range;
9131
9132  d3.time[day + "OfYear"] = function(date) {
9133    var day = d3.time.year(date).getDay();
9134    return Math.floor((d3.time.dayOfYear(date) + (day + i) % 7) / 7);
9135  };
9136});
9137
9138d3.time.week = d3.time.sunday;
9139d3.time.weeks = d3.time.sunday.range;
9140d3.time.weeks.utc = d3.time.sunday.utc.range;
9141d3.time.weekOfYear = d3.time.sundayOfYear;
9142d3.time.month = d3_time_interval(function(date) {
9143  return new d3_time(date.getFullYear(), date.getMonth(), 1);
9144}, function(date, offset) {
9145  date.setMonth(date.getMonth() + offset);
9146}, function(date) {
9147  return date.getMonth();
9148});
9149
9150d3.time.months = d3.time.month.range;
9151d3.time.months.utc = d3.time.month.utc.range;
9152d3.time.year = d3_time_interval(function(date) {
9153  return new d3_time(date.getFullYear(), 0, 1);
9154}, function(date, offset) {
9155  date.setFullYear(date.getFullYear() + offset);
9156}, function(date) {
9157  return date.getFullYear();
9158});
9159
9160d3.time.years = d3.time.year.range;
9161d3.time.years.utc = d3.time.year.utc.range;
9162function d3_time_scale(linear, methods, format) {
9163
9164  function scale(x) {
9165    return linear(x);
9166  }
9167
9168  scale.invert = function(x) {
9169    return d3_time_scaleDate(linear.invert(x));
9170  };
9171
9172  scale.domain = function(x) {
9173    if (!arguments.length) return linear.domain().map(d3_time_scaleDate);
9174    linear.domain(x);
9175    return scale;
9176  };
9177
9178  scale.nice = function(m) {
9179    var extent = d3_time_scaleExtent(scale.domain());
9180    return scale.domain([m.floor(extent[0]), m.ceil(extent[1])]);
9181  };
9182
9183  scale.ticks = function(m, k) {
9184    var extent = d3_time_scaleExtent(scale.domain());
9185    if (typeof m !== "function") {
9186      var span = extent[1] - extent[0],
9187          target = span / m,
9188          i = d3.bisect(d3_time_scaleSteps, target);
9189      if (i == d3_time_scaleSteps.length) return methods.year(extent, m);
9190      if (!i) return linear.ticks(m).map(d3_time_scaleDate);
9191      if (Math.log(target / d3_time_scaleSteps[i - 1]) < Math.log(d3_time_scaleSteps[i] / target)) --i;
9192      m = methods[i];
9193      k = m[1];
9194      m = m[0].range;
9195    }
9196    return m(extent[0], new Date(+extent[1] + 1), k); // inclusive upper bound
9197  };
9198
9199  scale.tickFormat = function() {
9200    return format;
9201  };
9202
9203  scale.copy = function() {
9204    return d3_time_scale(linear.copy(), methods, format);
9205  };
9206
9207  // TOOD expose d3_scale_linear_rebind?
9208  return d3.rebind(scale, linear, "range", "rangeRound", "interpolate", "clamp");
9209}
9210
9211// TODO expose d3_scaleExtent?
9212function d3_time_scaleExtent(domain) {
9213  var start = domain[0], stop = domain[domain.length - 1];
9214  return start < stop ? [start, stop] : [stop, start];
9215}
9216
9217function d3_time_scaleDate(t) {
9218  return new Date(t);
9219}
9220
9221function d3_time_scaleFormat(formats) {
9222  return function(date) {
9223    var i = formats.length - 1, f = formats[i];
9224    while (!f[1](date)) f = formats[--i];
9225    return f[0](date);
9226  };
9227}
9228
9229function d3_time_scaleSetYear(y) {
9230  var d = new Date(y, 0, 1);
9231  d.setFullYear(y); // Y2K fail
9232  return d;
9233}
9234
9235function d3_time_scaleGetYear(d) {
9236  var y = d.getFullYear(),
9237      d0 = d3_time_scaleSetYear(y),
9238      d1 = d3_time_scaleSetYear(y + 1);
9239  return y + (d - d0) / (d1 - d0);
9240}
9241
9242var d3_time_scaleSteps = [
9243  1e3,    // 1-second
9244  5e3,    // 5-second
9245  15e3,   // 15-second
9246  3e4,    // 30-second
9247  6e4,    // 1-minute
9248  3e5,    // 5-minute
9249  9e5,    // 15-minute
9250  18e5,   // 30-minute
9251  36e5,   // 1-hour
9252  108e5,  // 3-hour
9253  216e5,  // 6-hour
9254  432e5,  // 12-hour
9255  864e5,  // 1-day
9256  1728e5, // 2-day
9257  6048e5, // 1-week
9258  2592e6, // 1-month
9259  7776e6, // 3-month
9260  31536e6 // 1-year
9261];
9262
9263var d3_time_scaleLocalMethods = [
9264  [d3.time.second, 1],
9265  [d3.time.second, 5],
9266  [d3.time.second, 15],
9267  [d3.time.second, 30],
9268  [d3.time.minute, 1],
9269  [d3.time.minute, 5],
9270  [d3.time.minute, 15],
9271  [d3.time.minute, 30],
9272  [d3.time.hour, 1],
9273  [d3.time.hour, 3],
9274  [d3.time.hour, 6],
9275  [d3.time.hour, 12],
9276  [d3.time.day, 1],
9277  [d3.time.day, 2],
9278  [d3.time.week, 1],
9279  [d3.time.month, 1],
9280  [d3.time.month, 3],
9281  [d3.time.year, 1]
9282];
9283
9284var d3_time_scaleLocalFormats = [
9285  [d3.time.format("%Y"), function(d) { return true; }],
9286  [d3.time.format("%B"), function(d) { return d.getMonth(); }],
9287  [d3.time.format("%b %d"), function(d) { return d.getDate() != 1; }],
9288  [d3.time.format("%a %d"), function(d) { return d.getDay() && d.getDate() != 1; }],
9289  [d3.time.format("%I %p"), function(d) { return d.getHours(); }],
9290  [d3.time.format("%I:%M"), function(d) { return d.getMinutes(); }],
9291  [d3.time.format(":%S"), function(d) { return d.getSeconds(); }],
9292  [d3.time.format(".%L"), function(d) { return d.getMilliseconds(); }]
9293];
9294
9295var d3_time_scaleLinear = d3.scale.linear(),
9296    d3_time_scaleLocalFormat = d3_time_scaleFormat(d3_time_scaleLocalFormats);
9297
9298d3_time_scaleLocalMethods.year = function(extent, m) {
9299  return d3_time_scaleLinear.domain(extent.map(d3_time_scaleGetYear)).ticks(m).map(d3_time_scaleSetYear);
9300};
9301
9302d3.time.scale = function() {
9303  return d3_time_scale(d3.scale.linear(), d3_time_scaleLocalMethods, d3_time_scaleLocalFormat);
9304};
9305var d3_time_scaleUTCMethods = d3_time_scaleLocalMethods.map(function(m) {
9306  return [m[0].utc, m[1]];
9307});
9308
9309var d3_time_scaleUTCFormats = [
9310  [d3.time.format.utc("%Y"), function(d) { return true; }],
9311  [d3.time.format.utc("%B"), function(d) { return d.getUTCMonth(); }],
9312  [d3.time.format.utc("%b %d"), function(d) { return d.getUTCDate() != 1; }],
9313  [d3.time.format.utc("%a %d"), function(d) { return d.getUTCDay() && d.getUTCDate() != 1; }],
9314  [d3.time.format.utc("%I %p"), function(d) { return d.getUTCHours(); }],
9315  [d3.time.format.utc("%I:%M"), function(d) { return d.getUTCMinutes(); }],
9316  [d3.time.format.utc(":%S"), function(d) { return d.getUTCSeconds(); }],
9317  [d3.time.format.utc(".%L"), function(d) { return d.getUTCMilliseconds(); }]
9318];
9319
9320var d3_time_scaleUTCFormat = d3_time_scaleFormat(d3_time_scaleUTCFormats);
9321
9322function d3_time_scaleUTCSetYear(y) {
9323  var d = new Date(Date.UTC(y, 0, 1));
9324  d.setUTCFullYear(y); // Y2K fail
9325  return d;
9326}
9327
9328function d3_time_scaleUTCGetYear(d) {
9329  var y = d.getUTCFullYear(),
9330      d0 = d3_time_scaleUTCSetYear(y),
9331      d1 = d3_time_scaleUTCSetYear(y + 1);
9332  return y + (d - d0) / (d1 - d0);
9333}
9334
9335d3_time_scaleUTCMethods.year = function(extent, m) {
9336  return d3_time_scaleLinear.domain(extent.map(d3_time_scaleUTCGetYear)).ticks(m).map(d3_time_scaleUTCSetYear);
9337};
9338
9339d3.time.scale.utc = function() {
9340  return d3_time_scale(d3.scale.linear(), d3_time_scaleUTCMethods, d3_time_scaleUTCFormat);
9341};
9342})();
Note: See TracBrowser for help on using the repository browser.