text: /**
   * Module dependencies.
   */
  
  var index = require('indexof');
  
  /**
   * Whitespace regexp.
   */
  
  var re = /\s+/;
  
  /**
   * toString reference.
   */
  
  var toString = Object.prototype.toString;
  
  /**
   * Wrap `el` in a `ClassList`.
   *
   * @param {Element} el
   * @return {ClassList}
   * @api public
   */
  
  module.exports = function(el){
    return new ClassList(el);
  };
  
  /**
   * Initialize a new ClassList for `el`.
   *
   * @param {Element} el
   * @api private
   */
  
  function ClassList(el) {
    if (!el) throw new Error('A DOM element reference is required');
    this.el = el;
    this.list = el.classList;
  }
  
  /**
   * Add class `name` if not already present.
   *
   * @param {String} name
   * @return {ClassList}
   * @api public
   */
  
  ClassList.prototype.add = function(name){
    // classList
    if (this.list) {
      this.list.add(name);
      return this;
    }
  
    // fallback
    var arr = this.array();
    var i = index(arr, name);
    if (!~i) arr.push(name);
    this.el.className = arr.join(' ');
    return this;
  };
  
  /**
   * Remove class `name` when present, or
   * pass a regular expression to remove
   * any which match.
   *
   * @param {String|RegExp} name
   * @return {ClassList}
   * @api public
   */
  
  ClassList.prototype.remove = function(name){
    if ('[object RegExp]' == toString.call(name)) {
      return this.removeMatching(name);
    }
  
    // classList
    if (this.list) {
      this.list.remove(name);
      return this;
    }
  
    // fallback
    var arr = this.array();
    var i = index(arr, name);
    if (~i) arr.splice(i, 1);
    this.el.className = arr.join(' ');
    return this;
  };
  
  /**
   * Remove all classes matching `re`.
   *
   * @param {RegExp} re
   * @return {ClassList}
   * @api private
   */
  
  ClassList.prototype.removeMatching = function(re){
    var arr = this.array();
    for (var i = 0; i < arr.length; i++) {
      if (re.test(arr[i])) {
        this.remove(arr[i]);
      }
    }
    return this;
  };
  
  /**
   * Toggle class `name`, can force state via `force`.
   *
   * For browsers that support classList, but do not support `force` yet,
   * the mistake will be detected and corrected.
   *
   * @param {String} name
   * @param {Boolean} force
   * @return {ClassList}
   * @api public
   */
  
  ClassList.prototype.toggle = function(name, force){
    // classList
    if (this.list) {
      if ("undefined" !== typeof force) {
        if (force !== this.list.toggle(name, force)) {
          this.list.toggle(name); // toggle again to correct
        }
      } else {
        this.list.toggle(name);
      }
      return this;
    }
  
    // fallback
    if ("undefined" !== typeof force) {
      if (!force) {
        this.remove(name);
      } else {
        this.add(name);
      }
    } else {
      if (this.has(name)) {
        this.remove(name);
      } else {
        this.add(name);
      }
    }
  
    return this;
  };
  
  /**
   * Return an array of classes.
   *
   * @return {Array}
   * @api public
   */
  
  ClassList.prototype.array = function(){
    var str = this.el.className.replace(/^\s+|\s+$/g, '');
    var arr = str.split(re);
    if ('' === arr[0]) arr.shift();
    return arr;
  };
  
  /**
   * Check if class `name` is present.
   *
   * @param {String} name
   * @return {ClassList}
   * @api public
   */
  
  ClassList.prototype.has =
  ClassList.prototype.contains = function(name){
    return this.list
      ? this.list.contains(name)
      : !! ~index(this.array(), name);
  };
  