text: /*
  
  nodemon is a utility for node, and replaces the use of the executable
  node. So the user calls `nodemon foo.js` instead.
  
  nodemon can be run in a number of ways:
  
  `nodemon` - tries to use package.json#main property to run
  `nodemon` - if no package, looks for index.js
  `nodemon app.js` - runs app.js
  `nodemon --arg app.js --apparg` - eats arg1, and runs app.js with apparg
  `nodemon --apparg` - as above, but passes apparg to package.json#main (or
    index.js)
  `nodemon --debug app.js
  
  */
  
  var fs = require('fs');
  var path = require('path');
  var existsSync = fs.existsSync || path.existsSync;
  
  module.exports = parse;
  
  /**
   * Parses the command line arguments `process.argv` and returns the
   * nodemon options, the user script and the executable script.
   *
   * @param  {Array} full process arguments, including `node` leading arg
   * @return {Object} { options, script, args }
   */
  function parse(argv) {
    if (typeof argv === 'string') {
      argv = argv.split(' ');
    }
  
    var eat = function (i, args) {
      if (i <= args.length) {
        return args.splice(i + 1, 1).pop();
      }
    };
  
    var args = argv.slice(2);
    var script = null;
    var nodemonOptions = { scriptPosition: null };
  
    var nodemonOpt = nodemonOption.bind(null, nodemonOptions);
    var lookForArgs = true;
  
    // move forward through the arguments
    for (var i = 0; i < args.length; i++) {
      // if the argument looks like a file, then stop eating
      if (!script) {
        if (args[i] === '.' || existsSync(args[i])) {
          script = args.splice(i, 1).pop();
  
          // we capture the position of the script because we'll reinsert it in
          // the right place in run.js:command (though I'm not sure we should even
          // take it out of the array in the first place, but this solves passing
          // arguments to the exec process for now).
          nodemonOptions.scriptPosition = i;
          i--;
          continue;
        }
      }
  
      if (lookForArgs) {
        // respect the standard way of saying: hereafter belongs to my script
        if (args[i] === '--') {
          args.splice(i, 1);
          // cycle back one argument, as we just ate this one up
          i--;
  
          // ignore all further nodemon arguments
          lookForArgs = false;
  
          // move to the next iteration
          continue;
        }
  
        if (nodemonOpt(args[i], eat.bind(null, i, args)) !== false) {
          args.splice(i, 1);
          // cycle back one argument, as we just ate this one up
          i--;
        }
      }
    }
  
    if (script === null && !nodemonOptions.exec) {
      var found = findAppScript();
      if (found !== null) {
        if (found.exec) {
          nodemonOptions.exec = found.exec;
        }
        script = found.script;
        nodemonOptions.scriptPosition = args.length;
      }
    }
  
    nodemonOptions.script = script;
    nodemonOptions.args = args;
  
    return nodemonOptions;
  }
  
  
  /**
   * Given an argument (ie. from process.argv), sets nodemon
   * options and can eat up the argument value
   *
   * @param {Object} options object that will be updated
   * @param {Sting} current argument from argv
   * @param {Function} the callback to eat up the next argument in argv
   * @return {Boolean} false if argument was not a nodemon arg
   */
  function nodemonOption(options, arg, eatNext) {
    // line seperation on purpose to help legibility
    if (arg === '--help' || arg === '-h' || arg === '-?') {
      var help = eatNext();
      options.help = help ? help : true;
    } else
  
    if (arg === '--version' || arg === '-v') {
      options.version = true;
    } else
  
    if (arg === '--dump') {
      options.dump = true;
    } else
  
    if (arg === '--verbose' || arg === '-V') {
      options.verbose = true;
    } else
  
    // Depricated as this is "on" by default
    if (arg === '--js') {
      options.js = true;
    } else
  
    if (arg === '--quiet' || arg === '-q') {
      options.quiet = true;
    } else
  
    if (arg === '--hidden') { // TODO document this flag?
      options.hidden = true;
    } else
  
    if (arg === '--watch' || arg === '-w') {
      if (!options.watch) { options.watch = []; }
      options.watch.push(eatNext());
    } else
  
    if (arg === '--ignore' || arg === '-i') {
      if (!options.ignore) { options.ignore = []; }
      options.ignore.push(eatNext());
    } else
  
    if (arg === '--exitcrash') {
      options.exitcrash = true;
    } else
  
    if (arg === '--delay' || arg === '-d') {
      options.delay = parseDelay(eatNext());
    } else
  
    if (arg === '--exec' || arg === '-x') {
      options.exec = eatNext();
    } else
  
    if (arg === '--no-stdin' || arg === '-I') {
      options.stdin = false;
    } else
  
    if (arg === '--on-change-only' || arg === '-C') {
      options.runOnChangeOnly = true;
    } else
  
    if (arg === '--ext' || arg === '-e') {
      options.ext = eatNext();
    } else
  
    if (arg === '--cwd') {
      options.cwd = eatNext();
  
      // go ahead and change directory. This is primarily for nodemon tools like
      // grunt-nodemon - we're doing this early because it will affect where the
      // user script is searched for.
      process.chdir(path.resolve(options.cwd));
    } else {
  
      // this means we didn't match
      return false;
    }
  }
  
  function findAppScript() {
    // nodemon has been run alone, so try to read the package file
    // or try to read the index.js file
    if (existsSync('./index.js')) {
      return { exec: null, script: 'index.js' };
    }
  
    return null;
  }
  
  /**
   * Given an argument (ie. from nodemonOption()), will parse and return the
   * equivalent millisecond value or 0 if the argument cannot be parsed
   *
   * @param {String} argument value given to the --delay option
   * @return {Number} millisecond equivalent of the argument
   */
  function parseDelay(value) {
    var millisPerSecond = 1000;
    var millis = 0;
  
    if (value.match(/^\d*ms$/)) {
      // Explicitly parse for milliseconds when using ms time specifier
      millis = parseInt(value, 10);
    } else {
      // Otherwise, parse for seconds, with or without time specifier then convert
      millis = parseFloat(value) * millisPerSecond;
    }
  
    return isNaN(millis) ? 0 : millis;
  }
  
  