[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#930374: marked as done (stretch-pu: package node-url-parse/1.0.5-2+deb9u1)



Your message dated Sat, 18 Jul 2020 13:07:00 +0100
with message-id <b8d89cdfeeda7b6d1ef96a8706a20f9525c2151b.camel@adam-barratt.org.uk>
and subject line Closing requests for fixes included in 9.13 point release
has caused the Debian Bug report #930374,
regarding stretch-pu: package node-url-parse/1.0.5-2+deb9u1
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact owner@bugs.debian.org
immediately.)


-- 
930374: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=930374
Debian Bug Tracking System
Contact owner@bugs.debian.org with problems
--- Begin Message ---
Package: release.debian.org
Severity: normal
Tags: stretch
User: release.debian.org@packages.debian.org
Usertags: pu

Hi all,

node-url-parse does not parse correctly hostname which leads to multiple
vulnerabilities such as SSRF, Open Redirect, Bypass Authentication
Protocol,... (#906058, CVE-2018-3774)

I imported upstream patch in debian/patches/CVE-2018-3774.patch. This is
the only changes enabled on installed files. Since this package didn't
launch upstream test, I added also some build dependencies and installed
some little required test dependencies in debian/tests/test_modules, and
of course modify debian/rules.

If you prefer to have only the security change without test, I just can
just this commit with a debian/changelog entry:
https://salsa.debian.org/js-team/node-url-parse/commit/e4204c37

Cheers,
Xavier

-- System Information:
Debian Release: 10.0
  APT prefers testing
  APT policy: (600, 'testing'), (50, 'unstable')
Architecture: amd64 (x86_64)
Foreign Architectures: i386

Kernel: Linux 4.14.0-3-amd64 (SMP w/2 CPU cores)
Kernel taint flags: TAINT_WARN
Locale: LANG=fr_FR.UTF-8, LC_CTYPE=fr_FR.UTF-8 (charmap=UTF-8), LANGUAGE= (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
Init: systemd (via /run/systemd/system)
LSM: AppArmor: enabled
diff --git a/debian/changelog b/debian/changelog
index 64ce989..3033da4 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,13 @@
+node-url-parse (1.0.5-2+deb9u1) stretch; urgency=medium
+
+  * Add patch to sanitize paths and hosts before parsing (Closes: #906058,
+    CVE-2018-3774)
+  * Enable upstream test. This embeds some little modules for test only:
+    ansi-codes, assume, failing-code, failing-line, fn.name, format-text,
+    is-node, left-pad, pathval, prettify-error and style-format
+
+ -- Xavier Guimard <yadd@debian.org>  Tue, 11 Jun 2019 18:21:11 +0200
+
 node-url-parse (1.0.5-2) unstable; urgency=medium
 
   * debian/install: install more files into package
diff --git a/debian/control b/debian/control
index f620a6c..c7ea086 100644
--- a/debian/control
+++ b/debian/control
@@ -7,6 +7,11 @@ Build-Depends:
  debhelper (>= 9)
  , dh-buildinfo
  , nodejs
+ , mocha
+ , node-object-inspect
+ , node-requires-port
+ , node-querystringify
+ , node-deep-eql
 Standards-Version: 3.9.6
 Homepage: https://github.com/unshiftio/url-parse#readme
 Vcs-Git: https://anonscm.debian.org/git/pkg-javascript/node-url-parse.git
diff --git a/debian/copyright b/debian/copyright
index 490b21b..1f1f1f0 100644
--- a/debian/copyright
+++ b/debian/copyright
@@ -11,6 +11,26 @@ Files: debian/*
 Copyright: 2015 Thorsten Alteholz <debian@alteholz.de>
 License: Expat
 
+Files: debian/tests/test_modules/*
+Copyright: Azer Koçulu <azer@kodfabrik.com>
+License: BSD-3-Clause
+Comment: The upstream distribution does not contain an explicit statement of
+ copyright ownership. Pursuant to the Berne Convention for the Protection of
+ Literary and Artistic Works, it is assumed that all content is copyright by
+ its respective authors unless otherwise stated.
+
+Files: debian/tests/test_modules/assume/*
+ debian/tests/test_modules/fn.name/*
+Copyright: 2015, Arnout Kazemier
+ 2015, Martijn Swaagman
+ 2015, other Contributors
+License: Expat
+
+Files: debian/tests/test_modules/pathval/*
+Copyright: 2011-2014, Jake Luer <jake@alogicalparadox.com>
+ 2017, Veselin Todorov <hi@vesln.com>
+License: Expat
+
 License: Expat
  Permission is hereby granted, free of charge, to any person
  obtaining a copy of this software and associated documentation files
@@ -32,3 +52,27 @@ License: Expat
  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  SOFTWARE.
 
+License: BSD-3-Clause
+ All rights reserved.
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ .
+ * Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+ * Neither the name of the University of California, Berkeley nor the
+   names of its contributors may be used to endorse or promote products
+   derived from this software without specific prior written permission.
+ .
+ THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/debian/patches/CVE-2018-3774.patch b/debian/patches/CVE-2018-3774.patch
new file mode 100644
index 0000000..627a765
--- /dev/null
+++ b/debian/patches/CVE-2018-3774.patch
@@ -0,0 +1,79 @@
+Description: Fix for CVE-2018-3774
+Author: Arnout Kazemier <https://github.com/3rd-Eden/>
+Origin: upstream, https://github.com/unshiftio/url-parse/commit/53b1794e
+Bug: https://security-tracker.debian.org/tracker/CVE-2018-3774
+Bug-Debian: https://bugs.debian.org/906058
+Forwarded: not-needed
+Reviewed-By: Xavier Guimard <yadd@debian.org>
+Last-Update: 2019-06-11
+
+--- a/index.js
++++ b/index.js
+@@ -20,6 +20,9 @@
+ var instructions = [
+   ['#', 'hash'],                        // Extract from the back.
+   ['?', 'query'],                       // Extract from the back.
++  function sanitize(address) {          // Sanitize what is left of the address
++    return address.replace('\\', '/');
++  },
+   ['//', 'protocol', 2, 1, 1],          // Extract from the front.
+   ['/', 'pathname'],                    // Extract from the back.
+   ['@', 'auth', 1],                     // Extract from the front.
+@@ -74,6 +77,10 @@
+ 
+   for (; i < instructions.length; i++) {
+     instruction = instructions[i];
++    if (typeof instruction === 'function') {
++      address = instruction(address);
++      continue;
++    }
+     parse = instruction[0];
+     key = instruction[1];
+ 
+--- a/test.js
++++ b/test.js
+@@ -152,6 +152,28 @@
+     assume(parsed.pathname).equals('/b/c');
+   });
+ 
++  it('ignores \\ in pathnames', function () {
++    var url = 'http://google.com:80\\@yahoo.com/#what\\is going on'
++      , parsed = parse(url);
++
++    assume(parsed.port).equals('');
++    assume(parsed.username).equals('');
++    assume(parsed.password).equals('');
++    assume(parsed.hostname).equals('google.com');
++    assume(parsed.hash).equals('#what\\is going on');
++
++    parsed = parse('//\\what-is-up.com');
++    assume(parsed.pathname).equals('/what-is-up.com');
++  });
++
++  it('correctly ignores multiple slashes //', function () {
++    var url = '////what-is-up.com'
++      , parsed = parse(url);
++
++    assume(parsed.host).equals('');
++    assume(parsed.hostname).equals('');
++  });
++
+   describe('ip', function () {
+     // coap://
+     //
+@@ -386,6 +408,15 @@
+ 
+       assume(data.href).equals('https://google.com/?foo=bar');
+     });
++
++    it('maintains the port number for non-default port numbers', function () {
++      var parsed = parse('http://google.com:8080/pathname');
++
++      assume(parsed.set('host', 'google.com:8080')).equals(parsed);
++
++      assume(parsed.host).equals('google.com:8080');
++      assume(parsed.href).equals('http://google.com:8080/pathname');
++    });
+   });
+ 
+   describe('fuzzy', function () {
diff --git a/debian/patches/series b/debian/patches/series
new file mode 100644
index 0000000..7d8c415
--- /dev/null
+++ b/debian/patches/series
@@ -0,0 +1 @@
+CVE-2018-3774.patch
diff --git a/debian/rules b/debian/rules
index de57af0..a533b7b 100755
--- a/debian/rules
+++ b/debian/rules
@@ -7,9 +7,7 @@
 %:
 	dh $@
 
-#override_dh_auto_build:
-
-#override_dh_auto_test:
-
+override_dh_auto_test:
+	NODE_PATH=debian/tests/test_modules mocha test.js
 
 
diff --git a/debian/source/lintian-overrides b/debian/source/lintian-overrides
new file mode 100644
index 0000000..080b22e
--- /dev/null
+++ b/debian/source/lintian-overrides
@@ -0,0 +1,4 @@
+# False positives
+source: insane-line-length-in-source-file debian/tests/test_modules/assume/dist/assume.js line length is 804 characters (>512)
+source: source-contains-prebuilt-javascript-object debian/tests/test_modules/assume/dist/assume.js line length is 804 characters (>512)
+source: source-is-missing debian/tests/test_modules/assume/dist/assume.js line length is 804 characters (>512)
diff --git a/debian/tests/test_modules/ansi-codes/index.js b/debian/tests/test_modules/ansi-codes/index.js
new file mode 100644
index 0000000..3dc3d87
--- /dev/null
+++ b/debian/tests/test_modules/ansi-codes/index.js
@@ -0,0 +1,33 @@
+module.exports     = {
+  reset            : "\033[0m",
+  bold             : "\033[1m",
+  italic           : "\033[3m",
+  blink            : "\033[5m",
+  underline        : "\033[4m",
+  underlineOff     : "\033[24m",
+  inverse          : "\033[7m",
+  inverseOff       : "\033[27m",
+  strikethrough    : "\033[9m",
+  strikethroughOff : "\033[29m",
+
+  def              : "\033[39m",
+  white            : "\033[37m",
+  black            : "\033[30m",
+  grey             : "\x1B[90m",
+  red              : "\033[31m",
+  green            : "\033[32m",
+  blue             : "\033[34m",
+  yellow           : "\033[33m",
+  magenta          : "\033[35m",
+  cyan             : "\033[36m",
+
+  defBg            : "\033[49m",
+  whiteBg          : "\033[47m",
+  blackBg          : "\033[40m",
+  redBg            : "\033[41m",
+  greenBg          : "\033[42m",
+  blueBg           : "\033[44m",
+  yellowBg         : "\033[43m",
+  magentaBg        : "\033[45m",
+  cyanBg           : "\033[46m"
+}
diff --git a/debian/tests/test_modules/ansi-codes/package.json b/debian/tests/test_modules/ansi-codes/package.json
new file mode 100644
index 0000000..84bad16
--- /dev/null
+++ b/debian/tests/test_modules/ansi-codes/package.json
@@ -0,0 +1,55 @@
+{
+  "_from": "ansi-codes@0.0.1",
+  "_id": "ansi-codes@0.0.1",
+  "_inBundle": false,
+  "_integrity": "sha1-H8A/tcLZtPF6bEGCzXX0Yx3MKjM=",
+  "_location": "/ansi-codes",
+  "_phantomChildren": {},
+  "_requested": {
+    "type": "version",
+    "registry": true,
+    "raw": "ansi-codes@0.0.1",
+    "name": "ansi-codes",
+    "escapedName": "ansi-codes",
+    "rawSpec": "0.0.1",
+    "saveSpec": null,
+    "fetchSpec": "0.0.1"
+  },
+  "_requiredBy": [
+    "#USER",
+    "/",
+    "/style-format"
+  ],
+  "_resolved": "https://registry.npmjs.org/ansi-codes/-/ansi-codes-0.0.1.tgz";,
+  "_shasum": "1fc03fb5c2d9b4f17a6c4182cd75f4631dcc2a33",
+  "_spec": "ansi-codes@0.0.1",
+  "_where": "/home/xavier/dev/debian/packages/node-url-parse",
+  "author": {
+    "name": "azer"
+  },
+  "bugs": {
+    "url": "https://github.com/azer/ansi-codes/issues";
+  },
+  "bundleDependencies": false,
+  "deprecated": false,
+  "description": "just an object that returns ANSI styling codes",
+  "devDependencies": {
+    "fox": "*"
+  },
+  "homepage": "https://github.com/azer/ansi-codes#readme";,
+  "keywords": [
+    "ansi",
+    "styling"
+  ],
+  "license": "BSD",
+  "main": "index.js",
+  "name": "ansi-codes",
+  "repository": {
+    "url": "git+ssh://git@github.com/azer/ansi-codes.git",
+    "type": "git"
+  },
+  "scripts": {
+    "test": "mocha"
+  },
+  "version": "0.0.1"
+}
diff --git a/debian/tests/test_modules/assume/dist/assume.js b/debian/tests/test_modules/assume/dist/assume.js
new file mode 100644
index 0000000..1c8e7ce
--- /dev/null
+++ b/debian/tests/test_modules/assume/dist/assume.js
@@ -0,0 +1,3804 @@
+!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.assume=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
+(function (Buffer){
+'use strict';
+
+var stringify = require('object-inspect')
+  , pretty = require('prettify-error')
+  , displayName = require('fn.name')
+  , pathval = require('pathval')
+  , nodejs = require('is-node')
+  , deep = require('deep-eql');
+
+var undefined
+  , called = 0
+  , toString = Object.prototype.toString
+  , hasOwn = Object.prototype.hasOwnProperty;
+
+/**
+ * Get class information for a given type.
+ *
+ * @param {Mixed} of Type to check.
+ * @returns {String} The name of the type.
+ * @api private
+ */
+function type(of) {
+  if (Buffer.isBuffer(of)) return 'buffer';
+  if (of === undefined) return 'undefined';
+  if (of === null) return 'null';
+  if (of !== of) return 'nan';
+
+  return toString.call(of).slice(8, -1).toLowerCase();
+}
+
+/**
+ * Determine the size of a collection.
+ *
+ * @param {Mixed} collection The object we want to know the size of.
+ * @returns {Number} The size of the collection.
+ * @api private
+ */
+function size(collection) {
+  var x, i = 0;
+
+  if ('object' === type(collection)) {
+    if ('number' === type(collection.length)) return collection.length;
+
+    for (x in collection) {
+      if (hasOwn.call(collection, x)) i++;
+    }
+
+    return i;
+  }
+
+  try { return +collection.length || 0; }
+  catch (e) { return 0; }
+}
+
+/**
+ * Iterate over each item in an array.
+ *
+ * @param {Array} arr Array to iterate over.
+ * @param {Function} fn Callback for each item.
+ * @api private
+ */
+function each(what, fn) {
+  if ('array' === type(what)) {
+    for (var i = 0, length = what.length; i < length; i++) {
+      if (false === fn(what[i], i, what)) break;
+    }
+  } else {
+    for (var key in what) {
+      if (false === fn(what[key], key, what)) break;
+    }
+  }
+}
+
+/**
+ * Return a formatter function which compiles the expectation message. The
+ * message can contain various of patterns which will be replaced with
+ * a stringified/parsed version of the supplied argument for that given
+ * placeholder pattern. The following patterns are supported:
+ *
+ * - %% : Escape the % so you can write %d in your messages as %%d
+ * - %d : Cast argument in to a number.
+ * - %s : Cast argument in to a string.
+ * - %f : Transform function in to the name of the function.
+ * - %j : Transform object to a string.
+ *
+ * @param {String} expectation The expectation message.
+ * @returns {Function}
+ * @api private
+ */
+function format() {
+  var args = Array.prototype.slice.call(arguments, 0)
+    , expectation = args.shift()
+    , length = args.length
+    , i = 0;
+
+  return function compile(not) {
+    if (not) expectation = expectation.replace(/@/g, 'not');
+    else expectation = expectation.replace(/@\s/g, '');
+
+    return expectation.replace(/%[sdjf%]/g, function replace(char) {
+      if (i >= length) return char;
+
+      switch (char) {
+        case '%%':
+        return '%';
+
+        case '%s':
+        return String(args[i++]);
+
+        case '%d':
+        return Number(args[i++]);
+
+        case '%f':
+        return displayName(args[i++]);
+
+        case '%j':
+        try { return stringify(args[i++]); }
+        catch (e) { return '<error was thrown: '+ e.message +'>'; }
+
+        default: return char;
+      }
+    });
+  };
+}
+
+/**
+ * Assert values.
+ *
+ * Flags:
+ *
+ * - **stacktrace**: Include stacktrace in the assertion.
+ * - **diff**: Attempt to show the difference in object/values so we know why
+ *   the assertion failed.
+ * - **sliceStack**: The amount of stacks we should slice off errors messages.
+ *
+ * @constructor
+ * @param {Mixed} value Value we need to assert.
+ * @param {Object} flags Assertion flags.
+ * @api public
+ */
+function Assert(value, flags) {
+  if (!(this instanceof Assert)) return new Assert(value, flags);
+  flags = flags || {};
+
+  this.stacktrace = 'stacktrace' in flags ? flags.stacktrace : Assert.config.includeStack;
+  this.sliceStack = 'slice' in flags ? flags.slice : Assert.config.sliceStack;
+  this.diff = 'diff' in flags ? flags.diff : Assert.config.showDiff;
+
+  //
+  // These flags are by the alias function so we can generate .not and .deep
+  // properties which are basically new Assert instances with these flags set.
+  //
+  for (var alias in Assert.flags) {
+    this[alias] = alias in flags ? flags[alias] : false;
+  }
+
+  this.value = value;
+
+  Assert.assign(this)('to, be, been, is, and, has, have, with, that, at, of, same, does, itself, which');
+  Assert.alias(value, this);
+}
+
+/**
+ * Attempt to mimic the configuration API of chai.js so it's dead simple to
+ * migrate from chai.js to assume.
+ *
+ * @type {Object}
+ * @public
+ */
+Assert.config = {
+  includeStack: true,     // mapped to `stacktrace` as default value.
+  showDiff: true,         // mapped to `diff` as default value.
+  sliceStack: 2           // Number of stacks that we should slice of the err stack..
+};
+
+/**
+ * List of flags and properties that need to be created for chaining purposes.
+ * Plugins could add extra properties that needed to be chained as well.
+ *
+ * @type {Object}
+ * @public
+ */
+Assert.flags = {
+  _not: 'doesnt, not, dont',
+  _deep: 'deep, deeply, strict, strictly'
+};
+
+/**
+ * Certain assertions can be disabled based on their environment that they are
+ * executing in. This object allows you in spect which of these conditional
+ * assertions are supported.
+ *
+ * @type {Object}
+ * @public
+ */
+Assert.supports = (function detect() {
+  var supports = {};
+
+  try {
+    eval('(function*(){})()');
+    supports.generators = true;
+  } catch (e) {
+    supports.generators = false;
+  }
+
+  try {
+    eval('%GetV8Version()');
+    supports.native = true;
+  } catch (e) {
+    supports.native = false;
+  }
+
+  return supports;
+}(/* Douglas Crockford wants the dog balls inside youtu.be/taaEzHI9xyY#t=2020s */));
+
+/**
+ * Assign values to a given thing.
+ *
+ * @param {Mixed} where Where do the new properties need to be assigned on.
+ * @returns {Function}
+ * @api public
+ */
+Assert.assign = function assign(where) {
+  return function assigns(aliases, value) {
+    if ('string' === typeof aliases) {
+      if (~aliases.indexOf(',')) aliases = aliases.split(/[\s|\,]+/);
+      else aliases = [aliases];
+    }
+
+    for (var i = 0, length = aliases.length; i < length; i++) {
+      where[aliases[i]] = value || where;
+    }
+
+    return where;
+  };
+};
+
+/**
+ * Add aliases to the given constructed asserts. This allows us to chain
+ * assertion calls together.
+ *
+ * @param {Mixed} value Value that we need to assert.
+ * @param {Assert} assert The constructed assert instance.
+ * @returns {Assert} The given assert instance.
+ * @api private
+ */
+Assert.alias = function alias(value, assert) {
+  var assign = Assert.assign(assert)
+    , flags, flag, prop;
+
+  for (prop in Assert.flags) {
+    if (!hasOwn.call(Assert.flags, prop)) continue;
+
+    if (!assert[prop]) {
+      flags = {};
+
+      for (flag in Assert.flags) {
+        if (!hasOwn.call(Assert.flags, flag)) continue;
+        flags[flag] = assert[flag];
+      }
+
+      //
+      // Add some default values to the flags.
+      //
+      flags.stacktrace = assert.stacktrace;
+      flags.diff = assert.diff;
+      flags[prop] = true;
+
+      assign(Assert.flags[prop], new Assert(value, flags));
+    } else assign(Assert.flags);
+  }
+
+  return assert;
+};
+
+/**
+ * API sugar of adding aliased prototypes to the Assert. This makes the code
+ * a bit more workable and human readable.
+ *
+ * @param {String|Array} aliases List of methods.
+ * @param {Function} fn Actual assertion function.
+ * @returns {Assert}
+ * @api public
+ */
+Assert.add = Assert.assign(Assert.prototype);
+
+/**
+ * Asserts if the given value is the correct type. We need to use
+ * Object.toString here because there are some implementation bugs the `typeof`
+ * operator:
+ *
+ * - Chrome <= 9: /Regular Expressions/ are evaluated to `function`
+ *
+ * As well as all common flaws like Arrays being seen as Objects etc. This
+ * eliminates all these edge cases.
+ *
+ * @param {String} of Type of class it should equal
+ * @param {String} msg Reason of failure.
+ * @returns {Assert}
+ * @api public
+ */
+Assert.add('a, an', function typecheck(of, msg) {
+  of = of.toString().toLowerCase();
+
+  var value = type(this.value)
+    , expect = format('`%j` (%s) to @ be a %s', this.value, value, of);
+
+  return this.test(value === of, msg, expect);
+});
+
+/**
+ * Asserts that the value is instanceof the given constructor.
+ *
+ * @param {Function} constructor Constructur the value should inherit from.
+ * @param {String} msg Reason of failure.
+ * @returns {Assert}
+ * @api public
+ */
+Assert.add('instanceOf, instanceof, inherits, inherit', function of(constructor, msg) {
+  var expect = format('%f to @ be an instanceof %f', this.value, constructor);
+
+  return this.test(this.value instanceof constructor, msg, expect);
+});
+
+/**
+ * Assert that the value includes the given value.
+ *
+ * @param {Mixed} val Value to match.
+ * @param {String} msg Reason of failure.
+ * @returns {Assert}
+ * @api public
+ */
+Assert.add('include, includes, contain, contains', function contain(val, msg) {
+  var includes = false
+    , of = type(this.value)
+    , expect = format('`%j` to @ include %j', this.value, val);
+
+  switch (of) {
+    case 'array':
+      for (var i = 0, length = this.value.length; i < length; i++) {
+        if (val === this.value[i]) {
+          includes = true;
+          break;
+        }
+      }
+    break;
+
+    case 'object':
+      if (val in this.value) {
+        includes = true;
+      }
+    break;
+
+    case 'string':
+      if (~this.value.indexOf(val)) {
+        includes = true;
+      }
+    break;
+  }
+
+  return this.test(includes === true, msg, expect);
+});
+
+/**
+ * Assert that the value is truthy.
+ *
+ * @param {String} msg Reason of failure.
+ * @returns {Assert}
+ * @api public
+ */
+Assert.add('ok, okay, truthy, truly', function ok(msg) {
+  var expect = format('`%j` to @ be truthy', this.value);
+
+  return this.test(Boolean(this.value), msg, expect);
+});
+
+/**
+ * Assert that the value is falsey.
+ *
+ * @param {String} msg Reason of failure.
+ * @returns {Assert}
+ * @api public
+ */
+Assert.add('falsely, falsey, falsy', function nope(msg) {
+  var expect = format('`%j` to @ be falsely', this.value);
+
+  return this.test(Boolean(this.value) === false, msg, expect);
+});
+
+/**
+ * Assert that the value is `true`.
+ *
+ * @param {String} msg Reason of failure.
+ * @returns {Assert}
+ * @api public
+ */
+Assert.add('true', function ok(msg) {
+  var expect = format('`%j` to @ equal (===) true', this.value);
+
+  return this.test(this.value === true, msg, expect);
+});
+
+/**
+ * Assert that the value is `true`.
+ *
+ * @param {String} msg Reason of failure.
+ * @returns {Assert}
+ * @api public
+ */
+Assert.add('false', function nope(msg) {
+  var expect = format('`%j` to @ equal (===) false', this.value);
+
+  return this.test(this.value === false, msg, expect);
+});
+
+/**
+ * Assert that the value exists.
+ *
+ * @param {String} msg Reason of failure.
+ * @returns {Assert}
+ * @api public
+ */
+Assert.add('exists, exist', function exists(msg) {
+  var expect = format('`%j` to @ exist', this.value);
+
+  return this.test(this.value != null, msg, expect);
+});
+
+/**
+ * Asserts that the value's length is the given value.
+ *
+ * @param {Number} value Size of the value.
+ * @param {String} msg Reason of failure.
+ * @returns {Assert}
+ * @api public
+ */
+Assert.add('length, lengthOf, size', function length(value, msg) {
+  var expect = format('`%j` to @ have a length of %d', this.value, value);
+
+  return this.test(size(this.value) === +value, msg, expect);
+});
+
+/**
+ * Asserts that the value's length is 0 or doesn't contain any enumerable keys.
+ *
+ * @param {String} msg Reason of failure.
+ * @returns {Assert}
+ * @api public
+ */
+Assert.add('empty', function empty(msg) {
+  var expect = format('`%j` to @ be empty', this.value);
+
+  return this.test(size(this.value) === 0, msg, expect);
+});
+
+/**
+ * Assert that the value is greater than the specified value.
+ *
+ * @param {Number} value The greater than value.
+ * @param {String} msg Reason of failure.
+ * @returns {Assert}
+ * @api public
+ */
+Assert.add('above, gt, greater, greaterThan', function above(value, msg) {
+  var amount = type(this.value) !== 'number' ? size(this.value) : this.value
+    , expect = format('%d to @ be greater than %d', amount, value);
+
+  return this.test(amount > value, msg, expect);
+});
+
+/**
+ * Assert that the value is equal or greater than the specified value.
+ *
+ * @param {Number} value The specified value.
+ * @param {String} msg Reason of failure.
+ * @returns {Assert}
+ * @api public
+ */
+Assert.add('least, gte, atleast', function least(value, msg) {
+  var amount = type(this.value) !== 'number' ? size(this.value) : this.value
+    , expect = format('%d to @ be greater or equal to %d', amount, value);
+
+  return this.test(amount >= value, msg, expect);
+});
+
+/**
+ * Assert that the value starts with the given value.
+ *
+ * @param {String|Array} value String it should start with.
+ * @param {String} msg Reason of failure.
+ * @returns {Assert}
+ * @api public
+ */
+Assert.add('start, starts, startsWith, startWith', function start(value, msg) {
+  var expect = format('`%j` to @ start with %j', this.value, value);
+
+  return this.test(0 === this.value.indexOf(value), msg, expect);
+});
+
+/**
+ * Assert that the value ends with the given value.
+ *
+ * @param {String} value String it should start with.
+ * @param {String} msg Reason of failure.
+ * @returns {Assert}
+ * @api public
+ */
+Assert.add('end, ends, endsWith, endWith', function end(value, msg) {
+  var index = this.value.indexOf(value, this.value.length - value.length)
+    , expect = format('`%j` to @ end with %j', this.value, value);
+
+  return this.test(index >= 0, msg, expect);
+});
+
+/**
+ * Assert a floating point number is near the give value within the delta
+ * margin.
+ *
+ * @param {Number} value The specified value.
+ * @param {Number} delta Radius.
+ * @param {String} msg Reason of failure.
+ * @returns {Assert}
+ * @api public
+ */
+Assert.add('closeTo, close, approximately, near', function close(value, delta, msg) {
+  var expect = format('`%j` to @ be close to %d ± %d', this.value, value, delta);
+
+  return this.test(Math.abs(this.value - value) <= delta, msg, expect);
+});
+
+/**
+ * Assert that the value is below the specified value.
+ *
+ * @param {Number} value The specified value.
+ * @param {String} msg Reason of failure.
+ * @returns {Assert}
+ * @api public
+ */
+Assert.add('below, lt, less, lessThan', function below(value, msg) {
+  var amount = type(this.value) !== 'number' ? size(this.value) : this.value
+    , expect = format('%d to @ be less than %d', amount, value);
+
+  return this.test(amount < value, msg, expect);
+});
+
+/**
+ * Assert that the value is below or equal to the specified value.
+ *
+ * @param {Number} value The specified value.
+ * @param {String} msg Reason of failure.
+ * @returns {Assert}
+ * @api public
+ */
+Assert.add('most, lte, atmost', function most(value, msg) {
+  var amount = type(this.value) !== 'number' ? size(this.value) : this.value
+    , expect = format('%d to @ be less or equal to %d', amount, value);
+
+  return this.test(amount <= value, msg, expect);
+});
+
+/**
+ * Assert that that value is within the given range.
+ *
+ * @param {Number} start Lower bound.
+ * @param {Number} finish Upper bound.
+ * @param {String} msg Reason of failure.
+ * @returns {Assert}
+ * @api public
+ */
+Assert.add('within, between', function within(start, finish, msg) {
+  var amount = type(this.value) !== 'number' ? size(this.value) : this.value
+    , expect = format('%d to @ be greater or equal to %d and @ be less or equal to %d', amount, start, finish);
+
+  return this.test(amount >= start && amount <= finish, msg, expect);
+});
+
+/**
+ * Assert that the value has an own property with the given prop.
+ *
+ * @param {String} prop Property name.
+ * @param {String} msg Reason of failure.
+ * @returns {Assert}
+ * @api public
+ */
+Assert.add('hasOwn, own, ownProperty, haveOwnProperty, property, owns, hasown', function has(prop, value, msg) {
+  var expect = format('`%j` @ to have own property %s', this.value, prop)
+    , tested = this.test(hasOwn.call(this.value, prop), msg, expect);
+
+  return arguments.length > 1
+    ? this.clone(this.value[prop]).equals(value)
+    : tested;
+});
+
+/**
+ * Asserts that the value matches a regular expression.
+ *
+ * @param {RegExp} regex Regular expression to match against.
+ * @param {String} msg Reason of failure.
+ * @returns {Assert}
+ * @api public
+ */
+Assert.add('match, matches', function test(regex, msg) {
+  if ('string' === typeof regex) regex = new RegExp(regex);
+
+  var expect = format('`%j` to @ match %j', this.value, regex);
+
+  return this.test(!!regex.test(this.value), msg, expect);
+});
+
+/**
+ * Assert that the value equals a given thing.
+ *
+ * @param {Mixed} thing Thing it should equal.
+ * @param {String} msg Reason of failure.
+ * @returns {Assert}
+ * @api public
+ */
+Assert.add('equal, equals, eq, eqs, exactly', function equal(thing, msg) {
+  var expect = format('`%j` to @ equal (===) `%j`', this.value, thing);
+
+  if (!this._deep) return this.test(this.value === thing, msg, expect);
+
+  this.sliceStack++;
+  return this.eql(thing, msg);
+});
+
+/**
+ * Assert that the value **deeply** equals a given thing.
+ *
+ * @param {Mixed} thing Thing it should equal.
+ * @param {String} msg Reason of failure.
+ * @returns {Assert}
+ * @api public
+ */
+Assert.add('eql, eqls', function eqls(thing, msg) {
+  var expect = format('`%j` to deeply equal `%j`', this.value, thing);
+
+  return this.test(deep(this.value, thing), msg, expect);
+});
+
+/**
+ * Assert that the value is either one of the given values.
+ *
+ * @param {Array} arrgs All the values it can match.
+ * @param {String} msg Reason of failure.
+ * @returns {Assert}
+ * @api public
+ */
+Assert.add('either', function either(args, msg) {
+  var expect = '`%j` to equal either `%j` '
+    , i = args.length
+    , result = false
+    , values = [];
+
+  while (i-- || result) {
+    if (!this._deep) result = this.value === args[i];
+    else result = deep(this.value, args[i]);
+    if (result) break;
+
+    values.push(args[i]);
+  }
+
+  expect = format.apply(null, [expect + (new Array(values)).join('or `%j` ')].concat(values));
+  return this.test(result, msg, expect);
+});
+
+/**
+ * Assert if the given function throws.
+ *
+ * @param {Mixed} thing Thing it should equal.
+ * @param {String} msg Reason of failure.
+ * @returns {Assert}
+ * @api public
+ */
+Assert.add('throw, throws, fails, fail', function throws(thing, msg) {
+  try { this.value(); }
+  catch (e) {
+    var message = 'object' === typeof e ? e.message : e;
+
+    switch (type(thing)) {
+      case 'string': return this.clone(message).includes(thing, msg);
+      case 'regexp': return this.clone(message).matches(thing, msg);
+      case 'function': return this.clone(e).instanceOf(thing, msg);
+      case 'undefined': return this.test(true, msg, format('%f to @ throw', this.value));
+      default: return this.clone(e).equals(thing);
+    }
+  }
+
+  return this.test(false, msg, format('%f to @ throw', this.value));
+});
+
+/**
+ * Assert if the given value is finite.
+ *
+ * @param {String} msg Reason of failure.
+ * @returns {Assert}
+ * @api public
+ */
+Assert.add('isFinite, finite, finiteness', function finite(msg) {
+  var expect = format('`%j`s @ a is a finite number', this.value)
+    , result;
+
+  if (this._deep) {
+    result = Number.isFinite
+    ? Number.isFinite(this.value)
+    : 'number' === type(this.value) && isFinite(this.value);
+  } else {
+    result = isFinite(this.value);
+  }
+
+  return this.test(result, msg, expect);
+});
+
+/**
+ * Assert if the given function is an ES6 generator.
+ *
+ * @param {String} msg Reason of failure.
+ * @returns {Assert}
+ * @api public
+ */
+Assert.add('generator', function generators(msg) {
+  var expect = format('%f to @ be a generator', this.value)
+    , result;
+
+  //
+  // Non standard function from Mozilla allows us to check if a function is
+  // a generator.
+  //
+  // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/isGenerator
+  //
+  if ('function' === typeof this.value.isGenerator) {
+    result = this.value.isGenerator();
+  } else if ('generatorfunction' === type(this.value)) {
+    result = true;
+  } else {
+    result = 'function' === type(this.value) && this.value.toString().indexOf('function*') === 0;
+  }
+
+  return this.test(result, msg, expect);
+});
+
+//
+// The following assertions require's v8's allow-natives-syntax flag to be
+// enabled as this allows us to hook in to the more internal parts of the
+// engine. The native syntax is wrapped in a try catch with a new Function
+// construction so the rest of the code will execute when JavaScript engines do
+// not understand the instructions.
+//
+(function v8() {
+  var states = 'void,yes,no,always,never,void,maybe'.split(',')
+    , detect;
+
+  if (!Assert.supports.native) detect = function optimized() { return 0; };
+  else detect = new Function('fn', 'args', 'selfie', [
+    'fn.apply(selfie, args);',
+    '%OptimizeFunctionOnNextCall(fn);',
+    'fn.apply(selfie, args);',
+    'return %GetOptimizationStatus(fn);'
+  ].join('\n'));
+
+  /**
+   * Assert that a given function has reached a certain optimization level.
+   *
+   * @param {String} level Optimization level
+   * @param {Array} args Arguments for the function
+   * @param {Mixed} selfie This context for the function
+   * @param {String} msg Reason of failure
+   * @returns {Assert}
+   * @api public
+   */
+  Assert.add('optimisation, optimization', function optimization(level, args, selfie, msg) {
+    var expect = format('%f to be optimized as %s', this.value, level)
+      , status = states[detect(this.value, args, selfie)];
+
+    return this.test(status === level, msg, expect);
+  });
+
+  /**
+   * Assert that the function is optimized.
+   *
+   * @param {String} msg Reason of failure
+   * @returns {Assert}
+   * @api public
+   */
+  Assert.add('optimized, optimised', function optimized(msg) {
+    var expect = format('%f to be optimized', this.value)
+      , status = states[detect(this.value, [])];
+
+    return this.test(status === 'yes', msg, expect);
+  });
+}());
+
+/**
+ * Create a clone of the current assertion instance which has the same
+ * configuration but a different value.
+ *
+ * @param {Mixed} value The new value
+ * @returns {Assert}
+ * @api public
+ */
+Assert.add('clone', function clone(value) {
+  var configuration = {
+    stacktrace: this.stacktrace,
+    slice: this.sliceStack + 1,
+    diff: this.diff
+  };
+
+  for (var alias in Assert.flags) {
+    if (!hasOwn.call(Assert.flags, alias)) continue;
+    configuration[alias] = this[alias];
+  }
+
+  return new Assert(arguments.length ? value : this.value, configuration);
+});
+
+/**
+ * Validate the assertion.
+ *
+ * @param {Boolean} passed Didn't the test pass or fail.
+ * @param {String} msg Custom message provided by users.
+ * @param {String} expectation What the assertion expected.
+ * @param {Number} slice The amount of stack traces we need to remove.
+ * @returns {Assert}
+ * @api public
+ */
+Assert.add('test', function test(passed, msg, expectation, slice) {
+  called++; // Needed for tracking the amount of executed assertions.
+
+  if (this._not) passed = !passed;
+  if (passed) return this;
+
+  msg = msg || 'Unknown assertation failure occured';
+  slice = slice || this.sliceStack;
+
+  if (expectation) msg += ', assumed ' + expectation(this._not);
+
+  var failure = new Error(msg)
+    , err = { message: failure.message, stack: '' };
+
+  if (this.stacktrace) {
+    err.stack = failure.stack || err.stack;
+  }
+
+  //
+  // Clean up the stack by slicing off the parts that are pointless to most
+  // people. (Like where it enters this assertion library).
+  //
+  err.stack = err.stack.split('\n').slice(slice).join('\n') || err.stack;
+  err.stack = pretty(err);
+
+  if ('function' !== typeof Object.create) {
+    if ('object' === typeof console && 'function' === typeof console.error) {
+      console.error(err.stack);
+    }
+
+    throw failure;
+  }
+
+  failure = Object.create(Error.prototype);
+  failure.message = err.message;
+  failure.stack = err.stack;
+
+  throw failure;
+});
+
+/**
+ * Plan for the amount of assertions that needed to run. This is great way to
+ * figure out if you have edge cases in your code which prevented an assertion or
+ * callback from running.
+ *
+ * ```js
+ * it('run a lot of assertions', function (next) {
+ *   next = assume.plan(10, next);
+ * });
+ * ```
+ *
+ * @param {Number} tests The amount of assertions you expect to run.
+ * @param {Function} fn Optional completion callback which receives the error.
+ * @returns {Function} Completion callback.
+ * @api public
+ */
+Assert.plan = function plan(tests, fn) {
+  fn = fn || function next(err) {
+    if (err) throw err;
+  };
+
+  var atm = called;
+
+  return function validate(err) {
+    var ran = called - atm
+      , msg;
+
+    if (err) return fn(err);
+    if (tests === ran) return fn();
+
+    msg = [
+      'We ran',
+      ran - tests,
+      ran > tests ? 'more' : 'less',
+      'assertations than the expected',
+      tests
+    ];
+
+    fn(new Error(msg.join(' ')));
+  };
+};
+
+/**
+ * Wait until the returned callback is called x times before advancing. This
+ * makes it a bit easier to write async tests that require multiple callbacks.
+ *
+ * ```js
+ * it('does async things', function (next) {
+ *   next = assume.wait(2, 4, next);
+ *
+ *   asynctask(function (err, data) {
+ *     assume(err).is.a('undefined');
+ *     assume(data).equals('testing');
+ *
+ *     next();
+ *   });
+ *
+ *   asynctaskfail(function (err, data) {
+ *     assume(err).is.a('undefined');
+ *     assume(data).equals('testing');
+ *
+ *     next();
+ *   });
+ * });
+ * ```
+ *
+ * @param {Number} calls The amount of calls the returned callback should called.
+ * @param {Number} tests The amount of tests that should be completed before cb.
+ * @param {Function} fn Completion callback.
+ * @returns {Function} New function that does the counting.
+ * @api public
+ */
+Assert.wait = function wait(calls, tests, fn) {
+  //
+  // Make the `tests` argument optional by allowing callback to be used there.
+  //
+  if ('function' === typeof tests) {
+    fn = tests;
+    tests = 0;
+  }
+
+  //
+  // If `tests` are specified, pass it directly in to the Assert.plan function
+  // so we can use that as given callback.
+  //
+  if (tests) fn = Assert.plan(tests, fn);
+
+  var ignore = false;
+
+  return function counter(err) {
+    if (ignore) return;
+    if (err || !--calls) return ignore = true, fn(err);
+  };
+};
+
+/**
+ * Load/execute a new plugin.
+ *
+ * @param {Function} plugin Plugin to be executed.
+ * @returns {Function} Assert, for chaining purposes.
+ * @api public
+ */
+Assert.use = function use(plugin) {
+  plugin(this, {
+    name: displayName,    // Extract the name of a function.
+    string: stringify,    // Transform thing to a string.
+    get: pathval.get,     // Get a value from an object.
+    format: format,       // Format an expectation message.
+    nodejs: nodejs,       // Are we running on Node.js.
+    deep: deep,           // Deep assertion.
+    type: type,           // Get class information.
+    size: size,           // Get the size of an object.
+    each: each            // Iterate over arrays.
+  });
+
+  return Assert;
+};
+
+//
+// Create type checks for all build-in JavaScript classes.
+//
+each(('new String§new Number§new Array§new Date§new Error§new RegExp§new Boolean§'
+  + 'new Float32Array§new Float64Array§new Int16Array§new Int32Array§new Int8Array§'
+  + 'new Uint16Array§new Uint32Array§new Uint8Array§new Uint8ClampedArray§'
+  + 'new ParallelArray§new Map§new Set§new WeakMap§new WeakSet§new TypedArray(1)§'
+  + 'new DataView(new ArrayBuffer(1))§new ArrayBuffer(1)§new Promise(function(){})§'
+  + 'new Blob§arguments§null§undefined§new Buffer(1)§NaN§navigator§location§'
+  + 'new Function§new Proxy({}, function(){})§Symbol("assume")§Math'
+).split('§'), function iterate(code) {
+  var name, arg;
+
+  //
+  // Not all of these constructors are supported in the browser, we're going to
+  // compile dedicated functions that returns a new instance of the given
+  // constructor. If it's not supported the code will throw and we will simply
+  // return.
+  //
+  try { arg = (new Function('return '+ code))(); }
+  catch (e) { return; }
+
+  name = type(arg);
+
+  Assert.add(name, function typecheck(msg) {
+    var expect = format('`%j` to @ be an %s', this.value, name)
+      , of = type(this.value);
+
+    return this.test(of === name, msg, expect, 3);
+  });
+});
+
+//
+// Introduce an alternate API:
+//
+// ```js
+// var i = require('assume');
+//
+// i.assume.that('foo').equals('bar');
+// i.sincerely.hope.that('foo').equals('bar');
+// i.expect.that('foo').equals('bar');
+// ```
+//
+Assert.hope = { that: Assert };
+Assert.assign(Assert)('sincerely, expect');
+Assert.assign(Assert)('assume, expect', Assert.hope);
+
+//
+// Expose the module.
+//
+module.exports = Assert;
+
+}).call(this,require("buffer").Buffer)
+},{"buffer":2,"deep-eql":7,"fn.name":11,"is-node":12,"object-inspect":13,"pathval":14,"prettify-error":15}],2:[function(require,module,exports){
+/*!
+ * The buffer module from node.js, for the browser.
+ *
+ * @author   Feross Aboukhadijeh <feross@feross.org> <http://feross.org>
+ * @license  MIT
+ */
+
+var base64 = require('base64-js')
+var ieee754 = require('ieee754')
+var isArray = require('is-array')
+
+exports.Buffer = Buffer
+exports.SlowBuffer = SlowBuffer
+exports.INSPECT_MAX_BYTES = 50
+Buffer.poolSize = 8192 // not used by this implementation
+
+var kMaxLength = 0x3fffffff
+var rootParent = {}
+
+/**
+ * If `Buffer.TYPED_ARRAY_SUPPORT`:
+ *   === true    Use Uint8Array implementation (fastest)
+ *   === false   Use Object implementation (most compatible, even IE6)
+ *
+ * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,
+ * Opera 11.6+, iOS 4.2+.
+ *
+ * Note:
+ *
+ * - Implementation must support adding new properties to `Uint8Array` instances.
+ *   Firefox 4-29 lacked support, fixed in Firefox 30+.
+ *   See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438.
+ *
+ *  - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function.
+ *
+ *  - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of
+ *    incorrect length in some situations.
+ *
+ * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they will
+ * get the Object implementation, which is slower but will work correctly.
+ */
+Buffer.TYPED_ARRAY_SUPPORT = (function () {
+  try {
+    var buf = new ArrayBuffer(0)
+    var arr = new Uint8Array(buf)
+    arr.foo = function () { return 42 }
+    return 42 === arr.foo() && // typed array instances can be augmented
+        typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray`
+        new Uint8Array(1).subarray(1, 1).byteLength === 0 // ie10 has broken `subarray`
+  } catch (e) {
+    return false
+  }
+})()
+
+/**
+ * Class: Buffer
+ * =============
+ *
+ * The Buffer constructor returns instances of `Uint8Array` that are augmented
+ * with function properties for all the node `Buffer` API functions. We use
+ * `Uint8Array` so that square bracket notation works as expected -- it returns
+ * a single octet.
+ *
+ * By augmenting the instances, we can avoid modifying the `Uint8Array`
+ * prototype.
+ */
+function Buffer (subject, encoding, noZero) {
+  if (!(this instanceof Buffer))
+    return new Buffer(subject, encoding, noZero)
+
+  var type = typeof subject
+
+  // Find the length
+  var length
+  if (type === 'number')
+    length = subject > 0 ? subject >>> 0 : 0
+  else if (type === 'string') {
+    length = Buffer.byteLength(subject, encoding)
+  } else if (type === 'object' && subject !== null) { // assume object is array-like
+    if (subject.type === 'Buffer' && isArray(subject.data))
+      subject = subject.data
+    length = +subject.length > 0 ? Math.floor(+subject.length) : 0
+  } else
+    throw new TypeError('must start with number, buffer, array or string')
+
+  if (length > kMaxLength)
+    throw new RangeError('Attempt to allocate Buffer larger than maximum ' +
+      'size: 0x' + kMaxLength.toString(16) + ' bytes')
+
+  var buf
+  if (Buffer.TYPED_ARRAY_SUPPORT) {
+    // Preferred: Return an augmented `Uint8Array` instance for best performance
+    buf = Buffer._augment(new Uint8Array(length))
+  } else {
+    // Fallback: Return THIS instance of Buffer (created by `new`)
+    buf = this
+    buf.length = length
+    buf._isBuffer = true
+  }
+
+  var i
+  if (Buffer.TYPED_ARRAY_SUPPORT && typeof subject.byteLength === 'number') {
+    // Speed optimization -- use set if we're copying from a typed array
+    buf._set(subject)
+  } else if (isArrayish(subject)) {
+    // Treat array-ish objects as a byte array
+    if (Buffer.isBuffer(subject)) {
+      for (i = 0; i < length; i++)
+        buf[i] = subject.readUInt8(i)
+    } else {
+      for (i = 0; i < length; i++)
+        buf[i] = ((subject[i] % 256) + 256) % 256
+    }
+  } else if (type === 'string') {
+    buf.write(subject, 0, encoding)
+  } else if (type === 'number' && !Buffer.TYPED_ARRAY_SUPPORT && !noZero) {
+    for (i = 0; i < length; i++) {
+      buf[i] = 0
+    }
+  }
+
+  if (length > 0 && length <= Buffer.poolSize)
+    buf.parent = rootParent
+
+  return buf
+}
+
+function SlowBuffer(subject, encoding, noZero) {
+  if (!(this instanceof SlowBuffer))
+    return new SlowBuffer(subject, encoding, noZero)
+
+  var buf = new Buffer(subject, encoding, noZero)
+  delete buf.parent
+  return buf
+}
+
+Buffer.isBuffer = function (b) {
+  return !!(b != null && b._isBuffer)
+}
+
+Buffer.compare = function (a, b) {
+  if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b))
+    throw new TypeError('Arguments must be Buffers')
+
+  var x = a.length
+  var y = b.length
+  for (var i = 0, len = Math.min(x, y); i < len && a[i] === b[i]; i++) {}
+  if (i !== len) {
+    x = a[i]
+    y = b[i]
+  }
+  if (x < y) return -1
+  if (y < x) return 1
+  return 0
+}
+
+Buffer.isEncoding = function (encoding) {
+  switch (String(encoding).toLowerCase()) {
+    case 'hex':
+    case 'utf8':
+    case 'utf-8':
+    case 'ascii':
+    case 'binary':
+    case 'base64':
+    case 'raw':
+    case 'ucs2':
+    case 'ucs-2':
+    case 'utf16le':
+    case 'utf-16le':
+      return true
+    default:
+      return false
+  }
+}
+
+Buffer.concat = function (list, totalLength) {
+  if (!isArray(list)) throw new TypeError('Usage: Buffer.concat(list[, length])')
+
+  if (list.length === 0) {
+    return new Buffer(0)
+  } else if (list.length === 1) {
+    return list[0]
+  }
+
+  var i
+  if (totalLength === undefined) {
+    totalLength = 0
+    for (i = 0; i < list.length; i++) {
+      totalLength += list[i].length
+    }
+  }
+
+  var buf = new Buffer(totalLength)
+  var pos = 0
+  for (i = 0; i < list.length; i++) {
+    var item = list[i]
+    item.copy(buf, pos)
+    pos += item.length
+  }
+  return buf
+}
+
+Buffer.byteLength = function (str, encoding) {
+  var ret
+  str = str + ''
+  switch (encoding || 'utf8') {
+    case 'ascii':
+    case 'binary':
+    case 'raw':
+      ret = str.length
+      break
+    case 'ucs2':
+    case 'ucs-2':
+    case 'utf16le':
+    case 'utf-16le':
+      ret = str.length * 2
+      break
+    case 'hex':
+      ret = str.length >>> 1
+      break
+    case 'utf8':
+    case 'utf-8':
+      ret = utf8ToBytes(str).length
+      break
+    case 'base64':
+      ret = base64ToBytes(str).length
+      break
+    default:
+      ret = str.length
+  }
+  return ret
+}
+
+// pre-set for values that may exist in the future
+Buffer.prototype.length = undefined
+Buffer.prototype.parent = undefined
+
+// toString(encoding, start=0, end=buffer.length)
+Buffer.prototype.toString = function (encoding, start, end) {
+  var loweredCase = false
+
+  start = start >>> 0
+  end = end === undefined || end === Infinity ? this.length : end >>> 0
+
+  if (!encoding) encoding = 'utf8'
+  if (start < 0) start = 0
+  if (end > this.length) end = this.length
+  if (end <= start) return ''
+
+  while (true) {
+    switch (encoding) {
+      case 'hex':
+        return hexSlice(this, start, end)
+
+      case 'utf8':
+      case 'utf-8':
+        return utf8Slice(this, start, end)
+
+      case 'ascii':
+        return asciiSlice(this, start, end)
+
+      case 'binary':
+        return binarySlice(this, start, end)
+
+      case 'base64':
+        return base64Slice(this, start, end)
+
+      case 'ucs2':
+      case 'ucs-2':
+      case 'utf16le':
+      case 'utf-16le':
+        return utf16leSlice(this, start, end)
+
+      default:
+        if (loweredCase)
+          throw new TypeError('Unknown encoding: ' + encoding)
+        encoding = (encoding + '').toLowerCase()
+        loweredCase = true
+    }
+  }
+}
+
+Buffer.prototype.equals = function (b) {
+  if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')
+  return Buffer.compare(this, b) === 0
+}
+
+Buffer.prototype.inspect = function () {
+  var str = ''
+  var max = exports.INSPECT_MAX_BYTES
+  if (this.length > 0) {
+    str = this.toString('hex', 0, max).match(/.{2}/g).join(' ')
+    if (this.length > max)
+      str += ' ... '
+  }
+  return '<Buffer ' + str + '>'
+}
+
+Buffer.prototype.compare = function (b) {
+  if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')
+  return Buffer.compare(this, b)
+}
+
+// `get` will be removed in Node 0.13+
+Buffer.prototype.get = function (offset) {
+  console.log('.get() is deprecated. Access using array indexes instead.')
+  return this.readUInt8(offset)
+}
+
+// `set` will be removed in Node 0.13+
+Buffer.prototype.set = function (v, offset) {
+  console.log('.set() is deprecated. Access using array indexes instead.')
+  return this.writeUInt8(v, offset)
+}
+
+function hexWrite (buf, string, offset, length) {
+  offset = Number(offset) || 0
+  var remaining = buf.length - offset
+  if (!length) {
+    length = remaining
+  } else {
+    length = Number(length)
+    if (length > remaining) {
+      length = remaining
+    }
+  }
+
+  // must be an even number of digits
+  var strLen = string.length
+  if (strLen % 2 !== 0) throw new Error('Invalid hex string')
+
+  if (length > strLen / 2) {
+    length = strLen / 2
+  }
+  for (var i = 0; i < length; i++) {
+    var byte = parseInt(string.substr(i * 2, 2), 16)
+    if (isNaN(byte)) throw new Error('Invalid hex string')
+    buf[offset + i] = byte
+  }
+  return i
+}
+
+function utf8Write (buf, string, offset, length) {
+  var charsWritten = blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length)
+  return charsWritten
+}
+
+function asciiWrite (buf, string, offset, length) {
+  var charsWritten = blitBuffer(asciiToBytes(string), buf, offset, length)
+  return charsWritten
+}
+
+function binaryWrite (buf, string, offset, length) {
+  return asciiWrite(buf, string, offset, length)
+}
+
+function base64Write (buf, string, offset, length) {
+  var charsWritten = blitBuffer(base64ToBytes(string), buf, offset, length)
+  return charsWritten
+}
+
+function utf16leWrite (buf, string, offset, length) {
+  var charsWritten = blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length, 2)
+  return charsWritten
+}
+
+Buffer.prototype.write = function (string, offset, length, encoding) {
+  // Support both (string, offset, length, encoding)
+  // and the legacy (string, encoding, offset, length)
+  if (isFinite(offset)) {
+    if (!isFinite(length)) {
+      encoding = length
+      length = undefined
+    }
+  } else {  // legacy
+    var swap = encoding
+    encoding = offset
+    offset = length
+    length = swap
+  }
+
+  offset = Number(offset) || 0
+
+  if (length < 0 || offset < 0 || offset > this.length)
+    throw new RangeError('attempt to write outside buffer bounds');
+
+  var remaining = this.length - offset
+  if (!length) {
+    length = remaining
+  } else {
+    length = Number(length)
+    if (length > remaining) {
+      length = remaining
+    }
+  }
+  encoding = String(encoding || 'utf8').toLowerCase()
+
+  var ret
+  switch (encoding) {
+    case 'hex':
+      ret = hexWrite(this, string, offset, length)
+      break
+    case 'utf8':
+    case 'utf-8':
+      ret = utf8Write(this, string, offset, length)
+      break
+    case 'ascii':
+      ret = asciiWrite(this, string, offset, length)
+      break
+    case 'binary':
+      ret = binaryWrite(this, string, offset, length)
+      break
+    case 'base64':
+      ret = base64Write(this, string, offset, length)
+      break
+    case 'ucs2':
+    case 'ucs-2':
+    case 'utf16le':
+    case 'utf-16le':
+      ret = utf16leWrite(this, string, offset, length)
+      break
+    default:
+      throw new TypeError('Unknown encoding: ' + encoding)
+  }
+  return ret
+}
+
+Buffer.prototype.toJSON = function () {
+  return {
+    type: 'Buffer',
+    data: Array.prototype.slice.call(this._arr || this, 0)
+  }
+}
+
+function base64Slice (buf, start, end) {
+  if (start === 0 && end === buf.length) {
+    return base64.fromByteArray(buf)
+  } else {
+    return base64.fromByteArray(buf.slice(start, end))
+  }
+}
+
+function utf8Slice (buf, start, end) {
+  var res = ''
+  var tmp = ''
+  end = Math.min(buf.length, end)
+
+  for (var i = start; i < end; i++) {
+    if (buf[i] <= 0x7F) {
+      res += decodeUtf8Char(tmp) + String.fromCharCode(buf[i])
+      tmp = ''
+    } else {
+      tmp += '%' + buf[i].toString(16)
+    }
+  }
+
+  return res + decodeUtf8Char(tmp)
+}
+
+function asciiSlice (buf, start, end) {
+  var ret = ''
+  end = Math.min(buf.length, end)
+
+  for (var i = start; i < end; i++) {
+    ret += String.fromCharCode(buf[i] & 0x7F)
+  }
+  return ret
+}
+
+function binarySlice (buf, start, end) {
+  var ret = ''
+  end = Math.min(buf.length, end)
+
+  for (var i = start; i < end; i++) {
+    ret += String.fromCharCode(buf[i])
+  }
+  return ret
+}
+
+function hexSlice (buf, start, end) {
+  var len = buf.length
+
+  if (!start || start < 0) start = 0
+  if (!end || end < 0 || end > len) end = len
+
+  var out = ''
+  for (var i = start; i < end; i++) {
+    out += toHex(buf[i])
+  }
+  return out
+}
+
+function utf16leSlice (buf, start, end) {
+  var bytes = buf.slice(start, end)
+  var res = ''
+  for (var i = 0; i < bytes.length; i += 2) {
+    res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256)
+  }
+  return res
+}
+
+Buffer.prototype.slice = function (start, end) {
+  var len = this.length
+  start = ~~start
+  end = end === undefined ? len : ~~end
+
+  if (start < 0) {
+    start += len;
+    if (start < 0)
+      start = 0
+  } else if (start > len) {
+    start = len
+  }
+
+  if (end < 0) {
+    end += len
+    if (end < 0)
+      end = 0
+  } else if (end > len) {
+    end = len
+  }
+
+  if (end < start)
+    end = start
+
+  var newBuf
+  if (Buffer.TYPED_ARRAY_SUPPORT) {
+    newBuf = Buffer._augment(this.subarray(start, end))
+  } else {
+    var sliceLen = end - start
+    newBuf = new Buffer(sliceLen, undefined, true)
+    for (var i = 0; i < sliceLen; i++) {
+      newBuf[i] = this[i + start]
+    }
+  }
+
+  if (newBuf.length)
+    newBuf.parent = this.parent || this
+
+  return newBuf
+}
+
+/*
+ * Need to make sure that buffer isn't trying to write out of bounds.
+ */
+function checkOffset (offset, ext, length) {
+  if ((offset % 1) !== 0 || offset < 0)
+    throw new RangeError('offset is not uint')
+  if (offset + ext > length)
+    throw new RangeError('Trying to access beyond buffer length')
+}
+
+Buffer.prototype.readUIntLE = function (offset, byteLength, noAssert) {
+  offset = offset >>> 0
+  byteLength = byteLength >>> 0
+  if (!noAssert)
+    checkOffset(offset, byteLength, this.length)
+
+  var val = this[offset]
+  var mul = 1
+  var i = 0
+  while (++i < byteLength && (mul *= 0x100))
+    val += this[offset + i] * mul
+
+  return val
+}
+
+Buffer.prototype.readUIntBE = function (offset, byteLength, noAssert) {
+  offset = offset >>> 0
+  byteLength = byteLength >>> 0
+  if (!noAssert)
+    checkOffset(offset, byteLength, this.length)
+
+  var val = this[offset + --byteLength]
+  var mul = 1
+  while (byteLength > 0 && (mul *= 0x100))
+    val += this[offset + --byteLength] * mul;
+
+  return val
+}
+
+Buffer.prototype.readUInt8 = function (offset, noAssert) {
+  if (!noAssert)
+    checkOffset(offset, 1, this.length)
+  return this[offset]
+}
+
+Buffer.prototype.readUInt16LE = function (offset, noAssert) {
+  if (!noAssert)
+    checkOffset(offset, 2, this.length)
+  return this[offset] | (this[offset + 1] << 8)
+}
+
+Buffer.prototype.readUInt16BE = function (offset, noAssert) {
+  if (!noAssert)
+    checkOffset(offset, 2, this.length)
+  return (this[offset] << 8) | this[offset + 1]
+}
+
+Buffer.prototype.readUInt32LE = function (offset, noAssert) {
+  if (!noAssert)
+    checkOffset(offset, 4, this.length)
+
+  return ((this[offset]) |
+      (this[offset + 1] << 8) |
+      (this[offset + 2] << 16)) +
+      (this[offset + 3] * 0x1000000)
+}
+
+Buffer.prototype.readUInt32BE = function (offset, noAssert) {
+  if (!noAssert)
+    checkOffset(offset, 4, this.length)
+
+  return (this[offset] * 0x1000000) +
+      ((this[offset + 1] << 16) |
+      (this[offset + 2] << 8) |
+      this[offset + 3])
+}
+
+Buffer.prototype.readIntLE = function (offset, byteLength, noAssert) {
+  offset = offset >>> 0
+  byteLength = byteLength >>> 0
+  if (!noAssert)
+    checkOffset(offset, byteLength, this.length)
+
+  var val = this[offset]
+  var mul = 1
+  var i = 0
+  while (++i < byteLength && (mul *= 0x100))
+    val += this[offset + i] * mul
+  mul *= 0x80
+
+  if (val >= mul)
+    val -= Math.pow(2, 8 * byteLength)
+
+  return val
+}
+
+Buffer.prototype.readIntBE = function (offset, byteLength, noAssert) {
+  offset = offset >>> 0
+  byteLength = byteLength >>> 0
+  if (!noAssert)
+    checkOffset(offset, byteLength, this.length)
+
+  var i = byteLength
+  var mul = 1
+  var val = this[offset + --i]
+  while (i > 0 && (mul *= 0x100))
+    val += this[offset + --i] * mul
+  mul *= 0x80
+
+  if (val >= mul)
+    val -= Math.pow(2, 8 * byteLength)
+
+  return val
+}
+
+Buffer.prototype.readInt8 = function (offset, noAssert) {
+  if (!noAssert)
+    checkOffset(offset, 1, this.length)
+  if (!(this[offset] & 0x80))
+    return (this[offset])
+  return ((0xff - this[offset] + 1) * -1)
+}
+
+Buffer.prototype.readInt16LE = function (offset, noAssert) {
+  if (!noAssert)
+    checkOffset(offset, 2, this.length)
+  var val = this[offset] | (this[offset + 1] << 8)
+  return (val & 0x8000) ? val | 0xFFFF0000 : val
+}
+
+Buffer.prototype.readInt16BE = function (offset, noAssert) {
+  if (!noAssert)
+    checkOffset(offset, 2, this.length)
+  var val = this[offset + 1] | (this[offset] << 8)
+  return (val & 0x8000) ? val | 0xFFFF0000 : val
+}
+
+Buffer.prototype.readInt32LE = function (offset, noAssert) {
+  if (!noAssert)
+    checkOffset(offset, 4, this.length)
+
+  return (this[offset]) |
+      (this[offset + 1] << 8) |
+      (this[offset + 2] << 16) |
+      (this[offset + 3] << 24)
+}
+
+Buffer.prototype.readInt32BE = function (offset, noAssert) {
+  if (!noAssert)
+    checkOffset(offset, 4, this.length)
+
+  return (this[offset] << 24) |
+      (this[offset + 1] << 16) |
+      (this[offset + 2] << 8) |
+      (this[offset + 3])
+}
+
+Buffer.prototype.readFloatLE = function (offset, noAssert) {
+  if (!noAssert)
+    checkOffset(offset, 4, this.length)
+  return ieee754.read(this, offset, true, 23, 4)
+}
+
+Buffer.prototype.readFloatBE = function (offset, noAssert) {
+  if (!noAssert)
+    checkOffset(offset, 4, this.length)
+  return ieee754.read(this, offset, false, 23, 4)
+}
+
+Buffer.prototype.readDoubleLE = function (offset, noAssert) {
+  if (!noAssert)
+    checkOffset(offset, 8, this.length)
+  return ieee754.read(this, offset, true, 52, 8)
+}
+
+Buffer.prototype.readDoubleBE = function (offset, noAssert) {
+  if (!noAssert)
+    checkOffset(offset, 8, this.length)
+  return ieee754.read(this, offset, false, 52, 8)
+}
+
+function checkInt (buf, value, offset, ext, max, min) {
+  if (!Buffer.isBuffer(buf)) throw new TypeError('buffer must be a Buffer instance')
+  if (value > max || value < min) throw new RangeError('value is out of bounds')
+  if (offset + ext > buf.length) throw new RangeError('index out of range')
+}
+
+Buffer.prototype.writeUIntLE = function (value, offset, byteLength, noAssert) {
+  value = +value
+  offset = offset >>> 0
+  byteLength = byteLength >>> 0
+  if (!noAssert)
+    checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0)
+
+  var mul = 1
+  var i = 0
+  this[offset] = value & 0xFF
+  while (++i < byteLength && (mul *= 0x100))
+    this[offset + i] = (value / mul) >>> 0 & 0xFF
+
+  return offset + byteLength
+}
+
+Buffer.prototype.writeUIntBE = function (value, offset, byteLength, noAssert) {
+  value = +value
+  offset = offset >>> 0
+  byteLength = byteLength >>> 0
+  if (!noAssert)
+    checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0)
+
+  var i = byteLength - 1
+  var mul = 1
+  this[offset + i] = value & 0xFF
+  while (--i >= 0 && (mul *= 0x100))
+    this[offset + i] = (value / mul) >>> 0 & 0xFF
+
+  return offset + byteLength
+}
+
+Buffer.prototype.writeUInt8 = function (value, offset, noAssert) {
+  value = +value
+  offset = offset >>> 0
+  if (!noAssert)
+    checkInt(this, value, offset, 1, 0xff, 0)
+  if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)
+  this[offset] = value
+  return offset + 1
+}
+
+function objectWriteUInt16 (buf, value, offset, littleEndian) {
+  if (value < 0) value = 0xffff + value + 1
+  for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; i++) {
+    buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>>
+      (littleEndian ? i : 1 - i) * 8
+  }
+}
+
+Buffer.prototype.writeUInt16LE = function (value, offset, noAssert) {
+  value = +value
+  offset = offset >>> 0
+  if (!noAssert)
+    checkInt(this, value, offset, 2, 0xffff, 0)
+  if (Buffer.TYPED_ARRAY_SUPPORT) {
+    this[offset] = value
+    this[offset + 1] = (value >>> 8)
+  } else objectWriteUInt16(this, value, offset, true)
+  return offset + 2
+}
+
+Buffer.prototype.writeUInt16BE = function (value, offset, noAssert) {
+  value = +value
+  offset = offset >>> 0
+  if (!noAssert)
+    checkInt(this, value, offset, 2, 0xffff, 0)
+  if (Buffer.TYPED_ARRAY_SUPPORT) {
+    this[offset] = (value >>> 8)
+    this[offset + 1] = value
+  } else objectWriteUInt16(this, value, offset, false)
+  return offset + 2
+}
+
+function objectWriteUInt32 (buf, value, offset, littleEndian) {
+  if (value < 0) value = 0xffffffff + value + 1
+  for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; i++) {
+    buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff
+  }
+}
+
+Buffer.prototype.writeUInt32LE = function (value, offset, noAssert) {
+  value = +value
+  offset = offset >>> 0
+  if (!noAssert)
+    checkInt(this, value, offset, 4, 0xffffffff, 0)
+  if (Buffer.TYPED_ARRAY_SUPPORT) {
+    this[offset + 3] = (value >>> 24)
+    this[offset + 2] = (value >>> 16)
+    this[offset + 1] = (value >>> 8)
+    this[offset] = value
+  } else objectWriteUInt32(this, value, offset, true)
+  return offset + 4
+}
+
+Buffer.prototype.writeUInt32BE = function (value, offset, noAssert) {
+  value = +value
+  offset = offset >>> 0
+  if (!noAssert)
+    checkInt(this, value, offset, 4, 0xffffffff, 0)
+  if (Buffer.TYPED_ARRAY_SUPPORT) {
+    this[offset] = (value >>> 24)
+    this[offset + 1] = (value >>> 16)
+    this[offset + 2] = (value >>> 8)
+    this[offset + 3] = value
+  } else objectWriteUInt32(this, value, offset, false)
+  return offset + 4
+}
+
+Buffer.prototype.writeIntLE = function (value, offset, byteLength, noAssert) {
+  value = +value
+  offset = offset >>> 0
+  if (!noAssert) {
+    checkInt(this,
+             value,
+             offset,
+             byteLength,
+             Math.pow(2, 8 * byteLength - 1) - 1,
+             -Math.pow(2, 8 * byteLength - 1))
+  }
+
+  var i = 0
+  var mul = 1
+  var sub = value < 0 ? 1 : 0
+  this[offset] = value & 0xFF
+  while (++i < byteLength && (mul *= 0x100))
+    this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
+
+  return offset + byteLength
+}
+
+Buffer.prototype.writeIntBE = function (value, offset, byteLength, noAssert) {
+  value = +value
+  offset = offset >>> 0
+  if (!noAssert) {
+    checkInt(this,
+             value,
+             offset,
+             byteLength,
+             Math.pow(2, 8 * byteLength - 1) - 1,
+             -Math.pow(2, 8 * byteLength - 1))
+  }
+
+  var i = byteLength - 1
+  var mul = 1
+  var sub = value < 0 ? 1 : 0
+  this[offset + i] = value & 0xFF
+  while (--i >= 0 && (mul *= 0x100))
+    this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
+
+  return offset + byteLength
+}
+
+Buffer.prototype.writeInt8 = function (value, offset, noAssert) {
+  value = +value
+  offset = offset >>> 0
+  if (!noAssert)
+    checkInt(this, value, offset, 1, 0x7f, -0x80)
+  if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)
+  if (value < 0) value = 0xff + value + 1
+  this[offset] = value
+  return offset + 1
+}
+
+Buffer.prototype.writeInt16LE = function (value, offset, noAssert) {
+  value = +value
+  offset = offset >>> 0
+  if (!noAssert)
+    checkInt(this, value, offset, 2, 0x7fff, -0x8000)
+  if (Buffer.TYPED_ARRAY_SUPPORT) {
+    this[offset] = value
+    this[offset + 1] = (value >>> 8)
+  } else objectWriteUInt16(this, value, offset, true)
+  return offset + 2
+}
+
+Buffer.prototype.writeInt16BE = function (value, offset, noAssert) {
+  value = +value
+  offset = offset >>> 0
+  if (!noAssert)
+    checkInt(this, value, offset, 2, 0x7fff, -0x8000)
+  if (Buffer.TYPED_ARRAY_SUPPORT) {
+    this[offset] = (value >>> 8)
+    this[offset + 1] = value
+  } else objectWriteUInt16(this, value, offset, false)
+  return offset + 2
+}
+
+Buffer.prototype.writeInt32LE = function (value, offset, noAssert) {
+  value = +value
+  offset = offset >>> 0
+  if (!noAssert)
+    checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
+  if (Buffer.TYPED_ARRAY_SUPPORT) {
+    this[offset] = value
+    this[offset + 1] = (value >>> 8)
+    this[offset + 2] = (value >>> 16)
+    this[offset + 3] = (value >>> 24)
+  } else objectWriteUInt32(this, value, offset, true)
+  return offset + 4
+}
+
+Buffer.prototype.writeInt32BE = function (value, offset, noAssert) {
+  value = +value
+  offset = offset >>> 0
+  if (!noAssert)
+    checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
+  if (value < 0) value = 0xffffffff + value + 1
+  if (Buffer.TYPED_ARRAY_SUPPORT) {
+    this[offset] = (value >>> 24)
+    this[offset + 1] = (value >>> 16)
+    this[offset + 2] = (value >>> 8)
+    this[offset + 3] = value
+  } else objectWriteUInt32(this, value, offset, false)
+  return offset + 4
+}
+
+function checkIEEE754 (buf, value, offset, ext, max, min) {
+  if (value > max || value < min) throw new RangeError('value is out of bounds')
+  if (offset + ext > buf.length) throw new RangeError('index out of range')
+  if (offset < 0) throw new RangeError('index out of range')
+}
+
+function writeFloat (buf, value, offset, littleEndian, noAssert) {
+  if (!noAssert)
+    checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38)
+  ieee754.write(buf, value, offset, littleEndian, 23, 4)
+  return offset + 4
+}
+
+Buffer.prototype.writeFloatLE = function (value, offset, noAssert) {
+  return writeFloat(this, value, offset, true, noAssert)
+}
+
+Buffer.prototype.writeFloatBE = function (value, offset, noAssert) {
+  return writeFloat(this, value, offset, false, noAssert)
+}
+
+function writeDouble (buf, value, offset, littleEndian, noAssert) {
+  if (!noAssert)
+    checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308)
+  ieee754.write(buf, value, offset, littleEndian, 52, 8)
+  return offset + 8
+}
+
+Buffer.prototype.writeDoubleLE = function (value, offset, noAssert) {
+  return writeDouble(this, value, offset, true, noAssert)
+}
+
+Buffer.prototype.writeDoubleBE = function (value, offset, noAssert) {
+  return writeDouble(this, value, offset, false, noAssert)
+}
+
+// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)
+Buffer.prototype.copy = function (target, target_start, start, end) {
+  var source = this
+
+  if (!start) start = 0
+  if (!end && end !== 0) end = this.length
+  if (target_start >= target.length) target_start = target.length
+  if (!target_start) target_start = 0
+  if (end > 0 && end < start) end = start
+
+  // Copy 0 bytes; we're done
+  if (end === start) return 0
+  if (target.length === 0 || source.length === 0) return 0
+
+  // Fatal error conditions
+  if (target_start < 0)
+    throw new RangeError('targetStart out of bounds')
+  if (start < 0 || start >= source.length) throw new RangeError('sourceStart out of bounds')
+  if (end < 0) throw new RangeError('sourceEnd out of bounds')
+
+  // Are we oob?
+  if (end > this.length)
+    end = this.length
+  if (target.length - target_start < end - start)
+    end = target.length - target_start + start
+
+  var len = end - start
+
+  if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) {
+    for (var i = 0; i < len; i++) {
+      target[i + target_start] = this[i + start]
+    }
+  } else {
+    target._set(this.subarray(start, start + len), target_start)
+  }
+
+  return len
+}
+
+// fill(value, start=0, end=buffer.length)
+Buffer.prototype.fill = function (value, start, end) {
+  if (!value) value = 0
+  if (!start) start = 0
+  if (!end) end = this.length
+
+  if (end < start) throw new RangeError('end < start')
+
+  // Fill 0 bytes; we're done
+  if (end === start) return
+  if (this.length === 0) return
+
+  if (start < 0 || start >= this.length) throw new RangeError('start out of bounds')
+  if (end < 0 || end > this.length) throw new RangeError('end out of bounds')
+
+  var i
+  if (typeof value === 'number') {
+    for (i = start; i < end; i++) {
+      this[i] = value
+    }
+  } else {
+    var bytes = utf8ToBytes(value.toString())
+    var len = bytes.length
+    for (i = start; i < end; i++) {
+      this[i] = bytes[i % len]
+    }
+  }
+
+  return this
+}
+
+/**
+ * Creates a new `ArrayBuffer` with the *copied* memory of the buffer instance.
+ * Added in Node 0.12. Only available in browsers that support ArrayBuffer.
+ */
+Buffer.prototype.toArrayBuffer = function () {
+  if (typeof Uint8Array !== 'undefined') {
+    if (Buffer.TYPED_ARRAY_SUPPORT) {
+      return (new Buffer(this)).buffer
+    } else {
+      var buf = new Uint8Array(this.length)
+      for (var i = 0, len = buf.length; i < len; i += 1) {
+        buf[i] = this[i]
+      }
+      return buf.buffer
+    }
+  } else {
+    throw new TypeError('Buffer.toArrayBuffer not supported in this browser')
+  }
+}
+
+// HELPER FUNCTIONS
+// ================
+
+var BP = Buffer.prototype
+
+/**
+ * Augment a Uint8Array *instance* (not the Uint8Array class!) with Buffer methods
+ */
+Buffer._augment = function (arr) {
+  arr.constructor = Buffer
+  arr._isBuffer = true
+
+  // save reference to original Uint8Array get/set methods before overwriting
+  arr._get = arr.get
+  arr._set = arr.set
+
+  // deprecated, will be removed in node 0.13+
+  arr.get = BP.get
+  arr.set = BP.set
+
+  arr.write = BP.write
+  arr.toString = BP.toString
+  arr.toLocaleString = BP.toString
+  arr.toJSON = BP.toJSON
+  arr.equals = BP.equals
+  arr.compare = BP.compare
+  arr.copy = BP.copy
+  arr.slice = BP.slice
+  arr.readUIntLE = BP.readUIntLE
+  arr.readUIntBE = BP.readUIntBE
+  arr.readUInt8 = BP.readUInt8
+  arr.readUInt16LE = BP.readUInt16LE
+  arr.readUInt16BE = BP.readUInt16BE
+  arr.readUInt32LE = BP.readUInt32LE
+  arr.readUInt32BE = BP.readUInt32BE
+  arr.readIntLE = BP.readIntLE
+  arr.readIntBE = BP.readIntBE
+  arr.readInt8 = BP.readInt8
+  arr.readInt16LE = BP.readInt16LE
+  arr.readInt16BE = BP.readInt16BE
+  arr.readInt32LE = BP.readInt32LE
+  arr.readInt32BE = BP.readInt32BE
+  arr.readFloatLE = BP.readFloatLE
+  arr.readFloatBE = BP.readFloatBE
+  arr.readDoubleLE = BP.readDoubleLE
+  arr.readDoubleBE = BP.readDoubleBE
+  arr.writeUInt8 = BP.writeUInt8
+  arr.writeUIntLE = BP.writeUIntLE
+  arr.writeUIntBE = BP.writeUIntBE
+  arr.writeUInt16LE = BP.writeUInt16LE
+  arr.writeUInt16BE = BP.writeUInt16BE
+  arr.writeUInt32LE = BP.writeUInt32LE
+  arr.writeUInt32BE = BP.writeUInt32BE
+  arr.writeIntLE = BP.writeIntLE
+  arr.writeIntBE = BP.writeIntBE
+  arr.writeInt8 = BP.writeInt8
+  arr.writeInt16LE = BP.writeInt16LE
+  arr.writeInt16BE = BP.writeInt16BE
+  arr.writeInt32LE = BP.writeInt32LE
+  arr.writeInt32BE = BP.writeInt32BE
+  arr.writeFloatLE = BP.writeFloatLE
+  arr.writeFloatBE = BP.writeFloatBE
+  arr.writeDoubleLE = BP.writeDoubleLE
+  arr.writeDoubleBE = BP.writeDoubleBE
+  arr.fill = BP.fill
+  arr.inspect = BP.inspect
+  arr.toArrayBuffer = BP.toArrayBuffer
+
+  return arr
+}
+
+var INVALID_BASE64_RE = /[^+\/0-9A-z\-]/g
+
+function base64clean (str) {
+  // Node strips out invalid characters like \n and \t from the string, base64-js does not
+  str = stringtrim(str).replace(INVALID_BASE64_RE, '')
+  // Node converts strings with length < 2 to ''
+  if (str.length < 2) return ''
+  // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not
+  while (str.length % 4 !== 0) {
+    str = str + '='
+  }
+  return str
+}
+
+function stringtrim (str) {
+  if (str.trim) return str.trim()
+  return str.replace(/^\s+|\s+$/g, '')
+}
+
+function isArrayish (subject) {
+  return isArray(subject) || Buffer.isBuffer(subject) ||
+      subject && typeof subject === 'object' &&
+      typeof subject.length === 'number'
+}
+
+function toHex (n) {
+  if (n < 16) return '0' + n.toString(16)
+  return n.toString(16)
+}
+
+function utf8ToBytes(string, units) {
+  var codePoint, length = string.length
+  var leadSurrogate = null
+  units = units || Infinity
+  var bytes = []
+  var i = 0
+
+  for (; i<length; i++) {
+    codePoint = string.charCodeAt(i)
+
+    // is surrogate component
+    if (codePoint > 0xD7FF && codePoint < 0xE000) {
+
+      // last char was a lead
+      if (leadSurrogate) {
+
+        // 2 leads in a row
+        if (codePoint < 0xDC00) {
+          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
+          leadSurrogate = codePoint
+          continue
+        }
+
+        // valid surrogate pair
+        else {
+          codePoint = leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00 | 0x10000
+          leadSurrogate = null
+        }
+      }
+
+      // no lead yet
+      else {
+
+        // unexpected trail
+        if (codePoint > 0xDBFF) {
+          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
+          continue
+        }
+
+        // unpaired lead
+        else if (i + 1 === length) {
+          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
+          continue
+        }
+
+        // valid lead
+        else {
+          leadSurrogate = codePoint
+          continue
+        }
+      }
+    }
+
+    // valid bmp char, but last char was a lead
+    else if (leadSurrogate) {
+      if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
+      leadSurrogate = null
+    }
+
+    // encode utf8
+    if (codePoint < 0x80) {
+      if ((units -= 1) < 0) break
+      bytes.push(codePoint)
+    }
+    else if (codePoint < 0x800) {
+      if ((units -= 2) < 0) break
+      bytes.push(
+        codePoint >> 0x6 | 0xC0,
+        codePoint & 0x3F | 0x80
+      );
+    }
+    else if (codePoint < 0x10000) {
+      if ((units -= 3) < 0) break
+      bytes.push(
+        codePoint >> 0xC | 0xE0,
+        codePoint >> 0x6 & 0x3F | 0x80,
+        codePoint & 0x3F | 0x80
+      );
+    }
+    else if (codePoint < 0x200000) {
+      if ((units -= 4) < 0) break
+      bytes.push(
+        codePoint >> 0x12 | 0xF0,
+        codePoint >> 0xC & 0x3F | 0x80,
+        codePoint >> 0x6 & 0x3F | 0x80,
+        codePoint & 0x3F | 0x80
+      );
+    }
+    else {
+      throw new Error('Invalid code point')
+    }
+  }
+
+  return bytes
+}
+
+function asciiToBytes (str) {
+  var byteArray = []
+  for (var i = 0; i < str.length; i++) {
+    // Node's code seems to be doing this and not & 0x7F..
+    byteArray.push(str.charCodeAt(i) & 0xFF)
+  }
+  return byteArray
+}
+
+function utf16leToBytes (str, units) {
+  var c, hi, lo
+  var byteArray = []
+  for (var i = 0; i < str.length; i++) {
+
+    if ((units -= 2) < 0) break
+
+    c = str.charCodeAt(i)
+    hi = c >> 8
+    lo = c % 256
+    byteArray.push(lo)
+    byteArray.push(hi)
+  }
+
+  return byteArray
+}
+
+function base64ToBytes (str) {
+  return base64.toByteArray(base64clean(str))
+}
+
+function blitBuffer (src, dst, offset, length, unitSize) {
+  if (unitSize) length -= length % unitSize;
+  for (var i = 0; i < length; i++) {
+    if ((i + offset >= dst.length) || (i >= src.length))
+      break
+    dst[i + offset] = src[i]
+  }
+  return i
+}
+
+function decodeUtf8Char (str) {
+  try {
+    return decodeURIComponent(str)
+  } catch (err) {
+    return String.fromCharCode(0xFFFD) // UTF 8 invalid char
+  }
+}
+
+},{"base64-js":3,"ieee754":4,"is-array":5}],3:[function(require,module,exports){
+var lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
+
+;(function (exports) {
+	'use strict';
+
+  var Arr = (typeof Uint8Array !== 'undefined')
+    ? Uint8Array
+    : Array
+
+	var PLUS   = '+'.charCodeAt(0)
+	var SLASH  = '/'.charCodeAt(0)
+	var NUMBER = '0'.charCodeAt(0)
+	var LOWER  = 'a'.charCodeAt(0)
+	var UPPER  = 'A'.charCodeAt(0)
+	var PLUS_URL_SAFE = '-'.charCodeAt(0)
+	var SLASH_URL_SAFE = '_'.charCodeAt(0)
+
+	function decode (elt) {
+		var code = elt.charCodeAt(0)
+		if (code === PLUS ||
+		    code === PLUS_URL_SAFE)
+			return 62 // '+'
+		if (code === SLASH ||
+		    code === SLASH_URL_SAFE)
+			return 63 // '/'
+		if (code < NUMBER)
+			return -1 //no match
+		if (code < NUMBER + 10)
+			return code - NUMBER + 26 + 26
+		if (code < UPPER + 26)
+			return code - UPPER
+		if (code < LOWER + 26)
+			return code - LOWER + 26
+	}
+
+	function b64ToByteArray (b64) {
+		var i, j, l, tmp, placeHolders, arr
+
+		if (b64.length % 4 > 0) {
+			throw new Error('Invalid string. Length must be a multiple of 4')
+		}
+
+		// the number of equal signs (place holders)
+		// if there are two placeholders, than the two characters before it
+		// represent one byte
+		// if there is only one, then the three characters before it represent 2 bytes
+		// this is just a cheap hack to not do indexOf twice
+		var len = b64.length
+		placeHolders = '=' === b64.charAt(len - 2) ? 2 : '=' === b64.charAt(len - 1) ? 1 : 0
+
+		// base64 is 4/3 + up to two characters of the original data
+		arr = new Arr(b64.length * 3 / 4 - placeHolders)
+
+		// if there are placeholders, only get up to the last complete 4 chars
+		l = placeHolders > 0 ? b64.length - 4 : b64.length
+
+		var L = 0
+
+		function push (v) {
+			arr[L++] = v
+		}
+
+		for (i = 0, j = 0; i < l; i += 4, j += 3) {
+			tmp = (decode(b64.charAt(i)) << 18) | (decode(b64.charAt(i + 1)) << 12) | (decode(b64.charAt(i + 2)) << 6) | decode(b64.charAt(i + 3))
+			push((tmp & 0xFF0000) >> 16)
+			push((tmp & 0xFF00) >> 8)
+			push(tmp & 0xFF)
+		}
+
+		if (placeHolders === 2) {
+			tmp = (decode(b64.charAt(i)) << 2) | (decode(b64.charAt(i + 1)) >> 4)
+			push(tmp & 0xFF)
+		} else if (placeHolders === 1) {
+			tmp = (decode(b64.charAt(i)) << 10) | (decode(b64.charAt(i + 1)) << 4) | (decode(b64.charAt(i + 2)) >> 2)
+			push((tmp >> 8) & 0xFF)
+			push(tmp & 0xFF)
+		}
+
+		return arr
+	}
+
+	function uint8ToBase64 (uint8) {
+		var i,
+			extraBytes = uint8.length % 3, // if we have 1 byte left, pad 2 bytes
+			output = "",
+			temp, length
+
+		function encode (num) {
+			return lookup.charAt(num)
+		}
+
+		function tripletToBase64 (num) {
+			return encode(num >> 18 & 0x3F) + encode(num >> 12 & 0x3F) + encode(num >> 6 & 0x3F) + encode(num & 0x3F)
+		}
+
+		// go through the array every three bytes, we'll deal with trailing stuff later
+		for (i = 0, length = uint8.length - extraBytes; i < length; i += 3) {
+			temp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2])
+			output += tripletToBase64(temp)
+		}
+
+		// pad the end with zeros, but make sure to not forget the extra bytes
+		switch (extraBytes) {
+			case 1:
+				temp = uint8[uint8.length - 1]
+				output += encode(temp >> 2)
+				output += encode((temp << 4) & 0x3F)
+				output += '=='
+				break
+			case 2:
+				temp = (uint8[uint8.length - 2] << 8) + (uint8[uint8.length - 1])
+				output += encode(temp >> 10)
+				output += encode((temp >> 4) & 0x3F)
+				output += encode((temp << 2) & 0x3F)
+				output += '='
+				break
+		}
+
+		return output
+	}
+
+	exports.toByteArray = b64ToByteArray
+	exports.fromByteArray = uint8ToBase64
+}(typeof exports === 'undefined' ? (this.base64js = {}) : exports))
+
+},{}],4:[function(require,module,exports){
+exports.read = function(buffer, offset, isLE, mLen, nBytes) {
+  var e, m,
+      eLen = nBytes * 8 - mLen - 1,
+      eMax = (1 << eLen) - 1,
+      eBias = eMax >> 1,
+      nBits = -7,
+      i = isLE ? (nBytes - 1) : 0,
+      d = isLE ? -1 : 1,
+      s = buffer[offset + i];
+
+  i += d;
+
+  e = s & ((1 << (-nBits)) - 1);
+  s >>= (-nBits);
+  nBits += eLen;
+  for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8);
+
+  m = e & ((1 << (-nBits)) - 1);
+  e >>= (-nBits);
+  nBits += mLen;
+  for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8);
+
+  if (e === 0) {
+    e = 1 - eBias;
+  } else if (e === eMax) {
+    return m ? NaN : ((s ? -1 : 1) * Infinity);
+  } else {
+    m = m + Math.pow(2, mLen);
+    e = e - eBias;
+  }
+  return (s ? -1 : 1) * m * Math.pow(2, e - mLen);
+};
+
+exports.write = function(buffer, value, offset, isLE, mLen, nBytes) {
+  var e, m, c,
+      eLen = nBytes * 8 - mLen - 1,
+      eMax = (1 << eLen) - 1,
+      eBias = eMax >> 1,
+      rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0),
+      i = isLE ? 0 : (nBytes - 1),
+      d = isLE ? 1 : -1,
+      s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0;
+
+  value = Math.abs(value);
+
+  if (isNaN(value) || value === Infinity) {
+    m = isNaN(value) ? 1 : 0;
+    e = eMax;
+  } else {
+    e = Math.floor(Math.log(value) / Math.LN2);
+    if (value * (c = Math.pow(2, -e)) < 1) {
+      e--;
+      c *= 2;
+    }
+    if (e + eBias >= 1) {
+      value += rt / c;
+    } else {
+      value += rt * Math.pow(2, 1 - eBias);
+    }
+    if (value * c >= 2) {
+      e++;
+      c /= 2;
+    }
+
+    if (e + eBias >= eMax) {
+      m = 0;
+      e = eMax;
+    } else if (e + eBias >= 1) {
+      m = (value * c - 1) * Math.pow(2, mLen);
+      e = e + eBias;
+    } else {
+      m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen);
+      e = 0;
+    }
+  }
+
+  for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8);
+
+  e = (e << mLen) | m;
+  eLen += mLen;
+  for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8);
+
+  buffer[offset + i - d] |= s * 128;
+};
+
+},{}],5:[function(require,module,exports){
+
+/**
+ * isArray
+ */
+
+var isArray = Array.isArray;
+
+/**
+ * toString
+ */
+
+var str = Object.prototype.toString;
+
+/**
+ * Whether or not the given `val`
+ * is an array.
+ *
+ * example:
+ *
+ *        isArray([]);
+ *        // > true
+ *        isArray(arguments);
+ *        // > false
+ *        isArray('');
+ *        // > false
+ *
+ * @param {mixed} val
+ * @return {bool}
+ */
+
+module.exports = isArray || function (val) {
+  return !! val && '[object Array]' == str.call(val);
+};
+
+},{}],6:[function(require,module,exports){
+// shim for using process in browser
+
+var process = module.exports = {};
+
+process.nextTick = (function () {
+    var canSetImmediate = typeof window !== 'undefined'
+    && window.setImmediate;
+    var canMutationObserver = typeof window !== 'undefined'
+    && window.MutationObserver;
+    var canPost = typeof window !== 'undefined'
+    && window.postMessage && window.addEventListener
+    ;
+
+    if (canSetImmediate) {
+        return function (f) { return window.setImmediate(f) };
+    }
+
+    var queue = [];
+
+    if (canMutationObserver) {
+        var hiddenDiv = document.createElement("div");
+        var observer = new MutationObserver(function () {
+            var queueList = queue.slice();
+            queue.length = 0;
+            queueList.forEach(function (fn) {
+                fn();
+            });
+        });
+
+        observer.observe(hiddenDiv, { attributes: true });
+
+        return function nextTick(fn) {
+            if (!queue.length) {
+                hiddenDiv.setAttribute('yes', 'no');
+            }
+            queue.push(fn);
+        };
+    }
+
+    if (canPost) {
+        window.addEventListener('message', function (ev) {
+            var source = ev.source;
+            if ((source === window || source === null) && ev.data === 'process-tick') {
+                ev.stopPropagation();
+                if (queue.length > 0) {
+                    var fn = queue.shift();
+                    fn();
+                }
+            }
+        }, true);
+
+        return function nextTick(fn) {
+            queue.push(fn);
+            window.postMessage('process-tick', '*');
+        };
+    }
+
+    return function nextTick(fn) {
+        setTimeout(fn, 0);
+    };
+})();
+
+process.title = 'browser';
+process.browser = true;
+process.env = {};
+process.argv = [];
+
+function noop() {}
+
+process.on = noop;
+process.addListener = noop;
+process.once = noop;
+process.off = noop;
+process.removeListener = noop;
+process.removeAllListeners = noop;
+process.emit = noop;
+
+process.binding = function (name) {
+    throw new Error('process.binding is not supported');
+};
+
+// TODO(shtylman)
+process.cwd = function () { return '/' };
+process.chdir = function (dir) {
+    throw new Error('process.chdir is not supported');
+};
+
+},{}],7:[function(require,module,exports){
+module.exports = require('./lib/eql');
+
+},{"./lib/eql":8}],8:[function(require,module,exports){
+/*!
+ * deep-eql
+ * Copyright(c) 2013 Jake Luer <jake@alogicalparadox.com>
+ * MIT Licensed
+ */
+
+/*!
+ * Module dependencies
+ */
+
+var type = require('type-detect');
+
+/*!
+ * Buffer.isBuffer browser shim
+ */
+
+var Buffer;
+try { Buffer = require('buffer').Buffer; }
+catch(ex) {
+  Buffer = {};
+  Buffer.isBuffer = function() { return false; }
+}
+
+/*!
+ * Primary Export
+ */
+
+module.exports = deepEqual;
+
+/**
+ * Assert super-strict (egal) equality between
+ * two objects of any type.
+ *
+ * @param {Mixed} a
+ * @param {Mixed} b
+ * @param {Array} memoised (optional)
+ * @return {Boolean} equal match
+ */
+
+function deepEqual(a, b, m) {
+  if (sameValue(a, b)) {
+    return true;
+  } else if ('date' === type(a)) {
+    return dateEqual(a, b);
+  } else if ('regexp' === type(a)) {
+    return regexpEqual(a, b);
+  } else if (Buffer.isBuffer(a)) {
+    return bufferEqual(a, b);
+  } else if ('arguments' === type(a)) {
+    return argumentsEqual(a, b, m);
+  } else if (!typeEqual(a, b)) {
+    return false;
+  } else if (('object' !== type(a) && 'object' !== type(b))
+  && ('array' !== type(a) && 'array' !== type(b))) {
+    return sameValue(a, b);
+  } else {
+    return objectEqual(a, b, m);
+  }
+}
+
+/*!
+ * Strict (egal) equality test. Ensures that NaN always
+ * equals NaN and `-0` does not equal `+0`.
+ *
+ * @param {Mixed} a
+ * @param {Mixed} b
+ * @return {Boolean} equal match
+ */
+
+function sameValue(a, b) {
+  if (a === b) return a !== 0 || 1 / a === 1 / b;
+  return a !== a && b !== b;
+}
+
+/*!
+ * Compare the types of two given objects and
+ * return if they are equal. Note that an Array
+ * has a type of `array` (not `object`) and arguments
+ * have a type of `arguments` (not `array`/`object`).
+ *
+ * @param {Mixed} a
+ * @param {Mixed} b
+ * @return {Boolean} result
+ */
+
+function typeEqual(a, b) {
+  return type(a) === type(b);
+}
+
+/*!
+ * Compare two Date objects by asserting that
+ * the time values are equal using `saveValue`.
+ *
+ * @param {Date} a
+ * @param {Date} b
+ * @return {Boolean} result
+ */
+
+function dateEqual(a, b) {
+  if ('date' !== type(b)) return false;
+  return sameValue(a.getTime(), b.getTime());
+}
+
+/*!
+ * Compare two regular expressions by converting them
+ * to string and checking for `sameValue`.
+ *
+ * @param {RegExp} a
+ * @param {RegExp} b
+ * @return {Boolean} result
+ */
+
+function regexpEqual(a, b) {
+  if ('regexp' !== type(b)) return false;
+  return sameValue(a.toString(), b.toString());
+}
+
+/*!
+ * Assert deep equality of two `arguments` objects.
+ * Unfortunately, these must be sliced to arrays
+ * prior to test to ensure no bad behavior.
+ *
+ * @param {Arguments} a
+ * @param {Arguments} b
+ * @param {Array} memoize (optional)
+ * @return {Boolean} result
+ */
+
+function argumentsEqual(a, b, m) {
+  if ('arguments' !== type(b)) return false;
+  a = [].slice.call(a);
+  b = [].slice.call(b);
+  return deepEqual(a, b, m);
+}
+
+/*!
+ * Get enumerable properties of a given object.
+ *
+ * @param {Object} a
+ * @return {Array} property names
+ */
+
+function enumerable(a) {
+  var res = [];
+  for (var key in a) res.push(key);
+  return res;
+}
+
+/*!
+ * Simple equality for flat iterable objects
+ * such as Arrays or Node.js buffers.
+ *
+ * @param {Iterable} a
+ * @param {Iterable} b
+ * @return {Boolean} result
+ */
+
+function iterableEqual(a, b) {
+  if (a.length !==  b.length) return false;
+
+  var i = 0;
+  var match = true;
+
+  for (; i < a.length; i++) {
+    if (a[i] !== b[i]) {
+      match = false;
+      break;
+    }
+  }
+
+  return match;
+}
+
+/*!
+ * Extension to `iterableEqual` specifically
+ * for Node.js Buffers.
+ *
+ * @param {Buffer} a
+ * @param {Mixed} b
+ * @return {Boolean} result
+ */
+
+function bufferEqual(a, b) {
+  if (!Buffer.isBuffer(b)) return false;
+  return iterableEqual(a, b);
+}
+
+/*!
+ * Block for `objectEqual` ensuring non-existing
+ * values don't get in.
+ *
+ * @param {Mixed} object
+ * @return {Boolean} result
+ */
+
+function isValue(a) {
+  return a !== null && a !== undefined;
+}
+
+/*!
+ * Recursively check the equality of two objects.
+ * Once basic sameness has been established it will
+ * defer to `deepEqual` for each enumerable key
+ * in the object.
+ *
+ * @param {Mixed} a
+ * @param {Mixed} b
+ * @return {Boolean} result
+ */
+
+function objectEqual(a, b, m) {
+  if (!isValue(a) || !isValue(b)) {
+    return false;
+  }
+
+  if (a.prototype !== b.prototype) {
+    return false;
+  }
+
+  var i;
+  if (m) {
+    for (i = 0; i < m.length; i++) {
+      if ((m[i][0] === a && m[i][1] === b)
+      ||  (m[i][0] === b && m[i][1] === a)) {
+        return true;
+      }
+    }
+  } else {
+    m = [];
+  }
+
+  try {
+    var ka = enumerable(a);
+    var kb = enumerable(b);
+  } catch (ex) {
+    return false;
+  }
+
+  ka.sort();
+  kb.sort();
+
+  if (!iterableEqual(ka, kb)) {
+    return false;
+  }
+
+  m.push([ a, b ]);
+
+  var key;
+  for (i = ka.length - 1; i >= 0; i--) {
+    key = ka[i];
+    if (!deepEqual(a[key], b[key], m)) {
+      return false;
+    }
+  }
+
+  return true;
+}
+
+},{"buffer":2,"type-detect":9}],9:[function(require,module,exports){
+module.exports = require('./lib/type');
+
+},{"./lib/type":10}],10:[function(require,module,exports){
+/*!
+ * type-detect
+ * Copyright(c) 2013 jake luer <jake@alogicalparadox.com>
+ * MIT Licensed
+ */
+
+/*!
+ * Primary Exports
+ */
+
+var exports = module.exports = getType;
+
+/*!
+ * Detectable javascript natives
+ */
+
+var natives = {
+    '[object Array]': 'array'
+  , '[object RegExp]': 'regexp'
+  , '[object Function]': 'function'
+  , '[object Arguments]': 'arguments'
+  , '[object Date]': 'date'
+};
+
+/**
+ * ### typeOf (obj)
+ *
+ * Use several different techniques to determine
+ * the type of object being tested.
+ *
+ *
+ * @param {Mixed} object
+ * @return {String} object type
+ * @api public
+ */
+
+function getType (obj) {
+  var str = Object.prototype.toString.call(obj);
+  if (natives[str]) return natives[str];
+  if (obj === null) return 'null';
+  if (obj === undefined) return 'undefined';
+  if (obj === Object(obj)) return 'object';
+  return typeof obj;
+}
+
+exports.Library = Library;
+
+/**
+ * ### Library
+ *
+ * Create a repository for custom type detection.
+ *
+ * ```js
+ * var lib = new type.Library;
+ * ```
+ *
+ */
+
+function Library () {
+  this.tests = {};
+}
+
+/**
+ * #### .of (obj)
+ *
+ * Expose replacement `typeof` detection to the library.
+ *
+ * ```js
+ * if ('string' === lib.of('hello world')) {
+ *   // ...
+ * }
+ * ```
+ *
+ * @param {Mixed} object to test
+ * @return {String} type
+ */
+
+Library.prototype.of = getType;
+
+/**
+ * #### .define (type, test)
+ *
+ * Add a test to for the `.test()` assertion.
+ *
+ * Can be defined as a regular expression:
+ *
+ * ```js
+ * lib.define('int', /^[0-9]+$/);
+ * ```
+ *
+ * ... or as a function:
+ *
+ * ```js
+ * lib.define('bln', function (obj) {
+ *   if ('boolean' === lib.of(obj)) return true;
+ *   var blns = [ 'yes', 'no', 'true', 'false', 1, 0 ];
+ *   if ('string' === lib.of(obj)) obj = obj.toLowerCase();
+ *   return !! ~blns.indexOf(obj);
+ * });
+ * ```
+ *
+ * @param {String} type
+ * @param {RegExp|Function} test
+ * @api public
+ */
+
+Library.prototype.define = function (type, test) {
+  if (arguments.length === 1) return this.tests[type];
+  this.tests[type] = test;
+  return this;
+};
+
+/**
+ * #### .test (obj, test)
+ *
+ * Assert that an object is of type. Will first
+ * check natives, and if that does not pass it will
+ * use the user defined custom tests.
+ *
+ * ```js
+ * assert(lib.test('1', 'int'));
+ * assert(lib.test('yes', 'bln'));
+ * ```
+ *
+ * @param {Mixed} object
+ * @param {String} type
+ * @return {Boolean} result
+ * @api public
+ */
+
+Library.prototype.test = function (obj, type) {
+  if (type === getType(obj)) return true;
+  var test = this.tests[type];
+
+  if (test && 'regexp' === getType(test)) {
+    return test.test(obj);
+  } else if (test && 'function' === getType(test)) {
+    return test(obj);
+  } else {
+    throw new ReferenceError('Type test "' + type + '" not defined or invalid.');
+  }
+};
+
+},{}],11:[function(require,module,exports){
+'use strict';
+
+var toString = Object.prototype.toString;
+
+/**
+ * Extract names from functions.
+ *
+ * @param {Function} fn The function who's name we need to extract.
+ * @returns {String}
+ * @api public
+ */
+module.exports = function name(fn) {
+  if ('string' === typeof fn.displayName && fn.constructor.name) {
+    return fn.displayName;
+  } else if ('string' === typeof fn.name && fn.name) {
+    return fn.name;
+  }
+
+  //
+  // Check to see if the constructor has a name.
+  //
+  if (
+       'object' === typeof fn
+    && fn.constructor
+    && 'string' === typeof fn.constructor.name
+  ) return fn.constructor.name;
+
+  //
+  // toString the given function and attempt to parse it out of it, or determine
+  // the class.
+  //
+  var named = fn.toString()
+    , type = toString.call(fn).slice(8, -1);
+
+  if ('Function' === type) {
+    named = named.substring(named.indexOf('(') + 1, named.indexOf(')'));
+  } else {
+    named = type;
+  }
+
+  return named || 'anonymous';
+};
+
+},{}],12:[function(require,module,exports){
+(function (process){
+module.exports = !!(typeof process != 'undefined' && process.versions && process.versions.node);
+
+}).call(this,require('_process'))
+},{"_process":6}],13:[function(require,module,exports){
+module.exports = function inspect_ (obj, opts, depth, seen) {
+    if (!opts) opts = {};
+    
+    var maxDepth = opts.depth === undefined ? 5 : opts.depth;
+    if (depth === undefined) depth = 0;
+    if (depth >= maxDepth && maxDepth > 0
+    && obj && typeof obj === 'object') {
+        return '[Object]';
+    }
+    
+    if (seen === undefined) seen = [];
+    else if (indexOf(seen, obj) >= 0) {
+        return '[Circular]';
+    }
+    
+    function inspect (value, from) {
+        if (from) {
+            seen = seen.slice();
+            seen.push(from);
+        }
+        return inspect_(value, opts, depth + 1, seen);
+    }
+    
+    if (typeof obj === 'string') {
+        return inspectString(obj);
+    }
+    else if (typeof obj === 'function') {
+        var name = nameOf(obj);
+        return '[Function' + (name ? ': ' + name : '') + ']';
+    }
+    else if (obj === null) {
+        return 'null';
+    }
+    else if (isElement(obj)) {
+        var s = '<' + String(obj.nodeName).toLowerCase();
+        var attrs = obj.attributes || [];
+        for (var i = 0; i < attrs.length; i++) {
+            s += ' ' + attrs[i].name + '="' + quote(attrs[i].value) + '"';
+        }
+        s += '>';
+        if (obj.childNodes && obj.childNodes.length) s += '...';
+        s += '</' + String(obj.nodeName).toLowerCase() + '>';
+        return s;
+    }
+    else if (isArray(obj)) {
+        if (obj.length === 0) return '[]';
+        var xs = Array(obj.length);
+        for (var i = 0; i < obj.length; i++) {
+            xs[i] = has(obj, i) ? inspect(obj[i], obj) : '';
+        }
+        return '[ ' + xs.join(', ') + ' ]';
+    }
+    else if (isError(obj)) {
+        var parts = [];
+        for (var key in obj) {
+            if (!has(obj, key)) continue;
+            
+            if (/[^\w$]/.test(key)) {
+                parts.push(inspect(key) + ': ' + inspect(obj[key]));
+            }
+            else {
+                parts.push(key + ': ' + inspect(obj[key]));
+            }
+        }
+        if (parts.length === 0) return '[' + obj + ']';
+        return '{ [' + obj + '] ' + parts.join(', ') + ' }';
+    }
+    else if (typeof obj === 'object' && typeof obj.inspect === 'function') {
+        return obj.inspect();
+    }
+    else if (typeof obj === 'object' && !isDate(obj) && !isRegExp(obj)) {
+        var xs = [], keys = [];
+        for (var key in obj) {
+            if (has(obj, key)) keys.push(key);
+        }
+        keys.sort();
+        for (var i = 0; i < keys.length; i++) {
+            var key = keys[i];
+            if (/[^\w$]/.test(key)) {
+                xs.push(inspect(key) + ': ' + inspect(obj[key], obj));
+            }
+            else xs.push(key + ': ' + inspect(obj[key], obj));
+        }
+        if (xs.length === 0) return '{}';
+        return '{ ' + xs.join(', ') + ' }';
+    }
+    else return String(obj);
+};
+
+function quote (s) {
+    return String(s).replace(/"/g, '&quot;');
+}
+
+function isArray (obj) { return toStr(obj) === '[object Array]' }
+function isDate (obj) { return toStr(obj) === '[object Date]' }
+function isRegExp (obj) { return toStr(obj) === '[object RegExp]' }
+function isError (obj) { return toStr(obj) === '[object Error]' }
+
+function has (obj, key) {
+    if (!{}.hasOwnProperty) return key in obj;
+    return {}.hasOwnProperty.call(obj, key);
+}
+
+function toStr (obj) {
+    return Object.prototype.toString.call(obj);
+}
+
+function nameOf (f) {
+    if (f.name) return f.name;
+    var m = f.toString().match(/^function\s*([\w$]+)/);
+    if (m) return m[1];
+}
+
+function indexOf (xs, x) {
+    if (xs.indexOf) return xs.indexOf(x);
+    for (var i = 0, l = xs.length; i < l; i++) {
+        if (xs[i] === x) return i;
+    }
+    return -1;
+}
+
+function isElement (x) {
+    if (!x || typeof x !== 'object') return false;
+    if (typeof HTMLElement !== 'undefined' && x instanceof HTMLElement) {
+        return true;
+    }
+    return typeof x.nodeName === 'string'
+        && typeof x.getAttribute === 'function'
+    ;
+}
+
+function inspectString (str) {
+    var s = str.replace(/(['\\])/g, '\\$1').replace(/[\x00-\x1f]/g, lowbyte);
+    return "'" + s + "'";
+    
+    function lowbyte (c) {
+        var n = c.charCodeAt(0);
+        var x = { 8: 'b', 9: 't', 10: 'n', 12: 'f', 13: 'r' }[n];
+        if (x) return '\\' + x;
+        return '\\x' + (n < 0x10 ? '0' : '') + n.toString(16);
+    }
+}
+
+},{}],14:[function(require,module,exports){
+/**
+ * ### .get(obj, path)
+ *
+ * Retrieve the value in an object given a string path.
+ *
+ * ```js
+ * var obj = {
+ *     prop1: {
+ *         arr: ['a', 'b', 'c']
+ *       , str: 'Hello'
+ *     }
+ *   , prop2: {
+ *         arr: [ { nested: 'Universe' } ]
+ *       , str: 'Hello again!'
+ *     }
+ * };
+ * ```
+ *
+ * The following would be the results.
+ *
+ * ```js
+ * var properties = require('tea-properties');
+ * properties.get(obj, 'prop1.str'); // Hello
+ * properties.get(obj, 'prop1.att[2]'); // b
+ * properties.get(obj, 'prop2.arr[0].nested'); // Universe
+ * ```
+ *
+ * @param {Object} object
+ * @param {String} path
+ * @return {Object} value or `undefined`
+ */
+
+exports.get = function(obj, path) {
+  var parsed = exports.parse(path);
+  return getPathValue(parsed, obj);
+};
+
+/**
+ * ### .set(path, value, object)
+ *
+ * Define the value in an object at a given string path.
+ *
+ * ```js
+ * var obj = {
+ *     prop1: {
+ *         arr: ['a', 'b', 'c']
+ *       , str: 'Hello'
+ *     }
+ *   , prop2: {
+ *         arr: [ { nested: 'Universe' } ]
+ *       , str: 'Hello again!'
+ *     }
+ * };
+ * ```
+ *
+ * The following would be acceptable.
+ *
+ * ```js
+ * var properties = require('tea-properties');
+ * properties.set(obj, 'prop1.str', 'Hello Universe!');
+ * properties.set(obj, 'prop1.arr[2]', 'B');
+ * properties.set(obj, 'prop2.arr[0].nested.value', { hello: 'universe' });
+ * ```
+ *
+ * @param {Object} object
+ * @param {String} path
+ * @param {Mixed} value
+ * @api public
+ */
+
+exports.set = function(obj, path, val) {
+  var parsed = exports.parse(path);
+  setPathValue(parsed, val, obj);
+};
+
+/*!
+ * Helper function used to parse string object
+ * paths. Use in conjunction with `getPathValue`.
+ *
+ *  var parsed = parsePath('myobject.property.subprop');
+ *
+ * ### Paths:
+ *
+ * * Can be as near infinitely deep and nested
+ * * Arrays are also valid using the formal `myobject.document[3].property`.
+ *
+ * @param {String} path
+ * @returns {Object} parsed
+ */
+
+exports.parse = function(path) {
+  var str = (path || '').replace(/\[/g, '.[');
+  var parts = str.match(/(\\\.|[^.]+?)+/g);
+
+  return parts.map(function(value) {
+    var re = /\[(\d+)\]$/
+      , mArr = re.exec(value)
+    if (mArr) return { i: parseFloat(mArr[1]) };
+    else return { p: value };
+  });
+};
+
+/*!
+ * Companion function for `parsePath` that returns
+ * the value located at the parsed address.
+ *
+ *  var value = getPathValue(parsed, obj);
+ *
+ * @param {Object} parsed definition from `parsePath`.
+ * @param {Object} object to search against
+ * @returns {Object|Undefined} value
+ */
+
+function getPathValue(parsed, obj) {
+  var tmp = obj;
+  var res;
+
+  for (var i = 0, l = parsed.length; i < l; i++) {
+    var part = parsed[i];
+    if (tmp) {
+      if (defined(part.p)) tmp = tmp[part.p];
+      else if (defined(part.i)) tmp = tmp[part.i];
+      if (i == (l - 1)) res = tmp;
+    } else {
+      res = undefined;
+    }
+  }
+
+  return res;
+};
+
+/*!
+ * Companion function for `parsePath` that sets
+ * the value located at a parsed address.
+ *
+ *  setPathValue(parsed, 'value', obj);
+ *
+ * @param {Object} parsed definition from `parsePath`
+ * @param {*} value to use upon set
+ * @param {Object} object to search and define on
+ * @api private
+ */
+
+function setPathValue(parsed, val, obj) {
+  var tmp = obj;
+  var i = 0;
+  var l = parsed.length;
+  var part;
+
+  for (; i < l; i++) {
+    part = parsed[i];
+
+    if (defined(tmp) && i == (l - 1)) {
+      var x = defined(part.p) ? part.p : part.i;
+      tmp[x] = val;
+    } else if (defined(tmp)) {
+      if (defined(part.p) && tmp[part.p]) {
+        tmp = tmp[part.p];
+      } else if (defined(part.i) && tmp[part.i]) {
+        tmp = tmp[part.i];
+      } else {
+        var next = parsed[i + 1];
+        var x = defined(part.p) ? part.p : part.i;
+        var y = defined(next.p) ? {} : [];
+        tmp[x] = y;
+        tmp = tmp[x];
+      }
+    } else {
+      if (i == (l - 1)) tmp = val;
+      else if (defined(part.p)) tmp = {};
+      else if (defined(part.i)) tmp = [];
+    }
+  }
+};
+
+/*!
+ * Check if `val` is defined.
+ *
+ * @param {Mixed} val
+ * @returns {Boolean} `true` if defined
+ * @api private
+ */
+
+function defined(val) {
+  return !(!val && 'undefined' === typeof val);
+}
+
+},{}],15:[function(require,module,exports){
+var failingCode = require("failing-code");
+var format = require("format-text");
+var leftpad = require("left-pad");
+var style = require("style-format");
+
+var template = style('{bold}{red}{title} {grey}{filename}{reset}\n'
+                     + '    {red}{v}\n'
+                     + '    {grey}{previousLineNo}. {previousLine}\n'
+                     + '    {reset}{failingLineNo}. {failingLine}\n'
+                     + '    {grey}{nextLineNo}. {nextLine}\n'
+                     + '    {red}{^}{reset}\n'
+                     + '    {stack}\n'
+                     + '{reset}');
+
+module.exports = prettifyError;
+
+function prettifyError (error, shift, code) {
+  if (!error || !error.stack) return;
+
+  code || (code = failingCode(error, undefined, shift));
+
+  if (!code) return;
+
+  var previousLineNo = String(code[0].line);
+  var failingLineNo = String(code[1].line);
+  var nextLineNo = String(code[2].line);
+  var linumlen = Math.max(previousLineNo.length,
+                          failingLineNo.length,
+                          nextLineNo.length);
+
+  return format(template, {
+    title: error.message,
+    filename: code[1].filename,
+    previousLine: code[0].code,
+    previousLineNo: leftpad(previousLineNo, linumlen),
+    previousColNo: code[0].col,
+    failingLine: code[1].code,
+    failingLineNo: leftpad(failingLineNo, linumlen),
+    failingColNo: code[1].col,
+    nextLine: code[2].code,
+    nextLineNo: leftpad(nextLineNo, linumlen),
+    nextColNo: code[2].col,
+    stack: tabStack(error.stack),
+    '^': showColumn(code, linumlen - failingLineNo.length, '^'),
+    'v': showColumn(code, linumlen - failingLineNo.length, 'v')
+  });
+}
+
+function showColumn (code, tabn, ch) {
+  var result = '';
+  var i = String(code[1].line).length + code[1].col + 1 + tabn;
+
+  while (i--) {
+    result += ' ';
+  }
+
+  return result + ch;
+}
+
+function tabStack (stack) {
+  return stack.replace(/\n/g, '\n    ');
+}
+
+},{"failing-code":16,"format-text":18,"left-pad":19,"style-format":20}],16:[function(require,module,exports){
+var isNode = require("is-node");
+var failingLine = require("failing-line");
+
+var fs;
+var nodeRequire;
+
+if (isNode) {
+  nodeRequire = require;
+  fs = nodeRequire('fs');
+  nodeRequire = null;
+}
+
+module.exports = failingCode;
+
+function failingCode (error, doc, shift) {
+  var ln = failingLine(error, shift);
+
+  if (!ln) return;
+
+  if (!doc && fs) {
+    try {
+      doc = fs.readFileSync(ln.filename).toString();
+    } catch (readError) {
+      return undefined;
+    }
+  }
+
+  var result = [];
+  var lines = doc.split('\n');
+
+  var i = ln.line - 3;
+  while (++i < ln.line + 1) {
+    if (i + 1 != ln.line) {
+      result.push({
+        line: ln.line - (ln.line - i -1),
+        code: lines[i]
+      });
+      continue;
+    }
+
+    result.push({
+      line: ln.line,
+      col: ln.col,
+      fn: ln.fn,
+      filename: ln.filename,
+      code: lines[i],
+      failed: true
+    });
+  }
+
+  return result;
+}
+
+},{"failing-line":17,"is-node":12}],17:[function(require,module,exports){
+module.exports = detect;
+
+function detect (error, shift) {
+  if (!error || !error.stack) return;
+
+  if (/  at /.test(error.stack)) return v8(error, shift);
+
+  if (/:\d+:\d+$/.test(error.stack)) return safari(error, shift);
+
+  return firefox(error, shift);
+}
+
+function safari (error, shift) {
+  var index = 0;
+  if (shift) index += shift;
+
+  var fn, filename, line, col;
+  var lines = error.stack.split('\n');
+  var stack = lines[index] || lines[0];
+
+  var fields = stack.split(/\:(\d+)\:(\d+)$/);
+  var numbers = fields.slice(1, 3);
+  fields = fields[0].split('@');
+
+  return {
+    fn: fields[0],
+    filename: fields[1],
+    line: Number(numbers[0]),
+    col: Number(numbers[1])
+  };
+}
+
+function v8 (error, shift) {
+  if (!error || !error.stack) return;
+
+  var index = 1;
+  if (shift) index += shift;
+
+  var fn, filename, line, col;
+  var lines = error.stack.split('\n');
+  var stack = lines[index] || lines[1];
+
+  if (!stack) return;
+
+  var match = stack.match(/at ([\(\)\w\.<>\[\]\s]+) \((.+):(\d+):(\d+)/);
+
+  if (!match) {
+    match = stack.match(/at (.+):(\d+):(\d+)/);
+    if (!match) return undefined;
+
+    filename = match[1];
+    line = Number(match[2]);
+    col = Number(match[3]);
+  } else {
+    fn = match[1];
+    filename = match[2];
+    line = Number(match[3]);
+    col = Number(match[4]);
+  }
+
+  return {
+    fn: fn,
+    filename: filename,
+    line: line,
+    col: col
+  };
+}
+
+function firefox (error, shift) {
+  var index = 0;
+  if (shift) index += shift;
+
+  var fn, filename, line, col;
+  var lines = error.stack.split('\n');
+  var stack = lines[index] || lines[0];
+
+  var fields = stack.split(/\:(\d+)$/);
+  var numbers = fields.slice(1, 2);
+  fields = fields[0].split('@');
+
+  if (index == 0) {
+    col = error.columnNumber;
+  }
+
+  return {
+    fn: fields[0],
+    filename: fields[1],
+    line: Number(numbers[0]),
+    col: col
+  };
+}
+
+},{}],18:[function(require,module,exports){
+module.exports = format;
+
+function format(text) {
+  var context;
+
+  if (typeof arguments[1] == 'object' && arguments[1]) {
+    context = arguments[1];
+  } else {
+    context = Array.prototype.slice.call(arguments, 1);
+  }
+
+  return String(text).replace(/\{?\{([^{}]+)}}?/g, replace(context));
+};
+
+function replace (context, nil){
+  return function (tag, name) {
+    if (tag.substring(0, 2) == '{{' && tag.substring(tag.length - 2) == '}}') {
+      return '{' + name + '}';
+    }
+
+    if (!context.hasOwnProperty(name)) {
+      return tag;
+    }
+
+    if (typeof context[name] == 'function') {
+      return context[name]();
+    }
+
+    return context[name];
+  }
+}
+
+},{}],19:[function(require,module,exports){
+module.exports = leftpad;
+
+function leftpad (str, len) {
+  var i = -1;
+  len = len - str.length;
+
+  while (++i < len) {
+    str = ' ' + str;
+  }
+
+  return str;
+}
+
+},{}],20:[function(require,module,exports){
+var format = require("format-text");
+var ansi = require("ansi-codes");
+
+module.exports = styleFormat;
+
+function styleFormat (text) {
+  return format(text, ansi);
+}
+
+},{"ansi-codes":21,"format-text":18}],21:[function(require,module,exports){
+module.exports     = {
+  reset            : "\033[0m",
+  bold             : "\033[1m",
+  italic           : "\033[3m",
+  blink            : "\033[5m",
+  underline        : "\033[4m",
+  underlineOff     : "\033[24m",
+  inverse          : "\033[7m",
+  inverseOff       : "\033[27m",
+  strikethrough    : "\033[9m",
+  strikethroughOff : "\033[29m",
+
+  def              : "\033[39m",
+  white            : "\033[37m",
+  black            : "\033[30m",
+  grey             : "\x1B[90m",
+  red              : "\033[31m",
+  green            : "\033[32m",
+  blue             : "\033[34m",
+  yellow           : "\033[33m",
+  magenta          : "\033[35m",
+  cyan             : "\033[36m",
+
+  defBg            : "\033[49m",
+  whiteBg          : "\033[47m",
+  blackBg          : "\033[40m",
+  redBg            : "\033[41m",
+  greenBg          : "\033[42m",
+  blueBg           : "\033[44m",
+  yellowBg         : "\033[43m",
+  magentaBg        : "\033[45m",
+  cyanBg           : "\033[46m",
+  
+  brightBlack      : "\033[90m",
+  brightRed        : "\033[91m",
+  brightGreen      : "\033[92m",
+  brightYellow     : "\033[93m",
+  brightBlue       : "\033[94m",
+  brightMagenta    : "\033[95m",
+  brightCyan       : "\033[96m",
+  brightWhite      : "\033[97m",
+  
+  brightBlackBg    : "\033[100m",
+  brightRedBg      : "\033[101m",
+  brightGreenBg    : "\033[102m",
+  brightYellowBg   : "\033[103m",
+  brightBlueBg     : "\033[104m",
+  brightMagentaBg  : "\033[105m",
+  brightCyanBg     : "\033[106m",
+  brightWhiteBg    : "\033[107m"
+}
+
+},{}]},{},[1])(1)
+});
\ No newline at end of file
diff --git a/debian/tests/test_modules/assume/index.js b/debian/tests/test_modules/assume/index.js
new file mode 100644
index 0000000..0d904ab
--- /dev/null
+++ b/debian/tests/test_modules/assume/index.js
@@ -0,0 +1,1034 @@
+'use strict';
+
+var stringify = require('object-inspect')
+  , pretty = require('prettify-error')
+  , displayName = require('fn.name')
+  , pathval = require('pathval')
+  , nodejs = require('is-node')
+  , deep = require('deep-eql');
+
+var undefined
+  , called = 0
+  , toString = Object.prototype.toString
+  , hasOwn = Object.prototype.hasOwnProperty;
+
+/**
+ * Get class information for a given type.
+ *
+ * @param {Mixed} of Type to check.
+ * @returns {String} The name of the type.
+ * @api private
+ */
+function type(of) {
+  if (Buffer.isBuffer(of)) return 'buffer';
+  if (of === undefined) return 'undefined';
+  if (of === null) return 'null';
+  if (of !== of) return 'nan';
+
+  return toString.call(of).slice(8, -1).toLowerCase();
+}
+
+/**
+ * Determine the size of a collection.
+ *
+ * @param {Mixed} collection The object we want to know the size of.
+ * @returns {Number} The size of the collection.
+ * @api private
+ */
+function size(collection) {
+  var x, i = 0;
+
+  if ('object' === type(collection)) {
+    if ('number' === type(collection.length)) return collection.length;
+
+    for (x in collection) {
+      if (hasOwn.call(collection, x)) i++;
+    }
+
+    return i;
+  }
+
+  try { return +collection.length || 0; }
+  catch (e) { return 0; }
+}
+
+/**
+ * Iterate over each item in an array.
+ *
+ * @param {Array} arr Array to iterate over.
+ * @param {Function} fn Callback for each item.
+ * @api private
+ */
+function each(what, fn) {
+  if ('array' === type(what)) {
+    for (var i = 0, length = what.length; i < length; i++) {
+      if (false === fn(what[i], i, what)) break;
+    }
+  } else {
+    for (var key in what) {
+      if (false === fn(what[key], key, what)) break;
+    }
+  }
+}
+
+/**
+ * Return a formatter function which compiles the expectation message. The
+ * message can contain various of patterns which will be replaced with
+ * a stringified/parsed version of the supplied argument for that given
+ * placeholder pattern. The following patterns are supported:
+ *
+ * - %% : Escape the % so you can write %d in your messages as %%d
+ * - %d : Cast argument in to a number.
+ * - %s : Cast argument in to a string.
+ * - %f : Transform function in to the name of the function.
+ * - %j : Transform object to a string.
+ *
+ * @param {String} expectation The expectation message.
+ * @returns {Function}
+ * @api private
+ */
+function format() {
+  var args = Array.prototype.slice.call(arguments, 0)
+    , expectation = args.shift()
+    , length = args.length
+    , i = 0;
+
+  return function compile(not) {
+    if (not) expectation = expectation.replace(/@/g, 'not');
+    else expectation = expectation.replace(/@\s/g, '');
+
+    return expectation.replace(/%[sdjf%]/g, function replace(char) {
+      if (i >= length) return char;
+
+      switch (char) {
+        case '%%':
+        return '%';
+
+        case '%s':
+        return String(args[i++]);
+
+        case '%d':
+        return Number(args[i++]);
+
+        case '%f':
+        return displayName(args[i++]);
+
+        case '%j':
+        try { return stringify(args[i++]); }
+        catch (e) { return '<error was thrown: '+ e.message +'>'; }
+
+        default: return char;
+      }
+    });
+  };
+}
+
+/**
+ * Assert values.
+ *
+ * Flags:
+ *
+ * - **stacktrace**: Include stacktrace in the assertion.
+ * - **diff**: Attempt to show the difference in object/values so we know why
+ *   the assertion failed.
+ * - **sliceStack**: The amount of stacks we should slice off errors messages.
+ *
+ * @constructor
+ * @param {Mixed} value Value we need to assert.
+ * @param {Object} flags Assertion flags.
+ * @api public
+ */
+function Assert(value, flags) {
+  if (!(this instanceof Assert)) return new Assert(value, flags);
+  flags = flags || {};
+
+  this.stacktrace = 'stacktrace' in flags ? flags.stacktrace : Assert.config.includeStack;
+  this.sliceStack = 'slice' in flags ? flags.slice : Assert.config.sliceStack;
+  this.diff = 'diff' in flags ? flags.diff : Assert.config.showDiff;
+
+  //
+  // These flags are by the alias function so we can generate .not and .deep
+  // properties which are basically new Assert instances with these flags set.
+  //
+  for (var alias in Assert.flags) {
+    this[alias] = alias in flags ? flags[alias] : false;
+  }
+
+  this.value = value;
+
+  Assert.assign(this)('to, be, been, is, and, has, have, with, that, at, of, same, does, itself, which');
+  Assert.alias(value, this);
+}
+
+/**
+ * Attempt to mimic the configuration API of chai.js so it's dead simple to
+ * migrate from chai.js to assume.
+ *
+ * @type {Object}
+ * @public
+ */
+Assert.config = {
+  includeStack: true,     // mapped to `stacktrace` as default value.
+  showDiff: true,         // mapped to `diff` as default value.
+  sliceStack: 2           // Number of stacks that we should slice of the err stack..
+};
+
+/**
+ * List of flags and properties that need to be created for chaining purposes.
+ * Plugins could add extra properties that needed to be chained as well.
+ *
+ * @type {Object}
+ * @public
+ */
+Assert.flags = {
+  _not: 'doesnt, not, dont',
+  _deep: 'deep, deeply, strict, strictly'
+};
+
+/**
+ * Certain assertions can be disabled based on their environment that they are
+ * executing in. This object allows you in spect which of these conditional
+ * assertions are supported.
+ *
+ * @type {Object}
+ * @public
+ */
+Assert.supports = (function detect() {
+  var supports = {};
+
+  try {
+    eval('(function*(){})()');
+    supports.generators = true;
+  } catch (e) {
+    supports.generators = false;
+  }
+
+  try {
+    eval('%GetV8Version()');
+    supports.native = true;
+  } catch (e) {
+    supports.native = false;
+  }
+
+  return supports;
+}(/* Douglas Crockford wants the dog balls inside youtu.be/taaEzHI9xyY#t=2020s */));
+
+/**
+ * Assign values to a given thing.
+ *
+ * @param {Mixed} where Where do the new properties need to be assigned on.
+ * @returns {Function}
+ * @api public
+ */
+Assert.assign = function assign(where) {
+  return function assigns(aliases, value) {
+    if ('string' === typeof aliases) {
+      if (~aliases.indexOf(',')) aliases = aliases.split(/[\s|\,]+/);
+      else aliases = [aliases];
+    }
+
+    for (var i = 0, length = aliases.length; i < length; i++) {
+      where[aliases[i]] = value || where;
+    }
+
+    return where;
+  };
+};
+
+/**
+ * Add aliases to the given constructed asserts. This allows us to chain
+ * assertion calls together.
+ *
+ * @param {Mixed} value Value that we need to assert.
+ * @param {Assert} assert The constructed assert instance.
+ * @returns {Assert} The given assert instance.
+ * @api private
+ */
+Assert.alias = function alias(value, assert) {
+  var assign = Assert.assign(assert)
+    , flags, flag, prop;
+
+  for (prop in Assert.flags) {
+    if (!hasOwn.call(Assert.flags, prop)) continue;
+
+    if (!assert[prop]) {
+      flags = {};
+
+      for (flag in Assert.flags) {
+        if (!hasOwn.call(Assert.flags, flag)) continue;
+        flags[flag] = assert[flag];
+      }
+
+      //
+      // Add some default values to the flags.
+      //
+      flags.stacktrace = assert.stacktrace;
+      flags.diff = assert.diff;
+      flags[prop] = true;
+
+      assign(Assert.flags[prop], new Assert(value, flags));
+    } else assign(Assert.flags);
+  }
+
+  return assert;
+};
+
+/**
+ * API sugar of adding aliased prototypes to the Assert. This makes the code
+ * a bit more workable and human readable.
+ *
+ * @param {String|Array} aliases List of methods.
+ * @param {Function} fn Actual assertion function.
+ * @returns {Assert}
+ * @api public
+ */
+Assert.add = Assert.assign(Assert.prototype);
+
+/**
+ * Asserts if the given value is the correct type. We need to use
+ * Object.toString here because there are some implementation bugs the `typeof`
+ * operator:
+ *
+ * - Chrome <= 9: /Regular Expressions/ are evaluated to `function`
+ *
+ * As well as all common flaws like Arrays being seen as Objects etc. This
+ * eliminates all these edge cases.
+ *
+ * @param {String} of Type of class it should equal
+ * @param {String} msg Reason of failure.
+ * @returns {Assert}
+ * @api public
+ */
+Assert.add('a, an', function typecheck(of, msg) {
+  of = of.toString().toLowerCase();
+
+  var value = type(this.value)
+    , expect = format('`%j` (%s) to @ be a %s', this.value, value, of);
+
+  return this.test(value === of, msg, expect);
+});
+
+/**
+ * Asserts that the value is instanceof the given constructor.
+ *
+ * @param {Function} constructor Constructur the value should inherit from.
+ * @param {String} msg Reason of failure.
+ * @returns {Assert}
+ * @api public
+ */
+Assert.add('instanceOf, instanceof, inherits, inherit', function of(constructor, msg) {
+  var expect = format('%f to @ be an instanceof %f', this.value, constructor);
+
+  return this.test(this.value instanceof constructor, msg, expect);
+});
+
+/**
+ * Assert that the value includes the given value.
+ *
+ * @param {Mixed} val Value to match.
+ * @param {String} msg Reason of failure.
+ * @returns {Assert}
+ * @api public
+ */
+Assert.add('include, includes, contain, contains', function contain(val, msg) {
+  var includes = false
+    , of = type(this.value)
+    , expect = format('`%j` to @ include %j', this.value, val);
+
+  switch (of) {
+    case 'array':
+      for (var i = 0, length = this.value.length; i < length; i++) {
+        if (val === this.value[i]) {
+          includes = true;
+          break;
+        }
+      }
+    break;
+
+    case 'object':
+      if (val in this.value) {
+        includes = true;
+      }
+    break;
+
+    case 'string':
+      if (~this.value.indexOf(val)) {
+        includes = true;
+      }
+    break;
+  }
+
+  return this.test(includes === true, msg, expect);
+});
+
+/**
+ * Assert that the value is truthy.
+ *
+ * @param {String} msg Reason of failure.
+ * @returns {Assert}
+ * @api public
+ */
+Assert.add('ok, okay, truthy, truly', function ok(msg) {
+  var expect = format('`%j` to @ be truthy', this.value);
+
+  return this.test(Boolean(this.value), msg, expect);
+});
+
+/**
+ * Assert that the value is falsey.
+ *
+ * @param {String} msg Reason of failure.
+ * @returns {Assert}
+ * @api public
+ */
+Assert.add('falsely, falsey, falsy', function nope(msg) {
+  var expect = format('`%j` to @ be falsely', this.value);
+
+  return this.test(Boolean(this.value) === false, msg, expect);
+});
+
+/**
+ * Assert that the value is `true`.
+ *
+ * @param {String} msg Reason of failure.
+ * @returns {Assert}
+ * @api public
+ */
+Assert.add('true', function ok(msg) {
+  var expect = format('`%j` to @ equal (===) true', this.value);
+
+  return this.test(this.value === true, msg, expect);
+});
+
+/**
+ * Assert that the value is `true`.
+ *
+ * @param {String} msg Reason of failure.
+ * @returns {Assert}
+ * @api public
+ */
+Assert.add('false', function nope(msg) {
+  var expect = format('`%j` to @ equal (===) false', this.value);
+
+  return this.test(this.value === false, msg, expect);
+});
+
+/**
+ * Assert that the value exists.
+ *
+ * @param {String} msg Reason of failure.
+ * @returns {Assert}
+ * @api public
+ */
+Assert.add('exists, exist', function exists(msg) {
+  var expect = format('`%j` to @ exist', this.value);
+
+  return this.test(this.value != null, msg, expect);
+});
+
+/**
+ * Asserts that the value's length is the given value.
+ *
+ * @param {Number} value Size of the value.
+ * @param {String} msg Reason of failure.
+ * @returns {Assert}
+ * @api public
+ */
+Assert.add('length, lengthOf, size', function length(value, msg) {
+  var expect = format('`%j` to @ have a length of %d', this.value, value);
+
+  return this.test(size(this.value) === +value, msg, expect);
+});
+
+/**
+ * Asserts that the value's length is 0 or doesn't contain any enumerable keys.
+ *
+ * @param {String} msg Reason of failure.
+ * @returns {Assert}
+ * @api public
+ */
+Assert.add('empty', function empty(msg) {
+  var expect = format('`%j` to @ be empty', this.value);
+
+  return this.test(size(this.value) === 0, msg, expect);
+});
+
+/**
+ * Assert that the value is greater than the specified value.
+ *
+ * @param {Number} value The greater than value.
+ * @param {String} msg Reason of failure.
+ * @returns {Assert}
+ * @api public
+ */
+Assert.add('above, gt, greater, greaterThan', function above(value, msg) {
+  var amount = type(this.value) !== 'number' ? size(this.value) : this.value
+    , expect = format('%d to @ be greater than %d', amount, value);
+
+  return this.test(amount > value, msg, expect);
+});
+
+/**
+ * Assert that the value is equal or greater than the specified value.
+ *
+ * @param {Number} value The specified value.
+ * @param {String} msg Reason of failure.
+ * @returns {Assert}
+ * @api public
+ */
+Assert.add('least, gte, atleast', function least(value, msg) {
+  var amount = type(this.value) !== 'number' ? size(this.value) : this.value
+    , expect = format('%d to @ be greater or equal to %d', amount, value);
+
+  return this.test(amount >= value, msg, expect);
+});
+
+/**
+ * Assert that the value starts with the given value.
+ *
+ * @param {String|Array} value String it should start with.
+ * @param {String} msg Reason of failure.
+ * @returns {Assert}
+ * @api public
+ */
+Assert.add('start, starts, startsWith, startWith', function start(value, msg) {
+  var expect = format('`%j` to @ start with %j', this.value, value);
+
+  return this.test(0 === this.value.indexOf(value), msg, expect);
+});
+
+/**
+ * Assert that the value ends with the given value.
+ *
+ * @param {String} value String it should start with.
+ * @param {String} msg Reason of failure.
+ * @returns {Assert}
+ * @api public
+ */
+Assert.add('end, ends, endsWith, endWith', function end(value, msg) {
+  var index = this.value.indexOf(value, this.value.length - value.length)
+    , expect = format('`%j` to @ end with %j', this.value, value);
+
+  return this.test(index >= 0, msg, expect);
+});
+
+/**
+ * Assert a floating point number is near the give value within the delta
+ * margin.
+ *
+ * @param {Number} value The specified value.
+ * @param {Number} delta Radius.
+ * @param {String} msg Reason of failure.
+ * @returns {Assert}
+ * @api public
+ */
+Assert.add('closeTo, close, approximately, near', function close(value, delta, msg) {
+  var expect = format('`%j` to @ be close to %d ± %d', this.value, value, delta);
+
+  return this.test(Math.abs(this.value - value) <= delta, msg, expect);
+});
+
+/**
+ * Assert that the value is below the specified value.
+ *
+ * @param {Number} value The specified value.
+ * @param {String} msg Reason of failure.
+ * @returns {Assert}
+ * @api public
+ */
+Assert.add('below, lt, less, lessThan', function below(value, msg) {
+  var amount = type(this.value) !== 'number' ? size(this.value) : this.value
+    , expect = format('%d to @ be less than %d', amount, value);
+
+  return this.test(amount < value, msg, expect);
+});
+
+/**
+ * Assert that the value is below or equal to the specified value.
+ *
+ * @param {Number} value The specified value.
+ * @param {String} msg Reason of failure.
+ * @returns {Assert}
+ * @api public
+ */
+Assert.add('most, lte, atmost', function most(value, msg) {
+  var amount = type(this.value) !== 'number' ? size(this.value) : this.value
+    , expect = format('%d to @ be less or equal to %d', amount, value);
+
+  return this.test(amount <= value, msg, expect);
+});
+
+/**
+ * Assert that that value is within the given range.
+ *
+ * @param {Number} start Lower bound.
+ * @param {Number} finish Upper bound.
+ * @param {String} msg Reason of failure.
+ * @returns {Assert}
+ * @api public
+ */
+Assert.add('within, between', function within(start, finish, msg) {
+  var amount = type(this.value) !== 'number' ? size(this.value) : this.value
+    , expect = format('%d to @ be greater or equal to %d and @ be less or equal to %d', amount, start, finish);
+
+  return this.test(amount >= start && amount <= finish, msg, expect);
+});
+
+/**
+ * Assert that the value has an own property with the given prop.
+ *
+ * @param {String} prop Property name.
+ * @param {String} msg Reason of failure.
+ * @returns {Assert}
+ * @api public
+ */
+Assert.add('hasOwn, own, ownProperty, haveOwnProperty, property, owns, hasown', function has(prop, value, msg) {
+  var expect = format('`%j` @ to have own property %s', this.value, prop)
+    , tested = this.test(hasOwn.call(this.value, prop), msg, expect);
+
+  return arguments.length > 1
+    ? this.clone(this.value[prop]).equals(value)
+    : tested;
+});
+
+/**
+ * Asserts that the value matches a regular expression.
+ *
+ * @param {RegExp} regex Regular expression to match against.
+ * @param {String} msg Reason of failure.
+ * @returns {Assert}
+ * @api public
+ */
+Assert.add('match, matches', function test(regex, msg) {
+  if ('string' === typeof regex) regex = new RegExp(regex);
+
+  var expect = format('`%j` to @ match %j', this.value, regex);
+
+  return this.test(!!regex.test(this.value), msg, expect);
+});
+
+/**
+ * Assert that the value equals a given thing.
+ *
+ * @param {Mixed} thing Thing it should equal.
+ * @param {String} msg Reason of failure.
+ * @returns {Assert}
+ * @api public
+ */
+Assert.add('equal, equals, eq, eqs, exactly', function equal(thing, msg) {
+  var expect = format('`%j` to @ equal (===) `%j`', this.value, thing);
+
+  if (!this._deep) return this.test(this.value === thing, msg, expect);
+
+  this.sliceStack++;
+  return this.eql(thing, msg);
+});
+
+/**
+ * Assert that the value **deeply** equals a given thing.
+ *
+ * @param {Mixed} thing Thing it should equal.
+ * @param {String} msg Reason of failure.
+ * @returns {Assert}
+ * @api public
+ */
+Assert.add('eql, eqls', function eqls(thing, msg) {
+  var expect = format('`%j` to deeply equal `%j`', this.value, thing);
+
+  return this.test(deep(this.value, thing), msg, expect);
+});
+
+/**
+ * Assert that the value is either one of the given values.
+ *
+ * @param {Array} arrgs All the values it can match.
+ * @param {String} msg Reason of failure.
+ * @returns {Assert}
+ * @api public
+ */
+Assert.add('either', function either(args, msg) {
+  var expect = '`%j` to equal either `%j` '
+    , i = args.length
+    , result = false
+    , values = [];
+
+  while (i-- || result) {
+    if (!this._deep) result = this.value === args[i];
+    else result = deep(this.value, args[i]);
+    if (result) break;
+
+    values.push(args[i]);
+  }
+
+  expect = format.apply(null, [expect + (new Array(values)).join('or `%j` ')].concat(values));
+  return this.test(result, msg, expect);
+});
+
+/**
+ * Assert if the given function throws.
+ *
+ * @param {Mixed} thing Thing it should equal.
+ * @param {String} msg Reason of failure.
+ * @returns {Assert}
+ * @api public
+ */
+Assert.add('throw, throws, fails, fail', function throws(thing, msg) {
+  try { this.value(); }
+  catch (e) {
+    var message = 'object' === typeof e ? e.message : e;
+
+    switch (type(thing)) {
+      case 'string': return this.clone(message).includes(thing, msg);
+      case 'regexp': return this.clone(message).matches(thing, msg);
+      case 'function': return this.clone(e).instanceOf(thing, msg);
+      case 'undefined': return this.test(true, msg, format('%f to @ throw', this.value));
+      default: return this.clone(e).equals(thing);
+    }
+  }
+
+  return this.test(false, msg, format('%f to @ throw', this.value));
+});
+
+/**
+ * Assert if the given value is finite.
+ *
+ * @param {String} msg Reason of failure.
+ * @returns {Assert}
+ * @api public
+ */
+Assert.add('isFinite, finite, finiteness', function finite(msg) {
+  var expect = format('`%j`s @ a is a finite number', this.value)
+    , result;
+
+  if (this._deep) {
+    result = Number.isFinite
+    ? Number.isFinite(this.value)
+    : 'number' === type(this.value) && isFinite(this.value);
+  } else {
+    result = isFinite(this.value);
+  }
+
+  return this.test(result, msg, expect);
+});
+
+/**
+ * Assert if the given function is an ES6 generator.
+ *
+ * @param {String} msg Reason of failure.
+ * @returns {Assert}
+ * @api public
+ */
+Assert.add('generator', function generators(msg) {
+  var expect = format('%f to @ be a generator', this.value)
+    , result;
+
+  //
+  // Non standard function from Mozilla allows us to check if a function is
+  // a generator.
+  //
+  // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/isGenerator
+  //
+  if ('function' === typeof this.value.isGenerator) {
+    result = this.value.isGenerator();
+  } else if ('generatorfunction' === type(this.value)) {
+    result = true;
+  } else {
+    result = 'function' === type(this.value) && this.value.toString().indexOf('function*') === 0;
+  }
+
+  return this.test(result, msg, expect);
+});
+
+//
+// The following assertions require's v8's allow-natives-syntax flag to be
+// enabled as this allows us to hook in to the more internal parts of the
+// engine. The native syntax is wrapped in a try catch with a new Function
+// construction so the rest of the code will execute when JavaScript engines do
+// not understand the instructions.
+//
+(function v8() {
+  var states = 'void,yes,no,always,never,void,maybe'.split(',')
+    , detect;
+
+  if (!Assert.supports.native) detect = function optimized() { return 0; };
+  else detect = new Function('fn', 'args', 'selfie', [
+    'fn.apply(selfie, args);',
+    '%OptimizeFunctionOnNextCall(fn);',
+    'fn.apply(selfie, args);',
+    'return %GetOptimizationStatus(fn);'
+  ].join('\n'));
+
+  /**
+   * Assert that a given function has reached a certain optimization level.
+   *
+   * @param {String} level Optimization level
+   * @param {Array} args Arguments for the function
+   * @param {Mixed} selfie This context for the function
+   * @param {String} msg Reason of failure
+   * @returns {Assert}
+   * @api public
+   */
+  Assert.add('optimisation, optimization', function optimization(level, args, selfie, msg) {
+    var expect = format('%f to be optimized as %s', this.value, level)
+      , status = states[detect(this.value, args, selfie)];
+
+    return this.test(status === level, msg, expect);
+  });
+
+  /**
+   * Assert that the function is optimized.
+   *
+   * @param {String} msg Reason of failure
+   * @returns {Assert}
+   * @api public
+   */
+  Assert.add('optimized, optimised', function optimized(msg) {
+    var expect = format('%f to be optimized', this.value)
+      , status = states[detect(this.value, [])];
+
+    return this.test(status === 'yes', msg, expect);
+  });
+}());
+
+/**
+ * Create a clone of the current assertion instance which has the same
+ * configuration but a different value.
+ *
+ * @param {Mixed} value The new value
+ * @returns {Assert}
+ * @api public
+ */
+Assert.add('clone', function clone(value) {
+  var configuration = {
+    stacktrace: this.stacktrace,
+    slice: this.sliceStack + 1,
+    diff: this.diff
+  };
+
+  for (var alias in Assert.flags) {
+    if (!hasOwn.call(Assert.flags, alias)) continue;
+    configuration[alias] = this[alias];
+  }
+
+  return new Assert(arguments.length ? value : this.value, configuration);
+});
+
+/**
+ * Validate the assertion.
+ *
+ * @param {Boolean} passed Didn't the test pass or fail.
+ * @param {String} msg Custom message provided by users.
+ * @param {String} expectation What the assertion expected.
+ * @param {Number} slice The amount of stack traces we need to remove.
+ * @returns {Assert}
+ * @api public
+ */
+Assert.add('test', function test(passed, msg, expectation, slice) {
+  called++; // Needed for tracking the amount of executed assertions.
+
+  if (this._not) passed = !passed;
+  if (passed) return this;
+
+  msg = msg || 'Unknown assertation failure occured';
+  slice = slice || this.sliceStack;
+
+  if (expectation) msg += ', assumed ' + expectation(this._not);
+
+  var failure = new Error(msg)
+    , err = { message: failure.message, stack: '' };
+
+  if (this.stacktrace) {
+    err.stack = failure.stack || err.stack;
+  }
+
+  //
+  // Clean up the stack by slicing off the parts that are pointless to most
+  // people. (Like where it enters this assertion library).
+  //
+  err.stack = err.stack.split('\n').slice(slice).join('\n') || err.stack;
+  err.stack = pretty(err);
+
+  if ('function' !== typeof Object.create) {
+    if ('object' === typeof console && 'function' === typeof console.error) {
+      console.error(err.stack);
+    }
+
+    throw failure;
+  }
+
+  failure = Object.create(Error.prototype);
+  failure.message = err.message;
+  failure.stack = err.stack;
+
+  throw failure;
+});
+
+/**
+ * Plan for the amount of assertions that needed to run. This is great way to
+ * figure out if you have edge cases in your code which prevented an assertion or
+ * callback from running.
+ *
+ * ```js
+ * it('run a lot of assertions', function (next) {
+ *   next = assume.plan(10, next);
+ * });
+ * ```
+ *
+ * @param {Number} tests The amount of assertions you expect to run.
+ * @param {Function} fn Optional completion callback which receives the error.
+ * @returns {Function} Completion callback.
+ * @api public
+ */
+Assert.plan = function plan(tests, fn) {
+  fn = fn || function next(err) {
+    if (err) throw err;
+  };
+
+  var atm = called;
+
+  return function validate(err) {
+    var ran = called - atm
+      , msg;
+
+    if (err) return fn(err);
+    if (tests === ran) return fn();
+
+    msg = [
+      'We ran',
+      ran - tests,
+      ran > tests ? 'more' : 'less',
+      'assertations than the expected',
+      tests
+    ];
+
+    fn(new Error(msg.join(' ')));
+  };
+};
+
+/**
+ * Wait until the returned callback is called x times before advancing. This
+ * makes it a bit easier to write async tests that require multiple callbacks.
+ *
+ * ```js
+ * it('does async things', function (next) {
+ *   next = assume.wait(2, 4, next);
+ *
+ *   asynctask(function (err, data) {
+ *     assume(err).is.a('undefined');
+ *     assume(data).equals('testing');
+ *
+ *     next();
+ *   });
+ *
+ *   asynctaskfail(function (err, data) {
+ *     assume(err).is.a('undefined');
+ *     assume(data).equals('testing');
+ *
+ *     next();
+ *   });
+ * });
+ * ```
+ *
+ * @param {Number} calls The amount of calls the returned callback should called.
+ * @param {Number} tests The amount of tests that should be completed before cb.
+ * @param {Function} fn Completion callback.
+ * @returns {Function} New function that does the counting.
+ * @api public
+ */
+Assert.wait = function wait(calls, tests, fn) {
+  //
+  // Make the `tests` argument optional by allowing callback to be used there.
+  //
+  if ('function' === typeof tests) {
+    fn = tests;
+    tests = 0;
+  }
+
+  //
+  // If `tests` are specified, pass it directly in to the Assert.plan function
+  // so we can use that as given callback.
+  //
+  if (tests) fn = Assert.plan(tests, fn);
+
+  var ignore = false;
+
+  return function counter(err) {
+    if (ignore) return;
+    if (err || !--calls) return ignore = true, fn(err);
+  };
+};
+
+/**
+ * Load/execute a new plugin.
+ *
+ * @param {Function} plugin Plugin to be executed.
+ * @returns {Function} Assert, for chaining purposes.
+ * @api public
+ */
+Assert.use = function use(plugin) {
+  plugin(this, {
+    name: displayName,    // Extract the name of a function.
+    string: stringify,    // Transform thing to a string.
+    get: pathval.get,     // Get a value from an object.
+    format: format,       // Format an expectation message.
+    nodejs: nodejs,       // Are we running on Node.js.
+    deep: deep,           // Deep assertion.
+    type: type,           // Get class information.
+    size: size,           // Get the size of an object.
+    each: each            // Iterate over arrays.
+  });
+
+  return Assert;
+};
+
+//
+// Create type checks for all build-in JavaScript classes.
+//
+each(('new String§new Number§new Array§new Date§new Error§new RegExp§new Boolean§'
+  + 'new Float32Array§new Float64Array§new Int16Array§new Int32Array§new Int8Array§'
+  + 'new Uint16Array§new Uint32Array§new Uint8Array§new Uint8ClampedArray§'
+  + 'new ParallelArray§new Map§new Set§new WeakMap§new WeakSet§new TypedArray(1)§'
+  + 'new DataView(new ArrayBuffer(1))§new ArrayBuffer(1)§new Promise(function(){})§'
+  + 'new Blob§arguments§null§undefined§new Buffer(1)§NaN§navigator§location§'
+  + 'new Function§new Proxy({}, function(){})§Symbol("assume")§Math'
+).split('§'), function iterate(code) {
+  var name, arg;
+
+  //
+  // Not all of these constructors are supported in the browser, we're going to
+  // compile dedicated functions that returns a new instance of the given
+  // constructor. If it's not supported the code will throw and we will simply
+  // return.
+  //
+  try { arg = (new Function('return '+ code))(); }
+  catch (e) { return; }
+
+  name = type(arg);
+
+  Assert.add(name, function typecheck(msg) {
+    var expect = format('`%j` to @ be an %s', this.value, name)
+      , of = type(this.value);
+
+    return this.test(of === name, msg, expect, 3);
+  });
+});
+
+//
+// Introduce an alternate API:
+//
+// ```js
+// var i = require('assume');
+//
+// i.assume.that('foo').equals('bar');
+// i.sincerely.hope.that('foo').equals('bar');
+// i.expect.that('foo').equals('bar');
+// ```
+//
+Assert.hope = { that: Assert };
+Assert.assign(Assert)('sincerely, expect');
+Assert.assign(Assert)('assume, expect', Assert.hope);
+
+//
+// Expose the module.
+//
+module.exports = Assert;
diff --git a/debian/tests/test_modules/assume/package.json b/debian/tests/test_modules/assume/package.json
new file mode 100644
index 0000000..aecc2d6
--- /dev/null
+++ b/debian/tests/test_modules/assume/package.json
@@ -0,0 +1,97 @@
+{
+  "_from": "assume@1.3.x",
+  "_id": "assume@1.3.1",
+  "_inBundle": false,
+  "_integrity": "sha1-Ug41CVjNUnADcR8ehh59cULs6KU=",
+  "_location": "/assume",
+  "_phantomChildren": {},
+  "_requested": {
+    "type": "range",
+    "registry": true,
+    "raw": "assume@1.3.x",
+    "name": "assume",
+    "escapedName": "assume",
+    "rawSpec": "1.3.x",
+    "saveSpec": null,
+    "fetchSpec": "1.3.x"
+  },
+  "_requiredBy": [
+    "#DEV:/"
+  ],
+  "_resolved": "https://registry.npmjs.org/assume/-/assume-1.3.1.tgz";,
+  "_shasum": "520e350958cd527003711f1e861e7d7142ece8a5",
+  "_spec": "assume@1.3.x",
+  "_where": "/home/xavier/dev/debian/packages/node-url-parse",
+  "author": {
+    "name": "Arnout Kazemier"
+  },
+  "bugs": {
+    "url": "https://github.com/bigpipe/assume/issues";
+  },
+  "bundleDependencies": false,
+  "dependencies": {
+    "deep-eql": "0.1.x",
+    "fn.name": "1.0.x",
+    "is-node": "0.0.x",
+    "object-inspect": "1.0.x",
+    "pathval": "0.1.x",
+    "prettify-error": "0.1.x"
+  },
+  "deprecated": false,
+  "description": "Expect-like assertions that works seamlessly in node and browsers",
+  "devDependencies": {
+    "browserify": "9.0.x",
+    "istanbul": "0.3.x",
+    "mocha": "2.2.x",
+    "mocha-phantomjs": "3.5.x",
+    "phantomjs": "1.9.x",
+    "pre-commit": "1.0.x"
+  },
+  "homepage": "https://github.com/bigpipe/assume#readme";,
+  "keywords": [
+    "assert",
+    "assertion",
+    "asserts",
+    "assume",
+    "bdd",
+    "expect",
+    "expect.js",
+    "should",
+    "shouldjs",
+    "spec",
+    "tdd",
+    "test",
+    "testing",
+    "tests",
+    "unit testing",
+    "unit"
+  ],
+  "license": "MIT",
+  "main": "index.js",
+  "name": "assume",
+  "repository": {
+    "type": "git",
+    "url": "git://github.com/bigpipe/assume.git"
+  },
+  "scripts": {
+    "browserify-tests": "browserify test/test.js -o test/phantom.js --debug",
+    "coverage": "istanbul cover ./node_modules/.bin/_mocha -- --reporter spec --ui bdd test/test.js",
+    "iojs": "iojs --allow-natives-syntax --harmony ./node_modules/mocha/bin/_mocha test/test.js",
+    "node": "node --allow-natives-syntax --harmony ./node_modules/mocha/bin/_mocha test/test.js",
+    "phantom": "mocha-phantomjs test/phantom.html",
+    "prepublish": "mkdir -p dist && browserify index.js -o dist/assume.js --standalone assume",
+    "test": "npm run-script browserify-tests && npm run-script phantom",
+    "test-travis": "npm run node && istanbul cover node_modules/.bin/_mocha --report lcovonly -- --reporter spec --ui bdd test/test.js",
+    "watch": "mocha --watch --reporter spec --ui bdd test/test.js"
+  },
+  "testling": {
+    "harness": "mocha-bdd",
+    "files": "test/test.js",
+    "browsers": [
+      "ie/6..latest",
+      "chrome/latest",
+      "firefox/latest"
+    ]
+  },
+  "version": "1.3.1"
+}
diff --git a/debian/tests/test_modules/failing-code/index.js b/debian/tests/test_modules/failing-code/index.js
new file mode 100644
index 0000000..9f06e7c
--- /dev/null
+++ b/debian/tests/test_modules/failing-code/index.js
@@ -0,0 +1,52 @@
+var isNode = require("is-node");
+var failingLine = require("failing-line");
+
+var fs;
+var nodeRequire;
+
+if (isNode) {
+  nodeRequire = require;
+  fs = nodeRequire('fs');
+  nodeRequire = null;
+}
+
+module.exports = failingCode;
+
+function failingCode (error, doc, shift) {
+  var ln = failingLine(error, shift);
+
+  if (!ln) return;
+
+  if (!doc && fs) {
+    try {
+      doc = fs.readFileSync(ln.filename).toString();
+    } catch (readError) {
+      return undefined;
+    }
+  }
+
+  var result = [];
+  var lines = doc.split('\n');
+
+  var i = ln.line - 3;
+  while (++i < ln.line + 1) {
+    if (i + 1 != ln.line) {
+      result.push({
+        line: ln.line - (ln.line - i -1),
+        code: lines[i]
+      });
+      continue;
+    }
+
+    result.push({
+      line: ln.line,
+      col: ln.col,
+      fn: ln.fn,
+      filename: ln.filename,
+      code: lines[i],
+      failed: true
+    });
+  }
+
+  return result;
+}
diff --git a/debian/tests/test_modules/failing-code/package.json b/debian/tests/test_modules/failing-code/package.json
new file mode 100644
index 0000000..af20270
--- /dev/null
+++ b/debian/tests/test_modules/failing-code/package.json
@@ -0,0 +1,55 @@
+{
+  "_from": "failing-code@0.1.x",
+  "_id": "failing-code@0.1.0",
+  "_inBundle": false,
+  "_integrity": "sha1-plqIawkQgYQy4wMIcCFIZ3pukBE=",
+  "_location": "/failing-code",
+  "_phantomChildren": {},
+  "_requested": {
+    "type": "range",
+    "registry": true,
+    "raw": "failing-code@0.1.x",
+    "name": "failing-code",
+    "escapedName": "failing-code",
+    "rawSpec": "0.1.x",
+    "saveSpec": null,
+    "fetchSpec": "0.1.x"
+  },
+  "_requiredBy": [
+    "/prettify-error"
+  ],
+  "_resolved": "https://registry.npmjs.org/failing-code/-/failing-code-0.1.0.tgz";,
+  "_shasum": "a65a886b0910818432e30308702148677a6e9011",
+  "_spec": "failing-code@0.1.x",
+  "_where": "/home/xavier/dev/debian/packages/node-url-parse/node_modules/prettify-error",
+  "author": {
+    "name": "Azer Koçulu",
+    "email": "azer@kodfabrik.com"
+  },
+  "bugs": {
+    "url": "https://github.com/azer/failing-code/issues";
+  },
+  "bundleDependencies": false,
+  "dependencies": {
+    "failing-line": "0.1.x",
+    "is-node": "0.0.0"
+  },
+  "deprecated": false,
+  "description": "Returns failing code for given error",
+  "devDependencies": {
+    "tape": "*"
+  },
+  "homepage": "https://github.com/azer/failing-code#readme";,
+  "keywords": [
+    "error",
+    "reporter"
+  ],
+  "license": "BSD",
+  "main": "index.js",
+  "name": "failing-code",
+  "repository": {
+    "url": "git+ssh://git@github.com/azer/failing-code.git",
+    "type": "git"
+  },
+  "version": "0.1.0"
+}
diff --git a/debian/tests/test_modules/failing-line/index.js b/debian/tests/test_modules/failing-line/index.js
new file mode 100644
index 0000000..56a1707
--- /dev/null
+++ b/debian/tests/test_modules/failing-line/index.js
@@ -0,0 +1,91 @@
+module.exports = detect;
+
+function detect (error, shift) {
+  if (!error || !error.stack) return;
+
+  if (/  at /.test(error.stack)) return v8(error, shift);
+
+  if (/:\d+:\d+$/.test(error.stack)) return safari(error, shift);
+
+  return firefox(error, shift);
+}
+
+function safari (error, shift) {
+  var index = 0;
+  if (shift) index += shift;
+
+  var fn, filename, line, col;
+  var lines = error.stack.split('\n');
+  var stack = lines[index] || lines[0];
+
+  var fields = stack.split(/\:(\d+)\:(\d+)$/);
+  var numbers = fields.slice(1, 3);
+  fields = fields[0].split('@');
+
+  return {
+    fn: fields[0],
+    filename: fields[1],
+    line: Number(numbers[0]),
+    col: Number(numbers[1])
+  };
+}
+
+function v8 (error, shift) {
+  if (!error || !error.stack) return;
+
+  var index = 1;
+  if (shift) index += shift;
+
+  var fn, filename, line, col;
+  var lines = error.stack.split('\n');
+  var stack = lines[index] || lines[1];
+
+  if (!stack) return;
+
+  var match = stack.match(/at ([\(\)\w\.<>\[\]\s]+) \((.+):(\d+):(\d+)/);
+
+  if (!match) {
+    match = stack.match(/at (.+):(\d+):(\d+)/);
+    if (!match) return undefined;
+
+    filename = match[1];
+    line = Number(match[2]);
+    col = Number(match[3]);
+  } else {
+    fn = match[1];
+    filename = match[2];
+    line = Number(match[3]);
+    col = Number(match[4]);
+  }
+
+  return {
+    fn: fn,
+    filename: filename,
+    line: line,
+    col: col
+  };
+}
+
+function firefox (error, shift) {
+  var index = 0;
+  if (shift) index += shift;
+
+  var fn, filename, line, col;
+  var lines = error.stack.split('\n');
+  var stack = lines[index] || lines[0];
+
+  var fields = stack.split(/\:(\d+)$/);
+  var numbers = fields.slice(1, 2);
+  fields = fields[0].split('@');
+
+  if (index == 0) {
+    col = error.columnNumber;
+  }
+
+  return {
+    fn: fields[0],
+    filename: fields[1],
+    line: Number(numbers[0]),
+    col: col
+  };
+}
diff --git a/debian/tests/test_modules/failing-line/package.json b/debian/tests/test_modules/failing-line/package.json
new file mode 100644
index 0000000..c1ae3ca
--- /dev/null
+++ b/debian/tests/test_modules/failing-line/package.json
@@ -0,0 +1,55 @@
+{
+  "_from": "failing-line@0.1.x",
+  "_id": "failing-line@0.1.0",
+  "_inBundle": false,
+  "_integrity": "sha1-/BT9jwgBpkHxFE5OiTAQq2/qJJY=",
+  "_location": "/failing-line",
+  "_phantomChildren": {},
+  "_requested": {
+    "type": "range",
+    "registry": true,
+    "raw": "failing-line@0.1.x",
+    "name": "failing-line",
+    "escapedName": "failing-line",
+    "rawSpec": "0.1.x",
+    "saveSpec": null,
+    "fetchSpec": "0.1.x"
+  },
+  "_requiredBy": [
+    "/failing-code"
+  ],
+  "_resolved": "https://registry.npmjs.org/failing-line/-/failing-line-0.1.0.tgz";,
+  "_shasum": "fc14fd8f0801a641f1144e4e893010ab6fea2496",
+  "_spec": "failing-line@0.1.x",
+  "_where": "/home/xavier/dev/debian/packages/node-url-parse/node_modules/failing-code",
+  "author": {
+    "name": "azer"
+  },
+  "bugs": {
+    "url": "https://github.com/azer/failing-line/issues";
+  },
+  "bundleDependencies": false,
+  "deprecated": false,
+  "description": "Return the line number and filename of failing line from given error object",
+  "devDependencies": {
+    "tape": "*"
+  },
+  "homepage": "https://github.com/azer/failing-line#readme";,
+  "keywords": [
+    "error",
+    "fail",
+    "failing",
+    "line number"
+  ],
+  "license": "BSD",
+  "main": "index.js",
+  "name": "failing-line",
+  "repository": {
+    "url": "git+ssh://git@github.com/azer/failing-line.git",
+    "type": "git"
+  },
+  "scripts": {
+    "test": "node test.js"
+  },
+  "version": "0.1.0"
+}
diff --git a/debian/tests/test_modules/fn.name/index.js b/debian/tests/test_modules/fn.name/index.js
new file mode 100644
index 0000000..4078bb0
--- /dev/null
+++ b/debian/tests/test_modules/fn.name/index.js
@@ -0,0 +1,42 @@
+'use strict';
+
+var toString = Object.prototype.toString;
+
+/**
+ * Extract names from functions.
+ *
+ * @param {Function} fn The function who's name we need to extract.
+ * @returns {String}
+ * @api public
+ */
+module.exports = function name(fn) {
+  if ('string' === typeof fn.displayName && fn.constructor.name) {
+    return fn.displayName;
+  } else if ('string' === typeof fn.name && fn.name) {
+    return fn.name;
+  }
+
+  //
+  // Check to see if the constructor has a name.
+  //
+  if (
+       'object' === typeof fn
+    && fn.constructor
+    && 'string' === typeof fn.constructor.name
+  ) return fn.constructor.name;
+
+  //
+  // toString the given function and attempt to parse it out of it, or determine
+  // the class.
+  //
+  var named = fn.toString()
+    , type = toString.call(fn).slice(8, -1);
+
+  if ('Function' === type) {
+    named = named.substring(named.indexOf('(') + 1, named.indexOf(')'));
+  } else {
+    named = type;
+  }
+
+  return named || 'anonymous';
+};
diff --git a/debian/tests/test_modules/fn.name/package.json b/debian/tests/test_modules/fn.name/package.json
new file mode 100644
index 0000000..a0c5a5e
--- /dev/null
+++ b/debian/tests/test_modules/fn.name/package.json
@@ -0,0 +1,64 @@
+{
+  "_from": "fn.name@1.0.x",
+  "_id": "fn.name@1.0.1",
+  "_inBundle": false,
+  "_integrity": "sha1-gBWtFJwQEaEWzbieukzBHZA5rdg=",
+  "_location": "/fn.name",
+  "_phantomChildren": {},
+  "_requested": {
+    "type": "range",
+    "registry": true,
+    "raw": "fn.name@1.0.x",
+    "name": "fn.name",
+    "escapedName": "fn.name",
+    "rawSpec": "1.0.x",
+    "saveSpec": null,
+    "fetchSpec": "1.0.x"
+  },
+  "_requiredBy": [
+    "/assume"
+  ],
+  "_resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.0.1.tgz";,
+  "_shasum": "8015ad149c1011a116cdb89eba4cc11d9039add8",
+  "_spec": "fn.name@1.0.x",
+  "_where": "/home/xavier/dev/debian/packages/node-url-parse/node_modules/assume",
+  "author": {
+    "name": "Arnout Kazemier"
+  },
+  "bugs": {
+    "url": "https://github.com/bigpipe/fn.name/issues";
+  },
+  "bundleDependencies": false,
+  "deprecated": false,
+  "description": "Extract names from functions",
+  "devDependencies": {
+    "assume": "0.0.x",
+    "istanbul": "0.3.x",
+    "mocha": "2.1.x",
+    "pre-commit": "0.0.x"
+  },
+  "homepage": "https://github.com/bigpipe/fn.name";,
+  "keywords": [
+    "fn.name",
+    "function.name",
+    "name",
+    "function",
+    "extract",
+    "parse",
+    "names"
+  ],
+  "license": "MIT",
+  "main": "index.js",
+  "name": "fn.name",
+  "repository": {
+    "type": "git",
+    "url": "git+https://github.com/bigpipe/fn.name.git";
+  },
+  "scripts": {
+    "coverage": "istanbul cover ./node_modules/.bin/_mocha -- --reporter spec --ui bdd test.js",
+    "test": "mocha --reporter spec --ui bdd test.js",
+    "test-travis": "istanbul cover node_modules/.bin/_mocha --report lcovonly -- --reporter spec --ui bdd test.js",
+    "watch": "mocha --watch --reporter spec --ui bdd test.js"
+  },
+  "version": "1.0.1"
+}
diff --git a/debian/tests/test_modules/format-text/index.js b/debian/tests/test_modules/format-text/index.js
new file mode 100644
index 0000000..2116910
--- /dev/null
+++ b/debian/tests/test_modules/format-text/index.js
@@ -0,0 +1,31 @@
+module.exports = format;
+
+function format(text) {
+  var context;
+
+  if (typeof arguments[1] == 'object' && arguments[1]) {
+    context = arguments[1];
+  } else {
+    context = Array.prototype.slice.call(arguments, 1);
+  }
+
+  return String(text).replace(/\{?\{([^{}]+)}}?/g, replace(context));
+};
+
+function replace (context, nil){
+  return function (tag, name) {
+    if (tag.substring(0, 2) == '{{' && tag.substring(tag.length - 2) == '}}') {
+      return '{' + name + '}';
+    }
+
+    if (!context.hasOwnProperty(name)) {
+      return tag;
+    }
+
+    if (typeof context[name] == 'function') {
+      return context[name]();
+    }
+
+    return context[name];
+  }
+}
diff --git a/debian/tests/test_modules/format-text/package.json b/debian/tests/test_modules/format-text/package.json
new file mode 100644
index 0000000..7f3b702
--- /dev/null
+++ b/debian/tests/test_modules/format-text/package.json
@@ -0,0 +1,51 @@
+{
+  "_from": "format-text@0.x",
+  "_id": "format-text@0.0.3",
+  "_inBundle": false,
+  "_integrity": "sha1-tG1YV+C0qvM3l68zEwCdgmcJlxg=",
+  "_location": "/format-text",
+  "_phantomChildren": {},
+  "_requested": {
+    "type": "range",
+    "registry": true,
+    "raw": "format-text@0.x",
+    "name": "format-text",
+    "escapedName": "format-text",
+    "rawSpec": "0.x",
+    "saveSpec": null,
+    "fetchSpec": "0.x"
+  },
+  "_requiredBy": [
+    "/prettify-error",
+    "/style-format"
+  ],
+  "_resolved": "https://registry.npmjs.org/format-text/-/format-text-0.0.3.tgz";,
+  "_shasum": "b46d5857e0b4aaf33797af3313009d8267099718",
+  "_spec": "format-text@0.x",
+  "_where": "/home/xavier/dev/debian/packages/node-url-parse/node_modules/prettify-error",
+  "author": {
+    "name": "Azer Koçulu",
+    "email": "azer@kodfabrik.com"
+  },
+  "bugs": {
+    "url": "https://github.com/azer/format-text/issues";
+  },
+  "bundleDependencies": false,
+  "deprecated": false,
+  "description": "String formatting library inspired from Python",
+  "devDependencies": {
+    "prova": "*"
+  },
+  "homepage": "https://github.com/azer/format-text#readme";,
+  "license": "BSD",
+  "main": "index.js",
+  "name": "format-text",
+  "repository": {
+    "url": "git+ssh://git@github.com/azer/format-text.git",
+    "type": "git"
+  },
+  "scripts": {
+    "test": "prova"
+  },
+  "version": "0.0.3"
+}
diff --git a/debian/tests/test_modules/is-node/index.js b/debian/tests/test_modules/is-node/index.js
new file mode 100644
index 0000000..928fdd7
--- /dev/null
+++ b/debian/tests/test_modules/is-node/index.js
@@ -0,0 +1 @@
+module.exports = !!(typeof process != 'undefined' && process.versions && process.versions.node);
diff --git a/debian/tests/test_modules/is-node/package.json b/debian/tests/test_modules/is-node/package.json
new file mode 100644
index 0000000..9237b9e
--- /dev/null
+++ b/debian/tests/test_modules/is-node/package.json
@@ -0,0 +1,55 @@
+{
+  "_from": "is-node@0.0.x",
+  "_id": "is-node@0.0.0",
+  "_inBundle": false,
+  "_integrity": "sha1-h91lC4f7ajnFDKr+4On2g17BXkE=",
+  "_location": "/is-node",
+  "_phantomChildren": {},
+  "_requested": {
+    "type": "range",
+    "registry": true,
+    "raw": "is-node@0.0.x",
+    "name": "is-node",
+    "escapedName": "is-node",
+    "rawSpec": "0.0.x",
+    "saveSpec": null,
+    "fetchSpec": "0.0.x"
+  },
+  "_requiredBy": [
+    "/assume",
+    "/failing-code"
+  ],
+  "_resolved": "https://registry.npmjs.org/is-node/-/is-node-0.0.0.tgz";,
+  "_shasum": "87dd650b87fb6a39c50caafee0e9f6835ec15e41",
+  "_spec": "is-node@0.0.x",
+  "_where": "/home/xavier/dev/debian/packages/node-url-parse/node_modules/assume",
+  "author": {
+    "name": "Azer Koçulu",
+    "email": "azer@kodfabrik.com"
+  },
+  "bugs": {
+    "url": "https://github.com/azer/is-node/issues";
+  },
+  "bundleDependencies": false,
+  "deprecated": false,
+  "description": "Returns true if it's running on NodeJS",
+  "devDependencies": {
+    "fox": "*"
+  },
+  "homepage": "https://github.com/azer/is-node#readme";,
+  "keywords": [
+    "node",
+    "detection"
+  ],
+  "license": "BSD",
+  "main": "index.js",
+  "name": "is-node",
+  "repository": {
+    "url": "git+ssh://git@github.com/azer/is-node.git",
+    "type": "git"
+  },
+  "scripts": {
+    "test": "fox"
+  },
+  "version": "0.0.0"
+}
diff --git a/debian/tests/test_modules/left-pad/index.js b/debian/tests/test_modules/left-pad/index.js
new file mode 100644
index 0000000..257ec04
--- /dev/null
+++ b/debian/tests/test_modules/left-pad/index.js
@@ -0,0 +1,12 @@
+module.exports = leftpad;
+
+function leftpad (str, len) {
+  var i = -1;
+  len = len - str.length;
+
+  while (++i < len) {
+    str = ' ' + str;
+  }
+
+  return str;
+}
diff --git a/debian/tests/test_modules/left-pad/package.json b/debian/tests/test_modules/left-pad/package.json
new file mode 100644
index 0000000..3c8c2bd
--- /dev/null
+++ b/debian/tests/test_modules/left-pad/package.json
@@ -0,0 +1,56 @@
+{
+  "_from": "left-pad@0.0.0",
+  "_id": "left-pad@0.0.0",
+  "_inBundle": false,
+  "_integrity": "sha1-8YTGEcOznIkrsfOMV4YV8ejf/+Q=",
+  "_location": "/left-pad",
+  "_phantomChildren": {},
+  "_requested": {
+    "type": "version",
+    "registry": true,
+    "raw": "left-pad@0.0.0",
+    "name": "left-pad",
+    "escapedName": "left-pad",
+    "rawSpec": "0.0.0",
+    "saveSpec": null,
+    "fetchSpec": "0.0.0"
+  },
+  "_requiredBy": [
+    "/prettify-error"
+  ],
+  "_resolved": "https://registry.npmjs.org/left-pad/-/left-pad-0.0.0.tgz";,
+  "_shasum": "f184c611c3b39c892bb1f38c578615f1e8dfffe4",
+  "_spec": "left-pad@0.0.0",
+  "_where": "/home/xavier/dev/debian/packages/node-url-parse/node_modules/prettify-error",
+  "author": {
+    "name": "azer"
+  },
+  "bugs": {
+    "url": "https://github.com/azer/left-pad/issues";
+  },
+  "bundleDependencies": false,
+  "deprecated": "use String.prototype.padStart()",
+  "description": "String left pad",
+  "devDependencies": {
+    "tape": "*"
+  },
+  "homepage": "https://github.com/azer/left-pad#readme";,
+  "keywords": [
+    "leftpad",
+    "left",
+    "pad",
+    "padding",
+    "string"
+  ],
+  "license": "BSD",
+  "main": "index.js",
+  "name": "left-pad",
+  "repository": {
+    "url": "git+ssh://git@github.com/azer/left-pad.git",
+    "type": "git"
+  },
+  "scripts": {
+    "test": "node test"
+  },
+  "version": "0.0.0"
+}
diff --git a/debian/tests/test_modules/pathval/index.js b/debian/tests/test_modules/pathval/index.js
new file mode 100644
index 0000000..1ec2148
--- /dev/null
+++ b/debian/tests/test_modules/pathval/index.js
@@ -0,0 +1,291 @@
+'use strict';
+
+/* !
+ * Chai - pathval utility
+ * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
+ * @see https://github.com/logicalparadox/filtr
+ * MIT Licensed
+ */
+
+/**
+ * ### .hasProperty(object, name)
+ *
+ * This allows checking whether an object has own
+ * or inherited from prototype chain named property.
+ *
+ * Basically does the same thing as the `in`
+ * operator but works properly with null/undefined values
+ * and other primitives.
+ *
+ *     var obj = {
+ *         arr: ['a', 'b', 'c']
+ *       , str: 'Hello'
+ *     }
+ *
+ * The following would be the results.
+ *
+ *     hasProperty(obj, 'str');  // true
+ *     hasProperty(obj, 'constructor');  // true
+ *     hasProperty(obj, 'bar');  // false
+ *
+ *     hasProperty(obj.str, 'length'); // true
+ *     hasProperty(obj.str, 1);  // true
+ *     hasProperty(obj.str, 5);  // false
+ *
+ *     hasProperty(obj.arr, 'length');  // true
+ *     hasProperty(obj.arr, 2);  // true
+ *     hasProperty(obj.arr, 3);  // false
+ *
+ * @param {Object} object
+ * @param {String|Symbol} name
+ * @returns {Boolean} whether it exists
+ * @namespace Utils
+ * @name hasProperty
+ * @api public
+ */
+
+function hasProperty(obj, name) {
+  if (typeof obj === 'undefined' || obj === null) {
+    return false;
+  }
+
+  // The `in` operator does not work with primitives.
+  return name in Object(obj);
+}
+
+/* !
+ * ## parsePath(path)
+ *
+ * Helper function used to parse string object
+ * paths. Use in conjunction with `internalGetPathValue`.
+ *
+ *      var parsed = parsePath('myobject.property.subprop');
+ *
+ * ### Paths:
+ *
+ * * Can be infinitely deep and nested.
+ * * Arrays are also valid using the formal `myobject.document[3].property`.
+ * * Literal dots and brackets (not delimiter) must be backslash-escaped.
+ *
+ * @param {String} path
+ * @returns {Object} parsed
+ * @api private
+ */
+
+function parsePath(path) {
+  var str = path.replace(/([^\\])\[/g, '$1.[');
+  var parts = str.match(/(\\\.|[^.]+?)+/g);
+  return parts.map(function mapMatches(value) {
+    var regexp = /^\[(\d+)\]$/;
+    var mArr = regexp.exec(value);
+    var parsed = null;
+    if (mArr) {
+      parsed = { i: parseFloat(mArr[1]) };
+    } else {
+      parsed = { p: value.replace(/\\([.\[\]])/g, '$1') };
+    }
+
+    return parsed;
+  });
+}
+
+/* !
+ * ## internalGetPathValue(obj, parsed[, pathDepth])
+ *
+ * Helper companion function for `.parsePath` that returns
+ * the value located at the parsed address.
+ *
+ *      var value = getPathValue(obj, parsed);
+ *
+ * @param {Object} object to search against
+ * @param {Object} parsed definition from `parsePath`.
+ * @param {Number} depth (nesting level) of the property we want to retrieve
+ * @returns {Object|Undefined} value
+ * @api private
+ */
+
+function internalGetPathValue(obj, parsed, pathDepth) {
+  var temporaryValue = obj;
+  var res = null;
+  pathDepth = (typeof pathDepth === 'undefined' ? parsed.length : pathDepth);
+
+  for (var i = 0; i < pathDepth; i++) {
+    var part = parsed[i];
+    if (temporaryValue) {
+      if (typeof part.p === 'undefined') {
+        temporaryValue = temporaryValue[part.i];
+      } else {
+        temporaryValue = temporaryValue[part.p];
+      }
+
+      if (i === (pathDepth - 1)) {
+        res = temporaryValue;
+      }
+    }
+  }
+
+  return res;
+}
+
+/* !
+ * ## internalSetPathValue(obj, value, parsed)
+ *
+ * Companion function for `parsePath` that sets
+ * the value located at a parsed address.
+ *
+ *  internalSetPathValue(obj, 'value', parsed);
+ *
+ * @param {Object} object to search and define on
+ * @param {*} value to use upon set
+ * @param {Object} parsed definition from `parsePath`
+ * @api private
+ */
+
+function internalSetPathValue(obj, val, parsed) {
+  var tempObj = obj;
+  var pathDepth = parsed.length;
+  var part = null;
+  // Here we iterate through every part of the path
+  for (var i = 0; i < pathDepth; i++) {
+    var propName = null;
+    var propVal = null;
+    part = parsed[i];
+
+    // If it's the last part of the path, we set the 'propName' value with the property name
+    if (i === (pathDepth - 1)) {
+      propName = typeof part.p === 'undefined' ? part.i : part.p;
+      // Now we set the property with the name held by 'propName' on object with the desired val
+      tempObj[propName] = val;
+    } else if (typeof part.p !== 'undefined' && tempObj[part.p]) {
+      tempObj = tempObj[part.p];
+    } else if (typeof part.i !== 'undefined' && tempObj[part.i]) {
+      tempObj = tempObj[part.i];
+    } else {
+      // If the obj doesn't have the property we create one with that name to define it
+      var next = parsed[i + 1];
+      // Here we set the name of the property which will be defined
+      propName = typeof part.p === 'undefined' ? part.i : part.p;
+      // Here we decide if this property will be an array or a new object
+      propVal = typeof next.p === 'undefined' ? [] : {};
+      tempObj[propName] = propVal;
+      tempObj = tempObj[propName];
+    }
+  }
+}
+
+/**
+ * ### .getPathInfo(object, path)
+ *
+ * This allows the retrieval of property info in an
+ * object given a string path.
+ *
+ * The path info consists of an object with the
+ * following properties:
+ *
+ * * parent - The parent object of the property referenced by `path`
+ * * name - The name of the final property, a number if it was an array indexer
+ * * value - The value of the property, if it exists, otherwise `undefined`
+ * * exists - Whether the property exists or not
+ *
+ * @param {Object} object
+ * @param {String} path
+ * @returns {Object} info
+ * @namespace Utils
+ * @name getPathInfo
+ * @api public
+ */
+
+function getPathInfo(obj, path) {
+  var parsed = parsePath(path);
+  var last = parsed[parsed.length - 1];
+  var info = {
+    parent: parsed.length > 1 ? internalGetPathValue(obj, parsed, parsed.length - 1) : obj,
+    name: last.p || last.i,
+    value: internalGetPathValue(obj, parsed),
+  };
+  info.exists = hasProperty(info.parent, info.name);
+
+  return info;
+}
+
+/**
+ * ### .getPathValue(object, path)
+ *
+ * This allows the retrieval of values in an
+ * object given a string path.
+ *
+ *     var obj = {
+ *         prop1: {
+ *             arr: ['a', 'b', 'c']
+ *           , str: 'Hello'
+ *         }
+ *       , prop2: {
+ *             arr: [ { nested: 'Universe' } ]
+ *           , str: 'Hello again!'
+ *         }
+ *     }
+ *
+ * The following would be the results.
+ *
+ *     getPathValue(obj, 'prop1.str'); // Hello
+ *     getPathValue(obj, 'prop1.att[2]'); // b
+ *     getPathValue(obj, 'prop2.arr[0].nested'); // Universe
+ *
+ * @param {Object} object
+ * @param {String} path
+ * @returns {Object} value or `undefined`
+ * @namespace Utils
+ * @name getPathValue
+ * @api public
+ */
+
+function getPathValue(obj, path) {
+  var info = getPathInfo(obj, path);
+  return info.value;
+}
+
+/**
+ * ### .setPathValue(object, path, value)
+ *
+ * Define the value in an object at a given string path.
+ *
+ * ```js
+ * var obj = {
+ *     prop1: {
+ *         arr: ['a', 'b', 'c']
+ *       , str: 'Hello'
+ *     }
+ *   , prop2: {
+ *         arr: [ { nested: 'Universe' } ]
+ *       , str: 'Hello again!'
+ *     }
+ * };
+ * ```
+ *
+ * The following would be acceptable.
+ *
+ * ```js
+ * var properties = require('tea-properties');
+ * properties.set(obj, 'prop1.str', 'Hello Universe!');
+ * properties.set(obj, 'prop1.arr[2]', 'B');
+ * properties.set(obj, 'prop2.arr[0].nested.value', { hello: 'universe' });
+ * ```
+ *
+ * @param {Object} object
+ * @param {String} path
+ * @param {Mixed} value
+ * @api private
+ */
+
+function setPathValue(obj, path, val) {
+  var parsed = parsePath(path);
+  internalSetPathValue(obj, val, parsed);
+  return obj;
+}
+
+module.exports = {
+  hasProperty: hasProperty,
+  getPathInfo: getPathInfo,
+  getPathValue: getPathValue,
+  setPathValue: setPathValue,
+};
diff --git a/debian/tests/test_modules/pathval/package.json b/debian/tests/test_modules/pathval/package.json
new file mode 100644
index 0000000..c0f7b67
--- /dev/null
+++ b/debian/tests/test_modules/pathval/package.json
@@ -0,0 +1,78 @@
+{
+  "name": "pathval",
+  "description": "Object value retrieval given a string path",
+  "homepage": "https://github.com/chaijs/pathval";,
+  "keywords": [
+    "pathval",
+    "value retrieval",
+    "chai util"
+  ],
+  "license": "MIT",
+  "author": "Veselin Todorov <hi@vesln.com>",
+  "files": [
+    "index.js",
+    "pathval.js"
+  ],
+  "main": "./index.js",
+  "repository": {
+    "type": "git",
+    "url": "git+ssh://git@github.com/chaijs/pathval.git"
+  },
+  "scripts": {
+    "build": "browserify --bare $npm_package_main --standalone pathval -o pathval.js",
+    "lint": "eslint --ignore-path .gitignore .",
+    "prepublish": "npm run build",
+    "semantic-release": "semantic-release pre && npm publish && semantic-release post",
+    "pretest": "npm run lint",
+    "test": "npm run test:node && npm run test:browser && npm run upload-coverage",
+    "test:browser": "karma start --singleRun=true",
+    "test:node": "istanbul cover _mocha",
+    "upload-coverage": "lcov-result-merger 'coverage/**/lcov.info' | coveralls; exit 0"
+  },
+  "config": {
+    "ghooks": {
+      "commit-msg": "validate-commit-msg"
+    }
+  },
+  "eslintConfig": {
+    "extends": [
+      "strict/es5"
+    ],
+    "env": {
+      "es6": true
+    },
+    "globals": {
+      "HTMLElement": false
+    },
+    "rules": {
+      "complexity": 0,
+      "max-statements": 0
+    }
+  },
+  "devDependencies": {
+    "browserify": "^13.0.0",
+    "browserify-istanbul": "^1.0.0",
+    "coveralls": "2.11.9",
+    "eslint": "^2.4.0",
+    "eslint-config-strict": "^8.5.0",
+    "eslint-plugin-filenames": "^0.2.0",
+    "ghooks": "^1.0.1",
+    "istanbul": "^0.4.2",
+    "karma": "^0.13.22",
+    "karma-browserify": "^5.0.2",
+    "karma-coverage": "^0.5.5",
+    "karma-mocha": "^0.2.2",
+    "karma-phantomjs-launcher": "^1.0.0",
+    "karma-sauce-launcher": "^0.3.1",
+    "lcov-result-merger": "^1.0.2",
+    "mocha": "^3.1.2",
+    "phantomjs-prebuilt": "^2.1.5",
+    "semantic-release": "^4.3.5",
+    "simple-assert": "^1.0.0",
+    "travis-after-all": "^1.4.4",
+    "validate-commit-msg": "^2.3.1"
+  },
+  "engines": {
+    "node": "*"
+  }
+}
diff --git a/debian/tests/test_modules/prettify-error/index.js b/debian/tests/test_modules/prettify-error/index.js
new file mode 100644
index 0000000..03c9bf7
--- /dev/null
+++ b/debian/tests/test_modules/prettify-error/index.js
@@ -0,0 +1,62 @@
+var failingCode = require("failing-code");
+var format = require("format-text");
+var leftpad = require("left-pad");
+var style = require("style-format");
+
+var template = style('{bold}{red}{title} {grey}{filename}{reset}\n'
+                     + '    {red}{v}\n'
+                     + '    {grey}{previousLineNo}. {previousLine}\n'
+                     + '    {reset}{failingLineNo}. {failingLine}\n'
+                     + '    {grey}{nextLineNo}. {nextLine}\n'
+                     + '    {red}{^}{reset}\n'
+                     + '    {stack}\n'
+                     + '{reset}');
+
+module.exports = prettifyError;
+
+function prettifyError (error, shift, code) {
+  if (!error || !error.stack) return;
+
+  code || (code = failingCode(error, undefined, shift));
+
+  if (!code) return;
+
+  var previousLineNo = String(code[0].line);
+  var failingLineNo = String(code[1].line);
+  var nextLineNo = String(code[2].line);
+  var linumlen = Math.max(previousLineNo.length,
+                          failingLineNo.length,
+                          nextLineNo.length);
+
+  return format(template, {
+    title: error.message,
+    filename: code[1].filename,
+    previousLine: code[0].code,
+    previousLineNo: leftpad(previousLineNo, linumlen),
+    previousColNo: code[0].col,
+    failingLine: code[1].code,
+    failingLineNo: leftpad(failingLineNo, linumlen),
+    failingColNo: code[1].col,
+    nextLine: code[2].code,
+    nextLineNo: leftpad(nextLineNo, linumlen),
+    nextColNo: code[2].col,
+    stack: tabStack(error.stack),
+    '^': showColumn(code, linumlen - failingLineNo.length, '^'),
+    'v': showColumn(code, linumlen - failingLineNo.length, 'v')
+  });
+}
+
+function showColumn (code, tabn, ch) {
+  var result = '';
+  var i = String(code[1].line).length + code[1].col + 1 + tabn;
+
+  while (i--) {
+    result += ' ';
+  }
+
+  return result + ch;
+}
+
+function tabStack (stack) {
+  return stack.replace(/\n/g, '\n    ');
+}
diff --git a/debian/tests/test_modules/prettify-error/package.json b/debian/tests/test_modules/prettify-error/package.json
new file mode 100644
index 0000000..e2aab7e
--- /dev/null
+++ b/debian/tests/test_modules/prettify-error/package.json
@@ -0,0 +1,57 @@
+{
+  "_from": "prettify-error@0.1.x",
+  "_id": "prettify-error@0.1.1",
+  "_inBundle": false,
+  "_integrity": "sha1-OM8hBpLGOuXRdSftODmC8Qkhwl0=",
+  "_location": "/prettify-error",
+  "_phantomChildren": {},
+  "_requested": {
+    "type": "range",
+    "registry": true,
+    "raw": "prettify-error@0.1.x",
+    "name": "prettify-error",
+    "escapedName": "prettify-error",
+    "rawSpec": "0.1.x",
+    "saveSpec": null,
+    "fetchSpec": "0.1.x"
+  },
+  "_requiredBy": [
+    "/assume"
+  ],
+  "_resolved": "https://registry.npmjs.org/prettify-error/-/prettify-error-0.1.1.tgz";,
+  "_shasum": "38cf210692c63ae5d17527ed383982f10921c25d",
+  "_spec": "prettify-error@0.1.x",
+  "_where": "/home/xavier/dev/debian/packages/node-url-parse/node_modules/assume",
+  "author": {
+    "name": "azer"
+  },
+  "bugs": {
+    "url": "https://github.com/azer/prettify-error/issues";
+  },
+  "bundleDependencies": false,
+  "dependencies": {
+    "failing-code": "0.1.x",
+    "format-text": "0.x",
+    "left-pad": "0.0.0",
+    "style-format": "0.0.0"
+  },
+  "deprecated": false,
+  "description": "Prettify given error object",
+  "homepage": "https://github.com/azer/prettify-error#readme";,
+  "keywords": [
+    "error",
+    "pretty",
+    "prettify"
+  ],
+  "license": "BSD",
+  "main": "index.js",
+  "name": "prettify-error",
+  "repository": {
+    "url": "git+ssh://git@github.com/azer/prettify-error.git",
+    "type": "git"
+  },
+  "scripts": {
+    "test": "mocha"
+  },
+  "version": "0.1.1"
+}
diff --git a/debian/tests/test_modules/style-format/index.js b/debian/tests/test_modules/style-format/index.js
new file mode 100644
index 0000000..8af2d15
--- /dev/null
+++ b/debian/tests/test_modules/style-format/index.js
@@ -0,0 +1,8 @@
+var format = require("format-text");
+var ansi = require("ansi-codes");
+
+module.exports = styleFormat;
+
+function styleFormat (text) {
+  return format(text, ansi);
+}
diff --git a/debian/tests/test_modules/style-format/package.json b/debian/tests/test_modules/style-format/package.json
new file mode 100644
index 0000000..844e89d
--- /dev/null
+++ b/debian/tests/test_modules/style-format/package.json
@@ -0,0 +1,55 @@
+{
+  "_from": "style-format@0.0.0",
+  "_id": "style-format@0.0.0",
+  "_inBundle": false,
+  "_integrity": "sha1-Bd8oaW2HHM5ApWzCgMT3GcYFyeU=",
+  "_location": "/style-format",
+  "_phantomChildren": {},
+  "_requested": {
+    "type": "version",
+    "registry": true,
+    "raw": "style-format@0.0.0",
+    "name": "style-format",
+    "escapedName": "style-format",
+    "rawSpec": "0.0.0",
+    "saveSpec": null,
+    "fetchSpec": "0.0.0"
+  },
+  "_requiredBy": [
+    "/prettify-error"
+  ],
+  "_resolved": "https://registry.npmjs.org/style-format/-/style-format-0.0.0.tgz";,
+  "_shasum": "05df28696d871cce40a56cc280c4f719c605c9e5",
+  "_spec": "style-format@0.0.0",
+  "_where": "/home/xavier/dev/debian/packages/node-url-parse/node_modules/prettify-error",
+  "author": {
+    "name": "azer"
+  },
+  "bugs": {
+    "url": "https://github.com/azer/style-format/issues";
+  },
+  "bundleDependencies": false,
+  "dependencies": {
+    "ansi-codes": "*",
+    "format-text": "*"
+  },
+  "deprecated": false,
+  "description": "Library to easily style texts with string formatting",
+  "homepage": "https://github.com/azer/style-format#readme";,
+  "keywords": [
+    "style",
+    "text",
+    "format"
+  ],
+  "license": "BSD",
+  "main": "index.js",
+  "name": "style-format",
+  "repository": {
+    "url": "git+ssh://git@github.com/azer/style-format.git",
+    "type": "git"
+  },
+  "scripts": {
+    "test": "mocha"
+  },
+  "version": "0.0.0"
+}

--- End Message ---
--- Begin Message ---
Package: release.debian.org
Version: 9.13

Hi,

All of these requests relate to updates that were included in today's
stretch point release.

Regards,

Adam

--- End Message ---

Reply to: