http://git-wip-us.apache.org/repos/asf/incubator-griffin-site/blob/4f8fa326/node_modules/chokidar/index.js
----------------------------------------------------------------------
diff --git a/node_modules/chokidar/index.js b/node_modules/chokidar/index.js
new file mode 100644
index 0000000..e23a643
--- /dev/null
+++ b/node_modules/chokidar/index.js
@@ -0,0 +1,711 @@
+'use strict';
+var EventEmitter = require('events').EventEmitter;
+var fs = require('fs');
+var sysPath = require('path');
+var asyncEach = require('async-each');
+var anymatch = require('anymatch');
+var globParent = require('glob-parent');
+var isGlob = require('is-glob');
+var isAbsolute = require('path-is-absolute');
+var inherits = require('inherits');
+
+var NodeFsHandler = require('./lib/nodefs-handler');
+var FsEventsHandler = require('./lib/fsevents-handler');
+
+var arrify = function(value) {
+  if (value == null) return [];
+  return Array.isArray(value) ? value : [value];
+};
+
+var flatten = function(list, result) {
+  if (result == null) result = [];
+  list.forEach(function(item) {
+    if (Array.isArray(item)) {
+      flatten(item, result);
+    } else {
+      result.push(item);
+    }
+  });
+  return result;
+};
+
+// Little isString util for use in Array#every.
+var isString = function(thing) {
+  return typeof thing === 'string';
+};
+
+// Public: Main class.
+// Watches files & directories for changes.
+//
+// * _opts - object, chokidar options hash
+//
+// Emitted events:
+// `add`, `addDir`, `change`, `unlink`, `unlinkDir`, `all`, `error`
+//
+// Examples
+//
+//  var watcher = new FSWatcher()
+//    .add(directories)
+//    .on('add', path => console.log('File', path, 'was added'))
+//    .on('change', path => console.log('File', path, 'was changed'))
+//    .on('unlink', path => console.log('File', path, 'was removed'))
+//    .on('all', (event, path) => console.log(path, ' emitted ', event))
+//
+function FSWatcher(_opts) {
+  EventEmitter.call(this);
+  var opts = {};
+  // in case _opts that is passed in is a frozen object
+  if (_opts) for (var opt in _opts) opts[opt] = _opts[opt];
+  this._watched = Object.create(null);
+  this._closers = Object.create(null);
+  this._ignoredPaths = Object.create(null);
+  Object.defineProperty(this, '_globIgnored', {
+    get: function() { return Object.keys(this._ignoredPaths); }
+  });
+  this.closed = false;
+  this._throttled = Object.create(null);
+  this._symlinkPaths = Object.create(null);
+
+  function undef(key) {
+    return opts[key] === undefined;
+  }
+
+  // Set up default options.
+  if (undef('persistent')) opts.persistent = true;
+  if (undef('ignoreInitial')) opts.ignoreInitial = false;
+  if (undef('ignorePermissionErrors')) opts.ignorePermissionErrors = false;
+  if (undef('interval')) opts.interval = 100;
+  if (undef('binaryInterval')) opts.binaryInterval = 300;
+  this.enableBinaryInterval = opts.binaryInterval !== opts.interval;
+
+  // Enable fsevents on OS X when polling isn't explicitly enabled.
+  if (undef('useFsEvents')) opts.useFsEvents = !opts.usePolling;
+
+  // If we can't use fsevents, ensure the options reflect it's disabled.
+  if (!FsEventsHandler.canUse()) opts.useFsEvents = false;
+
+  // Use polling on Mac if not using fsevents.
+  // Other platforms use non-polling fs.watch.
+  if (undef('usePolling') && !opts.useFsEvents) {
+    opts.usePolling = process.platform === 'darwin';
+  }
+
+  // Global override (useful for end-developers that need to force polling for 
all
+  // instances of chokidar, regardless of usage/dependency depth)
+  var envPoll = process.env.CHOKIDAR_USEPOLLING;
+  if (envPoll !== undefined) {
+    var envLower = envPoll.toLowerCase();
+
+    if (envLower === 'false' || envLower === '0') {
+      opts.usePolling = false;
+    } else if (envLower === 'true' || envLower === '1') {
+      opts.usePolling = true;
+    } else {
+      opts.usePolling = !!envLower
+    }
+  }
+
+  // Editor atomic write normalization enabled by default with fs.watch
+  if (undef('atomic')) opts.atomic = !opts.usePolling && !opts.useFsEvents;
+  if (opts.atomic) this._pendingUnlinks = Object.create(null);
+
+  if (undef('followSymlinks')) opts.followSymlinks = true;
+
+  if (undef('awaitWriteFinish')) opts.awaitWriteFinish = false;
+  if (opts.awaitWriteFinish === true) opts.awaitWriteFinish = {};
+  var awf = opts.awaitWriteFinish;
+  if (awf) {
+    if (!awf.stabilityThreshold) awf.stabilityThreshold = 2000;
+    if (!awf.pollInterval) awf.pollInterval = 100;
+
+    this._pendingWrites = Object.create(null);
+  }
+  if (opts.ignored) opts.ignored = arrify(opts.ignored);
+
+  this._isntIgnored = function(path, stat) {
+    return !this._isIgnored(path, stat);
+  }.bind(this);
+
+  var readyCalls = 0;
+  this._emitReady = function() {
+    if (++readyCalls >= this._readyCount) {
+      this._emitReady = Function.prototype;
+      this._readyEmitted = true;
+      // use process.nextTick to allow time for listener to be bound
+      process.nextTick(this.emit.bind(this, 'ready'));
+    }
+  }.bind(this);
+
+  this.options = opts;
+
+  // You’re frozen when your heart’s not open.
+  Object.freeze(opts);
+}
+
+inherits(FSWatcher, EventEmitter);
+
+// Common helpers
+// --------------
+
+// Private method: Normalize and emit events
+//
+// * event     - string, type of event
+// * path      - string, file or directory path
+// * val[1..3] - arguments to be passed with event
+//
+// Returns the error if defined, otherwise the value of the
+// FSWatcher instance's `closed` flag
+FSWatcher.prototype._emit = function(event, path, val1, val2, val3) {
+  if (this.options.cwd) path = sysPath.relative(this.options.cwd, path);
+  var args = [event, path];
+  if (val3 !== undefined) args.push(val1, val2, val3);
+  else if (val2 !== undefined) args.push(val1, val2);
+  else if (val1 !== undefined) args.push(val1);
+
+  var awf = this.options.awaitWriteFinish;
+  if (awf && this._pendingWrites[path]) {
+    this._pendingWrites[path].lastChange = new Date();
+    return this;
+  }
+
+  if (this.options.atomic) {
+    if (event === 'unlink') {
+      this._pendingUnlinks[path] = args;
+      setTimeout(function() {
+        Object.keys(this._pendingUnlinks).forEach(function(path) {
+          this.emit.apply(this, this._pendingUnlinks[path]);
+          this.emit.apply(this, ['all'].concat(this._pendingUnlinks[path]));
+          delete this._pendingUnlinks[path];
+        }.bind(this));
+      }.bind(this), typeof this.options.atomic === "number"
+        ? this.options.atomic
+        : 100);
+      return this;
+    } else if (event === 'add' && this._pendingUnlinks[path]) {
+      event = args[0] = 'change';
+      delete this._pendingUnlinks[path];
+    }
+  }
+
+  var emitEvent = function() {
+    this.emit.apply(this, args);
+    if (event !== 'error') this.emit.apply(this, ['all'].concat(args));
+  }.bind(this);
+
+  if (awf && (event === 'add' || event === 'change') && this._readyEmitted) {
+    var awfEmit = function(err, stats) {
+      if (err) {
+        event = args[0] = 'error';
+        args[1] = err;
+        emitEvent();
+      } else if (stats) {
+        // if stats doesn't exist the file must have been deleted
+        if (args.length > 2) {
+          args[2] = stats;
+        } else {
+          args.push(stats);
+        }
+        emitEvent();
+      }
+    };
+
+    this._awaitWriteFinish(path, awf.stabilityThreshold, event, awfEmit);
+    return this;
+  }
+
+  if (event === 'change') {
+    if (!this._throttle('change', path, 50)) return this;
+  }
+
+  if (
+    this.options.alwaysStat && val1 === undefined &&
+    (event === 'add' || event === 'addDir' || event === 'change')
+  ) {
+    var fullPath = this.options.cwd ? sysPath.join(this.options.cwd, path) : 
path;
+    fs.stat(fullPath, function(error, stats) {
+      // Suppress event when fs.stat fails, to avoid sending undefined 'stat'
+      if (error || !stats) return;
+
+      args.push(stats);
+      emitEvent();
+    });
+  } else {
+    emitEvent();
+  }
+
+  return this;
+};
+
+// Private method: Common handler for errors
+//
+// * error  - object, Error instance
+//
+// Returns the error if defined, otherwise the value of the
+// FSWatcher instance's `closed` flag
+FSWatcher.prototype._handleError = function(error) {
+  var code = error && error.code;
+  var ipe = this.options.ignorePermissionErrors;
+  if (error &&
+    code !== 'ENOENT' &&
+    code !== 'ENOTDIR' &&
+    (!ipe || (code !== 'EPERM' && code !== 'EACCES'))
+  ) this.emit('error', error);
+  return error || this.closed;
+};
+
+// Private method: Helper utility for throttling
+//
+// * action  - string, type of action being throttled
+// * path    - string, path being acted upon
+// * timeout - int, duration of time to suppress duplicate actions
+//
+// Returns throttle tracking object or false if action should be suppressed
+FSWatcher.prototype._throttle = function(action, path, timeout) {
+  if (!(action in this._throttled)) {
+    this._throttled[action] = Object.create(null);
+  }
+  var throttled = this._throttled[action];
+  if (path in throttled) return false;
+  function clear() {
+    delete throttled[path];
+    clearTimeout(timeoutObject);
+  }
+  var timeoutObject = setTimeout(clear, timeout);
+  throttled[path] = {timeoutObject: timeoutObject, clear: clear};
+  return throttled[path];
+};
+
+// Private method: Awaits write operation to finish
+//
+// * path    - string, path being acted upon
+// * threshold - int, time in milliseconds a file size must be fixed before
+//                    acknowledgeing write operation is finished
+// * awfEmit - function, to be called when ready for event to be emitted
+// Polls a newly created file for size variations. When files size does not
+// change for 'threshold' milliseconds calls callback.
+FSWatcher.prototype._awaitWriteFinish = function(path, threshold, event, 
awfEmit) {
+  var timeoutHandler;
+
+  var fullPath = path;
+  if (this.options.cwd && !isAbsolute(path)) {
+    fullPath = sysPath.join(this.options.cwd, path);
+  }
+
+  var now = new Date();
+
+  var awaitWriteFinish = (function (prevStat) {
+    fs.stat(fullPath, function(err, curStat) {
+      if (err) {
+        if (err.code !== 'ENOENT') awfEmit(err);
+        return;
+      }
+
+      var now = new Date();
+
+      if (prevStat && curStat.size != prevStat.size) {
+        this._pendingWrites[path].lastChange = now;
+      }
+
+      if (now - this._pendingWrites[path].lastChange >= threshold) {
+        delete this._pendingWrites[path];
+        awfEmit(null, curStat);
+      } else {
+        timeoutHandler = setTimeout(
+          awaitWriteFinish.bind(this, curStat),
+          this.options.awaitWriteFinish.pollInterval
+        );
+      }
+    }.bind(this));
+  }.bind(this));
+
+  if (!(path in this._pendingWrites)) {
+    this._pendingWrites[path] = {
+      lastChange: now,
+      cancelWait: function() {
+        delete this._pendingWrites[path];
+        clearTimeout(timeoutHandler);
+        return event;
+      }.bind(this)
+    };
+    timeoutHandler = setTimeout(
+      awaitWriteFinish.bind(this),
+      this.options.awaitWriteFinish.pollInterval
+    );
+  }
+};
+
+// Private method: Determines whether user has asked to ignore this path
+//
+// * path  - string, path to file or directory
+// * stats - object, result of fs.stat
+//
+// Returns boolean
+var dotRe = /\..*\.(sw[px])$|\~$|\.subl.*\.tmp/;
+FSWatcher.prototype._isIgnored = function(path, stats) {
+  if (this.options.atomic && dotRe.test(path)) return true;
+
+  if (!this._userIgnored) {
+    var cwd = this.options.cwd;
+    var ignored = this.options.ignored;
+    if (cwd && ignored) {
+      ignored = ignored.map(function (path) {
+        if (typeof path !== 'string') return path;
+        return isAbsolute(path) ? path : sysPath.join(cwd, path);
+      });
+    }
+    var paths = arrify(ignored)
+      .filter(function(path) {
+        return typeof path === 'string' && !isGlob(path);
+      }).map(function(path) {
+        return path + '/**';
+      });
+    this._userIgnored = anymatch(
+      this._globIgnored.concat(ignored).concat(paths)
+    );
+  }
+
+  return this._userIgnored([path, stats]);
+};
+
+// Private method: Provides a set of common helpers and properties relating to
+// symlink and glob handling
+//
+// * path - string, file, directory, or glob pattern being watched
+// * depth - int, at any depth > 0, this isn't a glob
+//
+// Returns object containing helpers for this path
+var replacerRe = /^\.[\/\\]/;
+FSWatcher.prototype._getWatchHelpers = function(path, depth) {
+  path = path.replace(replacerRe, '');
+  var watchPath = depth || !isGlob(path) ? path : globParent(path);
+  var fullWatchPath = sysPath.resolve(watchPath);
+  var hasGlob = watchPath !== path;
+  var globFilter = hasGlob ? anymatch(path) : false;
+  var follow = this.options.followSymlinks;
+  var globSymlink = hasGlob && follow ? null : false;
+
+  var checkGlobSymlink = function(entry) {
+    // only need to resolve once
+    // first entry should always have entry.parentDir === ''
+    if (globSymlink == null) {
+      globSymlink = entry.fullParentDir === fullWatchPath ? false : {
+        realPath: entry.fullParentDir,
+        linkPath: fullWatchPath
+      };
+    }
+
+    if (globSymlink) {
+      return entry.fullPath.replace(globSymlink.realPath, 
globSymlink.linkPath);
+    }
+
+    return entry.fullPath;
+  };
+
+  var entryPath = function(entry) {
+    return sysPath.join(watchPath,
+      sysPath.relative(watchPath, checkGlobSymlink(entry))
+    );
+  };
+
+  var filterPath = function(entry) {
+    if (entry.stat && entry.stat.isSymbolicLink()) return filterDir(entry);
+    var resolvedPath = entryPath(entry);
+    return (!hasGlob || globFilter(resolvedPath)) &&
+      this._isntIgnored(resolvedPath, entry.stat) &&
+      (this.options.ignorePermissionErrors ||
+        this._hasReadPermissions(entry.stat));
+  }.bind(this);
+
+  var getDirParts = function(path) {
+    if (!hasGlob) return false;
+    var parts = sysPath.relative(watchPath, path).split(/[\/\\]/);
+    return parts;
+  };
+
+  var dirParts = getDirParts(path);
+  if (dirParts && dirParts.length > 1) dirParts.pop();
+  var unmatchedGlob;
+
+  var filterDir = function(entry) {
+    if (hasGlob) {
+      var entryParts = getDirParts(checkGlobSymlink(entry));
+      var globstar = false;
+      unmatchedGlob = !dirParts.every(function(part, i) {
+        if (part === '**') globstar = true;
+        return globstar || !entryParts[i] || anymatch(part, entryParts[i]);
+      });
+    }
+    return !unmatchedGlob && this._isntIgnored(entryPath(entry), entry.stat);
+  }.bind(this);
+
+  return {
+    followSymlinks: follow,
+    statMethod: follow ? 'stat' : 'lstat',
+    path: path,
+    watchPath: watchPath,
+    entryPath: entryPath,
+    hasGlob: hasGlob,
+    globFilter: globFilter,
+    filterPath: filterPath,
+    filterDir: filterDir
+  };
+};
+
+// Directory helpers
+// -----------------
+
+// Private method: Provides directory tracking objects
+//
+// * directory - string, path of the directory
+//
+// Returns the directory's tracking object
+FSWatcher.prototype._getWatchedDir = function(directory) {
+  var dir = sysPath.resolve(directory);
+  var watcherRemove = this._remove.bind(this);
+  if (!(dir in this._watched)) this._watched[dir] = {
+    _items: Object.create(null),
+    add: function(item) {
+      if (item !== '.') this._items[item] = true;
+    },
+    remove: function(item) {
+      delete this._items[item];
+      if (!this.children().length) {
+        fs.readdir(dir, function(err) {
+          if (err) watcherRemove(sysPath.dirname(dir), sysPath.basename(dir));
+        });
+      }
+    },
+    has: function(item) {return item in this._items;},
+    children: function() {return Object.keys(this._items);}
+  };
+  return this._watched[dir];
+};
+
+// File helpers
+// ------------
+
+// Private method: Check for read permissions
+// Based on this answer on SO: http://stackoverflow.com/a/11781404/1358405
+//
+// * stats - object, result of fs.stat
+//
+// Returns boolean
+FSWatcher.prototype._hasReadPermissions = function(stats) {
+  return Boolean(4 & parseInt(((stats && stats.mode) & 0x1ff).toString(8)[0], 
10));
+};
+
+// Private method: Handles emitting unlink events for
+// files and directories, and via recursion, for
+// files and directories within directories that are unlinked
+//
+// * directory - string, directory within which the following item is located
+// * item      - string, base path of item/directory
+//
+// Returns nothing
+FSWatcher.prototype._remove = function(directory, item) {
+  // if what is being deleted is a directory, get that directory's paths
+  // for recursive deleting and cleaning of watched object
+  // if it is not a directory, nestedDirectoryChildren will be empty array
+  var path = sysPath.join(directory, item);
+  var fullPath = sysPath.resolve(path);
+  var isDirectory = this._watched[path] || this._watched[fullPath];
+
+  // prevent duplicate handling in case of arriving here nearly simultaneously
+  // via multiple paths (such as _handleFile and _handleDir)
+  if (!this._throttle('remove', path, 100)) return;
+
+  // if the only watched file is removed, watch for its return
+  var watchedDirs = Object.keys(this._watched);
+  if (!isDirectory && !this.options.useFsEvents && watchedDirs.length === 1) {
+    this.add(directory, item, true);
+  }
+
+  // This will create a new entry in the watched object in either case
+  // so we got to do the directory check beforehand
+  var nestedDirectoryChildren = this._getWatchedDir(path).children();
+
+  // Recursively remove children directories / files.
+  nestedDirectoryChildren.forEach(function(nestedItem) {
+    this._remove(path, nestedItem);
+  }, this);
+
+  // Check if item was on the watched list and remove it
+  var parent = this._getWatchedDir(directory);
+  var wasTracked = parent.has(item);
+  parent.remove(item);
+
+  // If we wait for this file to be fully written, cancel the wait.
+  var relPath = path;
+  if (this.options.cwd) relPath = sysPath.relative(this.options.cwd, path);
+  if (this.options.awaitWriteFinish && this._pendingWrites[relPath]) {
+    var event = this._pendingWrites[relPath].cancelWait();
+    if (event === 'add') return;
+  }
+
+  // The Entry will either be a directory that just got removed
+  // or a bogus entry to a file, in either case we have to remove it
+  delete this._watched[path];
+  delete this._watched[fullPath];
+  var eventName = isDirectory ? 'unlinkDir' : 'unlink';
+  if (wasTracked && !this._isIgnored(path)) this._emit(eventName, path);
+
+  // Avoid conflicts if we later create another file with the same name
+  if (!this.options.useFsEvents) {
+    this._closePath(path);
+  }
+};
+
+FSWatcher.prototype._closePath = function(path) {
+  if (!this._closers[path]) return;
+  this._closers[path]();
+  delete this._closers[path];
+  this._getWatchedDir(sysPath.dirname(path)).remove(sysPath.basename(path));
+}
+
+// Public method: Adds paths to be watched on an existing FSWatcher instance
+
+// * paths     - string or array of strings, file/directory paths and/or globs
+// * _origAdd  - private boolean, for handling non-existent paths to be watched
+// * _internal - private boolean, indicates a non-user add
+
+// Returns an instance of FSWatcher for chaining.
+FSWatcher.prototype.add = function(paths, _origAdd, _internal) {
+  var cwd = this.options.cwd;
+  this.closed = false;
+  paths = flatten(arrify(paths));
+
+  if (!paths.every(isString)) {
+    throw new TypeError('Non-string provided as watch path: ' + paths);
+  }
+
+  if (cwd) paths = paths.map(function(path) {
+    if (isAbsolute(path)) {
+      return path;
+    } else if (path[0] === '!') {
+      return '!' + sysPath.join(cwd, path.substring(1));
+    } else {
+      return sysPath.join(cwd, path);
+    }
+  });
+
+  // set aside negated glob strings
+  paths = paths.filter(function(path) {
+    if (path[0] === '!') {
+      this._ignoredPaths[path.substring(1)] = true;
+    } else {
+      // if a path is being added that was previously ignored, stop ignoring it
+      delete this._ignoredPaths[path];
+      delete this._ignoredPaths[path + '/**'];
+
+      // reset the cached userIgnored anymatch fn
+      // to make ignoredPaths changes effective
+      this._userIgnored = null;
+
+      return true;
+    }
+  }, this);
+
+  if (this.options.useFsEvents && FsEventsHandler.canUse()) {
+    if (!this._readyCount) this._readyCount = paths.length;
+    if (this.options.persistent) this._readyCount *= 2;
+    paths.forEach(this._addToFsEvents, this);
+  } else {
+    if (!this._readyCount) this._readyCount = 0;
+    this._readyCount += paths.length;
+    asyncEach(paths, function(path, next) {
+      this._addToNodeFs(path, !_internal, 0, 0, _origAdd, function(err, res) {
+        if (res) this._emitReady();
+        next(err, res);
+      }.bind(this));
+    }.bind(this), function(error, results) {
+      results.forEach(function(item) {
+        if (!item) return;
+        this.add(sysPath.dirname(item), sysPath.basename(_origAdd || item));
+      }, this);
+    }.bind(this));
+  }
+
+  return this;
+};
+
+// Public method: Close watchers or start ignoring events from specified paths.
+
+// * paths     - string or array of strings, file/directory paths and/or globs
+
+// Returns instance of FSWatcher for chaining.
+FSWatcher.prototype.unwatch = function(paths) {
+  if (this.closed) return this;
+  paths = flatten(arrify(paths));
+
+  paths.forEach(function(path) {
+    // convert to absolute path unless relative path already matches
+    if (!isAbsolute(path) && !this._closers[path]) {
+      if (this.options.cwd) path = sysPath.join(this.options.cwd, path);
+      path = sysPath.resolve(path);
+    }
+
+    this._closePath(path);
+
+    this._ignoredPaths[path] = true;
+    if (path in this._watched) {
+      this._ignoredPaths[path + '/**'] = true;
+    }
+
+    // reset the cached userIgnored anymatch fn
+    // to make ignoredPaths changes effective
+    this._userIgnored = null;
+  }, this);
+
+  return this;
+};
+
+// Public method: Close watchers and remove all listeners from watched paths.
+
+// Returns instance of FSWatcher for chaining.
+FSWatcher.prototype.close = function() {
+  if (this.closed) return this;
+
+  this.closed = true;
+  Object.keys(this._closers).forEach(function(watchPath) {
+    this._closers[watchPath]();
+    delete this._closers[watchPath];
+  }, this);
+  this._watched = Object.create(null);
+
+  this.removeAllListeners();
+  return this;
+};
+
+// Public method: Expose list of watched paths
+
+// Returns object w/ dir paths as keys and arrays of contained paths as values.
+FSWatcher.prototype.getWatched = function() {
+  var watchList = {};
+  Object.keys(this._watched).forEach(function(dir) {
+    var key = this.options.cwd ? sysPath.relative(this.options.cwd, dir) : dir;
+    watchList[key || '.'] = Object.keys(this._watched[dir]._items).sort();
+  }.bind(this));
+  return watchList;
+};
+
+// Attach watch handler prototype methods
+function importHandler(handler) {
+  Object.keys(handler.prototype).forEach(function(method) {
+    FSWatcher.prototype[method] = handler.prototype[method];
+  });
+}
+importHandler(NodeFsHandler);
+if (FsEventsHandler.canUse()) importHandler(FsEventsHandler);
+
+// Export FSWatcher class
+exports.FSWatcher = FSWatcher;
+
+// Public function: Instantiates watcher with paths to be tracked.
+
+// * paths     - string or array of strings, file/directory paths and/or globs
+// * options   - object, chokidar options
+
+// Returns an instance of FSWatcher for chaining.
+exports.watch = function(paths, options) {
+  return new FSWatcher(options).add(paths);
+};

http://git-wip-us.apache.org/repos/asf/incubator-griffin-site/blob/4f8fa326/node_modules/chokidar/lib/fsevents-handler.js
----------------------------------------------------------------------
diff --git a/node_modules/chokidar/lib/fsevents-handler.js 
b/node_modules/chokidar/lib/fsevents-handler.js
new file mode 100644
index 0000000..dbf6ade
--- /dev/null
+++ b/node_modules/chokidar/lib/fsevents-handler.js
@@ -0,0 +1,396 @@
+'use strict';
+
+var fs = require('fs');
+var sysPath = require('path');
+var readdirp = require('readdirp');
+var fsevents;
+try { fsevents = require('fsevents'); } catch (error) {}
+
+// fsevents instance helper functions
+
+// object to hold per-process fsevents instances
+// (may be shared across chokidar FSWatcher instances)
+var FSEventsWatchers = Object.create(null);
+
+// Threshold of duplicate path prefixes at which to start
+// consolidating going forward
+var consolidateThreshhold = 10;
+
+// Private function: Instantiates the fsevents interface
+
+// * path       - string, path to be watched
+// * callback   - function, called when fsevents is bound and ready
+
+// Returns new fsevents instance
+function createFSEventsInstance(path, callback) {
+  return (new fsevents(path)).on('fsevent', callback).start();
+}
+
+// Private function: Instantiates the fsevents interface or binds listeners
+// to an existing one covering the same file tree
+
+// * path       - string, path to be watched
+// * realPath   - string, real path (in case of symlinks)
+// * listener   - function, called when fsevents emits events
+// * rawEmitter - function, passes data to listeners of the 'raw' event
+
+// Returns close function
+function setFSEventsListener(path, realPath, listener, rawEmitter) {
+  var watchPath = sysPath.extname(path) ? sysPath.dirname(path) : path;
+  var watchContainer;
+  var parentPath = sysPath.dirname(watchPath);
+
+  // If we've accumulated a substantial number of paths that
+  // could have been consolidated by watching one directory
+  // above the current one, create a watcher on the parent
+  // path instead, so that we do consolidate going forward.
+  if (couldConsolidate(parentPath)) {
+    watchPath = parentPath;
+  }
+
+  var resolvedPath = sysPath.resolve(path);
+  var hasSymlink = resolvedPath !== realPath;
+  function filteredListener(fullPath, flags, info) {
+    if (hasSymlink) fullPath = fullPath.replace(realPath, resolvedPath);
+    if (
+      fullPath === resolvedPath ||
+      !fullPath.indexOf(resolvedPath + sysPath.sep)
+    ) listener(fullPath, flags, info);
+  }
+
+  // check if there is already a watcher on a parent path
+  // modifies `watchPath` to the parent path when it finds a match
+  function watchedParent() {
+    return Object.keys(FSEventsWatchers).some(function(watchedPath) {
+      // condition is met when indexOf returns 0
+      if (!realPath.indexOf(sysPath.resolve(watchedPath) + sysPath.sep)) {
+        watchPath = watchedPath;
+        return true;
+      }
+    });
+  }
+
+  if (watchPath in FSEventsWatchers || watchedParent()) {
+    watchContainer = FSEventsWatchers[watchPath];
+    watchContainer.listeners.push(filteredListener);
+  } else {
+    watchContainer = FSEventsWatchers[watchPath] = {
+      listeners: [filteredListener],
+      rawEmitters: [rawEmitter],
+      watcher: createFSEventsInstance(watchPath, function(fullPath, flags) {
+        var info = fsevents.getInfo(fullPath, flags);
+        watchContainer.listeners.forEach(function(listener) {
+          listener(fullPath, flags, info);
+        });
+        watchContainer.rawEmitters.forEach(function(emitter) {
+          emitter(info.event, fullPath, info);
+        });
+      })
+    };
+  }
+  var listenerIndex = watchContainer.listeners.length - 1;
+
+  // removes this instance's listeners and closes the underlying fsevents
+  // instance if there are no more listeners left
+  return function close() {
+    delete watchContainer.listeners[listenerIndex];
+    delete watchContainer.rawEmitters[listenerIndex];
+    if (!Object.keys(watchContainer.listeners).length) {
+      watchContainer.watcher.stop();
+      delete FSEventsWatchers[watchPath];
+    }
+  };
+}
+
+// Decide whether or not we should start a new higher-level
+// parent watcher
+function couldConsolidate(path) {
+  var keys = Object.keys(FSEventsWatchers);
+  var count = 0;
+
+  for (var i = 0, len = keys.length; i < len; ++i) {
+    var watchPath = keys[i];
+    if (watchPath.indexOf(path) === 0) {
+      count++;
+      if (count >= consolidateThreshhold) {
+        return true;
+      }
+    }
+  }
+
+  return false;
+}
+
+// returns boolean indicating whether fsevents can be used
+function canUse() {
+  return fsevents && Object.keys(FSEventsWatchers).length < 128;
+}
+
+// determines subdirectory traversal levels from root to path
+function depth(path, root) {
+  var i = 0;
+  while (!path.indexOf(root) && (path = sysPath.dirname(path)) !== root) i++;
+  return i;
+}
+
+// fake constructor for attaching fsevents-specific prototype methods that
+// will be copied to FSWatcher's prototype
+function FsEventsHandler() {}
+
+// Private method: Handle symlinks encountered during directory scan
+
+// * watchPath  - string, file/dir path to be watched with fsevents
+// * realPath   - string, real path (in case of symlinks)
+// * transform  - function, path transformer
+// * globFilter - function, path filter in case a glob pattern was provided
+
+// Returns close function for the watcher instance
+FsEventsHandler.prototype._watchWithFsEvents =
+function(watchPath, realPath, transform, globFilter) {
+  if (this._isIgnored(watchPath)) return;
+  var watchCallback = function(fullPath, flags, info) {
+    if (
+      this.options.depth !== undefined &&
+      depth(fullPath, realPath) > this.options.depth
+    ) return;
+    var path = transform(sysPath.join(
+      watchPath, sysPath.relative(watchPath, fullPath)
+    ));
+    if (globFilter && !globFilter(path)) return;
+    // ensure directories are tracked
+    var parent = sysPath.dirname(path);
+    var item = sysPath.basename(path);
+    var watchedDir = this._getWatchedDir(
+      info.type === 'directory' ? path : parent
+    );
+    var checkIgnored = function(stats) {
+      if (this._isIgnored(path, stats)) {
+        this._ignoredPaths[path] = true;
+        if (stats && stats.isDirectory()) {
+          this._ignoredPaths[path + '/**/*'] = true;
+        }
+        return true;
+      } else {
+        delete this._ignoredPaths[path];
+        delete this._ignoredPaths[path + '/**/*'];
+      }
+    }.bind(this);
+
+    var handleEvent = function(event) {
+      if (checkIgnored()) return;
+
+      if (event === 'unlink') {
+        // suppress unlink events on never before seen files
+        if (info.type === 'directory' || watchedDir.has(item)) {
+          this._remove(parent, item);
+        }
+      } else {
+        if (event === 'add') {
+          // track new directories
+          if (info.type === 'directory') this._getWatchedDir(path);
+
+          if (info.type === 'symlink' && this.options.followSymlinks) {
+            // push symlinks back to the top of the stack to get handled
+            var curDepth = this.options.depth === undefined ?
+              undefined : depth(fullPath, realPath) + 1;
+            return this._addToFsEvents(path, false, true, curDepth);
+          } else {
+            // track new paths
+            // (other than symlinks being followed, which will be tracked soon)
+            this._getWatchedDir(parent).add(item);
+          }
+        }
+        var eventName = info.type === 'directory' ? event + 'Dir' : event;
+        this._emit(eventName, path);
+        if (eventName === 'addDir') this._addToFsEvents(path, false, true);
+      }
+    }.bind(this);
+
+    function addOrChange() {
+      handleEvent(watchedDir.has(item) ? 'change' : 'add');
+    }
+    function checkFd() {
+      fs.open(path, 'r', function(error, fd) {
+        if (fd) fs.close(fd);
+        error && error.code !== 'EACCES' ?
+          handleEvent('unlink') : addOrChange();
+      });
+    }
+    // correct for wrong events emitted
+    var wrongEventFlags = [
+      69888, 70400, 71424, 72704, 73472, 131328, 131840, 262912
+    ];
+    if (wrongEventFlags.indexOf(flags) !== -1 || info.event === 'unknown') {
+      if (typeof this.options.ignored === 'function') {
+        fs.stat(path, function(error, stats) {
+          if (checkIgnored(stats)) return;
+          stats ? addOrChange() : handleEvent('unlink');
+        });
+      } else {
+        checkFd();
+      }
+    } else {
+      switch (info.event) {
+      case 'created':
+      case 'modified':
+        return addOrChange();
+      case 'deleted':
+      case 'moved':
+        return checkFd();
+      }
+    }
+  }.bind(this);
+
+  var closer = setFSEventsListener(
+    watchPath,
+    realPath,
+    watchCallback,
+    this.emit.bind(this, 'raw')
+  );
+
+  this._emitReady();
+  return closer;
+};
+
+// Private method: Handle symlinks encountered during directory scan
+
+// * linkPath   - string, path to symlink
+// * fullPath   - string, absolute path to the symlink
+// * transform  - function, pre-existing path transformer
+// * curDepth   - int, level of subdirectories traversed to where symlink is
+
+// Returns nothing
+FsEventsHandler.prototype._handleFsEventsSymlink =
+function(linkPath, fullPath, transform, curDepth) {
+  // don't follow the same symlink more than once
+  if (this._symlinkPaths[fullPath]) return;
+  else this._symlinkPaths[fullPath] = true;
+
+  this._readyCount++;
+
+  fs.realpath(linkPath, function(error, linkTarget) {
+    if (this._handleError(error) || this._isIgnored(linkTarget)) {
+      return this._emitReady();
+    }
+
+    this._readyCount++;
+
+    // add the linkTarget for watching with a wrapper for transform
+    // that causes emitted paths to incorporate the link's path
+    this._addToFsEvents(linkTarget || linkPath, function(path) {
+      var dotSlash = '.' + sysPath.sep;
+      var aliasedPath = linkPath;
+      if (linkTarget && linkTarget !== dotSlash) {
+        aliasedPath = path.replace(linkTarget, linkPath);
+      } else if (path !== dotSlash) {
+        aliasedPath = sysPath.join(linkPath, path);
+      }
+      return transform(aliasedPath);
+    }, false, curDepth);
+  }.bind(this));
+};
+
+// Private method: Handle added path with fsevents
+
+// * path       - string, file/directory path or glob pattern
+// * transform  - function, converts working path to what the user expects
+// * forceAdd   - boolean, ensure add is emitted
+// * priorDepth - int, level of subdirectories already traversed
+
+// Returns nothing
+FsEventsHandler.prototype._addToFsEvents =
+function(path, transform, forceAdd, priorDepth) {
+
+  // applies transform if provided, otherwise returns same value
+  var processPath = typeof transform === 'function' ?
+    transform : function(val) { return val; };
+
+  var emitAdd = function(newPath, stats) {
+    var pp = processPath(newPath);
+    var isDir = stats.isDirectory();
+    var dirObj = this._getWatchedDir(sysPath.dirname(pp));
+    var base = sysPath.basename(pp);
+
+    // ensure empty dirs get tracked
+    if (isDir) this._getWatchedDir(pp);
+
+    if (dirObj.has(base)) return;
+    dirObj.add(base);
+
+    if (!this.options.ignoreInitial || forceAdd === true) {
+      this._emit(isDir ? 'addDir' : 'add', pp, stats);
+    }
+  }.bind(this);
+
+  var wh = this._getWatchHelpers(path);
+
+  // evaluate what is at the path we're being asked to watch
+  fs[wh.statMethod](wh.watchPath, function(error, stats) {
+    if (this._handleError(error) || this._isIgnored(wh.watchPath, stats)) {
+      this._emitReady();
+      return this._emitReady();
+    }
+
+    if (stats.isDirectory()) {
+      // emit addDir unless this is a glob parent
+      if (!wh.globFilter) emitAdd(processPath(path), stats);
+
+      // don't recurse further if it would exceed depth setting
+      if (priorDepth && priorDepth > this.options.depth) return;
+
+      // scan the contents of the dir
+      readdirp({
+        root: wh.watchPath,
+        entryType: 'all',
+        fileFilter: wh.filterPath,
+        directoryFilter: wh.filterDir,
+        lstat: true,
+        depth: this.options.depth - (priorDepth || 0)
+      }).on('data', function(entry) {
+        // need to check filterPath on dirs b/c filterDir is less restrictive
+        if (entry.stat.isDirectory() && !wh.filterPath(entry)) return;
+
+        var joinedPath = sysPath.join(wh.watchPath, entry.path);
+        var fullPath = entry.fullPath;
+
+        if (wh.followSymlinks && entry.stat.isSymbolicLink()) {
+          // preserve the current depth here since it can't be derived from
+          // real paths past the symlink
+          var curDepth = this.options.depth === undefined ?
+            undefined : depth(joinedPath, sysPath.resolve(wh.watchPath)) + 1;
+
+          this._handleFsEventsSymlink(joinedPath, fullPath, processPath, 
curDepth);
+        } else {
+          emitAdd(joinedPath, entry.stat);
+        }
+      }.bind(this)).on('error', function() {
+        // Ignore readdirp errors
+      }).on('end', this._emitReady);
+    } else {
+      emitAdd(wh.watchPath, stats);
+      this._emitReady();
+    }
+  }.bind(this));
+
+  if (this.options.persistent && forceAdd !== true) {
+    var initWatch = function(error, realPath) {
+      var closer = this._watchWithFsEvents(
+        wh.watchPath,
+        sysPath.resolve(realPath || wh.watchPath),
+        processPath,
+        wh.globFilter
+      );
+      if (closer) this._closers[path] = closer;
+    }.bind(this);
+
+    if (typeof transform === 'function') {
+      // realpath has already been resolved
+      initWatch();
+    } else {
+      fs.realpath(wh.watchPath, initWatch);
+    }
+  }
+};
+
+module.exports = FsEventsHandler;
+module.exports.canUse = canUse;

http://git-wip-us.apache.org/repos/asf/incubator-griffin-site/blob/4f8fa326/node_modules/chokidar/lib/nodefs-handler.js
----------------------------------------------------------------------
diff --git a/node_modules/chokidar/lib/nodefs-handler.js 
b/node_modules/chokidar/lib/nodefs-handler.js
new file mode 100644
index 0000000..9d05b6f
--- /dev/null
+++ b/node_modules/chokidar/lib/nodefs-handler.js
@@ -0,0 +1,481 @@
+'use strict';
+
+var fs = require('fs');
+var sysPath = require('path');
+var readdirp = require('readdirp');
+var isBinaryPath = require('is-binary-path');
+
+// fs.watch helpers
+
+// object to hold per-process fs.watch instances
+// (may be shared across chokidar FSWatcher instances)
+var FsWatchInstances = Object.create(null);
+
+// Private function: Instantiates the fs.watch interface
+
+// * path       - string, path to be watched
+// * options    - object, options to be passed to fs.watch
+// * listener   - function, main event handler
+// * errHandler - function, handler which emits info about errors
+// * emitRaw    - function, handler which emits raw event data
+
+// Returns new fsevents instance
+function createFsWatchInstance(path, options, listener, errHandler, emitRaw) {
+  var handleEvent = function(rawEvent, evPath) {
+    listener(path);
+    emitRaw(rawEvent, evPath, {watchedPath: path});
+
+    // emit based on events occuring for files from a directory's watcher in
+    // case the file's watcher misses it (and rely on throttling to de-dupe)
+    if (evPath && path !== evPath) {
+      fsWatchBroadcast(
+        sysPath.resolve(path, evPath), 'listeners', sysPath.join(path, evPath)
+      );
+    }
+  };
+  try {
+    return fs.watch(path, options, handleEvent);
+  } catch (error) {
+    errHandler(error);
+  }
+}
+
+// Private function: Helper for passing fs.watch event data to a
+// collection of listeners
+
+// * fullPath   - string, absolute path bound to the fs.watch instance
+// * type       - string, listener type
+// * val[1..3]  - arguments to be passed to listeners
+
+// Returns nothing
+function fsWatchBroadcast(fullPath, type, val1, val2, val3) {
+  if (!FsWatchInstances[fullPath]) return;
+  FsWatchInstances[fullPath][type].forEach(function(listener) {
+    listener(val1, val2, val3);
+  });
+}
+
+// Private function: Instantiates the fs.watch interface or binds listeners
+// to an existing one covering the same file system entry
+
+// * path       - string, path to be watched
+// * fullPath   - string, absolute path
+// * options    - object, options to be passed to fs.watch
+// * handlers   - object, container for event listener functions
+
+// Returns close function
+function setFsWatchListener(path, fullPath, options, handlers) {
+  var listener = handlers.listener;
+  var errHandler = handlers.errHandler;
+  var rawEmitter = handlers.rawEmitter;
+  var container = FsWatchInstances[fullPath];
+  var watcher;
+  if (!options.persistent) {
+    watcher = createFsWatchInstance(
+      path, options, listener, errHandler, rawEmitter
+    );
+    return watcher.close.bind(watcher);
+  }
+  if (!container) {
+    watcher = createFsWatchInstance(
+      path,
+      options,
+      fsWatchBroadcast.bind(null, fullPath, 'listeners'),
+      errHandler, // no need to use broadcast here
+      fsWatchBroadcast.bind(null, fullPath, 'rawEmitters')
+    );
+    if (!watcher) return;
+    var broadcastErr = fsWatchBroadcast.bind(null, fullPath, 'errHandlers');
+    watcher.on('error', function(error) {
+      // Workaround for https://github.com/joyent/node/issues/4337
+      if (process.platform === 'win32' && error.code === 'EPERM') {
+        fs.open(path, 'r', function(err, fd) {
+          if (fd) fs.close(fd);
+          if (!err) broadcastErr(error);
+        });
+      } else {
+        broadcastErr(error);
+      }
+    });
+    container = FsWatchInstances[fullPath] = {
+      listeners: [listener],
+      errHandlers: [errHandler],
+      rawEmitters: [rawEmitter],
+      watcher: watcher
+    };
+  } else {
+    container.listeners.push(listener);
+    container.errHandlers.push(errHandler);
+    container.rawEmitters.push(rawEmitter);
+  }
+  var listenerIndex = container.listeners.length - 1;
+
+  // removes this instance's listeners and closes the underlying fs.watch
+  // instance if there are no more listeners left
+  return function close() {
+    delete container.listeners[listenerIndex];
+    delete container.errHandlers[listenerIndex];
+    delete container.rawEmitters[listenerIndex];
+    if (!Object.keys(container.listeners).length) {
+      container.watcher.close();
+      delete FsWatchInstances[fullPath];
+    }
+  };
+}
+
+// fs.watchFile helpers
+
+// object to hold per-process fs.watchFile instances
+// (may be shared across chokidar FSWatcher instances)
+var FsWatchFileInstances = Object.create(null);
+
+// Private function: Instantiates the fs.watchFile interface or binds listeners
+// to an existing one covering the same file system entry
+
+// * path       - string, path to be watched
+// * fullPath   - string, absolute path
+// * options    - object, options to be passed to fs.watchFile
+// * handlers   - object, container for event listener functions
+
+// Returns close function
+function setFsWatchFileListener(path, fullPath, options, handlers) {
+  var listener = handlers.listener;
+  var rawEmitter = handlers.rawEmitter;
+  var container = FsWatchFileInstances[fullPath];
+  var listeners = [];
+  var rawEmitters = [];
+  if (
+    container && (
+      container.options.persistent < options.persistent ||
+      container.options.interval > options.interval
+    )
+  ) {
+    // "Upgrade" the watcher to persistence or a quicker interval.
+    // This creates some unlikely edge case issues if the user mixes
+    // settings in a very weird way, but solving for those cases
+    // doesn't seem worthwhile for the added complexity.
+    listeners = container.listeners;
+    rawEmitters = container.rawEmitters;
+    fs.unwatchFile(fullPath);
+    container = false;
+  }
+  if (!container) {
+    listeners.push(listener);
+    rawEmitters.push(rawEmitter);
+    container = FsWatchFileInstances[fullPath] = {
+      listeners: listeners,
+      rawEmitters: rawEmitters,
+      options: options,
+      watcher: fs.watchFile(fullPath, options, function(curr, prev) {
+        container.rawEmitters.forEach(function(rawEmitter) {
+          rawEmitter('change', fullPath, {curr: curr, prev: prev});
+        });
+        var currmtime = curr.mtime.getTime();
+        if (curr.size !== prev.size || currmtime > prev.mtime.getTime() || 
currmtime === 0) {
+          container.listeners.forEach(function(listener) {
+            listener(path, curr);
+          });
+        }
+      })
+    };
+  } else {
+    container.listeners.push(listener);
+    container.rawEmitters.push(rawEmitter);
+  }
+  var listenerIndex = container.listeners.length - 1;
+
+  // removes this instance's listeners and closes the underlying fs.watchFile
+  // instance if there are no more listeners left
+  return function close() {
+    delete container.listeners[listenerIndex];
+    delete container.rawEmitters[listenerIndex];
+    if (!Object.keys(container.listeners).length) {
+      fs.unwatchFile(fullPath);
+      delete FsWatchFileInstances[fullPath];
+    }
+  };
+}
+
+// fake constructor for attaching nodefs-specific prototype methods that
+// will be copied to FSWatcher's prototype
+function NodeFsHandler() {}
+
+// Private method: Watch file for changes with fs.watchFile or fs.watch.
+
+// * path     - string, path to file or directory.
+// * listener - function, to be executed on fs change.
+
+// Returns close function for the watcher instance
+NodeFsHandler.prototype._watchWithNodeFs =
+function(path, listener) {
+  var directory = sysPath.dirname(path);
+  var basename = sysPath.basename(path);
+  var parent = this._getWatchedDir(directory);
+  parent.add(basename);
+  var absolutePath = sysPath.resolve(path);
+  var options = {persistent: this.options.persistent};
+  if (!listener) listener = Function.prototype; // empty function
+
+  var closer;
+  if (this.options.usePolling) {
+    options.interval = this.enableBinaryInterval && isBinaryPath(basename) ?
+      this.options.binaryInterval : this.options.interval;
+    closer = setFsWatchFileListener(path, absolutePath, options, {
+      listener: listener,
+      rawEmitter: this.emit.bind(this, 'raw')
+    });
+  } else {
+    closer = setFsWatchListener(path, absolutePath, options, {
+      listener: listener,
+      errHandler: this._handleError.bind(this),
+      rawEmitter: this.emit.bind(this, 'raw')
+    });
+  }
+  return closer;
+};
+
+// Private method: Watch a file and emit add event if warranted
+
+// * file       - string, the file's path
+// * stats      - object, result of fs.stat
+// * initialAdd - boolean, was the file added at watch instantiation?
+// * callback   - function, called when done processing as a newly seen file
+
+// Returns close function for the watcher instance
+NodeFsHandler.prototype._handleFile =
+function(file, stats, initialAdd, callback) {
+  var dirname = sysPath.dirname(file);
+  var basename = sysPath.basename(file);
+  var parent = this._getWatchedDir(dirname);
+
+  // if the file is already being watched, do nothing
+  if (parent.has(basename)) return callback();
+
+  // kick off the watcher
+  var closer = this._watchWithNodeFs(file, function(path, newStats) {
+    if (!this._throttle('watch', file, 5)) return;
+    if (!newStats || newStats && newStats.mtime.getTime() === 0) {
+      fs.stat(file, function(error, newStats) {
+        // Fix issues where mtime is null but file is still present
+        if (error) {
+          this._remove(dirname, basename);
+        } else {
+          this._emit('change', file, newStats);
+        }
+      }.bind(this));
+    // add is about to be emitted if file not already tracked in parent
+    } else if (parent.has(basename)) {
+      this._emit('change', file, newStats);
+    }
+  }.bind(this));
+
+  // emit an add event if we're supposed to
+  if (!(initialAdd && this.options.ignoreInitial)) {
+    if (!this._throttle('add', file, 0)) return;
+    this._emit('add', file, stats);
+  }
+
+  if (callback) callback();
+  return closer;
+};
+
+// Private method: Handle symlinks encountered while reading a dir
+
+// * entry      - object, entry object returned by readdirp
+// * directory  - string, path of the directory being read
+// * path       - string, path of this item
+// * item       - string, basename of this item
+
+// Returns true if no more processing is needed for this entry.
+NodeFsHandler.prototype._handleSymlink =
+function(entry, directory, path, item) {
+  var full = entry.fullPath;
+  var dir = this._getWatchedDir(directory);
+
+  if (!this.options.followSymlinks) {
+    // watch symlink directly (don't follow) and detect changes
+    this._readyCount++;
+    fs.realpath(path, function(error, linkPath) {
+      if (dir.has(item)) {
+        if (this._symlinkPaths[full] !== linkPath) {
+          this._symlinkPaths[full] = linkPath;
+          this._emit('change', path, entry.stat);
+        }
+      } else {
+        dir.add(item);
+        this._symlinkPaths[full] = linkPath;
+        this._emit('add', path, entry.stat);
+      }
+      this._emitReady();
+    }.bind(this));
+    return true;
+  }
+
+  // don't follow the same symlink more than once
+  if (this._symlinkPaths[full]) return true;
+  else this._symlinkPaths[full] = true;
+};
+
+// Private method: Read directory to add / remove files from `@watched` list
+// and re-read it on change.
+
+// * dir        - string, fs path.
+// * stats      - object, result of fs.stat
+// * initialAdd - boolean, was the file added at watch instantiation?
+// * depth      - int, depth relative to user-supplied path
+// * target     - string, child path actually targeted for watch
+// * wh         - object, common watch helpers for this path
+// * callback   - function, called when dir scan is complete
+
+// Returns close function for the watcher instance
+NodeFsHandler.prototype._handleDir =
+function(dir, stats, initialAdd, depth, target, wh, callback) {
+  var parentDir = this._getWatchedDir(sysPath.dirname(dir));
+  var tracked = parentDir.has(sysPath.basename(dir));
+  if (!(initialAdd && this.options.ignoreInitial) && !target && !tracked) {
+    if (!wh.hasGlob || wh.globFilter(dir)) this._emit('addDir', dir, stats);
+  }
+
+  // ensure dir is tracked (harmless if redundant)
+  parentDir.add(sysPath.basename(dir));
+  this._getWatchedDir(dir);
+
+  var read = function(directory, initialAdd, done) {
+    // Normalize the directory name on Windows
+    directory = sysPath.join(directory, '');
+
+    if (!wh.hasGlob) {
+      var throttler = this._throttle('readdir', directory, 1000);
+      if (!throttler) return;
+    }
+
+    var previous = this._getWatchedDir(wh.path);
+    var current = [];
+
+    readdirp({
+      root: directory,
+      entryType: 'all',
+      fileFilter: wh.filterPath,
+      directoryFilter: wh.filterDir,
+      depth: 0,
+      lstat: true
+    }).on('data', function(entry) {
+      var item = entry.path;
+      var path = sysPath.join(directory, item);
+      current.push(item);
+
+      if (entry.stat.isSymbolicLink() &&
+        this._handleSymlink(entry, directory, path, item)) return;
+
+      // Files that present in current directory snapshot
+      // but absent in previous are added to watch list and
+      // emit `add` event.
+      if (item === target || !target && !previous.has(item)) {
+        this._readyCount++;
+
+        // ensure relativeness of path is preserved in case of watcher reuse
+        path = sysPath.join(dir, sysPath.relative(dir, path));
+
+        this._addToNodeFs(path, initialAdd, wh, depth + 1);
+      }
+    }.bind(this)).on('end', function() {
+      if (throttler) throttler.clear();
+      if (done) done();
+
+      // Files that absent in current directory snapshot
+      // but present in previous emit `remove` event
+      // and are removed from @watched[directory].
+      previous.children().filter(function(item) {
+        return item !== directory &&
+          current.indexOf(item) === -1 &&
+          // in case of intersecting globs;
+          // a path may have been filtered out of this readdir, but
+          // shouldn't be removed because it matches a different glob
+          (!wh.hasGlob || wh.filterPath({
+            fullPath: sysPath.resolve(directory, item)
+          }));
+      }).forEach(function(item) {
+        this._remove(directory, item);
+      }, this);
+    }.bind(this)).on('error', this._handleError.bind(this));
+  }.bind(this);
+
+  var closer;
+
+  if (this.options.depth == null || depth <= this.options.depth) {
+    if (!target) read(dir, initialAdd, callback);
+    closer = this._watchWithNodeFs(dir, function(dirPath, stats) {
+      // if current directory is removed, do nothing
+      if (stats && stats.mtime.getTime() === 0) return;
+
+      read(dirPath, false);
+    });
+  } else {
+    callback();
+  }
+  return closer;
+};
+
+// Private method: Handle added file, directory, or glob pattern.
+// Delegates call to _handleFile / _handleDir after checks.
+
+// * path       - string, path to file or directory.
+// * initialAdd - boolean, was the file added at watch instantiation?
+// * depth      - int, depth relative to user-supplied path
+// * target     - string, child path actually targeted for watch
+// * callback   - function, indicates whether the path was found or not
+
+// Returns nothing
+NodeFsHandler.prototype._addToNodeFs =
+function(path, initialAdd, priorWh, depth, target, callback) {
+  if (!callback) callback = Function.prototype;
+  var ready = this._emitReady;
+  if (this._isIgnored(path) || this.closed) {
+    ready();
+    return callback(null, false);
+  }
+
+  var wh = this._getWatchHelpers(path, depth);
+  if (!wh.hasGlob && priorWh) {
+    wh.hasGlob = priorWh.hasGlob;
+    wh.globFilter = priorWh.globFilter;
+    wh.filterPath = priorWh.filterPath;
+    wh.filterDir = priorWh.filterDir;
+  }
+
+  // evaluate what is at the path we're being asked to watch
+  fs[wh.statMethod](wh.watchPath, function(error, stats) {
+    if (this._handleError(error)) return callback(null, path);
+    if (this._isIgnored(wh.watchPath, stats)) {
+      ready();
+      return callback(null, false);
+    }
+
+    var initDir = function(dir, target) {
+      return this._handleDir(dir, stats, initialAdd, depth, target, wh, ready);
+    }.bind(this);
+
+    var closer;
+    if (stats.isDirectory()) {
+      closer = initDir(wh.watchPath, target);
+    } else if (stats.isSymbolicLink()) {
+      var parent = sysPath.dirname(wh.watchPath);
+      this._getWatchedDir(parent).add(wh.watchPath);
+      this._emit('add', wh.watchPath, stats);
+      closer = initDir(parent, path);
+
+      // preserve this symlink's target path
+      fs.realpath(path, function(error, targetPath) {
+        this._symlinkPaths[sysPath.resolve(path)] = targetPath;
+        ready();
+      }.bind(this));
+    } else {
+      closer = this._handleFile(wh.watchPath, stats, initialAdd, ready);
+    }
+
+    if (closer) this._closers[path] = closer;
+    callback(null, false);
+  }.bind(this));
+};
+
+module.exports = NodeFsHandler;

http://git-wip-us.apache.org/repos/asf/incubator-griffin-site/blob/4f8fa326/node_modules/chokidar/package.json
----------------------------------------------------------------------
diff --git a/node_modules/chokidar/package.json 
b/node_modules/chokidar/package.json
new file mode 100644
index 0000000..bbbf4fe
--- /dev/null
+++ b/node_modules/chokidar/package.json
@@ -0,0 +1,124 @@
+{
+  "_args": [
+    [
+      {
+        "raw": "chokidar@^1.5.2",
+        "scope": null,
+        "escapedName": "chokidar",
+        "name": "chokidar",
+        "rawSpec": "^1.5.2",
+        "spec": ">=1.5.2 <2.0.0",
+        "type": "range"
+      },
+      "/Users/yueguo/tmp/griffin-site/node_modules/hexo-fs"
+    ]
+  ],
+  "_from": "chokidar@>=1.5.2 <2.0.0",
+  "_id": "[email protected]",
+  "_inCache": true,
+  "_installable": true,
+  "_location": "/chokidar",
+  "_nodeVersion": "6.6.0",
+  "_npmOperationalInternal": {
+    "host": "packages-12-west.internal.npmjs.com",
+    "tmp": "tmp/chokidar-1.6.1.tgz_1476470196311_0.5785318606067449"
+  },
+  "_npmUser": {
+    "name": "paulmillr",
+    "email": "[email protected]"
+  },
+  "_npmVersion": "3.10.7",
+  "_phantomChildren": {},
+  "_requested": {
+    "raw": "chokidar@^1.5.2",
+    "scope": null,
+    "escapedName": "chokidar",
+    "name": "chokidar",
+    "rawSpec": "^1.5.2",
+    "spec": ">=1.5.2 <2.0.0",
+    "type": "range"
+  },
+  "_requiredBy": [
+    "/hexo-fs",
+    "/nunjucks"
+  ],
+  "_resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.6.1.tgz";,
+  "_shasum": "2f4447ab5e96e50fb3d789fd90d4c72e0e4c70c2",
+  "_shrinkwrap": null,
+  "_spec": "chokidar@^1.5.2",
+  "_where": "/Users/yueguo/tmp/griffin-site/node_modules/hexo-fs",
+  "author": {
+    "name": "Paul Miller",
+    "url": "http://paulmillr.com";
+  },
+  "bugs": {
+    "url": "http://github.com/paulmillr/chokidar/issues";
+  },
+  "dependencies": {
+    "anymatch": "^1.3.0",
+    "async-each": "^1.0.0",
+    "fsevents": "^1.0.0",
+    "glob-parent": "^2.0.0",
+    "inherits": "^2.0.1",
+    "is-binary-path": "^1.0.0",
+    "is-glob": "^2.0.0",
+    "path-is-absolute": "^1.0.0",
+    "readdirp": "^2.0.0"
+  },
+  "description": "A neat wrapper around node.js fs.watch / fs.watchFile / 
fsevents.",
+  "devDependencies": {
+    "chai": "^3.2.0",
+    "coveralls": "^2.11.2",
+    "graceful-fs": "4.1.4",
+    "istanbul": "^0.3.20",
+    "mocha": "^2.0.0",
+    "rimraf": "^2.4.3",
+    "sinon": "^1.10.3",
+    "sinon-chai": "^2.6.0"
+  },
+  "directories": {},
+  "dist": {
+    "shasum": "2f4447ab5e96e50fb3d789fd90d4c72e0e4c70c2",
+    "tarball": "https://registry.npmjs.org/chokidar/-/chokidar-1.6.1.tgz";
+  },
+  "files": [
+    "index.js",
+    "lib/"
+  ],
+  "gitHead": "c08145c5368fac6441773e621da9db215cc0d3b2",
+  "homepage": "https://github.com/paulmillr/chokidar";,
+  "keywords": [
+    "fs",
+    "watch",
+    "watchFile",
+    "watcher",
+    "watching",
+    "file",
+    "fsevents"
+  ],
+  "license": "MIT",
+  "maintainers": [
+    {
+      "name": "paulmillr",
+      "email": "[email protected]"
+    },
+    {
+      "name": "es128",
+      "email": "[email protected]"
+    }
+  ],
+  "name": "chokidar",
+  "optionalDependencies": {
+    "fsevents": "^1.0.0"
+  },
+  "readme": "ERROR: No README data found!",
+  "repository": {
+    "type": "git",
+    "url": "git+https://github.com/paulmillr/chokidar.git";
+  },
+  "scripts": {
+    "ci-test": "istanbul cover _mocha && cat ./coverage/lcov.info | coveralls",
+    "test": "istanbul test node_modules/mocha/bin/_mocha"
+  },
+  "version": "1.6.1"
+}

http://git-wip-us.apache.org/repos/asf/incubator-griffin-site/blob/4f8fa326/node_modules/cliui/CHANGELOG.md
----------------------------------------------------------------------
diff --git a/node_modules/cliui/CHANGELOG.md b/node_modules/cliui/CHANGELOG.md
new file mode 100644
index 0000000..ef6a35e
--- /dev/null
+++ b/node_modules/cliui/CHANGELOG.md
@@ -0,0 +1,15 @@
+# Change Log
+
+All notable changes to this project will be documented in this file. See 
[standard-version](https://github.com/conventional-changelog/standard-version) 
for commit guidelines.
+
+<a name="3.2.0"></a>
+# [3.2.0](https://github.com/yargs/cliui/compare/v3.1.2...v3.2.0) (2016-04-11)
+
+
+### Bug Fixes
+
+* reduces tarball size 
([acc6c33](https://github.com/yargs/cliui/commit/acc6c33))
+
+### Features
+
+* adds standard-version for release management 
([ff84e32](https://github.com/yargs/cliui/commit/ff84e32))

http://git-wip-us.apache.org/repos/asf/incubator-griffin-site/blob/4f8fa326/node_modules/cliui/LICENSE.txt
----------------------------------------------------------------------
diff --git a/node_modules/cliui/LICENSE.txt b/node_modules/cliui/LICENSE.txt
new file mode 100644
index 0000000..c7e2747
--- /dev/null
+++ b/node_modules/cliui/LICENSE.txt
@@ -0,0 +1,14 @@
+Copyright (c) 2015, Contributors
+
+Permission to use, copy, modify, and/or distribute this software
+for any purpose with or without fee is hereby granted, provided
+that the above copyright notice and this permission notice
+appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE
+LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
+OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

http://git-wip-us.apache.org/repos/asf/incubator-griffin-site/blob/4f8fa326/node_modules/cliui/README.md
----------------------------------------------------------------------
diff --git a/node_modules/cliui/README.md b/node_modules/cliui/README.md
new file mode 100644
index 0000000..028392c
--- /dev/null
+++ b/node_modules/cliui/README.md
@@ -0,0 +1,110 @@
+# cliui
+
+[![Build 
Status](https://travis-ci.org/yargs/cliui.svg)](https://travis-ci.org/yargs/cliui)
+[![Coverage 
Status](https://coveralls.io/repos/yargs/cliui/badge.svg?branch=)](https://coveralls.io/r/yargs/cliui?branch=)
+[![NPM 
version](https://img.shields.io/npm/v/cliui.svg)](https://www.npmjs.com/package/cliui)
+[![Standard 
Version](https://img.shields.io/badge/release-standard%20version-brightgreen.svg)](https://github.com/conventional-changelog/standard-version)
+
+easily create complex multi-column command-line-interfaces.
+
+## Example
+
+```js
+var ui = require('cliui')({
+  width: 80
+})
+
+ui.div('Usage: $0 [command] [options]')
+
+ui.div({
+  text: 'Options:',
+  padding: [2, 0, 2, 0]
+})
+
+ui.div(
+  {
+    text: "-f, --file",
+    width: 20,
+    padding: [0, 4, 0, 4]
+  },
+  {
+    text: "the file to load." +
+      chalk.green("(if this description is long it wraps).")
+    ,
+    width: 20
+  },
+  {
+    text: chalk.red("[required]"),
+    align: 'right'
+  }
+)
+
+console.log(ui.toString())
+```
+
+<img width="500" src="screenshot.png">
+
+## Layout DSL
+
+cliui exposes a simple layout DSL:
+
+If you create a single `ui.row`, passing a string rather than an
+object:
+
+* `\n`: characters will be interpreted as new rows.
+* `\t`: characters will be interpreted as new columns.
+* `\s`: characters will be interpreted as padding.
+
+**as an example...**
+
+```js
+var ui = require('./')({
+  width: 60
+})
+
+ui.div(
+  'Usage: node ./bin/foo.js\n' +
+  '  <regex>\t  provide a regex\n' +
+  '  <glob>\t  provide a glob\t [required]'
+)
+
+console.log(ui.toString())
+```
+
+**will output:**
+
+```shell
+Usage: node ./bin/foo.js
+  <regex>  provide a regex
+  <glob>   provide a glob          [required]
+```
+
+## Methods
+
+```js
+cliui = require('cliui')
+```
+
+### cliui({width: integer})
+
+Specify the maximum width of the UI being generated.
+
+### cliui({wrap: boolean})
+
+Enable or disable the wrapping of text in a column.
+
+### cliui.div(column, column, column)
+
+Create a row with any number of columns, a column
+can either be a string, or an object with the following
+options:
+
+* **width:** the width of a column.
+* **align:** alignment, `right` or `center`.
+* **padding:** `[top, right, bottom, left]`.
+* **border:** should a border be placed around the div?
+
+### cliui.span(column, column, column)
+
+Similar to `div`, except the next row will be appended without
+a new line being created.

http://git-wip-us.apache.org/repos/asf/incubator-griffin-site/blob/4f8fa326/node_modules/cliui/index.js
----------------------------------------------------------------------
diff --git a/node_modules/cliui/index.js b/node_modules/cliui/index.js
new file mode 100644
index 0000000..e501e78
--- /dev/null
+++ b/node_modules/cliui/index.js
@@ -0,0 +1,316 @@
+var stringWidth = require('string-width')
+var stripAnsi = require('strip-ansi')
+var wrap = require('wrap-ansi')
+var align = {
+  right: alignRight,
+  center: alignCenter
+}
+var top = 0
+var right = 1
+var bottom = 2
+var left = 3
+
+function UI (opts) {
+  this.width = opts.width
+  this.wrap = opts.wrap
+  this.rows = []
+}
+
+UI.prototype.span = function () {
+  var cols = this.div.apply(this, arguments)
+  cols.span = true
+}
+
+UI.prototype.div = function () {
+  if (arguments.length === 0) this.div('')
+  if (this.wrap && this._shouldApplyLayoutDSL.apply(this, arguments)) {
+    return this._applyLayoutDSL(arguments[0])
+  }
+
+  var cols = []
+
+  for (var i = 0, arg; (arg = arguments[i]) !== undefined; i++) {
+    if (typeof arg === 'string') cols.push(this._colFromString(arg))
+    else cols.push(arg)
+  }
+
+  this.rows.push(cols)
+  return cols
+}
+
+UI.prototype._shouldApplyLayoutDSL = function () {
+  return arguments.length === 1 && typeof arguments[0] === 'string' &&
+    /[\t\n]/.test(arguments[0])
+}
+
+UI.prototype._applyLayoutDSL = function (str) {
+  var _this = this
+  var rows = str.split('\n')
+  var leftColumnWidth = 0
+
+  // simple heuristic for layout, make sure the
+  // second column lines up along the left-hand.
+  // don't allow the first column to take up more
+  // than 50% of the screen.
+  rows.forEach(function (row) {
+    var columns = row.split('\t')
+    if (columns.length > 1 && stringWidth(columns[0]) > leftColumnWidth) {
+      leftColumnWidth = Math.min(
+        Math.floor(_this.width * 0.5),
+        stringWidth(columns[0])
+      )
+    }
+  })
+
+  // generate a table:
+  //  replacing ' ' with padding calculations.
+  //  using the algorithmically generated width.
+  rows.forEach(function (row) {
+    var columns = row.split('\t')
+    _this.div.apply(_this, columns.map(function (r, i) {
+      return {
+        text: r.trim(),
+        padding: _this._measurePadding(r),
+        width: (i === 0 && columns.length > 1) ? leftColumnWidth : undefined
+      }
+    }))
+  })
+
+  return this.rows[this.rows.length - 1]
+}
+
+UI.prototype._colFromString = function (str) {
+  return {
+    text: str,
+    padding: this._measurePadding(str)
+  }
+}
+
+UI.prototype._measurePadding = function (str) {
+  // measure padding without ansi escape codes
+  var noAnsi = stripAnsi(str)
+  return [0, noAnsi.match(/\s*$/)[0].length, 0, noAnsi.match(/^\s*/)[0].length]
+}
+
+UI.prototype.toString = function () {
+  var _this = this
+  var lines = []
+
+  _this.rows.forEach(function (row, i) {
+    _this.rowToString(row, lines)
+  })
+
+  // don't display any lines with the
+  // hidden flag set.
+  lines = lines.filter(function (line) {
+    return !line.hidden
+  })
+
+  return lines.map(function (line) {
+    return line.text
+  }).join('\n')
+}
+
+UI.prototype.rowToString = function (row, lines) {
+  var _this = this
+  var padding
+  var rrows = this._rasterize(row)
+  var str = ''
+  var ts
+  var width
+  var wrapWidth
+
+  rrows.forEach(function (rrow, r) {
+    str = ''
+    rrow.forEach(function (col, c) {
+      ts = '' // temporary string used during alignment/padding.
+      width = row[c].width // the width with padding.
+      wrapWidth = _this._negatePadding(row[c]) // the width without padding.
+
+      ts += col
+
+      for (var i = 0; i < wrapWidth - stringWidth(col); i++) {
+        ts += ' '
+      }
+
+      // align the string within its column.
+      if (row[c].align && row[c].align !== 'left' && _this.wrap) {
+        ts = align[row[c].align](ts, wrapWidth)
+        if (stringWidth(ts) < wrapWidth) ts += new Array(width - 
stringWidth(ts)).join(' ')
+      }
+
+      // apply border and padding to string.
+      padding = row[c].padding || [0, 0, 0, 0]
+      if (padding[left]) str += new Array(padding[left] + 1).join(' ')
+      str += addBorder(row[c], ts, '| ')
+      str += ts
+      str += addBorder(row[c], ts, ' |')
+      if (padding[right]) str += new Array(padding[right] + 1).join(' ')
+
+      // if prior row is span, try to render the
+      // current row on the prior line.
+      if (r === 0 && lines.length > 0) {
+        str = _this._renderInline(str, lines[lines.length - 1])
+      }
+    })
+
+    // remove trailing whitespace.
+    lines.push({
+      text: str.replace(/ +$/, ''),
+      span: row.span
+    })
+  })
+
+  return lines
+}
+
+function addBorder (col, ts, style) {
+  if (col.border) {
+    if (/[.']-+[.']/.test(ts)) return ''
+    else if (ts.trim().length) return style
+    else return '  '
+  }
+  return ''
+}
+
+// if the full 'source' can render in
+// the target line, do so.
+UI.prototype._renderInline = function (source, previousLine) {
+  var leadingWhitespace = source.match(/^ */)[0].length
+  var target = previousLine.text
+  var targetTextWidth = stringWidth(target.trimRight())
+
+  if (!previousLine.span) return source
+
+  // if we're not applying wrapping logic,
+  // just always append to the span.
+  if (!this.wrap) {
+    previousLine.hidden = true
+    return target + source
+  }
+
+  if (leadingWhitespace < targetTextWidth) return source
+
+  previousLine.hidden = true
+
+  return target.trimRight() + new Array(leadingWhitespace - targetTextWidth + 
1).join(' ') + source.trimLeft()
+}
+
+UI.prototype._rasterize = function (row) {
+  var _this = this
+  var i
+  var rrow
+  var rrows = []
+  var widths = this._columnWidths(row)
+  var wrapped
+
+  // word wrap all columns, and create
+  // a data-structure that is easy to rasterize.
+  row.forEach(function (col, c) {
+    // leave room for left and right padding.
+    col.width = widths[c]
+    if (_this.wrap) wrapped = wrap(col.text, _this._negatePadding(col), {hard: 
true}).split('\n')
+    else wrapped = col.text.split('\n')
+
+    if (col.border) {
+      wrapped.unshift('.' + new Array(_this._negatePadding(col) + 3).join('-') 
+ '.')
+      wrapped.push("'" + new Array(_this._negatePadding(col) + 3).join('-') + 
"'")
+    }
+
+    // add top and bottom padding.
+    if (col.padding) {
+      for (i = 0; i < (col.padding[top] || 0); i++) wrapped.unshift('')
+      for (i = 0; i < (col.padding[bottom] || 0); i++) wrapped.push('')
+    }
+
+    wrapped.forEach(function (str, r) {
+      if (!rrows[r]) rrows.push([])
+
+      rrow = rrows[r]
+
+      for (var i = 0; i < c; i++) {
+        if (rrow[i] === undefined) rrow.push('')
+      }
+      rrow.push(str)
+    })
+  })
+
+  return rrows
+}
+
+UI.prototype._negatePadding = function (col) {
+  var wrapWidth = col.width
+  if (col.padding) wrapWidth -= (col.padding[left] || 0) + (col.padding[right] 
|| 0)
+  if (col.border) wrapWidth -= 4
+  return wrapWidth
+}
+
+UI.prototype._columnWidths = function (row) {
+  var _this = this
+  var widths = []
+  var unset = row.length
+  var unsetWidth
+  var remainingWidth = this.width
+
+  // column widths can be set in config.
+  row.forEach(function (col, i) {
+    if (col.width) {
+      unset--
+      widths[i] = col.width
+      remainingWidth -= col.width
+    } else {
+      widths[i] = undefined
+    }
+  })
+
+  // any unset widths should be calculated.
+  if (unset) unsetWidth = Math.floor(remainingWidth / unset)
+  widths.forEach(function (w, i) {
+    if (!_this.wrap) widths[i] = row[i].width || stringWidth(row[i].text)
+    else if (w === undefined) widths[i] = Math.max(unsetWidth, 
_minWidth(row[i]))
+  })
+
+  return widths
+}
+
+// calculates the minimum width of
+// a column, based on padding preferences.
+function _minWidth (col) {
+  var padding = col.padding || []
+  var minWidth = 1 + (padding[left] || 0) + (padding[right] || 0)
+  if (col.border) minWidth += 4
+  return minWidth
+}
+
+function alignRight (str, width) {
+  str = str.trim()
+  var padding = ''
+  var strWidth = stringWidth(str)
+
+  if (strWidth < width) {
+    padding = new Array(width - strWidth + 1).join(' ')
+  }
+
+  return padding + str
+}
+
+function alignCenter (str, width) {
+  str = str.trim()
+  var padding = ''
+  var strWidth = stringWidth(str.trim())
+
+  if (strWidth < width) {
+    padding = new Array(parseInt((width - strWidth) / 2, 10) + 1).join(' ')
+  }
+
+  return padding + str
+}
+
+module.exports = function (opts) {
+  opts = opts || {}
+
+  return new UI({
+    width: (opts || {}).width || 80,
+    wrap: typeof opts.wrap === 'boolean' ? opts.wrap : true
+  })
+}

http://git-wip-us.apache.org/repos/asf/incubator-griffin-site/blob/4f8fa326/node_modules/cliui/package.json
----------------------------------------------------------------------
diff --git a/node_modules/cliui/package.json b/node_modules/cliui/package.json
new file mode 100644
index 0000000..5d2359c
--- /dev/null
+++ b/node_modules/cliui/package.json
@@ -0,0 +1,132 @@
+{
+  "_args": [
+    [
+      {
+        "raw": "cliui@^3.0.3",
+        "scope": null,
+        "escapedName": "cliui",
+        "name": "cliui",
+        "rawSpec": "^3.0.3",
+        "spec": ">=3.0.3 <4.0.0",
+        "type": "range"
+      },
+      "/Users/yueguo/tmp/griffin-site/node_modules/yargs"
+    ]
+  ],
+  "_from": "cliui@>=3.0.3 <4.0.0",
+  "_id": "[email protected]",
+  "_inCache": true,
+  "_installable": true,
+  "_location": "/cliui",
+  "_nodeVersion": "5.1.0",
+  "_npmOperationalInternal": {
+    "host": "packages-12-west.internal.npmjs.com",
+    "tmp": "tmp/cliui-3.2.0.tgz_1460342854008_0.8861493801232427"
+  },
+  "_npmUser": {
+    "name": "bcoe",
+    "email": "[email protected]"
+  },
+  "_npmVersion": "3.3.12",
+  "_phantomChildren": {},
+  "_requested": {
+    "raw": "cliui@^3.0.3",
+    "scope": null,
+    "escapedName": "cliui",
+    "name": "cliui",
+    "rawSpec": "^3.0.3",
+    "spec": ">=3.0.3 <4.0.0",
+    "type": "range"
+  },
+  "_requiredBy": [
+    "/yargs"
+  ],
+  "_resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz";,
+  "_shasum": "120601537a916d29940f934da3b48d585a39213d",
+  "_shrinkwrap": null,
+  "_spec": "cliui@^3.0.3",
+  "_where": "/Users/yueguo/tmp/griffin-site/node_modules/yargs",
+  "author": {
+    "name": "Ben Coe",
+    "email": "[email protected]"
+  },
+  "bugs": {
+    "url": "https://github.com/yargs/cliui/issues";
+  },
+  "config": {
+    "blanket": {
+      "pattern": [
+        "index.js"
+      ],
+      "data-cover-never": [
+        "node_modules",
+        "test"
+      ],
+      "output-reporter": "spec"
+    }
+  },
+  "dependencies": {
+    "string-width": "^1.0.1",
+    "strip-ansi": "^3.0.1",
+    "wrap-ansi": "^2.0.0"
+  },
+  "description": "easily create complex multi-column command-line-interfaces",
+  "devDependencies": {
+    "chai": "^3.5.0",
+    "chalk": "^1.1.2",
+    "coveralls": "^2.11.8",
+    "mocha": "^2.4.5",
+    "nyc": "^6.4.0",
+    "standard": "^6.0.8",
+    "standard-version": "^2.1.2"
+  },
+  "directories": {},
+  "dist": {
+    "shasum": "120601537a916d29940f934da3b48d585a39213d",
+    "tarball": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz";
+  },
+  "files": [
+    "index.js"
+  ],
+  "gitHead": "75d62e9dfa77a0e0a9c3ac3b96b02baa294142ce",
+  "homepage": "https://github.com/yargs/cliui#readme";,
+  "keywords": [
+    "cli",
+    "command-line",
+    "layout",
+    "design",
+    "console",
+    "wrap",
+    "table"
+  ],
+  "license": "ISC",
+  "main": "index.js",
+  "maintainers": [
+    {
+      "name": "bcoe",
+      "email": "[email protected]"
+    }
+  ],
+  "name": "cliui",
+  "optionalDependencies": {},
+  "readme": "ERROR: No README data found!",
+  "repository": {
+    "type": "git",
+    "url": "git+ssh://[email protected]/yargs/cliui.git"
+  },
+  "scripts": {
+    "coverage": "nyc --reporter=text-lcov mocha | coveralls",
+    "pretest": "standard",
+    "test": "nyc mocha",
+    "version": "standard-version"
+  },
+  "standard": {
+    "ignore": [
+      "**/example/**"
+    ],
+    "globals": [
+      "it"
+    ]
+  },
+  "version": "3.2.0"
+}

http://git-wip-us.apache.org/repos/asf/incubator-griffin-site/blob/4f8fa326/node_modules/co/History.md
----------------------------------------------------------------------
diff --git a/node_modules/co/History.md b/node_modules/co/History.md
new file mode 100644
index 0000000..68fbb15
--- /dev/null
+++ b/node_modules/co/History.md
@@ -0,0 +1,172 @@
+4.6.0 / 2015-07-09
+==================
+
+ * support passing the rest of the arguments to co into the generator
+
+ ```js
+ function *gen(...args) { }
+ co(gen, ...args);
+ ```
+
+4.5.0 / 2015-03-17
+==================
+
+ * support regular functions (that return promises)
+
+4.4.0 / 2015-02-14
+==================
+
+ * refactor `isGeneratorFunction`
+ * expose generator function from `co.wrap()`
+ * drop support for node < 0.12
+
+4.3.0 / 2015-02-05
+==================
+
+ * check for generator functions in a ES5-transpiler-friendly way
+
+4.2.0 / 2015-01-20
+==================
+
+ * support comparing generator functions with ES6 transpilers
+
+4.1.0 / 2014-12-26
+==================
+
+ * fix memory leak #180
+
+4.0.2 / 2014-12-18
+==================
+
+ * always return a global promise implementation
+
+4.0.1 / 2014-11-30
+==================
+
+ * friendlier ES6 module exports
+
+4.0.0 / 2014-11-15
+==================
+
+ * co now returns a promise and uses promises underneath
+ * `co.wrap()` for wrapping generator functions
+
+3.1.0 / 2014-06-30
+==================
+
+ * remove `setImmediate()` shim for node 0.8. semi-backwards breaking.
+   Users are expected to shim themselves. Also returns CommonJS browser 
support.
+ * added key order preservation for objects. thanks @greim
+ * replace `q` with `bluebird` in benchmarks and tests
+
+3.0.6 / 2014-05-03
+==================
+
+ * add `setImmediate()` fallback to `process.nextTick`
+ * remove duplicate code in toThunk
+ * update thunkify
+
+3.0.5 / 2014-03-17
+==================
+
+ * fix object/array test failure which tries to enumerate dates. Closes #98
+ * fix final callback error propagation. Closes #92
+
+3.0.4 / 2014-02-17
+==================
+
+ * fix toThunk object check regression. Closes #89
+
+3.0.3 / 2014-02-08
+==================
+
+ * refactor: arrayToThunk @AutoSponge #88
+
+3.0.2 / 2014-01-01
+==================
+
+ * fixed: nil arguments replaced with error fn
+
+3.0.1 / 2013-12-19
+==================
+
+ * fixed: callback passed as an argument to generators
+
+3.0.0 / 2013-12-19
+==================
+
+ * fixed: callback passed as an argument to generators
+ * change: `co(function *(){})` now returns a reusable thunk
+ * change: `this` must now be passed through the returned thunk, ex. 
`co(function *(){}).call(this)`
+ * fix "generator already finished" errors
+
+2.3.0 / 2013-11-12
+==================
+
+ * add `yield object` support
+
+2.2.0 / 2013-11-05
+==================
+
+ * change: make the `isGenerator()` function more generic
+
+2.1.0 / 2013-10-21
+==================
+
+ * add passing of arguments into the generator. closes #33.
+
+2.0.0 / 2013-10-14
+==================
+
+ * remove callback in favour of thunk-only co(). Closes #30 [breaking change]
+ * remove `co.wrap()` [breaking change]
+
+1.5.2 / 2013-09-02
+==================
+
+ * fix: preserve receiver with co.wrap()
+
+1.5.1 / 2013-08-11
+==================
+
+ * remove setImmediate() usage - ~110% perf increase. Closes #14
+
+0.5.0 / 2013-08-10
+==================
+
+ * add receiver propagation support
+ * examples: update streams.js example to use `http.get()` and streams2 API
+
+1.4.1 / 2013-07-01
+==================
+
+ * fix gen.next(val) for latest v8. Closes #8
+
+1.4.0 / 2013-06-21
+==================
+
+ * add promise support to joins
+ * add `yield generatorFunction` support
+ * add `yield generator` support
+ * add nested join support
+
+1.3.0 / 2013-06-10
+==================
+
+ * add passing of arguments
+
+1.2.1 / 2013-06-08
+==================
+
+ * fix join() of zero thunks
+
+1.2.0 / 2013-06-08
+==================
+
+ * add array yielding support. great suggestion by @domenic
+
+1.1.0 / 2013-06-06
+==================
+
+ * add promise support
+ * change nextTick to setImmediate

http://git-wip-us.apache.org/repos/asf/incubator-griffin-site/blob/4f8fa326/node_modules/co/LICENSE
----------------------------------------------------------------------
diff --git a/node_modules/co/LICENSE b/node_modules/co/LICENSE
new file mode 100644
index 0000000..92faba5
--- /dev/null
+++ b/node_modules/co/LICENSE
@@ -0,0 +1,22 @@
+(The MIT License)
+
+Copyright (c) 2014 TJ Holowaychuk &lt;[email protected]&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.

http://git-wip-us.apache.org/repos/asf/incubator-griffin-site/blob/4f8fa326/node_modules/co/Readme.md
----------------------------------------------------------------------
diff --git a/node_modules/co/Readme.md b/node_modules/co/Readme.md
new file mode 100644
index 0000000..c1d4882
--- /dev/null
+++ b/node_modules/co/Readme.md
@@ -0,0 +1,212 @@
+# co
+
+[![Gitter][gitter-image]][gitter-url]
+[![NPM version][npm-image]][npm-url]
+[![Build status][travis-image]][travis-url]
+[![Test coverage][coveralls-image]][coveralls-url]
+[![Downloads][downloads-image]][downloads-url]
+
+  Generator based control flow goodness for nodejs and the browser,
+  using promises, letting you write non-blocking code in a nice-ish way.
+
+## Co v4
+
+  `[email protected]` has been released, which now relies on promises.
+  It is a stepping stone towards [ES7 
async/await](https://github.com/lukehoban/ecmascript-asyncawait).
+  The primary API change is how `co()` is invoked.
+  Before, `co` returned a "thunk", which you then called with a callback and 
optional arguments.
+  Now, `co()` returns a promise.
+
+```js
+co(function* () {
+  var result = yield Promise.resolve(true);
+  return result;
+}).then(function (value) {
+  console.log(value);
+}, function (err) {
+  console.error(err.stack);
+});
+```
+
+  If you want to convert a `co`-generator-function into a regular function 
that returns a promise,
+  you now use `co.wrap(fn*)`.
+
+```js
+var fn = co.wrap(function* (val) {
+  return yield Promise.resolve(val);
+});
+
+fn(true).then(function (val) {
+
+});
+```
+
+## Platform Compatibility
+
+  `co@4+` requires a `Promise` implementation.
+  For versions of node `< 0.11` and for many older browsers,
+  you should/must include your own `Promise` polyfill.
+
+  When using node 0.11.x or greater, you must use the `--harmony-generators`
+  flag or just `--harmony` to get access to generators.
+
+  When using node 0.10.x and lower or browsers without generator support,
+  you must use [gnode](https://github.com/TooTallNate/gnode) and/or 
[regenerator](http://facebook.github.io/regenerator/).
+
+  io.js is supported out of the box, you can use `co` without flags or 
polyfills.
+
+## Installation
+
+```
+$ npm install co
+```
+
+## Associated libraries
+
+Any library that returns promises work well with `co`.
+
+- [mz](https://github.com/normalize/mz) - wrap all of node's code libraries as 
promises.
+
+View the [wiki](https://github.com/visionmedia/co/wiki) for more libraries.
+
+## Examples
+
+```js
+var co = require('co');
+
+co(function *(){
+  // yield any promise
+  var result = yield Promise.resolve(true);
+}).catch(onerror);
+
+co(function *(){
+  // resolve multiple promises in parallel
+  var a = Promise.resolve(1);
+  var b = Promise.resolve(2);
+  var c = Promise.resolve(3);
+  var res = yield [a, b, c];
+  console.log(res);
+  // => [1, 2, 3]
+}).catch(onerror);
+
+// errors can be try/catched
+co(function *(){
+  try {
+    yield Promise.reject(new Error('boom'));
+  } catch (err) {
+    console.error(err.message); // "boom"
+ }
+}).catch(onerror);
+
+function onerror(err) {
+  // log any uncaught errors
+  // co will not throw any errors you do not handle!!!
+  // HANDLE ALL YOUR ERRORS!!!
+  console.error(err.stack);
+}
+```
+
+## Yieldables
+
+  The `yieldable` objects currently supported are:
+
+  - promises
+  - thunks (functions)
+  - array (parallel execution)
+  - objects (parallel execution)
+  - generators (delegation)
+  - generator functions (delegation)
+
+Nested `yieldable` objects are supported, meaning you can nest
+promises within objects within arrays, and so on!
+
+### Promises
+
+[Read more on 
promises!](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)
+
+### Thunks
+
+Thunks are functions that only have a single argument, a callback.
+Thunk support only remains for backwards compatibility and may
+be removed in future versions of `co`.
+
+### Arrays
+
+`yield`ing an array will resolve all the `yieldables` in parallel.
+
+```js
+co(function* () {
+  var res = yield [
+    Promise.resolve(1),
+    Promise.resolve(2),
+    Promise.resolve(3),
+  ];
+  console.log(res); // => [1, 2, 3]
+}).catch(onerror);
+```
+
+### Objects
+
+Just like arrays, objects resolve all `yieldable`s in parallel.
+
+```js
+co(function* () {
+  var res = yield {
+    1: Promise.resolve(1),
+    2: Promise.resolve(2),
+  };
+  console.log(res); // => { 1: 1, 2: 2 }
+}).catch(onerror);
+```
+
+### Generators and Generator Functions
+
+Any generator or generator function you can pass into `co`
+can be yielded as well. This should generally be avoided
+as we should be moving towards spec-compliant `Promise`s instead.
+
+## API
+
+### co(fn*).then( val => )
+
+Returns a promise that resolves a generator, generator function,
+or any function that returns a generator.
+
+```js
+co(function* () {
+  return yield Promise.resolve(true);
+}).then(function (val) {
+  console.log(val);
+}, function (err) {
+  console.error(err.stack);
+});
+```
+
+### var fn = co.wrap(fn*)
+
+Convert a generator into a regular function that returns a `Promise`.
+
+```js
+var fn = co.wrap(function* (val) {
+  return yield Promise.resolve(val);
+});
+
+fn(true).then(function (val) {
+
+});
+```
+
+## License
+
+  MIT
+
+[npm-image]: https://img.shields.io/npm/v/co.svg?style=flat-square
+[npm-url]: https://npmjs.org/package/co
+[travis-image]: https://img.shields.io/travis/tj/co.svg?style=flat-square
+[travis-url]: https://travis-ci.org/tj/co
+[coveralls-image]: https://img.shields.io/coveralls/tj/co.svg?style=flat-square
+[coveralls-url]: https://coveralls.io/r/tj/co
+[downloads-image]: http://img.shields.io/npm/dm/co.svg?style=flat-square
+[downloads-url]: https://npmjs.org/package/co
+[gitter-image]: https://badges.gitter.im/Join%20Chat.svg
+[gitter-url]: 
https://gitter.im/tj/co?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge

Reply via email to