text: /*!
   * mocha
   * Copyright(c) 2011 TJ Holowaychuk <tj@vision-media.ca>
   * MIT Licensed
   */
  
  /**
   * Module dependencies.
   */
  
  var path = require('path')
    , utils = require('./utils');
  
  /**
   * Expose `Mocha`.
   */
  
  exports = module.exports = Mocha;
  
  /**
   * Expose internals.
   */
  
  exports.utils = 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
   *   - `bail` bail on the first test failure
   *   - `slow` milliseconds to wait before considering a test slow
   *   - `ignoreLeaks` ignore global leaks
   *   - `grep` string or regexp to filter tests with
   *
   * @param {Object} options
   * @api public
   */
  
  function Mocha(options) {
    options = options || {};
    this.files = [];
    this.options = options;
    this.grep(options.grep);
    this.suite = new exports.Suite('', new exports.Context);
    this.ui(options.ui);
    this.bail(options.bail);
    this.reporter(options.reporter);
    if (null != options.timeout) this.timeout(options.timeout);
    this.useColors(options.useColors)
    if (options.slow) this.slow(options.slow);
  
    this.suite.on('pre-require', function (context) {
      exports.afterEach = context.afterEach || context.teardown;
      exports.after = context.after || context.suiteTeardown;
      exports.beforeEach = context.beforeEach || context.setup;
      exports.before = context.before || context.suiteSetup;
      exports.describe = context.describe || context.suite;
      exports.it = context.it || context.test;
      exports.setup = context.setup || context.beforeEach;
      exports.suiteSetup = context.suiteSetup || context.before;
      exports.suiteTeardown = context.suiteTeardown || context.after;
      exports.suite = context.suite || context.describe;
      exports.teardown = context.teardown || context.afterEach;
      exports.test = context.test || context.it;
    });
  }
  
  /**
   * Enable or disable bailing on the first failure.
   *
   * @param {Boolean} [bail]
   * @api public
   */
  
  Mocha.prototype.bail = function(bail){
    if (0 == arguments.length) bail = true;
    this.suite.bail(bail);
    return this;
  };
  
  /**
   * Add test `file`.
   *
   * @param {String} file
   * @api public
   */
  
  Mocha.prototype.addFile = function(file){
    this.files.push(file);
    return this;
  };
  
  /**
   * Set reporter to `reporter`, defaults to "dot".
   *
   * @param {String|Function} reporter name or constructor
   * @api public
   */
  
  Mocha.prototype.reporter = function(reporter){
    if ('function' == typeof reporter) {
      this._reporter = reporter;
    } else {
      reporter = reporter || 'dot';
      var _reporter;
      try { _reporter = require('./reporters/' + reporter); } catch (err) {};
      if (!_reporter) try { _reporter = require(reporter); } catch (err) {};
      if (!_reporter && reporter === 'teamcity')
        console.warn('The Teamcity reporter was moved to a package named ' +
          'mocha-teamcity-reporter ' +
          '(https://npmjs.org/package/mocha-teamcity-reporter).');
      if (!_reporter) throw new Error('invalid reporter "' + reporter + '"');
      this._reporter = _reporter;
    }
    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) try { this._ui = require(name); } catch (err) {};
    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(fn){
    var self = this;
    var suite = this.suite;
    var pending = this.files.length;
    this.files.forEach(function(file){
      file = path.resolve(file);
      suite.emit('pre-require', global, file, self);
      suite.emit('require', require(file), file, self);
      suite.emit('post-require', global, file, self);
      --pending || (fn && fn());
    });
  };
  
  /**
   * 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, { name: 'mocha', title: 'Failed', image: image('error') });
      } else {
        notify(stats.passes + ' tests passed in ' + stats.duration + 'ms', {
            name: 'mocha'
          , title: 'Passed'
          , image: image('ok')
        });
      }
    });
  };
  
  /**
   * Add regexp to grep, if `re` is a string it is escaped.
   *
   * @param {RegExp|String} re
   * @return {Mocha}
   * @api public
   */
  
  Mocha.prototype.grep = function(re){
    this.options.grep = 'string' == typeof re
      ? new RegExp(utils.escapeRegexp(re))
      : re;
    return this;
  };
  
  /**
   * Invert `.grep()` matches.
   *
   * @return {Mocha}
   * @api public
   */
  
  Mocha.prototype.invert = function(){
    this.options.invert = true;
    return this;
  };
  
  /**
   * Ignore global leaks.
   *
   * @param {Boolean} ignore
   * @return {Mocha}
   * @api public
   */
  
  Mocha.prototype.ignoreLeaks = function(ignore){
    this.options.ignoreLeaks = !!ignore;
    return this;
  };
  
  /**
   * Enable global leak checking.
   *
   * @return {Mocha}
   * @api public
   */
  
  Mocha.prototype.checkLeaks = function(){
    this.options.ignoreLeaks = false;
    return this;
  };
  
  /**
   * Enable growl support.
   *
   * @return {Mocha}
   * @api public
   */
  
  Mocha.prototype.growl = function(){
    this.options.growl = true;
    return this;
  };
  
  /**
   * Ignore `globals` array or string.
   *
   * @param {Array|String} globals
   * @return {Mocha}
   * @api public
   */
  
  Mocha.prototype.globals = function(globals){
    this.options.globals = (this.options.globals || []).concat(globals);
    return this;
  };
  
  /**
   * Emit color output.
   *
   * @param {Boolean} colors
   * @return {Mocha}
   * @api public
   */
  
  Mocha.prototype.useColors = function(colors){
    this.options.useColors = arguments.length && colors != undefined
      ? colors
      : true;
    return this;
  };
  
  /**
   * Use inline diffs rather than +/-.
   *
   * @param {Boolean} inlineDiffs
   * @return {Mocha}
   * @api public
   */
  
  Mocha.prototype.useInlineDiffs = function(inlineDiffs) {
    this.options.useInlineDiffs = arguments.length && inlineDiffs != undefined
    ? inlineDiffs
    : false;
    return this;
  };
  
  /**
   * Set the timeout in milliseconds.
   *
   * @param {Number} timeout
   * @return {Mocha}
   * @api public
   */
  
  Mocha.prototype.timeout = function(timeout){
    this.suite.timeout(timeout);
    return this;
  };
  
  /**
   * Set slowness threshold in milliseconds.
   *
   * @param {Number} slow
   * @return {Mocha}
   * @api public
   */
  
  Mocha.prototype.slow = function(slow){
    this.suite.slow(slow);
    return this;
  };
  
  /**
   * Makes all tests async (accepting a callback)
   *
   * @return {Mocha}
   * @api public
   */
  
  Mocha.prototype.asyncOnly = function(){
    this.options.asyncOnly = true;
    return this;
  };
  
  /**
   * Run tests and invoke `fn()` when complete.
   *
   * @param {Function} fn
   * @return {Runner}
   * @api public
   */
  
  Mocha.prototype.run = function(fn){
    if (this.files.length) this.loadFiles();
    var suite = this.suite;
    var options = this.options;
    var runner = new exports.Runner(suite);
    var reporter = new this._reporter(runner);
    runner.ignoreLeaks = false !== options.ignoreLeaks;
    runner.asyncOnly = options.asyncOnly;
    if (options.grep) runner.grep(options.grep, options.invert);
    if (options.globals) runner.globals(options.globals);
    if (options.growl) this._growl(runner, reporter);
    exports.reporters.Base.useColors = options.useColors;
    exports.reporters.Base.inlineDiffs = options.useInlineDiffs;
    return runner.run(fn);
  };
  