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

Bug#930374: stretch-pu: package node-url-parse/1.0.5-2+deb9u1



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"
+}

Reply to: