text: /*! Amaze UI v2.4.2 ~ IE8 Fucker | by Amaze UI Team | (c) 2015 AllMobilize, Inc. | Licensed under MIT | 2015-07-06T10:25:45+0800 */
  // Console-polyfill. MIT license.
  // https://github.com/paulmillr/console-polyfill
  // Make it safe to do console.log() always.
  (function (global) {
      'use strict';
      global.console = global.console || {};
      var con = global.console;
      var prop, method;
      var empty = {};
      var dummy = function () {
      };
      var properties = 'memory'.split(',');
      var methods = ('assert,clear,count,debug,dir,dirxml,error,exception,group,' +
      'groupCollapsed,groupEnd,info,log,markTimeline,profile,profiles,profileEnd,' +
      'show,table,time,timeEnd,timeline,timelineEnd,timeStamp,trace,warn').split(',');
      while (prop = properties.pop()) if (!con[prop]) con[prop] = empty;
      while (method = methods.pop()) if (!con[method]) con[method] = dummy;
  })(typeof window === 'undefined' ? this : window);
  // Using `this` for web workers while maintaining compatibility with browser
  // targeted script loaders such as Browserify or Webpack where the only way to
  // get to the global object is via `window`.
  
  /*!
   * https://github.com/es-shims/es5-shim
   * @license es5-shim Copyright 2009-2015 by contributors, MIT License
   * see https://github.com/es-shims/es5-shim/blob/master/LICENSE
   */
  
  // vim: ts=4 sts=4 sw=4 expandtab
  
  // Add semicolon to prevent IIFE from being passed as argument to concatenated code.
  ;
  
  // UMD (Universal Module Definition)
  // see https://github.com/umdjs/umd/blob/master/returnExports.js
  (function (root, factory) {
      'use strict';
  
      /* global define, exports, module */
      if (typeof define === 'function' && define.amd) {
          // AMD. Register as an anonymous module.
          define(factory);
      } else if (typeof exports === 'object') {
          // Node. Does not work with strict CommonJS, but
          // only CommonJS-like enviroments that support module.exports,
          // like Node.
          module.exports = factory();
      } else {
          // Browser globals (root is window)
          root.returnExports = factory();
      }
  }(this, function () {
  
      var call = Function.prototype.call;
      var prototypeOfObject = Object.prototype;
      var owns = call.bind(prototypeOfObject.hasOwnProperty);
  
  // If JS engine supports accessors creating shortcuts.
      var defineGetter;
      var defineSetter;
      var lookupGetter;
      var lookupSetter;
      var supportsAccessors = owns(prototypeOfObject, '__defineGetter__');
      if (supportsAccessors) {
          /* eslint-disable no-underscore-dangle */
          defineGetter = call.bind(prototypeOfObject.__defineGetter__);
          defineSetter = call.bind(prototypeOfObject.__defineSetter__);
          lookupGetter = call.bind(prototypeOfObject.__lookupGetter__);
          lookupSetter = call.bind(prototypeOfObject.__lookupSetter__);
          /* eslint-enable no-underscore-dangle */
      }
  
  // ES5 15.2.3.2
  // http://es5.github.com/#x15.2.3.2
      if (!Object.getPrototypeOf) {
          // https://github.com/es-shims/es5-shim/issues#issue/2
          // http://ejohn.org/blog/objectgetprototypeof/
          // recommended by fschaefer on github
          //
          // sure, and webreflection says ^_^
          // ... this will nerever possibly return null
          // ... Opera Mini breaks here with infinite loops
          Object.getPrototypeOf = function getPrototypeOf(object) {
              /* eslint-disable no-proto */
              var proto = object.__proto__;
              /* eslint-enable no-proto */
              if (proto || proto === null) {
                  return proto;
              } else if (object.constructor) {
                  return object.constructor.prototype;
              } else {
                  return prototypeOfObject;
              }
          };
      }
  
  // ES5 15.2.3.3
  // http://es5.github.com/#x15.2.3.3
  
      var doesGetOwnPropertyDescriptorWork = function doesGetOwnPropertyDescriptorWork(object) {
          try {
              object.sentinel = 0;
              return Object.getOwnPropertyDescriptor(object, 'sentinel').value === 0;
          } catch (exception) {
              return false;
          }
      };
  
  // check whether getOwnPropertyDescriptor works if it's given. Otherwise, shim partially.
      if (Object.defineProperty) {
          var getOwnPropertyDescriptorWorksOnObject = doesGetOwnPropertyDescriptorWork({});
          var getOwnPropertyDescriptorWorksOnDom = typeof document === 'undefined' ||
              doesGetOwnPropertyDescriptorWork(document.createElement('div'));
          if (!getOwnPropertyDescriptorWorksOnDom || !getOwnPropertyDescriptorWorksOnObject) {
              var getOwnPropertyDescriptorFallback = Object.getOwnPropertyDescriptor;
          }
      }
  
      if (!Object.getOwnPropertyDescriptor || getOwnPropertyDescriptorFallback) {
          var ERR_NON_OBJECT = 'Object.getOwnPropertyDescriptor called on a non-object: ';
  
          /* eslint-disable no-proto */
          Object.getOwnPropertyDescriptor = function getOwnPropertyDescriptor(object, property) {
              if ((typeof object !== 'object' && typeof object !== 'function') || object === null) {
                  throw new TypeError(ERR_NON_OBJECT + object);
              }
  
              // make a valiant attempt to use the real getOwnPropertyDescriptor
              // for I8's DOM elements.
              if (getOwnPropertyDescriptorFallback) {
                  try {
                      return getOwnPropertyDescriptorFallback.call(Object, object, property);
                  } catch (exception) {
                      // try the shim if the real one doesn't work
                  }
              }
  
              var descriptor;
  
              // If object does not owns property return undefined immediately.
              if (!owns(object, property)) {
                  return descriptor;
              }
  
              // If object has a property then it's for sure both `enumerable` and
              // `configurable`.
              descriptor = {enumerable: true, configurable: true};
  
              // If JS engine supports accessor properties then property may be a
              // getter or setter.
              if (supportsAccessors) {
                  // Unfortunately `__lookupGetter__` will return a getter even
                  // if object has own non getter property along with a same named
                  // inherited getter. To avoid misbehavior we temporary remove
                  // `__proto__` so that `__lookupGetter__` will return getter only
                  // if it's owned by an object.
                  var prototype = object.__proto__;
                  var notPrototypeOfObject = object !== prototypeOfObject;
                  // avoid recursion problem, breaking in Opera Mini when
                  // Object.getOwnPropertyDescriptor(Object.prototype, 'toString')
                  // or any other Object.prototype accessor
                  if (notPrototypeOfObject) {
                      object.__proto__ = prototypeOfObject;
                  }
  
                  var getter = lookupGetter(object, property);
                  var setter = lookupSetter(object, property);
  
                  if (notPrototypeOfObject) {
                      // Once we have getter and setter we can put values back.
                      object.__proto__ = prototype;
                  }
  
                  if (getter || setter) {
                      if (getter) {
                          descriptor.get = getter;
                      }
                      if (setter) {
                          descriptor.set = setter;
                      }
                      // If it was accessor property we're done and return here
                      // in order to avoid adding `value` to the descriptor.
                      return descriptor;
                  }
              }
  
              // If we got this far we know that object has an own property that is
              // not an accessor so we set it as a value and return descriptor.
              descriptor.value = object[property];
              descriptor.writable = true;
              return descriptor;
          };
          /* eslint-enable no-proto */
      }
  
  // ES5 15.2.3.4
  // http://es5.github.com/#x15.2.3.4
      if (!Object.getOwnPropertyNames) {
          Object.getOwnPropertyNames = function getOwnPropertyNames(object) {
              return Object.keys(object);
          };
      }
  
  // ES5 15.2.3.5
  // http://es5.github.com/#x15.2.3.5
      if (!Object.create) {
  
          // Contributed by Brandon Benvie, October, 2012
          var createEmpty;
          var supportsProto = !({__proto__: null} instanceof Object);
          // the following produces false positives
          // in Opera Mini => not a reliable check
          // Object.prototype.__proto__ === null
  
          // Check for document.domain and active x support
          // No need to use active x approach when document.domain is not set
          // see https://github.com/es-shims/es5-shim/issues/150
          // variation of https://github.com/kitcambridge/es5-shim/commit/4f738ac066346
          /* global ActiveXObject */
          var shouldUseActiveX = function shouldUseActiveX() {
              // return early if document.domain not set
              if (!document.domain) {
                  return false;
              }
  
              try {
                  return !!new ActiveXObject('htmlfile');
              } catch (exception) {
                  return false;
              }
          };
  
          // This supports IE8 when document.domain is used
          // see https://github.com/es-shims/es5-shim/issues/150
          // variation of https://github.com/kitcambridge/es5-shim/commit/4f738ac066346
          var getEmptyViaActiveX = function getEmptyViaActiveX() {
              var empty;
              var xDoc;
  
              xDoc = new ActiveXObject('htmlfile');
  
              xDoc.write('<script><\/script>');
              xDoc.close();
  
              empty = xDoc.parentWindow.Object.prototype;
              xDoc = null;
  
              return empty;
          };
  
          // The original implementation using an iframe
          // before the activex approach was added
          // see https://github.com/es-shims/es5-shim/issues/150
          var getEmptyViaIFrame = function getEmptyViaIFrame() {
              var iframe = document.createElement('iframe');
              var parent = document.body || document.documentElement;
              var empty;
  
              iframe.style.display = 'none';
              parent.appendChild(iframe);
              /* eslint-disable no-script-url */
              iframe.src = 'javascript:';
              /* eslint-enable no-script-url */
  
              empty = iframe.contentWindow.Object.prototype;
              parent.removeChild(iframe);
              iframe = null;
  
              return empty;
          };
  
          /* global document */
          if (supportsProto || typeof document === 'undefined') {
              createEmpty = function () {
                  return {__proto__: null};
              };
          } else {
              // In old IE __proto__ can't be used to manually set `null`, nor does
              // any other method exist to make an object that inherits from nothing,
              // aside from Object.prototype itself. Instead, create a new global
              // object and *steal* its Object.prototype and strip it bare. This is
              // used as the prototype to create nullary objects.
              createEmpty = function () {
                  // Determine which approach to use
                  // see https://github.com/es-shims/es5-shim/issues/150
                  var empty = shouldUseActiveX() ? getEmptyViaActiveX() : getEmptyViaIFrame();
  
                  delete empty.constructor;
                  delete empty.hasOwnProperty;
                  delete empty.propertyIsEnumerable;
                  delete empty.isPrototypeOf;
                  delete empty.toLocaleString;
                  delete empty.toString;
                  delete empty.valueOf;
                  /* eslint-disable no-proto */
                  empty.__proto__ = null;
                  /* eslint-enable no-proto */
  
                  var Empty = function Empty() {
                  };
                  Empty.prototype = empty;
                  // short-circuit future calls
                  createEmpty = function () {
                      return new Empty();
                  };
                  return new Empty();
              };
          }
  
          Object.create = function create(prototype, properties) {
  
              var object;
              var Type = function Type() {
              }; // An empty constructor.
  
              if (prototype === null) {
                  object = createEmpty();
              } else {
                  if (typeof prototype !== 'object' && typeof prototype !== 'function') {
                      // In the native implementation `parent` can be `null`
                      // OR *any* `instanceof Object`  (Object|Function|Array|RegExp|etc)
                      // Use `typeof` tho, b/c in old IE, DOM elements are not `instanceof Object`
                      // like they are in modern browsers. Using `Object.create` on DOM elements
                      // is...err...probably inappropriate, but the native version allows for it.
                      throw new TypeError('Object prototype may only be an Object or null'); // same msg as Chrome
                  }
                  Type.prototype = prototype;
                  object = new Type();
                  // IE has no built-in implementation of `Object.getPrototypeOf`
                  // neither `__proto__`, but this manually setting `__proto__` will
                  // guarantee that `Object.getPrototypeOf` will work as expected with
                  // objects created using `Object.create`
                  /* eslint-disable no-proto */
                  object.__proto__ = prototype;
                  /* eslint-enable no-proto */
              }
  
              if (properties !== void 0) {
                  Object.defineProperties(object, properties);
              }
  
              return object;
          };
      }
  
  // ES5 15.2.3.6
  // http://es5.github.com/#x15.2.3.6
  
  // Patch for WebKit and IE8 standard mode
  // Designed by hax <hax.github.com>
  // related issue: https://github.com/es-shims/es5-shim/issues#issue/5
  // IE8 Reference:
  //     http://msdn.microsoft.com/en-us/library/dd282900.aspx
  //     http://msdn.microsoft.com/en-us/library/dd229916.aspx
  // WebKit Bugs:
  //     https://bugs.webkit.org/show_bug.cgi?id=36423
  
      var doesDefinePropertyWork = function doesDefinePropertyWork(object) {
          try {
              Object.defineProperty(object, 'sentinel', {});
              return 'sentinel' in object;
          } catch (exception) {
              return false;
          }
      };
  
  // check whether defineProperty works if it's given. Otherwise,
  // shim partially.
      if (Object.defineProperty) {
          var definePropertyWorksOnObject = doesDefinePropertyWork({});
          var definePropertyWorksOnDom = typeof document === 'undefined' ||
              doesDefinePropertyWork(document.createElement('div'));
          if (!definePropertyWorksOnObject || !definePropertyWorksOnDom) {
              var definePropertyFallback = Object.defineProperty,
                  definePropertiesFallback = Object.defineProperties;
          }
      }
  
      if (!Object.defineProperty || definePropertyFallback) {
          var ERR_NON_OBJECT_DESCRIPTOR = 'Property description must be an object: ';
          var ERR_NON_OBJECT_TARGET = 'Object.defineProperty called on non-object: ';
          var ERR_ACCESSORS_NOT_SUPPORTED = 'getters & setters can not be defined on this javascript engine';
  
          Object.defineProperty = function defineProperty(object, property, descriptor) {
              if ((typeof object !== 'object' && typeof object !== 'function') || object === null) {
                  throw new TypeError(ERR_NON_OBJECT_TARGET + object);
              }
              if ((typeof descriptor !== 'object' && typeof descriptor !== 'function') || descriptor === null) {
                  throw new TypeError(ERR_NON_OBJECT_DESCRIPTOR + descriptor);
              }
              // make a valiant attempt to use the real defineProperty
              // for I8's DOM elements.
              if (definePropertyFallback) {
                  try {
                      return definePropertyFallback.call(Object, object, property, descriptor);
                  } catch (exception) {
                      // try the shim if the real one doesn't work
                  }
              }
  
              // If it's a data property.
              if ('value' in descriptor) {
                  // fail silently if 'writable', 'enumerable', or 'configurable'
                  // are requested but not supported
                  /*
                   // alternate approach:
                   if ( // can't implement these features; allow false but not true
                   ('writable' in descriptor && !descriptor.writable) ||
                   ('enumerable' in descriptor && !descriptor.enumerable) ||
                   ('configurable' in descriptor && !descriptor.configurable)
                   ))
                   throw new RangeError(
                   'This implementation of Object.defineProperty does not support configurable, enumerable, or writable.'
                   );
                   */
  
                  if (supportsAccessors && (lookupGetter(object, property) || lookupSetter(object, property))) {
                      // As accessors are supported only on engines implementing
                      // `__proto__` we can safely override `__proto__` while defining
                      // a property to make sure that we don't hit an inherited
                      // accessor.
                      /* eslint-disable no-proto */
                      var prototype = object.__proto__;
                      object.__proto__ = prototypeOfObject;
                      // Deleting a property anyway since getter / setter may be
                      // defined on object itself.
                      delete object[property];
                      object[property] = descriptor.value;
                      // Setting original `__proto__` back now.
                      object.__proto__ = prototype;
                      /* eslint-enable no-proto */
                  } else {
                      object[property] = descriptor.value;
                  }
              } else {
                  if (!supportsAccessors) {
                      throw new TypeError(ERR_ACCESSORS_NOT_SUPPORTED);
                  }
                  // If we got that far then getters and setters can be defined !!
                  if ('get' in descriptor) {
                      defineGetter(object, property, descriptor.get);
                  }
                  if ('set' in descriptor) {
                      defineSetter(object, property, descriptor.set);
                  }
              }
              return object;
          };
      }
  
  // ES5 15.2.3.7
  // http://es5.github.com/#x15.2.3.7
      if (!Object.defineProperties || definePropertiesFallback) {
          Object.defineProperties = function defineProperties(object, properties) {
              // make a valiant attempt to use the real defineProperties
              if (definePropertiesFallback) {
                  try {
                      return definePropertiesFallback.call(Object, object, properties);
                  } catch (exception) {
                      // try the shim if the real one doesn't work
                  }
              }
  
              Object.keys(properties).forEach(function (property) {
                  if (property !== '__proto__') {
                      Object.defineProperty(object, property, properties[property]);
                  }
              });
              return object;
          };
      }
  
  // ES5 15.2.3.8
  // http://es5.github.com/#x15.2.3.8
      if (!Object.seal) {
          Object.seal = function seal(object) {
              if (Object(object) !== object) {
                  throw new TypeError('Object.seal can only be called on Objects.');
              }
              // this is misleading and breaks feature-detection, but
              // allows "securable" code to "gracefully" degrade to working
              // but insecure code.
              return object;
          };
      }
  
  // ES5 15.2.3.9
  // http://es5.github.com/#x15.2.3.9
      if (!Object.freeze) {
          Object.freeze = function freeze(object) {
              if (Object(object) !== object) {
                  throw new TypeError('Object.freeze can only be called on Objects.');
              }
              // this is misleading and breaks feature-detection, but
              // allows "securable" code to "gracefully" degrade to working
              // but insecure code.
              return object;
          };
      }
  
  // detect a Rhino bug and patch it
      try {
          Object.freeze(function () {
          });
      } catch (exception) {
          Object.freeze = (function (freezeObject) {
              return function freeze(object) {
                  if (typeof object === 'function') {
                      return object;
                  } else {
                      return freezeObject(object);
                  }
              };
          }(Object.freeze));
      }
  
  // ES5 15.2.3.10
  // http://es5.github.com/#x15.2.3.10
      if (!Object.preventExtensions) {
          Object.preventExtensions = function preventExtensions(object) {
              if (Object(object) !== object) {
                  throw new TypeError('Object.preventExtensions can only be called on Objects.');
              }
              // this is misleading and breaks feature-detection, but
              // allows "securable" code to "gracefully" degrade to working
              // but insecure code.
              return object;
          };
      }
  
  // ES5 15.2.3.11
  // http://es5.github.com/#x15.2.3.11
      if (!Object.isSealed) {
          Object.isSealed = function isSealed(object) {
              if (Object(object) !== object) {
                  throw new TypeError('Object.isSealed can only be called on Objects.');
              }
              return false;
          };
      }
  
  // ES5 15.2.3.12
  // http://es5.github.com/#x15.2.3.12
      if (!Object.isFrozen) {
          Object.isFrozen = function isFrozen(object) {
              if (Object(object) !== object) {
                  throw new TypeError('Object.isFrozen can only be called on Objects.');
              }
              return false;
          };
      }
  
  // ES5 15.2.3.13
  // http://es5.github.com/#x15.2.3.13
      if (!Object.isExtensible) {
          Object.isExtensible = function isExtensible(object) {
              // 1. If Type(O) is not Object throw a TypeError exception.
              if (Object(object) !== object) {
                  throw new TypeError('Object.isExtensible can only be called on Objects.');
              }
              // 2. Return the Boolean value of the [[Extensible]] internal property of O.
              var name = '';
              while (owns(object, name)) {
                  name += '?';
              }
              object[name] = true;
              var returnValue = owns(object, name);
              delete object[name];
              return returnValue;
          };
      }
  
  }));
  
  /*!
   * https://github.com/es-shims/es5-shim
   * @license es5-shim Copyright 2009-2015 by contributors, MIT License
   * see https://github.com/es-shims/es5-shim/blob/master/LICENSE
   */
  
  // vim: ts=4 sts=4 sw=4 expandtab
  
  // Add semicolon to prevent IIFE from being passed as argument to concatenated code.
  ;
  
  // UMD (Universal Module Definition)
  // see https://github.com/umdjs/umd/blob/master/returnExports.js
  (function (root, factory) {
      'use strict';
  
      /* global define, exports, module */
      if (typeof define === 'function' && define.amd) {
          // AMD. Register as an anonymous module.
          define(factory);
      } else if (typeof exports === 'object') {
          // Node. Does not work with strict CommonJS, but
          // only CommonJS-like enviroments that support module.exports,
          // like Node.
          module.exports = factory();
      } else {
          // Browser globals (root is window)
          root.returnExports = factory();
      }
  }(this, function () {
  
      /**
       * Brings an environment as close to ECMAScript 5 compliance
       * as is possible with the facilities of erstwhile engines.
       *
       * Annotated ES5: http://es5.github.com/ (specific links below)
       * ES5 Spec: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf
       * Required reading: http://javascriptweblog.wordpress.com/2011/12/05/extending-javascript-natives/
       */
  
  // Shortcut to an often accessed properties, in order to avoid multiple
  // dereference that costs universally.
      var ArrayPrototype = Array.prototype;
      var ObjectPrototype = Object.prototype;
      var FunctionPrototype = Function.prototype;
      var StringPrototype = String.prototype;
      var NumberPrototype = Number.prototype;
      var array_slice = ArrayPrototype.slice;
      var array_splice = ArrayPrototype.splice;
      var array_push = ArrayPrototype.push;
      var array_unshift = ArrayPrototype.unshift;
      var array_concat = ArrayPrototype.concat;
      var call = FunctionPrototype.call;
  
  // Having a toString local variable name breaks in Opera so use to_string.
      var to_string = ObjectPrototype.toString;
  
      var isArray = Array.isArray || function isArray(obj) {
              return to_string.call(obj) === '[object Array]';
          };
  
      var hasToStringTag = typeof Symbol === 'function' && typeof Symbol.toStringTag === 'symbol';
      var isCallable;
      /* inlined from https://npmjs.com/is-callable */
      var fnToStr = Function.prototype.toString, tryFunctionObject = function tryFunctionObject(value) {
          try {
              fnToStr.call(value);
              return true;
          } catch (e) {
              return false;
          }
      }, fnClass = '[object Function]', genClass = '[object GeneratorFunction]';
      isCallable = function isCallable(value) {
          if (typeof value !== 'function') {
              return false;
          }
          if (hasToStringTag) {
              return tryFunctionObject(value);
          }
          var strClass = to_string.call(value);
          return strClass === fnClass || strClass === genClass;
      };
      var isRegex;
      /* inlined from https://npmjs.com/is-regex */
      var regexExec = RegExp.prototype.exec, tryRegexExec = function tryRegexExec(value) {
          try {
              regexExec.call(value);
              return true;
          } catch (e) {
              return false;
          }
      }, regexClass = '[object RegExp]';
      isRegex = function isRegex(value) {
          if (typeof value !== 'object') {
              return false;
          }
          return hasToStringTag ? tryRegexExec(value) : to_string.call(value) === regexClass;
      };
      var isString;
      /* inlined from https://npmjs.com/is-string */
      var strValue = String.prototype.valueOf, tryStringObject = function tryStringObject(value) {
          try {
              strValue.call(value);
              return true;
          } catch (e) {
              return false;
          }
      }, stringClass = '[object String]';
      isString = function isString(value) {
          if (typeof value === 'string') {
              return true;
          }
          if (typeof value !== 'object') {
              return false;
          }
          return hasToStringTag ? tryStringObject(value) : to_string.call(value) === stringClass;
      };
  
      var isArguments = function isArguments(value) {
          var str = to_string.call(value);
          var isArgs = str === '[object Arguments]';
          if (!isArgs) {
              isArgs = !isArray(value) &&
                  value !== null &&
                  typeof value === 'object' &&
                  typeof value.length === 'number' &&
                  value.length >= 0 &&
                  isCallable(value.callee);
          }
          return isArgs;
      };
  
      /* inlined from http://npmjs.com/define-properties */
      var defineProperties = (function (has) {
          var supportsDescriptors = Object.defineProperty && (function () {
                  try {
                      var obj = {};
                      Object.defineProperty(obj, 'x', {enumerable: false, value: obj});
                      for (var _ in obj) {
                          return false;
                      }
                      return obj.x === obj;
                  } catch (e) { /* this is ES3 */
                      return false;
                  }
              }());
  
          // Define configurable, writable and non-enumerable props
          // if they don't exist.
          var defineProperty;
          if (supportsDescriptors) {
              defineProperty = function (object, name, method, forceAssign) {
                  if (!forceAssign && (name in object)) {
                      return;
                  }
                  Object.defineProperty(object, name, {
                      configurable: true,
                      enumerable: false,
                      writable: true,
                      value: method
                  });
              };
          } else {
              defineProperty = function (object, name, method, forceAssign) {
                  if (!forceAssign && (name in object)) {
                      return;
                  }
                  object[name] = method;
              };
          }
          return function defineProperties(object, map, forceAssign) {
              for (var name in map) {
                  if (has.call(map, name)) {
                      defineProperty(object, name, map[name], forceAssign);
                  }
              }
          };
      }(ObjectPrototype.hasOwnProperty));
  
  //
  // Util
  // ======
  //
  
      /* replaceable with https://npmjs.com/package/es-abstract /helpers/isPrimitive */
      var isPrimitive = function isPrimitive(input) {
          var type = typeof input;
          return input === null || (type !== 'object' && type !== 'function');
      };
  
      var ES = {
          // ES5 9.4
          // http://es5.github.com/#x9.4
          // http://jsperf.com/to-integer
          /* replaceable with https://npmjs.com/package/es-abstract ES5.ToInteger */
          ToInteger: function ToInteger(num) {
              var n = +num;
              if (n !== n) { // isNaN
                  n = 0;
              } else if (n !== 0 && n !== (1 / 0) && n !== -(1 / 0)) {
                  n = (n > 0 || -1) * Math.floor(Math.abs(n));
              }
              return n;
          },
  
          /* replaceable with https://npmjs.com/package/es-abstract ES5.ToPrimitive */
          ToPrimitive: function ToPrimitive(input) {
              var val, valueOf, toStr;
              if (isPrimitive(input)) {
                  return input;
              }
              valueOf = input.valueOf;
              if (isCallable(valueOf)) {
                  val = valueOf.call(input);
                  if (isPrimitive(val)) {
                      return val;
                  }
              }
              toStr = input.toString;
              if (isCallable(toStr)) {
                  val = toStr.call(input);
                  if (isPrimitive(val)) {
                      return val;
                  }
              }
              throw new TypeError();
          },
  
          // ES5 9.9
          // http://es5.github.com/#x9.9
          /* replaceable with https://npmjs.com/package/es-abstract ES5.ToObject */
          ToObject: function (o) {
              /* jshint eqnull: true */
              if (o == null) { // this matches both null and undefined
                  throw new TypeError("can't convert " + o + ' to object');
              }
              return Object(o);
          },
  
          /* replaceable with https://npmjs.com/package/es-abstract ES5.ToUint32 */
          ToUint32: function ToUint32(x) {
              return x >>> 0;
          }
      };
  
  //
  // Function
  // ========
  //
  
  // ES-5 15.3.4.5
  // http://es5.github.com/#x15.3.4.5
  
      var Empty = function Empty() {
      };
  
      defineProperties(FunctionPrototype, {
          bind: function bind(that) { // .length is 1
              // 1. Let Target be the this value.
              var target = this;
              // 2. If IsCallable(Target) is false, throw a TypeError exception.
              if (!isCallable(target)) {
                  throw new TypeError('Function.prototype.bind called on incompatible ' + target);
              }
              // 3. Let A be a new (possibly empty) internal list of all of the
              //   argument values provided after thisArg (arg1, arg2 etc), in order.
              // XXX slicedArgs will stand in for "A" if used
              var args = array_slice.call(arguments, 1); // for normal call
              // 4. Let F be a new native ECMAScript object.
              // 11. Set the [[Prototype]] internal property of F to the standard
              //   built-in Function prototype object as specified in 15.3.3.1.
              // 12. Set the [[Call]] internal property of F as described in
              //   15.3.4.5.1.
              // 13. Set the [[Construct]] internal property of F as described in
              //   15.3.4.5.2.
              // 14. Set the [[HasInstance]] internal property of F as described in
              //   15.3.4.5.3.
              var bound;
              var binder = function () {
  
                  if (this instanceof bound) {
                      // 15.3.4.5.2 [[Construct]]
                      // When the [[Construct]] internal method of a function object,
                      // F that was created using the bind function is called with a
                      // list of arguments ExtraArgs, the following steps are taken:
                      // 1. Let target be the value of F's [[TargetFunction]]
                      //   internal property.
                      // 2. If target has no [[Construct]] internal method, a
                      //   TypeError exception is thrown.
                      // 3. Let boundArgs be the value of F's [[BoundArgs]] internal
                      //   property.
                      // 4. Let args be a new list containing the same values as the
                      //   list boundArgs in the same order followed by the same
                      //   values as the list ExtraArgs in the same order.
                      // 5. Return the result of calling the [[Construct]] internal
                      //   method of target providing args as the arguments.
  
                      var result = target.apply(
                          this,
                          array_concat.call(args, array_slice.call(arguments))
                      );
                      if (Object(result) === result) {
                          return result;
                      }
                      return this;
  
                  } else {
                      // 15.3.4.5.1 [[Call]]
                      // When the [[Call]] internal method of a function object, F,
                      // which was created using the bind function is called with a
                      // this value and a list of arguments ExtraArgs, the following
                      // steps are taken:
                      // 1. Let boundArgs be the value of F's [[BoundArgs]] internal
                      //   property.
                      // 2. Let boundThis be the value of F's [[BoundThis]] internal
                      //   property.
                      // 3. Let target be the value of F's [[TargetFunction]] internal
                      //   property.
                      // 4. Let args be a new list containing the same values as the
                      //   list boundArgs in the same order followed by the same
                      //   values as the list ExtraArgs in the same order.
                      // 5. Return the result of calling the [[Call]] internal method
                      //   of target providing boundThis as the this value and
                      //   providing args as the arguments.
  
                      // equiv: target.call(this, ...boundArgs, ...args)
                      return target.apply(
                          that,
                          array_concat.call(args, array_slice.call(arguments))
                      );
  
                  }
  
              };
  
              // 15. If the [[Class]] internal property of Target is "Function", then
              //     a. Let L be the length property of Target minus the length of A.
              //     b. Set the length own property of F to either 0 or L, whichever is
              //       larger.
              // 16. Else set the length own property of F to 0.
  
              var boundLength = Math.max(0, target.length - args.length);
  
              // 17. Set the attributes of the length own property of F to the values
              //   specified in 15.3.5.1.
              var boundArgs = [];
              for (var i = 0; i < boundLength; i++) {
                  boundArgs.push('$' + i);
              }
  
              // XXX Build a dynamic function with desired amount of arguments is the only
              // way to set the length property of a function.
              // In environments where Content Security Policies enabled (Chrome extensions,
              // for ex.) all use of eval or Function costructor throws an exception.
              // However in all of these environments Function.prototype.bind exists
              // and so this code will never be executed.
              bound = Function('binder', 'return function (' + boundArgs.join(',') + '){ return binder.apply(this, arguments); }')(binder);
  
              if (target.prototype) {
                  Empty.prototype = target.prototype;
                  bound.prototype = new Empty();
                  // Clean up dangling references.
                  Empty.prototype = null;
              }
  
              // TODO
              // 18. Set the [[Extensible]] internal property of F to true.
  
              // TODO
              // 19. Let thrower be the [[ThrowTypeError]] function Object (13.2.3).
              // 20. Call the [[DefineOwnProperty]] internal method of F with
              //   arguments "caller", PropertyDescriptor {[[Get]]: thrower, [[Set]]:
              //   thrower, [[Enumerable]]: false, [[Configurable]]: false}, and
              //   false.
              // 21. Call the [[DefineOwnProperty]] internal method of F with
              //   arguments "arguments", PropertyDescriptor {[[Get]]: thrower,
              //   [[Set]]: thrower, [[Enumerable]]: false, [[Configurable]]: false},
              //   and false.
  
              // TODO
              // NOTE Function objects created using Function.prototype.bind do not
              // have a prototype property or the [[Code]], [[FormalParameters]], and
              // [[Scope]] internal properties.
              // XXX can't delete prototype in pure-js.
  
              // 22. Return F.
              return bound;
          }
      });
  
  // _Please note: Shortcuts are defined after `Function.prototype.bind` as we
  // us it in defining shortcuts.
      var owns = call.bind(ObjectPrototype.hasOwnProperty);
  
  //
  // Array
  // =====
  //
  
  // ES5 15.4.4.12
  // http://es5.github.com/#x15.4.4.12
      var spliceNoopReturnsEmptyArray = (function () {
          var a = [1, 2];
          var result = a.splice();
          return a.length === 2 && isArray(result) && result.length === 0;
      }());
      defineProperties(ArrayPrototype, {
          // Safari 5.0 bug where .splice() returns undefined
          splice: function splice(start, deleteCount) {
              if (arguments.length === 0) {
                  return [];
              } else {
                  return array_splice.apply(this, arguments);
              }
          }
      }, !spliceNoopReturnsEmptyArray);
  
      var spliceWorksWithEmptyObject = (function () {
          var obj = {};
          ArrayPrototype.splice.call(obj, 0, 0, 1);
          return obj.length === 1;
      }());
      defineProperties(ArrayPrototype, {
          splice: function splice(start, deleteCount) {
              if (arguments.length === 0) {
                  return [];
              }
              var args = arguments;
              this.length = Math.max(ES.ToInteger(this.length), 0);
              if (arguments.length > 0 && typeof deleteCount !== 'number') {
                  args = array_slice.call(arguments);
                  if (args.length < 2) {
                      args.push(this.length - start);
                  } else {
                      args[1] = ES.ToInteger(deleteCount);
                  }
              }
              return array_splice.apply(this, args);
          }
      }, !spliceWorksWithEmptyObject);
  
  // ES5 15.4.4.12
  // http://es5.github.com/#x15.4.4.13
  // Return len+argCount.
  // [bugfix, ielt8]
  // IE < 8 bug: [].unshift(0) === undefined but should be "1"
      var hasUnshiftReturnValueBug = [].unshift(0) !== 1;
      defineProperties(ArrayPrototype, {
          unshift: function () {
              array_unshift.apply(this, arguments);
              return this.length;
          }
      }, hasUnshiftReturnValueBug);
  
  // ES5 15.4.3.2
  // http://es5.github.com/#x15.4.3.2
  // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/isArray
      defineProperties(Array, {isArray: isArray});
  
  // The IsCallable() check in the Array functions
  // has been replaced with a strict check on the
  // internal class of the object to trap cases where
  // the provided function was actually a regular
  // expression literal, which in V8 and
  // JavaScriptCore is a typeof "function".  Only in
  // V8 are regular expression literals permitted as
  // reduce parameters, so it is desirable in the
  // general case for the shim to match the more
  // strict and common behavior of rejecting regular
  // expressions.
  
  // ES5 15.4.4.18
  // http://es5.github.com/#x15.4.4.18
  // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/array/forEach
  
  // Check failure of by-index access of string characters (IE < 9)
  // and failure of `0 in boxedString` (Rhino)
      var boxedString = Object('a');
      var splitString = boxedString[0] !== 'a' || !(0 in boxedString);
  
      var properlyBoxesContext = function properlyBoxed(method) {
          // Check node 0.6.21 bug where third parameter is not boxed
          var properlyBoxesNonStrict = true;
          var properlyBoxesStrict = true;
          if (method) {
              method.call('foo', function (_, __, context) {
                  if (typeof context !== 'object') {
                      properlyBoxesNonStrict = false;
                  }
              });
  
              method.call([1], function () {
                  'use strict';
  
                  properlyBoxesStrict = typeof this === 'string';
              }, 'x');
          }
          return !!method && properlyBoxesNonStrict && properlyBoxesStrict;
      };
  
      defineProperties(ArrayPrototype, {
          forEach: function forEach(callbackfn /*, thisArg*/) {
              var object = ES.ToObject(this);
              var self = splitString && isString(this) ? this.split('') : object;
              var i = -1;
              var length = self.length >>> 0;
              var T;
              if (arguments.length > 1) {
                  T = arguments[1];
              }
  
              // If no callback function or if callback is not a callable function
              if (!isCallable(callbackfn)) {
                  throw new TypeError('Array.prototype.forEach callback must be a function');
              }
  
              while (++i < length) {
                  if (i in self) {
                      // Invoke the callback function with call, passing arguments:
                      // context, property value, property key, thisArg object
                      if (typeof T !== 'undefined') {
                          callbackfn.call(T, self[i], i, object);
                      } else {
                          callbackfn(self[i], i, object);
                      }
                  }
              }
          }
      }, !properlyBoxesContext(ArrayPrototype.forEach));
  
  // ES5 15.4.4.19
  // http://es5.github.com/#x15.4.4.19
  // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/map
      defineProperties(ArrayPrototype, {
          map: function map(callbackfn/*, thisArg*/) {
              var object = ES.ToObject(this);
              var self = splitString && isString(this) ? this.split('') : object;
              var length = self.length >>> 0;
              var result = Array(length);
              var T;
              if (arguments.length > 1) {
                  T = arguments[1];
              }
  
              // If no callback function or if callback is not a callable function
              if (!isCallable(callbackfn)) {
                  throw new TypeError('Array.prototype.map callback must be a function');
              }
  
              for (var i = 0; i < length; i++) {
                  if (i in self) {
                      if (typeof T !== 'undefined') {
                          result[i] = callbackfn.call(T, self[i], i, object);
                      } else {
                          result[i] = callbackfn(self[i], i, object);
                      }
                  }
              }
              return result;
          }
      }, !properlyBoxesContext(ArrayPrototype.map));
  
  // ES5 15.4.4.20
  // http://es5.github.com/#x15.4.4.20
  // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/filter
      defineProperties(ArrayPrototype, {
          filter: function filter(callbackfn /*, thisArg*/) {
              var object = ES.ToObject(this);
              var self = splitString && isString(this) ? this.split('') : object;
              var length = self.length >>> 0;
              var result = [];
              var value;
              var T;
              if (arguments.length > 1) {
                  T = arguments[1];
              }
  
              // If no callback function or if callback is not a callable function
              if (!isCallable(callbackfn)) {
                  throw new TypeError('Array.prototype.filter callback must be a function');
              }
  
              for (var i = 0; i < length; i++) {
                  if (i in self) {
                      value = self[i];
                      if (typeof T === 'undefined' ? callbackfn(value, i, object) : callbackfn.call(T, value, i, object)) {
                          result.push(value);
                      }
                  }
              }
              return result;
          }
      }, !properlyBoxesContext(ArrayPrototype.filter));
  
  // ES5 15.4.4.16
  // http://es5.github.com/#x15.4.4.16
  // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/every
      defineProperties(ArrayPrototype, {
          every: function every(callbackfn /*, thisArg*/) {
              var object = ES.ToObject(this);
              var self = splitString && isString(this) ? this.split('') : object;
              var length = self.length >>> 0;
              var T;
              if (arguments.length > 1) {
                  T = arguments[1];
              }
  
              // If no callback function or if callback is not a callable function
              if (!isCallable(callbackfn)) {
                  throw new TypeError('Array.prototype.every callback must be a function');
              }
  
              for (var i = 0; i < length; i++) {
                  if (i in self && !(typeof T === 'undefined' ? callbackfn(self[i], i, object) : callbackfn.call(T, self[i], i, object))) {
                      return false;
                  }
              }
              return true;
          }
      }, !properlyBoxesContext(ArrayPrototype.every));
  
  // ES5 15.4.4.17
  // http://es5.github.com/#x15.4.4.17
  // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/some
      defineProperties(ArrayPrototype, {
          some: function some(callbackfn/*, thisArg */) {
              var object = ES.ToObject(this);
              var self = splitString && isString(this) ? this.split('') : object;
              var length = self.length >>> 0;
              var T;
              if (arguments.length > 1) {
                  T = arguments[1];
              }
  
              // If no callback function or if callback is not a callable function
              if (!isCallable(callbackfn)) {
                  throw new TypeError('Array.prototype.some callback must be a function');
              }
  
              for (var i = 0; i < length; i++) {
                  if (i in self && (typeof T === 'undefined' ? callbackfn(self[i], i, object) : callbackfn.call(T, self[i], i, object))) {
                      return true;
                  }
              }
              return false;
          }
      }, !properlyBoxesContext(ArrayPrototype.some));
  
  // ES5 15.4.4.21
  // http://es5.github.com/#x15.4.4.21
  // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduce
      var reduceCoercesToObject = false;
      if (ArrayPrototype.reduce) {
          reduceCoercesToObject = typeof ArrayPrototype.reduce.call('es5', function (_, __, ___, list) {
                  return list;
              }) === 'object';
      }
      defineProperties(ArrayPrototype, {
          reduce: function reduce(callbackfn /*, initialValue*/) {
              var object = ES.ToObject(this);
              var self = splitString && isString(this) ? this.split('') : object;
              var length = self.length >>> 0;
  
              // If no callback function or if callback is not a callable function
              if (!isCallable(callbackfn)) {
                  throw new TypeError('Array.prototype.reduce callback must be a function');
              }
  
              // no value to return if no initial value and an empty array
              if (length === 0 && arguments.length === 1) {
                  throw new TypeError('reduce of empty array with no initial value');
              }
  
              var i = 0;
              var result;
              if (arguments.length >= 2) {
                  result = arguments[1];
              } else {
                  do {
                      if (i in self) {
                          result = self[i++];
                          break;
                      }
  
                      // if array contains no values, no initial value to return
                      if (++i >= length) {
                          throw new TypeError('reduce of empty array with no initial value');
                      }
                  } while (true);
              }
  
              for (; i < length; i++) {
                  if (i in self) {
                      result = callbackfn(result, self[i], i, object);
                  }
              }
  
              return result;
          }
      }, !reduceCoercesToObject);
  
  // ES5 15.4.4.22
  // http://es5.github.com/#x15.4.4.22
  // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduceRight
      var reduceRightCoercesToObject = false;
      if (ArrayPrototype.reduceRight) {
          reduceRightCoercesToObject = typeof ArrayPrototype.reduceRight.call('es5', function (_, __, ___, list) {
                  return list;
              }) === 'object';
      }
      defineProperties(ArrayPrototype, {
          reduceRight: function reduceRight(callbackfn/*, initial*/) {
              var object = ES.ToObject(this);
              var self = splitString && isString(this) ? this.split('') : object;
              var length = self.length >>> 0;
  
              // If no callback function or if callback is not a callable function
              if (!isCallable(callbackfn)) {
                  throw new TypeError('Array.prototype.reduceRight callback must be a function');
              }
  
              // no value to return if no initial value, empty array
              if (length === 0 && arguments.length === 1) {
                  throw new TypeError('reduceRight of empty array with no initial value');
              }
  
              var result;
              var i = length - 1;
              if (arguments.length >= 2) {
                  result = arguments[1];
              } else {
                  do {
                      if (i in self) {
                          result = self[i--];
                          break;
                      }
  
                      // if array contains no values, no initial value to return
                      if (--i < 0) {
                          throw new TypeError('reduceRight of empty array with no initial value');
                      }
                  } while (true);
              }
  
              if (i < 0) {
                  return result;
              }
  
              do {
                  if (i in self) {
                      result = callbackfn(result, self[i], i, object);
                  }
              } while (i--);
  
              return result;
          }
      }, !reduceRightCoercesToObject);
  
  // ES5 15.4.4.14
  // http://es5.github.com/#x15.4.4.14
  // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf
      var hasFirefox2IndexOfBug = Array.prototype.indexOf && [0, 1].indexOf(1, 2) !== -1;
      defineProperties(ArrayPrototype, {
          indexOf: function indexOf(searchElement /*, fromIndex */) {
              var self = splitString && isString(this) ? this.split('') : ES.ToObject(this);
              var length = self.length >>> 0;
  
              if (length === 0) {
                  return -1;
              }
  
              var i = 0;
              if (arguments.length > 1) {
                  i = ES.ToInteger(arguments[1]);
              }
  
              // handle negative indices
              i = i >= 0 ? i : Math.max(0, length + i);
              for (; i < length; i++) {
                  if (i in self && self[i] === searchElement) {
                      return i;
                  }
              }
              return -1;
          }
      }, hasFirefox2IndexOfBug);
  
  // ES5 15.4.4.15
  // http://es5.github.com/#x15.4.4.15
  // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/lastIndexOf
      var hasFirefox2LastIndexOfBug = Array.prototype.lastIndexOf && [0, 1].lastIndexOf(0, -3) !== -1;
      defineProperties(ArrayPrototype, {
          lastIndexOf: function lastIndexOf(searchElement /*, fromIndex */) {
              var self = splitString && isString(this) ? this.split('') : ES.ToObject(this);
              var length = self.length >>> 0;
  
              if (length === 0) {
                  return -1;
              }
              var i = length - 1;
              if (arguments.length > 1) {
                  i = Math.min(i, ES.ToInteger(arguments[1]));
              }
              // handle negative indices
              i = i >= 0 ? i : length - Math.abs(i);
              for (; i >= 0; i--) {
                  if (i in self && searchElement === self[i]) {
                      return i;
                  }
              }
              return -1;
          }
      }, hasFirefox2LastIndexOfBug);
  
  //
  // Object
  // ======
  //
  
  // ES5 15.2.3.14
  // http://es5.github.com/#x15.2.3.14
  
  // http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation
      var hasDontEnumBug = !({'toString': null}).propertyIsEnumerable('toString'),
          hasProtoEnumBug = function () {
          }.propertyIsEnumerable('prototype'),
          hasStringEnumBug = !owns('x', '0'),
          dontEnums = [
              'toString',
              'toLocaleString',
              'valueOf',
              'hasOwnProperty',
              'isPrototypeOf',
              'propertyIsEnumerable',
              'constructor'
          ],
          dontEnumsLength = dontEnums.length;
  
      defineProperties(Object, {
          keys: function keys(object) {
              var isFn = isCallable(object),
                  isArgs = isArguments(object),
                  isObject = object !== null && typeof object === 'object',
                  isStr = isObject && isString(object);
  
              if (!isObject && !isFn && !isArgs) {
                  throw new TypeError('Object.keys called on a non-object');
              }
  
              var theKeys = [];
              var skipProto = hasProtoEnumBug && isFn;
              if ((isStr && hasStringEnumBug) || isArgs) {
                  for (var i = 0; i < object.length; ++i) {
                      theKeys.push(String(i));
                  }
              }
  
              if (!isArgs) {
                  for (var name in object) {
                      if (!(skipProto && name === 'prototype') && owns(object, name)) {
                          theKeys.push(String(name));
                      }
                  }
              }
  
              if (hasDontEnumBug) {
                  var ctor = object.constructor,
                      skipConstructor = ctor && ctor.prototype === object;
                  for (var j = 0; j < dontEnumsLength; j++) {
                      var dontEnum = dontEnums[j];
                      if (!(skipConstructor && dontEnum === 'constructor') && owns(object, dontEnum)) {
                          theKeys.push(dontEnum);
                      }
                  }
              }
              return theKeys;
          }
      });
  
      var keysWorksWithArguments = Object.keys && (function () {
              // Safari 5.0 bug
              return Object.keys(arguments).length === 2;
          }(1, 2));
      var originalKeys = Object.keys;
      defineProperties(Object, {
          keys: function keys(object) {
              if (isArguments(object)) {
                  return originalKeys(ArrayPrototype.slice.call(object));
              } else {
                  return originalKeys(object);
              }
          }
      }, !keysWorksWithArguments);
  
  //
  // Date
  // ====
  //
  
  // ES5 15.9.5.43
  // http://es5.github.com/#x15.9.5.43
  // This function returns a String value represent the instance in time
  // represented by this Date object. The format of the String is the Date Time
  // string format defined in 15.9.1.15. All fields are present in the String.
  // The time zone is always UTC, denoted by the suffix Z. If the time value of
  // this object is not a finite Number a RangeError exception is thrown.
      var negativeDate = -62198755200000;
      var negativeYearString = '-000001';
      var hasNegativeDateBug = Date.prototype.toISOString && new Date(negativeDate).toISOString().indexOf(negativeYearString) === -1;
  
      defineProperties(Date.prototype, {
          toISOString: function toISOString() {
              var result, length, value, year, month;
              if (!isFinite(this)) {
                  throw new RangeError('Date.prototype.toISOString called on non-finite value.');
              }
  
              year = this.getUTCFullYear();
  
              month = this.getUTCMonth();
              // see https://github.com/es-shims/es5-shim/issues/111
              year += Math.floor(month / 12);
              month = (month % 12 + 12) % 12;
  
              // the date time string format is specified in 15.9.1.15.
              result = [month + 1, this.getUTCDate(), this.getUTCHours(), this.getUTCMinutes(), this.getUTCSeconds()];
              year = (
                  (year < 0 ? '-' : (year > 9999 ? '+' : '')) +
                  ('00000' + Math.abs(year)).slice((0 <= year && year <= 9999) ? -4 : -6)
              );
  
              length = result.length;
              while (length--) {
                  value = result[length];
                  // pad months, days, hours, minutes, and seconds to have two
                  // digits.
                  if (value < 10) {
                      result[length] = '0' + value;
                  }
              }
              // pad milliseconds to have three digits.
              return (
                  year + '-' + result.slice(0, 2).join('-') +
                  'T' + result.slice(2).join(':') + '.' +
                  ('000' + this.getUTCMilliseconds()).slice(-3) + 'Z'
              );
          }
      }, hasNegativeDateBug);
  
  // ES5 15.9.5.44
  // http://es5.github.com/#x15.9.5.44
  // This function provides a String representation of a Date object for use by
  // JSON.stringify (15.12.3).
      var dateToJSONIsSupported = (function () {
          try {
              return Date.prototype.toJSON &&
                  new Date(NaN).toJSON() === null &&
                  new Date(negativeDate).toJSON().indexOf(negativeYearString) !== -1 &&
                  Date.prototype.toJSON.call({ // generic
                      toISOString: function () {
                          return true;
                      }
                  });
          } catch (e) {
              return false;
          }
      }());
      if (!dateToJSONIsSupported) {
          Date.prototype.toJSON = function toJSON(key) {
              // When the toJSON method is called with argument key, the following
              // steps are taken:
  
              // 1.  Let O be the result of calling ToObject, giving it the this
              // value as its argument.
              // 2. Let tv be ES.ToPrimitive(O, hint Number).
              var O = Object(this);
              var tv = ES.ToPrimitive(O);
              // 3. If tv is a Number and is not finite, return null.
              if (typeof tv === 'number' && !isFinite(tv)) {
                  return null;
              }
              // 4. Let toISO be the result of calling the [[Get]] internal method of
              // O with argument "toISOString".
              var toISO = O.toISOString;
              // 5. If IsCallable(toISO) is false, throw a TypeError exception.
              if (!isCallable(toISO)) {
                  throw new TypeError('toISOString property is not callable');
              }
              // 6. Return the result of calling the [[Call]] internal method of
              //  toISO with O as the this value and an empty argument list.
              return toISO.call(O);
  
              // NOTE 1 The argument is ignored.
  
              // NOTE 2 The toJSON function is intentionally generic; it does not
              // require that its this value be a Date object. Therefore, it can be
              // transferred to other kinds of objects for use as a method. However,
              // it does require that any such object have a toISOString method. An
              // object is free to use the argument key to filter its
              // stringification.
          };
      }
  
  // ES5 15.9.4.2
  // http://es5.github.com/#x15.9.4.2
  // based on work shared by Daniel Friesen (dantman)
  // http://gist.github.com/303249
      var supportsExtendedYears = Date.parse('+033658-09-27T01:46:40.000Z') === 1e15;
      var acceptsInvalidDates = !isNaN(Date.parse('2012-04-04T24:00:00.500Z')) || !isNaN(Date.parse('2012-11-31T23:59:59.000Z')) || !isNaN(Date.parse('2012-12-31T23:59:60.000Z'));
      var doesNotParseY2KNewYear = isNaN(Date.parse('2000-01-01T00:00:00.000Z'));
      if (!Date.parse || doesNotParseY2KNewYear || acceptsInvalidDates || !supportsExtendedYears) {
          // XXX global assignment won't work in embeddings that use
          // an alternate object for the context.
          /* global Date: true */
          /* eslint-disable no-undef */
          Date = (function (NativeDate) {
              /* eslint-enable no-undef */
              // Date.length === 7
              var DateShim = function Date(Y, M, D, h, m, s, ms) {
                  var length = arguments.length;
                  var date;
                  if (this instanceof NativeDate) {
                      date = length === 1 && String(Y) === Y ? // isString(Y)
                          // We explicitly pass it through parse:
                          new NativeDate(DateShim.parse(Y)) :
                          // We have to manually make calls depending on argument
                          // length here
                          length >= 7 ? new NativeDate(Y, M, D, h, m, s, ms) :
                              length >= 6 ? new NativeDate(Y, M, D, h, m, s) :
                                  length >= 5 ? new NativeDate(Y, M, D, h, m) :
                                      length >= 4 ? new NativeDate(Y, M, D, h) :
                                          length >= 3 ? new NativeDate(Y, M, D) :
                                              length >= 2 ? new NativeDate(Y, M) :
                                                  length >= 1 ? new NativeDate(Y) :
                                                      new NativeDate();
                  } else {
                      date = NativeDate.apply(this, arguments);
                  }
                  // Prevent mixups with unfixed Date object
                  defineProperties(date, {constructor: DateShim}, true);
                  return date;
              };
  
              // 15.9.1.15 Date Time String Format.
              var isoDateExpression = new RegExp('^' +
                  '(\\d{4}|[+-]\\d{6})' + // four-digit year capture or sign +
                      // 6-digit extended year
                  '(?:-(\\d{2})' + // optional month capture
                  '(?:-(\\d{2})' + // optional day capture
                  '(?:' + // capture hours:minutes:seconds.milliseconds
                  'T(\\d{2})' + // hours capture
                  ':(\\d{2})' + // minutes capture
                  '(?:' + // optional :seconds.milliseconds
                  ':(\\d{2})' + // seconds capture
                  '(?:(\\.\\d{1,}))?' + // milliseconds capture
                  ')?' +
                  '(' + // capture UTC offset component
                  'Z|' + // UTC capture
                  '(?:' + // offset specifier +/-hours:minutes
                  '([-+])' + // sign capture
                  '(\\d{2})' + // hours offset capture
                  ':(\\d{2})' + // minutes offset capture
                  ')' +
                  ')?)?)?)?' +
                  '$');
  
              var months = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365];
  
              var dayFromMonth = function dayFromMonth(year, month) {
                  var t = month > 1 ? 1 : 0;
                  return (
                      months[month] +
                      Math.floor((year - 1969 + t) / 4) -
                      Math.floor((year - 1901 + t) / 100) +
                      Math.floor((year - 1601 + t) / 400) +
                      365 * (year - 1970)
                  );
              };
  
              var toUTC = function toUTC(t) {
                  return Number(new NativeDate(1970, 0, 1, 0, 0, 0, t));
              };
  
              // Copy any custom methods a 3rd party library may have added
              for (var key in NativeDate) {
                  if (owns(NativeDate, key)) {
                      DateShim[key] = NativeDate[key];
                  }
              }
  
              // Copy "native" methods explicitly; they may be non-enumerable
              defineProperties(DateShim, {
                  now: NativeDate.now,
                  UTC: NativeDate.UTC
              }, true);
              DateShim.prototype = NativeDate.prototype;
              defineProperties(DateShim.prototype, {
                  constructor: DateShim
              }, true);
  
              // Upgrade Date.parse to handle simplified ISO 8601 strings
              var parseShim = function parse(string) {
                  var match = isoDateExpression.exec(string);
                  if (match) {
                      // parse months, days, hours, minutes, seconds, and milliseconds
                      // provide default values if necessary
                      // parse the UTC offset component
                      var year = Number(match[1]),
                          month = Number(match[2] || 1) - 1,
                          day = Number(match[3] || 1) - 1,
                          hour = Number(match[4] || 0),
                          minute = Number(match[5] || 0),
                          second = Number(match[6] || 0),
                          millisecond = Math.floor(Number(match[7] || 0) * 1000),
                      // When time zone is missed, local offset should be used
                      // (ES 5.1 bug)
                      // see https://bugs.ecmascript.org/show_bug.cgi?id=112
                          isLocalTime = Boolean(match[4] && !match[8]),
                          signOffset = match[9] === '-' ? 1 : -1,
                          hourOffset = Number(match[10] || 0),
                          minuteOffset = Number(match[11] || 0),
                          result;
                      if (
                          hour < (
                              minute > 0 || second > 0 || millisecond > 0 ?
                                  24 : 25
                          ) &&
                          minute < 60 && second < 60 && millisecond < 1000 &&
                          month > -1 && month < 12 && hourOffset < 24 &&
                          minuteOffset < 60 && // detect invalid offsets
                          day > -1 &&
                          day < (
                              dayFromMonth(year, month + 1) -
                              dayFromMonth(year, month)
                          )
                      ) {
                          result = (
                                  (dayFromMonth(year, month) + day) * 24 +
                                  hour +
                                  hourOffset * signOffset
                              ) * 60;
                          result = (
                                  (result + minute + minuteOffset * signOffset) * 60 +
                                  second
                              ) * 1000 + millisecond;
                          if (isLocalTime) {
                              result = toUTC(result);
                          }
                          if (-8.64e15 <= result && result <= 8.64e15) {
                              return result;
                          }
                      }
                      return NaN;
                  }
                  return NativeDate.parse.apply(this, arguments);
              };
              defineProperties(DateShim, {parse: parseShim});
  
              return DateShim;
          }(Date));
          /* global Date: false */
      }
  
  // ES5 15.9.4.4
  // http://es5.github.com/#x15.9.4.4
      if (!Date.now) {
          Date.now = function now() {
              return new Date().getTime();
          };
      }
  
  //
  // Number
  // ======
  //
  
  // ES5.1 15.7.4.5
  // http://es5.github.com/#x15.7.4.5
      var hasToFixedBugs = NumberPrototype.toFixed && (
              (0.00008).toFixed(3) !== '0.000' ||
              (0.9).toFixed(0) !== '1' ||
              (1.255).toFixed(2) !== '1.25' ||
              (1000000000000000128).toFixed(0) !== '1000000000000000128'
          );
  
      var toFixedHelpers = {
          base: 1e7,
          size: 6,
          data: [0, 0, 0, 0, 0, 0],
          multiply: function multiply(n, c) {
              var i = -1;
              var c2 = c;
              while (++i < toFixedHelpers.size) {
                  c2 += n * toFixedHelpers.data[i];
                  toFixedHelpers.data[i] = c2 % toFixedHelpers.base;
                  c2 = Math.floor(c2 / toFixedHelpers.base);
              }
          },
          divide: function divide(n) {
              var i = toFixedHelpers.size, c = 0;
              while (--i >= 0) {
                  c += toFixedHelpers.data[i];
                  toFixedHelpers.data[i] = Math.floor(c / n);
                  c = (c % n) * toFixedHelpers.base;
              }
          },
          numToString: function numToString() {
              var i = toFixedHelpers.size;
              var s = '';
              while (--i >= 0) {
                  if (s !== '' || i === 0 || toFixedHelpers.data[i] !== 0) {
                      var t = String(toFixedHelpers.data[i]);
                      if (s === '') {
                          s = t;
                      } else {
                          s += '0000000'.slice(0, 7 - t.length) + t;
                      }
                  }
              }
              return s;
          },
          pow: function pow(x, n, acc) {
              return (n === 0 ? acc : (n % 2 === 1 ? pow(x, n - 1, acc * x) : pow(x * x, n / 2, acc)));
          },
          log: function log(x) {
              var n = 0;
              var x2 = x;
              while (x2 >= 4096) {
                  n += 12;
                  x2 /= 4096;
              }
              while (x2 >= 2) {
                  n += 1;
                  x2 /= 2;
              }
              return n;
          }
      };
  
      defineProperties(NumberPrototype, {
          toFixed: function toFixed(fractionDigits) {
              var f, x, s, m, e, z, j, k;
  
              // Test for NaN and round fractionDigits down
              f = Number(fractionDigits);
              f = f !== f ? 0 : Math.floor(f);
  
              if (f < 0 || f > 20) {
                  throw new RangeError('Number.toFixed called with invalid number of decimals');
              }
  
              x = Number(this);
  
              // Test for NaN
              if (x !== x) {
                  return 'NaN';
              }
  
              // If it is too big or small, return the string value of the number
              if (x <= -1e21 || x >= 1e21) {
                  return String(x);
              }
  
              s = '';
  
              if (x < 0) {
                  s = '-';
                  x = -x;
              }
  
              m = '0';
  
              if (x > 1e-21) {
                  // 1e-21 < x < 1e21
                  // -70 < log2(x) < 70
                  e = toFixedHelpers.log(x * toFixedHelpers.pow(2, 69, 1)) - 69;
                  z = (e < 0 ? x * toFixedHelpers.pow(2, -e, 1) : x / toFixedHelpers.pow(2, e, 1));
                  z *= 0x10000000000000; // Math.pow(2, 52);
                  e = 52 - e;
  
                  // -18 < e < 122
                  // x = z / 2 ^ e
                  if (e > 0) {
                      toFixedHelpers.multiply(0, z);
                      j = f;
  
                      while (j >= 7) {
                          toFixedHelpers.multiply(1e7, 0);
                          j -= 7;
                      }
  
                      toFixedHelpers.multiply(toFixedHelpers.pow(10, j, 1), 0);
                      j = e - 1;
  
                      while (j >= 23) {
                          toFixedHelpers.divide(1 << 23);
                          j -= 23;
                      }
  
                      toFixedHelpers.divide(1 << j);
                      toFixedHelpers.multiply(1, 1);
                      toFixedHelpers.divide(2);
                      m = toFixedHelpers.numToString();
                  } else {
                      toFixedHelpers.multiply(0, z);
                      toFixedHelpers.multiply(1 << (-e), 0);
                      m = toFixedHelpers.numToString() + '0.00000000000000000000'.slice(2, 2 + f);
                  }
              }
  
              if (f > 0) {
                  k = m.length;
  
                  if (k <= f) {
                      m = s + '0.0000000000000000000'.slice(0, f - k + 2) + m;
                  } else {
                      m = s + m.slice(0, k - f) + '.' + m.slice(k - f);
                  }
              } else {
                  m = s + m;
              }
  
              return m;
          }
      }, hasToFixedBugs);
  
  //
  // String
  // ======
  //
  
  // ES5 15.5.4.14
  // http://es5.github.com/#x15.5.4.14
  
  // [bugfix, IE lt 9, firefox 4, Konqueror, Opera, obscure browsers]
  // Many browsers do not split properly with regular expressions or they
  // do not perform the split correctly under obscure conditions.
  // See http://blog.stevenlevithan.com/archives/cross-browser-split
  // I've tested in many browsers and this seems to cover the deviant ones:
  //    'ab'.split(/(?:ab)*/) should be ["", ""], not [""]
  //    '.'.split(/(.?)(.?)/) should be ["", ".", "", ""], not ["", ""]
  //    'tesst'.split(/(s)*/) should be ["t", undefined, "e", "s", "t"], not
  //       [undefined, "t", undefined, "e", ...]
  //    ''.split(/.?/) should be [], not [""]
  //    '.'.split(/()()/) should be ["."], not ["", "", "."]
  
      var string_split = StringPrototype.split;
      if (
          'ab'.split(/(?:ab)*/).length !== 2 ||
          '.'.split(/(.?)(.?)/).length !== 4 ||
          'tesst'.split(/(s)*/)[1] === 't' ||
          'test'.split(/(?:)/, -1).length !== 4 ||
          ''.split(/.?/).length ||
          '.'.split(/()()/).length > 1
      ) {
          (function () {
              var compliantExecNpcg = typeof (/()??/).exec('')[1] === 'undefined'; // NPCG: nonparticipating capturing group
  
              StringPrototype.split = function (separator, limit) {
                  var string = this;
                  if (typeof separator === 'undefined' && limit === 0) {
                      return [];
                  }
  
                  // If `separator` is not a regex, use native split
                  if (!isRegex(separator)) {
                      return string_split.call(this, separator, limit);
                  }
  
                  var output = [];
                  var flags = (separator.ignoreCase ? 'i' : '') +
                          (separator.multiline ? 'm' : '') +
                          (separator.extended ? 'x' : '') + // Proposed for ES6
                          (separator.sticky ? 'y' : ''), // Firefox 3+
                      lastLastIndex = 0,
                  // Make `global` and avoid `lastIndex` issues by working with a copy
                      separator2, match, lastIndex, lastLength;
                  var separatorCopy = new RegExp(separator.source, flags + 'g');
                  string += ''; // Type-convert
                  if (!compliantExecNpcg) {
                      // Doesn't need flags gy, but they don't hurt
                      separator2 = new RegExp('^' + separatorCopy.source + '$(?!\\s)', flags);
                  }
                  /* Values for `limit`, per the spec:
                   * If undefined: 4294967295 // Math.pow(2, 32) - 1
                   * If 0, Infinity, or NaN: 0
                   * If positive number: limit = Math.floor(limit); if (limit > 4294967295) limit -= 4294967296;
                   * If negative number: 4294967296 - Math.floor(Math.abs(limit))
                   * If other: Type-convert, then use the above rules
                   */
                  var splitLimit = typeof limit === 'undefined' ?
                  -1 >>> 0 : // Math.pow(2, 32) - 1
                      ES.ToUint32(limit);
                  match = separatorCopy.exec(string);
                  while (match) {
                      // `separatorCopy.lastIndex` is not reliable cross-browser
                      lastIndex = match.index + match[0].length;
                      if (lastIndex > lastLastIndex) {
                          output.push(string.slice(lastLastIndex, match.index));
                          // Fix browsers whose `exec` methods don't consistently return `undefined` for
                          // nonparticipating capturing groups
                          if (!compliantExecNpcg && match.length > 1) {
                              /* eslint-disable no-loop-func */
                              match[0].replace(separator2, function () {
                                  for (var i = 1; i < arguments.length - 2; i++) {
                                      if (typeof arguments[i] === 'undefined') {
                                          match[i] = void 0;
                                      }
                                  }
                              });
                              /* eslint-enable no-loop-func */
                          }
                          if (match.length > 1 && match.index < string.length) {
                              array_push.apply(output, match.slice(1));
                          }
                          lastLength = match[0].length;
                          lastLastIndex = lastIndex;
                          if (output.length >= splitLimit) {
                              break;
                          }
                      }
                      if (separatorCopy.lastIndex === match.index) {
                          separatorCopy.lastIndex++; // Avoid an infinite loop
                      }
                      match = separatorCopy.exec(string);
                  }
                  if (lastLastIndex === string.length) {
                      if (lastLength || !separatorCopy.test('')) {
                          output.push('');
                      }
                  } else {
                      output.push(string.slice(lastLastIndex));
                  }
                  return output.length > splitLimit ? output.slice(0, splitLimit) : output;
              };
          }());
  
  // [bugfix, chrome]
  // If separator is undefined, then the result array contains just one String,
  // which is the this value (converted to a String). If limit is not undefined,
  // then the output array is truncated so that it contains no more than limit
  // elements.
  // "0".split(undefined, 0) -> []
      } else if ('0'.split(void 0, 0).length) {
          StringPrototype.split = function split(separator, limit) {
              if (typeof separator === 'undefined' && limit === 0) {
                  return [];
              }
              return string_split.call(this, separator, limit);
          };
      }
  
      var str_replace = StringPrototype.replace;
      var replaceReportsGroupsCorrectly = (function () {
          var groups = [];
          'x'.replace(/x(.)?/g, function (match, group) {
              groups.push(group);
          });
          return groups.length === 1 && typeof groups[0] === 'undefined';
      }());
  
      if (!replaceReportsGroupsCorrectly) {
          StringPrototype.replace = function replace(searchValue, replaceValue) {
              var isFn = isCallable(replaceValue);
              var hasCapturingGroups = isRegex(searchValue) && (/\)[*?]/).test(searchValue.source);
              if (!isFn || !hasCapturingGroups) {
                  return str_replace.call(this, searchValue, replaceValue);
              } else {
                  var wrappedReplaceValue = function (match) {
                      var length = arguments.length;
                      var originalLastIndex = searchValue.lastIndex;
                      searchValue.lastIndex = 0;
                      var args = searchValue.exec(match) || [];
                      searchValue.lastIndex = originalLastIndex;
                      args.push(arguments[length - 2], arguments[length - 1]);
                      return replaceValue.apply(this, args);
                  };
                  return str_replace.call(this, searchValue, wrappedReplaceValue);
              }
          };
      }
  
  // ECMA-262, 3rd B.2.3
  // Not an ECMAScript standard, although ECMAScript 3rd Edition has a
  // non-normative section suggesting uniform semantics and it should be
  // normalized across all browsers
  // [bugfix, IE lt 9] IE < 9 substr() with negative value not working in IE
      var string_substr = StringPrototype.substr;
      var hasNegativeSubstrBug = ''.substr && '0b'.substr(-1) !== 'b';
      defineProperties(StringPrototype, {
          substr: function substr(start, length) {
              var normalizedStart = start;
              if (start < 0) {
                  normalizedStart = Math.max(this.length + start, 0);
              }
              return string_substr.call(this, normalizedStart, length);
          }
      }, hasNegativeSubstrBug);
  
  // ES5 15.5.4.20
  // whitespace from: http://es5.github.io/#x15.5.4.20
      var ws = '\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003' +
          '\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028' +
          '\u2029\uFEFF';
      var zeroWidth = '\u200b';
      var wsRegexChars = '[' + ws + ']';
      var trimBeginRegexp = new RegExp('^' + wsRegexChars + wsRegexChars + '*');
      var trimEndRegexp = new RegExp(wsRegexChars + wsRegexChars + '*$');
      var hasTrimWhitespaceBug = StringPrototype.trim && (ws.trim() || !zeroWidth.trim());
      defineProperties(StringPrototype, {
          // http://blog.stevenlevithan.com/archives/faster-trim-javascript
          // http://perfectionkills.com/whitespace-deviations/
          trim: function trim() {
              if (typeof this === 'undefined' || this === null) {
                  throw new TypeError("can't convert " + this + ' to object');
              }
              return String(this).replace(trimBeginRegexp, '').replace(trimEndRegexp, '');
          }
      }, hasTrimWhitespaceBug);
  
  // ES-5 15.1.2.2
      if (parseInt(ws + '08') !== 8 || parseInt(ws + '0x16') !== 22) {
          /* global parseInt: true */
          parseInt = (function (origParseInt) {
              var hexRegex = /^0[xX]/;
              return function parseInt(str, radix) {
                  var string = String(str).trim();
                  var defaultedRadix = Number(radix) || (hexRegex.test(string) ? 16 : 10);
                  return origParseInt(string, defaultedRadix);
              };
          }(parseInt));
      }
  
  }));
  
  !window.addEventListener && (function (WindowPrototype, DocumentPrototype, ElementPrototype, addEventListener, removeEventListener, dispatchEvent, registry) {
      WindowPrototype[addEventListener] = DocumentPrototype[addEventListener] = ElementPrototype[addEventListener] = function (type, listener) {
          var target = this;
  
          registry.unshift([target, type, listener, function (event) {
              event.currentTarget = target;
              event.preventDefault = function () {
                  event.returnValue = false
              };
              event.stopPropagation = function () {
                  event.cancelBubble = true
              };
              event.target = event.srcElement || target;
  
              listener.call(target, event);
          }]);
  
          this.attachEvent("on" + type, registry[0][3]);
      };
  
      WindowPrototype[removeEventListener] = DocumentPrototype[removeEventListener] = ElementPrototype[removeEventListener] = function (type, listener) {
          for (var index = 0, register; register = registry[index]; ++index) {
              if (register[0] == this && register[1] == type && register[2] == listener) {
                  return this.detachEvent("on" + type, registry.splice(index, 1)[0][3]);
              }
          }
      };
  
      WindowPrototype[dispatchEvent] = DocumentPrototype[dispatchEvent] = ElementPrototype[dispatchEvent] = function (eventObject) {
          return this.fireEvent("on" + eventObject.type, eventObject);
      };
  })(Window.prototype, HTMLDocument.prototype, Element.prototype, "addEventListener", "removeEventListener", "dispatchEvent", []);
  
  /**
   * Module: rem - v1.3.4
   * Description: A polyfill to parse CSS links and rewrite pixel equivalents into head for non supporting browsers
   * Date Built: 2014-07-02
   * Copyright (c) 2014  | Chuck Carpenter <chuck.carpenter@me.com>,Lucas Serven <lserven@gmail.com>;
   * @see https://github.com/chuckcarpenter/REM-unit-polyfill
   **/
  
  (function (window, undefined) {
      "use strict";
      // test for REM unit support
      var cssremunit = function () {
              var div = document.createElement('div');
              div.style.cssText = 'font-size: 1rem;';
  
              return (/rem/).test(div.style.fontSize);
          },
  
      // filter returned links for stylesheets
          isStyleSheet = function () {
              var styles = document.getElementsByTagName('link'),
                  filteredLinks = [];
  
              for (var i = 0; i < styles.length; i++) {
                  if (styles[i].rel.toLowerCase() === 'stylesheet' && styles[i].getAttribute('data-norem') === null) {
  
                      filteredLinks.push(styles[i].href);
                  }
              }
  
              return filteredLinks;
          },
  
          processLinks = function () {
              //prepare to match each link
              for (var i = 0; i < links.length; i++) {
                  xhr(links[i], storeCSS);
              }
          },
  
          storeCSS = function (response, link) {
  
              preCSS.push(response.responseText);
              CSSLinks.push(link);
  
              if (CSSLinks.length === links.length) {
                  for (var j = 0; j < CSSLinks.length; j++) {
                      matchCSS(preCSS[j], CSSLinks[j]);
                  }
  
                  if (( links = importLinks.slice(0) ).length > 0) { //after finishing all current links, set links equal to the new imports found
                      CSSLinks = [];
                      preCSS = [];
                      importLinks = [];
                      processLinks();
                  } else {
                      buildCSS();
                  }
              }
          },
  
          matchCSS = function (sheetCSS, link) { // collect all of the rules from the xhr response texts and match them to a pattern
              var clean = removeMediaQueries(sheetCSS).replace(/\/\*[\s\S]*?\*\//g, ''), // remove MediaQueries and comments
                  pattern = /[\w\d\s\-\/\\\[\]:,.'"*()<>+~%#^$_=|@]+\{[\w\d\s\-\/\\%#:!;,.'"*()]+\d*\.?\d+rem[\w\d\s\-\/\\%#:!;,.'"*()]*\}/g, //find selectors that use rem in one or more of their rules
                  current = clean.match(pattern),
                  remPattern = /\d*\.?\d+rem/g,
                  remCurrent = clean.match(remPattern),
                  sheetPathPattern = /(.*\/)/,
                  sheetPath = sheetPathPattern.exec(link)[0], //relative path to css file specified in @import
                  importPattern = /@import (?:url\()?['"]?([^'\)"]*)['"]?\)?[^;]*/gm, //matches all @import variations outlined at: https://developer.mozilla.org/en-US/docs/Web/CSS/@import
                  importStatement;
  
              while ((importStatement = importPattern.exec(sheetCSS)) !== null) {
                  if (importStatement[1].indexOf("/") === 0) { // check if the value of importStatement[1] is a root relative path, in which case it shouldn't be concatenated with sheetPath
                      importLinks.push(importStatement[1]);
                  } else {
                      importLinks.push(sheetPath + importStatement[1]);
                  }
              }
  
              if (current !== null && current.length !== 0) {
                  found = found.concat(current); // save all of the blocks of rules with rem in a property
                  foundProps = foundProps.concat(remCurrent); // save all of the properties with rem
              }
          },
  
          buildCSS = function () { // first build each individual rule from elements in the found array and then add it to the string of rules.
              var pattern = /[\w\d\s\-\/\\%#:,.'"*()]+\d*\.?\d+rem[\w\d\s\-\/\\%#:!,.'"*()]*[;}]/g; // find properties with rem values in them
              for (var i = 0; i < found.length; i++) {
                  rules = rules + found[i].substr(0, found[i].indexOf("{") + 1); // save the selector portion of each rule with a rem value
                  var current = found[i].match(pattern);
                  for (var j = 0; j < current.length; j++) { // build a new set of with only the selector and properties that have rem in the value
                      rules = rules + current[j];
                      if (j === current.length - 1 && rules[rules.length - 1] !== "}") {
                          rules = rules + "\n}";
                      }
                  }
              }
  
              parseCSS();
          },
  
          parseCSS = function () { // replace each set of parentheses with evaluated content
              for (var i = 0; i < foundProps.length; i++) {
                  css[i] = Math.round(parseFloat(foundProps[i].substr(0, foundProps[i].length - 3) * fontSize)) + 'px';
              }
  
              loadCSS();
          },
  
          loadCSS = function () { // replace and load the new rules
              for (var i = 0; i < css.length; i++) { // only run this loop as many times as css has entries
                  if (css[i]) {
                      rules = rules.replace(foundProps[i], css[i]); // replace old rules with our processed rules
                  }
              }
              var remcss = document.createElement('style');
              remcss.setAttribute('type', 'text/css');
              remcss.id = 'remReplace';
              document.getElementsByTagName('head')[0].appendChild(remcss);   // create the new element
              if (remcss.styleSheet) {
                  remcss.styleSheet.cssText = rules; // IE8 will not support innerHTML on read-only elements, such as STYLE
              } else {
                  remcss.appendChild(document.createTextNode(rules));
              }
          },
  
          xhr = function (url, callback) { // create new XMLHttpRequest object and run it
              try {
                  //try to create a request object
                  //arranging the two conditions this way is for IE7/8's benefit
                  //so that it works with any combination of ActiveX or Native XHR settings,
                  //as long as one or the other is enabled; but if both are enabled
                  //it prefers ActiveX, which means it still works with local files
                  //(Native XHR in IE7/8 is blocked and throws "access is denied",
                  // but ActiveX is permitted if the user allows it [default is to prompt])
                  var xhr = window.ActiveXObject ? ( new ActiveXObject('Microsoft.XMLHTTP') || new ActiveXObject('Msxml2.XMLHTTP') ) : new XMLHttpRequest();
  
                  xhr.open('GET', url, true);
                  xhr.onreadystatechange = function () {
                      if (xhr.readyState === 4) {
                          callback(xhr, url);
                      } // else { callback function on AJAX error }
                  };
  
                  xhr.send(null);
              } catch (e) {
                  if (window.XDomainRequest) {
                      var xdr = new XDomainRequest();
                      xdr.open('get', url);
                      xdr.onload = function () {
                          callback(xdr, url);
                      };
                      xdr.onerror = function () {
                          return false; // xdr load fail
                      };
                      xdr.send();
                  }
              }
          },
  
      // Remove queries.
          removeMediaQueries = function (css) {
              // Test for Media Query support
              if (!window.matchMedia && !window.msMatchMedia) {
                  // If the browser doesn't support media queries, we find all @media declarations in the CSS and remove them.
                  // Note: Since @rules can't be nested in the CSS spec, we're safe to just check for the closest following "}}" to the "@media".
                  css = css.replace(/@media[\s\S]*?\}\s*\}/g, "");
              }
  
              return css;
          };
  
      if (!cssremunit()) { // this checks if the rem value is supported
          var rules = '', // initialize the rules variable in this scope so it can be used later
              links = isStyleSheet(), // initialize the array holding the sheets urls for use later
              importLinks = [], //initialize the array holding the import sheet urls for use later
              found = [], // initialize the array holding the found rules for use later
              foundProps = [], // initialize the array holding the found properties for use later
              preCSS = [], // initialize array that holds css before being parsed
              CSSLinks = [], //initialize array holding css links returned from xhr
              css = [], // initialize the array holding the parsed rules for use later
              fontSize = '';
  
          // Notice: rem is a "root em" that means that in case when html element size was changed by css
          // or style we should not change document.documentElement.fontSize to 1em - only body size should be changed
          // to 1em for calculation
  
          fontSize = (function () {
              var doc = document,
                  docElement = doc.documentElement,
                  body = doc.body || doc.createElement('body'),
                  isFakeBody = !doc.body,
                  div = doc.createElement('div'),
                  currentSize = body.style.fontSize,
                  size;
  
              if (isFakeBody) {
                  docElement.appendChild(body);
              }
  
              div.style.cssText = 'width:1em; position:absolute; visibility:hidden; padding: 0;';
  
              body.style.fontSize = '1em';
  
              body.appendChild(div);
              size = div.offsetWidth;
  
              if (isFakeBody) {
                  docElement.removeChild(body);
              }
              else {
                  body.removeChild(div);
                  body.style.fontSize = currentSize;
              }
  
              return size;
          }());
  
          processLinks();
      } // else { do nothing, you are awesome and have REM support }
  
  })(window);
  
  /*! Respond.js v1.4.2: min/max-width media query polyfill
   * Copyright 2014 Scott Jehl
   * Licensed under MIT
   * http://j.mp/respondjs */
  
  !function (a) {
      "use strict";
      a.matchMedia = a.matchMedia || function (a) {
              var b, c = a.documentElement, d = c.firstElementChild || c.firstChild, e = a.createElement("body"), f = a.createElement("div");
              return f.id = "mq-test-1", f.style.cssText = "position:absolute;top:-100em", e.style.background = "none", e.appendChild(f), function (a) {
                  return f.innerHTML = '&shy;<style media="' + a + '"> #mq-test-1 { width: 42px; }</style>', c.insertBefore(e, d), b = 42 === f.offsetWidth, c.removeChild(e), {
                      matches: b,
                      media: a
                  }
              }
          }(a.document)
  }(this), function (a) {
      "use strict";
      function b() {
          v(!0)
      }
  
      var c = {};
      a.respond = c, c.update = function () {
      };
      var d = [], e = function () {
          var b = !1;
          try {
              b = new a.XMLHttpRequest
          } catch (c) {
              b = new a.ActiveXObject("Microsoft.XMLHTTP")
          }
          return function () {
              return b
          }
      }(), f = function (a, b) {
          var c = e();
          c && (c.open("GET", a, !0), c.onreadystatechange = function () {
              4 !== c.readyState || 200 !== c.status && 304 !== c.status || b(c.responseText)
          }, 4 !== c.readyState && c.send(null))
      }, g = function (a) {
          return a.replace(c.regex.minmaxwh, "").match(c.regex.other)
      };
      if (c.ajax = f, c.queue = d, c.unsupportedmq = g, c.regex = {
              media: /@media[^\{]+\{([^\{\}]*\{[^\}\{]*\})+/gi,
              keyframes: /@(?:\-(?:o|moz|webkit)\-)?keyframes[^\{]+\{(?:[^\{\}]*\{[^\}\{]*\})+[^\}]*\}/gi,
              comments: /\/\*[^*]*\*+([^/][^*]*\*+)*\//gi,
              urls: /(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g,
              findStyles: /@media *([^\{]+)\{([\S\s]+?)$/,
              only: /(only\s+)?([a-zA-Z]+)\s?/,
              minw: /\(\s*min\-width\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/,
              maxw: /\(\s*max\-width\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/,
              minmaxwh: /\(\s*m(in|ax)\-(height|width)\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/gi,
              other: /\([^\)]*\)/g
          }, c.mediaQueriesSupported = a.matchMedia && null !== a.matchMedia("only all") && a.matchMedia("only all").matches, !c.mediaQueriesSupported) {
          var h, i, j, k = a.document, l = k.documentElement, m = [], n = [], o = [], p = {}, q = 30, r = k.getElementsByTagName("head")[0] || l, s = k.getElementsByTagName("base")[0], t = r.getElementsByTagName("link"), u = function () {
              var a, b = k.createElement("div"), c = k.body, d = l.style.fontSize, e = c && c.style.fontSize, f = !1;
              return b.style.cssText = "position:absolute;font-size:1em;width:1em", c || (c = f = k.createElement("body"), c.style.background = "none"), l.style.fontSize = "100%", c.style.fontSize = "100%", c.appendChild(b), f && l.insertBefore(c, l.firstChild), a = b.offsetWidth, f ? l.removeChild(c) : c.removeChild(b), l.style.fontSize = d, e && (c.style.fontSize = e), a = j = parseFloat(a)
          }, v = function (b) {
              var c = "clientWidth", d = l[c], e = "CSS1Compat" === k.compatMode && d || k.body[c] || d, f = {}, g = t[t.length - 1], p = (new Date).getTime();
              if (b && h && q > p - h)return a.clearTimeout(i), i = a.setTimeout(v, q), void 0;
              h = p;
              for (var s in m)if (m.hasOwnProperty(s)) {
                  var w = m[s], x = w.minw, y = w.maxw, z = null === x, A = null === y, B = "em";
                  x && (x = parseFloat(x) * (x.indexOf(B) > -1 ? j || u() : 1)), y && (y = parseFloat(y) * (y.indexOf(B) > -1 ? j || u() : 1)), w.hasquery && (z && A || !(z || e >= x) || !(A || y >= e)) || (f[w.media] || (f[w.media] = []), f[w.media].push(n[w.rules]))
              }
              for (var C in o)o.hasOwnProperty(C) && o[C] && o[C].parentNode === r && r.removeChild(o[C]);
              o.length = 0;
              for (var D in f)if (f.hasOwnProperty(D)) {
                  var E = k.createElement("style"), F = f[D].join("\n");
                  E.type = "text/css", E.media = D, r.insertBefore(E, g.nextSibling), E.styleSheet ? E.styleSheet.cssText = F : E.appendChild(k.createTextNode(F)), o.push(E)
              }
          }, w = function (a, b, d) {
              var e = a.replace(c.regex.comments, "").replace(c.regex.keyframes, "").match(c.regex.media), f = e && e.length || 0;
              b = b.substring(0, b.lastIndexOf("/"));
              var h = function (a) {
                  return a.replace(c.regex.urls, "$1" + b + "$2$3")
              }, i = !f && d;
              b.length && (b += "/"), i && (f = 1);
              for (var j = 0; f > j; j++) {
                  var k, l, o, p;
                  i ? (k = d, n.push(h(a))) : (k = e[j].match(c.regex.findStyles) && RegExp.$1, n.push(RegExp.$2 && h(RegExp.$2))), o = k.split(","), p = o.length;
                  for (var q = 0; p > q; q++)l = o[q], g(l) || m.push({
                      media: l.split("(")[0].match(c.regex.only) && RegExp.$2 || "all",
                      rules: n.length - 1,
                      hasquery: l.indexOf("(") > -1,
                      minw: l.match(c.regex.minw) && parseFloat(RegExp.$1) + (RegExp.$2 || ""),
                      maxw: l.match(c.regex.maxw) && parseFloat(RegExp.$1) + (RegExp.$2 || "")
                  })
              }
              v()
          }, x = function () {
              if (d.length) {
                  var b = d.shift();
                  f(b.href, function (c) {
                      w(c, b.href, b.media), p[b.href] = !0, a.setTimeout(function () {
                          x()
                      }, 0)
                  })
              }
          }, y = function () {
              for (var b = 0; b < t.length; b++) {
                  var c = t[b], e = c.href, f = c.media, g = c.rel && "stylesheet" === c.rel.toLowerCase();
                  e && g && !p[e] && (c.styleSheet && c.styleSheet.rawCssText ? (w(c.styleSheet.rawCssText, e, f), p[e] = !0) : (!/^([a-zA-Z:]*\/\/)/.test(e) && !s || e.replace(RegExp.$1, "").split("/")[0] === a.location.host) && ("//" === e.substring(0, 2) && (e = a.location.protocol + e), d.push({
                      href: e,
                      media: f
                  })))
              }
              x()
          };
          y(), c.update = y, c.getEmValue = u, a.addEventListener ? a.addEventListener("resize", b, !1) : a.attachEvent && a.attachEvent("onresize", b)
      }
  }(this);