summaryrefslogtreecommitdiff
path: root/node_modules/mocha
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/mocha')
-rw-r--r--node_modules/mocha/.npmignore5
-rw-r--r--node_modules/mocha/.travis.yml5
-rw-r--r--node_modules/mocha/History.md317
-rw-r--r--node_modules/mocha/LICENSE22
-rw-r--r--node_modules/mocha/Makefile118
-rw-r--r--node_modules/mocha/Readme.md34
-rw-r--r--node_modules/mocha/_mocha.js3916
-rwxr-xr-xnode_modules/mocha/bin/_mocha345
-rwxr-xr-xnode_modules/mocha/bin/mocha32
-rw-r--r--node_modules/mocha/editors/JavaScript mocha.tmbundle/Snippets/bdd - after each.tmSnippet16
-rw-r--r--node_modules/mocha/editors/JavaScript mocha.tmbundle/Snippets/bdd - after.tmSnippet16
-rw-r--r--node_modules/mocha/editors/JavaScript mocha.tmbundle/Snippets/bdd - before each.tmSnippet16
-rw-r--r--node_modules/mocha/editors/JavaScript mocha.tmbundle/Snippets/bdd - before.tmSnippet16
-rw-r--r--node_modules/mocha/editors/JavaScript mocha.tmbundle/Snippets/bdd - it.tmSnippet16
-rw-r--r--node_modules/mocha/editors/JavaScript mocha.tmbundle/Snippets/untitled.tmSnippet16
-rw-r--r--node_modules/mocha/editors/JavaScript mocha.tmbundle/info.plist19
-rw-r--r--node_modules/mocha/images/error.pngbin0 -> 1100 bytes
-rw-r--r--node_modules/mocha/images/ok.pngbin0 -> 649 bytes
-rw-r--r--node_modules/mocha/index.js4
-rw-r--r--node_modules/mocha/lib/browser/debug.js6
-rw-r--r--node_modules/mocha/lib/browser/diff.js0
-rw-r--r--node_modules/mocha/lib/browser/events.js178
-rw-r--r--node_modules/mocha/lib/browser/fs.js0
-rw-r--r--node_modules/mocha/lib/browser/path.js0
-rw-r--r--node_modules/mocha/lib/browser/progress.js125
-rw-r--r--node_modules/mocha/lib/browser/tty.js8
-rw-r--r--node_modules/mocha/lib/context.js55
-rw-r--r--node_modules/mocha/lib/hook.js31
-rw-r--r--node_modules/mocha/lib/interfaces/bdd.js91
-rw-r--r--node_modules/mocha/lib/interfaces/exports.js60
-rw-r--r--node_modules/mocha/lib/interfaces/index.js5
-rw-r--r--node_modules/mocha/lib/interfaces/qunit.js91
-rw-r--r--node_modules/mocha/lib/interfaces/tdd.js94
-rw-r--r--node_modules/mocha/lib/mocha.js176
-rw-r--r--node_modules/mocha/lib/reporters/base.js319
-rw-r--r--node_modules/mocha/lib/reporters/doc.js74
-rw-r--r--node_modules/mocha/lib/reporters/dot.js62
-rw-r--r--node_modules/mocha/lib/reporters/html-cov.js44
-rw-r--r--node_modules/mocha/lib/reporters/html.js211
-rw-r--r--node_modules/mocha/lib/reporters/index.js17
-rw-r--r--node_modules/mocha/lib/reporters/json-cov.js149
-rw-r--r--node_modules/mocha/lib/reporters/json-stream.js61
-rw-r--r--node_modules/mocha/lib/reporters/json.js70
-rw-r--r--node_modules/mocha/lib/reporters/landing.js97
-rw-r--r--node_modules/mocha/lib/reporters/list.js64
-rw-r--r--node_modules/mocha/lib/reporters/markdown.js111
-rw-r--r--node_modules/mocha/lib/reporters/min.js37
-rw-r--r--node_modules/mocha/lib/reporters/progress.js85
-rw-r--r--node_modules/mocha/lib/reporters/spec.js87
-rw-r--r--node_modules/mocha/lib/reporters/tap.js63
-rw-r--r--node_modules/mocha/lib/reporters/teamcity.js56
-rw-r--r--node_modules/mocha/lib/reporters/templates/coverage.jade50
-rw-r--r--node_modules/mocha/lib/reporters/templates/menu.jade13
-rw-r--r--node_modules/mocha/lib/reporters/templates/script.html34
-rw-r--r--node_modules/mocha/lib/reporters/templates/style.html301
-rw-r--r--node_modules/mocha/lib/reporters/xunit.js101
-rw-r--r--node_modules/mocha/lib/runnable.js164
-rw-r--r--node_modules/mocha/lib/runner.js431
-rw-r--r--node_modules/mocha/lib/suite.js247
-rw-r--r--node_modules/mocha/lib/test.js49
-rw-r--r--node_modules/mocha/lib/utils.js189
-rw-r--r--node_modules/mocha/mocha.css137
-rw-r--r--node_modules/mocha/mocha.js4067
-rwxr-xr-xnode_modules/mocha/node_modules/.bin/jade125
-rw-r--r--node_modules/mocha/node_modules/commander/.npmignore4
-rw-r--r--node_modules/mocha/node_modules/commander/.travis.yml4
-rw-r--r--node_modules/mocha/node_modules/commander/History.md99
-rw-r--r--node_modules/mocha/node_modules/commander/Makefile7
-rw-r--r--node_modules/mocha/node_modules/commander/Readme.md263
-rw-r--r--node_modules/mocha/node_modules/commander/index.js2
-rw-r--r--node_modules/mocha/node_modules/commander/lib/commander.js992
-rw-r--r--node_modules/mocha/node_modules/commander/package.json38
-rw-r--r--node_modules/mocha/node_modules/debug/.npmignore4
-rw-r--r--node_modules/mocha/node_modules/debug/History.md41
-rw-r--r--node_modules/mocha/node_modules/debug/Makefile5
-rw-r--r--node_modules/mocha/node_modules/debug/Readme.md130
-rw-r--r--node_modules/mocha/node_modules/debug/debug.js122
-rw-r--r--node_modules/mocha/node_modules/debug/example/app.js19
-rw-r--r--node_modules/mocha/node_modules/debug/example/browser.html24
-rw-r--r--node_modules/mocha/node_modules/debug/example/wildcards.js10
-rw-r--r--node_modules/mocha/node_modules/debug/example/worker.js22
-rw-r--r--node_modules/mocha/node_modules/debug/index.js2
-rw-r--r--node_modules/mocha/node_modules/debug/lib/debug.js147
-rw-r--r--node_modules/mocha/node_modules/debug/package.json29
-rw-r--r--node_modules/mocha/node_modules/diff/LICENSE31
-rw-r--r--node_modules/mocha/node_modules/diff/README.md94
-rw-r--r--node_modules/mocha/node_modules/diff/diff.js287
-rw-r--r--node_modules/mocha/node_modules/diff/index.html89
-rw-r--r--node_modules/mocha/node_modules/diff/package.json46
-rw-r--r--node_modules/mocha/node_modules/diff/style.css81
-rw-r--r--node_modules/mocha/node_modules/diff/test/diffTest.js616
-rw-r--r--node_modules/mocha/node_modules/growl/History.md42
-rw-r--r--node_modules/mocha/node_modules/growl/Readme.md93
-rw-r--r--node_modules/mocha/node_modules/growl/lib/growl.js188
-rw-r--r--node_modules/mocha/node_modules/growl/package.json22
-rw-r--r--node_modules/mocha/node_modules/growl/test.js16
-rw-r--r--node_modules/mocha/node_modules/jade/.npmignore4
-rw-r--r--node_modules/mocha/node_modules/jade/LICENSE22
-rwxr-xr-xnode_modules/mocha/node_modules/jade/bin/jade125
-rw-r--r--node_modules/mocha/node_modules/jade/index.js2
-rw-r--r--node_modules/mocha/node_modules/jade/jade.js3140
-rw-r--r--node_modules/mocha/node_modules/jade/jade.min.js2
-rw-r--r--node_modules/mocha/node_modules/jade/lib/compiler.js503
-rw-r--r--node_modules/mocha/node_modules/jade/lib/doctypes.js18
-rw-r--r--node_modules/mocha/node_modules/jade/lib/filters.js97
-rw-r--r--node_modules/mocha/node_modules/jade/lib/inline-tags.js28
-rw-r--r--node_modules/mocha/node_modules/jade/lib/jade.js237
-rw-r--r--node_modules/mocha/node_modules/jade/lib/lexer.js707
-rw-r--r--node_modules/mocha/node_modules/jade/lib/nodes/block-comment.js33
-rw-r--r--node_modules/mocha/node_modules/jade/lib/nodes/block.js100
-rw-r--r--node_modules/mocha/node_modules/jade/lib/nodes/case.js43
-rw-r--r--node_modules/mocha/node_modules/jade/lib/nodes/code.js35
-rw-r--r--node_modules/mocha/node_modules/jade/lib/nodes/comment.js32
-rw-r--r--node_modules/mocha/node_modules/jade/lib/nodes/doctype.js29
-rw-r--r--node_modules/mocha/node_modules/jade/lib/nodes/each.js35
-rw-r--r--node_modules/mocha/node_modules/jade/lib/nodes/filter.js35
-rw-r--r--node_modules/mocha/node_modules/jade/lib/nodes/index.js20
-rw-r--r--node_modules/mocha/node_modules/jade/lib/nodes/literal.js31
-rw-r--r--node_modules/mocha/node_modules/jade/lib/nodes/mixin.js34
-rw-r--r--node_modules/mocha/node_modules/jade/lib/nodes/node.js14
-rw-r--r--node_modules/mocha/node_modules/jade/lib/nodes/tag.js80
-rw-r--r--node_modules/mocha/node_modules/jade/lib/nodes/text.js42
-rw-r--r--node_modules/mocha/node_modules/jade/lib/parser.js651
-rw-r--r--node_modules/mocha/node_modules/jade/lib/runtime.js118
-rw-r--r--node_modules/mocha/node_modules/jade/lib/self-closing.js18
-rw-r--r--node_modules/mocha/node_modules/jade/lib/utils.js49
-rw-r--r--node_modules/mocha/node_modules/jade/node_modules/mkdirp/.gitignore.orig2
-rw-r--r--node_modules/mocha/node_modules/jade/node_modules/mkdirp/.gitignore.rej5
-rw-r--r--node_modules/mocha/node_modules/jade/node_modules/mkdirp/.npmignore2
-rw-r--r--node_modules/mocha/node_modules/jade/node_modules/mkdirp/.travis.yml4
-rw-r--r--node_modules/mocha/node_modules/jade/node_modules/mkdirp/LICENSE21
-rw-r--r--node_modules/mocha/node_modules/jade/node_modules/mkdirp/README.markdown61
-rw-r--r--node_modules/mocha/node_modules/jade/node_modules/mkdirp/examples/pow.js6
-rw-r--r--node_modules/mocha/node_modules/jade/node_modules/mkdirp/examples/pow.js.orig6
-rw-r--r--node_modules/mocha/node_modules/jade/node_modules/mkdirp/examples/pow.js.rej19
-rw-r--r--node_modules/mocha/node_modules/jade/node_modules/mkdirp/index.js83
-rw-r--r--node_modules/mocha/node_modules/jade/node_modules/mkdirp/package.json37
-rw-r--r--node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/chmod.js38
-rw-r--r--node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/clobber.js37
-rw-r--r--node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/mkdirp.js28
-rw-r--r--node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/perm.js32
-rw-r--r--node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/perm_sync.js39
-rw-r--r--node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/race.js41
-rw-r--r--node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/rel.js32
-rw-r--r--node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/return.js25
-rw-r--r--node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/return_sync.js24
-rw-r--r--node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/sync.js32
-rw-r--r--node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/umask.js28
-rw-r--r--node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/umask_sync.js32
-rw-r--r--node_modules/mocha/node_modules/jade/package.json42
-rw-r--r--node_modules/mocha/node_modules/jade/runtime.js123
-rw-r--r--node_modules/mocha/node_modules/jade/runtime.min.js1
-rw-r--r--node_modules/mocha/package.json48
153 files changed, 24049 insertions, 0 deletions
diff --git a/node_modules/mocha/.npmignore b/node_modules/mocha/.npmignore
new file mode 100644
index 0000000..f4f8678
--- /dev/null
+++ b/node_modules/mocha/.npmignore
@@ -0,0 +1,5 @@
+support
+test
+examples
+*.sock
+lib-cov
diff --git a/node_modules/mocha/.travis.yml b/node_modules/mocha/.travis.yml
new file mode 100644
index 0000000..6a79c0c
--- /dev/null
+++ b/node_modules/mocha/.travis.yml
@@ -0,0 +1,5 @@
+language: node_js
+node_js:
+ - 0.4
+ - 0.6
+ #- 0.7 \ No newline at end of file
diff --git a/node_modules/mocha/History.md b/node_modules/mocha/History.md
new file mode 100644
index 0000000..4993f3f
--- /dev/null
+++ b/node_modules/mocha/History.md
@@ -0,0 +1,317 @@
+
+1.0.1 / 2012-04-04
+==================
+
+ * Fixed `.timeout()` in hooks
+ * Fixed: allow callback for `mocha.run()` in client version
+ * Fixed browser hook error display. Closes #361
+
+1.0.0 / 2012-03-24
+==================
+
+ * Added js API. Closes #265
+ * Added: initial run of tests with `--watch`. Closes #345
+ * Added: mark `location` as a global on the CS. Closes #311
+ * Added `markdown` reporter (github flavour)
+ * Added: scrolling menu to coverage.html. Closes #335
+ * Added source line to html report for Safari [Tyson Tate]
+ * Added "min" reporter, useful for `--watch` [Jakub Nešetřil]
+ * Added support for arbitrary compilers via . Closes #338 [Ian Young]
+ * Added Teamcity export to lib/reporters/index [Michael Riley]
+ * Fixed chopping of first char in error reporting. Closes #334 [reported by topfunky]
+ * Fixed terrible FF / Opera stack traces
+
+0.14.1 / 2012-03-06
+==================
+
+ * Added lib-cov to _.npmignore_
+ * Added reporter to `mocha.run([reporter])` as argument
+ * Added some margin-top to the HTML reporter
+ * Removed jQuery dependency
+ * Fixed `--watch`: purge require cache. Closes #266
+
+0.14.0 / 2012-03-01
+==================
+
+ * Added string diff support for terminal reporters
+
+0.13.0 / 2012-02-23
+==================
+
+ * Added preliminary test coverage support. Closes #5
+ * Added `HTMLCov` reporter
+ * Added `JSONCov` reporter [kunklejr]
+ * Added `xdescribe()` and `xit()` to the BDD interface. Closes #263 (docs * Changed: make json reporter output pretty json
+ * Fixed node-inspector support, swapped `--debug` for `debug` to match node.
+needed)
+Closes #247
+
+0.12.1 / 2012-02-14
+==================
+
+ * Added `npm docs mocha` support [TooTallNate]
+ * Added a `Context` object used for hook and test-case this. Closes #253
+ * Fixed `Suite#clone()` `.ctx` reference. Closes #262
+
+0.12.0 / 2012-02-02
+==================
+
+ * Added .coffee `--watch` support. Closes #242
+ * Added support to `--require` files relative to the CWD. Closes #241
+ * Added quick n dirty syntax highlighting. Closes #248
+ * Changed: made HTML progress indicator smaller
+ * Fixed xunit errors attribute [dhendo]
+
+0.10.2 / 2012-01-21
+==================
+
+ * Fixed suite count in reporter stats. Closes #222
+ * Fixed `done()` after timeout error reporting [Phil Sung]
+ * Changed the 0-based errors to 1
+
+0.10.1 / 2012-01-17
+==================
+
+ * Added support for node 0.7.x
+ * Fixed absolute path support. Closes #215 [kompiro]
+ * Fixed `--no-colors` option [Jussi Virtanen]
+ * Fixed Arial CSS typo in the correct file
+
+0.10.0 / 2012-01-13
+==================
+
+ * Added `-b, --bail` to exit on first exception [guillermo]
+ * Added support for `-gc` / `--expose-gc` [TooTallNate]
+ * Added `qunit`-inspired interface
+ * Added MIT LICENSE. Closes #194
+ * Added: `--watch` all .js in the CWD. Closes #139
+ * Fixed `self.test` reference in runner. Closes #189
+ * Fixed double reporting of uncaught exceptions after timeout. Closes #195
+
+0.8.2 / 2012-01-05
+==================
+
+ * Added test-case context support. Closes #113
+ * Fixed exit status. Closes #187
+ * Update commander. Closes #190
+
+0.8.1 / 2011-12-30
+==================
+
+ * Fixed reporting of uncaught exceptions. Closes #183
+ * Fixed error message defaulting [indutny]
+ * Changed mocha(1) from bash to node for windows [Nathan Rajlich]
+
+0.8.0 / 2011-12-28
+==================
+
+ * Added `XUnit` reporter [FeeFighters/visionmedia]
+ * Added `say(1)` notification support [Maciej Małecki]
+ * Changed: fail when done() is invoked with a non-Error. Closes #171
+ * Fixed `err.stack`, defaulting to message. Closes #180
+ * Fixed: `make tm` mkdir -p the dest. Closes #137
+ * Fixed mocha(1) --help bin name
+ * Fixed `-d` for `--debug` support
+
+0.7.1 / 2011-12-22
+==================
+
+ * Removed `mocha-debug(1)`, use `mocha --debug`
+ * Fixed CWD relative requires
+ * Fixed growl issue on windows [Raynos]
+ * Fixed: platform specific line endings [TooTallNate]
+ * Fixed: escape strings in HTML reporter. Closes #164
+
+0.7.0 / 2011-12-18
+==================
+
+ * Added support for IE{7,8} [guille]
+ * Changed: better browser nextTick implementation [guille]
+
+0.6.0 / 2011-12-18
+==================
+
+ * Added setZeroTimeout timeout for browser (nicer stack traces). Closes #153
+ * Added "view source" on hover for HTML reporter to make it obvious
+ * Changed: replace custom growl with growl lib
+ * Fixed duplicate reporting for HTML reporter. Closes #154
+ * Fixed silent hook errors in the HTML reporter. Closes #150
+
+0.5.0 / 2011-12-14
+==================
+
+ * Added: push node_modules directory onto module.paths for relative require Closes #93
+ * Added teamcity reporter [blindsey]
+ * Fixed: recover from uncaught exceptions for tests. Closes #94
+ * Fixed: only emit "test end" for uncaught within test, not hook
+
+0.4.0 / 2011-12-14
+==================
+
+ * Added support for test-specific timeouts via `this.timeout(0)`. Closes #134
+ * Added guillermo's client-side EventEmitter. Closes #132
+ * Added progress indicator to the HTML reporter
+ * Fixed slow browser tests. Closes #135
+ * Fixed "suite" color for light terminals
+ * Fixed `require()` leak spotted by [guillermo]
+
+0.3.6 / 2011-12-09
+==================
+
+ * Removed suite merging (for now)
+
+0.3.5 / 2011-12-08
+==================
+
+ * Added support for `window.onerror` [guillermo]
+ * Fixed: clear timeout on uncaught exceptions. Closes #131 [guillermo]
+ * Added `mocha.css` to PHONY list.
+ * Added `mocha.js` to PHONY list.
+
+0.3.4 / 2011-12-08
+==================
+
+ * Added: allow `done()` to be called with non-Error
+ * Added: return Runner from `mocha.run()`. Closes #126
+ * Fixed: run afterEach even on failures. Closes #125
+ * Fixed clobbering of current runnable. Closes #121
+
+0.3.3 / 2011-12-08
+==================
+
+ * Fixed hook timeouts. Closes #120
+ * Fixed uncaught exceptions in hooks
+
+0.3.2 / 2011-12-05
+==================
+
+ * Fixed weird reporting when `err.message` is not present
+
+0.3.1 / 2011-12-04
+==================
+
+ * Fixed hook event emitter leak. Closes #117
+ * Fixed: export `Spec` constructor. Closes #116
+
+0.3.0 / 2011-12-04
+==================
+
+ * Added `-w, --watch`. Closes #72
+ * Added `--ignore-leaks` to ignore global leak checking
+ * Added browser `?grep=pattern` support
+ * Added `--globals <names>` to specify accepted globals. Closes #99
+ * Fixed `mocha-debug(1)` on some systems. Closes #232
+ * Fixed growl total, use `runner.total`
+
+0.2.0 / 2011-11-30
+==================
+
+ * Added `--globals <names>` to specify accepted globals. Closes #99
+ * Fixed funky highlighting of messages. Closes #97
+ * Fixed `mocha-debug(1)`. Closes #232
+ * Fixed growl total, use runner.total
+
+0.1.0 / 2011-11-29
+==================
+
+ * Added `suiteSetup` and `suiteTeardown` to TDD interface [David Henderson]
+ * Added growl icons. Closes #84
+ * Fixed coffee-script support
+
+0.0.8 / 2011-11-25
+==================
+
+ * Fixed: use `Runner#total` for accurate reporting
+
+0.0.7 / 2011-11-25
+==================
+
+ * Added `Hook`
+ * Added `Runnable`
+ * Changed: `Test` is `Runnable`
+ * Fixed global leak reporting in hooks
+ * Fixed: > 2 calls to done() only report the error once
+ * Fixed: clear timer on failure. Closes #80
+
+0.0.6 / 2011-11-25
+==================
+
+ * Fixed return on immediate async error. Closes #80
+
+0.0.5 / 2011-11-24
+==================
+
+ * Fixed: make mocha.opts whitespace less picky [kkaefer]
+
+0.0.4 / 2011-11-24
+==================
+
+ * Added `--interfaces`
+ * Added `--reporters`
+ * Added `-c, --colors`. Closes #69
+ * Fixed hook timeouts
+
+0.0.3 / 2011-11-23
+==================
+
+ * Added `-C, --no-colors` to explicitly disable
+ * Added coffee-script support
+
+0.0.2 / 2011-11-22
+==================
+
+ * Fixed global leak detection due to Safari bind() change
+ * Fixed: escape html entities in Doc reporter
+ * Fixed: escape html entities in HTML reporter
+ * Fixed pending test support for HTML reporter. Closes #66
+
+0.0.1 / 2011-11-22
+==================
+
+ * Added `--timeout` second shorthand support, ex `--timeout 3s`.
+ * Fixed "test end" event for uncaughtExceptions. Closes #61
+
+0.0.1-alpha6 / 2011-11-19
+==================
+
+ * Added travis CI support (needs enabling when public)
+ * Added preliminary browser support
+ * Added `make mocha.css` target. Closes #45
+ * Added stack trace to TAP errors. Closes #52
+ * Renamed tearDown to teardown. Closes #49
+ * Fixed: cascading hooksc. Closes #30
+ * Fixed some colors for non-tty
+ * Fixed errors thrown in sync test-cases due to nextTick
+ * Fixed Base.window.width... again give precedence to 0.6.x
+
+0.0.1-alpha5 / 2011-11-17
+==================
+
+ * Added `doc` reporter. Closes #33
+ * Added suite merging. Closes #28
+ * Added TextMate bundle and `make tm`. Closes #20
+
+0.0.1-alpha4 / 2011-11-15
+==================
+
+ * Fixed getWindowSize() for 0.4.x
+
+0.0.1-alpha3 / 2011-11-15
+==================
+
+ * Added `-s, --slow <ms>` to specify "slow" test threshold
+ * Added `mocha-debug(1)`
+ * Added `mocha.opts` support. Closes #31
+ * Added: default [files] to _test/*.js_
+ * Added protection against multiple calls to `done()`. Closes #35
+ * Changed: bright yellow for slow Dot reporter tests
+
+0.0.1-alpha1 / 2011-11-08
+==================
+
+ * Missed this one :)
+
+0.0.1-alpha1 / 2011-11-08
+==================
+
+ * Initial release
diff --git a/node_modules/mocha/LICENSE b/node_modules/mocha/LICENSE
new file mode 100644
index 0000000..b66fae6
--- /dev/null
+++ b/node_modules/mocha/LICENSE
@@ -0,0 +1,22 @@
+(The MIT License)
+
+Copyright (c) 20011-2012 TJ Holowaychuk <tj@vision-media.ca>
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+'Software'), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file
diff --git a/node_modules/mocha/Makefile b/node_modules/mocha/Makefile
new file mode 100644
index 0000000..91a1da7
--- /dev/null
+++ b/node_modules/mocha/Makefile
@@ -0,0 +1,118 @@
+
+REPORTER = dot
+TM_DEST = ~/Library/Application\ Support/TextMate/Bundles
+TM_BUNDLE = JavaScript\ mocha.tmbundle
+SRC = $(shell find lib -name "*.js" -type f)
+SUPPORT = $(wildcard support/*.js)
+
+all: mocha.js mocha.css
+
+mocha.css: test/browser/style.css
+ cp -f $< $@
+
+mocha.js: $(SRC) $(SUPPORT)
+ @node support/compile $(SRC)
+ @cat \
+ support/head.js \
+ _mocha.js \
+ support/{tail,foot}.js \
+ > mocha.js
+
+clean:
+ rm -f mocha.{js,css}
+ rm -fr lib-cov
+ rm -f coverage.html
+
+test-cov: lib-cov
+ @COV=1 $(MAKE) test REPORTER=html-cov > coverage.html
+
+lib-cov:
+ @rm -fr ./$@
+ @jscoverage lib $@
+
+test: test-unit
+
+test-all: test-bdd test-tdd test-qunit test-exports test-unit test-grep test-jsapi test-compilers
+
+test-jsapi:
+ @node test/jsapi
+
+test-unit:
+ @./bin/mocha \
+ --reporter $(REPORTER) \
+ test/acceptance/*.js \
+ test/*.js
+
+test-compilers:
+ @./bin/mocha \
+ --reporter $(REPORTER) \
+ --compilers coffee:coffee-script,foo:./test/compiler/foo \
+ test/acceptance/test.coffee \
+ test/acceptance/test.foo
+
+test-bdd:
+ @./bin/mocha \
+ --reporter $(REPORTER) \
+ --ui bdd \
+ test/acceptance/interfaces/bdd
+
+test-tdd:
+ @./bin/mocha \
+ --reporter $(REPORTER) \
+ --ui tdd \
+ test/acceptance/interfaces/tdd
+
+test-qunit:
+ @./bin/mocha \
+ --reporter $(REPORTER) \
+ --ui qunit \
+ test/acceptance/interfaces/qunit
+
+test-exports:
+ @./bin/mocha \
+ --reporter $(REPORTER) \
+ --ui exports \
+ test/acceptance/interfaces/exports
+
+test-grep:
+ @./bin/mocha \
+ --reporter $(REPORTER) \
+ --grep fast \
+ test/acceptance/misc/grep
+
+test-bail:
+ @./bin/mocha \
+ --reporter $(REPORTER) \
+ --bail \
+ test/acceptance/misc/bail
+
+non-tty:
+ @./bin/mocha \
+ --reporter dot \
+ test/acceptance/interfaces/bdd 2>&1 > /tmp/dot.out
+
+ @echo dot:
+ @cat /tmp/dot.out
+
+ @./bin/mocha \
+ --reporter list \
+ test/acceptance/interfaces/bdd 2>&1 > /tmp/list.out
+
+ @echo list:
+ @cat /tmp/list.out
+
+ @./bin/mocha \
+ --reporter spec \
+ test/acceptance/interfaces/bdd 2>&1 > /tmp/spec.out
+
+ @echo spec:
+ @cat /tmp/spec.out
+
+watch:
+ @watch -q $(MAKE) mocha.{js,css}
+
+tm:
+ mkdir -p $(TM_DEST)/$(TM_BUNDLE)
+ cp -fr editors/$(TM_BUNDLE) $(TM_DEST)/$(TM_BUNDLE)
+
+.PHONY: test-cov test-jsapi test-compilers watch test test-all test-bdd test-tdd test-qunit test-exports test-unit non-tty test-grep tm clean
diff --git a/node_modules/mocha/Readme.md b/node_modules/mocha/Readme.md
new file mode 100644
index 0000000..d534371
--- /dev/null
+++ b/node_modules/mocha/Readme.md
@@ -0,0 +1,34 @@
+ [![Build Status](https://secure.travis-ci.org/visionmedia/mocha.png)](http://travis-ci.org/visionmedia/mocha)
+
+ [![Mocha test framework](http://f.cl.ly/items/3l1k0n2A1U3M1I1L210p/Screen%20Shot%202012-02-24%20at%202.21.43%20PM.png)](http://visionmedia.github.com/mocha)
+
+ Mocha is a simple, flexible, fun JavaScript test framework for node.js and the browser. For more information view the [documentation](http://visionmedia.github.com/mocha).
+
+## Contributors
+
+```
+project: mocha
+commits: 502
+files : 86
+authors:
+ 352 Tj Holowaychuk 70.1%
+ 98 TJ Holowaychuk 19.5%
+ 21 Guillermo Rauch 4.2%
+ 6 James Carr 1.2%
+ 4 Joshua Krall 0.8%
+ 3 Ben Lindsey 0.6%
+ 3 Nathan Rajlich 0.6%
+ 2 FARKAS Máté 0.4%
+ 2 Quang Van 0.4%
+ 1 Steve Mason 0.2%
+ 1 Yuest Wang 0.2%
+ 1 hokaccha 0.2%
+ 1 David Henderson 0.2%
+ 1 Fedor Indutny 0.2%
+ 1 Fredrik Lindin 0.2%
+ 1 Harry Brundage 0.2%
+ 1 Konstantin Käfer 0.2%
+ 1 Maciej Małecki 0.2%
+ 1 Raynos 0.2%
+ 1 Ryunosuke SATO 0.2%
+```
diff --git a/node_modules/mocha/_mocha.js b/node_modules/mocha/_mocha.js
new file mode 100644
index 0000000..c9bd1c8
--- /dev/null
+++ b/node_modules/mocha/_mocha.js
@@ -0,0 +1,3916 @@
+
+// CommonJS require()
+
+function require(p){
+ var path = require.resolve(p)
+ , mod = require.modules[path];
+ if (!mod) throw new Error('failed to require "' + p + '"');
+ if (!mod.exports) {
+ mod.exports = {};
+ mod.call(mod.exports, mod, mod.exports, require.relative(path));
+ }
+ return mod.exports;
+ }
+
+require.modules = {};
+
+require.resolve = function (path){
+ var orig = path
+ , reg = path + '.js'
+ , index = path + '/index.js';
+ return require.modules[reg] && reg
+ || require.modules[index] && index
+ || orig;
+ };
+
+require.register = function (path, fn){
+ require.modules[path] = fn;
+ };
+
+require.relative = function (parent) {
+ return function(p){
+ if ('.' != p.charAt(0)) return require(p);
+
+ var path = parent.split('/')
+ , segs = p.split('/');
+ path.pop();
+
+ for (var i = 0; i < segs.length; i++) {
+ var seg = segs[i];
+ if ('..' == seg) path.pop();
+ else if ('.' != seg) path.push(seg);
+ }
+
+ return require(path.join('/'));
+ };
+ };
+
+
+require.register("browser/debug.js", function(module, exports, require){
+
+module.exports = function(type){
+ return function(){
+
+ }
+};
+}); // module: browser/debug.js
+
+require.register("browser/diff.js", function(module, exports, require){
+
+}); // module: browser/diff.js
+
+require.register("browser/events.js", function(module, exports, require){
+
+/**
+ * Module exports.
+ */
+
+exports.EventEmitter = EventEmitter;
+
+/**
+ * Check if `obj` is an array.
+ */
+
+function isArray(obj) {
+ return '[object Array]' == {}.toString.call(obj);
+}
+
+/**
+ * Event emitter constructor.
+ *
+ * @api public.
+ */
+
+function EventEmitter(){};
+
+/**
+ * Adds a listener.
+ *
+ * @api public
+ */
+
+EventEmitter.prototype.on = function (name, fn) {
+ if (!this.$events) {
+ this.$events = {};
+ }
+
+ if (!this.$events[name]) {
+ this.$events[name] = fn;
+ } else if (isArray(this.$events[name])) {
+ this.$events[name].push(fn);
+ } else {
+ this.$events[name] = [this.$events[name], fn];
+ }
+
+ return this;
+};
+
+EventEmitter.prototype.addListener = EventEmitter.prototype.on;
+
+/**
+ * Adds a volatile listener.
+ *
+ * @api public
+ */
+
+EventEmitter.prototype.once = function (name, fn) {
+ var self = this;
+
+ function on () {
+ self.removeListener(name, on);
+ fn.apply(this, arguments);
+ };
+
+ on.listener = fn;
+ this.on(name, on);
+
+ return this;
+};
+
+/**
+ * Removes a listener.
+ *
+ * @api public
+ */
+
+EventEmitter.prototype.removeListener = function (name, fn) {
+ if (this.$events && this.$events[name]) {
+ var list = this.$events[name];
+
+ if (isArray(list)) {
+ var pos = -1;
+
+ for (var i = 0, l = list.length; i < l; i++) {
+ if (list[i] === fn || (list[i].listener && list[i].listener === fn)) {
+ pos = i;
+ break;
+ }
+ }
+
+ if (pos < 0) {
+ return this;
+ }
+
+ list.splice(pos, 1);
+
+ if (!list.length) {
+ delete this.$events[name];
+ }
+ } else if (list === fn || (list.listener && list.listener === fn)) {
+ delete this.$events[name];
+ }
+ }
+
+ return this;
+};
+
+/**
+ * Removes all listeners for an event.
+ *
+ * @api public
+ */
+
+EventEmitter.prototype.removeAllListeners = function (name) {
+ if (name === undefined) {
+ this.$events = {};
+ return this;
+ }
+
+ if (this.$events && this.$events[name]) {
+ this.$events[name] = null;
+ }
+
+ return this;
+};
+
+/**
+ * Gets all listeners for a certain event.
+ *
+ * @api publci
+ */
+
+EventEmitter.prototype.listeners = function (name) {
+ if (!this.$events) {
+ this.$events = {};
+ }
+
+ if (!this.$events[name]) {
+ this.$events[name] = [];
+ }
+
+ if (!isArray(this.$events[name])) {
+ this.$events[name] = [this.$events[name]];
+ }
+
+ return this.$events[name];
+};
+
+/**
+ * Emits an event.
+ *
+ * @api public
+ */
+
+EventEmitter.prototype.emit = function (name) {
+ if (!this.$events) {
+ return false;
+ }
+
+ var handler = this.$events[name];
+
+ if (!handler) {
+ return false;
+ }
+
+ var args = [].slice.call(arguments, 1);
+
+ if ('function' == typeof handler) {
+ handler.apply(this, args);
+ } else if (isArray(handler)) {
+ var listeners = handler.slice();
+
+ for (var i = 0, l = listeners.length; i < l; i++) {
+ listeners[i].apply(this, args);
+ }
+ } else {
+ return false;
+ }
+
+ return true;
+};
+}); // module: browser/events.js
+
+require.register("browser/fs.js", function(module, exports, require){
+
+}); // module: browser/fs.js
+
+require.register("browser/path.js", function(module, exports, require){
+
+}); // module: browser/path.js
+
+require.register("browser/progress.js", function(module, exports, require){
+
+/**
+ * Expose `Progress`.
+ */
+
+module.exports = Progress;
+
+/**
+ * Initialize a new `Progress` indicator.
+ */
+
+function Progress() {
+ this.percent = 0;
+ this.size(0);
+ this.fontSize(11);
+ this.font('helvetica, arial, sans-serif');
+}
+
+/**
+ * Set progress size to `n`.
+ *
+ * @param {Number} n
+ * @return {Progress} for chaining
+ * @api public
+ */
+
+Progress.prototype.size = function(n){
+ this._size = n;
+ return this;
+};
+
+/**
+ * Set text to `str`.
+ *
+ * @param {String} str
+ * @return {Progress} for chaining
+ * @api public
+ */
+
+Progress.prototype.text = function(str){
+ this._text = str;
+ return this;
+};
+
+/**
+ * Set font size to `n`.
+ *
+ * @param {Number} n
+ * @return {Progress} for chaining
+ * @api public
+ */
+
+Progress.prototype.fontSize = function(n){
+ this._fontSize = n;
+ return this;
+};
+
+/**
+ * Set font `family`.
+ *
+ * @param {String} family
+ * @return {Progress} for chaining
+ */
+
+Progress.prototype.font = function(family){
+ this._font = family;
+ return this;
+};
+
+/**
+ * Update percentage to `n`.
+ *
+ * @param {Number} n
+ * @return {Progress} for chaining
+ */
+
+Progress.prototype.update = function(n){
+ this.percent = n;
+ return this;
+};
+
+/**
+ * Draw on `ctx`.
+ *
+ * @param {CanvasRenderingContext2d} ctx
+ * @return {Progress} for chaining
+ */
+
+Progress.prototype.draw = function(ctx){
+ var percent = Math.min(this.percent, 100)
+ , size = this._size
+ , half = size / 2
+ , x = half
+ , y = half
+ , rad = half - 1
+ , fontSize = this._fontSize;
+
+ ctx.font = fontSize + 'px ' + this._font;
+
+ var angle = Math.PI * 2 * (percent / 100);
+ ctx.clearRect(0, 0, size, size);
+
+ // outer circle
+ ctx.strokeStyle = '#9f9f9f';
+ ctx.beginPath();
+ ctx.arc(x, y, rad, 0, angle, false);
+ ctx.stroke();
+
+ // inner circle
+ ctx.strokeStyle = '#eee';
+ ctx.beginPath();
+ ctx.arc(x, y, rad - 1, 0, angle, true);
+ ctx.stroke();
+
+ // text
+ var text = this._text || (percent | 0) + '%'
+ , w = ctx.measureText(text).width;
+
+ ctx.fillText(
+ text
+ , x - w / 2 + 1
+ , y + fontSize / 2 - 1);
+
+ return this;
+};
+
+}); // module: browser/progress.js
+
+require.register("browser/tty.js", function(module, exports, require){
+
+exports.isatty = function(){
+ return true;
+};
+
+exports.getWindowSize = function(){
+ return [window.innerHeight, window.innerWidth];
+};
+}); // module: browser/tty.js
+
+require.register("context.js", function(module, exports, require){
+
+/**
+ * Expose `Context`.
+ */
+
+module.exports = Context;
+
+/**
+ * Initialize a new `Context`.
+ *
+ * @api private
+ */
+
+function Context(){}
+
+/**
+ * Set the context `Runnable` to `runnable`.
+ *
+ * @param {Runnable} runnable
+ * @return {Context}
+ * @api private
+ */
+
+Context.prototype.runnable = function(runnable){
+ this._runnable = runnable;
+ return this;
+};
+
+/**
+ * Set test timeout `ms`.
+ *
+ * @param {Number} ms
+ * @return {Context} self
+ * @api private
+ */
+
+Context.prototype.timeout = function(ms){
+ this._runnable.timeout(ms);
+ return this;
+};
+
+/**
+ * Inspect the context void of `._runnable`.
+ *
+ * @return {String}
+ * @api private
+ */
+
+Context.prototype.inspect = function(){
+ return JSON.stringify(this, function(key, val){
+ return '_runnable' == key
+ ? undefined
+ : val;
+ }, 2);
+};
+
+}); // module: context.js
+
+require.register("hook.js", function(module, exports, require){
+
+/**
+ * Module dependencies.
+ */
+
+var Runnable = require('./runnable');
+
+/**
+ * Expose `Hook`.
+ */
+
+module.exports = Hook;
+
+/**
+ * Initialize a new `Hook` with the given `title` and callback `fn`.
+ *
+ * @param {String} title
+ * @param {Function} fn
+ * @api private
+ */
+
+function Hook(title, fn) {
+ Runnable.call(this, title, fn);
+ this.type = 'hook';
+}
+
+/**
+ * Inherit from `Runnable.prototype`.
+ */
+
+Hook.prototype = new Runnable;
+Hook.prototype.constructor = Hook;
+
+
+}); // module: hook.js
+
+require.register("interfaces/bdd.js", function(module, exports, require){
+
+/**
+ * Module dependencies.
+ */
+
+var Suite = require('../suite')
+ , Test = require('../test');
+
+/**
+ * BDD-style interface:
+ *
+ * describe('Array', function(){
+ * describe('#indexOf()', function(){
+ * it('should return -1 when not present', function(){
+ *
+ * });
+ *
+ * it('should return the index when present', function(){
+ *
+ * });
+ * });
+ * });
+ *
+ */
+
+module.exports = function(suite){
+ var suites = [suite];
+
+ suite.on('pre-require', function(context){
+
+ // noop variants
+
+ context.xdescribe = function(){};
+ context.xit = function(){};
+
+ /**
+ * Execute before running tests.
+ */
+
+ context.before = function(fn){
+ suites[0].beforeAll(fn);
+ };
+
+ /**
+ * Execute after running tests.
+ */
+
+ context.after = function(fn){
+ suites[0].afterAll(fn);
+ };
+
+ /**
+ * Execute before each test case.
+ */
+
+ context.beforeEach = function(fn){
+ suites[0].beforeEach(fn);
+ };
+
+ /**
+ * Execute after each test case.
+ */
+
+ context.afterEach = function(fn){
+ suites[0].afterEach(fn);
+ };
+
+ /**
+ * Describe a "suite" with the given `title`
+ * and callback `fn` containing nested suites
+ * and/or tests.
+ */
+
+ context.describe = function(title, fn){
+ var suite = Suite.create(suites[0], title);
+ suites.unshift(suite);
+ fn();
+ suites.shift();
+ };
+
+ /**
+ * Describe a specification or test-case
+ * with the given `title` and callback `fn`
+ * acting as a thunk.
+ */
+
+ context.it = function(title, fn){
+ suites[0].addTest(new Test(title, fn));
+ };
+ });
+};
+
+}); // module: interfaces/bdd.js
+
+require.register("interfaces/exports.js", function(module, exports, require){
+
+/**
+ * Module dependencies.
+ */
+
+var Suite = require('../suite')
+ , Test = require('../test');
+
+/**
+ * TDD-style interface:
+ *
+ * exports.Array = {
+ * '#indexOf()': {
+ * 'should return -1 when the value is not present': function(){
+ *
+ * },
+ *
+ * 'should return the correct index when the value is present': function(){
+ *
+ * }
+ * }
+ * };
+ *
+ */
+
+module.exports = function(suite){
+ var suites = [suite];
+
+ suite.on('require', visit);
+
+ function visit(obj) {
+ var suite;
+ for (var key in obj) {
+ if ('function' == typeof obj[key]) {
+ var fn = obj[key];
+ switch (key) {
+ case 'before':
+ suites[0].beforeAll(fn);
+ break;
+ case 'after':
+ suites[0].afterAll(fn);
+ break;
+ case 'beforeEach':
+ suites[0].beforeEach(fn);
+ break;
+ case 'afterEach':
+ suites[0].afterEach(fn);
+ break;
+ default:
+ suites[0].addTest(new Test(key, fn));
+ }
+ } else {
+ var suite = Suite.create(suites[0], key);
+ suites.unshift(suite);
+ visit(obj[key]);
+ suites.shift();
+ }
+ }
+ }
+};
+}); // module: interfaces/exports.js
+
+require.register("interfaces/index.js", function(module, exports, require){
+
+exports.bdd = require('./bdd');
+exports.tdd = require('./tdd');
+exports.qunit = require('./qunit');
+exports.exports = require('./exports');
+
+}); // module: interfaces/index.js
+
+require.register("interfaces/qunit.js", function(module, exports, require){
+
+/**
+ * Module dependencies.
+ */
+
+var Suite = require('../suite')
+ , Test = require('../test');
+
+/**
+ * QUnit-style interface:
+ *
+ * suite('Array');
+ *
+ * test('#length', function(){
+ * var arr = [1,2,3];
+ * ok(arr.length == 3);
+ * });
+ *
+ * test('#indexOf()', function(){
+ * var arr = [1,2,3];
+ * ok(arr.indexOf(1) == 0);
+ * ok(arr.indexOf(2) == 1);
+ * ok(arr.indexOf(3) == 2);
+ * });
+ *
+ * suite('String');
+ *
+ * test('#length', function(){
+ * ok('foo'.length == 3);
+ * });
+ *
+ */
+
+module.exports = function(suite){
+ var suites = [suite];
+
+ suite.on('pre-require', function(context){
+
+ /**
+ * Execute before running tests.
+ */
+
+ context.before = function(fn){
+ suites[0].beforeAll(fn);
+ };
+
+ /**
+ * Execute after running tests.
+ */
+
+ context.after = function(fn){
+ suites[0].afterAll(fn);
+ };
+
+ /**
+ * Execute before each test case.
+ */
+
+ context.beforeEach = function(fn){
+ suites[0].beforeEach(fn);
+ };
+
+ /**
+ * Execute after each test case.
+ */
+
+ context.afterEach = function(fn){
+ suites[0].afterEach(fn);
+ };
+
+ /**
+ * Describe a "suite" with the given `title`.
+ */
+
+ context.suite = function(title){
+ if (suites.length > 1) suites.shift();
+ var suite = Suite.create(suites[0], title);
+ suites.unshift(suite);
+ };
+
+ /**
+ * Describe a specification or test-case
+ * with the given `title` and callback `fn`
+ * acting as a thunk.
+ */
+
+ context.test = function(title, fn){
+ suites[0].addTest(new Test(title, fn));
+ };
+ });
+};
+
+}); // module: interfaces/qunit.js
+
+require.register("interfaces/tdd.js", function(module, exports, require){
+
+/**
+ * Module dependencies.
+ */
+
+var Suite = require('../suite')
+ , Test = require('../test');
+
+/**
+ * TDD-style interface:
+ *
+ * suite('Array', function(){
+ * suite('#indexOf()', function(){
+ * suiteSetup(function(){
+ *
+ * });
+ *
+ * test('should return -1 when not present', function(){
+ *
+ * });
+ *
+ * test('should return the index when present', function(){
+ *
+ * });
+ *
+ * suiteTeardown(function(){
+ *
+ * });
+ * });
+ * });
+ *
+ */
+
+module.exports = function(suite){
+ var suites = [suite];
+
+ suite.on('pre-require', function(context){
+
+ /**
+ * Execute before each test case.
+ */
+
+ context.setup = function(fn){
+ suites[0].beforeEach(fn);
+ };
+
+ /**
+ * Execute after each test case.
+ */
+
+ context.teardown = function(fn){
+ suites[0].afterEach(fn);
+ };
+
+ /**
+ * Execute before the suite.
+ */
+
+ context.suiteSetup = function(fn){
+ suites[0].beforeAll(fn);
+ };
+
+ /**
+ * Execute after the suite.
+ */
+
+ context.suiteTeardown = function(fn){
+ suites[0].afterAll(fn);
+ };
+
+ /**
+ * Describe a "suite" with the given `title`
+ * and callback `fn` containing nested suites
+ * and/or tests.
+ */
+
+ context.suite = function(title, fn){
+ var suite = Suite.create(suites[0], title);
+ suites.unshift(suite);
+ fn();
+ suites.shift();
+ };
+
+ /**
+ * Describe a specification or test-case
+ * with the given `title` and callback `fn`
+ * acting as a thunk.
+ */
+
+ context.test = function(title, fn){
+ suites[0].addTest(new Test(title, fn));
+ };
+ });
+};
+
+}); // module: interfaces/tdd.js
+
+require.register("mocha.js", function(module, exports, require){
+
+/*!
+ * mocha
+ * Copyright(c) 2011 TJ Holowaychuk <tj@vision-media.ca>
+ * MIT Licensed
+ */
+
+/**
+ * Module dependencies.
+ */
+
+var path = require('browser/path');
+
+/**
+ * Expose `Mocha`.
+ */
+
+exports = module.exports = Mocha;
+
+/**
+ * Library version.
+ */
+
+exports.version = '1.0.1';
+
+/**
+ * Expose internals.
+ */
+
+exports.utils = require('./utils');
+exports.interfaces = require('./interfaces');
+exports.reporters = require('./reporters');
+exports.Runnable = require('./runnable');
+exports.Context = require('./context');
+exports.Runner = require('./runner');
+exports.Suite = require('./suite');
+exports.Hook = require('./hook');
+exports.Test = require('./test');
+
+/**
+ * Return image `name` path.
+ *
+ * @param {String} name
+ * @return {String}
+ * @api private
+ */
+
+function image(name) {
+ return __dirname + '/../images/' + name + '.png';
+}
+
+/**
+ * Setup mocha with `options`.
+ *
+ * Options:
+ *
+ * - `ui` name "bdd", "tdd", "exports" etc
+ * - `reporter` reporter instance, defaults to `mocha.reporters.Dot`
+ * - `globals` array of accepted globals
+ * - `timeout` timeout in milliseconds
+ * - `ignoreLeaks` ignore global leaks
+ *
+ * @param {Object} options
+ * @api public
+ */
+
+function Mocha(options) {
+ options = options || {};
+ this.files = [];
+ this.options = options;
+ this.suite = new exports.Suite('', new exports.Context);
+ this.ui(options.ui);
+ this.reporter(options.reporter);
+ if (options.timeout) this.suite.timeout(options.timeout);
+}
+
+/**
+ * Add test `file`.
+ *
+ * @param {String} file
+ * @api public
+ */
+
+Mocha.prototype.addFile = function(file){
+ this.files.push(file);
+ return this;
+};
+
+/**
+ * Set reporter to `name`, defaults to "dot".
+ *
+ * @param {String} name
+ * @api public
+ */
+
+Mocha.prototype.reporter = function(name){
+ name = name || 'dot';
+ this._reporter = require('./reporters/' + name);
+ if (!this._reporter) throw new Error('invalid reporter "' + name + '"');
+ return this;
+};
+
+/**
+ * Set test UI `name`, defaults to "bdd".
+ *
+ * @param {String} bdd
+ * @api public
+ */
+
+Mocha.prototype.ui = function(name){
+ name = name || 'bdd';
+ this._ui = exports.interfaces[name];
+ if (!this._ui) throw new Error('invalid interface "' + name + '"');
+ this._ui = this._ui(this.suite);
+ return this;
+};
+
+/**
+ * Load registered files.
+ *
+ * @api private
+ */
+
+Mocha.prototype.loadFiles = function(){
+ var suite = this.suite;
+ this.files.forEach(function(file){
+ file = path.resolve(file);
+ suite.emit('pre-require', global, file);
+ suite.emit('require', require(file), file);
+ suite.emit('post-require', global, file);
+ });
+};
+
+/**
+ * Enable growl support.
+ *
+ * @api private
+ */
+
+Mocha.prototype.growl = function(runner, reporter) {
+ var notify = require('growl');
+
+ runner.on('end', function(){
+ var stats = reporter.stats;
+ if (stats.failures) {
+ var msg = stats.failures + ' of ' + runner.total + ' tests failed';
+ notify(msg, { title: 'Failed', image: image('fail') });
+ } else {
+ notify(stats.passes + ' tests passed in ' + stats.duration + 'ms', {
+ title: 'Passed'
+ , image: image('pass')
+ });
+ }
+ });
+};
+
+/**
+ * Run tests and invoke `fn()` when complete.
+ *
+ * @param {Function} fn
+ * @return {Runner}
+ * @api public
+ */
+
+Mocha.prototype.run = function(fn){
+ this.loadFiles();
+ var suite = this.suite;
+ var options = this.options;
+ var runner = new exports.Runner(suite);
+ var reporter = new this._reporter(runner);
+ runner.ignoreLeaks = options.ignoreLeaks;
+ if (options.grep) runner.grep(options.grep);
+ if (options.globals) runner.globals(options.globals);
+ if (options.growl) this.growl(runner, reporter);
+ return runner.run(fn);
+};
+
+}); // module: mocha.js
+
+require.register("reporters/base.js", function(module, exports, require){
+
+/**
+ * Module dependencies.
+ */
+
+var tty = require('browser/tty')
+ , diff = require('browser/diff');
+
+/**
+ * Check if both stdio streams are associated with a tty.
+ */
+
+var isatty = tty.isatty(1) && tty.isatty(2);
+
+/**
+ * Expose `Base`.
+ */
+
+exports = module.exports = Base;
+
+/**
+ * Enable coloring by default.
+ */
+
+exports.useColors = isatty;
+
+/**
+ * Default color map.
+ */
+
+exports.colors = {
+ 'pass': 90
+ , 'fail': 31
+ , 'bright pass': 92
+ , 'bright fail': 91
+ , 'bright yellow': 93
+ , 'pending': 36
+ , 'suite': 0
+ , 'error title': 0
+ , 'error message': 31
+ , 'error stack': 90
+ , 'checkmark': 32
+ , 'fast': 90
+ , 'medium': 33
+ , 'slow': 31
+ , 'green': 32
+ , 'light': 90
+ , 'diff gutter': 90
+ , 'diff added': 42
+ , 'diff removed': 41
+};
+
+/**
+ * Color `str` with the given `type`,
+ * allowing colors to be disabled,
+ * as well as user-defined color
+ * schemes.
+ *
+ * @param {String} type
+ * @param {String} str
+ * @return {String}
+ * @api private
+ */
+
+var color = exports.color = function(type, str) {
+ if (!exports.useColors) return str;
+ return '\033[' + exports.colors[type] + 'm' + str + '\033[0m';
+};
+
+/**
+ * Expose term window size, with some
+ * defaults for when stderr is not a tty.
+ */
+
+exports.window = {
+ width: isatty
+ ? process.stdout.getWindowSize
+ ? process.stdout.getWindowSize(1)[0]
+ : tty.getWindowSize()[1]
+ : 75
+};
+
+/**
+ * Expose some basic cursor interactions
+ * that are common among reporters.
+ */
+
+exports.cursor = {
+ hide: function(){
+ process.stdout.write('\033[?25l');
+ },
+
+ show: function(){
+ process.stdout.write('\033[?25h');
+ },
+
+ deleteLine: function(){
+ process.stdout.write('\033[2K');
+ },
+
+ beginningOfLine: function(){
+ process.stdout.write('\033[0G');
+ },
+
+ CR: function(){
+ exports.cursor.deleteLine();
+ exports.cursor.beginningOfLine();
+ }
+};
+
+/**
+ * A test is considered slow if it
+ * exceeds the following value in milliseconds.
+ */
+
+exports.slow = 75;
+
+/**
+ * Outut the given `failures` as a list.
+ *
+ * @param {Array} failures
+ * @api public
+ */
+
+exports.list = function(failures){
+ console.error();
+ failures.forEach(function(test, i){
+ // format
+ var fmt = color('error title', ' %s) %s:\n')
+ + color('error message', ' %s')
+ + color('error stack', '\n%s\n');
+
+ // msg
+ var err = test.err
+ , message = err.message || ''
+ , stack = err.stack || message
+ , index = stack.indexOf(message) + message.length
+ , msg = stack.slice(0, index)
+ , actual = err.actual
+ , expected = err.expected;
+
+ // actual / expected diff
+ if ('string' == typeof actual && 'string' == typeof expected) {
+ var len = Math.max(actual.length, expected.length);
+
+ if (len < 20) msg = errorDiff(err, 'Chars');
+ else msg = errorDiff(err, 'Words');
+
+ // linenos
+ var lines = msg.split('\n');
+ if (lines.length > 4) {
+ var width = String(lines.length).length;
+ msg = lines.map(function(str, i){
+ return pad(++i, width) + ' |' + ' ' + str;
+ }).join('\n');
+ }
+
+ // legend
+ msg = '\n'
+ + color('diff removed', 'actual')
+ + ' '
+ + color('diff added', 'expected')
+ + '\n\n'
+ + msg
+ + '\n';
+
+ // indent
+ msg = msg.replace(/^/gm, ' ');
+
+ fmt = color('error title', ' %s) %s:\n%s')
+ + color('error stack', '\n%s\n');
+ }
+
+ // indent stack trace without msg
+ stack = stack.slice(index ? index + 1 : index)
+ .replace(/^/gm, ' ');
+
+ console.error(fmt, (i + 1), test.fullTitle(), msg, stack);
+ });
+};
+
+/**
+ * Initialize a new `Base` reporter.
+ *
+ * All other reporters generally
+ * inherit from this reporter, providing
+ * stats such as test duration, number
+ * of tests passed / failed etc.
+ *
+ * @param {Runner} runner
+ * @api public
+ */
+
+function Base(runner) {
+ var self = this
+ , stats = this.stats = { suites: 0, tests: 0, passes: 0, failures: 0 }
+ , failures = this.failures = [];
+
+ if (!runner) return;
+ this.runner = runner;
+
+ runner.on('start', function(){
+ stats.start = new Date;
+ });
+
+ runner.on('suite', function(suite){
+ stats.suites = stats.suites || 0;
+ suite.root || stats.suites++;
+ });
+
+ runner.on('test end', function(test){
+ stats.tests = stats.tests || 0;
+ stats.tests++;
+ });
+
+ runner.on('pass', function(test){
+ stats.passes = stats.passes || 0;
+
+ var medium = exports.slow / 2;
+ test.speed = test.duration > exports.slow
+ ? 'slow'
+ : test.duration > medium
+ ? 'medium'
+ : 'fast';
+
+ stats.passes++;
+ });
+
+ runner.on('fail', function(test, err){
+ stats.failures = stats.failures || 0;
+ stats.failures++;
+ test.err = err;
+ failures.push(test);
+ });
+
+ runner.on('end', function(){
+ stats.end = new Date;
+ stats.duration = new Date - stats.start;
+ });
+}
+
+/**
+ * Output common epilogue used by many of
+ * the bundled reporters.
+ *
+ * @api public
+ */
+
+Base.prototype.epilogue = function(){
+ var stats = this.stats
+ , fmt;
+
+ console.log();
+
+ // failure
+ if (stats.failures) {
+ fmt = color('bright fail', ' ✖')
+ + color('fail', ' %d of %d tests failed')
+ + color('light', ':')
+
+ console.error(fmt, stats.failures, this.runner.total);
+ Base.list(this.failures);
+ console.error();
+ return;
+ }
+
+ // pass
+ fmt = color('bright pass', ' ✔')
+ + color('green', ' %d tests complete')
+ + color('light', ' (%dms)');
+
+ console.log(fmt, stats.tests || 0, stats.duration);
+ console.log();
+};
+
+/**
+ * Pad the given `str` to `len`.
+ *
+ * @param {String} str
+ * @param {String} len
+ * @return {String}
+ * @api private
+ */
+
+function pad(str, len) {
+ str = String(str);
+ return Array(len - str.length + 1).join(' ') + str;
+}
+
+/**
+ * Return a character diff for `err`.
+ *
+ * @param {Error} err
+ * @return {String}
+ * @api private
+ */
+
+function errorDiff(err, type) {
+ return diff['diff' + type](err.actual, err.expected).map(function(str){
+ if (str.added) return colorLines('diff added', str.value);
+ if (str.removed) return colorLines('diff removed', str.value);
+ return str.value;
+ }).join('');
+}
+
+/**
+ * Color lines for `str`, using the color `name`.
+ *
+ * @param {String} name
+ * @param {String} str
+ * @return {String}
+ * @api private
+ */
+
+function colorLines(name, str) {
+ return str.split('\n').map(function(str){
+ return color(name, str);
+ }).join('\n');
+}
+
+}); // module: reporters/base.js
+
+require.register("reporters/doc.js", function(module, exports, require){
+
+/**
+ * Module dependencies.
+ */
+
+var Base = require('./base')
+ , utils = require('../utils');
+
+/**
+ * Expose `Doc`.
+ */
+
+exports = module.exports = Doc;
+
+/**
+ * Initialize a new `Doc` reporter.
+ *
+ * @param {Runner} runner
+ * @api public
+ */
+
+function Doc(runner) {
+ Base.call(this, runner);
+
+ var self = this
+ , stats = this.stats
+ , total = runner.total
+ , indents = 2;
+
+ function indent() {
+ return Array(indents).join(' ');
+ }
+
+ runner.on('suite', function(suite){
+ if (suite.root) return;
+ ++indents;
+ console.log('%s<section class="suite">', indent());
+ ++indents;
+ console.log('%s<h1>%s</h1>', indent(), suite.title);
+ console.log('%s<dl>', indent());
+ });
+
+ runner.on('suite end', function(suite){
+ if (suite.root) return;
+ console.log('%s</dl>', indent());
+ --indents;
+ console.log('%s</section>', indent());
+ --indents;
+ });
+
+ runner.on('pass', function(test){
+ console.log('%s <dt>%s</dt>', indent(), test.title);
+ var code = utils.escape(clean(test.fn.toString()));
+ console.log('%s <dd><pre><code>%s</code></pre></dd>', indent(), code);
+ });
+}
+
+/**
+ * Strip the function definition from `str`,
+ * and re-indent for pre whitespace.
+ */
+
+function clean(str) {
+ str = str
+ .replace(/^function *\(.*\) *{/, '')
+ .replace(/\s+\}$/, '');
+
+ var spaces = str.match(/^\n?( *)/)[1].length
+ , re = new RegExp('^ {' + spaces + '}', 'gm');
+
+ str = str.replace(re, '');
+
+ return str;
+}
+}); // module: reporters/doc.js
+
+require.register("reporters/dot.js", function(module, exports, require){
+
+/**
+ * Module dependencies.
+ */
+
+var Base = require('./base')
+ , color = Base.color;
+
+/**
+ * Expose `Dot`.
+ */
+
+exports = module.exports = Dot;
+
+/**
+ * Initialize a new `Dot` matrix test reporter.
+ *
+ * @param {Runner} runner
+ * @api public
+ */
+
+function Dot(runner) {
+ Base.call(this, runner);
+
+ var self = this
+ , stats = this.stats
+ , width = Base.window.width * .75 | 0
+ , n = 0;
+
+ runner.on('start', function(){
+ process.stdout.write('\n ');
+ });
+
+ runner.on('pending', function(test){
+ process.stdout.write(color('pending', '.'));
+ });
+
+ runner.on('pass', function(test){
+ if (++n % width == 0) process.stdout.write('\n ');
+ if ('slow' == test.speed) {
+ process.stdout.write(color('bright yellow', '.'));
+ } else {
+ process.stdout.write(color(test.speed, '.'));
+ }
+ });
+
+ runner.on('fail', function(test, err){
+ if (++n % width == 0) process.stdout.write('\n ');
+ process.stdout.write(color('fail', '.'));
+ });
+
+ runner.on('end', function(){
+ console.log();
+ self.epilogue();
+ });
+}
+
+/**
+ * Inherit from `Base.prototype`.
+ */
+
+Dot.prototype = new Base;
+Dot.prototype.constructor = Dot;
+
+}); // module: reporters/dot.js
+
+require.register("reporters/html-cov.js", function(module, exports, require){
+
+/**
+ * Module dependencies.
+ */
+
+var JSONCov = require('./json-cov')
+ , fs = require('browser/fs');
+
+/**
+ * Expose `HTMLCov`.
+ */
+
+exports = module.exports = HTMLCov;
+
+/**
+ * Initialize a new `JsCoverage` reporter.
+ *
+ * @param {Runner} runner
+ * @api public
+ */
+
+function HTMLCov(runner) {
+ var jade = require('jade')
+ , file = __dirname + '/templates/coverage.jade'
+ , str = fs.readFileSync(file, 'utf8')
+ , fn = jade.compile(str, { filename: file })
+ , self = this;
+
+ JSONCov.call(this, runner, false);
+
+ runner.on('end', function(){
+ process.stdout.write(fn({
+ cov: self.cov
+ , coverageClass: coverageClass
+ }));
+ });
+}
+
+function coverageClass(n) {
+ if (n >= 75) return 'high';
+ if (n >= 50) return 'medium';
+ if (n >= 25) return 'low';
+ return 'terrible';
+}
+}); // module: reporters/html-cov.js
+
+require.register("reporters/html.js", function(module, exports, require){
+
+/**
+ * Module dependencies.
+ */
+
+var Base = require('./base')
+ , utils = require('../utils')
+ , Progress = require('../browser/progress')
+ , escape = utils.escape;
+
+/**
+ * Expose `Doc`.
+ */
+
+exports = module.exports = HTML;
+
+/**
+ * Stats template.
+ */
+
+var statsTemplate = '<ul id="stats">'
+ + '<li class="progress"><canvas width="40" height="40"></canvas></li>'
+ + '<li class="passes">passes: <em>0</em></li>'
+ + '<li class="failures">failures: <em>0</em></li>'
+ + '<li class="duration">duration: <em>0</em>s</li>'
+ + '</ul>';
+
+/**
+ * Initialize a new `Doc` reporter.
+ *
+ * @param {Runner} runner
+ * @api public
+ */
+
+function HTML(runner) {
+ Base.call(this, runner);
+
+ var self = this
+ , stats = this.stats
+ , total = runner.total
+ , root = document.getElementById('mocha')
+ , stat = fragment(statsTemplate)
+ , items = stat.getElementsByTagName('li')
+ , passes = items[1].getElementsByTagName('em')[0]
+ , failures = items[2].getElementsByTagName('em')[0]
+ , duration = items[3].getElementsByTagName('em')[0]
+ , canvas = stat.getElementsByTagName('canvas')[0]
+ , stack = [root]
+ , progress
+ , ctx
+
+ if (canvas.getContext) {
+ ctx = canvas.getContext('2d');
+ progress = new Progress;
+ }
+
+ if (!root) return error('#mocha div missing, add it to your document');
+
+ root.appendChild(stat);
+
+ if (progress) progress.size(40);
+
+ runner.on('suite', function(suite){
+ if (suite.root) return;
+
+ // suite
+ var el = fragment('<div class="suite"><h1>%s</h1></div>', suite.title);
+
+ // container
+ stack[0].appendChild(el);
+ stack.unshift(document.createElement('div'));
+ el.appendChild(stack[0]);
+ });
+
+ runner.on('suite end', function(suite){
+ if (suite.root) return;
+ stack.shift();
+ });
+
+ runner.on('fail', function(test, err){
+ if ('hook' == test.type || err.uncaught) runner.emit('test end', test);
+ });
+
+ runner.on('test end', function(test){
+ // TODO: add to stats
+ var percent = stats.tests / total * 100 | 0;
+ if (progress) progress.update(percent).draw(ctx);
+
+ // update stats
+ var ms = new Date - stats.start;
+ text(passes, stats.passes);
+ text(failures, stats.failures);
+ text(duration, (ms / 1000).toFixed(2));
+
+ // test
+ if ('passed' == test.state) {
+ var el = fragment('<div class="test pass"><h2>%e</h2></div>', test.title);
+ } else if (test.pending) {
+ var el = fragment('<div class="test pass pending"><h2>%e</h2></div>', test.title);
+ } else {
+ var el = fragment('<div class="test fail"><h2>%e</h2></div>', test.title);
+ var str = test.err.stack || test.err.toString();
+
+ // FF / Opera do not add the message
+ if (!~str.indexOf(test.err.message)) {
+ str = test.err.message + '\n' + str;
+ }
+
+ // <=IE7 stringifies to [Object Error]. Since it can be overloaded, we
+ // check for the result of the stringifying.
+ if ('[object Error]' == str) str = test.err.message;
+
+ // Safari doesn't give you a stack. Let's at least provide a source line.
+ if (!test.err.stack && test.err.sourceURL && test.err.line !== undefined) {
+ str += "\n(" + test.err.sourceURL + ":" + test.err.line + ")";
+ }
+
+ el.appendChild(fragment('<pre class="error">%e</pre>', str));
+ }
+
+ // toggle code
+ var h2 = el.getElementsByTagName('h2')[0];
+
+ on(h2, 'click', function(){
+ pre.style.display = 'none' == pre.style.display
+ ? 'block'
+ : 'none';
+ });
+
+ // code
+ // TODO: defer
+ if (!test.pending) {
+ var pre = fragment('<pre><code>%e</code></pre>', clean(test.fn.toString()));
+ el.appendChild(pre);
+ pre.style.display = 'none';
+ }
+
+ stack[0].appendChild(el);
+ });
+}
+
+/**
+ * Display error `msg`.
+ */
+
+function error(msg) {
+ document.body.appendChild(fragment('<div id="error">%s</div>', msg));
+}
+
+/**
+ * Return a DOM fragment from `html`.
+ */
+
+function fragment(html) {
+ var args = arguments
+ , div = document.createElement('div')
+ , i = 1;
+
+ div.innerHTML = html.replace(/%([se])/g, function(_, type){
+ switch (type) {
+ case 's': return String(args[i++]);
+ case 'e': return escape(args[i++]);
+ }
+ });
+
+ return div.firstChild;
+}
+
+/**
+ * Set `el` text to `str`.
+ */
+
+function text(el, str) {
+ if (el.textContent) {
+ el.textContent = str;
+ } else {
+ el.innerText = str;
+ }
+}
+
+/**
+ * Listen on `event` with callback `fn`.
+ */
+
+function on(el, event, fn) {
+ if (el.addEventListener) {
+ el.addEventListener(event, fn, false);
+ } else {
+ el.attachEvent('on' + event, fn);
+ }
+}
+
+/**
+ * Strip the function definition from `str`,
+ * and re-indent for pre whitespace.
+ */
+
+function clean(str) {
+ str = str
+ .replace(/^function *\(.*\) *{/, '')
+ .replace(/\s+\}$/, '');
+
+ var spaces = str.match(/^\n?( *)/)[1].length
+ , re = new RegExp('^ {' + spaces + '}', 'gm');
+
+ str = str
+ .replace(re, '')
+ .replace(/^\s+/, '');
+
+ return str;
+}
+
+}); // module: reporters/html.js
+
+require.register("reporters/index.js", function(module, exports, require){
+
+exports.Base = require('./base');
+exports.Dot = require('./dot');
+exports.Doc = require('./doc');
+exports.TAP = require('./tap');
+exports.JSON = require('./json');
+exports.HTML = require('./html');
+exports.List = require('./list');
+exports.Min = require('./min');
+exports.Spec = require('./spec');
+exports.Progress = require('./progress');
+exports.Landing = require('./landing');
+exports.JSONCov = require('./json-cov');
+exports.HTMLCov = require('./html-cov');
+exports.JSONStream = require('./json-stream');
+exports.XUnit = require('./xunit')
+exports.Teamcity = require('./teamcity')
+
+}); // module: reporters/index.js
+
+require.register("reporters/json-cov.js", function(module, exports, require){
+
+/**
+ * Module dependencies.
+ */
+
+var Base = require('./base');
+
+/**
+ * Expose `JSONCov`.
+ */
+
+exports = module.exports = JSONCov;
+
+/**
+ * Initialize a new `JsCoverage` reporter.
+ *
+ * @param {Runner} runner
+ * @param {Boolean} output
+ * @api public
+ */
+
+function JSONCov(runner, output) {
+ var self = this
+ , output = 1 == arguments.length ? true : output;
+
+ Base.call(this, runner);
+
+ var tests = []
+ , failures = []
+ , passes = [];
+
+ runner.on('test end', function(test){
+ tests.push(test);
+ });
+
+ runner.on('pass', function(test){
+ passes.push(test);
+ });
+
+ runner.on('fail', function(test){
+ failures.push(test);
+ });
+
+ runner.on('end', function(){
+ var cov = global._$jscoverage || {};
+ var result = self.cov = map(cov);
+ result.stats = self.stats;
+ result.tests = tests.map(clean);
+ result.failures = failures.map(clean);
+ result.passes = passes.map(clean);
+ if (!output) return;
+ process.stdout.write(JSON.stringify(result, null, 2 ));
+ });
+}
+
+/**
+ * Map jscoverage data to a JSON structure
+ * suitable for reporting.
+ *
+ * @param {Object} cov
+ * @return {Object}
+ * @api private
+ */
+
+function map(cov) {
+ var ret = {
+ instrumentation: 'node-jscoverage'
+ , sloc: 0
+ , hits: 0
+ , misses: 0
+ , coverage: 0
+ , files: []
+ };
+
+ for (var filename in cov) {
+ var data = coverage(filename, cov[filename]);
+ ret.files.push(data);
+ ret.hits += data.hits;
+ ret.misses += data.misses;
+ ret.sloc += data.sloc;
+ }
+
+ if (ret.sloc > 0) {
+ ret.coverage = (ret.hits / ret.sloc) * 100;
+ }
+
+ return ret;
+};
+
+/**
+ * Map jscoverage data for a single source file
+ * to a JSON structure suitable for reporting.
+ *
+ * @param {String} filename name of the source file
+ * @param {Object} data jscoverage coverage data
+ * @return {Object}
+ * @api private
+ */
+
+function coverage(filename, data) {
+ var ret = {
+ filename: filename,
+ coverage: 0,
+ hits: 0,
+ misses: 0,
+ sloc: 0,
+ source: {}
+ };
+
+ data.source.forEach(function(line, num){
+ num++;
+
+ if (data[num] === 0) {
+ ret.misses++;
+ ret.sloc++;
+ } else if (data[num] !== undefined) {
+ ret.hits++;
+ ret.sloc++;
+ }
+
+ ret.source[num] = {
+ source: line
+ , coverage: data[num] === undefined
+ ? ''
+ : data[num]
+ };
+ });
+
+ ret.coverage = ret.hits / ret.sloc * 100;
+
+ return ret;
+}
+
+/**
+ * Return a plain-object representation of `test`
+ * free of cyclic properties etc.
+ *
+ * @param {Object} test
+ * @return {Object}
+ * @api private
+ */
+
+function clean(test) {
+ return {
+ title: test.title
+ , fullTitle: test.fullTitle()
+ , duration: test.duration
+ }
+}
+
+}); // module: reporters/json-cov.js
+
+require.register("reporters/json-stream.js", function(module, exports, require){
+
+/**
+ * Module dependencies.
+ */
+
+var Base = require('./base')
+ , color = Base.color;
+
+/**
+ * Expose `List`.
+ */
+
+exports = module.exports = List;
+
+/**
+ * Initialize a new `List` test reporter.
+ *
+ * @param {Runner} runner
+ * @api public
+ */
+
+function List(runner) {
+ Base.call(this, runner);
+
+ var self = this
+ , stats = this.stats
+ , total = runner.total;
+
+ runner.on('start', function(){
+ console.log(JSON.stringify(['start', { total: total }]));
+ });
+
+ runner.on('pass', function(test){
+ console.log(JSON.stringify(['pass', clean(test)]));
+ });
+
+ runner.on('fail', function(test, err){
+ console.log(JSON.stringify(['fail', clean(test)]));
+ });
+
+ runner.on('end', function(){
+ process.stdout.write(JSON.stringify(['end', self.stats]));
+ });
+}
+
+/**
+ * Return a plain-object representation of `test`
+ * free of cyclic properties etc.
+ *
+ * @param {Object} test
+ * @return {Object}
+ * @api private
+ */
+
+function clean(test) {
+ return {
+ title: test.title
+ , fullTitle: test.fullTitle()
+ , duration: test.duration
+ }
+}
+}); // module: reporters/json-stream.js
+
+require.register("reporters/json.js", function(module, exports, require){
+
+/**
+ * Module dependencies.
+ */
+
+var Base = require('./base')
+ , cursor = Base.cursor
+ , color = Base.color;
+
+/**
+ * Expose `JSON`.
+ */
+
+exports = module.exports = JSONReporter;
+
+/**
+ * Initialize a new `JSON` reporter.
+ *
+ * @param {Runner} runner
+ * @api public
+ */
+
+function JSONReporter(runner) {
+ var self = this;
+ Base.call(this, runner);
+
+ var tests = []
+ , failures = []
+ , passes = [];
+
+ runner.on('test end', function(test){
+ tests.push(test);
+ });
+
+ runner.on('pass', function(test){
+ passes.push(test);
+ });
+
+ runner.on('fail', function(test){
+ failures.push(test);
+ });
+
+ runner.on('end', function(){
+ var obj = {
+ stats: self.stats
+ , tests: tests.map(clean)
+ , failures: failures.map(clean)
+ , passes: passes.map(clean)
+ };
+
+ process.stdout.write(JSON.stringify(obj, null, 2));
+ });
+}
+
+/**
+ * Return a plain-object representation of `test`
+ * free of cyclic properties etc.
+ *
+ * @param {Object} test
+ * @return {Object}
+ * @api private
+ */
+
+function clean(test) {
+ return {
+ title: test.title
+ , fullTitle: test.fullTitle()
+ , duration: test.duration
+ }
+}
+}); // module: reporters/json.js
+
+require.register("reporters/landing.js", function(module, exports, require){
+
+/**
+ * Module dependencies.
+ */
+
+var Base = require('./base')
+ , cursor = Base.cursor
+ , color = Base.color;
+
+/**
+ * Expose `Landing`.
+ */
+
+exports = module.exports = Landing;
+
+/**
+ * Airplane color.
+ */
+
+Base.colors.plane = 0;
+
+/**
+ * Airplane crash color.
+ */
+
+Base.colors['plane crash'] = 31;
+
+/**
+ * Runway color.
+ */
+
+Base.colors.runway = 90;
+
+/**
+ * Initialize a new `Landing` reporter.
+ *
+ * @param {Runner} runner
+ * @api public
+ */
+
+function Landing(runner) {
+ Base.call(this, runner);
+
+ var self = this
+ , stats = this.stats
+ , width = Base.window.width * .75 | 0
+ , total = runner.total
+ , stream = process.stdout
+ , plane = color('plane', '✈')
+ , crashed = -1
+ , n = 0;
+
+ function runway() {
+ var buf = Array(width).join('-');
+ return ' ' + color('runway', buf);
+ }
+
+ runner.on('start', function(){
+ stream.write('\n ');
+ cursor.hide();
+ });
+
+ runner.on('test end', function(test){
+ // check if the plane crashed
+ var col = -1 == crashed
+ ? width * ++n / total | 0
+ : crashed;
+
+ // show the crash
+ if ('failed' == test.state) {
+ plane = color('plane crash', '✈');
+ crashed = col;
+ }
+
+ // render landing strip
+ stream.write('\033[4F\n\n');
+ stream.write(runway());
+ stream.write('\n ');
+ stream.write(color('runway', Array(col).join('⋅')));
+ stream.write(plane)
+ stream.write(color('runway', Array(width - col).join('⋅') + '\n'));
+ stream.write(runway());
+ stream.write('\033[0m');
+ });
+
+ runner.on('end', function(){
+ cursor.show();
+ console.log();
+ self.epilogue();
+ });
+}
+
+/**
+ * Inherit from `Base.prototype`.
+ */
+
+Landing.prototype = new Base;
+Landing.prototype.constructor = Landing;
+
+}); // module: reporters/landing.js
+
+require.register("reporters/list.js", function(module, exports, require){
+
+/**
+ * Module dependencies.
+ */
+
+var Base = require('./base')
+ , cursor = Base.cursor
+ , color = Base.color;
+
+/**
+ * Expose `List`.
+ */
+
+exports = module.exports = List;
+
+/**
+ * Initialize a new `List` test reporter.
+ *
+ * @param {Runner} runner
+ * @api public
+ */
+
+function List(runner) {
+ Base.call(this, runner);
+
+ var self = this
+ , stats = this.stats
+ , n = 0;
+
+ runner.on('start', function(){
+ console.log();
+ });
+
+ runner.on('test', function(test){
+ process.stdout.write(color('pass', ' ' + test.fullTitle() + ': '));
+ });
+
+ runner.on('pending', function(test){
+ var fmt = color('checkmark', ' -')
+ + color('pending', ' %s');
+ console.log(fmt, test.fullTitle());
+ });
+
+ runner.on('pass', function(test){
+ var fmt = color('checkmark', ' ✓')
+ + color('pass', ' %s: ')
+ + color(test.speed, '%dms');
+ cursor.CR();
+ console.log(fmt, test.fullTitle(), test.duration);
+ });
+
+ runner.on('fail', function(test, err){
+ cursor.CR();
+ console.log(color('fail', ' %d) %s'), ++n, test.fullTitle());
+ });
+
+ runner.on('end', self.epilogue.bind(self));
+}
+
+/**
+ * Inherit from `Base.prototype`.
+ */
+
+List.prototype = new Base;
+List.prototype.constructor = List;
+
+
+}); // module: reporters/list.js
+
+require.register("reporters/markdown.js", function(module, exports, require){
+
+/**
+ * Module dependencies.
+ */
+
+var Base = require('./base')
+ , utils = require('../utils');
+
+/**
+ * Expose `Markdown`.
+ */
+
+exports = module.exports = Markdown;
+
+/**
+ * Initialize a new `Markdown` reporter.
+ *
+ * @param {Runner} runner
+ * @api public
+ */
+
+function Markdown(runner) {
+ Base.call(this, runner);
+
+ var self = this
+ , stats = this.stats
+ , total = runner.total
+ , level = 0
+ , buf = '';
+
+ function title(str) {
+ return Array(level).join('#') + ' ' + str;
+ }
+
+ function indent() {
+ return Array(level).join(' ');
+ }
+
+ function mapTOC(suite, obj) {
+ var ret = obj;
+ obj = obj[suite.title] = obj[suite.title] || { suite: suite };
+ suite.suites.forEach(function(suite){
+ mapTOC(suite, obj);
+ });
+ return ret;
+ }
+
+ function stringifyTOC(obj, level) {
+ ++level;
+ var buf = '';
+ var link;
+ for (var key in obj) {
+ if ('suite' == key) continue;
+ if (key) link = ' - [' + key + '](#' + utils.slug(obj[key].suite.fullTitle()) + ')\n';
+ if (key) buf += Array(level).join(' ') + link;
+ buf += stringifyTOC(obj[key], level);
+ }
+ --level;
+ return buf;
+ }
+
+ function generateTOC(suite) {
+ var obj = mapTOC(suite, {});
+ return stringifyTOC(obj, 0);
+ }
+
+ generateTOC(runner.suite);
+
+ runner.on('suite', function(suite){
+ ++level;
+ var slug = utils.slug(suite.fullTitle());
+ buf += '<a name="' + slug + '" />' + '\n';
+ buf += title(suite.title) + '\n';
+ });
+
+ runner.on('suite end', function(suite){
+ --level;
+ });
+
+ runner.on('pass', function(test){
+ var code = clean(test.fn.toString());
+ buf += test.title + '.\n';
+ buf += '\n```js';
+ buf += code + '\n';
+ buf += '```\n\n';
+ });
+
+ runner.on('end', function(){
+ process.stdout.write('# TOC\n');
+ process.stdout.write(generateTOC(runner.suite));
+ process.stdout.write(buf);
+ });
+}
+
+/**
+ * Strip the function definition from `str`,
+ * and re-indent for pre whitespace.
+ */
+
+function clean(str) {
+ str = str
+ .replace(/^function *\(.*\) *{/, '')
+ .replace(/\s+\}$/, '');
+
+ var spaces = str.match(/^\n?( *)/)[1].length
+ , re = new RegExp('^ {' + spaces + '}', 'gm');
+
+ str = str.replace(re, '');
+
+ return str;
+}
+}); // module: reporters/markdown.js
+
+require.register("reporters/min.js", function(module, exports, require){
+/**
+ * Module dependencies.
+ */
+
+var Base = require('./base');
+
+/**
+ * Expose `Min`.
+ */
+
+exports = module.exports = Min;
+
+/**
+ * Initialize a new `Min` minimal test reporter (best used with --watch).
+ *
+ * @param {Runner} runner
+ * @api public
+ */
+
+function Min(runner) {
+ Base.call(this, runner);
+
+ runner.on('start', function(){
+ // clear screen
+ process.stdout.write('\033[2J');
+ // set cursor position
+ process.stdout.write('\033[1;3H');
+ });
+
+ runner.on('end', this.epilogue.bind(this));
+}
+
+/**
+ * Inherit from `Base.prototype`.
+ */
+
+Min.prototype = new Base;
+Min.prototype.constructor = Min;
+
+}); // module: reporters/min.js
+
+require.register("reporters/progress.js", function(module, exports, require){
+
+/**
+ * Module dependencies.
+ */
+
+var Base = require('./base')
+ , cursor = Base.cursor
+ , color = Base.color;
+
+/**
+ * Expose `Progress`.
+ */
+
+exports = module.exports = Progress;
+
+/**
+ * General progress bar color.
+ */
+
+Base.colors.progress = 90;
+
+/**
+ * Initialize a new `Progress` bar test reporter.
+ *
+ * @param {Runner} runner
+ * @param {Object} options
+ * @api public
+ */
+
+function Progress(runner, options) {
+ Base.call(this, runner);
+
+ var self = this
+ , options = options || {}
+ , stats = this.stats
+ , width = Base.window.width * .50 | 0
+ , total = runner.total
+ , complete = 0
+ , max = Math.max;
+
+ // default chars
+ options.open = options.open || '[';
+ options.complete = options.complete || '▬';
+ options.incomplete = options.incomplete || '⋅';
+ options.close = options.close || ']';
+ options.verbose = false;
+
+ // tests started
+ runner.on('start', function(){
+ console.log();
+ cursor.hide();
+ });
+
+ // tests complete
+ runner.on('test end', function(){
+ var incomplete = total - complete
+ , percent = complete++ / total
+ , n = width * percent | 0
+ , i = width - n;
+
+ cursor.CR();
+ process.stdout.write('\033[J');
+ process.stdout.write(color('progress', ' ' + options.open));
+ process.stdout.write(Array(n).join(options.complete));
+ process.stdout.write(Array(i).join(options.incomplete));
+ process.stdout.write(color('progress', options.close));
+ if (options.verbose) {
+ process.stdout.write(color('progress', ' ' + complete + ' of ' + total));
+ }
+ });
+
+ // tests are complete, output some stats
+ // and the failures if any
+ runner.on('end', function(){
+ cursor.show();
+ console.log();
+ self.epilogue();
+ });
+}
+
+/**
+ * Inherit from `Base.prototype`.
+ */
+
+Progress.prototype = new Base;
+Progress.prototype.constructor = Progress;
+
+
+}); // module: reporters/progress.js
+
+require.register("reporters/spec.js", function(module, exports, require){
+
+/**
+ * Module dependencies.
+ */
+
+var Base = require('./base')
+ , cursor = Base.cursor
+ , color = Base.color;
+
+/**
+ * Expose `Spec`.
+ */
+
+exports = module.exports = Spec;
+
+/**
+ * Initialize a new `Spec` test reporter.
+ *
+ * @param {Runner} runner
+ * @api public
+ */
+
+function Spec(runner) {
+ Base.call(this, runner);
+
+ var self = this
+ , stats = this.stats
+ , indents = 0
+ , n = 0;
+
+ function indent() {
+ return Array(indents).join(' ')
+ }
+
+ runner.on('start', function(){
+ console.log();
+ });
+
+ runner.on('suite', function(suite){
+ ++indents;
+ console.log(color('suite', '%s%s'), indent(), suite.title);
+ });
+
+ runner.on('suite end', function(suite){
+ --indents;
+ if (1 == indents) console.log();
+ });
+
+ runner.on('test', function(test){
+ process.stdout.write(indent() + color('pass', ' ◦ ' + test.title + ': '));
+ });
+
+ runner.on('pending', function(test){
+ var fmt = indent() + color('pending', ' - %s');
+ console.log(fmt, test.title);
+ });
+
+ runner.on('pass', function(test){
+ if ('fast' == test.speed) {
+ var fmt = indent()
+ + color('checkmark', ' ✓')
+ + color('pass', ' %s ');
+ cursor.CR();
+ console.log(fmt, test.title);
+ } else {
+ var fmt = indent()
+ + color('checkmark', ' ✓')
+ + color('pass', ' %s ')
+ + color(test.speed, '(%dms)');
+ cursor.CR();
+ console.log(fmt, test.title, test.duration);
+ }
+ });
+
+ runner.on('fail', function(test, err){
+ cursor.CR();
+ console.log(indent() + color('fail', ' %d) %s'), ++n, test.title);
+ });
+
+ runner.on('end', self.epilogue.bind(self));
+}
+
+/**
+ * Inherit from `Base.prototype`.
+ */
+
+Spec.prototype = new Base;
+Spec.prototype.constructor = Spec;
+
+
+}); // module: reporters/spec.js
+
+require.register("reporters/tap.js", function(module, exports, require){
+
+/**
+ * Module dependencies.
+ */
+
+var Base = require('./base')
+ , cursor = Base.cursor
+ , color = Base.color;
+
+/**
+ * Expose `TAP`.
+ */
+
+exports = module.exports = TAP;
+
+/**
+ * Initialize a new `TAP` reporter.
+ *
+ * @param {Runner} runner
+ * @api public
+ */
+
+function TAP(runner) {
+ Base.call(this, runner);
+
+ var self = this
+ , stats = this.stats
+ , total = runner.total
+ , n = 1;
+
+ runner.on('start', function(){
+ console.log('%d..%d', 1, total);
+ });
+
+ runner.on('test end', function(){
+ ++n;
+ });
+
+ runner.on('pending', function(test){
+ console.log('ok %d %s # SKIP -', n, title(test));
+ });
+
+ runner.on('pass', function(test){
+ console.log('ok %d %s', n, title(test));
+ });
+
+ runner.on('fail', function(test, err){
+ console.log('not ok %d %s', n, title(test));
+ console.log(err.stack.replace(/^/gm, ' '));
+ });
+}
+
+/**
+ * Return a TAP-safe title of `test`
+ *
+ * @param {Object} test
+ * @return {String}
+ * @api private
+ */
+
+function title(test) {
+ return test.fullTitle().replace(/#/g, '');
+}
+
+}); // module: reporters/tap.js
+
+require.register("reporters/teamcity.js", function(module, exports, require){
+
+/**
+ * Module dependencies.
+ */
+
+var Base = require('./base');
+
+/**
+ * Expose `Teamcity`.
+ */
+
+exports = module.exports = Teamcity;
+
+/**
+ * Initialize a new `Teamcity` reporter.
+ *
+ * @param {Runner} runner
+ * @api public
+ */
+
+function Teamcity(runner) {
+ Base.call(this, runner);
+ var stats = this.stats;
+
+ runner.on('start', function() {
+ console.log("##teamcity[testSuiteStarted name='mocha.suite']");
+ });
+
+ runner.on('test', function(test) {
+ console.log("##teamcity[testStarted name='%s']", escape(test.fullTitle()));
+ });
+
+ runner.on('fail', function(test, err) {
+ console.log("##teamcity[testFailed name='%s' message='%s']", escape(test.fullTitle()), escape(err.message));
+ });
+
+ runner.on('pending', function(test) {
+ console.log("##teamcity[testIgnored name='%s' message='pending']", escape(test.fullTitle()));
+ });
+
+ runner.on('test end', function(test) {
+ console.log("##teamcity[testFinished name='%s' duration='%s']", escape(test.fullTitle()), test.duration);
+ });
+
+ runner.on('end', function() {
+ console.log("##teamcity[testSuiteFinished name='mocha.suite' duration='%s']", stats.duration);
+ });
+}
+
+/**
+ * Escape the given `str`.
+ */
+
+function escape(str) {
+ return str.replace(/'/g, "|'");
+}
+}); // module: reporters/teamcity.js
+
+require.register("reporters/xunit.js", function(module, exports, require){
+
+/**
+ * Module dependencies.
+ */
+
+var Base = require('./base')
+ , utils = require('../utils')
+ , escape = utils.escape;
+
+/**
+ * Expose `XUnit`.
+ */
+
+exports = module.exports = XUnit;
+
+/**
+ * Initialize a new `XUnit` reporter.
+ *
+ * @param {Runner} runner
+ * @api public
+ */
+
+function XUnit(runner) {
+ Base.call(this, runner);
+ var stats = this.stats
+ , tests = []
+ , self = this;
+
+ runner.on('test end', function(test){
+ tests.push(test);
+ });
+
+ runner.on('end', function(){
+ console.log(tag('testsuite', {
+ name: 'Mocha Tests'
+ , tests: stats.tests
+ , failures: stats.failures
+ , errors: stats.failures
+ , skip: stats.tests - stats.failures - stats.passes
+ , timestamp: (new Date).toUTCString()
+ , time: stats.duration / 1000
+ }, false));
+
+ tests.forEach(test);
+ console.log('</testsuite>');
+ });
+}
+
+/**
+ * Inherit from `Base.prototype`.
+ */
+
+XUnit.prototype = new Base;
+XUnit.prototype.constructor = XUnit;
+
+
+/**
+ * Output tag for the given `test.`
+ */
+
+function test(test) {
+ var attrs = {
+ classname: test.parent.fullTitle()
+ , name: test.title
+ , time: test.duration / 1000
+ };
+
+ if ('failed' == test.state) {
+ var err = test.err;
+ attrs.message = escape(err.message);
+ console.log(tag('testcase', attrs, false, tag('failure', attrs, false, cdata(err.stack))));
+ } else if (test.pending) {
+ console.log(tag('testcase', attrs, false, tag('skipped', {}, true)));
+ } else {
+ console.log(tag('testcase', attrs, true) );
+ }
+}
+
+/**
+ * HTML tag helper.
+ */
+
+function tag(name, attrs, close, content) {
+ var end = close ? '/>' : '>'
+ , pairs = []
+ , tag;
+
+ for (var key in attrs) {
+ pairs.push(key + '="' + escape(attrs[key]) + '"');
+ }
+
+ tag = '<' + name + (pairs.length ? ' ' + pairs.join(' ') : '') + end;
+ if (content) tag += content + '</' + name + end;
+ return tag;
+}
+
+/**
+ * Return cdata escaped CDATA `str`.
+ */
+
+function cdata(str) {
+ return '<![CDATA[' + escape(str) + ']]>';
+}
+
+}); // module: reporters/xunit.js
+
+require.register("runnable.js", function(module, exports, require){
+
+/**
+ * Module dependencies.
+ */
+
+var EventEmitter = require('browser/events').EventEmitter
+ , debug = require('browser/debug')('runnable');
+
+/**
+ * Expose `Runnable`.
+ */
+
+module.exports = Runnable;
+
+/**
+ * Initialize a new `Runnable` with the given `title` and callback `fn`.
+ *
+ * @param {String} title
+ * @param {Function} fn
+ * @api private
+ */
+
+function Runnable(title, fn) {
+ this.title = title;
+ this.fn = fn;
+ this.async = fn && fn.length;
+ this.sync = ! this.async;
+ this._timeout = 2000;
+ this.timedOut = false;
+}
+
+/**
+ * Inherit from `EventEmitter.prototype`.
+ */
+
+Runnable.prototype = new EventEmitter;
+Runnable.prototype.constructor = Runnable;
+
+
+/**
+ * Set & get timeout `ms`.
+ *
+ * @param {Number} ms
+ * @return {Runnable|Number} ms or self
+ * @api private
+ */
+
+Runnable.prototype.timeout = function(ms){
+ if (0 == arguments.length) return this._timeout;
+ debug('timeout %d', ms);
+ this._timeout = ms;
+ if (this.timer) this.resetTimeout();
+ return this;
+};
+
+/**
+ * Return the full title generated by recursively
+ * concatenating the parent's full title.
+ *
+ * @return {String}
+ * @api public
+ */
+
+Runnable.prototype.fullTitle = function(){
+ return this.parent.fullTitle() + ' ' + this.title;
+};
+
+/**
+ * Clear the timeout.
+ *
+ * @api private
+ */
+
+Runnable.prototype.clearTimeout = function(){
+ clearTimeout(this.timer);
+};
+
+/**
+ * Reset the timeout.
+ *
+ * @api private
+ */
+
+Runnable.prototype.resetTimeout = function(){
+ var self = this
+ , ms = this.timeout();
+
+ this.clearTimeout();
+ if (ms) {
+ this.timer = setTimeout(function(){
+ self.callback(new Error('timeout of ' + ms + 'ms exceeded'));
+ self.timedOut = true;
+ }, ms);
+ }
+};
+
+/**
+ * Run the test and invoke `fn(err)`.
+ *
+ * @param {Function} fn
+ * @api private
+ */
+
+Runnable.prototype.run = function(fn){
+ var self = this
+ , ms = this.timeout()
+ , start = new Date
+ , ctx = this.ctx
+ , finished
+ , emitted;
+
+ if (ctx) ctx.runnable(this);
+
+ // timeout
+ if (this.async) {
+ if (ms) {
+ this.timer = setTimeout(function(){
+ done(new Error('timeout of ' + ms + 'ms exceeded'));
+ self.timedOut = true;
+ }, ms);
+ }
+ }
+
+ // called multiple times
+ function multiple() {
+ if (emitted) return;
+ emitted = true;
+ self.emit('error', new Error('done() called multiple times'));
+ }
+
+ // finished
+ function done(err) {
+ if (self.timedOut) return;
+ if (finished) return multiple();
+ self.clearTimeout();
+ self.duration = new Date - start;
+ finished = true;
+ fn(err);
+ }
+
+ // for .resetTimeout()
+ this.callback = done;
+
+ // async
+ if (this.async) {
+ try {
+ this.fn.call(ctx, function(err){
+ if (err instanceof Error) return done(err);
+ if (null != err) return done(new Error('done() invoked with non-Error: ' + err));
+ done();
+ });
+ } catch (err) {
+ done(err);
+ }
+ return;
+ }
+
+ // sync
+ try {
+ if (!this.pending) this.fn.call(ctx);
+ this.duration = new Date - start;
+ fn();
+ } catch (err) {
+ fn(err);
+ }
+};
+
+}); // module: runnable.js
+
+require.register("runner.js", function(module, exports, require){
+
+/**
+ * Module dependencies.
+ */
+
+var EventEmitter = require('browser/events').EventEmitter
+ , debug = require('browser/debug')('runner')
+ , Test = require('./test')
+ , utils = require('./utils')
+ , noop = function(){};
+
+/**
+ * Expose `Runner`.
+ */
+
+module.exports = Runner;
+
+/**
+ * Initialize a `Runner` for the given `suite`.
+ *
+ * Events:
+ *
+ * - `start` execution started
+ * - `end` execution complete
+ * - `suite` (suite) test suite execution started
+ * - `suite end` (suite) all tests (and sub-suites) have finished
+ * - `test` (test) test execution started
+ * - `test end` (test) test completed
+ * - `hook` (hook) hook execution started
+ * - `hook end` (hook) hook complete
+ * - `pass` (test) test passed
+ * - `fail` (test, err) test failed
+ *
+ * @api public
+ */
+
+function Runner(suite) {
+ var self = this;
+ this._globals = [];
+ this.suite = suite;
+ this.total = suite.total();
+ this.failures = 0;
+ this.on('test end', function(test){ self.checkGlobals(test); });
+ this.on('hook end', function(hook){ self.checkGlobals(hook); });
+ this.grep(/.*/);
+ this.globals(utils.keys(global).concat(['errno']));
+}
+
+/**
+ * Inherit from `EventEmitter.prototype`.
+ */
+
+Runner.prototype = new EventEmitter;
+Runner.prototype.constructor = Runner;
+
+
+/**
+ * Run tests with full titles matching `re`.
+ *
+ * @param {RegExp} re
+ * @return {Runner} for chaining
+ * @api public
+ */
+
+Runner.prototype.grep = function(re){
+ debug('grep %s', re);
+ this._grep = re;
+ return this;
+};
+
+/**
+ * Allow the given `arr` of globals.
+ *
+ * @param {Array} arr
+ * @return {Runner} for chaining
+ * @api public
+ */
+
+Runner.prototype.globals = function(arr){
+ if (0 == arguments.length) return this._globals;
+ debug('globals %j', arr);
+ utils.forEach(arr, function(arr){
+ this._globals.push(arr);
+ }, this);
+ return this;
+};
+
+/**
+ * Check for global variable leaks.
+ *
+ * @api private
+ */
+
+Runner.prototype.checkGlobals = function(test){
+ if (this.ignoreLeaks) return;
+
+ var leaks = utils.filter(utils.keys(global), function(key){
+ return !~utils.indexOf(this._globals, key) && (!global.navigator || 'onerror' !== key);
+ }, this);
+
+ this._globals = this._globals.concat(leaks);
+
+ if (leaks.length > 1) {
+ this.fail(test, new Error('global leaks detected: ' + leaks.join(', ') + ''));
+ } else if (leaks.length) {
+ this.fail(test, new Error('global leak detected: ' + leaks[0]));
+ }
+};
+
+/**
+ * Fail the given `test`.
+ *
+ * @param {Test} test
+ * @param {Error} err
+ * @api private
+ */
+
+Runner.prototype.fail = function(test, err){
+ ++this.failures;
+ test.state = 'failed';
+ this.emit('fail', test, err);
+};
+
+/**
+ * Fail the given `hook` with `err`.
+ *
+ * Hook failures (currently) hard-end due
+ * to that fact that a failing hook will
+ * surely cause subsequent tests to fail,
+ * causing jumbled reporting.
+ *
+ * @param {Hook} hook
+ * @param {Error} err
+ * @api private
+ */
+
+Runner.prototype.failHook = function(hook, err){
+ this.fail(hook, err);
+ this.emit('end');
+};
+
+/**
+ * Run hook `name` callbacks and then invoke `fn()`.
+ *
+ * @param {String} name
+ * @param {Function} function
+ * @api private
+ */
+
+Runner.prototype.hook = function(name, fn){
+ var suite = this.suite
+ , hooks = suite['_' + name]
+ , ms = suite._timeout
+ , self = this
+ , timer;
+
+ function next(i) {
+ var hook = hooks[i];
+ if (!hook) return fn();
+ self.currentRunnable = hook;
+
+ self.emit('hook', hook);
+
+ hook.on('error', function(err){
+ self.failHook(hook, err);
+ });
+
+ hook.run(function(err){
+ hook.removeAllListeners('error');
+ if (err) return self.failHook(hook, err);
+ self.emit('hook end', hook);
+ next(++i);
+ });
+ }
+
+ process.nextTick(function(){
+ next(0);
+ });
+};
+
+/**
+ * Run hook `name` for the given array of `suites`
+ * in order, and callback `fn(err)`.
+ *
+ * @param {String} name
+ * @param {Array} suites
+ * @param {Function} fn
+ * @api private
+ */
+
+Runner.prototype.hooks = function(name, suites, fn){
+ var self = this
+ , orig = this.suite;
+
+ function next(suite) {
+ self.suite = suite;
+
+ if (!suite) {
+ self.suite = orig;
+ return fn();
+ }
+
+ self.hook(name, function(err){
+ if (err) {
+ self.suite = orig;
+ return fn(err);
+ }
+
+ next(suites.pop());
+ });
+ }
+
+ next(suites.pop());
+};
+
+/**
+ * Run hooks from the top level down.
+ *
+ * @param {String} name
+ * @param {Function} fn
+ * @api private
+ */
+
+Runner.prototype.hookUp = function(name, fn){
+ var suites = [this.suite].concat(this.parents()).reverse();
+ this.hooks(name, suites, fn);
+};
+
+/**
+ * Run hooks from the bottom up.
+ *
+ * @param {String} name
+ * @param {Function} fn
+ * @api private
+ */
+
+Runner.prototype.hookDown = function(name, fn){
+ var suites = [this.suite].concat(this.parents());
+ this.hooks(name, suites, fn);
+};
+
+/**
+ * Return an array of parent Suites from
+ * closest to furthest.
+ *
+ * @return {Array}
+ * @api private
+ */
+
+Runner.prototype.parents = function(){
+ var suite = this.suite
+ , suites = [];
+ while (suite = suite.parent) suites.push(suite);
+ return suites;
+};
+
+/**
+ * Run the current test and callback `fn(err)`.
+ *
+ * @param {Function} fn
+ * @api private
+ */
+
+Runner.prototype.runTest = function(fn){
+ var test = this.test
+ , self = this;
+
+ try {
+ test.on('error', function(err){
+ self.fail(test, err);
+ });
+ test.run(fn);
+ } catch (err) {
+ fn(err);
+ }
+};
+
+/**
+ * Run tests in the given `suite` and invoke
+ * the callback `fn()` when complete.
+ *
+ * @param {Suite} suite
+ * @param {Function} fn
+ * @api private
+ */
+
+Runner.prototype.runTests = function(suite, fn){
+ var self = this
+ , tests = suite.tests
+ , test;
+
+ function next(err) {
+ // if we bail after first err
+ if (self.failures && suite._bail) return fn();
+
+ // next test
+ test = tests.shift();
+
+ // all done
+ if (!test) return fn();
+
+ // grep
+ if (!self._grep.test(test.fullTitle())) return next();
+
+ // pending
+ if (test.pending) {
+ self.emit('pending', test);
+ self.emit('test end', test);
+ return next();
+ }
+
+ // execute test and hook(s)
+ self.emit('test', self.test = test);
+ self.hookDown('beforeEach', function(){
+ self.currentRunnable = self.test;
+ self.runTest(function(err){
+ test = self.test;
+
+ if (err) {
+ self.fail(test, err);
+ self.emit('test end', test);
+ return self.hookUp('afterEach', next);
+ }
+
+ test.state = 'passed';
+ self.emit('pass', test);
+ self.emit('test end', test);
+ self.hookUp('afterEach', next);
+ });
+ });
+ }
+
+ this.next = next;
+ next();
+};
+
+/**
+ * Run the given `suite` and invoke the
+ * callback `fn()` when complete.
+ *
+ * @param {Suite} suite
+ * @param {Function} fn
+ * @api private
+ */
+
+Runner.prototype.runSuite = function(suite, fn){
+ var self = this
+ , i = 0;
+
+ debug('run suite %s', suite.fullTitle());
+ this.emit('suite', this.suite = suite);
+
+ function next() {
+ var curr = suite.suites[i++];
+ if (!curr) return done();
+ self.runSuite(curr, next);
+ }
+
+ function done() {
+ self.suite = suite;
+ self.hook('afterAll', function(){
+ self.emit('suite end', suite);
+ fn();
+ });
+ }
+
+ this.hook('beforeAll', function(){
+ self.runTests(suite, next);
+ });
+};
+
+/**
+ * Handle uncaught exceptions.
+ *
+ * @param {Error} err
+ * @api private
+ */
+
+Runner.prototype.uncaught = function(err){
+ debug('uncaught exception');
+ var runnable = this.currentRunnable;
+ if ('failed' == runnable.state) return;
+ runnable.clearTimeout();
+ err.uncaught = true;
+ this.fail(runnable, err);
+
+ // recover from test
+ if ('test' == runnable.type) {
+ this.emit('test end', runnable);
+ this.hookUp('afterEach', this.next);
+ return;
+ }
+
+ // bail on hooks
+ this.emit('end');
+};
+
+/**
+ * Run the root suite and invoke `fn(failures)`
+ * on completion.
+ *
+ * @param {Function} fn
+ * @return {Runner} for chaining
+ * @api public
+ */
+
+Runner.prototype.run = function(fn){
+ var self = this
+ , fn = fn || function(){};
+
+ debug('start');
+
+ // callback
+ this.on('end', function(){
+ debug('end');
+ process.removeListener('uncaughtException', this.uncaught);
+ fn(self.failures);
+ });
+
+ // run suites
+ this.emit('start');
+ this.runSuite(this.suite, function(){
+ debug('finished running');
+ self.emit('end');
+ });
+
+ // uncaught exception
+ process.on('uncaughtException', function(err){
+ self.uncaught(err);
+ });
+
+ return this;
+};
+
+}); // module: runner.js
+
+require.register("suite.js", function(module, exports, require){
+
+/**
+ * Module dependencies.
+ */
+
+var EventEmitter = require('browser/events').EventEmitter
+ , debug = require('browser/debug')('suite')
+ , utils = require('./utils')
+ , Hook = require('./hook');
+
+/**
+ * Expose `Suite`.
+ */
+
+exports = module.exports = Suite;
+
+/**
+ * Create a new `Suite` with the given `title`
+ * and parent `Suite`. When a suite with the
+ * same title is already present, that suite
+ * is returned to provide nicer reporter
+ * and more flexible meta-testing.
+ *
+ * @param {Suite} parent
+ * @param {String} title
+ * @return {Suite}
+ * @api public
+ */
+
+exports.create = function(parent, title){
+ var suite = new Suite(title, parent.ctx);
+ suite.parent = parent;
+ title = suite.fullTitle();
+ parent.addSuite(suite);
+ return suite;
+};
+
+/**
+ * Initialize a new `Suite` with the given
+ * `title` and `ctx`.
+ *
+ * @param {String} title
+ * @param {Context} ctx
+ * @api private
+ */
+
+function Suite(title, ctx) {
+ this.title = title;
+ this.ctx = ctx;
+ this.suites = [];
+ this.tests = [];
+ this._beforeEach = [];
+ this._beforeAll = [];
+ this._afterEach = [];
+ this._afterAll = [];
+ this.root = !title;
+ this._timeout = 2000;
+ this._bail = false;
+}
+
+/**
+ * Inherit from `EventEmitter.prototype`.
+ */
+
+Suite.prototype = new EventEmitter;
+Suite.prototype.constructor = Suite;
+
+
+/**
+ * Return a clone of this `Suite`.
+ *
+ * @return {Suite}
+ * @api private
+ */
+
+Suite.prototype.clone = function(){
+ var suite = new Suite(this.title);
+ debug('clone');
+ suite.ctx = this.ctx;
+ suite.timeout(this.timeout());
+ suite.bail(this.bail());
+ return suite;
+};
+
+/**
+ * Set timeout `ms` or short-hand such as "2s".
+ *
+ * @param {Number|String} ms
+ * @return {Suite|Number} for chaining
+ * @api private
+ */
+
+Suite.prototype.timeout = function(ms){
+ if (0 == arguments.length) return this._timeout;
+ if (String(ms).match(/s$/)) ms = parseFloat(ms) * 1000;
+ debug('timeout %d', ms);
+ this._timeout = parseInt(ms, 10);
+ return this;
+};
+
+/**
+ * Sets whether to bail after first error.
+ *
+ * @parma {Boolean} bail
+ * @return {Suite|Number} for chaining
+ * @api private
+ */
+
+Suite.prototype.bail = function(bail){
+ if (0 == arguments.length) return this._bail;
+ debug('bail %s', bail);
+ this._bail = bail;
+ return this;
+};
+
+/**
+ * Run `fn(test[, done])` before running tests.
+ *
+ * @param {Function} fn
+ * @return {Suite} for chaining
+ * @api private
+ */
+
+Suite.prototype.beforeAll = function(fn){
+ var hook = new Hook('"before all" hook', fn);
+ hook.parent = this;
+ hook.timeout(this.timeout());
+ hook.ctx = this.ctx;
+ this._beforeAll.push(hook);
+ this.emit('beforeAll', hook);
+ return this;
+};
+
+/**
+ * Run `fn(test[, done])` after running tests.
+ *
+ * @param {Function} fn
+ * @return {Suite} for chaining
+ * @api private
+ */
+
+Suite.prototype.afterAll = function(fn){
+ var hook = new Hook('"after all" hook', fn);
+ hook.parent = this;
+ hook.timeout(this.timeout());
+ hook.ctx = this.ctx;
+ this._afterAll.push(hook);
+ this.emit('afterAll', hook);
+ return this;
+};
+
+/**
+ * Run `fn(test[, done])` before each test case.
+ *
+ * @param {Function} fn
+ * @return {Suite} for chaining
+ * @api private
+ */
+
+Suite.prototype.beforeEach = function(fn){
+ var hook = new Hook('"before each" hook', fn);
+ hook.parent = this;
+ hook.timeout(this.timeout());
+ hook.ctx = this.ctx;
+ this._beforeEach.push(hook);
+ this.emit('beforeEach', hook);
+ return this;
+};
+
+/**
+ * Run `fn(test[, done])` after each test case.
+ *
+ * @param {Function} fn
+ * @return {Suite} for chaining
+ * @api private
+ */
+
+Suite.prototype.afterEach = function(fn){
+ var hook = new Hook('"after each" hook', fn);
+ hook.parent = this;
+ hook.timeout(this.timeout());
+ hook.ctx = this.ctx;
+ this._afterEach.push(hook);
+ this.emit('afterEach', hook);
+ return this;
+};
+
+/**
+ * Add a test `suite`.
+ *
+ * @param {Suite} suite
+ * @return {Suite} for chaining
+ * @api private
+ */
+
+Suite.prototype.addSuite = function(suite){
+ suite.parent = this;
+ suite.timeout(this.timeout());
+ suite.bail(this.bail());
+ this.suites.push(suite);
+ this.emit('suite', suite);
+ return this;
+};
+
+/**
+ * Add a `test` to this suite.
+ *
+ * @param {Test} test
+ * @return {Suite} for chaining
+ * @api private
+ */
+
+Suite.prototype.addTest = function(test){
+ test.parent = this;
+ test.timeout(this.timeout());
+ test.ctx = this.ctx;
+ this.tests.push(test);
+ this.emit('test', test);
+ return this;
+};
+
+/**
+ * Return the full title generated by recursively
+ * concatenating the parent's full title.
+ *
+ * @return {String}
+ * @api public
+ */
+
+Suite.prototype.fullTitle = function(){
+ if (this.parent) {
+ var full = this.parent.fullTitle();
+ if (full) return full + ' ' + this.title;
+ }
+ return this.title;
+};
+
+/**
+ * Return the total number of tests.
+ *
+ * @return {Number}
+ * @api public
+ */
+
+Suite.prototype.total = function(){
+ return utils.reduce(this.suites, function(sum, suite){
+ return sum + suite.total();
+ }, 0) + this.tests.length;
+};
+
+}); // module: suite.js
+
+require.register("test.js", function(module, exports, require){
+
+/**
+ * Module dependencies.
+ */
+
+var Runnable = require('./runnable');
+
+/**
+ * Expose `Test`.
+ */
+
+module.exports = Test;
+
+/**
+ * Initialize a new `Test` with the given `title` and callback `fn`.
+ *
+ * @param {String} title
+ * @param {Function} fn
+ * @api private
+ */
+
+function Test(title, fn) {
+ Runnable.call(this, title, fn);
+ this.pending = !fn;
+ this.type = 'test';
+}
+
+/**
+ * Inherit from `Runnable.prototype`.
+ */
+
+Test.prototype = new Runnable;
+Test.prototype.constructor = Test;
+
+
+/**
+ * Inspect the context void of private properties.
+ *
+ * @return {String}
+ * @api private
+ */
+
+Test.prototype.inspect = function(){
+ return JSON.stringify(this, function(key, val){
+ return '_' == key[0]
+ ? undefined
+ : 'parent' == key
+ ? '#<Suite>'
+ : val;
+ }, 2);
+};
+}); // module: test.js
+
+require.register("utils.js", function(module, exports, require){
+
+/**
+ * Module dependencies.
+ */
+
+var fs = require('browser/fs')
+ , path = require('browser/path')
+ , join = path.join
+ , debug = require('browser/debug')('watch');
+
+/**
+ * Ignored directories.
+ */
+
+var ignore = ['node_modules', '.git'];
+
+/**
+ * Escape special characters in the given string of html.
+ *
+ * @param {String} html
+ * @return {String}
+ * @api private
+ */
+
+exports.escape = function(html) {
+ return String(html)
+ .replace(/&/g, '&amp;')
+ .replace(/"/g, '&quot;')
+ .replace(/</g, '&lt;')
+ .replace(/>/g, '&gt;');
+};
+
+/**
+ * Array#forEach (<=IE8)
+ *
+ * @param {Array} array
+ * @param {Function} fn
+ * @param {Object} scope
+ * @api private
+ */
+
+exports.forEach = function(arr, fn, scope) {
+ for (var i = 0, l = arr.length; i < l; i++)
+ fn.call(scope, arr[i], i);
+};
+
+/**
+ * Array#indexOf (<=IE8)
+ *
+ * @parma {Array} arr
+ * @param {Object} obj to find index of
+ * @param {Number} start
+ * @api private
+ */
+
+exports.indexOf = function (arr, obj, start) {
+ for (var i = start || 0, l = arr.length; i < l; i++) {
+ if (arr[i] === obj)
+ return i;
+ }
+ return -1;
+};
+
+/**
+ * Array#reduce (<=IE8)
+ *
+ * @param {Array} array
+ * @param {Function} fn
+ * @param {Object} initial value
+ * @param {Object} scope
+ * @api private
+ */
+
+exports.reduce = function(arr, fn, val, scope) {
+ var rval = val;
+
+ for (var i = 0, l = arr.length; i < l; i++) {
+ rval = fn.call(scope, rval, arr[i], i, arr);
+ }
+
+ return rval;
+};
+
+/**
+ * Array#filter (<=IE8)
+ *
+ * @param {Array} array
+ * @param {Function} fn
+ * @param {Object} scope
+ * @api private
+ */
+
+exports.filter = function(arr, fn, scope) {
+ var ret = [];
+
+ for (var i = 0, l = arr.length; i < l; i++) {
+ var val = arr[i];
+ if (fn.call(scope, val, i, arr))
+ ret.push(val);
+ }
+
+ return ret;
+};
+
+/**
+ * Object.keys (<=IE8)
+ *
+ * @param {Object} obj
+ * @return {Array} keys
+ * @api private
+ */
+
+exports.keys = Object.keys || function(obj) {
+ var keys = []
+ , has = Object.prototype.hasOwnProperty // for `window` on <=IE8
+
+ for (var key in obj) {
+ if (has.call(obj, key)) {
+ keys.push(key);
+ }
+ }
+
+ return keys;
+};
+
+/**
+ * Watch the given `files` for changes
+ * and invoke `fn(file)` on modification.
+ *
+ * @param {Array} files
+ * @param {Function} fn
+ * @api private
+ */
+
+exports.watch = function(files, fn){
+ var options = { interval: 100 };
+ files.forEach(function(file){
+ debug('file %s', file);
+ fs.watchFile(file, options, function(curr, prev){
+ if (prev.mtime < curr.mtime) fn(file);
+ });
+ });
+};
+
+/**
+ * Ignored files.
+ */
+
+function ignored(path){
+ return !~ignore.indexOf(path);
+}
+
+/**
+ * Lookup files in the given `dir`.
+ *
+ * @return {Array}
+ * @api private
+ */
+
+exports.files = function(dir, ret){
+ ret = ret || [];
+
+ fs.readdirSync(dir)
+ .filter(ignored)
+ .forEach(function(path){
+ path = join(dir, path);
+ if (fs.statSync(path).isDirectory()) {
+ exports.files(path, ret);
+ } else if (path.match(/\.(js|coffee)$/)) {
+ ret.push(path);
+ }
+ });
+
+ return ret;
+};
+
+/**
+ * Compute a slug from the given `str`.
+ *
+ * @param {String} str
+ * @return {String}
+ */
+
+exports.slug = function(str){
+ return str
+ .toLowerCase()
+ .replace(/ +/g, '-')
+ .replace(/[^-\w]/g, '');
+};
+}); // module: utils.js
diff --git a/node_modules/mocha/bin/_mocha b/node_modules/mocha/bin/_mocha
new file mode 100755
index 0000000..3a7a903
--- /dev/null
+++ b/node_modules/mocha/bin/_mocha
@@ -0,0 +1,345 @@
+#!/usr/bin/env node
+
+/**
+ * Module dependencies.
+ */
+
+var program = require('commander')
+ , exec = require('child_process').exec
+ , path = require('path')
+ , resolve = path.resolve
+ , mocha = require('../')
+ , utils = mocha.utils
+ , reporters = mocha.reporters
+ , interfaces = mocha.interfaces
+ , Context = mocha.Context
+ , Runner = mocha.Runner
+ , Suite = mocha.Suite
+ , vm = require('vm')
+ , fs = require('fs')
+ , join = path.join
+ , cwd = process.cwd();
+
+/**
+ * Files.
+ */
+
+var files = [];
+
+/**
+ * Images.
+ */
+
+var images = {
+ fail: __dirname + '/../images/error.png'
+ , pass: __dirname + '/../images/ok.png'
+};
+
+// options
+
+program
+ .version(mocha.version)
+ .usage('[debug] [options] [files]')
+ .option('-r, --require <name>', 'require the given module')
+ .option('-R, --reporter <name>', 'specify the reporter to use', 'dot')
+ .option('-u, --ui <name>', 'specify user-interface (bdd|tdd|exports)', 'bdd')
+ .option('-g, --grep <pattern>', 'only run tests matching <pattern>')
+ .option('-t, --timeout <ms>', 'set test-case timeout in milliseconds [2000]')
+ .option('-s, --slow <ms>', '"slow" test threshold in milliseconds [75]', parseInt)
+ .option('-w, --watch', 'watch files for changes')
+ .option('-c, --colors', 'force enabling of colors')
+ .option('-C, --no-colors', 'force disabling of colors')
+ .option('-G, --growl', 'enable growl notification support')
+ .option('-d, --debug', "enable node's debugger, synonym for node --debug")
+ .option('-b, --bail', "bail after first test failure")
+ .option('--debug-brk', "enable node's debugger breaking on the first line")
+ .option('--globals <names>', 'allow the given comma-delimited global [names]', list, [])
+ .option('--ignore-leaks', 'ignore global variable leaks')
+ .option('--interfaces', 'display available interfaces')
+ .option('--reporters', 'display available reporters')
+ .option('--compilers <ext>:<module>,...', 'use the given module(s) to compile files', list, [])
+
+program.name = 'mocha';
+
+// --reporters
+
+program.on('reporters', function(){
+ console.log();
+ console.log(' dot - dot matrix');
+ console.log(' doc - html documentation');
+ console.log(' spec - hierarchical spec list');
+ console.log(' json - single json object');
+ console.log(' progress - progress bar');
+ console.log(' list - spec-style listing');
+ console.log(' tap - test-anything-protocol');
+ console.log(' landing - unicode landing strip');
+ console.log(' xunit - xunit reportert');
+ console.log(' teamcity - teamcity ci support');
+ console.log(' html-cov - HTML test coverage');
+ console.log(' json-cov - JSON test coverage');
+ console.log(' min - minimal reporter (great with --watch)');
+ console.log(' json-stream - newline delimited json events');
+ console.log(' markdown - markdown documentation (github flavour)');
+ console.log();
+ process.exit();
+});
+
+// --interfaces
+
+program.on('interfaces', function(){
+ console.log('');
+ console.log(' bdd');
+ console.log(' tdd');
+ console.log(' qunit');
+ console.log(' exports');
+ console.log('');
+ process.exit();
+});
+
+// -r, --require
+
+module.paths.push(cwd, join(cwd, 'node_modules'));
+
+program.on('require', function(mod){
+ var abs = path.existsSync(mod)
+ || path.existsSync(mod + '.js');
+
+ if (abs) mod = join(cwd, mod);
+ require(mod);
+});
+
+// mocha.opts support
+
+try {
+ var opts = fs.readFileSync('test/mocha.opts', 'utf8')
+ .trim()
+ .split(/\s+/);
+
+ process.argv = process.argv
+ .slice(0, 2)
+ .concat(opts.concat(process.argv.slice(2)));
+} catch (err) {
+ // ignore
+}
+
+// parse args
+
+program.parse(process.argv);
+
+// infinite stack traces
+
+Error.stackTraceLimit = Infinity; // TODO: config
+
+// reporter
+
+var suite = new Suite('', new Context)
+ , Base = require('../lib/reporters/base')
+ , Reporter = require('../lib/reporters/' + program.reporter)
+ , ui = interfaces[program.ui](suite);
+
+// --no-colors
+
+if (!program.colors) Base.useColors = false;
+
+// --colors
+
+if (~process.argv.indexOf('--colors') ||
+ ~process.argv.indexOf('-c')) {
+ Base.useColors = true;
+}
+
+// --slow <ms>
+
+if (program.slow) Base.slow = program.slow;
+
+// --timeout
+
+if (program.timeout) suite.timeout(program.timeout);
+
+// --bail
+
+suite.bail(program.bail);
+
+// custom compiler support
+
+var extensions = ['js'];
+program.compilers.forEach(function(c) {
+ var compiler = c.split(':')
+ , ext = compiler[0]
+ , mod = compiler[1];
+
+ if (mod[0] == '.') mod = join(process.cwd(), mod);
+ require(mod);
+ extensions.push(ext);
+});
+
+var re = new RegExp('\\.(' + extensions.join('|') + ')$');
+
+// files
+
+var files = program.args;
+
+// default files to test/*.{js,coffee}
+
+if (!files.length) {
+ files = fs.readdirSync('test').filter(function(path){
+ return path.match(re);
+ }).map(function(path){
+ return join('test', path);
+ });
+}
+
+// resolve
+
+files = files.map(function(path){
+ return resolve(path);
+});
+
+// --watch
+
+if (program.watch) {
+ console.log();
+ hideCursor();
+ process.on('SIGINT', function(){
+ showCursor();
+ console.log('\n');
+ process.exit();
+ });
+
+ var frames = [
+ ' \033[96m◜ \033[90mwatching\033[0m'
+ , ' \033[96m◠ \033[90mwatching\033[0m'
+ , ' \033[96m◝ \033[90mwatching\033[0m'
+ , ' \033[96m◞ \033[90mwatching\033[0m'
+ , ' \033[96m◡ \033[90mwatching\033[0m'
+ , ' \033[96m◟ \033[90mwatching\033[0m'
+ ];
+
+ var watchFiles = utils.files(cwd);
+
+ function loadAndRun() {
+ load(files, function(){
+ run(suite, function(){
+ play(frames);
+ });
+ });
+ }
+
+ function purge() {
+ watchFiles.forEach(function(file){
+ delete require.cache[file];
+ });
+ }
+
+ loadAndRun();
+
+ utils.watch(watchFiles, function(){
+ purge();
+ stop()
+ suite = suite.clone();
+ ui = interfaces[program.ui](suite);
+ loadAndRun();
+ });
+
+ return;
+}
+
+// load
+
+load(files, function(){
+ run(suite, process.exit);
+});
+
+// require test files before
+// running the root suite
+
+function load(files, fn) {
+ var pending = files.length;
+ files.forEach(function(file){
+ delete require.cache[file];
+ suite.emit('pre-require', global, file);
+ suite.emit('require', require(file), file);
+ suite.emit('post-require', global, file);
+ --pending || fn();
+ });
+}
+
+// run the given suite
+
+function run(suite, fn) {
+ suite.emit('run');
+ var runner = new Runner(suite);
+ var reporter = new Reporter(runner);
+ runner.globals(program.globals);
+ if (program.ignoreLeaks) runner.ignoreLeaks = true;
+ if (program.grep) runner.grep(new RegExp(program.grep));
+ if (program.growl) growl(runner, reporter);
+ runner.run(fn);
+}
+
+// enable growl notifications
+
+function growl(runner, reporter) {
+ var notify = require('growl');
+
+ runner.on('end', function(){
+ var stats = reporter.stats;
+ if (stats.failures) {
+ var msg = stats.failures + ' of ' + runner.total + ' tests failed';
+ notify(msg, { title: 'Failed', image: images.fail });
+ } else {
+ notify(stats.passes + ' tests passed in ' + stats.duration + 'ms', {
+ title: 'Passed'
+ , image: images.pass
+ });
+ }
+ });
+}
+
+/**
+ * Parse list.
+ */
+
+function list(str) {
+ return str.split(/ *, */);
+}
+
+/**
+ * Hide the cursor.
+ */
+
+function hideCursor(){
+ process.stdout.write('\033[?25l');
+};
+
+/**
+ * Show the cursor.
+ */
+
+function showCursor(){
+ process.stdout.write('\033[?25h');
+};
+
+/**
+ * Stop play()ing.
+ */
+
+function stop() {
+ process.stdout.write('\033[2K');
+ clearInterval(play.timer);
+}
+
+/**
+ * Play the given array of strings.
+ */
+
+function play(arr, interval) {
+ var len = arr.length
+ , interval = interval || 100
+ , i = 0;
+
+ play.timer = setInterval(function(){
+ var str = arr[i++ % len];
+ process.stdout.write('\r' + str);
+ }, interval);
+}
diff --git a/node_modules/mocha/bin/mocha b/node_modules/mocha/bin/mocha
new file mode 100755
index 0000000..811ed9d
--- /dev/null
+++ b/node_modules/mocha/bin/mocha
@@ -0,0 +1,32 @@
+#!/usr/bin/env node
+
+/**
+ * This tiny wrapper file checks for known node flags and appends them
+ * when found, before invoking the "real" _mocha(1) executable.
+ */
+
+var spawn = require('child_process').spawn
+ , args = [ __dirname + '/_mocha' ];
+
+process.argv.slice(2).forEach(function (arg) {
+ switch (arg) {
+ case '-d':
+ args.unshift('--debug');
+ break;
+ case 'debug':
+ case '--debug':
+ case '--debug-brk':
+ args.unshift(arg);
+ break;
+ case '-gc':
+ case '--expose-gc':
+ args.unshift('--expose-gc');
+ break;
+ default:
+ args.push(arg);
+ break;
+ }
+});
+
+var proc = spawn(process.argv[0], args, { customFds: [0,1,2] });
+proc.on('exit', process.exit);
diff --git a/node_modules/mocha/editors/JavaScript mocha.tmbundle/Snippets/bdd - after each.tmSnippet b/node_modules/mocha/editors/JavaScript mocha.tmbundle/Snippets/bdd - after each.tmSnippet
new file mode 100644
index 0000000..e76cae1
--- /dev/null
+++ b/node_modules/mocha/editors/JavaScript mocha.tmbundle/Snippets/bdd - after each.tmSnippet
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>content</key>
+ <string>afterEach(function(){
+ $0
+})</string>
+ <key>name</key>
+ <string>bdd - after each</string>
+ <key>tabTrigger</key>
+ <string>ae</string>
+ <key>uuid</key>
+ <string>7B4DA8F4-2064-468B-B252-054148419B4B</string>
+</dict>
+</plist>
diff --git a/node_modules/mocha/editors/JavaScript mocha.tmbundle/Snippets/bdd - after.tmSnippet b/node_modules/mocha/editors/JavaScript mocha.tmbundle/Snippets/bdd - after.tmSnippet
new file mode 100644
index 0000000..f1a67aa
--- /dev/null
+++ b/node_modules/mocha/editors/JavaScript mocha.tmbundle/Snippets/bdd - after.tmSnippet
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>content</key>
+ <string>after(function(){
+ $0
+})</string>
+ <key>name</key>
+ <string>bdd - after</string>
+ <key>tabTrigger</key>
+ <string>a</string>
+ <key>uuid</key>
+ <string>A49A87F9-399E-4D74-A489-C535BB06D487</string>
+</dict>
+</plist>
diff --git a/node_modules/mocha/editors/JavaScript mocha.tmbundle/Snippets/bdd - before each.tmSnippet b/node_modules/mocha/editors/JavaScript mocha.tmbundle/Snippets/bdd - before each.tmSnippet
new file mode 100644
index 0000000..f8442fa
--- /dev/null
+++ b/node_modules/mocha/editors/JavaScript mocha.tmbundle/Snippets/bdd - before each.tmSnippet
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>content</key>
+ <string>beforeEach(function(){
+ $0
+})</string>
+ <key>name</key>
+ <string>bdd - before each</string>
+ <key>tabTrigger</key>
+ <string>be</string>
+ <key>uuid</key>
+ <string>7AB064E3-EFBB-4FA7-98CA-9E87C10CC04E</string>
+</dict>
+</plist>
diff --git a/node_modules/mocha/editors/JavaScript mocha.tmbundle/Snippets/bdd - before.tmSnippet b/node_modules/mocha/editors/JavaScript mocha.tmbundle/Snippets/bdd - before.tmSnippet
new file mode 100644
index 0000000..5c7e40f
--- /dev/null
+++ b/node_modules/mocha/editors/JavaScript mocha.tmbundle/Snippets/bdd - before.tmSnippet
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>content</key>
+ <string>before(function(){
+ $0
+})</string>
+ <key>name</key>
+ <string>bdd - before</string>
+ <key>tabTrigger</key>
+ <string>b</string>
+ <key>uuid</key>
+ <string>DF6F1F42-F80A-4A24-AF78-376F19070C4C</string>
+</dict>
+</plist>
diff --git a/node_modules/mocha/editors/JavaScript mocha.tmbundle/Snippets/bdd - it.tmSnippet b/node_modules/mocha/editors/JavaScript mocha.tmbundle/Snippets/bdd - it.tmSnippet
new file mode 100644
index 0000000..8cd3fb1
--- /dev/null
+++ b/node_modules/mocha/editors/JavaScript mocha.tmbundle/Snippets/bdd - it.tmSnippet
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>content</key>
+ <string>it('should $1', function(){
+ $0
+})</string>
+ <key>name</key>
+ <string>bdd - it</string>
+ <key>tabTrigger</key>
+ <string>it</string>
+ <key>uuid</key>
+ <string>591AE071-95E4-4E1E-B0F3-A7DAF41595EE</string>
+</dict>
+</plist>
diff --git a/node_modules/mocha/editors/JavaScript mocha.tmbundle/Snippets/untitled.tmSnippet b/node_modules/mocha/editors/JavaScript mocha.tmbundle/Snippets/untitled.tmSnippet
new file mode 100644
index 0000000..46fd720
--- /dev/null
+++ b/node_modules/mocha/editors/JavaScript mocha.tmbundle/Snippets/untitled.tmSnippet
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>content</key>
+ <string>describe('$1', function(){
+ $0
+})</string>
+ <key>name</key>
+ <string>bdd - describe</string>
+ <key>tabTrigger</key>
+ <string>des</string>
+ <key>uuid</key>
+ <string>4AA1FB50-9BB9-400E-A140-D61C39BDFDF5</string>
+</dict>
+</plist>
diff --git a/node_modules/mocha/editors/JavaScript mocha.tmbundle/info.plist b/node_modules/mocha/editors/JavaScript mocha.tmbundle/info.plist
new file mode 100644
index 0000000..16f6587
--- /dev/null
+++ b/node_modules/mocha/editors/JavaScript mocha.tmbundle/info.plist
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>name</key>
+ <string>JavaScript mocha</string>
+ <key>ordering</key>
+ <array>
+ <string>4AA1FB50-9BB9-400E-A140-D61C39BDFDF5</string>
+ <string>591AE071-95E4-4E1E-B0F3-A7DAF41595EE</string>
+ <string>DF6F1F42-F80A-4A24-AF78-376F19070C4C</string>
+ <string>A49A87F9-399E-4D74-A489-C535BB06D487</string>
+ <string>7AB064E3-EFBB-4FA7-98CA-9E87C10CC04E</string>
+ <string>7B4DA8F4-2064-468B-B252-054148419B4B</string>
+ </array>
+ <key>uuid</key>
+ <string>094ACE33-0C0E-422A-B3F7-5B919F5B1239</string>
+</dict>
+</plist>
diff --git a/node_modules/mocha/images/error.png b/node_modules/mocha/images/error.png
new file mode 100644
index 0000000..490822a
--- /dev/null
+++ b/node_modules/mocha/images/error.png
Binary files differ
diff --git a/node_modules/mocha/images/ok.png b/node_modules/mocha/images/ok.png
new file mode 100644
index 0000000..2983c0b
--- /dev/null
+++ b/node_modules/mocha/images/ok.png
Binary files differ
diff --git a/node_modules/mocha/index.js b/node_modules/mocha/index.js
new file mode 100644
index 0000000..507566f
--- /dev/null
+++ b/node_modules/mocha/index.js
@@ -0,0 +1,4 @@
+
+module.exports = process.env.COV
+ ? require('./lib-cov/mocha')
+ : require('./lib/mocha'); \ No newline at end of file
diff --git a/node_modules/mocha/lib/browser/debug.js b/node_modules/mocha/lib/browser/debug.js
new file mode 100644
index 0000000..946f4ab
--- /dev/null
+++ b/node_modules/mocha/lib/browser/debug.js
@@ -0,0 +1,6 @@
+
+module.exports = function(type){
+ return function(){
+
+ }
+}; \ No newline at end of file
diff --git a/node_modules/mocha/lib/browser/diff.js b/node_modules/mocha/lib/browser/diff.js
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/node_modules/mocha/lib/browser/diff.js
diff --git a/node_modules/mocha/lib/browser/events.js b/node_modules/mocha/lib/browser/events.js
new file mode 100644
index 0000000..4d94ee1
--- /dev/null
+++ b/node_modules/mocha/lib/browser/events.js
@@ -0,0 +1,178 @@
+
+/**
+ * Module exports.
+ */
+
+exports.EventEmitter = EventEmitter;
+
+/**
+ * Check if `obj` is an array.
+ */
+
+function isArray(obj) {
+ return '[object Array]' == {}.toString.call(obj);
+}
+
+/**
+ * Event emitter constructor.
+ *
+ * @api public.
+ */
+
+function EventEmitter(){};
+
+/**
+ * Adds a listener.
+ *
+ * @api public
+ */
+
+EventEmitter.prototype.on = function (name, fn) {
+ if (!this.$events) {
+ this.$events = {};
+ }
+
+ if (!this.$events[name]) {
+ this.$events[name] = fn;
+ } else if (isArray(this.$events[name])) {
+ this.$events[name].push(fn);
+ } else {
+ this.$events[name] = [this.$events[name], fn];
+ }
+
+ return this;
+};
+
+EventEmitter.prototype.addListener = EventEmitter.prototype.on;
+
+/**
+ * Adds a volatile listener.
+ *
+ * @api public
+ */
+
+EventEmitter.prototype.once = function (name, fn) {
+ var self = this;
+
+ function on () {
+ self.removeListener(name, on);
+ fn.apply(this, arguments);
+ };
+
+ on.listener = fn;
+ this.on(name, on);
+
+ return this;
+};
+
+/**
+ * Removes a listener.
+ *
+ * @api public
+ */
+
+EventEmitter.prototype.removeListener = function (name, fn) {
+ if (this.$events && this.$events[name]) {
+ var list = this.$events[name];
+
+ if (isArray(list)) {
+ var pos = -1;
+
+ for (var i = 0, l = list.length; i < l; i++) {
+ if (list[i] === fn || (list[i].listener && list[i].listener === fn)) {
+ pos = i;
+ break;
+ }
+ }
+
+ if (pos < 0) {
+ return this;
+ }
+
+ list.splice(pos, 1);
+
+ if (!list.length) {
+ delete this.$events[name];
+ }
+ } else if (list === fn || (list.listener && list.listener === fn)) {
+ delete this.$events[name];
+ }
+ }
+
+ return this;
+};
+
+/**
+ * Removes all listeners for an event.
+ *
+ * @api public
+ */
+
+EventEmitter.prototype.removeAllListeners = function (name) {
+ if (name === undefined) {
+ this.$events = {};
+ return this;
+ }
+
+ if (this.$events && this.$events[name]) {
+ this.$events[name] = null;
+ }
+
+ return this;
+};
+
+/**
+ * Gets all listeners for a certain event.
+ *
+ * @api publci
+ */
+
+EventEmitter.prototype.listeners = function (name) {
+ if (!this.$events) {
+ this.$events = {};
+ }
+
+ if (!this.$events[name]) {
+ this.$events[name] = [];
+ }
+
+ if (!isArray(this.$events[name])) {
+ this.$events[name] = [this.$events[name]];
+ }
+
+ return this.$events[name];
+};
+
+/**
+ * Emits an event.
+ *
+ * @api public
+ */
+
+EventEmitter.prototype.emit = function (name) {
+ if (!this.$events) {
+ return false;
+ }
+
+ var handler = this.$events[name];
+
+ if (!handler) {
+ return false;
+ }
+
+ var args = [].slice.call(arguments, 1);
+
+ if ('function' == typeof handler) {
+ handler.apply(this, args);
+ } else if (isArray(handler)) {
+ var listeners = handler.slice();
+
+ for (var i = 0, l = listeners.length; i < l; i++) {
+ listeners[i].apply(this, args);
+ }
+ } else {
+ return false;
+ }
+
+ return true;
+}; \ No newline at end of file
diff --git a/node_modules/mocha/lib/browser/fs.js b/node_modules/mocha/lib/browser/fs.js
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/node_modules/mocha/lib/browser/fs.js
diff --git a/node_modules/mocha/lib/browser/path.js b/node_modules/mocha/lib/browser/path.js
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/node_modules/mocha/lib/browser/path.js
diff --git a/node_modules/mocha/lib/browser/progress.js b/node_modules/mocha/lib/browser/progress.js
new file mode 100644
index 0000000..1d60cde
--- /dev/null
+++ b/node_modules/mocha/lib/browser/progress.js
@@ -0,0 +1,125 @@
+
+/**
+ * Expose `Progress`.
+ */
+
+module.exports = Progress;
+
+/**
+ * Initialize a new `Progress` indicator.
+ */
+
+function Progress() {
+ this.percent = 0;
+ this.size(0);
+ this.fontSize(11);
+ this.font('helvetica, arial, sans-serif');
+}
+
+/**
+ * Set progress size to `n`.
+ *
+ * @param {Number} n
+ * @return {Progress} for chaining
+ * @api public
+ */
+
+Progress.prototype.size = function(n){
+ this._size = n;
+ return this;
+};
+
+/**
+ * Set text to `str`.
+ *
+ * @param {String} str
+ * @return {Progress} for chaining
+ * @api public
+ */
+
+Progress.prototype.text = function(str){
+ this._text = str;
+ return this;
+};
+
+/**
+ * Set font size to `n`.
+ *
+ * @param {Number} n
+ * @return {Progress} for chaining
+ * @api public
+ */
+
+Progress.prototype.fontSize = function(n){
+ this._fontSize = n;
+ return this;
+};
+
+/**
+ * Set font `family`.
+ *
+ * @param {String} family
+ * @return {Progress} for chaining
+ */
+
+Progress.prototype.font = function(family){
+ this._font = family;
+ return this;
+};
+
+/**
+ * Update percentage to `n`.
+ *
+ * @param {Number} n
+ * @return {Progress} for chaining
+ */
+
+Progress.prototype.update = function(n){
+ this.percent = n;
+ return this;
+};
+
+/**
+ * Draw on `ctx`.
+ *
+ * @param {CanvasRenderingContext2d} ctx
+ * @return {Progress} for chaining
+ */
+
+Progress.prototype.draw = function(ctx){
+ var percent = Math.min(this.percent, 100)
+ , size = this._size
+ , half = size / 2
+ , x = half
+ , y = half
+ , rad = half - 1
+ , fontSize = this._fontSize;
+
+ ctx.font = fontSize + 'px ' + this._font;
+
+ var angle = Math.PI * 2 * (percent / 100);
+ ctx.clearRect(0, 0, size, size);
+
+ // outer circle
+ ctx.strokeStyle = '#9f9f9f';
+ ctx.beginPath();
+ ctx.arc(x, y, rad, 0, angle, false);
+ ctx.stroke();
+
+ // inner circle
+ ctx.strokeStyle = '#eee';
+ ctx.beginPath();
+ ctx.arc(x, y, rad - 1, 0, angle, true);
+ ctx.stroke();
+
+ // text
+ var text = this._text || (percent | 0) + '%'
+ , w = ctx.measureText(text).width;
+
+ ctx.fillText(
+ text
+ , x - w / 2 + 1
+ , y + fontSize / 2 - 1);
+
+ return this;
+};
diff --git a/node_modules/mocha/lib/browser/tty.js b/node_modules/mocha/lib/browser/tty.js
new file mode 100644
index 0000000..2d84374
--- /dev/null
+++ b/node_modules/mocha/lib/browser/tty.js
@@ -0,0 +1,8 @@
+
+exports.isatty = function(){
+ return true;
+};
+
+exports.getWindowSize = function(){
+ return [window.innerHeight, window.innerWidth];
+}; \ No newline at end of file
diff --git a/node_modules/mocha/lib/context.js b/node_modules/mocha/lib/context.js
new file mode 100644
index 0000000..f636f1b
--- /dev/null
+++ b/node_modules/mocha/lib/context.js
@@ -0,0 +1,55 @@
+
+/**
+ * Expose `Context`.
+ */
+
+module.exports = Context;
+
+/**
+ * Initialize a new `Context`.
+ *
+ * @api private
+ */
+
+function Context(){}
+
+/**
+ * Set the context `Runnable` to `runnable`.
+ *
+ * @param {Runnable} runnable
+ * @return {Context}
+ * @api private
+ */
+
+Context.prototype.runnable = function(runnable){
+ this._runnable = runnable;
+ return this;
+};
+
+/**
+ * Set test timeout `ms`.
+ *
+ * @param {Number} ms
+ * @return {Context} self
+ * @api private
+ */
+
+Context.prototype.timeout = function(ms){
+ this._runnable.timeout(ms);
+ return this;
+};
+
+/**
+ * Inspect the context void of `._runnable`.
+ *
+ * @return {String}
+ * @api private
+ */
+
+Context.prototype.inspect = function(){
+ return JSON.stringify(this, function(key, val){
+ return '_runnable' == key
+ ? undefined
+ : val;
+ }, 2);
+};
diff --git a/node_modules/mocha/lib/hook.js b/node_modules/mocha/lib/hook.js
new file mode 100644
index 0000000..3ed712e
--- /dev/null
+++ b/node_modules/mocha/lib/hook.js
@@ -0,0 +1,31 @@
+
+/**
+ * Module dependencies.
+ */
+
+var Runnable = require('./runnable');
+
+/**
+ * Expose `Hook`.
+ */
+
+module.exports = Hook;
+
+/**
+ * Initialize a new `Hook` with the given `title` and callback `fn`.
+ *
+ * @param {String} title
+ * @param {Function} fn
+ * @api private
+ */
+
+function Hook(title, fn) {
+ Runnable.call(this, title, fn);
+ this.type = 'hook';
+}
+
+/**
+ * Inherit from `Runnable.prototype`.
+ */
+
+Hook.prototype.__proto__ = Runnable.prototype;
diff --git a/node_modules/mocha/lib/interfaces/bdd.js b/node_modules/mocha/lib/interfaces/bdd.js
new file mode 100644
index 0000000..5f66e0e
--- /dev/null
+++ b/node_modules/mocha/lib/interfaces/bdd.js
@@ -0,0 +1,91 @@
+
+/**
+ * Module dependencies.
+ */
+
+var Suite = require('../suite')
+ , Test = require('../test');
+
+/**
+ * BDD-style interface:
+ *
+ * describe('Array', function(){
+ * describe('#indexOf()', function(){
+ * it('should return -1 when not present', function(){
+ *
+ * });
+ *
+ * it('should return the index when present', function(){
+ *
+ * });
+ * });
+ * });
+ *
+ */
+
+module.exports = function(suite){
+ var suites = [suite];
+
+ suite.on('pre-require', function(context){
+
+ // noop variants
+
+ context.xdescribe = function(){};
+ context.xit = function(){};
+
+ /**
+ * Execute before running tests.
+ */
+
+ context.before = function(fn){
+ suites[0].beforeAll(fn);
+ };
+
+ /**
+ * Execute after running tests.
+ */
+
+ context.after = function(fn){
+ suites[0].afterAll(fn);
+ };
+
+ /**
+ * Execute before each test case.
+ */
+
+ context.beforeEach = function(fn){
+ suites[0].beforeEach(fn);
+ };
+
+ /**
+ * Execute after each test case.
+ */
+
+ context.afterEach = function(fn){
+ suites[0].afterEach(fn);
+ };
+
+ /**
+ * Describe a "suite" with the given `title`
+ * and callback `fn` containing nested suites
+ * and/or tests.
+ */
+
+ context.describe = function(title, fn){
+ var suite = Suite.create(suites[0], title);
+ suites.unshift(suite);
+ fn();
+ suites.shift();
+ };
+
+ /**
+ * Describe a specification or test-case
+ * with the given `title` and callback `fn`
+ * acting as a thunk.
+ */
+
+ context.it = function(title, fn){
+ suites[0].addTest(new Test(title, fn));
+ };
+ });
+};
diff --git a/node_modules/mocha/lib/interfaces/exports.js b/node_modules/mocha/lib/interfaces/exports.js
new file mode 100644
index 0000000..b22607e
--- /dev/null
+++ b/node_modules/mocha/lib/interfaces/exports.js
@@ -0,0 +1,60 @@
+
+/**
+ * Module dependencies.
+ */
+
+var Suite = require('../suite')
+ , Test = require('../test');
+
+/**
+ * TDD-style interface:
+ *
+ * exports.Array = {
+ * '#indexOf()': {
+ * 'should return -1 when the value is not present': function(){
+ *
+ * },
+ *
+ * 'should return the correct index when the value is present': function(){
+ *
+ * }
+ * }
+ * };
+ *
+ */
+
+module.exports = function(suite){
+ var suites = [suite];
+
+ suite.on('require', visit);
+
+ function visit(obj) {
+ var suite;
+ for (var key in obj) {
+ if ('function' == typeof obj[key]) {
+ var fn = obj[key];
+ switch (key) {
+ case 'before':
+ suites[0].beforeAll(fn);
+ break;
+ case 'after':
+ suites[0].afterAll(fn);
+ break;
+ case 'beforeEach':
+ suites[0].beforeEach(fn);
+ break;
+ case 'afterEach':
+ suites[0].afterEach(fn);
+ break;
+ default:
+ suites[0].addTest(new Test(key, fn));
+ }
+ } else {
+ var suite = Suite.create(suites[0], key);
+ suites.unshift(suite);
+ visit(obj[key]);
+ suites.shift();
+ }
+ }
+ }
+}; \ No newline at end of file
diff --git a/node_modules/mocha/lib/interfaces/index.js b/node_modules/mocha/lib/interfaces/index.js
new file mode 100644
index 0000000..f7b2655
--- /dev/null
+++ b/node_modules/mocha/lib/interfaces/index.js
@@ -0,0 +1,5 @@
+
+exports.bdd = require('./bdd');
+exports.tdd = require('./tdd');
+exports.qunit = require('./qunit');
+exports.exports = require('./exports');
diff --git a/node_modules/mocha/lib/interfaces/qunit.js b/node_modules/mocha/lib/interfaces/qunit.js
new file mode 100644
index 0000000..cd03ab6
--- /dev/null
+++ b/node_modules/mocha/lib/interfaces/qunit.js
@@ -0,0 +1,91 @@
+
+/**
+ * Module dependencies.
+ */
+
+var Suite = require('../suite')
+ , Test = require('../test');
+
+/**
+ * QUnit-style interface:
+ *
+ * suite('Array');
+ *
+ * test('#length', function(){
+ * var arr = [1,2,3];
+ * ok(arr.length == 3);
+ * });
+ *
+ * test('#indexOf()', function(){
+ * var arr = [1,2,3];
+ * ok(arr.indexOf(1) == 0);
+ * ok(arr.indexOf(2) == 1);
+ * ok(arr.indexOf(3) == 2);
+ * });
+ *
+ * suite('String');
+ *
+ * test('#length', function(){
+ * ok('foo'.length == 3);
+ * });
+ *
+ */
+
+module.exports = function(suite){
+ var suites = [suite];
+
+ suite.on('pre-require', function(context){
+
+ /**
+ * Execute before running tests.
+ */
+
+ context.before = function(fn){
+ suites[0].beforeAll(fn);
+ };
+
+ /**
+ * Execute after running tests.
+ */
+
+ context.after = function(fn){
+ suites[0].afterAll(fn);
+ };
+
+ /**
+ * Execute before each test case.
+ */
+
+ context.beforeEach = function(fn){
+ suites[0].beforeEach(fn);
+ };
+
+ /**
+ * Execute after each test case.
+ */
+
+ context.afterEach = function(fn){
+ suites[0].afterEach(fn);
+ };
+
+ /**
+ * Describe a "suite" with the given `title`.
+ */
+
+ context.suite = function(title){
+ if (suites.length > 1) suites.shift();
+ var suite = Suite.create(suites[0], title);
+ suites.unshift(suite);
+ };
+
+ /**
+ * Describe a specification or test-case
+ * with the given `title` and callback `fn`
+ * acting as a thunk.
+ */
+
+ context.test = function(title, fn){
+ suites[0].addTest(new Test(title, fn));
+ };
+ });
+};
diff --git a/node_modules/mocha/lib/interfaces/tdd.js b/node_modules/mocha/lib/interfaces/tdd.js
new file mode 100644
index 0000000..53c51b8
--- /dev/null
+++ b/node_modules/mocha/lib/interfaces/tdd.js
@@ -0,0 +1,94 @@
+
+/**
+ * Module dependencies.
+ */
+
+var Suite = require('../suite')
+ , Test = require('../test');
+
+/**
+ * TDD-style interface:
+ *
+ * suite('Array', function(){
+ * suite('#indexOf()', function(){
+ * suiteSetup(function(){
+ *
+ * });
+ *
+ * test('should return -1 when not present', function(){
+ *
+ * });
+ *
+ * test('should return the index when present', function(){
+ *
+ * });
+ *
+ * suiteTeardown(function(){
+ *
+ * });
+ * });
+ * });
+ *
+ */
+
+module.exports = function(suite){
+ var suites = [suite];
+
+ suite.on('pre-require', function(context){
+
+ /**
+ * Execute before each test case.
+ */
+
+ context.setup = function(fn){
+ suites[0].beforeEach(fn);
+ };
+
+ /**
+ * Execute after each test case.
+ */
+
+ context.teardown = function(fn){
+ suites[0].afterEach(fn);
+ };
+
+ /**
+ * Execute before the suite.
+ */
+
+ context.suiteSetup = function(fn){
+ suites[0].beforeAll(fn);
+ };
+
+ /**
+ * Execute after the suite.
+ */
+
+ context.suiteTeardown = function(fn){
+ suites[0].afterAll(fn);
+ };
+
+ /**
+ * Describe a "suite" with the given `title`
+ * and callback `fn` containing nested suites
+ * and/or tests.
+ */
+
+ context.suite = function(title, fn){
+ var suite = Suite.create(suites[0], title);
+ suites.unshift(suite);
+ fn();
+ suites.shift();
+ };
+
+ /**
+ * Describe a specification or test-case
+ * with the given `title` and callback `fn`
+ * acting as a thunk.
+ */
+
+ context.test = function(title, fn){
+ suites[0].addTest(new Test(title, fn));
+ };
+ });
+};
diff --git a/node_modules/mocha/lib/mocha.js b/node_modules/mocha/lib/mocha.js
new file mode 100644
index 0000000..71d96f8
--- /dev/null
+++ b/node_modules/mocha/lib/mocha.js
@@ -0,0 +1,176 @@
+
+/*!
+ * mocha
+ * Copyright(c) 2011 TJ Holowaychuk <tj@vision-media.ca>
+ * MIT Licensed
+ */
+
+/**
+ * Module dependencies.
+ */
+
+var path = require('path');
+
+/**
+ * Expose `Mocha`.
+ */
+
+exports = module.exports = Mocha;
+
+/**
+ * Library version.
+ */
+
+exports.version = '1.0.1';
+
+/**
+ * Expose internals.
+ */
+
+exports.utils = require('./utils');
+exports.interfaces = require('./interfaces');
+exports.reporters = require('./reporters');
+exports.Runnable = require('./runnable');
+exports.Context = require('./context');
+exports.Runner = require('./runner');
+exports.Suite = require('./suite');
+exports.Hook = require('./hook');
+exports.Test = require('./test');
+
+/**
+ * Return image `name` path.
+ *
+ * @param {String} name
+ * @return {String}
+ * @api private
+ */
+
+function image(name) {
+ return __dirname + '/../images/' + name + '.png';
+}
+
+/**
+ * Setup mocha with `options`.
+ *
+ * Options:
+ *
+ * - `ui` name "bdd", "tdd", "exports" etc
+ * - `reporter` reporter instance, defaults to `mocha.reporters.Dot`
+ * - `globals` array of accepted globals
+ * - `timeout` timeout in milliseconds
+ * - `ignoreLeaks` ignore global leaks
+ *
+ * @param {Object} options
+ * @api public
+ */
+
+function Mocha(options) {
+ options = options || {};
+ this.files = [];
+ this.options = options;
+ this.suite = new exports.Suite('', new exports.Context);
+ this.ui(options.ui);
+ this.reporter(options.reporter);
+ if (options.timeout) this.suite.timeout(options.timeout);
+}
+
+/**
+ * Add test `file`.
+ *
+ * @param {String} file
+ * @api public
+ */
+
+Mocha.prototype.addFile = function(file){
+ this.files.push(file);
+ return this;
+};
+
+/**
+ * Set reporter to `name`, defaults to "dot".
+ *
+ * @param {String} name
+ * @api public
+ */
+
+Mocha.prototype.reporter = function(name){
+ name = name || 'dot';
+ this._reporter = require('./reporters/' + name);
+ if (!this._reporter) throw new Error('invalid reporter "' + name + '"');
+ return this;
+};
+
+/**
+ * Set test UI `name`, defaults to "bdd".
+ *
+ * @param {String} bdd
+ * @api public
+ */
+
+Mocha.prototype.ui = function(name){
+ name = name || 'bdd';
+ this._ui = exports.interfaces[name];
+ if (!this._ui) throw new Error('invalid interface "' + name + '"');
+ this._ui = this._ui(this.suite);
+ return this;
+};
+
+/**
+ * Load registered files.
+ *
+ * @api private
+ */
+
+Mocha.prototype.loadFiles = function(){
+ var suite = this.suite;
+ this.files.forEach(function(file){
+ file = path.resolve(file);
+ suite.emit('pre-require', global, file);
+ suite.emit('require', require(file), file);
+ suite.emit('post-require', global, file);
+ });
+};
+
+/**
+ * Enable growl support.
+ *
+ * @api private
+ */
+
+Mocha.prototype.growl = function(runner, reporter) {
+ var notify = require('growl');
+
+ runner.on('end', function(){
+ var stats = reporter.stats;
+ if (stats.failures) {
+ var msg = stats.failures + ' of ' + runner.total + ' tests failed';
+ notify(msg, { title: 'Failed', image: image('fail') });
+ } else {
+ notify(stats.passes + ' tests passed in ' + stats.duration + 'ms', {
+ title: 'Passed'
+ , image: image('pass')
+ });
+ }
+ });
+};
+
+/**
+ * Run tests and invoke `fn()` when complete.
+ *
+ * @param {Function} fn
+ * @return {Runner}
+ * @api public
+ */
+
+Mocha.prototype.run = function(fn){
+ this.loadFiles();
+ var suite = this.suite;
+ var options = this.options;
+ var runner = new exports.Runner(suite);
+ var reporter = new this._reporter(runner);
+ runner.ignoreLeaks = options.ignoreLeaks;
+ if (options.grep) runner.grep(options.grep);
+ if (options.globals) runner.globals(options.globals);
+ if (options.growl) this.growl(runner, reporter);
+ return runner.run(fn);
+};
diff --git a/node_modules/mocha/lib/reporters/base.js b/node_modules/mocha/lib/reporters/base.js
new file mode 100644
index 0000000..fddd0bb
--- /dev/null
+++ b/node_modules/mocha/lib/reporters/base.js
@@ -0,0 +1,319 @@
+
+/**
+ * Module dependencies.
+ */
+
+var tty = require('tty')
+ , diff = require('diff');
+
+/**
+ * Check if both stdio streams are associated with a tty.
+ */
+
+var isatty = tty.isatty(1) && tty.isatty(2);
+
+/**
+ * Expose `Base`.
+ */
+
+exports = module.exports = Base;
+
+/**
+ * Enable coloring by default.
+ */
+
+exports.useColors = isatty;
+
+/**
+ * Default color map.
+ */
+
+exports.colors = {
+ 'pass': 90
+ , 'fail': 31
+ , 'bright pass': 92
+ , 'bright fail': 91
+ , 'bright yellow': 93
+ , 'pending': 36
+ , 'suite': 0
+ , 'error title': 0
+ , 'error message': 31
+ , 'error stack': 90
+ , 'checkmark': 32
+ , 'fast': 90
+ , 'medium': 33
+ , 'slow': 31
+ , 'green': 32
+ , 'light': 90
+ , 'diff gutter': 90
+ , 'diff added': 42
+ , 'diff removed': 41
+};
+
+/**
+ * Color `str` with the given `type`,
+ * allowing colors to be disabled,
+ * as well as user-defined color
+ * schemes.
+ *
+ * @param {String} type
+ * @param {String} str
+ * @return {String}
+ * @api private
+ */
+
+var color = exports.color = function(type, str) {
+ if (!exports.useColors) return str;
+ return '\033[' + exports.colors[type] + 'm' + str + '\033[0m';
+};
+
+/**
+ * Expose term window size, with some
+ * defaults for when stderr is not a tty.
+ */
+
+exports.window = {
+ width: isatty
+ ? process.stdout.getWindowSize
+ ? process.stdout.getWindowSize(1)[0]
+ : tty.getWindowSize()[1]
+ : 75
+};
+
+/**
+ * Expose some basic cursor interactions
+ * that are common among reporters.
+ */
+
+exports.cursor = {
+ hide: function(){
+ process.stdout.write('\033[?25l');
+ },
+
+ show: function(){
+ process.stdout.write('\033[?25h');
+ },
+
+ deleteLine: function(){
+ process.stdout.write('\033[2K');
+ },
+
+ beginningOfLine: function(){
+ process.stdout.write('\033[0G');
+ },
+
+ CR: function(){
+ exports.cursor.deleteLine();
+ exports.cursor.beginningOfLine();
+ }
+};
+
+/**
+ * A test is considered slow if it
+ * exceeds the following value in milliseconds.
+ */
+
+exports.slow = 75;
+
+/**
+ * Outut the given `failures` as a list.
+ *
+ * @param {Array} failures
+ * @api public
+ */
+
+exports.list = function(failures){
+ console.error();
+ failures.forEach(function(test, i){
+ // format
+ var fmt = color('error title', ' %s) %s:\n')
+ + color('error message', ' %s')
+ + color('error stack', '\n%s\n');
+
+ // msg
+ var err = test.err
+ , message = err.message || ''
+ , stack = err.stack || message
+ , index = stack.indexOf(message) + message.length
+ , msg = stack.slice(0, index)
+ , actual = err.actual
+ , expected = err.expected;
+
+ // actual / expected diff
+ if ('string' == typeof actual && 'string' == typeof expected) {
+ var len = Math.max(actual.length, expected.length);
+
+ if (len < 20) msg = errorDiff(err, 'Chars');
+ else msg = errorDiff(err, 'Words');
+
+ // linenos
+ var lines = msg.split('\n');
+ if (lines.length > 4) {
+ var width = String(lines.length).length;
+ msg = lines.map(function(str, i){
+ return pad(++i, width) + ' |' + ' ' + str;
+ }).join('\n');
+ }
+
+ // legend
+ msg = '\n'
+ + color('diff removed', 'actual')
+ + ' '
+ + color('diff added', 'expected')
+ + '\n\n'
+ + msg
+ + '\n';
+
+ // indent
+ msg = msg.replace(/^/gm, ' ');
+
+ fmt = color('error title', ' %s) %s:\n%s')
+ + color('error stack', '\n%s\n');
+ }
+
+ // indent stack trace without msg
+ stack = stack.slice(index ? index + 1 : index)
+ .replace(/^/gm, ' ');
+
+ console.error(fmt, (i + 1), test.fullTitle(), msg, stack);
+ });
+};
+
+/**
+ * Initialize a new `Base` reporter.
+ *
+ * All other reporters generally
+ * inherit from this reporter, providing
+ * stats such as test duration, number
+ * of tests passed / failed etc.
+ *
+ * @param {Runner} runner
+ * @api public
+ */
+
+function Base(runner) {
+ var self = this
+ , stats = this.stats = { suites: 0, tests: 0, passes: 0, failures: 0 }
+ , failures = this.failures = [];
+
+ if (!runner) return;
+ this.runner = runner;
+
+ runner.on('start', function(){
+ stats.start = new Date;
+ });
+
+ runner.on('suite', function(suite){
+ stats.suites = stats.suites || 0;
+ suite.root || stats.suites++;
+ });
+
+ runner.on('test end', function(test){
+ stats.tests = stats.tests || 0;
+ stats.tests++;
+ });
+
+ runner.on('pass', function(test){
+ stats.passes = stats.passes || 0;
+
+ var medium = exports.slow / 2;
+ test.speed = test.duration > exports.slow
+ ? 'slow'
+ : test.duration > medium
+ ? 'medium'
+ : 'fast';
+
+ stats.passes++;
+ });
+
+ runner.on('fail', function(test, err){
+ stats.failures = stats.failures || 0;
+ stats.failures++;
+ test.err = err;
+ failures.push(test);
+ });
+
+ runner.on('end', function(){
+ stats.end = new Date;
+ stats.duration = new Date - stats.start;
+ });
+}
+
+/**
+ * Output common epilogue used by many of
+ * the bundled reporters.
+ *
+ * @api public
+ */
+
+Base.prototype.epilogue = function(){
+ var stats = this.stats
+ , fmt;
+
+ console.log();
+
+ // failure
+ if (stats.failures) {
+ fmt = color('bright fail', ' ✖')
+ + color('fail', ' %d of %d tests failed')
+ + color('light', ':')
+
+ console.error(fmt, stats.failures, this.runner.total);
+ Base.list(this.failures);
+ console.error();
+ return;
+ }
+
+ // pass
+ fmt = color('bright pass', ' ✔')
+ + color('green', ' %d tests complete')
+ + color('light', ' (%dms)');
+
+ console.log(fmt, stats.tests || 0, stats.duration);
+ console.log();
+};
+
+/**
+ * Pad the given `str` to `len`.
+ *
+ * @param {String} str
+ * @param {String} len
+ * @return {String}
+ * @api private
+ */
+
+function pad(str, len) {
+ str = String(str);
+ return Array(len - str.length + 1).join(' ') + str;
+}
+
+/**
+ * Return a character diff for `err`.
+ *
+ * @param {Error} err
+ * @return {String}
+ * @api private
+ */
+
+function errorDiff(err, type) {
+ return diff['diff' + type](err.actual, err.expected).map(function(str){
+ if (str.added) return colorLines('diff added', str.value);
+ if (str.removed) return colorLines('diff removed', str.value);
+ return str.value;
+ }).join('');
+}
+
+/**
+ * Color lines for `str`, using the color `name`.
+ *
+ * @param {String} name
+ * @param {String} str
+ * @return {String}
+ * @api private
+ */
+
+function colorLines(name, str) {
+ return str.split('\n').map(function(str){
+ return color(name, str);
+ }).join('\n');
+}
diff --git a/node_modules/mocha/lib/reporters/doc.js b/node_modules/mocha/lib/reporters/doc.js
new file mode 100644
index 0000000..cf7e712
--- /dev/null
+++ b/node_modules/mocha/lib/reporters/doc.js
@@ -0,0 +1,74 @@
+
+/**
+ * Module dependencies.
+ */
+
+var Base = require('./base')
+ , utils = require('../utils');
+
+/**
+ * Expose `Doc`.
+ */
+
+exports = module.exports = Doc;
+
+/**
+ * Initialize a new `Doc` reporter.
+ *
+ * @param {Runner} runner
+ * @api public
+ */
+
+function Doc(runner) {
+ Base.call(this, runner);
+
+ var self = this
+ , stats = this.stats
+ , total = runner.total
+ , indents = 2;
+
+ function indent() {
+ return Array(indents).join(' ');
+ }
+
+ runner.on('suite', function(suite){
+ if (suite.root) return;
+ ++indents;
+ console.log('%s<section class="suite">', indent());
+ ++indents;
+ console.log('%s<h1>%s</h1>', indent(), suite.title);
+ console.log('%s<dl>', indent());
+ });
+
+ runner.on('suite end', function(suite){
+ if (suite.root) return;
+ console.log('%s</dl>', indent());
+ --indents;
+ console.log('%s</section>', indent());
+ --indents;
+ });
+
+ runner.on('pass', function(test){
+ console.log('%s <dt>%s</dt>', indent(), test.title);
+ var code = utils.escape(clean(test.fn.toString()));
+ console.log('%s <dd><pre><code>%s</code></pre></dd>', indent(), code);
+ });
+}
+
+/**
+ * Strip the function definition from `str`,
+ * and re-indent for pre whitespace.
+ */
+
+function clean(str) {
+ str = str
+ .replace(/^function *\(.*\) *{/, '')
+ .replace(/\s+\}$/, '');
+
+ var spaces = str.match(/^\n?( *)/)[1].length
+ , re = new RegExp('^ {' + spaces + '}', 'gm');
+
+ str = str.replace(re, '');
+
+ return str;
+} \ No newline at end of file
diff --git a/node_modules/mocha/lib/reporters/dot.js b/node_modules/mocha/lib/reporters/dot.js
new file mode 100644
index 0000000..20158db
--- /dev/null
+++ b/node_modules/mocha/lib/reporters/dot.js
@@ -0,0 +1,62 @@
+
+/**
+ * Module dependencies.
+ */
+
+var Base = require('./base')
+ , color = Base.color;
+
+/**
+ * Expose `Dot`.
+ */
+
+exports = module.exports = Dot;
+
+/**
+ * Initialize a new `Dot` matrix test reporter.
+ *
+ * @param {Runner} runner
+ * @api public
+ */
+
+function Dot(runner) {
+ Base.call(this, runner);
+
+ var self = this
+ , stats = this.stats
+ , width = Base.window.width * .75 | 0
+ , n = 0;
+
+ runner.on('start', function(){
+ process.stdout.write('\n ');
+ });
+
+ runner.on('pending', function(test){
+ process.stdout.write(color('pending', '.'));
+ });
+
+ runner.on('pass', function(test){
+ if (++n % width == 0) process.stdout.write('\n ');
+ if ('slow' == test.speed) {
+ process.stdout.write(color('bright yellow', '.'));
+ } else {
+ process.stdout.write(color(test.speed, '.'));
+ }
+ });
+
+ runner.on('fail', function(test, err){
+ if (++n % width == 0) process.stdout.write('\n ');
+ process.stdout.write(color('fail', '.'));
+ });
+
+ runner.on('end', function(){
+ console.log();
+ self.epilogue();
+ });
+}
+
+/**
+ * Inherit from `Base.prototype`.
+ */
+
+Dot.prototype.__proto__ = Base.prototype; \ No newline at end of file
diff --git a/node_modules/mocha/lib/reporters/html-cov.js b/node_modules/mocha/lib/reporters/html-cov.js
new file mode 100644
index 0000000..6669bb0
--- /dev/null
+++ b/node_modules/mocha/lib/reporters/html-cov.js
@@ -0,0 +1,44 @@
+
+/**
+ * Module dependencies.
+ */
+
+var JSONCov = require('./json-cov')
+ , fs = require('fs');
+
+/**
+ * Expose `HTMLCov`.
+ */
+
+exports = module.exports = HTMLCov;
+
+/**
+ * Initialize a new `JsCoverage` reporter.
+ *
+ * @param {Runner} runner
+ * @api public
+ */
+
+function HTMLCov(runner) {
+ var jade = require('jade')
+ , file = __dirname + '/templates/coverage.jade'
+ , str = fs.readFileSync(file, 'utf8')
+ , fn = jade.compile(str, { filename: file })
+ , self = this;
+
+ JSONCov.call(this, runner, false);
+
+ runner.on('end', function(){
+ process.stdout.write(fn({
+ cov: self.cov
+ , coverageClass: coverageClass
+ }));
+ });
+}
+
+function coverageClass(n) {
+ if (n >= 75) return 'high';
+ if (n >= 50) return 'medium';
+ if (n >= 25) return 'low';
+ return 'terrible';
+} \ No newline at end of file
diff --git a/node_modules/mocha/lib/reporters/html.js b/node_modules/mocha/lib/reporters/html.js
new file mode 100644
index 0000000..2c3791c
--- /dev/null
+++ b/node_modules/mocha/lib/reporters/html.js
@@ -0,0 +1,211 @@
+
+/**
+ * Module dependencies.
+ */
+
+var Base = require('./base')
+ , utils = require('../utils')
+ , Progress = require('../browser/progress')
+ , escape = utils.escape;
+
+/**
+ * Expose `Doc`.
+ */
+
+exports = module.exports = HTML;
+
+/**
+ * Stats template.
+ */
+
+var statsTemplate = '<ul id="stats">'
+ + '<li class="progress"><canvas width="40" height="40"></canvas></li>'
+ + '<li class="passes">passes: <em>0</em></li>'
+ + '<li class="failures">failures: <em>0</em></li>'
+ + '<li class="duration">duration: <em>0</em>s</li>'
+ + '</ul>';
+
+/**
+ * Initialize a new `Doc` reporter.
+ *
+ * @param {Runner} runner
+ * @api public
+ */
+
+function HTML(runner) {
+ Base.call(this, runner);
+
+ var self = this
+ , stats = this.stats
+ , total = runner.total
+ , root = document.getElementById('mocha')
+ , stat = fragment(statsTemplate)
+ , items = stat.getElementsByTagName('li')
+ , passes = items[1].getElementsByTagName('em')[0]
+ , failures = items[2].getElementsByTagName('em')[0]
+ , duration = items[3].getElementsByTagName('em')[0]
+ , canvas = stat.getElementsByTagName('canvas')[0]
+ , stack = [root]
+ , progress
+ , ctx
+
+ if (canvas.getContext) {
+ ctx = canvas.getContext('2d');
+ progress = new Progress;
+ }
+
+ if (!root) return error('#mocha div missing, add it to your document');
+
+ root.appendChild(stat);
+
+ if (progress) progress.size(40);
+
+ runner.on('suite', function(suite){
+ if (suite.root) return;
+
+ // suite
+ var el = fragment('<div class="suite"><h1>%s</h1></div>', suite.title);
+
+ // container
+ stack[0].appendChild(el);
+ stack.unshift(document.createElement('div'));
+ el.appendChild(stack[0]);
+ });
+
+ runner.on('suite end', function(suite){
+ if (suite.root) return;
+ stack.shift();
+ });
+
+ runner.on('fail', function(test, err){
+ if ('hook' == test.type || err.uncaught) runner.emit('test end', test);
+ });
+
+ runner.on('test end', function(test){
+ // TODO: add to stats
+ var percent = stats.tests / total * 100 | 0;
+ if (progress) progress.update(percent).draw(ctx);
+
+ // update stats
+ var ms = new Date - stats.start;
+ text(passes, stats.passes);
+ text(failures, stats.failures);
+ text(duration, (ms / 1000).toFixed(2));
+
+ // test
+ if ('passed' == test.state) {
+ var el = fragment('<div class="test pass"><h2>%e</h2></div>', test.title);
+ } else if (test.pending) {
+ var el = fragment('<div class="test pass pending"><h2>%e</h2></div>', test.title);
+ } else {
+ var el = fragment('<div class="test fail"><h2>%e</h2></div>', test.title);
+ var str = test.err.stack || test.err.toString();
+
+ // FF / Opera do not add the message
+ if (!~str.indexOf(test.err.message)) {
+ str = test.err.message + '\n' + str;
+ }
+
+ // <=IE7 stringifies to [Object Error]. Since it can be overloaded, we
+ // check for the result of the stringifying.
+ if ('[object Error]' == str) str = test.err.message;
+
+ // Safari doesn't give you a stack. Let's at least provide a source line.
+ if (!test.err.stack && test.err.sourceURL && test.err.line !== undefined) {
+ str += "\n(" + test.err.sourceURL + ":" + test.err.line + ")";
+ }
+
+ el.appendChild(fragment('<pre class="error">%e</pre>', str));
+ }
+
+ // toggle code
+ var h2 = el.getElementsByTagName('h2')[0];
+
+ on(h2, 'click', function(){
+ pre.style.display = 'none' == pre.style.display
+ ? 'block'
+ : 'none';
+ });
+
+ // code
+ // TODO: defer
+ if (!test.pending) {
+ var pre = fragment('<pre><code>%e</code></pre>', clean(test.fn.toString()));
+ el.appendChild(pre);
+ pre.style.display = 'none';
+ }
+
+ stack[0].appendChild(el);
+ });
+}
+
+/**
+ * Display error `msg`.
+ */
+
+function error(msg) {
+ document.body.appendChild(fragment('<div id="error">%s</div>', msg));
+}
+
+/**
+ * Return a DOM fragment from `html`.
+ */
+
+function fragment(html) {
+ var args = arguments
+ , div = document.createElement('div')
+ , i = 1;
+
+ div.innerHTML = html.replace(/%([se])/g, function(_, type){
+ switch (type) {
+ case 's': return String(args[i++]);
+ case 'e': return escape(args[i++]);
+ }
+ });
+
+ return div.firstChild;
+}
+
+/**
+ * Set `el` text to `str`.
+ */
+
+function text(el, str) {
+ if (el.textContent) {
+ el.textContent = str;
+ } else {
+ el.innerText = str;
+ }
+}
+
+/**
+ * Listen on `event` with callback `fn`.
+ */
+
+function on(el, event, fn) {
+ if (el.addEventListener) {
+ el.addEventListener(event, fn, false);
+ } else {
+ el.attachEvent('on' + event, fn);
+ }
+}
+
+/**
+ * Strip the function definition from `str`,
+ * and re-indent for pre whitespace.
+ */
+
+function clean(str) {
+ str = str
+ .replace(/^function *\(.*\) *{/, '')
+ .replace(/\s+\}$/, '');
+
+ var spaces = str.match(/^\n?( *)/)[1].length
+ , re = new RegExp('^ {' + spaces + '}', 'gm');
+
+ str = str
+ .replace(re, '')
+ .replace(/^\s+/, '');
+
+ return str;
+}
diff --git a/node_modules/mocha/lib/reporters/index.js b/node_modules/mocha/lib/reporters/index.js
new file mode 100644
index 0000000..d7b5de7
--- /dev/null
+++ b/node_modules/mocha/lib/reporters/index.js
@@ -0,0 +1,17 @@
+
+exports.Base = require('./base');
+exports.Dot = require('./dot');
+exports.Doc = require('./doc');
+exports.TAP = require('./tap');
+exports.JSON = require('./json');
+exports.HTML = require('./html');
+exports.List = require('./list');
+exports.Min = require('./min');
+exports.Spec = require('./spec');
+exports.Progress = require('./progress');
+exports.Landing = require('./landing');
+exports.JSONCov = require('./json-cov');
+exports.HTMLCov = require('./html-cov');
+exports.JSONStream = require('./json-stream');
+exports.XUnit = require('./xunit')
+exports.Teamcity = require('./teamcity')
diff --git a/node_modules/mocha/lib/reporters/json-cov.js b/node_modules/mocha/lib/reporters/json-cov.js
new file mode 100644
index 0000000..7eeab30
--- /dev/null
+++ b/node_modules/mocha/lib/reporters/json-cov.js
@@ -0,0 +1,149 @@
+
+/**
+ * Module dependencies.
+ */
+
+var Base = require('./base');
+
+/**
+ * Expose `JSONCov`.
+ */
+
+exports = module.exports = JSONCov;
+
+/**
+ * Initialize a new `JsCoverage` reporter.
+ *
+ * @param {Runner} runner
+ * @param {Boolean} output
+ * @api public
+ */
+
+function JSONCov(runner, output) {
+ var self = this
+ , output = 1 == arguments.length ? true : output;
+
+ Base.call(this, runner);
+
+ var tests = []
+ , failures = []
+ , passes = [];
+
+ runner.on('test end', function(test){
+ tests.push(test);
+ });
+
+ runner.on('pass', function(test){
+ passes.push(test);
+ });
+
+ runner.on('fail', function(test){
+ failures.push(test);
+ });
+
+ runner.on('end', function(){
+ var cov = global._$jscoverage || {};
+ var result = self.cov = map(cov);
+ result.stats = self.stats;
+ result.tests = tests.map(clean);
+ result.failures = failures.map(clean);
+ result.passes = passes.map(clean);
+ if (!output) return;
+ process.stdout.write(JSON.stringify(result, null, 2 ));
+ });
+}
+
+/**
+ * Map jscoverage data to a JSON structure
+ * suitable for reporting.
+ *
+ * @param {Object} cov
+ * @return {Object}
+ * @api private
+ */
+
+function map(cov) {
+ var ret = {
+ instrumentation: 'node-jscoverage'
+ , sloc: 0
+ , hits: 0
+ , misses: 0
+ , coverage: 0
+ , files: []
+ };
+
+ for (var filename in cov) {
+ var data = coverage(filename, cov[filename]);
+ ret.files.push(data);
+ ret.hits += data.hits;
+ ret.misses += data.misses;
+ ret.sloc += data.sloc;
+ }
+
+ if (ret.sloc > 0) {
+ ret.coverage = (ret.hits / ret.sloc) * 100;
+ }
+
+ return ret;
+};
+
+/**
+ * Map jscoverage data for a single source file
+ * to a JSON structure suitable for reporting.
+ *
+ * @param {String} filename name of the source file
+ * @param {Object} data jscoverage coverage data
+ * @return {Object}
+ * @api private
+ */
+
+function coverage(filename, data) {
+ var ret = {
+ filename: filename,
+ coverage: 0,
+ hits: 0,
+ misses: 0,
+ sloc: 0,
+ source: {}
+ };
+
+ data.source.forEach(function(line, num){
+ num++;
+
+ if (data[num] === 0) {
+ ret.misses++;
+ ret.sloc++;
+ } else if (data[num] !== undefined) {
+ ret.hits++;
+ ret.sloc++;
+ }
+
+ ret.source[num] = {
+ source: line
+ , coverage: data[num] === undefined
+ ? ''
+ : data[num]
+ };
+ });
+
+ ret.coverage = ret.hits / ret.sloc * 100;
+
+ return ret;
+}
+
+/**
+ * Return a plain-object representation of `test`
+ * free of cyclic properties etc.
+ *
+ * @param {Object} test
+ * @return {Object}
+ * @api private
+ */
+
+function clean(test) {
+ return {
+ title: test.title
+ , fullTitle: test.fullTitle()
+ , duration: test.duration
+ }
+}
diff --git a/node_modules/mocha/lib/reporters/json-stream.js b/node_modules/mocha/lib/reporters/json-stream.js
new file mode 100644
index 0000000..7cb8fbe
--- /dev/null
+++ b/node_modules/mocha/lib/reporters/json-stream.js
@@ -0,0 +1,61 @@
+
+/**
+ * Module dependencies.
+ */
+
+var Base = require('./base')
+ , color = Base.color;
+
+/**
+ * Expose `List`.
+ */
+
+exports = module.exports = List;
+
+/**
+ * Initialize a new `List` test reporter.
+ *
+ * @param {Runner} runner
+ * @api public
+ */
+
+function List(runner) {
+ Base.call(this, runner);
+
+ var self = this
+ , stats = this.stats
+ , total = runner.total;
+
+ runner.on('start', function(){
+ console.log(JSON.stringify(['start', { total: total }]));
+ });
+
+ runner.on('pass', function(test){
+ console.log(JSON.stringify(['pass', clean(test)]));
+ });
+
+ runner.on('fail', function(test, err){
+ console.log(JSON.stringify(['fail', clean(test)]));
+ });
+
+ runner.on('end', function(){
+ process.stdout.write(JSON.stringify(['end', self.stats]));
+ });
+}
+
+/**
+ * Return a plain-object representation of `test`
+ * free of cyclic properties etc.
+ *
+ * @param {Object} test
+ * @return {Object}
+ * @api private
+ */
+
+function clean(test) {
+ return {
+ title: test.title
+ , fullTitle: test.fullTitle()
+ , duration: test.duration
+ }
+} \ No newline at end of file
diff --git a/node_modules/mocha/lib/reporters/json.js b/node_modules/mocha/lib/reporters/json.js
new file mode 100644
index 0000000..a699f50
--- /dev/null
+++ b/node_modules/mocha/lib/reporters/json.js
@@ -0,0 +1,70 @@
+
+/**
+ * Module dependencies.
+ */
+
+var Base = require('./base')
+ , cursor = Base.cursor
+ , color = Base.color;
+
+/**
+ * Expose `JSON`.
+ */
+
+exports = module.exports = JSONReporter;
+
+/**
+ * Initialize a new `JSON` reporter.
+ *
+ * @param {Runner} runner
+ * @api public
+ */
+
+function JSONReporter(runner) {
+ var self = this;
+ Base.call(this, runner);
+
+ var tests = []
+ , failures = []
+ , passes = [];
+
+ runner.on('test end', function(test){
+ tests.push(test);
+ });
+
+ runner.on('pass', function(test){
+ passes.push(test);
+ });
+
+ runner.on('fail', function(test){
+ failures.push(test);
+ });
+
+ runner.on('end', function(){
+ var obj = {
+ stats: self.stats
+ , tests: tests.map(clean)
+ , failures: failures.map(clean)
+ , passes: passes.map(clean)
+ };
+
+ process.stdout.write(JSON.stringify(obj, null, 2));
+ });
+}
+
+/**
+ * Return a plain-object representation of `test`
+ * free of cyclic properties etc.
+ *
+ * @param {Object} test
+ * @return {Object}
+ * @api private
+ */
+
+function clean(test) {
+ return {
+ title: test.title
+ , fullTitle: test.fullTitle()
+ , duration: test.duration
+ }
+} \ No newline at end of file
diff --git a/node_modules/mocha/lib/reporters/landing.js b/node_modules/mocha/lib/reporters/landing.js
new file mode 100644
index 0000000..8d59e50
--- /dev/null
+++ b/node_modules/mocha/lib/reporters/landing.js
@@ -0,0 +1,97 @@
+
+/**
+ * Module dependencies.
+ */
+
+var Base = require('./base')
+ , cursor = Base.cursor
+ , color = Base.color;
+
+/**
+ * Expose `Landing`.
+ */
+
+exports = module.exports = Landing;
+
+/**
+ * Airplane color.
+ */
+
+Base.colors.plane = 0;
+
+/**
+ * Airplane crash color.
+ */
+
+Base.colors['plane crash'] = 31;
+
+/**
+ * Runway color.
+ */
+
+Base.colors.runway = 90;
+
+/**
+ * Initialize a new `Landing` reporter.
+ *
+ * @param {Runner} runner
+ * @api public
+ */
+
+function Landing(runner) {
+ Base.call(this, runner);
+
+ var self = this
+ , stats = this.stats
+ , width = Base.window.width * .75 | 0
+ , total = runner.total
+ , stream = process.stdout
+ , plane = color('plane', '✈')
+ , crashed = -1
+ , n = 0;
+
+ function runway() {
+ var buf = Array(width).join('-');
+ return ' ' + color('runway', buf);
+ }
+
+ runner.on('start', function(){
+ stream.write('\n ');
+ cursor.hide();
+ });
+
+ runner.on('test end', function(test){
+ // check if the plane crashed
+ var col = -1 == crashed
+ ? width * ++n / total | 0
+ : crashed;
+
+ // show the crash
+ if ('failed' == test.state) {
+ plane = color('plane crash', '✈');
+ crashed = col;
+ }
+
+ // render landing strip
+ stream.write('\033[4F\n\n');
+ stream.write(runway());
+ stream.write('\n ');
+ stream.write(color('runway', Array(col).join('⋅')));
+ stream.write(plane)
+ stream.write(color('runway', Array(width - col).join('⋅') + '\n'));
+ stream.write(runway());
+ stream.write('\033[0m');
+ });
+
+ runner.on('end', function(){
+ cursor.show();
+ console.log();
+ self.epilogue();
+ });
+}
+
+/**
+ * Inherit from `Base.prototype`.
+ */
+
+Landing.prototype.__proto__ = Base.prototype; \ No newline at end of file
diff --git a/node_modules/mocha/lib/reporters/list.js b/node_modules/mocha/lib/reporters/list.js
new file mode 100644
index 0000000..1a88989
--- /dev/null
+++ b/node_modules/mocha/lib/reporters/list.js
@@ -0,0 +1,64 @@
+
+/**
+ * Module dependencies.
+ */
+
+var Base = require('./base')
+ , cursor = Base.cursor
+ , color = Base.color;
+
+/**
+ * Expose `List`.
+ */
+
+exports = module.exports = List;
+
+/**
+ * Initialize a new `List` test reporter.
+ *
+ * @param {Runner} runner
+ * @api public
+ */
+
+function List(runner) {
+ Base.call(this, runner);
+
+ var self = this
+ , stats = this.stats
+ , n = 0;
+
+ runner.on('start', function(){
+ console.log();
+ });
+
+ runner.on('test', function(test){
+ process.stdout.write(color('pass', ' ' + test.fullTitle() + ': '));
+ });
+
+ runner.on('pending', function(test){
+ var fmt = color('checkmark', ' -')
+ + color('pending', ' %s');
+ console.log(fmt, test.fullTitle());
+ });
+
+ runner.on('pass', function(test){
+ var fmt = color('checkmark', ' ✓')
+ + color('pass', ' %s: ')
+ + color(test.speed, '%dms');
+ cursor.CR();
+ console.log(fmt, test.fullTitle(), test.duration);
+ });
+
+ runner.on('fail', function(test, err){
+ cursor.CR();
+ console.log(color('fail', ' %d) %s'), ++n, test.fullTitle());
+ });
+
+ runner.on('end', self.epilogue.bind(self));
+}
+
+/**
+ * Inherit from `Base.prototype`.
+ */
+
+List.prototype.__proto__ = Base.prototype;
diff --git a/node_modules/mocha/lib/reporters/markdown.js b/node_modules/mocha/lib/reporters/markdown.js
new file mode 100644
index 0000000..7eeae85
--- /dev/null
+++ b/node_modules/mocha/lib/reporters/markdown.js
@@ -0,0 +1,111 @@
+
+/**
+ * Module dependencies.
+ */
+
+var Base = require('./base')
+ , utils = require('../utils');
+
+/**
+ * Expose `Markdown`.
+ */
+
+exports = module.exports = Markdown;
+
+/**
+ * Initialize a new `Markdown` reporter.
+ *
+ * @param {Runner} runner
+ * @api public
+ */
+
+function Markdown(runner) {
+ Base.call(this, runner);
+
+ var self = this
+ , stats = this.stats
+ , total = runner.total
+ , level = 0
+ , buf = '';
+
+ function title(str) {
+ return Array(level).join('#') + ' ' + str;
+ }
+
+ function indent() {
+ return Array(level).join(' ');
+ }
+
+ function mapTOC(suite, obj) {
+ var ret = obj;
+ obj = obj[suite.title] = obj[suite.title] || { suite: suite };
+ suite.suites.forEach(function(suite){
+ mapTOC(suite, obj);
+ });
+ return ret;
+ }
+
+ function stringifyTOC(obj, level) {
+ ++level;
+ var buf = '';
+ var link;
+ for (var key in obj) {
+ if ('suite' == key) continue;
+ if (key) link = ' - [' + key + '](#' + utils.slug(obj[key].suite.fullTitle()) + ')\n';
+ if (key) buf += Array(level).join(' ') + link;
+ buf += stringifyTOC(obj[key], level);
+ }
+ --level;
+ return buf;
+ }
+
+ function generateTOC(suite) {
+ var obj = mapTOC(suite, {});
+ return stringifyTOC(obj, 0);
+ }
+
+ generateTOC(runner.suite);
+
+ runner.on('suite', function(suite){
+ ++level;
+ var slug = utils.slug(suite.fullTitle());
+ buf += '<a name="' + slug + '" />' + '\n';
+ buf += title(suite.title) + '\n';
+ });
+
+ runner.on('suite end', function(suite){
+ --level;
+ });
+
+ runner.on('pass', function(test){
+ var code = clean(test.fn.toString());
+ buf += test.title + '.\n';
+ buf += '\n```js';
+ buf += code + '\n';
+ buf += '```\n\n';
+ });
+
+ runner.on('end', function(){
+ process.stdout.write('# TOC\n');
+ process.stdout.write(generateTOC(runner.suite));
+ process.stdout.write(buf);
+ });
+}
+
+/**
+ * Strip the function definition from `str`,
+ * and re-indent for pre whitespace.
+ */
+
+function clean(str) {
+ str = str
+ .replace(/^function *\(.*\) *{/, '')
+ .replace(/\s+\}$/, '');
+
+ var spaces = str.match(/^\n?( *)/)[1].length
+ , re = new RegExp('^ {' + spaces + '}', 'gm');
+
+ str = str.replace(re, '');
+
+ return str;
+} \ No newline at end of file
diff --git a/node_modules/mocha/lib/reporters/min.js b/node_modules/mocha/lib/reporters/min.js
new file mode 100644
index 0000000..9f3cea1
--- /dev/null
+++ b/node_modules/mocha/lib/reporters/min.js
@@ -0,0 +1,37 @@
+/**
+ * Module dependencies.
+ */
+
+var Base = require('./base');
+
+/**
+ * Expose `Min`.
+ */
+
+exports = module.exports = Min;
+
+/**
+ * Initialize a new `Min` minimal test reporter (best used with --watch).
+ *
+ * @param {Runner} runner
+ * @api public
+ */
+
+function Min(runner) {
+ Base.call(this, runner);
+
+ runner.on('start', function(){
+ // clear screen
+ process.stdout.write('\033[2J');
+ // set cursor position
+ process.stdout.write('\033[1;3H');
+ });
+
+ runner.on('end', this.epilogue.bind(this));
+}
+
+/**
+ * Inherit from `Base.prototype`.
+ */
+
+Min.prototype.__proto__ = Base.prototype; \ No newline at end of file
diff --git a/node_modules/mocha/lib/reporters/progress.js b/node_modules/mocha/lib/reporters/progress.js
new file mode 100644
index 0000000..311c8b7
--- /dev/null
+++ b/node_modules/mocha/lib/reporters/progress.js
@@ -0,0 +1,85 @@
+
+/**
+ * Module dependencies.
+ */
+
+var Base = require('./base')
+ , cursor = Base.cursor
+ , color = Base.color;
+
+/**
+ * Expose `Progress`.
+ */
+
+exports = module.exports = Progress;
+
+/**
+ * General progress bar color.
+ */
+
+Base.colors.progress = 90;
+
+/**
+ * Initialize a new `Progress` bar test reporter.
+ *
+ * @param {Runner} runner
+ * @param {Object} options
+ * @api public
+ */
+
+function Progress(runner, options) {
+ Base.call(this, runner);
+
+ var self = this
+ , options = options || {}
+ , stats = this.stats
+ , width = Base.window.width * .50 | 0
+ , total = runner.total
+ , complete = 0
+ , max = Math.max;
+
+ // default chars
+ options.open = options.open || '[';
+ options.complete = options.complete || '▬';
+ options.incomplete = options.incomplete || '⋅';
+ options.close = options.close || ']';
+ options.verbose = false;
+
+ // tests started
+ runner.on('start', function(){
+ console.log();
+ cursor.hide();
+ });
+
+ // tests complete
+ runner.on('test end', function(){
+ var incomplete = total - complete
+ , percent = complete++ / total
+ , n = width * percent | 0
+ , i = width - n;
+
+ cursor.CR();
+ process.stdout.write('\033[J');
+ process.stdout.write(color('progress', ' ' + options.open));
+ process.stdout.write(Array(n).join(options.complete));
+ process.stdout.write(Array(i).join(options.incomplete));
+ process.stdout.write(color('progress', options.close));
+ if (options.verbose) {
+ process.stdout.write(color('progress', ' ' + complete + ' of ' + total));
+ }
+ });
+
+ // tests are complete, output some stats
+ // and the failures if any
+ runner.on('end', function(){
+ cursor.show();
+ console.log();
+ self.epilogue();
+ });
+}
+
+/**
+ * Inherit from `Base.prototype`.
+ */
+
+Progress.prototype.__proto__ = Base.prototype;
diff --git a/node_modules/mocha/lib/reporters/spec.js b/node_modules/mocha/lib/reporters/spec.js
new file mode 100644
index 0000000..e546314
--- /dev/null
+++ b/node_modules/mocha/lib/reporters/spec.js
@@ -0,0 +1,87 @@
+
+/**
+ * Module dependencies.
+ */
+
+var Base = require('./base')
+ , cursor = Base.cursor
+ , color = Base.color;
+
+/**
+ * Expose `Spec`.
+ */
+
+exports = module.exports = Spec;
+
+/**
+ * Initialize a new `Spec` test reporter.
+ *
+ * @param {Runner} runner
+ * @api public
+ */
+
+function Spec(runner) {
+ Base.call(this, runner);
+
+ var self = this
+ , stats = this.stats
+ , indents = 0
+ , n = 0;
+
+ function indent() {
+ return Array(indents).join(' ')
+ }
+
+ runner.on('start', function(){
+ console.log();
+ });
+
+ runner.on('suite', function(suite){
+ ++indents;
+ console.log(color('suite', '%s%s'), indent(), suite.title);
+ });
+
+ runner.on('suite end', function(suite){
+ --indents;
+ if (1 == indents) console.log();
+ });
+
+ runner.on('test', function(test){
+ process.stdout.write(indent() + color('pass', ' ◦ ' + test.title + ': '));
+ });
+
+ runner.on('pending', function(test){
+ var fmt = indent() + color('pending', ' - %s');
+ console.log(fmt, test.title);
+ });
+
+ runner.on('pass', function(test){
+ if ('fast' == test.speed) {
+ var fmt = indent()
+ + color('checkmark', ' ✓')
+ + color('pass', ' %s ');
+ cursor.CR();
+ console.log(fmt, test.title);
+ } else {
+ var fmt = indent()
+ + color('checkmark', ' ✓')
+ + color('pass', ' %s ')
+ + color(test.speed, '(%dms)');
+ cursor.CR();
+ console.log(fmt, test.title, test.duration);
+ }
+ });
+
+ runner.on('fail', function(test, err){
+ cursor.CR();
+ console.log(indent() + color('fail', ' %d) %s'), ++n, test.title);
+ });
+
+ runner.on('end', self.epilogue.bind(self));
+}
+
+/**
+ * Inherit from `Base.prototype`.
+ */
+
+Spec.prototype.__proto__ = Base.prototype;
diff --git a/node_modules/mocha/lib/reporters/tap.js b/node_modules/mocha/lib/reporters/tap.js
new file mode 100644
index 0000000..e601dc9
--- /dev/null
+++ b/node_modules/mocha/lib/reporters/tap.js
@@ -0,0 +1,63 @@
+
+/**
+ * Module dependencies.
+ */
+
+var Base = require('./base')
+ , cursor = Base.cursor
+ , color = Base.color;
+
+/**
+ * Expose `TAP`.
+ */
+
+exports = module.exports = TAP;
+
+/**
+ * Initialize a new `TAP` reporter.
+ *
+ * @param {Runner} runner
+ * @api public
+ */
+
+function TAP(runner) {
+ Base.call(this, runner);
+
+ var self = this
+ , stats = this.stats
+ , total = runner.total
+ , n = 1;
+
+ runner.on('start', function(){
+ console.log('%d..%d', 1, total);
+ });
+
+ runner.on('test end', function(){
+ ++n;
+ });
+
+ runner.on('pending', function(test){
+ console.log('ok %d %s # SKIP -', n, title(test));
+ });
+
+ runner.on('pass', function(test){
+ console.log('ok %d %s', n, title(test));
+ });
+
+ runner.on('fail', function(test, err){
+ console.log('not ok %d %s', n, title(test));
+ console.log(err.stack.replace(/^/gm, ' '));
+ });
+}
+
+/**
+ * Return a TAP-safe title of `test`
+ *
+ * @param {Object} test
+ * @return {String}
+ * @api private
+ */
+
+function title(test) {
+ return test.fullTitle().replace(/#/g, '');
+}
diff --git a/node_modules/mocha/lib/reporters/teamcity.js b/node_modules/mocha/lib/reporters/teamcity.js
new file mode 100644
index 0000000..cef71c8
--- /dev/null
+++ b/node_modules/mocha/lib/reporters/teamcity.js
@@ -0,0 +1,56 @@
+
+/**
+ * Module dependencies.
+ */
+
+var Base = require('./base');
+
+/**
+ * Expose `Teamcity`.
+ */
+
+exports = module.exports = Teamcity;
+
+/**
+ * Initialize a new `Teamcity` reporter.
+ *
+ * @param {Runner} runner
+ * @api public
+ */
+
+function Teamcity(runner) {
+ Base.call(this, runner);
+ var stats = this.stats;
+
+ runner.on('start', function() {
+ console.log("##teamcity[testSuiteStarted name='mocha.suite']");
+ });
+
+ runner.on('test', function(test) {
+ console.log("##teamcity[testStarted name='%s']", escape(test.fullTitle()));
+ });
+
+ runner.on('fail', function(test, err) {
+ console.log("##teamcity[testFailed name='%s' message='%s']", escape(test.fullTitle()), escape(err.message));
+ });
+
+ runner.on('pending', function(test) {
+ console.log("##teamcity[testIgnored name='%s' message='pending']", escape(test.fullTitle()));
+ });
+
+ runner.on('test end', function(test) {
+ console.log("##teamcity[testFinished name='%s' duration='%s']", escape(test.fullTitle()), test.duration);
+ });
+
+ runner.on('end', function() {
+ console.log("##teamcity[testSuiteFinished name='mocha.suite' duration='%s']", stats.duration);
+ });
+}
+
+/**
+ * Escape the given `str`.
+ */
+
+function escape(str) {
+ return str.replace(/'/g, "|'");
+} \ No newline at end of file
diff --git a/node_modules/mocha/lib/reporters/templates/coverage.jade b/node_modules/mocha/lib/reporters/templates/coverage.jade
new file mode 100644
index 0000000..ca842ed
--- /dev/null
+++ b/node_modules/mocha/lib/reporters/templates/coverage.jade
@@ -0,0 +1,50 @@
+!!! 5
+html
+ head
+ title Coverage
+ include script.html
+ include style.html
+ body
+ #coverage
+ h1#overview Coverage
+ include menu
+
+ #stats(class=coverageClass(cov.coverage))
+ .percentage #{cov.coverage | 0}%
+ .sloc= cov.sloc
+ .hits= cov.hits
+ .misses= cov.misses
+
+ #files
+ for file in cov.files
+ .file
+ h2(id=file.filename)= file.filename
+ #stats(class=coverageClass(file.coverage))
+ .percentage #{file.coverage | 0}%
+ .sloc= file.sloc
+ .hits= file.hits
+ .misses= file.misses
+
+ table#source
+ thead
+ tr
+ th Line
+ th Hits
+ th Source
+ tbody
+ for line, number in file.source
+ if line.coverage > 0
+ tr.hit
+ td.line= number
+ td.hits= line.coverage
+ td.source= line.source
+ else if 0 === line.coverage
+ tr.miss
+ td.line= number
+ td.hits 0
+ td.source= line.source
+ else
+ tr
+ td.line= number
+ td.hits
+ td.source= line.source || ' ' \ No newline at end of file
diff --git a/node_modules/mocha/lib/reporters/templates/menu.jade b/node_modules/mocha/lib/reporters/templates/menu.jade
new file mode 100644
index 0000000..25cd1fa
--- /dev/null
+++ b/node_modules/mocha/lib/reporters/templates/menu.jade
@@ -0,0 +1,13 @@
+#menu
+ li
+ a(href='#overview') overview
+ for file in cov.files
+ li
+ span.cov(class=coverageClass(file.coverage)) #{file.coverage | 0}
+ a(href='##{file.filename}')
+ segments = file.filename.split('/')
+ basename = segments.pop()
+ if segments.length
+ span.dirname= segments.join('/') + '/'
+ span.basename= basename
+ a#logo(href='http://visionmedia.github.com/mocha/') m \ No newline at end of file
diff --git a/node_modules/mocha/lib/reporters/templates/script.html b/node_modules/mocha/lib/reporters/templates/script.html
new file mode 100644
index 0000000..7df9bcd
--- /dev/null
+++ b/node_modules/mocha/lib/reporters/templates/script.html
@@ -0,0 +1,34 @@
+<script>
+
+headings = [];
+
+onload = function(){
+ headings = document.querySelectorAll('h2');
+};
+
+onscroll = function(e){
+ var heading = find(window.scrollY);
+ if (!heading) return;
+ var links = document.querySelectorAll('#menu a')
+ , link;
+
+ for (var i = 0, len = links.length; i < len; ++i) {
+ link = links[i];
+ link.className = link.getAttribute('href') == '#' + heading.id
+ ? 'active'
+ : '';
+ }
+};
+
+function find(y) {
+ var i = headings.length
+ , heading;
+
+ while (i--) {
+ heading = headings[i];
+ if (y > heading.offsetTop) {
+ return heading;
+ }
+ }
+}
+</script> \ No newline at end of file
diff --git a/node_modules/mocha/lib/reporters/templates/style.html b/node_modules/mocha/lib/reporters/templates/style.html
new file mode 100644
index 0000000..c4dfe2a
--- /dev/null
+++ b/node_modules/mocha/lib/reporters/templates/style.html
@@ -0,0 +1,301 @@
+<style>
+
+body {
+ font: 14px/1.6 "Helvetica Neue", Helvetica, Arial, sans-serif;
+ margin: 0;
+ color: #2C2C2C;
+ border-top: 2px solid #ddd;
+}
+
+#coverage {
+ padding: 60px;
+}
+
+h1 a {
+ color: inherit;
+ font-weight: inherit;
+}
+
+h1 a:hover {
+ text-decoration: none;
+}
+
+.onload h1 {
+ opacity: 1;
+}
+
+h2 {
+ width: 80%;
+ margin-top: 80px;
+ margin-bottom: 0;
+ font-weight: 100;
+ letter-spacing: 1px;
+ border-bottom: 1px solid #eee;
+}
+
+a {
+ color: #8A6343;
+ font-weight: bold;
+ text-decoration: none;
+}
+
+a:hover {
+ text-decoration: underline;
+}
+
+ul {
+ margin-top: 20px;
+ padding: 0 15px;
+ width: 100%;
+}
+
+ul li {
+ float: left;
+ width: 40%;
+ margin-top: 5px;
+ margin-right: 60px;
+ list-style: none;
+ border-bottom: 1px solid #eee;
+ padding: 5px 0;
+ font-size: 12px;
+}
+
+ul::after {
+ content: '.';
+ height: 0;
+ display: block;
+ visibility: hidden;
+ clear: both;
+}
+
+code {
+ font: 12px monaco, monospace;
+}
+
+pre {
+ margin: 30px;
+ padding: 30px;
+ border: 1px solid #eee;
+ border-bottom-color: #ddd;
+ -webkit-border-radius: 2px;
+ -moz-border-radius: 2px;
+ -webkit-box-shadow: inset 0 0 10px #eee;
+ -moz-box-shadow: inset 0 0 10px #eee;
+ overflow-x: auto;
+}
+
+img {
+ margin: 30px;
+ padding: 1px;
+ -webkit-border-radius: 3px;
+ -moz-border-radius: 3px;
+ -webkit-box-shadow: 0 3px 10px #dedede, 0 1px 5px #888;
+ -moz-box-shadow: 0 3px 10px #dedede, 0 1px 5px #888;
+ max-width: 100%;
+}
+
+footer {
+ background: #eee;
+ width: 100%;
+ padding: 50px 0;
+ text-align: right;
+ border-top: 1px solid #ddd;
+}
+
+footer span {
+ display: block;
+ margin-right: 30px;
+ color: #888;
+ font-size: 12px;
+}
+
+#menu {
+ position: fixed;
+ font-size: 12px;
+ overflow-y: auto;
+ top: 0;
+ right: 0;
+ margin: 0;
+ height: 100%;
+ padding: 15px 0;
+ text-align: right;
+ border-left: 1px solid #eee;
+ -moz-box-shadow: 0 0 2px #888
+ , inset 5px 0 20px rgba(0,0,0,.5)
+ , inset 5px 0 3px rgba(0,0,0,.3);
+ -webkit-box-shadow: 0 0 2px #888
+ , inset 5px 0 20px rgba(0,0,0,.5)
+ , inset 5px 0 3px rgba(0,0,0,.3);
+ -webkit-font-smoothing: antialiased;
+ background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGYAAABmCAMAAAAOARRQAAABelBMVEUjJSU6OzshIyM5OjoqKy02NjgsLS01NTYjJCUzNTUgISMlJSc0NTUvMDA6PDwlJyg1NjYoKis2NjYrLS02ODkpKyw0NDYrLC04ODovLzA4Ojo0NDUtLy86OjwjIyU4OTosLS82ODgtLS8hIyQvMTEnKCooKSsrKy0qLCwkJSUnKCkrLCwpKiwwMjIxMzMqLC0tLS0pKissLC00NTYwMDIwMTQpKysoKSovMDEtLzA2OTkxMzUrKywvLy8qKyszNTY5OzsqKiw6OjswMDExNDUoKiozNDUvMDIyNDY1Njg2Njk5OTozMzU0NjY4ODkiIyUiIyQ4OTkuMDEmKCowMjQwMTErLS4qKywwMTMhIiMpKiopKy0tLjAkJScxNDQvLzExNDYyNDQmKCk5OTslJig5OjskJSYxMzQrLS8gISIwMTIoKCk1NTUlJSUnJygwMDA4ODgiIiMhISI8PDw6Ojo5OTkpKSojIyQ7OzsyMjIpKSssLCw6Ozw1NjlrfLakAAAg2UlEQVR42jR6i3ea6rYvPgANIAhVXh8WvkQlioUiFlFcBtAmoiRNdzxqu9p0J7vrdK29zuPeex77nnvO/35n1r1ndHRktI0jTOacv/l7lCBK5UqVpOha/YxmWK7BC4TQFKVXrbYsnimqxuuMVlOQ0XltWjUdCwRJ1M+tC1KudOs9q6+da2adUewG0SC0SwELfHtgDds93VEuydEbl3QMWeNoYkR7b/0x1ZRobGI3mLwzAhePqTAwhg6aogjNsGy7/jwQ4rkdqe7CWLxF8k9LfMVFyRS7VJqtkrW8Vt/bkR8FZJao16ipknbC3Yw2lM7laO6HBEOadEZ2tpf65c4v8e3u7FyU6qbiNNyCuzXZ6pawgnwgmrpTT/Q7w2EZmiIJ0dzWDI7mhQ80IfRnMu2kzA5r5r1pIFoia+/d93HRYp1GV8TbrkWoU/+jdI0Ff6yGwTjT1Hn8J+8m1rKpGiYPuNiHnMtNMIv+zpsk84MYTNW1/+DpwXLvckdOCMYowVNPREe0QlM8xRHXXFhcNDzupwsSmb5pH+0t0RP2Qk+QtI7F1Qm6JRC6ZPBtPq/dq/kH+jxtCljn9TIpW6rQIgmSVyj6lPICIw4N/taka41PFUInth0je9+jO6Kt1G4/a7V2LEgG02B0pHVuCZrgltSKMuIl5SyufUv9mYuQi+mFgzbBEtFo2g+Dh4sSTrLNu8JPh00sQydpb00tqXBvqRN7Q7kqzcnIxCGnvZt/WmJacoOEO6Dcn8Qre03pOCSQxbMOXUuDNx9SxuLz4W1I18gvjViQ67zV0rxdWL8Te/TQkuo8STS41DR48W7L6YP2uWIqiUV8rd6Gbf/rnegKZeG8TpAM6afhGze9JAOxbLjsnUXEbrZ9vLYd7MT32cPF5mKKxmjy7huaoD9n62GOxni3iIJwv0IzZAZjdZkUtolCNLVfYZNaquFjGszVVf+J0vrz4CawoKdHnOzb0NMH7CDBOybfYNJ4rfeMyFNjkFYVTzMFs87rnPGXLUOeNKRVc0LnU7/UIgelzsy3CMuth0YfvnY0wsD3vODUL3eJcKqHQpm8yM3XZQWJxO6Un9iYloyyLpOwN2obHy6W6gbpcb44XmyC+mg+itAcaprGcrwZCqMj/GmtKn0zPvpTz/Cv1dw21XwP3cRupg3H3MF/S71eTKj1YrdwKdc2Mw0fRmb2sFf8lW3aU6JbIZSEPqvXvjM7G/aApyXlXeqKfMq0g/Su3rUGJPSPrtGElgknrZM3xUXqsAP6zMCNVn5u8aJnSNpJv2uru7t2jfRziW2+GuhqfldUNbPk71olwo+46ePUo1U3WKk/e5YK07F/wGRgcpODmQnIlVeHCWBE4puBi2jq28UKpqiN1/4UOrGz59TNYrrQHtd+11sG40BGD+pXdelNqGOg4NXe8W4eacJV/NS9/2Umtym6WQqveqR9xdCMElpxnbkalM4Vf9uaEcWZaKdyibEIjWKxJZPN95niCL3GiaXyssIrHxoLkqkzLCXULN46/f2h3tQJgyip+Tk9EAjJ9aJshq7t8X45aowSKspMSvPf7r9R8yxNptIaHS5ozuEm6luPDApugyNP8OaqiQ4BjaequXA54SLC83eHIY2r+CZp4409Xqw8Aa2oI7XkCrQi+in0w5AqF/kLNrcUz+qkl/lAobY1jSnx5OJNhyXIz3qfNFlXc0TKaglNwdWkWYt9QQ1Kr6W8zue21iNrdJk+N5oCr2O9nEtWKC7IS5J/zdDEYrmnAYfg6agCy+qcgz7ZofeDc4PbUWSvkshWuAc7OjiUyLkj+RAtdlwXJcjxdpkTTHDhK8lBCi8+JtvDVL1W6elmOM++YS0LuSlaP1oUvAeiW3cFnvTr8EbTz1tsSMYdGeZe40sRWu5uAfj7q+ZoKv2FNQ0p5XY1lmlcigHZqTPpabufEVrNuNPi165w3uCVQJHyJqmSJ7ZHnguqwtCmwViIJijj04ba2JNYtB+yORf5gg1/9t9iw4vUpeqiunSAbf+IBdj/b+iG2qrHvuNP0Vd/+ThVZT/lrvHYjjgDbbyxaqgHNM2uhxa1GW3UedZYhMMwM4mQhltouK+IV4NdbIQNM+8Yv311RZk9kT4tiYR4LkyFcuPpdcjuhUuFqBAWRZa11lcZ3gEBlXywsNhrt+plISZP5DlsV9l4EgY6J3yZPTUcMrgaWAT3oI79eSbGEbcJpr6BD8kyDiVt+G0/hXosQN4NFXKlfWIfsIs0BHODVok1/IGnKFHJYIquh8Xo+2+bkQNTGgWmN/fZ0Y33LSj6lr1GyV7mWIKg7ZTRZPGuhF/zjRNcQ1UPtSYgnWQxSs0yrVhwNDcdGMNSNe2JT3WuzbAM3HykyAajS3Uphf6STKEqxLas9EnmnhA/lyj9Uj+JoY7SVgVmGLl46Rm2u98sbkap2lzAdKBG4r6LgulQOSSjQv1GWdQ0jtDUK/mAaqM1Uqjpu4k3Rvfvxv7YTxLSK+wN3E5jVIzmF23uZ7hiH/sVP49D7tvoKp4S8b1LuvRlivVB/algbhcFITYVXvDpLzpDfplR2uD5V4XJFxpjmIpLc9Y5sB2TpBRix7Bme6GZIq+06v3XzNeTcA4obQIKxrnT4C2JpOqD92dbmSX8MGazly5EsZVMvSU1f4RZwyu8iQXbVdeLlZrjuTT1jrY1uk5c7iZ7RsvhhluqAkq4JpVQAg7RJFtSu+xgJ8Pv6O1j5DkLxT8mkbfyRW5DrQmG7hiDIjCgBsADbjuof6YHLGeV6a5Q1Smx9joUXPpdaaDx97A/Wq00oJkdR7ZYuQRfS533JtxO1erduqWOYIt3wh0wpbLuCNIYkwxbswbikCUu2CDCS+Q+7rgVtfRcm+SOcdKPRlZ/rE7wNVUEE39KTS5uvUKN1PUnkloPkyzhyGQ8qkouEjJ3H/VXdqG6asSRiw3ecMlBvDDt8dDhBHXMwZ2Cajzjr7/76T+IavqPYvz6r7//E/3X3+N//h/0QozbjPgPiir69P/8X3/9F/yv8b/827/++98WItPu5/Hvwd8YPf5bp/2/lX/T/+Of/0MJ/lYTa+L/Ef+d9vN/3/2T6P/+jyTzu/evf6U7vxN7B6pJkRtAF6jUr8I+P8RsP/ptGhfqFk+pQ/DgAy6NJtRYJdXmp4gK7WLqLKJ+MaKhGjOojvL+SnIWrkpy0SLHDe4QuyNzaEA15mLMCcmE8Em+4HdOihW4/ZWuppJEmzeAwcDtv7MuLc9y2V5atvxXNe3S4DUMt5/Qy2LM9kSYKiVWBuKlfp4nxTntpuW03JbIlkiRvBXmT23g1I2OYe6IizUHPIq6zm6mbfsbteKmi/sg9J+ocQBMctGFO7iljo8TPN+z3jxw4do+ZwfqoR9dkNTKHyM305GpTkfhcHexVkPVGEbUOjuo9f0UMPHBFlGEx0SLvJvVRKTwW7PSew5oPme+E42+frJa9cGt2njS3dK5kIif2eYbhuSEQXEqMVfUjhGIuin0G0/W5ezJyJQy3SpMLai4M0JUWb5u1k9tny5bd1pPwYBpQuDCXZl62xg4CdVEAtflXHs6JKmP/pH6mOl796Lgopj0o8d5kKh00hxG3OSdEE/QBo9Hgr8JJqAeLDwJohG5j/DGh61Rc/+tf22/8kEnxHNCEjo0ElvvGfESZkqmz2BDcKV1H1buSkhkdg7p1IMGs2s17nYjpblrWuE2K9WEO/hcRp5e9oOF/QBmOaDtgil+oaU6szPrdwW65fOB0KUTsVUn7LFU7J8e6cxJIl9+FHw5MQMzuQJ+4oxMH3iW/5GK+hWuG0T+gTLs+fAjdtUd58TmIUq04EeyRCYCjkldow234aIgR5bqwrtZosZ+6YEqAmDqatJ9lWasz4IquKALPtd92hGI3Z2BdzzZue+REl1Om4DIWD+RrtUTOJLI+S0jHowXXdAxsGLSd40zYNuEUlOGhrwL6c7tcOtUOvpJCP7QBQS19H+GvZn05ewjlVLz+IGKoC9TyfQjLMBNmXCuqqtTdOSukZW48B0HqgSTCBrBnlFvF4CG2Su7yFzqmJFURK3UmTT3ru050r0ptUpMilYnBJWfl2Bv6kPlUuE1kxxpdzui9AubsR2N2boVSu81OulAwBqoSr1LZ0LLYOomyZHmjqnXlP72s8LnDouEJjtodBvdHaG1jMySYO7crWd90MpCRyCG14vb5IE7Arupw/y/RcCm/Tm3zK6zYj8PYNaGldiUfkB/LHWcmf2lVM+mwyU27a0qq2tscrQ/vzBjN26DnntIrOyGizzXK35yKQdYnUABkyN4saz3WD/viF+eCcsXnIajdWYJWaYHRstIis9CS+tqnFGmz2j5uzfr3Z4prqgK4XOT/PyftvjZqIm8lhkfxJ7Ol3CJF1piYBGAG8wtAk56Drw1YwmOpcz+NdfkSpSLplRXLXHL0Rquj6YW/gabqgK7Dgr6NwtH0B/AN7XrN+MVJ6AmXmUuqmQulrNNYPmH0RoDogydOKLo/QbfYNARSQQKISRCzRXU+q9WWJFL3LZW6u34CkeG97xC0NNGaJ0bvK6SnZS3zPskr5EtuCgjMWR5o2x5BqhKmDWJPRe7JMEOyRb5uUKlHaGVtq5ivSOaSliSXp9SQm2qk8MRJh10MAp9QQ2H5t59J8rjiwSZtoIfMGjlLPVNdYl/LBR0AO6WLGDmkLkIPRE45Y9MftdAK/yNu1Hn6tzOQTesgQ+8fSzB19wO91vCnO23vOWQdwJ63SJrYjdfKFW6W281PKs2k8iT9ai1cgJ4sa3xqdvmtxR8/+D1B8AKc2u+6JftryRhMWSQtoSBgIyyQGyxcnELuAasXN12oSriU4RMz1DD6RL0TSV+om7i1Yt+jEE/jnawM8cX/UhN4nkiv/w9eALrzNhXuQfOzFL0Fi6SjF7/4Qn8rLYBoa85cvgAnkCEBP+HPbEnquVXCZsMS/yzYw2Vru60P/+nJPYKkzZFjmbykzUoEqV836T5q3fP/L383dF82tx18/AZgZczMAgyeWYKmSZIqtHL+e+O4ZRcq9VI3g/qPeCoiK4pcgEqdbS0S/Be54sbVQOuJVPNBblIghzeasNu7h/g+Sz1IdhI5lCwq1nUb3Ji4OCIcqQZqtqJ5w7rXrg/DA9IgVmEGhDgGecEwnCTHffXcXs0V3OCEVzYDKS1vp/oX+ng+6XVU86UjA6FMO2RXOOOrqY1GgPvrAk9HV/BXtCu5RuwF8qgdGDLsBcui4E33ymdBip1X8uKyhIWT8qNRDsXz+gvO9UiEC0d8RG4Tf2x8H4slljgHtCBcxHLTWOYJm5H/fCPCzOgf9qgOUxTRZ0Pc6ha5yLuLVT9ntvIa6gacE99mCovdUumTQdRP4RPsS9129eEe2uSvvGh0bV4Y3QPPhPZMqhZWSMa5R0Hc1SGO4IVOQc0FrirlibTVfKRrYkD8kz3b+X65/QkUNaZdrdl3mCap0Hf3YcCw/LiouJYNbqz88UqeDYv93yO7vvXtgl4XCyAO4ODkY6W+83+LZU//p3/zXNGGrUKClCiOnL27iJZbNWDF02XXAOeFlB7IaADoMH1Yqr+UP9biyZDEa/iJt4MDeIz6GKTdLVBfWGVtRN4fdT2rgReX8UXwF2zOrradm4J0nyTgdPnai3RvzpZvCKDUqjOwD/QA6EDaMCLewX6QWYVnHY1sx1bd8ovYnPm1ZvPH+rE20lWjOCnZ66/xDt0QAl15FjfBcZp+i9OU0RNPQ0t3x2pSNWo8eiYudwsnuP1Hq6iH1LJCJynkYsfgJ0p3pF6SoQk2l+jqE8CPk+ziGJRSKjs+W5AO185umPdkYzlK4wl7TC9NxyyDP7ZoyYVoXiuS6SjnInlLWrwz1i8bGTKXX0AVQWkSfIlglW3zRJRJ8bg5VgE6ZEnqNu9B++0GNQvDQJvFize4ESNKBJP+8vA3LM4AX5SIBq08Mob+7QMTCZx4nwP/64+4BnlZC+8WtlP/CXw6t1PwMwkJ3jhP1FiXLhDF/3I6FGUzO2DSi9ABxKyyL9paZxSEz40ZCPQToDAJu1959k7QdbVxgB4icsu2s4zsTPJhcEDo+N1GX4zSk/wriRh8AqwL62972i9HJHd1ydaLXVzvKvOfGGw5RVcUVMiKXFH4APdkQU/dc5BX0YfKTNZYXCW9mb8bc8mufoQP6BbdQmT99ZjoYfr/go4TgQX9IDgztim7wyFeGMfbNaeqj8Dzs38pgcqwSv2hbqB3oSGKWKy+sesY7p57wAHldqE6NDudk/W7s/zjrK4rZFlFvaGxnSZdHbc1y47qDN6xkoK8O3bfr2j41dlJZ71rB4dlDqapPFa8N6xBrprUdtenUCHwxKNhw1uuTBh+9uU45k4REpQABN2bAO9DSLqoIL26gNroWgup5pUMxHUNSq4Gyz47vBPvilpo5f9OYI2ddAqTqmnxXERxQJ3UK8fHbVE9HagHi3+tqNRoNsArdmAxHA5LwtQo9ZAaNKUTljnokljo2x8scqVpEEIPc01fPCdHOCg0DeWBz8D5TVAAfx8aRH5X2ZYNI3ebKDZdeJ+oBDAxmRqJ30Eh2/DaeAy5diVNMpEDmXiPDsGTzBLXy8eVDdJoIafgx/gxMyQi454QrW56nCyeELgSuNNEmYkflF+t3CZQOVRWjKhIuCclmQSlAXT3+4JGG75B4t/5hQ+ldMP4LsAW6z3XmU6IJJwpnGVnsgUZhoY1fZlwTR8wSU7xRejf2uCx9Z5trVTRRJP9KnEb134dEieil6eCOGWgboI7xsqsqM99jfJLTePjygKlH2CVxxsse9QRzTBFjD/Kjqitr/CCTBt/SJ6nLxz7cKP9pFqBpp0lN5y+adKNsZjrPuroemZauH9aTTFD3EKHW8S55XBLFQAt1jgxTQCTwxmx/JyfsZDN1RroN3VaxpSenpIX7K+ZbL8VdlQDcI4Cbzg3QJLa9yVqNxUelu+EtxLVqeekaAvSJkO6sSVqbUajxqhKshNpvZqoeApF0k/0P0ikkwUcbdwc4A1ejN7Oo0O15kG7hTMoK3hZRBCX7YYeLW0wvcXx/18n/u37yLgzBYVBUvORGli+sfRcX/74uD6P4hq+7xu54TlWJLFzT63uwUDwuEDdOjJQqx7JV+ZjaEAPi7t0MMrR4Q8Rkf18uxD6RK0RKh0hL8YU+DeL97i4pa5ZSyAfXKwZRS/8gXcxdZXm62RBDj8U3sN8x95b5PpPs/mCBKYvpaA50pN5Ct/499AFTtwQ5vgeSh+NHrKIi4NVpwM/XzRaNfJD856lPE6M21zWPguFsH7jbLVyEDfRmt4VwrhCJ5VTYmcSPfGgO5clfN+vbaDZ7sakU5+2vZ2WCDY031NxJarVytfDDVtiafcTGO2rJ/taoL3zChN2qmjxofczTOYQPPVQPh0JVtYgdUQINcSiNEEy58UdYXX1MpWUCEBx7LbcGtAm8XWRQTVOaoV3ySri4RShhs/B/0m4jX6OAwXOvcA09bNSG4czEGv/Wey6V/jbTCNTW6awXdNTcA1GsPe1E9fZdGl7R0vyoVpIdJtfC6d32NNErrvq/R+d65VG+YOwRXppXxOCYyGNSf1K3x6VxAW/vtz4EC1SgCOSPdN62sLsoIzuDfg8GwZAbquVO8HIuFP/ToVoeUB7nnwMF35a1wK1tI6fkrqFKhQdeJpwyls0pIy8AZde3/6LUUbFaYJthyUJSU/kqDXTLQElnn0Jr4B2RVghNrmNmoEn7pXIeshPguXVsvwoTdmClq49JJU3LWhHyWTrJL9bRP6VKv3tZoA/th77p5Jw++OEENvyvWy/pNeExiDUVQaXIRGh8xySZTI36yueFaSXo1uJY0RnXYgEOoWWOJHeaVuX/bGNhHsh2yinznl/++NJcE9j6fBPRcBdq9hb8awNw8U7Bl6GM7x69EDOIIbX/npZ++amlHR9L/35mE/2Ss4gb0xCcY4VyTFLRE796vHysLAamqcyO+aFQyJIDBNslbH2/MrAvZiSEIedc/cqjmv4fbda2pXbv+F5a2szSsdkm9noiNURXt8edUhGUF6fSZWd1IJaXKFwD+49R6eCXD4Bkef7j9tRtNMVgW8BhRz/Qpy1TmeYk0doyjZoJSbePOReVHgkFsCFuQJ+Lgc4BxeAsK/cOiNDRmdNw0ctYhn/nQ498dYI5znzGLoJi1rav7Cn88rL3wLePVtDK5gl77Tki3gHEsIAQ2+IKgarj7Y8W1IQzV5V9N+0TjLqbg68WfKcOmBCOj3JkwJhVIkwDhc+JorXuZEPMEh0vvH3x7iqf+VAwXgd4diZiaJD1zHL9Snx6Wfg4IugreyhabQkcir+y5XgDtdx3Avs7lkeeCBwDvZoTUCXx5QrZkcEqWfYEiEYRs/EphmRALSNGR1Iclgdr5VFoELpzF4++f35w3/j0t5ucW3n2ch4PQCLuUXupsPRR7UA5FjSKrMtPcKAZJfagO4lGE7FH3YKMjorpK0ZxAv+i2JkJhtAMWWWFej4RhPR/cJ3DxwocCvXDi4SGZU4cu+K32XndiFWgopAl+0GApcwf1XvymJcFs39jExIBO4yUjU9MExBLQYc9H+W7+IgdESPRpciT+rKZPebVtaVq+1GYO/5xTAL3HASjNTGIgMvdjWbgc7JvdE1zIFpuC0U9ESiZyzBixzxWxj4Kwh8My34q+FK3KNLtmsA1qyrmKSNQOXCPUZd+ONelBTvFoUI/CYsqa/RhtKiyMf2CgSFqEPk59Y3uqnlZ8gFpswfSYyko23yVZYxzKGxGm49Zqxg1l8oz5Ra9XaRwHkuxepmgyhm0SoNy2KlbcEqK+9QqS9PNx9Ihm9U7gsR55SSJ1FBDNnkuWKxIZ0SDpXuOGwZdoUbOMDPHP4vBAgz2VlSEJAHZGJVbYIg7l/FO5KfIVvxC8pPPxMGcNMoevFDeStt2iqztE10n2TA4dgJH76YS9HDhKHD3iCx6ieFX84BAI3QQnngh76f5ruPQVbr5qZmck/5UjDc26lfrOvUBWy0Ogl8bCoOkMOns81TnC3cuUS9KW8+9A+fe3XYZOFUPG1u5epSSmDLw0s5s2F0W30ANeo+zJkJQz9SPZgzwYpEoktofhGVfmLOAB20boCbW1QWq/NpET/hnMecw/uSyAH4NJc3ECOU4nnkK1fj3S/i5dwb3R7k00AqQQUwt7Ie1qV0aY/VQX0J8hLPy7eBNXMHYZYDNxHZ2Qh6AuXJxq+AeRec/Q+JLhZV6hpXwQEzw7bf5v9uUf2vpq3qlhmy0IIGTkwYdCfSAFmqbdo+3XvDTDjFJde0mbeQLcn2n31xaAqJ0ixO/CLsT4I4G4DoncVTgRGNBtsCcjISWT+oeXZ4Iedw/8OsJI1aPnNKLX/60VvcZb94uasRxCkqlPQ11u1Sa2hHvB80WQENxVyzjns0/PiEByyil21Te6oisk3mNCEMrhouCFO3yEZTHHOCMy9eb/4Tmi8cVf3Lf7P53SY2hX3PSN033As3ETIMLHWumWEO9JXHA2y2SIBlIPpLGG2qvNsCIlIr+B1SWAqRKm2w6Blf7U+zCSBwJrfHG5i8J5Gax/cVonMlon7aHJX/gSvucIncRP93XCqkv7D8IFKFsLiBgHqUpXhE3pYjEcV1dk/JD9zFVCfEaQIVX8Jmfz7IIofcBKQ4OaG+C3xC2veX9CD+iAFXDNaGg9eTVxvkbJRJlW4Nk9Wk13kn696jWppRDe/8pDrYMO9ZyxZ98ReKSz9kWKLLyk2zCZgAniCkLJVX3n1M9DYbomyahWiv/KixRIV9hj/oFz87I+HLznbPTjpa+D+bZQnMuRsljTpv90vQUt/pK7jCFnA30B/jtroSF2/m/gpWn1aQs5WeA6ghzF8SdqWI20fghdSeDOCSCmLgTkfaGgGDmw7nHFkRzGtag57IHS2na06I+gzEphXo1w/Zx2BM/jKL2nZoFjHggtFQjYi8nSVRSXIE58RPbBObXk7uuIL9+rs/5Zo7suJInEUxgsiZZAWS25iBtpEiZeBgDtghEoAE0sjcayNq85M4tbu/LF5h51335PsGzQ09O875+vUS89lkWMyNOFoip2PuyWyMP/iU2XIZdfCCJNDjebDoBLQdpy7QQZC7s9c0wjHJervQNDu2jWzBW5MSAJMr7bP+Iv92BkS/GGgzjEn7MF1IRKFwwzbjbS4/slGOmhx9cZrFu7HSEefojNv3r0UaKfKOWzXsq1zEugbzlMDFsacRJJI/iJlK3vtkZ+PLZIVMFlKA32wbq2Kd5T0uCLZ1CPkAfCdzkz2EYscjDcZq2AWfziN2covN4kXE1lQXPPLTNM1xx3tbiepcO/t3SWm4w87qfh99SL0ZnY+LKFPLPeXVM2mIIoVWt+9Nk0I7nY4O79iGYqxZ8RVz289an6NVdJWnSKZvJQCAuHNiVaDxPAFoH392t9wot5t0/qmU95eEWNbU2udUW5sN9JVqcYlvAIfLeYC33oUzzxZgSktsv21mA7Uly1FA5VnoJFh6N244Wmv3YJGFv/TCPryaw+ZORlpZjQdq/2DYXr3EZskfed0G61P09ipTKmlTQ1067Rg5+PAk5FlQ9e0SWbGf2B/08kqymOTMVOznsALHHNFH4LFRKl2F/NOiYFl9khNHnSu9Ak5sq26Ynl/i2fdTle29Y1ugqmR5Yj4YT9pvslFyYCbw0mNFr5rVQm1LvkG27QMq9ph3t8fmn6r6SQ4oSbr5tz+J1kIawGzDxb6VYOvvWhobDTXfBeNv3b4aNm5XUinsCGqG2q/45m3+LoCOsddFceYhRx1Tsss9PLdPfJdErFMjYd3gddjiP0+XQjcRadZP6bwNLySvunFf20Czy6JqdEW2a96KxdYdOryBv1BjbuUq2yCHeh+6sk7fGmmPi50pe/1l5TyPe5oHW9oPnhPswLyf2TFDdCyYlhwBCstv5C1HwlW7xWoGT9XZt4qVj5WryLPLLD6h/5cMLEjWzgCeAIKNsLak92aBqBsHl4AJwl2N4jfvbSkBExGimv0nFvv09uDScQbjx+w4kPQjgjlW+g9ws9VEJvI2k8N6XxVu0uIwovgTFdunG24gBtaDi+y1YLQwZ8mwbip5fVlO3k0n0AEr/ETbtu8Vjkm+nNSiEb7X/3fMjBL5A8PdgG+/FnbexbFFExmEfetXAnisEKy5z44WVPpQZjSy/jzeGn4yDRsFGqhh87QPaDBWhlo37IFbe/C0xynS91d2tP/AJoJS0sVF6iwAAAAAElFTkSuQmCC");
+}
+
+#logo {
+ position: fixed;
+ bottom: 10px;
+ right: 10px;
+ background: rgba(255,255,255,.1);
+ font-size: 11px;
+ display: block;
+ width: 20px;
+ height: 20px;
+ line-height: 20px;
+ text-align: center;
+ -webkit-border-radius: 20px;
+ -moz-border-radius: 20px;
+ -webkit-box-shadow: 0 0 3px rgba(0,0,0,.2);
+ -moz-box-shadow: 0 0 3px rgba(0,0,0,.2);
+ color: inherit;
+}
+
+#menu li a {
+ display: block;
+ color: white;
+ padding: 0 35px 0 25px;
+ -webkit-transition: background 300ms;
+ -moz-transition: background 300ms;
+}
+
+#menu li {
+ position: relative;
+ list-style: none;
+}
+
+#menu a:hover,
+#menu a.active {
+ text-decoration: none;
+ background: rgba(255,255,255,.1);
+}
+
+#menu li:hover .cov {
+ opacity: 1;
+}
+
+#menu li .dirname {
+ opacity: .60;
+ padding-right: 2px;
+}
+
+#menu li .basename {
+ opacity: 1;
+}
+
+#menu .cov {
+ background: rgba(0,0,0,.4);
+ position: absolute;
+ top: 0;
+ right: 8px;
+ font-size: 9px;
+ opacity: .6;
+ text-align: left;
+ width: 17px;
+ -webkit-border-radius: 10px;
+ -moz-border-radius: 10px;
+ padding: 2px 3px;
+ text-align: center;
+}
+
+#stats:nth-child(2n) {
+ display: inline-block;
+ margin-top: 15px;
+ border: 1px solid #eee;
+ padding: 10px;
+ -webkit-box-shadow: inset 0 0 2px #eee;
+ -moz-box-shadow: inset 0 0 2px #eee;
+ -webkit-border-radius: 5px;
+ -moz-border-radius: 5px;
+}
+
+#stats div {
+ float: left;
+ padding: 0 5px;
+}
+
+#stats::after {
+ display: block;
+ content: '';
+ clear: both;
+}
+
+#stats .sloc::after {
+ content: ' SLOC';
+ color: #b6b6b6;
+}
+
+#stats .percentage::after {
+ content: ' coverage';
+ color: #b6b6b6;
+}
+
+#stats .hits,
+#stats .misses {
+ display: none;
+}
+
+.high {
+ color: #00d4b4;
+}
+.medium {
+ color: #e87d0d;
+}
+.low {
+ color: #d4081a;
+}
+.terrible {
+ color: #d4081a;
+ font-weight: bold;
+}
+
+table {
+ width: 80%;
+ margin-top: 10px;
+ border-collapse: collapse;
+ border: 1px solid #cbcbcb;
+ color: #363636;
+ -webkit-border-radius: 3px;
+ -moz-border-radius: 3px;
+}
+
+table thead {
+ display: none;
+}
+
+table td.line,
+table td.hits {
+ width: 20px;
+ background: #eaeaea;
+ text-align: center;
+ font-size: 11px;
+ padding: 0 10px;
+ color: #949494;
+}
+
+table td.hits {
+ width: 10px;
+ padding: 2px 5px;
+ color: rgba(0,0,0,.2);
+ background: #f0f0f0;
+}
+
+tr.miss td.line,
+tr.miss td.hits {
+ background: #e6c3c7;
+}
+
+tr.miss td {
+ background: #f8d5d8;
+}
+
+td.source {
+ padding-left: 15px;
+ line-height: 15px;
+ white-space: pre;
+ font: 12px monaco, monospace;
+}
+
+code .comment { color: #ddd }
+code .init { color: #2F6FAD }
+code .string { color: #5890AD }
+code .keyword { color: #8A6343 }
+code .number { color: #2F6FAD }
+</style> \ No newline at end of file
diff --git a/node_modules/mocha/lib/reporters/xunit.js b/node_modules/mocha/lib/reporters/xunit.js
new file mode 100644
index 0000000..63bcbd4
--- /dev/null
+++ b/node_modules/mocha/lib/reporters/xunit.js
@@ -0,0 +1,101 @@
+
+/**
+ * Module dependencies.
+ */
+
+var Base = require('./base')
+ , utils = require('../utils')
+ , escape = utils.escape;
+
+/**
+ * Expose `XUnit`.
+ */
+
+exports = module.exports = XUnit;
+
+/**
+ * Initialize a new `XUnit` reporter.
+ *
+ * @param {Runner} runner
+ * @api public
+ */
+
+function XUnit(runner) {
+ Base.call(this, runner);
+ var stats = this.stats
+ , tests = []
+ , self = this;
+
+ runner.on('test end', function(test){
+ tests.push(test);
+ });
+
+ runner.on('end', function(){
+ console.log(tag('testsuite', {
+ name: 'Mocha Tests'
+ , tests: stats.tests
+ , failures: stats.failures
+ , errors: stats.failures
+ , skip: stats.tests - stats.failures - stats.passes
+ , timestamp: (new Date).toUTCString()
+ , time: stats.duration / 1000
+ }, false));
+
+ tests.forEach(test);
+ console.log('</testsuite>');
+ });
+}
+
+/**
+ * Inherit from `Base.prototype`.
+ */
+
+XUnit.prototype.__proto__ = Base.prototype;
+
+/**
+ * Output tag for the given `test.`
+ */
+
+function test(test) {
+ var attrs = {
+ classname: test.parent.fullTitle()
+ , name: test.title
+ , time: test.duration / 1000
+ };
+
+ if ('failed' == test.state) {
+ var err = test.err;
+ attrs.message = escape(err.message);
+ console.log(tag('testcase', attrs, false, tag('failure', attrs, false, cdata(err.stack))));
+ } else if (test.pending) {
+ console.log(tag('testcase', attrs, false, tag('skipped', {}, true)));
+ } else {
+ console.log(tag('testcase', attrs, true) );
+ }
+}
+
+/**
+ * HTML tag helper.
+ */
+
+function tag(name, attrs, close, content) {
+ var end = close ? '/>' : '>'
+ , pairs = []
+ , tag;
+
+ for (var key in attrs) {
+ pairs.push(key + '="' + escape(attrs[key]) + '"');
+ }
+
+ tag = '<' + name + (pairs.length ? ' ' + pairs.join(' ') : '') + end;
+ if (content) tag += content + '</' + name + end;
+ return tag;
+}
+
+/**
+ * Return cdata escaped CDATA `str`.
+ */
+
+function cdata(str) {
+ return '<![CDATA[' + escape(str) + ']]>';
+}
diff --git a/node_modules/mocha/lib/runnable.js b/node_modules/mocha/lib/runnable.js
new file mode 100644
index 0000000..beb4691
--- /dev/null
+++ b/node_modules/mocha/lib/runnable.js
@@ -0,0 +1,164 @@
+
+/**
+ * Module dependencies.
+ */
+
+var EventEmitter = require('events').EventEmitter
+ , debug = require('debug')('runnable');
+
+/**
+ * Expose `Runnable`.
+ */
+
+module.exports = Runnable;
+
+/**
+ * Initialize a new `Runnable` with the given `title` and callback `fn`.
+ *
+ * @param {String} title
+ * @param {Function} fn
+ * @api private
+ */
+
+function Runnable(title, fn) {
+ this.title = title;
+ this.fn = fn;
+ this.async = fn && fn.length;
+ this.sync = ! this.async;
+ this._timeout = 2000;
+ this.timedOut = false;
+}
+
+/**
+ * Inherit from `EventEmitter.prototype`.
+ */
+
+Runnable.prototype.__proto__ = EventEmitter.prototype;
+
+/**
+ * Set & get timeout `ms`.
+ *
+ * @param {Number} ms
+ * @return {Runnable|Number} ms or self
+ * @api private
+ */
+
+Runnable.prototype.timeout = function(ms){
+ if (0 == arguments.length) return this._timeout;
+ debug('timeout %d', ms);
+ this._timeout = ms;
+ if (this.timer) this.resetTimeout();
+ return this;
+};
+
+/**
+ * Return the full title generated by recursively
+ * concatenating the parent's full title.
+ *
+ * @return {String}
+ * @api public
+ */
+
+Runnable.prototype.fullTitle = function(){
+ return this.parent.fullTitle() + ' ' + this.title;
+};
+
+/**
+ * Clear the timeout.
+ *
+ * @api private
+ */
+
+Runnable.prototype.clearTimeout = function(){
+ clearTimeout(this.timer);
+};
+
+/**
+ * Reset the timeout.
+ *
+ * @api private
+ */
+
+Runnable.prototype.resetTimeout = function(){
+ var self = this
+ , ms = this.timeout();
+
+ this.clearTimeout();
+ if (ms) {
+ this.timer = setTimeout(function(){
+ self.callback(new Error('timeout of ' + ms + 'ms exceeded'));
+ self.timedOut = true;
+ }, ms);
+ }
+};
+
+/**
+ * Run the test and invoke `fn(err)`.
+ *
+ * @param {Function} fn
+ * @api private
+ */
+
+Runnable.prototype.run = function(fn){
+ var self = this
+ , ms = this.timeout()
+ , start = new Date
+ , ctx = this.ctx
+ , finished
+ , emitted;
+
+ if (ctx) ctx.runnable(this);
+
+ // timeout
+ if (this.async) {
+ if (ms) {
+ this.timer = setTimeout(function(){
+ done(new Error('timeout of ' + ms + 'ms exceeded'));
+ self.timedOut = true;
+ }, ms);
+ }
+ }
+
+ // called multiple times
+ function multiple() {
+ if (emitted) return;
+ emitted = true;
+ self.emit('error', new Error('done() called multiple times'));
+ }
+
+ // finished
+ function done(err) {
+ if (self.timedOut) return;
+ if (finished) return multiple();
+ self.clearTimeout();
+ self.duration = new Date - start;
+ finished = true;
+ fn(err);
+ }
+
+ // for .resetTimeout()
+ this.callback = done;
+
+ // async
+ if (this.async) {
+ try {
+ this.fn.call(ctx, function(err){
+ if (err instanceof Error) return done(err);
+ if (null != err) return done(new Error('done() invoked with non-Error: ' + err));
+ done();
+ });
+ } catch (err) {
+ done(err);
+ }
+ return;
+ }
+
+ // sync
+ try {
+ if (!this.pending) this.fn.call(ctx);
+ this.duration = new Date - start;
+ fn();
+ } catch (err) {
+ fn(err);
+ }
+};
diff --git a/node_modules/mocha/lib/runner.js b/node_modules/mocha/lib/runner.js
new file mode 100644
index 0000000..c836d6b
--- /dev/null
+++ b/node_modules/mocha/lib/runner.js
@@ -0,0 +1,431 @@
+
+/**
+ * Module dependencies.
+ */
+
+var EventEmitter = require('events').EventEmitter
+ , debug = require('debug')('runner')
+ , Test = require('./test')
+ , utils = require('./utils')
+ , noop = function(){};
+
+/**
+ * Expose `Runner`.
+ */
+
+module.exports = Runner;
+
+/**
+ * Initialize a `Runner` for the given `suite`.
+ *
+ * Events:
+ *
+ * - `start` execution started
+ * - `end` execution complete
+ * - `suite` (suite) test suite execution started
+ * - `suite end` (suite) all tests (and sub-suites) have finished
+ * - `test` (test) test execution started
+ * - `test end` (test) test completed
+ * - `hook` (hook) hook execution started
+ * - `hook end` (hook) hook complete
+ * - `pass` (test) test passed
+ * - `fail` (test, err) test failed
+ *
+ * @api public
+ */
+
+function Runner(suite) {
+ var self = this;
+ this._globals = [];
+ this.suite = suite;
+ this.total = suite.total();
+ this.failures = 0;
+ this.on('test end', function(test){ self.checkGlobals(test); });
+ this.on('hook end', function(hook){ self.checkGlobals(hook); });
+ this.grep(/.*/);
+ this.globals(utils.keys(global).concat(['errno']));
+}
+
+/**
+ * Inherit from `EventEmitter.prototype`.
+ */
+
+Runner.prototype.__proto__ = EventEmitter.prototype;
+
+/**
+ * Run tests with full titles matching `re`.
+ *
+ * @param {RegExp} re
+ * @return {Runner} for chaining
+ * @api public
+ */
+
+Runner.prototype.grep = function(re){
+ debug('grep %s', re);
+ this._grep = re;
+ return this;
+};
+
+/**
+ * Allow the given `arr` of globals.
+ *
+ * @param {Array} arr
+ * @return {Runner} for chaining
+ * @api public
+ */
+
+Runner.prototype.globals = function(arr){
+ if (0 == arguments.length) return this._globals;
+ debug('globals %j', arr);
+ utils.forEach(arr, function(arr){
+ this._globals.push(arr);
+ }, this);
+ return this;
+};
+
+/**
+ * Check for global variable leaks.
+ *
+ * @api private
+ */
+
+Runner.prototype.checkGlobals = function(test){
+ if (this.ignoreLeaks) return;
+
+ var leaks = utils.filter(utils.keys(global), function(key){
+ return !~utils.indexOf(this._globals, key) && (!global.navigator || 'onerror' !== key);
+ }, this);
+
+ this._globals = this._globals.concat(leaks);
+
+ if (leaks.length > 1) {
+ this.fail(test, new Error('global leaks detected: ' + leaks.join(', ') + ''));
+ } else if (leaks.length) {
+ this.fail(test, new Error('global leak detected: ' + leaks[0]));
+ }
+};
+
+/**
+ * Fail the given `test`.
+ *
+ * @param {Test} test
+ * @param {Error} err
+ * @api private
+ */
+
+Runner.prototype.fail = function(test, err){
+ ++this.failures;
+ test.state = 'failed';
+ this.emit('fail', test, err);
+};
+
+/**
+ * Fail the given `hook` with `err`.
+ *
+ * Hook failures (currently) hard-end due
+ * to that fact that a failing hook will
+ * surely cause subsequent tests to fail,
+ * causing jumbled reporting.
+ *
+ * @param {Hook} hook
+ * @param {Error} err
+ * @api private
+ */
+
+Runner.prototype.failHook = function(hook, err){
+ this.fail(hook, err);
+ this.emit('end');
+};
+
+/**
+ * Run hook `name` callbacks and then invoke `fn()`.
+ *
+ * @param {String} name
+ * @param {Function} function
+ * @api private
+ */
+
+Runner.prototype.hook = function(name, fn){
+ var suite = this.suite
+ , hooks = suite['_' + name]
+ , ms = suite._timeout
+ , self = this
+ , timer;
+
+ function next(i) {
+ var hook = hooks[i];
+ if (!hook) return fn();
+ self.currentRunnable = hook;
+
+ self.emit('hook', hook);
+
+ hook.on('error', function(err){
+ self.failHook(hook, err);
+ });
+
+ hook.run(function(err){
+ hook.removeAllListeners('error');
+ if (err) return self.failHook(hook, err);
+ self.emit('hook end', hook);
+ next(++i);
+ });
+ }
+
+ process.nextTick(function(){
+ next(0);
+ });
+};
+
+/**
+ * Run hook `name` for the given array of `suites`
+ * in order, and callback `fn(err)`.
+ *
+ * @param {String} name
+ * @param {Array} suites
+ * @param {Function} fn
+ * @api private
+ */
+
+Runner.prototype.hooks = function(name, suites, fn){
+ var self = this
+ , orig = this.suite;
+
+ function next(suite) {
+ self.suite = suite;
+
+ if (!suite) {
+ self.suite = orig;
+ return fn();
+ }
+
+ self.hook(name, function(err){
+ if (err) {
+ self.suite = orig;
+ return fn(err);
+ }
+
+ next(suites.pop());
+ });
+ }
+
+ next(suites.pop());
+};
+
+/**
+ * Run hooks from the top level down.
+ *
+ * @param {String} name
+ * @param {Function} fn
+ * @api private
+ */
+
+Runner.prototype.hookUp = function(name, fn){
+ var suites = [this.suite].concat(this.parents()).reverse();
+ this.hooks(name, suites, fn);
+};
+
+/**
+ * Run hooks from the bottom up.
+ *
+ * @param {String} name
+ * @param {Function} fn
+ * @api private
+ */
+
+Runner.prototype.hookDown = function(name, fn){
+ var suites = [this.suite].concat(this.parents());
+ this.hooks(name, suites, fn);
+};
+
+/**
+ * Return an array of parent Suites from
+ * closest to furthest.
+ *
+ * @return {Array}
+ * @api private
+ */
+
+Runner.prototype.parents = function(){
+ var suite = this.suite
+ , suites = [];
+ while (suite = suite.parent) suites.push(suite);
+ return suites;
+};
+
+/**
+ * Run the current test and callback `fn(err)`.
+ *
+ * @param {Function} fn
+ * @api private
+ */
+
+Runner.prototype.runTest = function(fn){
+ var test = this.test
+ , self = this;
+
+ try {
+ test.on('error', function(err){
+ self.fail(test, err);
+ });
+ test.run(fn);
+ } catch (err) {
+ fn(err);
+ }
+};
+
+/**
+ * Run tests in the given `suite` and invoke
+ * the callback `fn()` when complete.
+ *
+ * @param {Suite} suite
+ * @param {Function} fn
+ * @api private
+ */
+
+Runner.prototype.runTests = function(suite, fn){
+ var self = this
+ , tests = suite.tests
+ , test;
+
+ function next(err) {
+ // if we bail after first err
+ if (self.failures && suite._bail) return fn();
+
+ // next test
+ test = tests.shift();
+
+ // all done
+ if (!test) return fn();
+
+ // grep
+ if (!self._grep.test(test.fullTitle())) return next();
+
+ // pending
+ if (test.pending) {
+ self.emit('pending', test);
+ self.emit('test end', test);
+ return next();
+ }
+
+ // execute test and hook(s)
+ self.emit('test', self.test = test);
+ self.hookDown('beforeEach', function(){
+ self.currentRunnable = self.test;
+ self.runTest(function(err){
+ test = self.test;
+
+ if (err) {
+ self.fail(test, err);
+ self.emit('test end', test);
+ return self.hookUp('afterEach', next);
+ }
+
+ test.state = 'passed';
+ self.emit('pass', test);
+ self.emit('test end', test);
+ self.hookUp('afterEach', next);
+ });
+ });
+ }
+
+ this.next = next;
+ next();
+};
+
+/**
+ * Run the given `suite` and invoke the
+ * callback `fn()` when complete.
+ *
+ * @param {Suite} suite
+ * @param {Function} fn
+ * @api private
+ */
+
+Runner.prototype.runSuite = function(suite, fn){
+ var self = this
+ , i = 0;
+
+ debug('run suite %s', suite.fullTitle());
+ this.emit('suite', this.suite = suite);
+
+ function next() {
+ var curr = suite.suites[i++];
+ if (!curr) return done();
+ self.runSuite(curr, next);
+ }
+
+ function done() {
+ self.suite = suite;
+ self.hook('afterAll', function(){
+ self.emit('suite end', suite);
+ fn();
+ });
+ }
+
+ this.hook('beforeAll', function(){
+ self.runTests(suite, next);
+ });
+};
+
+/**
+ * Handle uncaught exceptions.
+ *
+ * @param {Error} err
+ * @api private
+ */
+
+Runner.prototype.uncaught = function(err){
+ debug('uncaught exception');
+ var runnable = this.currentRunnable;
+ if ('failed' == runnable.state) return;
+ runnable.clearTimeout();
+ err.uncaught = true;
+ this.fail(runnable, err);
+
+ // recover from test
+ if ('test' == runnable.type) {
+ this.emit('test end', runnable);
+ this.hookUp('afterEach', this.next);
+ return;
+ }
+
+ // bail on hooks
+ this.emit('end');
+};
+
+/**
+ * Run the root suite and invoke `fn(failures)`
+ * on completion.
+ *
+ * @param {Function} fn
+ * @return {Runner} for chaining
+ * @api public
+ */
+
+Runner.prototype.run = function(fn){
+ var self = this
+ , fn = fn || function(){};
+
+ debug('start');
+
+ // callback
+ this.on('end', function(){
+ debug('end');
+ process.removeListener('uncaughtException', this.uncaught);
+ fn(self.failures);
+ });
+
+ // run suites
+ this.emit('start');
+ this.runSuite(this.suite, function(){
+ debug('finished running');
+ self.emit('end');
+ });
+
+ // uncaught exception
+ process.on('uncaughtException', function(err){
+ self.uncaught(err);
+ });
+
+ return this;
+};
diff --git a/node_modules/mocha/lib/suite.js b/node_modules/mocha/lib/suite.js
new file mode 100644
index 0000000..257b502
--- /dev/null
+++ b/node_modules/mocha/lib/suite.js
@@ -0,0 +1,247 @@
+
+/**
+ * Module dependencies.
+ */
+
+var EventEmitter = require('events').EventEmitter
+ , debug = require('debug')('suite')
+ , utils = require('./utils')
+ , Hook = require('./hook');
+
+/**
+ * Expose `Suite`.
+ */
+
+exports = module.exports = Suite;
+
+/**
+ * Create a new `Suite` with the given `title`
+ * and parent `Suite`. When a suite with the
+ * same title is already present, that suite
+ * is returned to provide nicer reporter
+ * and more flexible meta-testing.
+ *
+ * @param {Suite} parent
+ * @param {String} title
+ * @return {Suite}
+ * @api public
+ */
+
+exports.create = function(parent, title){
+ var suite = new Suite(title, parent.ctx);
+ suite.parent = parent;
+ title = suite.fullTitle();
+ parent.addSuite(suite);
+ return suite;
+};
+
+/**
+ * Initialize a new `Suite` with the given
+ * `title` and `ctx`.
+ *
+ * @param {String} title
+ * @param {Context} ctx
+ * @api private
+ */
+
+function Suite(title, ctx) {
+ this.title = title;
+ this.ctx = ctx;
+ this.suites = [];
+ this.tests = [];
+ this._beforeEach = [];
+ this._beforeAll = [];
+ this._afterEach = [];
+ this._afterAll = [];
+ this.root = !title;
+ this._timeout = 2000;
+ this._bail = false;
+}
+
+/**
+ * Inherit from `EventEmitter.prototype`.
+ */
+
+Suite.prototype.__proto__ = EventEmitter.prototype;
+
+/**
+ * Return a clone of this `Suite`.
+ *
+ * @return {Suite}
+ * @api private
+ */
+
+Suite.prototype.clone = function(){
+ var suite = new Suite(this.title);
+ debug('clone');
+ suite.ctx = this.ctx;
+ suite.timeout(this.timeout());
+ suite.bail(this.bail());
+ return suite;
+};
+
+/**
+ * Set timeout `ms` or short-hand such as "2s".
+ *
+ * @param {Number|String} ms
+ * @return {Suite|Number} for chaining
+ * @api private
+ */
+
+Suite.prototype.timeout = function(ms){
+ if (0 == arguments.length) return this._timeout;
+ if (String(ms).match(/s$/)) ms = parseFloat(ms) * 1000;
+ debug('timeout %d', ms);
+ this._timeout = parseInt(ms, 10);
+ return this;
+};
+
+/**
+ * Sets whether to bail after first error.
+ *
+ * @parma {Boolean} bail
+ * @return {Suite|Number} for chaining
+ * @api private
+ */
+
+Suite.prototype.bail = function(bail){
+ if (0 == arguments.length) return this._bail;
+ debug('bail %s', bail);
+ this._bail = bail;
+ return this;
+};
+
+/**
+ * Run `fn(test[, done])` before running tests.
+ *
+ * @param {Function} fn
+ * @return {Suite} for chaining
+ * @api private
+ */
+
+Suite.prototype.beforeAll = function(fn){
+ var hook = new Hook('"before all" hook', fn);
+ hook.parent = this;
+ hook.timeout(this.timeout());
+ hook.ctx = this.ctx;
+ this._beforeAll.push(hook);
+ this.emit('beforeAll', hook);
+ return this;
+};
+
+/**
+ * Run `fn(test[, done])` after running tests.
+ *
+ * @param {Function} fn
+ * @return {Suite} for chaining
+ * @api private
+ */
+
+Suite.prototype.afterAll = function(fn){
+ var hook = new Hook('"after all" hook', fn);
+ hook.parent = this;
+ hook.timeout(this.timeout());
+ hook.ctx = this.ctx;
+ this._afterAll.push(hook);
+ this.emit('afterAll', hook);
+ return this;
+};
+
+/**
+ * Run `fn(test[, done])` before each test case.
+ *
+ * @param {Function} fn
+ * @return {Suite} for chaining
+ * @api private
+ */
+
+Suite.prototype.beforeEach = function(fn){
+ var hook = new Hook('"before each" hook', fn);
+ hook.parent = this;
+ hook.timeout(this.timeout());
+ hook.ctx = this.ctx;
+ this._beforeEach.push(hook);
+ this.emit('beforeEach', hook);
+ return this;
+};
+
+/**
+ * Run `fn(test[, done])` after each test case.
+ *
+ * @param {Function} fn
+ * @return {Suite} for chaining
+ * @api private
+ */
+
+Suite.prototype.afterEach = function(fn){
+ var hook = new Hook('"after each" hook', fn);
+ hook.parent = this;
+ hook.timeout(this.timeout());
+ hook.ctx = this.ctx;
+ this._afterEach.push(hook);
+ this.emit('afterEach', hook);
+ return this;
+};
+
+/**
+ * Add a test `suite`.
+ *
+ * @param {Suite} suite
+ * @return {Suite} for chaining
+ * @api private
+ */
+
+Suite.prototype.addSuite = function(suite){
+ suite.parent = this;
+ suite.timeout(this.timeout());
+ suite.bail(this.bail());
+ this.suites.push(suite);
+ this.emit('suite', suite);
+ return this;
+};
+
+/**
+ * Add a `test` to this suite.
+ *
+ * @param {Test} test
+ * @return {Suite} for chaining
+ * @api private
+ */
+
+Suite.prototype.addTest = function(test){
+ test.parent = this;
+ test.timeout(this.timeout());
+ test.ctx = this.ctx;
+ this.tests.push(test);
+ this.emit('test', test);
+ return this;
+};
+
+/**
+ * Return the full title generated by recursively
+ * concatenating the parent's full title.
+ *
+ * @return {String}
+ * @api public
+ */
+
+Suite.prototype.fullTitle = function(){
+ if (this.parent) {
+ var full = this.parent.fullTitle();
+ if (full) return full + ' ' + this.title;
+ }
+ return this.title;
+};
+
+/**
+ * Return the total number of tests.
+ *
+ * @return {Number}
+ * @api public
+ */
+
+Suite.prototype.total = function(){
+ return utils.reduce(this.suites, function(sum, suite){
+ return sum + suite.total();
+ }, 0) + this.tests.length;
+};
diff --git a/node_modules/mocha/lib/test.js b/node_modules/mocha/lib/test.js
new file mode 100644
index 0000000..64a2f10
--- /dev/null
+++ b/node_modules/mocha/lib/test.js
@@ -0,0 +1,49 @@
+
+/**
+ * Module dependencies.
+ */
+
+var Runnable = require('./runnable');
+
+/**
+ * Expose `Test`.
+ */
+
+module.exports = Test;
+
+/**
+ * Initialize a new `Test` with the given `title` and callback `fn`.
+ *
+ * @param {String} title
+ * @param {Function} fn
+ * @api private
+ */
+
+function Test(title, fn) {
+ Runnable.call(this, title, fn);
+ this.pending = !fn;
+ this.type = 'test';
+}
+
+/**
+ * Inherit from `Runnable.prototype`.
+ */
+
+Test.prototype.__proto__ = Runnable.prototype;
+
+/**
+ * Inspect the context void of private properties.
+ *
+ * @return {String}
+ * @api private
+ */
+
+Test.prototype.inspect = function(){
+ return JSON.stringify(this, function(key, val){
+ return '_' == key[0]
+ ? undefined
+ : 'parent' == key
+ ? '#<Suite>'
+ : val;
+ }, 2);
+}; \ No newline at end of file
diff --git a/node_modules/mocha/lib/utils.js b/node_modules/mocha/lib/utils.js
new file mode 100644
index 0000000..22a942e
--- /dev/null
+++ b/node_modules/mocha/lib/utils.js
@@ -0,0 +1,189 @@
+
+/**
+ * Module dependencies.
+ */
+
+var fs = require('fs')
+ , path = require('path')
+ , join = path.join
+ , debug = require('debug')('watch');
+
+/**
+ * Ignored directories.
+ */
+
+var ignore = ['node_modules', '.git'];
+
+/**
+ * Escape special characters in the given string of html.
+ *
+ * @param {String} html
+ * @return {String}
+ * @api private
+ */
+
+exports.escape = function(html) {
+ return String(html)
+ .replace(/&/g, '&amp;')
+ .replace(/"/g, '&quot;')
+ .replace(/</g, '&lt;')
+ .replace(/>/g, '&gt;');
+};
+
+/**
+ * Array#forEach (<=IE8)
+ *
+ * @param {Array} array
+ * @param {Function} fn
+ * @param {Object} scope
+ * @api private
+ */
+
+exports.forEach = function(arr, fn, scope) {
+ for (var i = 0, l = arr.length; i < l; i++)
+ fn.call(scope, arr[i], i);
+};
+
+/**
+ * Array#indexOf (<=IE8)
+ *
+ * @parma {Array} arr
+ * @param {Object} obj to find index of
+ * @param {Number} start
+ * @api private
+ */
+
+exports.indexOf = function (arr, obj, start) {
+ for (var i = start || 0, l = arr.length; i < l; i++) {
+ if (arr[i] === obj)
+ return i;
+ }
+ return -1;
+};
+
+/**
+ * Array#reduce (<=IE8)
+ *
+ * @param {Array} array
+ * @param {Function} fn
+ * @param {Object} initial value
+ * @param {Object} scope
+ * @api private
+ */
+
+exports.reduce = function(arr, fn, val, scope) {
+ var rval = val;
+
+ for (var i = 0, l = arr.length; i < l; i++) {
+ rval = fn.call(scope, rval, arr[i], i, arr);
+ }
+
+ return rval;
+};
+
+/**
+ * Array#filter (<=IE8)
+ *
+ * @param {Array} array
+ * @param {Function} fn
+ * @param {Object} scope
+ * @api private
+ */
+
+exports.filter = function(arr, fn, scope) {
+ var ret = [];
+
+ for (var i = 0, l = arr.length; i < l; i++) {
+ var val = arr[i];
+ if (fn.call(scope, val, i, arr))
+ ret.push(val);
+ }
+
+ return ret;
+};
+
+/**
+ * Object.keys (<=IE8)
+ *
+ * @param {Object} obj
+ * @return {Array} keys
+ * @api private
+ */
+
+exports.keys = Object.keys || function(obj) {
+ var keys = []
+ , has = Object.prototype.hasOwnProperty // for `window` on <=IE8
+
+ for (var key in obj) {
+ if (has.call(obj, key)) {
+ keys.push(key);
+ }
+ }
+
+ return keys;
+};
+
+/**
+ * Watch the given `files` for changes
+ * and invoke `fn(file)` on modification.
+ *
+ * @param {Array} files
+ * @param {Function} fn
+ * @api private
+ */
+
+exports.watch = function(files, fn){
+ var options = { interval: 100 };
+ files.forEach(function(file){
+ debug('file %s', file);
+ fs.watchFile(file, options, function(curr, prev){
+ if (prev.mtime < curr.mtime) fn(file);
+ });
+ });
+};
+
+/**
+ * Ignored files.
+ */
+
+function ignored(path){
+ return !~ignore.indexOf(path);
+}
+
+/**
+ * Lookup files in the given `dir`.
+ *
+ * @return {Array}
+ * @api private
+ */
+
+exports.files = function(dir, ret){
+ ret = ret || [];
+
+ fs.readdirSync(dir)
+ .filter(ignored)
+ .forEach(function(path){
+ path = join(dir, path);
+ if (fs.statSync(path).isDirectory()) {
+ exports.files(path, ret);
+ } else if (path.match(/\.(js|coffee)$/)) {
+ ret.push(path);
+ }
+ });
+
+ return ret;
+};
+
+/**
+ * Compute a slug from the given `str`.
+ *
+ * @param {String} str
+ * @return {String}
+ */
+
+exports.slug = function(str){
+ return str
+ .toLowerCase()
+ .replace(/ +/g, '-')
+ .replace(/[^-\w]/g, '');
+}; \ No newline at end of file
diff --git a/node_modules/mocha/mocha.css b/node_modules/mocha/mocha.css
new file mode 100644
index 0000000..b49d91d
--- /dev/null
+++ b/node_modules/mocha/mocha.css
@@ -0,0 +1,137 @@
+
+body {
+ font: 20px/1.5 "Helvetica Neue", Helvetica, Arial, sans-serif;
+ padding: 60px 50px;
+}
+
+#mocha h1, h2 {
+ margin: 0;
+}
+
+#mocha h1 {
+ margin-top: 15px;
+ font-size: 1em;
+ font-weight: 200;
+}
+
+#mocha .suite .suite h1 {
+ margin-top: 0;
+ font-size: .8em;
+}
+
+#mocha h2 {
+ font-size: 12px;
+ font-weight: normal;
+ cursor: pointer;
+}
+
+#mocha .suite {
+ margin-left: 15px;
+}
+
+#mocha .test {
+ margin-left: 15px;
+}
+
+#mocha .test:hover h2::after {
+ position: relative;
+ top: 0;
+ right: -10px;
+ content: '(view source)';
+ font-size: 12px;
+ font-family: arial;
+ color: #888;
+}
+
+#mocha .test.pending:hover h2::after {
+ content: '(pending)';
+ font-family: arial;
+}
+
+#mocha .test.pass::before {
+ content: '✓';
+ font-size: 12px;
+ display: block;
+ float: left;
+ margin-right: 5px;
+ color: #00c41c;
+}
+
+#mocha .test.pending {
+ color: #0b97c4;
+}
+
+#mocha .test.pending::before {
+ content: '◦';
+ color: #0b97c4;
+}
+
+#mocha .test.fail {
+ color: #c00;
+}
+
+#mocha .test.fail pre {
+ color: black;
+}
+
+#mocha .test.fail::before {
+ content: '✖';
+ font-size: 12px;
+ display: block;
+ float: left;
+ margin-right: 5px;
+ color: #c00;
+}
+
+#mocha .test pre.error {
+ color: #c00;
+}
+
+#mocha .test pre {
+ display: inline-block;
+ font: 12px/1.5 monaco, monospace;
+ margin: 5px;
+ padding: 15px;
+ border: 1px solid #eee;
+ border-bottom-color: #ddd;
+ -webkit-border-radius: 3px;
+ -webkit-box-shadow: 0 1px 3px #eee;
+}
+
+#error {
+ color: #c00;
+ font-size: 1.5 em;
+ font-weight: 100;
+ letter-spacing: 1px;
+}
+
+#stats {
+ position: fixed;
+ top: 15px;
+ right: 10px;
+ font-size: 12px;
+ margin: 0;
+ color: #888;
+}
+
+#stats .progress {
+ float: right;
+ padding-top: 0;
+}
+
+#stats em {
+ color: black;
+}
+
+#stats li {
+ display: inline-block;
+ margin: 0 5px;
+ list-style: none;
+ padding-top: 11px;
+}
+
+code .comment { color: #ddd }
+code .init { color: #2F6FAD }
+code .string { color: #5890AD }
+code .keyword { color: #8A6343 }
+code .number { color: #2F6FAD }
diff --git a/node_modules/mocha/mocha.js b/node_modules/mocha/mocha.js
new file mode 100644
index 0000000..a2fe75d
--- /dev/null
+++ b/node_modules/mocha/mocha.js
@@ -0,0 +1,4067 @@
+;(function(){
+
+
+// CommonJS require()
+
+function require(p){
+ var path = require.resolve(p)
+ , mod = require.modules[path];
+ if (!mod) throw new Error('failed to require "' + p + '"');
+ if (!mod.exports) {
+ mod.exports = {};
+ mod.call(mod.exports, mod, mod.exports, require.relative(path));
+ }
+ return mod.exports;
+ }
+
+require.modules = {};
+
+require.resolve = function (path){
+ var orig = path
+ , reg = path + '.js'
+ , index = path + '/index.js';
+ return require.modules[reg] && reg
+ || require.modules[index] && index
+ || orig;
+ };
+
+require.register = function (path, fn){
+ require.modules[path] = fn;
+ };
+
+require.relative = function (parent) {
+ return function(p){
+ if ('.' != p.charAt(0)) return require(p);
+
+ var path = parent.split('/')
+ , segs = p.split('/');
+ path.pop();
+
+ for (var i = 0; i < segs.length; i++) {
+ var seg = segs[i];
+ if ('..' == seg) path.pop();
+ else if ('.' != seg) path.push(seg);
+ }
+
+ return require(path.join('/'));
+ };
+ };
+
+
+require.register("browser/debug.js", function(module, exports, require){
+
+module.exports = function(type){
+ return function(){
+
+ }
+};
+}); // module: browser/debug.js
+
+require.register("browser/diff.js", function(module, exports, require){
+
+}); // module: browser/diff.js
+
+require.register("browser/events.js", function(module, exports, require){
+
+/**
+ * Module exports.
+ */
+
+exports.EventEmitter = EventEmitter;
+
+/**
+ * Check if `obj` is an array.
+ */
+
+function isArray(obj) {
+ return '[object Array]' == {}.toString.call(obj);
+}
+
+/**
+ * Event emitter constructor.
+ *
+ * @api public.
+ */
+
+function EventEmitter(){};
+
+/**
+ * Adds a listener.
+ *
+ * @api public
+ */
+
+EventEmitter.prototype.on = function (name, fn) {
+ if (!this.$events) {
+ this.$events = {};
+ }
+
+ if (!this.$events[name]) {
+ this.$events[name] = fn;
+ } else if (isArray(this.$events[name])) {
+ this.$events[name].push(fn);
+ } else {
+ this.$events[name] = [this.$events[name], fn];
+ }
+
+ return this;
+};
+
+EventEmitter.prototype.addListener = EventEmitter.prototype.on;
+
+/**
+ * Adds a volatile listener.
+ *
+ * @api public
+ */
+
+EventEmitter.prototype.once = function (name, fn) {
+ var self = this;
+
+ function on () {
+ self.removeListener(name, on);
+ fn.apply(this, arguments);
+ };
+
+ on.listener = fn;
+ this.on(name, on);
+
+ return this;
+};
+
+/**
+ * Removes a listener.
+ *
+ * @api public
+ */
+
+EventEmitter.prototype.removeListener = function (name, fn) {
+ if (this.$events && this.$events[name]) {
+ var list = this.$events[name];
+
+ if (isArray(list)) {
+ var pos = -1;
+
+ for (var i = 0, l = list.length; i < l; i++) {
+ if (list[i] === fn || (list[i].listener && list[i].listener === fn)) {
+ pos = i;
+ break;
+ }
+ }
+
+ if (pos < 0) {
+ return this;
+ }
+
+ list.splice(pos, 1);
+
+ if (!list.length) {
+ delete this.$events[name];
+ }
+ } else if (list === fn || (list.listener && list.listener === fn)) {
+ delete this.$events[name];
+ }
+ }
+
+ return this;
+};
+
+/**
+ * Removes all listeners for an event.
+ *
+ * @api public
+ */
+
+EventEmitter.prototype.removeAllListeners = function (name) {
+ if (name === undefined) {
+ this.$events = {};
+ return this;
+ }
+
+ if (this.$events && this.$events[name]) {
+ this.$events[name] = null;
+ }
+
+ return this;
+};
+
+/**
+ * Gets all listeners for a certain event.
+ *
+ * @api publci
+ */
+
+EventEmitter.prototype.listeners = function (name) {
+ if (!this.$events) {
+ this.$events = {};
+ }
+
+ if (!this.$events[name]) {
+ this.$events[name] = [];
+ }
+
+ if (!isArray(this.$events[name])) {
+ this.$events[name] = [this.$events[name]];
+ }
+
+ return this.$events[name];
+};
+
+/**
+ * Emits an event.
+ *
+ * @api public
+ */
+
+EventEmitter.prototype.emit = function (name) {
+ if (!this.$events) {
+ return false;
+ }
+
+ var handler = this.$events[name];
+
+ if (!handler) {
+ return false;
+ }
+
+ var args = [].slice.call(arguments, 1);
+
+ if ('function' == typeof handler) {
+ handler.apply(this, args);
+ } else if (isArray(handler)) {
+ var listeners = handler.slice();
+
+ for (var i = 0, l = listeners.length; i < l; i++) {
+ listeners[i].apply(this, args);
+ }
+ } else {
+ return false;
+ }
+
+ return true;
+};
+}); // module: browser/events.js
+
+require.register("browser/fs.js", function(module, exports, require){
+
+}); // module: browser/fs.js
+
+require.register("browser/path.js", function(module, exports, require){
+
+}); // module: browser/path.js
+
+require.register("browser/progress.js", function(module, exports, require){
+
+/**
+ * Expose `Progress`.
+ */
+
+module.exports = Progress;
+
+/**
+ * Initialize a new `Progress` indicator.
+ */
+
+function Progress() {
+ this.percent = 0;
+ this.size(0);
+ this.fontSize(11);
+ this.font('helvetica, arial, sans-serif');
+}
+
+/**
+ * Set progress size to `n`.
+ *
+ * @param {Number} n
+ * @return {Progress} for chaining
+ * @api public
+ */
+
+Progress.prototype.size = function(n){
+ this._size = n;
+ return this;
+};
+
+/**
+ * Set text to `str`.
+ *
+ * @param {String} str
+ * @return {Progress} for chaining
+ * @api public
+ */
+
+Progress.prototype.text = function(str){
+ this._text = str;
+ return this;
+};
+
+/**
+ * Set font size to `n`.
+ *
+ * @param {Number} n
+ * @return {Progress} for chaining
+ * @api public
+ */
+
+Progress.prototype.fontSize = function(n){
+ this._fontSize = n;
+ return this;
+};
+
+/**
+ * Set font `family`.
+ *
+ * @param {String} family
+ * @return {Progress} for chaining
+ */
+
+Progress.prototype.font = function(family){
+ this._font = family;
+ return this;
+};
+
+/**
+ * Update percentage to `n`.
+ *
+ * @param {Number} n
+ * @return {Progress} for chaining
+ */
+
+Progress.prototype.update = function(n){
+ this.percent = n;
+ return this;
+};
+
+/**
+ * Draw on `ctx`.
+ *
+ * @param {CanvasRenderingContext2d} ctx
+ * @return {Progress} for chaining
+ */
+
+Progress.prototype.draw = function(ctx){
+ var percent = Math.min(this.percent, 100)
+ , size = this._size
+ , half = size / 2
+ , x = half
+ , y = half
+ , rad = half - 1
+ , fontSize = this._fontSize;
+
+ ctx.font = fontSize + 'px ' + this._font;
+
+ var angle = Math.PI * 2 * (percent / 100);
+ ctx.clearRect(0, 0, size, size);
+
+ // outer circle
+ ctx.strokeStyle = '#9f9f9f';
+ ctx.beginPath();
+ ctx.arc(x, y, rad, 0, angle, false);
+ ctx.stroke();
+
+ // inner circle
+ ctx.strokeStyle = '#eee';
+ ctx.beginPath();
+ ctx.arc(x, y, rad - 1, 0, angle, true);
+ ctx.stroke();
+
+ // text
+ var text = this._text || (percent | 0) + '%'
+ , w = ctx.measureText(text).width;
+
+ ctx.fillText(
+ text
+ , x - w / 2 + 1
+ , y + fontSize / 2 - 1);
+
+ return this;
+};
+
+}); // module: browser/progress.js
+
+require.register("browser/tty.js", function(module, exports, require){
+
+exports.isatty = function(){
+ return true;
+};
+
+exports.getWindowSize = function(){
+ return [window.innerHeight, window.innerWidth];
+};
+}); // module: browser/tty.js
+
+require.register("context.js", function(module, exports, require){
+
+/**
+ * Expose `Context`.
+ */
+
+module.exports = Context;
+
+/**
+ * Initialize a new `Context`.
+ *
+ * @api private
+ */
+
+function Context(){}
+
+/**
+ * Set the context `Runnable` to `runnable`.
+ *
+ * @param {Runnable} runnable
+ * @return {Context}
+ * @api private
+ */
+
+Context.prototype.runnable = function(runnable){
+ this._runnable = runnable;
+ return this;
+};
+
+/**
+ * Set test timeout `ms`.
+ *
+ * @param {Number} ms
+ * @return {Context} self
+ * @api private
+ */
+
+Context.prototype.timeout = function(ms){
+ this._runnable.timeout(ms);
+ return this;
+};
+
+/**
+ * Inspect the context void of `._runnable`.
+ *
+ * @return {String}
+ * @api private
+ */
+
+Context.prototype.inspect = function(){
+ return JSON.stringify(this, function(key, val){
+ return '_runnable' == key
+ ? undefined
+ : val;
+ }, 2);
+};
+
+}); // module: context.js
+
+require.register("hook.js", function(module, exports, require){
+
+/**
+ * Module dependencies.
+ */
+
+var Runnable = require('./runnable');
+
+/**
+ * Expose `Hook`.
+ */
+
+module.exports = Hook;
+
+/**
+ * Initialize a new `Hook` with the given `title` and callback `fn`.
+ *
+ * @param {String} title
+ * @param {Function} fn
+ * @api private
+ */
+
+function Hook(title, fn) {
+ Runnable.call(this, title, fn);
+ this.type = 'hook';
+}
+
+/**
+ * Inherit from `Runnable.prototype`.
+ */
+
+Hook.prototype = new Runnable;
+Hook.prototype.constructor = Hook;
+
+
+}); // module: hook.js
+
+require.register("interfaces/bdd.js", function(module, exports, require){
+
+/**
+ * Module dependencies.
+ */
+
+var Suite = require('../suite')
+ , Test = require('../test');
+
+/**
+ * BDD-style interface:
+ *
+ * describe('Array', function(){
+ * describe('#indexOf()', function(){
+ * it('should return -1 when not present', function(){
+ *
+ * });
+ *
+ * it('should return the index when present', function(){
+ *
+ * });
+ * });
+ * });
+ *
+ */
+
+module.exports = function(suite){
+ var suites = [suite];
+
+ suite.on('pre-require', function(context){
+
+ // noop variants
+
+ context.xdescribe = function(){};
+ context.xit = function(){};
+
+ /**
+ * Execute before running tests.
+ */
+
+ context.before = function(fn){
+ suites[0].beforeAll(fn);
+ };
+
+ /**
+ * Execute after running tests.
+ */
+
+ context.after = function(fn){
+ suites[0].afterAll(fn);
+ };
+
+ /**
+ * Execute before each test case.
+ */
+
+ context.beforeEach = function(fn){
+ suites[0].beforeEach(fn);
+ };
+
+ /**
+ * Execute after each test case.
+ */
+
+ context.afterEach = function(fn){
+ suites[0].afterEach(fn);
+ };
+
+ /**
+ * Describe a "suite" with the given `title`
+ * and callback `fn` containing nested suites
+ * and/or tests.
+ */
+
+ context.describe = function(title, fn){
+ var suite = Suite.create(suites[0], title);
+ suites.unshift(suite);
+ fn();
+ suites.shift();
+ };
+
+ /**
+ * Describe a specification or test-case
+ * with the given `title` and callback `fn`
+ * acting as a thunk.
+ */
+
+ context.it = function(title, fn){
+ suites[0].addTest(new Test(title, fn));
+ };
+ });
+};
+
+}); // module: interfaces/bdd.js
+
+require.register("interfaces/exports.js", function(module, exports, require){
+
+/**
+ * Module dependencies.
+ */
+
+var Suite = require('../suite')
+ , Test = require('../test');
+
+/**
+ * TDD-style interface:
+ *
+ * exports.Array = {
+ * '#indexOf()': {
+ * 'should return -1 when the value is not present': function(){
+ *
+ * },
+ *
+ * 'should return the correct index when the value is present': function(){
+ *
+ * }
+ * }
+ * };
+ *
+ */
+
+module.exports = function(suite){
+ var suites = [suite];
+
+ suite.on('require', visit);
+
+ function visit(obj) {
+ var suite;
+ for (var key in obj) {
+ if ('function' == typeof obj[key]) {
+ var fn = obj[key];
+ switch (key) {
+ case 'before':
+ suites[0].beforeAll(fn);
+ break;
+ case 'after':
+ suites[0].afterAll(fn);
+ break;
+ case 'beforeEach':
+ suites[0].beforeEach(fn);
+ break;
+ case 'afterEach':
+ suites[0].afterEach(fn);
+ break;
+ default:
+ suites[0].addTest(new Test(key, fn));
+ }
+ } else {
+ var suite = Suite.create(suites[0], key);
+ suites.unshift(suite);
+ visit(obj[key]);
+ suites.shift();
+ }
+ }
+ }
+};
+}); // module: interfaces/exports.js
+
+require.register("interfaces/index.js", function(module, exports, require){
+
+exports.bdd = require('./bdd');
+exports.tdd = require('./tdd');
+exports.qunit = require('./qunit');
+exports.exports = require('./exports');
+
+}); // module: interfaces/index.js
+
+require.register("interfaces/qunit.js", function(module, exports, require){
+
+/**
+ * Module dependencies.
+ */
+
+var Suite = require('../suite')
+ , Test = require('../test');
+
+/**
+ * QUnit-style interface:
+ *
+ * suite('Array');
+ *
+ * test('#length', function(){
+ * var arr = [1,2,3];
+ * ok(arr.length == 3);
+ * });
+ *
+ * test('#indexOf()', function(){
+ * var arr = [1,2,3];
+ * ok(arr.indexOf(1) == 0);
+ * ok(arr.indexOf(2) == 1);
+ * ok(arr.indexOf(3) == 2);
+ * });
+ *
+ * suite('String');
+ *
+ * test('#length', function(){
+ * ok('foo'.length == 3);
+ * });
+ *
+ */
+
+module.exports = function(suite){
+ var suites = [suite];
+
+ suite.on('pre-require', function(context){
+
+ /**
+ * Execute before running tests.
+ */
+
+ context.before = function(fn){
+ suites[0].beforeAll(fn);
+ };
+
+ /**
+ * Execute after running tests.
+ */
+
+ context.after = function(fn){
+ suites[0].afterAll(fn);
+ };
+
+ /**
+ * Execute before each test case.
+ */
+
+ context.beforeEach = function(fn){
+ suites[0].beforeEach(fn);
+ };
+
+ /**
+ * Execute after each test case.
+ */
+
+ context.afterEach = function(fn){
+ suites[0].afterEach(fn);
+ };
+
+ /**
+ * Describe a "suite" with the given `title`.
+ */
+
+ context.suite = function(title){
+ if (suites.length > 1) suites.shift();
+ var suite = Suite.create(suites[0], title);
+ suites.unshift(suite);
+ };
+
+ /**
+ * Describe a specification or test-case
+ * with the given `title` and callback `fn`
+ * acting as a thunk.
+ */
+
+ context.test = function(title, fn){
+ suites[0].addTest(new Test(title, fn));
+ };
+ });
+};
+
+}); // module: interfaces/qunit.js
+
+require.register("interfaces/tdd.js", function(module, exports, require){
+
+/**
+ * Module dependencies.
+ */
+
+var Suite = require('../suite')
+ , Test = require('../test');
+
+/**
+ * TDD-style interface:
+ *
+ * suite('Array', function(){
+ * suite('#indexOf()', function(){
+ * suiteSetup(function(){
+ *
+ * });
+ *
+ * test('should return -1 when not present', function(){
+ *
+ * });
+ *
+ * test('should return the index when present', function(){
+ *
+ * });
+ *
+ * suiteTeardown(function(){
+ *
+ * });
+ * });
+ * });
+ *
+ */
+
+module.exports = function(suite){
+ var suites = [suite];
+
+ suite.on('pre-require', function(context){
+
+ /**
+ * Execute before each test case.
+ */
+
+ context.setup = function(fn){
+ suites[0].beforeEach(fn);
+ };
+
+ /**
+ * Execute after each test case.
+ */
+
+ context.teardown = function(fn){
+ suites[0].afterEach(fn);
+ };
+
+ /**
+ * Execute before the suite.
+ */
+
+ context.suiteSetup = function(fn){
+ suites[0].beforeAll(fn);
+ };
+
+ /**
+ * Execute after the suite.
+ */
+
+ context.suiteTeardown = function(fn){
+ suites[0].afterAll(fn);
+ };
+
+ /**
+ * Describe a "suite" with the given `title`
+ * and callback `fn` containing nested suites
+ * and/or tests.
+ */
+
+ context.suite = function(title, fn){
+ var suite = Suite.create(suites[0], title);
+ suites.unshift(suite);
+ fn();
+ suites.shift();
+ };
+
+ /**
+ * Describe a specification or test-case
+ * with the given `title` and callback `fn`
+ * acting as a thunk.
+ */
+
+ context.test = function(title, fn){
+ suites[0].addTest(new Test(title, fn));
+ };
+ });
+};
+
+}); // module: interfaces/tdd.js
+
+require.register("mocha.js", function(module, exports, require){
+
+/*!
+ * mocha
+ * Copyright(c) 2011 TJ Holowaychuk <tj@vision-media.ca>
+ * MIT Licensed
+ */
+
+/**
+ * Module dependencies.
+ */
+
+var path = require('browser/path');
+
+/**
+ * Expose `Mocha`.
+ */
+
+exports = module.exports = Mocha;
+
+/**
+ * Library version.
+ */
+
+exports.version = '1.0.1';
+
+/**
+ * Expose internals.
+ */
+
+exports.utils = require('./utils');
+exports.interfaces = require('./interfaces');
+exports.reporters = require('./reporters');
+exports.Runnable = require('./runnable');
+exports.Context = require('./context');
+exports.Runner = require('./runner');
+exports.Suite = require('./suite');
+exports.Hook = require('./hook');
+exports.Test = require('./test');
+
+/**
+ * Return image `name` path.
+ *
+ * @param {String} name
+ * @return {String}
+ * @api private
+ */
+
+function image(name) {
+ return __dirname + '/../images/' + name + '.png';
+}
+
+/**
+ * Setup mocha with `options`.
+ *
+ * Options:
+ *
+ * - `ui` name "bdd", "tdd", "exports" etc
+ * - `reporter` reporter instance, defaults to `mocha.reporters.Dot`
+ * - `globals` array of accepted globals
+ * - `timeout` timeout in milliseconds
+ * - `ignoreLeaks` ignore global leaks
+ *
+ * @param {Object} options
+ * @api public
+ */
+
+function Mocha(options) {
+ options = options || {};
+ this.files = [];
+ this.options = options;
+ this.suite = new exports.Suite('', new exports.Context);
+ this.ui(options.ui);
+ this.reporter(options.reporter);
+ if (options.timeout) this.suite.timeout(options.timeout);
+}
+
+/**
+ * Add test `file`.
+ *
+ * @param {String} file
+ * @api public
+ */
+
+Mocha.prototype.addFile = function(file){
+ this.files.push(file);
+ return this;
+};
+
+/**
+ * Set reporter to `name`, defaults to "dot".
+ *
+ * @param {String} name
+ * @api public
+ */
+
+Mocha.prototype.reporter = function(name){
+ name = name || 'dot';
+ this._reporter = require('./reporters/' + name);
+ if (!this._reporter) throw new Error('invalid reporter "' + name + '"');
+ return this;
+};
+
+/**
+ * Set test UI `name`, defaults to "bdd".
+ *
+ * @param {String} bdd
+ * @api public
+ */
+
+Mocha.prototype.ui = function(name){
+ name = name || 'bdd';
+ this._ui = exports.interfaces[name];
+ if (!this._ui) throw new Error('invalid interface "' + name + '"');
+ this._ui = this._ui(this.suite);
+ return this;
+};
+
+/**
+ * Load registered files.
+ *
+ * @api private
+ */
+
+Mocha.prototype.loadFiles = function(){
+ var suite = this.suite;
+ this.files.forEach(function(file){
+ file = path.resolve(file);
+ suite.emit('pre-require', global, file);
+ suite.emit('require', require(file), file);
+ suite.emit('post-require', global, file);
+ });
+};
+
+/**
+ * Enable growl support.
+ *
+ * @api private
+ */
+
+Mocha.prototype.growl = function(runner, reporter) {
+ var notify = require('growl');
+
+ runner.on('end', function(){
+ var stats = reporter.stats;
+ if (stats.failures) {
+ var msg = stats.failures + ' of ' + runner.total + ' tests failed';
+ notify(msg, { title: 'Failed', image: image('fail') });
+ } else {
+ notify(stats.passes + ' tests passed in ' + stats.duration + 'ms', {
+ title: 'Passed'
+ , image: image('pass')
+ });
+ }
+ });
+};
+
+/**
+ * Run tests and invoke `fn()` when complete.
+ *
+ * @param {Function} fn
+ * @return {Runner}
+ * @api public
+ */
+
+Mocha.prototype.run = function(fn){
+ this.loadFiles();
+ var suite = this.suite;
+ var options = this.options;
+ var runner = new exports.Runner(suite);
+ var reporter = new this._reporter(runner);
+ runner.ignoreLeaks = options.ignoreLeaks;
+ if (options.grep) runner.grep(options.grep);
+ if (options.globals) runner.globals(options.globals);
+ if (options.growl) this.growl(runner, reporter);
+ return runner.run(fn);
+};
+
+}); // module: mocha.js
+
+require.register("reporters/base.js", function(module, exports, require){
+
+/**
+ * Module dependencies.
+ */
+
+var tty = require('browser/tty')
+ , diff = require('browser/diff');
+
+/**
+ * Check if both stdio streams are associated with a tty.
+ */
+
+var isatty = tty.isatty(1) && tty.isatty(2);
+
+/**
+ * Expose `Base`.
+ */
+
+exports = module.exports = Base;
+
+/**
+ * Enable coloring by default.
+ */
+
+exports.useColors = isatty;
+
+/**
+ * Default color map.
+ */
+
+exports.colors = {
+ 'pass': 90
+ , 'fail': 31
+ , 'bright pass': 92
+ , 'bright fail': 91
+ , 'bright yellow': 93
+ , 'pending': 36
+ , 'suite': 0
+ , 'error title': 0
+ , 'error message': 31
+ , 'error stack': 90
+ , 'checkmark': 32
+ , 'fast': 90
+ , 'medium': 33
+ , 'slow': 31
+ , 'green': 32
+ , 'light': 90
+ , 'diff gutter': 90
+ , 'diff added': 42
+ , 'diff removed': 41
+};
+
+/**
+ * Color `str` with the given `type`,
+ * allowing colors to be disabled,
+ * as well as user-defined color
+ * schemes.
+ *
+ * @param {String} type
+ * @param {String} str
+ * @return {String}
+ * @api private
+ */
+
+var color = exports.color = function(type, str) {
+ if (!exports.useColors) return str;
+ return '\033[' + exports.colors[type] + 'm' + str + '\033[0m';
+};
+
+/**
+ * Expose term window size, with some
+ * defaults for when stderr is not a tty.
+ */
+
+exports.window = {
+ width: isatty
+ ? process.stdout.getWindowSize
+ ? process.stdout.getWindowSize(1)[0]
+ : tty.getWindowSize()[1]
+ : 75
+};
+
+/**
+ * Expose some basic cursor interactions
+ * that are common among reporters.
+ */
+
+exports.cursor = {
+ hide: function(){
+ process.stdout.write('\033[?25l');
+ },
+
+ show: function(){
+ process.stdout.write('\033[?25h');
+ },
+
+ deleteLine: function(){
+ process.stdout.write('\033[2K');
+ },
+
+ beginningOfLine: function(){
+ process.stdout.write('\033[0G');
+ },
+
+ CR: function(){
+ exports.cursor.deleteLine();
+ exports.cursor.beginningOfLine();
+ }
+};
+
+/**
+ * A test is considered slow if it
+ * exceeds the following value in milliseconds.
+ */
+
+exports.slow = 75;
+
+/**
+ * Outut the given `failures` as a list.
+ *
+ * @param {Array} failures
+ * @api public
+ */
+
+exports.list = function(failures){
+ console.error();
+ failures.forEach(function(test, i){
+ // format
+ var fmt = color('error title', ' %s) %s:\n')
+ + color('error message', ' %s')
+ + color('error stack', '\n%s\n');
+
+ // msg
+ var err = test.err
+ , message = err.message || ''
+ , stack = err.stack || message
+ , index = stack.indexOf(message) + message.length
+ , msg = stack.slice(0, index)
+ , actual = err.actual
+ , expected = err.expected;
+
+ // actual / expected diff
+ if ('string' == typeof actual && 'string' == typeof expected) {
+ var len = Math.max(actual.length, expected.length);
+
+ if (len < 20) msg = errorDiff(err, 'Chars');
+ else msg = errorDiff(err, 'Words');
+
+ // linenos
+ var lines = msg.split('\n');
+ if (lines.length > 4) {
+ var width = String(lines.length).length;
+ msg = lines.map(function(str, i){
+ return pad(++i, width) + ' |' + ' ' + str;
+ }).join('\n');
+ }
+
+ // legend
+ msg = '\n'
+ + color('diff removed', 'actual')
+ + ' '
+ + color('diff added', 'expected')
+ + '\n\n'
+ + msg
+ + '\n';
+
+ // indent
+ msg = msg.replace(/^/gm, ' ');
+
+ fmt = color('error title', ' %s) %s:\n%s')
+ + color('error stack', '\n%s\n');
+ }
+
+ // indent stack trace without msg
+ stack = stack.slice(index ? index + 1 : index)
+ .replace(/^/gm, ' ');
+
+ console.error(fmt, (i + 1), test.fullTitle(), msg, stack);
+ });
+};
+
+/**
+ * Initialize a new `Base` reporter.
+ *
+ * All other reporters generally
+ * inherit from this reporter, providing
+ * stats such as test duration, number
+ * of tests passed / failed etc.
+ *
+ * @param {Runner} runner
+ * @api public
+ */
+
+function Base(runner) {
+ var self = this
+ , stats = this.stats = { suites: 0, tests: 0, passes: 0, failures: 0 }
+ , failures = this.failures = [];
+
+ if (!runner) return;
+ this.runner = runner;
+
+ runner.on('start', function(){
+ stats.start = new Date;
+ });
+
+ runner.on('suite', function(suite){
+ stats.suites = stats.suites || 0;
+ suite.root || stats.suites++;
+ });
+
+ runner.on('test end', function(test){
+ stats.tests = stats.tests || 0;
+ stats.tests++;
+ });
+
+ runner.on('pass', function(test){
+ stats.passes = stats.passes || 0;
+
+ var medium = exports.slow / 2;
+ test.speed = test.duration > exports.slow
+ ? 'slow'
+ : test.duration > medium
+ ? 'medium'
+ : 'fast';
+
+ stats.passes++;
+ });
+
+ runner.on('fail', function(test, err){
+ stats.failures = stats.failures || 0;
+ stats.failures++;
+ test.err = err;
+ failures.push(test);
+ });
+
+ runner.on('end', function(){
+ stats.end = new Date;
+ stats.duration = new Date - stats.start;
+ });
+}
+
+/**
+ * Output common epilogue used by many of
+ * the bundled reporters.
+ *
+ * @api public
+ */
+
+Base.prototype.epilogue = function(){
+ var stats = this.stats
+ , fmt;
+
+ console.log();
+
+ // failure
+ if (stats.failures) {
+ fmt = color('bright fail', ' ✖')
+ + color('fail', ' %d of %d tests failed')
+ + color('light', ':')
+
+ console.error(fmt, stats.failures, this.runner.total);
+ Base.list(this.failures);
+ console.error();
+ return;
+ }
+
+ // pass
+ fmt = color('bright pass', ' ✔')
+ + color('green', ' %d tests complete')
+ + color('light', ' (%dms)');
+
+ console.log(fmt, stats.tests || 0, stats.duration);
+ console.log();
+};
+
+/**
+ * Pad the given `str` to `len`.
+ *
+ * @param {String} str
+ * @param {String} len
+ * @return {String}
+ * @api private
+ */
+
+function pad(str, len) {
+ str = String(str);
+ return Array(len - str.length + 1).join(' ') + str;
+}
+
+/**
+ * Return a character diff for `err`.
+ *
+ * @param {Error} err
+ * @return {String}
+ * @api private
+ */
+
+function errorDiff(err, type) {
+ return diff['diff' + type](err.actual, err.expected).map(function(str){
+ if (str.added) return colorLines('diff added', str.value);
+ if (str.removed) return colorLines('diff removed', str.value);
+ return str.value;
+ }).join('');
+}
+
+/**
+ * Color lines for `str`, using the color `name`.
+ *
+ * @param {String} name
+ * @param {String} str
+ * @return {String}
+ * @api private
+ */
+
+function colorLines(name, str) {
+ return str.split('\n').map(function(str){
+ return color(name, str);
+ }).join('\n');
+}
+
+}); // module: reporters/base.js
+
+require.register("reporters/doc.js", function(module, exports, require){
+
+/**
+ * Module dependencies.
+ */
+
+var Base = require('./base')
+ , utils = require('../utils');
+
+/**
+ * Expose `Doc`.
+ */
+
+exports = module.exports = Doc;
+
+/**
+ * Initialize a new `Doc` reporter.
+ *
+ * @param {Runner} runner
+ * @api public
+ */
+
+function Doc(runner) {
+ Base.call(this, runner);
+
+ var self = this
+ , stats = this.stats
+ , total = runner.total
+ , indents = 2;
+
+ function indent() {
+ return Array(indents).join(' ');
+ }
+
+ runner.on('suite', function(suite){
+ if (suite.root) return;
+ ++indents;
+ console.log('%s<section class="suite">', indent());
+ ++indents;
+ console.log('%s<h1>%s</h1>', indent(), suite.title);
+ console.log('%s<dl>', indent());
+ });
+
+ runner.on('suite end', function(suite){
+ if (suite.root) return;
+ console.log('%s</dl>', indent());
+ --indents;
+ console.log('%s</section>', indent());
+ --indents;
+ });
+
+ runner.on('pass', function(test){
+ console.log('%s <dt>%s</dt>', indent(), test.title);
+ var code = utils.escape(clean(test.fn.toString()));
+ console.log('%s <dd><pre><code>%s</code></pre></dd>', indent(), code);
+ });
+}
+
+/**
+ * Strip the function definition from `str`,
+ * and re-indent for pre whitespace.
+ */
+
+function clean(str) {
+ str = str
+ .replace(/^function *\(.*\) *{/, '')
+ .replace(/\s+\}$/, '');
+
+ var spaces = str.match(/^\n?( *)/)[1].length
+ , re = new RegExp('^ {' + spaces + '}', 'gm');
+
+ str = str.replace(re, '');
+
+ return str;
+}
+}); // module: reporters/doc.js
+
+require.register("reporters/dot.js", function(module, exports, require){
+
+/**
+ * Module dependencies.
+ */
+
+var Base = require('./base')
+ , color = Base.color;
+
+/**
+ * Expose `Dot`.
+ */
+
+exports = module.exports = Dot;
+
+/**
+ * Initialize a new `Dot` matrix test reporter.
+ *
+ * @param {Runner} runner
+ * @api public
+ */
+
+function Dot(runner) {
+ Base.call(this, runner);
+
+ var self = this
+ , stats = this.stats
+ , width = Base.window.width * .75 | 0
+ , n = 0;
+
+ runner.on('start', function(){
+ process.stdout.write('\n ');
+ });
+
+ runner.on('pending', function(test){
+ process.stdout.write(color('pending', '.'));
+ });
+
+ runner.on('pass', function(test){
+ if (++n % width == 0) process.stdout.write('\n ');
+ if ('slow' == test.speed) {
+ process.stdout.write(color('bright yellow', '.'));
+ } else {
+ process.stdout.write(color(test.speed, '.'));
+ }
+ });
+
+ runner.on('fail', function(test, err){
+ if (++n % width == 0) process.stdout.write('\n ');
+ process.stdout.write(color('fail', '.'));
+ });
+
+ runner.on('end', function(){
+ console.log();
+ self.epilogue();
+ });
+}
+
+/**
+ * Inherit from `Base.prototype`.
+ */
+
+Dot.prototype = new Base;
+Dot.prototype.constructor = Dot;
+
+}); // module: reporters/dot.js
+
+require.register("reporters/html-cov.js", function(module, exports, require){
+
+/**
+ * Module dependencies.
+ */
+
+var JSONCov = require('./json-cov')
+ , fs = require('browser/fs');
+
+/**
+ * Expose `HTMLCov`.
+ */
+
+exports = module.exports = HTMLCov;
+
+/**
+ * Initialize a new `JsCoverage` reporter.
+ *
+ * @param {Runner} runner
+ * @api public
+ */
+
+function HTMLCov(runner) {
+ var jade = require('jade')
+ , file = __dirname + '/templates/coverage.jade'
+ , str = fs.readFileSync(file, 'utf8')
+ , fn = jade.compile(str, { filename: file })
+ , self = this;
+
+ JSONCov.call(this, runner, false);
+
+ runner.on('end', function(){
+ process.stdout.write(fn({
+ cov: self.cov
+ , coverageClass: coverageClass
+ }));
+ });
+}
+
+function coverageClass(n) {
+ if (n >= 75) return 'high';
+ if (n >= 50) return 'medium';
+ if (n >= 25) return 'low';
+ return 'terrible';
+}
+}); // module: reporters/html-cov.js
+
+require.register("reporters/html.js", function(module, exports, require){
+
+/**
+ * Module dependencies.
+ */
+
+var Base = require('./base')
+ , utils = require('../utils')
+ , Progress = require('../browser/progress')
+ , escape = utils.escape;
+
+/**
+ * Expose `Doc`.
+ */
+
+exports = module.exports = HTML;
+
+/**
+ * Stats template.
+ */
+
+var statsTemplate = '<ul id="stats">'
+ + '<li class="progress"><canvas width="40" height="40"></canvas></li>'
+ + '<li class="passes">passes: <em>0</em></li>'
+ + '<li class="failures">failures: <em>0</em></li>'
+ + '<li class="duration">duration: <em>0</em>s</li>'
+ + '</ul>';
+
+/**
+ * Initialize a new `Doc` reporter.
+ *
+ * @param {Runner} runner
+ * @api public
+ */
+
+function HTML(runner) {
+ Base.call(this, runner);
+
+ var self = this
+ , stats = this.stats
+ , total = runner.total
+ , root = document.getElementById('mocha')
+ , stat = fragment(statsTemplate)
+ , items = stat.getElementsByTagName('li')
+ , passes = items[1].getElementsByTagName('em')[0]
+ , failures = items[2].getElementsByTagName('em')[0]
+ , duration = items[3].getElementsByTagName('em')[0]
+ , canvas = stat.getElementsByTagName('canvas')[0]
+ , stack = [root]
+ , progress
+ , ctx
+
+ if (canvas.getContext) {
+ ctx = canvas.getContext('2d');
+ progress = new Progress;
+ }
+
+ if (!root) return error('#mocha div missing, add it to your document');
+
+ root.appendChild(stat);
+
+ if (progress) progress.size(40);
+
+ runner.on('suite', function(suite){
+ if (suite.root) return;
+
+ // suite
+ var el = fragment('<div class="suite"><h1>%s</h1></div>', suite.title);
+
+ // container
+ stack[0].appendChild(el);
+ stack.unshift(document.createElement('div'));
+ el.appendChild(stack[0]);
+ });
+
+ runner.on('suite end', function(suite){
+ if (suite.root) return;
+ stack.shift();
+ });
+
+ runner.on('fail', function(test, err){
+ if ('hook' == test.type || err.uncaught) runner.emit('test end', test);
+ });
+
+ runner.on('test end', function(test){
+ // TODO: add to stats
+ var percent = stats.tests / total * 100 | 0;
+ if (progress) progress.update(percent).draw(ctx);
+
+ // update stats
+ var ms = new Date - stats.start;
+ text(passes, stats.passes);
+ text(failures, stats.failures);
+ text(duration, (ms / 1000).toFixed(2));
+
+ // test
+ if ('passed' == test.state) {
+ var el = fragment('<div class="test pass"><h2>%e</h2></div>', test.title);
+ } else if (test.pending) {
+ var el = fragment('<div class="test pass pending"><h2>%e</h2></div>', test.title);
+ } else {
+ var el = fragment('<div class="test fail"><h2>%e</h2></div>', test.title);
+ var str = test.err.stack || test.err.toString();
+
+ // FF / Opera do not add the message
+ if (!~str.indexOf(test.err.message)) {
+ str = test.err.message + '\n' + str;
+ }
+
+ // <=IE7 stringifies to [Object Error]. Since it can be overloaded, we
+ // check for the result of the stringifying.
+ if ('[object Error]' == str) str = test.err.message;
+
+ // Safari doesn't give you a stack. Let's at least provide a source line.
+ if (!test.err.stack && test.err.sourceURL && test.err.line !== undefined) {
+ str += "\n(" + test.err.sourceURL + ":" + test.err.line + ")";
+ }
+
+ el.appendChild(fragment('<pre class="error">%e</pre>', str));
+ }
+
+ // toggle code
+ var h2 = el.getElementsByTagName('h2')[0];
+
+ on(h2, 'click', function(){
+ pre.style.display = 'none' == pre.style.display
+ ? 'block'
+ : 'none';
+ });
+
+ // code
+ // TODO: defer
+ if (!test.pending) {
+ var pre = fragment('<pre><code>%e</code></pre>', clean(test.fn.toString()));
+ el.appendChild(pre);
+ pre.style.display = 'none';
+ }
+
+ stack[0].appendChild(el);
+ });
+}
+
+/**
+ * Display error `msg`.
+ */
+
+function error(msg) {
+ document.body.appendChild(fragment('<div id="error">%s</div>', msg));
+}
+
+/**
+ * Return a DOM fragment from `html`.
+ */
+
+function fragment(html) {
+ var args = arguments
+ , div = document.createElement('div')
+ , i = 1;
+
+ div.innerHTML = html.replace(/%([se])/g, function(_, type){
+ switch (type) {
+ case 's': return String(args[i++]);
+ case 'e': return escape(args[i++]);
+ }
+ });
+
+ return div.firstChild;
+}
+
+/**
+ * Set `el` text to `str`.
+ */
+
+function text(el, str) {
+ if (el.textContent) {
+ el.textContent = str;
+ } else {
+ el.innerText = str;
+ }
+}
+
+/**
+ * Listen on `event` with callback `fn`.
+ */
+
+function on(el, event, fn) {
+ if (el.addEventListener) {
+ el.addEventListener(event, fn, false);
+ } else {
+ el.attachEvent('on' + event, fn);
+ }
+}
+
+/**
+ * Strip the function definition from `str`,
+ * and re-indent for pre whitespace.
+ */
+
+function clean(str) {
+ str = str
+ .replace(/^function *\(.*\) *{/, '')
+ .replace(/\s+\}$/, '');
+
+ var spaces = str.match(/^\n?( *)/)[1].length
+ , re = new RegExp('^ {' + spaces + '}', 'gm');
+
+ str = str
+ .replace(re, '')
+ .replace(/^\s+/, '');
+
+ return str;
+}
+
+}); // module: reporters/html.js
+
+require.register("reporters/index.js", function(module, exports, require){
+
+exports.Base = require('./base');
+exports.Dot = require('./dot');
+exports.Doc = require('./doc');
+exports.TAP = require('./tap');
+exports.JSON = require('./json');
+exports.HTML = require('./html');
+exports.List = require('./list');
+exports.Min = require('./min');
+exports.Spec = require('./spec');
+exports.Progress = require('./progress');
+exports.Landing = require('./landing');
+exports.JSONCov = require('./json-cov');
+exports.HTMLCov = require('./html-cov');
+exports.JSONStream = require('./json-stream');
+exports.XUnit = require('./xunit')
+exports.Teamcity = require('./teamcity')
+
+}); // module: reporters/index.js
+
+require.register("reporters/json-cov.js", function(module, exports, require){
+
+/**
+ * Module dependencies.
+ */
+
+var Base = require('./base');
+
+/**
+ * Expose `JSONCov`.
+ */
+
+exports = module.exports = JSONCov;
+
+/**
+ * Initialize a new `JsCoverage` reporter.
+ *
+ * @param {Runner} runner
+ * @param {Boolean} output
+ * @api public
+ */
+
+function JSONCov(runner, output) {
+ var self = this
+ , output = 1 == arguments.length ? true : output;
+
+ Base.call(this, runner);
+
+ var tests = []
+ , failures = []
+ , passes = [];
+
+ runner.on('test end', function(test){
+ tests.push(test);
+ });
+
+ runner.on('pass', function(test){
+ passes.push(test);
+ });
+
+ runner.on('fail', function(test){
+ failures.push(test);
+ });
+
+ runner.on('end', function(){
+ var cov = global._$jscoverage || {};
+ var result = self.cov = map(cov);
+ result.stats = self.stats;
+ result.tests = tests.map(clean);
+ result.failures = failures.map(clean);
+ result.passes = passes.map(clean);
+ if (!output) return;
+ process.stdout.write(JSON.stringify(result, null, 2 ));
+ });
+}
+
+/**
+ * Map jscoverage data to a JSON structure
+ * suitable for reporting.
+ *
+ * @param {Object} cov
+ * @return {Object}
+ * @api private
+ */
+
+function map(cov) {
+ var ret = {
+ instrumentation: 'node-jscoverage'
+ , sloc: 0
+ , hits: 0
+ , misses: 0
+ , coverage: 0
+ , files: []
+ };
+
+ for (var filename in cov) {
+ var data = coverage(filename, cov[filename]);
+ ret.files.push(data);
+ ret.hits += data.hits;
+ ret.misses += data.misses;
+ ret.sloc += data.sloc;
+ }
+
+ if (ret.sloc > 0) {
+ ret.coverage = (ret.hits / ret.sloc) * 100;
+ }
+
+ return ret;
+};
+
+/**
+ * Map jscoverage data for a single source file
+ * to a JSON structure suitable for reporting.
+ *
+ * @param {String} filename name of the source file
+ * @param {Object} data jscoverage coverage data
+ * @return {Object}
+ * @api private
+ */
+
+function coverage(filename, data) {
+ var ret = {
+ filename: filename,
+ coverage: 0,
+ hits: 0,
+ misses: 0,
+ sloc: 0,
+ source: {}
+ };
+
+ data.source.forEach(function(line, num){
+ num++;
+
+ if (data[num] === 0) {
+ ret.misses++;
+ ret.sloc++;
+ } else if (data[num] !== undefined) {
+ ret.hits++;
+ ret.sloc++;
+ }
+
+ ret.source[num] = {
+ source: line
+ , coverage: data[num] === undefined
+ ? ''
+ : data[num]
+ };
+ });
+
+ ret.coverage = ret.hits / ret.sloc * 100;
+
+ return ret;
+}
+
+/**
+ * Return a plain-object representation of `test`
+ * free of cyclic properties etc.
+ *
+ * @param {Object} test
+ * @return {Object}
+ * @api private
+ */
+
+function clean(test) {
+ return {
+ title: test.title
+ , fullTitle: test.fullTitle()
+ , duration: test.duration
+ }
+}
+
+}); // module: reporters/json-cov.js
+
+require.register("reporters/json-stream.js", function(module, exports, require){
+
+/**
+ * Module dependencies.
+ */
+
+var Base = require('./base')
+ , color = Base.color;
+
+/**
+ * Expose `List`.
+ */
+
+exports = module.exports = List;
+
+/**
+ * Initialize a new `List` test reporter.
+ *
+ * @param {Runner} runner
+ * @api public
+ */
+
+function List(runner) {
+ Base.call(this, runner);
+
+ var self = this
+ , stats = this.stats
+ , total = runner.total;
+
+ runner.on('start', function(){
+ console.log(JSON.stringify(['start', { total: total }]));
+ });
+
+ runner.on('pass', function(test){
+ console.log(JSON.stringify(['pass', clean(test)]));
+ });
+
+ runner.on('fail', function(test, err){
+ console.log(JSON.stringify(['fail', clean(test)]));
+ });
+
+ runner.on('end', function(){
+ process.stdout.write(JSON.stringify(['end', self.stats]));
+ });
+}
+
+/**
+ * Return a plain-object representation of `test`
+ * free of cyclic properties etc.
+ *
+ * @param {Object} test
+ * @return {Object}
+ * @api private
+ */
+
+function clean(test) {
+ return {
+ title: test.title
+ , fullTitle: test.fullTitle()
+ , duration: test.duration
+ }
+}
+}); // module: reporters/json-stream.js
+
+require.register("reporters/json.js", function(module, exports, require){
+
+/**
+ * Module dependencies.
+ */
+
+var Base = require('./base')
+ , cursor = Base.cursor
+ , color = Base.color;
+
+/**
+ * Expose `JSON`.
+ */
+
+exports = module.exports = JSONReporter;
+
+/**
+ * Initialize a new `JSON` reporter.
+ *
+ * @param {Runner} runner
+ * @api public
+ */
+
+function JSONReporter(runner) {
+ var self = this;
+ Base.call(this, runner);
+
+ var tests = []
+ , failures = []
+ , passes = [];
+
+ runner.on('test end', function(test){
+ tests.push(test);
+ });
+
+ runner.on('pass', function(test){
+ passes.push(test);
+ });
+
+ runner.on('fail', function(test){
+ failures.push(test);
+ });
+
+ runner.on('end', function(){
+ var obj = {
+ stats: self.stats
+ , tests: tests.map(clean)
+ , failures: failures.map(clean)
+ , passes: passes.map(clean)
+ };
+
+ process.stdout.write(JSON.stringify(obj, null, 2));
+ });
+}
+
+/**
+ * Return a plain-object representation of `test`
+ * free of cyclic properties etc.
+ *
+ * @param {Object} test
+ * @return {Object}
+ * @api private
+ */
+
+function clean(test) {
+ return {
+ title: test.title
+ , fullTitle: test.fullTitle()
+ , duration: test.duration
+ }
+}
+}); // module: reporters/json.js
+
+require.register("reporters/landing.js", function(module, exports, require){
+
+/**
+ * Module dependencies.
+ */
+
+var Base = require('./base')
+ , cursor = Base.cursor
+ , color = Base.color;
+
+/**
+ * Expose `Landing`.
+ */
+
+exports = module.exports = Landing;
+
+/**
+ * Airplane color.
+ */
+
+Base.colors.plane = 0;
+
+/**
+ * Airplane crash color.
+ */
+
+Base.colors['plane crash'] = 31;
+
+/**
+ * Runway color.
+ */
+
+Base.colors.runway = 90;
+
+/**
+ * Initialize a new `Landing` reporter.
+ *
+ * @param {Runner} runner
+ * @api public
+ */
+
+function Landing(runner) {
+ Base.call(this, runner);
+
+ var self = this
+ , stats = this.stats
+ , width = Base.window.width * .75 | 0
+ , total = runner.total
+ , stream = process.stdout
+ , plane = color('plane', '✈')
+ , crashed = -1
+ , n = 0;
+
+ function runway() {
+ var buf = Array(width).join('-');
+ return ' ' + color('runway', buf);
+ }
+
+ runner.on('start', function(){
+ stream.write('\n ');
+ cursor.hide();
+ });
+
+ runner.on('test end', function(test){
+ // check if the plane crashed
+ var col = -1 == crashed
+ ? width * ++n / total | 0
+ : crashed;
+
+ // show the crash
+ if ('failed' == test.state) {
+ plane = color('plane crash', '✈');
+ crashed = col;
+ }
+
+ // render landing strip
+ stream.write('\033[4F\n\n');
+ stream.write(runway());
+ stream.write('\n ');
+ stream.write(color('runway', Array(col).join('⋅')));
+ stream.write(plane)
+ stream.write(color('runway', Array(width - col).join('⋅') + '\n'));
+ stream.write(runway());
+ stream.write('\033[0m');
+ });
+
+ runner.on('end', function(){
+ cursor.show();
+ console.log();
+ self.epilogue();
+ });
+}
+
+/**
+ * Inherit from `Base.prototype`.
+ */
+
+Landing.prototype = new Base;
+Landing.prototype.constructor = Landing;
+
+}); // module: reporters/landing.js
+
+require.register("reporters/list.js", function(module, exports, require){
+
+/**
+ * Module dependencies.
+ */
+
+var Base = require('./base')
+ , cursor = Base.cursor
+ , color = Base.color;
+
+/**
+ * Expose `List`.
+ */
+
+exports = module.exports = List;
+
+/**
+ * Initialize a new `List` test reporter.
+ *
+ * @param {Runner} runner
+ * @api public
+ */
+
+function List(runner) {
+ Base.call(this, runner);
+
+ var self = this
+ , stats = this.stats
+ , n = 0;
+
+ runner.on('start', function(){
+ console.log();
+ });
+
+ runner.on('test', function(test){
+ process.stdout.write(color('pass', ' ' + test.fullTitle() + ': '));
+ });
+
+ runner.on('pending', function(test){
+ var fmt = color('checkmark', ' -')
+ + color('pending', ' %s');
+ console.log(fmt, test.fullTitle());
+ });
+
+ runner.on('pass', function(test){
+ var fmt = color('checkmark', ' ✓')
+ + color('pass', ' %s: ')
+ + color(test.speed, '%dms');
+ cursor.CR();
+ console.log(fmt, test.fullTitle(), test.duration);
+ });
+
+ runner.on('fail', function(test, err){
+ cursor.CR();
+ console.log(color('fail', ' %d) %s'), ++n, test.fullTitle());
+ });
+
+ runner.on('end', self.epilogue.bind(self));
+}
+
+/**
+ * Inherit from `Base.prototype`.
+ */
+
+List.prototype = new Base;
+List.prototype.constructor = List;
+
+
+}); // module: reporters/list.js
+
+require.register("reporters/markdown.js", function(module, exports, require){
+
+/**
+ * Module dependencies.
+ */
+
+var Base = require('./base')
+ , utils = require('../utils');
+
+/**
+ * Expose `Markdown`.
+ */
+
+exports = module.exports = Markdown;
+
+/**
+ * Initialize a new `Markdown` reporter.
+ *
+ * @param {Runner} runner
+ * @api public
+ */
+
+function Markdown(runner) {
+ Base.call(this, runner);
+
+ var self = this
+ , stats = this.stats
+ , total = runner.total
+ , level = 0
+ , buf = '';
+
+ function title(str) {
+ return Array(level).join('#') + ' ' + str;
+ }
+
+ function indent() {
+ return Array(level).join(' ');
+ }
+
+ function mapTOC(suite, obj) {
+ var ret = obj;
+ obj = obj[suite.title] = obj[suite.title] || { suite: suite };
+ suite.suites.forEach(function(suite){
+ mapTOC(suite, obj);
+ });
+ return ret;
+ }
+
+ function stringifyTOC(obj, level) {
+ ++level;
+ var buf = '';
+ var link;
+ for (var key in obj) {
+ if ('suite' == key) continue;
+ if (key) link = ' - [' + key + '](#' + utils.slug(obj[key].suite.fullTitle()) + ')\n';
+ if (key) buf += Array(level).join(' ') + link;
+ buf += stringifyTOC(obj[key], level);
+ }
+ --level;
+ return buf;
+ }
+
+ function generateTOC(suite) {
+ var obj = mapTOC(suite, {});
+ return stringifyTOC(obj, 0);
+ }
+
+ generateTOC(runner.suite);
+
+ runner.on('suite', function(suite){
+ ++level;
+ var slug = utils.slug(suite.fullTitle());
+ buf += '<a name="' + slug + '" />' + '\n';
+ buf += title(suite.title) + '\n';
+ });
+
+ runner.on('suite end', function(suite){
+ --level;
+ });
+
+ runner.on('pass', function(test){
+ var code = clean(test.fn.toString());
+ buf += test.title + '.\n';
+ buf += '\n```js';
+ buf += code + '\n';
+ buf += '```\n\n';
+ });
+
+ runner.on('end', function(){
+ process.stdout.write('# TOC\n');
+ process.stdout.write(generateTOC(runner.suite));
+ process.stdout.write(buf);
+ });
+}
+
+/**
+ * Strip the function definition from `str`,
+ * and re-indent for pre whitespace.
+ */
+
+function clean(str) {
+ str = str
+ .replace(/^function *\(.*\) *{/, '')
+ .replace(/\s+\}$/, '');
+
+ var spaces = str.match(/^\n?( *)/)[1].length
+ , re = new RegExp('^ {' + spaces + '}', 'gm');
+
+ str = str.replace(re, '');
+
+ return str;
+}
+}); // module: reporters/markdown.js
+
+require.register("reporters/min.js", function(module, exports, require){
+/**
+ * Module dependencies.
+ */
+
+var Base = require('./base');
+
+/**
+ * Expose `Min`.
+ */
+
+exports = module.exports = Min;
+
+/**
+ * Initialize a new `Min` minimal test reporter (best used with --watch).
+ *
+ * @param {Runner} runner
+ * @api public
+ */
+
+function Min(runner) {
+ Base.call(this, runner);
+
+ runner.on('start', function(){
+ // clear screen
+ process.stdout.write('\033[2J');
+ // set cursor position
+ process.stdout.write('\033[1;3H');
+ });
+
+ runner.on('end', this.epilogue.bind(this));
+}
+
+/**
+ * Inherit from `Base.prototype`.
+ */
+
+Min.prototype = new Base;
+Min.prototype.constructor = Min;
+
+}); // module: reporters/min.js
+
+require.register("reporters/progress.js", function(module, exports, require){
+
+/**
+ * Module dependencies.
+ */
+
+var Base = require('./base')
+ , cursor = Base.cursor
+ , color = Base.color;
+
+/**
+ * Expose `Progress`.
+ */
+
+exports = module.exports = Progress;
+
+/**
+ * General progress bar color.
+ */
+
+Base.colors.progress = 90;
+
+/**
+ * Initialize a new `Progress` bar test reporter.
+ *
+ * @param {Runner} runner
+ * @param {Object} options
+ * @api public
+ */
+
+function Progress(runner, options) {
+ Base.call(this, runner);
+
+ var self = this
+ , options = options || {}
+ , stats = this.stats
+ , width = Base.window.width * .50 | 0
+ , total = runner.total
+ , complete = 0
+ , max = Math.max;
+
+ // default chars
+ options.open = options.open || '[';
+ options.complete = options.complete || '▬';
+ options.incomplete = options.incomplete || '⋅';
+ options.close = options.close || ']';
+ options.verbose = false;
+
+ // tests started
+ runner.on('start', function(){
+ console.log();
+ cursor.hide();
+ });
+
+ // tests complete
+ runner.on('test end', function(){
+ var incomplete = total - complete
+ , percent = complete++ / total
+ , n = width * percent | 0
+ , i = width - n;
+
+ cursor.CR();
+ process.stdout.write('\033[J');
+ process.stdout.write(color('progress', ' ' + options.open));
+ process.stdout.write(Array(n).join(options.complete));
+ process.stdout.write(Array(i).join(options.incomplete));
+ process.stdout.write(color('progress', options.close));
+ if (options.verbose) {
+ process.stdout.write(color('progress', ' ' + complete + ' of ' + total));
+ }
+ });
+
+ // tests are complete, output some stats
+ // and the failures if any
+ runner.on('end', function(){
+ cursor.show();
+ console.log();
+ self.epilogue();
+ });
+}
+
+/**
+ * Inherit from `Base.prototype`.
+ */
+
+Progress.prototype = new Base;
+Progress.prototype.constructor = Progress;
+
+
+}); // module: reporters/progress.js
+
+require.register("reporters/spec.js", function(module, exports, require){
+
+/**
+ * Module dependencies.
+ */
+
+var Base = require('./base')
+ , cursor = Base.cursor
+ , color = Base.color;
+
+/**
+ * Expose `Spec`.
+ */
+
+exports = module.exports = Spec;
+
+/**
+ * Initialize a new `Spec` test reporter.
+ *
+ * @param {Runner} runner
+ * @api public
+ */
+
+function Spec(runner) {
+ Base.call(this, runner);
+
+ var self = this
+ , stats = this.stats
+ , indents = 0
+ , n = 0;
+
+ function indent() {
+ return Array(indents).join(' ')
+ }
+
+ runner.on('start', function(){
+ console.log();
+ });
+
+ runner.on('suite', function(suite){
+ ++indents;
+ console.log(color('suite', '%s%s'), indent(), suite.title);
+ });
+
+ runner.on('suite end', function(suite){
+ --indents;
+ if (1 == indents) console.log();
+ });
+
+ runner.on('test', function(test){
+ process.stdout.write(indent() + color('pass', ' ◦ ' + test.title + ': '));
+ });
+
+ runner.on('pending', function(test){
+ var fmt = indent() + color('pending', ' - %s');
+ console.log(fmt, test.title);
+ });
+
+ runner.on('pass', function(test){
+ if ('fast' == test.speed) {
+ var fmt = indent()
+ + color('checkmark', ' ✓')
+ + color('pass', ' %s ');
+ cursor.CR();
+ console.log(fmt, test.title);
+ } else {
+ var fmt = indent()
+ + color('checkmark', ' ✓')
+ + color('pass', ' %s ')
+ + color(test.speed, '(%dms)');
+ cursor.CR();
+ console.log(fmt, test.title, test.duration);
+ }
+ });
+
+ runner.on('fail', function(test, err){
+ cursor.CR();
+ console.log(indent() + color('fail', ' %d) %s'), ++n, test.title);
+ });
+
+ runner.on('end', self.epilogue.bind(self));
+}
+
+/**
+ * Inherit from `Base.prototype`.
+ */
+
+Spec.prototype = new Base;
+Spec.prototype.constructor = Spec;
+
+
+}); // module: reporters/spec.js
+
+require.register("reporters/tap.js", function(module, exports, require){
+
+/**
+ * Module dependencies.
+ */
+
+var Base = require('./base')
+ , cursor = Base.cursor
+ , color = Base.color;
+
+/**
+ * Expose `TAP`.
+ */
+
+exports = module.exports = TAP;
+
+/**
+ * Initialize a new `TAP` reporter.
+ *
+ * @param {Runner} runner
+ * @api public
+ */
+
+function TAP(runner) {
+ Base.call(this, runner);
+
+ var self = this
+ , stats = this.stats
+ , total = runner.total
+ , n = 1;
+
+ runner.on('start', function(){
+ console.log('%d..%d', 1, total);
+ });
+
+ runner.on('test end', function(){
+ ++n;
+ });
+
+ runner.on('pending', function(test){
+ console.log('ok %d %s # SKIP -', n, title(test));
+ });
+
+ runner.on('pass', function(test){
+ console.log('ok %d %s', n, title(test));
+ });
+
+ runner.on('fail', function(test, err){
+ console.log('not ok %d %s', n, title(test));
+ console.log(err.stack.replace(/^/gm, ' '));
+ });
+}
+
+/**
+ * Return a TAP-safe title of `test`
+ *
+ * @param {Object} test
+ * @return {String}
+ * @api private
+ */
+
+function title(test) {
+ return test.fullTitle().replace(/#/g, '');
+}
+
+}); // module: reporters/tap.js
+
+require.register("reporters/teamcity.js", function(module, exports, require){
+
+/**
+ * Module dependencies.
+ */
+
+var Base = require('./base');
+
+/**
+ * Expose `Teamcity`.
+ */
+
+exports = module.exports = Teamcity;
+
+/**
+ * Initialize a new `Teamcity` reporter.
+ *
+ * @param {Runner} runner
+ * @api public
+ */
+
+function Teamcity(runner) {
+ Base.call(this, runner);
+ var stats = this.stats;
+
+ runner.on('start', function() {
+ console.log("##teamcity[testSuiteStarted name='mocha.suite']");
+ });
+
+ runner.on('test', function(test) {
+ console.log("##teamcity[testStarted name='%s']", escape(test.fullTitle()));
+ });
+
+ runner.on('fail', function(test, err) {
+ console.log("##teamcity[testFailed name='%s' message='%s']", escape(test.fullTitle()), escape(err.message));
+ });
+
+ runner.on('pending', function(test) {
+ console.log("##teamcity[testIgnored name='%s' message='pending']", escape(test.fullTitle()));
+ });
+
+ runner.on('test end', function(test) {
+ console.log("##teamcity[testFinished name='%s' duration='%s']", escape(test.fullTitle()), test.duration);
+ });
+
+ runner.on('end', function() {
+ console.log("##teamcity[testSuiteFinished name='mocha.suite' duration='%s']", stats.duration);
+ });
+}
+
+/**
+ * Escape the given `str`.
+ */
+
+function escape(str) {
+ return str.replace(/'/g, "|'");
+}
+}); // module: reporters/teamcity.js
+
+require.register("reporters/xunit.js", function(module, exports, require){
+
+/**
+ * Module dependencies.
+ */
+
+var Base = require('./base')
+ , utils = require('../utils')
+ , escape = utils.escape;
+
+/**
+ * Expose `XUnit`.
+ */
+
+exports = module.exports = XUnit;
+
+/**
+ * Initialize a new `XUnit` reporter.
+ *
+ * @param {Runner} runner
+ * @api public
+ */
+
+function XUnit(runner) {
+ Base.call(this, runner);
+ var stats = this.stats
+ , tests = []
+ , self = this;
+
+ runner.on('test end', function(test){
+ tests.push(test);
+ });
+
+ runner.on('end', function(){
+ console.log(tag('testsuite', {
+ name: 'Mocha Tests'
+ , tests: stats.tests
+ , failures: stats.failures
+ , errors: stats.failures
+ , skip: stats.tests - stats.failures - stats.passes
+ , timestamp: (new Date).toUTCString()
+ , time: stats.duration / 1000
+ }, false));
+
+ tests.forEach(test);
+ console.log('</testsuite>');
+ });
+}
+
+/**
+ * Inherit from `Base.prototype`.
+ */
+
+XUnit.prototype = new Base;
+XUnit.prototype.constructor = XUnit;
+
+
+/**
+ * Output tag for the given `test.`
+ */
+
+function test(test) {
+ var attrs = {
+ classname: test.parent.fullTitle()
+ , name: test.title
+ , time: test.duration / 1000
+ };
+
+ if ('failed' == test.state) {
+ var err = test.err;
+ attrs.message = escape(err.message);
+ console.log(tag('testcase', attrs, false, tag('failure', attrs, false, cdata(err.stack))));
+ } else if (test.pending) {
+ console.log(tag('testcase', attrs, false, tag('skipped', {}, true)));
+ } else {
+ console.log(tag('testcase', attrs, true) );
+ }
+}
+
+/**
+ * HTML tag helper.
+ */
+
+function tag(name, attrs, close, content) {
+ var end = close ? '/>' : '>'
+ , pairs = []
+ , tag;
+
+ for (var key in attrs) {
+ pairs.push(key + '="' + escape(attrs[key]) + '"');
+ }
+
+ tag = '<' + name + (pairs.length ? ' ' + pairs.join(' ') : '') + end;
+ if (content) tag += content + '</' + name + end;
+ return tag;
+}
+
+/**
+ * Return cdata escaped CDATA `str`.
+ */
+
+function cdata(str) {
+ return '<![CDATA[' + escape(str) + ']]>';
+}
+
+}); // module: reporters/xunit.js
+
+require.register("runnable.js", function(module, exports, require){
+
+/**
+ * Module dependencies.
+ */
+
+var EventEmitter = require('browser/events').EventEmitter
+ , debug = require('browser/debug')('runnable');
+
+/**
+ * Expose `Runnable`.
+ */
+
+module.exports = Runnable;
+
+/**
+ * Initialize a new `Runnable` with the given `title` and callback `fn`.
+ *
+ * @param {String} title
+ * @param {Function} fn
+ * @api private
+ */
+
+function Runnable(title, fn) {
+ this.title = title;
+ this.fn = fn;
+ this.async = fn && fn.length;
+ this.sync = ! this.async;
+ this._timeout = 2000;
+ this.timedOut = false;
+}
+
+/**
+ * Inherit from `EventEmitter.prototype`.
+ */
+
+Runnable.prototype = new EventEmitter;
+Runnable.prototype.constructor = Runnable;
+
+
+/**
+ * Set & get timeout `ms`.
+ *
+ * @param {Number} ms
+ * @return {Runnable|Number} ms or self
+ * @api private
+ */
+
+Runnable.prototype.timeout = function(ms){
+ if (0 == arguments.length) return this._timeout;
+ debug('timeout %d', ms);
+ this._timeout = ms;
+ if (this.timer) this.resetTimeout();
+ return this;
+};
+
+/**
+ * Return the full title generated by recursively
+ * concatenating the parent's full title.
+ *
+ * @return {String}
+ * @api public
+ */
+
+Runnable.prototype.fullTitle = function(){
+ return this.parent.fullTitle() + ' ' + this.title;
+};
+
+/**
+ * Clear the timeout.
+ *
+ * @api private
+ */
+
+Runnable.prototype.clearTimeout = function(){
+ clearTimeout(this.timer);
+};
+
+/**
+ * Reset the timeout.
+ *
+ * @api private
+ */
+
+Runnable.prototype.resetTimeout = function(){
+ var self = this
+ , ms = this.timeout();
+
+ this.clearTimeout();
+ if (ms) {
+ this.timer = setTimeout(function(){
+ self.callback(new Error('timeout of ' + ms + 'ms exceeded'));
+ self.timedOut = true;
+ }, ms);
+ }
+};
+
+/**
+ * Run the test and invoke `fn(err)`.
+ *
+ * @param {Function} fn
+ * @api private
+ */
+
+Runnable.prototype.run = function(fn){
+ var self = this
+ , ms = this.timeout()
+ , start = new Date
+ , ctx = this.ctx
+ , finished
+ , emitted;
+
+ if (ctx) ctx.runnable(this);
+
+ // timeout
+ if (this.async) {
+ if (ms) {
+ this.timer = setTimeout(function(){
+ done(new Error('timeout of ' + ms + 'ms exceeded'));
+ self.timedOut = true;
+ }, ms);
+ }
+ }
+
+ // called multiple times
+ function multiple() {
+ if (emitted) return;
+ emitted = true;
+ self.emit('error', new Error('done() called multiple times'));
+ }
+
+ // finished
+ function done(err) {
+ if (self.timedOut) return;
+ if (finished) return multiple();
+ self.clearTimeout();
+ self.duration = new Date - start;
+ finished = true;
+ fn(err);
+ }
+
+ // for .resetTimeout()
+ this.callback = done;
+
+ // async
+ if (this.async) {
+ try {
+ this.fn.call(ctx, function(err){
+ if (err instanceof Error) return done(err);
+ if (null != err) return done(new Error('done() invoked with non-Error: ' + err));
+ done();
+ });
+ } catch (err) {
+ done(err);
+ }
+ return;
+ }
+
+ // sync
+ try {
+ if (!this.pending) this.fn.call(ctx);
+ this.duration = new Date - start;
+ fn();
+ } catch (err) {
+ fn(err);
+ }
+};
+
+}); // module: runnable.js
+
+require.register("runner.js", function(module, exports, require){
+
+/**
+ * Module dependencies.
+ */
+
+var EventEmitter = require('browser/events').EventEmitter
+ , debug = require('browser/debug')('runner')
+ , Test = require('./test')
+ , utils = require('./utils')
+ , noop = function(){};
+
+/**
+ * Expose `Runner`.
+ */
+
+module.exports = Runner;
+
+/**
+ * Initialize a `Runner` for the given `suite`.
+ *
+ * Events:
+ *
+ * - `start` execution started
+ * - `end` execution complete
+ * - `suite` (suite) test suite execution started
+ * - `suite end` (suite) all tests (and sub-suites) have finished
+ * - `test` (test) test execution started
+ * - `test end` (test) test completed
+ * - `hook` (hook) hook execution started
+ * - `hook end` (hook) hook complete
+ * - `pass` (test) test passed
+ * - `fail` (test, err) test failed
+ *
+ * @api public
+ */
+
+function Runner(suite) {
+ var self = this;
+ this._globals = [];
+ this.suite = suite;
+ this.total = suite.total();
+ this.failures = 0;
+ this.on('test end', function(test){ self.checkGlobals(test); });
+ this.on('hook end', function(hook){ self.checkGlobals(hook); });
+ this.grep(/.*/);
+ this.globals(utils.keys(global).concat(['errno']));
+}
+
+/**
+ * Inherit from `EventEmitter.prototype`.
+ */
+
+Runner.prototype = new EventEmitter;
+Runner.prototype.constructor = Runner;
+
+
+/**
+ * Run tests with full titles matching `re`.
+ *
+ * @param {RegExp} re
+ * @return {Runner} for chaining
+ * @api public
+ */
+
+Runner.prototype.grep = function(re){
+ debug('grep %s', re);
+ this._grep = re;
+ return this;
+};
+
+/**
+ * Allow the given `arr` of globals.
+ *
+ * @param {Array} arr
+ * @return {Runner} for chaining
+ * @api public
+ */
+
+Runner.prototype.globals = function(arr){
+ if (0 == arguments.length) return this._globals;
+ debug('globals %j', arr);
+ utils.forEach(arr, function(arr){
+ this._globals.push(arr);
+ }, this);
+ return this;
+};
+
+/**
+ * Check for global variable leaks.
+ *
+ * @api private
+ */
+
+Runner.prototype.checkGlobals = function(test){
+ if (this.ignoreLeaks) return;
+
+ var leaks = utils.filter(utils.keys(global), function(key){
+ return !~utils.indexOf(this._globals, key) && (!global.navigator || 'onerror' !== key);
+ }, this);
+
+ this._globals = this._globals.concat(leaks);
+
+ if (leaks.length > 1) {
+ this.fail(test, new Error('global leaks detected: ' + leaks.join(', ') + ''));
+ } else if (leaks.length) {
+ this.fail(test, new Error('global leak detected: ' + leaks[0]));
+ }
+};
+
+/**
+ * Fail the given `test`.
+ *
+ * @param {Test} test
+ * @param {Error} err
+ * @api private
+ */
+
+Runner.prototype.fail = function(test, err){
+ ++this.failures;
+ test.state = 'failed';
+ this.emit('fail', test, err);
+};
+
+/**
+ * Fail the given `hook` with `err`.
+ *
+ * Hook failures (currently) hard-end due
+ * to that fact that a failing hook will
+ * surely cause subsequent tests to fail,
+ * causing jumbled reporting.
+ *
+ * @param {Hook} hook
+ * @param {Error} err
+ * @api private
+ */
+
+Runner.prototype.failHook = function(hook, err){
+ this.fail(hook, err);
+ this.emit('end');
+};
+
+/**
+ * Run hook `name` callbacks and then invoke `fn()`.
+ *
+ * @param {String} name
+ * @param {Function} function
+ * @api private
+ */
+
+Runner.prototype.hook = function(name, fn){
+ var suite = this.suite
+ , hooks = suite['_' + name]
+ , ms = suite._timeout
+ , self = this
+ , timer;
+
+ function next(i) {
+ var hook = hooks[i];
+ if (!hook) return fn();
+ self.currentRunnable = hook;
+
+ self.emit('hook', hook);
+
+ hook.on('error', function(err){
+ self.failHook(hook, err);
+ });
+
+ hook.run(function(err){
+ hook.removeAllListeners('error');
+ if (err) return self.failHook(hook, err);
+ self.emit('hook end', hook);
+ next(++i);
+ });
+ }
+
+ process.nextTick(function(){
+ next(0);
+ });
+};
+
+/**
+ * Run hook `name` for the given array of `suites`
+ * in order, and callback `fn(err)`.
+ *
+ * @param {String} name
+ * @param {Array} suites
+ * @param {Function} fn
+ * @api private
+ */
+
+Runner.prototype.hooks = function(name, suites, fn){
+ var self = this
+ , orig = this.suite;
+
+ function next(suite) {
+ self.suite = suite;
+
+ if (!suite) {
+ self.suite = orig;
+ return fn();
+ }
+
+ self.hook(name, function(err){
+ if (err) {
+ self.suite = orig;
+ return fn(err);
+ }
+
+ next(suites.pop());
+ });
+ }
+
+ next(suites.pop());
+};
+
+/**
+ * Run hooks from the top level down.
+ *
+ * @param {String} name
+ * @param {Function} fn
+ * @api private
+ */
+
+Runner.prototype.hookUp = function(name, fn){
+ var suites = [this.suite].concat(this.parents()).reverse();
+ this.hooks(name, suites, fn);
+};
+
+/**
+ * Run hooks from the bottom up.
+ *
+ * @param {String} name
+ * @param {Function} fn
+ * @api private
+ */
+
+Runner.prototype.hookDown = function(name, fn){
+ var suites = [this.suite].concat(this.parents());
+ this.hooks(name, suites, fn);
+};
+
+/**
+ * Return an array of parent Suites from
+ * closest to furthest.
+ *
+ * @return {Array}
+ * @api private
+ */
+
+Runner.prototype.parents = function(){
+ var suite = this.suite
+ , suites = [];
+ while (suite = suite.parent) suites.push(suite);
+ return suites;
+};
+
+/**
+ * Run the current test and callback `fn(err)`.
+ *
+ * @param {Function} fn
+ * @api private
+ */
+
+Runner.prototype.runTest = function(fn){
+ var test = this.test
+ , self = this;
+
+ try {
+ test.on('error', function(err){
+ self.fail(test, err);
+ });
+ test.run(fn);
+ } catch (err) {
+ fn(err);
+ }
+};
+
+/**
+ * Run tests in the given `suite` and invoke
+ * the callback `fn()` when complete.
+ *
+ * @param {Suite} suite
+ * @param {Function} fn
+ * @api private
+ */
+
+Runner.prototype.runTests = function(suite, fn){
+ var self = this
+ , tests = suite.tests
+ , test;
+
+ function next(err) {
+ // if we bail after first err
+ if (self.failures && suite._bail) return fn();
+
+ // next test
+ test = tests.shift();
+
+ // all done
+ if (!test) return fn();
+
+ // grep
+ if (!self._grep.test(test.fullTitle())) return next();
+
+ // pending
+ if (test.pending) {
+ self.emit('pending', test);
+ self.emit('test end', test);
+ return next();
+ }
+
+ // execute test and hook(s)
+ self.emit('test', self.test = test);
+ self.hookDown('beforeEach', function(){
+ self.currentRunnable = self.test;
+ self.runTest(function(err){
+ test = self.test;
+
+ if (err) {
+ self.fail(test, err);
+ self.emit('test end', test);
+ return self.hookUp('afterEach', next);
+ }
+
+ test.state = 'passed';
+ self.emit('pass', test);
+ self.emit('test end', test);
+ self.hookUp('afterEach', next);
+ });
+ });
+ }
+
+ this.next = next;
+ next();
+};
+
+/**
+ * Run the given `suite` and invoke the
+ * callback `fn()` when complete.
+ *
+ * @param {Suite} suite
+ * @param {Function} fn
+ * @api private
+ */
+
+Runner.prototype.runSuite = function(suite, fn){
+ var self = this
+ , i = 0;
+
+ debug('run suite %s', suite.fullTitle());
+ this.emit('suite', this.suite = suite);
+
+ function next() {
+ var curr = suite.suites[i++];
+ if (!curr) return done();
+ self.runSuite(curr, next);
+ }
+
+ function done() {
+ self.suite = suite;
+ self.hook('afterAll', function(){
+ self.emit('suite end', suite);
+ fn();
+ });
+ }
+
+ this.hook('beforeAll', function(){
+ self.runTests(suite, next);
+ });
+};
+
+/**
+ * Handle uncaught exceptions.
+ *
+ * @param {Error} err
+ * @api private
+ */
+
+Runner.prototype.uncaught = function(err){
+ debug('uncaught exception');
+ var runnable = this.currentRunnable;
+ if ('failed' == runnable.state) return;
+ runnable.clearTimeout();
+ err.uncaught = true;
+ this.fail(runnable, err);
+
+ // recover from test
+ if ('test' == runnable.type) {
+ this.emit('test end', runnable);
+ this.hookUp('afterEach', this.next);
+ return;
+ }
+
+ // bail on hooks
+ this.emit('end');
+};
+
+/**
+ * Run the root suite and invoke `fn(failures)`
+ * on completion.
+ *
+ * @param {Function} fn
+ * @return {Runner} for chaining
+ * @api public
+ */
+
+Runner.prototype.run = function(fn){
+ var self = this
+ , fn = fn || function(){};
+
+ debug('start');
+
+ // callback
+ this.on('end', function(){
+ debug('end');
+ process.removeListener('uncaughtException', this.uncaught);
+ fn(self.failures);
+ });
+
+ // run suites
+ this.emit('start');
+ this.runSuite(this.suite, function(){
+ debug('finished running');
+ self.emit('end');
+ });
+
+ // uncaught exception
+ process.on('uncaughtException', function(err){
+ self.uncaught(err);
+ });
+
+ return this;
+};
+
+}); // module: runner.js
+
+require.register("suite.js", function(module, exports, require){
+
+/**
+ * Module dependencies.
+ */
+
+var EventEmitter = require('browser/events').EventEmitter
+ , debug = require('browser/debug')('suite')
+ , utils = require('./utils')
+ , Hook = require('./hook');
+
+/**
+ * Expose `Suite`.
+ */
+
+exports = module.exports = Suite;
+
+/**
+ * Create a new `Suite` with the given `title`
+ * and parent `Suite`. When a suite with the
+ * same title is already present, that suite
+ * is returned to provide nicer reporter
+ * and more flexible meta-testing.
+ *
+ * @param {Suite} parent
+ * @param {String} title
+ * @return {Suite}
+ * @api public
+ */
+
+exports.create = function(parent, title){
+ var suite = new Suite(title, parent.ctx);
+ suite.parent = parent;
+ title = suite.fullTitle();
+ parent.addSuite(suite);
+ return suite;
+};
+
+/**
+ * Initialize a new `Suite` with the given
+ * `title` and `ctx`.
+ *
+ * @param {String} title
+ * @param {Context} ctx
+ * @api private
+ */
+
+function Suite(title, ctx) {
+ this.title = title;
+ this.ctx = ctx;
+ this.suites = [];
+ this.tests = [];
+ this._beforeEach = [];
+ this._beforeAll = [];
+ this._afterEach = [];
+ this._afterAll = [];
+ this.root = !title;
+ this._timeout = 2000;
+ this._bail = false;
+}
+
+/**
+ * Inherit from `EventEmitter.prototype`.
+ */
+
+Suite.prototype = new EventEmitter;
+Suite.prototype.constructor = Suite;
+
+
+/**
+ * Return a clone of this `Suite`.
+ *
+ * @return {Suite}
+ * @api private
+ */
+
+Suite.prototype.clone = function(){
+ var suite = new Suite(this.title);
+ debug('clone');
+ suite.ctx = this.ctx;
+ suite.timeout(this.timeout());
+ suite.bail(this.bail());
+ return suite;
+};
+
+/**
+ * Set timeout `ms` or short-hand such as "2s".
+ *
+ * @param {Number|String} ms
+ * @return {Suite|Number} for chaining
+ * @api private
+ */
+
+Suite.prototype.timeout = function(ms){
+ if (0 == arguments.length) return this._timeout;
+ if (String(ms).match(/s$/)) ms = parseFloat(ms) * 1000;
+ debug('timeout %d', ms);
+ this._timeout = parseInt(ms, 10);
+ return this;
+};
+
+/**
+ * Sets whether to bail after first error.
+ *
+ * @parma {Boolean} bail
+ * @return {Suite|Number} for chaining
+ * @api private
+ */
+
+Suite.prototype.bail = function(bail){
+ if (0 == arguments.length) return this._bail;
+ debug('bail %s', bail);
+ this._bail = bail;
+ return this;
+};
+
+/**
+ * Run `fn(test[, done])` before running tests.
+ *
+ * @param {Function} fn
+ * @return {Suite} for chaining
+ * @api private
+ */
+
+Suite.prototype.beforeAll = function(fn){
+ var hook = new Hook('"before all" hook', fn);
+ hook.parent = this;
+ hook.timeout(this.timeout());
+ hook.ctx = this.ctx;
+ this._beforeAll.push(hook);
+ this.emit('beforeAll', hook);
+ return this;
+};
+
+/**
+ * Run `fn(test[, done])` after running tests.
+ *
+ * @param {Function} fn
+ * @return {Suite} for chaining
+ * @api private
+ */
+
+Suite.prototype.afterAll = function(fn){
+ var hook = new Hook('"after all" hook', fn);
+ hook.parent = this;
+ hook.timeout(this.timeout());
+ hook.ctx = this.ctx;
+ this._afterAll.push(hook);
+ this.emit('afterAll', hook);
+ return this;
+};
+
+/**
+ * Run `fn(test[, done])` before each test case.
+ *
+ * @param {Function} fn
+ * @return {Suite} for chaining
+ * @api private
+ */
+
+Suite.prototype.beforeEach = function(fn){
+ var hook = new Hook('"before each" hook', fn);
+ hook.parent = this;
+ hook.timeout(this.timeout());
+ hook.ctx = this.ctx;
+ this._beforeEach.push(hook);
+ this.emit('beforeEach', hook);
+ return this;
+};
+
+/**
+ * Run `fn(test[, done])` after each test case.
+ *
+ * @param {Function} fn
+ * @return {Suite} for chaining
+ * @api private
+ */
+
+Suite.prototype.afterEach = function(fn){
+ var hook = new Hook('"after each" hook', fn);
+ hook.parent = this;
+ hook.timeout(this.timeout());
+ hook.ctx = this.ctx;
+ this._afterEach.push(hook);
+ this.emit('afterEach', hook);
+ return this;
+};
+
+/**
+ * Add a test `suite`.
+ *
+ * @param {Suite} suite
+ * @return {Suite} for chaining
+ * @api private
+ */
+
+Suite.prototype.addSuite = function(suite){
+ suite.parent = this;
+ suite.timeout(this.timeout());
+ suite.bail(this.bail());
+ this.suites.push(suite);
+ this.emit('suite', suite);
+ return this;
+};
+
+/**
+ * Add a `test` to this suite.
+ *
+ * @param {Test} test
+ * @return {Suite} for chaining
+ * @api private
+ */
+
+Suite.prototype.addTest = function(test){
+ test.parent = this;
+ test.timeout(this.timeout());
+ test.ctx = this.ctx;
+ this.tests.push(test);
+ this.emit('test', test);
+ return this;
+};
+
+/**
+ * Return the full title generated by recursively
+ * concatenating the parent's full title.
+ *
+ * @return {String}
+ * @api public
+ */
+
+Suite.prototype.fullTitle = function(){
+ if (this.parent) {
+ var full = this.parent.fullTitle();
+ if (full) return full + ' ' + this.title;
+ }
+ return this.title;
+};
+
+/**
+ * Return the total number of tests.
+ *
+ * @return {Number}
+ * @api public
+ */
+
+Suite.prototype.total = function(){
+ return utils.reduce(this.suites, function(sum, suite){
+ return sum + suite.total();
+ }, 0) + this.tests.length;
+};
+
+}); // module: suite.js
+
+require.register("test.js", function(module, exports, require){
+
+/**
+ * Module dependencies.
+ */
+
+var Runnable = require('./runnable');
+
+/**
+ * Expose `Test`.
+ */
+
+module.exports = Test;
+
+/**
+ * Initialize a new `Test` with the given `title` and callback `fn`.
+ *
+ * @param {String} title
+ * @param {Function} fn
+ * @api private
+ */
+
+function Test(title, fn) {
+ Runnable.call(this, title, fn);
+ this.pending = !fn;
+ this.type = 'test';
+}
+
+/**
+ * Inherit from `Runnable.prototype`.
+ */
+
+Test.prototype = new Runnable;
+Test.prototype.constructor = Test;
+
+
+/**
+ * Inspect the context void of private properties.
+ *
+ * @return {String}
+ * @api private
+ */
+
+Test.prototype.inspect = function(){
+ return JSON.stringify(this, function(key, val){
+ return '_' == key[0]
+ ? undefined
+ : 'parent' == key
+ ? '#<Suite>'
+ : val;
+ }, 2);
+};
+}); // module: test.js
+
+require.register("utils.js", function(module, exports, require){
+
+/**
+ * Module dependencies.
+ */
+
+var fs = require('browser/fs')
+ , path = require('browser/path')
+ , join = path.join
+ , debug = require('browser/debug')('watch');
+
+/**
+ * Ignored directories.
+ */
+
+var ignore = ['node_modules', '.git'];
+
+/**
+ * Escape special characters in the given string of html.
+ *
+ * @param {String} html
+ * @return {String}
+ * @api private
+ */
+
+exports.escape = function(html) {
+ return String(html)
+ .replace(/&/g, '&amp;')
+ .replace(/"/g, '&quot;')
+ .replace(/</g, '&lt;')
+ .replace(/>/g, '&gt;');
+};
+
+/**
+ * Array#forEach (<=IE8)
+ *
+ * @param {Array} array
+ * @param {Function} fn
+ * @param {Object} scope
+ * @api private
+ */
+
+exports.forEach = function(arr, fn, scope) {
+ for (var i = 0, l = arr.length; i < l; i++)
+ fn.call(scope, arr[i], i);
+};
+
+/**
+ * Array#indexOf (<=IE8)
+ *
+ * @parma {Array} arr
+ * @param {Object} obj to find index of
+ * @param {Number} start
+ * @api private
+ */
+
+exports.indexOf = function (arr, obj, start) {
+ for (var i = start || 0, l = arr.length; i < l; i++) {
+ if (arr[i] === obj)
+ return i;
+ }
+ return -1;
+};
+
+/**
+ * Array#reduce (<=IE8)
+ *
+ * @param {Array} array
+ * @param {Function} fn
+ * @param {Object} initial value
+ * @param {Object} scope
+ * @api private
+ */
+
+exports.reduce = function(arr, fn, val, scope) {
+ var rval = val;
+
+ for (var i = 0, l = arr.length; i < l; i++) {
+ rval = fn.call(scope, rval, arr[i], i, arr);
+ }
+
+ return rval;
+};
+
+/**
+ * Array#filter (<=IE8)
+ *
+ * @param {Array} array
+ * @param {Function} fn
+ * @param {Object} scope
+ * @api private
+ */
+
+exports.filter = function(arr, fn, scope) {
+ var ret = [];
+
+ for (var i = 0, l = arr.length; i < l; i++) {
+ var val = arr[i];
+ if (fn.call(scope, val, i, arr))
+ ret.push(val);
+ }
+
+ return ret;
+};
+
+/**
+ * Object.keys (<=IE8)
+ *
+ * @param {Object} obj
+ * @return {Array} keys
+ * @api private
+ */
+
+exports.keys = Object.keys || function(obj) {
+ var keys = []
+ , has = Object.prototype.hasOwnProperty // for `window` on <=IE8
+
+ for (var key in obj) {
+ if (has.call(obj, key)) {
+ keys.push(key);
+ }
+ }
+
+ return keys;
+};
+
+/**
+ * Watch the given `files` for changes
+ * and invoke `fn(file)` on modification.
+ *
+ * @param {Array} files
+ * @param {Function} fn
+ * @api private
+ */
+
+exports.watch = function(files, fn){
+ var options = { interval: 100 };
+ files.forEach(function(file){
+ debug('file %s', file);
+ fs.watchFile(file, options, function(curr, prev){
+ if (prev.mtime < curr.mtime) fn(file);
+ });
+ });
+};
+
+/**
+ * Ignored files.
+ */
+
+function ignored(path){
+ return !~ignore.indexOf(path);
+}
+
+/**
+ * Lookup files in the given `dir`.
+ *
+ * @return {Array}
+ * @api private
+ */
+
+exports.files = function(dir, ret){
+ ret = ret || [];
+
+ fs.readdirSync(dir)
+ .filter(ignored)
+ .forEach(function(path){
+ path = join(dir, path);
+ if (fs.statSync(path).isDirectory()) {
+ exports.files(path, ret);
+ } else if (path.match(/\.(js|coffee)$/)) {
+ ret.push(path);
+ }
+ });
+
+ return ret;
+};
+
+/**
+ * Compute a slug from the given `str`.
+ *
+ * @param {String} str
+ * @return {String}
+ */
+
+exports.slug = function(str){
+ return str
+ .toLowerCase()
+ .replace(/ +/g, '-')
+ .replace(/[^-\w]/g, '');
+};
+}); // module: utils.js
+/**
+ * Node shims.
+ *
+ * These are meant only to allow
+ * mocha.js to run untouched, not
+ * to allow running node code in
+ * the browser.
+ */
+
+process = {};
+process.exit = function(status){};
+process.stdout = {};
+global = window;
+
+/**
+ * next tick implementation.
+ */
+
+process.nextTick = (function(){
+ // postMessage behaves badly on IE8
+ if (window.ActiveXObject || !window.postMessage) {
+ return function(fn){ fn() };
+ }
+
+ // based on setZeroTimeout by David Baron
+ // - http://dbaron.org/log/20100309-faster-timeouts
+ var timeouts = []
+ , name = 'mocha-zero-timeout'
+
+ return function(fn){
+ timeouts.push(fn);
+ window.postMessage(name, '*');
+ window.addEventListener('message', function(e){
+ if (e.source == window && e.data == name) {
+ if (e.stopPropagation) e.stopPropagation();
+ if (timeouts.length) timeouts.shift()();
+ }
+ }, true);
+ }
+})();
+
+/**
+ * Remove uncaughtException listener.
+ */
+
+process.removeListener = function(e){
+ if ('uncaughtException' == e) {
+ window.onerror = null;
+ }
+};
+
+/**
+ * Implements uncaughtException listener.
+ */
+
+process.on = function(e, fn){
+ if ('uncaughtException' == e) {
+ window.onerror = fn;
+ }
+};
+
+/**
+ * Expose mocha.
+ */
+
+window.mocha = require('mocha');
+
+// boot
+;(function(){
+ var suite = new mocha.Suite('', new mocha.Context)
+ , utils = mocha.utils
+ , options = {}
+
+ /**
+ * Highlight the given string of `js`.
+ */
+
+ function highlight(js) {
+ return js
+ .replace(/</g, '&lt;')
+ .replace(/>/g, '&gt;')
+ .replace(/\/\/(.*)/gm, '<span class="comment">//$1</span>')
+ .replace(/('.*?')/gm, '<span class="string">$1</span>')
+ .replace(/(\d+\.\d+)/gm, '<span class="number">$1</span>')
+ .replace(/(\d+)/gm, '<span class="number">$1</span>')
+ .replace(/\bnew *(\w+)/gm, '<span class="keyword">new</span> <span class="init">$1</span>')
+ .replace(/\b(function|new|throw|return|var|if|else)\b/gm, '<span class="keyword">$1</span>')
+ }
+
+ /**
+ * Highlight code contents.
+ */
+
+ function highlightCode() {
+ var code = document.getElementsByTagName('code');
+ for (var i = 0, len = code.length; i < len; ++i) {
+ code[i].innerHTML = highlight(code[i].innerHTML);
+ }
+ }
+
+ /**
+ * Parse the given `qs`.
+ */
+
+ function parse(qs) {
+ return utils.reduce(qs.replace('?', '').split('&'), function(obj, pair){
+ var i = pair.indexOf('=')
+ , key = pair.slice(0, i)
+ , val = pair.slice(++i);
+
+ obj[key] = decodeURIComponent(val);
+ return obj;
+ }, {});
+ }
+
+ /**
+ * Setup mocha with the given setting options.
+ */
+
+ mocha.setup = function(opts){
+ if ('string' === typeof opts) options.ui = opts;
+ else options = opts;
+
+ ui = mocha.interfaces[options.ui];
+ if (!ui) throw new Error('invalid mocha interface "' + ui + '"');
+ if (options.timeout) suite.timeout(options.timeout);
+ ui(suite);
+ suite.emit('pre-require', window);
+ };
+
+ /**
+ * Run mocha, returning the Runner.
+ */
+
+ mocha.run = function(fn){
+ suite.emit('run');
+ var runner = new mocha.Runner(suite);
+ var Reporter = options.reporter || mocha.reporters.HTML;
+ var reporter = new Reporter(runner);
+ var query = parse(window.location.search || "");
+ if (query.grep) runner.grep(new RegExp(query.grep));
+ if (options.ignoreLeaks) runner.ignoreLeaks = true;
+ if (options.globals) runner.globals(options.globals);
+ runner.globals(['location']);
+ runner.on('end', highlightCode);
+ return runner.run(fn);
+ };
+})();
+})(); \ No newline at end of file
diff --git a/node_modules/mocha/node_modules/.bin/jade b/node_modules/mocha/node_modules/.bin/jade
new file mode 100755
index 0000000..fd4122c
--- /dev/null
+++ b/node_modules/mocha/node_modules/.bin/jade
@@ -0,0 +1,125 @@
+#!/usr/bin/env node
+
+/**
+ * Module dependencies.
+ */
+
+var fs = require('fs')
+ , program = require('commander')
+ , path = require('path')
+ , basename = path.basename
+ , dirname = path.dirname
+ , resolve = path.resolve
+ , join = path.join
+ , mkdirp = require('mkdirp')
+ , jade = require('../');
+
+// jade options
+
+var options = {};
+
+// options
+
+program
+ .version(jade.version)
+ .usage('[options] [dir|file ...]')
+ .option('-o, --obj <str>', 'javascript options object')
+ .option('-O, --out <dir>', 'output the compiled html to <dir>')
+ .option('-p, --path <path>', 'filename used to resolve includes')
+
+program.on('--help', function(){
+ console.log(' Examples:');
+ console.log('');
+ console.log(' # translate jade the templates dir');
+ console.log(' $ jade templates');
+ console.log('');
+ console.log(' # create {foo,bar}.html');
+ console.log(' $ jade {foo,bar}.jade');
+ console.log('');
+ console.log(' # jade over stdio');
+ console.log(' $ jade < my.jade > my.html');
+ console.log('');
+ console.log(' # jade over stdio');
+ console.log(' $ echo "h1 Jade!" | jade');
+ console.log('');
+ console.log(' # foo, bar dirs rendering to /tmp');
+ console.log(' $ jade foo bar --out /tmp ');
+ console.log('');
+});
+
+program.parse(process.argv);
+
+// options given, parse them
+
+if (program.obj) options = eval('(' + program.obj + ')');
+
+// filename
+
+if (program.path) options.filename = program.path;
+
+// left-over args are file paths
+
+var files = program.args;
+
+// compile files
+
+if (files.length) {
+ console.log();
+ files.forEach(renderFile);
+ process.on('exit', console.log);
+// stdio
+} else {
+ stdin();
+}
+
+/**
+ * Compile from stdin.
+ */
+
+function stdin() {
+ var buf = '';
+ process.stdin.setEncoding('utf8');
+ process.stdin.on('data', function(chunk){ buf += chunk; });
+ process.stdin.on('end', function(){
+ var fn = jade.compile(buf, options);
+ process.stdout.write(fn(options));
+ }).resume();
+}
+
+/**
+ * Process the given path, compiling the jade files found.
+ * Always walk the subdirectories.
+ */
+
+function renderFile(path) {
+ var re = /\.jade$/;
+ fs.lstat(path, function(err, stat) {
+ if (err) throw err;
+ // Found jade file
+ if (stat.isFile() && re.test(path)) {
+ fs.readFile(path, 'utf8', function(err, str){
+ if (err) throw err;
+ options.filename = path;
+ var fn = jade.compile(str, options);
+ path = path.replace(re, '.html');
+ if (program.out) path = join(program.out, basename(path));
+ var dir = resolve(dirname(path));
+ mkdirp(dir, 0755, function(err){
+ if (err) throw err;
+ fs.writeFile(path, fn(options), function(err){
+ if (err) throw err;
+ console.log(' \033[90mrendered \033[36m%s\033[0m', path);
+ });
+ });
+ });
+ // Found directory
+ } else if (stat.isDirectory()) {
+ fs.readdir(path, function(err, files) {
+ if (err) throw err;
+ files.map(function(filename) {
+ return path + '/' + filename;
+ }).forEach(renderFile);
+ });
+ }
+ });
+}
diff --git a/node_modules/mocha/node_modules/commander/.npmignore b/node_modules/mocha/node_modules/commander/.npmignore
new file mode 100644
index 0000000..f1250e5
--- /dev/null
+++ b/node_modules/mocha/node_modules/commander/.npmignore
@@ -0,0 +1,4 @@
+support
+test
+examples
+*.sock
diff --git a/node_modules/mocha/node_modules/commander/.travis.yml b/node_modules/mocha/node_modules/commander/.travis.yml
new file mode 100644
index 0000000..f1d0f13
--- /dev/null
+++ b/node_modules/mocha/node_modules/commander/.travis.yml
@@ -0,0 +1,4 @@
+language: node_js
+node_js:
+ - 0.4
+ - 0.6
diff --git a/node_modules/mocha/node_modules/commander/History.md b/node_modules/mocha/node_modules/commander/History.md
new file mode 100644
index 0000000..66c6894
--- /dev/null
+++ b/node_modules/mocha/node_modules/commander/History.md
@@ -0,0 +1,99 @@
+
+0.5.2 / 2012-01-17
+==================
+
+ * Added support for 0.7.x
+
+0.5.1 / 2011-12-20
+==================
+
+ * Fixed `password()` for recent nodes. Closes #36
+
+0.5.0 / 2011-12-04
+==================
+
+ * Added sub-command option support [itay]
+
+0.4.3 / 2011-12-04
+==================
+
+ * Fixed custom help ordering. Closes #32
+
+0.4.2 / 2011-11-24
+==================
+
+ * Added travis support
+ * Fixed: line-buffered input automatically trimmed. Closes #31
+
+0.4.1 / 2011-11-18
+==================
+
+ * Removed listening for "close" on --help
+
+0.4.0 / 2011-11-15
+==================
+
+ * Added support for `--`. Closes #24
+
+0.3.3 / 2011-11-14
+==================
+
+ * Fixed: wait for close event when writing help info [Jerry Hamlet]
+
+0.3.2 / 2011-11-01
+==================
+
+ * Fixed long flag definitions with values [felixge]
+
+0.3.1 / 2011-10-31
+==================
+
+ * Changed `--version` short flag to `-V` from `-v`
+ * Changed `.version()` so it's configurable [felixge]
+
+0.3.0 / 2011-10-31
+==================
+
+ * Added support for long flags only. Closes #18
+
+0.2.1 / 2011-10-24
+==================
+
+ * "node": ">= 0.4.x < 0.7.0". Closes #20
+
+0.2.0 / 2011-09-26
+==================
+
+ * Allow for defaults that are not just boolean. Default peassignment only occurs for --no-*, optional, and required arguments. [Jim Isaacs]
+
+0.1.0 / 2011-08-24
+==================
+
+ * Added support for custom `--help` output
+
+0.0.5 / 2011-08-18
+==================
+
+ * Changed: when the user enters nothing prompt for password again
+ * Fixed issue with passwords beginning with numbers [NuckChorris]
+
+0.0.4 / 2011-08-15
+==================
+
+ * Fixed `Commander#args`
+
+0.0.3 / 2011-08-15
+==================
+
+ * Added default option value support
+
+0.0.2 / 2011-08-15
+==================
+
+ * Added mask support to `Command#password(str[, mask], fn)`
+ * Added `Command#password(str, fn)`
+
+0.0.1 / 2010-01-03
+==================
+
+ * Initial release
diff --git a/node_modules/mocha/node_modules/commander/Makefile b/node_modules/mocha/node_modules/commander/Makefile
new file mode 100644
index 0000000..0074625
--- /dev/null
+++ b/node_modules/mocha/node_modules/commander/Makefile
@@ -0,0 +1,7 @@
+
+TESTS = $(shell find test/test.*.js)
+
+test:
+ @./test/run $(TESTS)
+
+.PHONY: test \ No newline at end of file
diff --git a/node_modules/mocha/node_modules/commander/Readme.md b/node_modules/mocha/node_modules/commander/Readme.md
new file mode 100644
index 0000000..2efbe7a
--- /dev/null
+++ b/node_modules/mocha/node_modules/commander/Readme.md
@@ -0,0 +1,263 @@
+
+# Commander.js
+
+ The complete solution for [node.js](http://nodejs.org) command-line interfaces, inspired by Ruby's [commander](https://github.com/visionmedia/commander).
+
+ [![Build Status](https://secure.travis-ci.org/visionmedia/commander.js.png)](http://travis-ci.org/visionmedia/commander.js)
+
+## Installation
+
+ $ npm install commander
+
+## Option parsing
+
+ Options with commander are defined with the `.option()` method, also serving as documentation for the options. The example below parses args and options from `process.argv`, leaving remaining args as the `program.args` array which were not consumed by options.
+
+```js
+#!/usr/bin/env node
+
+/**
+ * Module dependencies.
+ */
+
+var program = require('commander');
+
+program
+ .version('0.0.1')
+ .option('-p, --peppers', 'Add peppers')
+ .option('-P, --pineapple', 'Add pineapple')
+ .option('-b, --bbq', 'Add bbq sauce')
+ .option('-c, --cheese [type]', 'Add the specified type of cheese [marble]', 'marble')
+ .parse(process.argv);
+
+console.log('you ordered a pizza with:');
+if (program.peppers) console.log(' - peppers');
+if (program.pineapple) console.log(' - pineappe');
+if (program.bbq) console.log(' - bbq');
+console.log(' - %s cheese', program.cheese);
+```
+
+ Short flags may be passed as a single arg, for example `-abc` is equivalent to `-a -b -c`. Multi-word options such as "--template-engine" are camel-cased, becoming `program.templateEngine` etc.
+
+## Automated --help
+
+ The help information is auto-generated based on the information commander already knows about your program, so the following `--help` info is for free:
+
+```
+ $ ./examples/pizza --help
+
+ Usage: pizza [options]
+
+ Options:
+
+ -v, --version output the version number
+ -p, --peppers Add peppers
+ -P, --pineapple Add pineappe
+ -b, --bbq Add bbq sauce
+ -c, --cheese <type> Add the specified type of cheese [marble]
+ -h, --help output usage information
+
+```
+
+## Coercion
+
+```js
+function range(val) {
+ return val.split('..').map(Number);
+}
+
+function list(val) {
+ return val.split(',');
+}
+
+program
+ .version('0.0.1')
+ .usage('[options] <file ...>')
+ .option('-i, --integer <n>', 'An integer argument', parseInt)
+ .option('-f, --float <n>', 'A float argument', parseFloat)
+ .option('-r, --range <a>..<b>', 'A range', range)
+ .option('-l, --list <items>', 'A list', list)
+ .option('-o, --optional [value]', 'An optional value')
+ .parse(process.argv);
+
+console.log(' int: %j', program.integer);
+console.log(' float: %j', program.float);
+console.log(' optional: %j', program.optional);
+program.range = program.range || [];
+console.log(' range: %j..%j', program.range[0], program.range[1]);
+console.log(' list: %j', program.list);
+console.log(' args: %j', program.args);
+```
+
+## Custom help
+
+ You can display arbitrary `-h, --help` information
+ by listening for "--help". Commander will automatically
+ exit once you are done so that the remainder of your program
+ does not execute causing undesired behaviours, for example
+ in the following executable "stuff" will not output when
+ `--help` is used.
+
+```js
+#!/usr/bin/env node
+
+/**
+ * Module dependencies.
+ */
+
+var program = require('../');
+
+function list(val) {
+ return val.split(',').map(Number);
+}
+
+program
+ .version('0.0.1')
+ .option('-f, --foo', 'enable some foo')
+ .option('-b, --bar', 'enable some bar')
+ .option('-B, --baz', 'enable some baz');
+
+// must be before .parse() since
+// node's emit() is immediate
+
+program.on('--help', function(){
+ console.log(' Examples:');
+ console.log('');
+ console.log(' $ custom-help --help');
+ console.log(' $ custom-help -h');
+ console.log('');
+});
+
+program.parse(process.argv);
+
+console.log('stuff');
+```
+
+yielding the following help output:
+
+```
+
+Usage: custom-help [options]
+
+Options:
+
+ -h, --help output usage information
+ -v, --version output the version number
+ -f, --foo enable some foo
+ -b, --bar enable some bar
+ -B, --baz enable some baz
+
+Examples:
+
+ $ custom-help --help
+ $ custom-help -h
+
+```
+
+## .prompt(msg, fn)
+
+ Single-line prompt:
+
+```js
+program.prompt('name: ', function(name){
+ console.log('hi %s', name);
+});
+```
+
+ Multi-line prompt:
+
+```js
+program.prompt('description:', function(name){
+ console.log('hi %s', name);
+});
+```
+
+ Coercion:
+
+```js
+program.prompt('Age: ', Number, function(age){
+ console.log('age: %j', age);
+});
+```
+
+```js
+program.prompt('Birthdate: ', Date, function(date){
+ console.log('date: %s', date);
+});
+```
+
+## .password(msg[, mask], fn)
+
+Prompt for password without echoing:
+
+```js
+program.password('Password: ', function(pass){
+ console.log('got "%s"', pass);
+ process.stdin.destroy();
+});
+```
+
+Prompt for password with mask char "*":
+
+```js
+program.password('Password: ', '*', function(pass){
+ console.log('got "%s"', pass);
+ process.stdin.destroy();
+});
+```
+
+## .confirm(msg, fn)
+
+ Confirm with the given `msg`:
+
+```js
+program.confirm('continue? ', function(ok){
+ console.log(' got %j', ok);
+});
+```
+
+## .choose(list, fn)
+
+ Let the user choose from a `list`:
+
+```js
+var list = ['tobi', 'loki', 'jane', 'manny', 'luna'];
+
+console.log('Choose the coolest pet:');
+program.choose(list, function(i){
+ console.log('you chose %d "%s"', i, list[i]);
+});
+```
+
+## Links
+
+ - [API documentation](http://visionmedia.github.com/commander.js/)
+ - [ascii tables](https://github.com/LearnBoost/cli-table)
+ - [progress bars](https://github.com/visionmedia/node-progress)
+ - [more progress bars](https://github.com/substack/node-multimeter)
+ - [examples](https://github.com/visionmedia/commander.js/tree/master/examples)
+
+## License
+
+(The MIT License)
+
+Copyright (c) 2011 TJ Holowaychuk &lt;tj@vision-media.ca&gt;
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+'Software'), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file
diff --git a/node_modules/mocha/node_modules/commander/index.js b/node_modules/mocha/node_modules/commander/index.js
new file mode 100644
index 0000000..06ec1e4
--- /dev/null
+++ b/node_modules/mocha/node_modules/commander/index.js
@@ -0,0 +1,2 @@
+
+module.exports = require('./lib/commander'); \ No newline at end of file
diff --git a/node_modules/mocha/node_modules/commander/lib/commander.js b/node_modules/mocha/node_modules/commander/lib/commander.js
new file mode 100644
index 0000000..b9cbd5d
--- /dev/null
+++ b/node_modules/mocha/node_modules/commander/lib/commander.js
@@ -0,0 +1,992 @@
+
+/*!
+ * commander
+ * Copyright(c) 2011 TJ Holowaychuk <tj@vision-media.ca>
+ * MIT Licensed
+ */
+
+/**
+ * Module dependencies.
+ */
+
+var EventEmitter = require('events').EventEmitter
+ , path = require('path')
+ , tty = require('tty')
+ , basename = path.basename;
+
+/**
+ * Expose the root command.
+ */
+
+exports = module.exports = new Command;
+
+/**
+ * Expose `Command`.
+ */
+
+exports.Command = Command;
+
+/**
+ * Expose `Option`.
+ */
+
+exports.Option = Option;
+
+/**
+ * Initialize a new `Option` with the given `flags` and `description`.
+ *
+ * @param {String} flags
+ * @param {String} description
+ * @api public
+ */
+
+function Option(flags, description) {
+ this.flags = flags;
+ this.required = ~flags.indexOf('<');
+ this.optional = ~flags.indexOf('[');
+ this.bool = !~flags.indexOf('-no-');
+ flags = flags.split(/[ ,|]+/);
+ if (flags.length > 1 && !/^[[<]/.test(flags[1])) this.short = flags.shift();
+ this.long = flags.shift();
+ this.description = description;
+}
+
+/**
+ * Return option name.
+ *
+ * @return {String}
+ * @api private
+ */
+
+Option.prototype.name = function(){
+ return this.long
+ .replace('--', '')
+ .replace('no-', '');
+};
+
+/**
+ * Check if `arg` matches the short or long flag.
+ *
+ * @param {String} arg
+ * @return {Boolean}
+ * @api private
+ */
+
+Option.prototype.is = function(arg){
+ return arg == this.short
+ || arg == this.long;
+};
+
+/**
+ * Initialize a new `Command`.
+ *
+ * @param {String} name
+ * @api public
+ */
+
+function Command(name) {
+ this.commands = [];
+ this.options = [];
+ this.args = [];
+ this.name = name;
+}
+
+/**
+ * Inherit from `EventEmitter.prototype`.
+ */
+
+Command.prototype.__proto__ = EventEmitter.prototype;
+
+/**
+ * Add command `name`.
+ *
+ * The `.action()` callback is invoked when the
+ * command `name` is specified via __ARGV__,
+ * and the remaining arguments are applied to the
+ * function for access.
+ *
+ * When the `name` is "*" an un-matched command
+ * will be passed as the first arg, followed by
+ * the rest of __ARGV__ remaining.
+ *
+ * Examples:
+ *
+ * program
+ * .version('0.0.1')
+ * .option('-C, --chdir <path>', 'change the working directory')
+ * .option('-c, --config <path>', 'set config path. defaults to ./deploy.conf')
+ * .option('-T, --no-tests', 'ignore test hook')
+ *
+ * program
+ * .command('setup')
+ * .description('run remote setup commands')
+ * .action(function(){
+ * console.log('setup');
+ * });
+ *
+ * program
+ * .command('exec <cmd>')
+ * .description('run the given remote command')
+ * .action(function(cmd){
+ * console.log('exec "%s"', cmd);
+ * });
+ *
+ * program
+ * .command('*')
+ * .description('deploy the given env')
+ * .action(function(env){
+ * console.log('deploying "%s"', env);
+ * });
+ *
+ * program.parse(process.argv);
+ *
+ * @param {String} name
+ * @return {Command} the new command
+ * @api public
+ */
+
+Command.prototype.command = function(name){
+ var args = name.split(/ +/);
+ var cmd = new Command(args.shift());
+ this.commands.push(cmd);
+ cmd.parseExpectedArgs(args);
+ cmd.parent = this;
+ return cmd;
+};
+
+/**
+ * Parse expected `args`.
+ *
+ * For example `["[type]"]` becomes `[{ required: false, name: 'type' }]`.
+ *
+ * @param {Array} args
+ * @return {Command} for chaining
+ * @api public
+ */
+
+Command.prototype.parseExpectedArgs = function(args){
+ if (!args.length) return;
+ var self = this;
+ args.forEach(function(arg){
+ switch (arg[0]) {
+ case '<':
+ self.args.push({ required: true, name: arg.slice(1, -1) });
+ break;
+ case '[':
+ self.args.push({ required: false, name: arg.slice(1, -1) });
+ break;
+ }
+ });
+ return this;
+};
+
+/**
+ * Register callback `fn` for the command.
+ *
+ * Examples:
+ *
+ * program
+ * .command('help')
+ * .description('display verbose help')
+ * .action(function(){
+ * // output help here
+ * });
+ *
+ * @param {Function} fn
+ * @return {Command} for chaining
+ * @api public
+ */
+
+Command.prototype.action = function(fn){
+ var self = this;
+ this.parent.on(this.name, function(args, unknown){
+ // Parse any so-far unknown options
+ unknown = unknown || [];
+ var parsed = self.parseOptions(unknown);
+
+ // Output help if necessary
+ outputHelpIfNecessary(self, parsed.unknown);
+
+ // If there are still any unknown options, then we simply
+ // die, unless someone asked for help, in which case we give it
+ // to them, and then we die.
+ if (parsed.unknown.length > 0) {
+ self.unknownOption(parsed.unknown[0]);
+ }
+
+ self.args.forEach(function(arg, i){
+ if (arg.required && null == args[i]) {
+ self.missingArgument(arg.name);
+ }
+ });
+
+ // Always append ourselves to the end of the arguments,
+ // to make sure we match the number of arguments the user
+ // expects
+ if (self.args.length) {
+ args[self.args.length] = self;
+ } else {
+ args.push(self);
+ }
+
+ fn.apply(this, args);
+ });
+ return this;
+};
+
+/**
+ * Define option with `flags`, `description` and optional
+ * coercion `fn`.
+ *
+ * The `flags` string should contain both the short and long flags,
+ * separated by comma, a pipe or space. The following are all valid
+ * all will output this way when `--help` is used.
+ *
+ * "-p, --pepper"
+ * "-p|--pepper"
+ * "-p --pepper"
+ *
+ * Examples:
+ *
+ * // simple boolean defaulting to false
+ * program.option('-p, --pepper', 'add pepper');
+ *
+ * --pepper
+ * program.pepper
+ * // => Boolean
+ *
+ * // simple boolean defaulting to false
+ * program.option('-C, --no-cheese', 'remove cheese');
+ *
+ * program.cheese
+ * // => true
+ *
+ * --no-cheese
+ * program.cheese
+ * // => true
+ *
+ * // required argument
+ * program.option('-C, --chdir <path>', 'change the working directory');
+ *
+ * --chdir /tmp
+ * program.chdir
+ * // => "/tmp"
+ *
+ * // optional argument
+ * program.option('-c, --cheese [type]', 'add cheese [marble]');
+ *
+ * @param {String} flags
+ * @param {String} description
+ * @param {Function|Mixed} fn or default
+ * @param {Mixed} defaultValue
+ * @return {Command} for chaining
+ * @api public
+ */
+
+Command.prototype.option = function(flags, description, fn, defaultValue){
+ var self = this
+ , option = new Option(flags, description)
+ , oname = option.name()
+ , name = camelcase(oname);
+
+ // default as 3rd arg
+ if ('function' != typeof fn) defaultValue = fn, fn = null;
+
+ // preassign default value only for --no-*, [optional], or <required>
+ if (false == option.bool || option.optional || option.required) {
+ // when --no-* we make sure default is true
+ if (false == option.bool) defaultValue = true;
+ // preassign only if we have a default
+ if (undefined !== defaultValue) self[name] = defaultValue;
+ }
+
+ // register the option
+ this.options.push(option);
+
+ // when it's passed assign the value
+ // and conditionally invoke the callback
+ this.on(oname, function(val){
+ // coercion
+ if (null != val && fn) val = fn(val);
+
+ // unassigned or bool
+ if ('boolean' == typeof self[name] || 'undefined' == typeof self[name]) {
+ // if no value, bool true, and we have a default, then use it!
+ if (null == val) {
+ self[name] = option.bool
+ ? defaultValue || true
+ : false;
+ } else {
+ self[name] = val;
+ }
+ } else if (null !== val) {
+ // reassign
+ self[name] = val;
+ }
+ });
+
+ return this;
+};
+
+/**
+ * Parse `argv`, settings options and invoking commands when defined.
+ *
+ * @param {Array} argv
+ * @return {Command} for chaining
+ * @api public
+ */
+
+Command.prototype.parse = function(argv){
+ // store raw args
+ this.rawArgs = argv;
+
+ // guess name
+ if (!this.name) this.name = basename(argv[1]);
+
+ // process argv
+ var parsed = this.parseOptions(this.normalize(argv.slice(2)));
+ this.args = parsed.args;
+ return this.parseArgs(this.args, parsed.unknown);
+};
+
+/**
+ * Normalize `args`, splitting joined short flags. For example
+ * the arg "-abc" is equivalent to "-a -b -c".
+ *
+ * @param {Array} args
+ * @return {Array}
+ * @api private
+ */
+
+Command.prototype.normalize = function(args){
+ var ret = []
+ , arg;
+
+ for (var i = 0, len = args.length; i < len; ++i) {
+ arg = args[i];
+ if (arg.length > 1 && '-' == arg[0] && '-' != arg[1]) {
+ arg.slice(1).split('').forEach(function(c){
+ ret.push('-' + c);
+ });
+ } else {
+ ret.push(arg);
+ }
+ }
+
+ return ret;
+};
+
+/**
+ * Parse command `args`.
+ *
+ * When listener(s) are available those
+ * callbacks are invoked, otherwise the "*"
+ * event is emitted and those actions are invoked.
+ *
+ * @param {Array} args
+ * @return {Command} for chaining
+ * @api private
+ */
+
+Command.prototype.parseArgs = function(args, unknown){
+ var cmds = this.commands
+ , len = cmds.length
+ , name;
+
+ if (args.length) {
+ name = args[0];
+ if (this.listeners(name).length) {
+ this.emit(args.shift(), args, unknown);
+ } else {
+ this.emit('*', args);
+ }
+ } else {
+ outputHelpIfNecessary(this, unknown);
+
+ // If there were no args and we have unknown options,
+ // then they are extraneous and we need to error.
+ if (unknown.length > 0) {
+ this.unknownOption(unknown[0]);
+ }
+ }
+
+ return this;
+};
+
+/**
+ * Return an option matching `arg` if any.
+ *
+ * @param {String} arg
+ * @return {Option}
+ * @api private
+ */
+
+Command.prototype.optionFor = function(arg){
+ for (var i = 0, len = this.options.length; i < len; ++i) {
+ if (this.options[i].is(arg)) {
+ return this.options[i];
+ }
+ }
+};
+
+/**
+ * Parse options from `argv` returning `argv`
+ * void of these options.
+ *
+ * @param {Array} argv
+ * @return {Array}
+ * @api public
+ */
+
+Command.prototype.parseOptions = function(argv){
+ var args = []
+ , len = argv.length
+ , literal
+ , option
+ , arg;
+
+ var unknownOptions = [];
+
+ // parse options
+ for (var i = 0; i < len; ++i) {
+ arg = argv[i];
+
+ // literal args after --
+ if ('--' == arg) {
+ literal = true;
+ continue;
+ }
+
+ if (literal) {
+ args.push(arg);
+ continue;
+ }
+
+ // find matching Option
+ option = this.optionFor(arg);
+
+ // option is defined
+ if (option) {
+ // requires arg
+ if (option.required) {
+ arg = argv[++i];
+ if (null == arg) return this.optionMissingArgument(option);
+ if ('-' == arg[0]) return this.optionMissingArgument(option, arg);
+ this.emit(option.name(), arg);
+ // optional arg
+ } else if (option.optional) {
+ arg = argv[i+1];
+ if (null == arg || '-' == arg[0]) {
+ arg = null;
+ } else {
+ ++i;
+ }
+ this.emit(option.name(), arg);
+ // bool
+ } else {
+ this.emit(option.name());
+ }
+ continue;
+ }
+
+ // looks like an option
+ if (arg.length > 1 && '-' == arg[0]) {
+ unknownOptions.push(arg);
+
+ // If the next argument looks like it might be
+ // an argument for this option, we pass it on.
+ // If it isn't, then it'll simply be ignored
+ if (argv[i+1] && '-' != argv[i+1][0]) {
+ unknownOptions.push(argv[++i]);
+ }
+ continue;
+ }
+
+ // arg
+ args.push(arg);
+ }
+
+ return { args: args, unknown: unknownOptions };
+};
+
+/**
+ * Argument `name` is missing.
+ *
+ * @param {String} name
+ * @api private
+ */
+
+Command.prototype.missingArgument = function(name){
+ console.error();
+ console.error(" error: missing required argument `%s'", name);
+ console.error();
+ process.exit(1);
+};
+
+/**
+ * `Option` is missing an argument, but received `flag` or nothing.
+ *
+ * @param {String} option
+ * @param {String} flag
+ * @api private
+ */
+
+Command.prototype.optionMissingArgument = function(option, flag){
+ console.error();
+ if (flag) {
+ console.error(" error: option `%s' argument missing, got `%s'", option.flags, flag);
+ } else {
+ console.error(" error: option `%s' argument missing", option.flags);
+ }
+ console.error();
+ process.exit(1);
+};
+
+/**
+ * Unknown option `flag`.
+ *
+ * @param {String} flag
+ * @api private
+ */
+
+Command.prototype.unknownOption = function(flag){
+ console.error();
+ console.error(" error: unknown option `%s'", flag);
+ console.error();
+ process.exit(1);
+};
+
+/**
+ * Set the program version to `str`.
+ *
+ * This method auto-registers the "-V, --version" flag
+ * which will print the version number when passed.
+ *
+ * @param {String} str
+ * @param {String} flags
+ * @return {Command} for chaining
+ * @api public
+ */
+
+Command.prototype.version = function(str, flags){
+ if (0 == arguments.length) return this._version;
+ this._version = str;
+ flags = flags || '-V, --version';
+ this.option(flags, 'output the version number');
+ this.on('version', function(){
+ console.log(str);
+ process.exit(0);
+ });
+ return this;
+};
+
+/**
+ * Set the description `str`.
+ *
+ * @param {String} str
+ * @return {String|Command}
+ * @api public
+ */
+
+Command.prototype.description = function(str){
+ if (0 == arguments.length) return this._description;
+ this._description = str;
+ return this;
+};
+
+/**
+ * Set / get the command usage `str`.
+ *
+ * @param {String} str
+ * @return {String|Command}
+ * @api public
+ */
+
+Command.prototype.usage = function(str){
+ var args = this.args.map(function(arg){
+ return arg.required
+ ? '<' + arg.name + '>'
+ : '[' + arg.name + ']';
+ });
+
+ var usage = '[options'
+ + (this.commands.length ? '] [command' : '')
+ + ']'
+ + (this.args.length ? ' ' + args : '');
+ if (0 == arguments.length) return this._usage || usage;
+ this._usage = str;
+
+ return this;
+};
+
+/**
+ * Return the largest option length.
+ *
+ * @return {Number}
+ * @api private
+ */
+
+Command.prototype.largestOptionLength = function(){
+ return this.options.reduce(function(max, option){
+ return Math.max(max, option.flags.length);
+ }, 0);
+};
+
+/**
+ * Return help for options.
+ *
+ * @return {String}
+ * @api private
+ */
+
+Command.prototype.optionHelp = function(){
+ var width = this.largestOptionLength();
+
+ // Prepend the help information
+ return [pad('-h, --help', width) + ' ' + 'output usage information']
+ .concat(this.options.map(function(option){
+ return pad(option.flags, width)
+ + ' ' + option.description;
+ }))
+ .join('\n');
+};
+
+/**
+ * Return command help documentation.
+ *
+ * @return {String}
+ * @api private
+ */
+
+Command.prototype.commandHelp = function(){
+ if (!this.commands.length) return '';
+ return [
+ ''
+ , ' Commands:'
+ , ''
+ , this.commands.map(function(cmd){
+ var args = cmd.args.map(function(arg){
+ return arg.required
+ ? '<' + arg.name + '>'
+ : '[' + arg.name + ']';
+ }).join(' ');
+
+ return cmd.name
+ + (cmd.options.length
+ ? ' [options]'
+ : '') + ' ' + args
+ + (cmd.description()
+ ? '\n' + cmd.description()
+ : '');
+ }).join('\n\n').replace(/^/gm, ' ')
+ , ''
+ ].join('\n');
+};
+
+/**
+ * Return program help documentation.
+ *
+ * @return {String}
+ * @api private
+ */
+
+Command.prototype.helpInformation = function(){
+ return [
+ ''
+ , ' Usage: ' + this.name + ' ' + this.usage()
+ , '' + this.commandHelp()
+ , ' Options:'
+ , ''
+ , '' + this.optionHelp().replace(/^/gm, ' ')
+ , ''
+ , ''
+ ].join('\n');
+};
+
+/**
+ * Prompt for a `Number`.
+ *
+ * @param {String} str
+ * @param {Function} fn
+ * @api private
+ */
+
+Command.prototype.promptForNumber = function(str, fn){
+ var self = this;
+ this.promptSingleLine(str, function parseNumber(val){
+ val = Number(val);
+ if (isNaN(val)) return self.promptSingleLine(str + '(must be a number) ', parseNumber);
+ fn(val);
+ });
+};
+
+/**
+ * Prompt for a `Date`.
+ *
+ * @param {String} str
+ * @param {Function} fn
+ * @api private
+ */
+
+Command.prototype.promptForDate = function(str, fn){
+ var self = this;
+ this.promptSingleLine(str, function parseDate(val){
+ val = new Date(val);
+ if (isNaN(val.getTime())) return self.promptSingleLine(str + '(must be a date) ', parseDate);
+ fn(val);
+ });
+};
+
+/**
+ * Single-line prompt.
+ *
+ * @param {String} str
+ * @param {Function} fn
+ * @api private
+ */
+
+Command.prototype.promptSingleLine = function(str, fn){
+ if ('function' == typeof arguments[2]) {
+ return this['promptFor' + (fn.name || fn)](str, arguments[2]);
+ }
+
+ process.stdout.write(str);
+ process.stdin.setEncoding('utf8');
+ process.stdin.once('data', function(val){
+ fn(val.trim());
+ }).resume();
+};
+
+/**
+ * Multi-line prompt.
+ *
+ * @param {String} str
+ * @param {Function} fn
+ * @api private
+ */
+
+Command.prototype.promptMultiLine = function(str, fn){
+ var buf = [];
+ console.log(str);
+ process.stdin.setEncoding('utf8');
+ process.stdin.on('data', function(val){
+ if ('\n' == val || '\r\n' == val) {
+ process.stdin.removeAllListeners('data');
+ fn(buf.join('\n'));
+ } else {
+ buf.push(val.trimRight());
+ }
+ }).resume();
+};
+
+/**
+ * Prompt `str` and callback `fn(val)`
+ *
+ * Commander supports single-line and multi-line prompts.
+ * To issue a single-line prompt simply add white-space
+ * to the end of `str`, something like "name: ", whereas
+ * for a multi-line prompt omit this "description:".
+ *
+ *
+ * Examples:
+ *
+ * program.prompt('Username: ', function(name){
+ * console.log('hi %s', name);
+ * });
+ *
+ * program.prompt('Description:', function(desc){
+ * console.log('description was "%s"', desc.trim());
+ * });
+ *
+ * @param {String} str
+ * @param {Function} fn
+ * @api public
+ */
+
+Command.prototype.prompt = function(str, fn){
+ if (/ $/.test(str)) return this.promptSingleLine.apply(this, arguments);
+ this.promptMultiLine(str, fn);
+};
+
+/**
+ * Prompt for password with `str`, `mask` char and callback `fn(val)`.
+ *
+ * The mask string defaults to '', aka no output is
+ * written while typing, you may want to use "*" etc.
+ *
+ * Examples:
+ *
+ * program.password('Password: ', function(pass){
+ * console.log('got "%s"', pass);
+ * process.stdin.destroy();
+ * });
+ *
+ * program.password('Password: ', '*', function(pass){
+ * console.log('got "%s"', pass);
+ * process.stdin.destroy();
+ * });
+ *
+ * @param {String} str
+ * @param {String} mask
+ * @param {Function} fn
+ * @api public
+ */
+
+Command.prototype.password = function(str, mask, fn){
+ var self = this
+ , buf = '';
+
+ // default mask
+ if ('function' == typeof mask) {
+ fn = mask;
+ mask = '';
+ }
+
+ process.stdin.resume();
+ tty.setRawMode(true);
+ process.stdout.write(str);
+
+ // keypress
+ process.stdin.on('keypress', function(c, key){
+ if (key && 'enter' == key.name) {
+ console.log();
+ process.stdin.removeAllListeners('keypress');
+ tty.setRawMode(false);
+ if (!buf.trim().length) return self.password(str, mask, fn);
+ fn(buf);
+ return;
+ }
+
+ if (key && key.ctrl && 'c' == key.name) {
+ console.log('%s', buf);
+ process.exit();
+ }
+
+ process.stdout.write(mask);
+ buf += c;
+ }).resume();
+};
+
+/**
+ * Confirmation prompt with `str` and callback `fn(bool)`
+ *
+ * Examples:
+ *
+ * program.confirm('continue? ', function(ok){
+ * console.log(' got %j', ok);
+ * process.stdin.destroy();
+ * });
+ *
+ * @param {String} str
+ * @param {Function} fn
+ * @api public
+ */
+
+
+Command.prototype.confirm = function(str, fn){
+ var self = this;
+ this.prompt(str, function(ok){
+ if (!ok.trim()) {
+ return self.confirm(str, fn);
+ }
+ fn(parseBool(ok));
+ });
+};
+
+/**
+ * Choice prompt with `list` of items and callback `fn(index, item)`
+ *
+ * Examples:
+ *
+ * var list = ['tobi', 'loki', 'jane', 'manny', 'luna'];
+ *
+ * console.log('Choose the coolest pet:');
+ * program.choose(list, function(i){
+ * console.log('you chose %d "%s"', i, list[i]);
+ * process.stdin.destroy();
+ * });
+ *
+ * @param {Array} list
+ * @param {Function} fn
+ * @api public
+ */
+
+Command.prototype.choose = function(list, fn){
+ var self = this;
+
+ list.forEach(function(item, i){
+ console.log(' %d) %s', i + 1, item);
+ });
+
+ function again() {
+ self.prompt(' : ', function(val){
+ val = parseInt(val, 10) - 1;
+ if (null == list[val]) {
+ again();
+ } else {
+ fn(val, list[val]);
+ }
+ });
+ }
+
+ again();
+};
+
+/**
+ * Camel-case the given `flag`
+ *
+ * @param {String} flag
+ * @return {String}
+ * @api private
+ */
+
+function camelcase(flag) {
+ return flag.split('-').reduce(function(str, word){
+ return str + word[0].toUpperCase() + word.slice(1);
+ });
+}
+
+/**
+ * Parse a boolean `str`.
+ *
+ * @param {String} str
+ * @return {Boolean}
+ * @api private
+ */
+
+function parseBool(str) {
+ return /^y|yes|ok|true$/i.test(str);
+}
+
+/**
+ * Pad `str` to `width`.
+ *
+ * @param {String} str
+ * @param {Number} width
+ * @return {String}
+ * @api private
+ */
+
+function pad(str, width) {
+ var len = Math.max(0, width - str.length);
+ return str + Array(len + 1).join(' ');
+}
+
+/**
+ * Output help information if necessary
+ *
+ * @param {Command} command to output help for
+ * @param {Array} array of options to search for -h or --help
+ * @api private
+ */
+
+function outputHelpIfNecessary(cmd, options) {
+ options = options || [];
+ for (var i = 0; i < options.length; i++) {
+ if (options[i] == '--help' || options[i] == '-h') {
+ process.stdout.write(cmd.helpInformation());
+ cmd.emit('--help');
+ process.exit(0);
+ }
+ }
+}
diff --git a/node_modules/mocha/node_modules/commander/package.json b/node_modules/mocha/node_modules/commander/package.json
new file mode 100644
index 0000000..b200164
--- /dev/null
+++ b/node_modules/mocha/node_modules/commander/package.json
@@ -0,0 +1,38 @@
+{
+ "name": "commander",
+ "version": "0.5.2",
+ "description": "the complete solution for node.js command-line programs",
+ "keywords": [
+ "command",
+ "option",
+ "parser",
+ "prompt",
+ "stdin"
+ ],
+ "author": {
+ "name": "TJ Holowaychuk",
+ "email": "tj@vision-media.ca"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/visionmedia/commander.js.git"
+ },
+ "dependencies": {},
+ "devDependencies": {
+ "should": ">= 0.0.1"
+ },
+ "scripts": {
+ "test": "make test"
+ },
+ "main": "index",
+ "engines": {
+ "node": ">= 0.4.x < 0.8.0"
+ },
+ "_id": "commander@0.5.2",
+ "optionalDependencies": {},
+ "_engineSupported": true,
+ "_npmVersion": "1.1.12",
+ "_nodeVersion": "v0.6.14",
+ "_defaultsLoaded": true,
+ "_from": "commander@0.5.x"
+}
diff --git a/node_modules/mocha/node_modules/debug/.npmignore b/node_modules/mocha/node_modules/debug/.npmignore
new file mode 100644
index 0000000..f1250e5
--- /dev/null
+++ b/node_modules/mocha/node_modules/debug/.npmignore
@@ -0,0 +1,4 @@
+support
+test
+examples
+*.sock
diff --git a/node_modules/mocha/node_modules/debug/History.md b/node_modules/mocha/node_modules/debug/History.md
new file mode 100644
index 0000000..f3c1a98
--- /dev/null
+++ b/node_modules/mocha/node_modules/debug/History.md
@@ -0,0 +1,41 @@
+
+0.6.0 / 2012-03-16
+==================
+
+ * Added support for "-" prefix in DEBUG [Vinay Pulim]
+ * Added `.enabled` flag to the node version [TooTallNate]
+
+0.5.0 / 2012-02-02
+==================
+
+ * Added: humanize diffs. Closes #8
+ * Added `debug.disable()` to the CS variant
+ * Removed padding. Closes #10
+ * Fixed: persist client-side variant again. Closes #9
+
+0.4.0 / 2012-02-01
+==================
+
+ * Added browser variant support for older browsers [TooTallNate]
+ * Added `debug.enable('project:*')` to browser variant [TooTallNate]
+ * Added padding to diff (moved it to the right)
+
+0.3.0 / 2012-01-26
+==================
+
+ * Added millisecond diff when isatty, otherwise UTC string
+
+0.2.0 / 2012-01-22
+==================
+
+ * Added wildcard support
+
+0.1.0 / 2011-12-02
+==================
+
+ * Added: remove colors unless stderr isatty [TooTallNate]
+
+0.0.1 / 2010-01-03
+==================
+
+ * Initial release
diff --git a/node_modules/mocha/node_modules/debug/Makefile b/node_modules/mocha/node_modules/debug/Makefile
new file mode 100644
index 0000000..36a3ed7
--- /dev/null
+++ b/node_modules/mocha/node_modules/debug/Makefile
@@ -0,0 +1,5 @@
+
+test:
+ @echo "populate me"
+
+.PHONY: test \ No newline at end of file
diff --git a/node_modules/mocha/node_modules/debug/Readme.md b/node_modules/mocha/node_modules/debug/Readme.md
new file mode 100644
index 0000000..419fcdf
--- /dev/null
+++ b/node_modules/mocha/node_modules/debug/Readme.md
@@ -0,0 +1,130 @@
+
+# debug
+
+ tiny node.js debugging utility.
+
+## Installation
+
+```
+$ npm install debug
+```
+
+## Example
+
+ This module is modelled after node core's debugging technique, allowing you to enable one or more topic-specific debugging functions, for example core does the following within many modules:
+
+```js
+var debug;
+if (process.env.NODE_DEBUG && /cluster/.test(process.env.NODE_DEBUG)) {
+ debug = function(x) {
+ var prefix = process.pid + ',' +
+ (process.env.NODE_WORKER_ID ? 'Worker' : 'Master');
+ console.error(prefix, x);
+ };
+} else {
+ debug = function() { };
+}
+```
+
+ This concept is extremely simple but it works well. With `debug` you simply invoke the exported function to generate your debug function, passing it a name which will determine if a noop function is returned, or a decorated `console.error`, so all of the `console` format string goodies you're used to work fine. A unique color is selected per-function for visibility.
+
+Example _app.js_:
+
+```js
+var debug = require('debug')('http')
+ , http = require('http')
+ , name = 'My App';
+
+// fake app
+
+debug('booting %s', name);
+
+http.createServer(function(req, res){
+ debug(req.method + ' ' + req.url);
+ res.end('hello\n');
+}).listen(3000, function(){
+ debug('listening');
+});
+
+// fake worker of some kind
+
+require('./worker');
+```
+
+Example _worker.js_:
+
+```js
+var debug = require('debug')('worker');
+
+setInterval(function(){
+ debug('doing some work');
+}, 1000);
+```
+
+ The __DEBUG__ environment variable is then used to enable these based on space or comma-delimited names. Here are some examples:
+
+ ![debug http and worker](http://f.cl.ly/items/18471z1H402O24072r1J/Screenshot.png)
+
+ ![debug worker](http://f.cl.ly/items/1X413v1a3M0d3C2c1E0i/Screenshot.png)
+
+## Millisecond diff
+
+ When actively developing an application it can be useful to see when the time spent between one `debug()` call and the next. Suppose for example you invoke `debug()` before requesting a resource, and after as well, the "+NNNms" will show you how much time was spent between calls.
+
+ ![](http://f.cl.ly/items/2i3h1d3t121M2Z1A3Q0N/Screenshot.png)
+
+ When stdout is not a TTY, `Date#toUTCString()` is used, making it more useful for logging the debug information as shown below:
+
+ ![](http://f.cl.ly/items/112H3i0e0o0P0a2Q2r11/Screenshot.png)
+
+## Conventions
+
+ If you're using this in one or more of your libraries, you _should_ use the name of your library so that developers may toggle debugging as desired without guessing names. If you have more than one debuggers you _should_ prefix them with your library name and use ":" to separate features. For example "bodyParser" from Connect would then be "connect:bodyParser".
+
+## Wildcards
+
+ The "*" character may be used as a wildcard. Suppose for example your library has debuggers named "connect:bodyParser", "connect:compress", "connect:session", instead of listing all three with `DEBUG=connect:bodyParser,connect.compress,connect:session`, you may simply do `DEBUG=connect:*`, or to run everything using this module simply use `DEBUG=*`.
+
+ You can also exclude specific debuggers by prefixing them with a "-" character. For example, `DEBUG=* -connect:*` would include all debuggers except those starting with "connect:".
+
+## Browser support
+
+ Debug works in the browser as well, currently persisted by `localStorage`. For example if you have `worker:a` and `worker:b` as shown below, and wish to debug both type `debug.enable('worker:*')` in the console and refresh the page, this will remain until you disable with `debug.disable()`.
+
+```js
+a = debug('worker:a');
+b = debug('worker:b');
+
+setInterval(function(){
+ a('doing some work');
+}, 1000);
+
+setInterval(function(){
+ a('doing some work');
+}, 1200);
+```
+
+## License
+
+(The MIT License)
+
+Copyright (c) 2011 TJ Holowaychuk &lt;tj@vision-media.ca&gt;
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+'Software'), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file
diff --git a/node_modules/mocha/node_modules/debug/debug.js b/node_modules/mocha/node_modules/debug/debug.js
new file mode 100644
index 0000000..b2f0798
--- /dev/null
+++ b/node_modules/mocha/node_modules/debug/debug.js
@@ -0,0 +1,122 @@
+
+/*!
+ * debug
+ * Copyright(c) 2012 TJ Holowaychuk <tj@vision-media.ca>
+ * MIT Licensed
+ */
+
+/**
+ * Create a debugger with the given `name`.
+ *
+ * @param {String} name
+ * @return {Type}
+ * @api public
+ */
+
+function debug(name) {
+ if (!debug.enabled(name)) return function(){};
+
+ return function(fmt){
+ var curr = new Date;
+ var ms = curr - (debug[name] || curr);
+ debug[name] = curr;
+
+ fmt = name
+ + ' '
+ + fmt
+ + ' +' + debug.humanize(ms);
+
+ // This hackery is required for IE8
+ // where `console.log` doesn't have 'apply'
+ window.console
+ && console.log
+ && Function.prototype.apply.call(console.log, console, arguments);
+ }
+}
+
+/**
+ * The currently active debug mode names.
+ */
+
+debug.names = [];
+debug.skips = [];
+
+/**
+ * Enables a debug mode by name. This can include modes
+ * separated by a colon and wildcards.
+ *
+ * @param {String} name
+ * @api public
+ */
+
+debug.enable = function(name) {
+ localStorage.debug = name;
+
+ var split = (name || '').split(/[\s,]+/)
+ , len = split.length;
+
+ for (var i = 0; i < len; i++) {
+ name = split[i].replace('*', '.*?');
+ if (name[0] === '-') {
+ debug.skips.push(new RegExp('^' + name.substr(1) + '$'));
+ }
+ else {
+ debug.names.push(new RegExp('^' + name + '$'));
+ }
+ }
+};
+
+/**
+ * Disable debug output.
+ *
+ * @api public
+ */
+
+debug.disable = function(){
+ debug.enable('');
+};
+
+/**
+ * Humanize the given `ms`.
+ *
+ * @param {Number} m
+ * @return {String}
+ * @api private
+ */
+
+debug.humanize = function(ms) {
+ var sec = 1000
+ , min = 60 * 1000
+ , hour = 60 * min;
+
+ if (ms >= hour) return (ms / hour).toFixed(1) + 'h';
+ if (ms >= min) return (ms / min).toFixed(1) + 'm';
+ if (ms >= sec) return (ms / sec | 0) + 's';
+ return ms + 'ms';
+};
+
+/**
+ * Returns true if the given mode name is enabled, false otherwise.
+ *
+ * @param {String} name
+ * @return {Boolean}
+ * @api public
+ */
+
+debug.enabled = function(name) {
+ for (var i = 0, len = debug.skips.length; i < len; i++) {
+ if (debug.skips[i].test(name)) {
+ return false;
+ }
+ }
+ for (var i = 0, len = debug.names.length; i < len; i++) {
+ if (debug.names[i].test(name)) {
+ return true;
+ }
+ }
+ return false;
+};
+
+// persist
+
+if (window.localStorage) debug.enable(localStorage.debug); \ No newline at end of file
diff --git a/node_modules/mocha/node_modules/debug/example/app.js b/node_modules/mocha/node_modules/debug/example/app.js
new file mode 100644
index 0000000..05374d9
--- /dev/null
+++ b/node_modules/mocha/node_modules/debug/example/app.js
@@ -0,0 +1,19 @@
+
+var debug = require('../')('http')
+ , http = require('http')
+ , name = 'My App';
+
+// fake app
+
+debug('booting %s', name);
+
+http.createServer(function(req, res){
+ debug(req.method + ' ' + req.url);
+ res.end('hello\n');
+}).listen(3000, function(){
+ debug('listening');
+});
+
+// fake worker of some kind
+
+require('./worker'); \ No newline at end of file
diff --git a/node_modules/mocha/node_modules/debug/example/browser.html b/node_modules/mocha/node_modules/debug/example/browser.html
new file mode 100644
index 0000000..7510eee
--- /dev/null
+++ b/node_modules/mocha/node_modules/debug/example/browser.html
@@ -0,0 +1,24 @@
+<html>
+ <head>
+ <title>debug()</title>
+ <script src="../debug.js"></script>
+ <script>
+ // type debug.enable('*') in
+ // the console and refresh :)
+
+ a = debug('worker:a');
+ b = debug('worker:b');
+
+ setInterval(function(){
+ a('doing some work');
+ }, 1000);
+
+ setInterval(function(){
+ a('doing some work');
+ }, 1200);
+ </script>
+ </head>
+ <body>
+
+ </body>
+</html>
diff --git a/node_modules/mocha/node_modules/debug/example/wildcards.js b/node_modules/mocha/node_modules/debug/example/wildcards.js
new file mode 100644
index 0000000..1fdac20
--- /dev/null
+++ b/node_modules/mocha/node_modules/debug/example/wildcards.js
@@ -0,0 +1,10 @@
+
+var debug = {
+ foo: require('../')('test:foo'),
+ bar: require('../')('test:bar'),
+ baz: require('../')('test:baz')
+};
+
+debug.foo('foo')
+debug.bar('bar')
+debug.baz('baz') \ No newline at end of file
diff --git a/node_modules/mocha/node_modules/debug/example/worker.js b/node_modules/mocha/node_modules/debug/example/worker.js
new file mode 100644
index 0000000..7f6d288
--- /dev/null
+++ b/node_modules/mocha/node_modules/debug/example/worker.js
@@ -0,0 +1,22 @@
+
+// DEBUG=* node example/worker
+// DEBUG=worker:* node example/worker
+// DEBUG=worker:a node example/worker
+// DEBUG=worker:b node example/worker
+
+var a = require('../')('worker:a')
+ , b = require('../')('worker:b');
+
+function work() {
+ a('doing lots of uninteresting work');
+ setTimeout(work, Math.random() * 1000);
+}
+
+work();
+
+function workb() {
+ b('doing some work');
+ setTimeout(workb, Math.random() * 2000);
+}
+
+workb(); \ No newline at end of file
diff --git a/node_modules/mocha/node_modules/debug/index.js b/node_modules/mocha/node_modules/debug/index.js
new file mode 100644
index 0000000..ee54454
--- /dev/null
+++ b/node_modules/mocha/node_modules/debug/index.js
@@ -0,0 +1,2 @@
+
+module.exports = require('./lib/debug'); \ No newline at end of file
diff --git a/node_modules/mocha/node_modules/debug/lib/debug.js b/node_modules/mocha/node_modules/debug/lib/debug.js
new file mode 100644
index 0000000..984dfb5
--- /dev/null
+++ b/node_modules/mocha/node_modules/debug/lib/debug.js
@@ -0,0 +1,147 @@
+
+/*!
+ * debug
+ * Copyright(c) 2012 TJ Holowaychuk <tj@vision-media.ca>
+ * MIT Licensed
+ */
+
+/**
+ * Module dependencies.
+ */
+
+var tty = require('tty');
+
+/**
+ * Expose `debug()` as the module.
+ */
+
+module.exports = debug;
+
+/**
+ * Library version.
+ */
+
+exports.version = '0.6.0';
+
+/**
+ * Enabled debuggers.
+ */
+
+var names = []
+ , skips = [];
+
+(process.env.DEBUG || '')
+ .split(/[\s,]+/)
+ .forEach(function(name){
+ name = name.replace('*', '.*?');
+ if (name[0] === '-') {
+ skips.push(new RegExp('^' + name.substr(1) + '$'));
+ } else {
+ names.push(new RegExp('^' + name + '$'));
+ }
+ });
+
+/**
+ * Colors.
+ */
+
+var colors = [6, 2, 3, 4, 5, 1];
+
+/**
+ * Previous debug() call.
+ */
+
+var prev = {};
+
+/**
+ * Previously assigned color.
+ */
+
+var prevColor = 0;
+
+/**
+ * Is stdout a TTY? Colored output is disabled when `true`.
+ */
+
+var isatty = tty.isatty(2);
+
+/**
+ * Select a color.
+ *
+ * @return {Number}
+ * @api private
+ */
+
+function color() {
+ return colors[prevColor++ % colors.length];
+}
+
+/**
+ * Humanize the given `ms`.
+ *
+ * @param {Number} m
+ * @return {String}
+ * @api private
+ */
+
+function humanize(ms) {
+ var sec = 1000
+ , min = 60 * 1000
+ , hour = 60 * min;
+
+ if (ms >= hour) return (ms / hour).toFixed(1) + 'h';
+ if (ms >= min) return (ms / min).toFixed(1) + 'm';
+ if (ms >= sec) return (ms / sec | 0) + 's';
+ return ms + 'ms';
+}
+
+/**
+ * Create a debugger with the given `name`.
+ *
+ * @param {String} name
+ * @return {Type}
+ * @api public
+ */
+
+function debug(name) {
+ function disabled(){}
+ disabled.enabled = false;
+
+ var match = skips.some(function(re){
+ return re.test(name);
+ });
+
+ if (match) return disabled;
+
+ match = names.some(function(re){
+ return re.test(name);
+ });
+
+ if (!match) return disabled;
+ var c = color();
+
+ function colored(fmt) {
+ var curr = new Date;
+ var ms = curr - (prev[name] || curr);
+ prev[name] = curr;
+
+ fmt = ' \033[9' + c + 'm' + name + ' '
+ + '\033[3' + c + 'm\033[90m'
+ + fmt + '\033[3' + c + 'm'
+ + ' +' + humanize(ms) + '\033[0m';
+
+ console.error.apply(this, arguments);
+ }
+
+ function plain(fmt) {
+ fmt = new Date().toUTCString()
+ + ' ' + name + ' ' + fmt;
+ console.error.apply(this, arguments);
+ }
+
+ colored.enabled = plain.enabled = true;
+
+ return isatty
+ ? colored
+ : plain;
+}
diff --git a/node_modules/mocha/node_modules/debug/package.json b/node_modules/mocha/node_modules/debug/package.json
new file mode 100644
index 0000000..83c12bb
--- /dev/null
+++ b/node_modules/mocha/node_modules/debug/package.json
@@ -0,0 +1,29 @@
+{
+ "name": "debug",
+ "version": "0.6.0",
+ "description": "small debugging utility",
+ "keywords": [
+ "debug",
+ "log",
+ "debugger"
+ ],
+ "author": {
+ "name": "TJ Holowaychuk",
+ "email": "tj@vision-media.ca"
+ },
+ "dependencies": {},
+ "devDependencies": {
+ "mocha": "*"
+ },
+ "main": "index",
+ "engines": {
+ "node": "*"
+ },
+ "_id": "debug@0.6.0",
+ "optionalDependencies": {},
+ "_engineSupported": true,
+ "_npmVersion": "1.1.12",
+ "_nodeVersion": "v0.6.14",
+ "_defaultsLoaded": true,
+ "_from": "debug@*"
+}
diff --git a/node_modules/mocha/node_modules/diff/LICENSE b/node_modules/mocha/node_modules/diff/LICENSE
new file mode 100644
index 0000000..c135dcf
--- /dev/null
+++ b/node_modules/mocha/node_modules/diff/LICENSE
@@ -0,0 +1,31 @@
+Software License Agreement (BSD License)
+
+Copyright (c) 2009-2011, Kevin Decker <kpdecker@gmail.com>
+
+All rights reserved.
+
+Redistribution and use of this software 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 Kevin Decker 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER OR
+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. \ No newline at end of file
diff --git a/node_modules/mocha/node_modules/diff/README.md b/node_modules/mocha/node_modules/diff/README.md
new file mode 100644
index 0000000..2ed7ee1
--- /dev/null
+++ b/node_modules/mocha/node_modules/diff/README.md
@@ -0,0 +1,94 @@
+# jsdiff
+
+A javascript text differencing implementation.
+
+Based on the algorithm proposed in
+["An O(ND) Difference Algorithm and its Variations" (Myers, 1986)](http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.4.6927).
+
+## Installation
+
+ npm install diff
+
+or
+
+ git clone git://github.com/kpdecker/jsdiff.git
+
+## API
+
+* JsDiff.diffChars(oldStr, newStr)
+ Diffs two blocks of text, comparing character by character.
+
+ Returns a list of change objects (See below).
+
+* JsDiff.diffWords(oldStr, newStr)
+ Diffs two blocks of text, comparing word by word.
+
+ Returns a list of change objects (See below).
+
+* JsDiff.diffLines(oldStr, newStr)
+ Diffs two blocks of text, comparing line by line.
+
+ Returns a list of change objects (See below).
+
+* JsDiff.diffCss(oldStr, newStr)
+ Diffs two blocks of text, comparing CSS tokens.
+
+ Returns a list of change objects (See below).
+
+* JsDiff.createPatch(fileName, oldStr, newStr, oldHeader, newHeader)
+ Creates a unified diff patch.
+
+ Parameters:
+ * fileName : String to be output in the filename sections of the patch
+ * oldStr : Original string value
+ * newStr : New string value
+ * oldHeader : Additional information to include in the old file header
+ * newHeader : Additional information to include in thew new file header
+
+* convertChangesToXML(changes)
+ Converts a list of changes to a serialized XML format
+
+### Change Objects
+Many of the methods above return change objects. These objects are consist of the following fields:
+
+* value: Text content
+* added: True if the value was inserted into the new string
+* removed: True of the value was removed from the old string
+
+Note that some cases may omit a particular flag field. Comparison on the flag fields should always be done in a truthy or falsy manner.
+
+## [Example](http://kpdecker.github.com/jsdiff)
+
+## License
+
+Software License Agreement (BSD License)
+
+Copyright (c) 2009-2011, Kevin Decker kpdecker@gmail.com
+
+All rights reserved.
+
+Redistribution and use of this software 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 Kevin Decker 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER OR
+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/node_modules/mocha/node_modules/diff/diff.js b/node_modules/mocha/node_modules/diff/diff.js
new file mode 100644
index 0000000..6b7ce24
--- /dev/null
+++ b/node_modules/mocha/node_modules/diff/diff.js
@@ -0,0 +1,287 @@
+/* See license.txt for terms of usage */
+
+/*
+ * Text diff implementation.
+ *
+ * This library supports the following APIS:
+ * JsDiff.diffChars: Character by character diff
+ * JsDiff.diffWords: Word (as defined by \b regex) diff which ignores whitespace
+ * JsDiff.diffLines: Line based diff
+ *
+ * JsDiff.diffCss: Diff targeted at CSS content
+ *
+ * These methods are based on the implementation proposed in
+ * "An O(ND) Difference Algorithm and its Variations" (Myers, 1986).
+ * http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.4.6927
+ */
+var JsDiff = (function() {
+ function clonePath(path) {
+ return { newPos: path.newPos, components: path.components.slice(0) };
+ }
+ function removeEmpty(array) {
+ var ret = [];
+ for (var i = 0; i < array.length; i++) {
+ if (array[i]) {
+ ret.push(array[i]);
+ }
+ }
+ return ret;
+ }
+ function escapeHTML(s) {
+ var n = s;
+ n = n.replace(/&/g, "&amp;");
+ n = n.replace(/</g, "&lt;");
+ n = n.replace(/>/g, "&gt;");
+ n = n.replace(/"/g, "&quot;");
+
+ return n;
+ }
+
+
+ var fbDiff = function(ignoreWhitespace) {
+ this.ignoreWhitespace = ignoreWhitespace;
+ };
+ fbDiff.prototype = {
+ diff: function(oldString, newString) {
+ // Handle the identity case (this is due to unrolling editLength == 0
+ if (newString == oldString) {
+ return [{ value: newString }];
+ }
+ if (!newString) {
+ return [{ value: oldString, removed: true }];
+ }
+ if (!oldString) {
+ return [{ value: newString, added: true }];
+ }
+
+ newString = this.tokenize(newString);
+ oldString = this.tokenize(oldString);
+
+ var newLen = newString.length, oldLen = oldString.length;
+ var maxEditLength = newLen + oldLen;
+ var bestPath = [{ newPos: -1, components: [] }];
+
+ // Seed editLength = 0
+ var oldPos = this.extractCommon(bestPath[0], newString, oldString, 0);
+ if (bestPath[0].newPos+1 >= newLen && oldPos+1 >= oldLen) {
+ return bestPath[0].components;
+ }
+
+ for (var editLength = 1; editLength <= maxEditLength; editLength++) {
+ for (var diagonalPath = -1*editLength; diagonalPath <= editLength; diagonalPath+=2) {
+ var basePath;
+ var addPath = bestPath[diagonalPath-1],
+ removePath = bestPath[diagonalPath+1];
+ oldPos = (removePath ? removePath.newPos : 0) - diagonalPath;
+ if (addPath) {
+ // No one else is going to attempt to use this value, clear it
+ bestPath[diagonalPath-1] = undefined;
+ }
+
+ var canAdd = addPath && addPath.newPos+1 < newLen;
+ var canRemove = removePath && 0 <= oldPos && oldPos < oldLen;
+ if (!canAdd && !canRemove) {
+ bestPath[diagonalPath] = undefined;
+ continue;
+ }
+
+ // Select the diagonal that we want to branch from. We select the prior
+ // path whose position in the new string is the farthest from the origin
+ // and does not pass the bounds of the diff graph
+ if (!canAdd || (canRemove && addPath.newPos < removePath.newPos)) {
+ basePath = clonePath(removePath);
+ this.pushComponent(basePath.components, oldString[oldPos], undefined, true);
+ } else {
+ basePath = clonePath(addPath);
+ basePath.newPos++;
+ this.pushComponent(basePath.components, newString[basePath.newPos], true, undefined);
+ }
+
+ var oldPos = this.extractCommon(basePath, newString, oldString, diagonalPath);
+
+ if (basePath.newPos+1 >= newLen && oldPos+1 >= oldLen) {
+ return basePath.components;
+ } else {
+ bestPath[diagonalPath] = basePath;
+ }
+ }
+ }
+ },
+
+ pushComponent: function(components, value, added, removed) {
+ var last = components[components.length-1];
+ if (last && last.added === added && last.removed === removed) {
+ // We need to clone here as the component clone operation is just
+ // as shallow array clone
+ components[components.length-1] =
+ {value: this.join(last.value, value), added: added, removed: removed };
+ } else {
+ components.push({value: value, added: added, removed: removed });
+ }
+ },
+ extractCommon: function(basePath, newString, oldString, diagonalPath) {
+ var newLen = newString.length,
+ oldLen = oldString.length,
+ newPos = basePath.newPos,
+ oldPos = newPos - diagonalPath;
+ while (newPos+1 < newLen && oldPos+1 < oldLen && this.equals(newString[newPos+1], oldString[oldPos+1])) {
+ newPos++;
+ oldPos++;
+
+ this.pushComponent(basePath.components, newString[newPos], undefined, undefined);
+ }
+ basePath.newPos = newPos;
+ return oldPos;
+ },
+
+ equals: function(left, right) {
+ var reWhitespace = /\S/;
+ if (this.ignoreWhitespace && !reWhitespace.test(left) && !reWhitespace.test(right)) {
+ return true;
+ } else {
+ return left == right;
+ }
+ },
+ join: function(left, right) {
+ return left + right;
+ },
+ tokenize: function(value) {
+ return value;
+ }
+ };
+
+ var CharDiff = new fbDiff();
+
+ var WordDiff = new fbDiff(true);
+ WordDiff.tokenize = function(value) {
+ return removeEmpty(value.split(/(\s+|\b)/));
+ };
+
+ var CssDiff = new fbDiff(true);
+ CssDiff.tokenize = function(value) {
+ return removeEmpty(value.split(/([{}:;,]|\s+)/));
+ };
+
+ var LineDiff = new fbDiff();
+ LineDiff.tokenize = function(value) {
+ return value.split(/^/m);
+ };
+
+ return {
+ diffChars: function(oldStr, newStr) { return CharDiff.diff(oldStr, newStr); },
+ diffWords: function(oldStr, newStr) { return WordDiff.diff(oldStr, newStr); },
+ diffLines: function(oldStr, newStr) { return LineDiff.diff(oldStr, newStr); },
+
+ diffCss: function(oldStr, newStr) { return CssDiff.diff(oldStr, newStr); },
+
+ createPatch: function(fileName, oldStr, newStr, oldHeader, newHeader) {
+ var ret = [];
+
+ ret.push("Index: " + fileName);
+ ret.push("===================================================================");
+ ret.push("--- " + fileName + (typeof oldHeader === "undefined" ? "" : "\t" + oldHeader));
+ ret.push("+++ " + fileName + (typeof newHeader === "undefined" ? "" : "\t" + newHeader));
+
+ var diff = LineDiff.diff(oldStr, newStr);
+ if (!diff[diff.length-1].value) {
+ diff.pop(); // Remove trailing newline add
+ }
+ diff.push({value: "", lines: []}); // Append an empty value to make cleanup easier
+
+ function contextLines(lines) {
+ return lines.map(function(entry) { return ' ' + entry; });
+ }
+ function eofNL(curRange, i, current) {
+ var last = diff[diff.length-2],
+ isLast = i === diff.length-2,
+ isLastOfType = i === diff.length-3 && (current.added === !last.added || current.removed === !last.removed);
+
+ // Figure out if this is the last line for the given file and missing NL
+ if (!/\n$/.test(current.value) && (isLast || isLastOfType)) {
+ curRange.push('\\ No newline at end of file');
+ }
+ }
+
+ var oldRangeStart = 0, newRangeStart = 0, curRange = [],
+ oldLine = 1, newLine = 1;
+ for (var i = 0; i < diff.length; i++) {
+ var current = diff[i],
+ lines = current.lines || current.value.replace(/\n$/, "").split("\n");
+ current.lines = lines;
+
+ if (current.added || current.removed) {
+ if (!oldRangeStart) {
+ var prev = diff[i-1];
+ oldRangeStart = oldLine;
+ newRangeStart = newLine;
+
+ if (prev) {
+ curRange = contextLines(prev.lines.slice(-4));
+ oldRangeStart -= curRange.length;
+ newRangeStart -= curRange.length;
+ }
+ }
+ curRange.push.apply(curRange, lines.map(function(entry) { return (current.added?"+":"-") + entry; }));
+ eofNL(curRange, i, current);
+
+ if (current.added) {
+ newLine += lines.length;
+ } else {
+ oldLine += lines.length;
+ }
+ } else {
+ if (oldRangeStart) {
+ // Close out any changes that have been output (or join overlapping)
+ if (lines.length <= 8 && i < diff.length-2) {
+ // Overlapping
+ curRange.push.apply(curRange, contextLines(lines));
+ } else {
+ // end the range and output
+ var contextSize = Math.min(lines.length, 4);
+ ret.push(
+ "@@ -" + oldRangeStart + "," + (oldLine-oldRangeStart+contextSize)
+ + " +" + newRangeStart + "," + (newLine-newRangeStart+contextSize)
+ + " @@");
+ ret.push.apply(ret, curRange);
+ ret.push.apply(ret, contextLines(lines.slice(0, contextSize)));
+ if (lines.length <= 4) {
+ eofNL(ret, i, current);
+ }
+
+ oldRangeStart = 0; newRangeStart = 0; curRange = [];
+ }
+ }
+ oldLine += lines.length;
+ newLine += lines.length;
+ }
+ }
+
+ return ret.join('\n') + '\n';
+ },
+
+ convertChangesToXML: function(changes){
+ var ret = [];
+ for ( var i = 0; i < changes.length; i++) {
+ var change = changes[i];
+ if (change.added) {
+ ret.push("<ins>");
+ } else if (change.removed) {
+ ret.push("<del>");
+ }
+
+ ret.push(escapeHTML(change.value));
+
+ if (change.added) {
+ ret.push("</ins>");
+ } else if (change.removed) {
+ ret.push("</del>");
+ }
+ }
+ return ret.join("");
+ }
+ };
+})();
+
+if (typeof module !== "undefined") {
+ module.exports = JsDiff;
+}
diff --git a/node_modules/mocha/node_modules/diff/index.html b/node_modules/mocha/node_modules/diff/index.html
new file mode 100644
index 0000000..ecb22fa
--- /dev/null
+++ b/node_modules/mocha/node_modules/diff/index.html
@@ -0,0 +1,89 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>Diff</title>
+ <link rel="stylesheet" href="style.css"/>
+</head>
+<body>
+
+<div id="settings">
+ <h1>Diff</h1>
+ <label><input type="radio" name="diff_type" value="diffChars" checked> Chars</label>
+ <label><input type="radio" name="diff_type" value="diffWords"> Words</label>
+ <label><input type="radio" name="diff_type" value="diffLines"> Lines</label>
+</div>
+
+<a href="https://github.com/kpdecker/jsdiff" class="source">github.com/kpdecker/jsdiff</a>
+
+<table>
+ <tr>
+ <td contenteditable="true" id="a">restaurant</td>
+ <td contenteditable="true" id="b">aura</td>
+ <td><pre id="result"></pre></td>
+ </tr>
+</table>
+
+<script src="diff.js"></script>
+<script defer>
+var a = document.getElementById('a');
+var b = document.getElementById('b');
+var result = document.getElementById('result');
+
+function changed() {
+ var diff = JsDiff[window.diffType](a.textContent, b.textContent);
+ var fragment = document.createDocumentFragment();
+ for (var i=0; i < diff.length; i++) {
+
+ if (diff[i].added && diff[i + 1] && diff[i + 1].removed) {
+ var swap = diff[i];
+ diff[i] = diff[i + 1];
+ diff[i + 1] = swap;
+ }
+
+ var node;
+ if (diff[i].removed) {
+ node = document.createElement('del');
+ node.appendChild(document.createTextNode(diff[i].value));
+ } else if (diff[i].added) {
+ node = document.createElement('ins');
+ node.appendChild(document.createTextNode(diff[i].value));
+ } else {
+ node = document.createTextNode(diff[i].value);
+ }
+ fragment.appendChild(node);
+ }
+
+ result.textContent = '';
+ result.appendChild(fragment);
+}
+
+window.onload = function() {
+ onDiffTypeChange(document.querySelector('#settings [name="diff_type"]:checked'));
+ changed();
+};
+
+a.onpaste = a.onchange =
+b.onpaste = b.onchange = changed;
+
+if ('oninput' in a) {
+ a.oninput = b.oninput = changed;
+} else {
+ a.onkeyup = b.onkeyup = changed;
+}
+
+function onDiffTypeChange(radio) {
+ window.diffType = radio.value;
+ document.title = "Diff " + radio.value.slice(4);
+}
+
+var radio = document.getElementsByName('diff_type');
+for (var i = 0; i < radio.length; i++) {
+ radio[i].onchange = function(e) {
+ onDiffTypeChange(e.target);
+ changed();
+ }
+}
+</script>
+</body>
+</html>
diff --git a/node_modules/mocha/node_modules/diff/package.json b/node_modules/mocha/node_modules/diff/package.json
new file mode 100644
index 0000000..8786bed
--- /dev/null
+++ b/node_modules/mocha/node_modules/diff/package.json
@@ -0,0 +1,46 @@
+{
+ "name": "diff",
+ "version": "1.0.2",
+ "description": "A javascript text diff implementation.",
+ "keywords": [
+ "diff",
+ "javascript"
+ ],
+ "maintainers": [
+ {
+ "name": "Kevin Decker",
+ "email": "kpdecker@gmail.com",
+ "url": "http://incaseofstairs.com"
+ }
+ ],
+ "bugs": {
+ "email": "kpdecker@gmail.com",
+ "url": "http://github.com/kpdecker/jsdiff/issues"
+ },
+ "licenses": [
+ {
+ "type": "BSD",
+ "url": "http://github.com/kpdecker/jsdiff/blob/master/LICENSE"
+ }
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/kpdecker/jsdiff.git"
+ },
+ "engines": {
+ "node": ">=0.3.1"
+ },
+ "main": "./diff",
+ "scripts": {
+ "test": "expresso test/*"
+ },
+ "dependencies": {},
+ "devDependencies": {},
+ "_id": "diff@1.0.2",
+ "optionalDependencies": {},
+ "_engineSupported": true,
+ "_npmVersion": "1.1.12",
+ "_nodeVersion": "v0.6.14",
+ "_defaultsLoaded": true,
+ "_from": "diff@1.0.2"
+}
diff --git a/node_modules/mocha/node_modules/diff/style.css b/node_modules/mocha/node_modules/diff/style.css
new file mode 100644
index 0000000..2047e2d
--- /dev/null
+++ b/node_modules/mocha/node_modules/diff/style.css
@@ -0,0 +1,81 @@
+* {
+ margin: 0;
+ padding: 0;
+}
+html, body {
+ background: #EEE;
+ font: 12px sans-serif;
+}
+body {
+ padding-top: 1.8em;
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+}
+html, body, table, tbody, tr, td {
+ height: 100%
+}
+table {
+ table-layout: fixed;
+ width: 100%;
+}
+td {
+ width: 33%;
+ padding: 3px 4px;
+ border: 1px solid transparent;
+ vertical-align: top;
+ font: 1em monospace;
+ text-align: left;
+ white-space: pre-wrap;
+}
+h1 {
+ display: inline;
+ font-size: 100%;
+}
+del {
+ text-decoration: none;
+ color: #b30000;
+ background: #fadad7;
+}
+ins {
+ background: #eaf2c2;
+ color: #406619;
+ text-decoration: none;
+}
+
+#settings {
+ position: absolute;
+ top: 0;
+ left: 5px;
+ right: 5px;
+ height: 2em;
+ line-height: 2em;
+}
+#settings label {
+ margin-left: 1em;
+}
+
+.source {
+ position: absolute;
+ right: 1%;
+ top: .2em;
+}
+
+[contentEditable] {
+ background: #F9F9F9;
+ border-color: #BBB #D9D9D9 #DDD;
+ border-radius: 4px;
+ -webkit-user-modify: read-write-plaintext-only;
+ outline: none;
+}
+[contentEditable]:focus {
+ background: #FFF;
+ border-color: #6699cc;
+ box-shadow: 0 0 4px #2175c9;
+}
+
+@-moz-document url-prefix() {
+ body {
+ height: 99%; /* Hide scroll bar in Firefox */
+ }
+}
diff --git a/node_modules/mocha/node_modules/diff/test/diffTest.js b/node_modules/mocha/node_modules/diff/test/diffTest.js
new file mode 100644
index 0000000..311b48b
--- /dev/null
+++ b/node_modules/mocha/node_modules/diff/test/diffTest.js
@@ -0,0 +1,616 @@
+const VERBOSE = false;
+
+var assert = require('assert'),
+ diff = require('../diff');
+
+function log() {
+ VERBOSE && console.log.apply(console, arguments);
+}
+
+exports['Whitespace diff'] = function() {
+ diffResult = diff.diffWords("New Value", "New ValueMoreData");
+ assert.equal(
+ "New <ins>ValueMoreData</ins><del>Value</del>",
+ diff.convertChangesToXML(diffResult),
+ "Single whitespace diffResult Value");
+
+ diffResult = diff.diffWords("New Value ", "New ValueMoreData ");
+ assert.equal(
+ "New <ins>ValueMoreData</ins><del>Value</del> ",
+ diff.convertChangesToXML(diffResult),
+ "Multiple whitespace diffResult Value");
+};
+
+// Diff on word boundary
+exports['Word Diff'] = function() {
+ diffResult = diff.diffWords("New :Value:Test", "New ValueMoreData ");
+ assert.equal(
+ "New <ins>ValueMoreData </ins><del>:Value:Test</del>",
+ diff.convertChangesToXML(diffResult),
+ "Nonmatching word boundary diffResult Value");
+ diffResult = diff.diffWords("New Value:Test", "New Value:MoreData ");
+ assert.equal(
+ "New Value:<ins>MoreData </ins><del>Test</del>",
+ diff.convertChangesToXML(diffResult),
+ "Word boundary diffResult Value");
+ diffResult = diff.diffWords("New Value-Test", "New Value:MoreData ");
+ assert.equal(
+ "New Value<ins>:MoreData </ins><del>-Test</del>",
+ diff.convertChangesToXML(diffResult),
+ "Uninque boundary diffResult Value");
+ diffResult = diff.diffWords("New Value", "New Value:MoreData ");
+ assert.equal(
+ "New Value<ins>:MoreData </ins>",
+ diff.convertChangesToXML(diffResult),
+ "Word boundary diffResult Value");
+};
+
+// Diff without changes
+exports['Diff without changes'] = function() {
+ diffResult = diff.diffWords("New Value", "New Value");
+ assert.equal(
+ "New Value",
+ diff.convertChangesToXML(diffResult),
+ "No changes diffResult Value");
+ diffResult = diff.diffWords("New Value", "New Value");
+ assert.equal(
+ "New Value",
+ diff.convertChangesToXML(diffResult),
+ "No changes whitespace diffResult Value");
+ diffResult = diff.diffWords("", "");
+ assert.equal(
+ "",
+ diff.convertChangesToXML(diffResult),
+ "Empty no changes diffResult Value");
+};
+
+// Empty diffs
+exports['Empty diffs'] = function() {
+ diffResult = diff.diffWords("New Value", "");
+ assert.equal(1, diffResult.length, "Empty diff result length");
+ assert.equal(
+ "<del>New Value</del>",
+ diff.convertChangesToXML(diffResult),
+ "Empty diffResult Value");
+ diffResult = diff.diffWords("", "New Value");
+ assert.equal(
+ "<ins>New Value</ins>",
+ diff.convertChangesToXML(diffResult),
+ "Empty diffResult Value");
+};
+
+// With without anchor (the Heckel algorithm error case)
+exports['No anchor'] = function() {
+ diffResult = diff.diffWords("New Value New Value", "Value Value New New");
+ assert.eql(
+ "<ins>Value</ins><del>New</del> Value New <ins>New</ins><del>Value</del>",
+ diff.convertChangesToXML(diffResult),
+ "No anchor diffResult Value");
+};
+
+// CSS Diff
+exports['CSS diffs'] = function() {
+ diffResult = diff.diffCss(
+ ".test,#value .test{margin-left:50px;margin-right:-40px}",
+ ".test2, #value2 .test {\nmargin-top:50px;\nmargin-right:-400px;\n}");
+ assert.equal(
+ "<ins>.test2</ins><del>.test</del>,<del>#value</del> <ins>#value2 </ins>.test<ins> </ins>{<ins>\n"
+ + "margin-top</ins><del>margin-left</del>:50px;<ins>\n</ins>"
+ + "margin-right:<ins>-400px;\n</ins><del>-40px</del>}",
+ diff.convertChangesToXML(diffResult),
+ "CSS diffResult Value");
+};
+
+// Line Diff
+exports['Line diffs'] = function() {
+ diffResult = diff.diffLines(
+ "line\nold value\nline",
+ "line\nnew value\nline");
+ assert.equal(
+ "line\n<ins>new value\n</ins><del>old value\n</del>line",
+ diff.convertChangesToXML(diffResult),
+ "Line diffResult Value");
+ diffResult = diff.diffLines(
+ "line\nvalue\nline",
+ "line\nvalue\nline");
+ assert.equal(
+ "line\nvalue\nline",
+ diff.convertChangesToXML(diffResult),
+ "Line same diffResult Value");
+ diffResult = diff.diffLines(
+ "line\nvalue \nline",
+ "line\nvalue\nline");
+ log("diffResult", diffResult);
+ log("diffResult", diff.convertChangesToXML(diffResult));
+ assert.equal(
+ "line\n<ins>value\n</ins><del>value \n</del>line",
+ diff.convertChangesToXML(diffResult),
+ "Line whitespace diffResult Value");
+};
+
+// Patch creation with diff at EOF
+exports['lastLineChanged'] = function() {
+ assert.eql(
+ 'Index: test\n'
+ + '===================================================================\n'
+ + '--- test\theader1\n'
+ + '+++ test\theader2\n'
+ + '@@ -1,3 +1,4 @@\n'
+ + ' line2\n'
+ + ' line3\n'
+ + '+line4\n'
+ + ' line5\n',
+ diff.createPatch('test', 'line2\nline3\nline5\n', 'line2\nline3\nline4\nline5\n', 'header1', 'header2'));
+
+ assert.eql(
+ 'Index: test\n'
+ + '===================================================================\n'
+ + '--- test\theader1\n'
+ + '+++ test\theader2\n'
+ + '@@ -1,3 +1,4 @@\n'
+ + ' line2\n'
+ + ' line3\n'
+ + ' line4\n'
+ + '+line5\n',
+ diff.createPatch('test', 'line2\nline3\nline4\n', 'line2\nline3\nline4\nline5\n', 'header1', 'header2'));
+
+ assert.eql(
+ 'Index: test\n'
+ + '===================================================================\n'
+ + '--- test\theader1\n'
+ + '+++ test\theader2\n'
+ + '@@ -1,4 +1,4 @@\n'
+ + ' line1\n'
+ + ' line2\n'
+ + ' line3\n'
+ + '+line44\n'
+ + '-line4\n',
+ diff.createPatch('test', 'line1\nline2\nline3\nline4\n', 'line1\nline2\nline3\nline44\n', 'header1', 'header2'));
+
+ assert.eql(
+ 'Index: test\n'
+ + '===================================================================\n'
+ + '--- test\theader1\n'
+ + '+++ test\theader2\n'
+ + '@@ -1,4 +1,5 @@\n'
+ + ' line1\n'
+ + ' line2\n'
+ + ' line3\n'
+ + '+line44\n'
+ + '+line5\n'
+ + '-line4\n',
+ diff.createPatch('test', 'line1\nline2\nline3\nline4\n', 'line1\nline2\nline3\nline44\nline5\n', 'header1', 'header2'));
+};
+
+exports['EOFNL'] = function() {
+ assert.eql(
+ 'Index: test\n'
+ + '===================================================================\n'
+ + '--- test\theader1\n'
+ + '+++ test\theader2\n'
+ + '@@ -1,4 +1,4 @@\n'
+ + ' line1\n'
+ + ' line2\n'
+ + ' line3\n'
+ + '+line4\n'
+ + '\\ No newline at end of file\n'
+ + '-line4\n',
+ diff.createPatch('test', 'line1\nline2\nline3\nline4\n', 'line1\nline2\nline3\nline4', 'header1', 'header2'));
+
+ assert.eql(
+ 'Index: test\n'
+ + '===================================================================\n'
+ + '--- test\theader1\n'
+ + '+++ test\theader2\n'
+ + '@@ -1,4 +1,4 @@\n'
+ + ' line1\n'
+ + ' line2\n'
+ + ' line3\n'
+ + '+line4\n'
+ + '-line4\n'
+ + '\\ No newline at end of file\n',
+ diff.createPatch('test', 'line1\nline2\nline3\nline4', 'line1\nline2\nline3\nline4\n', 'header1', 'header2'));
+
+ assert.eql(
+ 'Index: test\n'
+ + '===================================================================\n'
+ + '--- test\theader1\n'
+ + '+++ test\theader2\n'
+ + '@@ -1,4 +1,4 @@\n'
+ + '+line1\n'
+ + '-line11\n'
+ + ' line2\n'
+ + ' line3\n'
+ + ' line4\n'
+ + '\\ No newline at end of file\n',
+ diff.createPatch('test', 'line11\nline2\nline3\nline4', 'line1\nline2\nline3\nline4', 'header1', 'header2'));
+
+ assert.eql(
+ 'Index: test\n'
+ + '===================================================================\n'
+ + '--- test\theader1\n'
+ + '+++ test\theader2\n'
+ + '@@ -1,5 +1,5 @@\n'
+ + '+line1\n'
+ + '-line11\n'
+ + ' line2\n'
+ + ' line3\n'
+ + ' line4\n'
+ + ' line4\n',
+ diff.createPatch('test', 'line11\nline2\nline3\nline4\nline4\nline4\nline4', 'line1\nline2\nline3\nline4\nline4\nline4\nline4', 'header1', 'header2'));
+};
+
+exports['Large Test'] = function() {
+ var random = 42;
+ var mult = 134775813, range = Math.pow(2, 32);
+ function nextRandom() {
+ random = ((random * mult) + 1) % range;
+ return random;
+ }
+ var largeTest = ".hbh9asgiidc {ehaahc9:ses;bhg9hc:ses;idgaag-hi9aa:cdca;ihgd9gdgca-gdadg:ighchehgaci;ggghdg:edhciag;daagsada:ahhhiaa;ahai7:hgid;}.hbh9asgiidc.hchgihaa {ggghdg:hgid;}.igiidchbh9ah {ihgd9gdgca-hbh9a:gga("
+ + "hbh9ah/igiidcfhbh9ah.9hs);ihgd9gdgca-gaeahi:cd-gaeahi;7ah97i:7des;bhg9hc-gh97i:ses;ahai7:7des;ihgd9gdgca-edhhihdc:ses ses;}.igiidcfgde9 {ihgd9gdgca-edhhihdc:ses ses;}.bdghadaag .igiidcfgde9 {ihgd9gdgc"
+ + "a-edhhihdc:-7des ses;}.hchgihaa .igiidcfgde9 {ihgd9gdgca-edhhihdc:-dses ses;}.igiidcfaaaaia {ihgd9gdgca-edhhihdc:-bdes ses;}.bdghadaag .igiidcfaaaaia {ihgd9gdgca-edhhihdc:-9sses ses;}.hchgihaa .igiidc"
+ + "faaaaia {ihgd9gdgca-edhhihdc:-97des ses;}.igiidcfadacadha {ihgd9gdgca-edhhihdc:-9dses ses;}.bdghadaag .igiidcfadacadha {ihgd9gdgca-edhhihdc:-9bdes ses;}.hchgihaa .igiidcfadacadha {ihgd9gdgca-edhhihdc:"
+ + "-7sses ses;}.igiidcfabhha {ihgd9gdgca-edhhihdc:-77des ses;}.bdghadaag .igiidcfabhha {ihgd9gdgca-edhhihdc:-7dses ses;}.hchgihaa .igiidcfabhha {ihgd9gdgca-edhhihdc:-7bdes ses;}.igiidcfbdaa {ihgd9gdgca-e"
+ + "dhhihdc:-d7des ses;}.bdghadaag .igiidcfbdaa {ihgd9gdgca-edhhihdc:-ddses ses;}.hchgihaa .igiidcfbdaa {ihgd9gdgca-edhhihdc:-dbdes ses;}.igiidcfcaasdaaag {ihgd9gdgca-edhhihdc:-abdes ses;}.bdghadaag .igii"
+ + "dcfcaasdaaag {ihgd9gdgca-edhhihdc:-bsses ses;}.hchgihaa .igiidcfcaasdaaag {ihgd9gdgca-edhhihdc:-b7des ses;}.igiidcfgachba {ihgd9gdgca-edhhihdc:-dbdes ses;}.bdghadaag .igiidcfgachba {ihgd9gdgca-edhhihd"
+ + "c:-9ssses ses;}.hchgihaa .igiidcfgachba {ihgd9gdgca-edhhihdc:-9s7des ses;}.igiidcfghh {ihgd9gdgca-edhhihdc:-9sdses ses;}.bdghadaag .igiidcfghh {ihgd9gdgca-edhhihdc:-9sbdes ses;}.hchgihaa .igiidcfghh {"
+ + "ihgd9gdgca-edhhihdc:-99sses ses;}.igiidcfh7hga {ihgd9gdgca-edhhihdc:-97bdes ses;}.bdghadaag .igiidcfh7hga {ihgd9gdgca-edhhihdc:-9hsses ses;}.hchgihaa .igiidcfh7hga {ihgd9gdgca-edhhihdc:-9h7des ses;}.i"
+ + "giidcfgeadha {ihgd9gdgca-edhhihdc:-9hdses ses;}.bdghadaag .igiidcfgeadha {ihgd9gdgca-edhhihdc:-9hbdes ses;}.hchgihaa .igiidcfgeadha {ihgd9gdgca-edhhihdc:-9gsses ses;}.igiidcfaaisdaaag {ihgd9gdgca-edhh"
+ + "ihdc:-9dsses ses;}.bdghadaag .igiidcfaaisdaaag {ihgd9gdgca-edhhihdc:-9d7des ses;}.hchgihaa .igiidcfaaisdaaag {ihgd9gdgca-edhhihdc:-9ddses ses;}.igiidcfabei9ighh7 {ihgd9gdgca-edhhihdc:-hsses ses;}.bdgh"
+ + "adaag .igiidcfabei9ighh7 {ihgd9gdgca-edhhihdc:-h7des ses;}.hchgihaa .igiidcfabei9ighh7 {ihgd9gdgca-edhhihdc:-hdses ses;}.igiidcfadgd {ihgd9gdgca-edhhihdc:-hbdes ses;}.bdghadaag .igiidcfadgd {ihgd9gdgc"
+ + "a-edhhihdc:-gsses ses;}.hchgihaa .igiidcfadgd {ihgd9gdgca-edhhihdc:-g7des ses;}.igiidcfbhch9a {ihgd9gdgca-edhhihdc:-gdses ses;}.bdghadaag .igiidcfbhch9a {ihgd9gdgca-edhhihdc:-gbdes ses;}.hchgihaa .igi"
+ + "idcfbhch9a {ihgd9gdgca-edhhihdc:-dsses ses;}.igiidcfcaaahdh {ihgd9gdgca-edhhihdc:-bdses ses;}.bdghadaag .igiidcfcaaahdh {ihgd9gdgca-edhhihdc:-bbdes ses;}.hchgihaa .igiidcfcaaahdh {ihgd9gdgca-edhhihdc:"
+ + "-csses ses;}.igiidcfhhaahahgg7gahgaih {ihgd9gdgca-edhhihdc:-97sses ses;}.bdghadaag .igiidcfhhaahahgg7gahgaih {ihgd9gdgca-edhhihdc:-977des ses;}.hchgihaa .igiidcfhhaahahgg7gahgaih {ihgd9gdgca-edhhihdc:"
+ + "-97dses ses;}.igiidcfhhaahahgg7 {ihgd9gdgca-edhhihdc:-997des ses;}.bdghadaag .igiidcfhhaahahgg7 {ihgd9gdgca-edhhihdc:-99dses ses;}.hchgihaa .igiidcfhhaahahgg7 {ihgd9gdgca-edhhihdc:-99bdes ses;}.igiidc"
+ + "fcaaidddbhgd {ihgd9gdgca-edhhihdc:-asses ses;}.bdghadaag .igiidcfcaaidddbhgd {ihgd9gdgca-edhhihdc:-a7des ses;}.hchgihaa .igiidcfcaaidddbhgd {ihgd9gdgca-edhhihdc:-adses ses;}.igiidcfdeac {ihgd9gdgca-ed"
+ + "hhihdc:-c7des ses;}.bdghadaag .igiidcfdeac {ihgd9gdgca-edhhihdc:-cdses ses;}.hchgihaa .igiidcfdeac {ihgd9gdgca-edhhihdc:-cbdes ses;}.igiidcfdaagaghia {ihgd9gdgca-edhhihdc:-9hdses ses;}.bdghadaag .igii"
+ + "dcfdaagaghia {ihgd9gdgca-edhhihdc:-9hbdes ses;}.hchgihaa .igiidcfdaagaghia {ihgd9gdgca-edhhihdc:-9gsses ses;}.igiidcfahaa {ihgd9gdgca-edhhihdc:-9g7des ses;}.bdghadaag .igiidcfahaa {ihgd9gdgca-edhhihdc"
+ + ":-9gdses ses;}.hchgihaa .igiidcfahaa {ihgd9gdgca-edhhihdc:-9gbdes ses;}.igiidcfih9 {ihgd9gdgca-edhhihdc:-9dbdes ses;}.bdghadaag .igiidcfih9 {ihgd9gdgca-edhhihdc:-9asses ses;}.hchgihaa .igiidcfih9 {ihg"
+ + "d9gdgca-edhhihdc:-9a7des ses;}.igiidcfhgihgghia {ihgd9gdgca-edhhihdc:-9b7des ses;}.bdghadaag .igiidcfhgihgghia {ihgd9gdgca-edhhihdc:-9bdses ses;}.hchgihaa .igiidcfhgihgghia {ihgd9gdgca-edhhihdc:-9bbde"
+ + "s ses;}.igiidcfhgeaggaaa {ihgd9gdgca-edhhihdc:-9csses ses;}.bdghadaag .igiidcfhgeaggaaa {ihgd9gdgca-edhhihdc:-9c7des ses;}.hchgihaa .igiidcfhgeaggaaa {ihgd9gdgca-edhhihdc:-9cdses ses;}.igiidcfggahiaha"
+ + "ghah {ihgd9gdgca-edhhihdc:-9csses ses;}.bdghadaag .igiidcfggahiahaghah {ihgd9gdgca-edhhihdc:-9c7des ses;}.hchgihaa .igiidcfggahiahaghah {ihgd9gdgca-edhhihdc:-9cdses ses;}.igiidcfggahiagagdgaghia9dg9 {"
+ + "ihgd9gdgca-edhhihdc:-9cbdes ses;}.bdghadaag .igiidcfggahiagagdgaghia9dg9 {ihgd9gdgca-edhhihdc:-9dsses ses;}.hchgihaa .igiidcfggahiagagdgaghia9dg9 {ihgd9gdgca-edhhihdc:-9d7des ses;}.igiidcfggahiagagdga"
+ + "sdaaag {ihgd9gdgca-edhhihdc:-9ddses ses;}.bdghadaag .igiidcfggahiagagdgasdaaag {ihgd9gdgca-edhhihdc:-9dbdes ses;}.hchgihaa .igiidcfggahiagagdgasdaaag {ihgd9gdgca-edhhihdc:-7ssses ses;}.igiidcfggahiaga"
+ + "gdga {ihgd9gdgca-edhhihdc:-7s7des ses;}.bdghadaag .igiidcfggahiagagdga {ihgd9gdgca-edhhihdc:-7sdses ses;}.hchgihaa .igiidcfggahiagagdga {ihgd9gdgca-edhhihdc:-7sbdes ses;}.igiidcfggahiae79hhghagagdga {"
+ + "ihgd9gdgca-edhhihdc:-79bdes ses;}.bdghadaag .igiidcfggahiae79hhghagagdga {ihgd9gdgca-edhhihdc:-77sses ses;}.hchgihaa .igiidcfggahiae79hhghagagdga {ihgd9gdgca-edhhihdc:-777des ses;}.igiidcfbhdagagdga {"
+ + "ihgd9gdgca-edhhihdc:-77dses ses;}.bdghadaag .igiidcfbhdagagdga {ihgd9gdgca-edhhihdc:-77bdes ses;}.hchgihaa .igiidcfbhdagagdga {ihgd9gdgca-edhhihdc:-7hsses ses;}.igiidcfggahiagagdgaaaghhdc {ihgd9gdgca-"
+ + "edhhihdc:-79sses ses;}.bdghadaag .igiidcfggahiagagdgaaaghhdc {ihgd9gdgca-edhhihdc:-797des ses;}.hchgihaa .igiidcfggahiagagdgaaaghhdc {ihgd9gdgca-edhhihdc:-79dses ses;}.igiidcfgaea9abhha {ihgd9gdgca-ed"
+ + "hhihdc:-7h7des ses;}.bdghadaag .igiidcfgaea9abhha {ihgd9gdgca-edhhihdc:-7hdses ses;}.hchgihaa .igiidcfgaea9abhha {ihgd9gdgca-edhhihdc:-7hbdes ses;}.igiidcfsdgahgaabhha {ihgd9gdgca-edhhihdc:-9b7des ses"
+ + ";}.bdghadaag .igiidcfsdgahgaabhha {ihgd9gdgca-edhhihdc:-9bdses ses;}.hchgihaa .igiidcfsdgahgaabhha {ihgd9gdgca-edhhihdc:-9bbdes ses;}.igiidcfegiihgdabhha {ihgd9gdgca-edhhihdc:-7d7des ses;}.bdghadaag ."
+ + "igiidcfegiihgdabhha {ihgd9gdgca-edhhihdc:-7ddses ses;}.hchgihaa .igiidcfegiihgdabhha {ihgd9gdgca-edhhihdc:-7dbdes ses;}.igiidcfhhaa {ihgd9gdgca-edhhihdc:-7a7des ses;}.bdghadaag .igiidcfhhaa {ihgd9gdgc"
+ + "a-edhhihdc:-7adses ses;}.hchgihaa .igiidcfhhaa {ihgd9gdgca-edhhihdc:-7abdes ses;}.igiidcfhhaa {ihgd9gdgca-edhhihdc:-7a7des ses;}.bdghadaag .igiidcfhhaa {ihgd9gdgca-edhhihdc:-7adses ses;}.hchgihaa .igi"
+ + "idcfhhaa {ihgd9gdgca-edhhihdc:-7abdes ses;}.igiidcfaahi {ihgd9gdgca-edhhihdc:-h9shes ses;}.bdghadaag .igiidcfaahi {ihgd9gdgca-edhhihdc:-h97ces ses;}.hchgihaa .igiidcfaahi {ihgd9gdgca-edhhihdc:-h9dhes "
+ + "ses;}.igiidcfhaagdaa {ihgd9gdgca-edhhihdc:-h9bces ses;}.bdghadaag .igiidcfhaagdaa {ihgd9gdgca-edhhihdc:-h7shes ses;}.hchgihaa .igiidcfhaagdaa {ihgd9gdgca-edhhihdc:-h77ces ses;}.igiidcfcaagdcihgi {ihgd"
+ + "9gdgca-edhhihdc:-h7dhes ses;}.bdghadaag .igiidcfcaagdcihgi {ihgd9gdgca-edhhihdc:-h7bces ses;}.hchgihaa .igiidcfcaagdcihgi {ihgd9gdgca-edhhihdc:-hhshes ses;}.igiidcfcaa9gdge {ihgd9gdgca-edhhihdc:-hh7ce"
+ + "s ses;}.bdghadaag .igiidcfcaa9gdge {ihgd9gdgca-edhhihdc:-hhdhes ses;}.hchgihaa .igiidcfcaa9gdge {ihgd9gdgca-edhhihdc:-hhbces ses;}.igiidcf7aae {ihgd9gdgca-edhhihdc:-hgshes ses;}.bdghadaag .igiidcf7aae"
+ + " {ihgd9gdgca-edhhihdc:-hg7ces ses;}.igiidcfagdebacg {ihgd9gdgca-edhhihdc:-hscces ses;ahai7:9ges;}.bdghadaag .igiidcfagdebacg {ihgd9gdgca-edhhihdc:-hsbges ses;}.hchgihaa .igiidcfagdebacg {ihgd9gdgca-ed"
+ + "hhihdc:-hscces ses;}.igiidcfighchsaghc {ihgd9gdgca-edhhihdc:-7bbdes ses;}.bdghadaag .igiidcfighchsaghc {ihgd9gdgca-edhhihdc:-7csses ses;}.hchgihaa .igiidcfighchsaghc {ihgd9gdgca-edhhihdc:-7c7des ses;}"
+ + ".igiidcfhihgiadgdsada {ihgd9gdgca-edhhihdc:-hgdhes ses;}.bdghadaag .igiidcfhihgiadgdsada {ihgd9gdgca-edhhihdc:-hgbces ses;}.hchgihaa .igiidcfhihgiadgdsada {ihgd9gdgca-edhhihdc:-hdshes ses;}.igiidcfgas"
+ + "gah7 {ihgd9gdgca-edhhihdc:-hd7ces ses;}.bdghadaag .igiidcfgasgah7 {ihgd9gdgca-edhhihdc:-hddhes ses;}.hchgihaa .igiidcfgasgah7 {ihgd9gdgca-edhhihdc:-hdbces ses;}.igiidcfgadhaagdeids {ihgd9gdgca-edhhihd"
+ + "c:-hashes ses;}.bdghadaag .igiidcfgadhaagdeids {ihgd9gdgca-edhhihdc:-ha7ces ses;}.hchgihaa .igiidcfgadhaagdeids {ihgd9gdgca-edhhihdc:-hadhes ses;}.igiidcfdeacagdeids {ihgd9gdgca-edhhihdc:-habces ses;}"
+ + ".bdghadaag .igiidcfdeacagdeids {ihgd9gdgca-edhhihdc:-hbshes ses;}.hchgihaa .igiidcfdeacagdeids {ihgd9gdgca-edhhihdc:-hb7ces ses;}.igiidcfcaaagdeids {ihgd9gdgca-edhhihdc:-hbdges ses;}.bdghadaag .igiidc"
+ + "fcaaagdeids {ihgd9gdgca-edhhihdc:-hbbdes ses;}.hchgihaa .igiidcfcaaagdeids {ihgd9gdgca-edhhihdc:-hcsges ses;}.igiidcfighh7gahidga {ihgd9gdgca-edhhihdc:-hc7des ses;}.bdghadaag .igiidcfighh7gahidga {ihg"
+ + "d9gdgca-edhhihdc:-hcdges ses;}.hchgihaa .igiidcfighh7gahidga {ihgd9gdgca-edhhihdc:-hcbdes ses;}.hgdchbh9ah {ihgd9gdgca-hbh9a:gga(hbh9ah/hgdcfhbh9ah.9hs);ihgd9gdgca-gaeahi:cd-gaeahi;7ah97i:77es;ahca-7a"
+ + "h97i:77es;bhg9hc-gh97i:ses;ahai7:7des;ihgd9gdgca-edhhihdc:ses ses;}.hgdcfidddbhgdggggaci {ihgd9gdgca-edhhihdc:-ses ses;}.hgdcfidddbhgdggggacif7daag {ihgd9gdgca-edhhihdc:-7des ses;}.hgdcfidddbhgdggggac"
+ + "ifhchgihaa {ihgd9gdgca-edhhihdc:-dses ses;}.hgdcfasehca {ihgd9gdgca-edhhihdc:-bdes ses;}.hgdcfasehcaf7daag {ihgd9gdgca-edhhihdc:-9sses ses;}.hgdcfbhch9aggggaci {ihgd9gdgca-edhhihdc:-97des ses;}.hgdcfb"
+ + "hch9aggggacif7daag {ihgd9gdgca-edhhihdc:-9dses ses;}.hgdcfbhch9aggggacifhchgihaa {ihgd9gdgca-edhhihdc:-9bges ses;}.hgdcfgasgah7ggggaci {ihgd9gdgca-edhhihdc:-7sses ses;}.hgdcfgasgah7ggggacifhchgihaa {i"
+ + "hgd9gdgca-edhhihdc:-ah9es ses;}.hgdcfgasgah7ggggacif7daag {ihgd9gdgca-edhhihdc:-77des ses;}.hgdcfidddbhgdh {ahai7:7ses;ihgd9gdgca-edhhihdc:-7dses ses;}.hgdcfidddbhgdhf7daag {ahai7:7ses;ihgd9gdgca-edhh"
+ + "ihdc:-7bses ses;}.hgdcfge {ahai7:7ses;ihgd9gdgca-edhhihdc:-7cdes ses;}.hgdcfgef7daag {ahai7:7ses;ihgd9gdgca-edhhihdc:-hsdes ses;}.hgdcfgefhchgihaa {ahai7:7ses;ihgd9gdgca-edhhihdc:-h7des ses;}.hgdcfhah"
+ + "gg7 {ihgd9gdgca-edhhihdc:-hgdes ses;}.hgdcfhahgg7fhchgihaa {ihgd9gdgca-edhhihdc:-asaes ses;}.hgdcfhahgg7f7daag {ihgd9gdgca-edhhihdc:-hbges ses;}.hgdcfgdaaheha {ihgd9gdgca-edhhihdc:-gaaes ses;}.hgdcfgd"
+ + "aahehaf7daag {ihgd9gdgca-edhhihdc:-gd9es ses;}.hgdcfaggdg {ihgd9gdgca-edhhihdc:-g9hes ses;7ah97i:9ges;}.hgdcf7aae {ihgd9gdgca-edhhihdc:-gh9es ses;7ah97i:9ces;}.hgdcfhcsd {ihgd9gdgca-edhhihdc:-ggdes se"
+ + "s;7ah97i:9ges;}.hgdcfgddisdaaag {ihgd9gdgca-edhhihdc:-gades ses;7ah97i:7ses;}.hgdcfihgd {ihgd9gdgca-edhhihdc:-d9aes ses;ahai7 :7ses;}.hgdcfihgdf7daag {ihgd9gdgca-edhhihdc:-dhaes ses;ahai7 :7ses;}.hgdc"
+ + "fgadhafhahgg7 {ihgd9gdgca-edhhihdc:-ddaes ses;ahai7 :7des;}.hgdcfgadhafhahgg7f7daag {ihgd9gdgca-edhhihdc:-dc9es ses;ahai7:7des;}.gbhgdc {ihgd9gdgca-hbh9a:gga(hbh9ah/hgdchfaf.9hs);ihgd9gdgca-gaeahi:cd-"
+ + "gaeahi;7ah97i:7ses;bhg9hc-gh97i:ses;aagihgha-hah9c:bhaaaa;ahai7:7ses;ihgd9gdgca-edhhihdc:ses ses;}.haghah {ihgd9gdgca-edhhihdc:-ses ses;}.gagfghia9dg9 {ihgd9gdgca-edhhihdc:-7ses ses;}.gagfsdaaag {ihgd"
+ + "9gdgca-edhhihdc:-gses ses;}.gagfsdaaagfhahhifsa {ihgd9gdgca-edhhihdc:-9gses ses;}.gagfsdaaagfahhedhaa {ihgd9gdgca-edhhihdc:-9ases ses;}.gagfsdaaagfsgd7ac {ihgd9gdgca-edhhihdc:-97ses ses;}.gagdgafe79hh"
+ + "gha {ihgd9gdgca-edhhihdc:-9sses ses;}.gagdgafabhha {ihgd9gdgca-edhhihdc:-cses ses;}.gagdga {ihgd9gdgca-edhhihdc:-ases ses;}.gagdgafhahhifsa {ihgd9gdgca-edhhihdc:-7sses ses;}.gagdgafahhedhaa {ihgd9gdgc"
+ + "a-edhhihdc:-77ses ses;}.gagdgafsgd7ac {ihgd9gdgca-edhhihdc:-9cses ses;}.gbhgdc {ihgd9gdgca-hbh9a:gga(hbh9ah/hgdchfaf.9hs);ihgd9gdgca-gaeahi:cd-gaeahi;7ah97i:7ses;bhg9hc-gh97i:ses;aagihgha-hah9c:bhaaaa"
+ + ";ahai7:7ses;ihgd9gdgca-edhhihdc:ses ses;}.haghah {ihgd9gdgca-edhhihdc:-ses ses;}.gagfghia9dg9 {ihgd9gdgca-edhhihdc:-7ses ses;}.gagfsdaaag {ihgd9gdgca-edhhihdc:-gses ses;}.gagfsdaaagfhahhifsa {ihgd9gdg"
+ + "ca-edhhihdc:-9gses ses;}.gagfsdaaagfahhedhaa {ihgd9gdgca-edhhihdc:-9ases ses;}.gagfsdaaagfsgd7ac {ihgd9gdgca-edhhihdc:-97ses ses;}.gagdgafe79hhgha {ihgd9gdgca-edhhihdc:-9sses ses;}.gagdgafabhha {ihgd9"
+ + "gdgca-edhhihdc:-cses ses;}.gagdga {ihgd9gdgca-edhhihdc:-ases ses;}.gagdgafhahhifsa {ihgd9gdgca-edhhihdc:-7sses ses;}.gagdgafahhedhaa {ihgd9gdgca-edhhihdc:-77ses ses;}.gagdgafsgd7ac {ihgd9gdgca-edhhihd"
+ + "c:-9cses ses;}.shaahgdc {ihgd9gdgca-hbh9a:gga(hbh9ah/gdcghiachihdc.9hs);ihgd9gdgca-gaeahi:cd-gaeahi;7ah97i:7ses;bhg9hc-gh97i:ses;aagihgha-hah9c:bhaaaa;ahai7:7ses;ihgd9gdgca-edhhihdc:ses ses;}.shaa{ihg"
+ + "d9gdgca-edhhihdc:ses ses;}.shaafhggdihi{ihgd9gdgca-edhhihdc:-7ses ses;}.shaafheeaa{ihgd9gdgca-edhhihdc:-gses ses;}.shaafheeahghihdc{ihgd9gdgca-edhhihdc:-ases ses;}.shaafhgahd{ihgd9gdgca-edhhihdc:-cses"
+ + " ses;}.shaafasgaa{ihgd9gdgca-edhhihdc:-9sses ses;}.shaaf7iba{ihgd9gdgca-edhhihdc:-97ses ses;}.shaafhbh9a{ihgd9gdgca-edhhihdc:-9gses ses;}.shaafghah{ihgd9gdgca-edhhihdc:-9ases ses;}.shaafghahhgghei{ihg"
+ + "d9gdgca-edhhihdc:-9cses ses;}.shaafbhadga{ihgd9gdgca-edhhihdc:-7sses ses;}.shaafeei{ihgd9gdgca-edhhihdc:-77ses ses;}.shaafegdgagi{ihgd9gdgca-edhhihdc:-7gses ses;}.shaaffghgdihba{ihgd9gdgca-edhhihdc:-7"
+ + "ases ses;}.shaafiasi{ihgd9gdgca-edhhihdc:-7cses ses;}.shaafahaad{ihgd9gdgca-edhhihdc:-hsses ses;}.ahdh{ihgd9gdgca-edhhihdc:-hcses ses;}.shaafsba{ihgd9gdgca-edhhihdc:-h7ses ses;}.shaaf7he{ihgd9gdgca-ed"
+ + "hhihdc:-hgses ses;}.sdaaag{ihgd9gdgca-edhhihdc:-hases ses;}.shaafagdeids {ihgd9gdgca-edhhihdc:-gsses ses;}.aaaaiafhbhaa{ihgd9gdgca-edhhihdc:-ggses ses;ggghdg:edhciag;}.egiahgfh7hga{ihgd9gdgca-edhhihdc"
+ + ":-gases ses;}.h7hga{ihgd9gdgca-edhhihdc:-gcses ses;}.eghahia{ihgd9gdgca-edhhihdc:-dsses ses;}.gddisdaaag{ihgd9gdgca-edhhihdc:-dcses ses;}.adacfhggda{ihgd9gdgca-edhhihdc:-a77es ses;ahai7:9ces;}.7aae{ih"
+ + "gd9gdgca-edhhihdc:-agses ses;}.ighh7 {ihgd9gdgca-edhhihdc:-acses ses;}.hggdafgh97i {ihgd9gdgca-edhhihdc:-bs7es ses;ahai7:9ces;}.igahagggbih {a7hia-hehga:cdaghe;}.igahagggbih .igahagggbihfgddi {aagihgh"
+ + "a-hah9c:bhaaaa;ehaahc9:s;}.igahagggbih .igahagggbihfhggda {aagihgha-hah9c:bhaaaa;ehaahc9-aasi:7es;}.igahagggbih .igahagggbihfahgchba {aagihgha-hah9c:bhaaaa;ehaahc9-aasi:7es;sdci-shbha9:aghha,aaaaaihgh"
+ + ",hhch-haghs;sdci-hh7a:9ab;}.igahagggbih .igahagggbihfahgchba hcegi {ihgd9gdgca:ighchehgaci;idgaag:cdca;ehaahc9:ses;bhg9hc:ses;ahai7:9ss%;}a {sdci-shbha9:sh7dbh,aghha,aaaaaihgh,hhch-haghs;}a:ahcd {iasi"
+ + "-aagdghihdc:cdca;gdadg:#ssssss;}a:ahhhiaa {iasi-aagdghihdc:cdca;gdadg:#ssssss;}a:hgihaa {iasi-aagdghihdc:cdca;gdadg:#ssssss;}a:ahcd.iddaihgfigiidcfahcd {iasi-aagdghihdc:cdca;gdadg:#ssssss;}a:ahhhiaa.i"
+ + "ddaihgfigiidcfahcd {iasi-aagdghihdc:cdca;gdadg:#ssssss;}a:hgihaa.iddaihgfigiidcfahcd {iasi-aagdghihdc:cdca;gdadg:#ssssss;}a:7daag.iddaihgfigiidcfahcd {iasi-aagdghihdc:cdca;gdadg:#ggbggg;ggghdg:edhc"
+ + "iag;}a:ahcd.aaaaa9fiasi {iasi-aagdghihdc:cdca;gdadg:#gggggg;sdci-hh7a:dd%;}a:ahhhiaa.aaaaa9fiasi {iasi-aagdghihdc:cdca;gdadg:#gggggg;sdci-hh7a:dd%;}a:hgihaa.aaaaa9fiasi {iasi-aagdghihdc:gcaagahca;gdad"
+ + "g:#ssssss;sdci-hh7a:dd%;}a:7daag.aaaaa9fiasi {iasi-aagdghihdc:cdca;gdadg:#ggbggg;sdci-hh7a:dd%;ggghdg:edhciag;}a:ahcd.aaaaa9fhgihaafhagihdc {iasi-aagdghihdc:cdca;gdadg:#gggggg;sdci-aah97i:idaa;sdci-hh"
+ + "7a:dd%;}a:ahhhiaa.aaaaa9fhgihaafhagihdc {iasi-aagdghihdc:cdca;gdadg:#gggggg;sdci-aah97i:idaa;sdci-hh7a:dd%;}a:hgihaa.aaaaa9fhgihaafhagihdc {iasi-aagdghihdc:gcaagahca;gdadg:#ssssss;sdci-aah97i:idaa;sdc"
+ + "i-hh7a:dd%;}a:7daag.aaaaa9fhgihaafhagihdc {iasi-aagdghihdc:cdca;gdadg:#ggbggg;sdci-hh7a:dd%;sdci-aah97i:idaa;ggghdg:edhciag;}a:ahcd.aaaaa7fiasi {iasi-aagdghihdc:cdca;gdadg:#cdcdcd;}a:ahhhiaa.aaaaa7fia"
+ + "si {iasi-aagdghihdc:cdca;gdadg:#cdcdcd;}a:hgihaa.aaaaa7fiasi {iasi-aagdghihdc:gcaagahca;gdadg:#cdcdcd;}a:7daag.aaaaa7fiasi {iasi-aagdghihdc:gcaagahca;gdadg:#ggbggg;ggghdg:edhciag;}a:ahcd.aaaaahfiasi {"
+ + "iasi-aagdghihdc:cdca;gdadg:#cdcdcd;ahca-7ah97i:7ses;}a:ahhhiaa.aaaaahfiasi {iasi-aagdghihdc:cdca;gdadg:#cdcdcd;ahca-7ah97i:7ses;}a:hgihaa.aaaaahfiasi {iasi-aagdghihdc:gcaagahca;gdadg:#cdcdcd;ahca-7ah9"
+ + "7i:7ses;}a:7daag.aaaaahfiasi {iasi-aagdghihdc:cdca;gdadg:#ggbggg;ggghdg:edhciag;ahca-7ah97i:7ses;}a:ahcd.gcaagahca {gdadg:#ssssss;iasi-aagdghihdc:gcaagahca;ggghdg:edhciag;}a:ahhhiaa.gcaagahca {gdadg:#"
+ + "ssssss;iasi-aagdghihdc:gcaagahca;}a:hgihaa.gcaagahca {iasi-aagdghihdc:gcaagahca;gdadg:#ssssss;}a:7daag.gcaagahca {iasi-aagdghihdc:gcaagahca;gdadg:#ggbggg;}.igahagggbih hcegi {ggghdg:edhciag;}.igahaggg"
+ + "bih hcegi:7daag.hchgihaa {ggghdg:aashgai;gdadg:#adadad;}a:7daag,a.sdggh,a:ahcd.sdggh,a:ahhhiaa.sdggh,a:7daag.sdggh,a:hgihaa.sdggh,.ihiehhi igiidc:7daag,.igahagggbih hcegi:7daag {iasi-aagdghihdc:cdca;g"
+ + "dadg:#ggbggg;ggghdg:edhciag;}h hb9 {idgaag:cdca;}ida9 {ehaahc9-gh97i:ses;ehaahc9-aasi:ses;ehaahc9-idiidb:ses;ehaahc9-ide:ses;bhg9hc-gh97i:ses;bhg9hc-aasi:ses;bhg9hc-ide:ses;bhg9hc-idiidb:ses;ihgd9gdgc"
+ + "a-gdadg:#gggggg;sdci-shbha9:sh7dbh,aghha,aaaaaihgh,hhch-haghs;sdci-hh7a:bg%;}ihiaa {sdci-hh7a:9ab;}ihiaa ihiaa {sdci-hh7a:9ss%;}.aasigadhi {sadhi:aasi;}i {sdci-aah97i:idaa;}.igiidc {sdci-shbha9:sh7d"
+ + "bh,aghha,aaaaaihgh,hhch-haghs;ehaahc9:des;iasi-hah9c:gaciag;sadhi:aasi;}.ihhhgsgiidc {ehaahc9:ses;bhg9hc:ses;idgaag-hi9aa:cdca;ihgd9gdgca-gdadg:ighchehgaci;ggghdg:edhciag;}.ihhhgsgiidc .igiidcfiasi {a"
+ + "hca-7ah97i:7ses;sdci-hh7a:9ab;}.ihhhgsgiidc.bdghadaag .igiidcfiasi {gdadg:#ggbggg;}.ihhhgsgiidc.hchgihaa .igiidcfiasi {gdadg:#sgsgsg;ggghdg:aashgai;}.aasifigiidc {sdci-shbha9:sh7dbh,aghha,aaaaaihgh,hh"
+ + "ch-haghs;sdci-hh7a:s.dab;ehaahc9-ide:des;ehaahc9-aasi:des;ehaahc9-gh97i:des;iasi-hah9c:gaciag;sadhi:aasi;bhc-ahai7:dses;}.gh97ifigiidc {sdci-shbha9:sh7dbh,aghha,aaaaaihgh,hhch-haghs;sdci-hh7a:s.dab;eh"
+ + "aahc9:des;iasi-hah9c:gaciag;sadhi:gh97i;}.gdagbcf7ahaag {sdci-aah97i:idaa;sdci-hh7a:dd%;ahca-7ah97i:9des;gdadg:#ssssss;ehaahc9-ide:7es;ehaahc9-aasi:7es;ehaahc9-gh97i:7es;a7hia-hehga:cdaghe;iasi-hah9c:"
+ + "aasi;}.hgdcfgdagbcf7ahaag {ehaahc9-aasi:7des;}.ahihfgda i7 {iasi-hah9c:aasi;sdci-aah97i:cdgbha;}.ahihfgda .cd7hih {iasi-hah9c:gaciag;}#idddbhgdfihiaa i7 h {ehaahc9-aasi:9ses;}.ahihfgda {7ah97i:7des;ih"
+ + "gd9gdgca-gdadg:#gggggg;}.ahihfahhi9dagbc {ehaahc9-aasi:des;ehaahc9-gh97i:des;ahca-7ah97i:7des;}.agdeadac {idgaag-idiidb:9es iahgd;idgaag-gh97i:9es iahgd;idgaag-aasi:9es #9s9s9s;idgaag-ide:9es #9s9s"
+ + "9s;ahhhihahi9:7haaac;edhhihdc:hihdagia;ahai7:7sses;7-hcaas:9;ehaahc9:ses;ggghdg:edhciag;}.haaagi {ihgd9gdgca-gdadg:#g9gdga;sadhi:aasi;}haaagi.gghiaghh {sdci-hh7a:s.dab;ahai7:9cses;}.hbhaa {sdci-hh7a:d"
+ + "d%;sdci-shbha9:sh7dbh,aghha,aaaaaihgh,hhch-haghs;}.ihiaaaehgag {ahai7:7ses;}.iasihcegi {ehaahc9:des;bhg9hc:ses;aagihgha-hah9c:ide;}i7 {sdci-shbha9:sh7dbh,aghha,aaaaaihgh,hhch-haghs;sdci-aah97i:idaa;"
+ + "sdci-hh7a:dd%;}.ihiaa {sdci-shbha9:sh7dbh,aghha,aaaaaihgh,hhch-haghs;sdci-hh7a:9ab;sdci-aah97i:idaa;}.ahaga {sdci-shbha9:sh7dbh,aghha,aaaaaihgh,hhch-haghs;sdci-hh7a:9ab;}.aaaaafiddaihg {gaahg:idi7;a"
+ + "hai7:hgid;7ah97i:gces;ihgd9gdgca-gdadg:#d77ahc;}.iddaihgfaasi {sadhi:aasi;ahai7:hgid;iasi-hah9c:gaciag;}.iddaihgfgh97i {sadhi:gh97i;ahai7:hgid;iasi-hah9c:gaciag;}aha.iddaihg {sadhi:aasi;}.iddaihgfid9f"
+ + "aasi {sadhi:aasi;}.iddaihgfid9 {gdadg:#ssssss;sadhi:aasi;}.iddaihgfid9fgh97i {sadhi:aasi;}.iddaihgfigiidc {sadhi:aasi;iasi-hah9c:gaciag;ggghdg:edhciag;ehaahc9:ces ses ces ses;bhg9hc:ses;idgaag:ses cdc"
+ + "a;ihgd9gdgca-gdadg:ighchehgaci;}.iddaihgfigiidc.hchgihaa {ggghdg:hgid;}.iddaihgfigiidcfhgdc {gaahg:gh97i;sadhi:cdca;bhg9hc-aasi:hgid;bhg9hc-gh97i:hgid;idgaag:ses;}.iddaihgfigiidc .igiidcfiasi,.iddaihg"
+ + "figiidc hehc {ahheah9:iadgd;sdci-hh7a:s.cab;ehaahc9-aasi:des;ehaahc9-gh97i:des;sdci-shbha9:aghha,aaaaaihgh,hhch-haghs;ahca-7ah97i:s.cab;iasi-aagdghihdc:cdca;}.iddaihgfigiidc.bdghadaag .igiidcfiasi {gd"
+ + "adg:#ggbggg;}.iddaihgfigiidc.hchgihaa .igiidcfiasi {gdadg:9gh9;}.iicfahih9dcigdafaasi {sadhi:aasi;ehaahc9-aasi:des;}.cdaghe,.cdaghe ia,.iaehiaa {a7hia-hehga:cdaghe;}ihiaa.cdaghe,ihiaa.cdaghe ig,ia.ag"
+ + "he {a7hia-hehga:cdgbha;}.ihifhbhaafaasi {sadhi:aasi;}.ihifhbhaafgh97i {sadhi:aasi;}.ihifhbhaafid9 {sadhi:aasi;sdci-hh7a:dd%;}.ihifhbhaafid9 h {ahca-7ah97i:7ses;ehaahc9-ide:7es;}.ihifhbhaafdssfaasi {"
+ + "sadhi:aasi;ahai7:7ses;ehaahc9-ide:7es;}.ihifhbhaafdssfgh97i {sadhi:aasi;ehaahc9-ide:7es;}.ihifhbhaafdssfid9 {sadhi:aasi;sdci-hh7a:dd%;ehaahc9-ide:7es;}aha.ihifhbhaa {idgaag-aasi:9es hdaha #7a77hh;id"
+ + "gaag-gh97i:9es hdaha #7a77hh;idgaag-idiidb:9es hdaha #7a77hh;}aha.aaaaa9 {ahai7:hgid;gaahg:idi7;}aha.aaaaa9faasi {sadhi:aasi;ehaahc9-aasi:des;ehaahc9-ide:7es;ehaahc9-idiidb:7es;7ah97i:9ges;}aha.aaaaa"
+ + "9fgh97i {sadhi:gh97i;ehaahc9-aasi:des;ehaahc9-ide:7es;ehaahc9-idiidb:7es;7ah97i:9ges;}.aaaaa9fiasi {sdci-shbha9:sh7dbh,aghha,aaaaaihgh,hhch-haghs;gdadg:#gggggg;sdci-hh7a:dd%;ehaahc9-aasi:7es;ehaahc9-g"
+ + "h97i:7es;}.aaaaa9fad9hc {sdci-shbha9:sh7dbh,aghha,aaaaaihgh,hhch-haghs;gdadg:#gggggg;sdci-hh7a:dd%;sdci-aah97i:idaa;ehaahc9-aasi:des;ehaahc9-gh97i:des;}.aaaaa9fad9dgi {bhg9hc-gh97i:7es;}aha.ad9d {sad"
+ + "hi:aasi;}.aaaaa7fiasi {sdci-shbha9:sh7dbh,aghha,aaaaaihgh,hhch-haghs;gdadg:#i7i7i7;sdci-aah97i:idaa;ehaahc9-aasi:des;ehaahc9-gh97i:des;ahca-7ah97i:hhes;}.aaaaafadghihdc {gaahg:idi7;ahai7:hgid;7ah97i:7"
+ + "ces;ihgd9gdgca-gdadg:#d77ahc;edhhihdc:gaahihaa;}.adghihdcfaasi {bhg9hc-aasi:hes;sdci-shbha9:sh7dbh,aghha,aaaaaihgh,hhch-haghs;sdci-hh7a:9ab;}.aaaaafigahagggbi {gaahg:idi7;ahai7:hgid;7ah97i:7ces;ihgd9g"
+ + "dgca-gdadg:#d77ahc;}.igahagggbifaasi {ahai7:hgid;bhg9hc-gh97i:7dses;}.igahagggbifgh97i {sadhi:gh97i;ahai7:hgid;ahai7:7gces;}.igahagggbifigiidc {sadhi:aasi;bhg9hc-aasi:ses;bhg9hc-gh97i:ses;bhg9hc-ide:9"
+ + "es;ggghdg:edhciag;7ah97i:7ces;ihgd9gdgca-gdadg:ighchehgaci;idgaag:cdca;ehaahc9:ses;}.igahagggbifhbh9a {bhg9hc-aasi:hes;bhg9hc-gh97i:hes;bhg9hc-ide:9es;ggghdg:edhciag;7ah97i:7ces;idgaag:cdca;}.igahaggg"
+ + "bifehi7fgdcihhcag {ihgd9gdgca-gdadg:a7hia;ahai7:hgid;ehaahc9-ide:ses;ehaahc9-idiidb:ses;}.igahagggbihcah {ahai7:bes;7ah97i:7ces;ihgd9gdgca-gdadg:#d77ahc;}.igahagggbifehi7figiidc {sadhi:aasi;bhg9hc-gh9"
+ + "7i:9es;bhg9hc-ide:9es;bhg9hc-aasi:ses;}.cdsdgaag {idgaag:cdca;}.igahagggbifehi7fahcd {idgaag:cdca;}.igahagggbifehi7 {sadhi:aasi;}.igahagggbifehi7faasi,.igahagggbifehi7fgh97i {sdci-shbha9:sh7dbh,aghha,"
+ + "aaaaaihgh,hhch-haghs;sdci-hh7a:9ab;}.igahagggbifehi7fiasi {iasi-aagdghihdc:cdca;gdadg:#ssssss;sdci-hh7a:s.dab;ahca-7ah97i:7ges;bhg9hc-aasi:hes;}.hahgg7fehi7fgdcihhcag7 {sadhi:gh97i;ihgd9gdgca-gdadg:a7"
+ + "hia;gdadg:9gh9;ehaahc9-ide:ses;ehaahc9-idiidb:ses;7ah97i:7ges;idgaag:7es hdaha #d77ahc;}.hahgg7fhcegi7 {sadhi:aasi;ahai7:9gces;aagihgha-hah9c:bhaaaa;bhg9hc-aasi:9es;idgaag:7es hdaha a7hia;ihgd9gdgca-g"
+ + "dadg:a7hia;}#hahgg7iasi {sdci-shbha9:sh7dbh,dacaah,hhch-haghs;sdci-hh7a:9ab;}#hahgg7sddaihg {sdci-hh7a:9ab;}.hahgg7fehi7figiidc {sadhi:aasi;bhg9hc-aasi:ses;bhg9hc-ide:9es;bhg9hc-gh97i:9es;ggghdg:edhci"
+ + "ag;idgaag:cdca;}.ahgagidg9fehi7 {sadhi:aasi;}aha.ehi7faasi,aha.ehi7fgh97i {sadhi:aasi;sdci-aah97i:cdgbha;bhg9hc:ses;ahca-7ah97i:7des;ihgd9gdgca-gdadg:#d77ahc;}aha.ggggacifehi7figiidch {ihgd9gdgca-gd"
+ + "adg:#d77ahc;sadhi:aasi;}aha.idddbhgdh {sadhi:aasi;ihgd9gdgca-gdadg:#d77ahc;7ah97i:7des;ahca-7ah97i:7des;}ga.idddbhgd {ihgd9gdgca-gdadg:#gsg9g9;}ah.idddbhgd {ahhi-hi9aa:cdca;ehaahc9-aasi:des;ehaahc9-id"
+ + "e:7es;ehaahc9-idiidb:ses;ehaahc9-gh97i:des;sdci-shbha9:sh7dbh,aghha,aaaaaihgh,hhch-haghs;sdci-hh7a:s.dab;}ah.bhch9afidddbhgdh {ahhi-hi9aa:cdca;ehaahc9-aasi:des;ehaahc9-ide:7es;ehaahc9-idiidb:ses;ehaah"
+ + "c9-gh97i:des;sdci-shbha9:sh7dbh,aghha,aaaaaihgh,hhch-haghs;idgaag-ide:9es hdaha #7d7d7d;sdci-hh7a:s.dab;}aha.hahgg7 {sadhi:aasi;ahai7:hgid;ihgd9gdgca-gdadg:#d77ahc;}aha.9dd9aafhahgg7 {sadhi:gh97i;ihg"
+ + "d9gdgca-gdadg:#d77ahc;}aha.hahgg7fids {sdci-aah97i:cdgbha;bhg9hc:ses;ahca-7ah97i:7des;sadhi:aasi;ihgd9gdgca-gdadg:#d77ahc;}.bacg {idgaag-idiidb:9es hdaha #cscscs;idgaag-gh97i:9es hdaha #cscscs;idgaag"
+ + "-ide:9es hdaha #gggggg;idgaag-aasi:9es hdaha #gggggg;ihgd9gdgca-gdadg:#gggggg;sdci-shbha9:aghha,aaaaaihgh,hhch-haghs;sdci-hh7a:s.dab;ehaahc9:ses;}aha.shaafbhch9ag {ehaahc9:ses;ihgd9gdgca-gdadg:#s7sca"
+ + "7;idgaag:9es hdaha #sgsgsg;ahai7:9ss%;sadhi:aasi;}aha.sddiag {ahai7:hgid;sadhi:gh97i;ehaahc9-ide:7es;ehaahc9-idiidb:ses;}aha.bahhh9a {sadhi:aasi;sdci-aah97i:cdgbha;sdci-hh7a:dd%;gdadg:iahgd;bhg9hc:se"
+ + "s;ahca-7ah97i:77es;ahai7:hgid;ehaahc9:7es;}.gh97ifgahgd {idgaag:9es hdaha #9s9s9s;ihgd9gdgca-gdadg:#gsgggg;sdci-shbha9:sh7dbh,aghha,aaaaaihgh,hhch-haghs;sdci-hh7a:s.dab;ahhhihahi9:7haaac;edhhihdc:hihd"
+ + "agia;ahai7:97ses;7-hcaas:9;ehaahc9:9ses;ggghdg:edhciag;}aha.ehgdehhi {ihgd9gdgca-gdadg:#gggggg;idgaag:9es hdaha #b99h7h;ehaahc9:des;}aha.ehgdehhiagah {gaahg:idi7;ehaahc9:9ses;}.bhch9afeh9a {ihgd9gdgca"
+ + "-gdadg:#ghghgh;}.gdbbaci {edhhihdc:gaahihaa;bhg9hc-ide:7es;ehaahc9:9ses;gaahg:gh97i;}.aaac9dbbaci {ihgd9gdgca:#gggggg;}.daa9dbbaci {ihgd9gdgca-gdadg:#ghghgh;idgaag-ide:#sgsgsg;idgaag-idiidb:#sgsgsg;}."
+ + "haa9dbbaciagah {bhg9hc-idiidb:des;}.gdbbaciagi7dg {sdci-hh7a:9ab;sdci-aah97i:idaa;ehaahc9-idiidb:des;}.gdbbacisasi {sdci-hh7a:dd%;ehaahc9-idiidb:9es;}.gdbbacishbahihbe {sdci-hh7a:s.cab;}.gdbbaci7aaaia"
+ + "97agdids {edhhihdc:hihdagia;gh97i:9ses;ide:9ses;ggghdg:edhciag;}aha.eh9afihiaa {gaahg:idi7;ahai7:hgid;}aha.hhaafchah9hihdc {bhg9hc-ide:ses;}ia.hhaafchah9hihdc {ihgd9gdgca-hbh9a:gga(hi9aah/hhaafchafid"
+ + "9.ge9);ihgd9gdgca-gaeahi:gaeahi-s;ahai7:9bdes;idgaag-gh97i:9es hdaha #sgsgsg;}.ihiehhi {bhg9hc-aasi:7ses;bhg9hc-ide:7ses;bhg9hc-idiidb:7ses;ehaahc9-aasi:9bes;}.ihiehhi igiidc {ihgd9gdgca-gdadg:ighcheh"
+ + "gaci;idgaag:ses cdca;bhg9hc:ses;ehaahc9:ses;ggghdg:edhciag;sdci-shbha9:sh7dbh,aghha,aaaaaihgh,hhch-haghs;sdci-hh7a:9ab;iasi-hah9c:aasi;}.ihiehhi ah {ehaahc9-aasi:ses;ehaahc9-ide:ses;ehaahc9-gh97i:ses;"
+ + "ehaahc9-idiidb:ges;ahhi-hi9aa-i9ea:cdca;sdci-hh7a:s.dab;}.aaihfhiabfhgihaa {ahhi-hi9aa-hbh9a:gga(hbh9ah/haaagiaafhgihdc.9hs);}.aaihfhiabfhgihaa igiidc {sdci-aah97i:idaa;}aha.gh97ifeh9afgdciaci {ahai7"
+ + ":hgid;ihgd9gdgca-gdadg:a7hia;}aha.hbhaafhgifiddaihg {ihgd9gdgca-gdadg:#9s9s9s;7ah97i:7des;ehaahc9-idiidb:des;}aha.hgifigiidc {sdci-hh7a:s.dab;ehaahc9-aasi:7es;ehaahc9-gh97i:7es;sadhi:aasi;iasi-hah9c:"
+ + "gaciag;}aha.eh9afihiaa {bhg9hc:ses;}.eh9afihiaa hcegi,.eh9afihiaa hgibhi,.eh9afihiaa haaagi,.eh9afihiaa iasihgah,.sdgbfgdciaci iasihgah {sdci-shbha9:sh7dbh,aghha,aaaaaihgh,hhch-haghs;sdci-hh7a:9ab;}a"
+ + "ha.eh9afahih {bhg9hc:9ses;sadhi:aasi;}aha.bdahafsdgb {idgaag:9es hdaha #a9a9a9;bhc-ahai7:gases;}aha.sdgbfgdciaci {bhg9hc:7as;gaahg:idi7;ahai7:hgid;}.sdgbfgdciaci h {sdci-hh7a:9ab;}aha.sdgbfihiaafihg"
+ + " {idgaag-aasi:9es hdaha #b99h7h;idgaag-gh97i:9es hdaha #b99h7h;gaahg:idi7;}.sdgbfihiaafiasi {ahca-7ah97i:7aes;sdci-shbha9:sh7dbh,aghha,aaaaaihgh,hhch-haghs;sdci-hh7a:9ab;sdci-aah97i:idaa;gdadg:#hhhh"
+ + "hh;sdci-aah97i:idaa;aagihgha-hah9c:ihhaahca;bhg9hc:ses;ehaahc9-aasi:des;}.iicfeh9a9dcigdafaasi {ehaahc9-ide:ges;sadhi:aasi;}.iicfeh9a9dcigdafgh97i {ehaahc9-ide:ges;sadhi:gh97i;}aha.sdgbfgdcigdah {gaa"
+ + "hg:idi7;}aha.ghahdfigiidch {ehaahc9:des;}.aaig9sdgaag {idgaag:9es hdaha gaa;}.aaig9 {idgaag:9es hdaha #iii;}.haahcgaafhahgg7 {ahai7:hgid;gaahg:idi7;bhg9hc:9ses;ihgd9gdgca-gdadg:#ac7ahs;edhhihdc:gaah"
+ + "ihaa;}aha.hahgg7fid9 {edhhihdc:gaahihaa;ihgd9gdgca-gdadg:#h9h9h9;idgaag-idiidb:7es hdaha #d9a9sb;}.hahgg7fgdcihhcag {ahai7:hgid;bhg9hc-aasi:7ses;ehaahc9-ide:9ses;}aha.hahgg7fgefaasifgdgcag {sadhi:aa"
+ + "si;}aha.hahgg7fgefgh97ifgdgcag {sadhi:gh97i;}.hahgg7fihiaa {sdci-hh7a:dd%;sdci-aah97i:idaa;ehaahc9-aasi:des;ehaahc9-ide:des;}.hahgg7fgghiaghh {ehaahc9-aasi:9ses;ehaahc9-gh97i:ses;ehaahc9-ide:des;sdci-"
+ + "hh7a:dd%;ihgd9gdgca-gdadg:#gggggg;idgaag:9es hdaha #sgsgsg;}aha.hahgg7figiidcfgda {ehaahc9-ide:des;idgaag-ide:9es hdaha #sgsgsg;sadhi:aasi;ahai7:9ss%;}aha.hahgg7figiidcfgdcihhcag {sadhi:gh97i;}aha.hah"
+ + "gg7fhaa9ghiaghhfgda {idgaag-idiidb:9es hdaha #sgsgsg;sadhi:aasi;ahai7:9ss%;7ah97i:7des;}aha.hahgg7fgghiaghhfgdcihhcag {idgaag:7es hdaha #d9a9sb;ehaahc9:des;}.hgdcehiaafiasi {sadhi:aasi;bhg9hc:ses;7ah9"
+ + "7i:7des;ahca-7ah97i:7des;ehaahc9-gh97i:des;sdci-hh7a:dd%;sdci-aah97i:idaa;}aha.hgdc {ahai7:7des;7ah97i:7des;sadhi:aasi;}a:ahcd.hahgg79ghiaghhfiasi {iasi-aagdghihdc:gcaagahca;gdadg:#ssssss;sdci-hh7a"
+ + "{sadhi:aasi;ahhi-hi9aa:cdca;bhg9hc-ide:hes;}.7aae9dcihhcag {edhhihdc:hihdagia;ide:7es;gh97i:7es;bhg9hc:ses;ehaahc9:ses;idgaag:ses cdca;7-hcaas:g;ggghdg:edhciag;ahhhihahi9:hc7aghi;ihgd9gdgca-gdadg:ighc"
+ + "hehgaci;}.7aae9dcihhcagaihihg {bhg9hc:ses;ehaahc9:ses;ggghdg:edhciag;ahhhihahi9:hc7aghi;}.9gh-bdagaa .7aae9dcihhcag {gh97i:ges;}.9gh-ahhad9 .9gh-ehcaa .7aae9dcihhcag {gh97i:7ses;}.sdgb7hih {sdci-hh7a"
+ + ":9ab;}ihiaa.cdihs9shiaa {idgaag:ses;}ihiaa.cdihs9shiaa .aasi9dagbc {iasi-hah9c:gh97i;aagihgha-hah9c:ide;sdci-aah97i:idaa;}ihiaa.cdihs9shiaa .gh97i9dagbc {iasi-hah9c:aasi;}ihiaa.hgeagihiaa {bhg9hc:s s "
+ + "s 7es;}ihiaa.hgeagihiaa iida9 ig ia.geadhaf7ahaag {idgaag-ide:9es hdaha g9i(9g7,9g7,9g7);idgaag-gh97i:9es hdaha g9i(9g7,9g7,9g7);idgaag-idiidb:cdca;idgaag-aasi:9es hdaha g9i(9g7,9g7,9g7);ihgd9gdgca:g9"
+ + "i(77d,77d,77d);ehaahc9:s;sdci-hh7a:s;7ah97i:hses;}ihiaa.hgeagihiaa iida9 ig ia.geadhaf7ahaag ihiaa {sdci-aah97i:ass;sdci-hh7a:9ab;ihgd9gdgca:ighchehgaci;gdadg:iahgd;ahai7:9ss%;bhg9hc:s;}ihiaa.hgeagihi"
+ + "aa iida9 ig ia.gdcihhchfgeadha {bhg9hc:s;ehaahc9-aasi:s;}aha.geadha {bhg9hc:s;ehaahc9:s;daagsada:hgid;7ah97i:7hses;ahai7:asses;idgaag:9es hdaha g9i(9g7,9g7,9g7);ihgd9gdgca:a7hia;}aha.geadha ihiaa {7ah"
+ + "97i:9ss%;idgaag:cdca;}.geadha-daagaghia {}aha.geadha ihiaa iida9 ig {7ah97i:7des;}aha.geadha ihiaa iida9 ig#geadhafiahcdgda {7ah97i:hgid;}.geadhafsddiag {idgaag-ide:cdca;idgaag-gh97i:9es hdaha g9i(9g7"
+ + ",9g7,9g7);idgaag-idiidb:9es hdaha g9i(9g7,9g7,9g7);idgaag-aasi:9es hdaha g9i(9g7,9g7,9g7);7ah97i:hses;ihgd9gdgca:g9i(77d,77d,77d);}.iaehiaa {sdci-aah97i:idaa;}.ihiaaf7ahaag {sdci-aah97i:idaa;sdci-hh7a"
+ + ":9ab;gdadg:#ssssss;ahca-7ah97i:7hes;ahai7:9ss%;}.gh97ifihiaaf7ahaag {ahca-7ah97i:7hes;ahai7:hes;sdci-aah97i:idaa;gdadg:#ssssss;sdci-hh7a:9ab;}.aasifihiaaf7ahaag {ahca-7ah97i:7hes;ahai7:ges;sdci-aah97i"
+ + "{ihgd9gdgca-gdadg:#gggggg;ia77bgd-abdas:ses;ia77bgd-ehgs:ses;ia77bgd-shsshf:ses;ia77bgd-shi:hces;faadbg-abdas:des;faadbg-ehgs:des;faadbg-shi:hces;faadbg-shsshf:ses;ghgs-abah:9ss%;}.aabhcfhaiahiaa {"
+ + "sdci-hh7a:9ab;}#shaahgdgb {edhhihdc:hihdagia;ide:ses;aasi:ses;ahai7:ses;7ah97i:ses;}.aaaaafhgiihih {ihgd9gdgca-gdadg:#gggggg;7ah97i:7ses;}.gdagbcf7ahaagfadc9 {sdci-hh7a:dd%;7ah97i:hses;gdadg:#sssss"
+ + "s;}aha.ihifhaafeagbhhhhdch,aha.ihifihhhgfeagbhhhhdch {sadhi:aasi;ahai7:hgid;iasi-hah9c:gaciag;}aha.eagbhhhhdchbhhaehhi {bhg9hc:ses;ehaahc9-aasi:7ses;ehaahc9-ide:des;ehaahc9-idiidb:des;}aha.eagbhhhhdch"
+ + "bhhaehhi ga {bhg9hc:ses;ehaahc9:ses ses ses 9ses;}aha.hgdcehiaafiasi {sadhi:aasi;bhg9hc:ses;7ah97i:7des;ahca-7ah97i:7des;ehaahc9-gh97i:des;sdci-aah97i:idaa;}aha.hgdc {ahai7:7des;7ah97i:7des;sadhi:a"
+ + "asi;}a.ahia {gdadg:#ggssss;sdci-aah97i:cdgbha;}a:ahhhiaa.ahia {gdadg:#ggssss;sdci-aah97i:cdgbha;}a:7daag.ahia {gdadg:#ggssss;sdci-aah97i:cdgbha;}a:hgihaa.ahia {gdadg:#ggssss;sdci-aah97i:cdgbha;}.ahia"
+ + "{9heha:#ggssss;ghgs-hhbdas:idaa;}.gh97ifiddaihg {sadhi:gh97i;ehaahc9-gh97i:des;}aha.asfhahgg7fid9 {bhg9hc-aasi:hes;bhg9hc-gh97i:hes;bhg9hc-idiidb:9ses;idgaag-idiidb:7es hdaha #d9a9sb;}.asfhahgg7 {ah"
+ + "ai7:hgid;gaahg:idi7;7ah97i:9hses;ehaahc9-ide:ses;bhg9hc:ses;ihgd9gdgca-gdadg:#d77ahc;}aha.asfhahgg7faasiaca {sadhi:aasi;}aha.asfhahgg7fgh97iaca {sadhi:gh97i;}.ahih h {sdci-hh7a:9ab;}.asfhahgg7fgdcihh"
+ + "cag {sadhi:aasi;bhg9hc-ide:des;}ia.asfhahgg7fiasi {sdci-hh7a:s.dab;}.asfhahgg7fiasi hcegi {sdci-hh7a:s.dab;}.asfhahgg7fiasi haaagi {sdci-hh7a:s.dab;}ia.asfihiaaaehgag {ahai7:9ses;}.asfihiaa9aaa {ehaah"
+ + "c9-aasi:9ses;ehaahc9-gh97i:des;}aha.hgihdcfhiae {ehaahc9-ide:7es;ehaahc9-idiidb:7es;ehaahc9-aasi:des;ehaahc9-gh97i:9ses;bhg9hc-gh97i:9des;ihgd9gdgca-gdadg:a7hia;idgaag-idiidb:7es dgihai;idgaag-gh97i:7"
+ + "es dgihai;ahai7:dd%;}aha.aaghhhdcfhiae {ehaahc9-ide:7es;ehaahc9-idiidb:7es;ehaahc9-aasi:des;ehaahc9-gh97i:des;ihgd9gdgca-gdadg:a7hia;idgaag-idiidb:7es dgihai;idgaag-gh97i:7es dgihai;ahai7:dd%;}aha.i7"
+ + "ac {ihgd9gdgca:#hhgggh;ehaahc9-ide:7es;ehaahc9-idiidb:7es;ehaahc9-aasi:7es;ehaahc9-gh97i:des;idgaag-idiidb:7es dgihai;idgaag-gh97i:7es dgihai;ahai7:dd%;}aha.i7acfida9 {ehaahc9-ide:des;ehaahc9-idiidb:"
+ + "des;ehaahc9-aasi:9ses;ehaahc9-gh97i:des;ahai7:dd%;}aha.aaha {ihgd9gdgca:#hhgggh;ehaahc9-ide:7es;ehaahc9-idiidb:7es;ehaahc9-aasi:7es;ehaahc9-gh97i:des;idgaag-idiidb:7es dgihai;idgaag-gh97i:7es dgihai;a"
+ + "hai7:dd%;}aha.aahafida9 {ehaahc9-ide:des;ehaahc9-idiidb:des;ehaahc9-aasi:9ses;ehaahc9-gh97i:des;ahai7:dd%;}aha.haafhiae {ehaahc9-ide:9ses;ehaahc9-idiidb:9ses;iasi-hah9c:gaciag;}aha.casifhiae {ihgd9gd"
+ + "gca:#hhgggh;ehaahc9-ide:7es;ehaahc9-idiidb:7es;ehaahc9-aasi:7es;ehaahc9-gh97i:des;idgaag-idiidb:7es dgihai;idgaag-gh97i:7es dgihai;ahai7:dd%;}aha.hsfida9 {ehaahc9-ide:des;ehaahc9-idiidb:des;ehaahc9-aa"
+ + "si:9ses;ehaahc9-gh97i:des;ahai7:dd%;}aha.ehghbaiagh {ehaahc9-ide:des;ehaahc9-idiidb:des;ehaahc9-aasi:9ses;ehaahc9-gh97i:des;ahai7:dd%;}aha.eh9afida9 {ehaahc9-ide:9ses;ehaahc9-aasi:9ses;}aha.h7dgifhgi"
+ + "hdcfchba {sdci-hh7a:9ss%;}aha.h7dgifaaghhhdcfchba {sdci-hh7a:9ss%;}.gahaagfcdihshghihdc {ahheah9:cdca;}.gahaaghaabaci {edhhihdc:hihdagia;ide:-9es;aasi:-9ses;7ah97i:9es;ahca-7ah97i:9es;idgaag:cdca;eh"
+ + "aahc9:ses;bhg9hc:ses;ahai7:9es;daagsada:7haaac;}ihiaa.dig i7 aha {edhhihdc:gaahihaa;ide:-9ses;7ah97i:9es;daagsada:7haaac;}.idaaehiaah ahiaa,.ahiaa {sdci-aah97i:idaa;sdci-hh7a:9ab;}shaaahai.ghahddgdge "
+ + "{ehaahc9:ses;idgaag:cdca;iasi-hah9c:aasi;}shaaahai.ghahddgdge aa9aca {ehaahc9:ses;}shaaahai.ghahddgdge aha {ehaahc9-aasi:7ses;ehaahc9-idiidb:des;}shaaahai.ghahddgdge ahiaa {ahheah9:iadgd;bhg9hc-aasi:9"
+ + "79.ihiaa,77.ihiaa {bhg9hc:ses;}.9gh-bdagaa,.ahdhfihi7haa9dciaci,.hahgg7fid9,.haahcgaafhahgg7 {7ddb:9;}.eghcghehaehhi {ahhi-hi9aa-i9ea:cdca;}.ihiehhi igiidc,.aaaaa7fbacg igiidc,.aaaaahfbacg igiidc,.ihh"
+ + "hgsgiidc,.iddaihgfigiidc,.igahagggbihfahgchba hcegi,.shaaa9hiabsgdahagsgaa hcegi {ahai7:hgid;daagsada:ahhhiaa;}.gbaiaeaahahc9h {ehaahc9-aasi:7ses;sdci-aah97i:idaa;sdci-hh7a:9ss%;}.9ghaids {ahai7:9ss%;"
+ + "sdci-shbha9:sh7dbh,dacaah,hhch-haghs;sdci-hh7a:9ss%;ehaahc9:ses;bhg9hc:ses;idgaag-idiidb:ses;idgaag-aasi:ses;idgaag-gh97i:ses;ihgd9gdgca-gdadg:#gshghg;daagsada:7haaac;}.digids hcegi {ggghdg:aashgai;}."
+ + "bgaihehhi {sadhi:aasi;ahheah9:hcahca;ehaahc9:s 7ses;bhg9hc:s;}.bgaihehhi .cd7hagah {ahhi-hi9aa:cdca;}.s9fgaciagidhhihdc {bhg9hc:ses hgid;}.ahdhfeh9a9dciaci {ihgd9gdgca-hbh9a:gga(hi9aah/ahdhfid9.ge9);i"
+ + "hgd9gdgca-gaeahi:gaeahi-9;}shca9haghaaaaagihdc,.asfhahgg7fid9,#aaaaa7,.aaaaa7fihifshaafaasi,.iddaihg,.iddaihgfid9,.aaaaa7fihih,.aaaaa7fbacg .ihifbha,.aaaaa7fihifshaafgh97i,aha.aaaaa7fhgihaa .ihifbha,."
+ + "ahdhfaaaaa9,.gdagbcf7ahaagfadc9,.ahdhfeh9ashiaa,.ahdhfeh9agddiag,.igahagggbifehi7fgdcihhcag,.ggggacifehi7figiidch,.hahgg7fids,#aaaaah,.aaaaahfchah9hihdc,.aaaaahfhgihaa .ihifbha,.ahdhfihi .ihisd9,.ahdh"
+ + "fihi .haaagiaa .ihisd9,.ahdhfihighaa,#aaaaa9,.aaaaa9,aha.9ghaids .s7ag,aha.9ghaids .sig,aha.9ghaids .sig ia,.gdagbcf7ahaag,.ihifhbhaafid9,.ihifhbhaafdssfid9,.eagbfihifhaaagiaa .ihifhbhaafid9,.ahdhfaaa"
+ + "aah {ihgd9gdgca-hbh9a:gga(heghiahfgfd.ec9);ihgd9gdgca-gaeahi:gaeahi-s;}shca9haghaaaaagihdc {ihgd9gdgca-edhhihdc:-ses -ses;7ah97i:9gces;}.asfhahgg7fid9 {ihgd9gdgca-edhhihdc:-ses -9gces;7ah97i:97ses;}#a"
+ + "aaaa7,.aaaaa7fihifshaafaasi {ihgd9gdgca-edhhihdc:-ses -7aces;7ah97i:gces;}.iddaihg,.iddaihgfid9 {ihgd9gdgca-edhhihdc:-ses -h9aes;7ah97i:gces;}a.aaaaa7fihih,.aaaaa7fbacg .ihifbha,.aaaaa7fihifshaafgh97i"
+ + " {ihgd9gdgca-edhhihdc:-ses -hages;7ah97i:hhes;}aha.aaaaa7fhgihaa .ihifbha {ihgd9gdgca-edhhihdc:-ses -hdbes;7ah97i:hhes;}.ahdhfaaaaa9 {ihgd9gdgca-edhhihdc:-ses -ghses;7ah97i:h7es;}.gdagbcf7ahaagfadc9 {"
+ + "ihgd9gdgca-edhhihdc:-ses -ga7es;7ah97i:hses;}.ahdhfeh9ashiaa {ihgd9gdgca-edhhihdc:-ses -gd7es;7ah97i:7des;}.hahgg7fgefgh97ifgdgcag {ihgd9gdgca-edhhihdc:-h9es -99ges;ahai7:9ses;7ah97i:ces;}.hahgg7fid9 "
+ + "{ihgd9gdgca-hbh9a:gga(hi9aah/haahcgaafehcaafid9.ge9);ihgd9gdgca-gaeahi:gaeahi-s;}.eh9afihiaa,aha.eh9afgdcigdah,aha.sdgbfgdcigdah,aha.9gh-ahhad9 aha.9gh-bdagaa aha.si,aha.gh97ifeh9afgdciaci aha.9gh-bda"
+ + "gaa aha.7a,aha.ggahiahh7hga9dciaciagah aha.9gh-bdagaa aha.si,aha.cdihs99dciaciagah aha.9gh-bdagaa aha.si,aha.agdesdshh7hga9dciaciagah aha.9gh-bdagaa aha.si,.sdgbfihiaafihg,aha.9gh-ahhad9 aha.9gh-bdaga"
+ + "a aha.7a,.hcaggaacfihiaashg,.ihiaaf7ahaag,.gh97ifihiaaf7ahaag,.aasifihiaaf7ahaag,.igiidcfid9,.hchgihaa .igiidcfid9 {ihgd9gdgca-hbh9a:gga(ihhaaeghiahfgfd.ec9);ihgd9gdgca-gaeahi:gaeahi-s;}.eh9afihiaa,ah"
+ + "a.eh9afgdcigdah,aha.sdgbfgdcigdah,aha.9gh-ahhad9 aha.9gh-bdagaa aha.si,aha.gh97ifeh9afgdciaci aha.9gh-bdagaa aha.7a,aha.ggahiahh7hga9dciaciagah aha.9gh-bdagaa aha.si,aha.cdihs99dciaciagah aha.9gh-bdag"
+ + "aa aha.si,aha.agdesdshh7hga9dciaciagah aha.9gh-bdagaa aha.si {ihgd9gdgca-edhhihdc:-ses -ses;7ah97i:7des;}.sdgbfihiaafihg,aha.9gh-ahhad9 aha.9gh-bdagaa aha.7a,.hcaggaacfihiaashg,.ihiaaf7ahaag,.gh97ifih"
+ + "iaaf7ahaag,.aasifihiaaf7ahaag {ihgd9gdgca-edhhihdc:-ses -7des;7ah97i:7aes;}.igiidcfid9 {edhhihdc:gaahihaa;bhg9hc-gh97i:7es;ehaahc9-gh97i:9hes;ehaahc9-aasi:9hes;bhg9hc-aasi:7es;a7hia-hehga:cdaghe;ihgd9"
+ + "gdgca-edhhihdc:-ses -ddes;7ah97i:77es;}.hchgihaa .igiidcfid9 {ihgd9gdgca-edhhihdc:-ses -bbes;7ah97i:77es;}.aashgaifad9d,.hchgihaa .igiidcfaasi,.igiidcfaasi,.igiidcfgh97i,.hchgihaa .igiidcfgh97i,.hgdcf"
+ + "hcsd,.hgdcfaggdg {ihgd9gdgca-hbh9a:gga(ihhaaeghiahfghgh.ec9);ihgd9gdgca-gaeahi:cd-gaeahi;}.aashgaifad9d {ihgd9gdgca-edhhihdc:-ses -ses;ahai7:c7es;7ah97i:hdes;}.hchgihaa .igiidcfaasi {ihgd9gdgca-edhhih"
+ + "dc:-c7es -ses;ahai7:9ges;7ah97i:77es;}.igiidcfaasi {edhhihdc:hihdagia;ide:ses;aasi:-7es;ihgd9gdgca-edhhihdc:-daes -ses;ahai7:9hes;7ah97i:77es;}.igiidcfgh97i {edhhihdc:hihdagia;ide:ses;gh97i:-7es;ihgd9"
+ + "gdgca-edhhihdc:-9sdes -ses;ahai7:9hes;7ah97i:77es;}.hchgihaa .igiidcfgh97i {ihgd9gdgca-edhhihdc:-977es -ses;ahai7:9hes;7ah97i:77es;}.hgdcfhcsd {ihgd9gdgca-edhhihdc:-c7es -77es;ahai7:9ges;7ah97i:9des;}"
+ + ".hgdcfaggdg {ihgd9gdgca-edhhihdc:-daes -77es;ahai7:9ges;7ah97i:9ges;}";
+
+ var largeNewValue = largeTest,
+ len = largeTest.length,
+ count = nextRandom() % 20,
+ removeBound = len-(count*100),
+ logData = [];
+ for (; count > 0; count--) {
+ var removePos = nextRandom() % removeBound;
+ var removeLength = 1+nextRandom()%100;
+ logData.push("(" + removePos + ", " + removeLength + ")");
+ largeNewValue = largeNewValue.substring(0, removePos)
+ + largeNewValue.substring(removePos + removeLength);
+ }
+ log("len: " + len + " count: " + count + " removed ( " + logData.join(", ") + " )");
+
+ diffResult = diff.diffWords(largeTest, largeNewValue);
+ log("diffResult length: " + diffResult.length);
+ var removeCount = 0;
+ var removeChanges = [], addChanges = [], testChanges = [];
+ for (var i = 0; i < diffResult.length; i++) {
+ if (diffResult[i].removed) {
+ log("remove Change " + i, diffResult[i]);
+ removeChanges.push(diffResult[i].value);
+ } else if (diffResult[i].added) {
+ log("add Change " + i, diffResult[i]);
+ addChanges.push(diffResult[i].value);
+ } else {
+ log("no Change " + i, diffResult[i]);
+ removeChanges.push(diffResult[i].value);
+ addChanges.push(diffResult[i].value);
+ }
+ }
+
+ log("diffResult remove length: " + removeCount);
+ assert.equal(largeTest.replace(/s+/g, ""), removeChanges.join("").replace(/s+/g, ""), "New Diff results match");
+ assert.equal(largeNewValue.replace(/s+/g, ""), addChanges.join("").replace(/s+/g, ""), "Old Diff results match");
+};
+
+exports['Patch'] = function() {
+ // Create patch
+ var oldFile =
+ "value\n"
+ + "context\n"
+ + "context\n"
+ + "context\n"
+ + "context\n"
+ + "context\n"
+ + "context\n"
+ + "context\n"
+ + "context\n"
+ + "context\n"
+ + "remove value\n"
+ + "context\n"
+ + "context\n"
+ + "context\n"
+ + "context\n"
+ + "context\n"
+ + "context\n"
+ + "context\n"
+ + "context\n"
+ + "context\n"
+ + "remove value\n"
+ + "context\n"
+ + "context\n"
+ + "context\n"
+ + "context\n"
+ + "context\n"
+ + "context\n"
+ + "context\n"
+ + "context\n"
+ + "context\n"
+ + "context\n"
+ + "context\n"
+ + "context\n"
+ + "value\n"
+ + "context\n"
+ + "context";
+ var newFile =
+ "new value\n"
+ + "new value 2\n"
+ + "context\n"
+ + "context\n"
+ + "context\n"
+ + "context\n"
+ + "context\n"
+ + "context\n"
+ + "context\n"
+ + "context\n"
+ + "context\n"
+ + "context\n"
+ + "context\n"
+ + "context\n"
+ + "context\n"
+ + "context\n"
+ + "context\n"
+ + "context\n"
+ + "context\n"
+ + "context\n"
+ + "context\n"
+ + "context\n"
+ + "context\n"
+ + "context\n"
+ + "context\n"
+ + "context\n"
+ + "context\n"
+ + "context\n"
+ + "add value\n"
+ + "context\n"
+ + "context\n"
+ + "context\n"
+ + "context\n"
+ + "new value\n"
+ + "new value 2\n"
+ + "context\n"
+ + "context";
+ var expectedResult =
+ "Index: testFileName\n"
+ + "===================================================================\n"
+ + "--- testFileName\tOld Header\n"
+ + "+++ testFileName\tNew Header\n"
+ + "@@ -1,5 +1,6 @@\n"
+ + "+new value\n"
+ + "+new value 2\n"
+ + "-value\n"
+ + " context\n"
+ + " context\n"
+ + " context\n"
+ + " context\n"
+ + "@@ -7,9 +8,8 @@\n"
+ + " context\n"
+ + " context\n"
+ + " context\n"
+ + " context\n"
+ + "-remove value\n"
+ + " context\n"
+ + " context\n"
+ + " context\n"
+ + " context\n"
+ + "@@ -17,20 +17,21 @@\n"
+ + " context\n"
+ + " context\n"
+ + " context\n"
+ + " context\n"
+ + "-remove value\n"
+ + " context\n"
+ + " context\n"
+ + " context\n"
+ + " context\n"
+ + " context\n"
+ + " context\n"
+ + " context\n"
+ + " context\n"
+ + "+add value\n"
+ + " context\n"
+ + " context\n"
+ + " context\n"
+ + " context\n"
+ + "+new value\n"
+ + "+new value 2\n"
+ + "-value\n"
+ + " context\n"
+ + " context\n"
+ + "\\ No newline at end of file\n";
+
+ diffResult = diff.createPatch("testFileName", oldFile, newFile, "Old Header", "New Header");
+ assert.equal(
+ expectedResult,
+ diffResult);
+
+ expectedResult =
+ "Index: testFileName\n"
+ + "===================================================================\n"
+ + "--- testFileName\tOld Header\n"
+ + "+++ testFileName\tNew Header\n";
+ diffResult = diff.createPatch("testFileName", oldFile, oldFile, "Old Header", "New Header");
+ assert.equal(
+ expectedResult,
+ diffResult,
+ "Patch same diffResult Value");
+};
diff --git a/node_modules/mocha/node_modules/growl/History.md b/node_modules/mocha/node_modules/growl/History.md
new file mode 100644
index 0000000..7b1c5c2
--- /dev/null
+++ b/node_modules/mocha/node_modules/growl/History.md
@@ -0,0 +1,42 @@
+
+1.5.0 / 2012-02-08
+==================
+
+ * Added windows support [perfusorius]
+
+1.4.1 / 2011-12-28
+==================
+
+ * Fixed: dont exit(). Closes #9
+
+1.4.0 / 2011-12-17
+==================
+
+ * Changed API: `growl.notify()` -> `growl()`
+
+1.3.0 / 2011-12-17
+==================
+
+ * Added support for Ubuntu/Debian/Linux users [niftylettuce]
+ * Fixed: send notifications even if title not specified [alessioalex]
+
+1.2.0 / 2011-10-06
+==================
+
+ * Add support for priority.
+
+1.1.0 / 2011-03-15
+==================
+
+ * Added optional callbacks
+ * Added parsing of version
+
+1.0.1 / 2010-03-26
+==================
+
+ * Fixed; sys.exec -> child_process.exec to support latest node
+
+1.0.0 / 2010-03-19
+==================
+
+ * Initial release
diff --git a/node_modules/mocha/node_modules/growl/Readme.md b/node_modules/mocha/node_modules/growl/Readme.md
new file mode 100644
index 0000000..c40ecab
--- /dev/null
+++ b/node_modules/mocha/node_modules/growl/Readme.md
@@ -0,0 +1,93 @@
+# Growl for nodejs
+
+Growl support for Nodejs. This is essentially a port of my [Ruby Growl Library](http://github.com/visionmedia/growl). Ubuntu/Linux support added thanks to [@niftylettuce](http://github.com/niftylettuce). You'll need [growlnotify(1)](http://growl.info/extras.php#growlnotify).
+
+## Installation
+
+### Mac OS X (Darwin):
+
+ Install [npm](http://npmjs.org/) and run:
+
+ $ npm install growl
+
+### Ubuntu (Linux):
+
+ Install `notify-send` through the [libnotify-bin](http://packages.ubuntu.com/libnotify-bin) package:
+
+ $ sudo apt-get install libnotify-bin
+
+ Install [npm](http://npmjs.org/) and run:
+
+ $ npm install growl
+
+### Windows:
+
+ Download and install [Growl for Windows](http://www.growlforwindows.com/gfw/default.aspx)
+
+ Download [growlnotify](http://www.growlforwindows.com/gfw/help/growlnotify.aspx) - **IMPORTANT :** Unpack growlnotify to a folder that is present in your path!
+
+ Install [npm](http://npmjs.org/) and run:
+
+ $ npm install growl
+
+## Examples
+
+Callback functions are optional
+
+ var growl = require('growl')
+ growl('You have mail!')
+ growl('5 new messages', { sticky: true })
+ growl('5 new emails', { title: 'Email Client', image: 'Safari', sticky: true })
+ growl('Message with title', { title: 'Title'})
+ growl('Set priority', { priority: 2 })
+ growl('Show Safari icon', { image: 'Safari' })
+ growl('Show icon', { image: 'path/to/icon.icns' })
+ growl('Show image', { image: 'path/to/my.image.png' })
+ growl('Show png filesystem icon', { image: 'png' })
+ growl('Show pdf filesystem icon', { image: 'article.pdf' })
+ growl('Show pdf filesystem icon', { image: 'article.pdf' }, function(err){
+ // ... notified
+ })
+
+## Options
+
+ - title
+ - notification title
+ - name
+ - application name
+ - priority
+ - priority for the notification (default is 0)
+ - sticky
+ - weither or not the notification should remainin until closed
+ - image
+ - Auto-detects the context:
+ - path to an icon sets --iconpath
+ - path to an image sets --image
+ - capitalized word sets --appIcon
+ - filename uses extname as --icon
+ - otherwise treated as --icon
+
+## License
+
+(The MIT License)
+
+Copyright (c) 2009 TJ Holowaychuk <tj@vision-media.ca>
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+'Software'), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/node_modules/mocha/node_modules/growl/lib/growl.js b/node_modules/mocha/node_modules/growl/lib/growl.js
new file mode 100644
index 0000000..38a0c08
--- /dev/null
+++ b/node_modules/mocha/node_modules/growl/lib/growl.js
@@ -0,0 +1,188 @@
+// Growl - Copyright TJ Holowaychuk <tj@vision-media.ca> (MIT Licensed)
+
+/**
+ * Module dependencies.
+ */
+
+var exec = require('child_process').exec
+ , path = require('path')
+ , os = require('os')
+ , cmd;
+
+switch(os.type()) {
+ case 'Darwin':
+ cmd = {
+ type: "Darwin"
+ , pkg: "growlnotify"
+ , msg: '-m'
+ , sticky: '--sticky'
+ , priority: {
+ cmd: '--priority'
+ , range: [
+ -2
+ , -1
+ , 0
+ , 1
+ , 2
+ , "Very Low"
+ , "Moderate"
+ , "Normal"
+ , "High"
+ , "Emergency"
+ ]
+ }
+ };
+ break;
+ case 'Linux':
+ cmd = {
+ type: "Linux"
+ , pkg: "notify-send"
+ , msg: ''
+ , sticky: '-t 0'
+ , icon: '-i'
+ , priority: {
+ cmd: '-u'
+ , range: [
+ "low"
+ , "normal"
+ , "critical"
+ ]
+ }
+ };
+ break;
+ case 'Windows_NT':
+ cmd = {
+ type: "Windows"
+ , pkg: "growlnotify"
+ , msg: ''
+ , sticky: '/s:true'
+ , title: '/t:'
+ , icon: '/i:'
+ , priority: {
+ cmd: '/p:'
+ , range: [
+ -2
+ , -1
+ , 0
+ , 1
+ , 2
+ ]
+ }
+ };
+ break;
+}
+
+/**
+ * Expose `growl`.
+ */
+
+exports = module.exports = growl;
+
+/**
+ * Node-growl version.
+ */
+
+exports.version = '1.4.1'
+
+/**
+ * Send growl notification _msg_ with _options_.
+ *
+ * Options:
+ *
+ * - title Notification title
+ * - sticky Make the notification stick (defaults to false)
+ * - priority Specify an int or named key (default is 0)
+ * - name Application name (defaults to growlnotify)
+ * - image
+ * - path to an icon sets --iconpath
+ * - path to an image sets --image
+ * - capitalized word sets --appIcon
+ * - filename uses extname as --icon
+ * - otherwise treated as --icon
+ *
+ * Examples:
+ *
+ * growl('New email')
+ * growl('5 new emails', { title: 'Thunderbird' })
+ * growl('Email sent', function(){
+ * // ... notification sent
+ * })
+ *
+ * @param {string} msg
+ * @param {object} options
+ * @param {function} fn
+ * @api public
+ */
+
+function growl(msg, options, fn) {
+ var image
+ , args
+ , options = options || {}
+ , fn = fn || function(){};
+
+ // noop
+ if (!cmd) return fn(new Error('growl not supported on this platform'));
+ args = [cmd.pkg];
+
+ // image
+ if (image = options.image) {
+ switch(cmd.type) {
+ case 'Darwin':
+ var flag, ext = path.extname(image).substr(1)
+ flag = flag || ext == 'icns' && 'iconpath'
+ flag = flag || /^[A-Z]/.test(image) && 'appIcon'
+ flag = flag || /^png|gif|jpe?g$/.test(ext) && 'image'
+ flag = flag || ext && (image = ext) && 'icon'
+ flag = flag || 'icon'
+ args.push('--' + flag, image)
+ break;
+ case 'Linux':
+ args.push(cmd.icon + image);
+ break;
+ case 'Windows':
+ args.push(cmd.icon + '"' + image.replace(/\\/g, "\\\\") + '"');
+ break;
+ }
+ }
+
+ // sticky
+ if (options.sticky) args.push(cmd.sticky);
+
+ // priority
+ if (options.priority) {
+ var priority = options.priority + '';
+ var checkindexOf = cmd.priority.range.indexOf(priority);
+ if (~cmd.priority.range.indexOf(priority)) {
+ args.push(cmd.priority, options.priority);
+ }
+ }
+
+ // name
+ if (options.name && cmd.type === "Darwin") {
+ args.push('--name', options.name);
+ }
+
+ switch(cmd.type) {
+ case 'Darwin':
+ args.push(cmd.msg);
+ args.push('"' + msg + '"');
+ if (options.title) args.push(options.title);
+ break;
+ case 'Linux':
+ if (options.title) {
+ args.push("'" + options.title + "'");
+ args.push(cmd.msg);
+ args.push("'" + msg + "'");
+ } else {
+ args.push("'" + msg + "'");
+ }
+ break;
+ case 'Windows':
+ args.push('"' + msg + '"');
+ if (options.title) args.push(cmd.title + '"' + options.title + '"');
+ break;
+ }
+
+ // execute
+ exec(args.join(' '), fn);
+};
diff --git a/node_modules/mocha/node_modules/growl/package.json b/node_modules/mocha/node_modules/growl/package.json
new file mode 100644
index 0000000..2a5619f
--- /dev/null
+++ b/node_modules/mocha/node_modules/growl/package.json
@@ -0,0 +1,22 @@
+{
+ "name": "growl",
+ "version": "1.5.0",
+ "description": "Growl unobtrusive notifications",
+ "author": {
+ "name": "TJ Holowaychuk",
+ "email": "tj@vision-media.ca"
+ },
+ "main": "./lib/growl.js",
+ "_id": "growl@1.5.0",
+ "dependencies": {},
+ "devDependencies": {},
+ "optionalDependencies": {},
+ "engines": {
+ "node": "*"
+ },
+ "_engineSupported": true,
+ "_npmVersion": "1.1.12",
+ "_nodeVersion": "v0.6.14",
+ "_defaultsLoaded": true,
+ "_from": "growl@1.5.x"
+}
diff --git a/node_modules/mocha/node_modules/growl/test.js b/node_modules/mocha/node_modules/growl/test.js
new file mode 100644
index 0000000..2e75000
--- /dev/null
+++ b/node_modules/mocha/node_modules/growl/test.js
@@ -0,0 +1,16 @@
+
+var growl = require('./lib/growl')
+
+growl('You have mail!')
+growl('5 new messages', { sticky: true })
+growl('5 new emails', { title: 'Email Client', image: 'Safari', sticky: true })
+growl('Message with title', { title: 'Title'})
+growl('Set priority', { priority: 2 })
+growl('Show Safari icon', { image: 'Safari' })
+growl('Show icon', { image: 'path/to/icon.icns' })
+growl('Show image', { image: 'path/to/my.image.png' })
+growl('Show png filesystem icon', { image: 'png' })
+growl('Show pdf filesystem icon', { image: 'article.pdf' })
+growl('Show pdf filesystem icon', { image: 'article.pdf' }, function(){
+ console.log('callback');
+})
diff --git a/node_modules/mocha/node_modules/jade/.npmignore b/node_modules/mocha/node_modules/jade/.npmignore
new file mode 100644
index 0000000..5eb48f0
--- /dev/null
+++ b/node_modules/mocha/node_modules/jade/.npmignore
@@ -0,0 +1,4 @@
+.DS_Store
+lib-cov
+testing
+node_modules
diff --git a/node_modules/mocha/node_modules/jade/LICENSE b/node_modules/mocha/node_modules/jade/LICENSE
new file mode 100644
index 0000000..8ad0e0d
--- /dev/null
+++ b/node_modules/mocha/node_modules/jade/LICENSE
@@ -0,0 +1,22 @@
+(The MIT License)
+
+Copyright (c) 2009-2010 TJ Holowaychuk <tj@vision-media.ca>
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+'Software'), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file
diff --git a/node_modules/mocha/node_modules/jade/bin/jade b/node_modules/mocha/node_modules/jade/bin/jade
new file mode 100755
index 0000000..fd4122c
--- /dev/null
+++ b/node_modules/mocha/node_modules/jade/bin/jade
@@ -0,0 +1,125 @@
+#!/usr/bin/env node
+
+/**
+ * Module dependencies.
+ */
+
+var fs = require('fs')
+ , program = require('commander')
+ , path = require('path')
+ , basename = path.basename
+ , dirname = path.dirname
+ , resolve = path.resolve
+ , join = path.join
+ , mkdirp = require('mkdirp')
+ , jade = require('../');
+
+// jade options
+
+var options = {};
+
+// options
+
+program
+ .version(jade.version)
+ .usage('[options] [dir|file ...]')
+ .option('-o, --obj <str>', 'javascript options object')
+ .option('-O, --out <dir>', 'output the compiled html to <dir>')
+ .option('-p, --path <path>', 'filename used to resolve includes')
+
+program.on('--help', function(){
+ console.log(' Examples:');
+ console.log('');
+ console.log(' # translate jade the templates dir');
+ console.log(' $ jade templates');
+ console.log('');
+ console.log(' # create {foo,bar}.html');
+ console.log(' $ jade {foo,bar}.jade');
+ console.log('');
+ console.log(' # jade over stdio');
+ console.log(' $ jade < my.jade > my.html');
+ console.log('');
+ console.log(' # jade over stdio');
+ console.log(' $ echo "h1 Jade!" | jade');
+ console.log('');
+ console.log(' # foo, bar dirs rendering to /tmp');
+ console.log(' $ jade foo bar --out /tmp ');
+ console.log('');
+});
+
+program.parse(process.argv);
+
+// options given, parse them
+
+if (program.obj) options = eval('(' + program.obj + ')');
+
+// filename
+
+if (program.path) options.filename = program.path;
+
+// left-over args are file paths
+
+var files = program.args;
+
+// compile files
+
+if (files.length) {
+ console.log();
+ files.forEach(renderFile);
+ process.on('exit', console.log);
+// stdio
+} else {
+ stdin();
+}
+
+/**
+ * Compile from stdin.
+ */
+
+function stdin() {
+ var buf = '';
+ process.stdin.setEncoding('utf8');
+ process.stdin.on('data', function(chunk){ buf += chunk; });
+ process.stdin.on('end', function(){
+ var fn = jade.compile(buf, options);
+ process.stdout.write(fn(options));
+ }).resume();
+}
+
+/**
+ * Process the given path, compiling the jade files found.
+ * Always walk the subdirectories.
+ */
+
+function renderFile(path) {
+ var re = /\.jade$/;
+ fs.lstat(path, function(err, stat) {
+ if (err) throw err;
+ // Found jade file
+ if (stat.isFile() && re.test(path)) {
+ fs.readFile(path, 'utf8', function(err, str){
+ if (err) throw err;
+ options.filename = path;
+ var fn = jade.compile(str, options);
+ path = path.replace(re, '.html');
+ if (program.out) path = join(program.out, basename(path));
+ var dir = resolve(dirname(path));
+ mkdirp(dir, 0755, function(err){
+ if (err) throw err;
+ fs.writeFile(path, fn(options), function(err){
+ if (err) throw err;
+ console.log(' \033[90mrendered \033[36m%s\033[0m', path);
+ });
+ });
+ });
+ // Found directory
+ } else if (stat.isDirectory()) {
+ fs.readdir(path, function(err, files) {
+ if (err) throw err;
+ files.map(function(filename) {
+ return path + '/' + filename;
+ }).forEach(renderFile);
+ });
+ }
+ });
+}
diff --git a/node_modules/mocha/node_modules/jade/index.js b/node_modules/mocha/node_modules/jade/index.js
new file mode 100644
index 0000000..857e431
--- /dev/null
+++ b/node_modules/mocha/node_modules/jade/index.js
@@ -0,0 +1,2 @@
+
+module.exports = require('./lib/jade'); \ No newline at end of file
diff --git a/node_modules/mocha/node_modules/jade/jade.js b/node_modules/mocha/node_modules/jade/jade.js
new file mode 100644
index 0000000..22072f1
--- /dev/null
+++ b/node_modules/mocha/node_modules/jade/jade.js
@@ -0,0 +1,3140 @@
+(function() {
+
+// CommonJS require()
+
+function require(p){
+ var path = require.resolve(p)
+ , mod = require.modules[path];
+ if (!mod) throw new Error('failed to require "' + p + '"');
+ if (!mod.exports) {
+ mod.exports = {};
+ mod.call(mod.exports, mod, mod.exports, require.relative(path));
+ }
+ return mod.exports;
+ }
+
+require.modules = {};
+
+require.resolve = function (path){
+ var orig = path
+ , reg = path + '.js'
+ , index = path + '/index.js';
+ return require.modules[reg] && reg
+ || require.modules[index] && index
+ || orig;
+ };
+
+require.register = function (path, fn){
+ require.modules[path] = fn;
+ };
+
+require.relative = function (parent) {
+ return function(p){
+ if ('.' != p[0]) return require(p);
+
+ var path = parent.split('/')
+ , segs = p.split('/');
+ path.pop();
+
+ for (var i = 0; i < segs.length; i++) {
+ var seg = segs[i];
+ if ('..' == seg) path.pop();
+ else if ('.' != seg) path.push(seg);
+ }
+
+ return require(path.join('/'));
+ };
+ };
+
+
+require.register("compiler.js", function(module, exports, require){
+
+/*!
+ * Jade - Compiler
+ * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
+ * MIT Licensed
+ */
+
+/**
+ * Module dependencies.
+ */
+
+var nodes = require('./nodes')
+ , filters = require('./filters')
+ , doctypes = require('./doctypes')
+ , selfClosing = require('./self-closing')
+ , inlineTags = require('./inline-tags')
+ , utils = require('./utils');
+
+
+ if (!Object.keys) {
+ Object.keys = function(obj){
+ var arr = [];
+ for (var key in obj) {
+ if (obj.hasOwnProperty(key)) {
+ arr.push(key);
+ }
+ }
+ return arr;
+ }
+ }
+
+ if (!String.prototype.trimLeft) {
+ String.prototype.trimLeft = function(){
+ return this.replace(/^\s+/, '');
+ }
+ }
+
+
+
+/**
+ * Initialize `Compiler` with the given `node`.
+ *
+ * @param {Node} node
+ * @param {Object} options
+ * @api public
+ */
+
+var Compiler = module.exports = function Compiler(node, options) {
+ this.options = options = options || {};
+ this.node = node;
+ this.hasCompiledDoctype = false;
+ this.hasCompiledTag = false;
+ this.pp = options.pretty || false;
+ this.debug = false !== options.compileDebug;
+ this.indents = 0;
+ if (options.doctype) this.setDoctype(options.doctype);
+};
+
+/**
+ * Compiler prototype.
+ */
+
+Compiler.prototype = {
+
+ /**
+ * Compile parse tree to JavaScript.
+ *
+ * @api public
+ */
+
+ compile: function(){
+ this.buf = ['var interp;'];
+ this.lastBufferedIdx = -1
+ this.visit(this.node);
+ return this.buf.join('\n');
+ },
+
+ /**
+ * Sets the default doctype `name`. Sets terse mode to `true` when
+ * html 5 is used, causing self-closing tags to end with ">" vs "/>",
+ * and boolean attributes are not mirrored.
+ *
+ * @param {string} name
+ * @api public
+ */
+
+ setDoctype: function(name){
+ var doctype = doctypes[(name || 'default').toLowerCase()];
+ doctype = doctype || '<!DOCTYPE ' + name + '>';
+ this.doctype = doctype;
+ this.terse = '5' == name || 'html' == name;
+ this.xml = 0 == this.doctype.indexOf('<?xml');
+ },
+
+ /**
+ * Buffer the given `str` optionally escaped.
+ *
+ * @param {String} str
+ * @param {Boolean} esc
+ * @api public
+ */
+
+ buffer: function(str, esc){
+ if (esc) str = utils.escape(str);
+
+ if (this.lastBufferedIdx == this.buf.length) {
+ this.lastBuffered += str;
+ this.buf[this.lastBufferedIdx - 1] = "buf.push('" + this.lastBuffered + "');"
+ } else {
+ this.buf.push("buf.push('" + str + "');");
+ this.lastBuffered = str;
+ this.lastBufferedIdx = this.buf.length;
+ }
+ },
+
+ /**
+ * Visit `node`.
+ *
+ * @param {Node} node
+ * @api public
+ */
+
+ visit: function(node){
+ var debug = this.debug;
+
+ if (debug) {
+ this.buf.push('__jade.unshift({ lineno: ' + node.line
+ + ', filename: ' + (node.filename
+ ? '"' + node.filename + '"'
+ : '__jade[0].filename')
+ + ' });');
+ }
+
+ // Massive hack to fix our context
+ // stack for - else[ if] etc
+ if (false === node.debug && this.debug) {
+ this.buf.pop();
+ this.buf.pop();
+ }
+
+ this.visitNode(node);
+
+ if (debug) this.buf.push('__jade.shift();');
+ },
+
+ /**
+ * Visit `node`.
+ *
+ * @param {Node} node
+ * @api public
+ */
+
+ visitNode: function(node){
+ var name = node.constructor.name
+ || node.constructor.toString().match(/function ([^(\s]+)()/)[1];
+ return this['visit' + name](node);
+ },
+
+ /**
+ * Visit case `node`.
+ *
+ * @param {Literal} node
+ * @api public
+ */
+
+ visitCase: function(node){
+ var _ = this.withinCase;
+ this.withinCase = true;
+ this.buf.push('switch (' + node.expr + '){');
+ this.visit(node.block);
+ this.buf.push('}');
+ this.withinCase = _;
+ },
+
+ /**
+ * Visit when `node`.
+ *
+ * @param {Literal} node
+ * @api public
+ */
+
+ visitWhen: function(node){
+ if ('default' == node.expr) {
+ this.buf.push('default:');
+ } else {
+ this.buf.push('case ' + node.expr + ':');
+ }
+ this.visit(node.block);
+ this.buf.push(' break;');
+ },
+
+ /**
+ * Visit literal `node`.
+ *
+ * @param {Literal} node
+ * @api public
+ */
+
+ visitLiteral: function(node){
+ var str = node.str.replace(/\n/g, '\\\\n');
+ this.buffer(str);
+ },
+
+ /**
+ * Visit all nodes in `block`.
+ *
+ * @param {Block} block
+ * @api public
+ */
+
+ visitBlock: function(block){
+ var len = block.nodes.length;
+ for (var i = 0; i < len; ++i) {
+ this.visit(block.nodes[i]);
+ }
+ },
+
+ /**
+ * Visit `doctype`. Sets terse mode to `true` when html 5
+ * is used, causing self-closing tags to end with ">" vs "/>",
+ * and boolean attributes are not mirrored.
+ *
+ * @param {Doctype} doctype
+ * @api public
+ */
+
+ visitDoctype: function(doctype){
+ if (doctype && (doctype.val || !this.doctype)) {
+ this.setDoctype(doctype.val || 'default');
+ }
+
+ if (this.doctype) this.buffer(this.doctype);
+ this.hasCompiledDoctype = true;
+ },
+
+ /**
+ * Visit `mixin`, generating a function that
+ * may be called within the template.
+ *
+ * @param {Mixin} mixin
+ * @api public
+ */
+
+ visitMixin: function(mixin){
+ var name = mixin.name.replace(/-/g, '_') + '_mixin'
+ , args = mixin.args || '';
+
+ if (mixin.block) {
+ this.buf.push('var ' + name + ' = function(' + args + '){');
+ this.visit(mixin.block);
+ this.buf.push('}');
+ } else {
+ this.buf.push(name + '(' + args + ');');
+ }
+ },
+
+ /**
+ * Visit `tag` buffering tag markup, generating
+ * attributes, visiting the `tag`'s code and block.
+ *
+ * @param {Tag} tag
+ * @api public
+ */
+
+ visitTag: function(tag){
+ this.indents++;
+ var name = tag.name;
+
+ if (!this.hasCompiledTag) {
+ if (!this.hasCompiledDoctype && 'html' == name) {
+ this.visitDoctype();
+ }
+ this.hasCompiledTag = true;
+ }
+
+ // pretty print
+ if (this.pp && inlineTags.indexOf(name) == -1) {
+ this.buffer('\\n' + Array(this.indents).join(' '));
+ }
+
+ if (~selfClosing.indexOf(name) && !this.xml) {
+ this.buffer('<' + name);
+ this.visitAttributes(tag.attrs);
+ this.terse
+ ? this.buffer('>')
+ : this.buffer('/>');
+ } else {
+ // Optimize attributes buffering
+ if (tag.attrs.length) {
+ this.buffer('<' + name);
+ if (tag.attrs.length) this.visitAttributes(tag.attrs);
+ this.buffer('>');
+ } else {
+ this.buffer('<' + name + '>');
+ }
+ if (tag.code) this.visitCode(tag.code);
+ if (tag.text) this.buffer(utils.text(tag.text.nodes[0].trimLeft()));
+ this.escape = 'pre' == tag.name;
+ this.visit(tag.block);
+
+ // pretty print
+ if (this.pp && !~inlineTags.indexOf(name) && !tag.textOnly) {
+ this.buffer('\\n' + Array(this.indents).join(' '));
+ }
+
+ this.buffer('</' + name + '>');
+ }
+ this.indents--;
+ },
+
+ /**
+ * Visit `filter`, throwing when the filter does not exist.
+ *
+ * @param {Filter} filter
+ * @api public
+ */
+
+ visitFilter: function(filter){
+ var fn = filters[filter.name];
+
+ // unknown filter
+ if (!fn) {
+ if (filter.isASTFilter) {
+ throw new Error('unknown ast filter "' + filter.name + ':"');
+ } else {
+ throw new Error('unknown filter ":' + filter.name + '"');
+ }
+ }
+ if (filter.isASTFilter) {
+ this.buf.push(fn(filter.block, this, filter.attrs));
+ } else {
+ var text = filter.block.nodes.join('');
+ this.buffer(utils.text(fn(text, filter.attrs)));
+ }
+ },
+
+ /**
+ * Visit `text` node.
+ *
+ * @param {Text} text
+ * @api public
+ */
+
+ visitText: function(text){
+ text = utils.text(text.nodes.join(''));
+ if (this.escape) text = escape(text);
+ this.buffer(text);
+ this.buffer('\\n');
+ },
+
+ /**
+ * Visit a `comment`, only buffering when the buffer flag is set.
+ *
+ * @param {Comment} comment
+ * @api public
+ */
+
+ visitComment: function(comment){
+ if (!comment.buffer) return;
+ if (this.pp) this.buffer('\\n' + Array(this.indents + 1).join(' '));
+ this.buffer('<!--' + utils.escape(comment.val) + '-->');
+ },
+
+ /**
+ * Visit a `BlockComment`.
+ *
+ * @param {Comment} comment
+ * @api public
+ */
+
+ visitBlockComment: function(comment){
+ if (!comment.buffer) return;
+ if (0 == comment.val.trim().indexOf('if')) {
+ this.buffer('<!--[' + comment.val.trim() + ']>');
+ this.visit(comment.block);
+ this.buffer('<![endif]-->');
+ } else {
+ this.buffer('<!--' + comment.val);
+ this.visit(comment.block);
+ this.buffer('-->');
+ }
+ },
+
+ /**
+ * Visit `code`, respecting buffer / escape flags.
+ * If the code is followed by a block, wrap it in
+ * a self-calling function.
+ *
+ * @param {Code} code
+ * @api public
+ */
+
+ visitCode: function(code){
+ // Wrap code blocks with {}.
+ // we only wrap unbuffered code blocks ATM
+ // since they are usually flow control
+
+ // Buffer code
+ if (code.buffer) {
+ var val = code.val.trimLeft();
+ this.buf.push('var __val__ = ' + val);
+ val = 'null == __val__ ? "" : __val__';
+ if (code.escape) val = 'escape(' + val + ')';
+ this.buf.push("buf.push(" + val + ");");
+ } else {
+ this.buf.push(code.val);
+ }
+
+ // Block support
+ if (code.block) {
+ if (!code.buffer) this.buf.push('{');
+ this.visit(code.block);
+ if (!code.buffer) this.buf.push('}');
+ }
+ },
+
+ /**
+ * Visit `each` block.
+ *
+ * @param {Each} each
+ * @api public
+ */
+
+ visitEach: function(each){
+ this.buf.push(''
+ + '// iterate ' + each.obj + '\n'
+ + '(function(){\n'
+ + ' if (\'number\' == typeof ' + each.obj + '.length) {\n'
+ + ' for (var ' + each.key + ' = 0, $$l = ' + each.obj + '.length; ' + each.key + ' < $$l; ' + each.key + '++) {\n'
+ + ' var ' + each.val + ' = ' + each.obj + '[' + each.key + '];\n');
+
+ this.visit(each.block);
+
+ this.buf.push(''
+ + ' }\n'
+ + ' } else {\n'
+ + ' for (var ' + each.key + ' in ' + each.obj + ') {\n'
+ + ' if (' + each.obj + '.hasOwnProperty(' + each.key + ')){'
+ + ' var ' + each.val + ' = ' + each.obj + '[' + each.key + '];\n');
+
+ this.visit(each.block);
+
+ this.buf.push(' }\n');
+
+ this.buf.push(' }\n }\n}).call(this);\n');
+ },
+
+ /**
+ * Visit `attrs`.
+ *
+ * @param {Array} attrs
+ * @api public
+ */
+
+ visitAttributes: function(attrs){
+ var buf = []
+ , classes = [];
+
+ if (this.terse) buf.push('terse: true');
+
+ attrs.forEach(function(attr){
+ if (attr.name == 'class') {
+ classes.push('(' + attr.val + ')');
+ } else {
+ var pair = "'" + attr.name + "':(" + attr.val + ')';
+ buf.push(pair);
+ }
+ });
+
+ if (classes.length) {
+ classes = classes.join(" + ' ' + ");
+ buf.push("class: " + classes);
+ }
+
+ buf = buf.join(', ').replace('class:', '"class":');
+
+ this.buf.push("buf.push(attrs({ " + buf + " }));");
+ }
+};
+
+/**
+ * Escape the given string of `html`.
+ *
+ * @param {String} html
+ * @return {String}
+ * @api private
+ */
+
+function escape(html){
+ return String(html)
+ .replace(/&(?!\w+;)/g, '&amp;')
+ .replace(/</g, '&lt;')
+ .replace(/>/g, '&gt;')
+ .replace(/"/g, '&quot;');
+}
+
+}); // module: compiler.js
+
+require.register("doctypes.js", function(module, exports, require){
+
+/*!
+ * Jade - doctypes
+ * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
+ * MIT Licensed
+ */
+
+module.exports = {
+ '5': '<!DOCTYPE html>'
+ , 'xml': '<?xml version="1.0" encoding="utf-8" ?>'
+ , 'default': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">'
+ , 'transitional': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">'
+ , 'strict': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'
+ , 'frameset': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">'
+ , '1.1': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">'
+ , 'basic': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN" "http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd">'
+ , 'mobile': '<!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.2//EN" "http://www.openmobilealliance.org/tech/DTD/xhtml-mobile12.dtd">'
+};
+}); // module: doctypes.js
+
+require.register("filters.js", function(module, exports, require){
+
+/*!
+ * Jade - filters
+ * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
+ * MIT Licensed
+ */
+
+module.exports = {
+
+ /**
+ * Wrap text with CDATA block.
+ */
+
+ cdata: function(str){
+ return '<![CDATA[\\n' + str + '\\n]]>';
+ },
+
+ /**
+ * Transform sass to css, wrapped in style tags.
+ */
+
+ sass: function(str){
+ str = str.replace(/\\n/g, '\n');
+ var sass = require('sass').render(str).replace(/\n/g, '\\n');
+ return '<style type="text/css">' + sass + '</style>';
+ },
+
+ /**
+ * Transform stylus to css, wrapped in style tags.
+ */
+
+ stylus: function(str, options){
+ var ret;
+ str = str.replace(/\\n/g, '\n');
+ var stylus = require('stylus');
+ stylus(str, options).render(function(err, css){
+ if (err) throw err;
+ ret = css.replace(/\n/g, '\\n');
+ });
+ return '<style type="text/css">' + ret + '</style>';
+ },
+
+ /**
+ * Transform less to css, wrapped in style tags.
+ */
+
+ less: function(str){
+ var ret;
+ str = str.replace(/\\n/g, '\n');
+ require('less').render(str, function(err, css){
+ if (err) throw err;
+ ret = '<style type="text/css">' + css.replace(/\n/g, '\\n') + '</style>';
+ });
+ return ret;
+ },
+
+ /**
+ * Transform markdown to html.
+ */
+
+ markdown: function(str){
+ var md;
+
+ // support markdown / discount
+ try {
+ md = require('markdown');
+ } catch (err){
+ try {
+ md = require('discount');
+ } catch (err) {
+ try {
+ md = require('markdown-js');
+ } catch (err) {
+ try {
+ md = require('marked');
+ } catch (err) {
+ throw new
+ Error('Cannot find markdown library, install markdown, discount, or marked.');
+ }
+ }
+ }
+ }
+
+ str = str.replace(/\\n/g, '\n');
+ return md.parse(str).replace(/\n/g, '\\n').replace(/'/g,'&#39;');
+ },
+
+ /**
+ * Transform coffeescript to javascript.
+ */
+
+ coffeescript: function(str){
+ str = str.replace(/\\n/g, '\n');
+ var js = require('coffee-script').compile(str).replace(/\n/g, '\\n');
+ return '<script type="text/javascript">\\n' + js + '</script>';
+ }
+};
+
+}); // module: filters.js
+
+require.register("inline-tags.js", function(module, exports, require){
+
+/*!
+ * Jade - inline tags
+ * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
+ * MIT Licensed
+ */
+
+module.exports = [
+ 'a'
+ , 'abbr'
+ , 'acronym'
+ , 'b'
+ , 'br'
+ , 'code'
+ , 'em'
+ , 'font'
+ , 'i'
+ , 'img'
+ , 'ins'
+ , 'kbd'
+ , 'map'
+ , 'samp'
+ , 'small'
+ , 'span'
+ , 'strong'
+ , 'sub'
+ , 'sup'
+];
+}); // module: inline-tags.js
+
+require.register("jade.js", function(module, exports, require){
+/*!
+ * Jade
+ * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
+ * MIT Licensed
+ */
+
+/**
+ * Module dependencies.
+ */
+
+var Parser = require('./parser')
+ , Lexer = require('./lexer')
+ , Compiler = require('./compiler')
+ , runtime = require('./runtime')
+
+/**
+ * Library version.
+ */
+
+exports.version = '0.20.1';
+
+/**
+ * Expose self closing tags.
+ */
+
+exports.selfClosing = require('./self-closing');
+
+/**
+ * Default supported doctypes.
+ */
+
+exports.doctypes = require('./doctypes');
+
+/**
+ * Text filters.
+ */
+
+exports.filters = require('./filters');
+
+/**
+ * Utilities.
+ */
+
+exports.utils = require('./utils');
+
+/**
+ * Expose `Compiler`.
+ */
+
+exports.Compiler = Compiler;
+
+/**
+ * Expose `Parser`.
+ */
+
+exports.Parser = Parser;
+
+/**
+ * Expose `Lexer`.
+ */
+
+exports.Lexer = Lexer;
+
+/**
+ * Nodes.
+ */
+
+exports.nodes = require('./nodes');
+
+/**
+ * Jade runtime helpers.
+ */
+
+exports.runtime = runtime;
+
+/**
+ * Template function cache.
+ */
+
+exports.cache = {};
+
+/**
+ * Parse the given `str` of jade and return a function body.
+ *
+ * @param {String} str
+ * @param {Object} options
+ * @return {String}
+ * @api private
+ */
+
+function parse(str, options){
+ try {
+ // Parse
+ var parser = new Parser(str, options.filename, options);
+
+ // Compile
+ var compiler = new (options.compiler || Compiler)(parser.parse(), options)
+ , js = compiler.compile();
+
+ // Debug compiler
+ if (options.debug) {
+ console.error('\nCompiled Function:\n\n\033[90m%s\033[0m', js.replace(/^/gm, ' '));
+ }
+
+ return ''
+ + 'var buf = [];\n'
+ + (options.self
+ ? 'var self = locals || {};\n' + js
+ : 'with (locals || {}) {\n' + js + '\n}\n')
+ + 'return buf.join("");';
+ } catch (err) {
+ parser = parser.context();
+ runtime.rethrow(err, parser.filename, parser.lexer.lineno);
+ }
+}
+
+/**
+ * Compile a `Function` representation of the given jade `str`.
+ *
+ * Options:
+ *
+ * - `compileDebug` when `false` debugging code is stripped from the compiled template
+ * - `client` when `true` the helper functions `escape()` etc will reference `jade.escape()`
+ * for use with the Jade client-side runtime.js
+ *
+ * @param {String} str
+ * @param {Options} options
+ * @return {Function}
+ * @api public
+ */
+
+exports.compile = function(str, options){
+ var options = options || {}
+ , client = options.client
+ , filename = options.filename
+ ? JSON.stringify(options.filename)
+ : 'undefined'
+ , fn;
+
+ if (options.compileDebug !== false) {
+ fn = [
+ 'var __jade = [{ lineno: 1, filename: ' + filename + ' }];'
+ , 'try {'
+ , parse(String(str), options)
+ , '} catch (err) {'
+ , ' rethrow(err, __jade[0].filename, __jade[0].lineno);'
+ , '}'
+ ].join('\n');
+ } else {
+ fn = parse(String(str), options);
+ }
+
+ if (client) {
+ fn = 'var attrs = jade.attrs, escape = jade.escape, rethrow = jade.rethrow;\n' + fn;
+ }
+
+ fn = new Function('locals, attrs, escape, rethrow', fn);
+
+ if (client) return fn;
+
+ return function(locals){
+ return fn(locals, runtime.attrs, runtime.escape, runtime.rethrow);
+ };
+};
+
+/**
+ * Render the given `str` of jade and invoke
+ * the callback `fn(err, str)`.
+ *
+ * Options:
+ *
+ * - `cache` enable template caching
+ * - `filename` filename required for `include` / `extends` and caching
+ *
+ * @param {String} str
+ * @param {Object|Function} options or fn
+ * @param {Function} fn
+ * @api public
+ */
+
+exports.render = function(str, options, fn){
+ // swap args
+ if ('function' == typeof options) {
+ fn = options, options = {};
+ }
+
+ // cache requires .filename
+ if (options.cache && !options.filename) {
+ return fn(new Error('the "filename" option is required for caching'));
+ }
+
+ try {
+ var path = options.filename;
+ var tmpl = options.cache
+ ? exports.cache[path] || (exports.cache[path] = exports.compile(str, options))
+ : exports.compile(str, options);
+ fn(null, tmpl(options));
+ } catch (err) {
+ fn(err);
+ }
+};
+
+/**
+ * Render a Jade file at the given `path` and callback `fn(err, str)`.
+ *
+ * @param {String} path
+ * @param {Object|Function} options or callback
+ * @param {Function} fn
+ * @api public
+ */
+
+exports.renderFile = function(path, options, fn){
+ var key = path + ':string';
+
+ if ('function' == typeof options) {
+ fn = options, options = {};
+ }
+
+ try {
+ options.filename = path;
+ var str = options.cache
+ ? exports.cache[key] || (exports.cache[key] = fs.readFileSync(path, 'utf8'))
+ : fs.readFileSync(path, 'utf8');
+ exports.render(str, options, fn);
+ } catch (err) {
+ fn(err);
+ }
+};
+
+/**
+ * Express support.
+ */
+
+exports.__express = exports.renderFile;
+
+}); // module: jade.js
+
+require.register("lexer.js", function(module, exports, require){
+
+/*!
+ * Jade - Lexer
+ * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
+ * MIT Licensed
+ */
+
+/**
+ * Initialize `Lexer` with the given `str`.
+ *
+ * Options:
+ *
+ * - `colons` allow colons for attr delimiters
+ *
+ * @param {String} str
+ * @param {Object} options
+ * @api private
+ */
+
+var Lexer = module.exports = function Lexer(str, options) {
+ options = options || {};
+ this.input = str.replace(/\r\n|\r/g, '\n');
+ this.colons = options.colons;
+ this.deferredTokens = [];
+ this.lastIndents = 0;
+ this.lineno = 1;
+ this.stash = [];
+ this.indentStack = [];
+ this.indentRe = null;
+ this.pipeless = false;
+};
+
+/**
+ * Lexer prototype.
+ */
+
+Lexer.prototype = {
+
+ /**
+ * Construct a token with the given `type` and `val`.
+ *
+ * @param {String} type
+ * @param {String} val
+ * @return {Object}
+ * @api private
+ */
+
+ tok: function(type, val){
+ return {
+ type: type
+ , line: this.lineno
+ , val: val
+ }
+ },
+
+ /**
+ * Consume the given `len` of input.
+ *
+ * @param {Number} len
+ * @api private
+ */
+
+ consume: function(len){
+ this.input = this.input.substr(len);
+ },
+
+ /**
+ * Scan for `type` with the given `regexp`.
+ *
+ * @param {String} type
+ * @param {RegExp} regexp
+ * @return {Object}
+ * @api private
+ */
+
+ scan: function(regexp, type){
+ var captures;
+ if (captures = regexp.exec(this.input)) {
+ this.consume(captures[0].length);
+ return this.tok(type, captures[1]);
+ }
+ },
+
+ /**
+ * Defer the given `tok`.
+ *
+ * @param {Object} tok
+ * @api private
+ */
+
+ defer: function(tok){
+ this.deferredTokens.push(tok);
+ },
+
+ /**
+ * Lookahead `n` tokens.
+ *
+ * @param {Number} n
+ * @return {Object}
+ * @api private
+ */
+
+ lookahead: function(n){
+ var fetch = n - this.stash.length;
+ while (fetch-- > 0) this.stash.push(this.next());
+ return this.stash[--n];
+ },
+
+ /**
+ * Return the indexOf `start` / `end` delimiters.
+ *
+ * @param {String} start
+ * @param {String} end
+ * @return {Number}
+ * @api private
+ */
+
+ indexOfDelimiters: function(start, end){
+ var str = this.input
+ , nstart = 0
+ , nend = 0
+ , pos = 0;
+ for (var i = 0, len = str.length; i < len; ++i) {
+ if (start == str[i]) {
+ ++nstart;
+ } else if (end == str[i]) {
+ if (++nend == nstart) {
+ pos = i;
+ break;
+ }
+ }
+ }
+ return pos;
+ },
+
+ /**
+ * Stashed token.
+ */
+
+ stashed: function() {
+ return this.stash.length
+ && this.stash.shift();
+ },
+
+ /**
+ * Deferred token.
+ */
+
+ deferred: function() {
+ return this.deferredTokens.length
+ && this.deferredTokens.shift();
+ },
+
+ /**
+ * end-of-source.
+ */
+
+ eos: function() {
+ if (this.input.length) return;
+ if (this.indentStack.length) {
+ this.indentStack.shift();
+ return this.tok('outdent');
+ } else {
+ return this.tok('eos');
+ }
+ },
+
+ /**
+ * Comment.
+ */
+
+ comment: function() {
+ var captures;
+ if (captures = /^ *\/\/(-)?([^\n]*)/.exec(this.input)) {
+ this.consume(captures[0].length);
+ var tok = this.tok('comment', captures[2]);
+ tok.buffer = '-' != captures[1];
+ return tok;
+ }
+ },
+
+ /**
+ * Tag.
+ */
+
+ tag: function() {
+ var captures;
+ if (captures = /^(\w[-:\w]*)/.exec(this.input)) {
+ this.consume(captures[0].length);
+ var tok, name = captures[1];
+ if (':' == name[name.length - 1]) {
+ name = name.slice(0, -1);
+ tok = this.tok('tag', name);
+ this.defer(this.tok(':'));
+ while (' ' == this.input[0]) this.input = this.input.substr(1);
+ } else {
+ tok = this.tok('tag', name);
+ }
+ return tok;
+ }
+ },
+
+ /**
+ * Filter.
+ */
+
+ filter: function() {
+ return this.scan(/^:(\w+)/, 'filter');
+ },
+
+ /**
+ * Doctype.
+ */
+
+ doctype: function() {
+ return this.scan(/^(?:!!!|doctype) *([^\n]+)?/, 'doctype');
+ },
+
+ /**
+ * Id.
+ */
+
+ id: function() {
+ return this.scan(/^#([\w-]+)/, 'id');
+ },
+
+ /**
+ * Class.
+ */
+
+ className: function() {
+ return this.scan(/^\.([\w-]+)/, 'class');
+ },
+
+ /**
+ * Text.
+ */
+
+ text: function() {
+ return this.scan(/^(?:\| ?)?([^\n]+)/, 'text');
+ },
+
+ /**
+ * Extends.
+ */
+
+ extends: function() {
+ return this.scan(/^extends +([^\n]+)/, 'extends');
+ },
+
+ /**
+ * Block prepend.
+ */
+
+ prepend: function() {
+ var captures;
+ if (captures = /^prepend +([^\n]+)/.exec(this.input)) {
+ this.consume(captures[0].length);
+ var mode = 'prepend'
+ , name = captures[1]
+ , tok = this.tok('block', name);
+ tok.mode = mode;
+ return tok;
+ }
+ },
+
+ /**
+ * Block append.
+ */
+
+ append: function() {
+ var captures;
+ if (captures = /^append +([^\n]+)/.exec(this.input)) {
+ this.consume(captures[0].length);
+ var mode = 'append'
+ , name = captures[1]
+ , tok = this.tok('block', name);
+ tok.mode = mode;
+ return tok;
+ }
+ },
+
+ /**
+ * Block.
+ */
+
+ block: function() {
+ var captures;
+ if (captures = /^block +(?:(prepend|append) +)?([^\n]+)/.exec(this.input)) {
+ this.consume(captures[0].length);
+ var mode = captures[1] || 'replace'
+ , name = captures[2]
+ , tok = this.tok('block', name);
+ tok.mode = mode;
+ return tok;
+ }
+ },
+
+ /**
+ * Yield.
+ */
+
+ yield: function() {
+ return this.scan(/^yield */, 'yield');
+ },
+
+ /**
+ * Include.
+ */
+
+ include: function() {
+ return this.scan(/^include +([^\n]+)/, 'include');
+ },
+
+ /**
+ * Case.
+ */
+
+ case: function() {
+ return this.scan(/^case +([^\n]+)/, 'case');
+ },
+
+ /**
+ * When.
+ */
+
+ when: function() {
+ return this.scan(/^when +([^:\n]+)/, 'when');
+ },
+
+ /**
+ * Default.
+ */
+
+ default: function() {
+ return this.scan(/^default */, 'default');
+ },
+
+ /**
+ * Assignment.
+ */
+
+ assignment: function() {
+ var captures;
+ if (captures = /^(\w+) += *([^;\n]+)( *;? *)/.exec(this.input)) {
+ this.consume(captures[0].length);
+ var name = captures[1]
+ , val = captures[2];
+ return this.tok('code', 'var ' + name + ' = (' + val + ');');
+ }
+ },
+
+ /**
+ * Mixin.
+ */
+
+ mixin: function(){
+ var captures;
+ if (captures = /^mixin +([-\w]+)(?: *\((.*)\))?/.exec(this.input)) {
+ this.consume(captures[0].length);
+ var tok = this.tok('mixin', captures[1]);
+ tok.args = captures[2];
+ return tok;
+ }
+ },
+
+ /**
+ * Conditional.
+ */
+
+ conditional: function() {
+ var captures;
+ if (captures = /^(if|unless|else if|else)\b([^\n]*)/.exec(this.input)) {
+ this.consume(captures[0].length);
+ var type = captures[1]
+ , js = captures[2];
+
+ switch (type) {
+ case 'if': js = 'if (' + js + ')'; break;
+ case 'unless': js = 'if (!(' + js + '))'; break;
+ case 'else if': js = 'else if (' + js + ')'; break;
+ case 'else': js = 'else'; break;
+ }
+
+ return this.tok('code', js);
+ }
+ },
+
+ /**
+ * While.
+ */
+
+ while: function() {
+ var captures;
+ if (captures = /^while +([^\n]+)/.exec(this.input)) {
+ this.consume(captures[0].length);
+ return this.tok('code', 'while (' + captures[1] + ')');
+ }
+ },
+
+ /**
+ * Each.
+ */
+
+ each: function() {
+ var captures;
+ if (captures = /^(?:- *)?(?:each|for) +(\w+)(?: *, *(\w+))? * in *([^\n]+)/.exec(this.input)) {
+ this.consume(captures[0].length);
+ var tok = this.tok('each', captures[1]);
+ tok.key = captures[2] || '$index';
+ tok.code = captures[3];
+ return tok;
+ }
+ },
+
+ /**
+ * Code.
+ */
+
+ code: function() {
+ var captures;
+ if (captures = /^(!?=|-)([^\n]+)/.exec(this.input)) {
+ this.consume(captures[0].length);
+ var flags = captures[1];
+ captures[1] = captures[2];
+ var tok = this.tok('code', captures[1]);
+ tok.escape = flags[0] === '=';
+ tok.buffer = flags[0] === '=' || flags[1] === '=';
+ return tok;
+ }
+ },
+
+ /**
+ * Attributes.
+ */
+
+ attrs: function() {
+ if ('(' == this.input[0]) {
+ var index = this.indexOfDelimiters('(', ')')
+ , str = this.input.substr(1, index-1)
+ , tok = this.tok('attrs')
+ , len = str.length
+ , colons = this.colons
+ , states = ['key']
+ , key = ''
+ , val = ''
+ , quote
+ , c;
+
+ function state(){
+ return states[states.length - 1];
+ }
+
+ function interpolate(attr) {
+ return attr.replace(/#\{([^}]+)\}/g, function(_, expr){
+ return quote + " + (" + expr + ") + " + quote;
+ });
+ }
+
+ this.consume(index + 1);
+ tok.attrs = {};
+
+ function parse(c) {
+ var real = c;
+ // TODO: remove when people fix ":"
+ if (colons && ':' == c) c = '=';
+ switch (c) {
+ case ',':
+ case '\n':
+ switch (state()) {
+ case 'expr':
+ case 'array':
+ case 'string':
+ case 'object':
+ val += c;
+ break;
+ default:
+ states.push('key');
+ val = val.trim();
+ key = key.trim();
+ if ('' == key) return;
+ tok.attrs[key.replace(/^['"]|['"]$/g, '')] = '' == val
+ ? true
+ : interpolate(val);
+ key = val = '';
+ }
+ break;
+ case '=':
+ switch (state()) {
+ case 'key char':
+ key += real;
+ break;
+ case 'val':
+ case 'expr':
+ case 'array':
+ case 'string':
+ case 'object':
+ val += real;
+ break;
+ default:
+ states.push('val');
+ }
+ break;
+ case '(':
+ if ('val' == state()
+ || 'expr' == state()) states.push('expr');
+ val += c;
+ break;
+ case ')':
+ if ('expr' == state()
+ || 'val' == state()) states.pop();
+ val += c;
+ break;
+ case '{':
+ if ('val' == state()) states.push('object');
+ val += c;
+ break;
+ case '}':
+ if ('object' == state()) states.pop();
+ val += c;
+ break;
+ case '[':
+ if ('val' == state()) states.push('array');
+ val += c;
+ break;
+ case ']':
+ if ('array' == state()) states.pop();
+ val += c;
+ break;
+ case '"':
+ case "'":
+ switch (state()) {
+ case 'key':
+ states.push('key char');
+ break;
+ case 'key char':
+ states.pop();
+ break;
+ case 'string':
+ if (c == quote) states.pop();
+ val += c;
+ break;
+ default:
+ states.push('string');
+ val += c;
+ quote = c;
+ }
+ break;
+ case '':
+ break;
+ default:
+ switch (state()) {
+ case 'key':
+ case 'key char':
+ key += c;
+ break;
+ default:
+ val += c;
+ }
+ }
+ }
+
+ for (var i = 0; i < len; ++i) {
+ parse(str[i]);
+ }
+
+ parse(',');
+
+ return tok;
+ }
+ },
+
+ /**
+ * Indent | Outdent | Newline.
+ */
+
+ indent: function() {
+ var captures, re;
+
+ // established regexp
+ if (this.indentRe) {
+ captures = this.indentRe.exec(this.input);
+ // determine regexp
+ } else {
+ // tabs
+ re = /^\n(\t*) */;
+ captures = re.exec(this.input);
+
+ // spaces
+ if (captures && !captures[1].length) {
+ re = /^\n( *)/;
+ captures = re.exec(this.input);
+ }
+
+ // established
+ if (captures && captures[1].length) this.indentRe = re;
+ }
+
+ if (captures) {
+ var tok
+ , indents = captures[1].length;
+
+ ++this.lineno;
+ this.consume(indents + 1);
+
+ if (' ' == this.input[0] || '\t' == this.input[0]) {
+ throw new Error('Invalid indentation, you can use tabs or spaces but not both');
+ }
+
+ // blank line
+ if ('\n' == this.input[0]) return this.tok('newline');
+
+ // outdent
+ if (this.indentStack.length && indents < this.indentStack[0]) {
+ while (this.indentStack.length && this.indentStack[0] > indents) {
+ this.stash.push(this.tok('outdent'));
+ this.indentStack.shift();
+ }
+ tok = this.stash.pop();
+ // indent
+ } else if (indents && indents != this.indentStack[0]) {
+ this.indentStack.unshift(indents);
+ tok = this.tok('indent', indents);
+ // newline
+ } else {
+ tok = this.tok('newline');
+ }
+
+ return tok;
+ }
+ },
+
+ /**
+ * Pipe-less text consumed only when
+ * pipeless is true;
+ */
+
+ pipelessText: function() {
+ if (this.pipeless) {
+ if ('\n' == this.input[0]) return;
+ var i = this.input.indexOf('\n');
+ if (-1 == i) i = this.input.length;
+ var str = this.input.substr(0, i);
+ this.consume(str.length);
+ return this.tok('text', str);
+ }
+ },
+
+ /**
+ * ':'
+ */
+
+ colon: function() {
+ return this.scan(/^: */, ':');
+ },
+
+ /**
+ * Return the next token object, or those
+ * previously stashed by lookahead.
+ *
+ * @return {Object}
+ * @api private
+ */
+
+ advance: function(){
+ return this.stashed()
+ || this.next();
+ },
+
+ /**
+ * Return the next token object.
+ *
+ * @return {Object}
+ * @api private
+ */
+
+ next: function() {
+ return this.deferred()
+ || this.eos()
+ || this.pipelessText()
+ || this.yield()
+ || this.doctype()
+ || this.case()
+ || this.when()
+ || this.default()
+ || this.extends()
+ || this.append()
+ || this.prepend()
+ || this.block()
+ || this.include()
+ || this.mixin()
+ || this.conditional()
+ || this.each()
+ || this.while()
+ || this.assignment()
+ || this.tag()
+ || this.filter()
+ || this.code()
+ || this.id()
+ || this.className()
+ || this.attrs()
+ || this.indent()
+ || this.comment()
+ || this.colon()
+ || this.text();
+ }
+};
+
+}); // module: lexer.js
+
+require.register("nodes/block-comment.js", function(module, exports, require){
+
+/*!
+ * Jade - nodes - BlockComment
+ * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
+ * MIT Licensed
+ */
+
+/**
+ * Module dependencies.
+ */
+
+var Node = require('./node');
+
+/**
+ * Initialize a `BlockComment` with the given `block`.
+ *
+ * @param {String} val
+ * @param {Block} block
+ * @param {Boolean} buffer
+ * @api public
+ */
+
+var BlockComment = module.exports = function BlockComment(val, block, buffer) {
+ this.block = block;
+ this.val = val;
+ this.buffer = buffer;
+};
+
+/**
+ * Inherit from `Node`.
+ */
+
+BlockComment.prototype = new Node;
+BlockComment.prototype.constructor = BlockComment;
+
+}); // module: nodes/block-comment.js
+
+require.register("nodes/block.js", function(module, exports, require){
+
+/*!
+ * Jade - nodes - Block
+ * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
+ * MIT Licensed
+ */
+
+/**
+ * Module dependencies.
+ */
+
+var Node = require('./node');
+
+/**
+ * Initialize a new `Block` with an optional `node`.
+ *
+ * @param {Node} node
+ * @api public
+ */
+
+var Block = module.exports = function Block(node){
+ this.nodes = [];
+ if (node) this.push(node);
+};
+
+/**
+ * Inherit from `Node`.
+ */
+
+Block.prototype = new Node;
+Block.prototype.constructor = Block;
+
+
+/**
+ * Replace the nodes in `other` with the nodes
+ * in `this` block.
+ *
+ * @param {Block} other
+ * @api private
+ */
+
+Block.prototype.replace = function(other){
+ other.nodes = this.nodes;
+};
+
+/**
+ * Pust the given `node`.
+ *
+ * @param {Node} node
+ * @return {Number}
+ * @api public
+ */
+
+Block.prototype.push = function(node){
+ return this.nodes.push(node);
+};
+
+/**
+ * Check if this block is empty.
+ *
+ * @return {Boolean}
+ * @api public
+ */
+
+Block.prototype.isEmpty = function(){
+ return 0 == this.nodes.length;
+};
+
+/**
+ * Unshift the given `node`.
+ *
+ * @param {Node} node
+ * @return {Number}
+ * @api public
+ */
+
+Block.prototype.unshift = function(node){
+ return this.nodes.unshift(node);
+};
+
+/**
+ * Return the "last" block, or the first `yield` node.
+ *
+ * @return {Block}
+ * @api private
+ */
+
+Block.prototype.includeBlock = function(){
+ var ret = this
+ , node;
+
+ for (var i = 0, len = this.nodes.length; i < len; ++i) {
+ node = this.nodes[i];
+ if (node.yield) return node;
+ else if (node.textOnly) continue;
+ else if (node.includeBlock) ret = node.includeBlock();
+ else if (node.block && !node.block.isEmpty()) ret = node.block.includeBlock();
+ }
+
+ return ret;
+};
+
+
+}); // module: nodes/block.js
+
+require.register("nodes/case.js", function(module, exports, require){
+
+/*!
+ * Jade - nodes - Case
+ * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
+ * MIT Licensed
+ */
+
+/**
+ * Module dependencies.
+ */
+
+var Node = require('./node');
+
+/**
+ * Initialize a new `Case` with `expr`.
+ *
+ * @param {String} expr
+ * @api public
+ */
+
+var Case = exports = module.exports = function Case(expr, block){
+ this.expr = expr;
+ this.block = block;
+};
+
+/**
+ * Inherit from `Node`.
+ */
+
+Case.prototype = new Node;
+Case.prototype.constructor = Case;
+
+
+var When = exports.When = function When(expr, block){
+ this.expr = expr;
+ this.block = block;
+ this.debug = false;
+};
+
+/**
+ * Inherit from `Node`.
+ */
+
+When.prototype = new Node;
+When.prototype.constructor = When;
+
+
+
+}); // module: nodes/case.js
+
+require.register("nodes/code.js", function(module, exports, require){
+
+/*!
+ * Jade - nodes - Code
+ * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
+ * MIT Licensed
+ */
+
+/**
+ * Module dependencies.
+ */
+
+var Node = require('./node');
+
+/**
+ * Initialize a `Code` node with the given code `val`.
+ * Code may also be optionally buffered and escaped.
+ *
+ * @param {String} val
+ * @param {Boolean} buffer
+ * @param {Boolean} escape
+ * @api public
+ */
+
+var Code = module.exports = function Code(val, buffer, escape) {
+ this.val = val;
+ this.buffer = buffer;
+ this.escape = escape;
+ if (val.match(/^ *else/)) this.debug = false;
+};
+
+/**
+ * Inherit from `Node`.
+ */
+
+Code.prototype = new Node;
+Code.prototype.constructor = Code;
+
+}); // module: nodes/code.js
+
+require.register("nodes/comment.js", function(module, exports, require){
+
+/*!
+ * Jade - nodes - Comment
+ * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
+ * MIT Licensed
+ */
+
+/**
+ * Module dependencies.
+ */
+
+var Node = require('./node');
+
+/**
+ * Initialize a `Comment` with the given `val`, optionally `buffer`,
+ * otherwise the comment may render in the output.
+ *
+ * @param {String} val
+ * @param {Boolean} buffer
+ * @api public
+ */
+
+var Comment = module.exports = function Comment(val, buffer) {
+ this.val = val;
+ this.buffer = buffer;
+};
+
+/**
+ * Inherit from `Node`.
+ */
+
+Comment.prototype = new Node;
+Comment.prototype.constructor = Comment;
+
+}); // module: nodes/comment.js
+
+require.register("nodes/doctype.js", function(module, exports, require){
+
+/*!
+ * Jade - nodes - Doctype
+ * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
+ * MIT Licensed
+ */
+
+/**
+ * Module dependencies.
+ */
+
+var Node = require('./node');
+
+/**
+ * Initialize a `Doctype` with the given `val`.
+ *
+ * @param {String} val
+ * @api public
+ */
+
+var Doctype = module.exports = function Doctype(val) {
+ this.val = val;
+};
+
+/**
+ * Inherit from `Node`.
+ */
+
+Doctype.prototype = new Node;
+Doctype.prototype.constructor = Doctype;
+
+}); // module: nodes/doctype.js
+
+require.register("nodes/each.js", function(module, exports, require){
+
+/*!
+ * Jade - nodes - Each
+ * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
+ * MIT Licensed
+ */
+
+/**
+ * Module dependencies.
+ */
+
+var Node = require('./node');
+
+/**
+ * Initialize an `Each` node, representing iteration
+ *
+ * @param {String} obj
+ * @param {String} val
+ * @param {String} key
+ * @param {Block} block
+ * @api public
+ */
+
+var Each = module.exports = function Each(obj, val, key, block) {
+ this.obj = obj;
+ this.val = val;
+ this.key = key;
+ this.block = block;
+};
+
+/**
+ * Inherit from `Node`.
+ */
+
+Each.prototype = new Node;
+Each.prototype.constructor = Each;
+
+}); // module: nodes/each.js
+
+require.register("nodes/filter.js", function(module, exports, require){
+
+/*!
+ * Jade - nodes - Filter
+ * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
+ * MIT Licensed
+ */
+
+/**
+ * Module dependencies.
+ */
+
+var Node = require('./node')
+ , Block = require('./block');
+
+/**
+ * Initialize a `Filter` node with the given
+ * filter `name` and `block`.
+ *
+ * @param {String} name
+ * @param {Block|Node} block
+ * @api public
+ */
+
+var Filter = module.exports = function Filter(name, block, attrs) {
+ this.name = name;
+ this.block = block;
+ this.attrs = attrs;
+ this.isASTFilter = block instanceof Block;
+};
+
+/**
+ * Inherit from `Node`.
+ */
+
+Filter.prototype = new Node;
+Filter.prototype.constructor = Filter;
+
+}); // module: nodes/filter.js
+
+require.register("nodes/index.js", function(module, exports, require){
+
+/*!
+ * Jade - nodes
+ * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
+ * MIT Licensed
+ */
+
+exports.Node = require('./node');
+exports.Tag = require('./tag');
+exports.Code = require('./code');
+exports.Each = require('./each');
+exports.Case = require('./case');
+exports.Text = require('./text');
+exports.Block = require('./block');
+exports.Mixin = require('./mixin');
+exports.Filter = require('./filter');
+exports.Comment = require('./comment');
+exports.Literal = require('./literal');
+exports.BlockComment = require('./block-comment');
+exports.Doctype = require('./doctype');
+
+}); // module: nodes/index.js
+
+require.register("nodes/literal.js", function(module, exports, require){
+
+/*!
+ * Jade - nodes - Literal
+ * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
+ * MIT Licensed
+ */
+
+/**
+ * Module dependencies.
+ */
+
+var Node = require('./node');
+
+/**
+ * Initialize a `Literal` node with the given `str.
+ *
+ * @param {String} str
+ * @api public
+ */
+
+var Literal = module.exports = function Literal(str) {
+ this.str = str
+ .replace(/\n/g, "\\n")
+ .replace(/'/g, "\\'");
+};
+
+/**
+ * Inherit from `Node`.
+ */
+
+Literal.prototype = new Node;
+Literal.prototype.constructor = Literal;
+
+
+}); // module: nodes/literal.js
+
+require.register("nodes/mixin.js", function(module, exports, require){
+
+/*!
+ * Jade - nodes - Mixin
+ * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
+ * MIT Licensed
+ */
+
+/**
+ * Module dependencies.
+ */
+
+var Node = require('./node');
+
+/**
+ * Initialize a new `Mixin` with `name` and `block`.
+ *
+ * @param {String} name
+ * @param {String} args
+ * @param {Block} block
+ * @api public
+ */
+
+var Mixin = module.exports = function Mixin(name, args, block){
+ this.name = name;
+ this.args = args;
+ this.block = block;
+};
+
+/**
+ * Inherit from `Node`.
+ */
+
+Mixin.prototype = new Node;
+Mixin.prototype.constructor = Mixin;
+
+
+
+}); // module: nodes/mixin.js
+
+require.register("nodes/node.js", function(module, exports, require){
+
+/*!
+ * Jade - nodes - Node
+ * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
+ * MIT Licensed
+ */
+
+/**
+ * Initialize a `Node`.
+ *
+ * @api public
+ */
+
+var Node = module.exports = function Node(){};
+}); // module: nodes/node.js
+
+require.register("nodes/tag.js", function(module, exports, require){
+
+/*!
+ * Jade - nodes - Tag
+ * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
+ * MIT Licensed
+ */
+
+/**
+ * Module dependencies.
+ */
+
+var Node = require('./node'),
+ Block = require('./block');
+
+/**
+ * Initialize a `Tag` node with the given tag `name` and optional `block`.
+ *
+ * @param {String} name
+ * @param {Block} block
+ * @api public
+ */
+
+var Tag = module.exports = function Tag(name, block) {
+ this.name = name;
+ this.attrs = [];
+ this.block = block || new Block;
+};
+
+/**
+ * Inherit from `Node`.
+ */
+
+Tag.prototype = new Node;
+Tag.prototype.constructor = Tag;
+
+
+/**
+ * Set attribute `name` to `val`, keep in mind these become
+ * part of a raw js object literal, so to quote a value you must
+ * '"quote me"', otherwise or example 'user.name' is literal JavaScript.
+ *
+ * @param {String} name
+ * @param {String} val
+ * @return {Tag} for chaining
+ * @api public
+ */
+
+Tag.prototype.setAttribute = function(name, val){
+ this.attrs.push({ name: name, val: val });
+ return this;
+};
+
+/**
+ * Remove attribute `name` when present.
+ *
+ * @param {String} name
+ * @api public
+ */
+
+Tag.prototype.removeAttribute = function(name){
+ for (var i = 0, len = this.attrs.length; i < len; ++i) {
+ if (this.attrs[i] && this.attrs[i].name == name) {
+ delete this.attrs[i];
+ }
+ }
+};
+
+/**
+ * Get attribute value by `name`.
+ *
+ * @param {String} name
+ * @return {String}
+ * @api public
+ */
+
+Tag.prototype.getAttribute = function(name){
+ for (var i = 0, len = this.attrs.length; i < len; ++i) {
+ if (this.attrs[i] && this.attrs[i].name == name) {
+ return this.attrs[i].val;
+ }
+ }
+};
+
+}); // module: nodes/tag.js
+
+require.register("nodes/text.js", function(module, exports, require){
+
+/*!
+ * Jade - nodes - Text
+ * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
+ * MIT Licensed
+ */
+
+/**
+ * Module dependencies.
+ */
+
+var Node = require('./node');
+
+/**
+ * Initialize a `Text` node with optional `line`.
+ *
+ * @param {String} line
+ * @api public
+ */
+
+var Text = module.exports = function Text(line) {
+ this.nodes = [];
+ if ('string' == typeof line) this.push(line);
+};
+
+/**
+ * Inherit from `Node`.
+ */
+
+Text.prototype = new Node;
+Text.prototype.constructor = Text;
+
+
+/**
+ * Push the given `node.`
+ *
+ * @param {Node} node
+ * @return {Number}
+ * @api public
+ */
+
+Text.prototype.push = function(node){
+ return this.nodes.push(node);
+};
+
+}); // module: nodes/text.js
+
+require.register("parser.js", function(module, exports, require){
+
+/*!
+ * Jade - Parser
+ * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
+ * MIT Licensed
+ */
+
+/**
+ * Module dependencies.
+ */
+
+var Lexer = require('./lexer')
+ , nodes = require('./nodes');
+
+/**
+ * Initialize `Parser` with the given input `str` and `filename`.
+ *
+ * @param {String} str
+ * @param {String} filename
+ * @param {Object} options
+ * @api public
+ */
+
+var Parser = exports = module.exports = function Parser(str, filename, options){
+ this.input = str;
+ this.lexer = new Lexer(str, options);
+ this.filename = filename;
+ this.blocks = {};
+ this.options = options;
+ this.contexts = [this];
+};
+
+/**
+ * Tags that may not contain tags.
+ */
+
+var textOnly = exports.textOnly = ['script', 'style'];
+
+/**
+ * Parser prototype.
+ */
+
+Parser.prototype = {
+
+ /**
+ * Push `parser` onto the context stack,
+ * or pop and return a `Parser`.
+ */
+
+ context: function(parser){
+ if (parser) {
+ this.contexts.push(parser);
+ } else {
+ return this.contexts.pop();
+ }
+ },
+
+ /**
+ * Return the next token object.
+ *
+ * @return {Object}
+ * @api private
+ */
+
+ advance: function(){
+ return this.lexer.advance();
+ },
+
+ /**
+ * Skip `n` tokens.
+ *
+ * @param {Number} n
+ * @api private
+ */
+
+ skip: function(n){
+ while (n--) this.advance();
+ },
+
+ /**
+ * Single token lookahead.
+ *
+ * @return {Object}
+ * @api private
+ */
+
+ peek: function() {
+ return this.lookahead(1);
+ },
+
+ /**
+ * Return lexer lineno.
+ *
+ * @return {Number}
+ * @api private
+ */
+
+ line: function() {
+ return this.lexer.lineno;
+ },
+
+ /**
+ * `n` token lookahead.
+ *
+ * @param {Number} n
+ * @return {Object}
+ * @api private
+ */
+
+ lookahead: function(n){
+ return this.lexer.lookahead(n);
+ },
+
+ /**
+ * Parse input returning a string of js for evaluation.
+ *
+ * @return {String}
+ * @api public
+ */
+
+ parse: function(){
+ var block = new nodes.Block, parser;
+ block.line = this.line();
+
+ while ('eos' != this.peek().type) {
+ if ('newline' == this.peek().type) {
+ this.advance();
+ } else {
+ block.push(this.parseExpr());
+ }
+ }
+
+ if (parser = this.extending) {
+ this.context(parser);
+ var ast = parser.parse();
+ this.context();
+ return ast;
+ }
+
+ return block;
+ },
+
+ /**
+ * Expect the given type, or throw an exception.
+ *
+ * @param {String} type
+ * @api private
+ */
+
+ expect: function(type){
+ if (this.peek().type === type) {
+ return this.advance();
+ } else {
+ throw new Error('expected "' + type + '", but got "' + this.peek().type + '"');
+ }
+ },
+
+ /**
+ * Accept the given `type`.
+ *
+ * @param {String} type
+ * @api private
+ */
+
+ accept: function(type){
+ if (this.peek().type === type) {
+ return this.advance();
+ }
+ },
+
+ /**
+ * tag
+ * | doctype
+ * | mixin
+ * | include
+ * | filter
+ * | comment
+ * | text
+ * | each
+ * | code
+ * | yield
+ * | id
+ * | class
+ */
+
+ parseExpr: function(){
+ switch (this.peek().type) {
+ case 'tag':
+ return this.parseTag();
+ case 'mixin':
+ return this.parseMixin();
+ case 'block':
+ return this.parseBlock();
+ case 'case':
+ return this.parseCase();
+ case 'when':
+ return this.parseWhen();
+ case 'default':
+ return this.parseDefault();
+ case 'extends':
+ return this.parseExtends();
+ case 'include':
+ return this.parseInclude();
+ case 'doctype':
+ return this.parseDoctype();
+ case 'filter':
+ return this.parseFilter();
+ case 'comment':
+ return this.parseComment();
+ case 'text':
+ return this.parseText();
+ case 'each':
+ return this.parseEach();
+ case 'code':
+ return this.parseCode();
+ case 'yield':
+ this.advance();
+ var block = new nodes.Block;
+ block.yield = true;
+ return block;
+ case 'id':
+ case 'class':
+ var tok = this.advance();
+ this.lexer.defer(this.lexer.tok('tag', 'div'));
+ this.lexer.defer(tok);
+ return this.parseExpr();
+ default:
+ throw new Error('unexpected token "' + this.peek().type + '"');
+ }
+ },
+
+ /**
+ * Text
+ */
+
+ parseText: function(){
+ var tok = this.expect('text')
+ , node = new nodes.Text(tok.val);
+ node.line = this.line();
+ return node;
+ },
+
+ /**
+ * ':' expr
+ * | block
+ */
+
+ parseBlockExpansion: function(){
+ if (':' == this.peek().type) {
+ this.advance();
+ return new nodes.Block(this.parseExpr());
+ } else {
+ return this.block();
+ }
+ },
+
+ /**
+ * case
+ */
+
+ parseCase: function(){
+ var val = this.expect('case').val
+ , node = new nodes.Case(val);
+ node.line = this.line();
+ node.block = this.block();
+ return node;
+ },
+
+ /**
+ * when
+ */
+
+ parseWhen: function(){
+ var val = this.expect('when').val
+ return new nodes.Case.When(val, this.parseBlockExpansion());
+ },
+
+ /**
+ * default
+ */
+
+ parseDefault: function(){
+ this.expect('default');
+ return new nodes.Case.When('default', this.parseBlockExpansion());
+ },
+
+ /**
+ * code
+ */
+
+ parseCode: function(){
+ var tok = this.expect('code')
+ , node = new nodes.Code(tok.val, tok.buffer, tok.escape)
+ , block
+ , i = 1;
+ node.line = this.line();
+ while (this.lookahead(i) && 'newline' == this.lookahead(i).type) ++i;
+ block = 'indent' == this.lookahead(i).type;
+ if (block) {
+ this.skip(i-1);
+ node.block = this.block();
+ }
+ return node;
+ },
+
+ /**
+ * comment
+ */
+
+ parseComment: function(){
+ var tok = this.expect('comment')
+ , node;
+
+ if ('indent' == this.peek().type) {
+ node = new nodes.BlockComment(tok.val, this.block(), tok.buffer);
+ } else {
+ node = new nodes.Comment(tok.val, tok.buffer);
+ }
+
+ node.line = this.line();
+ return node;
+ },
+
+ /**
+ * doctype
+ */
+
+ parseDoctype: function(){
+ var tok = this.expect('doctype')
+ , node = new nodes.Doctype(tok.val);
+ node.line = this.line();
+ return node;
+ },
+
+ /**
+ * filter attrs? text-block
+ */
+
+ parseFilter: function(){
+ var block
+ , tok = this.expect('filter')
+ , attrs = this.accept('attrs');
+
+ this.lexer.pipeless = true;
+ block = this.parseTextBlock();
+ this.lexer.pipeless = false;
+
+ var node = new nodes.Filter(tok.val, block, attrs && attrs.attrs);
+ node.line = this.line();
+ return node;
+ },
+
+ /**
+ * tag ':' attrs? block
+ */
+
+ parseASTFilter: function(){
+ var block
+ , tok = this.expect('tag')
+ , attrs = this.accept('attrs');
+
+ this.expect(':');
+ block = this.block();
+
+ var node = new nodes.Filter(tok.val, block, attrs && attrs.attrs);
+ node.line = this.line();
+ return node;
+ },
+
+ /**
+ * each block
+ */
+
+ parseEach: function(){
+ var tok = this.expect('each')
+ , node = new nodes.Each(tok.code, tok.val, tok.key);
+ node.line = this.line();
+ node.block = this.block();
+ return node;
+ },
+
+ /**
+ * 'extends' name
+ */
+
+ parseExtends: function(){
+ var path = require('path')
+ , fs = require('fs')
+ , dirname = path.dirname
+ , basename = path.basename
+ , join = path.join;
+
+ if (!this.filename)
+ throw new Error('the "filename" option is required to extend templates');
+
+ var path = this.expect('extends').val.trim()
+ , dir = dirname(this.filename);
+
+ var path = join(dir, path + '.jade')
+ , str = fs.readFileSync(path, 'utf8')
+ , parser = new Parser(str, path, this.options);
+
+ parser.blocks = this.blocks;
+ parser.contexts = this.contexts;
+ this.extending = parser;
+
+ // TODO: null node
+ return new nodes.Literal('');
+ },
+
+ /**
+ * 'block' name block
+ */
+
+ parseBlock: function(){
+ var block = this.expect('block')
+ , mode = block.mode
+ , name = block.val.trim();
+
+ block = 'indent' == this.peek().type
+ ? this.block()
+ : new nodes.Block(new nodes.Literal(''));
+
+ var prev = this.blocks[name];
+
+ if (prev) {
+ switch (prev.mode) {
+ case 'append':
+ block.nodes = block.nodes.concat(prev.nodes);
+ prev = block;
+ break;
+ case 'prepend':
+ block.nodes = prev.nodes.concat(block.nodes);
+ prev = block;
+ break;
+ }
+ }
+
+ block.mode = mode;
+ return this.blocks[name] = prev || block;
+ },
+
+ /**
+ * include block?
+ */
+
+ parseInclude: function(){
+ var path = require('path')
+ , fs = require('fs')
+ , dirname = path.dirname
+ , basename = path.basename
+ , join = path.join;
+
+ var path = this.expect('include').val.trim()
+ , dir = dirname(this.filename);
+
+ if (!this.filename)
+ throw new Error('the "filename" option is required to use includes');
+
+ // no extension
+ if (!~basename(path).indexOf('.')) {
+ path += '.jade';
+ }
+
+ // non-jade
+ if ('.jade' != path.substr(-5)) {
+ var path = join(dir, path)
+ , str = fs.readFileSync(path, 'utf8');
+ return new nodes.Literal(str);
+ }
+
+ var path = join(dir, path)
+ , str = fs.readFileSync(path, 'utf8')
+ , parser = new Parser(str, path, this.options);
+
+ this.context(parser);
+ var ast = parser.parse();
+ this.context();
+ ast.filename = path;
+
+ if ('indent' == this.peek().type) {
+ ast.includeBlock().push(this.block());
+ }
+
+ return ast;
+ },
+
+ /**
+ * mixin block
+ */
+
+ parseMixin: function(){
+ var tok = this.expect('mixin')
+ , name = tok.val
+ , args = tok.args;
+ var block = 'indent' == this.peek().type
+ ? this.block()
+ : null;
+ return new nodes.Mixin(name, args, block);
+ },
+
+ /**
+ * indent (text | newline)* outdent
+ */
+
+ parseTextBlock: function(){
+ var text = new nodes.Text;
+ text.line = this.line();
+ var spaces = this.expect('indent').val;
+ if (null == this._spaces) this._spaces = spaces;
+ var indent = Array(spaces - this._spaces + 1).join(' ');
+ while ('outdent' != this.peek().type) {
+ switch (this.peek().type) {
+ case 'newline':
+ text.push('\\n');
+ this.advance();
+ break;
+ case 'indent':
+ text.push('\\n');
+ this.parseTextBlock().nodes.forEach(function(node){
+ text.push(node);
+ });
+ text.push('\\n');
+ break;
+ default:
+ text.push(indent + this.advance().val);
+ }
+ }
+
+ if (spaces == this._spaces) this._spaces = null;
+ this.expect('outdent');
+ return text;
+ },
+
+ /**
+ * indent expr* outdent
+ */
+
+ block: function(){
+ var block = new nodes.Block;
+ block.line = this.line();
+ this.expect('indent');
+ while ('outdent' != this.peek().type) {
+ if ('newline' == this.peek().type) {
+ this.advance();
+ } else {
+ block.push(this.parseExpr());
+ }
+ }
+ this.expect('outdent');
+ return block;
+ },
+
+ /**
+ * tag (attrs | class | id)* (text | code | ':')? newline* block?
+ */
+
+ parseTag: function(){
+ // ast-filter look-ahead
+ var i = 2;
+ if ('attrs' == this.lookahead(i).type) ++i;
+ if (':' == this.lookahead(i).type) {
+ if ('indent' == this.lookahead(++i).type) {
+ return this.parseASTFilter();
+ }
+ }
+
+ var name = this.advance().val
+ , tag = new nodes.Tag(name)
+ , dot;
+
+ tag.line = this.line();
+
+ // (attrs | class | id)*
+ out:
+ while (true) {
+ switch (this.peek().type) {
+ case 'id':
+ case 'class':
+ var tok = this.advance();
+ tag.setAttribute(tok.type, "'" + tok.val + "'");
+ continue;
+ case 'attrs':
+ var obj = this.advance().attrs
+ , names = Object.keys(obj);
+ for (var i = 0, len = names.length; i < len; ++i) {
+ var name = names[i]
+ , val = obj[name];
+ tag.setAttribute(name, val);
+ }
+ continue;
+ default:
+ break out;
+ }
+ }
+
+ // check immediate '.'
+ if ('.' == this.peek().val) {
+ dot = tag.textOnly = true;
+ this.advance();
+ }
+
+ // (text | code | ':')?
+ switch (this.peek().type) {
+ case 'text':
+ tag.text = this.parseText();
+ break;
+ case 'code':
+ tag.code = this.parseCode();
+ break;
+ case ':':
+ this.advance();
+ tag.block = new nodes.Block;
+ tag.block.push(this.parseTag());
+ break;
+ }
+
+ // newline*
+ while ('newline' == this.peek().type) this.advance();
+
+ tag.textOnly = tag.textOnly || ~textOnly.indexOf(tag.name);
+
+ // script special-case
+ if ('script' == tag.name) {
+ var type = tag.getAttribute('type');
+ if (!dot && type && 'text/javascript' != type.replace(/^['"]|['"]$/g, '')) {
+ tag.textOnly = false;
+ }
+ }
+
+ // block?
+ if ('indent' == this.peek().type) {
+ if (tag.textOnly) {
+ this.lexer.pipeless = true;
+ tag.block = this.parseTextBlock();
+ this.lexer.pipeless = false;
+ } else {
+ var block = this.block();
+ if (tag.block) {
+ for (var i = 0, len = block.nodes.length; i < len; ++i) {
+ tag.block.push(block.nodes[i]);
+ }
+ } else {
+ tag.block = block;
+ }
+ }
+ }
+
+ return tag;
+ }
+};
+
+}); // module: parser.js
+
+require.register("runtime.js", function(module, exports, require){
+
+/*!
+ * Jade - runtime
+ * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
+ * MIT Licensed
+ */
+
+/**
+ * Lame Array.isArray() polyfill for now.
+ */
+
+if (!Array.isArray) {
+ Array.isArray = function(arr){
+ return '[object Array]' == Object.prototype.toString.call(arr);
+ };
+}
+
+/**
+ * Lame Object.keys() polyfill for now.
+ */
+
+if (!Object.keys) {
+ Object.keys = function(obj){
+ var arr = [];
+ for (var key in obj) {
+ if (obj.hasOwnProperty(key)) {
+ arr.push(key);
+ }
+ }
+ return arr;
+ }
+}
+
+/**
+ * Render the given attributes object.
+ *
+ * @param {Object} obj
+ * @return {String}
+ * @api private
+ */
+
+exports.attrs = function attrs(obj){
+ var buf = []
+ , terse = obj.terse;
+ delete obj.terse;
+ var keys = Object.keys(obj)
+ , len = keys.length;
+ if (len) {
+ buf.push('');
+ for (var i = 0; i < len; ++i) {
+ var key = keys[i]
+ , val = obj[key];
+ if ('boolean' == typeof val || null == val) {
+ if (val) {
+ terse
+ ? buf.push(key)
+ : buf.push(key + '="' + key + '"');
+ }
+ } else if ('class' == key && Array.isArray(val)) {
+ buf.push(key + '="' + exports.escape(val.join(' ')) + '"');
+ } else {
+ buf.push(key + '="' + exports.escape(val) + '"');
+ }
+ }
+ }
+ return buf.join(' ');
+};
+
+/**
+ * Escape the given string of `html`.
+ *
+ * @param {String} html
+ * @return {String}
+ * @api private
+ */
+
+exports.escape = function escape(html){
+ return String(html)
+ .replace(/&(?!\w+;)/g, '&amp;')
+ .replace(/</g, '&lt;')
+ .replace(/>/g, '&gt;')
+ .replace(/"/g, '&quot;');
+};
+
+/**
+ * Re-throw the given `err` in context to the
+ * the jade in `filename` at the given `lineno`.
+ *
+ * @param {Error} err
+ * @param {String} filename
+ * @param {String} lineno
+ * @api private
+ */
+
+exports.rethrow = function rethrow(err, filename, lineno){
+ if (!filename) throw err;
+
+ var context = 3
+ , str = require('fs').readFileSync(filename, 'utf8')
+ , lines = str.split('\n')
+ , start = Math.max(lineno - context, 0)
+ , end = Math.min(lines.length, lineno + context);
+
+ // Error context
+ var context = lines.slice(start, end).map(function(line, i){
+ var curr = i + start + 1;
+ return (curr == lineno ? ' > ' : ' ')
+ + curr
+ + '| '
+ + line;
+ }).join('\n');
+
+ // Alter exception message
+ err.path = filename;
+ err.message = (filename || 'Jade') + ':' + lineno
+ + '\n' + context + '\n\n' + err.message;
+ throw err;
+};
+
+}); // module: runtime.js
+
+require.register("self-closing.js", function(module, exports, require){
+
+/*!
+ * Jade - self closing tags
+ * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
+ * MIT Licensed
+ */
+
+module.exports = [
+ 'meta'
+ , 'img'
+ , 'link'
+ , 'input'
+ , 'area'
+ , 'base'
+ , 'col'
+ , 'br'
+ , 'hr'
+];
+}); // module: self-closing.js
+
+require.register("utils.js", function(module, exports, require){
+
+/*!
+ * Jade - utils
+ * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
+ * MIT Licensed
+ */
+
+/**
+ * Convert interpolation in the given string to JavaScript.
+ *
+ * @param {String} str
+ * @return {String}
+ * @api private
+ */
+
+var interpolate = exports.interpolate = function(str){
+ return str.replace(/(\\)?([#!]){(.*?)}/g, function(str, escape, flag, code){
+ return escape
+ ? str
+ : "' + "
+ + ('!' == flag ? '' : 'escape')
+ + "((interp = " + code.replace(/\\'/g, "'")
+ + ") == null ? '' : interp) + '";
+ });
+};
+
+/**
+ * Escape single quotes in `str`.
+ *
+ * @param {String} str
+ * @return {String}
+ * @api private
+ */
+
+var escape = exports.escape = function(str) {
+ return str.replace(/'/g, "\\'");
+};
+
+/**
+ * Interpolate, and escape the given `str`.
+ *
+ * @param {String} str
+ * @return {String}
+ * @api private
+ */
+
+exports.text = function(str){
+ return interpolate(escape(str));
+};
+}); // module: utils.js
+
+window.jade = require("jade");
+})();
diff --git a/node_modules/mocha/node_modules/jade/jade.min.js b/node_modules/mocha/node_modules/jade/jade.min.js
new file mode 100644
index 0000000..ace59ff
--- /dev/null
+++ b/node_modules/mocha/node_modules/jade/jade.min.js
@@ -0,0 +1,2 @@
+(function(){function require(p){var path=require.resolve(p),mod=require.modules[path];if(!mod)throw new Error('failed to require "'+p+'"');return mod.exports||(mod.exports={},mod.call(mod.exports,mod,mod.exports,require.relative(path))),mod.exports}require.modules={},require.resolve=function(path){var orig=path,reg=path+".js",index=path+"/index.js";return require.modules[reg]&&reg||require.modules[index]&&index||orig},require.register=function(path,fn){require.modules[path]=fn},require.relative=function(parent){return function(p){if("."!=p[0])return require(p);var path=parent.split("/"),segs=p.split("/");path.pop();for(var i=0;i<segs.length;i++){var seg=segs[i];".."==seg?path.pop():"."!=seg&&path.push(seg)}return require(path.join("/"))}},require.register("compiler.js",function(module,exports,require){var nodes=require("./nodes"),filters=require("./filters"),doctypes=require("./doctypes"),selfClosing=require("./self-closing"),inlineTags=require("./inline-tags"),utils=require("./utils");Object.keys||(Object.keys=function(obj){var arr=[];for(var key in obj)obj.hasOwnProperty(key)&&arr.push(key);return arr}),String.prototype.trimLeft||(String.prototype.trimLeft=function(){return this.replace(/^\s+/,"")});var Compiler=module.exports=function(node,options){this.options=options=options||{},this.node=node,this.hasCompiledDoctype=!1,this.hasCompiledTag=!1,this.pp=options.pretty||!1,this.debug=!1!==options.compileDebug,this.indents=0,options.doctype&&this.setDoctype(options.doctype)};Compiler.prototype={compile:function(){return this.buf=["var interp;"],this.lastBufferedIdx=-1,this.visit(this.node),this.buf.join("\n")},setDoctype:function(name){var doctype=doctypes[(name||"default").toLowerCase()];doctype=doctype||"<!DOCTYPE "+name+">",this.doctype=doctype,this.terse="5"==name||"html"==name,this.xml=0==this.doctype.indexOf("<?xml")},buffer:function(str,esc){esc&&(str=utils.escape(str)),this.lastBufferedIdx==this.buf.length?(this.lastBuffered+=str,this.buf[this.lastBufferedIdx-1]="buf.push('"+this.lastBuffered+"');"):(this.buf.push("buf.push('"+str+"');"),this.lastBuffered=str,this.lastBufferedIdx=this.buf.length)},visit:function(node){var debug=this.debug;debug&&this.buf.push("__jade.unshift({ lineno: "+node.line+", filename: "+(node.filename?'"'+node.filename+'"':"__jade[0].filename")+" });"),!1===node.debug&&this.debug&&(this.buf.pop(),this.buf.pop()),this.visitNode(node),debug&&this.buf.push("__jade.shift();")},visitNode:function(node){var name=node.constructor.name||node.constructor.toString().match(/function ([^(\s]+)()/)[1];return this["visit"+name](node)},visitCase:function(node){var _=this.withinCase;this.withinCase=!0,this.buf.push("switch ("+node.expr+"){"),this.visit(node.block),this.buf.push("}"),this.withinCase=_},visitWhen:function(node){"default"==node.expr?this.buf.push("default:"):this.buf.push("case "+node.expr+":"),this.visit(node.block),this.buf.push(" break;")},visitLiteral:function(node){var str=node.str.replace(/\n/g,"\\\\n");this.buffer(str)},visitBlock:function(block){var len=block.nodes.length;for(var i=0;i<len;++i)this.visit(block.nodes[i])},visitDoctype:function(doctype){doctype&&(doctype.val||!this.doctype)&&this.setDoctype(doctype.val||"default"),this.doctype&&this.buffer(this.doctype),this.hasCompiledDoctype=!0},visitMixin:function(mixin){var name=mixin.name.replace(/-/g,"_")+"_mixin",args=mixin.args||"";mixin.block?(this.buf.push("var "+name+" = function("+args+"){"),this.visit(mixin.block),this.buf.push("}")):this.buf.push(name+"("+args+");")},visitTag:function(tag){this.indents++;var name=tag.name;this.hasCompiledTag||(!this.hasCompiledDoctype&&"html"==name&&this.visitDoctype(),this.hasCompiledTag=!0),this.pp&&inlineTags.indexOf(name)==-1&&this.buffer("\\n"+Array(this.indents).join(" ")),~selfClosing.indexOf(name)&&!this.xml?(this.buffer("<"+name),this.visitAttributes(tag.attrs),this.terse?this.buffer(">"):this.buffer("/>")):(tag.attrs.length?(this.buffer("<"+name),tag.attrs.length&&this.visitAttributes(tag.attrs),this.buffer(">")):this.buffer("<"+name+">"),tag.code&&this.visitCode(tag.code),tag.text&&this.buffer(utils.text(tag.text.nodes[0].trimLeft())),this.escape="pre"==tag.name,this.visit(tag.block),this.pp&&!~inlineTags.indexOf(name)&&!tag.textOnly&&this.buffer("\\n"+Array(this.indents).join(" ")),this.buffer("</"+name+">")),this.indents--},visitFilter:function(filter){var fn=filters[filter.name];if(!fn)throw filter.isASTFilter?new Error('unknown ast filter "'+filter.name+':"'):new Error('unknown filter ":'+filter.name+'"');if(filter.isASTFilter)this.buf.push(fn(filter.block,this,filter.attrs));else{var text=filter.block.nodes.join("");this.buffer(utils.text(fn(text,filter.attrs)))}},visitText:function(text){text=utils.text(text.nodes.join("")),this.escape&&(text=escape(text)),this.buffer(text),this.buffer("\\n")},visitComment:function(comment){if(!comment.buffer)return;this.pp&&this.buffer("\\n"+Array(this.indents+1).join(" ")),this.buffer("<!--"+utils.escape(comment.val)+"-->")},visitBlockComment:function(comment){if(!comment.buffer)return;0==comment.val.trim().indexOf("if")?(this.buffer("<!--["+comment.val.trim()+"]>"),this.visit(comment.block),this.buffer("<![endif]-->")):(this.buffer("<!--"+comment.val),this.visit(comment.block),this.buffer("-->"))},visitCode:function(code){if(code.buffer){var val=code.val.trimLeft();this.buf.push("var __val__ = "+val),val='null == __val__ ? "" : __val__',code.escape&&(val="escape("+val+")"),this.buf.push("buf.push("+val+");")}else this.buf.push(code.val);code.block&&(code.buffer||this.buf.push("{"),this.visit(code.block),code.buffer||this.buf.push("}"))},visitEach:function(each){this.buf.push("// iterate "+each.obj+"\n"+"(function(){\n"+" if ('number' == typeof "+each.obj+".length) {\n"+" for (var "+each.key+" = 0, $$l = "+each.obj+".length; "+each.key+" < $$l; "+each.key+"++) {\n"+" var "+each.val+" = "+each.obj+"["+each.key+"];\n"),this.visit(each.block),this.buf.push(" }\n } else {\n for (var "+each.key+" in "+each.obj+") {\n"+" if ("+each.obj+".hasOwnProperty("+each.key+")){"+" var "+each.val+" = "+each.obj+"["+each.key+"];\n"),this.visit(each.block),this.buf.push(" }\n"),this.buf.push(" }\n }\n}).call(this);\n")},visitAttributes:function(attrs){var buf=[],classes=[];this.terse&&buf.push("terse: true"),attrs.forEach(function(attr){if(attr.name=="class")classes.push("("+attr.val+")");else{var pair="'"+attr.name+"':("+attr.val+")";buf.push(pair)}}),classes.length&&(classes=classes.join(" + ' ' + "),buf.push("class: "+classes)),buf=buf.join(", ").replace("class:",'"class":'),this.buf.push("buf.push(attrs({ "+buf+" }));")}};function escape(html){return String(html).replace(/&(?!\w+;)/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}}),require.register("doctypes.js",function(module,exports,require){module.exports={5:"<!DOCTYPE html>",xml:'<?xml version="1.0" encoding="utf-8" ?>',"default":'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">',transitional:'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">',strict:'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">',frameset:'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">',1.1:'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">',basic:'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN" "http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd">',mobile:'<!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.2//EN" "http://www.openmobilealliance.org/tech/DTD/xhtml-mobile12.dtd">'}}),require.register("filters.js",function(module,exports,require){module.exports={cdata:function(str){return"<![CDATA[\\n"+str+"\\n]]>"},sass:function(str){str=str.replace(/\\n/g,"\n");var sass=require("sass").render(str).replace(/\n/g,"\\n");return'<style type="text/css">'+sass+"</style>"},stylus:function(str,options){var ret;str=str.replace(/\\n/g,"\n");var stylus=require("stylus");return stylus(str,options).render(function(err,css){if(err)throw err;ret=css.replace(/\n/g,"\\n")}),'<style type="text/css">'+ret+"</style>"},less:function(str){var ret;return str=str.replace(/\\n/g,"\n"),require("less").render(str,function(err,css){if(err)throw err;ret='<style type="text/css">'+css.replace(/\n/g,"\\n")+"</style>"}),ret},markdown:function(str){var md;try{md=require("markdown")}catch(err){try{md=require("discount")}catch(err){try{md=require("markdown-js")}catch(err){try{md=require("marked")}catch(err){throw new Error("Cannot find markdown library, install markdown, discount, or marked.")}}}}return str=str.replace(/\\n/g,"\n"),md.parse(str).replace(/\n/g,"\\n").replace(/'/g,"&#39;")},coffeescript:function(str){str=str.replace(/\\n/g,"\n");var js=require("coffee-script").compile(str).replace(/\n/g,"\\n");return'<script type="text/javascript">\\n'+js+"</script>"}}}),require.register("inline-tags.js",function(module,exports,require){module.exports=["a","abbr","acronym","b","br","code","em","font","i","img","ins","kbd","map","samp","small","span","strong","sub","sup"]}),require.register("jade.js",function(module,exports,require){var Parser=require("./parser"),Lexer=require("./lexer"),Compiler=require("./compiler"),runtime=require("./runtime");exports.version="0.20.1",exports.selfClosing=require("./self-closing"),exports.doctypes=require("./doctypes"),exports.filters=require("./filters"),exports.utils=require("./utils"),exports.Compiler=Compiler,exports.Parser=Parser,exports.Lexer=Lexer,exports.nodes=require("./nodes"),exports.runtime=runtime,exports.cache={};function parse(str,options){try{var parser=new Parser(str,options.filename,options),compiler=new(options.compiler||Compiler)(parser.parse(),options),js=compiler.compile();return options.debug&&console.error("\nCompiled Function:\n\n%s",js.replace(/^/gm," ")),"var buf = [];\n"+(options.self?"var self = locals || {};\n"+js:"with (locals || {}) {\n"+js+"\n}\n")+'return buf.join("");'}catch(err){parser=parser.context(),runtime.rethrow(err,parser.filename,parser.lexer.lineno)}}exports.compile=function(str,options){var options=options||{},client=options.client,filename=options.filename?JSON.stringify(options.filename):"undefined",fn;return options.compileDebug!==!1?fn=["var __jade = [{ lineno: 1, filename: "+filename+" }];","try {",parse(String(str),options),"} catch (err) {"," rethrow(err, __jade[0].filename, __jade[0].lineno);","}"].join("\n"):fn=parse(String(str),options),client&&(fn="var attrs = jade.attrs, escape = jade.escape, rethrow = jade.rethrow;\n"+fn),fn=new Function("locals, attrs, escape, rethrow",fn),client?fn:function(locals){return fn(locals,runtime.attrs,runtime.escape,runtime.rethrow)}},exports.render=function(str,options,fn){"function"==typeof options&&(fn=options,options={});if(options.cache&&!options.filename)return fn(new Error('the "filename" option is required for caching'));try{var path=options.filename,tmpl=options.cache?exports.cache[path]||(exports.cache[path]=exports.compile(str,options)):exports.compile(str,options);fn(null,tmpl(options))}catch(err){fn(err)}},exports.renderFile=function(path,options,fn){var key=path+":string";"function"==typeof options&&(fn=options,options={});try{options.filename=path;var str=options.cache?exports.cache[key]||(exports.cache[key]=fs.readFileSync(path,"utf8")):fs.readFileSync(path,"utf8");exports.render(str,options,fn)}catch(err){fn(err)}},exports.__express=exports.renderFile}),require.register("lexer.js",function(module,exports,require){var Lexer=module.exports=function(str,options){options=options||{},this.input=str.replace(/\r\n|\r/g,"\n"),this.colons=options.colons,this.deferredTokens=[],this.lastIndents=0,this.lineno=1,this.stash=[],this.indentStack=[],this.indentRe=null,this.pipeless=!1};Lexer.prototype={tok:function(type,val){return{type:type,line:this.lineno,val:val}},consume:function(len){this.input=this.input.substr(len)},scan:function(regexp,type){var captures;if(captures=regexp.exec(this.input))return this.consume(captures[0].length),this.tok(type,captures[1])},defer:function(tok){this.deferredTokens.push(tok)},lookahead:function(n){var fetch=n-this.stash.length;while(fetch-->0)this.stash.push(this.next());return this.stash[--n]},indexOfDelimiters:function(start,end){var str=this.input,nstart=0,nend=0,pos=0;for(var i=0,len=str.length;i<len;++i)if(start==str[i])++nstart;else if(end==str[i]&&++nend==nstart){pos=i;break}return pos},stashed:function(){return this.stash.length&&this.stash.shift()},deferred:function(){return this.deferredTokens.length&&this.deferredTokens.shift()},eos:function(){if(this.input.length)return;return this.indentStack.length?(this.indentStack.shift(),this.tok("outdent")):this.tok("eos")},comment:function(){var captures;if(captures=/^ *\/\/(-)?([^\n]*)/.exec(this.input)){this.consume(captures[0].length);var tok=this.tok("comment",captures[2]);return tok.buffer="-"!=captures[1],tok}},tag:function(){var captures;if(captures=/^(\w[-:\w]*)/.exec(this.input)){this.consume(captures[0].length);var tok,name=captures[1];if(":"==name[name.length-1]){name=name.slice(0,-1),tok=this.tok("tag",name),this.defer(this.tok(":"));while(" "==this.input[0])this.input=this.input.substr(1)}else tok=this.tok("tag",name);return tok}},filter:function(){return this.scan(/^:(\w+)/,"filter")},doctype:function(){return this.scan(/^(?:!!!|doctype) *([^\n]+)?/,"doctype")},id:function(){return this.scan(/^#([\w-]+)/,"id")},className:function(){return this.scan(/^\.([\w-]+)/,"class")},text:function(){return this.scan(/^(?:\| ?)?([^\n]+)/,"text")},"extends":function(){return this.scan(/^extends +([^\n]+)/,"extends")},prepend:function(){var captures;if(captures=/^prepend +([^\n]+)/.exec(this.input)){this.consume(captures[0].length);var mode="prepend",name=captures[1],tok=this.tok("block",name);return tok.mode=mode,tok}},append:function(){var captures;if(captures=/^append +([^\n]+)/.exec(this.input)){this.consume(captures[0].length);var mode="append",name=captures[1],tok=this.tok("block",name);return tok.mode=mode,tok}},block:function(){var captures;if(captures=/^block +(?:(prepend|append) +)?([^\n]+)/.exec(this.input)){this.consume(captures[0].length);var mode=captures[1]||"replace",name=captures[2],tok=this.tok("block",name);return tok.mode=mode,tok}},yield:function(){return this.scan(/^yield */,"yield")},include:function(){return this.scan(/^include +([^\n]+)/,"include")},"case":function(){return this.scan(/^case +([^\n]+)/,"case")},when:function(){return this.scan(/^when +([^:\n]+)/,"when")},"default":function(){return this.scan(/^default */,"default")},assignment:function(){var captures;if(captures=/^(\w+) += *([^;\n]+)( *;? *)/.exec(this.input)){this.consume(captures[0].length);var name=captures[1],val=captures[2];return this.tok("code","var "+name+" = ("+val+");")}},mixin:function(){var captures;if(captures=/^mixin +([-\w]+)(?: *\((.*)\))?/.exec(this.input)){this.consume(captures[0].length);var tok=this.tok("mixin",captures[1]);return tok.args=captures[2],tok}},conditional:function(){var captures;if(captures=/^(if|unless|else if|else)\b([^\n]*)/.exec(this.input)){this.consume(captures[0].length);var type=captures[1],js=captures[2];switch(type){case"if":js="if ("+js+")";break;case"unless":js="if (!("+js+"))";break;case"else if":js="else if ("+js+")";break;case"else":js="else"}return this.tok("code",js)}},"while":function(){var captures;if(captures=/^while +([^\n]+)/.exec(this.input))return this.consume(captures[0].length),this.tok("code","while ("+captures[1]+")")},each:function(){var captures;if(captures=/^(?:- *)?(?:each|for) +(\w+)(?: *, *(\w+))? * in *([^\n]+)/.exec(this.input)){this.consume(captures[0].length);var tok=this.tok("each",captures[1]);return tok.key=captures[2]||"$index",tok.code=captures[3],tok}},code:function(){var captures;if(captures=/^(!?=|-)([^\n]+)/.exec(this.input)){this.consume(captures[0].length);var flags=captures[1];captures[1]=captures[2];var tok=this.tok("code",captures[1]);return tok.escape=flags[0]==="=",tok.buffer=flags[0]==="="||flags[1]==="=",tok}},attrs:function(){if("("==this.input[0]){var index=this.indexOfDelimiters("(",")"),str=this.input.substr(1,index-1),tok=this.tok("attrs"),len=str.length,colons=this.colons,states=["key"],key="",val="",quote,c;function state(){return states[states.length-1]}function interpolate(attr){return attr.replace(/#\{([^}]+)\}/g,function(_,expr){return quote+" + ("+expr+") + "+quote})}this.consume(index+1),tok.attrs={};function parse(c){var real=c;colons&&":"==c&&(c="=");switch(c){case",":case"\n":switch(state()){case"expr":case"array":case"string":case"object":val+=c;break;default:states.push("key"),val=val.trim(),key=key.trim();if(""==key)return;tok.attrs[key.replace(/^['"]|['"]$/g,"")]=""==val?!0:interpolate(val),key=val=""}break;case"=":switch(state()){case"key char":key+=real;break;case"val":case"expr":case"array":case"string":case"object":val+=real;break;default:states.push("val")}break;case"(":("val"==state()||"expr"==state())&&states.push("expr"),val+=c;break;case")":("expr"==state()||"val"==state())&&states.pop(),val+=c;break;case"{":"val"==state()&&states.push("object"),val+=c;break;case"}":"object"==state()&&states.pop(),val+=c;break;case"[":"val"==state()&&states.push("array"),val+=c;break;case"]":"array"==state()&&states.pop(),val+=c;break;case'"':case"'":switch(state()){case"key":states.push("key char");break;case"key char":states.pop();break;case"string":c==quote&&states.pop(),val+=c;break;default:states.push("string"),val+=c,quote=c}break;case"":break;default:switch(state()){case"key":case"key char":key+=c;break;default:val+=c}}}for(var i=0;i<len;++i)parse(str[i]);return parse(","),tok}},indent:function(){var captures,re;this.indentRe?captures=this.indentRe.exec(this.input):(re=/^\n(\t*) */,captures=re.exec(this.input),captures&&!captures[1].length&&(re=/^\n( *)/,captures=re.exec(this.input)),captures&&captures[1].length&&(this.indentRe=re));if(captures){var tok,indents=captures[1].length;++this.lineno,this.consume(indents+1);if(" "==this.input[0]||"\t"==this.input[0])throw new Error("Invalid indentation, you can use tabs or spaces but not both");if("\n"==this.input[0])return this.tok("newline");if(this.indentStack.length&&indents<this.indentStack[0]){while(this.indentStack.length&&this.indentStack[0]>indents)this.stash.push(this.tok("outdent")),this.indentStack.shift();tok=this.stash.pop()}else indents&&indents!=this.indentStack[0]?(this.indentStack.unshift(indents),tok=this.tok("indent",indents)):tok=this.tok("newline");return tok}},pipelessText:function(){if(this.pipeless){if("\n"==this.input[0])return;var i=this.input.indexOf("\n");-1==i&&(i=this.input.length);var str=this.input.substr(0,i);return this.consume(str.length),this.tok("text",str)}},colon:function(){return this.scan(/^: */,":")},advance:function(){return this.stashed()||this.next()},next:function(){return this.deferred()||this.eos()||this.pipelessText()||this.yield()||this.doctype()||this.case()||this.when()||this.default()||this.extends()||this.append()||this.prepend()||this.block()||this.include()||this.mixin()||this.conditional()||this.each()||this.while()||this.assignment()||this.tag()||this.filter()||this.code()||this.id()||this.className()||this.attrs()||this.indent()||this.comment()||this.colon()||this.text()}}}),require.register("nodes/block-comment.js",function(module,exports,require){var Node=require("./node"),BlockComment=module.exports=function(val,block,buffer){this.block=block,this.val=val,this.buffer=buffer};BlockComment.prototype=new Node,BlockComment.prototype.constructor=BlockComment}),require.register("nodes/block.js",function(module,exports,require){var Node=require("./node"),Block=module.exports=function(node){this.nodes=[],node&&this.push(node)};Block.prototype=new Node,Block.prototype.constructor=Block,Block.prototype.replace=function(other){other.nodes=this.nodes},Block.prototype.push=function(node){return this.nodes.push(node)},Block.prototype.isEmpty=function(){return 0==this.nodes.length},Block.prototype.unshift=function(node){return this.nodes.unshift(node)},Block.prototype.includeBlock=function(){var ret=this,node;for(var i=0,len=this.nodes.length;i<len;++i){node=this.nodes[i];if(node.yield)return node;if(node.textOnly)continue;node.includeBlock?ret=node.includeBlock():node.block&&!node.block.isEmpty()&&(ret=node.block.includeBlock())}return ret}}),require.register("nodes/case.js",function(module,exports,require){var Node=require("./node"),Case=exports=module.exports=function(expr,block){this.expr=expr,this.block=block};Case.prototype=new Node,Case.prototype.constructor=Case;var When=exports.When=function(expr,block){this.expr=expr,this.block=block,this.debug=!1};When.prototype=new Node,When.prototype.constructor=When}),require.register("nodes/code.js",function(module,exports,require){var Node=require("./node"),Code=module.exports=function(val,buffer,escape){this.val=val,this.buffer=buffer,this.escape=escape,val.match(/^ *else/)&&(this.debug=!1)};Code.prototype=new Node,Code.prototype.constructor=Code}),require.register("nodes/comment.js",function(module,exports,require){var Node=require("./node"),Comment=module.exports=function(val,buffer){this.val=val,this.buffer=buffer};Comment.prototype=new Node,Comment.prototype.constructor=Comment}),require.register("nodes/doctype.js",function(module,exports,require){var Node=require("./node"),Doctype=module.exports=function(val){this.val=val};Doctype.prototype=new Node,Doctype.prototype.constructor=Doctype}),require.register("nodes/each.js",function(module,exports,require){var Node=require("./node"),Each=module.exports=function(obj,val,key,block){this.obj=obj,this.val=val,this.key=key,this.block=block};Each.prototype=new Node,Each.prototype.constructor=Each}),require.register("nodes/filter.js",function(module,exports,require){var Node=require("./node"),Block=require("./block"),Filter=module.exports=function(name,block,attrs){this.name=name,this.block=block,this.attrs=attrs,this.isASTFilter=block instanceof Block};Filter.prototype=new Node,Filter.prototype.constructor=Filter}),require.register("nodes/index.js",function(module,exports,require){exports.Node=require("./node"),exports.Tag=require("./tag"),exports.Code=require("./code"),exports.Each=require("./each"),exports.Case=require("./case"),exports.Text=require("./text"),exports.Block=require("./block"),exports.Mixin=require("./mixin"),exports.Filter=require("./filter"),exports.Comment=require("./comment"),exports.Literal=require("./literal"),exports.BlockComment=require("./block-comment"),exports.Doctype=require("./doctype")}),require.register("nodes/literal.js",function(module,exports,require){var Node=require("./node"),Literal=module.exports=function(str){this.str=str.replace(/\n/g,"\\n").replace(/'/g,"\\'")};Literal.prototype=new Node,Literal.prototype.constructor=Literal}),require.register("nodes/mixin.js",function(module,exports,require){var Node=require("./node"),Mixin=module.exports=function(name,args,block){this.name=name,this.args=args,this.block=block};Mixin.prototype=new Node,Mixin.prototype.constructor=Mixin}),require.register("nodes/node.js",function(module,exports,require){var Node=module.exports=function(){}}),require.register("nodes/tag.js",function(module,exports,require){var Node=require("./node"),Block=require("./block"),Tag=module.exports=function(name,block){this.name=name,this.attrs=[],this.block=block||new Block};Tag.prototype=new Node,Tag.prototype.constructor=Tag,Tag.prototype.setAttribute=function(name,val){return this.attrs.push({name:name,val:val}),this},Tag.prototype.removeAttribute=function(name){for(var i=0,len=this.attrs.length;i<len;++i)this.attrs[i]&&this.attrs[i].name==name&&delete this.attrs[i]},Tag.prototype.getAttribute=function(name){for(var i=0,len=this.attrs.length;i<len;++i)if(this.attrs[i]&&this.attrs[i].name==name)return this.attrs[i].val}}),require.register("nodes/text.js",function(module,exports,require){var Node=require("./node"),Text=module.exports=function(line){this.nodes=[],"string"==typeof line&&this.push(line)};Text.prototype=new Node,Text.prototype.constructor=Text,Text.prototype.push=function(node){return this.nodes.push(node)}}),require.register("parser.js",function(module,exports,require){var Lexer=require("./lexer"),nodes=require("./nodes"),Parser=exports=module.exports=function(str,filename,options){this.input=str,this.lexer=new Lexer(str,options),this.filename=filename,this.blocks={},this.options=options,this.contexts=[this]},textOnly=exports.textOnly=["script","style"];Parser.prototype={context:function(parser){if(parser)this.contexts.push(parser);else return this.contexts.pop()},advance:function(){return this.lexer.advance()},skip:function(n){while(n--)this.advance()},peek:function(){return this.lookahead(1)},line:function(){return this.lexer.lineno},lookahead:function(n){return this.lexer.lookahead(n)},parse:function(){var block=new nodes.Block,parser;block.line=this.line();while("eos"!=this.peek().type)"newline"==this.peek().type?this.advance():block.push(this.parseExpr());if(parser=this.extending){this.context(parser);var ast=parser.parse();return this.context(),ast}return block},expect:function(type){if(this.peek().type===type)return this.advance();throw new Error('expected "'+type+'", but got "'+this.peek().type+'"')},accept:function(type){if(this.peek().type===type)return this.advance()},parseExpr:function(){switch(this.peek().type){case"tag":return this.parseTag();case"mixin":return this.parseMixin();case"block":return this.parseBlock();case"case":return this.parseCase();case"when":return this.parseWhen();case"default":return this.parseDefault();case"extends":return this.parseExtends();case"include":return this.parseInclude();case"doctype":return this.parseDoctype();case"filter":return this.parseFilter();case"comment":return this.parseComment();case"text":return this.parseText();case"each":return this.parseEach();case"code":return this.parseCode();case"yield":this.advance();var block=new nodes.Block;return block.yield=!0,block;case"id":case"class":var tok=this.advance();return this.lexer.defer(this.lexer.tok("tag","div")),this.lexer.defer(tok),this.parseExpr();default:throw new Error('unexpected token "'+this.peek().type+'"')}},parseText:function(){var tok=this.expect("text"),node=new nodes.Text(tok.val);return node.line=this.line(),node},parseBlockExpansion:function(){return":"==this.peek().type?(this.advance(),new nodes.Block(this.parseExpr())):this.block()},parseCase:function(){var val=this.expect("case").val,node=new nodes.Case(val);return node.line=this.line(),node.block=this.block(),node},parseWhen:function(){var val=this.expect("when").val;return new nodes.Case.When(val,this.parseBlockExpansion())},parseDefault:function(){return this.expect("default"),new nodes.Case.When("default",this.parseBlockExpansion())},parseCode:function(){var tok=this.expect("code"),node=new nodes.Code(tok.val,tok.buffer,tok.escape),block,i=1;node.line=this.line();while(this.lookahead(i)&&"newline"==this.lookahead(i).type)++i;return block="indent"==this.lookahead(i).type,block&&(this.skip(i-1),node.block=this.block()),node},parseComment:function(){var tok=this.expect("comment"),node;return"indent"==this.peek().type?node=new nodes.BlockComment(tok.val,this.block(),tok.buffer):node=new nodes.Comment(tok.val,tok.buffer),node.line=this.line(),node},parseDoctype:function(){var tok=this.expect("doctype"),node=new nodes.Doctype(tok.val);return node.line=this.line(),node},parseFilter:function(){var block,tok=this.expect("filter"),attrs=this.accept("attrs");this.lexer.pipeless=!0,block=this.parseTextBlock(),this.lexer.pipeless=!1;var node=new nodes.Filter(tok.val,block,attrs&&attrs.attrs);return node.line=this.line(),node},parseASTFilter:function(){var block,tok=this.expect("tag"),attrs=this.accept("attrs");this.expect(":"),block=this.block();var node=new nodes.Filter(tok.val,block,attrs&&attrs.attrs);return node.line=this.line(),node},parseEach:function(){var tok=this.expect("each"),node=new nodes.Each(tok.code,tok.val,tok.key);return node.line=this.line(),node.block=this.block(),node},parseExtends:function(){var path=require("path"),fs=require("fs"),dirname=path.dirname,basename=path.basename,join=path.join;if(!this.filename)throw new Error('the "filename" option is required to extend templates');var path=this.expect("extends").val.trim(),dir=dirname(this.filename),path=join(dir,path+".jade"),str=fs.readFileSync(path,"utf8"),parser=new Parser(str,path,this.options);return parser.blocks=this.blocks,parser.contexts=this.contexts,this.extending=parser,new nodes.Literal("")},parseBlock:function(){var block=this.expect("block"),mode=block.mode,name=block.val.trim();block="indent"==this.peek().type?this.block():new nodes.Block(new nodes.Literal(""));var prev=this.blocks[name];if(prev)switch(prev.mode){case"append":block.nodes=block.nodes.concat(prev.nodes),prev=block;break;case"prepend":block.nodes=prev.nodes.concat(block.nodes),prev=block}return block.mode=mode,this.blocks[name]=prev||block},parseInclude:function(){var path=require("path"),fs=require("fs"),dirname=path.dirname,basename=path.basename,join=path.join,path=this.expect("include").val.trim(),dir=dirname(this.filename);if(!this.filename)throw new Error('the "filename" option is required to use includes');~basename(path).indexOf(".")||(path+=".jade");if(".jade"!=path.substr(-5)){var path=join(dir,path),str=fs.readFileSync(path,"utf8");return new nodes.Literal(str)}var path=join(dir,path),str=fs.readFileSync(path,"utf8"),parser=new Parser(str,path,this.options);this.context(parser);var ast=parser.parse();return this.context(),ast.filename=path,"indent"==this.peek().type&&ast.includeBlock().push(this.block()),ast},parseMixin:function(){var tok=this.expect("mixin"),name=tok.val,args=tok.args,block="indent"==this.peek().type?this.block():null;return new nodes.Mixin(name,args,block)},parseTextBlock:function(){var text=new nodes.Text;text.line=this.line();var spaces=this.expect("indent").val;null==this._spaces&&(this._spaces=spaces);var indent=Array(spaces-this._spaces+1).join(" ");while("outdent"!=this.peek().type)switch(this.peek().type){case"newline":text.push("\\n"),this.advance();break;case"indent":text.push("\\n"),this.parseTextBlock().nodes.forEach(function(node){text.push(node)}),text.push("\\n");break;default:text.push(indent+this.advance().val)}return spaces==this._spaces&&(this._spaces=null),this.expect("outdent"),text},block:function(){var block=new nodes.Block;block.line=this.line(),this.expect("indent");while("outdent"!=this.peek().type)"newline"==this.peek().type?this.advance():block.push(this.parseExpr());return this.expect("outdent"),block},parseTag:function(){var i=2;"attrs"==this.lookahead(i).type&&++i;if(":"==this.lookahead(i).type&&"indent"==this.lookahead(++i).type)return this.parseASTFilter();var name=this.advance().val,tag=new nodes.Tag(name),dot;tag.line=this.line();out:for(;;)switch(this.peek().type){case"id":case"class":var tok=this.advance();tag.setAttribute(tok.type,"'"+tok.val+"'");continue;case"attrs":var obj=this.advance().attrs,names=Object.keys(obj);for(var i=0,len=names.length;i<len;++i){var name=names[i],val=obj[name];tag.setAttribute(name,val)}continue;default:break out}"."==this.peek().val&&(dot=tag.textOnly=!0,this.advance());switch(this.peek().type){case"text":tag.text=this.parseText();break;case"code":tag.code=this.parseCode();break;case":":this.advance(),tag.block=new nodes.Block,tag.block.push(this.parseTag())}while("newline"==this.peek().type)this.advance();tag.textOnly=tag.textOnly||~textOnly.indexOf(tag.name);if("script"==tag.name){var type=tag.getAttribute("type");!dot&&type&&"text/javascript"!=type.replace(/^['"]|['"]$/g,"")&&(tag.textOnly=!1)}if("indent"==this.peek().type)if(tag.textOnly)this.lexer.pipeless=!0,tag.block=this.parseTextBlock(),this.lexer.pipeless=!1;else{var block=this.block();if(tag.block)for(var i=0,len=block.nodes.length;i<len;++i)tag.block.push(block.nodes[i]);else tag.block=block}return tag}}}),require.register("runtime.js",function(module,exports,require){Array.isArray||(Array.isArray=function(arr){return"[object Array]"==Object.prototype.toString.call(arr)}),Object.keys||(Object.keys=function(obj){var arr=[];for(var key in obj)obj.hasOwnProperty(key)&&arr.push(key);return arr}),exports.attrs=function(obj){var buf=[],terse=obj.terse;delete obj.terse;var keys=Object.keys(obj),len=keys.length;if(len){buf.push("");for(var i=0;i<len;++i){var key=keys[i],val=obj[key];"boolean"==typeof val||null==val?val&&(terse?buf.push(key):buf.push
+(key+'="'+key+'"')):"class"==key&&Array.isArray(val)?buf.push(key+'="'+exports.escape(val.join(" "))+'"'):buf.push(key+'="'+exports.escape(val)+'"')}}return buf.join(" ")},exports.escape=function(html){return String(html).replace(/&(?!\w+;)/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")},exports.rethrow=function(err,filename,lineno){if(!filename)throw err;var context=3,str=require("fs").readFileSync(filename,"utf8"),lines=str.split("\n"),start=Math.max(lineno-context,0),end=Math.min(lines.length,lineno+context),context=lines.slice(start,end).map(function(line,i){var curr=i+start+1;return(curr==lineno?" > ":" ")+curr+"| "+line}).join("\n");throw err.path=filename,err.message=(filename||"Jade")+":"+lineno+"\n"+context+"\n\n"+err.message,err}}),require.register("self-closing.js",function(module,exports,require){module.exports=["meta","img","link","input","area","base","col","br","hr"]}),require.register("utils.js",function(module,exports,require){var interpolate=exports.interpolate=function(str){return str.replace(/(\\)?([#!]){(.*?)}/g,function(str,escape,flag,code){return escape?str:"' + "+("!"==flag?"":"escape")+"((interp = "+code.replace(/\\'/g,"'")+") == null ? '' : interp) + '"})},escape=exports.escape=function(str){return str.replace(/'/g,"\\'")};exports.text=function(str){return interpolate(escape(str))}}),window.jade=require("jade")})(); \ No newline at end of file
diff --git a/node_modules/mocha/node_modules/jade/lib/compiler.js b/node_modules/mocha/node_modules/jade/lib/compiler.js
new file mode 100644
index 0000000..5459da8
--- /dev/null
+++ b/node_modules/mocha/node_modules/jade/lib/compiler.js
@@ -0,0 +1,503 @@
+
+/*!
+ * Jade - Compiler
+ * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
+ * MIT Licensed
+ */
+
+/**
+ * Module dependencies.
+ */
+
+var nodes = require('./nodes')
+ , filters = require('./filters')
+ , doctypes = require('./doctypes')
+ , selfClosing = require('./self-closing')
+ , inlineTags = require('./inline-tags')
+ , utils = require('./utils');
+
+// if browser
+//
+// if (!Object.keys) {
+// Object.keys = function(obj){
+// var arr = [];
+// for (var key in obj) {
+// if (obj.hasOwnProperty(key)) {
+// arr.push(key);
+// }
+// }
+// return arr;
+// }
+// }
+//
+// if (!String.prototype.trimLeft) {
+// String.prototype.trimLeft = function(){
+// return this.replace(/^\s+/, '');
+// }
+// }
+//
+// end
+
+
+/**
+ * Initialize `Compiler` with the given `node`.
+ *
+ * @param {Node} node
+ * @param {Object} options
+ * @api public
+ */
+
+var Compiler = module.exports = function Compiler(node, options) {
+ this.options = options = options || {};
+ this.node = node;
+ this.hasCompiledDoctype = false;
+ this.hasCompiledTag = false;
+ this.pp = options.pretty || false;
+ this.debug = false !== options.compileDebug;
+ this.indents = 0;
+ if (options.doctype) this.setDoctype(options.doctype);
+};
+
+/**
+ * Compiler prototype.
+ */
+
+Compiler.prototype = {
+
+ /**
+ * Compile parse tree to JavaScript.
+ *
+ * @api public
+ */
+
+ compile: function(){
+ this.buf = ['var interp;'];
+ this.lastBufferedIdx = -1
+ this.visit(this.node);
+ return this.buf.join('\n');
+ },
+
+ /**
+ * Sets the default doctype `name`. Sets terse mode to `true` when
+ * html 5 is used, causing self-closing tags to end with ">" vs "/>",
+ * and boolean attributes are not mirrored.
+ *
+ * @param {string} name
+ * @api public
+ */
+
+ setDoctype: function(name){
+ var doctype = doctypes[(name || 'default').toLowerCase()];
+ doctype = doctype || '<!DOCTYPE ' + name + '>';
+ this.doctype = doctype;
+ this.terse = '5' == name || 'html' == name;
+ this.xml = 0 == this.doctype.indexOf('<?xml');
+ },
+
+ /**
+ * Buffer the given `str` optionally escaped.
+ *
+ * @param {String} str
+ * @param {Boolean} esc
+ * @api public
+ */
+
+ buffer: function(str, esc){
+ if (esc) str = utils.escape(str);
+
+ if (this.lastBufferedIdx == this.buf.length) {
+ this.lastBuffered += str;
+ this.buf[this.lastBufferedIdx - 1] = "buf.push('" + this.lastBuffered + "');"
+ } else {
+ this.buf.push("buf.push('" + str + "');");
+ this.lastBuffered = str;
+ this.lastBufferedIdx = this.buf.length;
+ }
+ },
+
+ /**
+ * Visit `node`.
+ *
+ * @param {Node} node
+ * @api public
+ */
+
+ visit: function(node){
+ var debug = this.debug;
+
+ if (debug) {
+ this.buf.push('__jade.unshift({ lineno: ' + node.line
+ + ', filename: ' + (node.filename
+ ? '"' + node.filename + '"'
+ : '__jade[0].filename')
+ + ' });');
+ }
+
+ // Massive hack to fix our context
+ // stack for - else[ if] etc
+ if (false === node.debug && this.debug) {
+ this.buf.pop();
+ this.buf.pop();
+ }
+
+ this.visitNode(node);
+
+ if (debug) this.buf.push('__jade.shift();');
+ },
+
+ /**
+ * Visit `node`.
+ *
+ * @param {Node} node
+ * @api public
+ */
+
+ visitNode: function(node){
+ var name = node.constructor.name
+ || node.constructor.toString().match(/function ([^(\s]+)()/)[1];
+ return this['visit' + name](node);
+ },
+
+ /**
+ * Visit case `node`.
+ *
+ * @param {Literal} node
+ * @api public
+ */
+
+ visitCase: function(node){
+ var _ = this.withinCase;
+ this.withinCase = true;
+ this.buf.push('switch (' + node.expr + '){');
+ this.visit(node.block);
+ this.buf.push('}');
+ this.withinCase = _;
+ },
+
+ /**
+ * Visit when `node`.
+ *
+ * @param {Literal} node
+ * @api public
+ */
+
+ visitWhen: function(node){
+ if ('default' == node.expr) {
+ this.buf.push('default:');
+ } else {
+ this.buf.push('case ' + node.expr + ':');
+ }
+ this.visit(node.block);
+ this.buf.push(' break;');
+ },
+
+ /**
+ * Visit literal `node`.
+ *
+ * @param {Literal} node
+ * @api public
+ */
+
+ visitLiteral: function(node){
+ var str = node.str.replace(/\n/g, '\\\\n');
+ this.buffer(str);
+ },
+
+ /**
+ * Visit all nodes in `block`.
+ *
+ * @param {Block} block
+ * @api public
+ */
+
+ visitBlock: function(block){
+ var len = block.nodes.length;
+ for (var i = 0; i < len; ++i) {
+ this.visit(block.nodes[i]);
+ }
+ },
+
+ /**
+ * Visit `doctype`. Sets terse mode to `true` when html 5
+ * is used, causing self-closing tags to end with ">" vs "/>",
+ * and boolean attributes are not mirrored.
+ *
+ * @param {Doctype} doctype
+ * @api public
+ */
+
+ visitDoctype: function(doctype){
+ if (doctype && (doctype.val || !this.doctype)) {
+ this.setDoctype(doctype.val || 'default');
+ }
+
+ if (this.doctype) this.buffer(this.doctype);
+ this.hasCompiledDoctype = true;
+ },
+
+ /**
+ * Visit `mixin`, generating a function that
+ * may be called within the template.
+ *
+ * @param {Mixin} mixin
+ * @api public
+ */
+
+ visitMixin: function(mixin){
+ var name = mixin.name.replace(/-/g, '_') + '_mixin'
+ , args = mixin.args || '';
+
+ if (mixin.block) {
+ this.buf.push('var ' + name + ' = function(' + args + '){');
+ this.visit(mixin.block);
+ this.buf.push('}');
+ } else {
+ this.buf.push(name + '(' + args + ');');
+ }
+ },
+
+ /**
+ * Visit `tag` buffering tag markup, generating
+ * attributes, visiting the `tag`'s code and block.
+ *
+ * @param {Tag} tag
+ * @api public
+ */
+
+ visitTag: function(tag){
+ this.indents++;
+ var name = tag.name;
+
+ if (!this.hasCompiledTag) {
+ if (!this.hasCompiledDoctype && 'html' == name) {
+ this.visitDoctype();
+ }
+ this.hasCompiledTag = true;
+ }
+
+ // pretty print
+ if (this.pp && inlineTags.indexOf(name) == -1) {
+ this.buffer('\\n' + Array(this.indents).join(' '));
+ }
+
+ if (~selfClosing.indexOf(name) && !this.xml) {
+ this.buffer('<' + name);
+ this.visitAttributes(tag.attrs);
+ this.terse
+ ? this.buffer('>')
+ : this.buffer('/>');
+ } else {
+ // Optimize attributes buffering
+ if (tag.attrs.length) {
+ this.buffer('<' + name);
+ if (tag.attrs.length) this.visitAttributes(tag.attrs);
+ this.buffer('>');
+ } else {
+ this.buffer('<' + name + '>');
+ }
+ if (tag.code) this.visitCode(tag.code);
+ if (tag.text) this.buffer(utils.text(tag.text.nodes[0].trimLeft()));
+ this.escape = 'pre' == tag.name;
+ this.visit(tag.block);
+
+ // pretty print
+ if (this.pp && !~inlineTags.indexOf(name) && !tag.textOnly) {
+ this.buffer('\\n' + Array(this.indents).join(' '));
+ }
+
+ this.buffer('</' + name + '>');
+ }
+ this.indents--;
+ },
+
+ /**
+ * Visit `filter`, throwing when the filter does not exist.
+ *
+ * @param {Filter} filter
+ * @api public
+ */
+
+ visitFilter: function(filter){
+ var fn = filters[filter.name];
+
+ // unknown filter
+ if (!fn) {
+ if (filter.isASTFilter) {
+ throw new Error('unknown ast filter "' + filter.name + ':"');
+ } else {
+ throw new Error('unknown filter ":' + filter.name + '"');
+ }
+ }
+ if (filter.isASTFilter) {
+ this.buf.push(fn(filter.block, this, filter.attrs));
+ } else {
+ var text = filter.block.nodes.join('');
+ filter.attrs = filter.attrs || {};
+ filter.attrs.filename = this.options.filename;
+ this.buffer(utils.text(fn(text, filter.attrs)));
+ }
+ },
+
+ /**
+ * Visit `text` node.
+ *
+ * @param {Text} text
+ * @api public
+ */
+
+ visitText: function(text){
+ text = utils.text(text.nodes.join(''));
+ if (this.escape) text = escape(text);
+ this.buffer(text);
+ this.buffer('\\n');
+ },
+
+ /**
+ * Visit a `comment`, only buffering when the buffer flag is set.
+ *
+ * @param {Comment} comment
+ * @api public
+ */
+
+ visitComment: function(comment){
+ if (!comment.buffer) return;
+ if (this.pp) this.buffer('\\n' + Array(this.indents + 1).join(' '));
+ this.buffer('<!--' + utils.escape(comment.val) + '-->');
+ },
+
+ /**
+ * Visit a `BlockComment`.
+ *
+ * @param {Comment} comment
+ * @api public
+ */
+
+ visitBlockComment: function(comment){
+ if (!comment.buffer) return;
+ if (0 == comment.val.trim().indexOf('if')) {
+ this.buffer('<!--[' + comment.val.trim() + ']>');
+ this.visit(comment.block);
+ this.buffer('<![endif]-->');
+ } else {
+ this.buffer('<!--' + comment.val);
+ this.visit(comment.block);
+ this.buffer('-->');
+ }
+ },
+
+ /**
+ * Visit `code`, respecting buffer / escape flags.
+ * If the code is followed by a block, wrap it in
+ * a self-calling function.
+ *
+ * @param {Code} code
+ * @api public
+ */
+
+ visitCode: function(code){
+ // Wrap code blocks with {}.
+ // we only wrap unbuffered code blocks ATM
+ // since they are usually flow control
+
+ // Buffer code
+ if (code.buffer) {
+ var val = code.val.trimLeft();
+ this.buf.push('var __val__ = ' + val);
+ val = 'null == __val__ ? "" : __val__';
+ if (code.escape) val = 'escape(' + val + ')';
+ this.buf.push("buf.push(" + val + ");");
+ } else {
+ this.buf.push(code.val);
+ }
+
+ // Block support
+ if (code.block) {
+ if (!code.buffer) this.buf.push('{');
+ this.visit(code.block);
+ if (!code.buffer) this.buf.push('}');
+ }
+ },
+
+ /**
+ * Visit `each` block.
+ *
+ * @param {Each} each
+ * @api public
+ */
+
+ visitEach: function(each){
+ this.buf.push(''
+ + '// iterate ' + each.obj + '\n'
+ + '(function(){\n'
+ + ' if (\'number\' == typeof ' + each.obj + '.length) {\n'
+ + ' for (var ' + each.key + ' = 0, $$l = ' + each.obj + '.length; ' + each.key + ' < $$l; ' + each.key + '++) {\n'
+ + ' var ' + each.val + ' = ' + each.obj + '[' + each.key + '];\n');
+
+ this.visit(each.block);
+
+ this.buf.push(''
+ + ' }\n'
+ + ' } else {\n'
+ + ' for (var ' + each.key + ' in ' + each.obj + ') {\n'
+ // if browser
+ // + ' if (' + each.obj + '.hasOwnProperty(' + each.key + ')){'
+ // end
+ + ' var ' + each.val + ' = ' + each.obj + '[' + each.key + '];\n');
+
+ this.visit(each.block);
+
+ // if browser
+ // this.buf.push(' }\n');
+ // end
+
+ this.buf.push(' }\n }\n}).call(this);\n');
+ },
+
+ /**
+ * Visit `attrs`.
+ *
+ * @param {Array} attrs
+ * @api public
+ */
+
+ visitAttributes: function(attrs){
+ var buf = []
+ , classes = [];
+
+ if (this.terse) buf.push('terse: true');
+
+ attrs.forEach(function(attr){
+ if (attr.name == 'class') {
+ classes.push('(' + attr.val + ')');
+ } else {
+ var pair = "'" + attr.name + "':(" + attr.val + ')';
+ buf.push(pair);
+ }
+ });
+
+ if (classes.length) {
+ classes = classes.join(" + ' ' + ");
+ buf.push("class: " + classes);
+ }
+
+ buf = buf.join(', ').replace('class:', '"class":');
+
+ this.buf.push("buf.push(attrs({ " + buf + " }));");
+ }
+};
+
+/**
+ * Escape the given string of `html`.
+ *
+ * @param {String} html
+ * @return {String}
+ * @api private
+ */
+
+function escape(html){
+ return String(html)
+ .replace(/&(?!\w+;)/g, '&amp;')
+ .replace(/</g, '&lt;')
+ .replace(/>/g, '&gt;')
+ .replace(/"/g, '&quot;');
+}
diff --git a/node_modules/mocha/node_modules/jade/lib/doctypes.js b/node_modules/mocha/node_modules/jade/lib/doctypes.js
new file mode 100644
index 0000000..feeb560
--- /dev/null
+++ b/node_modules/mocha/node_modules/jade/lib/doctypes.js
@@ -0,0 +1,18 @@
+
+/*!
+ * Jade - doctypes
+ * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
+ * MIT Licensed
+ */
+
+module.exports = {
+ '5': '<!DOCTYPE html>'
+ , 'xml': '<?xml version="1.0" encoding="utf-8" ?>'
+ , 'default': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">'
+ , 'transitional': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">'
+ , 'strict': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'
+ , 'frameset': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">'
+ , '1.1': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">'
+ , 'basic': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN" "http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd">'
+ , 'mobile': '<!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.2//EN" "http://www.openmobilealliance.org/tech/DTD/xhtml-mobile12.dtd">'
+}; \ No newline at end of file
diff --git a/node_modules/mocha/node_modules/jade/lib/filters.js b/node_modules/mocha/node_modules/jade/lib/filters.js
new file mode 100644
index 0000000..a7e1bef
--- /dev/null
+++ b/node_modules/mocha/node_modules/jade/lib/filters.js
@@ -0,0 +1,97 @@
+
+/*!
+ * Jade - filters
+ * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
+ * MIT Licensed
+ */
+
+module.exports = {
+
+ /**
+ * Wrap text with CDATA block.
+ */
+
+ cdata: function(str){
+ return '<![CDATA[\\n' + str + '\\n]]>';
+ },
+
+ /**
+ * Transform sass to css, wrapped in style tags.
+ */
+
+ sass: function(str){
+ str = str.replace(/\\n/g, '\n');
+ var sass = require('sass').render(str).replace(/\n/g, '\\n');
+ return '<style type="text/css">' + sass + '</style>';
+ },
+
+ /**
+ * Transform stylus to css, wrapped in style tags.
+ */
+
+ stylus: function(str, options){
+ var ret;
+ str = str.replace(/\\n/g, '\n');
+ var stylus = require('stylus');
+ stylus(str, options).render(function(err, css){
+ if (err) throw err;
+ ret = css.replace(/\n/g, '\\n');
+ });
+ return '<style type="text/css">' + ret + '</style>';
+ },
+
+ /**
+ * Transform less to css, wrapped in style tags.
+ */
+
+ less: function(str){
+ var ret;
+ str = str.replace(/\\n/g, '\n');
+ require('less').render(str, function(err, css){
+ if (err) throw err;
+ ret = '<style type="text/css">' + css.replace(/\n/g, '\\n') + '</style>';
+ });
+ return ret;
+ },
+
+ /**
+ * Transform markdown to html.
+ */
+
+ markdown: function(str){
+ var md;
+
+ // support markdown / discount
+ try {
+ md = require('markdown');
+ } catch (err){
+ try {
+ md = require('discount');
+ } catch (err) {
+ try {
+ md = require('markdown-js');
+ } catch (err) {
+ try {
+ md = require('marked');
+ } catch (err) {
+ throw new
+ Error('Cannot find markdown library, install markdown, discount, or marked.');
+ }
+ }
+ }
+ }
+
+ str = str.replace(/\\n/g, '\n');
+ return md.parse(str).replace(/\n/g, '\\n').replace(/'/g,'&#39;');
+ },
+
+ /**
+ * Transform coffeescript to javascript.
+ */
+
+ coffeescript: function(str){
+ str = str.replace(/\\n/g, '\n');
+ var js = require('coffee-script').compile(str).replace(/\n/g, '\\n');
+ return '<script type="text/javascript">\\n' + js + '</script>';
+ }
+};
diff --git a/node_modules/mocha/node_modules/jade/lib/inline-tags.js b/node_modules/mocha/node_modules/jade/lib/inline-tags.js
new file mode 100644
index 0000000..491de0b
--- /dev/null
+++ b/node_modules/mocha/node_modules/jade/lib/inline-tags.js
@@ -0,0 +1,28 @@
+
+/*!
+ * Jade - inline tags
+ * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
+ * MIT Licensed
+ */
+
+module.exports = [
+ 'a'
+ , 'abbr'
+ , 'acronym'
+ , 'b'
+ , 'br'
+ , 'code'
+ , 'em'
+ , 'font'
+ , 'i'
+ , 'img'
+ , 'ins'
+ , 'kbd'
+ , 'map'
+ , 'samp'
+ , 'small'
+ , 'span'
+ , 'strong'
+ , 'sub'
+ , 'sup'
+]; \ No newline at end of file
diff --git a/node_modules/mocha/node_modules/jade/lib/jade.js b/node_modules/mocha/node_modules/jade/lib/jade.js
new file mode 100644
index 0000000..9312cf7
--- /dev/null
+++ b/node_modules/mocha/node_modules/jade/lib/jade.js
@@ -0,0 +1,237 @@
+/*!
+ * Jade
+ * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
+ * MIT Licensed
+ */
+
+/**
+ * Module dependencies.
+ */
+
+var Parser = require('./parser')
+ , Lexer = require('./lexer')
+ , Compiler = require('./compiler')
+ , runtime = require('./runtime')
+// if node
+ , fs = require('fs');
+// end
+
+/**
+ * Library version.
+ */
+
+exports.version = '0.20.3';
+
+/**
+ * Expose self closing tags.
+ */
+
+exports.selfClosing = require('./self-closing');
+
+/**
+ * Default supported doctypes.
+ */
+
+exports.doctypes = require('./doctypes');
+
+/**
+ * Text filters.
+ */
+
+exports.filters = require('./filters');
+
+/**
+ * Utilities.
+ */
+
+exports.utils = require('./utils');
+
+/**
+ * Expose `Compiler`.
+ */
+
+exports.Compiler = Compiler;
+
+/**
+ * Expose `Parser`.
+ */
+
+exports.Parser = Parser;
+
+/**
+ * Expose `Lexer`.
+ */
+
+exports.Lexer = Lexer;
+
+/**
+ * Nodes.
+ */
+
+exports.nodes = require('./nodes');
+
+/**
+ * Jade runtime helpers.
+ */
+
+exports.runtime = runtime;
+
+/**
+ * Template function cache.
+ */
+
+exports.cache = {};
+
+/**
+ * Parse the given `str` of jade and return a function body.
+ *
+ * @param {String} str
+ * @param {Object} options
+ * @return {String}
+ * @api private
+ */
+
+function parse(str, options){
+ try {
+ // Parse
+ var parser = new Parser(str, options.filename, options);
+
+ // Compile
+ var compiler = new (options.compiler || Compiler)(parser.parse(), options)
+ , js = compiler.compile();
+
+ // Debug compiler
+ if (options.debug) {
+ console.error('\nCompiled Function:\n\n\033[90m%s\033[0m', js.replace(/^/gm, ' '));
+ }
+
+ return ''
+ + 'var buf = [];\n'
+ + (options.self
+ ? 'var self = locals || {};\n' + js
+ : 'with (locals || {}) {\n' + js + '\n}\n')
+ + 'return buf.join("");';
+ } catch (err) {
+ parser = parser.context();
+ runtime.rethrow(err, parser.filename, parser.lexer.lineno);
+ }
+}
+
+/**
+ * Compile a `Function` representation of the given jade `str`.
+ *
+ * Options:
+ *
+ * - `compileDebug` when `false` debugging code is stripped from the compiled template
+ * - `client` when `true` the helper functions `escape()` etc will reference `jade.escape()`
+ * for use with the Jade client-side runtime.js
+ *
+ * @param {String} str
+ * @param {Options} options
+ * @return {Function}
+ * @api public
+ */
+
+exports.compile = function(str, options){
+ var options = options || {}
+ , client = options.client
+ , filename = options.filename
+ ? JSON.stringify(options.filename)
+ : 'undefined'
+ , fn;
+
+ if (options.compileDebug !== false) {
+ fn = [
+ 'var __jade = [{ lineno: 1, filename: ' + filename + ' }];'
+ , 'try {'
+ , parse(String(str), options)
+ , '} catch (err) {'
+ , ' rethrow(err, __jade[0].filename, __jade[0].lineno);'
+ , '}'
+ ].join('\n');
+ } else {
+ fn = parse(String(str), options);
+ }
+
+ if (client) {
+ fn = 'var attrs = jade.attrs, escape = jade.escape, rethrow = jade.rethrow;\n' + fn;
+ }
+
+ fn = new Function('locals, attrs, escape, rethrow', fn);
+
+ if (client) return fn;
+
+ return function(locals){
+ return fn(locals, runtime.attrs, runtime.escape, runtime.rethrow);
+ };
+};
+
+/**
+ * Render the given `str` of jade and invoke
+ * the callback `fn(err, str)`.
+ *
+ * Options:
+ *
+ * - `cache` enable template caching
+ * - `filename` filename required for `include` / `extends` and caching
+ *
+ * @param {String} str
+ * @param {Object|Function} options or fn
+ * @param {Function} fn
+ * @api public
+ */
+
+exports.render = function(str, options, fn){
+ // swap args
+ if ('function' == typeof options) {
+ fn = options, options = {};
+ }
+
+ // cache requires .filename
+ if (options.cache && !options.filename) {
+ return fn(new Error('the "filename" option is required for caching'));
+ }
+
+ try {
+ var path = options.filename;
+ var tmpl = options.cache
+ ? exports.cache[path] || (exports.cache[path] = exports.compile(str, options))
+ : exports.compile(str, options);
+ fn(null, tmpl(options));
+ } catch (err) {
+ fn(err);
+ }
+};
+
+/**
+ * Render a Jade file at the given `path` and callback `fn(err, str)`.
+ *
+ * @param {String} path
+ * @param {Object|Function} options or callback
+ * @param {Function} fn
+ * @api public
+ */
+
+exports.renderFile = function(path, options, fn){
+ var key = path + ':string';
+
+ if ('function' == typeof options) {
+ fn = options, options = {};
+ }
+
+ try {
+ options.filename = path;
+ var str = options.cache
+ ? exports.cache[key] || (exports.cache[key] = fs.readFileSync(path, 'utf8'))
+ : fs.readFileSync(path, 'utf8');
+ exports.render(str, options, fn);
+ } catch (err) {
+ fn(err);
+ }
+};
+
+/**
+ * Express support.
+ */
+
+exports.__express = exports.renderFile;
diff --git a/node_modules/mocha/node_modules/jade/lib/lexer.js b/node_modules/mocha/node_modules/jade/lib/lexer.js
new file mode 100644
index 0000000..aac94f5
--- /dev/null
+++ b/node_modules/mocha/node_modules/jade/lib/lexer.js
@@ -0,0 +1,707 @@
+
+/*!
+ * Jade - Lexer
+ * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
+ * MIT Licensed
+ */
+
+/**
+ * Initialize `Lexer` with the given `str`.
+ *
+ * Options:
+ *
+ * - `colons` allow colons for attr delimiters
+ *
+ * @param {String} str
+ * @param {Object} options
+ * @api private
+ */
+
+var Lexer = module.exports = function Lexer(str, options) {
+ options = options || {};
+ this.input = str.replace(/\r\n|\r/g, '\n');
+ this.colons = options.colons;
+ this.deferredTokens = [];
+ this.lastIndents = 0;
+ this.lineno = 1;
+ this.stash = [];
+ this.indentStack = [];
+ this.indentRe = null;
+ this.pipeless = false;
+};
+
+/**
+ * Lexer prototype.
+ */
+
+Lexer.prototype = {
+
+ /**
+ * Construct a token with the given `type` and `val`.
+ *
+ * @param {String} type
+ * @param {String} val
+ * @return {Object}
+ * @api private
+ */
+
+ tok: function(type, val){
+ return {
+ type: type
+ , line: this.lineno
+ , val: val
+ }
+ },
+
+ /**
+ * Consume the given `len` of input.
+ *
+ * @param {Number} len
+ * @api private
+ */
+
+ consume: function(len){
+ this.input = this.input.substr(len);
+ },
+
+ /**
+ * Scan for `type` with the given `regexp`.
+ *
+ * @param {String} type
+ * @param {RegExp} regexp
+ * @return {Object}
+ * @api private
+ */
+
+ scan: function(regexp, type){
+ var captures;
+ if (captures = regexp.exec(this.input)) {
+ this.consume(captures[0].length);
+ return this.tok(type, captures[1]);
+ }
+ },
+
+ /**
+ * Defer the given `tok`.
+ *
+ * @param {Object} tok
+ * @api private
+ */
+
+ defer: function(tok){
+ this.deferredTokens.push(tok);
+ },
+
+ /**
+ * Lookahead `n` tokens.
+ *
+ * @param {Number} n
+ * @return {Object}
+ * @api private
+ */
+
+ lookahead: function(n){
+ var fetch = n - this.stash.length;
+ while (fetch-- > 0) this.stash.push(this.next());
+ return this.stash[--n];
+ },
+
+ /**
+ * Return the indexOf `start` / `end` delimiters.
+ *
+ * @param {String} start
+ * @param {String} end
+ * @return {Number}
+ * @api private
+ */
+
+ indexOfDelimiters: function(start, end){
+ var str = this.input
+ , nstart = 0
+ , nend = 0
+ , pos = 0;
+ for (var i = 0, len = str.length; i < len; ++i) {
+ if (start == str[i]) {
+ ++nstart;
+ } else if (end == str[i]) {
+ if (++nend == nstart) {
+ pos = i;
+ break;
+ }
+ }
+ }
+ return pos;
+ },
+
+ /**
+ * Stashed token.
+ */
+
+ stashed: function() {
+ return this.stash.length
+ && this.stash.shift();
+ },
+
+ /**
+ * Deferred token.
+ */
+
+ deferred: function() {
+ return this.deferredTokens.length
+ && this.deferredTokens.shift();
+ },
+
+ /**
+ * end-of-source.
+ */
+
+ eos: function() {
+ if (this.input.length) return;
+ if (this.indentStack.length) {
+ this.indentStack.shift();
+ return this.tok('outdent');
+ } else {
+ return this.tok('eos');
+ }
+ },
+
+ /**
+ * Comment.
+ */
+
+ comment: function() {
+ var captures;
+ if (captures = /^ *\/\/(-)?([^\n]*)/.exec(this.input)) {
+ this.consume(captures[0].length);
+ var tok = this.tok('comment', captures[2]);
+ tok.buffer = '-' != captures[1];
+ return tok;
+ }
+ },
+
+ /**
+ * Tag.
+ */
+
+ tag: function() {
+ var captures;
+ if (captures = /^(\w[-:\w]*)/.exec(this.input)) {
+ this.consume(captures[0].length);
+ var tok, name = captures[1];
+ if (':' == name[name.length - 1]) {
+ name = name.slice(0, -1);
+ tok = this.tok('tag', name);
+ this.defer(this.tok(':'));
+ while (' ' == this.input[0]) this.input = this.input.substr(1);
+ } else {
+ tok = this.tok('tag', name);
+ }
+ return tok;
+ }
+ },
+
+ /**
+ * Filter.
+ */
+
+ filter: function() {
+ return this.scan(/^:(\w+)/, 'filter');
+ },
+
+ /**
+ * Doctype.
+ */
+
+ doctype: function() {
+ return this.scan(/^(?:!!!|doctype) *([^\n]+)?/, 'doctype');
+ },
+
+ /**
+ * Id.
+ */
+
+ id: function() {
+ return this.scan(/^#([\w-]+)/, 'id');
+ },
+
+ /**
+ * Class.
+ */
+
+ className: function() {
+ return this.scan(/^\.([\w-]+)/, 'class');
+ },
+
+ /**
+ * Text.
+ */
+
+ text: function() {
+ return this.scan(/^(?:\| ?)?([^\n]+)/, 'text');
+ },
+
+ /**
+ * Extends.
+ */
+
+ extends: function() {
+ return this.scan(/^extends +([^\n]+)/, 'extends');
+ },
+
+ /**
+ * Block prepend.
+ */
+
+ prepend: function() {
+ var captures;
+ if (captures = /^prepend +([^\n]+)/.exec(this.input)) {
+ this.consume(captures[0].length);
+ var mode = 'prepend'
+ , name = captures[1]
+ , tok = this.tok('block', name);
+ tok.mode = mode;
+ return tok;
+ }
+ },
+
+ /**
+ * Block append.
+ */
+
+ append: function() {
+ var captures;
+ if (captures = /^append +([^\n]+)/.exec(this.input)) {
+ this.consume(captures[0].length);
+ var mode = 'append'
+ , name = captures[1]
+ , tok = this.tok('block', name);
+ tok.mode = mode;
+ return tok;
+ }
+ },
+
+ /**
+ * Block.
+ */
+
+ block: function() {
+ var captures;
+ if (captures = /^block +(?:(prepend|append) +)?([^\n]+)/.exec(this.input)) {
+ this.consume(captures[0].length);
+ var mode = captures[1] || 'replace'
+ , name = captures[2]
+ , tok = this.tok('block', name);
+ tok.mode = mode;
+ return tok;
+ }
+ },
+
+ /**
+ * Yield.
+ */
+
+ yield: function() {
+ return this.scan(/^yield */, 'yield');
+ },
+
+ /**
+ * Include.
+ */
+
+ include: function() {
+ return this.scan(/^include +([^\n]+)/, 'include');
+ },
+
+ /**
+ * Case.
+ */
+
+ case: function() {
+ return this.scan(/^case +([^\n]+)/, 'case');
+ },
+
+ /**
+ * When.
+ */
+
+ when: function() {
+ return this.scan(/^when +([^:\n]+)/, 'when');
+ },
+
+ /**
+ * Default.
+ */
+
+ default: function() {
+ return this.scan(/^default */, 'default');
+ },
+
+ /**
+ * Assignment.
+ */
+
+ assignment: function() {
+ var captures;
+ if (captures = /^(\w+) += *([^;\n]+)( *;? *)/.exec(this.input)) {
+ this.consume(captures[0].length);
+ var name = captures[1]
+ , val = captures[2];
+ return this.tok('code', 'var ' + name + ' = (' + val + ');');
+ }
+ },
+
+ /**
+ * Mixin.
+ */
+
+ mixin: function(){
+ var captures;
+ if (captures = /^mixin +([-\w]+)(?: *\((.*)\))?/.exec(this.input)) {
+ this.consume(captures[0].length);
+ var tok = this.tok('mixin', captures[1]);
+ tok.args = captures[2];
+ return tok;
+ }
+ },
+
+ /**
+ * Conditional.
+ */
+
+ conditional: function() {
+ var captures;
+ if (captures = /^(if|unless|else if|else)\b([^\n]*)/.exec(this.input)) {
+ this.consume(captures[0].length);
+ var type = captures[1]
+ , js = captures[2];
+
+ switch (type) {
+ case 'if': js = 'if (' + js + ')'; break;
+ case 'unless': js = 'if (!(' + js + '))'; break;
+ case 'else if': js = 'else if (' + js + ')'; break;
+ case 'else': js = 'else'; break;
+ }
+
+ return this.tok('code', js);
+ }
+ },
+
+ /**
+ * While.
+ */
+
+ while: function() {
+ var captures;
+ if (captures = /^while +([^\n]+)/.exec(this.input)) {
+ this.consume(captures[0].length);
+ return this.tok('code', 'while (' + captures[1] + ')');
+ }
+ },
+
+ /**
+ * Each.
+ */
+
+ each: function() {
+ var captures;
+ if (captures = /^(?:- *)?(?:each|for) +(\w+)(?: *, *(\w+))? * in *([^\n]+)/.exec(this.input)) {
+ this.consume(captures[0].length);
+ var tok = this.tok('each', captures[1]);
+ tok.key = captures[2] || '$index';
+ tok.code = captures[3];
+ return tok;
+ }
+ },
+
+ /**
+ * Code.
+ */
+
+ code: function() {
+ var captures;
+ if (captures = /^(!?=|-)([^\n]+)/.exec(this.input)) {
+ this.consume(captures[0].length);
+ var flags = captures[1];
+ captures[1] = captures[2];
+ var tok = this.tok('code', captures[1]);
+ tok.escape = flags[0] === '=';
+ tok.buffer = flags[0] === '=' || flags[1] === '=';
+ return tok;
+ }
+ },
+
+ /**
+ * Attributes.
+ */
+
+ attrs: function() {
+ if ('(' == this.input[0]) {
+ var index = this.indexOfDelimiters('(', ')')
+ , str = this.input.substr(1, index-1)
+ , tok = this.tok('attrs')
+ , len = str.length
+ , colons = this.colons
+ , states = ['key']
+ , key = ''
+ , val = ''
+ , quote
+ , c;
+
+ function state(){
+ return states[states.length - 1];
+ }
+
+ function interpolate(attr) {
+ return attr.replace(/#\{([^}]+)\}/g, function(_, expr){
+ return quote + " + (" + expr + ") + " + quote;
+ });
+ }
+
+ this.consume(index + 1);
+ tok.attrs = {};
+
+ function parse(c) {
+ var real = c;
+ // TODO: remove when people fix ":"
+ if (colons && ':' == c) c = '=';
+ switch (c) {
+ case ',':
+ case '\n':
+ switch (state()) {
+ case 'expr':
+ case 'array':
+ case 'string':
+ case 'object':
+ val += c;
+ break;
+ default:
+ states.push('key');
+ val = val.trim();
+ key = key.trim();
+ if ('' == key) return;
+ tok.attrs[key.replace(/^['"]|['"]$/g, '')] = '' == val
+ ? true
+ : interpolate(val);
+ key = val = '';
+ }
+ break;
+ case '=':
+ switch (state()) {
+ case 'key char':
+ key += real;
+ break;
+ case 'val':
+ case 'expr':
+ case 'array':
+ case 'string':
+ case 'object':
+ val += real;
+ break;
+ default:
+ states.push('val');
+ }
+ break;
+ case '(':
+ if ('val' == state()
+ || 'expr' == state()) states.push('expr');
+ val += c;
+ break;
+ case ')':
+ if ('expr' == state()
+ || 'val' == state()) states.pop();
+ val += c;
+ break;
+ case '{':
+ if ('val' == state()) states.push('object');
+ val += c;
+ break;
+ case '}':
+ if ('object' == state()) states.pop();
+ val += c;
+ break;
+ case '[':
+ if ('val' == state()) states.push('array');
+ val += c;
+ break;
+ case ']':
+ if ('array' == state()) states.pop();
+ val += c;
+ break;
+ case '"':
+ case "'":
+ switch (state()) {
+ case 'key':
+ states.push('key char');
+ break;
+ case 'key char':
+ states.pop();
+ break;
+ case 'string':
+ if (c == quote) states.pop();
+ val += c;
+ break;
+ default:
+ states.push('string');
+ val += c;
+ quote = c;
+ }
+ break;
+ case '':
+ break;
+ default:
+ switch (state()) {
+ case 'key':
+ case 'key char':
+ key += c;
+ break;
+ default:
+ val += c;
+ }
+ }
+ }
+
+ for (var i = 0; i < len; ++i) {
+ parse(str[i]);
+ }
+
+ parse(',');
+
+ return tok;
+ }
+ },
+
+ /**
+ * Indent | Outdent | Newline.
+ */
+
+ indent: function() {
+ var captures, re;
+
+ // established regexp
+ if (this.indentRe) {
+ captures = this.indentRe.exec(this.input);
+ // determine regexp
+ } else {
+ // tabs
+ re = /^\n(\t*) */;
+ captures = re.exec(this.input);
+
+ // spaces
+ if (captures && !captures[1].length) {
+ re = /^\n( *)/;
+ captures = re.exec(this.input);
+ }
+
+ // established
+ if (captures && captures[1].length) this.indentRe = re;
+ }
+
+ if (captures) {
+ var tok
+ , indents = captures[1].length;
+
+ ++this.lineno;
+ this.consume(indents + 1);
+
+ if (' ' == this.input[0] || '\t' == this.input[0]) {
+ throw new Error('Invalid indentation, you can use tabs or spaces but not both');
+ }
+
+ // blank line
+ if ('\n' == this.input[0]) return this.tok('newline');
+
+ // outdent
+ if (this.indentStack.length && indents < this.indentStack[0]) {
+ while (this.indentStack.length && this.indentStack[0] > indents) {
+ this.stash.push(this.tok('outdent'));
+ this.indentStack.shift();
+ }
+ tok = this.stash.pop();
+ // indent
+ } else if (indents && indents != this.indentStack[0]) {
+ this.indentStack.unshift(indents);
+ tok = this.tok('indent', indents);
+ // newline
+ } else {
+ tok = this.tok('newline');
+ }
+
+ return tok;
+ }
+ },
+
+ /**
+ * Pipe-less text consumed only when
+ * pipeless is true;
+ */
+
+ pipelessText: function() {
+ if (this.pipeless) {
+ if ('\n' == this.input[0]) return;
+ var i = this.input.indexOf('\n');
+ if (-1 == i) i = this.input.length;
+ var str = this.input.substr(0, i);
+ this.consume(str.length);
+ return this.tok('text', str);
+ }
+ },
+
+ /**
+ * ':'
+ */
+
+ colon: function() {
+ return this.scan(/^: */, ':');
+ },
+
+ /**
+ * Return the next token object, or those
+ * previously stashed by lookahead.
+ *
+ * @return {Object}
+ * @api private
+ */
+
+ advance: function(){
+ return this.stashed()
+ || this.next();
+ },
+
+ /**
+ * Return the next token object.
+ *
+ * @return {Object}
+ * @api private
+ */
+
+ next: function() {
+ return this.deferred()
+ || this.eos()
+ || this.pipelessText()
+ || this.yield()
+ || this.doctype()
+ || this.case()
+ || this.when()
+ || this.default()
+ || this.extends()
+ || this.append()
+ || this.prepend()
+ || this.block()
+ || this.include()
+ || this.mixin()
+ || this.conditional()
+ || this.each()
+ || this.while()
+ || this.assignment()
+ || this.tag()
+ || this.filter()
+ || this.code()
+ || this.id()
+ || this.className()
+ || this.attrs()
+ || this.indent()
+ || this.comment()
+ || this.colon()
+ || this.text();
+ }
+};
diff --git a/node_modules/mocha/node_modules/jade/lib/nodes/block-comment.js b/node_modules/mocha/node_modules/jade/lib/nodes/block-comment.js
new file mode 100644
index 0000000..4f41e4a
--- /dev/null
+++ b/node_modules/mocha/node_modules/jade/lib/nodes/block-comment.js
@@ -0,0 +1,33 @@
+
+/*!
+ * Jade - nodes - BlockComment
+ * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
+ * MIT Licensed
+ */
+
+/**
+ * Module dependencies.
+ */
+
+var Node = require('./node');
+
+/**
+ * Initialize a `BlockComment` with the given `block`.
+ *
+ * @param {String} val
+ * @param {Block} block
+ * @param {Boolean} buffer
+ * @api public
+ */
+
+var BlockComment = module.exports = function BlockComment(val, block, buffer) {
+ this.block = block;
+ this.val = val;
+ this.buffer = buffer;
+};
+
+/**
+ * Inherit from `Node`.
+ */
+
+BlockComment.prototype.__proto__ = Node.prototype; \ No newline at end of file
diff --git a/node_modules/mocha/node_modules/jade/lib/nodes/block.js b/node_modules/mocha/node_modules/jade/lib/nodes/block.js
new file mode 100644
index 0000000..db63c77
--- /dev/null
+++ b/node_modules/mocha/node_modules/jade/lib/nodes/block.js
@@ -0,0 +1,100 @@
+
+/*!
+ * Jade - nodes - Block
+ * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
+ * MIT Licensed
+ */
+
+/**
+ * Module dependencies.
+ */
+
+var Node = require('./node');
+
+/**
+ * Initialize a new `Block` with an optional `node`.
+ *
+ * @param {Node} node
+ * @api public
+ */
+
+var Block = module.exports = function Block(node){
+ this.nodes = [];
+ if (node) this.push(node);
+};
+
+/**
+ * Inherit from `Node`.
+ */
+
+Block.prototype.__proto__ = Node.prototype;
+
+/**
+ * Replace the nodes in `other` with the nodes
+ * in `this` block.
+ *
+ * @param {Block} other
+ * @api private
+ */
+
+Block.prototype.replace = function(other){
+ other.nodes = this.nodes;
+};
+
+/**
+ * Pust the given `node`.
+ *
+ * @param {Node} node
+ * @return {Number}
+ * @api public
+ */
+
+Block.prototype.push = function(node){
+ return this.nodes.push(node);
+};
+
+/**
+ * Check if this block is empty.
+ *
+ * @return {Boolean}
+ * @api public
+ */
+
+Block.prototype.isEmpty = function(){
+ return 0 == this.nodes.length;
+};
+
+/**
+ * Unshift the given `node`.
+ *
+ * @param {Node} node
+ * @return {Number}
+ * @api public
+ */
+
+Block.prototype.unshift = function(node){
+ return this.nodes.unshift(node);
+};
+
+/**
+ * Return the "last" block, or the first `yield` node.
+ *
+ * @return {Block}
+ * @api private
+ */
+
+Block.prototype.includeBlock = function(){
+ var ret = this
+ , node;
+
+ for (var i = 0, len = this.nodes.length; i < len; ++i) {
+ node = this.nodes[i];
+ if (node.yield) return node;
+ else if (node.textOnly) continue;
+ else if (node.includeBlock) ret = node.includeBlock();
+ else if (node.block && !node.block.isEmpty()) ret = node.block.includeBlock();
+ }
+
+ return ret;
+};
+
diff --git a/node_modules/mocha/node_modules/jade/lib/nodes/case.js b/node_modules/mocha/node_modules/jade/lib/nodes/case.js
new file mode 100644
index 0000000..08ff033
--- /dev/null
+++ b/node_modules/mocha/node_modules/jade/lib/nodes/case.js
@@ -0,0 +1,43 @@
+
+/*!
+ * Jade - nodes - Case
+ * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
+ * MIT Licensed
+ */
+
+/**
+ * Module dependencies.
+ */
+
+var Node = require('./node');
+
+/**
+ * Initialize a new `Case` with `expr`.
+ *
+ * @param {String} expr
+ * @api public
+ */
+
+var Case = exports = module.exports = function Case(expr, block){
+ this.expr = expr;
+ this.block = block;
+};
+
+/**
+ * Inherit from `Node`.
+ */
+
+Case.prototype.__proto__ = Node.prototype;
+
+var When = exports.When = function When(expr, block){
+ this.expr = expr;
+ this.block = block;
+ this.debug = false;
+};
+
+/**
+ * Inherit from `Node`.
+ */
+
+When.prototype.__proto__ = Node.prototype;
+
diff --git a/node_modules/mocha/node_modules/jade/lib/nodes/code.js b/node_modules/mocha/node_modules/jade/lib/nodes/code.js
new file mode 100644
index 0000000..babc675
--- /dev/null
+++ b/node_modules/mocha/node_modules/jade/lib/nodes/code.js
@@ -0,0 +1,35 @@
+
+/*!
+ * Jade - nodes - Code
+ * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
+ * MIT Licensed
+ */
+
+/**
+ * Module dependencies.
+ */
+
+var Node = require('./node');
+
+/**
+ * Initialize a `Code` node with the given code `val`.
+ * Code may also be optionally buffered and escaped.
+ *
+ * @param {String} val
+ * @param {Boolean} buffer
+ * @param {Boolean} escape
+ * @api public
+ */
+
+var Code = module.exports = function Code(val, buffer, escape) {
+ this.val = val;
+ this.buffer = buffer;
+ this.escape = escape;
+ if (val.match(/^ *else/)) this.debug = false;
+};
+
+/**
+ * Inherit from `Node`.
+ */
+
+Code.prototype.__proto__ = Node.prototype; \ No newline at end of file
diff --git a/node_modules/mocha/node_modules/jade/lib/nodes/comment.js b/node_modules/mocha/node_modules/jade/lib/nodes/comment.js
new file mode 100644
index 0000000..2e1469e
--- /dev/null
+++ b/node_modules/mocha/node_modules/jade/lib/nodes/comment.js
@@ -0,0 +1,32 @@
+
+/*!
+ * Jade - nodes - Comment
+ * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
+ * MIT Licensed
+ */
+
+/**
+ * Module dependencies.
+ */
+
+var Node = require('./node');
+
+/**
+ * Initialize a `Comment` with the given `val`, optionally `buffer`,
+ * otherwise the comment may render in the output.
+ *
+ * @param {String} val
+ * @param {Boolean} buffer
+ * @api public
+ */
+
+var Comment = module.exports = function Comment(val, buffer) {
+ this.val = val;
+ this.buffer = buffer;
+};
+
+/**
+ * Inherit from `Node`.
+ */
+
+Comment.prototype.__proto__ = Node.prototype; \ No newline at end of file
diff --git a/node_modules/mocha/node_modules/jade/lib/nodes/doctype.js b/node_modules/mocha/node_modules/jade/lib/nodes/doctype.js
new file mode 100644
index 0000000..b8f33e5
--- /dev/null
+++ b/node_modules/mocha/node_modules/jade/lib/nodes/doctype.js
@@ -0,0 +1,29 @@
+
+/*!
+ * Jade - nodes - Doctype
+ * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
+ * MIT Licensed
+ */
+
+/**
+ * Module dependencies.
+ */
+
+var Node = require('./node');
+
+/**
+ * Initialize a `Doctype` with the given `val`.
+ *
+ * @param {String} val
+ * @api public
+ */
+
+var Doctype = module.exports = function Doctype(val) {
+ this.val = val;
+};
+
+/**
+ * Inherit from `Node`.
+ */
+
+Doctype.prototype.__proto__ = Node.prototype; \ No newline at end of file
diff --git a/node_modules/mocha/node_modules/jade/lib/nodes/each.js b/node_modules/mocha/node_modules/jade/lib/nodes/each.js
new file mode 100644
index 0000000..f54101f
--- /dev/null
+++ b/node_modules/mocha/node_modules/jade/lib/nodes/each.js
@@ -0,0 +1,35 @@
+
+/*!
+ * Jade - nodes - Each
+ * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
+ * MIT Licensed
+ */
+
+/**
+ * Module dependencies.
+ */
+
+var Node = require('./node');
+
+/**
+ * Initialize an `Each` node, representing iteration
+ *
+ * @param {String} obj
+ * @param {String} val
+ * @param {String} key
+ * @param {Block} block
+ * @api public
+ */
+
+var Each = module.exports = function Each(obj, val, key, block) {
+ this.obj = obj;
+ this.val = val;
+ this.key = key;
+ this.block = block;
+};
+
+/**
+ * Inherit from `Node`.
+ */
+
+Each.prototype.__proto__ = Node.prototype; \ No newline at end of file
diff --git a/node_modules/mocha/node_modules/jade/lib/nodes/filter.js b/node_modules/mocha/node_modules/jade/lib/nodes/filter.js
new file mode 100644
index 0000000..5a0a237
--- /dev/null
+++ b/node_modules/mocha/node_modules/jade/lib/nodes/filter.js
@@ -0,0 +1,35 @@
+
+/*!
+ * Jade - nodes - Filter
+ * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
+ * MIT Licensed
+ */
+
+/**
+ * Module dependencies.
+ */
+
+var Node = require('./node')
+ , Block = require('./block');
+
+/**
+ * Initialize a `Filter` node with the given
+ * filter `name` and `block`.
+ *
+ * @param {String} name
+ * @param {Block|Node} block
+ * @api public
+ */
+
+var Filter = module.exports = function Filter(name, block, attrs) {
+ this.name = name;
+ this.block = block;
+ this.attrs = attrs;
+ this.isASTFilter = block instanceof Block;
+};
+
+/**
+ * Inherit from `Node`.
+ */
+
+Filter.prototype.__proto__ = Node.prototype; \ No newline at end of file
diff --git a/node_modules/mocha/node_modules/jade/lib/nodes/index.js b/node_modules/mocha/node_modules/jade/lib/nodes/index.js
new file mode 100644
index 0000000..386ad2f
--- /dev/null
+++ b/node_modules/mocha/node_modules/jade/lib/nodes/index.js
@@ -0,0 +1,20 @@
+
+/*!
+ * Jade - nodes
+ * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
+ * MIT Licensed
+ */
+
+exports.Node = require('./node');
+exports.Tag = require('./tag');
+exports.Code = require('./code');
+exports.Each = require('./each');
+exports.Case = require('./case');
+exports.Text = require('./text');
+exports.Block = require('./block');
+exports.Mixin = require('./mixin');
+exports.Filter = require('./filter');
+exports.Comment = require('./comment');
+exports.Literal = require('./literal');
+exports.BlockComment = require('./block-comment');
+exports.Doctype = require('./doctype');
diff --git a/node_modules/mocha/node_modules/jade/lib/nodes/literal.js b/node_modules/mocha/node_modules/jade/lib/nodes/literal.js
new file mode 100644
index 0000000..3ddab65
--- /dev/null
+++ b/node_modules/mocha/node_modules/jade/lib/nodes/literal.js
@@ -0,0 +1,31 @@
+
+/*!
+ * Jade - nodes - Literal
+ * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
+ * MIT Licensed
+ */
+
+/**
+ * Module dependencies.
+ */
+
+var Node = require('./node');
+
+/**
+ * Initialize a `Literal` node with the given `str.
+ *
+ * @param {String} str
+ * @api public
+ */
+
+var Literal = module.exports = function Literal(str) {
+ this.str = str
+ .replace(/\n/g, "\\n")
+ .replace(/'/g, "\\'");
+};
+
+/**
+ * Inherit from `Node`.
+ */
+
+Literal.prototype.__proto__ = Node.prototype;
diff --git a/node_modules/mocha/node_modules/jade/lib/nodes/mixin.js b/node_modules/mocha/node_modules/jade/lib/nodes/mixin.js
new file mode 100644
index 0000000..f007c84
--- /dev/null
+++ b/node_modules/mocha/node_modules/jade/lib/nodes/mixin.js
@@ -0,0 +1,34 @@
+
+/*!
+ * Jade - nodes - Mixin
+ * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
+ * MIT Licensed
+ */
+
+/**
+ * Module dependencies.
+ */
+
+var Node = require('./node');
+
+/**
+ * Initialize a new `Mixin` with `name` and `block`.
+ *
+ * @param {String} name
+ * @param {String} args
+ * @param {Block} block
+ * @api public
+ */
+
+var Mixin = module.exports = function Mixin(name, args, block){
+ this.name = name;
+ this.args = args;
+ this.block = block;
+};
+
+/**
+ * Inherit from `Node`.
+ */
+
+Mixin.prototype.__proto__ = Node.prototype;
+
diff --git a/node_modules/mocha/node_modules/jade/lib/nodes/node.js b/node_modules/mocha/node_modules/jade/lib/nodes/node.js
new file mode 100644
index 0000000..0669e67
--- /dev/null
+++ b/node_modules/mocha/node_modules/jade/lib/nodes/node.js
@@ -0,0 +1,14 @@
+
+/*!
+ * Jade - nodes - Node
+ * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
+ * MIT Licensed
+ */
+
+/**
+ * Initialize a `Node`.
+ *
+ * @api public
+ */
+
+var Node = module.exports = function Node(){}; \ No newline at end of file
diff --git a/node_modules/mocha/node_modules/jade/lib/nodes/tag.js b/node_modules/mocha/node_modules/jade/lib/nodes/tag.js
new file mode 100644
index 0000000..35993c9
--- /dev/null
+++ b/node_modules/mocha/node_modules/jade/lib/nodes/tag.js
@@ -0,0 +1,80 @@
+
+/*!
+ * Jade - nodes - Tag
+ * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
+ * MIT Licensed
+ */
+
+/**
+ * Module dependencies.
+ */
+
+var Node = require('./node'),
+ Block = require('./block');
+
+/**
+ * Initialize a `Tag` node with the given tag `name` and optional `block`.
+ *
+ * @param {String} name
+ * @param {Block} block
+ * @api public
+ */
+
+var Tag = module.exports = function Tag(name, block) {
+ this.name = name;
+ this.attrs = [];
+ this.block = block || new Block;
+};
+
+/**
+ * Inherit from `Node`.
+ */
+
+Tag.prototype.__proto__ = Node.prototype;
+
+/**
+ * Set attribute `name` to `val`, keep in mind these become
+ * part of a raw js object literal, so to quote a value you must
+ * '"quote me"', otherwise or example 'user.name' is literal JavaScript.
+ *
+ * @param {String} name
+ * @param {String} val
+ * @return {Tag} for chaining
+ * @api public
+ */
+
+Tag.prototype.setAttribute = function(name, val){
+ this.attrs.push({ name: name, val: val });
+ return this;
+};
+
+/**
+ * Remove attribute `name` when present.
+ *
+ * @param {String} name
+ * @api public
+ */
+
+Tag.prototype.removeAttribute = function(name){
+ for (var i = 0, len = this.attrs.length; i < len; ++i) {
+ if (this.attrs[i] && this.attrs[i].name == name) {
+ delete this.attrs[i];
+ }
+ }
+};
+
+/**
+ * Get attribute value by `name`.
+ *
+ * @param {String} name
+ * @return {String}
+ * @api public
+ */
+
+Tag.prototype.getAttribute = function(name){
+ for (var i = 0, len = this.attrs.length; i < len; ++i) {
+ if (this.attrs[i] && this.attrs[i].name == name) {
+ return this.attrs[i].val;
+ }
+ }
+};
diff --git a/node_modules/mocha/node_modules/jade/lib/nodes/text.js b/node_modules/mocha/node_modules/jade/lib/nodes/text.js
new file mode 100644
index 0000000..3baff4b
--- /dev/null
+++ b/node_modules/mocha/node_modules/jade/lib/nodes/text.js
@@ -0,0 +1,42 @@
+
+/*!
+ * Jade - nodes - Text
+ * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
+ * MIT Licensed
+ */
+
+/**
+ * Module dependencies.
+ */
+
+var Node = require('./node');
+
+/**
+ * Initialize a `Text` node with optional `line`.
+ *
+ * @param {String} line
+ * @api public
+ */
+
+var Text = module.exports = function Text(line) {
+ this.nodes = [];
+ if ('string' == typeof line) this.push(line);
+};
+
+/**
+ * Inherit from `Node`.
+ */
+
+Text.prototype.__proto__ = Node.prototype;
+
+/**
+ * Push the given `node.`
+ *
+ * @param {Node} node
+ * @return {Number}
+ * @api public
+ */
+
+Text.prototype.push = function(node){
+ return this.nodes.push(node);
+};
diff --git a/node_modules/mocha/node_modules/jade/lib/parser.js b/node_modules/mocha/node_modules/jade/lib/parser.js
new file mode 100644
index 0000000..3dcfb57
--- /dev/null
+++ b/node_modules/mocha/node_modules/jade/lib/parser.js
@@ -0,0 +1,651 @@
+
+/*!
+ * Jade - Parser
+ * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
+ * MIT Licensed
+ */
+
+/**
+ * Module dependencies.
+ */
+
+var Lexer = require('./lexer')
+ , nodes = require('./nodes');
+
+/**
+ * Initialize `Parser` with the given input `str` and `filename`.
+ *
+ * @param {String} str
+ * @param {String} filename
+ * @param {Object} options
+ * @api public
+ */
+
+var Parser = exports = module.exports = function Parser(str, filename, options){
+ this.input = str;
+ this.lexer = new Lexer(str, options);
+ this.filename = filename;
+ this.blocks = {};
+ this.options = options;
+ this.contexts = [this];
+};
+
+/**
+ * Tags that may not contain tags.
+ */
+
+var textOnly = exports.textOnly = ['script', 'style'];
+
+/**
+ * Parser prototype.
+ */
+
+Parser.prototype = {
+
+ /**
+ * Push `parser` onto the context stack,
+ * or pop and return a `Parser`.
+ */
+
+ context: function(parser){
+ if (parser) {
+ this.contexts.push(parser);
+ } else {
+ return this.contexts.pop();
+ }
+ },
+
+ /**
+ * Return the next token object.
+ *
+ * @return {Object}
+ * @api private
+ */
+
+ advance: function(){
+ return this.lexer.advance();
+ },
+
+ /**
+ * Skip `n` tokens.
+ *
+ * @param {Number} n
+ * @api private
+ */
+
+ skip: function(n){
+ while (n--) this.advance();
+ },
+
+ /**
+ * Single token lookahead.
+ *
+ * @return {Object}
+ * @api private
+ */
+
+ peek: function() {
+ return this.lookahead(1);
+ },
+
+ /**
+ * Return lexer lineno.
+ *
+ * @return {Number}
+ * @api private
+ */
+
+ line: function() {
+ return this.lexer.lineno;
+ },
+
+ /**
+ * `n` token lookahead.
+ *
+ * @param {Number} n
+ * @return {Object}
+ * @api private
+ */
+
+ lookahead: function(n){
+ return this.lexer.lookahead(n);
+ },
+
+ /**
+ * Parse input returning a string of js for evaluation.
+ *
+ * @return {String}
+ * @api public
+ */
+
+ parse: function(){
+ var block = new nodes.Block, parser;
+ block.line = this.line();
+
+ while ('eos' != this.peek().type) {
+ if ('newline' == this.peek().type) {
+ this.advance();
+ } else {
+ block.push(this.parseExpr());
+ }
+ }
+
+ if (parser = this.extending) {
+ this.context(parser);
+ var ast = parser.parse();
+ this.context();
+ return ast;
+ }
+
+ return block;
+ },
+
+ /**
+ * Expect the given type, or throw an exception.
+ *
+ * @param {String} type
+ * @api private
+ */
+
+ expect: function(type){
+ if (this.peek().type === type) {
+ return this.advance();
+ } else {
+ throw new Error('expected "' + type + '", but got "' + this.peek().type + '"');
+ }
+ },
+
+ /**
+ * Accept the given `type`.
+ *
+ * @param {String} type
+ * @api private
+ */
+
+ accept: function(type){
+ if (this.peek().type === type) {
+ return this.advance();
+ }
+ },
+
+ /**
+ * tag
+ * | doctype
+ * | mixin
+ * | include
+ * | filter
+ * | comment
+ * | text
+ * | each
+ * | code
+ * | yield
+ * | id
+ * | class
+ */
+
+ parseExpr: function(){
+ switch (this.peek().type) {
+ case 'tag':
+ return this.parseTag();
+ case 'mixin':
+ return this.parseMixin();
+ case 'block':
+ return this.parseBlock();
+ case 'case':
+ return this.parseCase();
+ case 'when':
+ return this.parseWhen();
+ case 'default':
+ return this.parseDefault();
+ case 'extends':
+ return this.parseExtends();
+ case 'include':
+ return this.parseInclude();
+ case 'doctype':
+ return this.parseDoctype();
+ case 'filter':
+ return this.parseFilter();
+ case 'comment':
+ return this.parseComment();
+ case 'text':
+ return this.parseText();
+ case 'each':
+ return this.parseEach();
+ case 'code':
+ return this.parseCode();
+ case 'yield':
+ this.advance();
+ var block = new nodes.Block;
+ block.yield = true;
+ return block;
+ case 'id':
+ case 'class':
+ var tok = this.advance();
+ this.lexer.defer(this.lexer.tok('tag', 'div'));
+ this.lexer.defer(tok);
+ return this.parseExpr();
+ default:
+ throw new Error('unexpected token "' + this.peek().type + '"');
+ }
+ },
+
+ /**
+ * Text
+ */
+
+ parseText: function(){
+ var tok = this.expect('text')
+ , node = new nodes.Text(tok.val);
+ node.line = this.line();
+ return node;
+ },
+
+ /**
+ * ':' expr
+ * | block
+ */
+
+ parseBlockExpansion: function(){
+ if (':' == this.peek().type) {
+ this.advance();
+ return new nodes.Block(this.parseExpr());
+ } else {
+ return this.block();
+ }
+ },
+
+ /**
+ * case
+ */
+
+ parseCase: function(){
+ var val = this.expect('case').val
+ , node = new nodes.Case(val);
+ node.line = this.line();
+ node.block = this.block();
+ return node;
+ },
+
+ /**
+ * when
+ */
+
+ parseWhen: function(){
+ var val = this.expect('when').val
+ return new nodes.Case.When(val, this.parseBlockExpansion());
+ },
+
+ /**
+ * default
+ */
+
+ parseDefault: function(){
+ this.expect('default');
+ return new nodes.Case.When('default', this.parseBlockExpansion());
+ },
+
+ /**
+ * code
+ */
+
+ parseCode: function(){
+ var tok = this.expect('code')
+ , node = new nodes.Code(tok.val, tok.buffer, tok.escape)
+ , block
+ , i = 1;
+ node.line = this.line();
+ while (this.lookahead(i) && 'newline' == this.lookahead(i).type) ++i;
+ block = 'indent' == this.lookahead(i).type;
+ if (block) {
+ this.skip(i-1);
+ node.block = this.block();
+ }
+ return node;
+ },
+
+ /**
+ * comment
+ */
+
+ parseComment: function(){
+ var tok = this.expect('comment')
+ , node;
+
+ if ('indent' == this.peek().type) {
+ node = new nodes.BlockComment(tok.val, this.block(), tok.buffer);
+ } else {
+ node = new nodes.Comment(tok.val, tok.buffer);
+ }
+
+ node.line = this.line();
+ return node;
+ },
+
+ /**
+ * doctype
+ */
+
+ parseDoctype: function(){
+ var tok = this.expect('doctype')
+ , node = new nodes.Doctype(tok.val);
+ node.line = this.line();
+ return node;
+ },
+
+ /**
+ * filter attrs? text-block
+ */
+
+ parseFilter: function(){
+ var block
+ , tok = this.expect('filter')
+ , attrs = this.accept('attrs');
+
+ this.lexer.pipeless = true;
+ block = this.parseTextBlock();
+ this.lexer.pipeless = false;
+
+ var node = new nodes.Filter(tok.val, block, attrs && attrs.attrs);
+ node.line = this.line();
+ return node;
+ },
+
+ /**
+ * tag ':' attrs? block
+ */
+
+ parseASTFilter: function(){
+ var block
+ , tok = this.expect('tag')
+ , attrs = this.accept('attrs');
+
+ this.expect(':');
+ block = this.block();
+
+ var node = new nodes.Filter(tok.val, block, attrs && attrs.attrs);
+ node.line = this.line();
+ return node;
+ },
+
+ /**
+ * each block
+ */
+
+ parseEach: function(){
+ var tok = this.expect('each')
+ , node = new nodes.Each(tok.code, tok.val, tok.key);
+ node.line = this.line();
+ node.block = this.block();
+ return node;
+ },
+
+ /**
+ * 'extends' name
+ */
+
+ parseExtends: function(){
+ var path = require('path')
+ , fs = require('fs')
+ , dirname = path.dirname
+ , basename = path.basename
+ , join = path.join;
+
+ if (!this.filename)
+ throw new Error('the "filename" option is required to extend templates');
+
+ var path = this.expect('extends').val.trim()
+ , dir = dirname(this.filename);
+
+ var path = join(dir, path + '.jade')
+ , str = fs.readFileSync(path, 'utf8')
+ , parser = new Parser(str, path, this.options);
+
+ parser.blocks = this.blocks;
+ parser.contexts = this.contexts;
+ this.extending = parser;
+
+ // TODO: null node
+ return new nodes.Literal('');
+ },
+
+ /**
+ * 'block' name block
+ */
+
+ parseBlock: function(){
+ var block = this.expect('block')
+ , mode = block.mode
+ , name = block.val.trim();
+
+ block = 'indent' == this.peek().type
+ ? this.block()
+ : new nodes.Block(new nodes.Literal(''));
+
+ var prev = this.blocks[name];
+
+ if (prev) {
+ switch (prev.mode) {
+ case 'append':
+ block.nodes = block.nodes.concat(prev.nodes);
+ prev = block;
+ break;
+ case 'prepend':
+ block.nodes = prev.nodes.concat(block.nodes);
+ prev = block;
+ break;
+ }
+ }
+
+ block.mode = mode;
+ return this.blocks[name] = prev || block;
+ },
+
+ /**
+ * include block?
+ */
+
+ parseInclude: function(){
+ var path = require('path')
+ , fs = require('fs')
+ , dirname = path.dirname
+ , basename = path.basename
+ , join = path.join;
+
+ var path = this.expect('include').val.trim()
+ , dir = dirname(this.filename);
+
+ if (!this.filename)
+ throw new Error('the "filename" option is required to use includes');
+
+ // no extension
+ if (!~basename(path).indexOf('.')) {
+ path += '.jade';
+ }
+
+ // non-jade
+ if ('.jade' != path.substr(-5)) {
+ var path = join(dir, path)
+ , str = fs.readFileSync(path, 'utf8');
+ return new nodes.Literal(str);
+ }
+
+ var path = join(dir, path)
+ , str = fs.readFileSync(path, 'utf8')
+ , parser = new Parser(str, path, this.options);
+
+ this.context(parser);
+ var ast = parser.parse();
+ this.context();
+ ast.filename = path;
+
+ if ('indent' == this.peek().type) {
+ ast.includeBlock().push(this.block());
+ }
+
+ return ast;
+ },
+
+ /**
+ * mixin block
+ */
+
+ parseMixin: function(){
+ var tok = this.expect('mixin')
+ , name = tok.val
+ , args = tok.args;
+ var block = 'indent' == this.peek().type
+ ? this.block()
+ : null;
+ return new nodes.Mixin(name, args, block);
+ },
+
+ /**
+ * indent (text | newline)* outdent
+ */
+
+ parseTextBlock: function(){
+ var text = new nodes.Text;
+ text.line = this.line();
+ var spaces = this.expect('indent').val;
+ if (null == this._spaces) this._spaces = spaces;
+ var indent = Array(spaces - this._spaces + 1).join(' ');
+ while ('outdent' != this.peek().type) {
+ switch (this.peek().type) {
+ case 'newline':
+ text.push('\\n');
+ this.advance();
+ break;
+ case 'indent':
+ text.push('\\n');
+ this.parseTextBlock().nodes.forEach(function(node){
+ text.push(node);
+ });
+ text.push('\\n');
+ break;
+ default:
+ text.push(indent + this.advance().val);
+ }
+ }
+
+ if (spaces == this._spaces) this._spaces = null;
+ this.expect('outdent');
+ return text;
+ },
+
+ /**
+ * indent expr* outdent
+ */
+
+ block: function(){
+ var block = new nodes.Block;
+ block.line = this.line();
+ this.expect('indent');
+ while ('outdent' != this.peek().type) {
+ if ('newline' == this.peek().type) {
+ this.advance();
+ } else {
+ block.push(this.parseExpr());
+ }
+ }
+ this.expect('outdent');
+ return block;
+ },
+
+ /**
+ * tag (attrs | class | id)* (text | code | ':')? newline* block?
+ */
+
+ parseTag: function(){
+ // ast-filter look-ahead
+ var i = 2;
+ if ('attrs' == this.lookahead(i).type) ++i;
+ if (':' == this.lookahead(i).type) {
+ if ('indent' == this.lookahead(++i).type) {
+ return this.parseASTFilter();
+ }
+ }
+
+ var name = this.advance().val
+ , tag = new nodes.Tag(name)
+ , dot;
+
+ tag.line = this.line();
+
+ // (attrs | class | id)*
+ out:
+ while (true) {
+ switch (this.peek().type) {
+ case 'id':
+ case 'class':
+ var tok = this.advance();
+ tag.setAttribute(tok.type, "'" + tok.val + "'");
+ continue;
+ case 'attrs':
+ var obj = this.advance().attrs
+ , names = Object.keys(obj);
+ for (var i = 0, len = names.length; i < len; ++i) {
+ var name = names[i]
+ , val = obj[name];
+ tag.setAttribute(name, val);
+ }
+ continue;
+ default:
+ break out;
+ }
+ }
+
+ // check immediate '.'
+ if ('.' == this.peek().val) {
+ dot = tag.textOnly = true;
+ this.advance();
+ }
+
+ // (text | code | ':')?
+ switch (this.peek().type) {
+ case 'text':
+ tag.text = this.parseText();
+ break;
+ case 'code':
+ tag.code = this.parseCode();
+ break;
+ case ':':
+ this.advance();
+ tag.block = new nodes.Block;
+ tag.block.push(this.parseTag());
+ break;
+ }
+
+ // newline*
+ while ('newline' == this.peek().type) this.advance();
+
+ tag.textOnly = tag.textOnly || ~textOnly.indexOf(tag.name);
+
+ // script special-case
+ if ('script' == tag.name) {
+ var type = tag.getAttribute('type');
+ if (!dot && type && 'text/javascript' != type.replace(/^['"]|['"]$/g, '')) {
+ tag.textOnly = false;
+ }
+ }
+
+ // block?
+ if ('indent' == this.peek().type) {
+ if (tag.textOnly) {
+ this.lexer.pipeless = true;
+ tag.block = this.parseTextBlock();
+ this.lexer.pipeless = false;
+ } else {
+ var block = this.block();
+ if (tag.block) {
+ for (var i = 0, len = block.nodes.length; i < len; ++i) {
+ tag.block.push(block.nodes[i]);
+ }
+ } else {
+ tag.block = block;
+ }
+ }
+ }
+
+ return tag;
+ }
+};
diff --git a/node_modules/mocha/node_modules/jade/lib/runtime.js b/node_modules/mocha/node_modules/jade/lib/runtime.js
new file mode 100644
index 0000000..7b357ca
--- /dev/null
+++ b/node_modules/mocha/node_modules/jade/lib/runtime.js
@@ -0,0 +1,118 @@
+
+/*!
+ * Jade - runtime
+ * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
+ * MIT Licensed
+ */
+
+/**
+ * Lame Array.isArray() polyfill for now.
+ */
+
+if (!Array.isArray) {
+ Array.isArray = function(arr){
+ return '[object Array]' == Object.prototype.toString.call(arr);
+ };
+}
+
+/**
+ * Lame Object.keys() polyfill for now.
+ */
+
+if (!Object.keys) {
+ Object.keys = function(obj){
+ var arr = [];
+ for (var key in obj) {
+ if (obj.hasOwnProperty(key)) {
+ arr.push(key);
+ }
+ }
+ return arr;
+ }
+}
+
+/**
+ * Render the given attributes object.
+ *
+ * @param {Object} obj
+ * @return {String}
+ * @api private
+ */
+
+exports.attrs = function attrs(obj){
+ var buf = []
+ , terse = obj.terse;
+ delete obj.terse;
+ var keys = Object.keys(obj)
+ , len = keys.length;
+ if (len) {
+ buf.push('');
+ for (var i = 0; i < len; ++i) {
+ var key = keys[i]
+ , val = obj[key];
+ if ('boolean' == typeof val || null == val) {
+ if (val) {
+ terse
+ ? buf.push(key)
+ : buf.push(key + '="' + key + '"');
+ }
+ } else if ('class' == key && Array.isArray(val)) {
+ buf.push(key + '="' + exports.escape(val.join(' ')) + '"');
+ } else {
+ buf.push(key + '="' + exports.escape(val) + '"');
+ }
+ }
+ }
+ return buf.join(' ');
+};
+
+/**
+ * Escape the given string of `html`.
+ *
+ * @param {String} html
+ * @return {String}
+ * @api private
+ */
+
+exports.escape = function escape(html){
+ return String(html)
+ .replace(/&(?!\w+;)/g, '&amp;')
+ .replace(/</g, '&lt;')
+ .replace(/>/g, '&gt;')
+ .replace(/"/g, '&quot;');
+};
+
+/**
+ * Re-throw the given `err` in context to the
+ * the jade in `filename` at the given `lineno`.
+ *
+ * @param {Error} err
+ * @param {String} filename
+ * @param {String} lineno
+ * @api private
+ */
+
+exports.rethrow = function rethrow(err, filename, lineno){
+ if (!filename) throw err;
+
+ var context = 3
+ , str = require('fs').readFileSync(filename, 'utf8')
+ , lines = str.split('\n')
+ , start = Math.max(lineno - context, 0)
+ , end = Math.min(lines.length, lineno + context);
+
+ // Error context
+ var context = lines.slice(start, end).map(function(line, i){
+ var curr = i + start + 1;
+ return (curr == lineno ? ' > ' : ' ')
+ + curr
+ + '| '
+ + line;
+ }).join('\n');
+
+ // Alter exception message
+ err.path = filename;
+ err.message = (filename || 'Jade') + ':' + lineno
+ + '\n' + context + '\n\n' + err.message;
+ throw err;
+};
diff --git a/node_modules/mocha/node_modules/jade/lib/self-closing.js b/node_modules/mocha/node_modules/jade/lib/self-closing.js
new file mode 100644
index 0000000..293e7f8
--- /dev/null
+++ b/node_modules/mocha/node_modules/jade/lib/self-closing.js
@@ -0,0 +1,18 @@
+
+/*!
+ * Jade - self closing tags
+ * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
+ * MIT Licensed
+ */
+
+module.exports = [
+ 'meta'
+ , 'img'
+ , 'link'
+ , 'input'
+ , 'area'
+ , 'base'
+ , 'col'
+ , 'br'
+ , 'hr'
+]; \ No newline at end of file
diff --git a/node_modules/mocha/node_modules/jade/lib/utils.js b/node_modules/mocha/node_modules/jade/lib/utils.js
new file mode 100644
index 0000000..ff46d02
--- /dev/null
+++ b/node_modules/mocha/node_modules/jade/lib/utils.js
@@ -0,0 +1,49 @@
+
+/*!
+ * Jade - utils
+ * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
+ * MIT Licensed
+ */
+
+/**
+ * Convert interpolation in the given string to JavaScript.
+ *
+ * @param {String} str
+ * @return {String}
+ * @api private
+ */
+
+var interpolate = exports.interpolate = function(str){
+ return str.replace(/(\\)?([#!]){(.*?)}/g, function(str, escape, flag, code){
+ return escape
+ ? str
+ : "' + "
+ + ('!' == flag ? '' : 'escape')
+ + "((interp = " + code.replace(/\\'/g, "'")
+ + ") == null ? '' : interp) + '";
+ });
+};
+
+/**
+ * Escape single quotes in `str`.
+ *
+ * @param {String} str
+ * @return {String}
+ * @api private
+ */
+
+var escape = exports.escape = function(str) {
+ return str.replace(/'/g, "\\'");
+};
+
+/**
+ * Interpolate, and escape the given `str`.
+ *
+ * @param {String} str
+ * @return {String}
+ * @api private
+ */
+
+exports.text = function(str){
+ return interpolate(escape(str));
+}; \ No newline at end of file
diff --git a/node_modules/mocha/node_modules/jade/node_modules/mkdirp/.gitignore.orig b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/.gitignore.orig
new file mode 100644
index 0000000..9303c34
--- /dev/null
+++ b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/.gitignore.orig
@@ -0,0 +1,2 @@
+node_modules/
+npm-debug.log \ No newline at end of file
diff --git a/node_modules/mocha/node_modules/jade/node_modules/mkdirp/.gitignore.rej b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/.gitignore.rej
new file mode 100644
index 0000000..69244ff
--- /dev/null
+++ b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/.gitignore.rej
@@ -0,0 +1,5 @@
+--- /dev/null
++++ .gitignore
+@@ -0,0 +1,2 @@
++node_modules/
++npm-debug.log \ No newline at end of file
diff --git a/node_modules/mocha/node_modules/jade/node_modules/mkdirp/.npmignore b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/.npmignore
new file mode 100644
index 0000000..9303c34
--- /dev/null
+++ b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/.npmignore
@@ -0,0 +1,2 @@
+node_modules/
+npm-debug.log \ No newline at end of file
diff --git a/node_modules/mocha/node_modules/jade/node_modules/mkdirp/.travis.yml b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/.travis.yml
new file mode 100644
index 0000000..f1d0f13
--- /dev/null
+++ b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/.travis.yml
@@ -0,0 +1,4 @@
+language: node_js
+node_js:
+ - 0.4
+ - 0.6
diff --git a/node_modules/mocha/node_modules/jade/node_modules/mkdirp/LICENSE b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/LICENSE
new file mode 100644
index 0000000..432d1ae
--- /dev/null
+++ b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/LICENSE
@@ -0,0 +1,21 @@
+Copyright 2010 James Halliday (mail@substack.net)
+
+This project is free software released under the MIT/X11 license:
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/node_modules/mocha/node_modules/jade/node_modules/mkdirp/README.markdown b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/README.markdown
new file mode 100644
index 0000000..40de04f
--- /dev/null
+++ b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/README.markdown
@@ -0,0 +1,61 @@
+mkdirp
+======
+
+Like `mkdir -p`, but in node.js!
+
+[![build status](https://secure.travis-ci.org/substack/node-mkdirp.png)](http://travis-ci.org/substack/node-mkdirp)
+
+example
+=======
+
+pow.js
+------
+ var mkdirp = require('mkdirp');
+
+ mkdirp('/tmp/foo/bar/baz', function (err) {
+ if (err) console.error(err)
+ else console.log('pow!')
+ });
+
+Output
+ pow!
+
+And now /tmp/foo/bar/baz exists, huzzah!
+
+methods
+=======
+
+var mkdirp = require('mkdirp');
+
+mkdirp(dir, mode, cb)
+---------------------
+
+Create a new directory and any necessary subdirectories at `dir` with octal
+permission string `mode`.
+
+If `mode` isn't specified, it defaults to `0777 & (~process.umask())`.
+
+`cb(err, made)` fires with the error or the first directory `made`
+that had to be created, if any.
+
+mkdirp.sync(dir, mode)
+----------------------
+
+Synchronously create a new directory and any necessary subdirectories at `dir`
+with octal permission string `mode`.
+
+If `mode` isn't specified, it defaults to `0777 & (~process.umask())`.
+
+Returns the first directory that had to be created, if any.
+
+install
+=======
+
+With [npm](http://npmjs.org) do:
+
+ npm install mkdirp
+
+license
+=======
+
+MIT/X11
diff --git a/node_modules/mocha/node_modules/jade/node_modules/mkdirp/examples/pow.js b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/examples/pow.js
new file mode 100644
index 0000000..e692421
--- /dev/null
+++ b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/examples/pow.js
@@ -0,0 +1,6 @@
+var mkdirp = require('mkdirp');
+
+mkdirp('/tmp/foo/bar/baz', function (err) {
+ if (err) console.error(err)
+ else console.log('pow!')
+});
diff --git a/node_modules/mocha/node_modules/jade/node_modules/mkdirp/examples/pow.js.orig b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/examples/pow.js.orig
new file mode 100644
index 0000000..7741462
--- /dev/null
+++ b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/examples/pow.js.orig
@@ -0,0 +1,6 @@
+var mkdirp = require('mkdirp');
+
+mkdirp('/tmp/foo/bar/baz', 0755, function (err) {
+ if (err) console.error(err)
+ else console.log('pow!')
+});
diff --git a/node_modules/mocha/node_modules/jade/node_modules/mkdirp/examples/pow.js.rej b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/examples/pow.js.rej
new file mode 100644
index 0000000..81e7f43
--- /dev/null
+++ b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/examples/pow.js.rej
@@ -0,0 +1,19 @@
+--- examples/pow.js
++++ examples/pow.js
+@@ -1,6 +1,15 @@
+-var mkdirp = require('mkdirp').mkdirp;
++var mkdirp = require('../').mkdirp,
++ mkdirpSync = require('../').mkdirpSync;
+
+ mkdirp('/tmp/foo/bar/baz', 0755, function (err) {
+ if (err) console.error(err)
+ else console.log('pow!')
+ });
++
++try {
++ mkdirpSync('/tmp/bar/foo/baz', 0755);
++ console.log('double pow!');
++}
++catch (ex) {
++ console.log(ex);
++} \ No newline at end of file
diff --git a/node_modules/mocha/node_modules/jade/node_modules/mkdirp/index.js b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/index.js
new file mode 100644
index 0000000..6d81c62
--- /dev/null
+++ b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/index.js
@@ -0,0 +1,83 @@
+var path = require('path');
+var fs = require('fs');
+
+module.exports = mkdirP.mkdirp = mkdirP.mkdirP = mkdirP;
+
+function mkdirP (p, mode, f, made) {
+ if (typeof mode === 'function' || mode === undefined) {
+ f = mode;
+ mode = 0777 & (~process.umask());
+ }
+ if (!made) made = null;
+
+ var cb = f || function () {};
+ if (typeof mode === 'string') mode = parseInt(mode, 8);
+ p = path.resolve(p);
+
+ fs.mkdir(p, mode, function (er) {
+ if (!er) {
+ made = made || p;
+ return cb(null, made);
+ }
+ switch (er.code) {
+ case 'ENOENT':
+ mkdirP(path.dirname(p), mode, function (er, made) {
+ if (er) cb(er, made);
+ else mkdirP(p, mode, cb, made);
+ });
+ break;
+
+ case 'EEXIST':
+ fs.stat(p, function (er2, stat) {
+ // if the stat fails, then that's super weird.
+ // let the original EEXIST be the failure reason.
+ if (er2 || !stat.isDirectory()) cb(er, made)
+ else cb(null, made);
+ });
+ break;
+
+ default:
+ cb(er, made);
+ break;
+ }
+ });
+}
+
+mkdirP.sync = function sync (p, mode, made) {
+ if (mode === undefined) {
+ mode = 0777 & (~process.umask());
+ }
+ if (!made) made = null;
+
+ if (typeof mode === 'string') mode = parseInt(mode, 8);
+ p = path.resolve(p);
+
+ try {
+ fs.mkdirSync(p, mode);
+ made = made || p;
+ }
+ catch (err0) {
+ switch (err0.code) {
+ case 'ENOENT' :
+ made = sync(path.dirname(p), mode, made);
+ sync(p, mode, made);
+ break;
+
+ case 'EEXIST' :
+ var stat;
+ try {
+ stat = fs.statSync(p);
+ }
+ catch (err1) {
+ throw err0;
+ }
+ if (!stat.isDirectory()) throw err0;
+ break;
+ default :
+ throw err0
+ break;
+ }
+ }
+
+ return made;
+};
diff --git a/node_modules/mocha/node_modules/jade/node_modules/mkdirp/package.json b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/package.json
new file mode 100644
index 0000000..3e7363f
--- /dev/null
+++ b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/package.json
@@ -0,0 +1,37 @@
+{
+ "name": "mkdirp",
+ "description": "Recursively mkdir, like `mkdir -p`",
+ "version": "0.3.1",
+ "author": {
+ "name": "James Halliday",
+ "email": "mail@substack.net",
+ "url": "http://substack.net"
+ },
+ "main": "./index",
+ "keywords": [
+ "mkdir",
+ "directory"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/substack/node-mkdirp.git"
+ },
+ "scripts": {
+ "test": "tap test/*.js"
+ },
+ "devDependencies": {
+ "tap": "~0.2.4"
+ },
+ "license": "MIT/X11",
+ "engines": {
+ "node": "*"
+ },
+ "_id": "mkdirp@0.3.1",
+ "dependencies": {},
+ "optionalDependencies": {},
+ "_engineSupported": true,
+ "_npmVersion": "1.1.12",
+ "_nodeVersion": "v0.6.14",
+ "_defaultsLoaded": true,
+ "_from": "mkdirp@>= 0.0.7"
+}
diff --git a/node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/chmod.js b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/chmod.js
new file mode 100644
index 0000000..520dcb8
--- /dev/null
+++ b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/chmod.js
@@ -0,0 +1,38 @@
+var mkdirp = require('../').mkdirp;
+var path = require('path');
+var fs = require('fs');
+var test = require('tap').test;
+
+var ps = [ '', 'tmp' ];
+
+for (var i = 0; i < 25; i++) {
+ var dir = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
+ ps.push(dir);
+}
+
+var file = ps.join('/');
+
+test('chmod-pre', function (t) {
+ var mode = 0744
+ mkdirp(file, mode, function (er) {
+ t.ifError(er, 'should not error');
+ fs.stat(file, function (er, stat) {
+ t.ifError(er, 'should exist');
+ t.ok(stat && stat.isDirectory(), 'should be directory');
+ t.equal(stat && stat.mode & 0777, mode, 'should be 0744');
+ t.end();
+ });
+ });
+});
+
+test('chmod', function (t) {
+ var mode = 0755
+ mkdirp(file, mode, function (er) {
+ t.ifError(er, 'should not error');
+ fs.stat(file, function (er, stat) {
+ t.ifError(er, 'should exist');
+ t.ok(stat && stat.isDirectory(), 'should be directory');
+ t.end();
+ });
+ });
+});
diff --git a/node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/clobber.js b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/clobber.js
new file mode 100644
index 0000000..0eb7099
--- /dev/null
+++ b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/clobber.js
@@ -0,0 +1,37 @@
+var mkdirp = require('../').mkdirp;
+var path = require('path');
+var fs = require('fs');
+var test = require('tap').test;
+
+var ps = [ '', 'tmp' ];
+
+for (var i = 0; i < 25; i++) {
+ var dir = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
+ ps.push(dir);
+}
+
+var file = ps.join('/');
+
+// a file in the way
+var itw = ps.slice(0, 3).join('/');
+
+
+test('clobber-pre', function (t) {
+ console.error("about to write to "+itw)
+ fs.writeFileSync(itw, 'I AM IN THE WAY, THE TRUTH, AND THE LIGHT.');
+
+ fs.stat(itw, function (er, stat) {
+ t.ifError(er)
+ t.ok(stat && stat.isFile(), 'should be file')
+ t.end()
+ })
+})
+
+test('clobber', function (t) {
+ t.plan(2);
+ mkdirp(file, 0755, function (err) {
+ t.ok(err);
+ t.equal(err.code, 'ENOTDIR');
+ t.end();
+ });
+});
diff --git a/node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/mkdirp.js b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/mkdirp.js
new file mode 100644
index 0000000..b07cd70
--- /dev/null
+++ b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/mkdirp.js
@@ -0,0 +1,28 @@
+var mkdirp = require('../');
+var path = require('path');
+var fs = require('fs');
+var test = require('tap').test;
+
+test('woo', function (t) {
+ t.plan(2);
+ var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
+ var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
+ var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
+
+ var file = '/tmp/' + [x,y,z].join('/');
+
+ mkdirp(file, 0755, function (err) {
+ if (err) t.fail(err);
+ else path.exists(file, function (ex) {
+ if (!ex) t.fail('file not created')
+ else fs.stat(file, function (err, stat) {
+ if (err) t.fail(err)
+ else {
+ t.equal(stat.mode & 0777, 0755);
+ t.ok(stat.isDirectory(), 'target not a directory');
+ t.end();
+ }
+ })
+ })
+ });
+});
diff --git a/node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/perm.js b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/perm.js
new file mode 100644
index 0000000..23a7abb
--- /dev/null
+++ b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/perm.js
@@ -0,0 +1,32 @@
+var mkdirp = require('../');
+var path = require('path');
+var fs = require('fs');
+var test = require('tap').test;
+
+test('async perm', function (t) {
+ t.plan(2);
+ var file = '/tmp/' + (Math.random() * (1<<30)).toString(16);
+
+ mkdirp(file, 0755, function (err) {
+ if (err) t.fail(err);
+ else path.exists(file, function (ex) {
+ if (!ex) t.fail('file not created')
+ else fs.stat(file, function (err, stat) {
+ if (err) t.fail(err)
+ else {
+ t.equal(stat.mode & 0777, 0755);
+ t.ok(stat.isDirectory(), 'target not a directory');
+ t.end();
+ }
+ })
+ })
+ });
+});
+
+test('async root perm', function (t) {
+ mkdirp('/tmp', 0755, function (err) {
+ if (err) t.fail(err);
+ t.end();
+ });
+ t.end();
+});
diff --git a/node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/perm_sync.js b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/perm_sync.js
new file mode 100644
index 0000000..f685f60
--- /dev/null
+++ b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/perm_sync.js
@@ -0,0 +1,39 @@
+var mkdirp = require('../');
+var path = require('path');
+var fs = require('fs');
+var test = require('tap').test;
+
+test('sync perm', function (t) {
+ t.plan(2);
+ var file = '/tmp/' + (Math.random() * (1<<30)).toString(16) + '.json';
+
+ mkdirp.sync(file, 0755);
+ path.exists(file, function (ex) {
+ if (!ex) t.fail('file not created')
+ else fs.stat(file, function (err, stat) {
+ if (err) t.fail(err)
+ else {
+ t.equal(stat.mode & 0777, 0755);
+ t.ok(stat.isDirectory(), 'target not a directory');
+ t.end();
+ }
+ })
+ });
+});
+
+test('sync root perm', function (t) {
+ t.plan(1);
+
+ var file = '/tmp';
+ mkdirp.sync(file, 0755);
+ path.exists(file, function (ex) {
+ if (!ex) t.fail('file not created')
+ else fs.stat(file, function (err, stat) {
+ if (err) t.fail(err)
+ else {
+ t.ok(stat.isDirectory(), 'target not a directory');
+ t.end();
+ }
+ })
+ });
+});
diff --git a/node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/race.js b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/race.js
new file mode 100644
index 0000000..96a0447
--- /dev/null
+++ b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/race.js
@@ -0,0 +1,41 @@
+var mkdirp = require('../').mkdirp;
+var path = require('path');
+var fs = require('fs');
+var test = require('tap').test;
+
+test('race', function (t) {
+ t.plan(4);
+ var ps = [ '', 'tmp' ];
+
+ for (var i = 0; i < 25; i++) {
+ var dir = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
+ ps.push(dir);
+ }
+ var file = ps.join('/');
+
+ var res = 2;
+ mk(file, function () {
+ if (--res === 0) t.end();
+ });
+
+ mk(file, function () {
+ if (--res === 0) t.end();
+ });
+
+ function mk (file, cb) {
+ mkdirp(file, 0755, function (err) {
+ if (err) t.fail(err);
+ else path.exists(file, function (ex) {
+ if (!ex) t.fail('file not created')
+ else fs.stat(file, function (err, stat) {
+ if (err) t.fail(err)
+ else {
+ t.equal(stat.mode & 0777, 0755);
+ t.ok(stat.isDirectory(), 'target not a directory');
+ if (cb) cb();
+ }
+ })
+ })
+ });
+ }
+});
diff --git a/node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/rel.js b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/rel.js
new file mode 100644
index 0000000..7985824
--- /dev/null
+++ b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/rel.js
@@ -0,0 +1,32 @@
+var mkdirp = require('../');
+var path = require('path');
+var fs = require('fs');
+var test = require('tap').test;
+
+test('rel', function (t) {
+ t.plan(2);
+ var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
+ var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
+ var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
+
+ var cwd = process.cwd();
+ process.chdir('/tmp');
+
+ var file = [x,y,z].join('/');
+
+ mkdirp(file, 0755, function (err) {
+ if (err) t.fail(err);
+ else path.exists(file, function (ex) {
+ if (!ex) t.fail('file not created')
+ else fs.stat(file, function (err, stat) {
+ if (err) t.fail(err)
+ else {
+ process.chdir(cwd);
+ t.equal(stat.mode & 0777, 0755);
+ t.ok(stat.isDirectory(), 'target not a directory');
+ t.end();
+ }
+ })
+ })
+ });
+});
diff --git a/node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/return.js b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/return.js
new file mode 100644
index 0000000..bce68e5
--- /dev/null
+++ b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/return.js
@@ -0,0 +1,25 @@
+var mkdirp = require('../');
+var path = require('path');
+var fs = require('fs');
+var test = require('tap').test;
+
+test('return value', function (t) {
+ t.plan(4);
+ var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
+ var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
+ var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
+
+ var file = '/tmp/' + [x,y,z].join('/');
+
+ // should return the first dir created.
+ // By this point, it would be profoundly surprising if /tmp didn't
+ // already exist, since every other test makes things in there.
+ mkdirp(file, function (err, made) {
+ t.ifError(err);
+ t.equal(made, '/tmp/' + x);
+ mkdirp(file, function (err, made) {
+ t.ifError(err);
+ t.equal(made, null);
+ });
+ });
+});
diff --git a/node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/return_sync.js b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/return_sync.js
new file mode 100644
index 0000000..7c222d3
--- /dev/null
+++ b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/return_sync.js
@@ -0,0 +1,24 @@
+var mkdirp = require('../');
+var path = require('path');
+var fs = require('fs');
+var test = require('tap').test;
+
+test('return value', function (t) {
+ t.plan(2);
+ var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
+ var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
+ var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
+
+ var file = '/tmp/' + [x,y,z].join('/');
+
+ // should return the first dir created.
+ // By this point, it would be profoundly surprising if /tmp didn't
+ // already exist, since every other test makes things in there.
+ // Note that this will throw on failure, which will fail the test.
+ var made = mkdirp.sync(file);
+ t.equal(made, '/tmp/' + x);
+
+ // making the same file again should have no effect.
+ made = mkdirp.sync(file);
+ t.equal(made, null);
+});
diff --git a/node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/sync.js b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/sync.js
new file mode 100644
index 0000000..7530cad
--- /dev/null
+++ b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/sync.js
@@ -0,0 +1,32 @@
+var mkdirp = require('../');
+var path = require('path');
+var fs = require('fs');
+var test = require('tap').test;
+
+test('sync', function (t) {
+ t.plan(2);
+ var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
+ var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
+ var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
+
+ var file = '/tmp/' + [x,y,z].join('/');
+
+ try {
+ mkdirp.sync(file, 0755);
+ } catch (err) {
+ t.fail(err);
+ return t.end();
+ }
+
+ path.exists(file, function (ex) {
+ if (!ex) t.fail('file not created')
+ else fs.stat(file, function (err, stat) {
+ if (err) t.fail(err)
+ else {
+ t.equal(stat.mode & 0777, 0755);
+ t.ok(stat.isDirectory(), 'target not a directory');
+ t.end();
+ }
+ });
+ });
+});
diff --git a/node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/umask.js b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/umask.js
new file mode 100644
index 0000000..64ccafe
--- /dev/null
+++ b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/umask.js
@@ -0,0 +1,28 @@
+var mkdirp = require('../');
+var path = require('path');
+var fs = require('fs');
+var test = require('tap').test;
+
+test('implicit mode from umask', function (t) {
+ t.plan(2);
+ var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
+ var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
+ var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
+
+ var file = '/tmp/' + [x,y,z].join('/');
+
+ mkdirp(file, function (err) {
+ if (err) t.fail(err);
+ else path.exists(file, function (ex) {
+ if (!ex) t.fail('file not created')
+ else fs.stat(file, function (err, stat) {
+ if (err) t.fail(err)
+ else {
+ t.equal(stat.mode & 0777, 0777 & (~process.umask()));
+ t.ok(stat.isDirectory(), 'target not a directory');
+ t.end();
+ }
+ })
+ })
+ });
+});
diff --git a/node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/umask_sync.js b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/umask_sync.js
new file mode 100644
index 0000000..4bd5376
--- /dev/null
+++ b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/umask_sync.js
@@ -0,0 +1,32 @@
+var mkdirp = require('../');
+var path = require('path');
+var fs = require('fs');
+var test = require('tap').test;
+
+test('umask sync modes', function (t) {
+ t.plan(2);
+ var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
+ var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
+ var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
+
+ var file = '/tmp/' + [x,y,z].join('/');
+
+ try {
+ mkdirp.sync(file, 0755);
+ } catch (err) {
+ t.fail(err);
+ return t.end();
+ }
+
+ path.exists(file, function (ex) {
+ if (!ex) t.fail('file not created')
+ else fs.stat(file, function (err, stat) {
+ if (err) t.fail(err)
+ else {
+ t.equal(stat.mode & 0777, (0777 & (~process.umask())));
+ t.ok(stat.isDirectory(), 'target not a directory');
+ t.end();
+ }
+ });
+ });
+});
diff --git a/node_modules/mocha/node_modules/jade/package.json b/node_modules/mocha/node_modules/jade/package.json
new file mode 100644
index 0000000..e77e908
--- /dev/null
+++ b/node_modules/mocha/node_modules/jade/package.json
@@ -0,0 +1,42 @@
+{
+ "name": "jade",
+ "description": "Jade template engine",
+ "version": "0.20.3",
+ "author": {
+ "name": "TJ Holowaychuk",
+ "email": "tj@vision-media.ca"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/visionmedia/jade.git"
+ },
+ "main": "./index.js",
+ "bin": {
+ "jade": "./bin/jade"
+ },
+ "dependencies": {
+ "commander": "0.5.x",
+ "mkdirp": ">= 0.0.7"
+ },
+ "devDependencies": {
+ "mocha": "*",
+ "coffee-script": ">= 0.0.1",
+ "markdown": ">= 0.0.1",
+ "stylus": ">= 0.0.1",
+ "uubench": "0.0.1",
+ "uglify-js": ">= 1.0.7"
+ },
+ "scripts": {
+ "prepublish": "npm prune"
+ },
+ "engines": {
+ "node": ">= 0.1.98"
+ },
+ "_id": "jade@0.20.3",
+ "optionalDependencies": {},
+ "_engineSupported": true,
+ "_npmVersion": "1.1.12",
+ "_nodeVersion": "v0.6.14",
+ "_defaultsLoaded": true,
+ "_from": "jade@0.20.3"
+}
diff --git a/node_modules/mocha/node_modules/jade/runtime.js b/node_modules/mocha/node_modules/jade/runtime.js
new file mode 100644
index 0000000..39f8a28
--- /dev/null
+++ b/node_modules/mocha/node_modules/jade/runtime.js
@@ -0,0 +1,123 @@
+
+var jade = (function(exports){
+/*!
+ * Jade - runtime
+ * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
+ * MIT Licensed
+ */
+
+/**
+ * Lame Array.isArray() polyfill for now.
+ */
+
+if (!Array.isArray) {
+ Array.isArray = function(arr){
+ return '[object Array]' == Object.prototype.toString.call(arr);
+ };
+}
+
+/**
+ * Lame Object.keys() polyfill for now.
+ */
+
+if (!Object.keys) {
+ Object.keys = function(obj){
+ var arr = [];
+ for (var key in obj) {
+ if (obj.hasOwnProperty(key)) {
+ arr.push(key);
+ }
+ }
+ return arr;
+ }
+}
+
+/**
+ * Render the given attributes object.
+ *
+ * @param {Object} obj
+ * @return {String}
+ * @api private
+ */
+
+exports.attrs = function attrs(obj){
+ var buf = []
+ , terse = obj.terse;
+ delete obj.terse;
+ var keys = Object.keys(obj)
+ , len = keys.length;
+ if (len) {
+ buf.push('');
+ for (var i = 0; i < len; ++i) {
+ var key = keys[i]
+ , val = obj[key];
+ if ('boolean' == typeof val || null == val) {
+ if (val) {
+ terse
+ ? buf.push(key)
+ : buf.push(key + '="' + key + '"');
+ }
+ } else if ('class' == key && Array.isArray(val)) {
+ buf.push(key + '="' + exports.escape(val.join(' ')) + '"');
+ } else {
+ buf.push(key + '="' + exports.escape(val) + '"');
+ }
+ }
+ }
+ return buf.join(' ');
+};
+
+/**
+ * Escape the given string of `html`.
+ *
+ * @param {String} html
+ * @return {String}
+ * @api private
+ */
+
+exports.escape = function escape(html){
+ return String(html)
+ .replace(/&(?!\w+;)/g, '&amp;')
+ .replace(/</g, '&lt;')
+ .replace(/>/g, '&gt;')
+ .replace(/"/g, '&quot;');
+};
+
+/**
+ * Re-throw the given `err` in context to the
+ * the jade in `filename` at the given `lineno`.
+ *
+ * @param {Error} err
+ * @param {String} filename
+ * @param {String} lineno
+ * @api private
+ */
+
+exports.rethrow = function rethrow(err, filename, lineno){
+ if (!filename) throw err;
+
+ var context = 3
+ , str = require('fs').readFileSync(filename, 'utf8')
+ , lines = str.split('\n')
+ , start = Math.max(lineno - context, 0)
+ , end = Math.min(lines.length, lineno + context);
+
+ // Error context
+ var context = lines.slice(start, end).map(function(line, i){
+ var curr = i + start + 1;
+ return (curr == lineno ? ' > ' : ' ')
+ + curr
+ + '| '
+ + line;
+ }).join('\n');
+
+ // Alter exception message
+ err.path = filename;
+ err.message = (filename || 'Jade') + ':' + lineno
+ + '\n' + context + '\n\n' + err.message;
+ throw err;
+};
+
+ return exports;
+
+})({}); \ No newline at end of file
diff --git a/node_modules/mocha/node_modules/jade/runtime.min.js b/node_modules/mocha/node_modules/jade/runtime.min.js
new file mode 100644
index 0000000..8c19a98
--- /dev/null
+++ b/node_modules/mocha/node_modules/jade/runtime.min.js
@@ -0,0 +1 @@
+var jade=function(exports){return Array.isArray||(Array.isArray=function(arr){return"[object Array]"==Object.prototype.toString.call(arr)}),Object.keys||(Object.keys=function(obj){var arr=[];for(var key in obj)obj.hasOwnProperty(key)&&arr.push(key);return arr}),exports.attrs=function(obj){var buf=[],terse=obj.terse;delete obj.terse;var keys=Object.keys(obj),len=keys.length;if(len){buf.push("");for(var i=0;i<len;++i){var key=keys[i],val=obj[key];"boolean"==typeof val||null==val?val&&(terse?buf.push(key):buf.push(key+'="'+key+'"')):"class"==key&&Array.isArray(val)?buf.push(key+'="'+exports.escape(val.join(" "))+'"'):buf.push(key+'="'+exports.escape(val)+'"')}}return buf.join(" ")},exports.escape=function(html){return String(html).replace(/&(?!\w+;)/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")},exports.rethrow=function(err,filename,lineno){if(!filename)throw err;var context=3,str=require("fs").readFileSync(filename,"utf8"),lines=str.split("\n"),start=Math.max(lineno-context,0),end=Math.min(lines.length,lineno+context),context=lines.slice(start,end).map(function(line,i){var curr=i+start+1;return(curr==lineno?" > ":" ")+curr+"| "+line}).join("\n");throw err.path=filename,err.message=(filename||"Jade")+":"+lineno+"\n"+context+"\n\n"+err.message,err},exports}({}) \ No newline at end of file
diff --git a/node_modules/mocha/package.json b/node_modules/mocha/package.json
new file mode 100644
index 0000000..f77984b
--- /dev/null
+++ b/node_modules/mocha/package.json
@@ -0,0 +1,48 @@
+{
+ "name": "mocha",
+ "version": "1.0.1",
+ "description": "simple, flexible, fun test framework",
+ "keywords": [
+ "test",
+ "bdd",
+ "tdd",
+ "tap"
+ ],
+ "author": {
+ "name": "TJ Holowaychuk",
+ "email": "tj@vision-media.ca"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/visionmedia/mocha.git"
+ },
+ "main": "./index",
+ "bin": {
+ "mocha": "./bin/mocha",
+ "_mocha": "./bin/_mocha"
+ },
+ "engines": {
+ "node": ">= 0.4.x < 0.8.0"
+ },
+ "scripts": {
+ "test": "make test"
+ },
+ "dependencies": {
+ "commander": "0.5.x",
+ "growl": "1.5.x",
+ "jade": "0.20.3",
+ "diff": "1.0.2",
+ "debug": "*"
+ },
+ "devDependencies": {
+ "should": "*",
+ "coffee-script": "1.2"
+ },
+ "_id": "mocha@1.0.1",
+ "optionalDependencies": {},
+ "_engineSupported": true,
+ "_npmVersion": "1.1.12",
+ "_nodeVersion": "v0.6.14",
+ "_defaultsLoaded": true,
+ "_from": "mocha@>= 0.14.1"
+}