http://git-wip-us.apache.org/repos/asf/incubator-griffin-site/blob/ca1c37a7/node_modules/cheerio/lib/api/attributes.js
----------------------------------------------------------------------
diff --git a/node_modules/cheerio/lib/api/attributes.js 
b/node_modules/cheerio/lib/api/attributes.js
deleted file mode 100644
index a4947bd..0000000
--- a/node_modules/cheerio/lib/api/attributes.js
+++ /dev/null
@@ -1,482 +0,0 @@
-var _ = require('lodash'),
-  $ = require('../static'),
-  utils = require('../utils'),
-  isTag = utils.isTag,
-  domEach = utils.domEach,
-  hasOwn = Object.prototype.hasOwnProperty,
-  camelCase = utils.camelCase,
-  cssCase = utils.cssCase,
-  rspace = /\s+/,
-  dataAttrPrefix = 'data-',
-
-  // Lookup table for coercing string data-* attributes to their corresponding
-  // JavaScript primitives
-  primitives = {
-    null: null,
-    true: true,
-    false: false
-  },
-
-  // Attributes that are booleans
-  rboolean = 
/^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,
-  // Matches strings that look like JSON objects or arrays
-  rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/;
-
-
-var getAttr = function(elem, name) {
-  if (!elem || !isTag(elem)) return;
-
-  if (!elem.attribs) {
-    elem.attribs = {};
-  }
-
-  // Return the entire attribs object if no attribute specified
-  if (!name) {
-    return elem.attribs;
-  }
-
-  if (hasOwn.call(elem.attribs, name)) {
-    // Get the (decoded) attribute
-    return rboolean.test(name) ? name : elem.attribs[name];
-  }
-
-  // Mimic the DOM and return text content as value for `option's`
-  if (elem.name === 'option' && name === 'value') {
-    return $.text(elem.children);
-  }
-};
-
-var setAttr = function(el, name, value) {
-
-  if (value === null) {
-    removeAttribute(el, name);
-  } else {
-    el.attribs[name] = value+'';
-  }
-};
-
-exports.attr = function(name, value) {
-  // Set the value (with attr map support)
-  if (typeof name === 'object' || value !== undefined) {
-    if (typeof value === 'function') {
-      return domEach(this, function(i, el) {
-        setAttr(el, name, value.call(el, i, el.attribs[name]));
-      });
-    }
-    return domEach(this, function(i, el) {
-      if (!isTag(el)) return;
-
-      if (typeof name === 'object') {
-        _.each(name, function(value, name) {
-          setAttr(el, name, value);
-        });
-      } else {
-        setAttr(el, name, value);
-      }
-    });
-  }
-
-  return getAttr(this[0], name);
-};
-
-var getProp = function (el, name) {
-  return el.hasOwnProperty(name)
-      ? el[name]
-      : rboolean.test(name)
-          ? getAttr(el, name) !== undefined
-          : getAttr(el, name);
-};
-
-var setProp = function (el, name, value) {
-  el[name] = rboolean.test(name) ? !!value : value;
-};
-
-exports.prop = function (name, value) {
-  var i = 0,
-      property;
-
-  if (typeof name === 'string' && value === undefined) {
-
-    switch (name) {
-      case 'style':
-        property = this.css();
-
-        _.each(property, function (v, p) {
-          property[i++] = p;
-        });
-
-        property.length = i;
-
-        break;
-      case 'tagName':
-      case 'nodeName':
-        property = this[0].name.toUpperCase();
-        break;
-      default:
-        property = getProp(this[0], name);
-    }
-
-    return property;
-  }
-
-  if (typeof name === 'object' || value !== undefined) {
-
-    if (typeof value === 'function') {
-      return domEach(this, function(i, el) {
-        setProp(el, name, value.call(el, i, getProp(el, name)));
-      });
-    }
-
-    return domEach(this, function(i, el) {
-      if (!isTag(el)) return;
-
-      if (typeof name === 'object') {
-
-        _.each(name, function(val, name) {
-          setProp(el, name, val);
-        });
-
-      } else {
-        setProp(el, name, value);
-      }
-    });
-
-  }
-};
-
-var setData = function(el, name, value) {
-  if (!el.data) {
-    el.data = {};
-  }
-
-  if (typeof name === 'object') return _.extend(el.data, name);
-  if (typeof name === 'string' && value !== undefined) {
-    el.data[name] = value;
-  } else if (typeof name === 'object') {
-    _.exend(el.data, name);
-  }
-};
-
-// Read the specified attribute from the equivalent HTML5 `data-*` attribute,
-// and (if present) cache the value in the node's internal data store. If no
-// attribute name is specified, read *all* HTML5 `data-*` attributes in this
-// manner.
-var readData = function(el, name) {
-  var readAll = arguments.length === 1;
-  var domNames, domName, jsNames, jsName, value, idx, length;
-
-  if (readAll) {
-    domNames = Object.keys(el.attribs).filter(function(attrName) {
-      return attrName.slice(0, dataAttrPrefix.length) === dataAttrPrefix;
-    });
-    jsNames = domNames.map(function(domName) {
-      return camelCase(domName.slice(dataAttrPrefix.length));
-    });
-  } else {
-    domNames = [dataAttrPrefix + cssCase(name)];
-    jsNames = [name];
-  }
-
-  for (idx = 0, length = domNames.length; idx < length; ++idx) {
-    domName = domNames[idx];
-    jsName = jsNames[idx];
-    if (hasOwn.call(el.attribs, domName)) {
-      value = el.attribs[domName];
-
-      if (hasOwn.call(primitives, value)) {
-        value = primitives[value];
-      } else if (value === String(Number(value))) {
-        value = Number(value);
-      } else if (rbrace.test(value)) {
-        try {
-          value = JSON.parse(value);
-        } catch(e){ }
-      }
-
-      el.data[jsName] = value;
-    }
-  }
-
-  return readAll ? el.data : value;
-};
-
-exports.data = function(name, value) {
-  var elem = this[0];
-
-  if (!elem || !isTag(elem)) return;
-
-  if (!elem.data) {
-    elem.data = {};
-  }
-
-  // Return the entire data object if no data specified
-  if (!name) {
-    return readData(elem);
-  }
-
-  // Set the value (with attr map support)
-  if (typeof name === 'object' || value !== undefined) {
-    domEach(this, function(i, el) {
-      setData(el, name, value);
-    });
-    return this;
-  } else if (hasOwn.call(elem.data, name)) {
-    return elem.data[name];
-  }
-
-  return readData(elem, name);
-};
-
-/**
- * Get the value of an element
- */
-
-exports.val = function(value) {
-  var querying = arguments.length === 0,
-      element = this[0];
-
-  if(!element) return;
-
-  switch (element.name) {
-    case 'textarea':
-      return this.text(value);
-    case 'input':
-      switch (this.attr('type')) {
-        case 'radio':
-          if (querying) {
-            return this.attr('value');
-          } else {
-            this.attr('value', value);
-            return this;
-          }
-          break;
-        default:
-          return this.attr('value', value);
-      }
-      return;
-    case 'select':
-      var option = this.find('option:selected'),
-          returnValue;
-      if (option === undefined) return undefined;
-      if (!querying) {
-        if (!this.attr().hasOwnProperty('multiple') && typeof value == 
'object') {
-          return this;
-        }
-        if (typeof value != 'object') {
-          value = [value];
-        }
-        this.find('option').removeAttr('selected');
-        for (var i = 0; i < value.length; i++) {
-          this.find('option[value="' + value[i] + '"]').attr('selected', '');
-        }
-        return this;
-      }
-      returnValue = option.attr('value');
-      if (this.attr().hasOwnProperty('multiple')) {
-        returnValue = [];
-        domEach(option, function(i, el) {
-          returnValue.push(getAttr(el, 'value'));
-        });
-      }
-      return returnValue;
-    case 'option':
-      if (!querying) {
-        this.attr('value', value);
-        return this;
-      }
-      return this.attr('value');
-  }
-};
-
-/**
- * Remove an attribute
- */
-
-var removeAttribute = function(elem, name) {
-  if (!elem.attribs || !hasOwn.call(elem.attribs, name))
-    return;
-
-  delete elem.attribs[name];
-};
-
-
-exports.removeAttr = function(name) {
-  domEach(this, function(i, elem) {
-    removeAttribute(elem, name);
-  });
-
-  return this;
-};
-
-exports.hasClass = function(className) {
-  return _.some(this, function(elem) {
-    var attrs = elem.attribs,
-        clazz = attrs && attrs['class'],
-        idx = -1,
-        end;
-
-    if (clazz) {
-      while ((idx = clazz.indexOf(className, idx+1)) > -1) {
-        end = idx + className.length;
-
-        if ((idx === 0 || rspace.test(clazz[idx-1]))
-            && (end === clazz.length || rspace.test(clazz[end]))) {
-          return true;
-        }
-      }
-    }
-  });
-};
-
-exports.addClass = function(value) {
-  // Support functions
-  if (typeof value === 'function') {
-    return domEach(this, function(i, el) {
-      var className = el.attribs['class'] || '';
-      exports.addClass.call([el], value.call(el, i, className));
-    });
-  }
-
-  // Return if no value or not a string or function
-  if (!value || typeof value !== 'string') return this;
-
-  var classNames = value.split(rspace),
-      numElements = this.length;
-
-
-  for (var i = 0; i < numElements; i++) {
-    // If selected element isn't a tag, move on
-    if (!isTag(this[i])) continue;
-
-    // If we don't already have classes
-    var className = getAttr(this[i], 'class'),
-        numClasses,
-        setClass;
-
-    if (!className) {
-      setAttr(this[i], 'class', classNames.join(' ').trim());
-    } else {
-      setClass = ' ' + className + ' ';
-      numClasses = classNames.length;
-
-      // Check if class already exists
-      for (var j = 0; j < numClasses; j++) {
-        var appendClass = classNames[j] + ' ';
-        if (setClass.indexOf(' ' + appendClass) < 0)
-          setClass += appendClass;
-      }
-
-      setAttr(this[i], 'class', setClass.trim());
-    }
-  }
-
-  return this;
-};
-
-var splitClass = function(className) {
-  return className ? className.trim().split(rspace) : [];
-};
-
-exports.removeClass = function(value) {
-  var classes,
-      numClasses,
-      removeAll;
-
-  // Handle if value is a function
-  if (typeof value === 'function') {
-    return domEach(this, function(i, el) {
-      exports.removeClass.call(
-        [el], value.call(el, i, el.attribs['class'] || '')
-      );
-    });
-  }
-
-  classes = splitClass(value);
-  numClasses = classes.length;
-  removeAll = arguments.length === 0;
-
-  return domEach(this, function(i, el) {
-    if (!isTag(el)) return;
-
-    if (removeAll) {
-      // Short circuit the remove all case as this is the nice one
-      el.attribs.class = '';
-    } else {
-      var elClasses = splitClass(el.attribs.class),
-          index,
-          changed;
-
-      for (var j = 0; j < numClasses; j++) {
-        index = elClasses.indexOf(classes[j]);
-
-        if (index >= 0) {
-          elClasses.splice(index, 1);
-          changed = true;
-
-          // We have to do another pass to ensure that there are not duplicate
-          // classes listed
-          j--;
-        }
-      }
-      if (changed) {
-        el.attribs.class = elClasses.join(' ');
-      }
-    }
-  });
-};
-
-exports.toggleClass = function(value, stateVal) {
-  // Support functions
-  if (typeof value === 'function') {
-    return domEach(this, function(i, el) {
-      exports.toggleClass.call(
-        [el],
-        value.call(el, i, el.attribs['class'] || '', stateVal),
-        stateVal
-      );
-    });
-  }
-
-  // Return if no value or not a string or function
-  if (!value || typeof value !== 'string') return this;
-
-  var classNames = value.split(rspace),
-    numClasses = classNames.length,
-    state = typeof stateVal === 'boolean' ? stateVal ? 1 : -1 : 0,
-    numElements = this.length,
-    elementClasses,
-    index;
-
-  for (var i = 0; i < numElements; i++) {
-    // If selected element isn't a tag, move on
-    if (!isTag(this[i])) continue;
-
-    elementClasses = splitClass(this[i].attribs.class);
-
-    // Check if class already exists
-    for (var j = 0; j < numClasses; j++) {
-      // Check if the class name is currently defined
-      index = elementClasses.indexOf(classNames[j]);
-
-      // Add if stateValue === true or we are toggling and there is no value
-      if (state >= 0 && index < 0) {
-        elementClasses.push(classNames[j]);
-      } else if (state <= 0 && index >= 0) {
-        // Otherwise remove but only if the item exists
-        elementClasses.splice(index, 1);
-      }
-    }
-
-    this[i].attribs.class = elementClasses.join(' ');
-  }
-
-  return this;
-};
-
-exports.is = function (selector) {
-  if (selector) {
-    return this.filter(selector).length > 0;
-  }
-  return false;
-};
-

http://git-wip-us.apache.org/repos/asf/incubator-griffin-site/blob/ca1c37a7/node_modules/cheerio/lib/api/css.js
----------------------------------------------------------------------
diff --git a/node_modules/cheerio/lib/api/css.js 
b/node_modules/cheerio/lib/api/css.js
deleted file mode 100644
index bfbdcda..0000000
--- a/node_modules/cheerio/lib/api/css.js
+++ /dev/null
@@ -1,118 +0,0 @@
-var _ = require('lodash'),
-    domEach = require('../utils').domEach;
-var toString = Object.prototype.toString;
-
-/**
- * Set / Get css.
- *
- * @param {String|Object} prop
- * @param {String} val
- * @return {self}
- * @api public
- */
-
-exports.css = function(prop, val) {
-  if (arguments.length === 2 ||
-    // When `prop` is a "plain" object
-    (toString.call(prop) === '[object Object]')) {
-    return domEach(this, function(idx, el) {
-      setCss(el, prop, val, idx);
-    });
-  } else {
-    return getCss(this[0], prop);
-  }
-};
-
-/**
- * Set styles of all elements.
- *
- * @param {String|Object} prop
- * @param {String} val
- * @param {Number} idx - optional index within the selection
- * @return {self}
- * @api private
- */
-
-function setCss(el, prop, val, idx) {
-  if ('string' == typeof prop) {
-    var styles = getCss(el);
-    if (typeof val === 'function') {
-      val = val.call(el, idx, styles[prop]);
-    }
-
-    if (val === '') {
-      delete styles[prop];
-    } else if (val != null) {
-      styles[prop] = val;
-    }
-
-    el.attribs.style = stringify(styles);
-  } else if ('object' == typeof prop) {
-    Object.keys(prop).forEach(function(k){
-      setCss(el, k, prop[k]);
-    });
-  }
-}
-
-/**
- * Get parsed styles of the first element.
- *
- * @param {String} prop
- * @return {Object}
- * @api private
- */
-
-function getCss(el, prop) {
-  var styles = parse(el.attribs.style);
-  if (typeof prop === 'string') {
-    return styles[prop];
-  } else if (Array.isArray(prop)) {
-    return _.pick(styles, prop);
-  } else {
-    return styles;
-  }
-}
-
-/**
- * Stringify `obj` to styles.
- *
- * @param {Object} obj
- * @return {Object}
- * @api private
- */
-
-function stringify(obj) {
-  return Object.keys(obj || {})
-    .reduce(function(str, prop){
-      return str += ''
-        + (str ? ' ' : '')
-        + prop
-        + ': '
-        + obj[prop]
-        + ';';
-    }, '');
-}
-
-/**
- * Parse `styles`.
- *
- * @param {String} styles
- * @return {Object}
- * @api private
- */
-
-function parse(styles) {
-  styles = (styles || '').trim();
-
-  if (!styles) return {};
-
-  return styles
-    .split(';')
-    .reduce(function(obj, str){
-      var n = str.indexOf(':');
-      // skip if there is no :, or if it is the first/last character
-      if (n < 1 || n === str.length-1) return obj;
-      obj[str.slice(0,n).trim()] = str.slice(n+1).trim();
-      return obj;
-    }, {});
-}

http://git-wip-us.apache.org/repos/asf/incubator-griffin-site/blob/ca1c37a7/node_modules/cheerio/lib/api/forms.js
----------------------------------------------------------------------
diff --git a/node_modules/cheerio/lib/api/forms.js 
b/node_modules/cheerio/lib/api/forms.js
deleted file mode 100644
index 9e335c9..0000000
--- a/node_modules/cheerio/lib/api/forms.js
+++ /dev/null
@@ -1,49 +0,0 @@
-// 
https://github.com/jquery/jquery/blob/2.1.3/src/manipulation/var/rcheckableType.js
-// https://github.com/jquery/jquery/blob/2.1.3/src/serialize.js
-var _ = require('lodash'),
-    submittableSelector = 'input,select,textarea,keygen',
-    rCRLF = /\r?\n/g;
-
-exports.serializeArray = function() {
-  // Resolve all form elements from either forms or collections of form 
elements
-  var Cheerio = this.constructor;
-  return this.map(function() {
-      var elem = this;
-      var $elem = Cheerio(elem);
-      if (elem.name === 'form') {
-        return $elem.find(submittableSelector).toArray();
-      } else {
-        return $elem.filter(submittableSelector).toArray();
-      }
-    }).filter(
-        // Verify elements have a name (`attr.name`) and are not disabled 
(`:disabled`)
-        '[name!=""]:not(:disabled)'
-        // and cannot be clicked (`[type=submit]`) or are used in 
`x-www-form-urlencoded` (`[type=file]`)
-        + ':not(:submit, :button, :image, :reset, :file)'
-        // and are either checked/don't have a checkable state
-        + ':matches([checked], :not(:checkbox, :radio))'
-    // Convert each of the elements to its value(s)
-    ).map(function(i, elem) {
-      var $elem = Cheerio(elem);
-      var name = $elem.attr('name');
-      var val = $elem.val();
-
-      // If there is no value set (e.g. `undefined`, `null`), then return 
nothing
-      if (val == null) {
-        return null;
-      } else {
-        // If we have an array of values (e.g. `<select multiple>`), return an 
array of key/value pairs
-        if (Array.isArray(val)) {
-          return _.map(val, function(val) {
-            // We trim replace any line endings (e.g. `\r` or `\r\n` with 
`\r\n`) to guarantee consistency across platforms
-            //   These can occur inside of `<textarea>'s`
-            return {name: name, value: val.replace( rCRLF, '\r\n' )};
-          });
-        // Otherwise (e.g. `<input type="text">`, return only one key/value 
pair
-        } else {
-          return {name: name, value: val.replace( rCRLF, '\r\n' )};
-        }
-      }
-    // Convert our result to an array
-    }).get();
-};

http://git-wip-us.apache.org/repos/asf/incubator-griffin-site/blob/ca1c37a7/node_modules/cheerio/lib/api/manipulation.js
----------------------------------------------------------------------
diff --git a/node_modules/cheerio/lib/api/manipulation.js 
b/node_modules/cheerio/lib/api/manipulation.js
deleted file mode 100644
index 932b5da..0000000
--- a/node_modules/cheerio/lib/api/manipulation.js
+++ /dev/null
@@ -1,421 +0,0 @@
-var _ = require('lodash'),
-    parse = require('../parse'),
-    $ = require('../static'),
-    updateDOM = parse.update,
-    evaluate = parse.evaluate,
-    utils = require('../utils'),
-    domEach = utils.domEach,
-    cloneDom = utils.cloneDom,
-    isHtml = utils.isHtml,
-    slice = Array.prototype.slice;
-
-// Create an array of nodes, recursing into arrays and parsing strings if
-// necessary
-exports._makeDomArray = function makeDomArray(elem, clone) {
-  if (elem == null) {
-    return [];
-  } else if (elem.cheerio) {
-    return clone ? cloneDom(elem.get(), elem.options) : elem.get();
-  } else if (Array.isArray(elem)) {
-    return _.flatten(elem.map(function(el) {
-      return this._makeDomArray(el, clone);
-    }, this));
-  } else if (typeof elem === 'string') {
-    return evaluate(elem, this.options);
-  } else {
-    return clone ? cloneDom([elem]) : [elem];
-  }
-};
-
-var _insert = function(concatenator) {
-  return function() {
-    var elems = slice.call(arguments),
-        lastIdx = this.length - 1;
-
-    return domEach(this, function(i, el) {
-      var dom, domSrc;
-
-      if (typeof elems[0] === 'function') {
-        domSrc = elems[0].call(el, i, $.html(el.children));
-      } else {
-        domSrc = elems;
-      }
-
-      dom = this._makeDomArray(domSrc, i < lastIdx);
-      concatenator(dom, el.children, el);
-    });
-  };
-};
-
-/*
- * Modify an array in-place, removing some number of elements and adding new
- * elements directly following them.
- *
- * @param {Array} array Target array to splice.
- * @param {Number} spliceIdx Index at which to begin changing the array.
- * @param {Number} spliceCount Number of elements to remove from the array.
- * @param {Array} newElems Elements to insert into the array.
- *
- * @api private
- */
-var uniqueSplice = function(array, spliceIdx, spliceCount, newElems, parent) {
-  var spliceArgs = [spliceIdx, spliceCount].concat(newElems),
-      prev = array[spliceIdx - 1] || null,
-      next = array[spliceIdx] || null;
-  var idx, len, prevIdx, node, oldParent;
-
-  // Before splicing in new elements, ensure they do not already appear in the
-  // current array.
-  for (idx = 0, len = newElems.length; idx < len; ++idx) {
-    node = newElems[idx];
-    oldParent = node.parent || node.root;
-    prevIdx = oldParent && oldParent.children.indexOf(newElems[idx]);
-
-    if (oldParent && prevIdx > -1) {
-      oldParent.children.splice(prevIdx, 1);
-      if (parent === oldParent && spliceIdx > prevIdx) {
-        spliceArgs[0]--;
-      }
-    }
-
-    node.root = null;
-    node.parent = parent;
-
-    if (node.prev) {
-      node.prev.next = node.next || null;
-    }
-
-    if (node.next) {
-      node.next.prev = node.prev || null;
-    }
-
-    node.prev = newElems[idx - 1] || prev;
-    node.next = newElems[idx + 1] || next;
-  }
-
-  if (prev) {
-    prev.next = newElems[0];
-  }
-  if (next) {
-    next.prev = newElems[newElems.length - 1];
-  }
-  return array.splice.apply(array, spliceArgs);
-};
-
-exports.appendTo = function(target) {
-  if (!target.cheerio) {
-    target = this.constructor.call(this.constructor, target, null, 
this._originalRoot);
-  }
-
-  target.append(this);
-
-  return this;
-};
-
-exports.prependTo = function(target) {
-  if (!target.cheerio) {
-    target = this.constructor.call(this.constructor, target, null, 
this._originalRoot);
-  }
-
-  target.prepend(this);
-
-  return this;
-};
-
-exports.append = _insert(function(dom, children, parent) {
-  uniqueSplice(children, children.length, 0, dom, parent);
-});
-
-exports.prepend = _insert(function(dom, children, parent) {
-  uniqueSplice(children, 0, 0, dom, parent);
-});
-
-exports.wrap = function(wrapper) {
-  var wrapperFn = typeof wrapper === 'function' && wrapper,
-      lastIdx = this.length - 1;
-
-  _.forEach(this, _.bind(function(el, i) {
-    var parent = el.parent || el.root,
-        siblings = parent.children,
-        dom, index;
-
-    if (!parent) {
-      return;
-    }
-
-    if (wrapperFn) {
-      wrapper = wrapperFn.call(el, i);
-    }
-
-    if (typeof wrapper === 'string' && !isHtml(wrapper)) {
-      wrapper = this.parents().last().find(wrapper).clone();
-    }
-
-    dom = this._makeDomArray(wrapper, i < lastIdx).slice(0, 1);
-    index = siblings.indexOf(el);
-
-    updateDOM([el], dom[0]);
-    // The previous operation removed the current element from the `siblings`
-    // array, so the `dom` array can be inserted without removing any
-    // additional elements.
-    uniqueSplice(siblings, index, 0, dom, parent);
-  }, this));
-
-  return this;
-};
-
-exports.after = function() {
-  var elems = slice.call(arguments),
-      lastIdx = this.length - 1;
-
-  domEach(this, function(i, el) {
-    var parent = el.parent || el.root;
-    if (!parent) {
-      return;
-    }
-
-    var siblings = parent.children,
-        index = siblings.indexOf(el),
-        domSrc, dom;
-
-    // If not found, move on
-    if (index < 0) return;
-
-    if (typeof elems[0] === 'function') {
-      domSrc = elems[0].call(el, i, $.html(el.children));
-    } else {
-      domSrc = elems;
-    }
-    dom = this._makeDomArray(domSrc, i < lastIdx);
-
-    // Add element after `this` element
-    uniqueSplice(siblings, index + 1, 0, dom, parent);
-  });
-
-  return this;
-};
-
-exports.insertAfter = function(target) {
-  var clones = [],
-      self = this;
-  if (typeof target === 'string') {
-    target = this.constructor.call(this.constructor, target, null, 
this._originalRoot);
-  }
-  target = this._makeDomArray(target);
-  self.remove();
-  domEach(target, function(i, el) {
-    var clonedSelf = self._makeDomArray(self.clone());
-    var parent = el.parent || el.root;
-    if (!parent) {
-      return;
-    }
-
-    var siblings = parent.children,
-        index = siblings.indexOf(el);
-
-    // If not found, move on
-    if (index < 0) return;
-
-    // Add cloned `this` element(s) after target element
-    uniqueSplice(siblings, index + 1, 0, clonedSelf, parent);
-    clones.push(clonedSelf);
-  });
-  return this.constructor.call(this.constructor, this._makeDomArray(clones));
-};
-
-exports.before = function() {
-  var elems = slice.call(arguments),
-      lastIdx = this.length - 1;
-
-  domEach(this, function(i, el) {
-    var parent = el.parent || el.root;
-    if (!parent) {
-      return;
-    }
-
-    var siblings = parent.children,
-        index = siblings.indexOf(el),
-        domSrc, dom;
-
-    // If not found, move on
-    if (index < 0) return;
-
-    if (typeof elems[0] === 'function') {
-      domSrc = elems[0].call(el, i, $.html(el.children));
-    } else {
-      domSrc = elems;
-    }
-
-    dom = this._makeDomArray(domSrc, i < lastIdx);
-
-    // Add element before `el` element
-    uniqueSplice(siblings, index, 0, dom, parent);
-  });
-
-  return this;
-};
-
-exports.insertBefore = function(target) {
-  var clones = [],
-      self = this;
-  if (typeof target === 'string') {
-    target = this.constructor.call(this.constructor, target, null, 
this._originalRoot);
-  }
-  target = this._makeDomArray(target);
-  self.remove();
-  domEach(target, function(i, el) {
-    var clonedSelf = self._makeDomArray(self.clone());
-    var parent = el.parent || el.root;
-    if (!parent) {
-      return;
-    }
-
-    var siblings = parent.children,
-        index = siblings.indexOf(el);
-
-    // If not found, move on
-    if (index < 0) return;
-
-    // Add cloned `this` element(s) after target element
-    uniqueSplice(siblings, index, 0, clonedSelf, parent);
-    clones.push(clonedSelf);
-  });
-  return this.constructor.call(this.constructor, this._makeDomArray(clones));
-};
-
-/*
-  remove([selector])
-*/
-exports.remove = function(selector) {
-  var elems = this;
-
-  // Filter if we have selector
-  if (selector)
-    elems = elems.filter(selector);
-
-  domEach(elems, function(i, el) {
-    var parent = el.parent || el.root;
-    if (!parent) {
-      return;
-    }
-
-    var siblings = parent.children,
-        index = siblings.indexOf(el);
-
-    if (index < 0) return;
-
-    siblings.splice(index, 1);
-    if (el.prev) {
-      el.prev.next = el.next;
-    }
-    if (el.next) {
-      el.next.prev = el.prev;
-    }
-    el.prev = el.next = el.parent = el.root = null;
-  });
-
-  return this;
-};
-
-exports.replaceWith = function(content) {
-  var self = this;
-
-  domEach(this, function(i, el) {
-    var parent = el.parent || el.root;
-    if (!parent) {
-      return;
-    }
-
-    var siblings = parent.children,
-        dom = self._makeDomArray(typeof content === 'function' ? 
content.call(el, i, el) : content),
-        index;
-
-    // In the case that `dom` contains nodes that already exist in other
-    // structures, ensure those nodes are properly removed.
-    updateDOM(dom, null);
-
-    index = siblings.indexOf(el);
-
-    // Completely remove old element
-    uniqueSplice(siblings, index, 1, dom, parent);
-    el.parent = el.prev = el.next = el.root = null;
-  });
-
-  return this;
-};
-
-exports.empty = function() {
-  domEach(this, function(i, el) {
-    _.each(el.children, function(el) {
-      el.next = el.prev = el.parent = null;
-    });
-
-    el.children.length = 0;
-  });
-  return this;
-};
-
-/**
- * Set/Get the HTML
- */
-exports.html = function(str) {
-  if (str === undefined) {
-    if (!this[0] || !this[0].children) return null;
-    return $.html(this[0].children, this.options);
-  }
-
-  var opts = this.options;
-
-  domEach(this, function(i, el) {
-    _.each(el.children, function(el) {
-      el.next = el.prev = el.parent = null;
-    });
-
-    var content = str.cheerio ? str.clone().get() : evaluate('' + str, opts);
-
-    updateDOM(content, el);
-  });
-
-  return this;
-};
-
-exports.toString = function() {
-  return $.html(this, this.options);
-};
-
-exports.text = function(str) {
-  // If `str` is undefined, act as a "getter"
-  if (str === undefined) {
-    return $.text(this);
-  } else if (typeof str === 'function') {
-    // Function support
-    return domEach(this, function(i, el) {
-      var $el = [el];
-      return exports.text.call($el, str.call(el, i, $.text($el)));
-    });
-  }
-
-  // Append text node to each selected elements
-  domEach(this, function(i, el) {
-    _.each(el.children, function(el) {
-      el.next = el.prev = el.parent = null;
-    });
-
-    var elem = {
-      data: '' + str,
-      type: 'text',
-      parent: el,
-      prev: null,
-      next: null,
-      children: []
-    };
-
-    updateDOM(elem, el);
-  });
-
-  return this;
-};
-
-exports.clone = function() {
-  return this._make(cloneDom(this.get(), this.options));
-};

http://git-wip-us.apache.org/repos/asf/incubator-griffin-site/blob/ca1c37a7/node_modules/cheerio/lib/api/traversing.js
----------------------------------------------------------------------
diff --git a/node_modules/cheerio/lib/api/traversing.js 
b/node_modules/cheerio/lib/api/traversing.js
deleted file mode 100644
index b08d587..0000000
--- a/node_modules/cheerio/lib/api/traversing.js
+++ /dev/null
@@ -1,423 +0,0 @@
-var _ = require('lodash'),
-    select = require('css-select'),
-    utils = require('../utils'),
-    domEach = utils.domEach,
-    uniqueSort = require('htmlparser2').DomUtils.uniqueSort,
-    isTag = utils.isTag;
-
-exports.find = function(selectorOrHaystack) {
-  var elems = _.reduce(this, function(memo, elem) {
-    return memo.concat(_.filter(elem.children, isTag));
-  }, []);
-  var contains = this.constructor.contains;
-  var haystack;
-
-  if (selectorOrHaystack && typeof selectorOrHaystack !== 'string') {
-    if (selectorOrHaystack.cheerio) {
-      haystack = selectorOrHaystack.get();
-    } else {
-      haystack = [selectorOrHaystack];
-    }
-
-    return this._make(haystack.filter(function(elem) {
-      var idx, len;
-      for (idx = 0, len = this.length; idx < len; ++idx) {
-        if (contains(this[idx], elem)) {
-          return true;
-        }
-      }
-    }, this));
-  }
-
-  var options = {__proto__: this.options, context: this.toArray()};
-
-  return this._make(select(selectorOrHaystack, elems, options));
-};
-
-// Get the parent of each element in the current set of matched elements,
-// optionally filtered by a selector.
-exports.parent = function(selector) {
-  var set = [];
-
-  domEach(this, function(idx, elem) {
-    var parentElem = elem.parent;
-    if (parentElem && set.indexOf(parentElem) < 0) {
-      set.push(parentElem);
-    }
-  });
-
-  if (arguments.length) {
-    set = exports.filter.call(set, selector, this);
-  }
-
-  return this._make(set);
-};
-
-exports.parents = function(selector) {
-  var parentNodes = [];
-
-  // When multiple DOM elements are in the original set, the resulting set will
-  // be in *reverse* order of the original elements as well, with duplicates
-  // removed.
-  this.get().reverse().forEach(function(elem) {
-    traverseParents(this, elem.parent, selector, Infinity)
-      .forEach(function(node) {
-        if (parentNodes.indexOf(node) === -1) {
-          parentNodes.push(node);
-        }
-      }
-    );
-  }, this);
-
-  return this._make(parentNodes);
-};
-
-exports.parentsUntil = function(selector, filter) {
-  var parentNodes = [], untilNode, untilNodes;
-
-  if (typeof selector === 'string') {
-    untilNode = select(selector, this.parents().toArray(), this.options)[0];
-  } else if (selector && selector.cheerio) {
-    untilNodes = selector.toArray();
-  } else if (selector) {
-    untilNode = selector;
-  }
-
-  // When multiple DOM elements are in the original set, the resulting set will
-  // be in *reverse* order of the original elements as well, with duplicates
-  // removed.
-
-  this.toArray().reverse().forEach(function(elem) {
-    while ((elem = elem.parent)) {
-      if ((untilNode && elem !== untilNode) ||
-        (untilNodes && untilNodes.indexOf(elem) === -1) ||
-        (!untilNode && !untilNodes)) {
-        if (isTag(elem) && parentNodes.indexOf(elem) === -1) { 
parentNodes.push(elem); }
-      } else {
-        break;
-      }
-    }
-  }, this);
-
-  return this._make(filter ? select(filter, parentNodes, this.options) : 
parentNodes);
-};
-
-// For each element in the set, get the first element that matches the selector
-// by testing the element itself and traversing up through its ancestors in the
-// DOM tree.
-exports.closest = function(selector) {
-  var set = [];
-
-  if (!selector) {
-    return this._make(set);
-  }
-
-  domEach(this, function(idx, elem) {
-    var closestElem = traverseParents(this, elem, selector, 1)[0];
-
-    // Do not add duplicate elements to the set
-    if (closestElem && set.indexOf(closestElem) < 0) {
-      set.push(closestElem);
-    }
-  }.bind(this));
-
-  return this._make(set);
-};
-
-exports.next = function(selector) {
-  if (!this[0]) { return this; }
-  var elems = [];
-
-  _.forEach(this, function(elem) {
-    while ((elem = elem.next)) {
-      if (isTag(elem)) {
-        elems.push(elem);
-        return;
-      }
-    }
-  });
-
-  return selector ?
-    exports.filter.call(elems, selector, this) :
-    this._make(elems);
-};
-
-exports.nextAll = function(selector) {
-  if (!this[0]) { return this; }
-  var elems = [];
-
-  _.forEach(this, function(elem) {
-    while ((elem = elem.next)) {
-      if (isTag(elem) && elems.indexOf(elem) === -1) {
-        elems.push(elem);
-      }
-    }
-  });
-
-  return selector ?
-    exports.filter.call(elems, selector, this) :
-    this._make(elems);
-};
-
-exports.nextUntil = function(selector, filterSelector) {
-  if (!this[0]) { return this; }
-  var elems = [], untilNode, untilNodes;
-
-  if (typeof selector === 'string') {
-    untilNode = select(selector, this.nextAll().get(), this.options)[0];
-  } else if (selector && selector.cheerio) {
-    untilNodes = selector.get();
-  } else if (selector) {
-    untilNode = selector;
-  }
-
-  _.forEach(this, function(elem) {
-    while ((elem = elem.next)) {
-      if ((untilNode && elem !== untilNode) ||
-        (untilNodes && untilNodes.indexOf(elem) === -1) ||
-        (!untilNode && !untilNodes)) {
-        if (isTag(elem) && elems.indexOf(elem) === -1) {
-          elems.push(elem);
-        }
-      } else {
-        break;
-      }
-    }
-  });
-
-  return filterSelector ?
-    exports.filter.call(elems, filterSelector, this) :
-    this._make(elems);
-};
-
-exports.prev = function(selector) {
-  if (!this[0]) { return this; }
-  var elems = [];
-
-  _.forEach(this, function(elem) {
-    while ((elem = elem.prev)) {
-      if (isTag(elem)) {
-        elems.push(elem);
-        return;
-      }
-    }
-  });
-
-  return selector ?
-    exports.filter.call(elems, selector, this) :
-    this._make(elems);
-};
-
-exports.prevAll = function(selector) {
-  if (!this[0]) { return this; }
-  var elems = [];
-
-  _.forEach(this, function(elem) {
-    while ((elem = elem.prev)) {
-      if (isTag(elem) && elems.indexOf(elem) === -1) {
-        elems.push(elem);
-      }
-    }
-  });
-
-  return selector ?
-    exports.filter.call(elems, selector, this) :
-    this._make(elems);
-};
-
-exports.prevUntil = function(selector, filterSelector) {
-  if (!this[0]) { return this; }
-  var elems = [], untilNode, untilNodes;
-
-  if (typeof selector === 'string') {
-    untilNode = select(selector, this.prevAll().get(), this.options)[0];
-  } else if (selector && selector.cheerio) {
-    untilNodes = selector.get();
-  } else if (selector) {
-    untilNode = selector;
-  }
-
-  _.forEach(this, function(elem) {
-    while ((elem = elem.prev)) {
-      if ((untilNode && elem !== untilNode) ||
-        (untilNodes && untilNodes.indexOf(elem) === -1) ||
-        (!untilNode && !untilNodes)) {
-        if (isTag(elem) && elems.indexOf(elem) === -1) {
-          elems.push(elem);
-        }
-      } else {
-        break;
-      }
-    }
-  });
-
-  return filterSelector ?
-    exports.filter.call(elems, filterSelector, this) :
-    this._make(elems);
-};
-
-exports.siblings = function(selector) {
-  var parent = this.parent();
-
-  var elems = _.filter(
-    parent ? parent.children() : this.siblingsAndMe(),
-    _.bind(function(elem) { return isTag(elem) && !this.is(elem); }, this)
-  );
-
-  if (selector !== undefined) {
-    return exports.filter.call(elems, selector, this);
-  } else {
-    return this._make(elems);
-  }
-};
-
-exports.children = function(selector) {
-
-  var elems = _.reduce(this, function(memo, elem) {
-    return memo.concat(_.filter(elem.children, isTag));
-  }, []);
-
-  if (selector === undefined) return this._make(elems);
-
-  return exports.filter.call(elems, selector, this);
-};
-
-exports.contents = function() {
-  return this._make(_.reduce(this, function(all, elem) {
-    all.push.apply(all, elem.children);
-    return all;
-  }, []));
-};
-
-exports.each = function(fn) {
-  var i = 0, len = this.length;
-  while (i < len && fn.call(this[i], i, this[i]) !== false) ++i;
-  return this;
-};
-
-exports.map = function(fn) {
-  return this._make(_.reduce(this, function(memo, el, i) {
-    var val = fn.call(el, i, el);
-    return val == null ? memo : memo.concat(val);
-  }, []));
-};
-
-var makeFilterMethod = function(filterFn) {
-  return function(match, container) {
-    var testFn;
-    container = container || this;
-
-    if (typeof match === 'string') {
-      testFn = select.compile(match, container.options);
-    } else if (typeof match === 'function') {
-      testFn = function(el, i) {
-        return match.call(el, i, el);
-      };
-    } else if (match.cheerio) {
-      testFn = match.is.bind(match);
-    } else {
-      testFn = function(el) {
-        return match === el;
-      };
-    }
-
-    return container._make(filterFn(this, testFn));
-  };
-};
-
-exports.filter = makeFilterMethod(_.filter);
-exports.not = makeFilterMethod(_.reject);
-
-exports.has = function(selectorOrHaystack) {
-  var that = this;
-  return exports.filter.call(this, function() {
-    return that._make(this).find(selectorOrHaystack).length > 0;
-  });
-};
-
-exports.first = function() {
-  return this.length > 1 ? this._make(this[0]) : this;
-};
-
-exports.last = function() {
-  return this.length > 1 ? this._make(this[this.length - 1]) : this;
-};
-
-// Reduce the set of matched elements to the one at the specified index.
-exports.eq = function(i) {
-  i = +i;
-
-  // Use the first identity optimization if possible
-  if (i === 0 && this.length <= 1) return this;
-
-  if (i < 0) i = this.length + i;
-  return this[i] ? this._make(this[i]) : this._make([]);
-};
-
-// Retrieve the DOM elements matched by the jQuery object.
-exports.get = function(i) {
-  if (i == null) {
-    return Array.prototype.slice.call(this);
-  } else {
-    return this[i < 0 ? (this.length + i) : i];
-  }
-};
-
-// Search for a given element from among the matched elements.
-exports.index = function(selectorOrNeedle) {
-  var $haystack, needle;
-
-  if (arguments.length === 0) {
-    $haystack = this.parent().children();
-    needle = this[0];
-  } else if (typeof selectorOrNeedle === 'string') {
-    $haystack = this._make(selectorOrNeedle);
-    needle = this[0];
-  } else {
-    $haystack = this;
-    needle = selectorOrNeedle.cheerio ? selectorOrNeedle[0] : selectorOrNeedle;
-  }
-
-  return $haystack.get().indexOf(needle);
-};
-
-exports.slice = function() {
-  return this._make([].slice.apply(this, arguments));
-};
-
-function traverseParents(self, elem, selector, limit) {
-  var elems = [];
-  while (elem && elems.length < limit) {
-    if (!selector || exports.filter.call([elem], selector, self).length) {
-      elems.push(elem);
-    }
-    elem = elem.parent;
-  }
-  return elems;
-}
-
-// End the most recent filtering operation in the current chain and return the
-// set of matched elements to its previous state.
-exports.end = function() {
-  return this.prevObject || this._make([]);
-};
-
-exports.add = function(other, context) {
-  var selection = this._make(other, context);
-  var contents = uniqueSort(selection.get().concat(this.get()));
-
-  for (var i = 0; i < contents.length; ++i) {
-    selection[i] = contents[i];
-  }
-  selection.length = contents.length;
-
-  return selection;
-};
-
-// Add the previous set of elements on the stack to the current set, optionally
-// filtered by a selector.
-exports.addBack = function(selector) {
-  return this.add(
-    arguments.length ? this.prevObject.filter(selector) : this.prevObject
-  );
-};

http://git-wip-us.apache.org/repos/asf/incubator-griffin-site/blob/ca1c37a7/node_modules/cheerio/lib/cheerio.js
----------------------------------------------------------------------
diff --git a/node_modules/cheerio/lib/cheerio.js 
b/node_modules/cheerio/lib/cheerio.js
deleted file mode 100644
index 5b1156a..0000000
--- a/node_modules/cheerio/lib/cheerio.js
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
-  Module dependencies
-*/
-
-var parse = require('./parse'),
-    isHtml = require('./utils').isHtml,
-    _ = require('lodash');
-
-/*
- * The API
- */
-
-var api = [
-  require('./api/attributes'),
-  require('./api/traversing'),
-  require('./api/manipulation'),
-  require('./api/css'),
-  require('./api/forms')
-];
-
-/*
- * Instance of cheerio
- */
-
-var Cheerio = module.exports = function(selector, context, root, options) {
-  if (!(this instanceof Cheerio)) return new Cheerio(selector, context, root, 
options);
-
-  this.options = _.defaults(options || {}, this.options);
-
-  // $(), $(null), $(undefined), $(false)
-  if (!selector) return this;
-
-  if (root) {
-    if (typeof root === 'string') root = parse(root, this.options);
-    this._root = Cheerio.call(this, root);
-  }
-
-  // $($)
-  if (selector.cheerio) return selector;
-
-  // $(dom)
-  if (isNode(selector))
-    selector = [selector];
-
-  // $([dom])
-  if (Array.isArray(selector)) {
-    _.forEach(selector, _.bind(function(elem, idx) {
-      this[idx] = elem;
-    }, this));
-    this.length = selector.length;
-    return this;
-  }
-
-  // $(<html>)
-  if (typeof selector === 'string' && isHtml(selector)) {
-    return Cheerio.call(this, parse(selector, this.options).children);
-  }
-
-  // If we don't have a context, maybe we have a root, from loading
-  if (!context) {
-    context = this._root;
-  } else if (typeof context === 'string') {
-    if (isHtml(context)) {
-      // $('li', '<ul>...</ul>')
-      context = parse(context, this.options);
-      context = Cheerio.call(this, context);
-    } else {
-      // $('li', 'ul')
-      selector = [context, selector].join(' ');
-      context = this._root;
-    }
-  // $('li', node), $('li', [nodes])
-  } else if (!context.cheerio) {
-    context = Cheerio.call(this, context);
-  }
-
-  // If we still don't have a context, return
-  if (!context) return this;
-
-  // #id, .class, tag
-  return context.find(selector);
-};
-
-/**
- * Mix in `static`
- */
-
-_.extend(Cheerio, require('./static'));
-
-/*
- * Set a signature of the object
- */
-
-Cheerio.prototype.cheerio = '[cheerio object]';
-
-/*
- * Cheerio default options
- */
-
-Cheerio.prototype.options = {
-  withDomLvl1: true,
-  normalizeWhitespace: false,
-  xmlMode: false,
-  decodeEntities: true
-};
-
-/*
- * Make cheerio an array-like object
- */
-
-Cheerio.prototype.length = 0;
-Cheerio.prototype.splice = Array.prototype.splice;
-
-/*
- * Make a cheerio object
- *
- * @api private
- */
-
-Cheerio.prototype._make = function(dom, context) {
-  var cheerio = new this.constructor(dom, context, this._root, this.options);
-  cheerio.prevObject = this;
-  return cheerio;
-};
-
-/**
- * Turn a cheerio object into an array
- */
-
-Cheerio.prototype.toArray = function() {
-  return this.get();
-};
-
-/**
- * Plug in the API
- */
-api.forEach(function(mod) {
-  _.extend(Cheerio.prototype, mod);
-});
-
-var isNode = function(obj) {
-  return obj.name || obj.type === 'text' || obj.type === 'comment';
-};

http://git-wip-us.apache.org/repos/asf/incubator-griffin-site/blob/ca1c37a7/node_modules/cheerio/lib/parse.js
----------------------------------------------------------------------
diff --git a/node_modules/cheerio/lib/parse.js 
b/node_modules/cheerio/lib/parse.js
deleted file mode 100644
index b06245d..0000000
--- a/node_modules/cheerio/lib/parse.js
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
-  Module Dependencies
-*/
-var htmlparser = require('htmlparser2');
-
-/*
-  Parser
-*/
-exports = module.exports = function(content, options) {
-  var dom = exports.evaluate(content, options),
-      // Generic root element
-      root = exports.evaluate('<root></root>', options)[0];
-
-  root.type = 'root';
-
-  // Update the dom using the root
-  exports.update(dom, root);
-
-  return root;
-};
-
-exports.evaluate = function(content, options) {
-  // options = options || $.fn.options;
-
-  var dom;
-
-  if (typeof content === 'string' || Buffer.isBuffer(content)) {
-    dom = htmlparser.parseDOM(content, options);
-  } else {
-    dom = content;
-  }
-
-  return dom;
-};
-
-/*
-  Update the dom structure, for one changed layer
-*/
-exports.update = function(arr, parent) {
-  // normalize
-  if (!Array.isArray(arr)) arr = [arr];
-
-  // Update parent
-  if (parent) {
-    parent.children = arr;
-  } else {
-    parent = null;
-  }
-
-  // Update neighbors
-  for (var i = 0; i < arr.length; i++) {
-    var node = arr[i];
-
-    // Cleanly remove existing nodes from their previous structures.
-    var oldParent = node.parent || node.root,
-        oldSiblings = oldParent && oldParent.children;
-    if (oldSiblings && oldSiblings !== arr) {
-      oldSiblings.splice(oldSiblings.indexOf(node), 1);
-      if (node.prev) {
-        node.prev.next = node.next;
-      }
-      if (node.next) {
-        node.next.prev = node.prev;
-      }
-    }
-
-    if (parent) {
-      node.prev = arr[i - 1] || null;
-      node.next = arr[i + 1] || null;
-    } else {
-      node.prev = node.next = null;
-    }
-
-    if (parent && parent.type === 'root') {
-      node.root = parent;
-      node.parent = null;
-    } else {
-      node.root = null;
-      node.parent = parent;
-    }
-  }
-
-  return parent;
-};
-
-// module.exports = $.extend(exports);

http://git-wip-us.apache.org/repos/asf/incubator-griffin-site/blob/ca1c37a7/node_modules/cheerio/lib/static.js
----------------------------------------------------------------------
diff --git a/node_modules/cheerio/lib/static.js 
b/node_modules/cheerio/lib/static.js
deleted file mode 100644
index 88f9536..0000000
--- a/node_modules/cheerio/lib/static.js
+++ /dev/null
@@ -1,182 +0,0 @@
-/**
- * Module dependencies
- */
-
-var select = require('css-select'),
-    parse = require('./parse'),
-    serialize = require('dom-serializer'),
-    _ = require('lodash');
-
-/**
- * $.load(str)
- */
-
-exports.load = function(content, options) {
-  var Cheerio = require('./cheerio');
-
-  options = _.defaults(options || {}, Cheerio.prototype.options);
-
-  var root = parse(content, options);
-
-  var initialize = function(selector, context, r, opts) {
-    if (!(this instanceof initialize)) {
-      return new initialize(selector, context, r, opts);
-    }
-    opts = _.defaults(opts || {}, options);
-    return Cheerio.call(this, selector, context, r || root, opts);
-  };
-
-  // Ensure that selections created by the "loaded" `initialize` function are
-  // true Cheerio instances.
-  initialize.prototype = Object.create(Cheerio.prototype);
-  initialize.prototype.constructor = initialize;
-
-  // Mimic jQuery's prototype alias for plugin authors.
-  initialize.fn = initialize.prototype;
-
-  // Keep a reference to the top-level scope so we can chain methods that 
implicitly 
-  // resolve selectors; e.g. $("<span>").(".bar"), which otherwise loses ._root
-  initialize.prototype._originalRoot = root;
-
-  // Add in the static methods
-  _.merge(initialize, exports);
-
-  // Add in the root
-  initialize._root = root;
-  // store options
-  initialize._options = options;
-
-  return initialize;
-};
-
-/*
-* Helper function
-*/
-
-function render(that, dom, options) {
-  if (!dom) {
-    if (that._root && that._root.children) {
-      dom = that._root.children;
-    } else {
-      return '';
-    }
-  } else if (typeof dom === 'string') {
-    dom = select(dom, that._root, options);
-  }
-
-  return serialize(dom, options);
-}
-
-/**
- * $.html([selector | dom], [options])
- */
-
-exports.html = function(dom, options) {
-  var Cheerio = require('./cheerio');
-
-  // be flexible about parameters, sometimes we call html(),
-  // with options as only parameter
-  // check dom argument for dom element specific properties
-  // assume there is no 'length' or 'type' properties in the options object
-  if (Object.prototype.toString.call(dom) === '[object Object]' && !options && 
!('length' in dom) && !('type' in dom))
-  {
-    options = dom;
-    dom = undefined;
-  }
-
-  // sometimes $.html() used without preloading html
-  // so fallback non existing options to the default ones
-  options = _.defaults(options || {}, this._options, 
Cheerio.prototype.options);
-
-  return render(this, dom, options);
-};
-
-/**
- * $.xml([selector | dom])
- */
-
-exports.xml = function(dom) {
-  var options = _.defaults({xmlMode: true}, this._options);
-
-  return render(this, dom, options);
-};
-
-/**
- * $.text(dom)
- */
-
-exports.text = function(elems) {
-  if (!elems) return '';
-
-  var ret = '',
-      len = elems.length,
-      elem;
-
-  for (var i = 0; i < len; i++) {
-    elem = elems[i];
-    if (elem.type === 'text') ret += elem.data;
-    else if (elem.children && elem.type !== 'comment') {
-      ret += exports.text(elem.children);
-    }
-  }
-
-  return ret;
-};
-
-/**
- * $.parseHTML(data [, context ] [, keepScripts ])
- * Parses a string into an array of DOM nodes. The `context` argument has no
- * meaning for Cheerio, but it is maintained for API compatibility with jQuery.
- */
-exports.parseHTML = function(data, context, keepScripts) {
-  var parsed;
-
-  if (!data || typeof data !== 'string') {
-    return null;
-  }
-
-  if (typeof context === 'boolean') {
-    keepScripts = context;
-  }
-
-  parsed = this.load(data);
-  if (!keepScripts) {
-    parsed('script').remove();
-  }
-
-  // The `children` array is used by Cheerio internally to group elements that
-  // share the same parents. When nodes created through `parseHTML` are
-  // inserted into previously-existing DOM structures, they will be removed
-  // from the `children` array. The results of `parseHTML` should remain
-  // constant across these operations, so a shallow copy should be returned.
-  return parsed.root()[0].children.slice();
-};
-
-/**
- * $.root()
- */
-exports.root = function() {
-  return this(this._root);
-};
-
-/**
- * $.contains()
- */
-exports.contains = function(container, contained) {
-
-  // According to the jQuery API, an element does not "contain" itself
-  if (contained === container) {
-    return false;
-  }
-
-  // Step up the descendants, stopping when the root element is reached
-  // (signaled by `.parent` returning a reference to the same object)
-  while (contained && contained !== contained.parent) {
-    contained = contained.parent;
-    if (contained === container) {
-      return true;
-    }
-  }
-
-  return false;
-};

http://git-wip-us.apache.org/repos/asf/incubator-griffin-site/blob/ca1c37a7/node_modules/cheerio/lib/utils.js
----------------------------------------------------------------------
diff --git a/node_modules/cheerio/lib/utils.js 
b/node_modules/cheerio/lib/utils.js
deleted file mode 100644
index baa62fc..0000000
--- a/node_modules/cheerio/lib/utils.js
+++ /dev/null
@@ -1,83 +0,0 @@
-var parse = require('./parse'),
-    render = require('dom-serializer');
-
-/**
- * HTML Tags
- */
-
-var tags = { tag: true, script: true, style: true };
-
-/**
- * Check if the DOM element is a tag
- *
- * isTag(type) includes <script> and <style> tags
- */
-
-exports.isTag = function(type) {
-  if (type.type) type = type.type;
-  return tags[type] || false;
-};
-
-/**
- * Convert a string to camel case notation.
- * @param  {String} str String to be converted.
- * @return {String}     String in camel case notation.
- */
-
-exports.camelCase = function(str) {
-  return str.replace(/[_.-](\w|$)/g, function(_, x) {
-    return x.toUpperCase();
-  });
-};
-
-/**
- * Convert a string from camel case to "CSS case", where word boundaries are
- * described by hyphens ("-") and all characters are lower-case.
- * @param  {String} str String to be converted.
- * @return {string}     String in "CSS case".
- */
-exports.cssCase = function(str) {
-  return str.replace(/[A-Z]/g, '-$&').toLowerCase();
-};
-
-/**
- * Iterate over each DOM element without creating intermediary Cheerio 
instances.
- *
- * This is indented for use internally to avoid otherwise unnecessary memory 
pressure introduced
- * by _make.
- */
-
-exports.domEach = function(cheerio, fn) {
-  var i = 0, len = cheerio.length;
-  while (i < len && fn.call(cheerio, i, cheerio[i]) !== false) ++i;
-  return cheerio;
-};
-
-/**
- * Create a deep copy of the given DOM structure by first rendering it to a
- * string and then parsing the resultant markup.
- *
- * @argument {Object} dom - The htmlparser2-compliant DOM structure
- * @argument {Object} options - The parsing/rendering options
- */
-exports.cloneDom = function(dom, options) {
-  return parse(render(dom, options), options).children;
-};
-
-/*
- * A simple way to check for HTML strings or ID strings
- */
-
-var quickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/;
-
-/*
- * Check if string is HTML
- */
-exports.isHtml = function(str) {
-  // Faster than running regex, if str starts with `<` and ends with `>`, 
assume it's HTML
-  if (str.charAt(0) === '<' && str.charAt(str.length - 1) === '>' && 
str.length >= 3) return true;
-
-  // Run the regex
-  var match = quickExpr.exec(str);
-  return !!(match && match[1]);
-};

http://git-wip-us.apache.org/repos/asf/incubator-griffin-site/blob/ca1c37a7/node_modules/cheerio/package.json
----------------------------------------------------------------------
diff --git a/node_modules/cheerio/package.json 
b/node_modules/cheerio/package.json
deleted file mode 100644
index 511edae..0000000
--- a/node_modules/cheerio/package.json
+++ /dev/null
@@ -1,126 +0,0 @@
-{
-  "_args": [
-    [
-      {
-        "raw": "cheerio@^0.20.0",
-        "scope": null,
-        "escapedName": "cheerio",
-        "name": "cheerio",
-        "rawSpec": "^0.20.0",
-        "spec": ">=0.20.0 <0.21.0",
-        "type": "range"
-      },
-      "/Users/yueguo/repo.site/incubator-griffin-site/node_modules/hexo"
-    ]
-  ],
-  "_from": "cheerio@>=0.20.0 <0.21.0",
-  "_id": "cheerio@0.20.0",
-  "_inCache": true,
-  "_installable": true,
-  "_location": "/cheerio",
-  "_nodeVersion": "5.5.0",
-  "_npmUser": {
-    "name": "feedic",
-    "email": "m...@feedic.com"
-  },
-  "_npmVersion": "3.6.0",
-  "_phantomChildren": {},
-  "_requested": {
-    "raw": "cheerio@^0.20.0",
-    "scope": null,
-    "escapedName": "cheerio",
-    "name": "cheerio",
-    "rawSpec": "^0.20.0",
-    "spec": ">=0.20.0 <0.21.0",
-    "type": "range"
-  },
-  "_requiredBy": [
-    "/hexo"
-  ],
-  "_resolved": "https://registry.npmjs.org/cheerio/-/cheerio-0.20.0.tgz";,
-  "_shasum": "5c710f2bab95653272842ba01c6ea61b3545ec35",
-  "_shrinkwrap": null,
-  "_spec": "cheerio@^0.20.0",
-  "_where": "/Users/yueguo/repo.site/incubator-griffin-site/node_modules/hexo",
-  "author": {
-    "name": "Matt Mueller",
-    "email": "mattmue...@gmail.com",
-    "url": "mat.io"
-  },
-  "bugs": {
-    "url": "https://github.com/cheeriojs/cheerio/issues";
-  },
-  "dependencies": {
-    "css-select": "~1.2.0",
-    "dom-serializer": "~0.1.0",
-    "entities": "~1.1.1",
-    "htmlparser2": "~3.8.1",
-    "jsdom": "^7.0.2",
-    "lodash": "^4.1.0"
-  },
-  "description": "Tiny, fast, and elegant implementation of core jQuery 
designed specifically for the server",
-  "devDependencies": {
-    "benchmark": "~1.0.0",
-    "coveralls": "~2.10",
-    "expect.js": "~0.3.1",
-    "istanbul": "~0.2",
-    "jshint": "~2.5.1",
-    "mocha": "*",
-    "xyz": "~0.5.0"
-  },
-  "directories": {},
-  "dist": {
-    "shasum": "5c710f2bab95653272842ba01c6ea61b3545ec35",
-    "tarball": "https://registry.npmjs.org/cheerio/-/cheerio-0.20.0.tgz";
-  },
-  "engines": {
-    "node": ">= 0.6"
-  },
-  "files": [
-    "index.js",
-    "lib"
-  ],
-  "gitHead": "c3ec1cd7bff41da0033bdc45375d77844f0f81c0",
-  "homepage": "https://github.com/cheeriojs/cheerio#readme";,
-  "keywords": [
-    "htmlparser",
-    "jquery",
-    "selector",
-    "scraper",
-    "parser",
-    "html"
-  ],
-  "license": "MIT",
-  "main": "./index.js",
-  "maintainers": [
-    {
-      "name": "mattmueller",
-      "email": "mattmue...@gmail.com"
-    },
-    {
-      "name": "davidchambers",
-      "email": "d...@davidchambers.me"
-    },
-    {
-      "name": "jugglinmike",
-      "email": "m...@mikepennisi.com"
-    },
-    {
-      "name": "feedic",
-      "email": "m...@feedic.com"
-    }
-  ],
-  "name": "cheerio",
-  "optionalDependencies": {
-    "jsdom": "^7.0.2"
-  },
-  "readme": "ERROR: No README data found!",
-  "repository": {
-    "type": "git",
-    "url": "git://github.com/cheeriojs/cheerio.git"
-  },
-  "scripts": {
-    "test": "make test"
-  },
-  "version": "0.20.0"
-}

http://git-wip-us.apache.org/repos/asf/incubator-griffin-site/blob/ca1c37a7/node_modules/chokidar/CHANGELOG.md
----------------------------------------------------------------------
diff --git a/node_modules/chokidar/CHANGELOG.md 
b/node_modules/chokidar/CHANGELOG.md
deleted file mode 100644
index 0874dee..0000000
--- a/node_modules/chokidar/CHANGELOG.md
+++ /dev/null
@@ -1,268 +0,0 @@
-# Chokidar 1.6.0 (Jun 22, 2016)
-* Added ability for force `usePolling` mode by setting `CHOKIDAR_USEPOLLING`
-  env variable
-
-# Chokidar 1.5.2 (Jun 7, 2016)
-* Fix missing `addDir` events when using `cwd` and `alwaysStat` options
-* Fix missing `add` events for files within a renamed directory
-
-# Chokidar 1.5.1 (May 20, 2016)
-* To help prevent exhaustion of FSEvents system limitations, consolidate watch
-  instances to the common parent upon detection of separate watch instances on
-  many siblings
-
-# Chokidar 1.5.0 (May 10, 2016)
-* Make debounce delay setting used with `atomic: true` user-customizable
-* Fixes and improvements to `awaitWriteFinish` features
-
-# Chokidar 1.4.3 (Feb 26, 2016)
-* Update async-each dependency to ^1.0.0
-
-# Chokidar 1.4.2 (Dec 30, 2015)
-* Now correctly emitting `stats` with `awaitWriteFinish` option.
-
-# Chokidar 1.4.1 (Dec 9, 2015)
-* The watcher could now be correctly subclassed with ES6 class syntax.
-
-# Chokidar 1.4.0 (Dec 3, 2015)
-* Add `.getWatched()` method, exposing all file system entries being watched
-* Apply `awaitWriteFinish` methodology to `change` events (in addition to 
`add`)
-* Fix handling of symlinks within glob paths (#293)
-* Fix `addDir` and `unlinkDir` events under globs (#337, #401)
-* Fix issues with `.unwatch()` (#374, #403)
-
-# Chokidar 1.3.0 (Nov 18, 2015)
-* Improve `awaitWriteFinish` option behavior
-* Fix some `cwd` option behavior on Windows
-* `awaitWriteFinish` and `cwd` are now compatible
-* Fix some race conditions.
-* #379: Recreating deleted directory doesn't trigger event
-* When adding a previously-deleted file, emit 'add', not 'change'
-
-# Chokidar 1.2.0 (Oct 1, 2015)
-* Allow nested arrays of paths to be provided to `.watch()` and `.add()`
-* Add `awaitWriteFinish` option
-
-# Chokidar 1.1.0 (Sep 23, 2015)
-* Dependency updates including fsevents@1.0.0, improving installation
-
-# Chokidar 1.0.6 (Sep 18, 2015)
-* Fix issue with `.unwatch()` method and relative paths
-
-# Chokidar 1.0.5 (Jul 20, 2015)
-* Fix regression with regexes/fns using in `ignored`
-
-# Chokidar 1.0.4 (Jul 15, 2015)
-* Fix bug with `ignored` files/globs while `cwd` option is set
-
-# Chokidar 1.0.3 (Jun 4, 2015)
-* Fix race issue with `alwaysStat` option and removed files
-
-# Chokidar 1.0.2 (May 30, 2015)
-* Fix bug with absolute paths and ENAMETOOLONG error
-
-# Chokidar 1.0.1 (Apr 8, 2015)
-* Fix bug with `.close()` method in `fs.watch` mode with `persistent: false`
-  option
-
-# Chokidar 1.0.0 (Apr 7, 2015)
-* Glob support! Use globs in `watch`, `add`, and `unwatch` methods
-* Comprehensive symlink support
-* New `unwatch` method to turn off watching of previously watched paths
-* More flexible `ignored` option allowing regex, function, glob, or array
-  courtesy of [anymatch](https://github.com/es128/anymatch)
-* New `cwd` option to set base dir from which relative paths are derived
-* New `depth` option for limiting recursion
-* New `alwaysStat` option to ensure
-  [`fs.Stats`](https://nodejs.org/api/fs.html#fs_class_fs_stats) gets passed
-  with every add/change event
-* New `ready` event emitted when initial fs tree scan is done and watcher is
-  ready for changes
-* New `raw` event exposing data and events from the lower-level watch modules
-* New `followSymlinks` option to impact whether symlinks' targets or the 
symlink
-  files themselves are watched
-* New `atomic` option for normalizing artifacts from text editors that use
-  atomic write methods
-* Ensured watcher's stability with lots of bugfixes.
-
-# Chokidar 0.12.6 (Jan 6, 2015)
-* Fix bug which breaks `persistent: false` mode when change events occur
-
-# Chokidar 0.12.5 (Dec 17, 2014)
-* Fix bug with matching parent path detection for fsevents instance sharing
-* Fix bug with ignored watch path in nodefs modes
-
-# Chokidar 0.12.4 (Dec 14, 2014)
-* Fix bug in `fs.watch` mode that caused watcher to leak into `cwd`
-* Fix bug preventing ready event when there are symlinks to ignored paths
-
-# Chokidar 0.12.3 (Dec 13, 2014)
-* Fix handling of special files such as named pipes and sockets
-
-# Chokidar 0.12.2 (Dec 12, 2014)
-* Fix recursive symlink handling and some other path resolution problems
-
-# Chokidar 0.12.1 (Dec 10, 2014)
-* Fix a case where file symlinks were not followed properly
-
-# Chokidar 0.12.0 (Dec 8, 2014)
-* Symlink support
-  * Add `followSymlinks` option, which defaults to `true`
-* Change default watch mode on Linux to non-polling `fs.watch`
-* Add `atomic` option to normalize events from editors using atomic writes
-  * Particularly Vim and Sublime
-* Add `raw` event which exposes data from the underlying watch method
-
-# Chokidar 0.11.1 (Nov 19, 2014)
-* Fix a bug where an error is thrown when `fs.watch` instantiation fails
-
-# Chokidar 0.11.0 (Nov 16, 2014)
-* Add a `ready` event, which is emitted after initial file scan completes
-* Fix issue with options keys passed in defined as `undefined`
-* Rename some internal `FSWatcher` properties to indicate they're private
-
-# Chokidar 0.10.9 (Nov 15, 2014)
-* Fix some leftover issues from adding watcher reuse
-
-# Chokidar 0.10.8 (Nov 14, 2014)
-* Remove accidentally committed/published `console.log` statement.
-* Sry 'bout that :crying_cat_face:
-
-# Chokidar 0.10.7 (Nov 14, 2014)
-* Apply watcher reuse methodology to `fs.watch` and `fs.watchFile` as well
-
-# Chokidar 0.10.6 (Nov 12, 2014)
-* More efficient creation/reuse of FSEvents instances to avoid system limits
-* Reduce simultaneous FSEvents instances allowed in a process
-* Handle errors thrown by `fs.watch` upon invocation
-
-# Chokidar 0.10.5 (Nov 6, 2014)
-* Limit number of simultaneous FSEvents instances (fall back to other methods)
-* Prevent some cases of EMFILE errors during initialization
-* Fix ignored files emitting events in some fsevents-mode circumstances
-
-# Chokidar 0.10.4 (Nov 5, 2014)
-* Bump fsevents dependency to ~0.3.1
-  * Should resolve build warnings and `npm rebuild` on non-Macs
-
-# Chokidar 0.10.3 (Oct 28, 2014)
-* Fix removed dir emitting as `unlink` instead of `unlinkDir`
-* Fix issues with file changing to dir or vice versa (gh-165)
-* Fix handling of `ignored` option in fsevents mode
-
-# Chokidar 0.10.2 (Oct 23, 2014)
-* Improve individual file watching
-* Fix fsevents keeping process alive when `persistent: false`
-
-# Chokidar 0.10.1 (19 October 2014)
-* Improve handling of text editor atomic writes
-
-# Chokidar 0.10.0 (Oct 18, 2014)
-* Many stability and consistency improvements
-* Resolve many cases of duplicate or wrong events
-* Correct for fsevents inconsistencies
-* Standardize handling of errors and relative paths
-* Fix issues with watching `./`
-
-# Chokidar 0.9.0 (Sep 25, 2014)
-* Updated fsevents to 0.3
-* Update per-system defaults
-* Fix issues with closing chokidar instance
-* Fix duplicate change events on win32
-
-# Chokidar 0.8.2 (Mar 26, 2014)
-* Fixed npm issues related to fsevents dep.
-* Updated fsevents to 0.2.
-
-# Chokidar 0.8.1 (Dec 16, 2013)
-* Optional deps are now truly optional on windows and
-  linux.
-* Rewritten in JS, again.
-* Fixed some FSEvents-related bugs.
-
-# Chokidar 0.8.0 (Nov 29, 2013)
-* Added ultra-fast low-CPU OS X file watching with FSEvents.
-  It is enabled by default.
-* Added `addDir` and `unlinkDir` events.
-* Polling is now disabled by default on all platforms.
-
-# Chokidar 0.7.1 (Nov 18, 2013)
-* `Watcher#close` now also removes all event listeners.
-
-# Chokidar 0.7.0 (Oct 22, 2013)
-* When `options.ignored` is two-argument function, it will
-  also be called after stating the FS, with `stats` argument.
-* `unlink` is no longer emitted on directories.
-
-# Chokidar 0.6.3 (Aug 12, 2013)
-* Added `usePolling` option (default: `true`).
-  When `false`, chokidar will use `fs.watch` as backend.
-  `fs.watch` is much faster, but not like super reliable.
-
-# Chokidar 0.6.2 (Mar 19, 2013)
-* Fixed watching initially empty directories with `ignoreInitial` option.
-
-# Chokidar 0.6.1 (Mar 19, 2013)
-* Added node.js 0.10 support.
-
-# Chokidar 0.6.0 (Mar 10, 2013)
-* File attributes (stat()) are now passed to `add` and `change` events as 
second
-  arguments.
-* Changed default polling interval for binary files to 300ms.
-
-# Chokidar 0.5.3 (Jan 13, 2013)
-* Removed emitting of `change` events before `unlink`.
-
-# Chokidar 0.5.2 (Jan 13, 2013)
-* Removed postinstall script to prevent various npm bugs.
-
-# Chokidar 0.5.1 (Jan 6, 2013)
-* When starting to watch non-existing paths, chokidar will no longer throw
-  ENOENT error.
-* Fixed bug with absolute path.
-
-# Chokidar 0.5.0 (Dec 9, 2012)
-* Added a bunch of new options:
-    * `ignoreInitial` that allows to ignore initial `add` events.
-    * `ignorePermissionErrors` that allows to ignore ENOENT etc perm errors.
-    * `interval` and `binaryInterval` that allow to change default
-    fs polling intervals.
-
-# Chokidar 0.4.0 (Jul 26, 2012)
-* Added `all` event that receives two args (event name and path) that combines
-  `add`, `change` and `unlink` events.
-* Switched to `fs.watchFile` on node.js 0.8 on windows.
-* Files are now correctly unwatched after unlink.
-
-# Chokidar 0.3.0 (Jun 24, 2012)
-* `unlink` event are no longer emitted for directories, for consistency with
-  `add`.
-
-# Chokidar 0.2.6 (Jun 8, 2012)
-* Prevented creating of duplicate 'add' events.
-
-# Chokidar 0.2.5 (Jun 8, 2012)
-* Fixed a bug when new files in new directories hadn't been added.
-
-# Chokidar 0.2.4 (Jun 7, 2012)
-* Fixed a bug when unlinked files emitted events after unlink.
-
-# Chokidar 0.2.3 (May 12, 2012)
-* Fixed watching of files on windows.
-
-# Chokidar 0.2.2 (May 4, 2012)
-* Fixed watcher signature.
-
-# Chokidar 0.2.1 (May 4, 2012)
-* Fixed invalid API bug when using `watch()`.
-
-# Chokidar 0.2.0 (May 4, 2012)
-* Rewritten in js.
-
-# Chokidar 0.1.1 (Apr 26, 2012)
-* Changed api to `chokidar.watch()`.
-* Fixed compilation on windows.
-
-# Chokidar 0.1.0 (Apr 20, 2012)
-* Initial release, extracted from
-  
[Brunch](https://github.com/brunch/brunch/blob/9847a065aea300da99bd0753f90354cde9de1261/src/helpers.coffee#L66)

http://git-wip-us.apache.org/repos/asf/incubator-griffin-site/blob/ca1c37a7/node_modules/chokidar/README.md
----------------------------------------------------------------------
diff --git a/node_modules/chokidar/README.md b/node_modules/chokidar/README.md
deleted file mode 100644
index bcd005b..0000000
--- a/node_modules/chokidar/README.md
+++ /dev/null
@@ -1,289 +0,0 @@
-# Chokidar [![Mac/Linux Build 
Status](https://img.shields.io/travis/paulmillr/chokidar/master.svg?label=Mac%20OSX%20%26%20Linux)](https://travis-ci.org/paulmillr/chokidar)
 [![Windows Build 
status](https://img.shields.io/appveyor/ci/es128/chokidar/master.svg?label=Windows)](https://ci.appveyor.com/project/es128/chokidar/branch/master)
 [![Coverage 
Status](https://coveralls.io/repos/paulmillr/chokidar/badge.svg)](https://coveralls.io/r/paulmillr/chokidar)
 [![Join the chat at 
https://gitter.im/paulmillr/chokidar](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/paulmillr/chokidar?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
-
-> A neat wrapper around node.js fs.watch / fs.watchFile / fsevents.
-
-[![NPM](https://nodei.co/npm-dl/chokidar.png)](https://nodei.co/npm/chokidar/)
-[![NPM](https://nodei.co/npm/chokidar.png?downloads=true&downloadRank=true&stars=true)](https://nodei.co/npm/chokidar/)
-
-## Why?
-Node.js `fs.watch`:
-
-* Doesn't report filenames on OS X.
-* Doesn't report events at all when using editors like Sublime on OS X.
-* Often reports events twice.
-* Emits most changes as `rename`.
-* Has [a lot of other 
issues](https://github.com/joyent/node/search?q=fs.watch&type=Issues)
-* Does not provide an easy way to recursively watch file trees.
-
-Node.js `fs.watchFile`:
-
-* Almost as bad at event handling.
-* Also does not provide any recursive watching.
-* Results in high CPU utilization.
-
-Chokidar resolves these problems.
-
-Initially made for [brunch](http://brunch.io) (an ultra-swift web app build 
tool), it is now used in
-[gulp](https://github.com/gulpjs/gulp/),
-[karma](http://karma-runner.github.io),
-[PM2](https://github.com/Unitech/PM2),
-[browserify](http://browserify.org/),
-[webpack](http://webpack.github.io/),
-[BrowserSync](http://www.browsersync.io/),
-[Microsoft's Visual Studio Code](https://github.com/microsoft/vscode),
-and [many others](https://www.npmjs.org/browse/depended/chokidar/).
-It has proven itself in production environments.
-
-## How?
-Chokidar does still rely on the Node.js core `fs` module, but when using
-`fs.watch` and `fs.watchFile` for watching, it normalizes the events it
-receives, often checking for truth by getting file stats and/or dir contents.
-
-On Mac OS X, chokidar by default uses a native extension exposing the Darwin
-`FSEvents` API. This provides very efficient recursive watching compared with
-implementations like `kqueue` available on most \*nix platforms. Chokidar still
-does have to do some work to normalize the events received that way as well.
-
-On other platforms, the `fs.watch`-based implementation is the default, which
-avoids polling and keeps CPU usage down. Be advised that chokidar will initiate
-watchers recursively for everything within scope of the paths that have been
-specified, so be judicious about not wasting system resources by watching much
-more than needed.
-
-## Getting started
-Install with npm:
-
-    npm install chokidar --save
-
-Then `require` and use it in your code:
-
-```javascript
-var chokidar = require('chokidar');
-
-// One-liner for current directory, ignores .dotfiles
-chokidar.watch('.', {ignored: /[\/\\]\./}).on('all', (event, path) => {
-  console.log(event, path);
-});
-```
-
-```javascript
-// Example of a more typical implementation structure:
-
-// Initialize watcher.
-var watcher = chokidar.watch('file, dir, glob, or array', {
-  ignored: /[\/\\]\./,
-  persistent: true
-});
-
-// Something to use when events are received.
-var log = console.log.bind(console);
-// Add event listeners.
-watcher
-  .on('add', path => log(`File ${path} has been added`))
-  .on('change', path => log(`File ${path} has been changed`))
-  .on('unlink', path => log(`File ${path} has been removed`));
-
-// More possible events.
-watcher
-  .on('addDir', path => log(`Directory ${path} has been added`))
-  .on('unlinkDir', path => log(`Directory ${path} has been removed`))
-  .on('error', error => log(`Watcher error: ${error}`))
-  .on('ready', () => log('Initial scan complete. Ready for changes'))
-  .on('raw', (event, path, details) => {
-    log('Raw event info:', event, path, details);
-  });
-
-// 'add', 'addDir' and 'change' events also receive stat() results as second
-// argument when available: http://nodejs.org/api/fs.html#fs_class_fs_stats
-watcher.on('change', (path, stats) => {
-  if (stats) console.log(`File ${path} changed size to ${stats.size}`);
-});
-
-// Watch new files.
-watcher.add('new-file');
-watcher.add(['new-file-2', 'new-file-3', '**/other-file*']);
-
-// Get list of actual paths being watched on the filesystem
-var watchedPaths = watcher.getWatched();
-
-// Un-watch some files.
-watcher.unwatch('new-file*');
-
-// Stop watching.
-watcher.close();
-
-// Full list of options. See below for descriptions. (do not use this example)
-chokidar.watch('file', {
-  persistent: true,
-
-  ignored: '*.txt',
-  ignoreInitial: false,
-  followSymlinks: true,
-  cwd: '.',
-
-  usePolling: true,
-  interval: 100,
-  binaryInterval: 300,
-  alwaysStat: false,
-  depth: 99,
-  awaitWriteFinish: {
-    stabilityThreshold: 2000,
-    pollInterval: 100
-  },
-
-  ignorePermissionErrors: false,
-  atomic: true // or a custom 'atomicity delay', in milliseconds (default 100)
-});
-
-```
-
-## API
-
-`chokidar.watch(paths, [options])`
-
-* `paths` (string or array of strings). Paths to files, dirs to be watched
-recursively, or glob patterns.
-* `options` (object) Options object as defined below:
-
-#### Persistence
-
-* `persistent` (default: `true`). Indicates whether the process
-should continue to run as long as files are being watched. If set to
-`false` when using `fsevents` to watch, no more events will be emitted
-after `ready`, even if the process continues to run.
-
-#### Path filtering
-
-* `ignored` ([anymatch](https://github.com/es128/anymatch)-compatible 
definition)
-Defines files/paths to be ignored. The whole relative or absolute path is
-tested, not just filename. If a function with two arguments is provided, it
-gets called twice per path - once with a single argument (the path), second
-time with two arguments (the path and the
-[`fs.Stats`](http://nodejs.org/api/fs.html#fs_class_fs_stats)
-object of that path).
-* `ignoreInitial` (default: `false`). If set to `false` then `add`/`addDir` 
events are also emitted for matching paths while
-instantiating the watching as chokidar discovers these file paths (before the 
`ready` event).
-* `followSymlinks` (default: `true`). When `false`, only the
-symlinks themselves will be watched for changes instead of following
-the link references and bubbling events through the link's path.
-* `cwd` (no default). The base directory from which watch `paths` are to be
-derived. Paths emitted with events will be relative to this.
-
-#### Performance
-
-* `usePolling` (default: `false`).
-Whether to use fs.watchFile (backed by polling), or fs.watch. If polling
-leads to high CPU utilization, consider setting this to `false`. It is
-typically necessary to **set this to `true` to successfully watch files over
-a network**, and it may be necessary to successfully watch files in other
-non-standard situations. Setting to `true` explicitly on OS X overrides the
-`useFsEvents` default. You may also set the CHOKIDAR_USEPOLLING env variable
-to true (1) or false (0) in order to override this option.
-* _Polling-specific settings_ (effective when `usePolling: true`)
-  * `interval` (default: `100`). Interval of file system polling.
-  * `binaryInterval` (default: `300`). Interval of file system
-  polling for binary files.
-  ([see list of binary 
extensions](https://github.com/sindresorhus/binary-extensions/blob/master/binary-extensions.json))
-* `useFsEvents` (default: `true` on OS X). Whether to use the
-`fsevents` watching interface if available. When set to `true` explicitly
-and `fsevents` is available this supercedes the `usePolling` setting. When
-set to `false` on OS X, `usePolling: true` becomes the default.
-* `alwaysStat` (default: `false`). If relying upon the
-[`fs.Stats`](http://nodejs.org/api/fs.html#fs_class_fs_stats)
-object that may get passed with `add`, `addDir`, and `change` events, set
-this to `true` to ensure it is provided even in cases where it wasn't
-already available from the underlying watch events.
-* `depth` (default: `undefined`). If set, limits how many levels of
-subdirectories will be traversed.
-* `awaitWriteFinish` (default: `false`).
-By default, the `add` event will fire when a file first appear on disk, before
-the entire file has been written. Furthermore, in some cases some `change`
-events will be emitted while the file is being written. In some cases,
-especially when watching for large files there will be a need to wait for the
-write operation to finish before responding to a file creation or modification.
-Setting `awaitWriteFinish` to `true` (or a truthy value) will poll file size,
-holding its `add` and `change` events until the size does not change for a
-configurable amount of time. The appropriate duration setting is heavily
-dependent on the OS and hardware. For accurate detection this parameter should
-be relatively high, making file watching much less responsive.
-Use with caution.
-  * *`options.awaitWriteFinish` can be set to an object in order to adjust
-  timing params:*
-  * `awaitWriteFinish.stabilityThreshold` (default: 2000). Amount of time in
-  milliseconds for a file size to remain constant before emitting its event.
-  * `awaitWriteFinish.pollInterval` (default: 100). File size polling interval.
-
-#### Errors
-* `ignorePermissionErrors` (default: `false`). Indicates whether to watch files
-that don't have read permissions if possible. If watching fails due to `EPERM`
-or `EACCES` with this set to `true`, the errors will be suppressed silently.
-* `atomic` (default: `true` if `useFsEvents` and `usePolling` are `false`).
-Automatically filters out artifacts that occur when using editors that use
-"atomic writes" instead of writing directly to the source file. If a file is
-re-added within 100 ms of being deleted, Chokidar emits a `change` event
-rather than `unlink` then `add`. If the default of 100 ms does not work well
-for you, you can override it by setting `atomic` to a custom value, in
-milliseconds.
-
-### Methods & Events
-
-`chokidar.watch()` produces an instance of `FSWatcher`. Methods of `FSWatcher`:
-
-* `.add(path / paths)`: Add files, directories, or glob patterns for tracking.
-Takes an array of strings or just one string.
-* `.on(event, callback)`: Listen for an FS event.
-Available events: `add`, `addDir`, `change`, `unlink`, `unlinkDir`, `ready`,
-`raw`, `error`.
-Additionally `all` is available which gets emitted with the underlying event
-name and path for every event other than `ready`, `raw`, and `error`.
-* `.unwatch(path / paths)`: Stop watching files, directories, or glob patterns.
-Takes an array of strings or just one string.
-* `.close()`: Removes all listeners from watched files.
-* `.getWatched()`: Returns an object representing all the paths on the file
-system being watched by this `FSWatcher` instance. The object's keys are all 
the
-directories (using absolute paths unless the `cwd` option was used), and the
-values are arrays of the names of the items contained in each directory.
-
-## CLI
-
-If you need a CLI interface for your file watching, check out
-[chokidar-cli](https://github.com/kimmobrunfeldt/chokidar-cli), allowing you to
-execute a command on each change, or get a stdio stream of change events.
-
-## Install Troubleshooting
-
-* `npm WARN optional dep failed, continuing fsevents@n.n.n`
-  * This message is normal part of how `npm` handles optional dependencies and 
is
-    not indicative of a problem. Even if accompanied by other related error 
messages,
-    Chokidar should function properly.
-
-* `ERR! stack Error: Python executable "python" is v3.4.1, which is not 
supported by gyp.`
-  * You should be able to resolve this by installing python 2.7 and running:
-    `npm config set python python2.7`
-
-* `gyp ERR! stack Error: not found: make`
-  * On Mac, install the XCode command-line tools
-
-## License
-
-The MIT License (MIT)
-
-Copyright (c) 2016 Paul Miller (http://paulmillr.com) & Elan Shanker
-
-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.

Reply via email to