text: 'use strict';
  
  var hexTable = (function () {
      var array = new Array(256);
      for (var i = 0; i < 256; ++i) {
          array[i] = '%' + ((i < 16 ? '0' : '') + i.toString(16)).toUpperCase();
      }
  
      return array;
  }());
  
  exports.arrayToObject = function (source, options) {
      var obj = options.plainObjects ? Object.create(null) : {};
      for (var i = 0; i < source.length; ++i) {
          if (typeof source[i] !== 'undefined') {
              obj[i] = source[i];
          }
      }
  
      return obj;
  };
  
  exports.merge = function (target, source, options) {
      if (!source) {
          return target;
      }
  
      if (typeof source !== 'object') {
          if (Array.isArray(target)) {
              target.push(source);
          } else if (typeof target === 'object') {
              target[source] = true;
          } else {
              return [target, source];
          }
  
          return target;
      }
  
      if (typeof target !== 'object') {
          return [target].concat(source);
      }
  
      var mergeTarget = target;
      if (Array.isArray(target) && !Array.isArray(source)) {
          mergeTarget = exports.arrayToObject(target, options);
      }
  
  	return Object.keys(source).reduce(function (acc, key) {
          var value = source[key];
  
          if (Object.prototype.hasOwnProperty.call(acc, key)) {
              acc[key] = exports.merge(acc[key], value, options);
          } else {
              acc[key] = value;
          }
  		return acc;
      }, mergeTarget);
  };
  
  exports.decode = function (str) {
      try {
          return decodeURIComponent(str.replace(/\+/g, ' '));
      } catch (e) {
          return str;
      }
  };
  
  exports.encode = function (str) {
      // This code was originally written by Brian White (mscdex) for the io.js core querystring library.
      // It has been adapted here for stricter adherence to RFC 3986
      if (str.length === 0) {
          return str;
      }
  
      var string = typeof str === 'string' ? str : String(str);
  
      var out = '';
      for (var i = 0; i < string.length; ++i) {
          var c = string.charCodeAt(i);
  
          if (
              c === 0x2D || // -
              c === 0x2E || // .
              c === 0x5F || // _
              c === 0x7E || // ~
              (c >= 0x30 && c <= 0x39) || // 0-9
              (c >= 0x41 && c <= 0x5A) || // a-z
              (c >= 0x61 && c <= 0x7A) // A-Z
          ) {
              out += string.charAt(i);
              continue;
          }
  
          if (c < 0x80) {
              out = out + hexTable[c];
              continue;
          }
  
          if (c < 0x800) {
              out = out + (hexTable[0xC0 | (c >> 6)] + hexTable[0x80 | (c & 0x3F)]);
              continue;
          }
  
          if (c < 0xD800 || c >= 0xE000) {
              out = out + (hexTable[0xE0 | (c >> 12)] + hexTable[0x80 | ((c >> 6) & 0x3F)] + hexTable[0x80 | (c & 0x3F)]);
              continue;
          }
  
          i += 1;
          c = 0x10000 + (((c & 0x3FF) << 10) | (string.charCodeAt(i) & 0x3FF));
          out += (hexTable[0xF0 | (c >> 18)] + hexTable[0x80 | ((c >> 12) & 0x3F)] + hexTable[0x80 | ((c >> 6) & 0x3F)] + hexTable[0x80 | (c & 0x3F)]);
      }
  
      return out;
  };
  
  exports.compact = function (obj, references) {
      if (typeof obj !== 'object' || obj === null) {
          return obj;
      }
  
      var refs = references || [];
      var lookup = refs.indexOf(obj);
      if (lookup !== -1) {
          return refs[lookup];
      }
  
      refs.push(obj);
  
      if (Array.isArray(obj)) {
          var compacted = [];
  
          for (var i = 0; i < obj.length; ++i) {
              if (obj[i] && typeof obj[i] === 'object') {
                  compacted.push(exports.compact(obj[i], refs));
              } else if (typeof obj[i] !== 'undefined') {
                  compacted.push(obj[i]);
              }
          }
  
          return compacted;
      }
  
      var keys = Object.keys(obj);
      for (var j = 0; j < keys.length; ++j) {
          var key = keys[j];
          obj[key] = exports.compact(obj[key], refs);
      }
  
      return obj;
  };
  
  exports.isRegExp = function (obj) {
      return Object.prototype.toString.call(obj) === '[object RegExp]';
  };
  
  exports.isBuffer = function (obj) {
      if (obj === null || typeof obj === 'undefined') {
          return false;
      }
  
      return !!(obj.constructor && obj.constructor.isBuffer && obj.constructor.isBuffer(obj));
  };
  