text: (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
  // Copyright Joyent, Inc. and other Node contributors.
  //
  // Permission is hereby granted, free of charge, to any person obtaining a
  // copy of this software and associated documentation files (the
  // "Software"), to deal in the Software without restriction, including
  // without limitation the rights to use, copy, modify, merge, publish,
  // distribute, sublicense, and/or sell copies of the Software, and to permit
  // persons to whom the Software is furnished to do so, subject to the
  // following conditions:
  //
  // The above copyright notice and this permission notice shall be included
  // in all copies or substantial portions of the Software.
  //
  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
  // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
  // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  // USE OR OTHER DEALINGS IN THE SOFTWARE.
  
  'use strict';
  
  var R = typeof Reflect === 'object' ? Reflect : null
  var ReflectApply = R && typeof R.apply === 'function'
    ? R.apply
    : function ReflectApply(target, receiver, args) {
      return Function.prototype.apply.call(target, receiver, args);
    }
  
  var ReflectOwnKeys
  if (R && typeof R.ownKeys === 'function') {
    ReflectOwnKeys = R.ownKeys
  } else if (Object.getOwnPropertySymbols) {
    ReflectOwnKeys = function ReflectOwnKeys(target) {
      return Object.getOwnPropertyNames(target)
        .concat(Object.getOwnPropertySymbols(target));
    };
  } else {
    ReflectOwnKeys = function ReflectOwnKeys(target) {
      return Object.getOwnPropertyNames(target);
    };
  }
  
  function ProcessEmitWarning(warning) {
    if (console && console.warn) console.warn(warning);
  }
  
  var NumberIsNaN = Number.isNaN || function NumberIsNaN(value) {
    return value !== value;
  }
  
  function EventEmitter() {
    EventEmitter.init.call(this);
  }
  module.exports = EventEmitter;
  module.exports.once = once;
  
  // Backwards-compat with node 0.10.x
  EventEmitter.EventEmitter = EventEmitter;
  
  EventEmitter.prototype._events = undefined;
  EventEmitter.prototype._eventsCount = 0;
  EventEmitter.prototype._maxListeners = undefined;
  
  // By default EventEmitters will print a warning if more than 10 listeners are
  // added to it. This is a useful default which helps finding memory leaks.
  var defaultMaxListeners = 10;
  
  function checkListener(listener) {
    if (typeof listener !== 'function') {
      throw new TypeError('The "listener" argument must be of type Function. Received type ' + typeof listener);
    }
  }
  
  Object.defineProperty(EventEmitter, 'defaultMaxListeners', {
    enumerable: true,
    get: function() {
      return defaultMaxListeners;
    },
    set: function(arg) {
      if (typeof arg !== 'number' || arg < 0 || NumberIsNaN(arg)) {
        throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received ' + arg + '.');
      }
      defaultMaxListeners = arg;
    }
  });
  
  EventEmitter.init = function() {
  
    if (this._events === undefined ||
        this._events === Object.getPrototypeOf(this)._events) {
      this._events = Object.create(null);
      this._eventsCount = 0;
    }
  
    this._maxListeners = this._maxListeners || undefined;
  };
  
  // Obviously not all Emitters should be limited to 10. This function allows
  // that to be increased. Set to zero for unlimited.
  EventEmitter.prototype.setMaxListeners = function setMaxListeners(n) {
    if (typeof n !== 'number' || n < 0 || NumberIsNaN(n)) {
      throw new RangeError('The value of "n" is out of range. It must be a non-negative number. Received ' + n + '.');
    }
    this._maxListeners = n;
    return this;
  };
  
  function _getMaxListeners(that) {
    if (that._maxListeners === undefined)
      return EventEmitter.defaultMaxListeners;
    return that._maxListeners;
  }
  
  EventEmitter.prototype.getMaxListeners = function getMaxListeners() {
    return _getMaxListeners(this);
  };
  
  EventEmitter.prototype.emit = function emit(type) {
    var args = [];
    for (var i = 1; i < arguments.length; i++) args.push(arguments[i]);
    var doError = (type === 'error');
  
    var events = this._events;
    if (events !== undefined)
      doError = (doError && events.error === undefined);
    else if (!doError)
      return false;
  
    // If there is no 'error' event listener then throw.
    if (doError) {
      var er;
      if (args.length > 0)
        er = args[0];
      if (er instanceof Error) {
        // Note: The comments on the `throw` lines are intentional, they show
        // up in Node's output if this results in an unhandled exception.
        throw er; // Unhandled 'error' event
      }
      // At least give some kind of context to the user
      var err = new Error('Unhandled error.' + (er ? ' (' + er.message + ')' : ''));
      err.context = er;
      throw err; // Unhandled 'error' event
    }
  
    var handler = events[type];
  
    if (handler === undefined)
      return false;
  
    if (typeof handler === 'function') {
      ReflectApply(handler, this, args);
    } else {
      var len = handler.length;
      var listeners = arrayClone(handler, len);
      for (var i = 0; i < len; ++i)
        ReflectApply(listeners[i], this, args);
    }
  
    return true;
  };
  
  function _addListener(target, type, listener, prepend) {
    var m;
    var events;
    var existing;
  
    checkListener(listener);
  
    events = target._events;
    if (events === undefined) {
      events = target._events = Object.create(null);
      target._eventsCount = 0;
    } else {
      // To avoid recursion in the case that type === "newListener"! Before
      // adding it to the listeners, first emit "newListener".
      if (events.newListener !== undefined) {
        target.emit('newListener', type,
                    listener.listener ? listener.listener : listener);
  
        // Re-assign `events` because a newListener handler could have caused the
        // this._events to be assigned to a new object
        events = target._events;
      }
      existing = events[type];
    }
  
    if (existing === undefined) {
      // Optimize the case of one listener. Don't need the extra array object.
      existing = events[type] = listener;
      ++target._eventsCount;
    } else {
      if (typeof existing === 'function') {
        // Adding the second element, need to change to array.
        existing = events[type] =
          prepend ? [listener, existing] : [existing, listener];
        // If we've already got an array, just append.
      } else if (prepend) {
        existing.unshift(listener);
      } else {
        existing.push(listener);
      }
  
      // Check for listener leak
      m = _getMaxListeners(target);
      if (m > 0 && existing.length > m && !existing.warned) {
        existing.warned = true;
        // No error code for this since it is a Warning
        // eslint-disable-next-line no-restricted-syntax
        var w = new Error('Possible EventEmitter memory leak detected. ' +
                            existing.length + ' ' + String(type) + ' listeners ' +
                            'added. Use emitter.setMaxListeners() to ' +
                            'increase limit');
        w.name = 'MaxListenersExceededWarning';
        w.emitter = target;
        w.type = type;
        w.count = existing.length;
        ProcessEmitWarning(w);
      }
    }
  
    return target;
  }
  
  EventEmitter.prototype.addListener = function addListener(type, listener) {
    return _addListener(this, type, listener, false);
  };
  
  EventEmitter.prototype.on = EventEmitter.prototype.addListener;
  
  EventEmitter.prototype.prependListener =
      function prependListener(type, listener) {
        return _addListener(this, type, listener, true);
      };
  
  function onceWrapper() {
    if (!this.fired) {
      this.target.removeListener(this.type, this.wrapFn);
      this.fired = true;
      if (arguments.length === 0)
        return this.listener.call(this.target);
      return this.listener.apply(this.target, arguments);
    }
  }
  
  function _onceWrap(target, type, listener) {
    var state = { fired: false, wrapFn: undefined, target: target, type: type, listener: listener };
    var wrapped = onceWrapper.bind(state);
    wrapped.listener = listener;
    state.wrapFn = wrapped;
    return wrapped;
  }
  
  EventEmitter.prototype.once = function once(type, listener) {
    checkListener(listener);
    this.on(type, _onceWrap(this, type, listener));
    return this;
  };
  
  EventEmitter.prototype.prependOnceListener =
      function prependOnceListener(type, listener) {
        checkListener(listener);
        this.prependListener(type, _onceWrap(this, type, listener));
        return this;
      };
  
  // Emits a 'removeListener' event if and only if the listener was removed.
  EventEmitter.prototype.removeListener =
      function removeListener(type, listener) {
        var list, events, position, i, originalListener;
  
        checkListener(listener);
  
        events = this._events;
        if (events === undefined)
          return this;
  
        list = events[type];
        if (list === undefined)
          return this;
  
        if (list === listener || list.listener === listener) {
          if (--this._eventsCount === 0)
            this._events = Object.create(null);
          else {
            delete events[type];
            if (events.removeListener)
              this.emit('removeListener', type, list.listener || listener);
          }
        } else if (typeof list !== 'function') {
          position = -1;
  
          for (i = list.length - 1; i >= 0; i--) {
            if (list[i] === listener || list[i].listener === listener) {
              originalListener = list[i].listener;
              position = i;
              break;
            }
          }
  
          if (position < 0)
            return this;
  
          if (position === 0)
            list.shift();
          else {
            spliceOne(list, position);
          }
  
          if (list.length === 1)
            events[type] = list[0];
  
          if (events.removeListener !== undefined)
            this.emit('removeListener', type, originalListener || listener);
        }
  
        return this;
      };
  
  EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
  
  EventEmitter.prototype.removeAllListeners =
      function removeAllListeners(type) {
        var listeners, events, i;
  
        events = this._events;
        if (events === undefined)
          return this;
  
        // not listening for removeListener, no need to emit
        if (events.removeListener === undefined) {
          if (arguments.length === 0) {
            this._events = Object.create(null);
            this._eventsCount = 0;
          } else if (events[type] !== undefined) {
            if (--this._eventsCount === 0)
              this._events = Object.create(null);
            else
              delete events[type];
          }
          return this;
        }
  
        // emit removeListener for all listeners on all events
        if (arguments.length === 0) {
          var keys = Object.keys(events);
          var key;
          for (i = 0; i < keys.length; ++i) {
            key = keys[i];
            if (key === 'removeListener') continue;
            this.removeAllListeners(key);
          }
          this.removeAllListeners('removeListener');
          this._events = Object.create(null);
          this._eventsCount = 0;
          return this;
        }
  
        listeners = events[type];
  
        if (typeof listeners === 'function') {
          this.removeListener(type, listeners);
        } else if (listeners !== undefined) {
          // LIFO order
          for (i = listeners.length - 1; i >= 0; i--) {
            this.removeListener(type, listeners[i]);
          }
        }
  
        return this;
      };
  
  function _listeners(target, type, unwrap) {
    var events = target._events;
  
    if (events === undefined)
      return [];
  
    var evlistener = events[type];
    if (evlistener === undefined)
      return [];
  
    if (typeof evlistener === 'function')
      return unwrap ? [evlistener.listener || evlistener] : [evlistener];
  
    return unwrap ?
      unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length);
  }
  
  EventEmitter.prototype.listeners = function listeners(type) {
    return _listeners(this, type, true);
  };
  
  EventEmitter.prototype.rawListeners = function rawListeners(type) {
    return _listeners(this, type, false);
  };
  
  EventEmitter.listenerCount = function(emitter, type) {
    if (typeof emitter.listenerCount === 'function') {
      return emitter.listenerCount(type);
    } else {
      return listenerCount.call(emitter, type);
    }
  };
  
  EventEmitter.prototype.listenerCount = listenerCount;
  function listenerCount(type) {
    var events = this._events;
  
    if (events !== undefined) {
      var evlistener = events[type];
  
      if (typeof evlistener === 'function') {
        return 1;
      } else if (evlistener !== undefined) {
        return evlistener.length;
      }
    }
  
    return 0;
  }
  
  EventEmitter.prototype.eventNames = function eventNames() {
    return this._eventsCount > 0 ? ReflectOwnKeys(this._events) : [];
  };
  
  function arrayClone(arr, n) {
    var copy = new Array(n);
    for (var i = 0; i < n; ++i)
      copy[i] = arr[i];
    return copy;
  }
  
  function spliceOne(list, index) {
    for (; index + 1 < list.length; index++)
      list[index] = list[index + 1];
    list.pop();
  }
  
  function unwrapListeners(arr) {
    var ret = new Array(arr.length);
    for (var i = 0; i < ret.length; ++i) {
      ret[i] = arr[i].listener || arr[i];
    }
    return ret;
  }
  
  function once(emitter, name) {
    return new Promise(function (resolve, reject) {
      function errorListener(err) {
        emitter.removeListener(name, resolver);
        reject(err);
      }
  
      function resolver() {
        if (typeof emitter.removeListener === 'function') {
          emitter.removeListener('error', errorListener);
        }
        resolve([].slice.call(arguments));
      };
  
      eventTargetAgnosticAddListener(emitter, name, resolver, { once: true });
      if (name !== 'error') {
        addErrorHandlerIfEventEmitter(emitter, errorListener, { once: true });
      }
    });
  }
  
  function addErrorHandlerIfEventEmitter(emitter, handler, flags) {
    if (typeof emitter.on === 'function') {
      eventTargetAgnosticAddListener(emitter, 'error', handler, flags);
    }
  }
  
  function eventTargetAgnosticAddListener(emitter, name, listener, flags) {
    if (typeof emitter.on === 'function') {
      if (flags.once) {
        emitter.once(name, listener);
      } else {
        emitter.on(name, listener);
      }
    } else if (typeof emitter.addEventListener === 'function') {
      // EventTarget does not have `error` event semantics like Node
      // EventEmitters, we do not listen for `error` events here.
      emitter.addEventListener(name, function wrapListener(arg) {
        // IE does not have builtin `{ once: true }` support so we
        // have to do it manually.
        if (flags.once) {
          emitter.removeEventListener(name, wrapListener);
        }
        listener(arg);
      });
    } else {
      throw new TypeError('The "emitter" argument must be of type EventEmitter. Received type ' + typeof emitter);
    }
  }
  
  },{}],2:[function(require,module,exports){
  var regl = require('regl')({
    extensions: ['oes_standard_derivatives']
  })
  var resl = require('resl')
  var camera = require('regl-camera')(regl, {
    distance: 1.5, theta: -Math.PI/2, phi: 0.0,
    center: [+0.0,+0.0,+0.0]
  })
  var mat4 = require('gl-mat4')
  var vec3 = require('gl-vec3')
  var tmpm = new Float32Array(16)
  var tmpv = new Float32Array(3)
  var PI = Math.PI
  
  var emitter = new(require('events').EventEmitter)()
  
  
  var icons = (function () {
    document.body.style = "background-color:#131f26"
    var div = document.createElement('div')
    div.innerHTML = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<!-- Created with Inkscape (http://www.inkscape.org/) -->\n\n<svg\n   xmlns:osb=\"http://www.openswatchbook.org/uri/2009/osb\"\n   xmlns:dc=\"http://purl.org/dc/elements/1.1/\"\n   xmlns:cc=\"http://creativecommons.org/ns#\"\n   xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"\n   xmlns:svg=\"http://www.w3.org/2000/svg\"\n   xmlns=\"http://www.w3.org/2000/svg\"\n   xmlns:sodipodi=\"http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd\"\n   xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\"\n   width=\"744.09448819\"\n   height=\"1052.3622047\"\n   id=\"svg2\"\n   version=\"1.1\"\n   inkscape:version=\"0.48.5 r10040\"\n   sodipodi:docname=\"icons.svg\">\n  <defs\n     id=\"defs4\">\n    <linearGradient\n       id=\"linearGradient5480\"\n       osb:paint=\"solid\">\n      <stop\n         style=\"stop-color:#f0eaea;stop-opacity:1;\"\n         offset=\"0\"\n         id=\"stop5482\" />\n    </linearGradient>\n  </defs>\n  <sodipodi:namedview\n     id=\"base\"\n     pagecolor=\"#ffffff\"\n     bordercolor=\"#666666\"\n     borderopacity=\"1.0\"\n     inkscape:pageopacity=\"0.0\"\n     inkscape:pageshadow=\"2\"\n     inkscape:zoom=\"4\"\n     inkscape:cx=\"292.55307\"\n     inkscape:cy=\"954.48721\"\n     inkscape:document-units=\"px\"\n     inkscape:current-layer=\"grid\"\n     showgrid=\"false\"\n     inkscape:window-width=\"1366\"\n     inkscape:window-height=\"768\"\n     inkscape:window-x=\"0\"\n     inkscape:window-y=\"0\"\n     inkscape:window-maximized=\"0\" />\n  <metadata\n     id=\"metadata7\">\n    <rdf:RDF>\n      <cc:Work\n         rdf:about=\"\">\n        <dc:format>image/svg+xml</dc:format>\n        <dc:type\n           rdf:resource=\"http://purl.org/dc/dcmitype/StillImage\" />\n        <dc:title />\n      </cc:Work>\n    </rdf:RDF>\n  </metadata>\n  <g\n     inkscape:label=\"Layer 1\"\n     inkscape:groupmode=\"layer\"\n     id=\"layer1\">\n    <g\n       id=\"fold\"\n       transform=\"translate(-34,-25.5)\"\n       inkscape:label=\"#g4037\">\n      <rect\n         y=\"73.989479\"\n         x=\"205.3773\"\n         height=\"53.870399\"\n         width=\"89.753067\"\n         id=\"rect4035\"\n         style=\"fill:#f0eaea;fill-opacity:1;stroke:#000000;stroke-width:0.75460124;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:3.01840492, 3.01840492;stroke-dashoffset:0\" />\n      <path\n         sodipodi:nodetypes=\"cc\"\n         inkscape:connector-curvature=\"0\"\n         id=\"path3890\"\n         d=\"m 208.02887,101.19538 86.13228,0\"\n         style=\"fill:none;stroke:#ac9393;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:4, 4;stroke-dashoffset:0.1\" />\n      <path\n         inkscape:connector-curvature=\"0\"\n         id=\"path3892\"\n         d=\"m 226.24191,71.941807 0,58.897193\"\n         style=\"fill:none;stroke:#ac9393;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:4, 4;stroke-dashoffset:4.9\" />\n      <path\n         style=\"fill:none;stroke:#ac9393;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:4, 4;stroke-dashoffset:4.9\"\n         d=\"m 250.07996,71.941807 0,58.897193\"\n         id=\"path3894\"\n         inkscape:connector-curvature=\"0\" />\n      <path\n         inkscape:connector-curvature=\"0\"\n         id=\"path3896\"\n         d=\"m 274.05805,71.941807 0,58.897193\"\n         style=\"fill:none;stroke:#ac9393;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:4, 4;stroke-dashoffset:4.9\" />\n    </g>\n    <path\n       style=\"fill:#f0eaea;fill-opacity:1;stroke:#000000;stroke-width:0.70692617px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:0\"\n       d=\"M 69.65625,40.697213 31.415963,78.9375 69.65625,117.17779 z\"\n       id=\"left\"\n       inkscape:connector-curvature=\"0\"\n       sodipodi:nodetypes=\"cccc\"\n       inkscape:label=\"#path3920\" />\n    <g\n       id=\"grid\"\n       inkscape:label=\"#g3845\">\n      <rect\n         y=\"37.112183\"\n         x=\"293.75\"\n         height=\"65.5\"\n         width=\"81.5\"\n         id=\"rect3831\"\n         style=\"fill:#ffffff;fill-opacity:0.05752213;stroke:none\" />\n      <path\n         style=\"fill:#f0eaea;fill-opacity:1;stroke:#000000;stroke-width:1.50406396;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:6.01625586, 6.01625586;stroke-dashoffset:0.1504064\"\n         d=\"m 297.00202,40.864206 15.22865,0 0,18.236765 -15.22865,0 z\"\n         id=\"rect5493\"\n         inkscape:connector-curvature=\"0\" />\n      <path\n         style=\"fill:#f0eaea;fill-opacity:1;stroke:#000000;stroke-width:1.50406396;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:6.01625586, 6.01625586;stroke-dashoffset:0.1504064\"\n         d=\"m 316.55484,40.864206 15.22865,0 0,18.236765 -15.22865,0 z\"\n         id=\"rect5495\"\n         inkscape:connector-curvature=\"0\" />\n      <path\n         style=\"fill:#f0eaea;fill-opacity:1;stroke:#000000;stroke-width:1.50406396;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:6.01625586, 6.01625586;stroke-dashoffset:0.1504064\"\n         d=\"m 336.29569,40.864206 15.22865,0 0,18.236765 -15.22865,0 z\"\n         id=\"rect5497\"\n         inkscape:connector-curvature=\"0\" />\n      <path\n         style=\"fill:#f0eaea;fill-opacity:1;stroke:#000000;stroke-width:1.50406396;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:6.01625586, 6.01625586;stroke-dashoffset:0.1504064\"\n         d=\"m 356.60056,40.864206 15.22865,0 0,18.236765 -15.22865,0 z\"\n         id=\"rect5499\"\n         inkscape:connector-curvature=\"0\" />\n      <path\n         style=\"fill:#f0eaea;fill-opacity:1;stroke:#000000;stroke-width:1.50406396;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:6.01625586, 6.01625586;stroke-dashoffset:0.1504064\"\n         d=\"m 297.00202,60.981075 15.22865,0 0,18.236776 -15.22865,0 z\"\n         id=\"rect5514\"\n         inkscape:connector-curvature=\"0\" />\n      <path\n         style=\"fill:#f0eaea;fill-opacity:1;stroke:#000000;stroke-width:1.50406396;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:6.01625586, 6.01625586;stroke-dashoffset:0.1504064\"\n         d=\"m 316.55484,60.981075 15.22865,0 0,18.236776 -15.22865,0 z\"\n         id=\"rect5516\"\n         inkscape:connector-curvature=\"0\" />\n      <path\n         style=\"fill:#f0eaea;fill-opacity:1;stroke:#000000;stroke-width:1.50406396;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:6.01625586, 6.01625586;stroke-dashoffset:0.1504064\"\n         d=\"m 336.29569,60.981075 15.22865,0 0,18.236776 -15.22865,0 z\"\n         id=\"rect5518\"\n         inkscape:connector-curvature=\"0\" />\n      <path\n         style=\"fill:#f0eaea;fill-opacity:1;stroke:#000000;stroke-width:1.50406396;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:6.01625586, 6.01625586;stroke-dashoffset:0.1504064\"\n         d=\"m 356.60056,60.981075 15.22865,0 0,18.236776 -15.22865,0 z\"\n         id=\"rect5520\"\n         inkscape:connector-curvature=\"0\" />\n      <path\n         style=\"fill:#f0eaea;fill-opacity:1;stroke:#000000;stroke-width:1.50406396;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:6.01625586, 6.01625586;stroke-dashoffset:0.1504064\"\n         d=\"m 297.00202,81.285931 15.22865,0 0,18.236776 -15.22865,0 z\"\n         id=\"rect5539\"\n         inkscape:connector-curvature=\"0\" />\n      <path\n         style=\"fill:#f0eaea;fill-opacity:1;stroke:#000000;stroke-width:1.50406396;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:6.01625586, 6.01625586;stroke-dashoffset:0.1504064\"\n         d=\"m 316.55484,81.285931 15.22865,0 0,18.236776 -15.22865,0 z\"\n         id=\"rect5541\"\n         inkscape:connector-curvature=\"0\" />\n      <path\n         style=\"fill:#f0eaea;fill-opacity:1;stroke:#000000;stroke-width:1.50406396;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:6.01625586, 6.01625586;stroke-dashoffset:0.1504064\"\n         d=\"m 336.29569,81.285931 15.22865,0 0,18.236776 -15.22865,0 z\"\n         id=\"rect5543\"\n         inkscape:connector-curvature=\"0\" />\n      <path\n         style=\"fill:#f0eaea;fill-opacity:1;stroke:#000000;stroke-width:1.50406396;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:6.01625586, 6.01625586;stroke-dashoffset:0.1504064\"\n         d=\"m 356.60056,81.285931 15.22865,0 0,18.236776 -15.22865,0 z\"\n         id=\"rect5545\"\n         inkscape:connector-curvature=\"0\" />\n    </g>\n    <path\n       inkscape:label=\"#path3920\"\n       sodipodi:nodetypes=\"cccc\"\n       inkscape:connector-curvature=\"0\"\n       id=\"right\"\n       d=\"M 97.415963,40.697213 135.65625,78.9375 97.415963,117.17779 z\"\n       style=\"fill:#f0eaea;fill-opacity:1;stroke:#000000;stroke-width:0.70692617px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:0\" />\n  </g>\n</svg>\n"
    var root = div.children[0]
    root.style.position = 'absolute'
    root.style.top = '0px'
    root.style.left = '0px'
    root.style.visibility = 'hidden'
    document.body.appendChild(root)
    return {
      element: root,
      get: function (name) {
        var elem = root.querySelector('#'+name)
        var copy = elem.cloneNode(true)
        var svg = document.createElementNS('http://www.w3.org/2000/svg','svg')
        var g = document.createElementNS('http://www.w3.org/2000/svg','g')
        var bbox = elem.getBoundingClientRect()
        svg.setAttribute('width', bbox.width)
        svg.setAttribute('height', bbox.height)
        g.setAttribute('transform',
          'translate('+(-bbox.left)+','+(-bbox.top)+')')
        svg.appendChild(g)
        g.appendChild(copy)
        return svg
      }
    }
  })()
  
  ;(function () {
    document.body.style.margin = '0px'
    document.body.style.overflow = 'hidden'
  
    var left = icons.get('left')
    left.style.position = 'absolute'
    left.style.left = '15px'
    left.style.bottom = '15px'
    left.style.zIndex = 100
    left.style.opacity = 0.2
    var lpath = left.querySelector('path')
    lpath.addEventListener('mouseover', function () {
      left.style.opacity = 0.8
    })
    lpath.addEventListener('mouseout', function () {
      left.style.opacity = 0.2
    })
    lpath.addEventListener('click', function () {
      emitter.emit('page:prev')
    })
    document.body.appendChild(left)
  
    var right = icons.get('right')
    right.style.position = 'absolute'
    right.style.right = '15px'
    right.style.bottom = '15px'
    right.style.zIndex = 100
    right.style.opacity = 0.2
    var rpath = right.querySelector('path')
    rpath.addEventListener('mouseover', function () {
      right.style.opacity = 0.8
    })
    rpath.addEventListener('mouseout', function () {
      right.style.opacity = 0.2
    })
    rpath.addEventListener('click', function () {
      emitter.emit('page:next')
    })
    document.body.appendChild(right)
  
    var fold = icons.get('fold')
    fold.style.position = 'absolute'
    fold.style.right = '15px'
    fold.style.top = '15px'
    fold.style.zIndex = 100
    fold.style.opacity = 0.2
    var fg = fold.querySelector('g')
    fg.addEventListener('mouseover', function () {
      fold.style.opacity = 0.8
    })
    fg.addEventListener('mouseout', function () {
      fold.style.opacity = 0.2
    })
    fg.addEventListener('click', function () {
      emitter.emit('fold:toggle')
    })
    document.body.appendChild(fold)
  })()
  
  var state = {
    page: 0,
    folded: true,
    speed: 0.35,
    zoom: 1,
    pan: [0,0,0],
    prevMouse: [-1,-1]
  }
  
  window.addEventListener('mousedown', frame)
  window.addEventListener('mouseup', frame)
  window.addEventListener('mousemove', function (ev) {
    if ((ev.buttons&1) && state.prevMouse[0] >= 0) {
      var dx = state.prevMouse[0] - ev.clientX
      var dy = state.prevMouse[1] - ev.clientY
      state.pan[0] -= dx*0.00175*state.zoom
      state.pan[1] -= dy*0.00175*state.zoom
      frame()
    }
    state.prevMouse[0] = ev.clientX
    state.prevMouse[1] = ev.clientY
  })
  
  var camera = (function () {
    var projection = new Float32Array(16)
    var view = new Float32Array(16)
    var eye = [0,0,-1.5]
    var center = [0,0,0]
    var up = [0,1,0]
    return regl({
      uniforms: {
        projection: function (context, props) {
          var aspect = context.viewportWidth / context.viewportHeight
          return mat4.perspective(projection,
            Math.PI/4, aspect, 0.1, 1000.0
          )
        },
        view: function (context, props) {
          center[0] = state.pan[0]
          center[1] = state.pan[1]
          eye[0] = state.pan[0]
          eye[1] = state.pan[1]
          eye[2] = -state.zoom * Math.max(1.0,
            Math.atan2(context.viewportHeight, context.viewportWidth)*PI)
          return mat4.lookAt(view, eye, center, up)
        }
      }
    })
  })()
  
  var papers = {
    p0: {
      parent: 'p7',
      positions: [+0.5,+0.5,+1.5,+0.5,+1.5,+1.5,+0.5,+1.5],
      cells: [[0,1,2],[0,2,3]],
      pose: new Float32Array(16),
      model: new Float32Array(16),
      pivot: [+0.5,+0.5,0.0],
      color: [0,0,0],
      page: 0
    },
    p1: {
      parent: 'p0',
      positions: [+1.5,+0.5,+2.5,+0.5,+2.5,+1.5,+1.5,+1.5],
      cells: [[0,1,2],[0,2,3]],
      pose: new Float32Array(16),
      model: new Float32Array(16),
      pivot: [+1.5,+0.5,0.0],
      color: [0,0,1],
      page: 1
    },
    p2: {
      parent: 'p1',
      positions: [+2.5,+0.5,+3.5,+0.5,+3.5,+1.5,+2.5,+1.5],
      cells: [[0,1,2],[0,2,3]],
      pose: new Float32Array(16),
      model: new Float32Array(16),
      pivot: [+2.5,+0.5,0.0],
      color: [0,1,0],
      page: 2
    },
    p3: {
      parent: 'p4',
      positions: [+2.5,-0.5,+3.5,-0.5,+3.5,+0.5,+2.5,+0.5],
      cells: [[0,1,2],[0,2,3]],
      pose: new Float32Array(16),
      model: new Float32Array(16),
      pivot: [2.5,0.5,0.0],
      color: [0,1,1],
      page: 3
    },
    p4: {
      parent: 'p5',
      positions: [+1.5,-0.5,+2.5,-0.5,+2.5,+0.5,+1.5,+0.5],
      cells: [[0,1,2],[0,2,3]],
      pose: new Float32Array(16),
      model: new Float32Array(16),
      pivot: [1.5,0.5,0.0],
      color: [1,0,0],
      page: 4
    },
    p5: {
      parent: 'p6',
      positions: [+0.5,-0.5,+1.5,-0.5,+1.5,+0.5,+0.5,+0.5],
      cells: [[0,1,2],[0,2,3]],
      pose: new Float32Array(16),
      model: new Float32Array(16),
      pivot: [0.5,0.5,0.0],
      color: [1,0,1],
      page: 5
    },
    p6: {
      parent: null,
      positions: [-0.5,-0.5,+0.5,-0.5,+0.5,+0.5,-0.5,+0.5],
      cells: [[0,1,2],[0,2,3]],
      pose: new Float32Array(16),
      model: new Float32Array(16),
      pivot: [0.0,0.0,0.0],
      color: [1,1,0],
      page: 6
    },
    p7: {
      parent: 'p6',
      positions: [-0.5,+0.5,+0.5,+0.5,+0.5,+1.5,-0.5,+1.5],
      cells: [[0,1,2],[0,2,3]],
      pose: new Float32Array(16),
      model: new Float32Array(16),
      pivot: [+0.0,+0.5,0.0],
      color: [1,1,1],
      page: 7
    }
  }
  var paperProps = Object.values(papers)
  var pose = {}
  Object.keys(papers).forEach(function (key) {
    pose[key] = papers[key].pose
    papers[key].offset = [0,0,0]
  })
  
  var file = 'decent-small.png'
  var pageOffset = 5
  var zine = regl.texture()
  
  resl({
    manifest: {
      zine: { type: 'image', src: file }
    },
    onDone: function (assets) {
      zine(assets.zine)
      frame()
    }
  })
  
  var flips = {
    5: [+1,+1,+1,+1,+1,+1,+1,+1],
    7: [+1,-1,-1,+1,+1,-1,-1,+1]
  }
  paperProps.forEach(function (paper) {
    paper.pageFlip = flips[pageOffset][paper.page]
    paper.pageOffset = pageOffset
  })
  
  var ease = {
    sineIn: require('eases/sine-in.js'),
    sineOut: require('eases/sine-out.js')
  }
  var zNear = 0
  var zFar = +2.0
  var tm = require('./tm.js')({
    page0Flip: {
      state: { x: PI, y: PI, page: 0, offset: [+0.0,+0.0,zNear], flip: +PI },
      easing: { x: ease.sineOut, y: ease.sineOut }
    },
    page0: {
      state: { x: PI, y: PI, page: 0, offset: [+0.0,+0.0,zNear], flip: 0 },
      easing: { x: ease.sineOut, y: ease.sineOut }
    },
    page1: {
      state: { x: PI, y: PI, page: 1, offset: [-0.5,+0.0,zNear], flip: 0 },
      easing: { x: ease.sineOut, y: ease.sineOut }
    },
    page2: {
      state: { x: PI, y: PI, page: 2, offset: [-0.5,+0.0,zNear], flip: 0 },
      easing: { x: ease.sineOut, y: ease.sineOut }
    },
    page3: {
      state: { x: PI, y: PI, page: 3, offset: [-0.5,+0.0,zNear], flip: 0 },
      easing: { x: ease.sineOut, y: ease.sineOut }
    },
    page4: {
      state: { x: PI, y: PI, page: 4, offset: [+0.0,+0.0,zNear], flip: 0 },
      easing: { x: ease.sineOut, y: ease.sineOut }
    },
    page4Flip: {
      state: { x: PI, y: PI, page: 4, offset: [+0.0,+0.0,zNear], flip: -PI },
      easing: { x: ease.sineOut, y: ease.sineOut }
    },
    fold0: {
      state: { x: PI, y: 0, page: 0, offset: [+0.0,+0.0,zFar], flip: 0 },
      easing: { x: ease.sineOut, y: ease.sineOut }
    },
    fold1: {
      state: { x: 0, y: 0, page: 0, offset: [-1.5,-0.5,zFar], flip: 0 },
      easing: { x: ease.sineOut, y: ease.sineOut }
    }
  })
  
  var draw = {
    paper: paper(regl, zine)
  }
  
  tm.go([ 'page0' ])
  frame()
  
  emitter.on('page:next', function () {
    var sp = state.speed
    if (!state.folded && state.page === 4) {
      tm.go([
        'fold1',
        sp,
        'fold0',
        sp,
        'page0'
      ])
      state.folded = true
    } else if (!state.folded) {
      tm.go([
        'fold1',
        sp,
        'fold0',
        sp,
        'page' + state.page,
        sp,
        'page' + String((state.page+1)%5)
      ])
      state.folded = true
    } else if (state.page === 4) {
      tm.go([ 'page4', sp, 'page4Flip' ])
    } else {
      tm.go([
        'page' + state.page,
        sp,
        'page' + String((state.page+1)%5)
      ])
    }
    state.page = (state.page+1)%5
    frame()
  })
  
  emitter.on('page:prev', function () {
    var sp = state.speed
    if (!state.folded && state.page === 0) {
      tm.go([
        'fold1',
        sp,
        'fold0',
        sp,
        'page4'
      ])
      state.folded = true
    } else if (!state.folded) {
      tm.go([
        'fold1',
        sp,
        'fold0',
        sp,
        'page' + state.page,
        sp,
        'page' + String((state.page+4)%5)
      ])
      state.folded = true
    } else if (state.page === 0) {
      tm.go([ 'page0', sp, 'page0Flip' ])
    } else {
      tm.go([
        'page' + state.page,
        sp,
        'page' + String((state.page+4)%5)
      ])
    }
    state.page = (state.page+4)%5
    frame()
  })
  
  emitter.on('fold:toggle', function () {
    if (state.folded) emitter.emit('fold:unfold')
    else emitter.emit('fold:fold')
  })
  
  emitter.on('fold:unfold', function () {
    var sp = state.speed
    tm.go([ 'page' + state.page, sp, 'fold0', sp, 'fold1' ])
    state.folded = false
    frame()
  })
  
  emitter.on('fold:fold', function () {
    var sp = state.speed
    tm.go([ 'fold1', sp, 'fold0', sp, 'page' + state.page ])
    state.folded = true
    frame()
  })
  
  window.addEventListener('keydown', function (ev) {
    if (ev.key === 'ArrowRight') {
      emitter.emit('page:next')
    } else if (ev.key === 'ArrowLeft') {
      emitter.emit('page:prev')
    } else if (ev.key === ' ') {
      emitter.emit('fold:toggle')
    }
  })
  
  window.addEventListener('resize', frame)
  
  function frame () {
    regl.poll()
    update(performance.now()/1000)
    updateModels()
    regl.clear({ color: [0,0.0,0,0], depth: true })
    camera(function () {
      draw.paper(paperProps)
    })
    if (!tm.stopped) window.requestAnimationFrame(frame)
  }
  
  function update (t) {
    paperProps.forEach(function (paper) {
      mat4.identity(paper.pose)
    })
    var { x, y, offset, page, flip } = tm.tick(t)
    paperProps.forEach(function (paper) {
      vec3.copy(paper.offset, offset)
      var z = 0
      if (paper.page < page*2) {
        z = -paper.page * x * 0.004
      } else {
        z = (paper.page - page*3) * x * 0.004
      }
      z *= (Math.abs(flip) > PI*0.5 ? -1 : +1)
      paper.offset[2] += z
    })
  
    mat4.rotateY(pose.p5,pose.p5,+x*0.5)
    mat4.rotateY(pose.p4,pose.p4,-x*1.0)
    mat4.rotateY(pose.p3,pose.p3,+x*0.5)
    mat4.rotateY(pose.p0,pose.p0,+x*0.5)
    mat4.rotateY(pose.p1,pose.p1,-x*1.0)
    mat4.rotateY(pose.p2,pose.p2,+x*0.5)
    mat4.rotateX(pose.p7,pose.p7,+x*1.0)
  
    mat4.rotateY(pose.p5,pose.p5,+y*0.5)
    mat4.rotateY(pose.p3,pose.p3,+y*0.5)
    mat4.rotateY(pose.p0,pose.p0,-y*1.5)
    mat4.rotateY(pose.p2,pose.p2,+y*0.5)
  
    mat4.rotateY(pose.p0,pose.p0,
      +smstep(0,1,page)*PI
      -smstep(3,4,page)*PI
    )
    mat4.rotateY(pose.p2,pose.p2,
      +smstep(1,2,page)*PI
      -smstep(0,1,page)*PI
    )
    mat4.rotateY(pose.p3,pose.p3,
      -smstep(1,2,page)*PI
      +smstep(2,3,page)*PI
    )
    mat4.rotateY(pose.p5,pose.p5,
      -smstep(2,3,page)*PI
      +smstep(3,4,page)*PI
    )
    mat4.rotateY(pose.p6,pose.p6,
      -smstep(3,4,page)*PI
      + flip
    )
  }
  
  function smstep (a, b, x) {
    return clamp(0, 1, (x-a) / (b-a))
  }
  function clamp (a, b, x) {
    return Math.max(a, Math.min(b, x))
  }
  
  function updateModels () {
    paperProps.forEach(function (paper) {
      mat4.identity(paper.model)
      var p = paper
      while (p) {
        mat4.identity(tmpm)
        mat4.translate(tmpm, tmpm, p.pivot)
        mat4.multiply(tmpm, tmpm, p.pose)
        mat4.translate(tmpm, tmpm, vec3.negate(tmpv,p.pivot))
        mat4.multiply(paper.model, tmpm, paper.model)
        p = papers[p.parent]
      }
    })
  }
  
  function paper (regl, texture) {
    var size = [0,0]
    return regl({
      frag: `
        precision highp float;
        #extension GL_OES_standard_derivatives: enable
        uniform float page, pageOffset, pageFlip;
        uniform sampler2D texture;
        uniform vec2 size;
        varying vec2 vpos;
        void main () {
          float p = mod(page + pageOffset, 8.0);
          float y = floor(p/4.0);
          vec2 offset = vec2(
            mix(1.0-(mod(p+1.0,4.01))/4.0,mod(p,4.0)/4.0,y),
            y*0.5
          );
          vec2 uv = mod(vpos.xy*vec2(pageFlip)+0.5,vec2(1))/vec2(4,2) + offset;
          vec2 d = vec2(0.2)/size;
          vec4 c = texture2D(texture,uv);
          vec4 cW = texture2D(texture,uv + vec2(-d.x,0));
          vec4 cS = texture2D(texture,uv + vec2(0,d.y));
          vec4 cE = texture2D(texture,uv + vec2(d.x,0));
          vec4 cN = texture2D(texture,uv + vec2(0,-d.y));
          gl_FragColor = (c + cW + cS + cE + cN) / 5.0;
        }
      `,
      vert: `
        precision highp float;
        uniform mat4 projection, view, model;
        uniform vec3 offset;
        attribute vec2 position;
        varying vec2 vpos;
        void main () {
          vpos = position;
          vec3 p = (model * vec4(position,0,1)).xyz + offset;
          gl_Position = projection * view * vec4(p*vec3(1,1.3,1),1);
        }
      `,
      uniforms: {
        pageOffset: regl.prop('pageOffset'),
        pageFlip: regl.prop('pageFlip'),
        page: regl.prop('page'),
        model: regl.prop('model'),
        offset: regl.prop('offset'),
        texture: function () { return texture },
        size: function (context) {
          size[0] = context.viewportWidth
          size[1] = context.viewportHeight
          return size
        }
      },
      attributes: {
        position: regl.prop('positions')
      },
      elements: regl.prop('cells')
    })
  }
  
  
  },{"./tm.js":89,"eases/sine-in.js":3,"eases/sine-out.js":4,"events":1,"gl-mat4":20,"gl-vec3":53,"regl":86,"regl-camera":85,"resl":87}],3:[function(require,module,exports){
  function sineIn (t) {
    var v = Math.cos(t * Math.PI * 0.5)
    if (Math.abs(v) < 1e-14) return 1
    else return 1 - v
  }
  
  module.exports = sineIn
  
  },{}],4:[function(require,module,exports){
  function sineOut(t) {
    return Math.sin(t * Math.PI/2)
  }
  
  module.exports = sineOut
  },{}],5:[function(require,module,exports){
  module.exports = adjoint;
  
  /**
   * Calculates the adjugate of a mat4
   *
   * @param {mat4} out the receiving matrix
   * @param {mat4} a the source matrix
   * @returns {mat4} out
   */
  function adjoint(out, a) {
      var a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3],
          a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7],
          a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11],
          a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15];
  
      out[0]  =  (a11 * (a22 * a33 - a23 * a32) - a21 * (a12 * a33 - a13 * a32) + a31 * (a12 * a23 - a13 * a22));
      out[1]  = -(a01 * (a22 * a33 - a23 * a32) - a21 * (a02 * a33 - a03 * a32) + a31 * (a02 * a23 - a03 * a22));
      out[2]  =  (a01 * (a12 * a33 - a13 * a32) - a11 * (a02 * a33 - a03 * a32) + a31 * (a02 * a13 - a03 * a12));
      out[3]  = -(a01 * (a12 * a23 - a13 * a22) - a11 * (a02 * a23 - a03 * a22) + a21 * (a02 * a13 - a03 * a12));
      out[4]  = -(a10 * (a22 * a33 - a23 * a32) - a20 * (a12 * a33 - a13 * a32) + a30 * (a12 * a23 - a13 * a22));
      out[5]  =  (a00 * (a22 * a33 - a23 * a32) - a20 * (a02 * a33 - a03 * a32) + a30 * (a02 * a23 - a03 * a22));
      out[6]  = -(a00 * (a12 * a33 - a13 * a32) - a10 * (a02 * a33 - a03 * a32) + a30 * (a02 * a13 - a03 * a12));
      out[7]  =  (a00 * (a12 * a23 - a13 * a22) - a10 * (a02 * a23 - a03 * a22) + a20 * (a02 * a13 - a03 * a12));
      out[8]  =  (a10 * (a21 * a33 - a23 * a31) - a20 * (a11 * a33 - a13 * a31) + a30 * (a11 * a23 - a13 * a21));
      out[9]  = -(a00 * (a21 * a33 - a23 * a31) - a20 * (a01 * a33 - a03 * a31) + a30 * (a01 * a23 - a03 * a21));
      out[10] =  (a00 * (a11 * a33 - a13 * a31) - a10 * (a01 * a33 - a03 * a31) + a30 * (a01 * a13 - a03 * a11));
      out[11] = -(a00 * (a11 * a23 - a13 * a21) - a10 * (a01 * a23 - a03 * a21) + a20 * (a01 * a13 - a03 * a11));
      out[12] = -(a10 * (a21 * a32 - a22 * a31) - a20 * (a11 * a32 - a12 * a31) + a30 * (a11 * a22 - a12 * a21));
      out[13] =  (a00 * (a21 * a32 - a22 * a31) - a20 * (a01 * a32 - a02 * a31) + a30 * (a01 * a22 - a02 * a21));
      out[14] = -(a00 * (a11 * a32 - a12 * a31) - a10 * (a01 * a32 - a02 * a31) + a30 * (a01 * a12 - a02 * a11));
      out[15] =  (a00 * (a11 * a22 - a12 * a21) - a10 * (a01 * a22 - a02 * a21) + a20 * (a01 * a12 - a02 * a11));
      return out;
  };
  },{}],6:[function(require,module,exports){
  module.exports = clone;
  
  /**
   * Creates a new mat4 initialized with values from an existing matrix
   *
   * @param {mat4} a matrix to clone
   * @returns {mat4} a new 4x4 matrix
   */
  function clone(a) {
      var out = new Float32Array(16);
      out[0] = a[0];
      out[1] = a[1];
      out[2] = a[2];
      out[3] = a[3];
      out[4] = a[4];
      out[5] = a[5];
      out[6] = a[6];
      out[7] = a[7];
      out[8] = a[8];
      out[9] = a[9];
      out[10] = a[10];
      out[11] = a[11];
      out[12] = a[12];
      out[13] = a[13];
      out[14] = a[14];
      out[15] = a[15];
      return out;
  };
  },{}],7:[function(require,module,exports){
  module.exports = copy;
  
  /**
   * Copy the values from one mat4 to another
   *
   * @param {mat4} out the receiving matrix
   * @param {mat4} a the source matrix
   * @returns {mat4} out
   */
  function copy(out, a) {
      out[0] = a[0];
      out[1] = a[1];
      out[2] = a[2];
      out[3] = a[3];
      out[4] = a[4];
      out[5] = a[5];
      out[6] = a[6];
      out[7] = a[7];
      out[8] = a[8];
      out[9] = a[9];
      out[10] = a[10];
      out[11] = a[11];
      out[12] = a[12];
      out[13] = a[13];
      out[14] = a[14];
      out[15] = a[15];
      return out;
  };
  },{}],8:[function(require,module,exports){
  module.exports = create;
  
  /**
   * Creates a new identity mat4
   *
   * @returns {mat4} a new 4x4 matrix
   */
  function create() {
      var out = new Float32Array(16);
      out[0] = 1;
      out[1] = 0;
      out[2] = 0;
      out[3] = 0;
      out[4] = 0;
      out[5] = 1;
      out[6] = 0;
      out[7] = 0;
      out[8] = 0;
      out[9] = 0;
      out[10] = 1;
      out[11] = 0;
      out[12] = 0;
      out[13] = 0;
      out[14] = 0;
      out[15] = 1;
      return out;
  };
  },{}],9:[function(require,module,exports){
  module.exports = determinant;
  
  /**
   * Calculates the determinant of a mat4
   *
   * @param {mat4} a the source matrix
   * @returns {Number} determinant of a
   */
  function determinant(a) {
      var a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3],
          a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7],
          a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11],
          a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15],
  
          b00 = a00 * a11 - a01 * a10,
          b01 = a00 * a12 - a02 * a10,
          b02 = a00 * a13 - a03 * a10,
          b03 = a01 * a12 - a02 * a11,
          b04 = a01 * a13 - a03 * a11,
          b05 = a02 * a13 - a03 * a12,
          b06 = a20 * a31 - a21 * a30,
          b07 = a20 * a32 - a22 * a30,
          b08 = a20 * a33 - a23 * a30,
          b09 = a21 * a32 - a22 * a31,
          b10 = a21 * a33 - a23 * a31,
          b11 = a22 * a33 - a23 * a32;
  
      // Calculate the determinant
      return b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
  };
  },{}],10:[function(require,module,exports){
  module.exports = fromQuat;
  
  /**
   * Creates a matrix from a quaternion rotation.
   *
   * @param {mat4} out mat4 receiving operation result
   * @param {quat4} q Rotation quaternion
   * @returns {mat4} out
   */
  function fromQuat(out, q) {
      var x = q[0], y = q[1], z = q[2], w = q[3],
          x2 = x + x,
          y2 = y + y,
          z2 = z + z,
  
          xx = x * x2,
          yx = y * x2,
          yy = y * y2,
          zx = z * x2,
          zy = z * y2,
          zz = z * z2,
          wx = w * x2,
          wy = w * y2,
          wz = w * z2;
  
      out[0] = 1 - yy - zz;
      out[1] = yx + wz;
      out[2] = zx - wy;
      out[3] = 0;
  
      out[4] = yx - wz;
      out[5] = 1 - xx - zz;
      out[6] = zy + wx;
      out[7] = 0;
  
      out[8] = zx + wy;
      out[9] = zy - wx;
      out[10] = 1 - xx - yy;
      out[11] = 0;
  
      out[12] = 0;
      out[13] = 0;
      out[14] = 0;
      out[15] = 1;
  
      return out;
  };
  },{}],11:[function(require,module,exports){
  module.exports = fromRotation
  
  /**
   * Creates a matrix from a given angle around a given axis
   * This is equivalent to (but much faster than):
   *
   *     mat4.identity(dest)
   *     mat4.rotate(dest, dest, rad, axis)
   *
   * @param {mat4} out mat4 receiving operation result
   * @param {Number} rad the angle to rotate the matrix by
   * @param {vec3} axis the axis to rotate around
   * @returns {mat4} out
   */
  function fromRotation(out, rad, axis) {
    var s, c, t
    var x = axis[0]
    var y = axis[1]
    var z = axis[2]
    var len = Math.sqrt(x * x + y * y + z * z)
  
    if (Math.abs(len) < 0.000001) {
      return null
    }
  
    len = 1 / len
    x *= len
    y *= len
    z *= len
  
    s = Math.sin(rad)
    c = Math.cos(rad)
    t = 1 - c
  
    // Perform rotation-specific matrix multiplication
    out[0] = x * x * t + c
    out[1] = y * x * t + z * s
    out[2] = z * x * t - y * s
    out[3] = 0
    out[4] = x * y * t - z * s
    out[5] = y * y * t + c
    out[6] = z * y * t + x * s
    out[7] = 0
    out[8] = x * z * t + y * s
    out[9] = y * z * t - x * s
    out[10] = z * z * t + c
    out[11] = 0
    out[12] = 0
    out[13] = 0
    out[14] = 0
    out[15] = 1
    return out
  }
  
  },{}],12:[function(require,module,exports){
  module.exports = fromRotationTranslation;
  
  /**
   * Creates a matrix from a quaternion rotation and vector translation
   * This is equivalent to (but much faster than):
   *
   *     mat4.identity(dest);
   *     mat4.translate(dest, vec);
   *     var quatMat = mat4.create();
   *     quat4.toMat4(quat, quatMat);
   *     mat4.multiply(dest, quatMat);
   *
   * @param {mat4} out mat4 receiving operation result
   * @param {quat4} q Rotation quaternion
   * @param {vec3} v Translation vector
   * @returns {mat4} out
   */
  function fromRotationTranslation(out, q, v) {
      // Quaternion math
      var x = q[0], y = q[1], z = q[2], w = q[3],
          x2 = x + x,
          y2 = y + y,
          z2 = z + z,
  
          xx = x * x2,
          xy = x * y2,
          xz = x * z2,
          yy = y * y2,
          yz = y * z2,
          zz = z * z2,
          wx = w * x2,
          wy = w * y2,
          wz = w * z2;
  
      out[0] = 1 - (yy + zz);
      out[1] = xy + wz;
      out[2] = xz - wy;
      out[3] = 0;
      out[4] = xy - wz;
      out[5] = 1 - (xx + zz);
      out[6] = yz + wx;
      out[7] = 0;
      out[8] = xz + wy;
      out[9] = yz - wx;
      out[10] = 1 - (xx + yy);
      out[11] = 0;
      out[12] = v[0];
      out[13] = v[1];
      out[14] = v[2];
      out[15] = 1;
      
      return out;
  };
  },{}],13:[function(require,module,exports){
  module.exports = fromScaling
  
  /**
   * Creates a matrix from a vector scaling
   * This is equivalent to (but much faster than):
   *
   *     mat4.identity(dest)
   *     mat4.scale(dest, dest, vec)
   *
   * @param {mat4} out mat4 receiving operation result
   * @param {vec3} v Scaling vector
   * @returns {mat4} out
   */
  function fromScaling(out, v) {
    out[0] = v[0]
    out[1] = 0
    out[2] = 0
    out[3] = 0
    out[4] = 0
    out[5] = v[1]
    out[6] = 0
    out[7] = 0
    out[8] = 0
    out[9] = 0
    out[10] = v[2]
    out[11] = 0
    out[12] = 0
    out[13] = 0
    out[14] = 0
    out[15] = 1
    return out
  }
  
  },{}],14:[function(require,module,exports){
  module.exports = fromTranslation
  
  /**
   * Creates a matrix from a vector translation
   * This is equivalent to (but much faster than):
   *
   *     mat4.identity(dest)
   *     mat4.translate(dest, dest, vec)
   *
   * @param {mat4} out mat4 receiving operation result
   * @param {vec3} v Translation vector
   * @returns {mat4} out
   */
  function fromTranslation(out, v) {
    out[0] = 1
    out[1] = 0
    out[2] = 0
    out[3] = 0
    out[4] = 0
    out[5] = 1
    out[6] = 0
    out[7] = 0
    out[8] = 0
    out[9] = 0
    out[10] = 1
    out[11] = 0
    out[12] = v[0]
    out[13] = v[1]
    out[14] = v[2]
    out[15] = 1
    return out
  }
  
  },{}],15:[function(require,module,exports){
  module.exports = fromXRotation
  
  /**
   * Creates a matrix from the given angle around the X axis
   * This is equivalent to (but much faster than):
   *
   *     mat4.identity(dest)
   *     mat4.rotateX(dest, dest, rad)
   *
   * @param {mat4} out mat4 receiving operation result
   * @param {Number} rad the angle to rotate the matrix by
   * @returns {mat4} out
   */
  function fromXRotation(out, rad) {
      var s = Math.sin(rad),
          c = Math.cos(rad)
  
      // Perform axis-specific matrix multiplication
      out[0] = 1
      out[1] = 0
      out[2] = 0
      out[3] = 0
      out[4] = 0
      out[5] = c
      out[6] = s
      out[7] = 0
      out[8] = 0
      out[9] = -s
      out[10] = c
      out[11] = 0
      out[12] = 0
      out[13] = 0
      out[14] = 0
      out[15] = 1
      return out
  }
  },{}],16:[function(require,module,exports){
  module.exports = fromYRotation
  
  /**
   * Creates a matrix from the given angle around the Y axis
   * This is equivalent to (but much faster than):
   *
   *     mat4.identity(dest)
   *     mat4.rotateY(dest, dest, rad)
   *
   * @param {mat4} out mat4 receiving operation result
   * @param {Number} rad the angle to rotate the matrix by
   * @returns {mat4} out
   */
  function fromYRotation(out, rad) {
      var s = Math.sin(rad),
          c = Math.cos(rad)
  
      // Perform axis-specific matrix multiplication
      out[0] = c
      out[1] = 0
      out[2] = -s
      out[3] = 0
      out[4] = 0
      out[5] = 1
      out[6] = 0
      out[7] = 0
      out[8] = s
      out[9] = 0
      out[10] = c
      out[11] = 0
      out[12] = 0
      out[13] = 0
      out[14] = 0
      out[15] = 1
      return out
  }
  },{}],17:[function(require,module,exports){
  module.exports = fromZRotation
  
  /**
   * Creates a matrix from the given angle around the Z axis
   * This is equivalent to (but much faster than):
   *
   *     mat4.identity(dest)
   *     mat4.rotateZ(dest, dest, rad)
   *
   * @param {mat4} out mat4 receiving operation result
   * @param {Number} rad the angle to rotate the matrix by
   * @returns {mat4} out
   */
  function fromZRotation(out, rad) {
      var s = Math.sin(rad),
          c = Math.cos(rad)
  
      // Perform axis-specific matrix multiplication
      out[0] = c
      out[1] = s
      out[2] = 0
      out[3] = 0
      out[4] = -s
      out[5] = c
      out[6] = 0
      out[7] = 0
      out[8] = 0
      out[9] = 0
      out[10] = 1
      out[11] = 0
      out[12] = 0
      out[13] = 0
      out[14] = 0
      out[15] = 1
      return out
  }
  },{}],18:[function(require,module,exports){
  module.exports = frustum;
  
  /**
   * Generates a frustum matrix with the given bounds
   *
   * @param {mat4} out mat4 frustum matrix will be written into
   * @param {Number} left Left bound of the frustum
   * @param {Number} right Right bound of the frustum
   * @param {Number} bottom Bottom bound of the frustum
   * @param {Number} top Top bound of the frustum
   * @param {Number} near Near bound of the frustum
   * @param {Number} far Far bound of the frustum
   * @returns {mat4} out
   */
  function frustum(out, left, right, bottom, top, near, far) {
      var rl = 1 / (right - left),
          tb = 1 / (top - bottom),
          nf = 1 / (near - far);
      out[0] = (near * 2) * rl;
      out[1] = 0;
      out[2] = 0;
      out[3] = 0;
      out[4] = 0;
      out[5] = (near * 2) * tb;
      out[6] = 0;
      out[7] = 0;
      out[8] = (right + left) * rl;
      out[9] = (top + bottom) * tb;
      out[10] = (far + near) * nf;
      out[11] = -1;
      out[12] = 0;
      out[13] = 0;
      out[14] = (far * near * 2) * nf;
      out[15] = 0;
      return out;
  };
  },{}],19:[function(require,module,exports){
  module.exports = identity;
  
  /**
   * Set a mat4 to the identity matrix
   *
   * @param {mat4} out the receiving matrix
   * @returns {mat4} out
   */
  function identity(out) {
      out[0] = 1;
      out[1] = 0;
      out[2] = 0;
      out[3] = 0;
      out[4] = 0;
      out[5] = 1;
      out[6] = 0;
      out[7] = 0;
      out[8] = 0;
      out[9] = 0;
      out[10] = 1;
      out[11] = 0;
      out[12] = 0;
      out[13] = 0;
      out[14] = 0;
      out[15] = 1;
      return out;
  };
  },{}],20:[function(require,module,exports){
  module.exports = {
    create: require('./create')
    , clone: require('./clone')
    , copy: require('./copy')
    , identity: require('./identity')
    , transpose: require('./transpose')
    , invert: require('./invert')
    , adjoint: require('./adjoint')
    , determinant: require('./determinant')
    , multiply: require('./multiply')
    , translate: require('./translate')
    , scale: require('./scale')
    , rotate: require('./rotate')
    , rotateX: require('./rotateX')
    , rotateY: require('./rotateY')
    , rotateZ: require('./rotateZ')
    , fromRotation: require('./fromRotation')
    , fromRotationTranslation: require('./fromRotationTranslation')
    , fromScaling: require('./fromScaling')
    , fromTranslation: require('./fromTranslation')
    , fromXRotation: require('./fromXRotation')
    , fromYRotation: require('./fromYRotation')
    , fromZRotation: require('./fromZRotation')
    , fromQuat: require('./fromQuat')
    , frustum: require('./frustum')
    , perspective: require('./perspective')
    , perspectiveFromFieldOfView: require('./perspectiveFromFieldOfView')
    , ortho: require('./ortho')
    , lookAt: require('./lookAt')
    , str: require('./str')
  }
  
  },{"./adjoint":5,"./clone":6,"./copy":7,"./create":8,"./determinant":9,"./fromQuat":10,"./fromRotation":11,"./fromRotationTranslation":12,"./fromScaling":13,"./fromTranslation":14,"./fromXRotation":15,"./fromYRotation":16,"./fromZRotation":17,"./frustum":18,"./identity":19,"./invert":21,"./lookAt":22,"./multiply":23,"./ortho":24,"./perspective":25,"./perspectiveFromFieldOfView":26,"./rotate":27,"./rotateX":28,"./rotateY":29,"./rotateZ":30,"./scale":31,"./str":32,"./translate":33,"./transpose":34}],21:[function(require,module,exports){
  module.exports = invert;
  
  /**
   * Inverts a mat4
   *
   * @param {mat4} out the receiving matrix
   * @param {mat4} a the source matrix
   * @returns {mat4} out
   */
  function invert(out, a) {
      var a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3],
          a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7],
          a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11],
          a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15],
  
          b00 = a00 * a11 - a01 * a10,
          b01 = a00 * a12 - a02 * a10,
          b02 = a00 * a13 - a03 * a10,
          b03 = a01 * a12 - a02 * a11,
          b04 = a01 * a13 - a03 * a11,
          b05 = a02 * a13 - a03 * a12,
          b06 = a20 * a31 - a21 * a30,
          b07 = a20 * a32 - a22 * a30,
          b08 = a20 * a33 - a23 * a30,
          b09 = a21 * a32 - a22 * a31,
          b10 = a21 * a33 - a23 * a31,
          b11 = a22 * a33 - a23 * a32,
  
          // Calculate the determinant
          det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
  
      if (!det) { 
          return null; 
      }
      det = 1.0 / det;
  
      out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det;
      out[1] = (a02 * b10 - a01 * b11 - a03 * b09) * det;
      out[2] = (a31 * b05 - a32 * b04 + a33 * b03) * det;
      out[3] = (a22 * b04 - a21 * b05 - a23 * b03) * det;
      out[4] = (a12 * b08 - a10 * b11 - a13 * b07) * det;
      out[5] = (a00 * b11 - a02 * b08 + a03 * b07) * det;
      out[6] = (a32 * b02 - a30 * b05 - a33 * b01) * det;
      out[7] = (a20 * b05 - a22 * b02 + a23 * b01) * det;
      out[8] = (a10 * b10 - a11 * b08 + a13 * b06) * det;
      out[9] = (a01 * b08 - a00 * b10 - a03 * b06) * det;
      out[10] = (a30 * b04 - a31 * b02 + a33 * b00) * det;
      out[11] = (a21 * b02 - a20 * b04 - a23 * b00) * det;
      out[12] = (a11 * b07 - a10 * b09 - a12 * b06) * det;
      out[13] = (a00 * b09 - a01 * b07 + a02 * b06) * det;
      out[14] = (a31 * b01 - a30 * b03 - a32 * b00) * det;
      out[15] = (a20 * b03 - a21 * b01 + a22 * b00) * det;
  
      return out;
  };
  },{}],22:[function(require,module,exports){
  var identity = require('./identity');
  
  module.exports = lookAt;
  
  /**
   * Generates a look-at matrix with the given eye position, focal point, and up axis
   *
   * @param {mat4} out mat4 frustum matrix will be written into
   * @param {vec3} eye Position of the viewer
   * @param {vec3} center Point the viewer is looking at
   * @param {vec3} up vec3 pointing up
   * @returns {mat4} out
   */
  function lookAt(out, eye, center, up) {
      var x0, x1, x2, y0, y1, y2, z0, z1, z2, len,
          eyex = eye[0],
          eyey = eye[1],
          eyez = eye[2],
          upx = up[0],
          upy = up[1],
          upz = up[2],
          centerx = center[0],
          centery = center[1],
          centerz = center[2];
  
      if (Math.abs(eyex - centerx) < 0.000001 &&
          Math.abs(eyey - centery) < 0.000001 &&
          Math.abs(eyez - centerz) < 0.000001) {
          return identity(out);
      }
  
      z0 = eyex - centerx;
      z1 = eyey - centery;
      z2 = eyez - centerz;
  
      len = 1 / Math.sqrt(z0 * z0 + z1 * z1 + z2 * z2);
      z0 *= len;
      z1 *= len;
      z2 *= len;
  
      x0 = upy * z2 - upz * z1;
      x1 = upz * z0 - upx * z2;
      x2 = upx * z1 - upy * z0;
      len = Math.sqrt(x0 * x0 + x1 * x1 + x2 * x2);
      if (!len) {
          x0 = 0;
          x1 = 0;
          x2 = 0;
      } else {
          len = 1 / len;
          x0 *= len;
          x1 *= len;
          x2 *= len;
      }
  
      y0 = z1 * x2 - z2 * x1;
      y1 = z2 * x0 - z0 * x2;
      y2 = z0 * x1 - z1 * x0;
  
      len = Math.sqrt(y0 * y0 + y1 * y1 + y2 * y2);
      if (!len) {
          y0 = 0;
          y1 = 0;
          y2 = 0;
      } else {
          len = 1 / len;
          y0 *= len;
          y1 *= len;
          y2 *= len;
      }
  
      out[0] = x0;
      out[1] = y0;
      out[2] = z0;
      out[3] = 0;
      out[4] = x1;
      out[5] = y1;
      out[6] = z1;
      out[7] = 0;
      out[8] = x2;
      out[9] = y2;
      out[10] = z2;
      out[11] = 0;
      out[12] = -(x0 * eyex + x1 * eyey + x2 * eyez);
      out[13] = -(y0 * eyex + y1 * eyey + y2 * eyez);
      out[14] = -(z0 * eyex + z1 * eyey + z2 * eyez);
      out[15] = 1;
  
      return out;
  };
  },{"./identity":19}],23:[function(require,module,exports){
  module.exports = multiply;
  
  /**
   * Multiplies two mat4's
   *
   * @param {mat4} out the receiving matrix
   * @param {mat4} a the first operand
   * @param {mat4} b the second operand
   * @returns {mat4} out
   */
  function multiply(out, a, b) {
      var a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3],
          a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7],
          a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11],
          a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15];
  
      // Cache only the current line of the second matrix
      var b0  = b[0], b1 = b[1], b2 = b[2], b3 = b[3];  
      out[0] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
      out[1] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
      out[2] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
      out[3] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
  
      b0 = b[4]; b1 = b[5]; b2 = b[6]; b3 = b[7];
      out[4] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
      out[5] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
      out[6] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
      out[7] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
  
      b0 = b[8]; b1 = b[9]; b2 = b[10]; b3 = b[11];
      out[8] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
      out[9] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
      out[10] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
      out[11] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
  
      b0 = b[12]; b1 = b[13]; b2 = b[14]; b3 = b[15];
      out[12] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
      out[13] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
      out[14] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
      out[15] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
      return out;
  };
  },{}],24:[function(require,module,exports){
  module.exports = ortho;
  
  /**
   * Generates a orthogonal projection matrix with the given bounds
   *
   * @param {mat4} out mat4 frustum matrix will be written into
   * @param {number} left Left bound of the frustum
   * @param {number} right Right bound of the frustum
   * @param {number} bottom Bottom bound of the frustum
   * @param {number} top Top bound of the frustum
   * @param {number} near Near bound of the frustum
   * @param {number} far Far bound of the frustum
   * @returns {mat4} out
   */
  function ortho(out, left, right, bottom, top, near, far) {
      var lr = 1 / (left - right),
          bt = 1 / (bottom - top),
          nf = 1 / (near - far);
      out[0] = -2 * lr;
      out[1] = 0;
      out[2] = 0;
      out[3] = 0;
      out[4] = 0;
      out[5] = -2 * bt;
      out[6] = 0;
      out[7] = 0;
      out[8] = 0;
      out[9] = 0;
      out[10] = 2 * nf;
      out[11] = 0;
      out[12] = (left + right) * lr;
      out[13] = (top + bottom) * bt;
      out[14] = (far + near) * nf;
      out[15] = 1;
      return out;
  };
  },{}],25:[function(require,module,exports){
  module.exports = perspective;
  
  /**
   * Generates a perspective projection matrix with the given bounds
   *
   * @param {mat4} out mat4 frustum matrix will be written into
   * @param {number} fovy Vertical field of view in radians
   * @param {number} aspect Aspect ratio. typically viewport width/height
   * @param {number} near Near bound of the frustum
   * @param {number} far Far bound of the frustum
   * @returns {mat4} out
   */
  function perspective(out, fovy, aspect, near, far) {
      var f = 1.0 / Math.tan(fovy / 2),
          nf = 1 / (near - far);
      out[0] = f / aspect;
      out[1] = 0;
      out[2] = 0;
      out[3] = 0;
      out[4] = 0;
      out[5] = f;
      out[6] = 0;
      out[7] = 0;
      out[8] = 0;
      out[9] = 0;
      out[10] = (far + near) * nf;
      out[11] = -1;
      out[12] = 0;
      out[13] = 0;
      out[14] = (2 * far * near) * nf;
      out[15] = 0;
      return out;
  };
  },{}],26:[function(require,module,exports){
  module.exports = perspectiveFromFieldOfView;
  
  /**
   * Generates a perspective projection matrix with the given field of view.
   * This is primarily useful for generating projection matrices to be used
   * with the still experiemental WebVR API.
   *
   * @param {mat4} out mat4 frustum matrix will be written into
   * @param {number} fov Object containing the following values: upDegrees, downDegrees, leftDegrees, rightDegrees
   * @param {number} near Near bound of the frustum
   * @param {number} far Far bound of the frustum
   * @returns {mat4} out
   */
  function perspectiveFromFieldOfView(out, fov, near, far) {
      var upTan = Math.tan(fov.upDegrees * Math.PI/180.0),
          downTan = Math.tan(fov.downDegrees * Math.PI/180.0),
          leftTan = Math.tan(fov.leftDegrees * Math.PI/180.0),
          rightTan = Math.tan(fov.rightDegrees * Math.PI/180.0),
          xScale = 2.0 / (leftTan + rightTan),
          yScale = 2.0 / (upTan + downTan);
  
      out[0] = xScale;
      out[1] = 0.0;
      out[2] = 0.0;
      out[3] = 0.0;
      out[4] = 0.0;
      out[5] = yScale;
      out[6] = 0.0;
      out[7] = 0.0;
      out[8] = -((leftTan - rightTan) * xScale * 0.5);
      out[9] = ((upTan - downTan) * yScale * 0.5);
      out[10] = far / (near - far);
      out[11] = -1.0;
      out[12] = 0.0;
      out[13] = 0.0;
      out[14] = (far * near) / (near - far);
      out[15] = 0.0;
      return out;
  }
  
  
  },{}],27:[function(require,module,exports){
  module.exports = rotate;
  
  /**
   * Rotates a mat4 by the given angle
   *
   * @param {mat4} out the receiving matrix
   * @param {mat4} a the matrix to rotate
   * @param {Number} rad the angle to rotate the matrix by
   * @param {vec3} axis the axis to rotate around
   * @returns {mat4} out
   */
  function rotate(out, a, rad, axis) {
      var x = axis[0], y = axis[1], z = axis[2],
          len = Math.sqrt(x * x + y * y + z * z),
          s, c, t,
          a00, a01, a02, a03,
          a10, a11, a12, a13,
          a20, a21, a22, a23,
          b00, b01, b02,
          b10, b11, b12,
          b20, b21, b22;
  
      if (Math.abs(len) < 0.000001) { return null; }
      
      len = 1 / len;
      x *= len;
      y *= len;
      z *= len;
  
      s = Math.sin(rad);
      c = Math.cos(rad);
      t = 1 - c;
  
      a00 = a[0]; a01 = a[1]; a02 = a[2]; a03 = a[3];
      a10 = a[4]; a11 = a[5]; a12 = a[6]; a13 = a[7];
      a20 = a[8]; a21 = a[9]; a22 = a[10]; a23 = a[11];
  
      // Construct the elements of the rotation matrix
      b00 = x * x * t + c; b01 = y * x * t + z * s; b02 = z * x * t - y * s;
      b10 = x * y * t - z * s; b11 = y * y * t + c; b12 = z * y * t + x * s;
      b20 = x * z * t + y * s; b21 = y * z * t - x * s; b22 = z * z * t + c;
  
      // Perform rotation-specific matrix multiplication
      out[0] = a00 * b00 + a10 * b01 + a20 * b02;
      out[1] = a01 * b00 + a11 * b01 + a21 * b02;
      out[2] = a02 * b00 + a12 * b01 + a22 * b02;
      out[3] = a03 * b00 + a13 * b01 + a23 * b02;
      out[4] = a00 * b10 + a10 * b11 + a20 * b12;
      out[5] = a01 * b10 + a11 * b11 + a21 * b12;
      out[6] = a02 * b10 + a12 * b11 + a22 * b12;
      out[7] = a03 * b10 + a13 * b11 + a23 * b12;
      out[8] = a00 * b20 + a10 * b21 + a20 * b22;
      out[9] = a01 * b20 + a11 * b21 + a21 * b22;
      out[10] = a02 * b20 + a12 * b21 + a22 * b22;
      out[11] = a03 * b20 + a13 * b21 + a23 * b22;
  
      if (a !== out) { // If the source and destination differ, copy the unchanged last row
          out[12] = a[12];
          out[13] = a[13];
          out[14] = a[14];
          out[15] = a[15];
      }
      return out;
  };
  },{}],28:[function(require,module,exports){
  module.exports = rotateX;
  
  /**
   * Rotates a matrix by the given angle around the X axis
   *
   * @param {mat4} out the receiving matrix
   * @param {mat4} a the matrix to rotate
   * @param {Number} rad the angle to rotate the matrix by
   * @returns {mat4} out
   */
  function rotateX(out, a, rad) {
      var s = Math.sin(rad),
          c = Math.cos(rad),
          a10 = a[4],
          a11 = a[5],
          a12 = a[6],
          a13 = a[7],
          a20 = a[8],
          a21 = a[9],
          a22 = a[10],
          a23 = a[11];
  
      if (a !== out) { // If the source and destination differ, copy the unchanged rows
          out[0]  = a[0];
          out[1]  = a[1];
          out[2]  = a[2];
          out[3]  = a[3];
          out[12] = a[12];
          out[13] = a[13];
          out[14] = a[14];
          out[15] = a[15];
      }
  
      // Perform axis-specific matrix multiplication
      out[4] = a10 * c + a20 * s;
      out[5] = a11 * c + a21 * s;
      out[6] = a12 * c + a22 * s;
      out[7] = a13 * c + a23 * s;
      out[8] = a20 * c - a10 * s;
      out[9] = a21 * c - a11 * s;
      out[10] = a22 * c - a12 * s;
      out[11] = a23 * c - a13 * s;
      return out;
  };
  },{}],29:[function(require,module,exports){
  module.exports = rotateY;
  
  /**
   * Rotates a matrix by the given angle around the Y axis
   *
   * @param {mat4} out the receiving matrix
   * @param {mat4} a the matrix to rotate
   * @param {Number} rad the angle to rotate the matrix by
   * @returns {mat4} out
   */
  function rotateY(out, a, rad) {
      var s = Math.sin(rad),
          c = Math.cos(rad),
          a00 = a[0],
          a01 = a[1],
          a02 = a[2],
          a03 = a[3],
          a20 = a[8],
          a21 = a[9],
          a22 = a[10],
          a23 = a[11];
  
      if (a !== out) { // If the source and destination differ, copy the unchanged rows
          out[4]  = a[4];
          out[5]  = a[5];
          out[6]  = a[6];
          out[7]  = a[7];
          out[12] = a[12];
          out[13] = a[13];
          out[14] = a[14];
          out[15] = a[15];
      }
  
      // Perform axis-specific matrix multiplication
      out[0] = a00 * c - a20 * s;
      out[1] = a01 * c - a21 * s;
      out[2] = a02 * c - a22 * s;
      out[3] = a03 * c - a23 * s;
      out[8] = a00 * s + a20 * c;
      out[9] = a01 * s + a21 * c;
      out[10] = a02 * s + a22 * c;
      out[11] = a03 * s + a23 * c;
      return out;
  };
  },{}],30:[function(require,module,exports){
  module.exports = rotateZ;
  
  /**
   * Rotates a matrix by the given angle around the Z axis
   *
   * @param {mat4} out the receiving matrix
   * @param {mat4} a the matrix to rotate
   * @param {Number} rad the angle to rotate the matrix by
   * @returns {mat4} out
   */
  function rotateZ(out, a, rad) {
      var s = Math.sin(rad),
          c = Math.cos(rad),
          a00 = a[0],
          a01 = a[1],
          a02 = a[2],
          a03 = a[3],
          a10 = a[4],
          a11 = a[5],
          a12 = a[6],
          a13 = a[7];
  
      if (a !== out) { // If the source and destination differ, copy the unchanged last row
          out[8]  = a[8];
          out[9]  = a[9];
          out[10] = a[10];
          out[11] = a[11];
          out[12] = a[12];
          out[13] = a[13];
          out[14] = a[14];
          out[15] = a[15];
      }
  
      // Perform axis-specific matrix multiplication
      out[0] = a00 * c + a10 * s;
      out[1] = a01 * c + a11 * s;
      out[2] = a02 * c + a12 * s;
      out[3] = a03 * c + a13 * s;
      out[4] = a10 * c - a00 * s;
      out[5] = a11 * c - a01 * s;
      out[6] = a12 * c - a02 * s;
      out[7] = a13 * c - a03 * s;
      return out;
  };
  },{}],31:[function(require,module,exports){
  module.exports = scale;
  
  /**
   * Scales the mat4 by the dimensions in the given vec3
   *
   * @param {mat4} out the receiving matrix
   * @param {mat4} a the matrix to scale
   * @param {vec3} v the vec3 to scale the matrix by
   * @returns {mat4} out
   **/
  function scale(out, a, v) {
      var x = v[0], y = v[1], z = v[2];
  
      out[0] = a[0] * x;
      out[1] = a[1] * x;
      out[2] = a[2] * x;
      out[3] = a[3] * x;
      out[4] = a[4] * y;
      out[5] = a[5] * y;
      out[6] = a[6] * y;
      out[7] = a[7] * y;
      out[8] = a[8] * z;
      out[9] = a[9] * z;
      out[10] = a[10] * z;
      out[11] = a[11] * z;
      out[12] = a[12];
      out[13] = a[13];
      out[14] = a[14];
      out[15] = a[15];
      return out;
  };
  },{}],32:[function(require,module,exports){
  module.exports = str;
  
  /**
   * Returns a string representation of a mat4
   *
   * @param {mat4} mat matrix to represent as a string
   * @returns {String} string representation of the matrix
   */
  function str(a) {
      return 'mat4(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' + a[3] + ', ' +
                      a[4] + ', ' + a[5] + ', ' + a[6] + ', ' + a[7] + ', ' +
                      a[8] + ', ' + a[9] + ', ' + a[10] + ', ' + a[11] + ', ' + 
                      a[12] + ', ' + a[13] + ', ' + a[14] + ', ' + a[15] + ')';
  };
  },{}],33:[function(require,module,exports){
  module.exports = translate;
  
  /**
   * Translate a mat4 by the given vector
   *
   * @param {mat4} out the receiving matrix
   * @param {mat4} a the matrix to translate
   * @param {vec3} v vector to translate by
   * @returns {mat4} out
   */
  function translate(out, a, v) {
      var x = v[0], y = v[1], z = v[2],
          a00, a01, a02, a03,
          a10, a11, a12, a13,
          a20, a21, a22, a23;
  
      if (a === out) {
          out[12] = a[0] * x + a[4] * y + a[8] * z + a[12];
          out[13] = a[1] * x + a[5] * y + a[9] * z + a[13];
          out[14] = a[2] * x + a[6] * y + a[10] * z + a[14];
          out[15] = a[3] * x + a[7] * y + a[11] * z + a[15];
      } else {
          a00 = a[0]; a01 = a[1]; a02 = a[2]; a03 = a[3];
          a10 = a[4]; a11 = a[5]; a12 = a[6]; a13 = a[7];
          a20 = a[8]; a21 = a[9]; a22 = a[10]; a23 = a[11];
  
          out[0] = a00; out[1] = a01; out[2] = a02; out[3] = a03;
          out[4] = a10; out[5] = a11; out[6] = a12; out[7] = a13;
          out[8] = a20; out[9] = a21; out[10] = a22; out[11] = a23;
  
          out[12] = a00 * x + a10 * y + a20 * z + a[12];
          out[13] = a01 * x + a11 * y + a21 * z + a[13];
          out[14] = a02 * x + a12 * y + a22 * z + a[14];
          out[15] = a03 * x + a13 * y + a23 * z + a[15];
      }
  
      return out;
  };
  },{}],34:[function(require,module,exports){
  module.exports = transpose;
  
  /**
   * Transpose the values of a mat4
   *
   * @param {mat4} out the receiving matrix
   * @param {mat4} a the source matrix
   * @returns {mat4} out
   */
  function transpose(out, a) {
      // If we are transposing ourselves we can skip a few steps but have to cache some values
      if (out === a) {
          var a01 = a[1], a02 = a[2], a03 = a[3],
              a12 = a[6], a13 = a[7],
              a23 = a[11];
  
          out[1] = a[4];
          out[2] = a[8];
          out[3] = a[12];
          out[4] = a01;
          out[6] = a[9];
          out[7] = a[13];
          out[8] = a02;
          out[9] = a12;
          out[11] = a[14];
          out[12] = a03;
          out[13] = a13;
          out[14] = a23;
      } else {
          out[0] = a[0];
          out[1] = a[4];
          out[2] = a[8];
          out[3] = a[12];
          out[4] = a[1];
          out[5] = a[5];
          out[6] = a[9];
          out[7] = a[13];
          out[8] = a[2];
          out[9] = a[6];
          out[10] = a[10];
          out[11] = a[14];
          out[12] = a[3];
          out[13] = a[7];
          out[14] = a[11];
          out[15] = a[15];
      }
      
      return out;
  };
  },{}],35:[function(require,module,exports){
  module.exports = add;
  
  /**
   * Adds two vec3's
   *
   * @param {vec3} out the receiving vector
   * @param {vec3} a the first operand
   * @param {vec3} b the second operand
   * @returns {vec3} out
   */
  function add(out, a, b) {
      out[0] = a[0] + b[0]
      out[1] = a[1] + b[1]
      out[2] = a[2] + b[2]
      return out
  }
  },{}],36:[function(require,module,exports){
  module.exports = angle
  
  var fromValues = require('./fromValues')
  var normalize = require('./normalize')
  var dot = require('./dot')
  
  /**
   * Get the angle between two 3D vectors
   * @param {vec3} a The first operand
   * @param {vec3} b The second operand
   * @returns {Number} The angle in radians
   */
  function angle(a, b) {
      var tempA = fromValues(a[0], a[1], a[2])
      var tempB = fromValues(b[0], b[1], b[2])
   
      normalize(tempA, tempA)
      normalize(tempB, tempB)
   
      var cosine = dot(tempA, tempB)
  
      if(cosine > 1.0){
          return 0
      } else {
          return Math.acos(cosine)
      }     
  }
  
  },{"./dot":46,"./fromValues":52,"./normalize":63}],37:[function(require,module,exports){
  module.exports = ceil
  
  /**
   * Math.ceil the components of a vec3
   *
   * @param {vec3} out the receiving vector
   * @param {vec3} a vector to ceil
   * @returns {vec3} out
   */
  function ceil(out, a) {
    out[0] = Math.ceil(a[0])
    out[1] = Math.ceil(a[1])
    out[2] = Math.ceil(a[2])
    return out
  }
  
  },{}],38:[function(require,module,exports){
  module.exports = clone;
  
  /**
   * Creates a new vec3 initialized with values from an existing vector
   *
   * @param {vec3} a vector to clone
   * @returns {vec3} a new 3D vector
   */
  function clone(a) {
      var out = new Float32Array(3)
      out[0] = a[0]
      out[1] = a[1]
      out[2] = a[2]
      return out
  }
  },{}],39:[function(require,module,exports){
  module.exports = copy;
  
  /**
   * Copy the values from one vec3 to another
   *
   * @param {vec3} out the receiving vector
   * @param {vec3} a the source vector
   * @returns {vec3} out
   */
  function copy(out, a) {
      out[0] = a[0]
      out[1] = a[1]
      out[2] = a[2]
      return out
  }
  },{}],40:[function(require,module,exports){
  module.exports = create;
  
  /**
   * Creates a new, empty vec3
   *
   * @returns {vec3} a new 3D vector
   */
  function create() {
      var out = new Float32Array(3)
      out[0] = 0
      out[1] = 0
      out[2] = 0
      return out
  }
  },{}],41:[function(require,module,exports){
  module.exports = cross;
  
  /**
   * Computes the cross product of two vec3's
   *
   * @param {vec3} out the receiving vector
   * @param {vec3} a the first operand
   * @param {vec3} b the second operand
   * @returns {vec3} out
   */
  function cross(out, a, b) {
      var ax = a[0], ay = a[1], az = a[2],
          bx = b[0], by = b[1], bz = b[2]
  
      out[0] = ay * bz - az * by
      out[1] = az * bx - ax * bz
      out[2] = ax * by - ay * bx
      return out
  }
  },{}],42:[function(require,module,exports){
  module.exports = require('./distance')
  
  },{"./distance":43}],43:[function(require,module,exports){
  module.exports = distance;
  
  /**
   * Calculates the euclidian distance between two vec3's
   *
   * @param {vec3} a the first operand
   * @param {vec3} b the second operand
   * @returns {Number} distance between a and b
   */
  function distance(a, b) {
      var x = b[0] - a[0],
          y = b[1] - a[1],
          z = b[2] - a[2]
      return Math.sqrt(x*x + y*y + z*z)
  }
  },{}],44:[function(require,module,exports){
  module.exports = require('./divide')
  
  },{"./divide":45}],45:[function(require,module,exports){
  module.exports = divide;
  
  /**
   * Divides two vec3's
   *
   * @param {vec3} out the receiving vector
   * @param {vec3} a the first operand
   * @param {vec3} b the second operand
   * @returns {vec3} out
   */
  function divide(out, a, b) {
      out[0] = a[0] / b[0]
      out[1] = a[1] / b[1]
      out[2] = a[2] / b[2]
      return out
  }
  },{}],46:[function(require,module,exports){
  module.exports = dot;
  
  /**
   * Calculates the dot product of two vec3's
   *
   * @param {vec3} a the first operand
   * @param {vec3} b the second operand
   * @returns {Number} dot product of a and b
   */
  function dot(a, b) {
      return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]
  }
  },{}],47:[function(require,module,exports){
  module.exports = 0.000001
  
  },{}],48:[function(require,module,exports){
  module.exports = equals
  
  var EPSILON = require('./epsilon')
  
  /**
   * Returns whether or not the vectors have approximately the same elements in the same position.
   *
   * @param {vec3} a The first vector.
   * @param {vec3} b The second vector.
   * @returns {Boolean} True if the vectors are equal, false otherwise.
   */
  function equals(a, b) {
    var a0 = a[0]
    var a1 = a[1]
    var a2 = a[2]
    var b0 = b[0]
    var b1 = b[1]
    var b2 = b[2]
    return (Math.abs(a0 - b0) <= EPSILON * Math.max(1.0, Math.abs(a0), Math.abs(b0)) &&
            Math.abs(a1 - b1) <= EPSILON * Math.max(1.0, Math.abs(a1), Math.abs(b1)) &&
            Math.abs(a2 - b2) <= EPSILON * Math.max(1.0, Math.abs(a2), Math.abs(b2)))
  }
  
  },{"./epsilon":47}],49:[function(require,module,exports){
  module.exports = exactEquals
  
  /**
   * Returns whether or not the vectors exactly have the same elements in the same position (when compared with ===)
   *
   * @param {vec3} a The first vector.
   * @param {vec3} b The second vector.
   * @returns {Boolean} True if the vectors are equal, false otherwise.
   */
  function exactEquals(a, b) {
    return a[0] === b[0] && a[1] === b[1] && a[2] === b[2]
  }
  
  },{}],50:[function(require,module,exports){
  module.exports = floor
  
  /**
   * Math.floor the components of a vec3
   *
   * @param {vec3} out the receiving vector
   * @param {vec3} a vector to floor
   * @returns {vec3} out
   */
  function floor(out, a) {
    out[0] = Math.floor(a[0])
    out[1] = Math.floor(a[1])
    out[2] = Math.floor(a[2])
    return out
  }
  
  },{}],51:[function(require,module,exports){
  module.exports = forEach;
  
  var vec = require('./create')()
  
  /**
   * Perform some operation over an array of vec3s.
   *
   * @param {Array} a the array of vectors to iterate over
   * @param {Number} stride Number of elements between the start of each vec3. If 0 assumes tightly packed
   * @param {Number} offset Number of elements to skip at the beginning of the array
   * @param {Number} count Number of vec3s to iterate over. If 0 iterates over entire array
   * @param {Function} fn Function to call for each vector in the array
   * @param {Object} [arg] additional argument to pass to fn
   * @returns {Array} a
   * @function
   */
  function forEach(a, stride, offset, count, fn, arg) {
          var i, l
          if(!stride) {
              stride = 3
          }
  
          if(!offset) {
              offset = 0
          }
          
          if(count) {
              l = Math.min((count * stride) + offset, a.length)
          } else {
              l = a.length
          }
  
          for(i = offset; i < l; i += stride) {
              vec[0] = a[i] 
              vec[1] = a[i+1] 
              vec[2] = a[i+2]
              fn(vec, vec, arg)
              a[i] = vec[0] 
              a[i+1] = vec[1] 
              a[i+2] = vec[2]
          }
          
          return a
  }
  },{"./create":40}],52:[function(require,module,exports){
  module.exports = fromValues;
  
  /**
   * Creates a new vec3 initialized with the given values
   *
   * @param {Number} x X component
   * @param {Number} y Y component
   * @param {Number} z Z component
   * @returns {vec3} a new 3D vector
   */
  function fromValues(x, y, z) {
      var out = new Float32Array(3)
      out[0] = x
      out[1] = y
      out[2] = z
      return out
  }
  },{}],53:[function(require,module,exports){
  module.exports = {
    EPSILON: require('./epsilon')
    , create: require('./create')
    , clone: require('./clone')
    , angle: require('./angle')
    , fromValues: require('./fromValues')
    , copy: require('./copy')
    , set: require('./set')
    , equals: require('./equals')
    , exactEquals: require('./exactEquals')
    , add: require('./add')
    , subtract: require('./subtract')
    , sub: require('./sub')
    , multiply: require('./multiply')
    , mul: require('./mul')
    , divide: require('./divide')
    , div: require('./div')
    , min: require('./min')
    , max: require('./max')
    , floor: require('./floor')
    , ceil: require('./ceil')
    , round: require('./round')
    , scale: require('./scale')
    , scaleAndAdd: require('./scaleAndAdd')
    , distance: require('./distance')
    , dist: require('./dist')
    , squaredDistance: require('./squaredDistance')
    , sqrDist: require('./sqrDist')
    , length: require('./length')
    , len: require('./len')
    , squaredLength: require('./squaredLength')
    , sqrLen: require('./sqrLen')
    , negate: require('./negate')
    , inverse: require('./inverse')
    , normalize: require('./normalize')
    , dot: require('./dot')
    , cross: require('./cross')
    , lerp: require('./lerp')
    , random: require('./random')
    , transformMat4: require('./transformMat4')
    , transformMat3: require('./transformMat3')
    , transformQuat: require('./transformQuat')
    , rotateX: require('./rotateX')
    , rotateY: require('./rotateY')
    , rotateZ: require('./rotateZ')
    , forEach: require('./forEach')
  }
  
  },{"./add":35,"./angle":36,"./ceil":37,"./clone":38,"./copy":39,"./create":40,"./cross":41,"./dist":42,"./distance":43,"./div":44,"./divide":45,"./dot":46,"./epsilon":47,"./equals":48,"./exactEquals":49,"./floor":50,"./forEach":51,"./fromValues":52,"./inverse":54,"./len":55,"./length":56,"./lerp":57,"./max":58,"./min":59,"./mul":60,"./multiply":61,"./negate":62,"./normalize":63,"./random":64,"./rotateX":65,"./rotateY":66,"./rotateZ":67,"./round":68,"./scale":69,"./scaleAndAdd":70,"./set":71,"./sqrDist":72,"./sqrLen":73,"./squaredDistance":74,"./squaredLength":75,"./sub":76,"./subtract":77,"./transformMat3":78,"./transformMat4":79,"./transformQuat":80}],54:[function(require,module,exports){
  module.exports = inverse;
  
  /**
   * Returns the inverse of the components of a vec3
   *
   * @param {vec3} out the receiving vector
   * @param {vec3} a vector to invert
   * @returns {vec3} out
   */
  function inverse(out, a) {
    out[0] = 1.0 / a[0]
    out[1] = 1.0 / a[1]
    out[2] = 1.0 / a[2]
    return out
  }
  },{}],55:[function(require,module,exports){
  module.exports = require('./length')
  
  },{"./length":56}],56:[function(require,module,exports){
  module.exports = length;
  
  /**
   * Calculates the length of a vec3
   *
   * @param {vec3} a vector to calculate length of
   * @returns {Number} length of a
   */
  function length(a) {
      var x = a[0],
          y = a[1],
          z = a[2]
      return Math.sqrt(x*x + y*y + z*z)
  }
  },{}],57:[function(require,module,exports){
  module.exports = lerp;
  
  /**
   * Performs a linear interpolation between two vec3's
   *
   * @param {vec3} out the receiving vector
   * @param {vec3} a the first operand
   * @param {vec3} b the second operand
   * @param {Number} t interpolation amount between the two inputs
   * @returns {vec3} out
   */
  function lerp(out, a, b, t) {
      var ax = a[0],
          ay = a[1],
          az = a[2]
      out[0] = ax + t * (b[0] - ax)
      out[1] = ay + t * (b[1] - ay)
      out[2] = az + t * (b[2] - az)
      return out
  }
  },{}],58:[function(require,module,exports){
  module.exports = max;
  
  /**
   * Returns the maximum of two vec3's
   *
   * @param {vec3} out the receiving vector
   * @param {vec3} a the first operand
   * @param {vec3} b the second operand
   * @returns {vec3} out
   */
  function max(out, a, b) {
      out[0] = Math.max(a[0], b[0])
      out[1] = Math.max(a[1], b[1])
      out[2] = Math.max(a[2], b[2])
      return out
  }
  },{}],59:[function(require,module,exports){
  module.exports = min;
  
  /**
   * Returns the minimum of two vec3's
   *
   * @param {vec3} out the receiving vector
   * @param {vec3} a the first operand
   * @param {vec3} b the second operand
   * @returns {vec3} out
   */
  function min(out, a, b) {
      out[0] = Math.min(a[0], b[0])
      out[1] = Math.min(a[1], b[1])
      out[2] = Math.min(a[2], b[2])
      return out
  }
  },{}],60:[function(require,module,exports){
  module.exports = require('./multiply')
  
  },{"./multiply":61}],61:[function(require,module,exports){
  module.exports = multiply;
  
  /**
   * Multiplies two vec3's
   *
   * @param {vec3} out the receiving vector
   * @param {vec3} a the first operand
   * @param {vec3} b the second operand
   * @returns {vec3} out
   */
  function multiply(out, a, b) {
      out[0] = a[0] * b[0]
      out[1] = a[1] * b[1]
      out[2] = a[2] * b[2]
      return out
  }
  },{}],62:[function(require,module,exports){
  module.exports = negate;
  
  /**
   * Negates the components of a vec3
   *
   * @param {vec3} out the receiving vector
   * @param {vec3} a vector to negate
   * @returns {vec3} out
   */
  function negate(out, a) {
      out[0] = -a[0]
      out[1] = -a[1]
      out[2] = -a[2]
      return out
  }
  },{}],63:[function(require,module,exports){
  module.exports = normalize;
  
  /**
   * Normalize a vec3
   *
   * @param {vec3} out the receiving vector
   * @param {vec3} a vector to normalize
   * @returns {vec3} out
   */
  function normalize(out, a) {
      var x = a[0],
          y = a[1],
          z = a[2]
      var len = x*x + y*y + z*z
      if (len > 0) {
          //TODO: evaluate use of glm_invsqrt here?
          len = 1 / Math.sqrt(len)
          out[0] = a[0] * len
          out[1] = a[1] * len
          out[2] = a[2] * len
      }
      return out
  }
  },{}],64:[function(require,module,exports){
  module.exports = random;
  
  /**
   * Generates a random vector with the given scale
   *
   * @param {vec3} out the receiving vector
   * @param {Number} [scale] Length of the resulting vector. If ommitted, a unit vector will be returned
   * @returns {vec3} out
   */
  function random(out, scale) {
      scale = scale || 1.0
  
      var r = Math.random() * 2.0 * Math.PI
      var z = (Math.random() * 2.0) - 1.0
      var zScale = Math.sqrt(1.0-z*z) * scale
  
      out[0] = Math.cos(r) * zScale
      out[1] = Math.sin(r) * zScale
      out[2] = z * scale
      return out
  }
  },{}],65:[function(require,module,exports){
  module.exports = rotateX;
  
  /**
   * Rotate a 3D vector around the x-axis
   * @param {vec3} out The receiving vec3
   * @param {vec3} a The vec3 point to rotate
   * @param {vec3} b The origin of the rotation
   * @param {Number} c The angle of rotation
   * @returns {vec3} out
   */
  function rotateX(out, a, b, c){
      var by = b[1]
      var bz = b[2]
  
      // Translate point to the origin
      var py = a[1] - by
      var pz = a[2] - bz
  
      var sc = Math.sin(c)
      var cc = Math.cos(c)
  
      // perform rotation and translate to correct position
      out[0] = a[0]
      out[1] = by + py * cc - pz * sc
      out[2] = bz + py * sc + pz * cc
  
      return out
  }
  
  },{}],66:[function(require,module,exports){
  module.exports = rotateY;
  
  /**
   * Rotate a 3D vector around the y-axis
   * @param {vec3} out The receiving vec3
   * @param {vec3} a The vec3 point to rotate
   * @param {vec3} b The origin of the rotation
   * @param {Number} c The angle of rotation
   * @returns {vec3} out
   */
  function rotateY(out, a, b, c){
      var bx = b[0]
      var bz = b[2]
  
      // translate point to the origin
      var px = a[0] - bx
      var pz = a[2] - bz
      
      var sc = Math.sin(c)
      var cc = Math.cos(c)
    
      // perform rotation and translate to correct position
      out[0] = bx + pz * sc + px * cc
      out[1] = a[1]
      out[2] = bz + pz * cc - px * sc
    
      return out
  }
  
  },{}],67:[function(require,module,exports){
  module.exports = rotateZ;
  
  /**
   * Rotate a 3D vector around the z-axis
   * @param {vec3} out The receiving vec3
   * @param {vec3} a The vec3 point to rotate
   * @param {vec3} b The origin of the rotation
   * @param {Number} c The angle of rotation
   * @returns {vec3} out
   */
  function rotateZ(out, a, b, c){
      var bx = b[0]
      var by = b[1]
  
      //Translate point to the origin
      var px = a[0] - bx
      var py = a[1] - by
    
      var sc = Math.sin(c)
      var cc = Math.cos(c)
  
      // perform rotation and translate to correct position
      out[0] = bx + px * cc - py * sc
      out[1] = by + px * sc + py * cc
      out[2] = a[2]
    
      return out
  }
  
  },{}],68:[function(require,module,exports){
  module.exports = round
  
  /**
   * Math.round the components of a vec3
   *
   * @param {vec3} out the receiving vector
   * @param {vec3} a vector to round
   * @returns {vec3} out
   */
  function round(out, a) {
    out[0] = Math.round(a[0])
    out[1] = Math.round(a[1])
    out[2] = Math.round(a[2])
    return out
  }
  
  },{}],69:[function(require,module,exports){
  module.exports = scale;
  
  /**
   * Scales a vec3 by a scalar number
   *
   * @param {vec3} out the receiving vector
   * @param {vec3} a the vector to scale
   * @param {Number} b amount to scale the vector by
   * @returns {vec3} out
   */
  function scale(out, a, b) {
      out[0] = a[0] * b
      out[1] = a[1] * b
      out[2] = a[2] * b
      return out
  }
  },{}],70:[function(require,module,exports){
  module.exports = scaleAndAdd;
  
  /**
   * Adds two vec3's after scaling the second operand by a scalar value
   *
   * @param {vec3} out the receiving vector
   * @param {vec3} a the first operand
   * @param {vec3} b the second operand
   * @param {Number} scale the amount to scale b by before adding
   * @returns {vec3} out
   */
  function scaleAndAdd(out, a, b, scale) {
      out[0] = a[0] + (b[0] * scale)
      out[1] = a[1] + (b[1] * scale)
      out[2] = a[2] + (b[2] * scale)
      return out
  }
  },{}],71:[function(require,module,exports){
  module.exports = set;
  
  /**
   * Set the components of a vec3 to the given values
   *
   * @param {vec3} out the receiving vector
   * @param {Number} x X component
   * @param {Number} y Y component
   * @param {Number} z Z component
   * @returns {vec3} out
   */
  function set(out, x, y, z) {
      out[0] = x
      out[1] = y
      out[2] = z
      return out
  }
  },{}],72:[function(require,module,exports){
  module.exports = require('./squaredDistance')
  
  },{"./squaredDistance":74}],73:[function(require,module,exports){
  module.exports = require('./squaredLength')
  
  },{"./squaredLength":75}],74:[function(require,module,exports){
  module.exports = squaredDistance;
  
  /**
   * Calculates the squared euclidian distance between two vec3's
   *
   * @param {vec3} a the first operand
   * @param {vec3} b the second operand
   * @returns {Number} squared distance between a and b
   */
  function squaredDistance(a, b) {
      var x = b[0] - a[0],
          y = b[1] - a[1],
          z = b[2] - a[2]
      return x*x + y*y + z*z
  }
  },{}],75:[function(require,module,exports){
  module.exports = squaredLength;
  
  /**
   * Calculates the squared length of a vec3
   *
   * @param {vec3} a vector to calculate squared length of
   * @returns {Number} squared length of a
   */
  function squaredLength(a) {
      var x = a[0],
          y = a[1],
          z = a[2]
      return x*x + y*y + z*z
  }
  },{}],76:[function(require,module,exports){
  module.exports = require('./subtract')
  
  },{"./subtract":77}],77:[function(require,module,exports){
  module.exports = subtract;
  
  /**
   * Subtracts vector b from vector a
   *
   * @param {vec3} out the receiving vector
   * @param {vec3} a the first operand
   * @param {vec3} b the second operand
   * @returns {vec3} out
   */
  function subtract(out, a, b) {
      out[0] = a[0] - b[0]
      out[1] = a[1] - b[1]
      out[2] = a[2] - b[2]
      return out
  }
  },{}],78:[function(require,module,exports){
  module.exports = transformMat3;
  
  /**
   * Transforms the vec3 with a mat3.
   *
   * @param {vec3} out the receiving vector
   * @param {vec3} a the vector to transform
   * @param {mat4} m the 3x3 matrix to transform with
   * @returns {vec3} out
   */
  function transformMat3(out, a, m) {
      var x = a[0], y = a[1], z = a[2]
      out[0] = x * m[0] + y * m[3] + z * m[6]
      out[1] = x * m[1] + y * m[4] + z * m[7]
      out[2] = x * m[2] + y * m[5] + z * m[8]
      return out
  }
  },{}],79:[function(require,module,exports){
  module.exports = transformMat4;
  
  /**
   * Transforms the vec3 with a mat4.
   * 4th vector component is implicitly '1'
   *
   * @param {vec3} out the receiving vector
   * @param {vec3} a the vector to transform
   * @param {mat4} m matrix to transform with
   * @returns {vec3} out
   */
  function transformMat4(out, a, m) {
      var x = a[0], y = a[1], z = a[2],
          w = m[3] * x + m[7] * y + m[11] * z + m[15]
      w = w || 1.0
      out[0] = (m[0] * x + m[4] * y + m[8] * z + m[12]) / w
      out[1] = (m[1] * x + m[5] * y + m[9] * z + m[13]) / w
      out[2] = (m[2] * x + m[6] * y + m[10] * z + m[14]) / w
      return out
  }
  },{}],80:[function(require,module,exports){
  module.exports = transformQuat;
  
  /**
   * Transforms the vec3 with a quat
   *
   * @param {vec3} out the receiving vector
   * @param {vec3} a the vector to transform
   * @param {quat} q quaternion to transform with
   * @returns {vec3} out
   */
  function transformQuat(out, a, q) {
      // benchmarks: http://jsperf.com/quaternion-transform-vec3-implementations
  
      var x = a[0], y = a[1], z = a[2],
          qx = q[0], qy = q[1], qz = q[2], qw = q[3],
  
          // calculate quat * vec
          ix = qw * x + qy * z - qz * y,
          iy = qw * y + qz * x - qx * z,
          iz = qw * z + qx * y - qy * x,
          iw = -qx * x - qy * y - qz * z
  
      // calculate result * inverse quat
      out[0] = ix * qw + iw * -qx + iy * -qz - iz * -qy
      out[1] = iy * qw + iw * -qy + iz * -qx - ix * -qz
      out[2] = iz * qw + iw * -qz + ix * -qy - iy * -qx
      return out
  }
  },{}],81:[function(require,module,exports){
  'use strict'
  
  module.exports = mouseListen
  
  var mouse = require('mouse-event')
  
  function mouseListen (element, callback) {
    if (!callback) {
      callback = element
      element = window
    }
  
    var buttonState = 0
    var x = 0
    var y = 0
    var mods = {
      shift: false,
      alt: false,
      control: false,
      meta: false
    }
    var attached = false
  
    function updateMods (ev) {
      var changed = false
      if ('altKey' in ev) {
        changed = changed || ev.altKey !== mods.alt
        mods.alt = !!ev.altKey
      }
      if ('shiftKey' in ev) {
        changed = changed || ev.shiftKey !== mods.shift
        mods.shift = !!ev.shiftKey
      }
      if ('ctrlKey' in ev) {
        changed = changed || ev.ctrlKey !== mods.control
        mods.control = !!ev.ctrlKey
      }
      if ('metaKey' in ev) {
        changed = changed || ev.metaKey !== mods.meta
        mods.meta = !!ev.metaKey
      }
      return changed
    }
  
    function handleEvent (nextButtons, ev) {
      var nextX = mouse.x(ev)
      var nextY = mouse.y(ev)
      if ('buttons' in ev) {
        nextButtons = ev.buttons | 0
      }
      if (nextButtons !== buttonState ||
        nextX !== x ||
        nextY !== y ||
        updateMods(ev)) {
        buttonState = nextButtons | 0
        x = nextX || 0
        y = nextY || 0
        callback && callback(buttonState, x, y, mods)
      }
    }
  
    function clearState (ev) {
      handleEvent(0, ev)
    }
  
    function handleBlur () {
      if (buttonState ||
        x ||
        y ||
        mods.shift ||
        mods.alt ||
        mods.meta ||
        mods.control) {
        x = y = 0
        buttonState = 0
        mods.shift = mods.alt = mods.control = mods.meta = false
        callback && callback(0, 0, 0, mods)
      }
    }
  
    function handleMods (ev) {
      if (updateMods(ev)) {
        callback && callback(buttonState, x, y, mods)
      }
    }
  
    function handleMouseMove (ev) {
      if (mouse.buttons(ev) === 0) {
        handleEvent(0, ev)
      } else {
        handleEvent(buttonState, ev)
      }
    }
  
    function handleMouseDown (ev) {
      handleEvent(buttonState | mouse.buttons(ev), ev)
    }
  
    function handleMouseUp (ev) {
      handleEvent(buttonState & ~mouse.buttons(ev), ev)
    }
  
    function attachListeners () {
      if (attached) {
        return
      }
      attached = true
  
      element.addEventListener('mousemove', handleMouseMove)
  
      element.addEventListener('mousedown', handleMouseDown)
  
      element.addEventListener('mouseup', handleMouseUp)
  
      element.addEventListener('mouseleave', clearState)
      element.addEventListener('mouseenter', clearState)
      element.addEventListener('mouseout', clearState)
      element.addEventListener('mouseover', clearState)
  
      element.addEventListener('blur', handleBlur)
  
      element.addEventListener('keyup', handleMods)
      element.addEventListener('keydown', handleMods)
      element.addEventListener('keypress', handleMods)
  
      if (element !== window) {
        window.addEventListener('blur', handleBlur)
  
        window.addEventListener('keyup', handleMods)
        window.addEventListener('keydown', handleMods)
        window.addEventListener('keypress', handleMods)
      }
    }
  
    function detachListeners () {
      if (!attached) {
        return
      }
      attached = false
  
      element.removeEventListener('mousemove', handleMouseMove)
  
      element.removeEventListener('mousedown', handleMouseDown)
  
      element.removeEventListener('mouseup', handleMouseUp)
  
      element.removeEventListener('mouseleave', clearState)
      element.removeEventListener('mouseenter', clearState)
      element.removeEventListener('mouseout', clearState)
      element.removeEventListener('mouseover', clearState)
  
      element.removeEventListener('blur', handleBlur)
  
      element.removeEventListener('keyup', handleMods)
      element.removeEventListener('keydown', handleMods)
      element.removeEventListener('keypress', handleMods)
  
      if (element !== window) {
        window.removeEventListener('blur', handleBlur)
  
        window.removeEventListener('keyup', handleMods)
        window.removeEventListener('keydown', handleMods)
        window.removeEventListener('keypress', handleMods)
      }
    }
  
    // Attach listeners
    attachListeners()
  
    var result = {
      element: element
    }
  
    Object.defineProperties(result, {
      enabled: {
        get: function () { return attached },
        set: function (f) {
          if (f) {
            attachListeners()
          } else {
            detachListeners()
          }
        },
        enumerable: true
      },
      buttons: {
        get: function () { return buttonState },
        enumerable: true
      },
      x: {
        get: function () { return x },
        enumerable: true
      },
      y: {
        get: function () { return y },
        enumerable: true
      },
      mods: {
        get: function () { return mods },
        enumerable: true
      }
    })
  
    return result
  }
  
  },{"mouse-event":82}],82:[function(require,module,exports){
  'use strict'
  
  function mouseButtons(ev) {
    if(typeof ev === 'object') {
      if('buttons' in ev) {
        return ev.buttons
      } else if('which' in ev) {
        var b = ev.which
        if(b === 2) {
          return 4
        } else if(b === 3) {
          return 2
        } else if(b > 0) {
          return 1<<(b-1)
        }
      } else if('button' in ev) {
        var b = ev.button
        if(b === 1) {
          return 4
        } else if(b === 2) {
          return 2
        } else if(b >= 0) {
          return 1<<b
        }
      }
    }
    return 0
  }
  exports.buttons = mouseButtons
  
  function mouseElement(ev) {
    return ev.target || ev.srcElement || window
  }
  exports.element = mouseElement
  
  function mouseRelativeX(ev) {
    if(typeof ev === 'object') {
      if('offsetX' in ev) {
        return ev.offsetX
      }
      var target = mouseElement(ev)
      var bounds = target.getBoundingClientRect()
      return ev.clientX - bounds.left
    }
    return 0
  }
  exports.x = mouseRelativeX
  
  function mouseRelativeY(ev) {
    if(typeof ev === 'object') {
      if('offsetY' in ev) {
        return ev.offsetY
      }
      var target = mouseElement(ev)
      var bounds = target.getBoundingClientRect()
      return ev.clientY - bounds.top
    }
    return 0
  }
  exports.y = mouseRelativeY
  
  },{}],83:[function(require,module,exports){
  'use strict'
  
  var toPX = require('to-px')
  
  module.exports = mouseWheelListen
  
  function mouseWheelListen(element, callback, noScroll) {
    if(typeof element === 'function') {
      noScroll = !!callback
      callback = element
      element = window
    }
    var lineHeight = toPX('ex', element)
    var listener = function(ev) {
      if(noScroll) {
        ev.preventDefault()
      }
      var dx = ev.deltaX || 0
      var dy = ev.deltaY || 0
      var dz = ev.deltaZ || 0
      var mode = ev.deltaMode
      var scale = 1
      switch(mode) {
        case 1:
          scale = lineHeight
        break
        case 2:
          scale = window.innerHeight
        break
      }
      dx *= scale
      dy *= scale
      dz *= scale
      if(dx || dy || dz) {
        return callback(dx, dy, dz, ev)
      }
    }
    element.addEventListener('wheel', listener)
    return listener
  }
  
  },{"to-px":88}],84:[function(require,module,exports){
  module.exports = function parseUnit(str, out) {
      if (!out)
          out = [ 0, '' ]
  
      str = String(str)
      var num = parseFloat(str, 10)
      out[0] = num
      out[1] = str.match(/[\d.\-\+]*\s*(.*)/)[1] || ''
      return out
  }
  },{}],85:[function(require,module,exports){
  var mouseChange = require('mouse-change')
  var mouseWheel = require('mouse-wheel')
  var identity = require('gl-mat4/identity')
  var perspective = require('gl-mat4/perspective')
  var lookAt = require('gl-mat4/lookAt')
  
  module.exports = createCamera
  
  var isBrowser = typeof window !== 'undefined'
  
  function createCamera (regl, props_) {
    var props = props_ || {}
  
    // Preserve backward-compatibilty while renaming preventDefault -> noScroll
    if (typeof props.noScroll === 'undefined') {
      props.noScroll = props.preventDefault;
    }
  
    var cameraState = {
      view: identity(new Float32Array(16)),
      projection: identity(new Float32Array(16)),
      center: new Float32Array(props.center || 3),
      theta: props.theta || 0,
      phi: props.phi || 0,
      distance: Math.log(props.distance || 10.0),
      eye: new Float32Array(3),
      up: new Float32Array(props.up || [0, 1, 0]),
      fovy: props.fovy || Math.PI / 4.0,
      near: typeof props.near !== 'undefined' ? props.near : 0.01,
      far: typeof props.far !== 'undefined' ? props.far : 1000.0,
      noScroll: typeof props.noScroll !== 'undefined' ? props.noScroll : false,
      flipY: !!props.flipY,
      dtheta: 0,
      dphi: 0,
      rotationSpeed: typeof props.rotationSpeed !== 'undefined' ? props.rotationSpeed : 1,
      zoomSpeed: typeof props.zoomSpeed !== 'undefined' ? props.zoomSpeed : 1,
      renderOnDirty: typeof props.renderOnDirty !== undefined ? !!props.renderOnDirty : false
    }
  
    var element = props.element
    var damping = typeof props.damping !== 'undefined' ? props.damping : 0.9
  
    var right = new Float32Array([1, 0, 0])
    var front = new Float32Array([0, 0, 1])
  
    var minDistance = Math.log('minDistance' in props ? props.minDistance : 0.1)
    var maxDistance = Math.log('maxDistance' in props ? props.maxDistance : 1000)
  
    var ddistance = 0
  
    var prevX = 0
    var prevY = 0
  
    if (isBrowser && props.mouse !== false) {
      var source = element || regl._gl.canvas
  
      function getWidth () {
        return element ? element.offsetWidth : window.innerWidth
      }
  
      function getHeight () {
        return element ? element.offsetHeight : window.innerHeight
      }
  
      mouseChange(source, function (buttons, x, y) {
        if (buttons & 1) {
          var dx = (x - prevX) / getWidth()
          var dy = (y - prevY) / getHeight()
  
          cameraState.dtheta += cameraState.rotationSpeed * 4.0 * dx
          cameraState.dphi += cameraState.rotationSpeed * 4.0 * dy
          cameraState.dirty = true;
        }
        prevX = x
        prevY = y
      })
  
      mouseWheel(source, function (dx, dy) {
        ddistance += dy / getHeight() * cameraState.zoomSpeed
        cameraState.dirty = true;
      }, props.noScroll)
    }
  
    function damp (x) {
      var xd = x * damping
      if (Math.abs(xd) < 0.1) {
        return 0
      }
      cameraState.dirty = true;
      return xd
    }
  
    function clamp (x, lo, hi) {
      return Math.min(Math.max(x, lo), hi)
    }
  
    function updateCamera (props) {
      Object.keys(props).forEach(function (prop) {
        cameraState[prop] = props[prop]
      })
  
      var center = cameraState.center
      var eye = cameraState.eye
      var up = cameraState.up
      var dtheta = cameraState.dtheta
      var dphi = cameraState.dphi
  
      cameraState.theta += dtheta
      cameraState.phi = clamp(
        cameraState.phi + dphi,
        -Math.PI / 2.0,
        Math.PI / 2.0)
      cameraState.distance = clamp(
        cameraState.distance + ddistance,
        minDistance,
        maxDistance)
  
      cameraState.dtheta = damp(dtheta)
      cameraState.dphi = damp(dphi)
      ddistance = damp(ddistance)
  
      var theta = cameraState.theta
      var phi = cameraState.phi
      var r = Math.exp(cameraState.distance)
  
      var vf = r * Math.sin(theta) * Math.cos(phi)
      var vr = r * Math.cos(theta) * Math.cos(phi)
      var vu = r * Math.sin(phi)
  
      for (var i = 0; i < 3; ++i) {
        eye[i] = center[i] + vf * front[i] + vr * right[i] + vu * up[i]
      }
  
      lookAt(cameraState.view, eye, center, up)
    }
  
    cameraState.dirty = true;
  
    var injectContext = regl({
      context: Object.assign({}, cameraState, {
        dirty: function () {
          return cameraState.dirty;
        },
        projection: function (context) {
          perspective(cameraState.projection,
            cameraState.fovy,
            context.viewportWidth / context.viewportHeight,
            cameraState.near,
            cameraState.far)
          if (cameraState.flipY) { cameraState.projection[5] *= -1 }
          return cameraState.projection
        }
      }),
      uniforms: Object.keys(cameraState).reduce(function (uniforms, name) {
        uniforms[name] = regl.context(name)
        return uniforms
      }, {})
    })
  
    function setupCamera (props, block) {
      if (typeof setupCamera.dirty !== 'undefined') {
        cameraState.dirty = setupCamera.dirty || cameraState.dirty
        setupCamera.dirty = undefined;
      }
  
      if (props && block) {
        cameraState.dirty = true;
      }
  
      if (cameraState.renderOnDirty && !cameraState.dirty) return;
  
      if (!block) {
        block = props
        props = {}
      }
  
      updateCamera(props)
      injectContext(block)
      cameraState.dirty = false;
    }
  
    Object.keys(cameraState).forEach(function (name) {
      setupCamera[name] = cameraState[name]
    })
  
    return setupCamera
  }
  
  },{"gl-mat4/identity":19,"gl-mat4/lookAt":22,"gl-mat4/perspective":25,"mouse-change":81,"mouse-wheel":83}],86:[function(require,module,exports){
  (function(U,X){"object"===typeof exports&&"undefined"!==typeof module?module.exports=X():"function"===typeof define&&define.amd?define(X):U.createREGL=X()})(this,function(){function U(a,b){this.id=Eb++;this.type=a;this.data=b}function X(a){if(0===a.length)return[];var b=a.charAt(0),c=a.charAt(a.length-1);if(1<a.length&&b===c&&('"'===b||"'"===b))return['"'+a.substr(1,a.length-2).replace(/\\/g,"\\\\").replace(/"/g,'\\"')+'"'];if(b=/\[(false|true|null|\d+|'[^']*'|"[^"]*")\]/.exec(a))return X(a.substr(0,
  b.index)).concat(X(b[1])).concat(X(a.substr(b.index+b[0].length)));b=a.split(".");if(1===b.length)return['"'+a.replace(/\\/g,"\\\\").replace(/"/g,'\\"')+'"'];a=[];for(c=0;c<b.length;++c)a=a.concat(X(b[c]));return a}function cb(a){return"["+X(a).join("][")+"]"}function db(a,b){if("function"===typeof a)return new U(0,a);if("number"===typeof a||"boolean"===typeof a)return new U(5,a);if(Array.isArray(a))return new U(6,a.map(function(a,e){return db(a,b+"["+e+"]")}));if(a instanceof U)return a}function Fb(){var a=
  {"":0},b=[""];return{id:function(c){var e=a[c];if(e)return e;e=a[c]=b.length;b.push(c);return e},str:function(a){return b[a]}}}function Gb(a,b,c){function e(){var b=window.innerWidth,e=window.innerHeight;a!==document.body&&(e=a.getBoundingClientRect(),b=e.right-e.left,e=e.bottom-e.top);f.width=c*b;f.height=c*e;A(f.style,{width:b+"px",height:e+"px"})}var f=document.createElement("canvas");A(f.style,{border:0,margin:0,padding:0,top:0,left:0});a.appendChild(f);a===document.body&&(f.style.position="absolute",
  A(a.style,{margin:0,padding:0}));var d;a!==document.body&&"function"===typeof ResizeObserver?(d=new ResizeObserver(function(){setTimeout(e)}),d.observe(a)):window.addEventListener("resize",e,!1);e();return{canvas:f,onDestroy:function(){d?d.disconnect():window.removeEventListener("resize",e);a.removeChild(f)}}}function Hb(a,b){function c(c){try{return a.getContext(c,b)}catch(f){return null}}return c("webgl")||c("experimental-webgl")||c("webgl-experimental")}function eb(a){return"string"===typeof a?
  a.split():a}function fb(a){return"string"===typeof a?document.querySelector(a):a}function Ib(a){var b=a||{},c,e,f,d;a={};var p=[],n=[],u="undefined"===typeof window?1:window.devicePixelRatio,t=!1,w=function(a){},k=function(){};"string"===typeof b?c=document.querySelector(b):"object"===typeof b&&("string"===typeof b.nodeName&&"function"===typeof b.appendChild&&"function"===typeof b.getBoundingClientRect?c=b:"function"===typeof b.drawArrays||"function"===typeof b.drawElements?(d=b,f=d.canvas):("gl"in
  b?d=b.gl:"canvas"in b?f=fb(b.canvas):"container"in b&&(e=fb(b.container)),"attributes"in b&&(a=b.attributes),"extensions"in b&&(p=eb(b.extensions)),"optionalExtensions"in b&&(n=eb(b.optionalExtensions)),"onDone"in b&&(w=b.onDone),"profile"in b&&(t=!!b.profile),"pixelRatio"in b&&(u=+b.pixelRatio)));c&&("canvas"===c.nodeName.toLowerCase()?f=c:e=c);if(!d){if(!f){c=Gb(e||document.body,w,u);if(!c)return null;f=c.canvas;k=c.onDestroy}void 0===a.premultipliedAlpha&&(a.premultipliedAlpha=!0);d=Hb(f,a)}return d?
  {gl:d,canvas:f,container:e,extensions:p,optionalExtensions:n,pixelRatio:u,profile:t,onDone:w,onDestroy:k}:(k(),w("webgl not supported, try upgrading your browser or graphics drivers http://get.webgl.org"),null)}function Jb(a,b){function c(b){b=b.toLowerCase();var c;try{c=e[b]=a.getExtension(b)}catch(f){}return!!c}for(var e={},f=0;f<b.extensions.length;++f){var d=b.extensions[f];if(!c(d))return b.onDestroy(),b.onDone('"'+d+'" extension is not supported by the current WebGL context, try upgrading your system or a different browser'),
  null}b.optionalExtensions.forEach(c);return{extensions:e,restore:function(){Object.keys(e).forEach(function(a){if(e[a]&&!c(a))throw Error("(regl): error restoring extension "+a);})}}}function J(a,b){for(var c=Array(a),e=0;e<a;++e)c[e]=b(e);return c}function gb(a){var b,c;b=(65535<a)<<4;a>>>=b;c=(255<a)<<3;a>>>=c;b|=c;c=(15<a)<<2;a>>>=c;b|=c;c=(3<a)<<1;return b|c|a>>>c>>1}function hb(){function a(a){a:{for(var b=16;268435456>=b;b*=16)if(a<=b){a=b;break a}a=0}b=c[gb(a)>>2];return 0<b.length?b.pop():
  new ArrayBuffer(a)}function b(a){c[gb(a.byteLength)>>2].push(a)}var c=J(8,function(){return[]});return{alloc:a,free:b,allocType:function(b,c){var d=null;switch(b){case 5120:d=new Int8Array(a(c),0,c);break;case 5121:d=new Uint8Array(a(c),0,c);break;case 5122:d=new Int16Array(a(2*c),0,c);break;case 5123:d=new Uint16Array(a(2*c),0,c);break;case 5124:d=new Int32Array(a(4*c),0,c);break;case 5125:d=new Uint32Array(a(4*c),0,c);break;case 5126:d=new Float32Array(a(4*c),0,c);break;default:return null}return d.length!==
  c?d.subarray(0,c):d},freeType:function(a){b(a.buffer)}}}function da(a){return!!a&&"object"===typeof a&&Array.isArray(a.shape)&&Array.isArray(a.stride)&&"number"===typeof a.offset&&a.shape.length===a.stride.length&&(Array.isArray(a.data)||M(a.data))}function ib(a,b,c,e,f,d){for(var p=0;p<b;++p)for(var n=a[p],u=0;u<c;++u)for(var t=n[u],w=0;w<e;++w)f[d++]=t[w]}function jb(a,b,c,e,f){for(var d=1,p=c+1;p<b.length;++p)d*=b[p];var n=b[c];if(4===b.length-c){var u=b[c+1],t=b[c+2];b=b[c+3];for(p=0;p<n;++p)ib(a[p],
  u,t,b,e,f),f+=d}else for(p=0;p<n;++p)jb(a[p],b,c+1,e,f),f+=d}function Fa(a){return Ga[Object.prototype.toString.call(a)]|0}function kb(a,b){for(var c=0;c<b.length;++c)a[c]=b[c]}function lb(a,b,c,e,f,d,p){for(var n=0,u=0;u<c;++u)for(var t=0;t<e;++t)a[n++]=b[f*u+d*t+p]}function Kb(a,b,c,e){function f(b){this.id=u++;this.buffer=a.createBuffer();this.type=b;this.usage=35044;this.byteLength=0;this.dimension=1;this.dtype=5121;this.persistentData=null;c.profile&&(this.stats={size:0})}function d(b,c,l){b.byteLength=
  c.byteLength;a.bufferData(b.type,c,l)}function p(a,b,c,h,g,q){a.usage=c;if(Array.isArray(b)){if(a.dtype=h||5126,0<b.length)if(Array.isArray(b[0])){g=mb(b);for(var r=h=1;r<g.length;++r)h*=g[r];a.dimension=h;b=Sa(b,g,a.dtype);d(a,b,c);q?a.persistentData=b:E.freeType(b)}else"number"===typeof b[0]?(a.dimension=g,g=E.allocType(a.dtype,b.length),kb(g,b),d(a,g,c),q?a.persistentData=g:E.freeType(g)):M(b[0])&&(a.dimension=b[0].length,a.dtype=h||Fa(b[0])||5126,b=Sa(b,[b.length,b[0].length],a.dtype),d(a,b,c),
  q?a.persistentData=b:E.freeType(b))}else if(M(b))a.dtype=h||Fa(b),a.dimension=g,d(a,b,c),q&&(a.persistentData=new Uint8Array(new Uint8Array(b.buffer)));else if(da(b)){g=b.shape;var m=b.stride,r=b.offset,e=0,f=0,t=0,n=0;1===g.length?(e=g[0],f=1,t=m[0],n=0):2===g.length&&(e=g[0],f=g[1],t=m[0],n=m[1]);a.dtype=h||Fa(b.data)||5126;a.dimension=f;g=E.allocType(a.dtype,e*f);lb(g,b.data,e,f,t,n,r);d(a,g,c);q?a.persistentData=g:E.freeType(g)}else b instanceof ArrayBuffer&&(a.dtype=5121,a.dimension=g,d(a,b,
  c),q&&(a.persistentData=new Uint8Array(new Uint8Array(b))))}function n(c){b.bufferCount--;e(c);a.deleteBuffer(c.buffer);c.buffer=null;delete t[c.id]}var u=0,t={};f.prototype.bind=function(){a.bindBuffer(this.type,this.buffer)};f.prototype.destroy=function(){n(this)};var w=[];c.profile&&(b.getTotalBufferSize=function(){var a=0;Object.keys(t).forEach(function(b){a+=t[b].stats.size});return a});return{create:function(k,e,d,h){function g(b){var m=35044,k=null,e=0,d=0,f=1;Array.isArray(b)||M(b)||da(b)||
  b instanceof ArrayBuffer?k=b:"number"===typeof b?e=b|0:b&&("data"in b&&(k=b.data),"usage"in b&&(m=ob[b.usage]),"type"in b&&(d=Ia[b.type]),"dimension"in b&&(f=b.dimension|0),"length"in b&&(e=b.length|0));q.bind();k?p(q,k,m,d,f,h):(e&&a.bufferData(q.type,e,m),q.dtype=d||5121,q.usage=m,q.dimension=f,q.byteLength=e);c.profile&&(q.stats.size=q.byteLength*ha[q.dtype]);return g}b.bufferCount++;var q=new f(e);t[q.id]=q;d||g(k);g._reglType="buffer";g._buffer=q;g.subdata=function(b,c){var k=(c||0)|0,e;q.bind();
  if(M(b)||b instanceof ArrayBuffer)a.bufferSubData(q.type,k,b);else if(Array.isArray(b)){if(0<b.length)if("number"===typeof b[0]){var h=E.allocType(q.dtype,b.length);kb(h,b);a.bufferSubData(q.type,k,h);E.freeType(h)}else if(Array.isArray(b[0])||M(b[0]))e=mb(b),h=Sa(b,e,q.dtype),a.bufferSubData(q.type,k,h),E.freeType(h)}else if(da(b)){e=b.shape;var d=b.stride,f=h=0,l=0,O=0;1===e.length?(h=e[0],f=1,l=d[0],O=0):2===e.length&&(h=e[0],f=e[1],l=d[0],O=d[1]);e=Array.isArray(b.data)?q.dtype:Fa(b.data);e=E.allocType(e,
  h*f);lb(e,b.data,h,f,l,O,b.offset);a.bufferSubData(q.type,k,e);E.freeType(e)}return g};c.profile&&(g.stats=q.stats);g.destroy=function(){n(q)};return g},createStream:function(a,b){var c=w.pop();c||(c=new f(a));c.bind();p(c,b,35040,0,1,!1);return c},destroyStream:function(a){w.push(a)},clear:function(){S(t).forEach(n);w.forEach(n)},getBuffer:function(a){return a&&a._buffer instanceof f?a._buffer:null},restore:function(){S(t).forEach(function(b){b.buffer=a.createBuffer();a.bindBuffer(b.type,b.buffer);
  a.bufferData(b.type,b.persistentData||b.byteLength,b.usage)})},_initBuffer:p}}function Lb(a,b,c,e){function f(a){this.id=u++;n[this.id]=this;this.buffer=a;this.primType=4;this.type=this.vertCount=0}function d(e,d,f,h,g,q,r){e.buffer.bind();var m;d?((m=r)||M(d)&&(!da(d)||M(d.data))||(m=b.oes_element_index_uint?5125:5123),c._initBuffer(e.buffer,d,f,m,3)):(a.bufferData(34963,q,f),e.buffer.dtype=m||5121,e.buffer.usage=f,e.buffer.dimension=3,e.buffer.byteLength=q);m=r;if(!r){switch(e.buffer.dtype){case 5121:case 5120:m=
  5121;break;case 5123:case 5122:m=5123;break;case 5125:case 5124:m=5125}e.buffer.dtype=m}e.type=m;d=g;0>d&&(d=e.buffer.byteLength,5123===m?d>>=1:5125===m&&(d>>=2));e.vertCount=d;d=h;0>h&&(d=4,h=e.buffer.dimension,1===h&&(d=0),2===h&&(d=1),3===h&&(d=4));e.primType=d}function p(a){e.elementsCount--;delete n[a.id];a.buffer.destroy();a.buffer=null}var n={},u=0,t={uint8:5121,uint16:5123};b.oes_element_index_uint&&(t.uint32=5125);f.prototype.bind=function(){this.buffer.bind()};var w=[];return{create:function(a,
  b){function l(a){if(a)if("number"===typeof a)h(a),g.primType=4,g.vertCount=a|0,g.type=5121;else{var b=null,c=35044,e=-1,f=-1,k=0,n=0;if(Array.isArray(a)||M(a)||da(a))b=a;else if("data"in a&&(b=a.data),"usage"in a&&(c=ob[a.usage]),"primitive"in a&&(e=Ta[a.primitive]),"count"in a&&(f=a.count|0),"type"in a&&(n=t[a.type]),"length"in a)k=a.length|0;else if(k=f,5123===n||5122===n)k*=2;else if(5125===n||5124===n)k*=4;d(g,b,c,e,f,k,n)}else h(),g.primType=4,g.vertCount=0,g.type=5121;return l}var h=c.create(null,
  34963,!0),g=new f(h._buffer);e.elementsCount++;l(a);l._reglType="elements";l._elements=g;l.subdata=function(a,b){h.subdata(a,b);return l};l.destroy=function(){p(g)};return l},createStream:function(a){var b=w.pop();b||(b=new f(c.create(null,34963,!0,!1)._buffer));d(b,a,35040,-1,-1,0,0);return b},destroyStream:function(a){w.push(a)},getElements:function(a){return"function"===typeof a&&a._elements instanceof f?a._elements:null},clear:function(){S(n).forEach(p)}}}function pb(a){for(var b=E.allocType(5123,
  a.length),c=0;c<a.length;++c)if(isNaN(a[c]))b[c]=65535;else if(Infinity===a[c])b[c]=31744;else if(-Infinity===a[c])b[c]=64512;else{qb[0]=a[c];var e=Mb[0],f=e>>>31<<15,d=(e<<1>>>24)-127,e=e>>13&1023;b[c]=-24>d?f:-14>d?f+(e+1024>>-14-d):15<d?f+31744:f+(d+15<<10)+e}return b}function ma(a){return Array.isArray(a)||M(a)}function na(a){return"[object "+a+"]"}function rb(a){return Array.isArray(a)&&(0===a.length||"number"===typeof a[0])}function sb(a){return Array.isArray(a)&&0!==a.length&&ma(a[0])?!0:!1}
  function ea(a){return Object.prototype.toString.call(a)}function Ua(a){if(!a)return!1;var b=ea(a);return 0<=Nb.indexOf(b)?!0:rb(a)||sb(a)||da(a)}function tb(a,b){36193===a.type?(a.data=pb(b),E.freeType(b)):a.data=b}function Ja(a,b,c,e,f,d){a="undefined"!==typeof F[a]?F[a]:Q[a]*wa[b];d&&(a*=6);if(f){for(e=0;1<=c;)e+=a*c*c,c/=2;return e}return a*c*e}function Ob(a,b,c,e,f,d,p){function n(){this.format=this.internalformat=6408;this.type=5121;this.flipY=this.premultiplyAlpha=this.compressed=!1;this.unpackAlignment=
  1;this.colorSpace=37444;this.channels=this.height=this.width=0}function u(a,b){a.internalformat=b.internalformat;a.format=b.format;a.type=b.type;a.compressed=b.compressed;a.premultiplyAlpha=b.premultiplyAlpha;a.flipY=b.flipY;a.unpackAlignment=b.unpackAlignment;a.colorSpace=b.colorSpace;a.width=b.width;a.height=b.height;a.channels=b.channels}function t(a,b){if("object"===typeof b&&b){"premultiplyAlpha"in b&&(a.premultiplyAlpha=b.premultiplyAlpha);"flipY"in b&&(a.flipY=b.flipY);"alignment"in b&&(a.unpackAlignment=
  b.alignment);"colorSpace"in b&&(a.colorSpace=Pb[b.colorSpace]);"type"in b&&(a.type=N[b.type]);var c=a.width,g=a.height,e=a.channels,d=!1;"shape"in b?(c=b.shape[0],g=b.shape[1],3===b.shape.length&&(e=b.shape[2],d=!0)):("radius"in b&&(c=g=b.radius),"width"in b&&(c=b.width),"height"in b&&(g=b.height),"channels"in b&&(e=b.channels,d=!0));a.width=c|0;a.height=g|0;a.channels=e|0;c=!1;"format"in b&&(c=b.format,g=a.internalformat=C[c],a.format=P[g],c in N&&!("type"in b)&&(a.type=N[c]),c in v&&(a.compressed=
  !0),c=!0);!d&&c?a.channels=Q[a.format]:d&&!c&&a.channels!==Ma[a.format]&&(a.format=a.internalformat=Ma[a.channels])}}function w(b){a.pixelStorei(37440,b.flipY);a.pixelStorei(37441,b.premultiplyAlpha);a.pixelStorei(37443,b.colorSpace);a.pixelStorei(3317,b.unpackAlignment)}function k(){n.call(this);this.yOffset=this.xOffset=0;this.data=null;this.needsFree=!1;this.element=null;this.needsCopy=!1}function B(a,b){var c=null;Ua(b)?c=b:b&&(t(a,b),"x"in b&&(a.xOffset=b.x|0),"y"in b&&(a.yOffset=b.y|0),Ua(b.data)&&
  (c=b.data));if(b.copy){var g=f.viewportWidth,e=f.viewportHeight;a.width=a.width||g-a.xOffset;a.height=a.height||e-a.yOffset;a.needsCopy=!0}else if(!c)a.width=a.width||1,a.height=a.height||1,a.channels=a.channels||4;else if(M(c))a.channels=a.channels||4,a.data=c,"type"in b||5121!==a.type||(a.type=Ga[Object.prototype.toString.call(c)]|0);else if(rb(c)){a.channels=a.channels||4;g=c;e=g.length;switch(a.type){case 5121:case 5123:case 5125:case 5126:e=E.allocType(a.type,e);e.set(g);a.data=e;break;case 36193:a.data=
  pb(g)}a.alignment=1;a.needsFree=!0}else if(da(c)){g=c.data;Array.isArray(g)||5121!==a.type||(a.type=Ga[Object.prototype.toString.call(g)]|0);var e=c.shape,d=c.stride,h,r,m,q;3===e.length?(m=e[2],q=d[2]):q=m=1;h=e[0];r=e[1];e=d[0];d=d[1];a.alignment=1;a.width=h;a.height=r;a.channels=m;a.format=a.internalformat=Ma[m];a.needsFree=!0;h=q;c=c.offset;m=a.width;q=a.height;r=a.channels;for(var x=E.allocType(36193===a.type?5126:a.type,m*q*r),I=0,ja=0;ja<q;++ja)for(var ka=0;ka<m;++ka)for(var Va=0;Va<r;++Va)x[I++]=
  g[e*ka+d*ja+h*Va+c];tb(a,x)}else if(ea(c)===Wa||ea(c)===Xa||ea(c)===vb)ea(c)===Wa||ea(c)===Xa?a.element=c:a.element=c.canvas,a.width=a.element.width,a.height=a.element.height,a.channels=4;else if(ea(c)===wb)a.element=c,a.width=c.width,a.height=c.height,a.channels=4;else if(ea(c)===xb)a.element=c,a.width=c.naturalWidth,a.height=c.naturalHeight,a.channels=4;else if(ea(c)===yb)a.element=c,a.width=c.videoWidth,a.height=c.videoHeight,a.channels=4;else if(sb(c)){g=a.width||c[0].length;e=a.height||c.length;
  d=a.channels;d=ma(c[0][0])?d||c[0][0].length:d||1;h=Oa.shape(c);m=1;for(q=0;q<h.length;++q)m*=h[q];m=E.allocType(36193===a.type?5126:a.type,m);Oa.flatten(c,h,"",m);tb(a,m);a.alignment=1;a.width=g;a.height=e;a.channels=d;a.format=a.internalformat=Ma[d];a.needsFree=!0}}function l(b,c,g,d,h){var m=b.element,f=b.data,r=b.internalformat,q=b.format,l=b.type,x=b.width,I=b.height;w(b);m?a.texSubImage2D(c,h,g,d,q,l,m):b.compressed?a.compressedTexSubImage2D(c,h,g,d,r,x,I,f):b.needsCopy?(e(),a.copyTexSubImage2D(c,
  h,g,d,b.xOffset,b.yOffset,x,I)):a.texSubImage2D(c,h,g,d,x,I,q,l,f)}function h(){return J.pop()||new k}function g(a){a.needsFree&&E.freeType(a.data);k.call(a);J.push(a)}function q(){n.call(this);this.genMipmaps=!1;this.mipmapHint=4352;this.mipmask=0;this.images=Array(16)}function r(a,b,c){var g=a.images[0]=h();a.mipmask=1;g.width=a.width=b;g.height=a.height=c;g.channels=a.channels=4}function m(a,b){var c=null;if(Ua(b))c=a.images[0]=h(),u(c,a),B(c,b),a.mipmask=1;else if(t(a,b),Array.isArray(b.mipmap))for(var g=
  b.mipmap,e=0;e<g.length;++e)c=a.images[e]=h(),u(c,a),c.width>>=e,c.height>>=e,B(c,g[e]),a.mipmask|=1<<e;else c=a.images[0]=h(),u(c,a),B(c,b),a.mipmask=1;u(a,a.images[0])}function z(b,c){for(var g=b.images,d=0;d<g.length&&g[d];++d){var h=g[d],m=c,f=d,r=h.element,q=h.data,l=h.internalformat,x=h.format,I=h.type,ja=h.width,ka=h.height;w(h);r?a.texImage2D(m,f,x,x,I,r):h.compressed?a.compressedTexImage2D(m,f,l,ja,ka,0,q):h.needsCopy?(e(),a.copyTexImage2D(m,f,x,h.xOffset,h.yOffset,ja,ka,0)):a.texImage2D(m,
  f,x,ja,ka,0,x,I,q||null)}}function Ha(){var a=L.pop()||new q;n.call(a);for(var b=a.mipmask=0;16>b;++b)a.images[b]=null;return a}function nb(a){for(var b=a.images,c=0;c<b.length;++c)b[c]&&g(b[c]),b[c]=null;L.push(a)}function Z(){this.magFilter=this.minFilter=9728;this.wrapT=this.wrapS=33071;this.anisotropic=1;this.genMipmaps=!1;this.mipmapHint=4352}function G(a,b){"min"in b&&(a.minFilter=R[b.min],0<=Qb.indexOf(a.minFilter)&&!("faces"in b)&&(a.genMipmaps=!0));"mag"in b&&(a.magFilter=V[b.mag]);var c=
  a.wrapS,g=a.wrapT;if("wrap"in b){var e=b.wrap;"string"===typeof e?c=g=la[e]:Array.isArray(e)&&(c=la[e[0]],g=la[e[1]])}else"wrapS"in b&&(c=la[b.wrapS]),"wrapT"in b&&(g=la[b.wrapT]);a.wrapS=c;a.wrapT=g;"anisotropic"in b&&(a.anisotropic=b.anisotropic);if("mipmap"in b){c=!1;switch(typeof b.mipmap){case "string":a.mipmapHint=y[b.mipmap];c=a.genMipmaps=!0;break;case "boolean":c=a.genMipmaps=b.mipmap;break;case "object":a.genMipmaps=!1,c=!0}!c||"min"in b||(a.minFilter=9984)}}function H(c,g){a.texParameteri(g,
  10241,c.minFilter);a.texParameteri(g,10240,c.magFilter);a.texParameteri(g,10242,c.wrapS);a.texParameteri(g,10243,c.wrapT);b.ext_texture_filter_anisotropic&&a.texParameteri(g,34046,c.anisotropic);c.genMipmaps&&(a.hint(33170,c.mipmapHint),a.generateMipmap(g))}function O(b){n.call(this);this.mipmask=0;this.internalformat=6408;this.id=Y++;this.refCount=1;this.target=b;this.texture=a.createTexture();this.unit=-1;this.bindCount=0;this.texInfo=new Z;p.profile&&(this.stats={size:0})}function xa(b){a.activeTexture(33984);
  a.bindTexture(b.target,b.texture)}function ya(){var b=W[0];b?a.bindTexture(b.target,b.texture):a.bindTexture(3553,null)}function D(b){var c=b.texture,g=b.unit,e=b.target;0<=g&&(a.activeTexture(33984+g),a.bindTexture(e,null),W[g]=null);a.deleteTexture(c);b.texture=null;b.params=null;b.pixels=null;b.refCount=0;delete ia[b.id];d.textureCount--}var y={"don't care":4352,"dont care":4352,nice:4354,fast:4353},la={repeat:10497,clamp:33071,mirror:33648},V={nearest:9728,linear:9729},R=A({mipmap:9987,"nearest mipmap nearest":9984,
  "linear mipmap nearest":9985,"nearest mipmap linear":9986,"linear mipmap linear":9987},V),Pb={none:0,browser:37444},N={uint8:5121,rgba4:32819,rgb565:33635,"rgb5 a1":32820},C={alpha:6406,luminance:6409,"luminance alpha":6410,rgb:6407,rgba:6408,rgba4:32854,"rgb5 a1":32855,rgb565:36194},v={};b.ext_srgb&&(C.srgb=35904,C.srgba=35906);b.oes_texture_float&&(N.float32=N["float"]=5126);b.oes_texture_half_float&&(N.float16=N["half float"]=36193);b.webgl_depth_texture&&(A(C,{depth:6402,"depth stencil":34041}),
  A(N,{uint16:5123,uint32:5125,"depth stencil":34042}));b.webgl_compressed_texture_s3tc&&A(v,{"rgb s3tc dxt1":33776,"rgba s3tc dxt1":33777,"rgba s3tc dxt3":33778,"rgba s3tc dxt5":33779});b.webgl_compressed_texture_atc&&A(v,{"rgb atc":35986,"rgba atc explicit alpha":35987,"rgba atc interpolated alpha":34798});b.webgl_compressed_texture_pvrtc&&A(v,{"rgb pvrtc 4bppv1":35840,"rgb pvrtc 2bppv1":35841,"rgba pvrtc 4bppv1":35842,"rgba pvrtc 2bppv1":35843});b.webgl_compressed_texture_etc1&&(v["rgb etc1"]=36196);
  var F=Array.prototype.slice.call(a.getParameter(34467));Object.keys(v).forEach(function(a){var b=v[a];0<=F.indexOf(b)&&(C[a]=b)});var ta=Object.keys(C);c.textureFormats=ta;var aa=[];Object.keys(C).forEach(function(a){aa[C[a]]=a});var K=[];Object.keys(N).forEach(function(a){K[N[a]]=a});var fa=[];Object.keys(V).forEach(function(a){fa[V[a]]=a});var Da=[];Object.keys(R).forEach(function(a){Da[R[a]]=a});var ua=[];Object.keys(la).forEach(function(a){ua[la[a]]=a});var P=ta.reduce(function(a,c){var g=C[c];
  6409===g||6406===g||6409===g||6410===g||6402===g||34041===g||b.ext_srgb&&(35904===g||35906===g)?a[g]=g:32855===g||0<=c.indexOf("rgba")?a[g]=6408:a[g]=6407;return a},{}),J=[],L=[],Y=0,ia={},ga=c.maxTextureUnits,W=Array(ga).map(function(){return null});A(O.prototype,{bind:function(){this.bindCount+=1;var b=this.unit;if(0>b){for(var c=0;c<ga;++c){var g=W[c];if(g){if(0<g.bindCount)continue;g.unit=-1}W[c]=this;b=c;break}p.profile&&d.maxTextureUnits<b+1&&(d.maxTextureUnits=b+1);this.unit=b;a.activeTexture(33984+
  b);a.bindTexture(this.target,this.texture)}return b},unbind:function(){--this.bindCount},decRef:function(){0>=--this.refCount&&D(this)}});p.profile&&(d.getTotalTextureSize=function(){var a=0;Object.keys(ia).forEach(function(b){a+=ia[b].stats.size});return a});return{create2D:function(b,c){function e(a,b){var c=f.texInfo;Z.call(c);var g=Ha();"number"===typeof a?"number"===typeof b?r(g,a|0,b|0):r(g,a|0,a|0):a?(G(c,a),m(g,a)):r(g,1,1);c.genMipmaps&&(g.mipmask=(g.width<<1)-1);f.mipmask=g.mipmask;u(f,
  g);f.internalformat=g.internalformat;e.width=g.width;e.height=g.height;xa(f);z(g,3553);H(c,3553);ya();nb(g);p.profile&&(f.stats.size=Ja(f.internalformat,f.type,g.width,g.height,c.genMipmaps,!1));e.format=aa[f.internalformat];e.type=K[f.type];e.mag=fa[c.magFilter];e.min=Da[c.minFilter];e.wrapS=ua[c.wrapS];e.wrapT=ua[c.wrapT];return e}var f=new O(3553);ia[f.id]=f;d.textureCount++;e(b,c);e.subimage=function(a,b,c,d){b|=0;c|=0;d|=0;var m=h();u(m,f);m.width=0;m.height=0;B(m,a);m.width=m.width||(f.width>>
  d)-b;m.height=m.height||(f.height>>d)-c;xa(f);l(m,3553,b,c,d);ya();g(m);return e};e.resize=function(b,c){var g=b|0,d=c|0||g;if(g===f.width&&d===f.height)return e;e.width=f.width=g;e.height=f.height=d;xa(f);for(var h=0;f.mipmask>>h;++h){var m=g>>h,x=d>>h;if(!m||!x)break;a.texImage2D(3553,h,f.format,m,x,0,f.format,f.type,null)}ya();p.profile&&(f.stats.size=Ja(f.internalformat,f.type,g,d,!1,!1));return e};e._reglType="texture2d";e._texture=f;p.profile&&(e.stats=f.stats);e.destroy=function(){f.decRef()};
  return e},createCube:function(b,c,e,f,q,n){function k(a,b,c,g,e,d){var f,ca=y.texInfo;Z.call(ca);for(f=0;6>f;++f)D[f]=Ha();if("number"===typeof a||!a)for(a=a|0||1,f=0;6>f;++f)r(D[f],a,a);else if("object"===typeof a)if(b)m(D[0],a),m(D[1],b),m(D[2],c),m(D[3],g),m(D[4],e),m(D[5],d);else if(G(ca,a),t(y,a),"faces"in a)for(a=a.faces,f=0;6>f;++f)u(D[f],y),m(D[f],a[f]);else for(f=0;6>f;++f)m(D[f],a);u(y,D[0]);y.mipmask=ca.genMipmaps?(D[0].width<<1)-1:D[0].mipmask;y.internalformat=D[0].internalformat;k.width=
  D[0].width;k.height=D[0].height;xa(y);for(f=0;6>f;++f)z(D[f],34069+f);H(ca,34067);ya();p.profile&&(y.stats.size=Ja(y.internalformat,y.type,k.width,k.height,ca.genMipmaps,!0));k.format=aa[y.internalformat];k.type=K[y.type];k.mag=fa[ca.magFilter];k.min=Da[ca.minFilter];k.wrapS=ua[ca.wrapS];k.wrapT=ua[ca.wrapT];for(f=0;6>f;++f)nb(D[f]);return k}var y=new O(34067);ia[y.id]=y;d.cubeCount++;var D=Array(6);k(b,c,e,f,q,n);k.subimage=function(a,b,c,e,f){c|=0;e|=0;f|=0;var d=h();u(d,y);d.width=0;d.height=0;
  B(d,b);d.width=d.width||(y.width>>f)-c;d.height=d.height||(y.height>>f)-e;xa(y);l(d,34069+a,c,e,f);ya();g(d);return k};k.resize=function(b){b|=0;if(b!==y.width){k.width=y.width=b;k.height=y.height=b;xa(y);for(var c=0;6>c;++c)for(var g=0;y.mipmask>>g;++g)a.texImage2D(34069+c,g,y.format,b>>g,b>>g,0,y.format,y.type,null);ya();p.profile&&(y.stats.size=Ja(y.internalformat,y.type,k.width,k.height,!1,!0));return k}};k._reglType="textureCube";k._texture=y;p.profile&&(k.stats=y.stats);k.destroy=function(){y.decRef()};
  return k},clear:function(){for(var b=0;b<ga;++b)a.activeTexture(33984+b),a.bindTexture(3553,null),W[b]=null;S(ia).forEach(D);d.cubeCount=0;d.textureCount=0},getTexture:function(a){return null},restore:function(){for(var b=0;b<ga;++b){var c=W[b];c&&(c.bindCount=0,c.unit=-1,W[b]=null)}S(ia).forEach(function(b){b.texture=a.createTexture();a.bindTexture(b.target,b.texture);for(var c=0;32>c;++c)if(0!==(b.mipmask&1<<c))if(3553===b.target)a.texImage2D(3553,c,b.internalformat,b.width>>c,b.height>>c,0,b.internalformat,
  b.type,null);else for(var g=0;6>g;++g)a.texImage2D(34069+g,c,b.internalformat,b.width>>c,b.height>>c,0,b.internalformat,b.type,null);H(b.texInfo,b.target)})},refresh:function(){for(var b=0;b<ga;++b){var c=W[b];c&&(c.bindCount=0,c.unit=-1,W[b]=null);a.activeTexture(33984+b);a.bindTexture(3553,null);a.bindTexture(34067,null)}}}}function Rb(a,b,c,e,f,d){function p(a,b,c){this.target=a;this.texture=b;this.renderbuffer=c;var g=a=0;b?(a=b.width,g=b.height):c&&(a=c.width,g=c.height);this.width=a;this.height=
  g}function n(a){a&&(a.texture&&a.texture._texture.decRef(),a.renderbuffer&&a.renderbuffer._renderbuffer.decRef())}function u(a,b,c){a&&(a.texture?a.texture._texture.refCount+=1:a.renderbuffer._renderbuffer.refCount+=1)}function t(b,c){c&&(c.texture?a.framebufferTexture2D(36160,b,c.target,c.texture._texture.texture,0):a.framebufferRenderbuffer(36160,b,36161,c.renderbuffer._renderbuffer.renderbuffer))}function w(a){var b=3553,c=null,g=null,e=a;"object"===typeof a&&(e=a.data,"target"in a&&(b=a.target|
  0));a=e._reglType;"texture2d"===a?c=e:"textureCube"===a?c=e:"renderbuffer"===a&&(g=e,b=36161);return new p(b,c,g)}function k(a,b,c,g,d){if(c)return a=e.create2D({width:a,height:b,format:g,type:d}),a._texture.refCount=0,new p(3553,a,null);a=f.create({width:a,height:b,format:g});a._renderbuffer.refCount=0;return new p(36161,null,a)}function B(a){return a&&(a.texture||a.renderbuffer)}function l(a,b,c){a&&(a.texture?a.texture.resize(b,c):a.renderbuffer&&a.renderbuffer.resize(b,c),a.width=b,a.height=c)}
  function h(){this.id=G++;H[this.id]=this;this.framebuffer=a.createFramebuffer();this.height=this.width=0;this.colorAttachments=[];this.depthStencilAttachment=this.stencilAttachment=this.depthAttachment=null}function g(a){a.colorAttachments.forEach(n);n(a.depthAttachment);n(a.stencilAttachment);n(a.depthStencilAttachment)}function q(b){a.deleteFramebuffer(b.framebuffer);b.framebuffer=null;d.framebufferCount--;delete H[b.id]}function r(b){var g;a.bindFramebuffer(36160,b.framebuffer);var e=b.colorAttachments;
  for(g=0;g<e.length;++g)t(36064+g,e[g]);for(g=e.length;g<c.maxColorAttachments;++g)a.framebufferTexture2D(36160,36064+g,3553,null,0);a.framebufferTexture2D(36160,33306,3553,null,0);a.framebufferTexture2D(36160,36096,3553,null,0);a.framebufferTexture2D(36160,36128,3553,null,0);t(36096,b.depthAttachment);t(36128,b.stencilAttachment);t(33306,b.depthStencilAttachment);a.checkFramebufferStatus(36160);a.isContextLost();a.bindFramebuffer(36160,z.next?z.next.framebuffer:null);z.cur=z.next;a.getError()}function m(a,
  b){function c(a,b){var f,d=0,h=0,m=!0,q=!0;f=null;var l=!0,n="rgba",t="uint8",p=1,G=null,fa=null,z=null,O=!1;if("number"===typeof a)d=a|0,h=b|0||d;else if(a){"shape"in a?(h=a.shape,d=h[0],h=h[1]):("radius"in a&&(d=h=a.radius),"width"in a&&(d=a.width),"height"in a&&(h=a.height));if("color"in a||"colors"in a)f=a.color||a.colors,Array.isArray(f);if(!f){"colorCount"in a&&(p=a.colorCount|0);"colorTexture"in a&&(l=!!a.colorTexture,n="rgba4");if("colorType"in a&&(t=a.colorType,!l))if("half float"===t||"float16"===
  t)n="rgba16f";else if("float"===t||"float32"===t)n="rgba32f";"colorFormat"in a&&(n=a.colorFormat,0<=Ha.indexOf(n)?l=!0:0<=v.indexOf(n)&&(l=!1))}if("depthTexture"in a||"depthStencilTexture"in a)O=!(!a.depthTexture&&!a.depthStencilTexture);"depth"in a&&("boolean"===typeof a.depth?m=a.depth:(G=a.depth,q=!1));"stencil"in a&&("boolean"===typeof a.stencil?q=a.stencil:(fa=a.stencil,m=!1));"depthStencil"in a&&("boolean"===typeof a.depthStencil?m=q=a.depthStencil:(z=a.depthStencil,q=m=!1))}else d=h=1;var P=
  null,Z=null,H=null,A=null;if(Array.isArray(f))P=f.map(w);else if(f)P=[w(f)];else for(P=Array(p),f=0;f<p;++f)P[f]=k(d,h,l,n,t);d=d||P[0].width;h=h||P[0].height;G?Z=w(G):m&&!q&&(Z=k(d,h,O,"depth","uint32"));fa?H=w(fa):q&&!m&&(H=k(d,h,!1,"stencil","uint8"));z?A=w(z):!G&&!fa&&q&&m&&(A=k(d,h,O,"depth stencil","depth stencil"));m=null;for(f=0;f<P.length;++f)u(P[f],d,h),P[f]&&P[f].texture&&(q=Ya[P[f].texture._texture.format]*Pa[P[f].texture._texture.type],null===m&&(m=q));u(Z,d,h);u(H,d,h);u(A,d,h);g(e);
  e.width=d;e.height=h;e.colorAttachments=P;e.depthAttachment=Z;e.stencilAttachment=H;e.depthStencilAttachment=A;c.color=P.map(B);c.depth=B(Z);c.stencil=B(H);c.depthStencil=B(A);c.width=e.width;c.height=e.height;r(e);return c}var e=new h;d.framebufferCount++;c(a,b);return A(c,{resize:function(a,b){var g=Math.max(a|0,1),f=Math.max(b|0||g,1);if(g===e.width&&f===e.height)return c;for(var d=e.colorAttachments,h=0;h<d.length;++h)l(d[h],g,f);l(e.depthAttachment,g,f);l(e.stencilAttachment,g,f);l(e.depthStencilAttachment,
  g,f);e.width=c.width=g;e.height=c.height=f;r(e);return c},_reglType:"framebuffer",_framebuffer:e,destroy:function(){q(e);g(e)},use:function(a){z.setFBO({framebuffer:c},a)}})}var z={cur:null,next:null,dirty:!1,setFBO:null},Ha=["rgba"],v=["rgba4","rgb565","rgb5 a1"];b.ext_srgb&&v.push("srgba");b.ext_color_buffer_half_float&&v.push("rgba16f","rgb16f");b.webgl_color_buffer_float&&v.push("rgba32f");var Z=["uint8"];b.oes_texture_half_float&&Z.push("half float","float16");b.oes_texture_float&&Z.push("float",
  "float32");var G=0,H={};return A(z,{getFramebuffer:function(a){return"function"===typeof a&&"framebuffer"===a._reglType&&(a=a._framebuffer,a instanceof h)?a:null},create:m,createCube:function(a){function b(a){var g,f={color:null},d=0,h=null;g="rgba";var q="uint8",r=1;if("number"===typeof a)d=a|0;else if(a){"shape"in a?d=a.shape[0]:("radius"in a&&(d=a.radius|0),"width"in a?d=a.width|0:"height"in a&&(d=a.height|0));if("color"in a||"colors"in a)h=a.color||a.colors,Array.isArray(h);h||("colorCount"in
  a&&(r=a.colorCount|0),"colorType"in a&&(q=a.colorType),"colorFormat"in a&&(g=a.colorFormat));"depth"in a&&(f.depth=a.depth);"stencil"in a&&(f.stencil=a.stencil);"depthStencil"in a&&(f.depthStencil=a.depthStencil)}else d=1;if(h)if(Array.isArray(h))for(a=[],g=0;g<h.length;++g)a[g]=h[g];else a=[h];else for(a=Array(r),h={radius:d,format:g,type:q},g=0;g<r;++g)a[g]=e.createCube(h);f.color=Array(a.length);for(g=0;g<a.length;++g)r=a[g],d=d||r.width,f.color[g]={target:34069,data:a[g]};for(g=0;6>g;++g){for(r=
  0;r<a.length;++r)f.color[r].target=34069+g;0<g&&(f.depth=c[0].depth,f.stencil=c[0].stencil,f.depthStencil=c[0].depthStencil);if(c[g])c[g](f);else c[g]=m(f)}return A(b,{width:d,height:d,color:a})}var c=Array(6);b(a);return A(b,{faces:c,resize:function(a){var g=a|0;if(g===b.width)return b;var e=b.color;for(a=0;a<e.length;++a)e[a].resize(g);for(a=0;6>a;++a)c[a].resize(g);b.width=b.height=g;return b},_reglType:"framebufferCube",destroy:function(){c.forEach(function(a){a.destroy()})}})},clear:function(){S(H).forEach(q)},
  restore:function(){z.cur=null;z.next=null;z.dirty=!0;S(H).forEach(function(b){b.framebuffer=a.createFramebuffer();r(b)})}})}function Za(){this.w=this.z=this.y=this.x=this.state=0;this.buffer=null;this.size=0;this.normalized=!1;this.type=5126;this.divisor=this.stride=this.offset=0}function Sb(a,b,c,e,f){function d(a){if(a!==h.currentVAO){var c=b.oes_vertex_array_object;a?c.bindVertexArrayOES(a.vao):c.bindVertexArrayOES(null);h.currentVAO=a}}function p(c){if(c!==h.currentVAO){if(c)c.bindAttrs();else for(var e=
  b.angle_instanced_arrays,f=0;f<k.length;++f){var d=k[f];d.buffer?(a.enableVertexAttribArray(f),a.vertexAttribPointer(f,d.size,d.type,d.normalized,d.stride,d.offfset),e&&d.divisor&&e.vertexAttribDivisorANGLE(f,d.divisor)):(a.disableVertexAttribArray(f),a.vertexAttrib4f(f,d.x,d.y,d.z,d.w))}h.currentVAO=c}}function n(){S(l).forEach(function(a){a.destroy()})}function u(){this.id=++B;this.attributes=[];var a=b.oes_vertex_array_object;this.vao=a?a.createVertexArrayOES():null;l[this.id]=this;this.buffers=
  []}function t(){b.oes_vertex_array_object&&S(l).forEach(function(a){a.refresh()})}var w=c.maxAttributes,k=Array(w);for(c=0;c<w;++c)k[c]=new Za;var B=0,l={},h={Record:Za,scope:{},state:k,currentVAO:null,targetVAO:null,restore:b.oes_vertex_array_object?t:function(){},createVAO:function(a){function b(a){var g={},e=c.attributes;e.length=a.length;for(var d=0;d<a.length;++d){var h=a[d],k=e[d]=new Za,l=h.data||h;if(Array.isArray(l)||M(l)||da(l)){var n;c.buffers[d]&&(n=c.buffers[d],M(l)&&n._buffer.byteLength>=
  l.byteLength?n.subdata(l):(n.destroy(),c.buffers[d]=null));c.buffers[d]||(n=c.buffers[d]=f.create(h,34962,!1,!0));k.buffer=f.getBuffer(n);k.size=k.buffer.dimension|0;k.normalized=!1;k.type=k.buffer.dtype;k.offset=0;k.stride=0;k.divisor=0;k.state=1;g[d]=1}else f.getBuffer(h)?(k.buffer=f.getBuffer(h),k.size=k.buffer.dimension|0,k.normalized=!1,k.type=k.buffer.dtype,k.offset=0,k.stride=0,k.divisor=0,k.state=1):f.getBuffer(h.buffer)?(k.buffer=f.getBuffer(h.buffer),k.size=(+h.size||k.buffer.dimension)|
  0,k.normalized=!!h.normalized||!1,k.type="type"in h?Ia[h.type]:k.buffer.dtype,k.offset=(h.offset||0)|0,k.stride=(h.stride||0)|0,k.divisor=(h.divisor||0)|0,k.state=1):"x"in h&&(k.x=+h.x||0,k.y=+h.y||0,k.z=+h.z||0,k.w=+h.w||0,k.state=2)}for(a=0;a<c.buffers.length;++a)!g[a]&&c.buffers[a]&&(c.buffers[a].destroy(),c.buffers[a]=null);c.refresh();return b}var c=new u;e.vaoCount+=1;b.destroy=function(){for(var a=0;a<c.buffers.length;++a)c.buffers[a]&&c.buffers[a].destroy();c.buffers.length=0;c.destroy()};
  b._vao=c;b._reglType="vao";return b(a)},getVAO:function(a){return"function"===typeof a&&a._vao?a._vao:null},destroyBuffer:function(b){for(var c=0;c<k.length;++c){var e=k[c];e.buffer===b&&(a.disableVertexAttribArray(c),e.buffer=null)}},setVAO:b.oes_vertex_array_object?d:p,clear:b.oes_vertex_array_object?n:function(){}};u.prototype.bindAttrs=function(){for(var c=b.angle_instanced_arrays,e=this.attributes,f=0;f<e.length;++f){var d=e[f];d.buffer?(a.enableVertexAttribArray(f),a.bindBuffer(34962,d.buffer.buffer),
  a.vertexAttribPointer(f,d.size,d.type,d.normalized,d.stride,d.offset),c&&d.divisor&&c.vertexAttribDivisorANGLE(f,d.divisor)):(a.disableVertexAttribArray(f),a.vertexAttrib4f(f,d.x,d.y,d.z,d.w))}for(c=e.length;c<w;++c)a.disableVertexAttribArray(c)};u.prototype.refresh=function(){var a=b.oes_vertex_array_object;a&&(a.bindVertexArrayOES(this.vao),this.bindAttrs(),h.currentVAO=this)};u.prototype.destroy=function(){if(this.vao){var a=b.oes_vertex_array_object;this===h.currentVAO&&(h.currentVAO=null,a.bindVertexArrayOES(null));
  a.deleteVertexArrayOES(this.vao);this.vao=null}l[this.id]&&(delete l[this.id],--e.vaoCount)};return h}function Tb(a,b,c,e){function f(a,b,c,e){this.name=a;this.id=b;this.location=c;this.info=e}function d(a,b){for(var c=0;c<a.length;++c)if(a[c].id===b.id){a[c].location=b.location;return}a.push(b)}function p(c,g,e){e=35632===c?t:w;var d=e[g];if(!d){var f=b.str(g),d=a.createShader(c);a.shaderSource(d,f);a.compileShader(d);e[g]=d}return d}function n(a,b){this.id=l++;this.fragId=a;this.vertId=b;this.program=
  null;this.uniforms=[];this.attributes=[];this.refCount=1;e.profile&&(this.stats={uniformsCount:0,attributesCount:0})}function u(c,g,k){var l;l=p(35632,c.fragId);var m=p(35633,c.vertId);g=c.program=a.createProgram();a.attachShader(g,l);a.attachShader(g,m);if(k)for(l=0;l<k.length;++l)m=k[l],a.bindAttribLocation(g,m[0],m[1]);a.linkProgram(g);m=a.getProgramParameter(g,35718);e.profile&&(c.stats.uniformsCount=m);var n=c.uniforms;for(l=0;l<m;++l)if(k=a.getActiveUniform(g,l))if(1<k.size)for(var t=0;t<k.size;++t){var u=
  k.name.replace("[0]","["+t+"]");d(n,new f(u,b.id(u),a.getUniformLocation(g,u),k))}else d(n,new f(k.name,b.id(k.name),a.getUniformLocation(g,k.name),k));m=a.getProgramParameter(g,35721);e.profile&&(c.stats.attributesCount=m);c=c.attributes;for(l=0;l<m;++l)(k=a.getActiveAttrib(g,l))&&d(c,new f(k.name,b.id(k.name),a.getAttribLocation(g,k.name),k))}var t={},w={},k={},B=[],l=0;e.profile&&(c.getMaxUniformsCount=function(){var a=0;B.forEach(function(b){b.stats.uniformsCount>a&&(a=b.stats.uniformsCount)});
  return a},c.getMaxAttributesCount=function(){var a=0;B.forEach(function(b){b.stats.attributesCount>a&&(a=b.stats.attributesCount)});return a});return{clear:function(){var b=a.deleteShader.bind(a);S(t).forEach(b);t={};S(w).forEach(b);w={};B.forEach(function(b){a.deleteProgram(b.program)});B.length=0;k={};c.shaderCount=0},program:function(b,e,d,f){var l=k[e];l||(l=k[e]={});var p=l[b];if(p&&(p.refCount++,!f))return p;var v=new n(e,b);c.shaderCount++;u(v,d,f);p||(l[b]=v);B.push(v);return A(v,{destroy:function(){v.refCount--;
  if(0>=v.refCount){a.deleteProgram(v.program);var b=B.indexOf(v);B.splice(b,1);c.shaderCount--}0>=l[v.vertId].refCount&&(a.deleteShader(w[v.vertId]),delete w[v.vertId],delete k[v.fragId][v.vertId]);Object.keys(k[v.fragId]).length||(a.deleteShader(t[v.fragId]),delete t[v.fragId],delete k[v.fragId])}})},restore:function(){t={};w={};for(var a=0;a<B.length;++a)u(B[a],null,B[a].attributes.map(function(a){return[a.location,a.name]}))},shader:p,frag:-1,vert:-1}}function Ub(a,b,c,e,f,d,p){function n(d){var f;
  f=null===b.next?5121:b.next.colorAttachments[0].texture._texture.type;var k=0,n=0,l=e.framebufferWidth,h=e.framebufferHeight,g=null;M(d)?g=d:d&&(k=d.x|0,n=d.y|0,l=(d.width||e.framebufferWidth-k)|0,h=(d.height||e.framebufferHeight-n)|0,g=d.data||null);c();d=l*h*4;g||(5121===f?g=new Uint8Array(d):5126===f&&(g=g||new Float32Array(d)));a.pixelStorei(3333,4);a.readPixels(k,n,l,h,6408,f,g);return g}function u(a){var c;b.setFBO({framebuffer:a.framebuffer},function(){c=n(a)});return c}return function(a){return a&&
  "framebuffer"in a?u(a):n(a)}}function za(a){return Array.prototype.slice.call(a)}function Aa(a){return za(a).join("")}function Vb(){function a(){var a=[],b=[];return A(function(){a.push.apply(a,za(arguments))},{def:function(){var d="v"+c++;b.push(d);0<arguments.length&&(a.push(d,"="),a.push.apply(a,za(arguments)),a.push(";"));return d},toString:function(){return Aa([0<b.length?"var "+b.join(",")+";":"",Aa(a)])}})}function b(){function b(a,e){d(a,e,"=",c.def(a,e),";")}var c=a(),d=a(),e=c.toString,
  f=d.toString;return A(function(){c.apply(c,za(arguments))},{def:c.def,entry:c,exit:d,save:b,set:function(a,d,e){b(a,d);c(a,d,"=",e,";")},toString:function(){return e()+f()}})}var c=0,e=[],f=[],d=a(),p={};return{global:d,link:function(a){for(var b=0;b<f.length;++b)if(f[b]===a)return e[b];b="g"+c++;e.push(b);f.push(a);return b},block:a,proc:function(a,c){function d(){var a="a"+e.length;e.push(a);return a}var e=[];c=c||0;for(var f=0;f<c;++f)d();var f=b(),B=f.toString;return p[a]=A(f,{arg:d,toString:function(){return Aa(["function(",
  e.join(),"){",B(),"}"])}})},scope:b,cond:function(){var a=Aa(arguments),c=b(),d=b(),e=c.toString,f=d.toString;return A(c,{then:function(){c.apply(c,za(arguments));return this},"else":function(){d.apply(d,za(arguments));return this},toString:function(){var b=f();b&&(b="else{"+b+"}");return Aa(["if(",a,"){",e(),"}",b])}})},compile:function(){var a=['"use strict";',d,"return {"];Object.keys(p).forEach(function(b){a.push('"',b,'":',p[b].toString(),",")});a.push("}");var b=Aa(a).replace(/;/g,";\n").replace(/}/g,
  "}\n").replace(/{/g,"{\n");return Function.apply(null,e.concat(b)).apply(null,f)}}}function Qa(a){return Array.isArray(a)||M(a)||da(a)}function zb(a){return a.sort(function(a,c){return"viewport"===a?-1:"viewport"===c?1:a<c?-1:1})}function K(a,b,c,e){this.thisDep=a;this.contextDep=b;this.propDep=c;this.append=e}function sa(a){return a&&!(a.thisDep||a.contextDep||a.propDep)}function v(a){return new K(!1,!1,!1,a)}function L(a,b){var c=a.type;if(0===c)return c=a.data.length,new K(!0,1<=c,2<=c,b);if(4===
  c)return c=a.data,new K(c.thisDep,c.contextDep,c.propDep,b);if(5===c)return new K(!1,!1,!1,b);if(6===c){for(var e=c=!1,f=!1,d=0;d<a.data.length;++d){var p=a.data[d];1===p.type?f=!0:2===p.type?e=!0:3===p.type?c=!0:0===p.type?(c=!0,p=p.data,1<=p&&(e=!0),2<=p&&(f=!0)):4===p.type&&(c=c||p.data.thisDep,e=e||p.data.contextDep,f=f||p.data.propDep)}return new K(c,e,f,b)}return new K(3===c,2===c,1===c,b)}function Wb(a,b,c,e,f,d,p,n,u,t,w,k,B,l,h){function g(a){return a.replace(".","_")}function q(a,b,c){var d=
  g(a);La.push(a);Ca[d]=pa[d]=!!c;qa[d]=b}function r(a,b,c){var d=g(a);La.push(a);Array.isArray(c)?(pa[d]=c.slice(),Ca[d]=c.slice()):pa[d]=Ca[d]=c;ra[d]=b}function m(){var a=Vb(),c=a.link,d=a.global;a.id=na++;a.batchId="0";var e=c(ub),f=a.shared={props:"a0"};Object.keys(ub).forEach(function(a){f[a]=d.def(e,".",a)});var g=a.next={},h=a.current={};Object.keys(ra).forEach(function(a){Array.isArray(pa[a])&&(g[a]=d.def(f.next,".",a),h[a]=d.def(f.current,".",a))});var ba=a.constants={};Object.keys(Na).forEach(function(a){ba[a]=
  d.def(JSON.stringify(Na[a]))});a.invoke=function(b,d){switch(d.type){case 0:var e=["this",f.context,f.props,a.batchId];return b.def(c(d.data),".call(",e.slice(0,Math.max(d.data.length+1,4)),")");case 1:return b.def(f.props,d.data);case 2:return b.def(f.context,d.data);case 3:return b.def("this",d.data);case 4:return d.data.append(a,b),d.data.ref;case 5:return d.data.toString();case 6:return d.data.map(function(c){return a.invoke(b,c)})}};a.attribCache={};var va={};a.scopeAttrib=function(a){a=b.id(a);
  if(a in va)return va[a];var d=t.scope[a];d||(d=t.scope[a]=new ga);return va[a]=c(d)};return a}function z(a){var b=a["static"];a=a.dynamic;var c;if("profile"in b){var d=!!b.profile;c=v(function(a,b){return d});c.enable=d}else if("profile"in a){var e=a.profile;c=L(e,function(a,b){return a.invoke(b,e)})}return c}function E(a,b){var c=a["static"],d=a.dynamic;if("framebuffer"in c){var e=c.framebuffer;return e?(e=n.getFramebuffer(e),v(function(a,b){var c=a.link(e),d=a.shared;b.set(d.framebuffer,".next",
  c);d=d.context;b.set(d,".framebufferWidth",c+".width");b.set(d,".framebufferHeight",c+".height");return c})):v(function(a,b){var c=a.shared;b.set(c.framebuffer,".next","null");c=c.context;b.set(c,".framebufferWidth",c+".drawingBufferWidth");b.set(c,".framebufferHeight",c+".drawingBufferHeight");return"null"})}if("framebuffer"in d){var f=d.framebuffer;return L(f,function(a,b){var c=a.invoke(b,f),d=a.shared,e=d.framebuffer,c=b.def(e,".getFramebuffer(",c,")");b.set(e,".next",c);d=d.context;b.set(d,".framebufferWidth",
  c+"?"+c+".width:"+d+".drawingBufferWidth");b.set(d,".framebufferHeight",c+"?"+c+".height:"+d+".drawingBufferHeight");return c})}return null}function F(a,b,c){function d(a){if(a in e){var c=e[a];a=!0;var g=c.x|0,x=c.y|0,h,k;"width"in c?h=c.width|0:a=!1;"height"in c?k=c.height|0:a=!1;return new K(!a&&b&&b.thisDep,!a&&b&&b.contextDep,!a&&b&&b.propDep,function(a,b){var d=a.shared.context,e=h;"width"in c||(e=b.def(d,".","framebufferWidth","-",g));var f=k;"height"in c||(f=b.def(d,".","framebufferHeight",
  "-",x));return[g,x,e,f]})}if(a in f){var ca=f[a];a=L(ca,function(a,b){var c=a.invoke(b,ca),d=a.shared.context,e=b.def(c,".x|0"),f=b.def(c,".y|0"),g=b.def('"width" in ',c,"?",c,".width|0:","(",d,".","framebufferWidth","-",e,")"),c=b.def('"height" in ',c,"?",c,".height|0:","(",d,".","framebufferHeight","-",f,")");return[e,f,g,c]});b&&(a.thisDep=a.thisDep||b.thisDep,a.contextDep=a.contextDep||b.contextDep,a.propDep=a.propDep||b.propDep);return a}return b?new K(b.thisDep,b.contextDep,b.propDep,function(a,
  b){var c=a.shared.context;return[0,0,b.def(c,".","framebufferWidth"),b.def(c,".","framebufferHeight")]}):null}var e=a["static"],f=a.dynamic;if(a=d("viewport")){var g=a;a=new K(a.thisDep,a.contextDep,a.propDep,function(a,b){var c=g.append(a,b),d=a.shared.context;b.set(d,".viewportWidth",c[2]);b.set(d,".viewportHeight",c[3]);return c})}return{viewport:a,scissor_box:d("scissor.box")}}function Z(a,b){var c=a["static"];if("string"===typeof c.frag&&"string"===typeof c.vert){if(0<Object.keys(b.dynamic).length)return null;
  var c=b["static"],d=Object.keys(c);if(0<d.length&&"number"===typeof c[d[0]]){for(var e=[],f=0;f<d.length;++f)e.push([c[d[f]]|0,d[f]]);return e}}return null}function G(a,c,d){function e(a){if(a in f){var c=b.id(f[a]);a=v(function(){return c});a.id=c;return a}if(a in g){var d=g[a];return L(d,function(a,b){var c=a.invoke(b,d);return b.def(a.shared.strings,".id(",c,")")})}return null}var f=a["static"],g=a.dynamic,h=e("frag"),ba=e("vert"),va=null;sa(h)&&sa(ba)?(va=w.program(ba.id,h.id,null,d),a=v(function(a,
  b){return a.link(va)})):a=new K(h&&h.thisDep||ba&&ba.thisDep,h&&h.contextDep||ba&&ba.contextDep,h&&h.propDep||ba&&ba.propDep,function(a,b){var c=a.shared.shader,d;d=h?h.append(a,b):b.def(c,".","frag");var e;e=ba?ba.append(a,b):b.def(c,".","vert");return b.def(c+".program("+e+","+d+")")});return{frag:h,vert:ba,progVar:a,program:va}}function H(a,b){function c(a,b){if(a in e){var d=e[a]|0;return v(function(a,c){b&&(a.OFFSET=d);return d})}if(a in f){var x=f[a];return L(x,function(a,c){var d=a.invoke(c,
  x);b&&(a.OFFSET=d);return d})}return b&&g?v(function(a,b){a.OFFSET="0";return 0}):null}var e=a["static"],f=a.dynamic,g=function(){if("elements"in e){var a=e.elements;Qa(a)?a=d.getElements(d.create(a,!0)):a&&(a=d.getElements(a));var b=v(function(b,c){if(a){var d=b.link(a);return b.ELEMENTS=d}return b.ELEMENTS=null});b.value=a;return b}if("elements"in f){var c=f.elements;return L(c,function(a,b){var d=a.shared,e=d.isBufferArgs,d=d.elements,f=a.invoke(b,c),g=b.def("null"),e=b.def(e,"(",f,")"),f=a.cond(e).then(g,
  "=",d,".createStream(",f,");")["else"](g,"=",d,".getElements(",f,");");b.entry(f);b.exit(a.cond(e).then(d,".destroyStream(",g,");"));return a.ELEMENTS=g})}return null}(),h=c("offset",!0);return{elements:g,primitive:function(){if("primitive"in e){var a=e.primitive;return v(function(b,c){return Ta[a]})}if("primitive"in f){var b=f.primitive;return L(b,function(a,c){var d=a.constants.primTypes,e=a.invoke(c,b);return c.def(d,"[",e,"]")})}return g?sa(g)?g.value?v(function(a,b){return b.def(a.ELEMENTS,".primType")}):
  v(function(){return 4}):new K(g.thisDep,g.contextDep,g.propDep,function(a,b){var c=a.ELEMENTS;return b.def(c,"?",c,".primType:",4)}):null}(),count:function(){if("count"in e){var a=e.count|0;return v(function(){return a})}if("count"in f){var b=f.count;return L(b,function(a,c){return a.invoke(c,b)})}return g?sa(g)?g?h?new K(h.thisDep,h.contextDep,h.propDep,function(a,b){return b.def(a.ELEMENTS,".vertCount-",a.OFFSET)}):v(function(a,b){return b.def(a.ELEMENTS,".vertCount")}):v(function(){return-1}):
  new K(g.thisDep||h.thisDep,g.contextDep||h.contextDep,g.propDep||h.propDep,function(a,b){var c=a.ELEMENTS;return a.OFFSET?b.def(c,"?",c,".vertCount-",a.OFFSET,":-1"):b.def(c,"?",c,".vertCount:-1")}):null}(),instances:c("instances",!1),offset:h}}function O(a,b){var c=a["static"],d=a.dynamic,e={};La.forEach(function(a){function b(g,x){if(a in c){var h=g(c[a]);e[f]=v(function(){return h})}else if(a in d){var I=d[a];e[f]=L(I,function(a,b){return x(a,b,a.invoke(b,I))})}}var f=g(a);switch(a){case "cull.enable":case "blend.enable":case "dither":case "stencil.enable":case "depth.enable":case "scissor.enable":case "polygonOffset.enable":case "sample.alpha":case "sample.enable":case "depth.mask":return b(function(a){return a},
  function(a,b,c){return c});case "depth.func":return b(function(a){return ab[a]},function(a,b,c){return b.def(a.constants.compareFuncs,"[",c,"]")});case "depth.range":return b(function(a){return a},function(a,b,c){a=b.def("+",c,"[0]");b=b.def("+",c,"[1]");return[a,b]});case "blend.func":return b(function(a){return[Ea["srcRGB"in a?a.srcRGB:a.src],Ea["dstRGB"in a?a.dstRGB:a.dst],Ea["srcAlpha"in a?a.srcAlpha:a.src],Ea["dstAlpha"in a?a.dstAlpha:a.dst]]},function(a,b,c){function d(a,e){return b.def('"',
  a,e,'" in ',c,"?",c,".",a,e,":",c,".",a)}a=a.constants.blendFuncs;var e=d("src","RGB"),f=d("dst","RGB"),e=b.def(a,"[",e,"]"),g=b.def(a,"[",d("src","Alpha"),"]"),f=b.def(a,"[",f,"]");a=b.def(a,"[",d("dst","Alpha"),"]");return[e,f,g,a]});case "blend.equation":return b(function(a){if("string"===typeof a)return[W[a],W[a]];if("object"===typeof a)return[W[a.rgb],W[a.alpha]]},function(a,b,c){var d=a.constants.blendEquations,e=b.def(),f=b.def();a=a.cond("typeof ",c,'==="string"');a.then(e,"=",f,"=",d,"[",
  c,"];");a["else"](e,"=",d,"[",c,".rgb];",f,"=",d,"[",c,".alpha];");b(a);return[e,f]});case "blend.color":return b(function(a){return J(4,function(b){return+a[b]})},function(a,b,c){return J(4,function(a){return b.def("+",c,"[",a,"]")})});case "stencil.mask":return b(function(a){return a|0},function(a,b,c){return b.def(c,"|0")});case "stencil.func":return b(function(a){return[ab[a.cmp||"keep"],a.ref||0,"mask"in a?a.mask:-1]},function(a,b,c){a=b.def('"cmp" in ',c,"?",a.constants.compareFuncs,"[",c,".cmp]",
  ":",7680);var d=b.def(c,".ref|0");b=b.def('"mask" in ',c,"?",c,".mask|0:-1");return[a,d,b]});case "stencil.opFront":case "stencil.opBack":return b(function(b){return["stencil.opBack"===a?1029:1028,Ra[b.fail||"keep"],Ra[b.zfail||"keep"],Ra[b.zpass||"keep"]]},function(b,c,d){function e(a){return c.def('"',a,'" in ',d,"?",f,"[",d,".",a,"]:",7680)}var f=b.constants.stencilOps;return["stencil.opBack"===a?1029:1028,e("fail"),e("zfail"),e("zpass")]});case "polygonOffset.offset":return b(function(a){return[a.factor|
  0,a.units|0]},function(a,b,c){a=b.def(c,".factor|0");b=b.def(c,".units|0");return[a,b]});case "cull.face":return b(function(a){var b=0;"front"===a?b=1028:"back"===a&&(b=1029);return b},function(a,b,c){return b.def(c,'==="front"?',1028,":",1029)});case "lineWidth":return b(function(a){return a},function(a,b,c){return c});case "frontFace":return b(function(a){return Ab[a]},function(a,b,c){return b.def(c+'==="cw"?2304:2305')});case "colorMask":return b(function(a){return a.map(function(a){return!!a})},
  function(a,b,c){return J(4,function(a){return"!!"+c+"["+a+"]"})});case "sample.coverage":return b(function(a){return["value"in a?a.value:1,!!a.invert]},function(a,b,c){a=b.def('"value" in ',c,"?+",c,".value:1");b=b.def("!!",c,".invert");return[a,b]})}});return e}function M(a,b){var c=a["static"],d=a.dynamic,e={};Object.keys(c).forEach(function(a){var b=c[a],d;if("number"===typeof b||"boolean"===typeof b)d=v(function(){return b});else if("function"===typeof b){var f=b._reglType;if("texture2d"===f||
  "textureCube"===f)d=v(function(a){return a.link(b)});else if("framebuffer"===f||"framebufferCube"===f)d=v(function(a){return a.link(b.color[0])})}else ma(b)&&(d=v(function(a){return a.global.def("[",J(b.length,function(a){return b[a]}),"]")}));d.value=b;e[a]=d});Object.keys(d).forEach(function(a){var b=d[a];e[a]=L(b,function(a,c){return a.invoke(c,b)})});return e}function S(a,c){var d=a["static"],e=a.dynamic,g={};Object.keys(d).forEach(function(a){var c=d[a],e=b.id(a),x=new ga;if(Qa(c))x.state=1,
  x.buffer=f.getBuffer(f.create(c,34962,!1,!0)),x.type=0;else{var h=f.getBuffer(c);if(h)x.state=1,x.buffer=h,x.type=0;else if("constant"in c){var I=c.constant;x.buffer="null";x.state=2;"number"===typeof I?x.x=I:Ba.forEach(function(a,b){b<I.length&&(x[a]=I[b])})}else{var h=Qa(c.buffer)?f.getBuffer(f.create(c.buffer,34962,!1,!0)):f.getBuffer(c.buffer),k=c.offset|0,l=c.stride|0,m=c.size|0,ka=!!c.normalized,n=0;"type"in c&&(n=Ia[c.type]);c=c.divisor|0;x.buffer=h;x.state=1;x.size=m;x.normalized=ka;x.type=
  n||h.dtype;x.offset=k;x.stride=l;x.divisor=c}}g[a]=v(function(a,b){var c=a.attribCache;if(e in c)return c[e];var d={isStream:!1};Object.keys(x).forEach(function(a){d[a]=x[a]});x.buffer&&(d.buffer=a.link(x.buffer),d.type=d.type||d.buffer+".dtype");return c[e]=d})});Object.keys(e).forEach(function(a){var b=e[a];g[a]=L(b,function(a,c){function d(a){c(h[a],"=",e,".",a,"|0;")}var e=a.invoke(c,b),f=a.shared,g=a.constants,x=f.isBufferArgs,f=f.buffer,h={isStream:c.def(!1)},I=new ga;I.state=1;Object.keys(I).forEach(function(a){h[a]=
  c.def(""+I[a])});var k=h.buffer,l=h.type;c("if(",x,"(",e,")){",h.isStream,"=true;",k,"=",f,".createStream(",34962,",",e,");",l,"=",k,".dtype;","}else{",k,"=",f,".getBuffer(",e,");","if(",k,"){",l,"=",k,".dtype;",'}else if("constant" in ',e,"){",h.state,"=",2,";","if(typeof "+e+'.constant === "number"){',h[Ba[0]],"=",e,".constant;",Ba.slice(1).map(function(a){return h[a]}).join("="),"=0;","}else{",Ba.map(function(a,b){return h[a]+"="+e+".constant.length>"+b+"?"+e+".constant["+b+"]:0;"}).join(""),"}}else{",
  "if(",x,"(",e,".buffer)){",k,"=",f,".createStream(",34962,",",e,".buffer);","}else{",k,"=",f,".getBuffer(",e,".buffer);","}",l,'="type" in ',e,"?",g.glTypes,"[",e,".type]:",k,".dtype;",h.normalized,"=!!",e,".normalized;");d("size");d("offset");d("stride");d("divisor");c("}}");c.exit("if(",h.isStream,"){",f,".destroyStream(",k,");","}");return h})});return g}function D(a,b){var c=a["static"],d=a.dynamic;if("vao"in c){var e=c.vao;null!==e&&null===t.getVAO(e)&&(e=t.createVAO(e));return v(function(a){return a.link(t.getVAO(e))})}if("vao"in
  d){var f=d.vao;return L(f,function(a,b){var c=a.invoke(b,f);return b.def(a.shared.vao+".getVAO("+c+")")})}return null}function y(a){var b=a["static"],c=a.dynamic,d={};Object.keys(b).forEach(function(a){var c=b[a];d[a]=v(function(a,b){return"number"===typeof c||"boolean"===typeof c?""+c:a.link(c)})});Object.keys(c).forEach(function(a){var b=c[a];d[a]=L(b,function(a,c){return a.invoke(c,b)})});return d}function la(a,b,d,e,f){function h(a){var b=m[a];b&&($a[a]=b)}var k=Z(a,b),l=E(a,f),m=F(a,l,f),n=H(a,
  f),$a=O(a,f),p=G(a,f,k);h("viewport");h(g("scissor.box"));var q=0<Object.keys($a).length,l={framebuffer:l,draw:n,shader:p,state:$a,dirty:q,scopeVAO:null,drawVAO:null,useVAO:!1,attributes:{}};l.profile=z(a,f);l.uniforms=M(d,f);l.drawVAO=l.scopeVAO=D(a,f);if(!l.drawVAO&&p.program&&!k&&c.angle_instanced_arrays){var r=!0;a=p.program.attributes.map(function(a){a=b["static"][a];r=r&&!!a;return a});if(r&&0<a.length){var w=t.getVAO(t.createVAO(a));l.drawVAO=new K(null,null,null,function(a,b){return a.link(w)});
  l.useVAO=!0}}k?l.useVAO=!0:l.attributes=S(b,f);l.context=y(e,f);return l}function V(a,b,c){var d=a.shared.context,e=a.scope();Object.keys(c).forEach(function(f){b.save(d,"."+f);var g=c[f].append(a,b);Array.isArray(g)?e(d,".",f,"=[",g.join(),"];"):e(d,".",f,"=",g,";")});b(e)}function R(a,b,c,d){var e=a.shared,f=e.gl,g=e.framebuffer,h;Ka&&(h=b.def(e.extensions,".webgl_draw_buffers"));var k=a.constants,e=k.drawBuffer,k=k.backBuffer;a=c?c.append(a,b):b.def(g,".next");d||b("if(",a,"!==",g,".cur){");b("if(",
  a,"){",f,".bindFramebuffer(",36160,",",a,".framebuffer);");Ka&&b(h,".drawBuffersWEBGL(",e,"[",a,".colorAttachments.length]);");b("}else{",f,".bindFramebuffer(",36160,",null);");Ka&&b(h,".drawBuffersWEBGL(",k,");");b("}",g,".cur=",a,";");d||b("}")}function T(a,b,c){var d=a.shared,e=d.gl,f=a.current,h=a.next,k=d.current,l=d.next,m=a.cond(k,".dirty");La.forEach(function(b){b=g(b);if(!(b in c.state)){var d,I;if(b in h){d=h[b];I=f[b];var n=J(pa[b].length,function(a){return m.def(d,"[",a,"]")});m(a.cond(n.map(function(a,
  b){return a+"!=="+I+"["+b+"]"}).join("||")).then(e,".",ra[b],"(",n,");",n.map(function(a,b){return I+"["+b+"]="+a}).join(";"),";"))}else d=m.def(l,".",b),n=a.cond(d,"!==",k,".",b),m(n),b in qa?n(a.cond(d).then(e,".enable(",qa[b],");")["else"](e,".disable(",qa[b],");"),k,".",b,"=",d,";"):n(e,".",ra[b],"(",d,");",k,".",b,"=",d,";")}});0===Object.keys(c.state).length&&m(k,".dirty=false;");b(m)}function N(a,b,c,d){var e=a.shared,f=a.current,g=e.current,h=e.gl;zb(Object.keys(c)).forEach(function(e){var k=
  c[e];if(!d||d(k)){var l=k.append(a,b);if(qa[e]){var m=qa[e];sa(k)?l?b(h,".enable(",m,");"):b(h,".disable(",m,");"):b(a.cond(l).then(h,".enable(",m,");")["else"](h,".disable(",m,");"));b(g,".",e,"=",l,";")}else if(ma(l)){var n=f[e];b(h,".",ra[e],"(",l,");",l.map(function(a,b){return n+"["+b+"]="+a}).join(";"),";")}else b(h,".",ra[e],"(",l,");",g,".",e,"=",l,";")}})}function C(a,b){oa&&(a.instancing=b.def(a.shared.extensions,".angle_instanced_arrays"))}function Q(a,b,c,d,e){function f(){return"undefined"===
  typeof performance?"Date.now()":"performance.now()"}function g(a){r=b.def();a(r,"=",f(),";");"string"===typeof e?a(n,".count+=",e,";"):a(n,".count++;");l&&(d?(t=b.def(),a(t,"=",q,".getNumPendingQueries();")):a(q,".beginQuery(",n,");"))}function h(a){a(n,".cpuTime+=",f(),"-",r,";");l&&(d?a(q,".pushScopeStats(",t,",",q,".getNumPendingQueries(),",n,");"):a(q,".endQuery();"))}function k(a){var c=b.def(p,".profile");b(p,".profile=",a,";");b.exit(p,".profile=",c,";")}var m=a.shared,n=a.stats,p=m.current,
  q=m.timer;c=c.profile;var r,t;if(c){if(sa(c)){c.enable?(g(b),h(b.exit),k("true")):k("false");return}c=c.append(a,b);k(c)}else c=b.def(p,".profile");m=a.block();g(m);b("if(",c,"){",m,"}");a=a.block();h(a);b.exit("if(",c,"){",a,"}")}function U(a,b,c,d,e){function f(a){switch(a){case 35664:case 35667:case 35671:return 2;case 35665:case 35668:case 35672:return 3;case 35666:case 35669:case 35673:return 4;default:return 1}}function g(c,d,e){function f(){b("if(!",n,".buffer){",l,".enableVertexAttribArray(",
  m,");}");var c=e.type,g;g=e.size?b.def(e.size,"||",d):d;b("if(",n,".type!==",c,"||",n,".size!==",g,"||",q.map(function(a){return n+"."+a+"!=="+e[a]}).join("||"),"){",l,".bindBuffer(",34962,",",ja,".buffer);",l,".vertexAttribPointer(",[m,g,c,e.normalized,e.stride,e.offset],");",n,".type=",c,";",n,".size=",g,";",q.map(function(a){return n+"."+a+"="+e[a]+";"}).join(""),"}");oa&&(c=e.divisor,b("if(",n,".divisor!==",c,"){",a.instancing,".vertexAttribDivisorANGLE(",[m,c],");",n,".divisor=",c,";}"))}function k(){b("if(",
  n,".buffer){",l,".disableVertexAttribArray(",m,");",n,".buffer=null;","}if(",Ba.map(function(a,b){return n+"."+a+"!=="+p[b]}).join("||"),"){",l,".vertexAttrib4f(",m,",",p,");",Ba.map(function(a,b){return n+"."+a+"="+p[b]+";"}).join(""),"}")}var l=h.gl,m=b.def(c,".location"),n=b.def(h.attributes,"[",m,"]");c=e.state;var ja=e.buffer,p=[e.x,e.y,e.z,e.w],q=["buffer","normalized","offset","stride"];1===c?f():2===c?k():(b("if(",c,"===",1,"){"),f(),b("}else{"),k(),b("}"))}var h=a.shared;d.forEach(function(d){var h=
  d.name,k=c.attributes[h],l;if(k){if(!e(k))return;l=k.append(a,b)}else{if(!e(Bb))return;var m=a.scopeAttrib(h);l={};Object.keys(new ga).forEach(function(a){l[a]=b.def(m,".",a)})}g(a.link(d),f(d.info.type),l)})}function ta(a,c,d,e,f){for(var g=a.shared,h=g.gl,k,l=0;l<e.length;++l){var m=e[l],n=m.name,p=m.info.type,q=d.uniforms[n],m=a.link(m)+".location",r;if(q){if(!f(q))continue;if(sa(q)){n=q.value;if(35678===p||35680===p)p=a.link(n._texture||n.color[0]._texture),c(h,".uniform1i(",m,",",p+".bind());"),
  c.exit(p,".unbind();");else if(35674===p||35675===p||35676===p)n=a.global.def("new Float32Array(["+Array.prototype.slice.call(n)+"])"),q=2,35675===p?q=3:35676===p&&(q=4),c(h,".uniformMatrix",q,"fv(",m,",false,",n,");");else{switch(p){case 5126:k="1f";break;case 35664:k="2f";break;case 35665:k="3f";break;case 35666:k="4f";break;case 35670:k="1i";break;case 5124:k="1i";break;case 35671:k="2i";break;case 35667:k="2i";break;case 35672:k="3i";break;case 35668:k="3i";break;case 35673:k="4i";break;case 35669:k=
  "4i"}c(h,".uniform",k,"(",m,",",ma(n)?Array.prototype.slice.call(n):n,");")}continue}else r=q.append(a,c)}else{if(!f(Bb))continue;r=c.def(g.uniforms,"[",b.id(n),"]")}35678===p?c("if(",r,"&&",r,'._reglType==="framebuffer"){',r,"=",r,".color[0];","}"):35680===p&&c("if(",r,"&&",r,'._reglType==="framebufferCube"){',r,"=",r,".color[0];","}");n=1;switch(p){case 35678:case 35680:p=c.def(r,"._texture");c(h,".uniform1i(",m,",",p,".bind());");c.exit(p,".unbind();");continue;case 5124:case 35670:k="1i";break;
  case 35667:case 35671:k="2i";n=2;break;case 35668:case 35672:k="3i";n=3;break;case 35669:case 35673:k="4i";n=4;break;case 5126:k="1f";break;case 35664:k="2f";n=2;break;case 35665:k="3f";n=3;break;case 35666:k="4f";n=4;break;case 35674:k="Matrix2fv";break;case 35675:k="Matrix3fv";break;case 35676:k="Matrix4fv"}c(h,".uniform",k,"(",m,",");if("M"===k.charAt(0)){var m=Math.pow(p-35674+2,2),t=a.global.def("new Float32Array(",m,")");Array.isArray(r)?c("false,(",J(m,function(a){return t+"["+a+"]="+r[a]}),
  ",",t,")"):c("false,(Array.isArray(",r,")||",r," instanceof Float32Array)?",r,":(",J(m,function(a){return t+"["+a+"]="+r+"["+a+"]"}),",",t,")")}else 1<n?c(J(n,function(a){return Array.isArray(r)?r[a]:r+"["+a+"]"})):c(r);c(");")}}function aa(a,b,c,d){function e(f){var g=m[f];return g?g.contextDep&&d.contextDynamic||g.propDep?g.append(a,c):g.append(a,b):b.def(l,".",f)}function f(){function a(){c(w,".drawElementsInstancedANGLE(",[p,q,u,r+"<<(("+u+"-5121)>>1)",t],");")}function b(){c(w,".drawArraysInstancedANGLE(",
  [p,r,q,t],");")}n?B?a():(c("if(",n,"){"),a(),c("}else{"),b(),c("}")):b()}function g(){function a(){c(k+".drawElements("+[p,q,u,r+"<<(("+u+"-5121)>>1)"]+");")}function b(){c(k+".drawArrays("+[p,r,q]+");")}n?B?a():(c("if(",n,"){"),a(),c("}else{"),b(),c("}")):b()}var h=a.shared,k=h.gl,l=h.draw,m=d.draw,n=function(){var e=m.elements,f=b;if(e){if(e.contextDep&&d.contextDynamic||e.propDep)f=c;e=e.append(a,f)}else e=f.def(l,".","elements");e&&f("if("+e+")"+k+".bindBuffer(34963,"+e+".buffer.buffer);");return e}(),
  p=e("primitive"),r=e("offset"),q=function(){var e=m.count,f=b;if(e){if(e.contextDep&&d.contextDynamic||e.propDep)f=c;e=e.append(a,f)}else e=f.def(l,".","count");return e}();if("number"===typeof q){if(0===q)return}else c("if(",q,"){"),c.exit("}");var t,w;oa&&(t=e("instances"),w=a.instancing);var u=n+".type",B=m.elements&&sa(m.elements);oa&&("number"!==typeof t||0<=t)?"string"===typeof t?(c("if(",t,">0){"),f(),c("}else if(",t,"<0){"),g(),c("}")):f():g()}function X(a,b,c,d,e){b=m();e=b.proc("body",e);
  oa&&(b.instancing=e.def(b.shared.extensions,".angle_instanced_arrays"));a(b,e,c,d);return b.compile().body}function fa(a,b,c,d){C(a,b);c.useVAO?c.drawVAO?b(a.shared.vao,".setVAO(",c.drawVAO.append(a,b),");"):b(a.shared.vao,".setVAO(",a.shared.vao,".targetVAO);"):(b(a.shared.vao,".setVAO(null);"),U(a,b,c,d.attributes,function(){return!0}));ta(a,b,c,d.uniforms,function(){return!0});aa(a,b,b,c)}function Da(a,b){var c=a.proc("draw",1);C(a,c);V(a,c,b.context);R(a,c,b.framebuffer);T(a,c,b);N(a,c,b.state);
  Q(a,c,b,!1,!0);var d=b.shader.progVar.append(a,c);c(a.shared.gl,".useProgram(",d,".program);");if(b.shader.program)fa(a,c,b,b.shader.program);else{c(a.shared.vao,".setVAO(null);");var e=a.global.def("{}"),f=c.def(d,".id"),g=c.def(e,"[",f,"]");c(a.cond(g).then(g,".call(this,a0);")["else"](g,"=",e,"[",f,"]=",a.link(function(c){return X(fa,a,b,c,1)}),"(",d,");",g,".call(this,a0);"))}0<Object.keys(b.state).length&&c(a.shared.current,".dirty=true;")}function ua(a,b,c,d){function e(){return!0}a.batchId=
  "a1";C(a,b);U(a,b,c,d.attributes,e);ta(a,b,c,d.uniforms,e);aa(a,b,b,c)}function P(a,b,c,d){function e(a){return a.contextDep&&g||a.propDep}function f(a){return!e(a)}C(a,b);var g=c.contextDep,h=b.def(),k=b.def();a.shared.props=k;a.batchId=h;var l=a.scope(),m=a.scope();b(l.entry,"for(",h,"=0;",h,"<","a1",";++",h,"){",k,"=","a0","[",h,"];",m,"}",l.exit);c.needsContext&&V(a,m,c.context);c.needsFramebuffer&&R(a,m,c.framebuffer);N(a,m,c.state,e);c.profile&&e(c.profile)&&Q(a,m,c,!1,!0);d?(c.useVAO?c.drawVAO?
  e(c.drawVAO)?m(a.shared.vao,".setVAO(",c.drawVAO.append(a,m),");"):l(a.shared.vao,".setVAO(",c.drawVAO.append(a,l),");"):l(a.shared.vao,".setVAO(",a.shared.vao,".targetVAO);"):(l(a.shared.vao,".setVAO(null);"),U(a,l,c,d.attributes,f),U(a,m,c,d.attributes,e)),ta(a,l,c,d.uniforms,f),ta(a,m,c,d.uniforms,e),aa(a,l,m,c)):(b=a.global.def("{}"),d=c.shader.progVar.append(a,m),k=m.def(d,".id"),l=m.def(b,"[",k,"]"),m(a.shared.gl,".useProgram(",d,".program);","if(!",l,"){",l,"=",b,"[",k,"]=",a.link(function(b){return X(ua,
  a,c,b,2)}),"(",d,");}",l,".call(this,a0[",h,"],",h,");"))}function da(a,b){function c(a){return a.contextDep&&e||a.propDep}var d=a.proc("batch",2);a.batchId="0";C(a,d);var e=!1,f=!0;Object.keys(b.context).forEach(function(a){e=e||b.context[a].propDep});e||(V(a,d,b.context),f=!1);var g=b.framebuffer,h=!1;g?(g.propDep?e=h=!0:g.contextDep&&e&&(h=!0),h||R(a,d,g)):R(a,d,null);b.state.viewport&&b.state.viewport.propDep&&(e=!0);T(a,d,b);N(a,d,b.state,function(a){return!c(a)});b.profile&&c(b.profile)||Q(a,
  d,b,!1,"a1");b.contextDep=e;b.needsContext=f;b.needsFramebuffer=h;f=b.shader.progVar;if(f.contextDep&&e||f.propDep)P(a,d,b,null);else if(f=f.append(a,d),d(a.shared.gl,".useProgram(",f,".program);"),b.shader.program)P(a,d,b,b.shader.program);else{d(a.shared.vao,".setVAO(null);");var g=a.global.def("{}"),h=d.def(f,".id"),k=d.def(g,"[",h,"]");d(a.cond(k).then(k,".call(this,a0,a1);")["else"](k,"=",g,"[",h,"]=",a.link(function(c){return X(P,a,b,c,2)}),"(",f,");",k,".call(this,a0,a1);"))}0<Object.keys(b.state).length&&
  d(a.shared.current,".dirty=true;")}function ea(a,c){function d(b){var g=c.shader[b];g&&e.set(f.shader,"."+b,g.append(a,e))}var e=a.proc("scope",3);a.batchId="a2";var f=a.shared,g=f.current;V(a,e,c.context);c.framebuffer&&c.framebuffer.append(a,e);zb(Object.keys(c.state)).forEach(function(b){var d=c.state[b].append(a,e);ma(d)?d.forEach(function(c,d){e.set(a.next[b],"["+d+"]",c)}):e.set(f.next,"."+b,d)});Q(a,e,c,!0,!0);["elements","offset","count","instances","primitive"].forEach(function(b){var d=
  c.draw[b];d&&e.set(f.draw,"."+b,""+d.append(a,e))});Object.keys(c.uniforms).forEach(function(d){var g=c.uniforms[d].append(a,e);Array.isArray(g)&&(g="["+g.join()+"]");e.set(f.uniforms,"["+b.id(d)+"]",g)});Object.keys(c.attributes).forEach(function(b){var d=c.attributes[b].append(a,e),f=a.scopeAttrib(b);Object.keys(new ga).forEach(function(a){e.set(f,"."+a,d[a])})});c.scopeVAO&&e.set(f.vao,".targetVAO",c.scopeVAO.append(a,e));d("vert");d("frag");0<Object.keys(c.state).length&&(e(g,".dirty=true;"),
  e.exit(g,".dirty=true;"));e("a1(",a.shared.context,",a0,",a.batchId,");")}function ha(a){if("object"===typeof a&&!ma(a)){for(var b=Object.keys(a),c=0;c<b.length;++c)if(Y.isDynamic(a[b[c]]))return!0;return!1}}function ia(a,b,c){function d(a,b){g.forEach(function(c){var d=e[c];Y.isDynamic(d)&&(d=a.invoke(b,d),b(m,".",c,"=",d,";"))})}var e=b["static"][c];if(e&&ha(e)){var f=a.global,g=Object.keys(e),h=!1,k=!1,l=!1,m=a.global.def("{}");g.forEach(function(b){var c=e[b];if(Y.isDynamic(c))"function"===typeof c&&
  (c=e[b]=Y.unbox(c)),b=L(c,null),h=h||b.thisDep,l=l||b.propDep,k=k||b.contextDep;else{f(m,".",b,"=");switch(typeof c){case "number":f(c);break;case "string":f('"',c,'"');break;case "object":Array.isArray(c)&&f("[",c.join(),"]");break;default:f(a.link(c))}f(";")}});b.dynamic[c]=new Y.DynamicVariable(4,{thisDep:h,contextDep:k,propDep:l,ref:m,append:d});delete b["static"][c]}}var ga=t.Record,W={add:32774,subtract:32778,"reverse subtract":32779};c.ext_blend_minmax&&(W.min=32775,W.max=32776);var oa=c.angle_instanced_arrays,
  Ka=c.webgl_draw_buffers,pa={dirty:!0,profile:h.profile},Ca={},La=[],qa={},ra={};q("dither",3024);q("blend.enable",3042);r("blend.color","blendColor",[0,0,0,0]);r("blend.equation","blendEquationSeparate",[32774,32774]);r("blend.func","blendFuncSeparate",[1,0,1,0]);q("depth.enable",2929,!0);r("depth.func","depthFunc",513);r("depth.range","depthRange",[0,1]);r("depth.mask","depthMask",!0);r("colorMask","colorMask",[!0,!0,!0,!0]);q("cull.enable",2884);r("cull.face","cullFace",1029);r("frontFace","frontFace",
  2305);r("lineWidth","lineWidth",1);q("polygonOffset.enable",32823);r("polygonOffset.offset","polygonOffset",[0,0]);q("sample.alpha",32926);q("sample.enable",32928);r("sample.coverage","sampleCoverage",[1,!1]);q("stencil.enable",2960);r("stencil.mask","stencilMask",-1);r("stencil.func","stencilFunc",[519,0,-1]);r("stencil.opFront","stencilOpSeparate",[1028,7680,7680,7680]);r("stencil.opBack","stencilOpSeparate",[1029,7680,7680,7680]);q("scissor.enable",3089);r("scissor.box","scissor",[0,0,a.drawingBufferWidth,
  a.drawingBufferHeight]);r("viewport","viewport",[0,0,a.drawingBufferWidth,a.drawingBufferHeight]);var ub={gl:a,context:B,strings:b,next:Ca,current:pa,draw:k,elements:d,buffer:f,shader:w,attributes:t.state,vao:t,uniforms:u,framebuffer:n,extensions:c,timer:l,isBufferArgs:Qa},Na={primTypes:Ta,compareFuncs:ab,blendFuncs:Ea,blendEquations:W,stencilOps:Ra,glTypes:Ia,orientationType:Ab};Ka&&(Na.backBuffer=[1029],Na.drawBuffer=J(e.maxDrawbuffers,function(a){return 0===a?[0]:J(a,function(a){return 36064+a})}));
  var na=0;return{next:Ca,current:pa,procs:function(){var a=m(),b=a.proc("poll"),d=a.proc("refresh"),f=a.block();b(f);d(f);var g=a.shared,h=g.gl,k=g.next,l=g.current;f(l,".dirty=false;");R(a,b);R(a,d,null,!0);var n;oa&&(n=a.link(oa));c.oes_vertex_array_object&&d(a.link(c.oes_vertex_array_object),".bindVertexArrayOES(null);");for(var p=0;p<e.maxAttributes;++p){var q=d.def(g.attributes,"[",p,"]"),r=a.cond(q,".buffer");r.then(h,".enableVertexAttribArray(",p,");",h,".bindBuffer(",34962,",",q,".buffer.buffer);",
  h,".vertexAttribPointer(",p,",",q,".size,",q,".type,",q,".normalized,",q,".stride,",q,".offset);")["else"](h,".disableVertexAttribArray(",p,");",h,".vertexAttrib4f(",p,",",q,".x,",q,".y,",q,".z,",q,".w);",q,".buffer=null;");d(r);oa&&d(n,".vertexAttribDivisorANGLE(",p,",",q,".divisor);")}d(a.shared.vao,".currentVAO=null;",a.shared.vao,".setVAO(",a.shared.vao,".targetVAO);");Object.keys(qa).forEach(function(c){var e=qa[c],g=f.def(k,".",c),m=a.block();m("if(",g,"){",h,".enable(",e,")}else{",h,".disable(",
  e,")}",l,".",c,"=",g,";");d(m);b("if(",g,"!==",l,".",c,"){",m,"}")});Object.keys(ra).forEach(function(c){var e=ra[c],g=pa[c],m,n,p=a.block();p(h,".",e,"(");ma(g)?(e=g.length,m=a.global.def(k,".",c),n=a.global.def(l,".",c),p(J(e,function(a){return m+"["+a+"]"}),");",J(e,function(a){return n+"["+a+"]="+m+"["+a+"];"}).join("")),b("if(",J(e,function(a){return m+"["+a+"]!=="+n+"["+a+"]"}).join("||"),"){",p,"}")):(m=f.def(k,".",c),n=f.def(l,".",c),p(m,");",l,".",c,"=",m,";"),b("if(",m,"!==",n,"){",p,"}"));
  d(p)});return a.compile()}(),compile:function(a,b,c,d,e){var f=m();f.stats=f.link(e);Object.keys(b["static"]).forEach(function(a){ia(f,b,a)});Xb.forEach(function(b){ia(f,a,b)});var g=la(a,b,c,d,f);Da(f,g);ea(f,g);da(f,g);return A(f.compile(),{destroy:function(){g.shader.program.destroy()}})}}}function Cb(a,b){for(var c=0;c<a.length;++c)if(a[c]===b)return c;return-1}var A=function(a,b){for(var c=Object.keys(b),e=0;e<c.length;++e)a[c[e]]=b[c[e]];return a},Eb=0,Y={DynamicVariable:U,define:function(a,
  b){return new U(a,cb(b+""))},isDynamic:function(a){return"function"===typeof a&&!a._reglType||a instanceof U},unbox:db,accessor:cb},bb={next:"function"===typeof requestAnimationFrame?function(a){return requestAnimationFrame(a)}:function(a){return setTimeout(a,16)},cancel:"function"===typeof cancelAnimationFrame?function(a){return cancelAnimationFrame(a)}:clearTimeout},Db="undefined"!==typeof performance&&performance.now?function(){return performance.now()}:function(){return+new Date},E=hb();E.zero=
  hb();var Yb=function(a,b){var c=1;b.ext_texture_filter_anisotropic&&(c=a.getParameter(34047));var e=1,f=1;b.webgl_draw_buffers&&(e=a.getParameter(34852),f=a.getParameter(36063));var d=!!b.oes_texture_float;if(d){d=a.createTexture();a.bindTexture(3553,d);a.texImage2D(3553,0,6408,1,1,0,6408,5126,null);var p=a.createFramebuffer();a.bindFramebuffer(36160,p);a.framebufferTexture2D(36160,36064,3553,d,0);a.bindTexture(3553,null);if(36053!==a.checkFramebufferStatus(36160))d=!1;else{a.viewport(0,0,1,1);a.clearColor(1,
  0,0,1);a.clear(16384);var n=E.allocType(5126,4);a.readPixels(0,0,1,1,6408,5126,n);a.getError()?d=!1:(a.deleteFramebuffer(p),a.deleteTexture(d),d=1===n[0]);E.freeType(n)}}n=!0;"undefined"!==typeof navigator&&(/MSIE/.test(navigator.userAgent)||/Trident\//.test(navigator.appVersion)||/Edge/.test(navigator.userAgent))||(n=a.createTexture(),p=E.allocType(5121,36),a.activeTexture(33984),a.bindTexture(34067,n),a.texImage2D(34069,0,6408,3,3,0,6408,5121,p),E.freeType(p),a.bindTexture(34067,null),a.deleteTexture(n),
  n=!a.getError());return{colorBits:[a.getParameter(3410),a.getParameter(3411),a.getParameter(3412),a.getParameter(3413)],depthBits:a.getParameter(3414),stencilBits:a.getParameter(3415),subpixelBits:a.getParameter(3408),extensions:Object.keys(b).filter(function(a){return!!b[a]}),maxAnisotropic:c,maxDrawbuffers:e,maxColorAttachments:f,pointSizeDims:a.getParameter(33901),lineWidthDims:a.getParameter(33902),maxViewportDims:a.getParameter(3386),maxCombinedTextureUnits:a.getParameter(35661),maxCubeMapSize:a.getParameter(34076),
  maxRenderbufferSize:a.getParameter(34024),maxTextureUnits:a.getParameter(34930),maxTextureSize:a.getParameter(3379),maxAttributes:a.getParameter(34921),maxVertexUniforms:a.getParameter(36347),maxVertexTextureUnits:a.getParameter(35660),maxVaryingVectors:a.getParameter(36348),maxFragmentUniforms:a.getParameter(36349),glsl:a.getParameter(35724),renderer:a.getParameter(7937),vendor:a.getParameter(7936),version:a.getParameter(7938),readFloat:d,npotTextureCube:n}},M=function(a){return a instanceof Uint8Array||
  a instanceof Uint16Array||a instanceof Uint32Array||a instanceof Int8Array||a instanceof Int16Array||a instanceof Int32Array||a instanceof Float32Array||a instanceof Float64Array||a instanceof Uint8ClampedArray},S=function(a){return Object.keys(a).map(function(b){return a[b]})},Oa={shape:function(a){for(var b=[];a.length;a=a[0])b.push(a.length);return b},flatten:function(a,b,c,e){var f=1;if(b.length)for(var d=0;d<b.length;++d)f*=b[d];else f=0;c=e||E.allocType(c,f);switch(b.length){case 0:break;case 1:e=
  b[0];for(b=0;b<e;++b)c[b]=a[b];break;case 2:e=b[0];b=b[1];for(d=f=0;d<e;++d)for(var p=a[d],n=0;n<b;++n)c[f++]=p[n];break;case 3:ib(a,b[0],b[1],b[2],c,0);break;default:jb(a,b,0,c,0)}return c}},Ga={"[object Int8Array]":5120,"[object Int16Array]":5122,"[object Int32Array]":5124,"[object Uint8Array]":5121,"[object Uint8ClampedArray]":5121,"[object Uint16Array]":5123,"[object Uint32Array]":5125,"[object Float32Array]":5126,"[object Float64Array]":5121,"[object ArrayBuffer]":5121},Ia={int8:5120,int16:5122,
  int32:5124,uint8:5121,uint16:5123,uint32:5125,"float":5126,float32:5126},ob={dynamic:35048,stream:35040,"static":35044},Sa=Oa.flatten,mb=Oa.shape,ha=[];ha[5120]=1;ha[5122]=2;ha[5124]=4;ha[5121]=1;ha[5123]=2;ha[5125]=4;ha[5126]=4;var Ta={points:0,point:0,lines:1,line:1,triangles:4,triangle:4,"line loop":2,"line strip":3,"triangle strip":5,"triangle fan":6},qb=new Float32Array(1),Mb=new Uint32Array(qb.buffer),Qb=[9984,9986,9985,9987],Ma=[0,6409,6410,6407,6408],Q={};Q[6409]=Q[6406]=Q[6402]=1;Q[34041]=
  Q[6410]=2;Q[6407]=Q[35904]=3;Q[6408]=Q[35906]=4;var Wa=na("HTMLCanvasElement"),Xa=na("OffscreenCanvas"),vb=na("CanvasRenderingContext2D"),wb=na("ImageBitmap"),xb=na("HTMLImageElement"),yb=na("HTMLVideoElement"),Nb=Object.keys(Ga).concat([Wa,Xa,vb,wb,xb,yb]),wa=[];wa[5121]=1;wa[5126]=4;wa[36193]=2;wa[5123]=2;wa[5125]=4;var F=[];F[32854]=2;F[32855]=2;F[36194]=2;F[34041]=4;F[33776]=.5;F[33777]=.5;F[33778]=1;F[33779]=1;F[35986]=.5;F[35987]=1;F[34798]=1;F[35840]=.5;F[35841]=.25;F[35842]=.5;F[35843]=.25;
  F[36196]=.5;var T=[];T[32854]=2;T[32855]=2;T[36194]=2;T[33189]=2;T[36168]=1;T[34041]=4;T[35907]=4;T[34836]=16;T[34842]=8;T[34843]=6;var Zb=function(a,b,c,e,f){function d(a){this.id=t++;this.refCount=1;this.renderbuffer=a;this.format=32854;this.height=this.width=0;f.profile&&(this.stats={size:0})}function p(b){var c=b.renderbuffer;a.bindRenderbuffer(36161,null);a.deleteRenderbuffer(c);b.renderbuffer=null;b.refCount=0;delete w[b.id];e.renderbufferCount--}var n={rgba4:32854,rgb565:36194,"rgb5 a1":32855,
  depth:33189,stencil:36168,"depth stencil":34041};b.ext_srgb&&(n.srgba=35907);b.ext_color_buffer_half_float&&(n.rgba16f=34842,n.rgb16f=34843);b.webgl_color_buffer_float&&(n.rgba32f=34836);var u=[];Object.keys(n).forEach(function(a){u[n[a]]=a});var t=0,w={};d.prototype.decRef=function(){0>=--this.refCount&&p(this)};f.profile&&(e.getTotalRenderbufferSize=function(){var a=0;Object.keys(w).forEach(function(b){a+=w[b].stats.size});return a});return{create:function(b,c){function l(b,c){var d=0,e=0,k=32854;
  "object"===typeof b&&b?("shape"in b?(e=b.shape,d=e[0]|0,e=e[1]|0):("radius"in b&&(d=e=b.radius|0),"width"in b&&(d=b.width|0),"height"in b&&(e=b.height|0)),"format"in b&&(k=n[b.format])):"number"===typeof b?(d=b|0,e="number"===typeof c?c|0:d):b||(d=e=1);if(d!==h.width||e!==h.height||k!==h.format)return l.width=h.width=d,l.height=h.height=e,h.format=k,a.bindRenderbuffer(36161,h.renderbuffer),a.renderbufferStorage(36161,k,d,e),f.profile&&(h.stats.size=T[h.format]*h.width*h.height),l.format=u[h.format],
  l}var h=new d(a.createRenderbuffer());w[h.id]=h;e.renderbufferCount++;l(b,c);l.resize=function(b,c){var d=b|0,e=c|0||d;if(d===h.width&&e===h.height)return l;l.width=h.width=d;l.height=h.height=e;a.bindRenderbuffer(36161,h.renderbuffer);a.renderbufferStorage(36161,h.format,d,e);f.profile&&(h.stats.size=T[h.format]*h.width*h.height);return l};l._reglType="renderbuffer";l._renderbuffer=h;f.profile&&(l.stats=h.stats);l.destroy=function(){h.decRef()};return l},clear:function(){S(w).forEach(p)},restore:function(){S(w).forEach(function(b){b.renderbuffer=
  a.createRenderbuffer();a.bindRenderbuffer(36161,b.renderbuffer);a.renderbufferStorage(36161,b.format,b.width,b.height)});a.bindRenderbuffer(36161,null)}}},Ya=[];Ya[6408]=4;Ya[6407]=3;var Pa=[];Pa[5121]=1;Pa[5126]=4;Pa[36193]=2;var Ba=["x","y","z","w"],Xb="blend.func blend.equation stencil.func stencil.opFront stencil.opBack sample.coverage viewport scissor.box polygonOffset.offset".split(" "),Ea={0:0,1:1,zero:0,one:1,"src color":768,"one minus src color":769,"src alpha":770,"one minus src alpha":771,
  "dst color":774,"one minus dst color":775,"dst alpha":772,"one minus dst alpha":773,"constant color":32769,"one minus constant color":32770,"constant alpha":32771,"one minus constant alpha":32772,"src alpha saturate":776},ab={never:512,less:513,"<":513,equal:514,"=":514,"==":514,"===":514,lequal:515,"<=":515,greater:516,">":516,notequal:517,"!=":517,"!==":517,gequal:518,">=":518,always:519},Ra={0:0,zero:0,keep:7680,replace:7681,increment:7682,decrement:7683,"increment wrap":34055,"decrement wrap":34056,
  invert:5386},Ab={cw:2304,ccw:2305},Bb=new K(!1,!1,!1,function(){}),$b=function(a,b){function c(){this.endQueryIndex=this.startQueryIndex=-1;this.sum=0;this.stats=null}function e(a,b,d){var e=p.pop()||new c;e.startQueryIndex=a;e.endQueryIndex=b;e.sum=0;e.stats=d;n.push(e)}if(!b.ext_disjoint_timer_query)return null;var f=[],d=[],p=[],n=[],u=[],t=[];return{beginQuery:function(a){var c=f.pop()||b.ext_disjoint_timer_query.createQueryEXT();b.ext_disjoint_timer_query.beginQueryEXT(35007,c);d.push(c);e(d.length-
  1,d.length,a)},endQuery:function(){b.ext_disjoint_timer_query.endQueryEXT(35007)},pushScopeStats:e,update:function(){var a,c;a=d.length;if(0!==a){t.length=Math.max(t.length,a+1);u.length=Math.max(u.length,a+1);u[0]=0;var e=t[0]=0;for(c=a=0;c<d.length;++c){var l=d[c];b.ext_disjoint_timer_query.getQueryObjectEXT(l,34919)?(e+=b.ext_disjoint_timer_query.getQueryObjectEXT(l,34918),f.push(l)):d[a++]=l;u[c+1]=e;t[c+1]=a}d.length=a;for(c=a=0;c<n.length;++c){var e=n[c],h=e.startQueryIndex,l=e.endQueryIndex;
  e.sum+=u[l]-u[h];h=t[h];l=t[l];l===h?(e.stats.gpuTime+=e.sum/1E6,p.push(e)):(e.startQueryIndex=h,e.endQueryIndex=l,n[a++]=e)}n.length=a}},getNumPendingQueries:function(){return d.length},clear:function(){f.push.apply(f,d);for(var a=0;a<f.length;a++)b.ext_disjoint_timer_query.deleteQueryEXT(f[a]);d.length=0;f.length=0},restore:function(){d.length=0;f.length=0}}};return function(a){function b(){if(0===C.length)z&&z.update(),aa=null;else{aa=bb.next(b);w();for(var a=C.length-1;0<=a;--a){var c=C[a];c&&
  c(G,null,0)}l.flush();z&&z.update()}}function c(){!aa&&0<C.length&&(aa=bb.next(b))}function e(){aa&&(bb.cancel(b),aa=null)}function f(a){a.preventDefault();e();S.forEach(function(a){a()})}function d(a){l.getError();g.restore();D.restore();O.restore();y.restore();L.restore();V.restore();J.restore();z&&z.restore();R.procs.refresh();c();T.forEach(function(a){a()})}function p(a){function b(a,c){var d={},e={};Object.keys(a).forEach(function(b){var f=a[b];if(Y.isDynamic(f))e[b]=Y.unbox(f,b);else{if(c&&
  Array.isArray(f))for(var g=0;g<f.length;++g)if(Y.isDynamic(f[g])){e[b]=Y.unbox(f,b);return}d[b]=f}});return{dynamic:e,"static":d}}function c(a){for(;n.length<a;)n.push(null);return n}var d=b(a.context||{},!0),e=b(a.uniforms||{},!0),f=b(a.attributes||{},!1);a=b(function(a){function b(a){if(a in c){var d=c[a];delete c[a];Object.keys(d).forEach(function(b){c[a+"."+b]=d[b]})}}var c=A({},a);delete c.uniforms;delete c.attributes;delete c.context;delete c.vao;"stencil"in c&&c.stencil.op&&(c.stencil.opBack=
  c.stencil.opFront=c.stencil.op,delete c.stencil.op);b("blend");b("depth");b("cull");b("stencil");b("polygonOffset");b("scissor");b("sample");"vao"in a&&(c.vao=a.vao);return c}(a),!1);var g={gpuTime:0,cpuTime:0,count:0},h=R.compile(a,f,e,d,g),k=h.draw,l=h.batch,m=h.scope,n=[];return A(function(a,b){var d;if("function"===typeof a)return m.call(this,null,a,0);if("function"===typeof b)if("number"===typeof a)for(d=0;d<a;++d)m.call(this,null,b,d);else if(Array.isArray(a))for(d=0;d<a.length;++d)m.call(this,
  a[d],b,d);else return m.call(this,a,b,0);else if("number"===typeof a){if(0<a)return l.call(this,c(a|0),a|0)}else if(Array.isArray(a)){if(a.length)return l.call(this,a,a.length)}else return k.call(this,a)},{stats:g,destroy:function(){h.destroy()}})}function n(a,b){var c=0;R.procs.poll();var d=b.color;d&&(l.clearColor(+d[0]||0,+d[1]||0,+d[2]||0,+d[3]||0),c|=16384);"depth"in b&&(l.clearDepth(+b.depth),c|=256);"stencil"in b&&(l.clearStencil(b.stencil|0),c|=1024);l.clear(c)}function u(a){C.push(a);c();
  return{cancel:function(){function b(){var a=Cb(C,b);C[a]=C[C.length-1];--C.length;0>=C.length&&e()}var c=Cb(C,a);C[c]=b}}}function t(){var a=Q.viewport,b=Q.scissor_box;a[0]=a[1]=b[0]=b[1]=0;G.viewportWidth=G.framebufferWidth=G.drawingBufferWidth=a[2]=b[2]=l.drawingBufferWidth;G.viewportHeight=G.framebufferHeight=G.drawingBufferHeight=a[3]=b[3]=l.drawingBufferHeight}function w(){G.tick+=1;G.time=v();t();R.procs.poll()}function k(){y.refresh();t();R.procs.refresh();z&&z.update()}function v(){return(Db()-
  E)/1E3}a=Ib(a);if(!a)return null;var l=a.gl,h=l.getContextAttributes();l.isContextLost();var g=Jb(l,a);if(!g)return null;var q=Fb(),r={vaoCount:0,bufferCount:0,elementsCount:0,framebufferCount:0,shaderCount:0,textureCount:0,cubeCount:0,renderbufferCount:0,maxTextureUnits:0},m=g.extensions,z=$b(l,m),E=Db(),F=l.drawingBufferWidth,K=l.drawingBufferHeight,G={tick:0,time:0,viewportWidth:F,viewportHeight:K,framebufferWidth:F,framebufferHeight:K,drawingBufferWidth:F,drawingBufferHeight:K,pixelRatio:a.pixelRatio},
  H=Yb(l,m),O=Kb(l,r,a,function(a){return J.destroyBuffer(a)}),J=Sb(l,m,H,r,O),M=Lb(l,m,O,r),D=Tb(l,q,r,a),y=Ob(l,m,H,function(){R.procs.poll()},G,r,a),L=Zb(l,m,H,r,a),V=Rb(l,m,H,y,L,r),R=Wb(l,q,m,H,O,M,y,V,{},J,D,{elements:null,primitive:4,count:-1,offset:0,instances:-1},G,z,a),q=Ub(l,V,R.procs.poll,G,h,m,H),Q=R.next,N=l.canvas,C=[],S=[],T=[],U=[a.onDestroy],aa=null;N&&(N.addEventListener("webglcontextlost",f,!1),N.addEventListener("webglcontextrestored",d,!1));var X=V.setFBO=p({framebuffer:Y.define.call(null,
  1,"framebuffer")});k();h=A(p,{clear:function(a){if("framebuffer"in a)if(a.framebuffer&&"framebufferCube"===a.framebuffer_reglType)for(var b=0;6>b;++b)X(A({framebuffer:a.framebuffer.faces[b]},a),n);else X(a,n);else n(null,a)},prop:Y.define.bind(null,1),context:Y.define.bind(null,2),"this":Y.define.bind(null,3),draw:p({}),buffer:function(a){return O.create(a,34962,!1,!1)},elements:function(a){return M.create(a,!1)},texture:y.create2D,cube:y.createCube,renderbuffer:L.create,framebuffer:V.create,framebufferCube:V.createCube,
  vao:J.createVAO,attributes:h,frame:u,on:function(a,b){var c;switch(a){case "frame":return u(b);case "lost":c=S;break;case "restore":c=T;break;case "destroy":c=U}c.push(b);return{cancel:function(){for(var a=0;a<c.length;++a)if(c[a]===b){c[a]=c[c.length-1];c.pop();break}}}},limits:H,hasExtension:function(a){return 0<=H.extensions.indexOf(a.toLowerCase())},read:q,destroy:function(){C.length=0;e();N&&(N.removeEventListener("webglcontextlost",f),N.removeEventListener("webglcontextrestored",d));D.clear();
  V.clear();L.clear();y.clear();M.clear();O.clear();J.clear();z&&z.clear();U.forEach(function(a){a()})},_gl:l,_refresh:k,poll:function(){w();z&&z.update()},now:v,stats:r});a.onDone(null,h);return h}});
  
  },{}],87:[function(require,module,exports){
  /* global XMLHttpRequest */
  var configParameters = [
    'manifest',
    'onDone',
    'onProgress',
    'onError'
  ]
  
  var manifestParameters = [
    'type',
    'src',
    'stream',
    'credentials',
    'parser'
  ]
  
  var parserParameters = [
    'onData',
    'onDone'
  ]
  
  var STATE_ERROR = -1
  var STATE_DATA = 0
  var STATE_COMPLETE = 1
  
  function raise (message) {
    throw new Error('resl: ' + message)
  }
  
  function checkType (object, parameters, name) {
    Object.keys(object).forEach(function (param) {
      if (parameters.indexOf(param) < 0) {
        raise('invalid parameter "' + param + '" in ' + name)
      }
    })
  }
  
  function Loader (name, cancel) {
    this.state = STATE_DATA
    this.ready = false
    this.progress = 0
    this.name = name
    this.cancel = cancel
  }
  
  module.exports = function resl (config) {
    if (typeof config !== 'object' || !config) {
      raise('invalid or missing configuration')
    }
  
    checkType(config, configParameters, 'config')
  
    var manifest = config.manifest
    if (typeof manifest !== 'object' || !manifest) {
      raise('missing manifest')
    }
  
    function getFunction (name, dflt) {
      if (name in config) {
        var func = config[name]
        if (typeof func !== 'function') {
          raise('invalid callback "' + name + '"')
        }
        return func
      }
      return null
    }
  
    var onDone = getFunction('onDone')
    if (!onDone) {
      raise('missing onDone() callback')
    }
  
    var onProgress = getFunction('onProgress')
    var onError = getFunction('onError')
  
    var assets = {}
  
    var state = STATE_DATA
  
    function loadXHR (request) {
      var name = request.name
      var stream = request.stream
      var binary = request.type === 'binary'
      var parser = request.parser
  
      var xhr = new XMLHttpRequest()
      var asset = null
  
      var loader = new Loader(name, cancel)
  
      if (stream) {
        xhr.onreadystatechange = onReadyStateChange
      } else {
        xhr.onreadystatechange = function () {
          if (xhr.readyState === 4) {
            onReadyStateChange()
          }
        }
      }
  
      if (binary) {
        xhr.responseType = 'arraybuffer'
      }
  
      function onReadyStateChange () {
        if (xhr.readyState < 2 ||
            loader.state === STATE_COMPLETE ||
            loader.state === STATE_ERROR) {
          return
        }
        if (xhr.status !== 200) {
          return abort('error loading resource "' + request.name + '"')
        }
        if (xhr.readyState > 2 && loader.state === STATE_DATA) {
          var response
          if (request.type === 'binary') {
            response = xhr.response
          } else {
            response = xhr.responseText
          }
          if (parser.data) {
            try {
              asset = parser.data(response)
            } catch (e) {
              return abort(e)
            }
          } else {
            asset = response
          }
        }
        if (xhr.readyState > 3 && loader.state === STATE_DATA) {
          if (parser.done) {
            try {
              asset = parser.done()
            } catch (e) {
              return abort(e)
            }
          }
          loader.state = STATE_COMPLETE
        }
        assets[name] = asset
        loader.progress = 0.75 * loader.progress + 0.25
        loader.ready =
          (request.stream && !!asset) ||
          loader.state === STATE_COMPLETE
        notifyProgress()
      }
  
      function cancel () {
        if (loader.state === STATE_COMPLETE || loader.state === STATE_ERROR) {
          return
        }
        xhr.onreadystatechange = null
        xhr.abort()
        loader.state = STATE_ERROR
      }
  
      // set up request
      if (request.credentials) {
        xhr.withCredentials = true
      }
      xhr.open('GET', request.src, true)
      xhr.send()
  
      return loader
    }
  
    function loadElement (request, element) {
      var name = request.name
      var parser = request.parser
  
      var loader = new Loader(name, cancel)
      var asset = element
  
      function handleProgress () {
        if (loader.state === STATE_DATA) {
          if (parser.data) {
            try {
              asset = parser.data(element)
            } catch (e) {
              return abort(e)
            }
          } else {
            asset = element
          }
        }
      }
  
      function onProgress (e) {
        handleProgress()
        assets[name] = asset
        if (e.lengthComputable) {
          loader.progress = Math.max(loader.progress, e.loaded / e.total)
        } else {
          loader.progress = 0.75 * loader.progress + 0.25
        }
        notifyProgress(name)
      }
  
      function onComplete () {
        handleProgress()
        if (loader.state === STATE_DATA) {
          if (parser.done) {
            try {
              asset = parser.done()
            } catch (e) {
              return abort(e)
            }
          }
          loader.state = STATE_COMPLETE
        }
        loader.progress = 1
        loader.ready = true
        assets[name] = asset
        removeListeners()
        notifyProgress('finish ' + name)
      }
  
      function onError () {
        abort('error loading asset "' + name + '"')
      }
  
      if (request.stream) {
        element.addEventListener('progress', onProgress)
      }
      if (request.type === 'image') {
        element.addEventListener('load', onComplete)
      } else {
        var canPlay = false
        var loadedMetaData = false
        element.addEventListener('loadedmetadata', function () {
          loadedMetaData = true
          if (canPlay) {
            onComplete()
          }
        })
        element.addEventListener('canplay', function () {
          canPlay = true
          if (loadedMetaData) {
            onComplete()
          }
        })
      }
      element.addEventListener('error', onError)
  
      function removeListeners () {
        if (request.stream) {
          element.removeEventListener('progress', onProgress)
        }
        if (request.type === 'image') {
          element.addEventListener('load', onComplete)
        } else {
          element.addEventListener('canplay', onComplete)
        }
        element.removeEventListener('error', onError)
      }
  
      function cancel () {
        if (loader.state === STATE_COMPLETE || loader.state === STATE_ERROR) {
          return
        }
        loader.state = STATE_ERROR
        removeListeners()
        element.src = ''
      }
  
      // set up request
      if (request.credentials) {
        element.crossOrigin = 'use-credentials'
      } else {
        element.crossOrigin = 'anonymous'
      }
      element.src = request.src
  
      return loader
    }
  
    var loaders = {
      text: loadXHR,
      binary: function (request) {
        // TODO use fetch API for streaming if supported
        return loadXHR(request)
      },
      image: function (request) {
        return loadElement(request, document.createElement('img'))
      },
      video: function (request) {
        return loadElement(request, document.createElement('video'))
      },
      audio: function (request) {
        return loadElement(request, document.createElement('audio'))
      }
    }
  
    // First we parse all objects in order to verify that all type information
    // is correct
    var pending = Object.keys(manifest).map(function (name) {
      var request = manifest[name]
      if (typeof request === 'string') {
        request = {
          src: request
        }
      } else if (typeof request !== 'object' || !request) {
        raise('invalid asset definition "' + name + '"')
      }
  
      checkType(request, manifestParameters, 'asset "' + name + '"')
  
      function getParameter (prop, accepted, init) {
        var value = init
        if (prop in request) {
          value = request[prop]
        }
        if (accepted.indexOf(value) < 0) {
          raise('invalid ' + prop + ' "' + value + '" for asset "' + name + '", possible values: ' + accepted)
        }
        return value
      }
  
      function getString (prop, required, init) {
        var value = init
        if (prop in request) {
          value = request[prop]
        } else if (required) {
          raise('missing ' + prop + ' for asset "' + name + '"')
        }
        if (typeof value !== 'string') {
          raise('invalid ' + prop + ' for asset "' + name + '", must be a string')
        }
        return value
      }
  
      function getParseFunc (name, dflt) {
        if (name in request.parser) {
          var result = request.parser[name]
          if (typeof result !== 'function') {
            raise('invalid parser callback ' + name + ' for asset "' + name + '"')
          }
          return result
        } else {
          return dflt
        }
      }
  
      var parser = {}
      if ('parser' in request) {
        if (typeof request.parser === 'function') {
          parser = {
            data: request.parser
          }
        } else if (typeof request.parser === 'object' && request.parser) {
          checkType(parser, parserParameters, 'parser for asset "' + name + '"')
          if (!('onData' in parser)) {
            raise('missing onData callback for parser in asset "' + name + '"')
          }
          parser = {
            data: getParseFunc('onData'),
            done: getParseFunc('onDone')
          }
        } else {
          raise('invalid parser for asset "' + name + '"')
        }
      }
  
      return {
        name: name,
        type: getParameter('type', Object.keys(loaders), 'text'),
        stream: !!request.stream,
        credentials: !!request.credentials,
        src: getString('src', true, ''),
        parser: parser
      }
    }).map(function (request) {
      return (loaders[request.type])(request)
    })
  
    function abort (message) {
      if (state === STATE_ERROR || state === STATE_COMPLETE) {
        return
      }
      state = STATE_ERROR
      pending.forEach(function (loader) {
        loader.cancel()
      })
      if (onError) {
        if (typeof message === 'string') {
          onError(new Error('resl: ' + message))
        } else {
          onError(message)
        }
      } else {
        console.error('resl error:', message)
      }
    }
  
    function notifyProgress (message) {
      if (state === STATE_ERROR || state === STATE_COMPLETE) {
        return
      }
  
      var progress = 0
      var numReady = 0
      pending.forEach(function (loader) {
        if (loader.ready) {
          numReady += 1
        }
        progress += loader.progress
      })
  
      if (numReady === pending.length) {
        state = STATE_COMPLETE
        onDone(assets)
      } else {
        if (onProgress) {
          onProgress(progress / pending.length, message)
        }
      }
    }
  
    if (pending.length === 0) {
      setTimeout(function () {
        notifyProgress('done')
      }, 1)
    }
  }
  
  },{}],88:[function(require,module,exports){
  'use strict'
  
  var parseUnit = require('parse-unit')
  
  module.exports = toPX
  
  var PIXELS_PER_INCH = getSizeBrutal('in', document.body) // 96
  
  
  function getPropertyInPX(element, prop) {
    var parts = parseUnit(getComputedStyle(element).getPropertyValue(prop))
    return parts[0] * toPX(parts[1], element)
  }
  
  //This brutal hack is needed
  function getSizeBrutal(unit, element) {
    var testDIV = document.createElement('div')
    testDIV.style['height'] = '128' + unit
    element.appendChild(testDIV)
    var size = getPropertyInPX(testDIV, 'height') / 128
    element.removeChild(testDIV)
    return size
  }
  
  function toPX(str, element) {
    if (!str) return null
  
    element = element || document.body
    str = (str + '' || 'px').trim().toLowerCase()
    if(element === window || element === document) {
      element = document.body
    }
  
    switch(str) {
      case '%':  //Ambiguous, not sure if we should use width or height
        return element.clientHeight / 100.0
      case 'ch':
      case 'ex':
        return getSizeBrutal(str, element)
      case 'em':
        return getPropertyInPX(element, 'font-size')
      case 'rem':
        return getPropertyInPX(document.body, 'font-size')
      case 'vw':
        return window.innerWidth/100
      case 'vh':
        return window.innerHeight/100
      case 'vmin':
        return Math.min(window.innerWidth, window.innerHeight) / 100
      case 'vmax':
        return Math.max(window.innerWidth, window.innerHeight) / 100
      case 'in':
        return PIXELS_PER_INCH
      case 'cm':
        return PIXELS_PER_INCH / 2.54
      case 'mm':
        return PIXELS_PER_INCH / 25.4
      case 'pt':
        return PIXELS_PER_INCH / 72
      case 'pc':
        return PIXELS_PER_INCH / 6
      case 'px':
        return 1
    }
  
    // detect number of units
    var parts = parseUnit(str)
    if (!isNaN(parts[0]) && parts[1]) {
      var px = toPX(parts[1], element)
      return typeof px === 'number' ? parts[0] * px : null
    }
  
    return null
  }
  
  },{"parse-unit":84}],89:[function(require,module,exports){
  module.exports = States
  
  function States (states) {
    var self = this
    if (!(this instanceof States)) return new States(states)
    this.last = null
    this.states = states
    this.stopped = true
    this.value = {}
    var init = Object.keys(states)[0]
    Object.keys(states[init].state).forEach(function (key) {
      ;(function walk (dst, src, key) {
        if (Array.isArray(src[key])) {
          dst[key] = []
          src[key].forEach(function (x,i) {
            walk(dst[key],src[key],i)
          })
        } else if (src[key] && typeof src[key] === 'object') {
          dst[key] = {}
          Object.keys(src[key]).forEach(function (k) {
            walk(dst[key],src[key],k)
          })
        } else {
          dst[key] = 0
        }
      })(self.value, states[init].state, key)
    })
    this.keys = Object.keys(this.value)
    this.sequence = []
    this.index = 0
  }
  
  States.prototype.go = function (sequence) {
    this.sequence = sequence
    this.state = sequence[0]
    this.index = 0
    this.last = null
    this.stopped = false
  }
  
  States.prototype.tick = function (t) {
    if (this.last === null) this.last = t
    if (t - this.last >= this.sequence[this.index+1]) {
      this.last += this.sequence[this.index+1]
      this.index += 2
      this.state = this.sequence[this.index]
    }
    var A = this.states[this.state]
    if (!A) {
      this.stopped = true
      this.last = null
      return this.value
    }
    var B = this.states[this.sequence[this.index+2]]
    if (!B) {
      B = A
      this.last = null
      this.stopped = true
    }
    var x = this.sequence[this.index+1] !== undefined
      ? (t - this.last) / this.sequence[this.index+1]
      : 0
    for (var i = 0; i < this.keys.length; i++) {
      var key = this.keys[i]
      var e = A.easing && typeof A.easing[key] === 'function'
        ? A.easing[key](x)
        : x
      tween(this.value, A.state, B.state, key, e)
    }
    return this.value
  }
  
  function mix (a, b, x) {
    x = Math.max(0,Math.min(1,x))
    return a*(1-x) + b*x
  }
  
  function tween (out, a, b, key, x) {
    if (Array.isArray(out[key])) {
      for (var i = 0; i < out[key].length; i++) {
        tween(out[key], a[key], b[key], i, x)
      }
    } else if (out[key] && typeof out[key] === 'object') {
      out[key] = {}
      var keys = Object.keys(out[key])
      for (var i = 0; i < keys.length; i++) {
        tween(out[key], a[key], b[key], keys[i], x)
      }
    } else {
      out[key] = mix(a[key], b[key], x)
    }
  }
  
  },{}]},{},[2]);
  