All Downloads are FREE. Search and download functionalities are using the official Maven repository.

package.stackgl_modules.index.js Maven / Gradle / Ivy

The newest version!
/******/ (function() { // webpackBootstrap
/******/ 	var __webpack_modules__ = ({

/***/ 1964:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

module.exports = {
  alpha_shape: __webpack_require__(3502),
  convex_hull: __webpack_require__(7352),
  delaunay_triangulate: __webpack_require__(7642),
  gl_cone3d: __webpack_require__(6405),
  gl_error3d: __webpack_require__(9165),
  gl_heatmap2d: __webpack_require__(2510),
  gl_line3d: __webpack_require__(5714),
  gl_mesh3d: __webpack_require__(7201),
  gl_plot2d: __webpack_require__(1850),
  gl_plot3d: __webpack_require__(4100),
  gl_pointcloud2d: __webpack_require__(4696),
  gl_scatter3d: __webpack_require__(8418),
  gl_select_box: __webpack_require__(3161),
  gl_spikes2d: __webpack_require__(4098),
  gl_streamtube3d: __webpack_require__(7815),
  gl_surface3d: __webpack_require__(9499),
  ndarray: __webpack_require__(9618),
  ndarray_linear_interpolate: __webpack_require__(4317)
};

/***/ }),

/***/ 4793:
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {

"use strict";
var __webpack_unused_export__;
/*!
 * The buffer module from node.js, for the browser.
 *
 * @author   Feross Aboukhadijeh 
 * @license  MIT
 */
/* eslint-disable no-proto */



function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); }
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); }
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
var base64 = __webpack_require__(7507);
var ieee754 = __webpack_require__(3778);
var customInspectSymbol = typeof Symbol === 'function' && typeof Symbol['for'] === 'function' // eslint-disable-line dot-notation
? Symbol['for']('nodejs.util.inspect.custom') // eslint-disable-line dot-notation
: null;
exports.hp = Buffer;
__webpack_unused_export__ = SlowBuffer;
exports.IS = 50;
var K_MAX_LENGTH = 0x7fffffff;
__webpack_unused_export__ = K_MAX_LENGTH;

/**
 * If `Buffer.TYPED_ARRAY_SUPPORT`:
 *   === true    Use Uint8Array implementation (fastest)
 *   === false   Print warning and recommend using `buffer` v4.x which has an Object
 *               implementation (most compatible, even IE6)
 *
 * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,
 * Opera 11.6+, iOS 4.2+.
 *
 * We report that the browser does not support typed arrays if the are not subclassable
 * using __proto__. Firefox 4-29 lacks support for adding new properties to `Uint8Array`
 * (See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438). IE 10 lacks support
 * for __proto__ and has a buggy typed array implementation.
 */
Buffer.TYPED_ARRAY_SUPPORT = typedArraySupport();
if (!Buffer.TYPED_ARRAY_SUPPORT && typeof console !== 'undefined' && typeof console.error === 'function') {
  console.error('This browser lacks typed array (Uint8Array) support which is required by ' + '`buffer` v5.x. Use `buffer` v4.x if you require old browser support.');
}
function typedArraySupport() {
  // Can typed array instances can be augmented?
  try {
    var arr = new Uint8Array(1);
    var proto = {
      foo: function foo() {
        return 42;
      }
    };
    Object.setPrototypeOf(proto, Uint8Array.prototype);
    Object.setPrototypeOf(arr, proto);
    return arr.foo() === 42;
  } catch (e) {
    return false;
  }
}
Object.defineProperty(Buffer.prototype, 'parent', {
  enumerable: true,
  get: function get() {
    if (!Buffer.isBuffer(this)) return undefined;
    return this.buffer;
  }
});
Object.defineProperty(Buffer.prototype, 'offset', {
  enumerable: true,
  get: function get() {
    if (!Buffer.isBuffer(this)) return undefined;
    return this.byteOffset;
  }
});
function createBuffer(length) {
  if (length > K_MAX_LENGTH) {
    throw new RangeError('The value "' + length + '" is invalid for option "size"');
  }
  // Return an augmented `Uint8Array` instance
  var buf = new Uint8Array(length);
  Object.setPrototypeOf(buf, Buffer.prototype);
  return buf;
}

/**
 * The Buffer constructor returns instances of `Uint8Array` that have their
 * prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of
 * `Uint8Array`, so the returned instances will have all the node `Buffer` methods
 * and the `Uint8Array` methods. Square bracket notation works as expected -- it
 * returns a single octet.
 *
 * The `Uint8Array` prototype remains unmodified.
 */

function Buffer(arg, encodingOrOffset, length) {
  // Common case.
  if (typeof arg === 'number') {
    if (typeof encodingOrOffset === 'string') {
      throw new TypeError('The "string" argument must be of type string. Received type number');
    }
    return allocUnsafe(arg);
  }
  return from(arg, encodingOrOffset, length);
}
Buffer.poolSize = 8192; // not used by this implementation

function from(value, encodingOrOffset, length) {
  if (typeof value === 'string') {
    return fromString(value, encodingOrOffset);
  }
  if (ArrayBuffer.isView(value)) {
    return fromArrayView(value);
  }
  if (value == null) {
    throw new TypeError('The first argument must be one of type string, Buffer, ArrayBuffer, Array, ' + 'or Array-like Object. Received type ' + _typeof(value));
  }
  if (isInstance(value, ArrayBuffer) || value && isInstance(value.buffer, ArrayBuffer)) {
    return fromArrayBuffer(value, encodingOrOffset, length);
  }
  if (typeof SharedArrayBuffer !== 'undefined' && (isInstance(value, SharedArrayBuffer) || value && isInstance(value.buffer, SharedArrayBuffer))) {
    return fromArrayBuffer(value, encodingOrOffset, length);
  }
  if (typeof value === 'number') {
    throw new TypeError('The "value" argument must not be of type number. Received type number');
  }
  var valueOf = value.valueOf && value.valueOf();
  if (valueOf != null && valueOf !== value) {
    return Buffer.from(valueOf, encodingOrOffset, length);
  }
  var b = fromObject(value);
  if (b) return b;
  if (typeof Symbol !== 'undefined' && Symbol.toPrimitive != null && typeof value[Symbol.toPrimitive] === 'function') {
    return Buffer.from(value[Symbol.toPrimitive]('string'), encodingOrOffset, length);
  }
  throw new TypeError('The first argument must be one of type string, Buffer, ArrayBuffer, Array, ' + 'or Array-like Object. Received type ' + _typeof(value));
}

/**
 * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError
 * if value is a number.
 * Buffer.from(str[, encoding])
 * Buffer.from(array)
 * Buffer.from(buffer)
 * Buffer.from(arrayBuffer[, byteOffset[, length]])
 **/
Buffer.from = function (value, encodingOrOffset, length) {
  return from(value, encodingOrOffset, length);
};

// Note: Change prototype *after* Buffer.from is defined to workaround Chrome bug:
// https://github.com/feross/buffer/pull/148
Object.setPrototypeOf(Buffer.prototype, Uint8Array.prototype);
Object.setPrototypeOf(Buffer, Uint8Array);
function assertSize(size) {
  if (typeof size !== 'number') {
    throw new TypeError('"size" argument must be of type number');
  } else if (size < 0) {
    throw new RangeError('The value "' + size + '" is invalid for option "size"');
  }
}
function alloc(size, fill, encoding) {
  assertSize(size);
  if (size <= 0) {
    return createBuffer(size);
  }
  if (fill !== undefined) {
    // Only pay attention to encoding if it's a string. This
    // prevents accidentally sending in a number that would
    // be interpreted as a start offset.
    return typeof encoding === 'string' ? createBuffer(size).fill(fill, encoding) : createBuffer(size).fill(fill);
  }
  return createBuffer(size);
}

/**
 * Creates a new filled Buffer instance.
 * alloc(size[, fill[, encoding]])
 **/
Buffer.alloc = function (size, fill, encoding) {
  return alloc(size, fill, encoding);
};
function allocUnsafe(size) {
  assertSize(size);
  return createBuffer(size < 0 ? 0 : checked(size) | 0);
}

/**
 * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance.
 * */
Buffer.allocUnsafe = function (size) {
  return allocUnsafe(size);
};
/**
 * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance.
 */
Buffer.allocUnsafeSlow = function (size) {
  return allocUnsafe(size);
};
function fromString(string, encoding) {
  if (typeof encoding !== 'string' || encoding === '') {
    encoding = 'utf8';
  }
  if (!Buffer.isEncoding(encoding)) {
    throw new TypeError('Unknown encoding: ' + encoding);
  }
  var length = byteLength(string, encoding) | 0;
  var buf = createBuffer(length);
  var actual = buf.write(string, encoding);
  if (actual !== length) {
    // Writing a hex string, for example, that contains invalid characters will
    // cause everything after the first invalid character to be ignored. (e.g.
    // 'abxxcd' will be treated as 'ab')
    buf = buf.slice(0, actual);
  }
  return buf;
}
function fromArrayLike(array) {
  var length = array.length < 0 ? 0 : checked(array.length) | 0;
  var buf = createBuffer(length);
  for (var i = 0; i < length; i += 1) {
    buf[i] = array[i] & 255;
  }
  return buf;
}
function fromArrayView(arrayView) {
  if (isInstance(arrayView, Uint8Array)) {
    var copy = new Uint8Array(arrayView);
    return fromArrayBuffer(copy.buffer, copy.byteOffset, copy.byteLength);
  }
  return fromArrayLike(arrayView);
}
function fromArrayBuffer(array, byteOffset, length) {
  if (byteOffset < 0 || array.byteLength < byteOffset) {
    throw new RangeError('"offset" is outside of buffer bounds');
  }
  if (array.byteLength < byteOffset + (length || 0)) {
    throw new RangeError('"length" is outside of buffer bounds');
  }
  var buf;
  if (byteOffset === undefined && length === undefined) {
    buf = new Uint8Array(array);
  } else if (length === undefined) {
    buf = new Uint8Array(array, byteOffset);
  } else {
    buf = new Uint8Array(array, byteOffset, length);
  }

  // Return an augmented `Uint8Array` instance
  Object.setPrototypeOf(buf, Buffer.prototype);
  return buf;
}
function fromObject(obj) {
  if (Buffer.isBuffer(obj)) {
    var len = checked(obj.length) | 0;
    var buf = createBuffer(len);
    if (buf.length === 0) {
      return buf;
    }
    obj.copy(buf, 0, 0, len);
    return buf;
  }
  if (obj.length !== undefined) {
    if (typeof obj.length !== 'number' || numberIsNaN(obj.length)) {
      return createBuffer(0);
    }
    return fromArrayLike(obj);
  }
  if (obj.type === 'Buffer' && Array.isArray(obj.data)) {
    return fromArrayLike(obj.data);
  }
}
function checked(length) {
  // Note: cannot use `length < K_MAX_LENGTH` here because that fails when
  // length is NaN (which is otherwise coerced to zero.)
  if (length >= K_MAX_LENGTH) {
    throw new RangeError('Attempt to allocate Buffer larger than maximum ' + 'size: 0x' + K_MAX_LENGTH.toString(16) + ' bytes');
  }
  return length | 0;
}
function SlowBuffer(length) {
  if (+length != length) {
    // eslint-disable-line eqeqeq
    length = 0;
  }
  return Buffer.alloc(+length);
}
Buffer.isBuffer = function isBuffer(b) {
  return b != null && b._isBuffer === true && b !== Buffer.prototype; // so Buffer.isBuffer(Buffer.prototype) will be false
};
Buffer.compare = function compare(a, b) {
  if (isInstance(a, Uint8Array)) a = Buffer.from(a, a.offset, a.byteLength);
  if (isInstance(b, Uint8Array)) b = Buffer.from(b, b.offset, b.byteLength);
  if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {
    throw new TypeError('The "buf1", "buf2" arguments must be one of type Buffer or Uint8Array');
  }
  if (a === b) return 0;
  var x = a.length;
  var y = b.length;
  for (var i = 0, len = Math.min(x, y); i < len; ++i) {
    if (a[i] !== b[i]) {
      x = a[i];
      y = b[i];
      break;
    }
  }
  if (x < y) return -1;
  if (y < x) return 1;
  return 0;
};
Buffer.isEncoding = function isEncoding(encoding) {
  switch (String(encoding).toLowerCase()) {
    case 'hex':
    case 'utf8':
    case 'utf-8':
    case 'ascii':
    case 'latin1':
    case 'binary':
    case 'base64':
    case 'ucs2':
    case 'ucs-2':
    case 'utf16le':
    case 'utf-16le':
      return true;
    default:
      return false;
  }
};
Buffer.concat = function concat(list, length) {
  if (!Array.isArray(list)) {
    throw new TypeError('"list" argument must be an Array of Buffers');
  }
  if (list.length === 0) {
    return Buffer.alloc(0);
  }
  var i;
  if (length === undefined) {
    length = 0;
    for (i = 0; i < list.length; ++i) {
      length += list[i].length;
    }
  }
  var buffer = Buffer.allocUnsafe(length);
  var pos = 0;
  for (i = 0; i < list.length; ++i) {
    var buf = list[i];
    if (isInstance(buf, Uint8Array)) {
      if (pos + buf.length > buffer.length) {
        if (!Buffer.isBuffer(buf)) buf = Buffer.from(buf);
        buf.copy(buffer, pos);
      } else {
        Uint8Array.prototype.set.call(buffer, buf, pos);
      }
    } else if (!Buffer.isBuffer(buf)) {
      throw new TypeError('"list" argument must be an Array of Buffers');
    } else {
      buf.copy(buffer, pos);
    }
    pos += buf.length;
  }
  return buffer;
};
function byteLength(string, encoding) {
  if (Buffer.isBuffer(string)) {
    return string.length;
  }
  if (ArrayBuffer.isView(string) || isInstance(string, ArrayBuffer)) {
    return string.byteLength;
  }
  if (typeof string !== 'string') {
    throw new TypeError('The "string" argument must be one of type string, Buffer, or ArrayBuffer. ' + 'Received type ' + _typeof(string));
  }
  var len = string.length;
  var mustMatch = arguments.length > 2 && arguments[2] === true;
  if (!mustMatch && len === 0) return 0;

  // Use a for loop to avoid recursion
  var loweredCase = false;
  for (;;) {
    switch (encoding) {
      case 'ascii':
      case 'latin1':
      case 'binary':
        return len;
      case 'utf8':
      case 'utf-8':
        return utf8ToBytes(string).length;
      case 'ucs2':
      case 'ucs-2':
      case 'utf16le':
      case 'utf-16le':
        return len * 2;
      case 'hex':
        return len >>> 1;
      case 'base64':
        return base64ToBytes(string).length;
      default:
        if (loweredCase) {
          return mustMatch ? -1 : utf8ToBytes(string).length; // assume utf8
        }
        encoding = ('' + encoding).toLowerCase();
        loweredCase = true;
    }
  }
}
Buffer.byteLength = byteLength;
function slowToString(encoding, start, end) {
  var loweredCase = false;

  // No need to verify that "this.length <= MAX_UINT32" since it's a read-only
  // property of a typed array.

  // This behaves neither like String nor Uint8Array in that we set start/end
  // to their upper/lower bounds if the value passed is out of range.
  // undefined is handled specially as per ECMA-262 6th Edition,
  // Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization.
  if (start === undefined || start < 0) {
    start = 0;
  }
  // Return early if start > this.length. Done here to prevent potential uint32
  // coercion fail below.
  if (start > this.length) {
    return '';
  }
  if (end === undefined || end > this.length) {
    end = this.length;
  }
  if (end <= 0) {
    return '';
  }

  // Force coercion to uint32. This will also coerce falsey/NaN values to 0.
  end >>>= 0;
  start >>>= 0;
  if (end <= start) {
    return '';
  }
  if (!encoding) encoding = 'utf8';
  while (true) {
    switch (encoding) {
      case 'hex':
        return hexSlice(this, start, end);
      case 'utf8':
      case 'utf-8':
        return utf8Slice(this, start, end);
      case 'ascii':
        return asciiSlice(this, start, end);
      case 'latin1':
      case 'binary':
        return latin1Slice(this, start, end);
      case 'base64':
        return base64Slice(this, start, end);
      case 'ucs2':
      case 'ucs-2':
      case 'utf16le':
      case 'utf-16le':
        return utf16leSlice(this, start, end);
      default:
        if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding);
        encoding = (encoding + '').toLowerCase();
        loweredCase = true;
    }
  }
}

// This property is used by `Buffer.isBuffer` (and the `is-buffer` npm package)
// to detect a Buffer instance. It's not possible to use `instanceof Buffer`
// reliably in a browserify context because there could be multiple different
// copies of the 'buffer' package in use. This method works even for Buffer
// instances that were created from another copy of the `buffer` package.
// See: https://github.com/feross/buffer/issues/154
Buffer.prototype._isBuffer = true;
function swap(b, n, m) {
  var i = b[n];
  b[n] = b[m];
  b[m] = i;
}
Buffer.prototype.swap16 = function swap16() {
  var len = this.length;
  if (len % 2 !== 0) {
    throw new RangeError('Buffer size must be a multiple of 16-bits');
  }
  for (var i = 0; i < len; i += 2) {
    swap(this, i, i + 1);
  }
  return this;
};
Buffer.prototype.swap32 = function swap32() {
  var len = this.length;
  if (len % 4 !== 0) {
    throw new RangeError('Buffer size must be a multiple of 32-bits');
  }
  for (var i = 0; i < len; i += 4) {
    swap(this, i, i + 3);
    swap(this, i + 1, i + 2);
  }
  return this;
};
Buffer.prototype.swap64 = function swap64() {
  var len = this.length;
  if (len % 8 !== 0) {
    throw new RangeError('Buffer size must be a multiple of 64-bits');
  }
  for (var i = 0; i < len; i += 8) {
    swap(this, i, i + 7);
    swap(this, i + 1, i + 6);
    swap(this, i + 2, i + 5);
    swap(this, i + 3, i + 4);
  }
  return this;
};
Buffer.prototype.toString = function toString() {
  var length = this.length;
  if (length === 0) return '';
  if (arguments.length === 0) return utf8Slice(this, 0, length);
  return slowToString.apply(this, arguments);
};
Buffer.prototype.toLocaleString = Buffer.prototype.toString;
Buffer.prototype.equals = function equals(b) {
  if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer');
  if (this === b) return true;
  return Buffer.compare(this, b) === 0;
};
Buffer.prototype.inspect = function inspect() {
  var str = '';
  var max = exports.IS;
  str = this.toString('hex', 0, max).replace(/(.{2})/g, '$1 ').trim();
  if (this.length > max) str += ' ... ';
  return '';
};
if (customInspectSymbol) {
  Buffer.prototype[customInspectSymbol] = Buffer.prototype.inspect;
}
Buffer.prototype.compare = function compare(target, start, end, thisStart, thisEnd) {
  if (isInstance(target, Uint8Array)) {
    target = Buffer.from(target, target.offset, target.byteLength);
  }
  if (!Buffer.isBuffer(target)) {
    throw new TypeError('The "target" argument must be one of type Buffer or Uint8Array. ' + 'Received type ' + _typeof(target));
  }
  if (start === undefined) {
    start = 0;
  }
  if (end === undefined) {
    end = target ? target.length : 0;
  }
  if (thisStart === undefined) {
    thisStart = 0;
  }
  if (thisEnd === undefined) {
    thisEnd = this.length;
  }
  if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) {
    throw new RangeError('out of range index');
  }
  if (thisStart >= thisEnd && start >= end) {
    return 0;
  }
  if (thisStart >= thisEnd) {
    return -1;
  }
  if (start >= end) {
    return 1;
  }
  start >>>= 0;
  end >>>= 0;
  thisStart >>>= 0;
  thisEnd >>>= 0;
  if (this === target) return 0;
  var x = thisEnd - thisStart;
  var y = end - start;
  var len = Math.min(x, y);
  var thisCopy = this.slice(thisStart, thisEnd);
  var targetCopy = target.slice(start, end);
  for (var i = 0; i < len; ++i) {
    if (thisCopy[i] !== targetCopy[i]) {
      x = thisCopy[i];
      y = targetCopy[i];
      break;
    }
  }
  if (x < y) return -1;
  if (y < x) return 1;
  return 0;
};

// Finds either the first index of `val` in `buffer` at offset >= `byteOffset`,
// OR the last index of `val` in `buffer` at offset <= `byteOffset`.
//
// Arguments:
// - buffer - a Buffer to search
// - val - a string, Buffer, or number
// - byteOffset - an index into `buffer`; will be clamped to an int32
// - encoding - an optional encoding, relevant is val is a string
// - dir - true for indexOf, false for lastIndexOf
function bidirectionalIndexOf(buffer, val, byteOffset, encoding, dir) {
  // Empty buffer means no match
  if (buffer.length === 0) return -1;

  // Normalize byteOffset
  if (typeof byteOffset === 'string') {
    encoding = byteOffset;
    byteOffset = 0;
  } else if (byteOffset > 0x7fffffff) {
    byteOffset = 0x7fffffff;
  } else if (byteOffset < -0x80000000) {
    byteOffset = -0x80000000;
  }
  byteOffset = +byteOffset; // Coerce to Number.
  if (numberIsNaN(byteOffset)) {
    // byteOffset: it it's undefined, null, NaN, "foo", etc, search whole buffer
    byteOffset = dir ? 0 : buffer.length - 1;
  }

  // Normalize byteOffset: negative offsets start from the end of the buffer
  if (byteOffset < 0) byteOffset = buffer.length + byteOffset;
  if (byteOffset >= buffer.length) {
    if (dir) return -1;else byteOffset = buffer.length - 1;
  } else if (byteOffset < 0) {
    if (dir) byteOffset = 0;else return -1;
  }

  // Normalize val
  if (typeof val === 'string') {
    val = Buffer.from(val, encoding);
  }

  // Finally, search either indexOf (if dir is true) or lastIndexOf
  if (Buffer.isBuffer(val)) {
    // Special case: looking for empty string/buffer always fails
    if (val.length === 0) {
      return -1;
    }
    return arrayIndexOf(buffer, val, byteOffset, encoding, dir);
  } else if (typeof val === 'number') {
    val = val & 0xFF; // Search for a byte value [0-255]
    if (typeof Uint8Array.prototype.indexOf === 'function') {
      if (dir) {
        return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset);
      } else {
        return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset);
      }
    }
    return arrayIndexOf(buffer, [val], byteOffset, encoding, dir);
  }
  throw new TypeError('val must be string, number or Buffer');
}
function arrayIndexOf(arr, val, byteOffset, encoding, dir) {
  var indexSize = 1;
  var arrLength = arr.length;
  var valLength = val.length;
  if (encoding !== undefined) {
    encoding = String(encoding).toLowerCase();
    if (encoding === 'ucs2' || encoding === 'ucs-2' || encoding === 'utf16le' || encoding === 'utf-16le') {
      if (arr.length < 2 || val.length < 2) {
        return -1;
      }
      indexSize = 2;
      arrLength /= 2;
      valLength /= 2;
      byteOffset /= 2;
    }
  }
  function read(buf, i) {
    if (indexSize === 1) {
      return buf[i];
    } else {
      return buf.readUInt16BE(i * indexSize);
    }
  }
  var i;
  if (dir) {
    var foundIndex = -1;
    for (i = byteOffset; i < arrLength; i++) {
      if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) {
        if (foundIndex === -1) foundIndex = i;
        if (i - foundIndex + 1 === valLength) return foundIndex * indexSize;
      } else {
        if (foundIndex !== -1) i -= i - foundIndex;
        foundIndex = -1;
      }
    }
  } else {
    if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength;
    for (i = byteOffset; i >= 0; i--) {
      var found = true;
      for (var j = 0; j < valLength; j++) {
        if (read(arr, i + j) !== read(val, j)) {
          found = false;
          break;
        }
      }
      if (found) return i;
    }
  }
  return -1;
}
Buffer.prototype.includes = function includes(val, byteOffset, encoding) {
  return this.indexOf(val, byteOffset, encoding) !== -1;
};
Buffer.prototype.indexOf = function indexOf(val, byteOffset, encoding) {
  return bidirectionalIndexOf(this, val, byteOffset, encoding, true);
};
Buffer.prototype.lastIndexOf = function lastIndexOf(val, byteOffset, encoding) {
  return bidirectionalIndexOf(this, val, byteOffset, encoding, false);
};
function hexWrite(buf, string, offset, length) {
  offset = Number(offset) || 0;
  var remaining = buf.length - offset;
  if (!length) {
    length = remaining;
  } else {
    length = Number(length);
    if (length > remaining) {
      length = remaining;
    }
  }
  var strLen = string.length;
  if (length > strLen / 2) {
    length = strLen / 2;
  }
  var i;
  for (i = 0; i < length; ++i) {
    var parsed = parseInt(string.substr(i * 2, 2), 16);
    if (numberIsNaN(parsed)) return i;
    buf[offset + i] = parsed;
  }
  return i;
}
function utf8Write(buf, string, offset, length) {
  return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length);
}
function asciiWrite(buf, string, offset, length) {
  return blitBuffer(asciiToBytes(string), buf, offset, length);
}
function base64Write(buf, string, offset, length) {
  return blitBuffer(base64ToBytes(string), buf, offset, length);
}
function ucs2Write(buf, string, offset, length) {
  return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length);
}
Buffer.prototype.write = function write(string, offset, length, encoding) {
  // Buffer#write(string)
  if (offset === undefined) {
    encoding = 'utf8';
    length = this.length;
    offset = 0;
    // Buffer#write(string, encoding)
  } else if (length === undefined && typeof offset === 'string') {
    encoding = offset;
    length = this.length;
    offset = 0;
    // Buffer#write(string, offset[, length][, encoding])
  } else if (isFinite(offset)) {
    offset = offset >>> 0;
    if (isFinite(length)) {
      length = length >>> 0;
      if (encoding === undefined) encoding = 'utf8';
    } else {
      encoding = length;
      length = undefined;
    }
  } else {
    throw new Error('Buffer.write(string, encoding, offset[, length]) is no longer supported');
  }
  var remaining = this.length - offset;
  if (length === undefined || length > remaining) length = remaining;
  if (string.length > 0 && (length < 0 || offset < 0) || offset > this.length) {
    throw new RangeError('Attempt to write outside buffer bounds');
  }
  if (!encoding) encoding = 'utf8';
  var loweredCase = false;
  for (;;) {
    switch (encoding) {
      case 'hex':
        return hexWrite(this, string, offset, length);
      case 'utf8':
      case 'utf-8':
        return utf8Write(this, string, offset, length);
      case 'ascii':
      case 'latin1':
      case 'binary':
        return asciiWrite(this, string, offset, length);
      case 'base64':
        // Warning: maxLength not taken into account in base64Write
        return base64Write(this, string, offset, length);
      case 'ucs2':
      case 'ucs-2':
      case 'utf16le':
      case 'utf-16le':
        return ucs2Write(this, string, offset, length);
      default:
        if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding);
        encoding = ('' + encoding).toLowerCase();
        loweredCase = true;
    }
  }
};
Buffer.prototype.toJSON = function toJSON() {
  return {
    type: 'Buffer',
    data: Array.prototype.slice.call(this._arr || this, 0)
  };
};
function base64Slice(buf, start, end) {
  if (start === 0 && end === buf.length) {
    return base64.fromByteArray(buf);
  } else {
    return base64.fromByteArray(buf.slice(start, end));
  }
}
function utf8Slice(buf, start, end) {
  end = Math.min(buf.length, end);
  var res = [];
  var i = start;
  while (i < end) {
    var firstByte = buf[i];
    var codePoint = null;
    var bytesPerSequence = firstByte > 0xEF ? 4 : firstByte > 0xDF ? 3 : firstByte > 0xBF ? 2 : 1;
    if (i + bytesPerSequence <= end) {
      var secondByte = void 0,
        thirdByte = void 0,
        fourthByte = void 0,
        tempCodePoint = void 0;
      switch (bytesPerSequence) {
        case 1:
          if (firstByte < 0x80) {
            codePoint = firstByte;
          }
          break;
        case 2:
          secondByte = buf[i + 1];
          if ((secondByte & 0xC0) === 0x80) {
            tempCodePoint = (firstByte & 0x1F) << 0x6 | secondByte & 0x3F;
            if (tempCodePoint > 0x7F) {
              codePoint = tempCodePoint;
            }
          }
          break;
        case 3:
          secondByte = buf[i + 1];
          thirdByte = buf[i + 2];
          if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {
            tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | thirdByte & 0x3F;
            if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {
              codePoint = tempCodePoint;
            }
          }
          break;
        case 4:
          secondByte = buf[i + 1];
          thirdByte = buf[i + 2];
          fourthByte = buf[i + 3];
          if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {
            tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | fourthByte & 0x3F;
            if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {
              codePoint = tempCodePoint;
            }
          }
      }
    }
    if (codePoint === null) {
      // we did not generate a valid codePoint so insert a
      // replacement char (U+FFFD) and advance only 1 byte
      codePoint = 0xFFFD;
      bytesPerSequence = 1;
    } else if (codePoint > 0xFFFF) {
      // encode to utf16 (surrogate pair dance)
      codePoint -= 0x10000;
      res.push(codePoint >>> 10 & 0x3FF | 0xD800);
      codePoint = 0xDC00 | codePoint & 0x3FF;
    }
    res.push(codePoint);
    i += bytesPerSequence;
  }
  return decodeCodePointsArray(res);
}

// Based on http://stackoverflow.com/a/22747272/680742, the browser with
// the lowest limit is Chrome, with 0x10000 args.
// We go 1 magnitude less, for safety
var MAX_ARGUMENTS_LENGTH = 0x1000;
function decodeCodePointsArray(codePoints) {
  var len = codePoints.length;
  if (len <= MAX_ARGUMENTS_LENGTH) {
    return String.fromCharCode.apply(String, codePoints); // avoid extra slice()
  }

  // Decode in chunks to avoid "call stack size exceeded".
  var res = '';
  var i = 0;
  while (i < len) {
    res += String.fromCharCode.apply(String, codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH));
  }
  return res;
}
function asciiSlice(buf, start, end) {
  var ret = '';
  end = Math.min(buf.length, end);
  for (var i = start; i < end; ++i) {
    ret += String.fromCharCode(buf[i] & 0x7F);
  }
  return ret;
}
function latin1Slice(buf, start, end) {
  var ret = '';
  end = Math.min(buf.length, end);
  for (var i = start; i < end; ++i) {
    ret += String.fromCharCode(buf[i]);
  }
  return ret;
}
function hexSlice(buf, start, end) {
  var len = buf.length;
  if (!start || start < 0) start = 0;
  if (!end || end < 0 || end > len) end = len;
  var out = '';
  for (var i = start; i < end; ++i) {
    out += hexSliceLookupTable[buf[i]];
  }
  return out;
}
function utf16leSlice(buf, start, end) {
  var bytes = buf.slice(start, end);
  var res = '';
  // If bytes.length is odd, the last 8 bits must be ignored (same as node.js)
  for (var i = 0; i < bytes.length - 1; i += 2) {
    res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256);
  }
  return res;
}
Buffer.prototype.slice = function slice(start, end) {
  var len = this.length;
  start = ~~start;
  end = end === undefined ? len : ~~end;
  if (start < 0) {
    start += len;
    if (start < 0) start = 0;
  } else if (start > len) {
    start = len;
  }
  if (end < 0) {
    end += len;
    if (end < 0) end = 0;
  } else if (end > len) {
    end = len;
  }
  if (end < start) end = start;
  var newBuf = this.subarray(start, end);
  // Return an augmented `Uint8Array` instance
  Object.setPrototypeOf(newBuf, Buffer.prototype);
  return newBuf;
};

/*
 * Need to make sure that buffer isn't trying to write out of bounds.
 */
function checkOffset(offset, ext, length) {
  if (offset % 1 !== 0 || offset < 0) throw new RangeError('offset is not uint');
  if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length');
}
Buffer.prototype.readUintLE = Buffer.prototype.readUIntLE = function readUIntLE(offset, byteLength, noAssert) {
  offset = offset >>> 0;
  byteLength = byteLength >>> 0;
  if (!noAssert) checkOffset(offset, byteLength, this.length);
  var val = this[offset];
  var mul = 1;
  var i = 0;
  while (++i < byteLength && (mul *= 0x100)) {
    val += this[offset + i] * mul;
  }
  return val;
};
Buffer.prototype.readUintBE = Buffer.prototype.readUIntBE = function readUIntBE(offset, byteLength, noAssert) {
  offset = offset >>> 0;
  byteLength = byteLength >>> 0;
  if (!noAssert) {
    checkOffset(offset, byteLength, this.length);
  }
  var val = this[offset + --byteLength];
  var mul = 1;
  while (byteLength > 0 && (mul *= 0x100)) {
    val += this[offset + --byteLength] * mul;
  }
  return val;
};
Buffer.prototype.readUint8 = Buffer.prototype.readUInt8 = function readUInt8(offset, noAssert) {
  offset = offset >>> 0;
  if (!noAssert) checkOffset(offset, 1, this.length);
  return this[offset];
};
Buffer.prototype.readUint16LE = Buffer.prototype.readUInt16LE = function readUInt16LE(offset, noAssert) {
  offset = offset >>> 0;
  if (!noAssert) checkOffset(offset, 2, this.length);
  return this[offset] | this[offset + 1] << 8;
};
Buffer.prototype.readUint16BE = Buffer.prototype.readUInt16BE = function readUInt16BE(offset, noAssert) {
  offset = offset >>> 0;
  if (!noAssert) checkOffset(offset, 2, this.length);
  return this[offset] << 8 | this[offset + 1];
};
Buffer.prototype.readUint32LE = Buffer.prototype.readUInt32LE = function readUInt32LE(offset, noAssert) {
  offset = offset >>> 0;
  if (!noAssert) checkOffset(offset, 4, this.length);
  return (this[offset] | this[offset + 1] << 8 | this[offset + 2] << 16) + this[offset + 3] * 0x1000000;
};
Buffer.prototype.readUint32BE = Buffer.prototype.readUInt32BE = function readUInt32BE(offset, noAssert) {
  offset = offset >>> 0;
  if (!noAssert) checkOffset(offset, 4, this.length);
  return this[offset] * 0x1000000 + (this[offset + 1] << 16 | this[offset + 2] << 8 | this[offset + 3]);
};
Buffer.prototype.readBigUInt64LE = defineBigIntMethod(function readBigUInt64LE(offset) {
  offset = offset >>> 0;
  validateNumber(offset, 'offset');
  var first = this[offset];
  var last = this[offset + 7];
  if (first === undefined || last === undefined) {
    boundsError(offset, this.length - 8);
  }
  var lo = first + this[++offset] * Math.pow(2, 8) + this[++offset] * Math.pow(2, 16) + this[++offset] * Math.pow(2, 24);
  var hi = this[++offset] + this[++offset] * Math.pow(2, 8) + this[++offset] * Math.pow(2, 16) + last * Math.pow(2, 24);
  return BigInt(lo) + (BigInt(hi) << BigInt(32));
});
Buffer.prototype.readBigUInt64BE = defineBigIntMethod(function readBigUInt64BE(offset) {
  offset = offset >>> 0;
  validateNumber(offset, 'offset');
  var first = this[offset];
  var last = this[offset + 7];
  if (first === undefined || last === undefined) {
    boundsError(offset, this.length - 8);
  }
  var hi = first * Math.pow(2, 24) + this[++offset] * Math.pow(2, 16) + this[++offset] * Math.pow(2, 8) + this[++offset];
  var lo = this[++offset] * Math.pow(2, 24) + this[++offset] * Math.pow(2, 16) + this[++offset] * Math.pow(2, 8) + last;
  return (BigInt(hi) << BigInt(32)) + BigInt(lo);
});
Buffer.prototype.readIntLE = function readIntLE(offset, byteLength, noAssert) {
  offset = offset >>> 0;
  byteLength = byteLength >>> 0;
  if (!noAssert) checkOffset(offset, byteLength, this.length);
  var val = this[offset];
  var mul = 1;
  var i = 0;
  while (++i < byteLength && (mul *= 0x100)) {
    val += this[offset + i] * mul;
  }
  mul *= 0x80;
  if (val >= mul) val -= Math.pow(2, 8 * byteLength);
  return val;
};
Buffer.prototype.readIntBE = function readIntBE(offset, byteLength, noAssert) {
  offset = offset >>> 0;
  byteLength = byteLength >>> 0;
  if (!noAssert) checkOffset(offset, byteLength, this.length);
  var i = byteLength;
  var mul = 1;
  var val = this[offset + --i];
  while (i > 0 && (mul *= 0x100)) {
    val += this[offset + --i] * mul;
  }
  mul *= 0x80;
  if (val >= mul) val -= Math.pow(2, 8 * byteLength);
  return val;
};
Buffer.prototype.readInt8 = function readInt8(offset, noAssert) {
  offset = offset >>> 0;
  if (!noAssert) checkOffset(offset, 1, this.length);
  if (!(this[offset] & 0x80)) return this[offset];
  return (0xff - this[offset] + 1) * -1;
};
Buffer.prototype.readInt16LE = function readInt16LE(offset, noAssert) {
  offset = offset >>> 0;
  if (!noAssert) checkOffset(offset, 2, this.length);
  var val = this[offset] | this[offset + 1] << 8;
  return val & 0x8000 ? val | 0xFFFF0000 : val;
};
Buffer.prototype.readInt16BE = function readInt16BE(offset, noAssert) {
  offset = offset >>> 0;
  if (!noAssert) checkOffset(offset, 2, this.length);
  var val = this[offset + 1] | this[offset] << 8;
  return val & 0x8000 ? val | 0xFFFF0000 : val;
};
Buffer.prototype.readInt32LE = function readInt32LE(offset, noAssert) {
  offset = offset >>> 0;
  if (!noAssert) checkOffset(offset, 4, this.length);
  return this[offset] | this[offset + 1] << 8 | this[offset + 2] << 16 | this[offset + 3] << 24;
};
Buffer.prototype.readInt32BE = function readInt32BE(offset, noAssert) {
  offset = offset >>> 0;
  if (!noAssert) checkOffset(offset, 4, this.length);
  return this[offset] << 24 | this[offset + 1] << 16 | this[offset + 2] << 8 | this[offset + 3];
};
Buffer.prototype.readBigInt64LE = defineBigIntMethod(function readBigInt64LE(offset) {
  offset = offset >>> 0;
  validateNumber(offset, 'offset');
  var first = this[offset];
  var last = this[offset + 7];
  if (first === undefined || last === undefined) {
    boundsError(offset, this.length - 8);
  }
  var val = this[offset + 4] + this[offset + 5] * Math.pow(2, 8) + this[offset + 6] * Math.pow(2, 16) + (last << 24); // Overflow

  return (BigInt(val) << BigInt(32)) + BigInt(first + this[++offset] * Math.pow(2, 8) + this[++offset] * Math.pow(2, 16) + this[++offset] * Math.pow(2, 24));
});
Buffer.prototype.readBigInt64BE = defineBigIntMethod(function readBigInt64BE(offset) {
  offset = offset >>> 0;
  validateNumber(offset, 'offset');
  var first = this[offset];
  var last = this[offset + 7];
  if (first === undefined || last === undefined) {
    boundsError(offset, this.length - 8);
  }
  var val = (first << 24) +
  // Overflow
  this[++offset] * Math.pow(2, 16) + this[++offset] * Math.pow(2, 8) + this[++offset];
  return (BigInt(val) << BigInt(32)) + BigInt(this[++offset] * Math.pow(2, 24) + this[++offset] * Math.pow(2, 16) + this[++offset] * Math.pow(2, 8) + last);
});
Buffer.prototype.readFloatLE = function readFloatLE(offset, noAssert) {
  offset = offset >>> 0;
  if (!noAssert) checkOffset(offset, 4, this.length);
  return ieee754.read(this, offset, true, 23, 4);
};
Buffer.prototype.readFloatBE = function readFloatBE(offset, noAssert) {
  offset = offset >>> 0;
  if (!noAssert) checkOffset(offset, 4, this.length);
  return ieee754.read(this, offset, false, 23, 4);
};
Buffer.prototype.readDoubleLE = function readDoubleLE(offset, noAssert) {
  offset = offset >>> 0;
  if (!noAssert) checkOffset(offset, 8, this.length);
  return ieee754.read(this, offset, true, 52, 8);
};
Buffer.prototype.readDoubleBE = function readDoubleBE(offset, noAssert) {
  offset = offset >>> 0;
  if (!noAssert) checkOffset(offset, 8, this.length);
  return ieee754.read(this, offset, false, 52, 8);
};
function checkInt(buf, value, offset, ext, max, min) {
  if (!Buffer.isBuffer(buf)) throw new TypeError('"buffer" argument must be a Buffer instance');
  if (value > max || value < min) throw new RangeError('"value" argument is out of bounds');
  if (offset + ext > buf.length) throw new RangeError('Index out of range');
}
Buffer.prototype.writeUintLE = Buffer.prototype.writeUIntLE = function writeUIntLE(value, offset, byteLength, noAssert) {
  value = +value;
  offset = offset >>> 0;
  byteLength = byteLength >>> 0;
  if (!noAssert) {
    var maxBytes = Math.pow(2, 8 * byteLength) - 1;
    checkInt(this, value, offset, byteLength, maxBytes, 0);
  }
  var mul = 1;
  var i = 0;
  this[offset] = value & 0xFF;
  while (++i < byteLength && (mul *= 0x100)) {
    this[offset + i] = value / mul & 0xFF;
  }
  return offset + byteLength;
};
Buffer.prototype.writeUintBE = Buffer.prototype.writeUIntBE = function writeUIntBE(value, offset, byteLength, noAssert) {
  value = +value;
  offset = offset >>> 0;
  byteLength = byteLength >>> 0;
  if (!noAssert) {
    var maxBytes = Math.pow(2, 8 * byteLength) - 1;
    checkInt(this, value, offset, byteLength, maxBytes, 0);
  }
  var i = byteLength - 1;
  var mul = 1;
  this[offset + i] = value & 0xFF;
  while (--i >= 0 && (mul *= 0x100)) {
    this[offset + i] = value / mul & 0xFF;
  }
  return offset + byteLength;
};
Buffer.prototype.writeUint8 = Buffer.prototype.writeUInt8 = function writeUInt8(value, offset, noAssert) {
  value = +value;
  offset = offset >>> 0;
  if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0);
  this[offset] = value & 0xff;
  return offset + 1;
};
Buffer.prototype.writeUint16LE = Buffer.prototype.writeUInt16LE = function writeUInt16LE(value, offset, noAssert) {
  value = +value;
  offset = offset >>> 0;
  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0);
  this[offset] = value & 0xff;
  this[offset + 1] = value >>> 8;
  return offset + 2;
};
Buffer.prototype.writeUint16BE = Buffer.prototype.writeUInt16BE = function writeUInt16BE(value, offset, noAssert) {
  value = +value;
  offset = offset >>> 0;
  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0);
  this[offset] = value >>> 8;
  this[offset + 1] = value & 0xff;
  return offset + 2;
};
Buffer.prototype.writeUint32LE = Buffer.prototype.writeUInt32LE = function writeUInt32LE(value, offset, noAssert) {
  value = +value;
  offset = offset >>> 0;
  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0);
  this[offset + 3] = value >>> 24;
  this[offset + 2] = value >>> 16;
  this[offset + 1] = value >>> 8;
  this[offset] = value & 0xff;
  return offset + 4;
};
Buffer.prototype.writeUint32BE = Buffer.prototype.writeUInt32BE = function writeUInt32BE(value, offset, noAssert) {
  value = +value;
  offset = offset >>> 0;
  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0);
  this[offset] = value >>> 24;
  this[offset + 1] = value >>> 16;
  this[offset + 2] = value >>> 8;
  this[offset + 3] = value & 0xff;
  return offset + 4;
};
function wrtBigUInt64LE(buf, value, offset, min, max) {
  checkIntBI(value, min, max, buf, offset, 7);
  var lo = Number(value & BigInt(0xffffffff));
  buf[offset++] = lo;
  lo = lo >> 8;
  buf[offset++] = lo;
  lo = lo >> 8;
  buf[offset++] = lo;
  lo = lo >> 8;
  buf[offset++] = lo;
  var hi = Number(value >> BigInt(32) & BigInt(0xffffffff));
  buf[offset++] = hi;
  hi = hi >> 8;
  buf[offset++] = hi;
  hi = hi >> 8;
  buf[offset++] = hi;
  hi = hi >> 8;
  buf[offset++] = hi;
  return offset;
}
function wrtBigUInt64BE(buf, value, offset, min, max) {
  checkIntBI(value, min, max, buf, offset, 7);
  var lo = Number(value & BigInt(0xffffffff));
  buf[offset + 7] = lo;
  lo = lo >> 8;
  buf[offset + 6] = lo;
  lo = lo >> 8;
  buf[offset + 5] = lo;
  lo = lo >> 8;
  buf[offset + 4] = lo;
  var hi = Number(value >> BigInt(32) & BigInt(0xffffffff));
  buf[offset + 3] = hi;
  hi = hi >> 8;
  buf[offset + 2] = hi;
  hi = hi >> 8;
  buf[offset + 1] = hi;
  hi = hi >> 8;
  buf[offset] = hi;
  return offset + 8;
}
Buffer.prototype.writeBigUInt64LE = defineBigIntMethod(function writeBigUInt64LE(value) {
  var offset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
  return wrtBigUInt64LE(this, value, offset, BigInt(0), BigInt('0xffffffffffffffff'));
});
Buffer.prototype.writeBigUInt64BE = defineBigIntMethod(function writeBigUInt64BE(value) {
  var offset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
  return wrtBigUInt64BE(this, value, offset, BigInt(0), BigInt('0xffffffffffffffff'));
});
Buffer.prototype.writeIntLE = function writeIntLE(value, offset, byteLength, noAssert) {
  value = +value;
  offset = offset >>> 0;
  if (!noAssert) {
    var limit = Math.pow(2, 8 * byteLength - 1);
    checkInt(this, value, offset, byteLength, limit - 1, -limit);
  }
  var i = 0;
  var mul = 1;
  var sub = 0;
  this[offset] = value & 0xFF;
  while (++i < byteLength && (mul *= 0x100)) {
    if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) {
      sub = 1;
    }
    this[offset + i] = (value / mul >> 0) - sub & 0xFF;
  }
  return offset + byteLength;
};
Buffer.prototype.writeIntBE = function writeIntBE(value, offset, byteLength, noAssert) {
  value = +value;
  offset = offset >>> 0;
  if (!noAssert) {
    var limit = Math.pow(2, 8 * byteLength - 1);
    checkInt(this, value, offset, byteLength, limit - 1, -limit);
  }
  var i = byteLength - 1;
  var mul = 1;
  var sub = 0;
  this[offset + i] = value & 0xFF;
  while (--i >= 0 && (mul *= 0x100)) {
    if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) {
      sub = 1;
    }
    this[offset + i] = (value / mul >> 0) - sub & 0xFF;
  }
  return offset + byteLength;
};
Buffer.prototype.writeInt8 = function writeInt8(value, offset, noAssert) {
  value = +value;
  offset = offset >>> 0;
  if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80);
  if (value < 0) value = 0xff + value + 1;
  this[offset] = value & 0xff;
  return offset + 1;
};
Buffer.prototype.writeInt16LE = function writeInt16LE(value, offset, noAssert) {
  value = +value;
  offset = offset >>> 0;
  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000);
  this[offset] = value & 0xff;
  this[offset + 1] = value >>> 8;
  return offset + 2;
};
Buffer.prototype.writeInt16BE = function writeInt16BE(value, offset, noAssert) {
  value = +value;
  offset = offset >>> 0;
  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000);
  this[offset] = value >>> 8;
  this[offset + 1] = value & 0xff;
  return offset + 2;
};
Buffer.prototype.writeInt32LE = function writeInt32LE(value, offset, noAssert) {
  value = +value;
  offset = offset >>> 0;
  if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000);
  this[offset] = value & 0xff;
  this[offset + 1] = value >>> 8;
  this[offset + 2] = value >>> 16;
  this[offset + 3] = value >>> 24;
  return offset + 4;
};
Buffer.prototype.writeInt32BE = function writeInt32BE(value, offset, noAssert) {
  value = +value;
  offset = offset >>> 0;
  if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000);
  if (value < 0) value = 0xffffffff + value + 1;
  this[offset] = value >>> 24;
  this[offset + 1] = value >>> 16;
  this[offset + 2] = value >>> 8;
  this[offset + 3] = value & 0xff;
  return offset + 4;
};
Buffer.prototype.writeBigInt64LE = defineBigIntMethod(function writeBigInt64LE(value) {
  var offset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
  return wrtBigUInt64LE(this, value, offset, -BigInt('0x8000000000000000'), BigInt('0x7fffffffffffffff'));
});
Buffer.prototype.writeBigInt64BE = defineBigIntMethod(function writeBigInt64BE(value) {
  var offset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
  return wrtBigUInt64BE(this, value, offset, -BigInt('0x8000000000000000'), BigInt('0x7fffffffffffffff'));
});
function checkIEEE754(buf, value, offset, ext, max, min) {
  if (offset + ext > buf.length) throw new RangeError('Index out of range');
  if (offset < 0) throw new RangeError('Index out of range');
}
function writeFloat(buf, value, offset, littleEndian, noAssert) {
  value = +value;
  offset = offset >>> 0;
  if (!noAssert) {
    checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38);
  }
  ieee754.write(buf, value, offset, littleEndian, 23, 4);
  return offset + 4;
}
Buffer.prototype.writeFloatLE = function writeFloatLE(value, offset, noAssert) {
  return writeFloat(this, value, offset, true, noAssert);
};
Buffer.prototype.writeFloatBE = function writeFloatBE(value, offset, noAssert) {
  return writeFloat(this, value, offset, false, noAssert);
};
function writeDouble(buf, value, offset, littleEndian, noAssert) {
  value = +value;
  offset = offset >>> 0;
  if (!noAssert) {
    checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308);
  }
  ieee754.write(buf, value, offset, littleEndian, 52, 8);
  return offset + 8;
}
Buffer.prototype.writeDoubleLE = function writeDoubleLE(value, offset, noAssert) {
  return writeDouble(this, value, offset, true, noAssert);
};
Buffer.prototype.writeDoubleBE = function writeDoubleBE(value, offset, noAssert) {
  return writeDouble(this, value, offset, false, noAssert);
};

// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)
Buffer.prototype.copy = function copy(target, targetStart, start, end) {
  if (!Buffer.isBuffer(target)) throw new TypeError('argument should be a Buffer');
  if (!start) start = 0;
  if (!end && end !== 0) end = this.length;
  if (targetStart >= target.length) targetStart = target.length;
  if (!targetStart) targetStart = 0;
  if (end > 0 && end < start) end = start;

  // Copy 0 bytes; we're done
  if (end === start) return 0;
  if (target.length === 0 || this.length === 0) return 0;

  // Fatal error conditions
  if (targetStart < 0) {
    throw new RangeError('targetStart out of bounds');
  }
  if (start < 0 || start >= this.length) throw new RangeError('Index out of range');
  if (end < 0) throw new RangeError('sourceEnd out of bounds');

  // Are we oob?
  if (end > this.length) end = this.length;
  if (target.length - targetStart < end - start) {
    end = target.length - targetStart + start;
  }
  var len = end - start;
  if (this === target && typeof Uint8Array.prototype.copyWithin === 'function') {
    // Use built-in when available, missing from IE11
    this.copyWithin(targetStart, start, end);
  } else {
    Uint8Array.prototype.set.call(target, this.subarray(start, end), targetStart);
  }
  return len;
};

// Usage:
//    buffer.fill(number[, offset[, end]])
//    buffer.fill(buffer[, offset[, end]])
//    buffer.fill(string[, offset[, end]][, encoding])
Buffer.prototype.fill = function fill(val, start, end, encoding) {
  // Handle string cases:
  if (typeof val === 'string') {
    if (typeof start === 'string') {
      encoding = start;
      start = 0;
      end = this.length;
    } else if (typeof end === 'string') {
      encoding = end;
      end = this.length;
    }
    if (encoding !== undefined && typeof encoding !== 'string') {
      throw new TypeError('encoding must be a string');
    }
    if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) {
      throw new TypeError('Unknown encoding: ' + encoding);
    }
    if (val.length === 1) {
      var code = val.charCodeAt(0);
      if (encoding === 'utf8' && code < 128 || encoding === 'latin1') {
        // Fast path: If `val` fits into a single byte, use that numeric value.
        val = code;
      }
    }
  } else if (typeof val === 'number') {
    val = val & 255;
  } else if (typeof val === 'boolean') {
    val = Number(val);
  }

  // Invalid ranges are not set to a default, so can range check early.
  if (start < 0 || this.length < start || this.length < end) {
    throw new RangeError('Out of range index');
  }
  if (end <= start) {
    return this;
  }
  start = start >>> 0;
  end = end === undefined ? this.length : end >>> 0;
  if (!val) val = 0;
  var i;
  if (typeof val === 'number') {
    for (i = start; i < end; ++i) {
      this[i] = val;
    }
  } else {
    var bytes = Buffer.isBuffer(val) ? val : Buffer.from(val, encoding);
    var len = bytes.length;
    if (len === 0) {
      throw new TypeError('The value "' + val + '" is invalid for argument "value"');
    }
    for (i = 0; i < end - start; ++i) {
      this[i + start] = bytes[i % len];
    }
  }
  return this;
};

// CUSTOM ERRORS
// =============

// Simplified versions from Node, changed for Buffer-only usage
var errors = {};
function E(sym, getMessage, Base) {
  errors[sym] = /*#__PURE__*/function (_Base) {
    function NodeError() {
      var _this;
      _classCallCheck(this, NodeError);
      _this = _callSuper(this, NodeError);
      Object.defineProperty(_this, 'message', {
        value: getMessage.apply(_this, arguments),
        writable: true,
        configurable: true
      });

      // Add the error code to the name to include it in the stack trace.
      _this.name = "".concat(_this.name, " [").concat(sym, "]");
      // Access the stack to generate the error message including the error code
      // from the name.
      _this.stack; // eslint-disable-line no-unused-expressions
      // Reset the name to the actual name.
      delete _this.name;
      return _this;
    }
    _inherits(NodeError, _Base);
    return _createClass(NodeError, [{
      key: "code",
      get: function get() {
        return sym;
      },
      set: function set(value) {
        Object.defineProperty(this, 'code', {
          configurable: true,
          enumerable: true,
          value: value,
          writable: true
        });
      }
    }, {
      key: "toString",
      value: function toString() {
        return "".concat(this.name, " [").concat(sym, "]: ").concat(this.message);
      }
    }]);
  }(Base);
}
E('ERR_BUFFER_OUT_OF_BOUNDS', function (name) {
  if (name) {
    return "".concat(name, " is outside of buffer bounds");
  }
  return 'Attempt to access memory outside buffer bounds';
}, RangeError);
E('ERR_INVALID_ARG_TYPE', function (name, actual) {
  return "The \"".concat(name, "\" argument must be of type number. Received type ").concat(_typeof(actual));
}, TypeError);
E('ERR_OUT_OF_RANGE', function (str, range, input) {
  var msg = "The value of \"".concat(str, "\" is out of range.");
  var received = input;
  if (Number.isInteger(input) && Math.abs(input) > Math.pow(2, 32)) {
    received = addNumericalSeparator(String(input));
  } else if (typeof input === 'bigint') {
    received = String(input);
    if (input > Math.pow(BigInt(2), BigInt(32)) || input < -Math.pow(BigInt(2), BigInt(32))) {
      received = addNumericalSeparator(received);
    }
    received += 'n';
  }
  msg += " It must be ".concat(range, ". Received ").concat(received);
  return msg;
}, RangeError);
function addNumericalSeparator(val) {
  var res = '';
  var i = val.length;
  var start = val[0] === '-' ? 1 : 0;
  for (; i >= start + 4; i -= 3) {
    res = "_".concat(val.slice(i - 3, i)).concat(res);
  }
  return "".concat(val.slice(0, i)).concat(res);
}

// CHECK FUNCTIONS
// ===============

function checkBounds(buf, offset, byteLength) {
  validateNumber(offset, 'offset');
  if (buf[offset] === undefined || buf[offset + byteLength] === undefined) {
    boundsError(offset, buf.length - (byteLength + 1));
  }
}
function checkIntBI(value, min, max, buf, offset, byteLength) {
  if (value > max || value < min) {
    var n = typeof min === 'bigint' ? 'n' : '';
    var range;
    if (byteLength > 3) {
      if (min === 0 || min === BigInt(0)) {
        range = ">= 0".concat(n, " and < 2").concat(n, " ** ").concat((byteLength + 1) * 8).concat(n);
      } else {
        range = ">= -(2".concat(n, " ** ").concat((byteLength + 1) * 8 - 1).concat(n, ") and < 2 ** ") + "".concat((byteLength + 1) * 8 - 1).concat(n);
      }
    } else {
      range = ">= ".concat(min).concat(n, " and <= ").concat(max).concat(n);
    }
    throw new errors.ERR_OUT_OF_RANGE('value', range, value);
  }
  checkBounds(buf, offset, byteLength);
}
function validateNumber(value, name) {
  if (typeof value !== 'number') {
    throw new errors.ERR_INVALID_ARG_TYPE(name, 'number', value);
  }
}
function boundsError(value, length, type) {
  if (Math.floor(value) !== value) {
    validateNumber(value, type);
    throw new errors.ERR_OUT_OF_RANGE(type || 'offset', 'an integer', value);
  }
  if (length < 0) {
    throw new errors.ERR_BUFFER_OUT_OF_BOUNDS();
  }
  throw new errors.ERR_OUT_OF_RANGE(type || 'offset', ">= ".concat(type ? 1 : 0, " and <= ").concat(length), value);
}

// HELPER FUNCTIONS
// ================

var INVALID_BASE64_RE = /[^+/0-9A-Za-z-_]/g;
function base64clean(str) {
  // Node takes equal signs as end of the Base64 encoding
  str = str.split('=')[0];
  // Node strips out invalid characters like \n and \t from the string, base64-js does not
  str = str.trim().replace(INVALID_BASE64_RE, '');
  // Node converts strings with length < 2 to ''
  if (str.length < 2) return '';
  // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not
  while (str.length % 4 !== 0) {
    str = str + '=';
  }
  return str;
}
function utf8ToBytes(string, units) {
  units = units || Infinity;
  var codePoint;
  var length = string.length;
  var leadSurrogate = null;
  var bytes = [];
  for (var i = 0; i < length; ++i) {
    codePoint = string.charCodeAt(i);

    // is surrogate component
    if (codePoint > 0xD7FF && codePoint < 0xE000) {
      // last char was a lead
      if (!leadSurrogate) {
        // no lead yet
        if (codePoint > 0xDBFF) {
          // unexpected trail
          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD);
          continue;
        } else if (i + 1 === length) {
          // unpaired lead
          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD);
          continue;
        }

        // valid lead
        leadSurrogate = codePoint;
        continue;
      }

      // 2 leads in a row
      if (codePoint < 0xDC00) {
        if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD);
        leadSurrogate = codePoint;
        continue;
      }

      // valid surrogate pair
      codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000;
    } else if (leadSurrogate) {
      // valid bmp char, but last char was a lead
      if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD);
    }
    leadSurrogate = null;

    // encode utf8
    if (codePoint < 0x80) {
      if ((units -= 1) < 0) break;
      bytes.push(codePoint);
    } else if (codePoint < 0x800) {
      if ((units -= 2) < 0) break;
      bytes.push(codePoint >> 0x6 | 0xC0, codePoint & 0x3F | 0x80);
    } else if (codePoint < 0x10000) {
      if ((units -= 3) < 0) break;
      bytes.push(codePoint >> 0xC | 0xE0, codePoint >> 0x6 & 0x3F | 0x80, codePoint & 0x3F | 0x80);
    } else if (codePoint < 0x110000) {
      if ((units -= 4) < 0) break;
      bytes.push(codePoint >> 0x12 | 0xF0, codePoint >> 0xC & 0x3F | 0x80, codePoint >> 0x6 & 0x3F | 0x80, codePoint & 0x3F | 0x80);
    } else {
      throw new Error('Invalid code point');
    }
  }
  return bytes;
}
function asciiToBytes(str) {
  var byteArray = [];
  for (var i = 0; i < str.length; ++i) {
    // Node's code seems to be doing this and not & 0x7F..
    byteArray.push(str.charCodeAt(i) & 0xFF);
  }
  return byteArray;
}
function utf16leToBytes(str, units) {
  var c, hi, lo;
  var byteArray = [];
  for (var i = 0; i < str.length; ++i) {
    if ((units -= 2) < 0) break;
    c = str.charCodeAt(i);
    hi = c >> 8;
    lo = c % 256;
    byteArray.push(lo);
    byteArray.push(hi);
  }
  return byteArray;
}
function base64ToBytes(str) {
  return base64.toByteArray(base64clean(str));
}
function blitBuffer(src, dst, offset, length) {
  var i;
  for (i = 0; i < length; ++i) {
    if (i + offset >= dst.length || i >= src.length) break;
    dst[i + offset] = src[i];
  }
  return i;
}

// ArrayBuffer or Uint8Array objects from other contexts (i.e. iframes) do not pass
// the `instanceof` check but they should be treated as of that type.
// See: https://github.com/feross/buffer/issues/166
function isInstance(obj, type) {
  return obj instanceof type || obj != null && obj.constructor != null && obj.constructor.name != null && obj.constructor.name === type.name;
}
function numberIsNaN(obj) {
  // For IE11 support
  return obj !== obj; // eslint-disable-line no-self-compare
}

// Create lookup table for `toString('hex')`
// See: https://github.com/feross/buffer/issues/219
var hexSliceLookupTable = function () {
  var alphabet = '0123456789abcdef';
  var table = new Array(256);
  for (var i = 0; i < 16; ++i) {
    var i16 = i * 16;
    for (var j = 0; j < 16; ++j) {
      table[i16 + j] = alphabet[i] + alphabet[j];
    }
  }
  return table;
}();

// Return not function with Error if BigInt not supported
function defineBigIntMethod(fn) {
  return typeof BigInt === 'undefined' ? BufferBigIntNotDefined : fn;
}
function BufferBigIntNotDefined() {
  throw new Error('BigInt not supported');
}

/***/ }),

/***/ 9216:
/***/ (function(module) {

"use strict";


module.exports = isMobile;
module.exports.isMobile = isMobile;
module.exports["default"] = isMobile;
var mobileRE = /(android|bb\d+|meego).+mobile|armv7l|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series[46]0|samsungbrowser.*mobile|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i;
var notMobileRE = /CrOS/;
var tabletRE = /android|ipad|playbook|silk/i;
function isMobile(opts) {
  if (!opts) opts = {};
  var ua = opts.ua;
  if (!ua && typeof navigator !== 'undefined') ua = navigator.userAgent;
  if (ua && ua.headers && typeof ua.headers['user-agent'] === 'string') {
    ua = ua.headers['user-agent'];
  }
  if (typeof ua !== 'string') return false;
  var result = mobileRE.test(ua) && !notMobileRE.test(ua) || !!opts.tablet && tabletRE.test(ua);
  if (!result && opts.tablet && opts.featureDetect && navigator && navigator.maxTouchPoints > 1 && ua.indexOf('Macintosh') !== -1 && ua.indexOf('Safari') !== -1) {
    result = true;
  }
  return result;
}

/***/ }),

/***/ 6296:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

"use strict";


module.exports = createViewController

var createTurntable = __webpack_require__(7261)
var createOrbit     = __webpack_require__(9977)
var createMatrix    = __webpack_require__(4192)

function ViewController(controllers, mode) {
  this._controllerNames = Object.keys(controllers)
  this._controllerList = this._controllerNames.map(function(n) {
    return controllers[n]
  })
  this._mode   = mode
  this._active = controllers[mode]
  if(!this._active) {
    this._mode   = 'turntable'
    this._active = controllers.turntable
  }
  this.modes = this._controllerNames
  this.computedMatrix = this._active.computedMatrix
  this.computedEye    = this._active.computedEye
  this.computedUp     = this._active.computedUp
  this.computedCenter = this._active.computedCenter
  this.computedRadius = this._active.computedRadius
}

var proto = ViewController.prototype

proto.flush = function(a0) {
  var cc = this._controllerList
  for (var i = 0; i < cc.length; ++i) {
    cc[i].flush(a0)
  }
}
proto.idle = function(a0) {
  var cc = this._controllerList
  for (var i = 0; i < cc.length; ++i) {
    cc[i].idle(a0)
  }
}
proto.lookAt = function(a0, a1, a2, a3) {
  var cc = this._controllerList
  for (var i = 0; i < cc.length; ++i) {
    cc[i].lookAt(a0, a1, a2, a3)
  }
}
proto.rotate = function(a0, a1, a2, a3) {
  var cc = this._controllerList
  for (var i = 0; i < cc.length; ++i) {
    cc[i].rotate(a0, a1, a2, a3)
  }
}
proto.pan = function(a0, a1, a2, a3) {
  var cc = this._controllerList
  for (var i = 0; i < cc.length; ++i) {
    cc[i].pan(a0, a1, a2, a3)
  }
}
proto.translate = function(a0, a1, a2, a3) {
  var cc = this._controllerList
  for (var i = 0; i < cc.length; ++i) {
    cc[i].translate(a0, a1, a2, a3)
  }
}
proto.setMatrix = function(a0, a1) {
  var cc = this._controllerList
  for (var i = 0; i < cc.length; ++i) {
    cc[i].setMatrix(a0, a1)
  }
}
proto.setDistanceLimits = function(a0, a1) {
  var cc = this._controllerList
  for (var i = 0; i < cc.length; ++i) {
    cc[i].setDistanceLimits(a0, a1)
  }
}
proto.setDistance = function(a0, a1) {
  var cc = this._controllerList
  for (var i = 0; i < cc.length; ++i) {
    cc[i].setDistance(a0, a1)
  }
}

proto.recalcMatrix = function(t) {
  this._active.recalcMatrix(t)
}

proto.getDistance = function(t) {
  return this._active.getDistance(t)
}
proto.getDistanceLimits = function(out) {
  return this._active.getDistanceLimits(out)
}

proto.lastT = function() {
  return this._active.lastT()
}

proto.setMode = function(mode) {
  if(mode === this._mode) {
    return
  }
  var idx = this._controllerNames.indexOf(mode)
  if(idx < 0) {
    return
  }
  var prev  = this._active
  var next  = this._controllerList[idx]
  var lastT = Math.max(prev.lastT(), next.lastT())

  prev.recalcMatrix(lastT)
  next.setMatrix(lastT, prev.computedMatrix)

  this._active = next
  this._mode   = mode

  //Update matrix properties
  this.computedMatrix = this._active.computedMatrix
  this.computedEye    = this._active.computedEye
  this.computedUp     = this._active.computedUp
  this.computedCenter = this._active.computedCenter
  this.computedRadius = this._active.computedRadius
}

proto.getMode = function() {
  return this._mode
}

function createViewController(options) {
  options = options || {}

  var eye       = options.eye    || [0,0,1]
  var center    = options.center || [0,0,0]
  var up        = options.up     || [0,1,0]
  var limits    = options.distanceLimits || [0, Infinity]
  var mode      = options.mode   || 'turntable'

  var turntable = createTurntable()
  var orbit     = createOrbit()
  var matrix    = createMatrix()

  turntable.setDistanceLimits(limits[0], limits[1])
  turntable.lookAt(0, eye, center, up)
  orbit.setDistanceLimits(limits[0], limits[1])
  orbit.lookAt(0, eye, center, up)
  matrix.setDistanceLimits(limits[0], limits[1])
  matrix.lookAt(0, eye, center, up)

  return new ViewController({
    turntable: turntable,
    orbit: orbit,
    matrix: matrix
  }, mode)
}

/***/ }),

/***/ 7169:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

"use strict";


var weakMap      = typeof WeakMap === 'undefined' ? __webpack_require__(1538) : WeakMap
var createBuffer = __webpack_require__(2762)
var createVAO    = __webpack_require__(8116)

var TriangleCache = new weakMap()

function createABigTriangle(gl) {

  var triangleVAO = TriangleCache.get(gl)
  var handle = triangleVAO && (triangleVAO._triangleBuffer.handle || triangleVAO._triangleBuffer.buffer)
  if(!handle || !gl.isBuffer(handle)) {
    var buf = createBuffer(gl, new Float32Array([-1, -1, -1, 4, 4, -1]))
    triangleVAO = createVAO(gl, [
      { buffer: buf,
        type: gl.FLOAT,
        size: 2
      }
    ])
    triangleVAO._triangleBuffer = buf
    TriangleCache.set(gl, triangleVAO)
  }
  triangleVAO.bind()
  gl.drawArrays(gl.TRIANGLES, 0, 3)
  triangleVAO.unbind()
}

module.exports = createABigTriangle


/***/ }),

/***/ 1085:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

var padLeft = __webpack_require__(1371)

module.exports = addLineNumbers
function addLineNumbers (string, start, delim) {
  start = typeof start === 'number' ? start : 1
  delim = delim || ': '

  var lines = string.split(/\r?\n/)
  var totalDigits = String(lines.length + start - 1).length
  return lines.map(function (line, i) {
    var c = i + start
    var digits = String(c).length
    var prefix = padLeft(c, totalDigits - digits)
    return prefix + delim + line
  }).join('\n')
}


/***/ }),

/***/ 3952:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

"use strict";


module.exports = affineHull

var orient = __webpack_require__(3250)

function linearlyIndependent(points, d) {
  var nhull = new Array(d+1)
  for(var i=0; i 0) {
    throw new Error('Invalid string. Length must be a multiple of 4')
  }

  // Trim off extra bytes after placeholder bytes are found
  // See: https://github.com/beatgammit/base64-js/issues/42
  var validLen = b64.indexOf('=')
  if (validLen === -1) validLen = len

  var placeHoldersLen = validLen === len
    ? 0
    : 4 - (validLen % 4)

  return [validLen, placeHoldersLen]
}

// base64 is 4/3 + up to two characters of the original data
function byteLength (b64) {
  var lens = getLens(b64)
  var validLen = lens[0]
  var placeHoldersLen = lens[1]
  return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen
}

function _byteLength (b64, validLen, placeHoldersLen) {
  return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen
}

function toByteArray (b64) {
  var tmp
  var lens = getLens(b64)
  var validLen = lens[0]
  var placeHoldersLen = lens[1]

  var arr = new Arr(_byteLength(b64, validLen, placeHoldersLen))

  var curByte = 0

  // if there are placeholders, only get up to the last complete 4 chars
  var len = placeHoldersLen > 0
    ? validLen - 4
    : validLen

  var i
  for (i = 0; i < len; i += 4) {
    tmp =
      (revLookup[b64.charCodeAt(i)] << 18) |
      (revLookup[b64.charCodeAt(i + 1)] << 12) |
      (revLookup[b64.charCodeAt(i + 2)] << 6) |
      revLookup[b64.charCodeAt(i + 3)]
    arr[curByte++] = (tmp >> 16) & 0xFF
    arr[curByte++] = (tmp >> 8) & 0xFF
    arr[curByte++] = tmp & 0xFF
  }

  if (placeHoldersLen === 2) {
    tmp =
      (revLookup[b64.charCodeAt(i)] << 2) |
      (revLookup[b64.charCodeAt(i + 1)] >> 4)
    arr[curByte++] = tmp & 0xFF
  }

  if (placeHoldersLen === 1) {
    tmp =
      (revLookup[b64.charCodeAt(i)] << 10) |
      (revLookup[b64.charCodeAt(i + 1)] << 4) |
      (revLookup[b64.charCodeAt(i + 2)] >> 2)
    arr[curByte++] = (tmp >> 8) & 0xFF
    arr[curByte++] = tmp & 0xFF
  }

  return arr
}

function tripletToBase64 (num) {
  return lookup[num >> 18 & 0x3F] +
    lookup[num >> 12 & 0x3F] +
    lookup[num >> 6 & 0x3F] +
    lookup[num & 0x3F]
}

function encodeChunk (uint8, start, end) {
  var tmp
  var output = []
  for (var i = start; i < end; i += 3) {
    tmp =
      ((uint8[i] << 16) & 0xFF0000) +
      ((uint8[i + 1] << 8) & 0xFF00) +
      (uint8[i + 2] & 0xFF)
    output.push(tripletToBase64(tmp))
  }
  return output.join('')
}

function fromByteArray (uint8) {
  var tmp
  var len = uint8.length
  var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes
  var parts = []
  var maxChunkLength = 16383 // must be multiple of 3

  // go through the array every three bytes, we'll deal with trailing stuff later
  for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {
    parts.push(encodeChunk(uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength)))
  }

  // pad the end with zeros, but make sure to not forget the extra bytes
  if (extraBytes === 1) {
    tmp = uint8[len - 1]
    parts.push(
      lookup[tmp >> 2] +
      lookup[(tmp << 4) & 0x3F] +
      '=='
    )
  } else if (extraBytes === 2) {
    tmp = (uint8[len - 2] << 8) + uint8[len - 1]
    parts.push(
      lookup[tmp >> 10] +
      lookup[(tmp >> 4) & 0x3F] +
      lookup[(tmp << 2) & 0x3F] +
      '='
    )
  }

  return parts.join('')
}


/***/ }),

/***/ 3865:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

"use strict";


var rationalize = __webpack_require__(869)

module.exports = add

function add(a, b) {
  return rationalize(
    a[0].mul(b[1]).add(b[0].mul(a[1])),
    a[1].mul(b[1]))
}


/***/ }),

/***/ 1318:
/***/ (function(module) {

"use strict";


module.exports = cmp

function cmp(a, b) {
    return a[0].mul(b[1]).cmp(b[0].mul(a[1]))
}


/***/ }),

/***/ 8697:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

"use strict";


var rationalize = __webpack_require__(869)

module.exports = div

function div(a, b) {
  return rationalize(a[0].mul(b[1]), a[1].mul(b[0]))
}


/***/ }),

/***/ 7842:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

"use strict";


var isRat = __webpack_require__(6330)
var isBN = __webpack_require__(1533)
var num2bn = __webpack_require__(2651)
var str2bn = __webpack_require__(4387)
var rationalize = __webpack_require__(869)
var div = __webpack_require__(8697)

module.exports = makeRational

function makeRational(numer, denom) {
  if(isRat(numer)) {
    if(denom) {
      return div(numer, makeRational(denom))
    }
    return [numer[0].clone(), numer[1].clone()]
  }
  var shift = 0
  var a, b
  if(isBN(numer)) {
    a = numer.clone()
  } else if(typeof numer === 'string') {
    a = str2bn(numer)
  } else if(numer === 0) {
    return [num2bn(0), num2bn(1)]
  } else if(numer === Math.floor(numer)) {
    a = num2bn(numer)
  } else {
    while(numer !== Math.floor(numer)) {
      numer = numer * Math.pow(2, 256)
      shift -= 256
    }
    a = num2bn(numer)
  }
  if(isRat(denom)) {
    a.mul(denom[1])
    b = denom[0].clone()
  } else if(isBN(denom)) {
    b = denom.clone()
  } else if(typeof denom === 'string') {
    b = str2bn(denom)
  } else if(!denom) {
    b = num2bn(1)
  } else if(denom === Math.floor(denom)) {
    b = num2bn(denom)
  } else {
    while(denom !== Math.floor(denom)) {
      denom = denom * Math.pow(2, 256)
      shift += 256
    }
    b = num2bn(denom)
  }
  if(shift > 0) {
    a = a.ushln(shift)
  } else if(shift < 0) {
    b = b.ushln(-shift)
  }
  return rationalize(a, b)
}


/***/ }),

/***/ 6330:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

"use strict";


var isBN = __webpack_require__(1533)

module.exports = isRat

function isRat(x) {
  return Array.isArray(x) && x.length === 2 && isBN(x[0]) && isBN(x[1])
}


/***/ }),

/***/ 5716:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

"use strict";


var BN = __webpack_require__(6859)

module.exports = sign

function sign (x) {
  return x.cmp(new BN(0))
}


/***/ }),

/***/ 1369:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

"use strict";


var sign = __webpack_require__(5716)

module.exports = bn2num

//TODO: Make this better
function bn2num(b) {
  var l = b.length
  var words = b.words
  var out = 0
  if (l === 1) {
    out = words[0]
  } else if (l === 2) {
    out = words[0] + (words[1] * 0x4000000)
  } else {
    for (var i = 0; i < l; i++) {
      var w = words[i]
      out += w * Math.pow(0x4000000, i)
    }
  }
  return sign(b) * out
}


/***/ }),

/***/ 4025:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

"use strict";


var db = __webpack_require__(2361)
var ctz = (__webpack_require__(8828).countTrailingZeros)

module.exports = ctzNumber

//Counts the number of trailing zeros
function ctzNumber(x) {
  var l = ctz(db.lo(x))
  if(l < 32) {
    return l
  }
  var h = ctz(db.hi(x))
  if(h > 20) {
    return 52
  }
  return h + 32
}


/***/ }),

/***/ 1533:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

"use strict";


var BN = __webpack_require__(6859)

module.exports = isBN

//Test if x is a bignumber
//FIXME: obviously this is the wrong way to do it
function isBN(x) {
  return x && typeof x === 'object' && Boolean(x.words)
}


/***/ }),

/***/ 2651:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

"use strict";


var BN = __webpack_require__(6859)
var db = __webpack_require__(2361)

module.exports = num2bn

function num2bn(x) {
  var e = db.exponent(x)
  if(e < 52) {
    return new BN(x)
  } else {
    return (new BN(x * Math.pow(2, 52-e))).ushln(e-52)
  }
}


/***/ }),

/***/ 869:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

"use strict";


var num2bn = __webpack_require__(2651)
var sign = __webpack_require__(5716)

module.exports = rationalize

function rationalize(numer, denom) {
  var snumer = sign(numer)
  var sdenom = sign(denom)
  if(snumer === 0) {
    return [num2bn(0), num2bn(1)]
  }
  if(sdenom === 0) {
    return [num2bn(0), num2bn(0)]
  }
  if(sdenom < 0) {
    numer = numer.neg()
    denom = denom.neg()
  }
  var d = numer.gcd(denom)
  if(d.cmpn(1)) {
    return [ numer.div(d), denom.div(d) ]
  }
  return [ numer, denom ]
}


/***/ }),

/***/ 4387:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

"use strict";


var BN = __webpack_require__(6859)

module.exports = str2BN

function str2BN(x) {
  return new BN(x)
}


/***/ }),

/***/ 6504:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

"use strict";


var rationalize = __webpack_require__(869)

module.exports = mul

function mul(a, b) {
  return rationalize(a[0].mul(b[0]), a[1].mul(b[1]))
}


/***/ }),

/***/ 7721:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

"use strict";


var bnsign = __webpack_require__(5716)

module.exports = sign

function sign(x) {
  return bnsign(x[0]) * bnsign(x[1])
}


/***/ }),

/***/ 5572:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

"use strict";


var rationalize = __webpack_require__(869)

module.exports = sub

function sub(a, b) {
  return rationalize(a[0].mul(b[1]).sub(a[1].mul(b[0])), a[1].mul(b[1]))
}


/***/ }),

/***/ 946:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

"use strict";


var bn2num = __webpack_require__(1369)
var ctz = __webpack_require__(4025)

module.exports = roundRat

// Round a rational to the closest float
function roundRat (f) {
  var a = f[0]
  var b = f[1]
  if (a.cmpn(0) === 0) {
    return 0
  }
  var h = a.abs().divmod(b.abs())
  var iv = h.div
  var x = bn2num(iv)
  var ir = h.mod
  var sgn = (a.negative !== b.negative) ? -1 : 1
  if (ir.cmpn(0) === 0) {
    return sgn * x
  }
  if (x) {
    var s = ctz(x) + 4
    var y = bn2num(ir.ushln(s).divRound(b))
    return sgn * (x + y * Math.pow(2, -s))
  } else {
    var ybits = b.bitLength() - ir.bitLength() + 53
    var y = bn2num(ir.ushln(ybits).divRound(b))
    if (ybits < 1023) {
      return sgn * y * Math.pow(2, -ybits)
    }
    y *= Math.pow(2, -1023)
    return sgn * y * Math.pow(2, 1023 - ybits)
  }
}


/***/ }),

/***/ 2478:
/***/ (function(module) {

"use strict";


// (a, y, c, l, h) = (array, y[, cmp, lo, hi])

function ge(a, y, c, l, h) {
  var i = h + 1;
  while (l <= h) {
    var m = (l + h) >>> 1, x = a[m];
    var p = (c !== undefined) ? c(x, y) : (x - y);
    if (p >= 0) { i = m; h = m - 1 } else { l = m + 1 }
  }
  return i;
};

function gt(a, y, c, l, h) {
  var i = h + 1;
  while (l <= h) {
    var m = (l + h) >>> 1, x = a[m];
    var p = (c !== undefined) ? c(x, y) : (x - y);
    if (p > 0) { i = m; h = m - 1 } else { l = m + 1 }
  }
  return i;
};

function lt(a, y, c, l, h) {
  var i = l - 1;
  while (l <= h) {
    var m = (l + h) >>> 1, x = a[m];
    var p = (c !== undefined) ? c(x, y) : (x - y);
    if (p < 0) { i = m; l = m + 1 } else { h = m - 1 }
  }
  return i;
};

function le(a, y, c, l, h) {
  var i = l - 1;
  while (l <= h) {
    var m = (l + h) >>> 1, x = a[m];
    var p = (c !== undefined) ? c(x, y) : (x - y);
    if (p <= 0) { i = m; l = m + 1 } else { h = m - 1 }
  }
  return i;
};

function eq(a, y, c, l, h) {
  while (l <= h) {
    var m = (l + h) >>> 1, x = a[m];
    var p = (c !== undefined) ? c(x, y) : (x - y);
    if (p === 0) { return m }
    if (p <= 0) { l = m + 1 } else { h = m - 1 }
  }
  return -1;
};

function norm(a, y, c, l, h, f) {
  if (typeof c === 'function') {
    return f(a, y, c, (l === undefined) ? 0 : l | 0, (h === undefined) ? a.length - 1 : h | 0);
  }
  return f(a, y, undefined, (c === undefined) ? 0 : c | 0, (l === undefined) ? a.length - 1 : l | 0);
}

module.exports = {
  ge: function(a, y, c, l, h) { return norm(a, y, c, l, h, ge)},
  gt: function(a, y, c, l, h) { return norm(a, y, c, l, h, gt)},
  lt: function(a, y, c, l, h) { return norm(a, y, c, l, h, lt)},
  le: function(a, y, c, l, h) { return norm(a, y, c, l, h, le)},
  eq: function(a, y, c, l, h) { return norm(a, y, c, l, h, eq)}
}


/***/ }),

/***/ 8828:
/***/ (function(__unused_webpack_module, exports) {

"use strict";
/**
 * Bit twiddling hacks for JavaScript.
 *
 * Author: Mikola Lysenko
 *
 * Ported from Stanford bit twiddling hack library:
 *    http://graphics.stanford.edu/~seander/bithacks.html
 */

 "use restrict";

//Number of bits in an integer
var INT_BITS = 32;

//Constants
exports.INT_BITS  = INT_BITS;
exports.INT_MAX   =  0x7fffffff;
exports.INT_MIN   = -1<<(INT_BITS-1);

//Returns -1, 0, +1 depending on sign of x
exports.sign = function(v) {
  return (v > 0) - (v < 0);
}

//Computes absolute value of integer
exports.abs = function(v) {
  var mask = v >> (INT_BITS-1);
  return (v ^ mask) - mask;
}

//Computes minimum of integers x and y
exports.min = function(x, y) {
  return y ^ ((x ^ y) & -(x < y));
}

//Computes maximum of integers x and y
exports.max = function(x, y) {
  return x ^ ((x ^ y) & -(x < y));
}

//Checks if a number is a power of two
exports.isPow2 = function(v) {
  return !(v & (v-1)) && (!!v);
}

//Computes log base 2 of v
exports.log2 = function(v) {
  var r, shift;
  r =     (v > 0xFFFF) << 4; v >>>= r;
  shift = (v > 0xFF  ) << 3; v >>>= shift; r |= shift;
  shift = (v > 0xF   ) << 2; v >>>= shift; r |= shift;
  shift = (v > 0x3   ) << 1; v >>>= shift; r |= shift;
  return r | (v >> 1);
}

//Computes log base 10 of v
exports.log10 = function(v) {
  return  (v >= 1000000000) ? 9 : (v >= 100000000) ? 8 : (v >= 10000000) ? 7 :
          (v >= 1000000) ? 6 : (v >= 100000) ? 5 : (v >= 10000) ? 4 :
          (v >= 1000) ? 3 : (v >= 100) ? 2 : (v >= 10) ? 1 : 0;
}

//Counts number of bits
exports.popCount = function(v) {
  v = v - ((v >>> 1) & 0x55555555);
  v = (v & 0x33333333) + ((v >>> 2) & 0x33333333);
  return ((v + (v >>> 4) & 0xF0F0F0F) * 0x1010101) >>> 24;
}

//Counts number of trailing zeros
function countTrailingZeros(v) {
  var c = 32;
  v &= -v;
  if (v) c--;
  if (v & 0x0000FFFF) c -= 16;
  if (v & 0x00FF00FF) c -= 8;
  if (v & 0x0F0F0F0F) c -= 4;
  if (v & 0x33333333) c -= 2;
  if (v & 0x55555555) c -= 1;
  return c;
}
exports.countTrailingZeros = countTrailingZeros;

//Rounds to next power of 2
exports.nextPow2 = function(v) {
  v += v === 0;
  --v;
  v |= v >>> 1;
  v |= v >>> 2;
  v |= v >>> 4;
  v |= v >>> 8;
  v |= v >>> 16;
  return v + 1;
}

//Rounds down to previous power of 2
exports.prevPow2 = function(v) {
  v |= v >>> 1;
  v |= v >>> 2;
  v |= v >>> 4;
  v |= v >>> 8;
  v |= v >>> 16;
  return v - (v>>>1);
}

//Computes parity of word
exports.parity = function(v) {
  v ^= v >>> 16;
  v ^= v >>> 8;
  v ^= v >>> 4;
  v &= 0xf;
  return (0x6996 >>> v) & 1;
}

var REVERSE_TABLE = new Array(256);

(function(tab) {
  for(var i=0; i<256; ++i) {
    var v = i, r = i, s = 7;
    for (v >>>= 1; v; v >>>= 1) {
      r <<= 1;
      r |= v & 1;
      --s;
    }
    tab[i] = (r << s) & 0xff;
  }
})(REVERSE_TABLE);

//Reverse bits in a 32 bit word
exports.reverse = function(v) {
  return  (REVERSE_TABLE[ v         & 0xff] << 24) |
          (REVERSE_TABLE[(v >>> 8)  & 0xff] << 16) |
          (REVERSE_TABLE[(v >>> 16) & 0xff] << 8)  |
           REVERSE_TABLE[(v >>> 24) & 0xff];
}

//Interleave bits of 2 coordinates with 16 bits.  Useful for fast quadtree codes
exports.interleave2 = function(x, y) {
  x &= 0xFFFF;
  x = (x | (x << 8)) & 0x00FF00FF;
  x = (x | (x << 4)) & 0x0F0F0F0F;
  x = (x | (x << 2)) & 0x33333333;
  x = (x | (x << 1)) & 0x55555555;

  y &= 0xFFFF;
  y = (y | (y << 8)) & 0x00FF00FF;
  y = (y | (y << 4)) & 0x0F0F0F0F;
  y = (y | (y << 2)) & 0x33333333;
  y = (y | (y << 1)) & 0x55555555;

  return x | (y << 1);
}

//Extracts the nth interleaved component
exports.deinterleave2 = function(v, n) {
  v = (v >>> n) & 0x55555555;
  v = (v | (v >>> 1))  & 0x33333333;
  v = (v | (v >>> 2))  & 0x0F0F0F0F;
  v = (v | (v >>> 4))  & 0x00FF00FF;
  v = (v | (v >>> 16)) & 0x000FFFF;
  return (v << 16) >> 16;
}


//Interleave bits of 3 coordinates, each with 10 bits.  Useful for fast octree codes
exports.interleave3 = function(x, y, z) {
  x &= 0x3FF;
  x  = (x | (x<<16)) & 4278190335;
  x  = (x | (x<<8))  & 251719695;
  x  = (x | (x<<4))  & 3272356035;
  x  = (x | (x<<2))  & 1227133513;

  y &= 0x3FF;
  y  = (y | (y<<16)) & 4278190335;
  y  = (y | (y<<8))  & 251719695;
  y  = (y | (y<<4))  & 3272356035;
  y  = (y | (y<<2))  & 1227133513;
  x |= (y << 1);
  
  z &= 0x3FF;
  z  = (z | (z<<16)) & 4278190335;
  z  = (z | (z<<8))  & 251719695;
  z  = (z | (z<<4))  & 3272356035;
  z  = (z | (z<<2))  & 1227133513;
  
  return x | (z << 2);
}

//Extracts nth interleaved component of a 3-tuple
exports.deinterleave3 = function(v, n) {
  v = (v >>> n)       & 1227133513;
  v = (v | (v>>>2))   & 3272356035;
  v = (v | (v>>>4))   & 251719695;
  v = (v | (v>>>8))   & 4278190335;
  v = (v | (v>>>16))  & 0x3FF;
  return (v<<22)>>22;
}

//Computes next combination in colexicographic order (this is mistakenly called nextPermutation on the bit twiddling hacks page)
exports.nextCombination = function(v) {
  var t = v | (v - 1);
  return (t + 1) | (((~t & -~t) - 1) >>> (countTrailingZeros(v) + 1));
}



/***/ }),

/***/ 6859:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

/* module decorator */ module = __webpack_require__.nmd(module);
(function (module, exports) {
  'use strict';

  // Utils
  function assert (val, msg) {
    if (!val) throw new Error(msg || 'Assertion failed');
  }

  // Could use `inherits` module, but don't want to move from single file
  // architecture yet.
  function inherits (ctor, superCtor) {
    ctor.super_ = superCtor;
    var TempCtor = function () {};
    TempCtor.prototype = superCtor.prototype;
    ctor.prototype = new TempCtor();
    ctor.prototype.constructor = ctor;
  }

  // BN

  function BN (number, base, endian) {
    if (BN.isBN(number)) {
      return number;
    }

    this.negative = 0;
    this.words = null;
    this.length = 0;

    // Reduction context
    this.red = null;

    if (number !== null) {
      if (base === 'le' || base === 'be') {
        endian = base;
        base = 10;
      }

      this._init(number || 0, base || 10, endian || 'be');
    }
  }
  if (typeof module === 'object') {
    module.exports = BN;
  } else {
    exports.BN = BN;
  }

  BN.BN = BN;
  BN.wordSize = 26;

  var Buffer;
  try {
    if (typeof window !== 'undefined' && typeof window.Buffer !== 'undefined') {
      Buffer = window.Buffer;
    } else {
      Buffer = (__webpack_require__(7790).Buffer);
    }
  } catch (e) {
  }

  BN.isBN = function isBN (num) {
    if (num instanceof BN) {
      return true;
    }

    return num !== null && typeof num === 'object' &&
      num.constructor.wordSize === BN.wordSize && Array.isArray(num.words);
  };

  BN.max = function max (left, right) {
    if (left.cmp(right) > 0) return left;
    return right;
  };

  BN.min = function min (left, right) {
    if (left.cmp(right) < 0) return left;
    return right;
  };

  BN.prototype._init = function init (number, base, endian) {
    if (typeof number === 'number') {
      return this._initNumber(number, base, endian);
    }

    if (typeof number === 'object') {
      return this._initArray(number, base, endian);
    }

    if (base === 'hex') {
      base = 16;
    }
    assert(base === (base | 0) && base >= 2 && base <= 36);

    number = number.toString().replace(/\s+/g, '');
    var start = 0;
    if (number[0] === '-') {
      start++;
      this.negative = 1;
    }

    if (start < number.length) {
      if (base === 16) {
        this._parseHex(number, start, endian);
      } else {
        this._parseBase(number, base, start);
        if (endian === 'le') {
          this._initArray(this.toArray(), base, endian);
        }
      }
    }
  };

  BN.prototype._initNumber = function _initNumber (number, base, endian) {
    if (number < 0) {
      this.negative = 1;
      number = -number;
    }
    if (number < 0x4000000) {
      this.words = [ number & 0x3ffffff ];
      this.length = 1;
    } else if (number < 0x10000000000000) {
      this.words = [
        number & 0x3ffffff,
        (number / 0x4000000) & 0x3ffffff
      ];
      this.length = 2;
    } else {
      assert(number < 0x20000000000000); // 2 ^ 53 (unsafe)
      this.words = [
        number & 0x3ffffff,
        (number / 0x4000000) & 0x3ffffff,
        1
      ];
      this.length = 3;
    }

    if (endian !== 'le') return;

    // Reverse the bytes
    this._initArray(this.toArray(), base, endian);
  };

  BN.prototype._initArray = function _initArray (number, base, endian) {
    // Perhaps a Uint8Array
    assert(typeof number.length === 'number');
    if (number.length <= 0) {
      this.words = [ 0 ];
      this.length = 1;
      return this;
    }

    this.length = Math.ceil(number.length / 3);
    this.words = new Array(this.length);
    for (var i = 0; i < this.length; i++) {
      this.words[i] = 0;
    }

    var j, w;
    var off = 0;
    if (endian === 'be') {
      for (i = number.length - 1, j = 0; i >= 0; i -= 3) {
        w = number[i] | (number[i - 1] << 8) | (number[i - 2] << 16);
        this.words[j] |= (w << off) & 0x3ffffff;
        this.words[j + 1] = (w >>> (26 - off)) & 0x3ffffff;
        off += 24;
        if (off >= 26) {
          off -= 26;
          j++;
        }
      }
    } else if (endian === 'le') {
      for (i = 0, j = 0; i < number.length; i += 3) {
        w = number[i] | (number[i + 1] << 8) | (number[i + 2] << 16);
        this.words[j] |= (w << off) & 0x3ffffff;
        this.words[j + 1] = (w >>> (26 - off)) & 0x3ffffff;
        off += 24;
        if (off >= 26) {
          off -= 26;
          j++;
        }
      }
    }
    return this.strip();
  };

  function parseHex4Bits (string, index) {
    var c = string.charCodeAt(index);
    // 'A' - 'F'
    if (c >= 65 && c <= 70) {
      return c - 55;
    // 'a' - 'f'
    } else if (c >= 97 && c <= 102) {
      return c - 87;
    // '0' - '9'
    } else {
      return (c - 48) & 0xf;
    }
  }

  function parseHexByte (string, lowerBound, index) {
    var r = parseHex4Bits(string, index);
    if (index - 1 >= lowerBound) {
      r |= parseHex4Bits(string, index - 1) << 4;
    }
    return r;
  }

  BN.prototype._parseHex = function _parseHex (number, start, endian) {
    // Create possibly bigger array to ensure that it fits the number
    this.length = Math.ceil((number.length - start) / 6);
    this.words = new Array(this.length);
    for (var i = 0; i < this.length; i++) {
      this.words[i] = 0;
    }

    // 24-bits chunks
    var off = 0;
    var j = 0;

    var w;
    if (endian === 'be') {
      for (i = number.length - 1; i >= start; i -= 2) {
        w = parseHexByte(number, start, i) << off;
        this.words[j] |= w & 0x3ffffff;
        if (off >= 18) {
          off -= 18;
          j += 1;
          this.words[j] |= w >>> 26;
        } else {
          off += 8;
        }
      }
    } else {
      var parseLength = number.length - start;
      for (i = parseLength % 2 === 0 ? start + 1 : start; i < number.length; i += 2) {
        w = parseHexByte(number, start, i) << off;
        this.words[j] |= w & 0x3ffffff;
        if (off >= 18) {
          off -= 18;
          j += 1;
          this.words[j] |= w >>> 26;
        } else {
          off += 8;
        }
      }
    }

    this.strip();
  };

  function parseBase (str, start, end, mul) {
    var r = 0;
    var len = Math.min(str.length, end);
    for (var i = start; i < len; i++) {
      var c = str.charCodeAt(i) - 48;

      r *= mul;

      // 'a'
      if (c >= 49) {
        r += c - 49 + 0xa;

      // 'A'
      } else if (c >= 17) {
        r += c - 17 + 0xa;

      // '0' - '9'
      } else {
        r += c;
      }
    }
    return r;
  }

  BN.prototype._parseBase = function _parseBase (number, base, start) {
    // Initialize as zero
    this.words = [ 0 ];
    this.length = 1;

    // Find length of limb in base
    for (var limbLen = 0, limbPow = 1; limbPow <= 0x3ffffff; limbPow *= base) {
      limbLen++;
    }
    limbLen--;
    limbPow = (limbPow / base) | 0;

    var total = number.length - start;
    var mod = total % limbLen;
    var end = Math.min(total, total - mod) + start;

    var word = 0;
    for (var i = start; i < end; i += limbLen) {
      word = parseBase(number, i, i + limbLen, base);

      this.imuln(limbPow);
      if (this.words[0] + word < 0x4000000) {
        this.words[0] += word;
      } else {
        this._iaddn(word);
      }
    }

    if (mod !== 0) {
      var pow = 1;
      word = parseBase(number, i, number.length, base);

      for (i = 0; i < mod; i++) {
        pow *= base;
      }

      this.imuln(pow);
      if (this.words[0] + word < 0x4000000) {
        this.words[0] += word;
      } else {
        this._iaddn(word);
      }
    }

    this.strip();
  };

  BN.prototype.copy = function copy (dest) {
    dest.words = new Array(this.length);
    for (var i = 0; i < this.length; i++) {
      dest.words[i] = this.words[i];
    }
    dest.length = this.length;
    dest.negative = this.negative;
    dest.red = this.red;
  };

  BN.prototype.clone = function clone () {
    var r = new BN(null);
    this.copy(r);
    return r;
  };

  BN.prototype._expand = function _expand (size) {
    while (this.length < size) {
      this.words[this.length++] = 0;
    }
    return this;
  };

  // Remove leading `0` from `this`
  BN.prototype.strip = function strip () {
    while (this.length > 1 && this.words[this.length - 1] === 0) {
      this.length--;
    }
    return this._normSign();
  };

  BN.prototype._normSign = function _normSign () {
    // -0 = 0
    if (this.length === 1 && this.words[0] === 0) {
      this.negative = 0;
    }
    return this;
  };

  BN.prototype.inspect = function inspect () {
    return (this.red ? '';
  };

  /*

  var zeros = [];
  var groupSizes = [];
  var groupBases = [];

  var s = '';
  var i = -1;
  while (++i < BN.wordSize) {
    zeros[i] = s;
    s += '0';
  }
  groupSizes[0] = 0;
  groupSizes[1] = 0;
  groupBases[0] = 0;
  groupBases[1] = 0;
  var base = 2 - 1;
  while (++base < 36 + 1) {
    var groupSize = 0;
    var groupBase = 1;
    while (groupBase < (1 << BN.wordSize) / base) {
      groupBase *= base;
      groupSize += 1;
    }
    groupSizes[base] = groupSize;
    groupBases[base] = groupBase;
  }

  */

  var zeros = [
    '',
    '0',
    '00',
    '000',
    '0000',
    '00000',
    '000000',
    '0000000',
    '00000000',
    '000000000',
    '0000000000',
    '00000000000',
    '000000000000',
    '0000000000000',
    '00000000000000',
    '000000000000000',
    '0000000000000000',
    '00000000000000000',
    '000000000000000000',
    '0000000000000000000',
    '00000000000000000000',
    '000000000000000000000',
    '0000000000000000000000',
    '00000000000000000000000',
    '000000000000000000000000',
    '0000000000000000000000000'
  ];

  var groupSizes = [
    0, 0,
    25, 16, 12, 11, 10, 9, 8,
    8, 7, 7, 7, 7, 6, 6,
    6, 6, 6, 6, 6, 5, 5,
    5, 5, 5, 5, 5, 5, 5,
    5, 5, 5, 5, 5, 5, 5
  ];

  var groupBases = [
    0, 0,
    33554432, 43046721, 16777216, 48828125, 60466176, 40353607, 16777216,
    43046721, 10000000, 19487171, 35831808, 62748517, 7529536, 11390625,
    16777216, 24137569, 34012224, 47045881, 64000000, 4084101, 5153632,
    6436343, 7962624, 9765625, 11881376, 14348907, 17210368, 20511149,
    24300000, 28629151, 33554432, 39135393, 45435424, 52521875, 60466176
  ];

  BN.prototype.toString = function toString (base, padding) {
    base = base || 10;
    padding = padding | 0 || 1;

    var out;
    if (base === 16 || base === 'hex') {
      out = '';
      var off = 0;
      var carry = 0;
      for (var i = 0; i < this.length; i++) {
        var w = this.words[i];
        var word = (((w << off) | carry) & 0xffffff).toString(16);
        carry = (w >>> (24 - off)) & 0xffffff;
        if (carry !== 0 || i !== this.length - 1) {
          out = zeros[6 - word.length] + word + out;
        } else {
          out = word + out;
        }
        off += 2;
        if (off >= 26) {
          off -= 26;
          i--;
        }
      }
      if (carry !== 0) {
        out = carry.toString(16) + out;
      }
      while (out.length % padding !== 0) {
        out = '0' + out;
      }
      if (this.negative !== 0) {
        out = '-' + out;
      }
      return out;
    }

    if (base === (base | 0) && base >= 2 && base <= 36) {
      // var groupSize = Math.floor(BN.wordSize * Math.LN2 / Math.log(base));
      var groupSize = groupSizes[base];
      // var groupBase = Math.pow(base, groupSize);
      var groupBase = groupBases[base];
      out = '';
      var c = this.clone();
      c.negative = 0;
      while (!c.isZero()) {
        var r = c.modn(groupBase).toString(base);
        c = c.idivn(groupBase);

        if (!c.isZero()) {
          out = zeros[groupSize - r.length] + r + out;
        } else {
          out = r + out;
        }
      }
      if (this.isZero()) {
        out = '0' + out;
      }
      while (out.length % padding !== 0) {
        out = '0' + out;
      }
      if (this.negative !== 0) {
        out = '-' + out;
      }
      return out;
    }

    assert(false, 'Base should be between 2 and 36');
  };

  BN.prototype.toNumber = function toNumber () {
    var ret = this.words[0];
    if (this.length === 2) {
      ret += this.words[1] * 0x4000000;
    } else if (this.length === 3 && this.words[2] === 0x01) {
      // NOTE: at this stage it is known that the top bit is set
      ret += 0x10000000000000 + (this.words[1] * 0x4000000);
    } else if (this.length > 2) {
      assert(false, 'Number can only safely store up to 53 bits');
    }
    return (this.negative !== 0) ? -ret : ret;
  };

  BN.prototype.toJSON = function toJSON () {
    return this.toString(16);
  };

  BN.prototype.toBuffer = function toBuffer (endian, length) {
    assert(typeof Buffer !== 'undefined');
    return this.toArrayLike(Buffer, endian, length);
  };

  BN.prototype.toArray = function toArray (endian, length) {
    return this.toArrayLike(Array, endian, length);
  };

  BN.prototype.toArrayLike = function toArrayLike (ArrayType, endian, length) {
    var byteLength = this.byteLength();
    var reqLength = length || Math.max(1, byteLength);
    assert(byteLength <= reqLength, 'byte array longer than desired length');
    assert(reqLength > 0, 'Requested array length <= 0');

    this.strip();
    var littleEndian = endian === 'le';
    var res = new ArrayType(reqLength);

    var b, i;
    var q = this.clone();
    if (!littleEndian) {
      // Assume big-endian
      for (i = 0; i < reqLength - byteLength; i++) {
        res[i] = 0;
      }

      for (i = 0; !q.isZero(); i++) {
        b = q.andln(0xff);
        q.iushrn(8);

        res[reqLength - i - 1] = b;
      }
    } else {
      for (i = 0; !q.isZero(); i++) {
        b = q.andln(0xff);
        q.iushrn(8);

        res[i] = b;
      }

      for (; i < reqLength; i++) {
        res[i] = 0;
      }
    }

    return res;
  };

  if (Math.clz32) {
    BN.prototype._countBits = function _countBits (w) {
      return 32 - Math.clz32(w);
    };
  } else {
    BN.prototype._countBits = function _countBits (w) {
      var t = w;
      var r = 0;
      if (t >= 0x1000) {
        r += 13;
        t >>>= 13;
      }
      if (t >= 0x40) {
        r += 7;
        t >>>= 7;
      }
      if (t >= 0x8) {
        r += 4;
        t >>>= 4;
      }
      if (t >= 0x02) {
        r += 2;
        t >>>= 2;
      }
      return r + t;
    };
  }

  BN.prototype._zeroBits = function _zeroBits (w) {
    // Short-cut
    if (w === 0) return 26;

    var t = w;
    var r = 0;
    if ((t & 0x1fff) === 0) {
      r += 13;
      t >>>= 13;
    }
    if ((t & 0x7f) === 0) {
      r += 7;
      t >>>= 7;
    }
    if ((t & 0xf) === 0) {
      r += 4;
      t >>>= 4;
    }
    if ((t & 0x3) === 0) {
      r += 2;
      t >>>= 2;
    }
    if ((t & 0x1) === 0) {
      r++;
    }
    return r;
  };

  // Return number of used bits in a BN
  BN.prototype.bitLength = function bitLength () {
    var w = this.words[this.length - 1];
    var hi = this._countBits(w);
    return (this.length - 1) * 26 + hi;
  };

  function toBitArray (num) {
    var w = new Array(num.bitLength());

    for (var bit = 0; bit < w.length; bit++) {
      var off = (bit / 26) | 0;
      var wbit = bit % 26;

      w[bit] = (num.words[off] & (1 << wbit)) >>> wbit;
    }

    return w;
  }

  // Number of trailing zero bits
  BN.prototype.zeroBits = function zeroBits () {
    if (this.isZero()) return 0;

    var r = 0;
    for (var i = 0; i < this.length; i++) {
      var b = this._zeroBits(this.words[i]);
      r += b;
      if (b !== 26) break;
    }
    return r;
  };

  BN.prototype.byteLength = function byteLength () {
    return Math.ceil(this.bitLength() / 8);
  };

  BN.prototype.toTwos = function toTwos (width) {
    if (this.negative !== 0) {
      return this.abs().inotn(width).iaddn(1);
    }
    return this.clone();
  };

  BN.prototype.fromTwos = function fromTwos (width) {
    if (this.testn(width - 1)) {
      return this.notn(width).iaddn(1).ineg();
    }
    return this.clone();
  };

  BN.prototype.isNeg = function isNeg () {
    return this.negative !== 0;
  };

  // Return negative clone of `this`
  BN.prototype.neg = function neg () {
    return this.clone().ineg();
  };

  BN.prototype.ineg = function ineg () {
    if (!this.isZero()) {
      this.negative ^= 1;
    }

    return this;
  };

  // Or `num` with `this` in-place
  BN.prototype.iuor = function iuor (num) {
    while (this.length < num.length) {
      this.words[this.length++] = 0;
    }

    for (var i = 0; i < num.length; i++) {
      this.words[i] = this.words[i] | num.words[i];
    }

    return this.strip();
  };

  BN.prototype.ior = function ior (num) {
    assert((this.negative | num.negative) === 0);
    return this.iuor(num);
  };

  // Or `num` with `this`
  BN.prototype.or = function or (num) {
    if (this.length > num.length) return this.clone().ior(num);
    return num.clone().ior(this);
  };

  BN.prototype.uor = function uor (num) {
    if (this.length > num.length) return this.clone().iuor(num);
    return num.clone().iuor(this);
  };

  // And `num` with `this` in-place
  BN.prototype.iuand = function iuand (num) {
    // b = min-length(num, this)
    var b;
    if (this.length > num.length) {
      b = num;
    } else {
      b = this;
    }

    for (var i = 0; i < b.length; i++) {
      this.words[i] = this.words[i] & num.words[i];
    }

    this.length = b.length;

    return this.strip();
  };

  BN.prototype.iand = function iand (num) {
    assert((this.negative | num.negative) === 0);
    return this.iuand(num);
  };

  // And `num` with `this`
  BN.prototype.and = function and (num) {
    if (this.length > num.length) return this.clone().iand(num);
    return num.clone().iand(this);
  };

  BN.prototype.uand = function uand (num) {
    if (this.length > num.length) return this.clone().iuand(num);
    return num.clone().iuand(this);
  };

  // Xor `num` with `this` in-place
  BN.prototype.iuxor = function iuxor (num) {
    // a.length > b.length
    var a;
    var b;
    if (this.length > num.length) {
      a = this;
      b = num;
    } else {
      a = num;
      b = this;
    }

    for (var i = 0; i < b.length; i++) {
      this.words[i] = a.words[i] ^ b.words[i];
    }

    if (this !== a) {
      for (; i < a.length; i++) {
        this.words[i] = a.words[i];
      }
    }

    this.length = a.length;

    return this.strip();
  };

  BN.prototype.ixor = function ixor (num) {
    assert((this.negative | num.negative) === 0);
    return this.iuxor(num);
  };

  // Xor `num` with `this`
  BN.prototype.xor = function xor (num) {
    if (this.length > num.length) return this.clone().ixor(num);
    return num.clone().ixor(this);
  };

  BN.prototype.uxor = function uxor (num) {
    if (this.length > num.length) return this.clone().iuxor(num);
    return num.clone().iuxor(this);
  };

  // Not ``this`` with ``width`` bitwidth
  BN.prototype.inotn = function inotn (width) {
    assert(typeof width === 'number' && width >= 0);

    var bytesNeeded = Math.ceil(width / 26) | 0;
    var bitsLeft = width % 26;

    // Extend the buffer with leading zeroes
    this._expand(bytesNeeded);

    if (bitsLeft > 0) {
      bytesNeeded--;
    }

    // Handle complete words
    for (var i = 0; i < bytesNeeded; i++) {
      this.words[i] = ~this.words[i] & 0x3ffffff;
    }

    // Handle the residue
    if (bitsLeft > 0) {
      this.words[i] = ~this.words[i] & (0x3ffffff >> (26 - bitsLeft));
    }

    // And remove leading zeroes
    return this.strip();
  };

  BN.prototype.notn = function notn (width) {
    return this.clone().inotn(width);
  };

  // Set `bit` of `this`
  BN.prototype.setn = function setn (bit, val) {
    assert(typeof bit === 'number' && bit >= 0);

    var off = (bit / 26) | 0;
    var wbit = bit % 26;

    this._expand(off + 1);

    if (val) {
      this.words[off] = this.words[off] | (1 << wbit);
    } else {
      this.words[off] = this.words[off] & ~(1 << wbit);
    }

    return this.strip();
  };

  // Add `num` to `this` in-place
  BN.prototype.iadd = function iadd (num) {
    var r;

    // negative + positive
    if (this.negative !== 0 && num.negative === 0) {
      this.negative = 0;
      r = this.isub(num);
      this.negative ^= 1;
      return this._normSign();

    // positive + negative
    } else if (this.negative === 0 && num.negative !== 0) {
      num.negative = 0;
      r = this.isub(num);
      num.negative = 1;
      return r._normSign();
    }

    // a.length > b.length
    var a, b;
    if (this.length > num.length) {
      a = this;
      b = num;
    } else {
      a = num;
      b = this;
    }

    var carry = 0;
    for (var i = 0; i < b.length; i++) {
      r = (a.words[i] | 0) + (b.words[i] | 0) + carry;
      this.words[i] = r & 0x3ffffff;
      carry = r >>> 26;
    }
    for (; carry !== 0 && i < a.length; i++) {
      r = (a.words[i] | 0) + carry;
      this.words[i] = r & 0x3ffffff;
      carry = r >>> 26;
    }

    this.length = a.length;
    if (carry !== 0) {
      this.words[this.length] = carry;
      this.length++;
    // Copy the rest of the words
    } else if (a !== this) {
      for (; i < a.length; i++) {
        this.words[i] = a.words[i];
      }
    }

    return this;
  };

  // Add `num` to `this`
  BN.prototype.add = function add (num) {
    var res;
    if (num.negative !== 0 && this.negative === 0) {
      num.negative = 0;
      res = this.sub(num);
      num.negative ^= 1;
      return res;
    } else if (num.negative === 0 && this.negative !== 0) {
      this.negative = 0;
      res = num.sub(this);
      this.negative = 1;
      return res;
    }

    if (this.length > num.length) return this.clone().iadd(num);

    return num.clone().iadd(this);
  };

  // Subtract `num` from `this` in-place
  BN.prototype.isub = function isub (num) {
    // this - (-num) = this + num
    if (num.negative !== 0) {
      num.negative = 0;
      var r = this.iadd(num);
      num.negative = 1;
      return r._normSign();

    // -this - num = -(this + num)
    } else if (this.negative !== 0) {
      this.negative = 0;
      this.iadd(num);
      this.negative = 1;
      return this._normSign();
    }

    // At this point both numbers are positive
    var cmp = this.cmp(num);

    // Optimization - zeroify
    if (cmp === 0) {
      this.negative = 0;
      this.length = 1;
      this.words[0] = 0;
      return this;
    }

    // a > b
    var a, b;
    if (cmp > 0) {
      a = this;
      b = num;
    } else {
      a = num;
      b = this;
    }

    var carry = 0;
    for (var i = 0; i < b.length; i++) {
      r = (a.words[i] | 0) - (b.words[i] | 0) + carry;
      carry = r >> 26;
      this.words[i] = r & 0x3ffffff;
    }
    for (; carry !== 0 && i < a.length; i++) {
      r = (a.words[i] | 0) + carry;
      carry = r >> 26;
      this.words[i] = r & 0x3ffffff;
    }

    // Copy rest of the words
    if (carry === 0 && i < a.length && a !== this) {
      for (; i < a.length; i++) {
        this.words[i] = a.words[i];
      }
    }

    this.length = Math.max(this.length, i);

    if (a !== this) {
      this.negative = 1;
    }

    return this.strip();
  };

  // Subtract `num` from `this`
  BN.prototype.sub = function sub (num) {
    return this.clone().isub(num);
  };

  function smallMulTo (self, num, out) {
    out.negative = num.negative ^ self.negative;
    var len = (self.length + num.length) | 0;
    out.length = len;
    len = (len - 1) | 0;

    // Peel one iteration (compiler can't do it, because of code complexity)
    var a = self.words[0] | 0;
    var b = num.words[0] | 0;
    var r = a * b;

    var lo = r & 0x3ffffff;
    var carry = (r / 0x4000000) | 0;
    out.words[0] = lo;

    for (var k = 1; k < len; k++) {
      // Sum all words with the same `i + j = k` and accumulate `ncarry`,
      // note that ncarry could be >= 0x3ffffff
      var ncarry = carry >>> 26;
      var rword = carry & 0x3ffffff;
      var maxJ = Math.min(k, num.length - 1);
      for (var j = Math.max(0, k - self.length + 1); j <= maxJ; j++) {
        var i = (k - j) | 0;
        a = self.words[i] | 0;
        b = num.words[j] | 0;
        r = a * b + rword;
        ncarry += (r / 0x4000000) | 0;
        rword = r & 0x3ffffff;
      }
      out.words[k] = rword | 0;
      carry = ncarry | 0;
    }
    if (carry !== 0) {
      out.words[k] = carry | 0;
    } else {
      out.length--;
    }

    return out.strip();
  }

  // TODO(indutny): it may be reasonable to omit it for users who don't need
  // to work with 256-bit numbers, otherwise it gives 20% improvement for 256-bit
  // multiplication (like elliptic secp256k1).
  var comb10MulTo = function comb10MulTo (self, num, out) {
    var a = self.words;
    var b = num.words;
    var o = out.words;
    var c = 0;
    var lo;
    var mid;
    var hi;
    var a0 = a[0] | 0;
    var al0 = a0 & 0x1fff;
    var ah0 = a0 >>> 13;
    var a1 = a[1] | 0;
    var al1 = a1 & 0x1fff;
    var ah1 = a1 >>> 13;
    var a2 = a[2] | 0;
    var al2 = a2 & 0x1fff;
    var ah2 = a2 >>> 13;
    var a3 = a[3] | 0;
    var al3 = a3 & 0x1fff;
    var ah3 = a3 >>> 13;
    var a4 = a[4] | 0;
    var al4 = a4 & 0x1fff;
    var ah4 = a4 >>> 13;
    var a5 = a[5] | 0;
    var al5 = a5 & 0x1fff;
    var ah5 = a5 >>> 13;
    var a6 = a[6] | 0;
    var al6 = a6 & 0x1fff;
    var ah6 = a6 >>> 13;
    var a7 = a[7] | 0;
    var al7 = a7 & 0x1fff;
    var ah7 = a7 >>> 13;
    var a8 = a[8] | 0;
    var al8 = a8 & 0x1fff;
    var ah8 = a8 >>> 13;
    var a9 = a[9] | 0;
    var al9 = a9 & 0x1fff;
    var ah9 = a9 >>> 13;
    var b0 = b[0] | 0;
    var bl0 = b0 & 0x1fff;
    var bh0 = b0 >>> 13;
    var b1 = b[1] | 0;
    var bl1 = b1 & 0x1fff;
    var bh1 = b1 >>> 13;
    var b2 = b[2] | 0;
    var bl2 = b2 & 0x1fff;
    var bh2 = b2 >>> 13;
    var b3 = b[3] | 0;
    var bl3 = b3 & 0x1fff;
    var bh3 = b3 >>> 13;
    var b4 = b[4] | 0;
    var bl4 = b4 & 0x1fff;
    var bh4 = b4 >>> 13;
    var b5 = b[5] | 0;
    var bl5 = b5 & 0x1fff;
    var bh5 = b5 >>> 13;
    var b6 = b[6] | 0;
    var bl6 = b6 & 0x1fff;
    var bh6 = b6 >>> 13;
    var b7 = b[7] | 0;
    var bl7 = b7 & 0x1fff;
    var bh7 = b7 >>> 13;
    var b8 = b[8] | 0;
    var bl8 = b8 & 0x1fff;
    var bh8 = b8 >>> 13;
    var b9 = b[9] | 0;
    var bl9 = b9 & 0x1fff;
    var bh9 = b9 >>> 13;

    out.negative = self.negative ^ num.negative;
    out.length = 19;
    /* k = 0 */
    lo = Math.imul(al0, bl0);
    mid = Math.imul(al0, bh0);
    mid = (mid + Math.imul(ah0, bl0)) | 0;
    hi = Math.imul(ah0, bh0);
    var w0 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
    c = (((hi + (mid >>> 13)) | 0) + (w0 >>> 26)) | 0;
    w0 &= 0x3ffffff;
    /* k = 1 */
    lo = Math.imul(al1, bl0);
    mid = Math.imul(al1, bh0);
    mid = (mid + Math.imul(ah1, bl0)) | 0;
    hi = Math.imul(ah1, bh0);
    lo = (lo + Math.imul(al0, bl1)) | 0;
    mid = (mid + Math.imul(al0, bh1)) | 0;
    mid = (mid + Math.imul(ah0, bl1)) | 0;
    hi = (hi + Math.imul(ah0, bh1)) | 0;
    var w1 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
    c = (((hi + (mid >>> 13)) | 0) + (w1 >>> 26)) | 0;
    w1 &= 0x3ffffff;
    /* k = 2 */
    lo = Math.imul(al2, bl0);
    mid = Math.imul(al2, bh0);
    mid = (mid + Math.imul(ah2, bl0)) | 0;
    hi = Math.imul(ah2, bh0);
    lo = (lo + Math.imul(al1, bl1)) | 0;
    mid = (mid + Math.imul(al1, bh1)) | 0;
    mid = (mid + Math.imul(ah1, bl1)) | 0;
    hi = (hi + Math.imul(ah1, bh1)) | 0;
    lo = (lo + Math.imul(al0, bl2)) | 0;
    mid = (mid + Math.imul(al0, bh2)) | 0;
    mid = (mid + Math.imul(ah0, bl2)) | 0;
    hi = (hi + Math.imul(ah0, bh2)) | 0;
    var w2 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
    c = (((hi + (mid >>> 13)) | 0) + (w2 >>> 26)) | 0;
    w2 &= 0x3ffffff;
    /* k = 3 */
    lo = Math.imul(al3, bl0);
    mid = Math.imul(al3, bh0);
    mid = (mid + Math.imul(ah3, bl0)) | 0;
    hi = Math.imul(ah3, bh0);
    lo = (lo + Math.imul(al2, bl1)) | 0;
    mid = (mid + Math.imul(al2, bh1)) | 0;
    mid = (mid + Math.imul(ah2, bl1)) | 0;
    hi = (hi + Math.imul(ah2, bh1)) | 0;
    lo = (lo + Math.imul(al1, bl2)) | 0;
    mid = (mid + Math.imul(al1, bh2)) | 0;
    mid = (mid + Math.imul(ah1, bl2)) | 0;
    hi = (hi + Math.imul(ah1, bh2)) | 0;
    lo = (lo + Math.imul(al0, bl3)) | 0;
    mid = (mid + Math.imul(al0, bh3)) | 0;
    mid = (mid + Math.imul(ah0, bl3)) | 0;
    hi = (hi + Math.imul(ah0, bh3)) | 0;
    var w3 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
    c = (((hi + (mid >>> 13)) | 0) + (w3 >>> 26)) | 0;
    w3 &= 0x3ffffff;
    /* k = 4 */
    lo = Math.imul(al4, bl0);
    mid = Math.imul(al4, bh0);
    mid = (mid + Math.imul(ah4, bl0)) | 0;
    hi = Math.imul(ah4, bh0);
    lo = (lo + Math.imul(al3, bl1)) | 0;
    mid = (mid + Math.imul(al3, bh1)) | 0;
    mid = (mid + Math.imul(ah3, bl1)) | 0;
    hi = (hi + Math.imul(ah3, bh1)) | 0;
    lo = (lo + Math.imul(al2, bl2)) | 0;
    mid = (mid + Math.imul(al2, bh2)) | 0;
    mid = (mid + Math.imul(ah2, bl2)) | 0;
    hi = (hi + Math.imul(ah2, bh2)) | 0;
    lo = (lo + Math.imul(al1, bl3)) | 0;
    mid = (mid + Math.imul(al1, bh3)) | 0;
    mid = (mid + Math.imul(ah1, bl3)) | 0;
    hi = (hi + Math.imul(ah1, bh3)) | 0;
    lo = (lo + Math.imul(al0, bl4)) | 0;
    mid = (mid + Math.imul(al0, bh4)) | 0;
    mid = (mid + Math.imul(ah0, bl4)) | 0;
    hi = (hi + Math.imul(ah0, bh4)) | 0;
    var w4 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
    c = (((hi + (mid >>> 13)) | 0) + (w4 >>> 26)) | 0;
    w4 &= 0x3ffffff;
    /* k = 5 */
    lo = Math.imul(al5, bl0);
    mid = Math.imul(al5, bh0);
    mid = (mid + Math.imul(ah5, bl0)) | 0;
    hi = Math.imul(ah5, bh0);
    lo = (lo + Math.imul(al4, bl1)) | 0;
    mid = (mid + Math.imul(al4, bh1)) | 0;
    mid = (mid + Math.imul(ah4, bl1)) | 0;
    hi = (hi + Math.imul(ah4, bh1)) | 0;
    lo = (lo + Math.imul(al3, bl2)) | 0;
    mid = (mid + Math.imul(al3, bh2)) | 0;
    mid = (mid + Math.imul(ah3, bl2)) | 0;
    hi = (hi + Math.imul(ah3, bh2)) | 0;
    lo = (lo + Math.imul(al2, bl3)) | 0;
    mid = (mid + Math.imul(al2, bh3)) | 0;
    mid = (mid + Math.imul(ah2, bl3)) | 0;
    hi = (hi + Math.imul(ah2, bh3)) | 0;
    lo = (lo + Math.imul(al1, bl4)) | 0;
    mid = (mid + Math.imul(al1, bh4)) | 0;
    mid = (mid + Math.imul(ah1, bl4)) | 0;
    hi = (hi + Math.imul(ah1, bh4)) | 0;
    lo = (lo + Math.imul(al0, bl5)) | 0;
    mid = (mid + Math.imul(al0, bh5)) | 0;
    mid = (mid + Math.imul(ah0, bl5)) | 0;
    hi = (hi + Math.imul(ah0, bh5)) | 0;
    var w5 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
    c = (((hi + (mid >>> 13)) | 0) + (w5 >>> 26)) | 0;
    w5 &= 0x3ffffff;
    /* k = 6 */
    lo = Math.imul(al6, bl0);
    mid = Math.imul(al6, bh0);
    mid = (mid + Math.imul(ah6, bl0)) | 0;
    hi = Math.imul(ah6, bh0);
    lo = (lo + Math.imul(al5, bl1)) | 0;
    mid = (mid + Math.imul(al5, bh1)) | 0;
    mid = (mid + Math.imul(ah5, bl1)) | 0;
    hi = (hi + Math.imul(ah5, bh1)) | 0;
    lo = (lo + Math.imul(al4, bl2)) | 0;
    mid = (mid + Math.imul(al4, bh2)) | 0;
    mid = (mid + Math.imul(ah4, bl2)) | 0;
    hi = (hi + Math.imul(ah4, bh2)) | 0;
    lo = (lo + Math.imul(al3, bl3)) | 0;
    mid = (mid + Math.imul(al3, bh3)) | 0;
    mid = (mid + Math.imul(ah3, bl3)) | 0;
    hi = (hi + Math.imul(ah3, bh3)) | 0;
    lo = (lo + Math.imul(al2, bl4)) | 0;
    mid = (mid + Math.imul(al2, bh4)) | 0;
    mid = (mid + Math.imul(ah2, bl4)) | 0;
    hi = (hi + Math.imul(ah2, bh4)) | 0;
    lo = (lo + Math.imul(al1, bl5)) | 0;
    mid = (mid + Math.imul(al1, bh5)) | 0;
    mid = (mid + Math.imul(ah1, bl5)) | 0;
    hi = (hi + Math.imul(ah1, bh5)) | 0;
    lo = (lo + Math.imul(al0, bl6)) | 0;
    mid = (mid + Math.imul(al0, bh6)) | 0;
    mid = (mid + Math.imul(ah0, bl6)) | 0;
    hi = (hi + Math.imul(ah0, bh6)) | 0;
    var w6 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
    c = (((hi + (mid >>> 13)) | 0) + (w6 >>> 26)) | 0;
    w6 &= 0x3ffffff;
    /* k = 7 */
    lo = Math.imul(al7, bl0);
    mid = Math.imul(al7, bh0);
    mid = (mid + Math.imul(ah7, bl0)) | 0;
    hi = Math.imul(ah7, bh0);
    lo = (lo + Math.imul(al6, bl1)) | 0;
    mid = (mid + Math.imul(al6, bh1)) | 0;
    mid = (mid + Math.imul(ah6, bl1)) | 0;
    hi = (hi + Math.imul(ah6, bh1)) | 0;
    lo = (lo + Math.imul(al5, bl2)) | 0;
    mid = (mid + Math.imul(al5, bh2)) | 0;
    mid = (mid + Math.imul(ah5, bl2)) | 0;
    hi = (hi + Math.imul(ah5, bh2)) | 0;
    lo = (lo + Math.imul(al4, bl3)) | 0;
    mid = (mid + Math.imul(al4, bh3)) | 0;
    mid = (mid + Math.imul(ah4, bl3)) | 0;
    hi = (hi + Math.imul(ah4, bh3)) | 0;
    lo = (lo + Math.imul(al3, bl4)) | 0;
    mid = (mid + Math.imul(al3, bh4)) | 0;
    mid = (mid + Math.imul(ah3, bl4)) | 0;
    hi = (hi + Math.imul(ah3, bh4)) | 0;
    lo = (lo + Math.imul(al2, bl5)) | 0;
    mid = (mid + Math.imul(al2, bh5)) | 0;
    mid = (mid + Math.imul(ah2, bl5)) | 0;
    hi = (hi + Math.imul(ah2, bh5)) | 0;
    lo = (lo + Math.imul(al1, bl6)) | 0;
    mid = (mid + Math.imul(al1, bh6)) | 0;
    mid = (mid + Math.imul(ah1, bl6)) | 0;
    hi = (hi + Math.imul(ah1, bh6)) | 0;
    lo = (lo + Math.imul(al0, bl7)) | 0;
    mid = (mid + Math.imul(al0, bh7)) | 0;
    mid = (mid + Math.imul(ah0, bl7)) | 0;
    hi = (hi + Math.imul(ah0, bh7)) | 0;
    var w7 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
    c = (((hi + (mid >>> 13)) | 0) + (w7 >>> 26)) | 0;
    w7 &= 0x3ffffff;
    /* k = 8 */
    lo = Math.imul(al8, bl0);
    mid = Math.imul(al8, bh0);
    mid = (mid + Math.imul(ah8, bl0)) | 0;
    hi = Math.imul(ah8, bh0);
    lo = (lo + Math.imul(al7, bl1)) | 0;
    mid = (mid + Math.imul(al7, bh1)) | 0;
    mid = (mid + Math.imul(ah7, bl1)) | 0;
    hi = (hi + Math.imul(ah7, bh1)) | 0;
    lo = (lo + Math.imul(al6, bl2)) | 0;
    mid = (mid + Math.imul(al6, bh2)) | 0;
    mid = (mid + Math.imul(ah6, bl2)) | 0;
    hi = (hi + Math.imul(ah6, bh2)) | 0;
    lo = (lo + Math.imul(al5, bl3)) | 0;
    mid = (mid + Math.imul(al5, bh3)) | 0;
    mid = (mid + Math.imul(ah5, bl3)) | 0;
    hi = (hi + Math.imul(ah5, bh3)) | 0;
    lo = (lo + Math.imul(al4, bl4)) | 0;
    mid = (mid + Math.imul(al4, bh4)) | 0;
    mid = (mid + Math.imul(ah4, bl4)) | 0;
    hi = (hi + Math.imul(ah4, bh4)) | 0;
    lo = (lo + Math.imul(al3, bl5)) | 0;
    mid = (mid + Math.imul(al3, bh5)) | 0;
    mid = (mid + Math.imul(ah3, bl5)) | 0;
    hi = (hi + Math.imul(ah3, bh5)) | 0;
    lo = (lo + Math.imul(al2, bl6)) | 0;
    mid = (mid + Math.imul(al2, bh6)) | 0;
    mid = (mid + Math.imul(ah2, bl6)) | 0;
    hi = (hi + Math.imul(ah2, bh6)) | 0;
    lo = (lo + Math.imul(al1, bl7)) | 0;
    mid = (mid + Math.imul(al1, bh7)) | 0;
    mid = (mid + Math.imul(ah1, bl7)) | 0;
    hi = (hi + Math.imul(ah1, bh7)) | 0;
    lo = (lo + Math.imul(al0, bl8)) | 0;
    mid = (mid + Math.imul(al0, bh8)) | 0;
    mid = (mid + Math.imul(ah0, bl8)) | 0;
    hi = (hi + Math.imul(ah0, bh8)) | 0;
    var w8 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
    c = (((hi + (mid >>> 13)) | 0) + (w8 >>> 26)) | 0;
    w8 &= 0x3ffffff;
    /* k = 9 */
    lo = Math.imul(al9, bl0);
    mid = Math.imul(al9, bh0);
    mid = (mid + Math.imul(ah9, bl0)) | 0;
    hi = Math.imul(ah9, bh0);
    lo = (lo + Math.imul(al8, bl1)) | 0;
    mid = (mid + Math.imul(al8, bh1)) | 0;
    mid = (mid + Math.imul(ah8, bl1)) | 0;
    hi = (hi + Math.imul(ah8, bh1)) | 0;
    lo = (lo + Math.imul(al7, bl2)) | 0;
    mid = (mid + Math.imul(al7, bh2)) | 0;
    mid = (mid + Math.imul(ah7, bl2)) | 0;
    hi = (hi + Math.imul(ah7, bh2)) | 0;
    lo = (lo + Math.imul(al6, bl3)) | 0;
    mid = (mid + Math.imul(al6, bh3)) | 0;
    mid = (mid + Math.imul(ah6, bl3)) | 0;
    hi = (hi + Math.imul(ah6, bh3)) | 0;
    lo = (lo + Math.imul(al5, bl4)) | 0;
    mid = (mid + Math.imul(al5, bh4)) | 0;
    mid = (mid + Math.imul(ah5, bl4)) | 0;
    hi = (hi + Math.imul(ah5, bh4)) | 0;
    lo = (lo + Math.imul(al4, bl5)) | 0;
    mid = (mid + Math.imul(al4, bh5)) | 0;
    mid = (mid + Math.imul(ah4, bl5)) | 0;
    hi = (hi + Math.imul(ah4, bh5)) | 0;
    lo = (lo + Math.imul(al3, bl6)) | 0;
    mid = (mid + Math.imul(al3, bh6)) | 0;
    mid = (mid + Math.imul(ah3, bl6)) | 0;
    hi = (hi + Math.imul(ah3, bh6)) | 0;
    lo = (lo + Math.imul(al2, bl7)) | 0;
    mid = (mid + Math.imul(al2, bh7)) | 0;
    mid = (mid + Math.imul(ah2, bl7)) | 0;
    hi = (hi + Math.imul(ah2, bh7)) | 0;
    lo = (lo + Math.imul(al1, bl8)) | 0;
    mid = (mid + Math.imul(al1, bh8)) | 0;
    mid = (mid + Math.imul(ah1, bl8)) | 0;
    hi = (hi + Math.imul(ah1, bh8)) | 0;
    lo = (lo + Math.imul(al0, bl9)) | 0;
    mid = (mid + Math.imul(al0, bh9)) | 0;
    mid = (mid + Math.imul(ah0, bl9)) | 0;
    hi = (hi + Math.imul(ah0, bh9)) | 0;
    var w9 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
    c = (((hi + (mid >>> 13)) | 0) + (w9 >>> 26)) | 0;
    w9 &= 0x3ffffff;
    /* k = 10 */
    lo = Math.imul(al9, bl1);
    mid = Math.imul(al9, bh1);
    mid = (mid + Math.imul(ah9, bl1)) | 0;
    hi = Math.imul(ah9, bh1);
    lo = (lo + Math.imul(al8, bl2)) | 0;
    mid = (mid + Math.imul(al8, bh2)) | 0;
    mid = (mid + Math.imul(ah8, bl2)) | 0;
    hi = (hi + Math.imul(ah8, bh2)) | 0;
    lo = (lo + Math.imul(al7, bl3)) | 0;
    mid = (mid + Math.imul(al7, bh3)) | 0;
    mid = (mid + Math.imul(ah7, bl3)) | 0;
    hi = (hi + Math.imul(ah7, bh3)) | 0;
    lo = (lo + Math.imul(al6, bl4)) | 0;
    mid = (mid + Math.imul(al6, bh4)) | 0;
    mid = (mid + Math.imul(ah6, bl4)) | 0;
    hi = (hi + Math.imul(ah6, bh4)) | 0;
    lo = (lo + Math.imul(al5, bl5)) | 0;
    mid = (mid + Math.imul(al5, bh5)) | 0;
    mid = (mid + Math.imul(ah5, bl5)) | 0;
    hi = (hi + Math.imul(ah5, bh5)) | 0;
    lo = (lo + Math.imul(al4, bl6)) | 0;
    mid = (mid + Math.imul(al4, bh6)) | 0;
    mid = (mid + Math.imul(ah4, bl6)) | 0;
    hi = (hi + Math.imul(ah4, bh6)) | 0;
    lo = (lo + Math.imul(al3, bl7)) | 0;
    mid = (mid + Math.imul(al3, bh7)) | 0;
    mid = (mid + Math.imul(ah3, bl7)) | 0;
    hi = (hi + Math.imul(ah3, bh7)) | 0;
    lo = (lo + Math.imul(al2, bl8)) | 0;
    mid = (mid + Math.imul(al2, bh8)) | 0;
    mid = (mid + Math.imul(ah2, bl8)) | 0;
    hi = (hi + Math.imul(ah2, bh8)) | 0;
    lo = (lo + Math.imul(al1, bl9)) | 0;
    mid = (mid + Math.imul(al1, bh9)) | 0;
    mid = (mid + Math.imul(ah1, bl9)) | 0;
    hi = (hi + Math.imul(ah1, bh9)) | 0;
    var w10 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
    c = (((hi + (mid >>> 13)) | 0) + (w10 >>> 26)) | 0;
    w10 &= 0x3ffffff;
    /* k = 11 */
    lo = Math.imul(al9, bl2);
    mid = Math.imul(al9, bh2);
    mid = (mid + Math.imul(ah9, bl2)) | 0;
    hi = Math.imul(ah9, bh2);
    lo = (lo + Math.imul(al8, bl3)) | 0;
    mid = (mid + Math.imul(al8, bh3)) | 0;
    mid = (mid + Math.imul(ah8, bl3)) | 0;
    hi = (hi + Math.imul(ah8, bh3)) | 0;
    lo = (lo + Math.imul(al7, bl4)) | 0;
    mid = (mid + Math.imul(al7, bh4)) | 0;
    mid = (mid + Math.imul(ah7, bl4)) | 0;
    hi = (hi + Math.imul(ah7, bh4)) | 0;
    lo = (lo + Math.imul(al6, bl5)) | 0;
    mid = (mid + Math.imul(al6, bh5)) | 0;
    mid = (mid + Math.imul(ah6, bl5)) | 0;
    hi = (hi + Math.imul(ah6, bh5)) | 0;
    lo = (lo + Math.imul(al5, bl6)) | 0;
    mid = (mid + Math.imul(al5, bh6)) | 0;
    mid = (mid + Math.imul(ah5, bl6)) | 0;
    hi = (hi + Math.imul(ah5, bh6)) | 0;
    lo = (lo + Math.imul(al4, bl7)) | 0;
    mid = (mid + Math.imul(al4, bh7)) | 0;
    mid = (mid + Math.imul(ah4, bl7)) | 0;
    hi = (hi + Math.imul(ah4, bh7)) | 0;
    lo = (lo + Math.imul(al3, bl8)) | 0;
    mid = (mid + Math.imul(al3, bh8)) | 0;
    mid = (mid + Math.imul(ah3, bl8)) | 0;
    hi = (hi + Math.imul(ah3, bh8)) | 0;
    lo = (lo + Math.imul(al2, bl9)) | 0;
    mid = (mid + Math.imul(al2, bh9)) | 0;
    mid = (mid + Math.imul(ah2, bl9)) | 0;
    hi = (hi + Math.imul(ah2, bh9)) | 0;
    var w11 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
    c = (((hi + (mid >>> 13)) | 0) + (w11 >>> 26)) | 0;
    w11 &= 0x3ffffff;
    /* k = 12 */
    lo = Math.imul(al9, bl3);
    mid = Math.imul(al9, bh3);
    mid = (mid + Math.imul(ah9, bl3)) | 0;
    hi = Math.imul(ah9, bh3);
    lo = (lo + Math.imul(al8, bl4)) | 0;
    mid = (mid + Math.imul(al8, bh4)) | 0;
    mid = (mid + Math.imul(ah8, bl4)) | 0;
    hi = (hi + Math.imul(ah8, bh4)) | 0;
    lo = (lo + Math.imul(al7, bl5)) | 0;
    mid = (mid + Math.imul(al7, bh5)) | 0;
    mid = (mid + Math.imul(ah7, bl5)) | 0;
    hi = (hi + Math.imul(ah7, bh5)) | 0;
    lo = (lo + Math.imul(al6, bl6)) | 0;
    mid = (mid + Math.imul(al6, bh6)) | 0;
    mid = (mid + Math.imul(ah6, bl6)) | 0;
    hi = (hi + Math.imul(ah6, bh6)) | 0;
    lo = (lo + Math.imul(al5, bl7)) | 0;
    mid = (mid + Math.imul(al5, bh7)) | 0;
    mid = (mid + Math.imul(ah5, bl7)) | 0;
    hi = (hi + Math.imul(ah5, bh7)) | 0;
    lo = (lo + Math.imul(al4, bl8)) | 0;
    mid = (mid + Math.imul(al4, bh8)) | 0;
    mid = (mid + Math.imul(ah4, bl8)) | 0;
    hi = (hi + Math.imul(ah4, bh8)) | 0;
    lo = (lo + Math.imul(al3, bl9)) | 0;
    mid = (mid + Math.imul(al3, bh9)) | 0;
    mid = (mid + Math.imul(ah3, bl9)) | 0;
    hi = (hi + Math.imul(ah3, bh9)) | 0;
    var w12 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
    c = (((hi + (mid >>> 13)) | 0) + (w12 >>> 26)) | 0;
    w12 &= 0x3ffffff;
    /* k = 13 */
    lo = Math.imul(al9, bl4);
    mid = Math.imul(al9, bh4);
    mid = (mid + Math.imul(ah9, bl4)) | 0;
    hi = Math.imul(ah9, bh4);
    lo = (lo + Math.imul(al8, bl5)) | 0;
    mid = (mid + Math.imul(al8, bh5)) | 0;
    mid = (mid + Math.imul(ah8, bl5)) | 0;
    hi = (hi + Math.imul(ah8, bh5)) | 0;
    lo = (lo + Math.imul(al7, bl6)) | 0;
    mid = (mid + Math.imul(al7, bh6)) | 0;
    mid = (mid + Math.imul(ah7, bl6)) | 0;
    hi = (hi + Math.imul(ah7, bh6)) | 0;
    lo = (lo + Math.imul(al6, bl7)) | 0;
    mid = (mid + Math.imul(al6, bh7)) | 0;
    mid = (mid + Math.imul(ah6, bl7)) | 0;
    hi = (hi + Math.imul(ah6, bh7)) | 0;
    lo = (lo + Math.imul(al5, bl8)) | 0;
    mid = (mid + Math.imul(al5, bh8)) | 0;
    mid = (mid + Math.imul(ah5, bl8)) | 0;
    hi = (hi + Math.imul(ah5, bh8)) | 0;
    lo = (lo + Math.imul(al4, bl9)) | 0;
    mid = (mid + Math.imul(al4, bh9)) | 0;
    mid = (mid + Math.imul(ah4, bl9)) | 0;
    hi = (hi + Math.imul(ah4, bh9)) | 0;
    var w13 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
    c = (((hi + (mid >>> 13)) | 0) + (w13 >>> 26)) | 0;
    w13 &= 0x3ffffff;
    /* k = 14 */
    lo = Math.imul(al9, bl5);
    mid = Math.imul(al9, bh5);
    mid = (mid + Math.imul(ah9, bl5)) | 0;
    hi = Math.imul(ah9, bh5);
    lo = (lo + Math.imul(al8, bl6)) | 0;
    mid = (mid + Math.imul(al8, bh6)) | 0;
    mid = (mid + Math.imul(ah8, bl6)) | 0;
    hi = (hi + Math.imul(ah8, bh6)) | 0;
    lo = (lo + Math.imul(al7, bl7)) | 0;
    mid = (mid + Math.imul(al7, bh7)) | 0;
    mid = (mid + Math.imul(ah7, bl7)) | 0;
    hi = (hi + Math.imul(ah7, bh7)) | 0;
    lo = (lo + Math.imul(al6, bl8)) | 0;
    mid = (mid + Math.imul(al6, bh8)) | 0;
    mid = (mid + Math.imul(ah6, bl8)) | 0;
    hi = (hi + Math.imul(ah6, bh8)) | 0;
    lo = (lo + Math.imul(al5, bl9)) | 0;
    mid = (mid + Math.imul(al5, bh9)) | 0;
    mid = (mid + Math.imul(ah5, bl9)) | 0;
    hi = (hi + Math.imul(ah5, bh9)) | 0;
    var w14 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
    c = (((hi + (mid >>> 13)) | 0) + (w14 >>> 26)) | 0;
    w14 &= 0x3ffffff;
    /* k = 15 */
    lo = Math.imul(al9, bl6);
    mid = Math.imul(al9, bh6);
    mid = (mid + Math.imul(ah9, bl6)) | 0;
    hi = Math.imul(ah9, bh6);
    lo = (lo + Math.imul(al8, bl7)) | 0;
    mid = (mid + Math.imul(al8, bh7)) | 0;
    mid = (mid + Math.imul(ah8, bl7)) | 0;
    hi = (hi + Math.imul(ah8, bh7)) | 0;
    lo = (lo + Math.imul(al7, bl8)) | 0;
    mid = (mid + Math.imul(al7, bh8)) | 0;
    mid = (mid + Math.imul(ah7, bl8)) | 0;
    hi = (hi + Math.imul(ah7, bh8)) | 0;
    lo = (lo + Math.imul(al6, bl9)) | 0;
    mid = (mid + Math.imul(al6, bh9)) | 0;
    mid = (mid + Math.imul(ah6, bl9)) | 0;
    hi = (hi + Math.imul(ah6, bh9)) | 0;
    var w15 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
    c = (((hi + (mid >>> 13)) | 0) + (w15 >>> 26)) | 0;
    w15 &= 0x3ffffff;
    /* k = 16 */
    lo = Math.imul(al9, bl7);
    mid = Math.imul(al9, bh7);
    mid = (mid + Math.imul(ah9, bl7)) | 0;
    hi = Math.imul(ah9, bh7);
    lo = (lo + Math.imul(al8, bl8)) | 0;
    mid = (mid + Math.imul(al8, bh8)) | 0;
    mid = (mid + Math.imul(ah8, bl8)) | 0;
    hi = (hi + Math.imul(ah8, bh8)) | 0;
    lo = (lo + Math.imul(al7, bl9)) | 0;
    mid = (mid + Math.imul(al7, bh9)) | 0;
    mid = (mid + Math.imul(ah7, bl9)) | 0;
    hi = (hi + Math.imul(ah7, bh9)) | 0;
    var w16 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
    c = (((hi + (mid >>> 13)) | 0) + (w16 >>> 26)) | 0;
    w16 &= 0x3ffffff;
    /* k = 17 */
    lo = Math.imul(al9, bl8);
    mid = Math.imul(al9, bh8);
    mid = (mid + Math.imul(ah9, bl8)) | 0;
    hi = Math.imul(ah9, bh8);
    lo = (lo + Math.imul(al8, bl9)) | 0;
    mid = (mid + Math.imul(al8, bh9)) | 0;
    mid = (mid + Math.imul(ah8, bl9)) | 0;
    hi = (hi + Math.imul(ah8, bh9)) | 0;
    var w17 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
    c = (((hi + (mid >>> 13)) | 0) + (w17 >>> 26)) | 0;
    w17 &= 0x3ffffff;
    /* k = 18 */
    lo = Math.imul(al9, bl9);
    mid = Math.imul(al9, bh9);
    mid = (mid + Math.imul(ah9, bl9)) | 0;
    hi = Math.imul(ah9, bh9);
    var w18 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
    c = (((hi + (mid >>> 13)) | 0) + (w18 >>> 26)) | 0;
    w18 &= 0x3ffffff;
    o[0] = w0;
    o[1] = w1;
    o[2] = w2;
    o[3] = w3;
    o[4] = w4;
    o[5] = w5;
    o[6] = w6;
    o[7] = w7;
    o[8] = w8;
    o[9] = w9;
    o[10] = w10;
    o[11] = w11;
    o[12] = w12;
    o[13] = w13;
    o[14] = w14;
    o[15] = w15;
    o[16] = w16;
    o[17] = w17;
    o[18] = w18;
    if (c !== 0) {
      o[19] = c;
      out.length++;
    }
    return out;
  };

  // Polyfill comb
  if (!Math.imul) {
    comb10MulTo = smallMulTo;
  }

  function bigMulTo (self, num, out) {
    out.negative = num.negative ^ self.negative;
    out.length = self.length + num.length;

    var carry = 0;
    var hncarry = 0;
    for (var k = 0; k < out.length - 1; k++) {
      // Sum all words with the same `i + j = k` and accumulate `ncarry`,
      // note that ncarry could be >= 0x3ffffff
      var ncarry = hncarry;
      hncarry = 0;
      var rword = carry & 0x3ffffff;
      var maxJ = Math.min(k, num.length - 1);
      for (var j = Math.max(0, k - self.length + 1); j <= maxJ; j++) {
        var i = k - j;
        var a = self.words[i] | 0;
        var b = num.words[j] | 0;
        var r = a * b;

        var lo = r & 0x3ffffff;
        ncarry = (ncarry + ((r / 0x4000000) | 0)) | 0;
        lo = (lo + rword) | 0;
        rword = lo & 0x3ffffff;
        ncarry = (ncarry + (lo >>> 26)) | 0;

        hncarry += ncarry >>> 26;
        ncarry &= 0x3ffffff;
      }
      out.words[k] = rword;
      carry = ncarry;
      ncarry = hncarry;
    }
    if (carry !== 0) {
      out.words[k] = carry;
    } else {
      out.length--;
    }

    return out.strip();
  }

  function jumboMulTo (self, num, out) {
    var fftm = new FFTM();
    return fftm.mulp(self, num, out);
  }

  BN.prototype.mulTo = function mulTo (num, out) {
    var res;
    var len = this.length + num.length;
    if (this.length === 10 && num.length === 10) {
      res = comb10MulTo(this, num, out);
    } else if (len < 63) {
      res = smallMulTo(this, num, out);
    } else if (len < 1024) {
      res = bigMulTo(this, num, out);
    } else {
      res = jumboMulTo(this, num, out);
    }

    return res;
  };

  // Cooley-Tukey algorithm for FFT
  // slightly revisited to rely on looping instead of recursion

  function FFTM (x, y) {
    this.x = x;
    this.y = y;
  }

  FFTM.prototype.makeRBT = function makeRBT (N) {
    var t = new Array(N);
    var l = BN.prototype._countBits(N) - 1;
    for (var i = 0; i < N; i++) {
      t[i] = this.revBin(i, l, N);
    }

    return t;
  };

  // Returns binary-reversed representation of `x`
  FFTM.prototype.revBin = function revBin (x, l, N) {
    if (x === 0 || x === N - 1) return x;

    var rb = 0;
    for (var i = 0; i < l; i++) {
      rb |= (x & 1) << (l - i - 1);
      x >>= 1;
    }

    return rb;
  };

  // Performs "tweedling" phase, therefore 'emulating'
  // behaviour of the recursive algorithm
  FFTM.prototype.permute = function permute (rbt, rws, iws, rtws, itws, N) {
    for (var i = 0; i < N; i++) {
      rtws[i] = rws[rbt[i]];
      itws[i] = iws[rbt[i]];
    }
  };

  FFTM.prototype.transform = function transform (rws, iws, rtws, itws, N, rbt) {
    this.permute(rbt, rws, iws, rtws, itws, N);

    for (var s = 1; s < N; s <<= 1) {
      var l = s << 1;

      var rtwdf = Math.cos(2 * Math.PI / l);
      var itwdf = Math.sin(2 * Math.PI / l);

      for (var p = 0; p < N; p += l) {
        var rtwdf_ = rtwdf;
        var itwdf_ = itwdf;

        for (var j = 0; j < s; j++) {
          var re = rtws[p + j];
          var ie = itws[p + j];

          var ro = rtws[p + j + s];
          var io = itws[p + j + s];

          var rx = rtwdf_ * ro - itwdf_ * io;

          io = rtwdf_ * io + itwdf_ * ro;
          ro = rx;

          rtws[p + j] = re + ro;
          itws[p + j] = ie + io;

          rtws[p + j + s] = re - ro;
          itws[p + j + s] = ie - io;

          /* jshint maxdepth : false */
          if (j !== l) {
            rx = rtwdf * rtwdf_ - itwdf * itwdf_;

            itwdf_ = rtwdf * itwdf_ + itwdf * rtwdf_;
            rtwdf_ = rx;
          }
        }
      }
    }
  };

  FFTM.prototype.guessLen13b = function guessLen13b (n, m) {
    var N = Math.max(m, n) | 1;
    var odd = N & 1;
    var i = 0;
    for (N = N / 2 | 0; N; N = N >>> 1) {
      i++;
    }

    return 1 << i + 1 + odd;
  };

  FFTM.prototype.conjugate = function conjugate (rws, iws, N) {
    if (N <= 1) return;

    for (var i = 0; i < N / 2; i++) {
      var t = rws[i];

      rws[i] = rws[N - i - 1];
      rws[N - i - 1] = t;

      t = iws[i];

      iws[i] = -iws[N - i - 1];
      iws[N - i - 1] = -t;
    }
  };

  FFTM.prototype.normalize13b = function normalize13b (ws, N) {
    var carry = 0;
    for (var i = 0; i < N / 2; i++) {
      var w = Math.round(ws[2 * i + 1] / N) * 0x2000 +
        Math.round(ws[2 * i] / N) +
        carry;

      ws[i] = w & 0x3ffffff;

      if (w < 0x4000000) {
        carry = 0;
      } else {
        carry = w / 0x4000000 | 0;
      }
    }

    return ws;
  };

  FFTM.prototype.convert13b = function convert13b (ws, len, rws, N) {
    var carry = 0;
    for (var i = 0; i < len; i++) {
      carry = carry + (ws[i] | 0);

      rws[2 * i] = carry & 0x1fff; carry = carry >>> 13;
      rws[2 * i + 1] = carry & 0x1fff; carry = carry >>> 13;
    }

    // Pad with zeroes
    for (i = 2 * len; i < N; ++i) {
      rws[i] = 0;
    }

    assert(carry === 0);
    assert((carry & ~0x1fff) === 0);
  };

  FFTM.prototype.stub = function stub (N) {
    var ph = new Array(N);
    for (var i = 0; i < N; i++) {
      ph[i] = 0;
    }

    return ph;
  };

  FFTM.prototype.mulp = function mulp (x, y, out) {
    var N = 2 * this.guessLen13b(x.length, y.length);

    var rbt = this.makeRBT(N);

    var _ = this.stub(N);

    var rws = new Array(N);
    var rwst = new Array(N);
    var iwst = new Array(N);

    var nrws = new Array(N);
    var nrwst = new Array(N);
    var niwst = new Array(N);

    var rmws = out.words;
    rmws.length = N;

    this.convert13b(x.words, x.length, rws, N);
    this.convert13b(y.words, y.length, nrws, N);

    this.transform(rws, _, rwst, iwst, N, rbt);
    this.transform(nrws, _, nrwst, niwst, N, rbt);

    for (var i = 0; i < N; i++) {
      var rx = rwst[i] * nrwst[i] - iwst[i] * niwst[i];
      iwst[i] = rwst[i] * niwst[i] + iwst[i] * nrwst[i];
      rwst[i] = rx;
    }

    this.conjugate(rwst, iwst, N);
    this.transform(rwst, iwst, rmws, _, N, rbt);
    this.conjugate(rmws, _, N);
    this.normalize13b(rmws, N);

    out.negative = x.negative ^ y.negative;
    out.length = x.length + y.length;
    return out.strip();
  };

  // Multiply `this` by `num`
  BN.prototype.mul = function mul (num) {
    var out = new BN(null);
    out.words = new Array(this.length + num.length);
    return this.mulTo(num, out);
  };

  // Multiply employing FFT
  BN.prototype.mulf = function mulf (num) {
    var out = new BN(null);
    out.words = new Array(this.length + num.length);
    return jumboMulTo(this, num, out);
  };

  // In-place Multiplication
  BN.prototype.imul = function imul (num) {
    return this.clone().mulTo(num, this);
  };

  BN.prototype.imuln = function imuln (num) {
    assert(typeof num === 'number');
    assert(num < 0x4000000);

    // Carry
    var carry = 0;
    for (var i = 0; i < this.length; i++) {
      var w = (this.words[i] | 0) * num;
      var lo = (w & 0x3ffffff) + (carry & 0x3ffffff);
      carry >>= 26;
      carry += (w / 0x4000000) | 0;
      // NOTE: lo is 27bit maximum
      carry += lo >>> 26;
      this.words[i] = lo & 0x3ffffff;
    }

    if (carry !== 0) {
      this.words[i] = carry;
      this.length++;
    }

    return this;
  };

  BN.prototype.muln = function muln (num) {
    return this.clone().imuln(num);
  };

  // `this` * `this`
  BN.prototype.sqr = function sqr () {
    return this.mul(this);
  };

  // `this` * `this` in-place
  BN.prototype.isqr = function isqr () {
    return this.imul(this.clone());
  };

  // Math.pow(`this`, `num`)
  BN.prototype.pow = function pow (num) {
    var w = toBitArray(num);
    if (w.length === 0) return new BN(1);

    // Skip leading zeroes
    var res = this;
    for (var i = 0; i < w.length; i++, res = res.sqr()) {
      if (w[i] !== 0) break;
    }

    if (++i < w.length) {
      for (var q = res.sqr(); i < w.length; i++, q = q.sqr()) {
        if (w[i] === 0) continue;

        res = res.mul(q);
      }
    }

    return res;
  };

  // Shift-left in-place
  BN.prototype.iushln = function iushln (bits) {
    assert(typeof bits === 'number' && bits >= 0);
    var r = bits % 26;
    var s = (bits - r) / 26;
    var carryMask = (0x3ffffff >>> (26 - r)) << (26 - r);
    var i;

    if (r !== 0) {
      var carry = 0;

      for (i = 0; i < this.length; i++) {
        var newCarry = this.words[i] & carryMask;
        var c = ((this.words[i] | 0) - newCarry) << r;
        this.words[i] = c | carry;
        carry = newCarry >>> (26 - r);
      }

      if (carry) {
        this.words[i] = carry;
        this.length++;
      }
    }

    if (s !== 0) {
      for (i = this.length - 1; i >= 0; i--) {
        this.words[i + s] = this.words[i];
      }

      for (i = 0; i < s; i++) {
        this.words[i] = 0;
      }

      this.length += s;
    }

    return this.strip();
  };

  BN.prototype.ishln = function ishln (bits) {
    // TODO(indutny): implement me
    assert(this.negative === 0);
    return this.iushln(bits);
  };

  // Shift-right in-place
  // NOTE: `hint` is a lowest bit before trailing zeroes
  // NOTE: if `extended` is present - it will be filled with destroyed bits
  BN.prototype.iushrn = function iushrn (bits, hint, extended) {
    assert(typeof bits === 'number' && bits >= 0);
    var h;
    if (hint) {
      h = (hint - (hint % 26)) / 26;
    } else {
      h = 0;
    }

    var r = bits % 26;
    var s = Math.min((bits - r) / 26, this.length);
    var mask = 0x3ffffff ^ ((0x3ffffff >>> r) << r);
    var maskedWords = extended;

    h -= s;
    h = Math.max(0, h);

    // Extended mode, copy masked part
    if (maskedWords) {
      for (var i = 0; i < s; i++) {
        maskedWords.words[i] = this.words[i];
      }
      maskedWords.length = s;
    }

    if (s === 0) {
      // No-op, we should not move anything at all
    } else if (this.length > s) {
      this.length -= s;
      for (i = 0; i < this.length; i++) {
        this.words[i] = this.words[i + s];
      }
    } else {
      this.words[0] = 0;
      this.length = 1;
    }

    var carry = 0;
    for (i = this.length - 1; i >= 0 && (carry !== 0 || i >= h); i--) {
      var word = this.words[i] | 0;
      this.words[i] = (carry << (26 - r)) | (word >>> r);
      carry = word & mask;
    }

    // Push carried bits as a mask
    if (maskedWords && carry !== 0) {
      maskedWords.words[maskedWords.length++] = carry;
    }

    if (this.length === 0) {
      this.words[0] = 0;
      this.length = 1;
    }

    return this.strip();
  };

  BN.prototype.ishrn = function ishrn (bits, hint, extended) {
    // TODO(indutny): implement me
    assert(this.negative === 0);
    return this.iushrn(bits, hint, extended);
  };

  // Shift-left
  BN.prototype.shln = function shln (bits) {
    return this.clone().ishln(bits);
  };

  BN.prototype.ushln = function ushln (bits) {
    return this.clone().iushln(bits);
  };

  // Shift-right
  BN.prototype.shrn = function shrn (bits) {
    return this.clone().ishrn(bits);
  };

  BN.prototype.ushrn = function ushrn (bits) {
    return this.clone().iushrn(bits);
  };

  // Test if n bit is set
  BN.prototype.testn = function testn (bit) {
    assert(typeof bit === 'number' && bit >= 0);
    var r = bit % 26;
    var s = (bit - r) / 26;
    var q = 1 << r;

    // Fast case: bit is much higher than all existing words
    if (this.length <= s) return false;

    // Check bit and return
    var w = this.words[s];

    return !!(w & q);
  };

  // Return only lowers bits of number (in-place)
  BN.prototype.imaskn = function imaskn (bits) {
    assert(typeof bits === 'number' && bits >= 0);
    var r = bits % 26;
    var s = (bits - r) / 26;

    assert(this.negative === 0, 'imaskn works only with positive numbers');

    if (this.length <= s) {
      return this;
    }

    if (r !== 0) {
      s++;
    }
    this.length = Math.min(s, this.length);

    if (r !== 0) {
      var mask = 0x3ffffff ^ ((0x3ffffff >>> r) << r);
      this.words[this.length - 1] &= mask;
    }

    return this.strip();
  };

  // Return only lowers bits of number
  BN.prototype.maskn = function maskn (bits) {
    return this.clone().imaskn(bits);
  };

  // Add plain number `num` to `this`
  BN.prototype.iaddn = function iaddn (num) {
    assert(typeof num === 'number');
    assert(num < 0x4000000);
    if (num < 0) return this.isubn(-num);

    // Possible sign change
    if (this.negative !== 0) {
      if (this.length === 1 && (this.words[0] | 0) < num) {
        this.words[0] = num - (this.words[0] | 0);
        this.negative = 0;
        return this;
      }

      this.negative = 0;
      this.isubn(num);
      this.negative = 1;
      return this;
    }

    // Add without checks
    return this._iaddn(num);
  };

  BN.prototype._iaddn = function _iaddn (num) {
    this.words[0] += num;

    // Carry
    for (var i = 0; i < this.length && this.words[i] >= 0x4000000; i++) {
      this.words[i] -= 0x4000000;
      if (i === this.length - 1) {
        this.words[i + 1] = 1;
      } else {
        this.words[i + 1]++;
      }
    }
    this.length = Math.max(this.length, i + 1);

    return this;
  };

  // Subtract plain number `num` from `this`
  BN.prototype.isubn = function isubn (num) {
    assert(typeof num === 'number');
    assert(num < 0x4000000);
    if (num < 0) return this.iaddn(-num);

    if (this.negative !== 0) {
      this.negative = 0;
      this.iaddn(num);
      this.negative = 1;
      return this;
    }

    this.words[0] -= num;

    if (this.length === 1 && this.words[0] < 0) {
      this.words[0] = -this.words[0];
      this.negative = 1;
    } else {
      // Carry
      for (var i = 0; i < this.length && this.words[i] < 0; i++) {
        this.words[i] += 0x4000000;
        this.words[i + 1] -= 1;
      }
    }

    return this.strip();
  };

  BN.prototype.addn = function addn (num) {
    return this.clone().iaddn(num);
  };

  BN.prototype.subn = function subn (num) {
    return this.clone().isubn(num);
  };

  BN.prototype.iabs = function iabs () {
    this.negative = 0;

    return this;
  };

  BN.prototype.abs = function abs () {
    return this.clone().iabs();
  };

  BN.prototype._ishlnsubmul = function _ishlnsubmul (num, mul, shift) {
    var len = num.length + shift;
    var i;

    this._expand(len);

    var w;
    var carry = 0;
    for (i = 0; i < num.length; i++) {
      w = (this.words[i + shift] | 0) + carry;
      var right = (num.words[i] | 0) * mul;
      w -= right & 0x3ffffff;
      carry = (w >> 26) - ((right / 0x4000000) | 0);
      this.words[i + shift] = w & 0x3ffffff;
    }
    for (; i < this.length - shift; i++) {
      w = (this.words[i + shift] | 0) + carry;
      carry = w >> 26;
      this.words[i + shift] = w & 0x3ffffff;
    }

    if (carry === 0) return this.strip();

    // Subtraction overflow
    assert(carry === -1);
    carry = 0;
    for (i = 0; i < this.length; i++) {
      w = -(this.words[i] | 0) + carry;
      carry = w >> 26;
      this.words[i] = w & 0x3ffffff;
    }
    this.negative = 1;

    return this.strip();
  };

  BN.prototype._wordDiv = function _wordDiv (num, mode) {
    var shift = this.length - num.length;

    var a = this.clone();
    var b = num;

    // Normalize
    var bhi = b.words[b.length - 1] | 0;
    var bhiBits = this._countBits(bhi);
    shift = 26 - bhiBits;
    if (shift !== 0) {
      b = b.ushln(shift);
      a.iushln(shift);
      bhi = b.words[b.length - 1] | 0;
    }

    // Initialize quotient
    var m = a.length - b.length;
    var q;

    if (mode !== 'mod') {
      q = new BN(null);
      q.length = m + 1;
      q.words = new Array(q.length);
      for (var i = 0; i < q.length; i++) {
        q.words[i] = 0;
      }
    }

    var diff = a.clone()._ishlnsubmul(b, 1, m);
    if (diff.negative === 0) {
      a = diff;
      if (q) {
        q.words[m] = 1;
      }
    }

    for (var j = m - 1; j >= 0; j--) {
      var qj = (a.words[b.length + j] | 0) * 0x4000000 +
        (a.words[b.length + j - 1] | 0);

      // NOTE: (qj / bhi) is (0x3ffffff * 0x4000000 + 0x3ffffff) / 0x2000000 max
      // (0x7ffffff)
      qj = Math.min((qj / bhi) | 0, 0x3ffffff);

      a._ishlnsubmul(b, qj, j);
      while (a.negative !== 0) {
        qj--;
        a.negative = 0;
        a._ishlnsubmul(b, 1, j);
        if (!a.isZero()) {
          a.negative ^= 1;
        }
      }
      if (q) {
        q.words[j] = qj;
      }
    }
    if (q) {
      q.strip();
    }
    a.strip();

    // Denormalize
    if (mode !== 'div' && shift !== 0) {
      a.iushrn(shift);
    }

    return {
      div: q || null,
      mod: a
    };
  };

  // NOTE: 1) `mode` can be set to `mod` to request mod only,
  //       to `div` to request div only, or be absent to
  //       request both div & mod
  //       2) `positive` is true if unsigned mod is requested
  BN.prototype.divmod = function divmod (num, mode, positive) {
    assert(!num.isZero());

    if (this.isZero()) {
      return {
        div: new BN(0),
        mod: new BN(0)
      };
    }

    var div, mod, res;
    if (this.negative !== 0 && num.negative === 0) {
      res = this.neg().divmod(num, mode);

      if (mode !== 'mod') {
        div = res.div.neg();
      }

      if (mode !== 'div') {
        mod = res.mod.neg();
        if (positive && mod.negative !== 0) {
          mod.iadd(num);
        }
      }

      return {
        div: div,
        mod: mod
      };
    }

    if (this.negative === 0 && num.negative !== 0) {
      res = this.divmod(num.neg(), mode);

      if (mode !== 'mod') {
        div = res.div.neg();
      }

      return {
        div: div,
        mod: res.mod
      };
    }

    if ((this.negative & num.negative) !== 0) {
      res = this.neg().divmod(num.neg(), mode);

      if (mode !== 'div') {
        mod = res.mod.neg();
        if (positive && mod.negative !== 0) {
          mod.isub(num);
        }
      }

      return {
        div: res.div,
        mod: mod
      };
    }

    // Both numbers are positive at this point

    // Strip both numbers to approximate shift value
    if (num.length > this.length || this.cmp(num) < 0) {
      return {
        div: new BN(0),
        mod: this
      };
    }

    // Very short reduction
    if (num.length === 1) {
      if (mode === 'div') {
        return {
          div: this.divn(num.words[0]),
          mod: null
        };
      }

      if (mode === 'mod') {
        return {
          div: null,
          mod: new BN(this.modn(num.words[0]))
        };
      }

      return {
        div: this.divn(num.words[0]),
        mod: new BN(this.modn(num.words[0]))
      };
    }

    return this._wordDiv(num, mode);
  };

  // Find `this` / `num`
  BN.prototype.div = function div (num) {
    return this.divmod(num, 'div', false).div;
  };

  // Find `this` % `num`
  BN.prototype.mod = function mod (num) {
    return this.divmod(num, 'mod', false).mod;
  };

  BN.prototype.umod = function umod (num) {
    return this.divmod(num, 'mod', true).mod;
  };

  // Find Round(`this` / `num`)
  BN.prototype.divRound = function divRound (num) {
    var dm = this.divmod(num);

    // Fast case - exact division
    if (dm.mod.isZero()) return dm.div;

    var mod = dm.div.negative !== 0 ? dm.mod.isub(num) : dm.mod;

    var half = num.ushrn(1);
    var r2 = num.andln(1);
    var cmp = mod.cmp(half);

    // Round down
    if (cmp < 0 || r2 === 1 && cmp === 0) return dm.div;

    // Round up
    return dm.div.negative !== 0 ? dm.div.isubn(1) : dm.div.iaddn(1);
  };

  BN.prototype.modn = function modn (num) {
    assert(num <= 0x3ffffff);
    var p = (1 << 26) % num;

    var acc = 0;
    for (var i = this.length - 1; i >= 0; i--) {
      acc = (p * acc + (this.words[i] | 0)) % num;
    }

    return acc;
  };

  // In-place division by number
  BN.prototype.idivn = function idivn (num) {
    assert(num <= 0x3ffffff);

    var carry = 0;
    for (var i = this.length - 1; i >= 0; i--) {
      var w = (this.words[i] | 0) + carry * 0x4000000;
      this.words[i] = (w / num) | 0;
      carry = w % num;
    }

    return this.strip();
  };

  BN.prototype.divn = function divn (num) {
    return this.clone().idivn(num);
  };

  BN.prototype.egcd = function egcd (p) {
    assert(p.negative === 0);
    assert(!p.isZero());

    var x = this;
    var y = p.clone();

    if (x.negative !== 0) {
      x = x.umod(p);
    } else {
      x = x.clone();
    }

    // A * x + B * y = x
    var A = new BN(1);
    var B = new BN(0);

    // C * x + D * y = y
    var C = new BN(0);
    var D = new BN(1);

    var g = 0;

    while (x.isEven() && y.isEven()) {
      x.iushrn(1);
      y.iushrn(1);
      ++g;
    }

    var yp = y.clone();
    var xp = x.clone();

    while (!x.isZero()) {
      for (var i = 0, im = 1; (x.words[0] & im) === 0 && i < 26; ++i, im <<= 1);
      if (i > 0) {
        x.iushrn(i);
        while (i-- > 0) {
          if (A.isOdd() || B.isOdd()) {
            A.iadd(yp);
            B.isub(xp);
          }

          A.iushrn(1);
          B.iushrn(1);
        }
      }

      for (var j = 0, jm = 1; (y.words[0] & jm) === 0 && j < 26; ++j, jm <<= 1);
      if (j > 0) {
        y.iushrn(j);
        while (j-- > 0) {
          if (C.isOdd() || D.isOdd()) {
            C.iadd(yp);
            D.isub(xp);
          }

          C.iushrn(1);
          D.iushrn(1);
        }
      }

      if (x.cmp(y) >= 0) {
        x.isub(y);
        A.isub(C);
        B.isub(D);
      } else {
        y.isub(x);
        C.isub(A);
        D.isub(B);
      }
    }

    return {
      a: C,
      b: D,
      gcd: y.iushln(g)
    };
  };

  // This is reduced incarnation of the binary EEA
  // above, designated to invert members of the
  // _prime_ fields F(p) at a maximal speed
  BN.prototype._invmp = function _invmp (p) {
    assert(p.negative === 0);
    assert(!p.isZero());

    var a = this;
    var b = p.clone();

    if (a.negative !== 0) {
      a = a.umod(p);
    } else {
      a = a.clone();
    }

    var x1 = new BN(1);
    var x2 = new BN(0);

    var delta = b.clone();

    while (a.cmpn(1) > 0 && b.cmpn(1) > 0) {
      for (var i = 0, im = 1; (a.words[0] & im) === 0 && i < 26; ++i, im <<= 1);
      if (i > 0) {
        a.iushrn(i);
        while (i-- > 0) {
          if (x1.isOdd()) {
            x1.iadd(delta);
          }

          x1.iushrn(1);
        }
      }

      for (var j = 0, jm = 1; (b.words[0] & jm) === 0 && j < 26; ++j, jm <<= 1);
      if (j > 0) {
        b.iushrn(j);
        while (j-- > 0) {
          if (x2.isOdd()) {
            x2.iadd(delta);
          }

          x2.iushrn(1);
        }
      }

      if (a.cmp(b) >= 0) {
        a.isub(b);
        x1.isub(x2);
      } else {
        b.isub(a);
        x2.isub(x1);
      }
    }

    var res;
    if (a.cmpn(1) === 0) {
      res = x1;
    } else {
      res = x2;
    }

    if (res.cmpn(0) < 0) {
      res.iadd(p);
    }

    return res;
  };

  BN.prototype.gcd = function gcd (num) {
    if (this.isZero()) return num.abs();
    if (num.isZero()) return this.abs();

    var a = this.clone();
    var b = num.clone();
    a.negative = 0;
    b.negative = 0;

    // Remove common factor of two
    for (var shift = 0; a.isEven() && b.isEven(); shift++) {
      a.iushrn(1);
      b.iushrn(1);
    }

    do {
      while (a.isEven()) {
        a.iushrn(1);
      }
      while (b.isEven()) {
        b.iushrn(1);
      }

      var r = a.cmp(b);
      if (r < 0) {
        // Swap `a` and `b` to make `a` always bigger than `b`
        var t = a;
        a = b;
        b = t;
      } else if (r === 0 || b.cmpn(1) === 0) {
        break;
      }

      a.isub(b);
    } while (true);

    return b.iushln(shift);
  };

  // Invert number in the field F(num)
  BN.prototype.invm = function invm (num) {
    return this.egcd(num).a.umod(num);
  };

  BN.prototype.isEven = function isEven () {
    return (this.words[0] & 1) === 0;
  };

  BN.prototype.isOdd = function isOdd () {
    return (this.words[0] & 1) === 1;
  };

  // And first word and num
  BN.prototype.andln = function andln (num) {
    return this.words[0] & num;
  };

  // Increment at the bit position in-line
  BN.prototype.bincn = function bincn (bit) {
    assert(typeof bit === 'number');
    var r = bit % 26;
    var s = (bit - r) / 26;
    var q = 1 << r;

    // Fast case: bit is much higher than all existing words
    if (this.length <= s) {
      this._expand(s + 1);
      this.words[s] |= q;
      return this;
    }

    // Add bit and propagate, if needed
    var carry = q;
    for (var i = s; carry !== 0 && i < this.length; i++) {
      var w = this.words[i] | 0;
      w += carry;
      carry = w >>> 26;
      w &= 0x3ffffff;
      this.words[i] = w;
    }
    if (carry !== 0) {
      this.words[i] = carry;
      this.length++;
    }
    return this;
  };

  BN.prototype.isZero = function isZero () {
    return this.length === 1 && this.words[0] === 0;
  };

  BN.prototype.cmpn = function cmpn (num) {
    var negative = num < 0;

    if (this.negative !== 0 && !negative) return -1;
    if (this.negative === 0 && negative) return 1;

    this.strip();

    var res;
    if (this.length > 1) {
      res = 1;
    } else {
      if (negative) {
        num = -num;
      }

      assert(num <= 0x3ffffff, 'Number is too big');

      var w = this.words[0] | 0;
      res = w === num ? 0 : w < num ? -1 : 1;
    }
    if (this.negative !== 0) return -res | 0;
    return res;
  };

  // Compare two numbers and return:
  // 1 - if `this` > `num`
  // 0 - if `this` == `num`
  // -1 - if `this` < `num`
  BN.prototype.cmp = function cmp (num) {
    if (this.negative !== 0 && num.negative === 0) return -1;
    if (this.negative === 0 && num.negative !== 0) return 1;

    var res = this.ucmp(num);
    if (this.negative !== 0) return -res | 0;
    return res;
  };

  // Unsigned comparison
  BN.prototype.ucmp = function ucmp (num) {
    // At this point both numbers have the same sign
    if (this.length > num.length) return 1;
    if (this.length < num.length) return -1;

    var res = 0;
    for (var i = this.length - 1; i >= 0; i--) {
      var a = this.words[i] | 0;
      var b = num.words[i] | 0;

      if (a === b) continue;
      if (a < b) {
        res = -1;
      } else if (a > b) {
        res = 1;
      }
      break;
    }
    return res;
  };

  BN.prototype.gtn = function gtn (num) {
    return this.cmpn(num) === 1;
  };

  BN.prototype.gt = function gt (num) {
    return this.cmp(num) === 1;
  };

  BN.prototype.gten = function gten (num) {
    return this.cmpn(num) >= 0;
  };

  BN.prototype.gte = function gte (num) {
    return this.cmp(num) >= 0;
  };

  BN.prototype.ltn = function ltn (num) {
    return this.cmpn(num) === -1;
  };

  BN.prototype.lt = function lt (num) {
    return this.cmp(num) === -1;
  };

  BN.prototype.lten = function lten (num) {
    return this.cmpn(num) <= 0;
  };

  BN.prototype.lte = function lte (num) {
    return this.cmp(num) <= 0;
  };

  BN.prototype.eqn = function eqn (num) {
    return this.cmpn(num) === 0;
  };

  BN.prototype.eq = function eq (num) {
    return this.cmp(num) === 0;
  };

  //
  // A reduce context, could be using montgomery or something better, depending
  // on the `m` itself.
  //
  BN.red = function red (num) {
    return new Red(num);
  };

  BN.prototype.toRed = function toRed (ctx) {
    assert(!this.red, 'Already a number in reduction context');
    assert(this.negative === 0, 'red works only with positives');
    return ctx.convertTo(this)._forceRed(ctx);
  };

  BN.prototype.fromRed = function fromRed () {
    assert(this.red, 'fromRed works only with numbers in reduction context');
    return this.red.convertFrom(this);
  };

  BN.prototype._forceRed = function _forceRed (ctx) {
    this.red = ctx;
    return this;
  };

  BN.prototype.forceRed = function forceRed (ctx) {
    assert(!this.red, 'Already a number in reduction context');
    return this._forceRed(ctx);
  };

  BN.prototype.redAdd = function redAdd (num) {
    assert(this.red, 'redAdd works only with red numbers');
    return this.red.add(this, num);
  };

  BN.prototype.redIAdd = function redIAdd (num) {
    assert(this.red, 'redIAdd works only with red numbers');
    return this.red.iadd(this, num);
  };

  BN.prototype.redSub = function redSub (num) {
    assert(this.red, 'redSub works only with red numbers');
    return this.red.sub(this, num);
  };

  BN.prototype.redISub = function redISub (num) {
    assert(this.red, 'redISub works only with red numbers');
    return this.red.isub(this, num);
  };

  BN.prototype.redShl = function redShl (num) {
    assert(this.red, 'redShl works only with red numbers');
    return this.red.shl(this, num);
  };

  BN.prototype.redMul = function redMul (num) {
    assert(this.red, 'redMul works only with red numbers');
    this.red._verify2(this, num);
    return this.red.mul(this, num);
  };

  BN.prototype.redIMul = function redIMul (num) {
    assert(this.red, 'redMul works only with red numbers');
    this.red._verify2(this, num);
    return this.red.imul(this, num);
  };

  BN.prototype.redSqr = function redSqr () {
    assert(this.red, 'redSqr works only with red numbers');
    this.red._verify1(this);
    return this.red.sqr(this);
  };

  BN.prototype.redISqr = function redISqr () {
    assert(this.red, 'redISqr works only with red numbers');
    this.red._verify1(this);
    return this.red.isqr(this);
  };

  // Square root over p
  BN.prototype.redSqrt = function redSqrt () {
    assert(this.red, 'redSqrt works only with red numbers');
    this.red._verify1(this);
    return this.red.sqrt(this);
  };

  BN.prototype.redInvm = function redInvm () {
    assert(this.red, 'redInvm works only with red numbers');
    this.red._verify1(this);
    return this.red.invm(this);
  };

  // Return negative clone of `this` % `red modulo`
  BN.prototype.redNeg = function redNeg () {
    assert(this.red, 'redNeg works only with red numbers');
    this.red._verify1(this);
    return this.red.neg(this);
  };

  BN.prototype.redPow = function redPow (num) {
    assert(this.red && !num.red, 'redPow(normalNum)');
    this.red._verify1(this);
    return this.red.pow(this, num);
  };

  // Prime numbers with efficient reduction
  var primes = {
    k256: null,
    p224: null,
    p192: null,
    p25519: null
  };

  // Pseudo-Mersenne prime
  function MPrime (name, p) {
    // P = 2 ^ N - K
    this.name = name;
    this.p = new BN(p, 16);
    this.n = this.p.bitLength();
    this.k = new BN(1).iushln(this.n).isub(this.p);

    this.tmp = this._tmp();
  }

  MPrime.prototype._tmp = function _tmp () {
    var tmp = new BN(null);
    tmp.words = new Array(Math.ceil(this.n / 13));
    return tmp;
  };

  MPrime.prototype.ireduce = function ireduce (num) {
    // Assumes that `num` is less than `P^2`
    // num = HI * (2 ^ N - K) + HI * K + LO = HI * K + LO (mod P)
    var r = num;
    var rlen;

    do {
      this.split(r, this.tmp);
      r = this.imulK(r);
      r = r.iadd(this.tmp);
      rlen = r.bitLength();
    } while (rlen > this.n);

    var cmp = rlen < this.n ? -1 : r.ucmp(this.p);
    if (cmp === 0) {
      r.words[0] = 0;
      r.length = 1;
    } else if (cmp > 0) {
      r.isub(this.p);
    } else {
      if (r.strip !== undefined) {
        // r is BN v4 instance
        r.strip();
      } else {
        // r is BN v5 instance
        r._strip();
      }
    }

    return r;
  };

  MPrime.prototype.split = function split (input, out) {
    input.iushrn(this.n, 0, out);
  };

  MPrime.prototype.imulK = function imulK (num) {
    return num.imul(this.k);
  };

  function K256 () {
    MPrime.call(
      this,
      'k256',
      'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f');
  }
  inherits(K256, MPrime);

  K256.prototype.split = function split (input, output) {
    // 256 = 9 * 26 + 22
    var mask = 0x3fffff;

    var outLen = Math.min(input.length, 9);
    for (var i = 0; i < outLen; i++) {
      output.words[i] = input.words[i];
    }
    output.length = outLen;

    if (input.length <= 9) {
      input.words[0] = 0;
      input.length = 1;
      return;
    }

    // Shift by 9 limbs
    var prev = input.words[9];
    output.words[output.length++] = prev & mask;

    for (i = 10; i < input.length; i++) {
      var next = input.words[i] | 0;
      input.words[i - 10] = ((next & mask) << 4) | (prev >>> 22);
      prev = next;
    }
    prev >>>= 22;
    input.words[i - 10] = prev;
    if (prev === 0 && input.length > 10) {
      input.length -= 10;
    } else {
      input.length -= 9;
    }
  };

  K256.prototype.imulK = function imulK (num) {
    // K = 0x1000003d1 = [ 0x40, 0x3d1 ]
    num.words[num.length] = 0;
    num.words[num.length + 1] = 0;
    num.length += 2;

    // bounded at: 0x40 * 0x3ffffff + 0x3d0 = 0x100000390
    var lo = 0;
    for (var i = 0; i < num.length; i++) {
      var w = num.words[i] | 0;
      lo += w * 0x3d1;
      num.words[i] = lo & 0x3ffffff;
      lo = w * 0x40 + ((lo / 0x4000000) | 0);
    }

    // Fast length reduction
    if (num.words[num.length - 1] === 0) {
      num.length--;
      if (num.words[num.length - 1] === 0) {
        num.length--;
      }
    }
    return num;
  };

  function P224 () {
    MPrime.call(
      this,
      'p224',
      'ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001');
  }
  inherits(P224, MPrime);

  function P192 () {
    MPrime.call(
      this,
      'p192',
      'ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff');
  }
  inherits(P192, MPrime);

  function P25519 () {
    // 2 ^ 255 - 19
    MPrime.call(
      this,
      '25519',
      '7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed');
  }
  inherits(P25519, MPrime);

  P25519.prototype.imulK = function imulK (num) {
    // K = 0x13
    var carry = 0;
    for (var i = 0; i < num.length; i++) {
      var hi = (num.words[i] | 0) * 0x13 + carry;
      var lo = hi & 0x3ffffff;
      hi >>>= 26;

      num.words[i] = lo;
      carry = hi;
    }
    if (carry !== 0) {
      num.words[num.length++] = carry;
    }
    return num;
  };

  // Exported mostly for testing purposes, use plain name instead
  BN._prime = function prime (name) {
    // Cached version of prime
    if (primes[name]) return primes[name];

    var prime;
    if (name === 'k256') {
      prime = new K256();
    } else if (name === 'p224') {
      prime = new P224();
    } else if (name === 'p192') {
      prime = new P192();
    } else if (name === 'p25519') {
      prime = new P25519();
    } else {
      throw new Error('Unknown prime ' + name);
    }
    primes[name] = prime;

    return prime;
  };

  //
  // Base reduction engine
  //
  function Red (m) {
    if (typeof m === 'string') {
      var prime = BN._prime(m);
      this.m = prime.p;
      this.prime = prime;
    } else {
      assert(m.gtn(1), 'modulus must be greater than 1');
      this.m = m;
      this.prime = null;
    }
  }

  Red.prototype._verify1 = function _verify1 (a) {
    assert(a.negative === 0, 'red works only with positives');
    assert(a.red, 'red works only with red numbers');
  };

  Red.prototype._verify2 = function _verify2 (a, b) {
    assert((a.negative | b.negative) === 0, 'red works only with positives');
    assert(a.red && a.red === b.red,
      'red works only with red numbers');
  };

  Red.prototype.imod = function imod (a) {
    if (this.prime) return this.prime.ireduce(a)._forceRed(this);
    return a.umod(this.m)._forceRed(this);
  };

  Red.prototype.neg = function neg (a) {
    if (a.isZero()) {
      return a.clone();
    }

    return this.m.sub(a)._forceRed(this);
  };

  Red.prototype.add = function add (a, b) {
    this._verify2(a, b);

    var res = a.add(b);
    if (res.cmp(this.m) >= 0) {
      res.isub(this.m);
    }
    return res._forceRed(this);
  };

  Red.prototype.iadd = function iadd (a, b) {
    this._verify2(a, b);

    var res = a.iadd(b);
    if (res.cmp(this.m) >= 0) {
      res.isub(this.m);
    }
    return res;
  };

  Red.prototype.sub = function sub (a, b) {
    this._verify2(a, b);

    var res = a.sub(b);
    if (res.cmpn(0) < 0) {
      res.iadd(this.m);
    }
    return res._forceRed(this);
  };

  Red.prototype.isub = function isub (a, b) {
    this._verify2(a, b);

    var res = a.isub(b);
    if (res.cmpn(0) < 0) {
      res.iadd(this.m);
    }
    return res;
  };

  Red.prototype.shl = function shl (a, num) {
    this._verify1(a);
    return this.imod(a.ushln(num));
  };

  Red.prototype.imul = function imul (a, b) {
    this._verify2(a, b);
    return this.imod(a.imul(b));
  };

  Red.prototype.mul = function mul (a, b) {
    this._verify2(a, b);
    return this.imod(a.mul(b));
  };

  Red.prototype.isqr = function isqr (a) {
    return this.imul(a, a.clone());
  };

  Red.prototype.sqr = function sqr (a) {
    return this.mul(a, a);
  };

  Red.prototype.sqrt = function sqrt (a) {
    if (a.isZero()) return a.clone();

    var mod3 = this.m.andln(3);
    assert(mod3 % 2 === 1);

    // Fast case
    if (mod3 === 3) {
      var pow = this.m.add(new BN(1)).iushrn(2);
      return this.pow(a, pow);
    }

    // Tonelli-Shanks algorithm (Totally unoptimized and slow)
    //
    // Find Q and S, that Q * 2 ^ S = (P - 1)
    var q = this.m.subn(1);
    var s = 0;
    while (!q.isZero() && q.andln(1) === 0) {
      s++;
      q.iushrn(1);
    }
    assert(!q.isZero());

    var one = new BN(1).toRed(this);
    var nOne = one.redNeg();

    // Find quadratic non-residue
    // NOTE: Max is such because of generalized Riemann hypothesis.
    var lpow = this.m.subn(1).iushrn(1);
    var z = this.m.bitLength();
    z = new BN(2 * z * z).toRed(this);

    while (this.pow(z, lpow).cmp(nOne) !== 0) {
      z.redIAdd(nOne);
    }

    var c = this.pow(z, q);
    var r = this.pow(a, q.addn(1).iushrn(1));
    var t = this.pow(a, q);
    var m = s;
    while (t.cmp(one) !== 0) {
      var tmp = t;
      for (var i = 0; tmp.cmp(one) !== 0; i++) {
        tmp = tmp.redSqr();
      }
      assert(i < m);
      var b = this.pow(c, new BN(1).iushln(m - i - 1));

      r = r.redMul(b);
      c = b.redSqr();
      t = t.redMul(c);
      m = i;
    }

    return r;
  };

  Red.prototype.invm = function invm (a) {
    var inv = a._invmp(this.m);
    if (inv.negative !== 0) {
      inv.negative = 0;
      return this.imod(inv).redNeg();
    } else {
      return this.imod(inv);
    }
  };

  Red.prototype.pow = function pow (a, num) {
    if (num.isZero()) return new BN(1).toRed(this);
    if (num.cmpn(1) === 0) return a.clone();

    var windowSize = 4;
    var wnd = new Array(1 << windowSize);
    wnd[0] = new BN(1).toRed(this);
    wnd[1] = a;
    for (var i = 2; i < wnd.length; i++) {
      wnd[i] = this.mul(wnd[i - 1], a);
    }

    var res = wnd[0];
    var current = 0;
    var currentLen = 0;
    var start = num.bitLength() % 26;
    if (start === 0) {
      start = 26;
    }

    for (i = num.length - 1; i >= 0; i--) {
      var word = num.words[i];
      for (var j = start - 1; j >= 0; j--) {
        var bit = (word >> j) & 1;
        if (res !== wnd[0]) {
          res = this.sqr(res);
        }

        if (bit === 0 && current === 0) {
          currentLen = 0;
          continue;
        }

        current <<= 1;
        current |= bit;
        currentLen++;
        if (currentLen !== windowSize && (i !== 0 || j !== 0)) continue;

        res = this.mul(res, wnd[current]);
        currentLen = 0;
        current = 0;
      }
      start = 26;
    }

    return res;
  };

  Red.prototype.convertTo = function convertTo (num) {
    var r = num.umod(this.m);

    return r === num ? r.clone() : r;
  };

  Red.prototype.convertFrom = function convertFrom (num) {
    var res = num.clone();
    res.red = null;
    return res;
  };

  //
  // Montgomery method engine
  //

  BN.mont = function mont (num) {
    return new Mont(num);
  };

  function Mont (m) {
    Red.call(this, m);

    this.shift = this.m.bitLength();
    if (this.shift % 26 !== 0) {
      this.shift += 26 - (this.shift % 26);
    }

    this.r = new BN(1).iushln(this.shift);
    this.r2 = this.imod(this.r.sqr());
    this.rinv = this.r._invmp(this.m);

    this.minv = this.rinv.mul(this.r).isubn(1).div(this.m);
    this.minv = this.minv.umod(this.r);
    this.minv = this.r.sub(this.minv);
  }
  inherits(Mont, Red);

  Mont.prototype.convertTo = function convertTo (num) {
    return this.imod(num.ushln(this.shift));
  };

  Mont.prototype.convertFrom = function convertFrom (num) {
    var r = this.imod(num.mul(this.rinv));
    r.red = null;
    return r;
  };

  Mont.prototype.imul = function imul (a, b) {
    if (a.isZero() || b.isZero()) {
      a.words[0] = 0;
      a.length = 1;
      return a;
    }

    var t = a.imul(b);
    var c = t.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m);
    var u = t.isub(c).iushrn(this.shift);
    var res = u;

    if (u.cmp(this.m) >= 0) {
      res = u.isub(this.m);
    } else if (u.cmpn(0) < 0) {
      res = u.iadd(this.m);
    }

    return res._forceRed(this);
  };

  Mont.prototype.mul = function mul (a, b) {
    if (a.isZero() || b.isZero()) return new BN(0)._forceRed(this);

    var t = a.mul(b);
    var c = t.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m);
    var u = t.isub(c).iushrn(this.shift);
    var res = u;
    if (u.cmp(this.m) >= 0) {
      res = u.isub(this.m);
    } else if (u.cmpn(0) < 0) {
      res = u.iadd(this.m);
    }

    return res._forceRed(this);
  };

  Mont.prototype.invm = function invm (a) {
    // (AR)^-1 * R^2 = (A^-1 * R^-1) * R^2 = A^-1 * R
    var res = this.imod(a._invmp(this.m).mul(this.r2));
    return res._forceRed(this);
  };
})( false || module, this);


/***/ }),

/***/ 6204:
/***/ (function(module) {

"use strict";


module.exports = boundary

function boundary (cells) {
  var i, j, k
  var n = cells.length
  var sz = 0
  for (i = 0; i < n; ++i) {
    sz += cells[i].length
  }
  var result = new Array(sz)
  var ptr = 0
  for (i = 0; i < n; ++i) {
    var c = cells[i]
    var d = c.length
    for (j = 0; j < d; ++j) {
      var b = result[ptr++] = new Array(d - 1)
      var p = 0
      for (k = 0; k < d; ++k) {
        if (k === j) {
          continue
        }
        b[p++] = c[k]
      }
      if (j & 1) {
        var tmp = b[1]
        b[1] = b[0]
        b[0] = tmp
      }
    }
  }
  return result
}


/***/ }),

/***/ 6867:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

"use strict";


module.exports = boxIntersectWrapper

var pool = __webpack_require__(1888)
var sweep = __webpack_require__(855)
var boxIntersectIter = __webpack_require__(7150)

function boxEmpty(d, box) {
  for(var j=0; j>>1
  if(d <= 0) {
    return
  }

  var retval

  //Convert red boxes
  var redList  = pool.mallocDouble(2*d*n)
  var redIds   = pool.mallocInt32(n)
  n = convertBoxes(red, d, redList, redIds)

  if(n > 0) {
    if(d === 1 && full) {
      //Special case: 1d complete
      sweep.init(n)
      retval = sweep.sweepComplete(
        d, visit,
        0, n, redList, redIds,
        0, n, redList, redIds)
    } else {

      //Convert blue boxes
      var blueList = pool.mallocDouble(2*d*m)
      var blueIds  = pool.mallocInt32(m)
      m = convertBoxes(blue, d, blueList, blueIds)

      if(m > 0) {
        sweep.init(n+m)

        if(d === 1) {
          //Special case: 1d bipartite
          retval = sweep.sweepBipartite(
            d, visit,
            0, n, redList,  redIds,
            0, m, blueList, blueIds)
        } else {
          //General case:  d>1
          retval = boxIntersectIter(
            d, visit,    full,
            n, redList,  redIds,
            m, blueList, blueIds)
        }

        pool.free(blueList)
        pool.free(blueIds)
      }
    }

    pool.free(redList)
    pool.free(redIds)
  }

  return retval
}


var RESULT

function appendItem(i,j) {
  RESULT.push([i,j])
}

function intersectFullArray(x) {
  RESULT = []
  boxIntersect(x, x, appendItem, true)
  return RESULT
}

function intersectBipartiteArray(x, y) {
  RESULT = []
  boxIntersect(x, y, appendItem, false)
  return RESULT
}

//User-friendly wrapper, handle full input and no-visitor cases
function boxIntersectWrapper(arg0, arg1, arg2) {
  switch(arguments.length) {
    case 1:
      return intersectFullArray(arg0)
    case 2:
      if(typeof arg1 === 'function') {
        return boxIntersect(arg0, arg0, arg1, true)
      } else {
        return intersectBipartiteArray(arg0, arg1)
      }
    case 3:
      return boxIntersect(arg0, arg1, arg2, false)
    default:
      throw new Error('box-intersect: Invalid arguments')
  }
}

/***/ }),

/***/ 2455:
/***/ (function(__unused_webpack_module, exports) {

"use strict";


function full() {
  function bruteForceRedFull(d, ax, vv, rs, re, rb, ri, bs, be, bb, bi) {
    var es = 2 * d
    for (var i = rs, rp = es * rs; i < re; ++i, rp += es) {
      var x0 = rb[ax + rp], x1 = rb[ax + rp + d], xi = ri[i]
      Q: for (var j = bs, bp = es * bs; j < be; ++j, bp += es) {
        var y0 = bb[ax + bp], y1 = bb[ax + bp + d], yi = bi[j]
        if (y1 < x0 || x1 < y0) continue
        for (var k = ax + 1; k < d; ++k) {
          var r0 = rb[k + rp], r1 = rb[k + d + rp], b0 = bb[k + bp], b1 = bb[k + d + bp]
          if (r1 < b0 || b1 < r0) continue Q
        }
        var rv = vv(xi, yi)
        if (rv !== void 0) return rv
      }
    }
  }
  function bruteForceBlueFull(d, ax, vv, rs, re, rb, ri, bs, be, bb, bi) {
    var es = 2 * d
    for (var j = bs, bp = es * bs; j < be; ++j, bp += es) {
      var y0 = bb[ax + bp], y1 = bb[ax + bp + d], yi = bi[j]
      Q: for (var i = rs, rp = es * rs; i < re; ++i, rp += es) {
        var x0 = rb[ax + rp], x1 = rb[ax + rp + d], xi = ri[i]
        if (y1 < x0 || x1 < y0) continue
        for (var k = ax + 1; k < d; ++k) {
          var r0 = rb[k + rp], r1 = rb[k + d + rp], b0 = bb[k + bp], b1 = bb[k + d + bp]
          if (r1 < b0 || b1 < r0) continue Q
        }
        var rv = vv(xi, yi)
        if (rv !== void 0) return rv
      }
    }
  }
  function bruteForceFull(d, ax, vv, rs, re, rb, ri, bs, be, bb, bi) {
    if (re - rs > be - bs) {
      return bruteForceRedFull(d, ax, vv, rs, re, rb, ri, bs, be, bb, bi)
    }
    else {
      return bruteForceBlueFull(d, ax, vv, rs, re, rb, ri, bs, be, bb, bi)
    }
  }
  return bruteForceFull
}

function partial() {
  function bruteForceRedFlip(d, ax, vv, rs, re, rb, ri, bs, be, bb, bi) {
    var es = 2 * d
    for (var i = rs, rp = es * rs; i < re; ++i, rp += es) {
      var x0 = rb[ax + rp], x1 = rb[ax + rp + d], xi = ri[i]
      Q: for (var j = bs, bp = es * bs; j < be; ++j, bp += es) {
        var y0 = bb[ax + bp], yi = bi[j]
        if (y0 <= x0 || x1 < y0) continue
        for (var k = ax + 1; k < d; ++k) {
          var r0 = rb[k + rp], r1 = rb[k + d + rp], b0 = bb[k + bp], b1 = bb[k + d + bp]
          if (r1 < b0 || b1 < r0) continue Q
        }
        var rv = vv(yi, xi)
        if (rv !== void 0) return rv
      }
    }
  }
  function bruteForceRed(d, ax, vv, rs, re, rb, ri, bs, be, bb, bi) {
    var es = 2 * d
    for (var i = rs, rp = es * rs; i < re; ++i, rp += es) {
      var x0 = rb[ax + rp], x1 = rb[ax + rp + d], xi = ri[i]
      Q: for (var j = bs, bp = es * bs; j < be; ++j, bp += es) {
        var y0 = bb[ax + bp], yi = bi[j]
        if (y0 < x0 || x1 < y0) continue
        for (var k = ax + 1; k < d; ++k) {
          var r0 = rb[k + rp], r1 = rb[k + d + rp], b0 = bb[k + bp], b1 = bb[k + d + bp]
          if (r1 < b0 || b1 < r0) continue Q
        }
        var rv = vv(xi, yi)
        if (rv !== void 0) return rv
      }
    }
  }
  function bruteForceBlueFlip(d, ax, vv, rs, re, rb, ri, bs, be, bb, bi) {
    var es = 2 * d
    for (var j = bs, bp = es * bs; j < be; ++j, bp += es) {
      var y0 = bb[ax + bp], yi = bi[j]
      Q: for (var i = rs, rp = es * rs; i < re; ++i, rp += es) {
        var x0 = rb[ax + rp], x1 = rb[ax + rp + d], xi = ri[i]
        if (y0 <= x0 || x1 < y0) continue
        for (var k = ax + 1; k < d; ++k) {
          var r0 = rb[k + rp], r1 = rb[k + d + rp], b0 = bb[k + bp], b1 = bb[k + d + bp]
          if (r1 < b0 || b1 < r0) continue Q
        }
        var rv = vv(yi, xi)
        if (rv !== void 0) return rv
      }
    }
  }
  function bruteForceBlue(d, ax, vv, rs, re, rb, ri, bs, be, bb, bi) {
    var es = 2 * d
    for (var j = bs, bp = es * bs; j < be; ++j, bp += es) {
      var y0 = bb[ax + bp], yi = bi[j]
      Q: for (var i = rs, rp = es * rs; i < re; ++i, rp += es) {
        var x0 = rb[ax + rp], x1 = rb[ax + rp + d], xi = ri[i]
        if (y0 < x0 || x1 < y0) continue
        for (var k = ax + 1; k < d; ++k) {
          var r0 = rb[k + rp], r1 = rb[k + d + rp], b0 = bb[k + bp], b1 = bb[k + d + bp]
          if (r1 < b0 || b1 < r0) continue Q
        }
        var rv = vv(xi, yi)
        if (rv !== void 0) return rv
      }
    }
  }
  function bruteForcePartial(d, ax, vv, fp, rs, re, rb, ri, bs, be, bb, bi) {
    if (re - rs > be - bs) {
      if (fp) {
        return bruteForceRedFlip(d, ax, vv, rs, re, rb, ri, bs, be, bb, bi)
      }
      else {
        return bruteForceRed(d, ax, vv, rs, re, rb, ri, bs, be, bb, bi)
      }
    }
    else {
      if (fp) {
        return bruteForceBlueFlip(d, ax, vv, rs, re, rb, ri, bs, be, bb, bi)
      }
      else {
        return bruteForceBlue(d, ax, vv, rs, re, rb, ri, bs, be, bb, bi)
      }
    }
  }
  return bruteForcePartial
}

function bruteForcePlanner(isFull) {
  return isFull ? full() : partial()

}

exports.partial = bruteForcePlanner(false)
exports.full    = bruteForcePlanner(true)

/***/ }),

/***/ 7150:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

"use strict";


module.exports = boxIntersectIter

var pool = __webpack_require__(1888)
var bits = __webpack_require__(8828)
var bruteForce = __webpack_require__(2455)
var bruteForcePartial = bruteForce.partial
var bruteForceFull = bruteForce.full
var sweep = __webpack_require__(855)
var findMedian = __webpack_require__(3545)
var genPartition = __webpack_require__(8105)

//Twiddle parameters
var BRUTE_FORCE_CUTOFF    = 128       //Cut off for brute force search
var SCAN_CUTOFF           = (1<<22)   //Cut off for two way scan
var SCAN_COMPLETE_CUTOFF  = (1<<22)

//Partition functions
var partitionInteriorContainsInterval = genPartition(
  '!(lo>=p0)&&!(p1>=hi)')

var partitionStartEqual = genPartition(
  'lo===p0')

var partitionStartLessThan = genPartition(
  'lo 0) {
    top  -= 1

    var iptr = top * IFRAME_SIZE
    var axis      = BOX_ISTACK[iptr]
    var redStart  = BOX_ISTACK[iptr+1]
    var redEnd    = BOX_ISTACK[iptr+2]
    var blueStart = BOX_ISTACK[iptr+3]
    var blueEnd   = BOX_ISTACK[iptr+4]
    var state     = BOX_ISTACK[iptr+5]

    var dptr = top * DFRAME_SIZE
    var lo        = BOX_DSTACK[dptr]
    var hi        = BOX_DSTACK[dptr+1]

    //Unpack state info
    var flip      = (state & 1)
    var full      = !!(state & 16)

    //Unpack indices
    var red       = xBoxes
    var redIndex  = xIndex
    var blue      = yBoxes
    var blueIndex = yIndex
    if(flip) {
      red         = yBoxes
      redIndex    = yIndex
      blue        = xBoxes
      blueIndex   = xIndex
    }

    if(state & 2) {
      redEnd = partitionStartLessThan(
        d, axis,
        redStart, redEnd, red, redIndex,
        hi)
      if(redStart >= redEnd) {
        continue
      }
    }
    if(state & 4) {
      redStart = partitionEndLessThanEqual(
        d, axis,
        redStart, redEnd, red, redIndex,
        lo)
      if(redStart >= redEnd) {
        continue
      }
    }

    var redCount  = redEnd  - redStart
    var blueCount = blueEnd - blueStart

    if(full) {
      if(d * redCount * (redCount + blueCount) < SCAN_COMPLETE_CUTOFF) {
        retval = sweep.scanComplete(
          d, axis, visit,
          redStart, redEnd, red, redIndex,
          blueStart, blueEnd, blue, blueIndex)
        if(retval !== void 0) {
          return retval
        }
        continue
      }
    } else {
      if(d * Math.min(redCount, blueCount) < BRUTE_FORCE_CUTOFF) {
        //If input small, then use brute force
        retval = bruteForcePartial(
            d, axis, visit, flip,
            redStart,  redEnd,  red,  redIndex,
            blueStart, blueEnd, blue, blueIndex)
        if(retval !== void 0) {
          return retval
        }
        continue
      } else if(d * redCount * blueCount < SCAN_CUTOFF) {
        //If input medium sized, then use sweep and prune
        retval = sweep.scanBipartite(
          d, axis, visit, flip,
          redStart, redEnd, red, redIndex,
          blueStart, blueEnd, blue, blueIndex)
        if(retval !== void 0) {
          return retval
        }
        continue
      }
    }

    //First, find all red intervals whose interior contains (lo,hi)
    var red0 = partitionInteriorContainsInterval(
      d, axis,
      redStart, redEnd, red, redIndex,
      lo, hi)

    //Lower dimensional case
    if(redStart < red0) {

      if(d * (red0 - redStart) < BRUTE_FORCE_CUTOFF) {
        //Special case for small inputs: use brute force
        retval = bruteForceFull(
          d, axis+1, visit,
          redStart, red0, red, redIndex,
          blueStart, blueEnd, blue, blueIndex)
        if(retval !== void 0) {
          return retval
        }
      } else if(axis === d-2) {
        if(flip) {
          retval = sweep.sweepBipartite(
            d, visit,
            blueStart, blueEnd, blue, blueIndex,
            redStart, red0, red, redIndex)
        } else {
          retval = sweep.sweepBipartite(
            d, visit,
            redStart, red0, red, redIndex,
            blueStart, blueEnd, blue, blueIndex)
        }
        if(retval !== void 0) {
          return retval
        }
      } else {
        iterPush(top++,
          axis+1,
          redStart, red0,
          blueStart, blueEnd,
          flip,
          -Infinity, Infinity)
        iterPush(top++,
          axis+1,
          blueStart, blueEnd,
          redStart, red0,
          flip^1,
          -Infinity, Infinity)
      }
    }

    //Divide and conquer phase
    if(red0 < redEnd) {

      //Cut blue into 3 parts:
      //
      //  Points < mid point
      //  Points = mid point
      //  Points > mid point
      //
      var blue0 = findMedian(
        d, axis,
        blueStart, blueEnd, blue, blueIndex)
      var mid = blue[elemSize * blue0 + axis]
      var blue1 = partitionStartEqual(
        d, axis,
        blue0, blueEnd, blue, blueIndex,
        mid)

      //Right case
      if(blue1 < blueEnd) {
        iterPush(top++,
          axis,
          red0, redEnd,
          blue1, blueEnd,
          (flip|4) + (full ? 16 : 0),
          mid, hi)
      }

      //Left case
      if(blueStart < blue0) {
        iterPush(top++,
          axis,
          red0, redEnd,
          blueStart, blue0,
          (flip|2) + (full ? 16 : 0),
          lo, mid)
      }

      //Center case (the hard part)
      if(blue0 + 1 === blue1) {
        //Optimization: Range with exactly 1 point, use a brute force scan
        if(full) {
          retval = onePointFull(
            d, axis, visit,
            red0, redEnd, red, redIndex,
            blue0, blue, blueIndex[blue0])
        } else {
          retval = onePointPartial(
            d, axis, visit, flip,
            red0, redEnd, red, redIndex,
            blue0, blue, blueIndex[blue0])
        }
        if(retval !== void 0) {
          return retval
        }
      } else if(blue0 < blue1) {
        var red1
        if(full) {
          //If full intersection, need to handle special case
          red1 = partitionContainsPoint(
            d, axis,
            red0, redEnd, red, redIndex,
            mid)
          if(red0 < red1) {
            var redX = partitionStartEqual(
              d, axis,
              red0, red1, red, redIndex,
              mid)
            if(axis === d-2) {
              //Degenerate sweep intersection:
              //  [red0, redX] with [blue0, blue1]
              if(red0 < redX) {
                retval = sweep.sweepComplete(
                  d, visit,
                  red0, redX, red, redIndex,
                  blue0, blue1, blue, blueIndex)
                if(retval !== void 0) {
                  return retval
                }
              }

              //Normal sweep intersection:
              //  [redX, red1] with [blue0, blue1]
              if(redX < red1) {
                retval = sweep.sweepBipartite(
                  d, visit,
                  redX, red1, red, redIndex,
                  blue0, blue1, blue, blueIndex)
                if(retval !== void 0) {
                  return retval
                }
              }
            } else {
              if(red0 < redX) {
                iterPush(top++,
                  axis+1,
                  red0, redX,
                  blue0, blue1,
                  16,
                  -Infinity, Infinity)
              }
              if(redX < red1) {
                iterPush(top++,
                  axis+1,
                  redX, red1,
                  blue0, blue1,
                  0,
                  -Infinity, Infinity)
                iterPush(top++,
                  axis+1,
                  blue0, blue1,
                  redX, red1,
                  1,
                  -Infinity, Infinity)
              }
            }
          }
        } else {
          if(flip) {
            red1 = partitionContainsPointProper(
              d, axis,
              red0, redEnd, red, redIndex,
              mid)
          } else {
            red1 = partitionContainsPoint(
              d, axis,
              red0, redEnd, red, redIndex,
              mid)
          }
          if(red0 < red1) {
            if(axis === d-2) {
              if(flip) {
                retval = sweep.sweepBipartite(
                  d, visit,
                  blue0, blue1, blue, blueIndex,
                  red0, red1, red, redIndex)
              } else {
                retval = sweep.sweepBipartite(
                  d, visit,
                  red0, red1, red, redIndex,
                  blue0, blue1, blue, blueIndex)
              }
            } else {
              iterPush(top++,
                axis+1,
                red0, red1,
                blue0, blue1,
                flip,
                -Infinity, Infinity)
              iterPush(top++,
                axis+1,
                blue0, blue1,
                red0, red1,
                flip^1,
                -Infinity, Infinity)
            }
          }
        }
      }
    }
  }
}

/***/ }),

/***/ 3545:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

"use strict";


module.exports = findMedian

var genPartition = __webpack_require__(8105)

var partitionStartLessThan = genPartition('lostart && boxes[ptr+axis] > x;
        --j, ptr-=elemSize) {
      //Swap
      var aPtr = ptr
      var bPtr = ptr+elemSize
      for(var k=0; k>> 1)
  var elemSize = 2*d
  var pivot    = mid
  var value    = boxes[elemSize*mid+axis]

  while(lo < hi) {
    if(hi - lo < PARTITION_THRESHOLD) {
      insertionSort(d, axis, lo, hi, boxes, ids)
      value = boxes[elemSize*mid+axis]
      break
    }

    //Select pivot using median-of-3
    var count  = hi - lo
    var pivot0 = (Math.random()*count+lo)|0
    var value0 = boxes[elemSize*pivot0 + axis]
    var pivot1 = (Math.random()*count+lo)|0
    var value1 = boxes[elemSize*pivot1 + axis]
    var pivot2 = (Math.random()*count+lo)|0
    var value2 = boxes[elemSize*pivot2 + axis]
    if(value0 <= value1) {
      if(value2 >= value1) {
        pivot = pivot1
        value = value1
      } else if(value0 >= value2) {
        pivot = pivot0
        value = value0
      } else {
        pivot = pivot2
        value = value2
      }
    } else {
      if(value1 >= value2) {
        pivot = pivot1
        value = value1
      } else if(value2 >= value0) {
        pivot = pivot0
        value = value0
      } else {
        pivot = pivot2
        value = value2
      }
    }

    //Swap pivot to end of array
    var aPtr = elemSize * (hi-1)
    var bPtr = elemSize * pivot
    for(var i=0; i=p0)&&!(p1>=hi)': lo_lessThan_p0_and_p1_lessThan_hi
}

function genPartition(predicate) {
  return P2F[predicate]
}

// lo===p0
function lo_equal_p0(a, b, c, d, e, f, p0) {
  for (var j = 2 * a, k = j * c, l = k, m = c, n = b, o = a + b, p = c; d > p; ++p, k += j) {
    var lo = e[k + n];
    if (lo === p0) if (m === p) m += 1, l += j; else {
      for (var s = 0; j > s; ++s) {
        var t = e[k + s]; e[k + s] = e[l], e[l++] = t
      } var u = f[p]; f[p] = f[m], f[m++] = u
    }
  }
  return m
}

// lo p; ++p, k += j) {
    var lo = e[k + n];
    if (lo < p0) if (m === p) m += 1, l += j; else {
      for (var s = 0; j > s; ++s) {
        var t = e[k + s]; e[k + s] = e[l], e[l++] = t
      } var u = f[p]; f[p] = f[m], f[m++] = u
    }
  }
  return m
}

// lo<=p0
function lo_lessOrEqual_p0(a, b, c, d, e, f, p0) {
  for (var j = 2 * a, k = j * c, l = k, m = c, n = b, o = a + b, p = c; d > p; ++p, k += j) {
    var hi = e[k + o];
    if (hi <= p0) if (m === p) m += 1, l += j; else {
      for (var s = 0; j > s; ++s) {
        var t = e[k + s]; e[k + s] = e[l], e[l++] = t
      }
      var u = f[p]; f[p] = f[m], f[m++] = u
    }
  } return m
}

// hi<=p0
function hi_lessOrEqual_p0(a, b, c, d, e, f, p0) {
  for (var j = 2 * a, k = j * c, l = k, m = c, n = b, o = a + b, p = c; d > p; ++p, k += j) {
    var hi = e[k + o];
    if (hi <= p0) if (m === p) m += 1, l += j; else {
      for (var s = 0; j > s; ++s) {
        var t = e[k + s]; e[k + s] = e[l], e[l++] = t
      }
      var u = f[p]; f[p] = f[m], f[m++] = u
    }
  }
  return m
}

// lo<=p0&&p0<=hi
function lo_lassOrEqual_p0_and_p0_lessOrEqual_hi(a, b, c, d, e, f, p0) {
  for (var j = 2 * a, k = j * c, l = k, m = c, n = b, o = a + b, p = c; d > p; ++p, k += j) {
    var lo = e[k + n], hi = e[k + o];
    if (lo <= p0 && p0 <= hi) if (m === p) m += 1, l += j; else {
      for (var s = 0; j > s; ++s) {
        var t = e[k + s]; e[k + s] = e[l], e[l++] = t
      }
      var u = f[p]; f[p] = f[m], f[m++] = u
    }
  }
  return m
}

// lo p; ++p, k += j) {
    var lo = e[k + n], hi = e[k + o];
    if (lo < p0 && p0 <= hi) if (m === p) m += 1, l += j; else {
      for (var s = 0; j > s; ++s) {
        var t = e[k + s]; e[k + s] = e[l], e[l++] = t
      }
      var u = f[p]; f[p] = f[m], f[m++] = u
    }
  }
  return m
}

// !(lo>=p0)&&!(p1>=hi)
function lo_lessThan_p0_and_p1_lessThan_hi(a, b, c, d, e, f, p0, p1) {
  for (var j = 2 * a, k = j * c, l = k, m = c, n = b, o = a + b, p = c; d > p; ++p, k += j) {
    var lo = e[k + n], hi = e[k + o];
    if (!(lo >= p0) && !(p1 >= hi)) if (m === p) m += 1, l += j; else {
      for (var s = 0; j > s; ++s) {
        var t = e[k + s]; e[k + s] = e[l], e[l++] = t
      }
      var u = f[p]; f[p] = f[m], f[m++] = u
    }
  }
  return m
}


/***/ }),

/***/ 1811:
/***/ (function(module) {

"use strict";


//This code is extracted from ndarray-sort
//It is inlined here as a temporary workaround

module.exports = wrapper;

var INSERT_SORT_CUTOFF = 32

function wrapper(data, n0) {
  if (n0 <= 4*INSERT_SORT_CUTOFF) {
    insertionSort(0, n0 - 1, data);
  } else {
    quickSort(0, n0 - 1, data);
  }
}

function insertionSort(left, right, data) {
  var ptr = 2*(left+1)
  for(var i=left+1; i<=right; ++i) {
    var a = data[ptr++]
    var b = data[ptr++]
    var j = i
    var jptr = ptr-2
    while(j-- > left) {
      var x = data[jptr-2]
      var y = data[jptr-1]
      if(x < a) {
        break
      } else if(x === a && y < b) {
        break
      }
      data[jptr]   = x
      data[jptr+1] = y
      jptr -= 2
    }
    data[jptr]   = a
    data[jptr+1] = b
  }
}

function swap(i, j, data) {
  i *= 2
  j *= 2
  var x = data[i]
  var y = data[i+1]
  data[i] = data[j]
  data[i+1] = data[j+1]
  data[j] = x
  data[j+1] = y
}

function move(i, j, data) {
  i *= 2
  j *= 2
  data[i] = data[j]
  data[i+1] = data[j+1]
}

function rotate(i, j, k, data) {
  i *= 2
  j *= 2
  k *= 2
  var x = data[i]
  var y = data[i+1]
  data[i] = data[j]
  data[i+1] = data[j+1]
  data[j] = data[k]
  data[j+1] = data[k+1]
  data[k] = x
  data[k+1] = y
}

function shufflePivot(i, j, px, py, data) {
  i *= 2
  j *= 2
  data[i] = data[j]
  data[j] = px
  data[i+1] = data[j+1]
  data[j+1] = py
}

function compare(i, j, data) {
  i *= 2
  j *= 2
  var x = data[i],
      y = data[j]
  if(x < y) {
    return false
  } else if(x === y) {
    return data[i+1] > data[j+1]
  }
  return true
}

function comparePivot(i, y, b, data) {
  i *= 2
  var x = data[i]
  if(x < y) {
    return true
  } else if(x === y) {
    return data[i+1] < b
  }
  return false
}

function quickSort(left, right, data) {
  var sixth = (right - left + 1) / 6 | 0, 
      index1 = left + sixth, 
      index5 = right - sixth, 
      index3 = left + right >> 1, 
      index2 = index3 - sixth, 
      index4 = index3 + sixth, 
      el1 = index1, 
      el2 = index2, 
      el3 = index3, 
      el4 = index4, 
      el5 = index5, 
      less = left + 1, 
      great = right - 1, 
      tmp = 0
  if(compare(el1, el2, data)) {
    tmp = el1
    el1 = el2
    el2 = tmp
  }
  if(compare(el4, el5, data)) {
    tmp = el4
    el4 = el5
    el5 = tmp
  }
  if(compare(el1, el3, data)) {
    tmp = el1
    el1 = el3
    el3 = tmp
  }
  if(compare(el2, el3, data)) {
    tmp = el2
    el2 = el3
    el3 = tmp
  }
  if(compare(el1, el4, data)) {
    tmp = el1
    el1 = el4
    el4 = tmp
  }
  if(compare(el3, el4, data)) {
    tmp = el3
    el3 = el4
    el4 = tmp
  }
  if(compare(el2, el5, data)) {
    tmp = el2
    el2 = el5
    el5 = tmp
  }
  if(compare(el2, el3, data)) {
    tmp = el2
    el2 = el3
    el3 = tmp
  }
  if(compare(el4, el5, data)) {
    tmp = el4
    el4 = el5
    el5 = tmp
  }

  var pivot1X = data[2*el2]
  var pivot1Y = data[2*el2+1]
  var pivot2X = data[2*el4]
  var pivot2Y = data[2*el4+1]

  var ptr0 = 2 * el1;
  var ptr2 = 2 * el3;
  var ptr4 = 2 * el5;
  var ptr5 = 2 * index1;
  var ptr6 = 2 * index3;
  var ptr7 = 2 * index5;
  for (var i1 = 0; i1 < 2; ++i1) {
    var x = data[ptr0+i1];
    var y = data[ptr2+i1];
    var z = data[ptr4+i1];
    data[ptr5+i1] = x;
    data[ptr6+i1] = y;
    data[ptr7+i1] = z;
  }

  move(index2, left, data)
  move(index4, right, data)
  for (var k = less; k <= great; ++k) {
    if (comparePivot(k, pivot1X, pivot1Y, data)) {
      if (k !== less) {
        swap(k, less, data)
      }
      ++less;
    } else {
      if (!comparePivot(k, pivot2X, pivot2Y, data)) {
        while (true) {
          if (!comparePivot(great, pivot2X, pivot2Y, data)) {
            if (--great < k) {
              break;
            }
            continue;
          } else {
            if (comparePivot(great, pivot1X, pivot1Y, data)) {
              rotate(k, less, great, data)
              ++less;
              --great;
            } else {
              swap(k, great, data)
              --great;
            }
            break;
          }
        }
      }
    }
  }
  shufflePivot(left, less-1, pivot1X, pivot1Y, data)
  shufflePivot(right, great+1, pivot2X, pivot2Y, data)
  if (less - 2 - left <= INSERT_SORT_CUTOFF) {
    insertionSort(left, less - 2, data);
  } else {
    quickSort(left, less - 2, data);
  }
  if (right - (great + 2) <= INSERT_SORT_CUTOFF) {
    insertionSort(great + 2, right, data);
  } else {
    quickSort(great + 2, right, data);
  }
  if (great - less <= INSERT_SORT_CUTOFF) {
    insertionSort(less, great, data);
  } else {
    quickSort(less, great, data);
  }
}

/***/ }),

/***/ 855:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

"use strict";


module.exports = {
  init:           sqInit,
  sweepBipartite: sweepBipartite,
  sweepComplete:  sweepComplete,
  scanBipartite:  scanBipartite,
  scanComplete:   scanComplete
}

var pool  = __webpack_require__(1888)
var bits  = __webpack_require__(8828)
var isort = __webpack_require__(1811)

//Flag for blue
var BLUE_FLAG = (1<<28)

//1D sweep event queue stuff (use pool to save space)
var INIT_CAPACITY      = 1024
var RED_SWEEP_QUEUE    = pool.mallocInt32(INIT_CAPACITY)
var RED_SWEEP_INDEX    = pool.mallocInt32(INIT_CAPACITY)
var BLUE_SWEEP_QUEUE   = pool.mallocInt32(INIT_CAPACITY)
var BLUE_SWEEP_INDEX   = pool.mallocInt32(INIT_CAPACITY)
var COMMON_SWEEP_QUEUE = pool.mallocInt32(INIT_CAPACITY)
var COMMON_SWEEP_INDEX = pool.mallocInt32(INIT_CAPACITY)
var SWEEP_EVENTS       = pool.mallocDouble(INIT_CAPACITY * 8)

//Reserves memory for the 1D sweep data structures
function sqInit(count) {
  var rcount = bits.nextPow2(count)
  if(RED_SWEEP_QUEUE.length < rcount) {
    pool.free(RED_SWEEP_QUEUE)
    RED_SWEEP_QUEUE = pool.mallocInt32(rcount)
  }
  if(RED_SWEEP_INDEX.length < rcount) {
    pool.free(RED_SWEEP_INDEX)
    RED_SWEEP_INDEX = pool.mallocInt32(rcount)
  }
  if(BLUE_SWEEP_QUEUE.length < rcount) {
    pool.free(BLUE_SWEEP_QUEUE)
    BLUE_SWEEP_QUEUE = pool.mallocInt32(rcount)
  }
  if(BLUE_SWEEP_INDEX.length < rcount) {
    pool.free(BLUE_SWEEP_INDEX)
    BLUE_SWEEP_INDEX = pool.mallocInt32(rcount)
  }
  if(COMMON_SWEEP_QUEUE.length < rcount) {
    pool.free(COMMON_SWEEP_QUEUE)
    COMMON_SWEEP_QUEUE = pool.mallocInt32(rcount)
  }
  if(COMMON_SWEEP_INDEX.length < rcount) {
    pool.free(COMMON_SWEEP_INDEX)
    COMMON_SWEEP_INDEX = pool.mallocInt32(rcount)
  }
  var eventLength = 8 * rcount
  if(SWEEP_EVENTS.length < eventLength) {
    pool.free(SWEEP_EVENTS)
    SWEEP_EVENTS = pool.mallocDouble(eventLength)
  }
}

//Remove an item from the active queue in O(1)
function sqPop(queue, index, count, item) {
  var idx = index[item]
  var top = queue[count-1]
  queue[idx] = top
  index[top] = idx
}

//Insert an item into the active queue in O(1)
function sqPush(queue, index, count, item) {
  queue[count] = item
  index[item]  = count
}

//Recursion base case: use 1D sweep algorithm
function sweepBipartite(
    d, visit,
    redStart,  redEnd, red, redIndex,
    blueStart, blueEnd, blue, blueIndex) {

  //store events as pairs [coordinate, idx]
  //
  //  red create:  -(idx+1)
  //  red destroy: idx
  //  blue create: -(idx+BLUE_FLAG)
  //  blue destroy: idx+BLUE_FLAG
  //
  var ptr      = 0
  var elemSize = 2*d
  var istart   = d-1
  var iend     = elemSize-1

  for(var i=redStart; iright
  var n = ptr >>> 1
  isort(SWEEP_EVENTS, n)
  
  var redActive  = 0
  var blueActive = 0
  for(var i=0; i= BLUE_FLAG) {
      //blue destroy event
      e = (e-BLUE_FLAG)|0
      sqPop(BLUE_SWEEP_QUEUE, BLUE_SWEEP_INDEX, blueActive--, e)
    } else if(e >= 0) {
      //red destroy event
      sqPop(RED_SWEEP_QUEUE, RED_SWEEP_INDEX, redActive--, e)
    } else if(e <= -BLUE_FLAG) {
      //blue create event
      e = (-e-BLUE_FLAG)|0
      for(var j=0; jright
  var n = ptr >>> 1
  isort(SWEEP_EVENTS, n)
  
  var redActive    = 0
  var blueActive   = 0
  var commonActive = 0
  for(var i=0; i>1) === (SWEEP_EVENTS[2*i+3]>>1)) {
      color = 2
      i += 1
    }
    
    if(e < 0) {
      //Create event
      var id = -(e>>1) - 1

      //Intersect with common
      for(var j=0; j>1) - 1
      if(color === 0) {
        //Red
        sqPop(RED_SWEEP_QUEUE, RED_SWEEP_INDEX, redActive--, id)
      } else if(color === 1) {
        //Blue
        sqPop(BLUE_SWEEP_QUEUE, BLUE_SWEEP_INDEX, blueActive--, id)
      } else if(color === 2) {
        //Both
        sqPop(COMMON_SWEEP_QUEUE, COMMON_SWEEP_INDEX, commonActive--, id)
      }
    }
  }
}

//Sweep and prune/scanline algorithm:
//  Scan along axis, detect intersections
//  Brute force all boxes along axis
function scanBipartite(
  d, axis, visit, flip,
  redStart,  redEnd, red, redIndex,
  blueStart, blueEnd, blue, blueIndex) {
  
  var ptr      = 0
  var elemSize = 2*d
  var istart   = axis
  var iend     = axis+d

  var redShift  = 1
  var blueShift = 1
  if(flip) {
    blueShift = BLUE_FLAG
  } else {
    redShift  = BLUE_FLAG
  }

  for(var i=redStart; iright
  var n = ptr >>> 1
  isort(SWEEP_EVENTS, n)
  
  var redActive    = 0
  for(var i=0; i= BLUE_FLAG) {
        isRed = !flip
        idx -= BLUE_FLAG 
      } else {
        isRed = !!flip
        idx -= 1
      }
      if(isRed) {
        sqPush(RED_SWEEP_QUEUE, RED_SWEEP_INDEX, redActive++, idx)
      } else {
        var blueId  = blueIndex[idx]
        var bluePtr = elemSize * idx
        
        var b0 = blue[bluePtr+axis+1]
        var b1 = blue[bluePtr+axis+1+d]

red_loop:
        for(var j=0; jright
  var n = ptr >>> 1
  isort(SWEEP_EVENTS, n)
  
  var redActive    = 0
  for(var i=0; i= BLUE_FLAG) {
        RED_SWEEP_QUEUE[redActive++] = idx - BLUE_FLAG
      } else {
        idx -= 1
        var blueId  = blueIndex[idx]
        var bluePtr = elemSize * idx

        var b0 = blue[bluePtr+axis+1]
        var b1 = blue[bluePtr+axis+1+d]

red_loop:
        for(var j=0; j=0; --j) {
        if(RED_SWEEP_QUEUE[j] === idx) {
          for(var k=j+1; k 0) {
    var b = stack.pop()
    var a = stack.pop()

    //Find opposite pairs
    var x = -1, y = -1
    var star = stars[a]
    for(var i=1; i= 0) {
      continue
    }

    //Flip the edge
    triangulation.flip(a, b)

    //Test flipping neighboring edges
    testFlip(points, triangulation, stack, x, a, y)
    testFlip(points, triangulation, stack, a, y, x)
    testFlip(points, triangulation, stack, y, b, x)
    testFlip(points, triangulation, stack, b, x, y)
  }
}


/***/ }),

/***/ 5023:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

"use strict";


var bsearch = __webpack_require__(2478)

module.exports = classifyFaces

function FaceIndex(cells, neighbor, constraint, flags, active, next, boundary) {
  this.cells       = cells
  this.neighbor    = neighbor
  this.flags       = flags
  this.constraint  = constraint
  this.active      = active
  this.next        = next
  this.boundary    = boundary
}

var proto = FaceIndex.prototype

function compareCell(a, b) {
  return a[0] - b[0] ||
         a[1] - b[1] ||
         a[2] - b[2]
}

proto.locate = (function() {
  var key = [0,0,0]
  return function(a, b, c) {
    var x = a, y = b, z = c
    if(b < c) {
      if(b < a) {
        x = b
        y = c
        z = a
      }
    } else if(c < a) {
      x = c
      y = a
      z = b
    }
    if(x < 0) {
      return -1
    }
    key[0] = x
    key[1] = y
    key[2] = z
    return bsearch.eq(this.cells, key, compareCell)
  }
})()

function indexCells(triangulation, infinity) {
  //First get cells and canonicalize
  var cells = triangulation.cells()
  var nc = cells.length
  for(var i=0; i 0 || next.length > 0) {
    while(active.length > 0) {
      var t = active.pop()
      if(flags[t] === -side) {
        continue
      }
      flags[t] = side
      var c = cells[t]
      for(var j=0; j<3; ++j) {
        var f = neighbor[3*t+j]
        if(f >= 0 && flags[f] === 0) {
          if(constraint[3*t+j]) {
            next.push(f)
          } else {
            active.push(f)
            flags[f] = side
          }
        }
      }
    }

    //Swap arrays and loop
    var tmp = next
    next = active
    active = tmp
    next.length = 0
    side = -side
  }

  var result = filterCells(cells, flags, target)
  if(infinity) {
    return result.concat(index.boundary)
  }
  return result
}


/***/ }),

/***/ 8902:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

"use strict";


var bsearch = __webpack_require__(2478)
var orient = (__webpack_require__(3250)[3])

var EVENT_POINT = 0
var EVENT_END   = 1
var EVENT_START = 2

module.exports = monotoneTriangulate

//A partial convex hull fragment, made of two unimonotone polygons
function PartialHull(a, b, idx, lowerIds, upperIds) {
  this.a = a
  this.b = b
  this.idx = idx
  this.lowerIds = lowerIds
  this.upperIds = upperIds
}

//An event in the sweep line procedure
function Event(a, b, type, idx) {
  this.a    = a
  this.b    = b
  this.type = type
  this.idx  = idx
}

//This is used to compare events for the sweep line procedure
// Points are:
//  1. sorted lexicographically
//  2. sorted by type  (point < end < start)
//  3. segments sorted by winding order
//  4. sorted by index
function compareEvent(a, b) {
  var d =
    (a.a[0] - b.a[0]) ||
    (a.a[1] - b.a[1]) ||
    (a.type - b.type)
  if(d) { return d }
  if(a.type !== EVENT_POINT) {
    d = orient(a.a, a.b, b.b)
    if(d) { return d }
  }
  return a.idx - b.idx
}

function testPoint(hull, p) {
  return orient(hull.a, hull.b, p)
}

function addPoint(cells, hulls, points, p, idx) {
  var lo = bsearch.lt(hulls, p, testPoint)
  var hi = bsearch.gt(hulls, p, testPoint)
  for(var i=lo; i 1 && orient(
        points[lowerIds[m-2]],
        points[lowerIds[m-1]],
        p) > 0) {
      cells.push(
        [lowerIds[m-1],
         lowerIds[m-2],
         idx])
      m -= 1
    }
    lowerIds.length = m
    lowerIds.push(idx)

    //Insert p into upper hull
    var upperIds = hull.upperIds
    var m = upperIds.length
    while(m > 1 && orient(
        points[upperIds[m-2]],
        points[upperIds[m-1]],
        p) < 0) {
      cells.push(
        [upperIds[m-2],
         upperIds[m-1],
         idx])
      m -= 1
    }
    upperIds.length = m
    upperIds.push(idx)
  }
}

function findSplit(hull, edge) {
  var d
  if(hull.a[0] < edge.a[0]) {
    d = orient(hull.a, hull.b, edge.a)
  } else {
    d = orient(edge.b, edge.a, hull.a)
  }
  if(d) { return d }
  if(edge.b[0] < hull.b[0]) {
    d = orient(hull.a, hull.b, edge.b)
  } else {
    d = orient(edge.b, edge.a, hull.b)
  }
  return d || hull.idx - edge.idx
}

function splitHulls(hulls, points, event) {
  var splitIdx = bsearch.le(hulls, event, findSplit)
  var hull = hulls[splitIdx]
  var upperIds = hull.upperIds
  var x = upperIds[upperIds.length-1]
  hull.upperIds = [x]
  hulls.splice(splitIdx+1, 0,
    new PartialHull(event.a, event.b, event.idx, [x], upperIds))
}


function mergeHulls(hulls, points, event) {
  //Swap pointers for merge search
  var tmp = event.a
  event.a = event.b
  event.b = tmp
  var mergeIdx = bsearch.eq(hulls, event, findSplit)
  var upper = hulls[mergeIdx]
  var lower = hulls[mergeIdx-1]
  lower.upperIds = upper.upperIds
  hulls.splice(mergeIdx, 1)
}


function monotoneTriangulate(points, edges) {

  var numPoints = points.length
  var numEdges = edges.length

  var events = []

  //Create point events
  for(var i=0; i b[0]) {
      events.push(
        new Event(b, a, EVENT_START, i),
        new Event(a, b, EVENT_END, i))
    }
  }

  //Sort events
  events.sort(compareEvent)

  //Initialize hull
  var minX = events[0].a[0] - (1 + Math.abs(events[0].a[0])) * Math.pow(2, -52)
  var hull = [ new PartialHull([minX, 1], [minX, 0], -1, [], [], [], []) ]

  //Process events in order
  var cells = []
  for(var i=0, numEvents=events.length; i= 0
  }
})()

proto.removeTriangle = function(i, j, k) {
  var stars = this.stars
  removePair(stars[i], j, k)
  removePair(stars[j], k, i)
  removePair(stars[k], i, j)
}

proto.addTriangle = function(i, j, k) {
  var stars = this.stars
  stars[i].push(j, k)
  stars[j].push(k, i)
  stars[k].push(i, j)
}

proto.opposite = function(j, i) {
  var list = this.stars[i]
  for(var k=1, n=list.length; k= 0; --i) {
    var junction = junctions[i]
    e = junction[0]

    var edge = edges[e]
    var s = edge[0]
    var t = edge[1]

    // Check if edge is not lexicographically sorted
    var a = floatPoints[s]
    var b = floatPoints[t]
    if (((a[0] - b[0]) || (a[1] - b[1])) < 0) {
      var tmp = s
      s = t
      t = tmp
    }

    // Split leading edge
    edge[0] = s
    var last = edge[1] = junction[1]

    // If we are grouping edges by color, remember to track data
    var color
    if (useColor) {
      color = edge[2]
    }

    // Split other edges
    while (i > 0 && junctions[i - 1][0] === e) {
      var junction = junctions[--i]
      var next = junction[1]
      if (useColor) {
        edges.push([last, next, color])
      } else {
        edges.push([last, next])
      }
      last = next
    }

    // Add final edge
    if (useColor) {
      edges.push([last, t, color])
    } else {
      edges.push([last, t])
    }
  }

  // Return constructed rational points
  return ratPoints
}

// Merge overlapping points
function dedupPoints (floatPoints, ratPoints, floatBounds) {
  var numPoints = ratPoints.length
  var uf = new UnionFind(numPoints)

  // Compute rational bounds
  var bounds = []
  for (var i = 0; i < ratPoints.length; ++i) {
    var p = ratPoints[i]
    var xb = boundRat(p[0])
    var yb = boundRat(p[1])
    bounds.push([
      nextafter(xb[0], -Infinity),
      nextafter(yb[0], -Infinity),
      nextafter(xb[1], Infinity),
      nextafter(yb[1], Infinity)
    ])
  }

  // Link all points with over lapping boxes
  boxIntersect(bounds, function (i, j) {
    uf.link(i, j)
  })

  // Do 1 pass over points to combine points in label sets
  var noDupes = true
  var labels = new Array(numPoints)
  for (var i = 0; i < numPoints; ++i) {
    var j = uf.find(i)
    if (j !== i) {
      // Clear no-dupes flag, zero out label
      noDupes = false
      // Make each point the top-left point from its cell
      floatPoints[j] = [
        Math.min(floatPoints[i][0], floatPoints[j][0]),
        Math.min(floatPoints[i][1], floatPoints[j][1])
      ]
    }
  }

  // If no duplicates, return null to signal termination
  if (noDupes) {
    return null
  }

  var ptr = 0
  for (var i = 0; i < numPoints; ++i) {
    var j = uf.find(i)
    if (j === i) {
      labels[i] = ptr
      floatPoints[ptr++] = floatPoints[i]
    } else {
      labels[i] = -1
    }
  }

  floatPoints.length = ptr

  // Do a second pass to fix up missing labels
  for (var i = 0; i < numPoints; ++i) {
    if (labels[i] < 0) {
      labels[i] = labels[uf.find(i)]
    }
  }

  // Return resulting union-find data structure
  return labels
}

function compareLex2 (a, b) { return (a[0] - b[0]) || (a[1] - b[1]) }
function compareLex3 (a, b) {
  var d = (a[0] - b[0]) || (a[1] - b[1])
  if (d) {
    return d
  }
  if (a[2] < b[2]) {
    return -1
  } else if (a[2] > b[2]) {
    return 1
  }
  return 0
}

// Remove duplicate edge labels
function dedupEdges (edges, labels, useColor) {
  if (edges.length === 0) {
    return
  }
  if (labels) {
    for (var i = 0; i < edges.length; ++i) {
      var e = edges[i]
      var a = labels[e[0]]
      var b = labels[e[1]]
      e[0] = Math.min(a, b)
      e[1] = Math.max(a, b)
    }
  } else {
    for (var i = 0; i < edges.length; ++i) {
      var e = edges[i]
      var a = e[0]
      var b = e[1]
      e[0] = Math.min(a, b)
      e[1] = Math.max(a, b)
    }
  }
  if (useColor) {
    edges.sort(compareLex3)
  } else {
    edges.sort(compareLex2)
  }
  var ptr = 1
  for (var i = 1; i < edges.length; ++i) {
    var prev = edges[i - 1]
    var next = edges[i]
    if (next[0] === prev[0] && next[1] === prev[1] &&
      (!useColor || next[2] === prev[2])) {
      continue
    }
    edges[ptr++] = next
  }
  edges.length = ptr
}

function preRound (points, edges, useColor) {
  var labels = dedupPoints(points, [], boundPoints(points))
  dedupEdges(edges, labels, useColor)
  return !!labels
}

// Repeat until convergence
function snapRound (points, edges, useColor) {
  // 1. find edge crossings
  var edgeBounds = boundEdges(points, edges)
  var crossings = getCrossings(points, edges, edgeBounds)

  // 2. find t-junctions
  var vertBounds = boundPoints(points)
  var tjunctions = getTJunctions(points, edges, edgeBounds, vertBounds)

  // 3. cut edges, construct rational points
  var ratPoints = cutEdges(points, edges, crossings, tjunctions, useColor)

  // 4. dedupe verts
  var labels = dedupPoints(points, ratPoints, vertBounds)

  // 5. dedupe edges
  dedupEdges(edges, labels, useColor)

  // 6. check termination
  if (!labels) {
    return (crossings.length > 0 || tjunctions.length > 0)
  }

  // More iterations necessary
  return true
}

// Main loop, runs PSLG clean up until completion
function cleanPSLG (points, edges, colors) {
  // If using colors, augment edges with color data
  var prevEdges
  if (colors) {
    prevEdges = edges
    var augEdges = new Array(edges.length)
    for (var i = 0; i < edges.length; ++i) {
      var e = edges[i]
      augEdges[i] = [e[0], e[1], colors[i]]
    }
    edges = augEdges
  }

  // First round: remove duplicate edges and points
  var modified = preRound(points, edges, !!colors)

  // Run snap rounding until convergence
  while (snapRound(points, edges, !!colors)) {
    modified = true
  }

  // Strip color tags
  if (!!colors && modified) {
    prevEdges.length = 0
    colors.length = 0
    for (var i = 0; i < edges.length; ++i) {
      var e = edges[i]
      prevEdges.push([e[0], e[1]])
      colors.push(e[2])
    }
  }

  return modified
}


/***/ }),

/***/ 3637:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

"use strict";


module.exports = solveIntersection

var ratMul = __webpack_require__(6504)
var ratDiv = __webpack_require__(8697)
var ratSub = __webpack_require__(5572)
var ratSign = __webpack_require__(7721)
var rvSub = __webpack_require__(544)
var rvAdd = __webpack_require__(2653)
var rvMuls = __webpack_require__(8987)

function ratPerp (a, b) {
  return ratSub(ratMul(a[0], b[1]), ratMul(a[1], b[0]))
}

// Solve for intersection
//  x = a + t (b-a)
//  (x - c) ^ (d-c) = 0
//  (t * (b-a) + (a-c) ) ^ (d-c) = 0
//  t * (b-a)^(d-c) = (d-c)^(a-c)
//  t = (d-c)^(a-c) / (b-a)^(d-c)

function solveIntersection (a, b, c, d) {
  var ba = rvSub(b, a)
  var dc = rvSub(d, c)

  var baXdc = ratPerp(ba, dc)

  if (ratSign(baXdc) === 0) {
    return null
  }

  var ac = rvSub(a, c)
  var dcXac = ratPerp(dc, ac)

  var t = ratDiv(dcXac, baXdc)
  var s = rvMuls(ba, t)
  var r = rvAdd(a, s)

  return r
}


/***/ }),

/***/ 3642:
/***/ (function(module) {

module.exports={
	"jet":[{"index":0,"rgb":[0,0,131]},{"index":0.125,"rgb":[0,60,170]},{"index":0.375,"rgb":[5,255,255]},{"index":0.625,"rgb":[255,255,0]},{"index":0.875,"rgb":[250,0,0]},{"index":1,"rgb":[128,0,0]}],

	"hsv":[{"index":0,"rgb":[255,0,0]},{"index":0.169,"rgb":[253,255,2]},{"index":0.173,"rgb":[247,255,2]},{"index":0.337,"rgb":[0,252,4]},{"index":0.341,"rgb":[0,252,10]},{"index":0.506,"rgb":[1,249,255]},{"index":0.671,"rgb":[2,0,253]},{"index":0.675,"rgb":[8,0,253]},{"index":0.839,"rgb":[255,0,251]},{"index":0.843,"rgb":[255,0,245]},{"index":1,"rgb":[255,0,6]}],

	"hot":[{"index":0,"rgb":[0,0,0]},{"index":0.3,"rgb":[230,0,0]},{"index":0.6,"rgb":[255,210,0]},{"index":1,"rgb":[255,255,255]}],

	"spring":[{"index":0,"rgb":[255,0,255]},{"index":1,"rgb":[255,255,0]}],

	"summer":[{"index":0,"rgb":[0,128,102]},{"index":1,"rgb":[255,255,102]}],

	"autumn":[{"index":0,"rgb":[255,0,0]},{"index":1,"rgb":[255,255,0]}],

	"winter":[{"index":0,"rgb":[0,0,255]},{"index":1,"rgb":[0,255,128]}],

	"bone":[{"index":0,"rgb":[0,0,0]},{"index":0.376,"rgb":[84,84,116]},{"index":0.753,"rgb":[169,200,200]},{"index":1,"rgb":[255,255,255]}],

	"copper":[{"index":0,"rgb":[0,0,0]},{"index":0.804,"rgb":[255,160,102]},{"index":1,"rgb":[255,199,127]}],

	"greys":[{"index":0,"rgb":[0,0,0]},{"index":1,"rgb":[255,255,255]}],

	"yignbu":[{"index":0,"rgb":[8,29,88]},{"index":0.125,"rgb":[37,52,148]},{"index":0.25,"rgb":[34,94,168]},{"index":0.375,"rgb":[29,145,192]},{"index":0.5,"rgb":[65,182,196]},{"index":0.625,"rgb":[127,205,187]},{"index":0.75,"rgb":[199,233,180]},{"index":0.875,"rgb":[237,248,217]},{"index":1,"rgb":[255,255,217]}],

	"greens":[{"index":0,"rgb":[0,68,27]},{"index":0.125,"rgb":[0,109,44]},{"index":0.25,"rgb":[35,139,69]},{"index":0.375,"rgb":[65,171,93]},{"index":0.5,"rgb":[116,196,118]},{"index":0.625,"rgb":[161,217,155]},{"index":0.75,"rgb":[199,233,192]},{"index":0.875,"rgb":[229,245,224]},{"index":1,"rgb":[247,252,245]}],

	"yiorrd":[{"index":0,"rgb":[128,0,38]},{"index":0.125,"rgb":[189,0,38]},{"index":0.25,"rgb":[227,26,28]},{"index":0.375,"rgb":[252,78,42]},{"index":0.5,"rgb":[253,141,60]},{"index":0.625,"rgb":[254,178,76]},{"index":0.75,"rgb":[254,217,118]},{"index":0.875,"rgb":[255,237,160]},{"index":1,"rgb":[255,255,204]}],

	"bluered":[{"index":0,"rgb":[0,0,255]},{"index":1,"rgb":[255,0,0]}],

	"rdbu":[{"index":0,"rgb":[5,10,172]},{"index":0.35,"rgb":[106,137,247]},{"index":0.5,"rgb":[190,190,190]},{"index":0.6,"rgb":[220,170,132]},{"index":0.7,"rgb":[230,145,90]},{"index":1,"rgb":[178,10,28]}],

	"picnic":[{"index":0,"rgb":[0,0,255]},{"index":0.1,"rgb":[51,153,255]},{"index":0.2,"rgb":[102,204,255]},{"index":0.3,"rgb":[153,204,255]},{"index":0.4,"rgb":[204,204,255]},{"index":0.5,"rgb":[255,255,255]},{"index":0.6,"rgb":[255,204,255]},{"index":0.7,"rgb":[255,153,255]},{"index":0.8,"rgb":[255,102,204]},{"index":0.9,"rgb":[255,102,102]},{"index":1,"rgb":[255,0,0]}],

	"rainbow":[{"index":0,"rgb":[150,0,90]},{"index":0.125,"rgb":[0,0,200]},{"index":0.25,"rgb":[0,25,255]},{"index":0.375,"rgb":[0,152,255]},{"index":0.5,"rgb":[44,255,150]},{"index":0.625,"rgb":[151,255,0]},{"index":0.75,"rgb":[255,234,0]},{"index":0.875,"rgb":[255,111,0]},{"index":1,"rgb":[255,0,0]}],

	"portland":[{"index":0,"rgb":[12,51,131]},{"index":0.25,"rgb":[10,136,186]},{"index":0.5,"rgb":[242,211,56]},{"index":0.75,"rgb":[242,143,56]},{"index":1,"rgb":[217,30,30]}],

	"blackbody":[{"index":0,"rgb":[0,0,0]},{"index":0.2,"rgb":[230,0,0]},{"index":0.4,"rgb":[230,210,0]},{"index":0.7,"rgb":[255,255,255]},{"index":1,"rgb":[160,200,255]}],

	"earth":[{"index":0,"rgb":[0,0,130]},{"index":0.1,"rgb":[0,180,180]},{"index":0.2,"rgb":[40,210,40]},{"index":0.4,"rgb":[230,230,50]},{"index":0.6,"rgb":[120,70,20]},{"index":1,"rgb":[255,255,255]}],

	"electric":[{"index":0,"rgb":[0,0,0]},{"index":0.15,"rgb":[30,0,100]},{"index":0.4,"rgb":[120,0,100]},{"index":0.6,"rgb":[160,90,0]},{"index":0.8,"rgb":[230,200,0]},{"index":1,"rgb":[255,250,220]}],

	"alpha": [{"index":0, "rgb": [255,255,255,0]},{"index":1, "rgb": [255,255,255,1]}],

	"viridis": [{"index":0,"rgb":[68,1,84]},{"index":0.13,"rgb":[71,44,122]},{"index":0.25,"rgb":[59,81,139]},{"index":0.38,"rgb":[44,113,142]},{"index":0.5,"rgb":[33,144,141]},{"index":0.63,"rgb":[39,173,129]},{"index":0.75,"rgb":[92,200,99]},{"index":0.88,"rgb":[170,220,50]},{"index":1,"rgb":[253,231,37]}],

	"inferno": [{"index":0,"rgb":[0,0,4]},{"index":0.13,"rgb":[31,12,72]},{"index":0.25,"rgb":[85,15,109]},{"index":0.38,"rgb":[136,34,106]},{"index":0.5,"rgb":[186,54,85]},{"index":0.63,"rgb":[227,89,51]},{"index":0.75,"rgb":[249,140,10]},{"index":0.88,"rgb":[249,201,50]},{"index":1,"rgb":[252,255,164]}],

	"magma": [{"index":0,"rgb":[0,0,4]},{"index":0.13,"rgb":[28,16,68]},{"index":0.25,"rgb":[79,18,123]},{"index":0.38,"rgb":[129,37,129]},{"index":0.5,"rgb":[181,54,122]},{"index":0.63,"rgb":[229,80,100]},{"index":0.75,"rgb":[251,135,97]},{"index":0.88,"rgb":[254,194,135]},{"index":1,"rgb":[252,253,191]}],

	"plasma": [{"index":0,"rgb":[13,8,135]},{"index":0.13,"rgb":[75,3,161]},{"index":0.25,"rgb":[125,3,168]},{"index":0.38,"rgb":[168,34,150]},{"index":0.5,"rgb":[203,70,121]},{"index":0.63,"rgb":[229,107,93]},{"index":0.75,"rgb":[248,148,65]},{"index":0.88,"rgb":[253,195,40]},{"index":1,"rgb":[240,249,33]}],

	"warm": [{"index":0,"rgb":[125,0,179]},{"index":0.13,"rgb":[172,0,187]},{"index":0.25,"rgb":[219,0,170]},{"index":0.38,"rgb":[255,0,130]},{"index":0.5,"rgb":[255,63,74]},{"index":0.63,"rgb":[255,123,0]},{"index":0.75,"rgb":[234,176,0]},{"index":0.88,"rgb":[190,228,0]},{"index":1,"rgb":[147,255,0]}],

	"cool": [{"index":0,"rgb":[125,0,179]},{"index":0.13,"rgb":[116,0,218]},{"index":0.25,"rgb":[98,74,237]},{"index":0.38,"rgb":[68,146,231]},{"index":0.5,"rgb":[0,204,197]},{"index":0.63,"rgb":[0,247,146]},{"index":0.75,"rgb":[0,255,88]},{"index":0.88,"rgb":[40,255,8]},{"index":1,"rgb":[147,255,0]}],

	"rainbow-soft": [{"index":0,"rgb":[125,0,179]},{"index":0.1,"rgb":[199,0,180]},{"index":0.2,"rgb":[255,0,121]},{"index":0.3,"rgb":[255,108,0]},{"index":0.4,"rgb":[222,194,0]},{"index":0.5,"rgb":[150,255,0]},{"index":0.6,"rgb":[0,255,55]},{"index":0.7,"rgb":[0,246,150]},{"index":0.8,"rgb":[50,167,222]},{"index":0.9,"rgb":[103,51,235]},{"index":1,"rgb":[124,0,186]}],

	"bathymetry": [{"index":0,"rgb":[40,26,44]},{"index":0.13,"rgb":[59,49,90]},{"index":0.25,"rgb":[64,76,139]},{"index":0.38,"rgb":[63,110,151]},{"index":0.5,"rgb":[72,142,158]},{"index":0.63,"rgb":[85,174,163]},{"index":0.75,"rgb":[120,206,163]},{"index":0.88,"rgb":[187,230,172]},{"index":1,"rgb":[253,254,204]}],

	"cdom": [{"index":0,"rgb":[47,15,62]},{"index":0.13,"rgb":[87,23,86]},{"index":0.25,"rgb":[130,28,99]},{"index":0.38,"rgb":[171,41,96]},{"index":0.5,"rgb":[206,67,86]},{"index":0.63,"rgb":[230,106,84]},{"index":0.75,"rgb":[242,149,103]},{"index":0.88,"rgb":[249,193,135]},{"index":1,"rgb":[254,237,176]}],

	"chlorophyll": [{"index":0,"rgb":[18,36,20]},{"index":0.13,"rgb":[25,63,41]},{"index":0.25,"rgb":[24,91,59]},{"index":0.38,"rgb":[13,119,72]},{"index":0.5,"rgb":[18,148,80]},{"index":0.63,"rgb":[80,173,89]},{"index":0.75,"rgb":[132,196,122]},{"index":0.88,"rgb":[175,221,162]},{"index":1,"rgb":[215,249,208]}],

	"density": [{"index":0,"rgb":[54,14,36]},{"index":0.13,"rgb":[89,23,80]},{"index":0.25,"rgb":[110,45,132]},{"index":0.38,"rgb":[120,77,178]},{"index":0.5,"rgb":[120,113,213]},{"index":0.63,"rgb":[115,151,228]},{"index":0.75,"rgb":[134,185,227]},{"index":0.88,"rgb":[177,214,227]},{"index":1,"rgb":[230,241,241]}],

	"freesurface-blue": [{"index":0,"rgb":[30,4,110]},{"index":0.13,"rgb":[47,14,176]},{"index":0.25,"rgb":[41,45,236]},{"index":0.38,"rgb":[25,99,212]},{"index":0.5,"rgb":[68,131,200]},{"index":0.63,"rgb":[114,156,197]},{"index":0.75,"rgb":[157,181,203]},{"index":0.88,"rgb":[200,208,216]},{"index":1,"rgb":[241,237,236]}],

	"freesurface-red": [{"index":0,"rgb":[60,9,18]},{"index":0.13,"rgb":[100,17,27]},{"index":0.25,"rgb":[142,20,29]},{"index":0.38,"rgb":[177,43,27]},{"index":0.5,"rgb":[192,87,63]},{"index":0.63,"rgb":[205,125,105]},{"index":0.75,"rgb":[216,162,148]},{"index":0.88,"rgb":[227,199,193]},{"index":1,"rgb":[241,237,236]}],

	"oxygen": [{"index":0,"rgb":[64,5,5]},{"index":0.13,"rgb":[106,6,15]},{"index":0.25,"rgb":[144,26,7]},{"index":0.38,"rgb":[168,64,3]},{"index":0.5,"rgb":[188,100,4]},{"index":0.63,"rgb":[206,136,11]},{"index":0.75,"rgb":[220,174,25]},{"index":0.88,"rgb":[231,215,44]},{"index":1,"rgb":[248,254,105]}],

	"par": [{"index":0,"rgb":[51,20,24]},{"index":0.13,"rgb":[90,32,35]},{"index":0.25,"rgb":[129,44,34]},{"index":0.38,"rgb":[159,68,25]},{"index":0.5,"rgb":[182,99,19]},{"index":0.63,"rgb":[199,134,22]},{"index":0.75,"rgb":[212,171,35]},{"index":0.88,"rgb":[221,210,54]},{"index":1,"rgb":[225,253,75]}],

	"phase": [{"index":0,"rgb":[145,105,18]},{"index":0.13,"rgb":[184,71,38]},{"index":0.25,"rgb":[186,58,115]},{"index":0.38,"rgb":[160,71,185]},{"index":0.5,"rgb":[110,97,218]},{"index":0.63,"rgb":[50,123,164]},{"index":0.75,"rgb":[31,131,110]},{"index":0.88,"rgb":[77,129,34]},{"index":1,"rgb":[145,105,18]}],

	"salinity": [{"index":0,"rgb":[42,24,108]},{"index":0.13,"rgb":[33,50,162]},{"index":0.25,"rgb":[15,90,145]},{"index":0.38,"rgb":[40,118,137]},{"index":0.5,"rgb":[59,146,135]},{"index":0.63,"rgb":[79,175,126]},{"index":0.75,"rgb":[120,203,104]},{"index":0.88,"rgb":[193,221,100]},{"index":1,"rgb":[253,239,154]}],

	"temperature": [{"index":0,"rgb":[4,35,51]},{"index":0.13,"rgb":[23,51,122]},{"index":0.25,"rgb":[85,59,157]},{"index":0.38,"rgb":[129,79,143]},{"index":0.5,"rgb":[175,95,130]},{"index":0.63,"rgb":[222,112,101]},{"index":0.75,"rgb":[249,146,66]},{"index":0.88,"rgb":[249,196,65]},{"index":1,"rgb":[232,250,91]}],

	"turbidity": [{"index":0,"rgb":[34,31,27]},{"index":0.13,"rgb":[65,50,41]},{"index":0.25,"rgb":[98,69,52]},{"index":0.38,"rgb":[131,89,57]},{"index":0.5,"rgb":[161,112,59]},{"index":0.63,"rgb":[185,140,66]},{"index":0.75,"rgb":[202,174,88]},{"index":0.88,"rgb":[216,209,126]},{"index":1,"rgb":[233,246,171]}],

	"velocity-blue": [{"index":0,"rgb":[17,32,64]},{"index":0.13,"rgb":[35,52,116]},{"index":0.25,"rgb":[29,81,156]},{"index":0.38,"rgb":[31,113,162]},{"index":0.5,"rgb":[50,144,169]},{"index":0.63,"rgb":[87,173,176]},{"index":0.75,"rgb":[149,196,189]},{"index":0.88,"rgb":[203,221,211]},{"index":1,"rgb":[254,251,230]}],

	"velocity-green": [{"index":0,"rgb":[23,35,19]},{"index":0.13,"rgb":[24,64,38]},{"index":0.25,"rgb":[11,95,45]},{"index":0.38,"rgb":[39,123,35]},{"index":0.5,"rgb":[95,146,12]},{"index":0.63,"rgb":[152,165,18]},{"index":0.75,"rgb":[201,186,69]},{"index":0.88,"rgb":[233,216,137]},{"index":1,"rgb":[255,253,205]}],

	"cubehelix": [{"index":0,"rgb":[0,0,0]},{"index":0.07,"rgb":[22,5,59]},{"index":0.13,"rgb":[60,4,105]},{"index":0.2,"rgb":[109,1,135]},{"index":0.27,"rgb":[161,0,147]},{"index":0.33,"rgb":[210,2,142]},{"index":0.4,"rgb":[251,11,123]},{"index":0.47,"rgb":[255,29,97]},{"index":0.53,"rgb":[255,54,69]},{"index":0.6,"rgb":[255,85,46]},{"index":0.67,"rgb":[255,120,34]},{"index":0.73,"rgb":[255,157,37]},{"index":0.8,"rgb":[241,191,57]},{"index":0.87,"rgb":[224,220,93]},{"index":0.93,"rgb":[218,241,142]},{"index":1,"rgb":[227,253,198]}]
};


/***/ }),

/***/ 6729:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

"use strict";
/*
 * Ben Postlethwaite
 * January 2013
 * License MIT
 */


var colorScale = __webpack_require__(3642);
var lerp = __webpack_require__(395)

module.exports = createColormap;

function createColormap (spec) {
    /*
     * Default Options
     */
    var indicies, fromrgba, torgba,
        nsteps, cmap, colormap, format,
        nshades, colors, alpha, i;

    if ( !spec ) spec = {};

    nshades = (spec.nshades || 72) - 1;
    format = spec.format || 'hex';

    colormap = spec.colormap;
    if (!colormap) colormap = 'jet';

    if (typeof colormap === 'string') {
        colormap = colormap.toLowerCase();

        if (!colorScale[colormap]) {
            throw Error(colormap + ' not a supported colorscale');
        }

        cmap = colorScale[colormap];

    } else if (Array.isArray(colormap)) {
        cmap = colormap.slice();

    } else {
        throw Error('unsupported colormap option', colormap);
    }

    if (cmap.length > nshades + 1) {
        throw new Error(
            colormap+' map requires nshades to be at least size '+cmap.length
        );
    }

    if (!Array.isArray(spec.alpha)) {

        if (typeof spec.alpha === 'number') {
            alpha = [spec.alpha, spec.alpha];

        } else {
            alpha = [1, 1];
        }

    } else if (spec.alpha.length !== 2) {
        alpha = [1, 1];

    } else {
        alpha = spec.alpha.slice();
    }

    // map index points from 0..1 to 0..n-1
    indicies = cmap.map(function(c) {
        return Math.round(c.index * nshades);
    });

    // Add alpha channel to the map
    alpha[0] = Math.min(Math.max(alpha[0], 0), 1);
    alpha[1] = Math.min(Math.max(alpha[1], 0), 1);

    var steps = cmap.map(function(c, i) {
        var index = cmap[i].index

        var rgba = cmap[i].rgb.slice();

        // if user supplies their own map use it
        if (rgba.length === 4 && rgba[3] >= 0 && rgba[3] <= 1) {
            return rgba
        }
        rgba[3] = alpha[0] + (alpha[1] - alpha[0])*index;

        return rgba
    })


    /*
     * map increasing linear values between indicies to
     * linear steps in colorvalues
     */
    var colors = []
    for (i = 0; i < indicies.length-1; ++i) {
        nsteps = indicies[i+1] - indicies[i];
        fromrgba = steps[i];
        torgba = steps[i+1];

        for (var j = 0; j < nsteps; j++) {
            var amt = j / nsteps
            colors.push([
                Math.round(lerp(fromrgba[0], torgba[0], amt)),
                Math.round(lerp(fromrgba[1], torgba[1], amt)),
                Math.round(lerp(fromrgba[2], torgba[2], amt)),
                lerp(fromrgba[3], torgba[3], amt)
            ])
        }
    }

    //add 1 step as last value
    colors.push(cmap[cmap.length - 1].rgb.concat(alpha[1]))

    if (format === 'hex') colors = colors.map( rgb2hex );
    else if (format === 'rgbaString') colors = colors.map( rgbaStr );
    else if (format === 'float') colors = colors.map( rgb2float );

    return colors;
};

function rgb2float (rgba) {
    return [
        rgba[0] / 255,
        rgba[1] / 255,
        rgba[2] / 255,
        rgba[3]
    ]
}

function rgb2hex (rgba) {
    var dig, hex = '#';
    for (var i = 0; i < 3; ++i) {
        dig = rgba[i];
        dig = dig.toString(16);
        hex += ('00' + dig).substr( dig.length );
    }
    return hex;
}

function rgbaStr (rgba) {
    return 'rgba(' + rgba.join(',') + ')';
}


/***/ }),

/***/ 3140:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

"use strict";


module.exports = compareAngle

var orient = __webpack_require__(3250)
var sgn = __webpack_require__(8572)
var twoSum = __webpack_require__(9362)
var robustProduct = __webpack_require__(5382)
var robustSum = __webpack_require__(8210)

function testInterior(a, b, c) {
  var x0 = twoSum(a[0], -b[0])
  var y0 = twoSum(a[1], -b[1])
  var x1 = twoSum(c[0], -b[0])
  var y1 = twoSum(c[1], -b[1])

  var d = robustSum(
    robustProduct(x0, x1),
    robustProduct(y0, y1))

  return d[d.length-1] >= 0
}

function compareAngle(a, b, c, d) {
  var bcd = orient(b, c, d)
  if(bcd === 0) {
    //Handle degenerate cases
    var sabc = sgn(orient(a, b, c))
    var sabd = sgn(orient(a, b, d))
    if(sabc === sabd) {
      if(sabc === 0) {
        var ic = testInterior(a, b, c)
        var id = testInterior(a, b, d)
        if(ic === id) {
          return 0
        } else if(ic) {
          return 1
        } else {
          return -1
        }
      }
      return 0
    } else if(sabd === 0) {
      if(sabc > 0) {
        return -1
      } else if(testInterior(a, b, d)) {
        return -1
      } else {
        return 1
      }
    } else if(sabc === 0) {
      if(sabd > 0) {
        return 1
      } else if(testInterior(a, b, c)) {
        return 1
      } else {
        return -1
      }
    }
    return sgn(sabd - sabc)
  }
  var abc = orient(a, b, c)
  if(abc > 0) {
    if(bcd > 0 && orient(a, b, d) > 0) {
      return 1
    }
    return -1
  } else if(abc < 0) {
    if(bcd > 0 || orient(a, b, d) > 0) {
      return 1
    }
    return -1
  } else {
    var abd = orient(a, b, d)
    if(abd > 0) {
      return 1
    } else {
      if(testInterior(a, b, c)) {
        return 1
      } else {
        return -1
      }
    }
  }
}

/***/ }),

/***/ 8572:
/***/ (function(module) {

"use strict";


module.exports = function signum(x) {
  if(x < 0) { return -1 }
  if(x > 0) { return 1 }
  return 0.0
}

/***/ }),

/***/ 8507:
/***/ (function(module) {

module.exports = compareCells

var min = Math.min

function compareInt(a, b) {
  return a - b
}

function compareCells(a, b) {
  var n = a.length
    , t = a.length - b.length
  if(t) {
    return t
  }
  switch(n) {
    case 0:
      return 0
    case 1:
      return a[0] - b[0]
    case 2:
      return (a[0]+a[1]-b[0]-b[1]) ||
             min(a[0],a[1]) - min(b[0],b[1])
    case 3:
      var l1 = a[0]+a[1]
        , m1 = b[0]+b[1]
      t = l1+a[2] - (m1+b[2])
      if(t) {
        return t
      }
      var l0 = min(a[0], a[1])
        , m0 = min(b[0], b[1])
      return min(l0, a[2]) - min(m0, b[2]) ||
             min(l0+a[2], l1) - min(m0+b[2], m1)
    case 4:
      var aw=a[0], ax=a[1], ay=a[2], az=a[3]
        , bw=b[0], bx=b[1], by=b[2], bz=b[3]
      return (aw+ax+ay+az)-(bw+bx+by+bz) ||
             min(aw,ax,ay,az)-min(bw,bx,by,bz,bw) ||
             min(aw+ax,aw+ay,aw+az,ax+ay,ax+az,ay+az) -
               min(bw+bx,bw+by,bw+bz,bx+by,bx+bz,by+bz) ||
             min(aw+ax+ay,aw+ax+az,aw+ay+az,ax+ay+az) -
               min(bw+bx+by,bw+bx+bz,bw+by+bz,bx+by+bz)
    default:
      var as = a.slice().sort(compareInt)
      var bs = b.slice().sort(compareInt)
      for(var i=0; i points[hi][0]) {
      hi = i
    }
  }
  if(lo < hi) {
    return [[lo], [hi]]
  } else if(lo > hi) {
    return [[hi], [lo]]
  } else {
    return [[lo]]
  }
}

/***/ }),

/***/ 4750:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

"use strict";


module.exports = convexHull2D

var monotoneHull = __webpack_require__(3090)

function convexHull2D(points) {
  var hull = monotoneHull(points)
  var h = hull.length
  if(h <= 2) {
    return []
  }
  var edges = new Array(h)
  var a = hull[h-1]
  for(var i=0; i= front[k]) {
            x += 1
          }
        }
        c[j] = x
      }
    }
  }
  return cells
}

function convexHullnD(points, d) {
  try {
    return ich(points, true)
  } catch(e) {
    //If point set is degenerate, try to find a basis and rerun it
    var ah = aff(points)
    if(ah.length <= d) {
      //No basis, no try
      return []
    }
    var npoints = permute(points, ah)
    var nhull   = ich(npoints, true)
    return invPermute(nhull, ah)
  }
}

/***/ }),

/***/ 4769:
/***/ (function(module) {

"use strict";


function dcubicHermite(p0, v0, p1, v1, t, f) {
  var dh00 = 6*t*t-6*t,
      dh10 = 3*t*t-4*t + 1,
      dh01 = -6*t*t+6*t,
      dh11 = 3*t*t-2*t
  if(p0.length) {
    if(!f) {
      f = new Array(p0.length)
    }
    for(var i=p0.length-1; i>=0; --i) {
      f[i] = dh00*p0[i] + dh10*v0[i] + dh01*p1[i] + dh11*v1[i]
    }
    return f
  }
  return dh00*p0 + dh10*v0 + dh01*p1[i] + dh11*v1
}

function cubicHermite(p0, v0, p1, v1, t, f) {
  var ti  = (t-1), t2 = t*t, ti2 = ti*ti,
      h00 = (1+2*t)*ti2,
      h10 = t*ti2,
      h01 = t2*(3-2*t),
      h11 = t2*ti
  if(p0.length) {
    if(!f) {
      f = new Array(p0.length)
    }
    for(var i=p0.length-1; i>=0; --i) {
      f[i] = h00*p0[i] + h10*v0[i] + h01*p1[i] + h11*v1[i]
    }
    return f
  }
  return h00*p0 + h10*v0 + h01*p1 + h11*v1
}

module.exports = cubicHermite
module.exports.derivative = dcubicHermite

/***/ }),

/***/ 7642:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

"use strict";


var ch = __webpack_require__(8954)
var uniq = __webpack_require__(1682)

module.exports = triangulate

function LiftedPoint(p, i) {
  this.point = p
  this.index = i
}

function compareLifted(a, b) {
  var ap = a.point
  var bp = b.point
  var d = ap.length
  for(var i=0; i= 2) {
            return false
          }
        }
        cell[j] = v
      }
      return true
    })
  } else {
    hull = hull.filter(function(cell) {
      for(var i=0; i<=d; ++i) {
        var v = dindex[cell[i]]
        if(v < 0) {
          return false
        }
        cell[i] = v
      }
      return true
    })
  }

  if(d & 1) {
    for(var i=0; i>> 31
}

module.exports.exponent = function(n) {
  var b = module.exports.hi(n)
  return ((b<<1) >>> 21) - 1023
}

module.exports.fraction = function(n) {
  var lo = module.exports.lo(n)
  var hi = module.exports.hi(n)
  var b = hi & ((1<<20) - 1)
  if(hi & 0x7ff00000) {
    b += (1<<20)
  }
  return [lo, b]
}

module.exports.denormalized = function(n) {
  var hi = module.exports.hi(n)
  return !(hi & 0x7ff00000)
}

/***/ }),

/***/ 1338:
/***/ (function(module) {

"use strict";


function dupe_array(count, value, i) {
  var c = count[i]|0
  if(c <= 0) {
    return []
  }
  var result = new Array(c), j
  if(i === count.length-1) {
    for(j=0; j 0) {
        return dupe_number(count|0, value)
      }
    break
    case "object":
      if(typeof (count.length) === "number") {
        return dupe_array(count, value, 0)
      }
    break
  }
  return []
}

module.exports = dupe

/***/ }),

/***/ 3134:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

"use strict";


module.exports = edgeToAdjacency

var uniq = __webpack_require__(1682)

function edgeToAdjacency(edges, numVertices) {
  var numEdges = edges.length
  if(typeof numVertices !== "number") {
    numVertices = 0
    for(var i=0; i= n-1) {
    var ptr = state.length-1
    var tf = t - time[n-1]
    for(var i=0; i= n-1) {
    var ptr = state.length-1
    var tf = t - time[n-1]
    for(var i=0; i=0; --i) {
    if(velocity[--ptr]) {
      return false
    }
  }
  return true
}

proto.jump = function(t) {
  var t0 = this.lastT()
  var d  = this.dimension
  if(t < t0 || arguments.length !== d+1) {
    return
  }
  var state     = this._state
  var velocity  = this._velocity
  var ptr       = state.length-this.dimension
  var bounds    = this.bounds
  var lo        = bounds[0]
  var hi        = bounds[1]
  this._time.push(t0, t)
  for(var j=0; j<2; ++j) {
    for(var i=0; i0; --i) {
    state.push(clamp(lo[i-1], hi[i-1], arguments[i]))
    velocity.push(0)
  }
}

proto.push = function(t) {
  var t0 = this.lastT()
  var d  = this.dimension
  if(t < t0 || arguments.length !== d+1) {
    return
  }
  var state     = this._state
  var velocity  = this._velocity
  var ptr       = state.length-this.dimension
  var dt        = t - t0
  var bounds    = this.bounds
  var lo        = bounds[0]
  var hi        = bounds[1]
  var sf        = (dt > 1e-6) ? 1/dt : 0
  this._time.push(t)
  for(var i=d; i>0; --i) {
    var xc = clamp(lo[i-1], hi[i-1], arguments[i])
    state.push(xc)
    velocity.push((xc - state[ptr++]) * sf)
  }
}

proto.set = function(t) {
  var d = this.dimension
  if(t < this.lastT() || arguments.length !== d+1) {
    return
  }
  var state     = this._state
  var velocity  = this._velocity
  var bounds    = this.bounds
  var lo        = bounds[0]
  var hi        = bounds[1]
  this._time.push(t)
  for(var i=d; i>0; --i) {
    state.push(clamp(lo[i-1], hi[i-1], arguments[i]))
    velocity.push(0)
  }
}

proto.move = function(t) {
  var t0 = this.lastT()
  var d  = this.dimension
  if(t <= t0 || arguments.length !== d+1) {
    return
  }
  var state    = this._state
  var velocity = this._velocity
  var statePtr = state.length - this.dimension
  var bounds   = this.bounds
  var lo       = bounds[0]
  var hi       = bounds[1]
  var dt       = t - t0
  var sf       = (dt > 1e-6) ? 1/dt : 0.0
  this._time.push(t)
  for(var i=d; i>0; --i) {
    var dx = arguments[i]
    state.push(clamp(lo[i-1], hi[i-1], state[statePtr++] + dx))
    velocity.push(dx * sf)
  }
}

proto.idle = function(t) {
  var t0 = this.lastT()
  if(t < t0) {
    return
  }
  var d        = this.dimension
  var state    = this._state
  var velocity = this._velocity
  var statePtr = state.length-d
  var bounds   = this.bounds
  var lo       = bounds[0]
  var hi       = bounds[1]
  var dt       = t - t0
  this._time.push(t)
  for(var i=d-1; i>=0; --i) {
    state.push(clamp(lo[i], hi[i], state[statePtr] + dt * velocity[statePtr]))
    velocity.push(0)
    statePtr += 1
  }
}

function getZero(d) {
  var result = new Array(d)
  for(var i=0; i=0; --s) {
    var n = n_stack[s]
    if(d_stack[s] <= 0) {
      n_stack[s] = new RBNode(n._color, n.key, n.value, n_stack[s+1], n.right, n._count+1)
    } else {
      n_stack[s] = new RBNode(n._color, n.key, n.value, n.left, n_stack[s+1], n._count+1)
    }
  }
  //Rebalance tree using rotations
  //console.log("start insert", key, d_stack)
  for(var s=n_stack.length-1; s>1; --s) {
    var p = n_stack[s-1]
    var n = n_stack[s]
    if(p._color === BLACK || n._color === BLACK) {
      break
    }
    var pp = n_stack[s-2]
    if(pp.left === p) {
      if(p.left === n) {
        var y = pp.right
        if(y && y._color === RED) {
          //console.log("LLr")
          p._color = BLACK
          pp.right = repaint(BLACK, y)
          pp._color = RED
          s -= 1
        } else {
          //console.log("LLb")
          pp._color = RED
          pp.left = p.right
          p._color = BLACK
          p.right = pp
          n_stack[s-2] = p
          n_stack[s-1] = n
          recount(pp)
          recount(p)
          if(s >= 3) {
            var ppp = n_stack[s-3]
            if(ppp.left === pp) {
              ppp.left = p
            } else {
              ppp.right = p
            }
          }
          break
        }
      } else {
        var y = pp.right
        if(y && y._color === RED) {
          //console.log("LRr")
          p._color = BLACK
          pp.right = repaint(BLACK, y)
          pp._color = RED
          s -= 1
        } else {
          //console.log("LRb")
          p.right = n.left
          pp._color = RED
          pp.left = n.right
          n._color = BLACK
          n.left = p
          n.right = pp
          n_stack[s-2] = n
          n_stack[s-1] = p
          recount(pp)
          recount(p)
          recount(n)
          if(s >= 3) {
            var ppp = n_stack[s-3]
            if(ppp.left === pp) {
              ppp.left = n
            } else {
              ppp.right = n
            }
          }
          break
        }
      }
    } else {
      if(p.right === n) {
        var y = pp.left
        if(y && y._color === RED) {
          //console.log("RRr", y.key)
          p._color = BLACK
          pp.left = repaint(BLACK, y)
          pp._color = RED
          s -= 1
        } else {
          //console.log("RRb")
          pp._color = RED
          pp.right = p.left
          p._color = BLACK
          p.left = pp
          n_stack[s-2] = p
          n_stack[s-1] = n
          recount(pp)
          recount(p)
          if(s >= 3) {
            var ppp = n_stack[s-3]
            if(ppp.right === pp) {
              ppp.right = p
            } else {
              ppp.left = p
            }
          }
          break
        }
      } else {
        var y = pp.left
        if(y && y._color === RED) {
          //console.log("RLr")
          p._color = BLACK
          pp.left = repaint(BLACK, y)
          pp._color = RED
          s -= 1
        } else {
          //console.log("RLb")
          p.left = n.right
          pp._color = RED
          pp.right = n.left
          n._color = BLACK
          n.right = p
          n.left = pp
          n_stack[s-2] = n
          n_stack[s-1] = p
          recount(pp)
          recount(p)
          recount(n)
          if(s >= 3) {
            var ppp = n_stack[s-3]
            if(ppp.right === pp) {
              ppp.right = n
            } else {
              ppp.left = n
            }
          }
          break
        }
      }
    }
  }
  //Return new tree
  n_stack[0]._color = BLACK
  return new RedBlackTree(cmp, n_stack[0])
}


//Visit all nodes inorder
function doVisitFull(visit, node) {
  if(node.left) {
    var v = doVisitFull(visit, node.left)
    if(v) { return v }
  }
  var v = visit(node.key, node.value)
  if(v) { return v }
  if(node.right) {
    return doVisitFull(visit, node.right)
  }
}

//Visit half nodes in order
function doVisitHalf(lo, compare, visit, node) {
  var l = compare(lo, node.key)
  if(l <= 0) {
    if(node.left) {
      var v = doVisitHalf(lo, compare, visit, node.left)
      if(v) { return v }
    }
    var v = visit(node.key, node.value)
    if(v) { return v }
  }
  if(node.right) {
    return doVisitHalf(lo, compare, visit, node.right)
  }
}

//Visit all nodes within a range
function doVisit(lo, hi, compare, visit, node) {
  var l = compare(lo, node.key)
  var h = compare(hi, node.key)
  var v
  if(l <= 0) {
    if(node.left) {
      v = doVisit(lo, hi, compare, visit, node.left)
      if(v) { return v }
    }
    if(h > 0) {
      v = visit(node.key, node.value)
      if(v) { return v }
    }
  }
  if(h > 0 && node.right) {
    return doVisit(lo, hi, compare, visit, node.right)
  }
}


proto.forEach = function rbTreeForEach(visit, lo, hi) {
  if(!this.root) {
    return
  }
  switch(arguments.length) {
    case 1:
      return doVisitFull(visit, this.root)
    break

    case 2:
      return doVisitHalf(lo, this._compare, visit, this.root)
    break

    case 3:
      if(this._compare(lo, hi) >= 0) {
        return
      }
      return doVisit(lo, hi, this._compare, visit, this.root)
    break
  }
}

//First item in list
Object.defineProperty(proto, "begin", {
  get: function() {
    var stack = []
    var n = this.root
    while(n) {
      stack.push(n)
      n = n.left
    }
    return new RedBlackTreeIterator(this, stack)
  }
})

//Last item in list
Object.defineProperty(proto, "end", {
  get: function() {
    var stack = []
    var n = this.root
    while(n) {
      stack.push(n)
      n = n.right
    }
    return new RedBlackTreeIterator(this, stack)
  }
})

//Find the ith item in the tree
proto.at = function(idx) {
  if(idx < 0) {
    return new RedBlackTreeIterator(this, [])
  }
  var n = this.root
  var stack = []
  while(true) {
    stack.push(n)
    if(n.left) {
      if(idx < n.left._count) {
        n = n.left
        continue
      }
      idx -= n.left._count
    }
    if(!idx) {
      return new RedBlackTreeIterator(this, stack)
    }
    idx -= 1
    if(n.right) {
      if(idx >= n.right._count) {
        break
      }
      n = n.right
    } else {
      break
    }
  }
  return new RedBlackTreeIterator(this, [])
}

proto.ge = function(key) {
  var cmp = this._compare
  var n = this.root
  var stack = []
  var last_ptr = 0
  while(n) {
    var d = cmp(key, n.key)
    stack.push(n)
    if(d <= 0) {
      last_ptr = stack.length
    }
    if(d <= 0) {
      n = n.left
    } else {
      n = n.right
    }
  }
  stack.length = last_ptr
  return new RedBlackTreeIterator(this, stack)
}

proto.gt = function(key) {
  var cmp = this._compare
  var n = this.root
  var stack = []
  var last_ptr = 0
  while(n) {
    var d = cmp(key, n.key)
    stack.push(n)
    if(d < 0) {
      last_ptr = stack.length
    }
    if(d < 0) {
      n = n.left
    } else {
      n = n.right
    }
  }
  stack.length = last_ptr
  return new RedBlackTreeIterator(this, stack)
}

proto.lt = function(key) {
  var cmp = this._compare
  var n = this.root
  var stack = []
  var last_ptr = 0
  while(n) {
    var d = cmp(key, n.key)
    stack.push(n)
    if(d > 0) {
      last_ptr = stack.length
    }
    if(d <= 0) {
      n = n.left
    } else {
      n = n.right
    }
  }
  stack.length = last_ptr
  return new RedBlackTreeIterator(this, stack)
}

proto.le = function(key) {
  var cmp = this._compare
  var n = this.root
  var stack = []
  var last_ptr = 0
  while(n) {
    var d = cmp(key, n.key)
    stack.push(n)
    if(d >= 0) {
      last_ptr = stack.length
    }
    if(d < 0) {
      n = n.left
    } else {
      n = n.right
    }
  }
  stack.length = last_ptr
  return new RedBlackTreeIterator(this, stack)
}

//Finds the item with key if it exists
proto.find = function(key) {
  var cmp = this._compare
  var n = this.root
  var stack = []
  while(n) {
    var d = cmp(key, n.key)
    stack.push(n)
    if(d === 0) {
      return new RedBlackTreeIterator(this, stack)
    }
    if(d <= 0) {
      n = n.left
    } else {
      n = n.right
    }
  }
  return new RedBlackTreeIterator(this, [])
}

//Removes item with key from tree
proto.remove = function(key) {
  var iter = this.find(key)
  if(iter) {
    return iter.remove()
  }
  return this
}

//Returns the item at `key`
proto.get = function(key) {
  var cmp = this._compare
  var n = this.root
  while(n) {
    var d = cmp(key, n.key)
    if(d === 0) {
      return n.value
    }
    if(d <= 0) {
      n = n.left
    } else {
      n = n.right
    }
  }
  return
}

//Iterator for red black tree
function RedBlackTreeIterator(tree, stack) {
  this.tree = tree
  this._stack = stack
}

var iproto = RedBlackTreeIterator.prototype

//Test if iterator is valid
Object.defineProperty(iproto, "valid", {
  get: function() {
    return this._stack.length > 0
  }
})

//Node of the iterator
Object.defineProperty(iproto, "node", {
  get: function() {
    if(this._stack.length > 0) {
      return this._stack[this._stack.length-1]
    }
    return null
  },
  enumerable: true
})

//Makes a copy of an iterator
iproto.clone = function() {
  return new RedBlackTreeIterator(this.tree, this._stack.slice())
}

//Swaps two nodes
function swapNode(n, v) {
  n.key = v.key
  n.value = v.value
  n.left = v.left
  n.right = v.right
  n._color = v._color
  n._count = v._count
}

//Fix up a double black node in a tree
function fixDoubleBlack(stack) {
  var n, p, s, z
  for(var i=stack.length-1; i>=0; --i) {
    n = stack[i]
    if(i === 0) {
      n._color = BLACK
      return
    }
    //console.log("visit node:", n.key, i, stack[i].key, stack[i-1].key)
    p = stack[i-1]
    if(p.left === n) {
      //console.log("left child")
      s = p.right
      if(s.right && s.right._color === RED) {
        //console.log("case 1: right sibling child red")
        s = p.right = cloneNode(s)
        z = s.right = cloneNode(s.right)
        p.right = s.left
        s.left = p
        s.right = z
        s._color = p._color
        n._color = BLACK
        p._color = BLACK
        z._color = BLACK
        recount(p)
        recount(s)
        if(i > 1) {
          var pp = stack[i-2]
          if(pp.left === p) {
            pp.left = s
          } else {
            pp.right = s
          }
        }
        stack[i-1] = s
        return
      } else if(s.left && s.left._color === RED) {
        //console.log("case 1: left sibling child red")
        s = p.right = cloneNode(s)
        z = s.left = cloneNode(s.left)
        p.right = z.left
        s.left = z.right
        z.left = p
        z.right = s
        z._color = p._color
        p._color = BLACK
        s._color = BLACK
        n._color = BLACK
        recount(p)
        recount(s)
        recount(z)
        if(i > 1) {
          var pp = stack[i-2]
          if(pp.left === p) {
            pp.left = z
          } else {
            pp.right = z
          }
        }
        stack[i-1] = z
        return
      }
      if(s._color === BLACK) {
        if(p._color === RED) {
          //console.log("case 2: black sibling, red parent", p.right.value)
          p._color = BLACK
          p.right = repaint(RED, s)
          return
        } else {
          //console.log("case 2: black sibling, black parent", p.right.value)
          p.right = repaint(RED, s)
          continue  
        }
      } else {
        //console.log("case 3: red sibling")
        s = cloneNode(s)
        p.right = s.left
        s.left = p
        s._color = p._color
        p._color = RED
        recount(p)
        recount(s)
        if(i > 1) {
          var pp = stack[i-2]
          if(pp.left === p) {
            pp.left = s
          } else {
            pp.right = s
          }
        }
        stack[i-1] = s
        stack[i] = p
        if(i+1 < stack.length) {
          stack[i+1] = n
        } else {
          stack.push(n)
        }
        i = i+2
      }
    } else {
      //console.log("right child")
      s = p.left
      if(s.left && s.left._color === RED) {
        //console.log("case 1: left sibling child red", p.value, p._color)
        s = p.left = cloneNode(s)
        z = s.left = cloneNode(s.left)
        p.left = s.right
        s.right = p
        s.left = z
        s._color = p._color
        n._color = BLACK
        p._color = BLACK
        z._color = BLACK
        recount(p)
        recount(s)
        if(i > 1) {
          var pp = stack[i-2]
          if(pp.right === p) {
            pp.right = s
          } else {
            pp.left = s
          }
        }
        stack[i-1] = s
        return
      } else if(s.right && s.right._color === RED) {
        //console.log("case 1: right sibling child red")
        s = p.left = cloneNode(s)
        z = s.right = cloneNode(s.right)
        p.left = z.right
        s.right = z.left
        z.right = p
        z.left = s
        z._color = p._color
        p._color = BLACK
        s._color = BLACK
        n._color = BLACK
        recount(p)
        recount(s)
        recount(z)
        if(i > 1) {
          var pp = stack[i-2]
          if(pp.right === p) {
            pp.right = z
          } else {
            pp.left = z
          }
        }
        stack[i-1] = z
        return
      }
      if(s._color === BLACK) {
        if(p._color === RED) {
          //console.log("case 2: black sibling, red parent")
          p._color = BLACK
          p.left = repaint(RED, s)
          return
        } else {
          //console.log("case 2: black sibling, black parent")
          p.left = repaint(RED, s)
          continue  
        }
      } else {
        //console.log("case 3: red sibling")
        s = cloneNode(s)
        p.left = s.right
        s.right = p
        s._color = p._color
        p._color = RED
        recount(p)
        recount(s)
        if(i > 1) {
          var pp = stack[i-2]
          if(pp.right === p) {
            pp.right = s
          } else {
            pp.left = s
          }
        }
        stack[i-1] = s
        stack[i] = p
        if(i+1 < stack.length) {
          stack[i+1] = n
        } else {
          stack.push(n)
        }
        i = i+2
      }
    }
  }
}

//Removes item at iterator from tree
iproto.remove = function() {
  var stack = this._stack
  if(stack.length === 0) {
    return this.tree
  }
  //First copy path to node
  var cstack = new Array(stack.length)
  var n = stack[stack.length-1]
  cstack[cstack.length-1] = new RBNode(n._color, n.key, n.value, n.left, n.right, n._count)
  for(var i=stack.length-2; i>=0; --i) {
    var n = stack[i]
    if(n.left === stack[i+1]) {
      cstack[i] = new RBNode(n._color, n.key, n.value, cstack[i+1], n.right, n._count)
    } else {
      cstack[i] = new RBNode(n._color, n.key, n.value, n.left, cstack[i+1], n._count)
    }
  }

  //Get node
  n = cstack[cstack.length-1]
  //console.log("start remove: ", n.value)

  //If not leaf, then swap with previous node
  if(n.left && n.right) {
    //console.log("moving to leaf")

    //First walk to previous leaf
    var split = cstack.length
    n = n.left
    while(n.right) {
      cstack.push(n)
      n = n.right
    }
    //Copy path to leaf
    var v = cstack[split-1]
    cstack.push(new RBNode(n._color, v.key, v.value, n.left, n.right, n._count))
    cstack[split-1].key = n.key
    cstack[split-1].value = n.value

    //Fix up stack
    for(var i=cstack.length-2; i>=split; --i) {
      n = cstack[i]
      cstack[i] = new RBNode(n._color, n.key, n.value, n.left, cstack[i+1], n._count)
    }
    cstack[split-1].left = cstack[split]
  }
  //console.log("stack=", cstack.map(function(v) { return v.value }))

  //Remove leaf node
  n = cstack[cstack.length-1]
  if(n._color === RED) {
    //Easy case: removing red leaf
    //console.log("RED leaf")
    var p = cstack[cstack.length-2]
    if(p.left === n) {
      p.left = null
    } else if(p.right === n) {
      p.right = null
    }
    cstack.pop()
    for(var i=0; i 0) {
      return this._stack[this._stack.length-1].key
    }
    return
  },
  enumerable: true
})

//Returns value
Object.defineProperty(iproto, "value", {
  get: function() {
    if(this._stack.length > 0) {
      return this._stack[this._stack.length-1].value
    }
    return
  },
  enumerable: true
})


//Returns the position of this iterator in the sorted list
Object.defineProperty(iproto, "index", {
  get: function() {
    var idx = 0
    var stack = this._stack
    if(stack.length === 0) {
      var r = this.tree.root
      if(r) {
        return r._count
      }
      return 0
    } else if(stack[stack.length-1].left) {
      idx = stack[stack.length-1].left._count
    }
    for(var s=stack.length-2; s>=0; --s) {
      if(stack[s+1] === stack[s].right) {
        ++idx
        if(stack[s].left) {
          idx += stack[s].left._count
        }
      }
    }
    return idx
  },
  enumerable: true
})

//Advances iterator to next element in list
iproto.next = function() {
  var stack = this._stack
  if(stack.length === 0) {
    return
  }
  var n = stack[stack.length-1]
  if(n.right) {
    n = n.right
    while(n) {
      stack.push(n)
      n = n.left
    }
  } else {
    stack.pop()
    while(stack.length > 0 && stack[stack.length-1].right === n) {
      n = stack[stack.length-1]
      stack.pop()
    }
  }
}

//Checks if iterator is at end of tree
Object.defineProperty(iproto, "hasNext", {
  get: function() {
    var stack = this._stack
    if(stack.length === 0) {
      return false
    }
    if(stack[stack.length-1].right) {
      return true
    }
    for(var s=stack.length-1; s>0; --s) {
      if(stack[s-1].left === stack[s]) {
        return true
      }
    }
    return false
  }
})

//Update value
iproto.update = function(value) {
  var stack = this._stack
  if(stack.length === 0) {
    throw new Error("Can't update empty node!")
  }
  var cstack = new Array(stack.length)
  var n = stack[stack.length-1]
  cstack[cstack.length-1] = new RBNode(n._color, n.key, value, n.left, n.right, n._count)
  for(var i=stack.length-2; i>=0; --i) {
    n = stack[i]
    if(n.left === stack[i+1]) {
      cstack[i] = new RBNode(n._color, n.key, n.value, cstack[i+1], n.right, n._count)
    } else {
      cstack[i] = new RBNode(n._color, n.key, n.value, n.left, cstack[i+1], n._count)
    }
  }
  return new RedBlackTree(this.tree._compare, cstack[0])
}

//Moves iterator backward one element
iproto.prev = function() {
  var stack = this._stack
  if(stack.length === 0) {
    return
  }
  var n = stack[stack.length-1]
  if(n.left) {
    n = n.left
    while(n) {
      stack.push(n)
      n = n.right
    }
  } else {
    stack.pop()
    while(stack.length > 0 && stack[stack.length-1].left === n) {
      n = stack[stack.length-1]
      stack.pop()
    }
  }
}

//Checks if iterator is at start of tree
Object.defineProperty(iproto, "hasPrev", {
  get: function() {
    var stack = this._stack
    if(stack.length === 0) {
      return false
    }
    if(stack[stack.length-1].left) {
      return true
    }
    for(var s=stack.length-1; s>0; --s) {
      if(stack[s-1].right === stack[s]) {
        return true
      }
    }
    return false
  }
})

//Default comparison function
function defaultCompare(a, b) {
  if(a < b) {
    return -1
  }
  if(a > b) {
    return 1
  }
  return 0
}

//Build a tree
function createRBTree(compare) {
  return new RedBlackTree(compare || defaultCompare, null)
}

/***/ }),

/***/ 3837:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

"use strict";


module.exports = createAxes

var createText        = __webpack_require__(4935)
var createLines       = __webpack_require__(501)
var createBackground  = __webpack_require__(5304)
var getCubeProperties = __webpack_require__(6429)
var Ticks             = __webpack_require__(6444)

var identity = new Float32Array([
  1, 0, 0, 0,
  0, 1, 0, 0,
  0, 0, 1, 0,
  0, 0, 0, 1])

var ab = ArrayBuffer
var dv = DataView

function isTypedArray(a) {
    return ab.isView(a) && !(a instanceof dv)
}

function isArrayOrTypedArray(a) {
    return Array.isArray(a) || isTypedArray(a)
}

function copyVec3(a, b) {
  a[0] = b[0]
  a[1] = b[1]
  a[2] = b[2]
  return a
}

function Axes(gl) {
  this.gl             = gl

  this.pixelRatio     = 1

  this.bounds         = [ [-10, -10, -10],
                          [ 10,  10,  10] ]
  this.ticks          = [ [], [], [] ]
  this.autoTicks      = true
  this.tickSpacing    = [ 1, 1, 1 ]

  this.tickEnable     = [ true, true, true ]
  this.tickFont       = [ 'sans-serif', 'sans-serif', 'sans-serif' ]
  this.tickFontStyle   = [ 'normal', 'normal', 'normal' ]
  this.tickFontWeight  = [ 'normal', 'normal', 'normal' ]
  this.tickFontVariant = [ 'normal', 'normal', 'normal' ]
  this.tickSize       = [ 12, 12, 12 ]
  this.tickAngle      = [ 0, 0, 0 ]
  this.tickAlign      = [ 'auto', 'auto', 'auto' ]
  this.tickColor      = [ [0,0,0,1], [0,0,0,1], [0,0,0,1] ]
  this.tickPad        = [ 10, 10, 10 ]

  this.lastCubeProps  = {
    cubeEdges: [0,0,0],
    axis:      [0,0,0]
  }

  this.labels         = [ 'x', 'y', 'z' ]
  this.labelEnable    = [ true, true, true ]
  this.labelFont      = [ 'sans-serif', 'sans-serif', 'sans-serif' ]
  this.labelFontStyle   = [ 'normal', 'normal', 'normal' ]
  this.labelFontWeight  = [ 'normal', 'normal', 'normal' ]
  this.labelFontVariant = [ 'normal', 'normal', 'normal' ]
  this.labelSize      = [ 20, 20, 20 ]
  this.labelAngle     = [ 0, 0, 0 ]
  this.labelAlign     = [ 'auto', 'auto', 'auto' ]
  this.labelColor     = [ [0,0,0,1], [0,0,0,1], [0,0,0,1] ]
  this.labelPad       = [ 10, 10, 10 ]

  this.lineEnable     = [ true, true, true ]
  this.lineMirror     = [ false, false, false ]
  this.lineWidth      = [ 1, 1, 1 ]
  this.lineColor      = [ [0,0,0,1], [0,0,0,1], [0,0,0,1] ]

  this.lineTickEnable = [ true, true, true ]
  this.lineTickMirror = [ false, false, false ]
  this.lineTickLength = [ 0, 0, 0 ]
  this.lineTickWidth  = [ 1, 1, 1 ]
  this.lineTickColor  = [ [0,0,0,1], [0,0,0,1], [0,0,0,1] ]

  this.gridEnable     = [ true, true, true ]
  this.gridWidth      = [ 1, 1, 1 ]
  this.gridColor      = [ [0,0,0,1], [0,0,0,1], [0,0,0,1] ]

  this.zeroEnable     = [ true, true, true ]
  this.zeroLineColor  = [ [0,0,0,1], [0,0,0,1], [0,0,0,1] ]
  this.zeroLineWidth  = [ 2, 2, 2 ]

  this.backgroundEnable = [ false, false, false ]
  this.backgroundColor  = [ [0.8, 0.8, 0.8, 0.5],
                            [0.8, 0.8, 0.8, 0.5],
                            [0.8, 0.8, 0.8, 0.5] ]

  this._firstInit = true
  this._text  = null
  this._lines = null
  this._background = createBackground(gl)
}

var proto = Axes.prototype

proto.update = function(options) {
  options = options || {}

  //Option parsing helper functions
  function parseOption(nest, cons, name) {
    if(name in options) {
      var opt = options[name]
      var prev = this[name]
      var next
      if(nest ? (isArrayOrTypedArray(opt) && isArrayOrTypedArray(opt[0])) :
                 isArrayOrTypedArray(opt) ) {
        this[name] = next = [ cons(opt[0]), cons(opt[1]), cons(opt[2]) ]
      } else {
        this[name] = next = [ cons(opt), cons(opt), cons(opt) ]
      }
      for(var i=0; i<3; ++i) {
        if(next[i] !== prev[i]) {
          return true
        }
      }
    }
    return false
  }

  var NUMBER  = parseOption.bind(this, false, Number)
  var BOOLEAN = parseOption.bind(this, false, Boolean)
  var STRING  = parseOption.bind(this, false, String)
  var COLOR   = parseOption.bind(this, true, function(v) {
    if(isArrayOrTypedArray(v)) {
      if(v.length === 3) {
        return [ +v[0], +v[1], +v[2], 1.0 ]
      } else if(v.length === 4) {
        return [ +v[0], +v[1], +v[2], +v[3] ]
      }
    }
    return [ 0, 0, 0, 1 ]
  })

  //Tick marks and bounds
  var nextTicks
  var ticksUpdate   = false
  var boundsChanged = false
  if('bounds' in options) {
    var bounds = options.bounds
i_loop:
    for(var i=0; i<2; ++i) {
      for(var j=0; j<3; ++j) {
        if(bounds[i][j] !== this.bounds[i][j]) {
          boundsChanged = true
        }
        this.bounds[i][j] = bounds[i][j]
      }
    }
  }
  if('ticks' in options) {
    nextTicks      = options.ticks
    ticksUpdate    = true
    this.autoTicks = false
    for(var i=0; i<3; ++i) {
      this.tickSpacing[i] = 0.0
    }
  } else if(NUMBER('tickSpacing')) {
    this.autoTicks  = true
    boundsChanged   = true
  }

  if(this._firstInit) {
    if(!('ticks' in options || 'tickSpacing' in options)) {
      this.autoTicks = true
    }

    //Force tick recomputation on first update
    boundsChanged   = true
    ticksUpdate     = true
    this._firstInit = false
  }

  if(boundsChanged && this.autoTicks) {
    nextTicks = Ticks.create(this.bounds, this.tickSpacing)
    ticksUpdate = true
  }

  //Compare next ticks to previous ticks, only update if needed
  if(ticksUpdate) {
    for(var i=0; i<3; ++i) {
      nextTicks[i].sort(function(a,b) {
        return a.x-b.x
      })
    }
    if(Ticks.equal(nextTicks, this.ticks)) {
      ticksUpdate = false
    } else {
      this.ticks = nextTicks
    }
  }

  //Parse tick properties
  BOOLEAN('tickEnable')

  //If font changes, must rebuild vbo
  if(STRING('tickFont')) ticksUpdate = true
  if(STRING('tickFontStyle')) ticksUpdate = true
  if(STRING('tickFontWeight')) ticksUpdate = true
  if(STRING('tickFontVariant')) ticksUpdate = true

  NUMBER('tickSize')
  NUMBER('tickAngle')
  NUMBER('tickPad')
  COLOR('tickColor')

  //Axis labels
  var labelUpdate = STRING('labels')

  if(STRING('labelFont')) labelUpdate = true
  if(STRING('labelFontStyle')) labelUpdate = true
  if(STRING('labelFontWeight')) labelUpdate = true
  if(STRING('labelFontVariant')) labelUpdate = true

  BOOLEAN('labelEnable')
  NUMBER('labelSize')
  NUMBER('labelPad')
  COLOR('labelColor')

  //Axis lines
  BOOLEAN('lineEnable')
  BOOLEAN('lineMirror')
  NUMBER('lineWidth')
  COLOR('lineColor')

  //Axis line ticks
  BOOLEAN('lineTickEnable')
  BOOLEAN('lineTickMirror')
  NUMBER('lineTickLength')
  NUMBER('lineTickWidth')
  COLOR('lineTickColor')

  //Grid lines
  BOOLEAN('gridEnable')
  NUMBER('gridWidth')
  COLOR('gridColor')

  //Zero line
  BOOLEAN('zeroEnable')
  COLOR('zeroLineColor')
  NUMBER('zeroLineWidth')

  //Background
  BOOLEAN('backgroundEnable')
  COLOR('backgroundColor')

  var labelFontOpts = [
    {
      family: this.labelFont[0],
      style: this.labelFontStyle[0],
      weight: this.labelFontWeight[0],
      variant: this.labelFontVariant[0],
    },
    {
      family: this.labelFont[1],
      style: this.labelFontStyle[1],
      weight: this.labelFontWeight[1],
      variant: this.labelFontVariant[1],
    },
    {
      family: this.labelFont[2],
      style: this.labelFontStyle[2],
      weight: this.labelFontWeight[2],
      variant: this.labelFontVariant[2],
    }
  ]

  var tickFontOpts = [
    {
      family: this.tickFont[0],
      style: this.tickFontStyle[0],
      weight: this.tickFontWeight[0],
      variant: this.tickFontVariant[0],
    },
    {
      family: this.tickFont[1],
      style: this.tickFontStyle[1],
      weight: this.tickFontWeight[1],
      variant: this.tickFontVariant[1],
    },
    {
      family: this.tickFont[2],
      style: this.tickFontStyle[2],
      weight: this.tickFontWeight[2],
      variant: this.tickFontVariant[2],
    }
  ]

  //Update text if necessary
  if(!this._text) {
    this._text = createText(
      this.gl,
      this.bounds,
      this.labels,
      labelFontOpts,
      this.ticks,
      tickFontOpts)
  } else if(this._text && (labelUpdate || ticksUpdate)) {
    this._text.update(
      this.bounds,
      this.labels,
      labelFontOpts,
      this.ticks,
      tickFontOpts)
  }

  //Update lines if necessary
  if(this._lines && ticksUpdate) {
    this._lines.dispose()
    this._lines = null
  }
  if(!this._lines) {
    this._lines = createLines(this.gl, this.bounds, this.ticks)
  }
}

function OffsetInfo() {
  this.primalOffset = [0,0,0]
  this.primalMinor  = [0,0,0]
  this.mirrorOffset = [0,0,0]
  this.mirrorMinor  = [0,0,0]
}

var LINE_OFFSET = [ new OffsetInfo(), new OffsetInfo(), new OffsetInfo() ]

function computeLineOffset(result, i, bounds, cubeEdges, cubeAxis) {
  var primalOffset = result.primalOffset
  var primalMinor  = result.primalMinor
  var dualOffset   = result.mirrorOffset
  var dualMinor    = result.mirrorMinor
  var e = cubeEdges[i]

  //Calculate offsets
  for(var j=0; j<3; ++j) {
    if(i === j) {
      continue
    }
    var a = primalOffset,
        b = dualOffset,
        c = primalMinor,
        d = dualMinor
    if(e & (1< 0) {
      c[j] = -1
      d[j] = 0
    } else {
      c[j] = 0
      d[j] = +1
    }
  }
}

var CUBE_ENABLE = [0,0,0]
var DEFAULT_PARAMS = {
  model:      identity,
  view:       identity,
  projection: identity,
  _ortho:      false
}

proto.isOpaque = function() {
  return true
}

proto.isTransparent = function() {
  return false
}

proto.drawTransparent = function(params) {}

var ALIGN_OPTION_AUTO = 0 // i.e. as defined in the shader the text would rotate to stay upwards range: [-90,90]

var PRIMAL_MINOR  = [0,0,0]
var MIRROR_MINOR  = [0,0,0]
var PRIMAL_OFFSET = [0,0,0]

proto.draw = function(params) {
  params = params || DEFAULT_PARAMS

  var gl = this.gl

  //Geometry for camera and axes
  var model       = params.model || identity
  var view        = params.view || identity
  var projection  = params.projection || identity
  var bounds      = this.bounds
  var isOrtho     = params._ortho || false

  //Unpack axis info
  var cubeParams  = getCubeProperties(model, view, projection, bounds, isOrtho)
  var cubeEdges   = cubeParams.cubeEdges
  var cubeAxis    = cubeParams.axis

  var cx = view[12]
  var cy = view[13]
  var cz = view[14]
  var cw = view[15]

  var orthoFix = (isOrtho) ? 2 : 1 // double up padding for orthographic ticks & labels
  var pixelScaleF = orthoFix * this.pixelRatio * (projection[3]*cx + projection[7]*cy + projection[11]*cz + projection[15]*cw) / gl.drawingBufferHeight

  for(var i=0; i<3; ++i) {
    this.lastCubeProps.cubeEdges[i] = cubeEdges[i]
    this.lastCubeProps.axis[i] = cubeAxis[i]
  }

  //Compute axis info
  var lineOffset  = LINE_OFFSET
  for(var i=0; i<3; ++i) {
    computeLineOffset(
      LINE_OFFSET[i],
      i,
      this.bounds,
      cubeEdges,
      cubeAxis)
  }

  //Set up state parameters
  var gl = this.gl

  //Draw background first
  var cubeEnable = CUBE_ENABLE
  for(var i=0; i<3; ++i) {
    if(this.backgroundEnable[i]) {
      cubeEnable[i] = cubeAxis[i]
    } else {
      cubeEnable[i] = 0
    }
  }

  this._background.draw(
    model,
    view,
    projection,
    bounds,
    cubeEnable,
    this.backgroundColor)

  //Draw lines
  this._lines.bind(
    model,
    view,
    projection,
    this)

  //First draw grid lines and zero lines
  for(var i=0; i<3; ++i) {
    var x = [0,0,0]
    if(cubeAxis[i] > 0) {
      x[i] = bounds[1][i]
    } else {
      x[i] = bounds[0][i]
    }

    //Draw grid lines
    for(var j=0; j<2; ++j) {
      var u = (i + 1 + j) % 3
      var v = (i + 1 + (j^1)) % 3
      if(this.gridEnable[u]) {
        this._lines.drawGrid(u, v, this.bounds, x, this.gridColor[u], this.gridWidth[u]*this.pixelRatio)
      }
    }

    //Draw zero lines (need to do this AFTER all grid lines are drawn)
    for(var j=0; j<2; ++j) {
      var u = (i + 1 + j) % 3
      var v = (i + 1 + (j^1)) % 3
      if(this.zeroEnable[v]) {
        //Check if zero line in bounds
        if(Math.min(bounds[0][v], bounds[1][v]) <= 0 && Math.max(bounds[0][v], bounds[1][v]) >= 0) {
          this._lines.drawZero(u, v, this.bounds, x, this.zeroLineColor[v], this.zeroLineWidth[v]*this.pixelRatio)
        }
      }
    }
  }

  //Then draw axis lines and tick marks
  for(var i=0; i<3; ++i) {

    //Draw axis lines
    if(this.lineEnable[i]) {
      this._lines.drawAxisLine(i, this.bounds, lineOffset[i].primalOffset, this.lineColor[i], this.lineWidth[i]*this.pixelRatio)
    }
    if(this.lineMirror[i]) {
      this._lines.drawAxisLine(i, this.bounds, lineOffset[i].mirrorOffset, this.lineColor[i], this.lineWidth[i]*this.pixelRatio)
    }

    //Compute minor axes
    var primalMinor = copyVec3(PRIMAL_MINOR, lineOffset[i].primalMinor)
    var mirrorMinor = copyVec3(MIRROR_MINOR, lineOffset[i].mirrorMinor)
    var tickLength  = this.lineTickLength
    for(var j=0; j<3; ++j) {
      var scaleFactor = pixelScaleF / model[5*j]
      primalMinor[j] *= tickLength[j] * scaleFactor
      mirrorMinor[j] *= tickLength[j] * scaleFactor
    }



    //Draw axis line ticks
    if(this.lineTickEnable[i]) {
      this._lines.drawAxisTicks(i, lineOffset[i].primalOffset, primalMinor, this.lineTickColor[i], this.lineTickWidth[i]*this.pixelRatio)
    }
    if(this.lineTickMirror[i]) {
      this._lines.drawAxisTicks(i, lineOffset[i].mirrorOffset, mirrorMinor, this.lineTickColor[i], this.lineTickWidth[i]*this.pixelRatio)
    }
  }
  this._lines.unbind()

  //Draw text sprites
  this._text.bind(
    model,
    view,
    projection,
    this.pixelRatio)

  var alignOpt // options in shader are from this list {-1, 0, 1, 2, 3, ..., n}
  // -1: backward compatible
  //  0: raw data
  //  1: auto align, free angles
  //  2: auto align, horizontal or vertical
  //3-n: auto align, round to n directions e.g. 12 -> round to angles with 30-degree steps

  var hv_ratio = 0.5 // can have an effect on the ratio between horizontals and verticals when using option 2

  var enableAlign
  var alignDir

  function alignTo(i) {
    alignDir = [0,0,0]
    alignDir[i] = 1
  }

  function solveTickAlignments(i, minor, major) {

    var i1 = (i + 1) % 3
    var i2 = (i + 2) % 3

    var A = minor[i1]
    var B = minor[i2]
    var C = major[i1]
    var D = major[i2]

         if ((A > 0) && (D > 0)) { alignTo(i1); return; }
    else if ((A > 0) && (D < 0)) { alignTo(i1); return; }
    else if ((A < 0) && (D > 0)) { alignTo(i1); return; }
    else if ((A < 0) && (D < 0)) { alignTo(i1); return; }
    else if ((B > 0) && (C > 0)) { alignTo(i2); return; }
    else if ((B > 0) && (C < 0)) { alignTo(i2); return; }
    else if ((B < 0) && (C > 0)) { alignTo(i2); return; }
    else if ((B < 0) && (C < 0)) { alignTo(i2); return; }
  }

  for(var i=0; i<3; ++i) {

    var minor      = lineOffset[i].primalMinor
    var major      = lineOffset[i].mirrorMinor

    var offset     = copyVec3(PRIMAL_OFFSET, lineOffset[i].primalOffset)

    for(var j=0; j<3; ++j) {
      if(this.lineTickEnable[i]) {
        offset[j] += pixelScaleF * minor[j] * Math.max(this.lineTickLength[j], 0)  / model[5*j]
      }
    }

    var axis = [0,0,0]
    axis[i] = 1

    //Draw tick text
    if(this.tickEnable[i]) {

      if(this.tickAngle[i] === -3600) {
        this.tickAngle[i] = 0
        this.tickAlign[i] = 'auto'
      } else {
        this.tickAlign[i] = -1
      }

      enableAlign = 1;

      alignOpt = [this.tickAlign[i], hv_ratio, enableAlign]
      if(alignOpt[0] === 'auto') alignOpt[0] = ALIGN_OPTION_AUTO
      else alignOpt[0] = parseInt('' + alignOpt[0])

      alignDir = [0,0,0]
      solveTickAlignments(i, minor, major)

      //Add tick padding
      for(var j=0; j<3; ++j) {
        offset[j] += pixelScaleF * minor[j] * this.tickPad[j] / model[5*j]
      }

      //Draw axis
      this._text.drawTicks(
        i,
        this.tickSize[i],
        this.tickAngle[i],
        offset,
        this.tickColor[i],
        axis,
        alignDir,
        alignOpt)
    }

    //Draw labels
    if(this.labelEnable[i]) {

      enableAlign = 0
      alignDir = [0,0,0]
      if(this.labels[i].length > 4) { // for large label axis enable alignDir to axis
        alignTo(i)
        enableAlign = 1
      }

      alignOpt = [this.labelAlign[i], hv_ratio, enableAlign]
      if(alignOpt[0] === 'auto') alignOpt[0] = ALIGN_OPTION_AUTO
      else alignOpt[0] = parseInt('' + alignOpt[0])

      //Add label padding
      for(var j=0; j<3; ++j) {
        offset[j] += pixelScaleF * minor[j] * this.labelPad[j] / model[5*j]
      }
      offset[i] += 0.5 * (bounds[0][i] + bounds[1][i])

      //Draw axis
      this._text.drawLabel(
        i,
        this.labelSize[i],
        this.labelAngle[i],
        offset,
        this.labelColor[i],
        [0,0,0],
        alignDir,
        alignOpt)
    }
  }

  this._text.unbind()
}

proto.dispose = function() {
  this._text.dispose()
  this._lines.dispose()
  this._background.dispose()
  this._lines = null
  this._text = null
  this._background = null
  this.gl = null
}

function createAxes(gl, options) {
  var axes = new Axes(gl)
  axes.update(options)
  return axes
}


/***/ }),

/***/ 5304:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

"use strict";


module.exports = createBackgroundCube

var createBuffer = __webpack_require__(2762)
var createVAO    = __webpack_require__(8116)
var createShader = (__webpack_require__(1879).bg)

function BackgroundCube(gl, buffer, vao, shader) {
  this.gl = gl
  this.buffer = buffer
  this.vao = vao
  this.shader = shader
}

var proto = BackgroundCube.prototype

proto.draw = function(model, view, projection, bounds, enable, colors) {
  var needsBG = false
  for(var i=0; i<3; ++i) {
    needsBG = needsBG || enable[i]
  }
  if(!needsBG) {
    return
  }

  var gl = this.gl

  gl.enable(gl.POLYGON_OFFSET_FILL)
  gl.polygonOffset(1, 2)

  this.shader.bind()
  this.shader.uniforms = {
    model: model,
    view: view,
    projection: projection,
    bounds: bounds,
    enable: enable,
    colors: colors
  }
  this.vao.bind()
  this.vao.draw(this.gl.TRIANGLES, 36)
  this.vao.unbind()

  gl.disable(gl.POLYGON_OFFSET_FILL)
}

proto.dispose = function() {
  this.vao.dispose()
  this.buffer.dispose()
  this.shader.dispose()
}

function createBackgroundCube(gl) {
  //Create cube vertices
  var vertices = []
  var indices  = []
  var ptr = 0
  for(var d=0; d<3; ++d) {
    var u = (d+1) % 3
    var v = (d+2) % 3
    var x = [0,0,0]
    var c = [0,0,0]
    for(var s=-1; s<=1; s+=2) {
      indices.push(ptr,   ptr+2, ptr+1,
                   ptr+1, ptr+2, ptr+3)
      x[d] = s
      c[d] = s
      for(var i=-1; i<=1; i+=2) {
        x[u] = i
        for(var j=-1; j<=1; j+=2) {
          x[v] = j
          vertices.push(x[0], x[1], x[2],
                        c[0], c[1], c[2])
          ptr += 1
        }
      }
      //Swap u and v
      var tt = u
      u = v
      v = tt
    }
  }

  //Allocate buffer and vertex array
  var buffer = createBuffer(gl, new Float32Array(vertices))
  var elements = createBuffer(gl, new Uint16Array(indices), gl.ELEMENT_ARRAY_BUFFER)
  var vao = createVAO(gl, [
      {
        buffer: buffer,
        type: gl.FLOAT,
        size: 3,
        offset: 0,
        stride: 24
      },
      {
        buffer: buffer,
        type: gl.FLOAT,
        size: 3,
        offset: 12,
        stride: 24
      }
    ], elements)

  //Create shader object
  var shader = createShader(gl)
  shader.attributes.position.location = 0
  shader.attributes.normal.location = 1

  return new BackgroundCube(gl, buffer, vao, shader)
}


/***/ }),

/***/ 6429:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

"use strict";


module.exports = getCubeEdges

var bits      = __webpack_require__(8828)
var multiply  = __webpack_require__(6760)
var splitPoly = __webpack_require__(5202)
var orient    = __webpack_require__(3250)

var mvp        = new Array(16)
var pCubeVerts = new Array(8)
var cubeVerts  = new Array(8)
var x          = new Array(3)
var zero3      = [0,0,0]

;(function() {
  for(var i=0; i<8; ++i) {
    pCubeVerts[i] =[1,1,1,1]
    cubeVerts[i] = [1,1,1]
  }
})()


function transformHg(result, x, mat) {
  for(var i=0; i<4; ++i) {
    result[i] = mat[12+i]
    for(var j=0; j<3; ++j) {
      result[i] += x[j]*mat[4*j+i]
    }
  }
}

var FRUSTUM_PLANES = [
  [ 0, 0, 1, 0, 0],
  [ 0, 0,-1, 1, 0],
  [ 0,-1, 0, 1, 0],
  [ 0, 1, 0, 1, 0],
  [-1, 0, 0, 1, 0],
  [ 1, 0, 0, 1, 0]
]

function polygonArea(p) {
  for(var i=0; i o0) {
          closest |= 1< o0) {
        closest |= 1< cubeVerts[i][1]) {
      bottom = i
    }
  }

  //Find left/right neighbors of bottom vertex
  var left = -1
  for(var i=0; i<3; ++i) {
    var idx = bottom ^ (1< cubeVerts[right][0]) {
      right = idx
    }
  }

  //Determine edge axis coordinates
  var cubeEdges = CUBE_EDGES
  cubeEdges[0] = cubeEdges[1] = cubeEdges[2] = 0
  cubeEdges[bits.log2(left^bottom)] = bottom&left
  cubeEdges[bits.log2(bottom^right)] = bottom&right
  var top = right ^ 7
  if(top === closest || top === farthest) {
    top = left ^ 7
    cubeEdges[bits.log2(right^top)] = top&right
  } else {
    cubeEdges[bits.log2(left^top)] = top&left
  }

  //Determine visible faces
  var axis = CUBE_AXIS
  var cutCorner = closest
  for(var d=0; d<3; ++d) {
    if(cutCorner & (1< HALF_PI) && (b <= ONE_AND_HALF_PI)) ?\n    b - PI :\n    b;\n}\n\nfloat look_horizontal_or_vertical(float a, float ratio) {\n  // ratio controls the ratio between being horizontal to (vertical + horizontal)\n  // if ratio is set to 0.5 then it is 50%, 50%.\n  // when using a higher ratio e.g. 0.75 the result would\n  // likely be more horizontal than vertical.\n\n  float b = positive_angle(a);\n\n  return\n    (b < (      ratio) * HALF_PI) ? 0.0 :\n    (b < (2.0 - ratio) * HALF_PI) ? -HALF_PI :\n    (b < (2.0 + ratio) * HALF_PI) ? 0.0 :\n    (b < (4.0 - ratio) * HALF_PI) ? HALF_PI :\n                                    0.0;\n}\n\nfloat roundTo(float a, float b) {\n  return float(b * floor((a + 0.5 * b) / b));\n}\n\nfloat look_round_n_directions(float a, int n) {\n  float b = positive_angle(a);\n  float div = TWO_PI / float(n);\n  float c = roundTo(b, div);\n  return look_upwards(c);\n}\n\nfloat applyAlignOption(float rawAngle, float delta) {\n  return\n    (option >  2) ? look_round_n_directions(rawAngle + delta, option) :       // option 3-n: round to n directions\n    (option == 2) ? look_horizontal_or_vertical(rawAngle + delta, hv_ratio) : // horizontal or vertical\n    (option == 1) ? rawAngle + delta :       // use free angle, and flip to align with one direction of the axis\n    (option == 0) ? look_upwards(rawAngle) : // use free angle, and stay upwards\n    (option ==-1) ? 0.0 :                    // useful for backward compatibility, all texts remains horizontal\n                    rawAngle;                // otherwise return back raw input angle\n}\n\nbool isAxisTitle = (axis.x == 0.0) &&\n                   (axis.y == 0.0) &&\n                   (axis.z == 0.0);\n\nvoid main() {\n  //Compute world offset\n  float axisDistance = position.z;\n  vec3 dataPosition = axisDistance * axis + offset;\n\n  float beta = angle; // i.e. user defined attributes for each tick\n\n  float axisAngle;\n  float clipAngle;\n  float flip;\n\n  if (enableAlign) {\n    axisAngle = (isAxisTitle) ? HALF_PI :\n                      computeViewAngle(dataPosition, dataPosition + axis);\n    clipAngle = computeViewAngle(dataPosition, dataPosition + alignDir);\n\n    axisAngle += (sin(axisAngle) < 0.0) ? PI : 0.0;\n    clipAngle += (sin(clipAngle) < 0.0) ? PI : 0.0;\n\n    flip = (dot(vec2(cos(axisAngle), sin(axisAngle)),\n                vec2(sin(clipAngle),-cos(clipAngle))) > 0.0) ? 1.0 : 0.0;\n\n    beta += applyAlignOption(clipAngle, flip * PI);\n  }\n\n  //Compute plane offset\n  vec2 planeCoord = position.xy * pixelScale;\n\n  mat2 planeXform = scale * mat2(\n     cos(beta), sin(beta),\n    -sin(beta), cos(beta)\n  );\n\n  vec2 viewOffset = 2.0 * planeXform * planeCoord / resolution;\n\n  //Compute clip position\n  vec3 clipPosition = project(dataPosition);\n\n  //Apply text offset in clip coordinates\n  clipPosition += vec3(viewOffset, 0.0);\n\n  //Done\n  gl_Position = vec4(clipPosition, 1.0);\n}\n"])
var textFrag = glslify(["precision highp float;\n#define GLSLIFY 1\n\nuniform vec4 color;\nvoid main() {\n  gl_FragColor = color;\n}"])
exports.Q = function(gl) {
  return createShader(gl, textVert, textFrag, null, [
    {name: 'position', type: 'vec3'}
  ])
}

var bgVert = glslify(["precision highp float;\n#define GLSLIFY 1\n\nattribute vec3 position;\nattribute vec3 normal;\n\nuniform mat4 model, view, projection;\nuniform vec3 enable;\nuniform vec3 bounds[2];\n\nvarying vec3 colorChannel;\n\nvoid main() {\n\n  vec3 signAxis = sign(bounds[1] - bounds[0]);\n\n  vec3 realNormal = signAxis * normal;\n\n  if(dot(realNormal, enable) > 0.0) {\n    vec3 minRange = min(bounds[0], bounds[1]);\n    vec3 maxRange = max(bounds[0], bounds[1]);\n    vec3 nPosition = mix(minRange, maxRange, 0.5 * (position + 1.0));\n    gl_Position = projection * (view * (model * vec4(nPosition, 1.0)));\n  } else {\n    gl_Position = vec4(0,0,0,0);\n  }\n\n  colorChannel = abs(realNormal);\n}\n"])
var bgFrag = glslify(["precision highp float;\n#define GLSLIFY 1\n\nuniform vec4 colors[3];\n\nvarying vec3 colorChannel;\n\nvoid main() {\n  gl_FragColor = colorChannel.x * colors[0] +\n                 colorChannel.y * colors[1] +\n                 colorChannel.z * colors[2];\n}"])
exports.bg = function(gl) {
  return createShader(gl, bgVert, bgFrag, null, [
    {name: 'position', type: 'vec3'},
    {name: 'normal', type: 'vec3'}
  ])
}


/***/ }),

/***/ 4935:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

"use strict";


module.exports = createTextSprites

var createBuffer  = __webpack_require__(2762)
var createVAO     = __webpack_require__(8116)
var vectorizeText = __webpack_require__(4359)
var createShader  = (__webpack_require__(1879)/* .text */ .Q)

var globals = window || process.global || {}
var __TEXT_CACHE  = globals.__TEXT_CACHE || {}
globals.__TEXT_CACHE = {}

//Vertex buffer format for text is:
//
/// [x,y,z] = Spatial coordinate
//

var VERTEX_SIZE = 3

function TextSprites(
  gl,
  shader,
  buffer,
  vao) {
  this.gl           = gl
  this.shader       = shader
  this.buffer       = buffer
  this.vao          = vao
  this.tickOffset   =
  this.tickCount    =
  this.labelOffset  =
  this.labelCount   = null
}

var proto = TextSprites.prototype

//Bind textures for rendering
var SHAPE = [0,0]
proto.bind = function(model, view, projection, pixelScale) {
  this.vao.bind()
  this.shader.bind()
  var uniforms = this.shader.uniforms
  uniforms.model = model
  uniforms.view = view
  uniforms.projection = projection
  uniforms.pixelScale = pixelScale
  SHAPE[0] = this.gl.drawingBufferWidth
  SHAPE[1] = this.gl.drawingBufferHeight
  this.shader.uniforms.resolution = SHAPE
}

proto.unbind = function() {
  this.vao.unbind()
}

proto.update = function(bounds, labels, labelFont, ticks, tickFont) {
  var data = []

  function addItem(t, text, font, size, lineSpacing, styletags) {
    var fontKey = [
      font.style,
      font.weight,
      font.variant,
      font.family
    ].join('_')

    var fontcache = __TEXT_CACHE[fontKey]
    if(!fontcache) {
      fontcache = __TEXT_CACHE[fontKey] = {}
    }
    var mesh = fontcache[text]
    if(!mesh) {
      mesh = fontcache[text] = tryVectorizeText(text, {
        triangles: true,
        font: font.family,
        fontStyle: font.style,
        fontWeight: font.weight,
        fontVariant: font.variant,
        textAlign: 'center',
        textBaseline: 'middle',
        lineSpacing: lineSpacing,
        styletags: styletags
      })
    }
    var scale = (size || 12) / 12
    var positions = mesh.positions
    var cells = mesh.cells
    for(var i=0, nc=cells.length; i=0; --j) {
        var p = positions[c[j]]
        data.push(scale*p[0], -scale*p[1], t)
      }
    }
  }

  //Generate sprites for all 3 axes, store data in texture atlases
  var tickOffset  = [0,0,0]
  var tickCount   = [0,0,0]
  var labelOffset = [0,0,0]
  var labelCount  = [0,0,0]
  var lineSpacing = 1.25
  var styletags = {
    breaklines:true,
    bolds: true,
    italics: true,
    subscripts:true,
    superscripts:true
  }
  for(var d=0; d<3; ++d) {

    //Generate label
    labelOffset[d] = (data.length/VERTEX_SIZE)|0
    addItem(
      0.5*(bounds[0][d]+bounds[1][d]),
      labels[d],
      labelFont[d],
      12, // labelFontSize
      lineSpacing,
      styletags
    )
    labelCount[d] = ((data.length/VERTEX_SIZE)|0) - labelOffset[d]

    //Generate sprites for tick marks
    tickOffset[d] = (data.length/VERTEX_SIZE)|0
    for(var i=0; i= 0) {
    sigFigs = stepStr.length - u - 1
  }
  var shift = Math.pow(10, sigFigs)
  var x = Math.round(spacing * i * shift)
  var xstr = x + ""
  if(xstr.indexOf("e") >= 0) {
    return xstr
  }
  var xi = x / shift, xf = x % shift
  if(x < 0) {
    xi = -Math.ceil(xi)|0
    xf = (-xf)|0
  } else {
    xi = Math.floor(xi)|0
    xf = xf|0
  }
  var xis = "" + xi 
  if(x < 0) {
    xis = "-" + xis
  }
  if(sigFigs) {
    var xs = "" + xf
    while(xs.length < sigFigs) {
      xs = "0" + xs
    }
    return xis + "." + xs
  } else {
    return xis
  }
}

function defaultTicks(bounds, tickSpacing) {
  var array = []
  for(var d=0; d<3; ++d) {
    var ticks = []
    var m = 0.5*(bounds[0][d]+bounds[1][d])
    for(var t=0; t*tickSpacing[d]<=bounds[1][d]; ++t) {
      ticks.push({x: t*tickSpacing[d], text: prettyPrint(tickSpacing[d], t)})
    }
    for(var t=-1; t*tickSpacing[d]>=bounds[0][d]; --t) {
      ticks.push({x: t*tickSpacing[d], text: prettyPrint(tickSpacing[d], t)})
    }
    array.push(ticks)
  }
  return array
}

function ticksEqual(ticksA, ticksB) {
  for(var i=0; i<3; ++i) {
    if(ticksA[i].length !== ticksB[i].length) {
      return false
    }
    for(var j=0; j len) {
    throw new Error("gl-buffer: If resizing buffer, must not specify offset")
  }
  gl.bufferSubData(type, offset, data)
  return len
}

function makeScratchTypeArray(array, dtype) {
  var res = pool.malloc(array.length, dtype)
  var n = array.length
  for(var i=0; i=0; --i) {
    if(stride[i] !== n) {
      return false
    }
    n *= shape[i]
  }
  return true
}

proto.update = function(array, offset) {
  if(typeof offset !== "number") {
    offset = -1
  }
  this.bind()
  if(typeof array === "object" && typeof array.shape !== "undefined") { //ndarray
    var dtype = array.dtype
    if(SUPPORTED_TYPES.indexOf(dtype) < 0) {
      dtype = "float32"
    }
    if(this.type === this.gl.ELEMENT_ARRAY_BUFFER) {
      var ext = gl.getExtension('OES_element_index_uint')
      if(ext && dtype !== "uint16") {
        dtype = "uint32"
      } else {
        dtype = "uint16"
      }
    }
    if(dtype === array.dtype && isPacked(array.shape, array.stride)) {
      if(array.offset === 0 && array.data.length === array.shape[0]) {
        this.length = updateTypeArray(this.gl, this.type, this.length, this.usage, array.data, offset)
      } else {
        this.length = updateTypeArray(this.gl, this.type, this.length, this.usage, array.data.subarray(array.offset, array.shape[0]), offset)
      }
    } else {
      var tmp = pool.malloc(array.size, dtype)
      var ndt = ndarray(tmp, array.shape)
      ops.assign(ndt, array)
      if(offset < 0) {
        this.length = updateTypeArray(this.gl, this.type, this.length, this.usage, tmp, offset)
      } else {
        this.length = updateTypeArray(this.gl, this.type, this.length, this.usage, tmp.subarray(0, array.size), offset)
      }
      pool.free(tmp)
    }
  } else if(Array.isArray(array)) { //Vanilla array
    var t
    if(this.type === this.gl.ELEMENT_ARRAY_BUFFER) {
      t = makeScratchTypeArray(array, "uint16")
    } else {
      t = makeScratchTypeArray(array, "float32")
    }
    if(offset < 0) {
      this.length = updateTypeArray(this.gl, this.type, this.length, this.usage, t, offset)
    } else {
      this.length = updateTypeArray(this.gl, this.type, this.length, this.usage, t.subarray(0, array.length), offset)
    }
    pool.free(t)
  } else if(typeof array === "object" && typeof array.length === "number") { //Typed array
    this.length = updateTypeArray(this.gl, this.type, this.length, this.usage, array, offset)
  } else if(typeof array === "number" || array === undefined) { //Number/default
    if(offset >= 0) {
      throw new Error("gl-buffer: Cannot specify offset when resizing buffer")
    }
    array = array | 0
    if(array <= 0) {
      array = 1
    }
    this.gl.bufferData(this.type, array|0, this.usage)
    this.length = array
  } else { //Error, case should not happen
    throw new Error("gl-buffer: Invalid data type")
  }
}

function createBuffer(gl, data, type, usage) {
  type = type || gl.ARRAY_BUFFER
  usage = usage || gl.DYNAMIC_DRAW
  if(type !== gl.ARRAY_BUFFER && type !== gl.ELEMENT_ARRAY_BUFFER) {
    throw new Error("gl-buffer: Invalid type for webgl buffer, must be either gl.ARRAY_BUFFER or gl.ELEMENT_ARRAY_BUFFER")
  }
  if(usage !== gl.DYNAMIC_DRAW && usage !== gl.STATIC_DRAW && usage !== gl.STREAM_DRAW) {
    throw new Error("gl-buffer: Invalid usage for buffer, must be either gl.DYNAMIC_DRAW, gl.STATIC_DRAW or gl.STREAM_DRAW")
  }
  var handle = gl.createBuffer()
  var result = new GLBuffer(gl, type, handle, 0, usage)
  result.update(data)
  return result
}

module.exports = createBuffer


/***/ }),

/***/ 6405:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

"use strict";


var vec3 = __webpack_require__(2931);

module.exports = function(vectorfield, bounds) {
	var positions = vectorfield.positions;
	var vectors = vectorfield.vectors;
	var geo = {
		positions: [],
		vertexIntensity: [],
		vertexIntensityBounds: vectorfield.vertexIntensityBounds,
		vectors: [],
		cells: [],
		coneOffset: vectorfield.coneOffset,
		colormap: vectorfield.colormap
	};

	if (vectorfield.positions.length === 0) {
		if (bounds) {
			bounds[0] = [0,0,0];
			bounds[1] = [0,0,0];
		}
		return geo;
	}

	// Compute bounding box for the dataset.
	// Compute maximum velocity for the dataset to use for scaling the cones.
	var maxNorm = 0;
	var minX = Infinity, maxX = -Infinity;
	var minY = Infinity, maxY = -Infinity;
	var minZ = Infinity, maxZ = -Infinity;
	var p2 = null;
	var u2 = null;
	var positionVectors = [];
	var vectorScale = Infinity;
	var skipIt = false;
	var rawSizemodemode = vectorfield.coneSizemode === 'raw';
	for (var i = 0; i < positions.length; i++) {
		var p = positions[i];
		minX = Math.min(p[0], minX);
		maxX = Math.max(p[0], maxX);
		minY = Math.min(p[1], minY);
		maxY = Math.max(p[1], maxY);
		minZ = Math.min(p[2], minZ);
		maxZ = Math.max(p[2], maxZ);
		var u = vectors[i];

		if (vec3.length(u) > maxNorm) {
			maxNorm = vec3.length(u);
		}
		if (i && !rawSizemodemode) {
			// Find vector scale [w/ units of time] using "successive" positions
			// (not "adjacent" with would be O(n^2)),
			//
			// The vector scale corresponds to the minimum "time" to travel across two
			// two adjacent positions at the average velocity of those two adjacent positions

			var q = (2 * vec3.distance(p2, p) / (vec3.length(u2) + vec3.length(u)));
			if(q) {
				vectorScale = Math.min(vectorScale, q);
				skipIt = false;
			} else {
				skipIt = true;
			}
		}
		if(!skipIt) {
			p2 = p;
			u2 = u;
		}
		positionVectors.push(u);
	}
	var minV = [minX, minY, minZ];
	var maxV = [maxX, maxY, maxZ];
	if (bounds) {
		bounds[0] = minV;
		bounds[1] = maxV;
	}
	if (maxNorm === 0) {
		maxNorm = 1;
	}

	// Inverted max norm would map vector with norm maxNorm to 1 coord space units in length
	var invertedMaxNorm = 1 / maxNorm;

	if (!isFinite(vectorScale)) {
		vectorScale = 1.0;
	}
	geo.vectorScale = vectorScale;

	var coneScale = vectorfield.coneSize || (
		rawSizemodemode ? 1 :0.5
	);

	if (vectorfield.absoluteConeSize) {
		coneScale = vectorfield.absoluteConeSize * invertedMaxNorm;
	}

	geo.coneScale = coneScale;

	// Build the cone model.
	for (var i = 0, j = 0; i < positions.length; i++) {
		var p = positions[i];
		var x = p[0], y = p[1], z = p[2];
		var d = positionVectors[i];
		var intensity = vec3.length(d) * invertedMaxNorm;
		for (var k = 0, l = 8; k < l; k++) {
			geo.positions.push([x, y, z, j++]);
			geo.positions.push([x, y, z, j++]);
			geo.positions.push([x, y, z, j++]);
			geo.positions.push([x, y, z, j++]);
			geo.positions.push([x, y, z, j++]);
			geo.positions.push([x, y, z, j++]);

			geo.vectors.push(d);
			geo.vectors.push(d);
			geo.vectors.push(d);
			geo.vectors.push(d);
			geo.vectors.push(d);
			geo.vectors.push(d);

			geo.vertexIntensity.push(intensity, intensity, intensity);
			geo.vertexIntensity.push(intensity, intensity, intensity);

			var m = geo.positions.length;
			geo.cells.push([m-6, m-5, m-4], [m-3, m-2, m-1]);
		}
	}

	return geo;
};

var shaders = __webpack_require__(614);
module.exports.createMesh = __webpack_require__(9060);
module.exports.createConeMesh = function(gl, params) {
	return module.exports.createMesh(gl, params, {
		shaders: shaders,
		traceType: 'cone'
	});
}


/***/ }),

/***/ 9060:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

"use strict";


var createShader  = __webpack_require__(9405)
var createBuffer  = __webpack_require__(2762)
var createVAO     = __webpack_require__(8116)
var createTexture = __webpack_require__(7766)
var multiply      = __webpack_require__(6760)
var invert        = __webpack_require__(7608)
var ndarray       = __webpack_require__(9618)
var colormap      = __webpack_require__(6729)

var IDENTITY = [
  1,0,0,0,
  0,1,0,0,
  0,0,1,0,
  0,0,0,1]

function VectorMesh(gl
  , texture
  , triShader
  , pickShader
  , trianglePositions
  , triangleVectors
  , triangleIds
  , triangleColors
  , triangleUVs
  , triangleVAO
  , traceType) {

  this.gl                = gl
  this.pixelRatio         = 1
  this.cells             = []
  this.positions         = []
  this.intensity         = []
  this.texture           = texture
  this.dirty             = true

  this.triShader         = triShader
  this.pickShader        = pickShader

  this.trianglePositions = trianglePositions
  this.triangleVectors   = triangleVectors
  this.triangleColors    = triangleColors
  this.triangleUVs       = triangleUVs
  this.triangleIds       = triangleIds
  this.triangleVAO       = triangleVAO
  this.triangleCount     = 0

  this.pickId            = 1
  this.bounds            = [
    [ Infinity, Infinity, Infinity],
    [-Infinity,-Infinity,-Infinity] ]
  this.clipBounds        = [
    [-Infinity,-Infinity,-Infinity],
    [ Infinity, Infinity, Infinity] ]

  this.lightPosition = [1e5, 1e5, 0]
  this.ambientLight  = 0.8
  this.diffuseLight  = 0.8
  this.specularLight = 2.0
  this.roughness     = 0.5
  this.fresnel       = 1.5

  this.opacity       = 1

  this.traceType     = traceType
  this.tubeScale     = 1 // used in streamtube
  this.coneScale     = 2 // used in cone
  this.vectorScale   = 1 // used in cone
  this.coneOffset    = 0.25 // used in cone

  this._model       = IDENTITY
  this._view        = IDENTITY
  this._projection  = IDENTITY
  this._resolution  = [1,1]
}

var proto = VectorMesh.prototype

proto.isOpaque = function() {
  return this.opacity >= 1
}

proto.isTransparent = function() {
  return this.opacity < 1
}

proto.pickSlots = 1

proto.setPickBase = function(id) {
  this.pickId = id
}

function genColormap(param) {
  var colors = colormap({
      colormap: param
    , nshades:  256
    , format:  'rgba'
  })

  var result = new Uint8Array(256*4)
  for(var i=0; i<256; ++i) {
    var c = colors[i]
    for(var j=0; j<3; ++j) {
      result[4*i+j] = c[j]
    }
    result[4*i+3] = c[3]*255
  }

  return ndarray(result, [256,256,4], [4,0,1])
}

function takeZComponent(array) {
  var n = array.length
  var result = new Array(n)
  for(var i=0; i 0) {
    var shader = this.triShader
    shader.bind()
    shader.uniforms = uniforms

    this.triangleVAO.bind()
    gl.drawArrays(gl.TRIANGLES, 0, this.triangleCount*3)
    this.triangleVAO.unbind()
  }
}

proto.drawPick = function(params) {
  params = params || {}

  var gl         = this.gl

  var model      = params.model      || IDENTITY
  var view       = params.view       || IDENTITY
  var projection = params.projection || IDENTITY

  var clipBounds = [[-1e6,-1e6,-1e6],[1e6,1e6,1e6]]
  for(var i=0; i<3; ++i) {
    clipBounds[0][i] = Math.max(clipBounds[0][i], this.clipBounds[0][i])
    clipBounds[1][i] = Math.min(clipBounds[1][i], this.clipBounds[1][i])
  }

  //Save camera parameters
  this._model      = [].slice.call(model)
  this._view       = [].slice.call(view)
  this._projection = [].slice.call(projection)
  this._resolution = [gl.drawingBufferWidth, gl.drawingBufferHeight]

  var uniforms = {
    model:      model,
    view:       view,
    projection: projection,
    clipBounds: clipBounds,

    tubeScale: this.tubeScale,
    vectorScale: this.vectorScale,
    coneScale: this.coneScale,
    coneOffset: this.coneOffset,

    pickId:     this.pickId / 255.0,
  }

  var shader = this.pickShader
  shader.bind()
  shader.uniforms = uniforms

  if(this.triangleCount > 0) {
    this.triangleVAO.bind()
    gl.drawArrays(gl.TRIANGLES, 0, this.triangleCount*3)
    this.triangleVAO.unbind()
  }
}


proto.pick = function(pickData) {
  if(!pickData) {
    return null
  }
  if(pickData.id !== this.pickId) {
    return null
  }

  var cellId    = pickData.value[0] + 256*pickData.value[1] + 65536*pickData.value[2]
  var cell      = this.cells[cellId]
  var pos =     this.positions[cell[1]].slice(0, 3)

  var result = {
    position: pos,
    dataCoordinate: pos,
    index: Math.floor(cell[1] / 48)
  }


  if(this.traceType === 'cone') {
    result.index = Math.floor(cell[1] / 48)
  } else if(this.traceType === 'streamtube') {
    result.intensity = this.intensity[cell[1]]
    result.velocity = this.vectors[cell[1]].slice(0, 3)
    result.divergence = this.vectors[cell[1]][3]
    result.index = cellId
  }

  return result
}


proto.dispose = function() {
  this.texture.dispose()

  this.triShader.dispose()
  this.pickShader.dispose()

  this.triangleVAO.dispose()
  this.trianglePositions.dispose()
  this.triangleVectors.dispose()
  this.triangleColors.dispose()
  this.triangleUVs.dispose()
  this.triangleIds.dispose()
}

function createMeshShader(gl, shaders) {
  var shader = createShader(gl,
    shaders.meshShader.vertex,
    shaders.meshShader.fragment,
    null,
    shaders.meshShader.attributes
  )

  shader.attributes.position.location = 0
  shader.attributes.color.location    = 2
  shader.attributes.uv.location       = 3
  shader.attributes.vector.location   = 4
  return shader
}


function createPickShader(gl, shaders) {
  var shader = createShader(gl,
    shaders.pickShader.vertex,
    shaders.pickShader.fragment,
    null,
    shaders.pickShader.attributes
  )

  shader.attributes.position.location = 0
  shader.attributes.id.location       = 1
  shader.attributes.vector.location   = 4
  return shader
}


function createVectorMesh(gl, params, opts) {
  var shaders = opts.shaders

  if (arguments.length === 1) {
    params = gl
    gl = params.gl
  }


  var triShader       = createMeshShader(gl, shaders)
  var pickShader      = createPickShader(gl, shaders)
  var meshTexture       = createTexture(gl,
    ndarray(new Uint8Array([255,255,255,255]), [1,1,4]))
  meshTexture.generateMipmap()
  meshTexture.minFilter = gl.LINEAR_MIPMAP_LINEAR
  meshTexture.magFilter = gl.LINEAR

  var trianglePositions = createBuffer(gl)
  var triangleVectors   = createBuffer(gl)
  var triangleColors    = createBuffer(gl)
  var triangleUVs       = createBuffer(gl)
  var triangleIds       = createBuffer(gl)
  var triangleVAO       = createVAO(gl, [
    { buffer: trianglePositions,
      type: gl.FLOAT,
      size: 4
    },
    { buffer: triangleIds,
      type: gl.UNSIGNED_BYTE,
      size: 4,
      normalized: true
    },
    { buffer: triangleColors,
      type: gl.FLOAT,
      size: 4
    },
    { buffer: triangleUVs,
      type: gl.FLOAT,
      size: 2
    },
    { buffer: triangleVectors,
      type: gl.FLOAT,
      size: 4
    }
  ])

  var mesh = new VectorMesh(gl
    , meshTexture
    , triShader
    , pickShader
    , trianglePositions
    , triangleVectors
    , triangleIds
    , triangleColors
    , triangleUVs
    , triangleVAO
    , opts.traceType || 'cone'
  )

  mesh.update(params)

  return mesh
}

module.exports = createVectorMesh


/***/ }),

/***/ 614:
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {

var glslify       = __webpack_require__(3236)

var triVertSrc = glslify(["precision highp float;\n\nprecision highp float;\n#define GLSLIFY 1\n\nvec3 getOrthogonalVector(vec3 v) {\n  // Return up-vector for only-z vector.\n  // Return ax + by + cz = 0, a point that lies on the plane that has v as a normal and that isn't (0,0,0).\n  // From the above if-statement we have ||a|| > 0  U  ||b|| > 0.\n  // Assign z = 0, x = -b, y = a:\n  // a*-b + b*a + c*0 = -ba + ba + 0 = 0\n  if (v.x*v.x > v.z*v.z || v.y*v.y > v.z*v.z) {\n    return normalize(vec3(-v.y, v.x, 0.0));\n  } else {\n    return normalize(vec3(0.0, v.z, -v.y));\n  }\n}\n\n// Calculate the cone vertex and normal at the given index.\n//\n// The returned vertex is for a cone with its top at origin and height of 1.0,\n// pointing in the direction of the vector attribute.\n//\n// Each cone is made up of a top vertex, a center base vertex and base perimeter vertices.\n// These vertices are used to make up the triangles of the cone by the following:\n//   segment + 0 top vertex\n//   segment + 1 perimeter vertex a+1\n//   segment + 2 perimeter vertex a\n//   segment + 3 center base vertex\n//   segment + 4 perimeter vertex a\n//   segment + 5 perimeter vertex a+1\n// Where segment is the number of the radial segment * 6 and a is the angle at that radial segment.\n// To go from index to segment, floor(index / 6)\n// To go from segment to angle, 2*pi * (segment/segmentCount)\n// To go from index to segment index, index - (segment*6)\n//\nvec3 getConePosition(vec3 d, float rawIndex, float coneOffset, out vec3 normal) {\n\n  const float segmentCount = 8.0;\n\n  float index = rawIndex - floor(rawIndex /\n    (segmentCount * 6.0)) *\n    (segmentCount * 6.0);\n\n  float segment = floor(0.001 + index/6.0);\n  float segmentIndex = index - (segment*6.0);\n\n  normal = -normalize(d);\n\n  if (segmentIndex > 2.99 && segmentIndex < 3.01) {\n    return mix(vec3(0.0), -d, coneOffset);\n  }\n\n  float nextAngle = (\n    (segmentIndex > 0.99 &&  segmentIndex < 1.01) ||\n    (segmentIndex > 4.99 &&  segmentIndex < 5.01)\n  ) ? 1.0 : 0.0;\n  float angle = 2.0 * 3.14159 * ((segment + nextAngle) / segmentCount);\n\n  vec3 v1 = mix(d, vec3(0.0), coneOffset);\n  vec3 v2 = v1 - d;\n\n  vec3 u = getOrthogonalVector(d);\n  vec3 v = normalize(cross(u, d));\n\n  vec3 x = u * cos(angle) * length(d)*0.25;\n  vec3 y = v * sin(angle) * length(d)*0.25;\n  vec3 v3 = v2 + x + y;\n  if (segmentIndex < 3.0) {\n    vec3 tx = u * sin(angle);\n    vec3 ty = v * -cos(angle);\n    vec3 tangent = tx + ty;\n    normal = normalize(cross(v3 - v1, tangent));\n  }\n\n  if (segmentIndex == 0.0) {\n    return mix(d, vec3(0.0), coneOffset);\n  }\n  return v3;\n}\n\nattribute vec3 vector;\nattribute vec4 color, position;\nattribute vec2 uv;\n\nuniform float vectorScale, coneScale, coneOffset;\nuniform mat4 model, view, projection, inverseModel;\nuniform vec3 eyePosition, lightPosition;\n\nvarying vec3 f_normal, f_lightDirection, f_eyeDirection, f_data, f_position;\nvarying vec4 f_color;\nvarying vec2 f_uv;\n\nvoid main() {\n  // Scale the vector magnitude to stay constant with\n  // model & view changes.\n  vec3 normal;\n  vec3 XYZ = getConePosition(mat3(model) * ((vectorScale * coneScale) * vector), position.w, coneOffset, normal);\n  vec4 conePosition = model * vec4(position.xyz, 1.0) + vec4(XYZ, 0.0);\n\n  //Lighting geometry parameters\n  vec4 cameraCoordinate = view * conePosition;\n  cameraCoordinate.xyz /= cameraCoordinate.w;\n  f_lightDirection = lightPosition - cameraCoordinate.xyz;\n  f_eyeDirection   = eyePosition - cameraCoordinate.xyz;\n  f_normal = normalize((vec4(normal, 0.0) * inverseModel).xyz);\n\n  // vec4 m_position  = model * vec4(conePosition, 1.0);\n  vec4 t_position  = view * conePosition;\n  gl_Position      = projection * t_position;\n\n  f_color          = color;\n  f_data           = conePosition.xyz;\n  f_position       = position.xyz;\n  f_uv             = uv;\n}\n"])
var triFragSrc = glslify(["#extension GL_OES_standard_derivatives : enable\n\nprecision highp float;\n#define GLSLIFY 1\n\nfloat beckmannDistribution(float x, float roughness) {\n  float NdotH = max(x, 0.0001);\n  float cos2Alpha = NdotH * NdotH;\n  float tan2Alpha = (cos2Alpha - 1.0) / cos2Alpha;\n  float roughness2 = roughness * roughness;\n  float denom = 3.141592653589793 * roughness2 * cos2Alpha * cos2Alpha;\n  return exp(tan2Alpha / roughness2) / denom;\n}\n\nfloat cookTorranceSpecular(\n  vec3 lightDirection,\n  vec3 viewDirection,\n  vec3 surfaceNormal,\n  float roughness,\n  float fresnel) {\n\n  float VdotN = max(dot(viewDirection, surfaceNormal), 0.0);\n  float LdotN = max(dot(lightDirection, surfaceNormal), 0.0);\n\n  //Half angle vector\n  vec3 H = normalize(lightDirection + viewDirection);\n\n  //Geometric term\n  float NdotH = max(dot(surfaceNormal, H), 0.0);\n  float VdotH = max(dot(viewDirection, H), 0.000001);\n  float LdotH = max(dot(lightDirection, H), 0.000001);\n  float G1 = (2.0 * NdotH * VdotN) / VdotH;\n  float G2 = (2.0 * NdotH * LdotN) / LdotH;\n  float G = min(1.0, min(G1, G2));\n  \n  //Distribution term\n  float D = beckmannDistribution(NdotH, roughness);\n\n  //Fresnel term\n  float F = pow(1.0 - VdotN, fresnel);\n\n  //Multiply terms and done\n  return  G * F * D / max(3.14159265 * VdotN, 0.000001);\n}\n\nbool outOfRange(float a, float b, float p) {\n  return ((p > max(a, b)) || \n          (p < min(a, b)));\n}\n\nbool outOfRange(vec2 a, vec2 b, vec2 p) {\n  return (outOfRange(a.x, b.x, p.x) ||\n          outOfRange(a.y, b.y, p.y));\n}\n\nbool outOfRange(vec3 a, vec3 b, vec3 p) {\n  return (outOfRange(a.x, b.x, p.x) ||\n          outOfRange(a.y, b.y, p.y) ||\n          outOfRange(a.z, b.z, p.z));\n}\n\nbool outOfRange(vec4 a, vec4 b, vec4 p) {\n  return outOfRange(a.xyz, b.xyz, p.xyz);\n}\n\nuniform vec3 clipBounds[2];\nuniform float roughness, fresnel, kambient, kdiffuse, kspecular, opacity;\nuniform sampler2D texture;\n\nvarying vec3 f_normal, f_lightDirection, f_eyeDirection, f_data, f_position;\nvarying vec4 f_color;\nvarying vec2 f_uv;\n\nvoid main() {\n  if (outOfRange(clipBounds[0], clipBounds[1], f_position)) discard;\n  vec3 N = normalize(f_normal);\n  vec3 L = normalize(f_lightDirection);\n  vec3 V = normalize(f_eyeDirection);\n\n  if(gl_FrontFacing) {\n    N = -N;\n  }\n\n  float specular = min(1.0, max(0.0, cookTorranceSpecular(L, V, N, roughness, fresnel)));\n  float diffuse  = min(kambient + kdiffuse * max(dot(N, L), 0.0), 1.0);\n\n  vec4 surfaceColor = f_color * texture2D(texture, f_uv);\n  vec4 litColor = surfaceColor.a * vec4(diffuse * surfaceColor.rgb + kspecular * vec3(1,1,1) * specular,  1.0);\n\n  gl_FragColor = litColor * opacity;\n}\n"])
var pickVertSrc = glslify(["precision highp float;\n\nprecision highp float;\n#define GLSLIFY 1\n\nvec3 getOrthogonalVector(vec3 v) {\n  // Return up-vector for only-z vector.\n  // Return ax + by + cz = 0, a point that lies on the plane that has v as a normal and that isn't (0,0,0).\n  // From the above if-statement we have ||a|| > 0  U  ||b|| > 0.\n  // Assign z = 0, x = -b, y = a:\n  // a*-b + b*a + c*0 = -ba + ba + 0 = 0\n  if (v.x*v.x > v.z*v.z || v.y*v.y > v.z*v.z) {\n    return normalize(vec3(-v.y, v.x, 0.0));\n  } else {\n    return normalize(vec3(0.0, v.z, -v.y));\n  }\n}\n\n// Calculate the cone vertex and normal at the given index.\n//\n// The returned vertex is for a cone with its top at origin and height of 1.0,\n// pointing in the direction of the vector attribute.\n//\n// Each cone is made up of a top vertex, a center base vertex and base perimeter vertices.\n// These vertices are used to make up the triangles of the cone by the following:\n//   segment + 0 top vertex\n//   segment + 1 perimeter vertex a+1\n//   segment + 2 perimeter vertex a\n//   segment + 3 center base vertex\n//   segment + 4 perimeter vertex a\n//   segment + 5 perimeter vertex a+1\n// Where segment is the number of the radial segment * 6 and a is the angle at that radial segment.\n// To go from index to segment, floor(index / 6)\n// To go from segment to angle, 2*pi * (segment/segmentCount)\n// To go from index to segment index, index - (segment*6)\n//\nvec3 getConePosition(vec3 d, float rawIndex, float coneOffset, out vec3 normal) {\n\n  const float segmentCount = 8.0;\n\n  float index = rawIndex - floor(rawIndex /\n    (segmentCount * 6.0)) *\n    (segmentCount * 6.0);\n\n  float segment = floor(0.001 + index/6.0);\n  float segmentIndex = index - (segment*6.0);\n\n  normal = -normalize(d);\n\n  if (segmentIndex > 2.99 && segmentIndex < 3.01) {\n    return mix(vec3(0.0), -d, coneOffset);\n  }\n\n  float nextAngle = (\n    (segmentIndex > 0.99 &&  segmentIndex < 1.01) ||\n    (segmentIndex > 4.99 &&  segmentIndex < 5.01)\n  ) ? 1.0 : 0.0;\n  float angle = 2.0 * 3.14159 * ((segment + nextAngle) / segmentCount);\n\n  vec3 v1 = mix(d, vec3(0.0), coneOffset);\n  vec3 v2 = v1 - d;\n\n  vec3 u = getOrthogonalVector(d);\n  vec3 v = normalize(cross(u, d));\n\n  vec3 x = u * cos(angle) * length(d)*0.25;\n  vec3 y = v * sin(angle) * length(d)*0.25;\n  vec3 v3 = v2 + x + y;\n  if (segmentIndex < 3.0) {\n    vec3 tx = u * sin(angle);\n    vec3 ty = v * -cos(angle);\n    vec3 tangent = tx + ty;\n    normal = normalize(cross(v3 - v1, tangent));\n  }\n\n  if (segmentIndex == 0.0) {\n    return mix(d, vec3(0.0), coneOffset);\n  }\n  return v3;\n}\n\nattribute vec4 vector;\nattribute vec4 position;\nattribute vec4 id;\n\nuniform mat4 model, view, projection;\nuniform float vectorScale, coneScale, coneOffset;\n\nvarying vec3 f_position;\nvarying vec4 f_id;\n\nvoid main() {\n  vec3 normal;\n  vec3 XYZ = getConePosition(mat3(model) * ((vectorScale * coneScale) * vector.xyz), position.w, coneOffset, normal);\n  vec4 conePosition = model * vec4(position.xyz, 1.0) + vec4(XYZ, 0.0);\n  gl_Position = projection * (view * conePosition);\n  f_id        = id;\n  f_position  = position.xyz;\n}\n"])
var pickFragSrc = glslify(["precision highp float;\n#define GLSLIFY 1\n\nbool outOfRange(float a, float b, float p) {\n  return ((p > max(a, b)) || \n          (p < min(a, b)));\n}\n\nbool outOfRange(vec2 a, vec2 b, vec2 p) {\n  return (outOfRange(a.x, b.x, p.x) ||\n          outOfRange(a.y, b.y, p.y));\n}\n\nbool outOfRange(vec3 a, vec3 b, vec3 p) {\n  return (outOfRange(a.x, b.x, p.x) ||\n          outOfRange(a.y, b.y, p.y) ||\n          outOfRange(a.z, b.z, p.z));\n}\n\nbool outOfRange(vec4 a, vec4 b, vec4 p) {\n  return outOfRange(a.xyz, b.xyz, p.xyz);\n}\n\nuniform vec3  clipBounds[2];\nuniform float pickId;\n\nvarying vec3 f_position;\nvarying vec4 f_id;\n\nvoid main() {\n  if (outOfRange(clipBounds[0], clipBounds[1], f_position)) discard;\n\n  gl_FragColor = vec4(pickId, f_id.xyz);\n}"])

exports.meshShader = {
  vertex:   triVertSrc,
  fragment: triFragSrc,
  attributes: [
    {name: 'position', type: 'vec4'},
    {name: 'color', type: 'vec4'},
    {name: 'uv', type: 'vec2'},
    {name: 'vector', type: 'vec3'}
  ]
}
exports.pickShader = {
  vertex:   pickVertSrc,
  fragment: pickFragSrc,
  attributes: [
    {name: 'position', type: 'vec4'},
    {name: 'id', type: 'vec4'},
    {name: 'vector', type: 'vec3'}
  ]
}


/***/ }),

/***/ 737:
/***/ (function(module) {

module.exports = {
  0: 'NONE',
  1: 'ONE',
  2: 'LINE_LOOP',
  3: 'LINE_STRIP',
  4: 'TRIANGLES',
  5: 'TRIANGLE_STRIP',
  6: 'TRIANGLE_FAN',
  256: 'DEPTH_BUFFER_BIT',
  512: 'NEVER',
  513: 'LESS',
  514: 'EQUAL',
  515: 'LEQUAL',
  516: 'GREATER',
  517: 'NOTEQUAL',
  518: 'GEQUAL',
  519: 'ALWAYS',
  768: 'SRC_COLOR',
  769: 'ONE_MINUS_SRC_COLOR',
  770: 'SRC_ALPHA',
  771: 'ONE_MINUS_SRC_ALPHA',
  772: 'DST_ALPHA',
  773: 'ONE_MINUS_DST_ALPHA',
  774: 'DST_COLOR',
  775: 'ONE_MINUS_DST_COLOR',
  776: 'SRC_ALPHA_SATURATE',
  1024: 'STENCIL_BUFFER_BIT',
  1028: 'FRONT',
  1029: 'BACK',
  1032: 'FRONT_AND_BACK',
  1280: 'INVALID_ENUM',
  1281: 'INVALID_VALUE',
  1282: 'INVALID_OPERATION',
  1285: 'OUT_OF_MEMORY',
  1286: 'INVALID_FRAMEBUFFER_OPERATION',
  2304: 'CW',
  2305: 'CCW',
  2849: 'LINE_WIDTH',
  2884: 'CULL_FACE',
  2885: 'CULL_FACE_MODE',
  2886: 'FRONT_FACE',
  2928: 'DEPTH_RANGE',
  2929: 'DEPTH_TEST',
  2930: 'DEPTH_WRITEMASK',
  2931: 'DEPTH_CLEAR_VALUE',
  2932: 'DEPTH_FUNC',
  2960: 'STENCIL_TEST',
  2961: 'STENCIL_CLEAR_VALUE',
  2962: 'STENCIL_FUNC',
  2963: 'STENCIL_VALUE_MASK',
  2964: 'STENCIL_FAIL',
  2965: 'STENCIL_PASS_DEPTH_FAIL',
  2966: 'STENCIL_PASS_DEPTH_PASS',
  2967: 'STENCIL_REF',
  2968: 'STENCIL_WRITEMASK',
  2978: 'VIEWPORT',
  3024: 'DITHER',
  3042: 'BLEND',
  3088: 'SCISSOR_BOX',
  3089: 'SCISSOR_TEST',
  3106: 'COLOR_CLEAR_VALUE',
  3107: 'COLOR_WRITEMASK',
  3317: 'UNPACK_ALIGNMENT',
  3333: 'PACK_ALIGNMENT',
  3379: 'MAX_TEXTURE_SIZE',
  3386: 'MAX_VIEWPORT_DIMS',
  3408: 'SUBPIXEL_BITS',
  3410: 'RED_BITS',
  3411: 'GREEN_BITS',
  3412: 'BLUE_BITS',
  3413: 'ALPHA_BITS',
  3414: 'DEPTH_BITS',
  3415: 'STENCIL_BITS',
  3553: 'TEXTURE_2D',
  4352: 'DONT_CARE',
  4353: 'FASTEST',
  4354: 'NICEST',
  5120: 'BYTE',
  5121: 'UNSIGNED_BYTE',
  5122: 'SHORT',
  5123: 'UNSIGNED_SHORT',
  5124: 'INT',
  5125: 'UNSIGNED_INT',
  5126: 'FLOAT',
  5386: 'INVERT',
  5890: 'TEXTURE',
  6401: 'STENCIL_INDEX',
  6402: 'DEPTH_COMPONENT',
  6406: 'ALPHA',
  6407: 'RGB',
  6408: 'RGBA',
  6409: 'LUMINANCE',
  6410: 'LUMINANCE_ALPHA',
  7680: 'KEEP',
  7681: 'REPLACE',
  7682: 'INCR',
  7683: 'DECR',
  7936: 'VENDOR',
  7937: 'RENDERER',
  7938: 'VERSION',
  9728: 'NEAREST',
  9729: 'LINEAR',
  9984: 'NEAREST_MIPMAP_NEAREST',
  9985: 'LINEAR_MIPMAP_NEAREST',
  9986: 'NEAREST_MIPMAP_LINEAR',
  9987: 'LINEAR_MIPMAP_LINEAR',
  10240: 'TEXTURE_MAG_FILTER',
  10241: 'TEXTURE_MIN_FILTER',
  10242: 'TEXTURE_WRAP_S',
  10243: 'TEXTURE_WRAP_T',
  10497: 'REPEAT',
  10752: 'POLYGON_OFFSET_UNITS',
  16384: 'COLOR_BUFFER_BIT',
  32769: 'CONSTANT_COLOR',
  32770: 'ONE_MINUS_CONSTANT_COLOR',
  32771: 'CONSTANT_ALPHA',
  32772: 'ONE_MINUS_CONSTANT_ALPHA',
  32773: 'BLEND_COLOR',
  32774: 'FUNC_ADD',
  32777: 'BLEND_EQUATION_RGB',
  32778: 'FUNC_SUBTRACT',
  32779: 'FUNC_REVERSE_SUBTRACT',
  32819: 'UNSIGNED_SHORT_4_4_4_4',
  32820: 'UNSIGNED_SHORT_5_5_5_1',
  32823: 'POLYGON_OFFSET_FILL',
  32824: 'POLYGON_OFFSET_FACTOR',
  32854: 'RGBA4',
  32855: 'RGB5_A1',
  32873: 'TEXTURE_BINDING_2D',
  32926: 'SAMPLE_ALPHA_TO_COVERAGE',
  32928: 'SAMPLE_COVERAGE',
  32936: 'SAMPLE_BUFFERS',
  32937: 'SAMPLES',
  32938: 'SAMPLE_COVERAGE_VALUE',
  32939: 'SAMPLE_COVERAGE_INVERT',
  32968: 'BLEND_DST_RGB',
  32969: 'BLEND_SRC_RGB',
  32970: 'BLEND_DST_ALPHA',
  32971: 'BLEND_SRC_ALPHA',
  33071: 'CLAMP_TO_EDGE',
  33170: 'GENERATE_MIPMAP_HINT',
  33189: 'DEPTH_COMPONENT16',
  33306: 'DEPTH_STENCIL_ATTACHMENT',
  33635: 'UNSIGNED_SHORT_5_6_5',
  33648: 'MIRRORED_REPEAT',
  33901: 'ALIASED_POINT_SIZE_RANGE',
  33902: 'ALIASED_LINE_WIDTH_RANGE',
  33984: 'TEXTURE0',
  33985: 'TEXTURE1',
  33986: 'TEXTURE2',
  33987: 'TEXTURE3',
  33988: 'TEXTURE4',
  33989: 'TEXTURE5',
  33990: 'TEXTURE6',
  33991: 'TEXTURE7',
  33992: 'TEXTURE8',
  33993: 'TEXTURE9',
  33994: 'TEXTURE10',
  33995: 'TEXTURE11',
  33996: 'TEXTURE12',
  33997: 'TEXTURE13',
  33998: 'TEXTURE14',
  33999: 'TEXTURE15',
  34000: 'TEXTURE16',
  34001: 'TEXTURE17',
  34002: 'TEXTURE18',
  34003: 'TEXTURE19',
  34004: 'TEXTURE20',
  34005: 'TEXTURE21',
  34006: 'TEXTURE22',
  34007: 'TEXTURE23',
  34008: 'TEXTURE24',
  34009: 'TEXTURE25',
  34010: 'TEXTURE26',
  34011: 'TEXTURE27',
  34012: 'TEXTURE28',
  34013: 'TEXTURE29',
  34014: 'TEXTURE30',
  34015: 'TEXTURE31',
  34016: 'ACTIVE_TEXTURE',
  34024: 'MAX_RENDERBUFFER_SIZE',
  34041: 'DEPTH_STENCIL',
  34055: 'INCR_WRAP',
  34056: 'DECR_WRAP',
  34067: 'TEXTURE_CUBE_MAP',
  34068: 'TEXTURE_BINDING_CUBE_MAP',
  34069: 'TEXTURE_CUBE_MAP_POSITIVE_X',
  34070: 'TEXTURE_CUBE_MAP_NEGATIVE_X',
  34071: 'TEXTURE_CUBE_MAP_POSITIVE_Y',
  34072: 'TEXTURE_CUBE_MAP_NEGATIVE_Y',
  34073: 'TEXTURE_CUBE_MAP_POSITIVE_Z',
  34074: 'TEXTURE_CUBE_MAP_NEGATIVE_Z',
  34076: 'MAX_CUBE_MAP_TEXTURE_SIZE',
  34338: 'VERTEX_ATTRIB_ARRAY_ENABLED',
  34339: 'VERTEX_ATTRIB_ARRAY_SIZE',
  34340: 'VERTEX_ATTRIB_ARRAY_STRIDE',
  34341: 'VERTEX_ATTRIB_ARRAY_TYPE',
  34342: 'CURRENT_VERTEX_ATTRIB',
  34373: 'VERTEX_ATTRIB_ARRAY_POINTER',
  34466: 'NUM_COMPRESSED_TEXTURE_FORMATS',
  34467: 'COMPRESSED_TEXTURE_FORMATS',
  34660: 'BUFFER_SIZE',
  34661: 'BUFFER_USAGE',
  34816: 'STENCIL_BACK_FUNC',
  34817: 'STENCIL_BACK_FAIL',
  34818: 'STENCIL_BACK_PASS_DEPTH_FAIL',
  34819: 'STENCIL_BACK_PASS_DEPTH_PASS',
  34877: 'BLEND_EQUATION_ALPHA',
  34921: 'MAX_VERTEX_ATTRIBS',
  34922: 'VERTEX_ATTRIB_ARRAY_NORMALIZED',
  34930: 'MAX_TEXTURE_IMAGE_UNITS',
  34962: 'ARRAY_BUFFER',
  34963: 'ELEMENT_ARRAY_BUFFER',
  34964: 'ARRAY_BUFFER_BINDING',
  34965: 'ELEMENT_ARRAY_BUFFER_BINDING',
  34975: 'VERTEX_ATTRIB_ARRAY_BUFFER_BINDING',
  35040: 'STREAM_DRAW',
  35044: 'STATIC_DRAW',
  35048: 'DYNAMIC_DRAW',
  35632: 'FRAGMENT_SHADER',
  35633: 'VERTEX_SHADER',
  35660: 'MAX_VERTEX_TEXTURE_IMAGE_UNITS',
  35661: 'MAX_COMBINED_TEXTURE_IMAGE_UNITS',
  35663: 'SHADER_TYPE',
  35664: 'FLOAT_VEC2',
  35665: 'FLOAT_VEC3',
  35666: 'FLOAT_VEC4',
  35667: 'INT_VEC2',
  35668: 'INT_VEC3',
  35669: 'INT_VEC4',
  35670: 'BOOL',
  35671: 'BOOL_VEC2',
  35672: 'BOOL_VEC3',
  35673: 'BOOL_VEC4',
  35674: 'FLOAT_MAT2',
  35675: 'FLOAT_MAT3',
  35676: 'FLOAT_MAT4',
  35678: 'SAMPLER_2D',
  35680: 'SAMPLER_CUBE',
  35712: 'DELETE_STATUS',
  35713: 'COMPILE_STATUS',
  35714: 'LINK_STATUS',
  35715: 'VALIDATE_STATUS',
  35716: 'INFO_LOG_LENGTH',
  35717: 'ATTACHED_SHADERS',
  35718: 'ACTIVE_UNIFORMS',
  35719: 'ACTIVE_UNIFORM_MAX_LENGTH',
  35720: 'SHADER_SOURCE_LENGTH',
  35721: 'ACTIVE_ATTRIBUTES',
  35722: 'ACTIVE_ATTRIBUTE_MAX_LENGTH',
  35724: 'SHADING_LANGUAGE_VERSION',
  35725: 'CURRENT_PROGRAM',
  36003: 'STENCIL_BACK_REF',
  36004: 'STENCIL_BACK_VALUE_MASK',
  36005: 'STENCIL_BACK_WRITEMASK',
  36006: 'FRAMEBUFFER_BINDING',
  36007: 'RENDERBUFFER_BINDING',
  36048: 'FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE',
  36049: 'FRAMEBUFFER_ATTACHMENT_OBJECT_NAME',
  36050: 'FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL',
  36051: 'FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE',
  36053: 'FRAMEBUFFER_COMPLETE',
  36054: 'FRAMEBUFFER_INCOMPLETE_ATTACHMENT',
  36055: 'FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT',
  36057: 'FRAMEBUFFER_INCOMPLETE_DIMENSIONS',
  36061: 'FRAMEBUFFER_UNSUPPORTED',
  36064: 'COLOR_ATTACHMENT0',
  36096: 'DEPTH_ATTACHMENT',
  36128: 'STENCIL_ATTACHMENT',
  36160: 'FRAMEBUFFER',
  36161: 'RENDERBUFFER',
  36162: 'RENDERBUFFER_WIDTH',
  36163: 'RENDERBUFFER_HEIGHT',
  36164: 'RENDERBUFFER_INTERNAL_FORMAT',
  36168: 'STENCIL_INDEX8',
  36176: 'RENDERBUFFER_RED_SIZE',
  36177: 'RENDERBUFFER_GREEN_SIZE',
  36178: 'RENDERBUFFER_BLUE_SIZE',
  36179: 'RENDERBUFFER_ALPHA_SIZE',
  36180: 'RENDERBUFFER_DEPTH_SIZE',
  36181: 'RENDERBUFFER_STENCIL_SIZE',
  36194: 'RGB565',
  36336: 'LOW_FLOAT',
  36337: 'MEDIUM_FLOAT',
  36338: 'HIGH_FLOAT',
  36339: 'LOW_INT',
  36340: 'MEDIUM_INT',
  36341: 'HIGH_INT',
  36346: 'SHADER_COMPILER',
  36347: 'MAX_VERTEX_UNIFORM_VECTORS',
  36348: 'MAX_VARYING_VECTORS',
  36349: 'MAX_FRAGMENT_UNIFORM_VECTORS',
  37440: 'UNPACK_FLIP_Y_WEBGL',
  37441: 'UNPACK_PREMULTIPLY_ALPHA_WEBGL',
  37442: 'CONTEXT_LOST_WEBGL',
  37443: 'UNPACK_COLORSPACE_CONVERSION_WEBGL',
  37444: 'BROWSER_DEFAULT_WEBGL'
}


/***/ }),

/***/ 5171:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

var gl10 = __webpack_require__(737)

module.exports = function lookupConstant (number) {
  return gl10[number]
}


/***/ }),

/***/ 9165:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

"use strict";


module.exports = createErrorBars

var createBuffer  = __webpack_require__(2762)
var createVAO     = __webpack_require__(8116)
var createShader  = __webpack_require__(3436)

var IDENTITY = [1,0,0,0,
                0,1,0,0,
                0,0,1,0,
                0,0,0,1]

function ErrorBars(gl, buffer, vao, shader) {
  this.gl           = gl
  this.shader       = shader
  this.buffer       = buffer
  this.vao          = vao
  this.pixelRatio   = 1
  this.bounds       = [[ Infinity, Infinity, Infinity], [-Infinity,-Infinity,-Infinity]]
  this.clipBounds   = [[-Infinity,-Infinity,-Infinity], [ Infinity, Infinity, Infinity]]
  this.lineWidth    = [1,1,1]
  this.capSize      = [10,10,10]
  this.lineCount    = [0,0,0]
  this.lineOffset   = [0,0,0]
  this.opacity      = 1
  this.hasAlpha     = false
}

var proto = ErrorBars.prototype

proto.isOpaque = function() {
  return !this.hasAlpha
}

proto.isTransparent = function() {
  return this.hasAlpha
}

proto.drawTransparent = proto.draw = function(cameraParams) {
  var gl = this.gl
  var uniforms        = this.shader.uniforms

  this.shader.bind()
  var view       = uniforms.view       = cameraParams.view       || IDENTITY
  var projection = uniforms.projection = cameraParams.projection || IDENTITY
  uniforms.model      = cameraParams.model      || IDENTITY
  uniforms.clipBounds = this.clipBounds
  uniforms.opacity    = this.opacity


  var cx = view[12]
  var cy = view[13]
  var cz = view[14]
  var cw = view[15]

  var isOrtho = cameraParams._ortho || false
  var orthoFix = (isOrtho) ? 2 : 1 // double up padding for orthographic ticks & labels
  var pixelScaleF = orthoFix * this.pixelRatio * (projection[3]*cx + projection[7]*cy + projection[11]*cz + projection[15]*cw) / gl.drawingBufferHeight

  this.vao.bind()
  for(var i=0; i<3; ++i) {
    gl.lineWidth(this.lineWidth[i] * this.pixelRatio)
    uniforms.capSize = this.capSize[i] * pixelScaleF
    if (this.lineCount[i]) {
      gl.drawArrays(gl.LINES, this.lineOffset[i], this.lineCount[i])
    }
  }
  this.vao.unbind()
}

function updateBounds(bounds, point) {
  for(var i=0; i<3; ++i) {
    bounds[0][i] = Math.min(bounds[0][i], point[i])
    bounds[1][i] = Math.max(bounds[1][i], point[i])
  }
}

var FACE_TABLE = (function(){
  var table = new Array(3)
  for(var d=0; d<3; ++d) {
    var row = []
    for(var j=1; j<=2; ++j) {
      for(var s=-1; s<=1; s+=2) {
        var u = (j+d) % 3
        var y = [0,0,0]
        y[u] = s
        row.push(y)
      }
    }
    table[d] = row
  }
  return table
})()


function emitFace(verts, x, c, d) {
  var offsets = FACE_TABLE[d]
  for(var i=0; i 0) {
          var x = p.slice()
          x[j] += e[1][j]
          verts.push(p[0], p[1], p[2],
                     c[0], c[1], c[2], c[3],
                        0,    0,    0,
                     x[0], x[1], x[2],
                     c[0], c[1], c[2], c[3],
                        0,    0,    0)
          updateBounds(this.bounds, x)
          vertexCount += 2 + emitFace(verts, x, c, j)
        }
      }
      this.lineCount[j] = vertexCount - this.lineOffset[j]
    }
    this.buffer.update(verts)
  }
}

proto.dispose = function() {
  this.shader.dispose()
  this.buffer.dispose()
  this.vao.dispose()
}

function createErrorBars(options) {
  var gl = options.gl
  var buffer = createBuffer(gl)
  var vao = createVAO(gl, [
      {
        buffer: buffer,
        type:   gl.FLOAT,
        size:   3,
        offset: 0,
        stride: 40
      },
      {
        buffer: buffer,
        type:   gl.FLOAT,
        size:   4,
        offset: 12,
        stride: 40
      },
      {
        buffer: buffer,
        type:   gl.FLOAT,
        size:   3,
        offset: 28,
        stride: 40
      }
    ])

  var shader = createShader(gl)
  shader.attributes.position.location = 0
  shader.attributes.color.location    = 1
  shader.attributes.offset.location   = 2

  var result = new ErrorBars(gl, buffer, vao, shader)
  result.update(options)
  return result
}


/***/ }),

/***/ 3436:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

"use strict";


var glslify = __webpack_require__(3236)
var createShader = __webpack_require__(9405)

var vertSrc = glslify(["precision highp float;\n#define GLSLIFY 1\n\nattribute vec3 position, offset;\nattribute vec4 color;\nuniform mat4 model, view, projection;\nuniform float capSize;\nvarying vec4 fragColor;\nvarying vec3 fragPosition;\n\nvoid main() {\n  vec4 worldPosition  = model * vec4(position, 1.0);\n  worldPosition       = (worldPosition / worldPosition.w) + vec4(capSize * offset, 0.0);\n  gl_Position         = projection * (view * worldPosition);\n  fragColor           = color;\n  fragPosition        = position;\n}"])
var fragSrc = glslify(["precision highp float;\n#define GLSLIFY 1\n\nbool outOfRange(float a, float b, float p) {\n  return ((p > max(a, b)) || \n          (p < min(a, b)));\n}\n\nbool outOfRange(vec2 a, vec2 b, vec2 p) {\n  return (outOfRange(a.x, b.x, p.x) ||\n          outOfRange(a.y, b.y, p.y));\n}\n\nbool outOfRange(vec3 a, vec3 b, vec3 p) {\n  return (outOfRange(a.x, b.x, p.x) ||\n          outOfRange(a.y, b.y, p.y) ||\n          outOfRange(a.z, b.z, p.z));\n}\n\nbool outOfRange(vec4 a, vec4 b, vec4 p) {\n  return outOfRange(a.xyz, b.xyz, p.xyz);\n}\n\nuniform vec3 clipBounds[2];\nuniform float opacity;\nvarying vec3 fragPosition;\nvarying vec4 fragColor;\n\nvoid main() {\n  if (\n    outOfRange(clipBounds[0], clipBounds[1], fragPosition) ||\n    fragColor.a * opacity == 0.\n  ) discard;\n\n  gl_FragColor = opacity * fragColor;\n}"])

module.exports = function(gl) {
  return createShader(gl, vertSrc, fragSrc, null, [
    {name: 'position', type: 'vec3'},
    {name: 'color', type: 'vec4'},
    {name: 'offset', type: 'vec3'}
  ])
}


/***/ }),

/***/ 2260:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

"use strict";


var createTexture = __webpack_require__(7766)

module.exports = createFBO

var colorAttachmentArrays = null
var FRAMEBUFFER_UNSUPPORTED
var FRAMEBUFFER_INCOMPLETE_ATTACHMENT
var FRAMEBUFFER_INCOMPLETE_DIMENSIONS
var FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT

function saveFBOState(gl) {
  var fbo = gl.getParameter(gl.FRAMEBUFFER_BINDING)
  var rbo = gl.getParameter(gl.RENDERBUFFER_BINDING)
  var tex = gl.getParameter(gl.TEXTURE_BINDING_2D)
  return [fbo, rbo, tex]
}

function restoreFBOState(gl, data) {
  gl.bindFramebuffer(gl.FRAMEBUFFER, data[0])
  gl.bindRenderbuffer(gl.RENDERBUFFER, data[1])
  gl.bindTexture(gl.TEXTURE_2D, data[2])
}

function lazyInitColorAttachments(gl, ext) {
  var maxColorAttachments = gl.getParameter(ext.MAX_COLOR_ATTACHMENTS_WEBGL)
  colorAttachmentArrays = new Array(maxColorAttachments + 1)
  for(var i=0; i<=maxColorAttachments; ++i) {
    var x = new Array(maxColorAttachments)
    for(var j=0; j 1) {
    ext.drawBuffersWEBGL(colorAttachmentArrays[numColors])
  }

  //Allocate depth/stencil buffers
  var WEBGL_depth_texture = gl.getExtension('WEBGL_depth_texture')
  if(WEBGL_depth_texture) {
    if(useStencil) {
      fbo.depth = initTexture(gl, width, height,
                          WEBGL_depth_texture.UNSIGNED_INT_24_8_WEBGL,
                          gl.DEPTH_STENCIL,
                          gl.DEPTH_STENCIL_ATTACHMENT)
    } else if(useDepth) {
      fbo.depth = initTexture(gl, width, height,
                          gl.UNSIGNED_SHORT,
                          gl.DEPTH_COMPONENT,
                          gl.DEPTH_ATTACHMENT)
    }
  } else {
    if(useDepth && useStencil) {
      fbo._depth_rb = initRenderBuffer(gl, width, height, gl.DEPTH_STENCIL, gl.DEPTH_STENCIL_ATTACHMENT)
    } else if(useDepth) {
      fbo._depth_rb = initRenderBuffer(gl, width, height, gl.DEPTH_COMPONENT16, gl.DEPTH_ATTACHMENT)
    } else if(useStencil) {
      fbo._depth_rb = initRenderBuffer(gl, width, height, gl.STENCIL_INDEX, gl.STENCIL_ATTACHMENT)
    }
  }

  //Check frame buffer state
  var status = gl.checkFramebufferStatus(gl.FRAMEBUFFER)
  if(status !== gl.FRAMEBUFFER_COMPLETE) {

    //Release all partially allocated resources
    fbo._destroyed = true

    //Release all resources
    gl.bindFramebuffer(gl.FRAMEBUFFER, null)
    gl.deleteFramebuffer(fbo.handle)
    fbo.handle = null
    if(fbo.depth) {
      fbo.depth.dispose()
      fbo.depth = null
    }
    if(fbo._depth_rb) {
      gl.deleteRenderbuffer(fbo._depth_rb)
      fbo._depth_rb = null
    }
    for(var i=0; i maxFBOSize ||
      h < 0 || h > maxFBOSize) {
    throw new Error('gl-fbo: Can\'t resize FBO, invalid dimensions')
  }

  //Update shape
  fbo._shape[0] = w
  fbo._shape[1] = h

  //Save framebuffer state
  var state = saveFBOState(gl)

  //Resize framebuffer attachments
  for(var i=0; i maxFBOSize || height < 0 || height > maxFBOSize) {
    throw new Error('gl-fbo: Parameters are too large for FBO')
  }

  //Handle each option type
  options = options || {}

  //Figure out number of color buffers to use
  var numColors = 1
  if('color' in options) {
    numColors = Math.max(options.color|0, 0)
    if(numColors < 0) {
      throw new Error('gl-fbo: Must specify a nonnegative number of colors')
    }
    if(numColors > 1) {
      //Check if multiple render targets supported
      if(!WEBGL_draw_buffers) {
        throw new Error('gl-fbo: Multiple draw buffer extension not supported')
      } else if(numColors > gl.getParameter(WEBGL_draw_buffers.MAX_COLOR_ATTACHMENTS_WEBGL)) {
        throw new Error('gl-fbo: Context does not support ' + numColors + ' draw buffers')
      }
    }
  }

  //Determine whether to use floating point textures
  var colorType = gl.UNSIGNED_BYTE
  var OES_texture_float = gl.getExtension('OES_texture_float')
  if(options.float && numColors > 0) {
    if(!OES_texture_float) {
      throw new Error('gl-fbo: Context does not support floating point textures')
    }
    colorType = gl.FLOAT
  } else if(options.preferFloat && numColors > 0) {
    if(OES_texture_float) {
      colorType = gl.FLOAT
    }
  }

  //Check if we should use depth buffer
  var useDepth = true
  if('depth' in options) {
    useDepth = !!options.depth
  }

  //Check if we should use a stencil buffer
  var useStencil = false
  if('stencil' in options) {
    useStencil = !!options.stencil
  }

  return new Framebuffer(
    gl,
    width,
    height,
    colorType,
    numColors,
    useDepth,
    useStencil,
    WEBGL_draw_buffers)
}


/***/ }),

/***/ 2992:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {


var sprintf = (__webpack_require__(3387).sprintf);
var glConstants = __webpack_require__(5171);
var shaderName = __webpack_require__(1848);
var addLineNumbers = __webpack_require__(1085);

module.exports = formatCompilerError;

function formatCompilerError(errLog, src, type) {
    "use strict";

    var name = shaderName(src) || 'of unknown name (see npm glsl-shader-name)';

    var typeName = 'unknown type';
    if (type !== undefined) {
        typeName = type === glConstants.FRAGMENT_SHADER ? 'fragment' : 'vertex'
    }

    var longForm = sprintf('Error compiling %s shader %s:\n', typeName, name);
    var shortForm = sprintf("%s%s", longForm, errLog);

    var errorStrings = errLog.split('\n');
    var errors = {};

    for (var i = 0; i < errorStrings.length; i++) {
        var errorString = errorStrings[i];
        if (errorString === '' || errorString === "\0") continue;
        var lineNo = parseInt(errorString.split(':')[2]);
        if (isNaN(lineNo)) {
            throw new Error(sprintf('Could not parse error: %s', errorString));
        }
        errors[lineNo] = errorString;
    }

    var lines = addLineNumbers(src).split('\n');

    for (var i = 0; i < lines.length; i++) {
        if (!errors[i+3] && !errors[i+2] && !errors[i+1]) continue;
        var line = lines[i];
        longForm += line + '\n';
        if (errors[i+1]) {
            var e = errors[i+1];
            e = e.substr(e.split(':', 3).join(':').length + 1).trim();
            longForm += sprintf('^^^ %s\n\n', e);
        }
    }

    return {
        long: longForm.trim(),
        short: shortForm.trim()
    };
}



/***/ }),

/***/ 2510:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

"use strict";


module.exports = createHeatmap2D

var bsearch = __webpack_require__(2478)
var iota = __webpack_require__(7762)
var pool = __webpack_require__(1888)
var createShader = __webpack_require__(9405)
var createBuffer = __webpack_require__(2762)

var shaders = __webpack_require__(6768)

function GLHeatmap2D (
  plot,
  shader,
  pickShader,
  positionBuffer,
  weightBuffer,
  colorBuffer,
  idBuffer) {
  this.plot = plot
  this.shader = shader
  this.pickShader = pickShader
  this.positionBuffer = positionBuffer
  this.weightBuffer = weightBuffer
  this.colorBuffer = colorBuffer
  this.idBuffer = idBuffer
  this.xData = []
  this.yData = []
  this.shape = [0, 0]
  this.bounds = [Infinity, Infinity, -Infinity, -Infinity]
  this.pickOffset = 0
}

var proto = GLHeatmap2D.prototype

var WEIGHTS = [
  0, 0,
  1, 0,
  0, 1,
  1, 0,
  1, 1,
  0, 1
]

proto.draw = (function () {
  var MATRIX = [
    1, 0, 0,
    0, 1, 0,
    0, 0, 1
  ]

  return function () {
    var plot = this.plot
    var shader = this.shader
    var bounds = this.bounds
    var numVertices = this.numVertices

    if (numVertices <= 0) {
      return
    }

    var gl = plot.gl
    var dataBox = plot.dataBox

    var boundX = bounds[2] - bounds[0]
    var boundY = bounds[3] - bounds[1]
    var dataX = dataBox[2] - dataBox[0]
    var dataY = dataBox[3] - dataBox[1]

    MATRIX[0] = 2.0 * boundX / dataX
    MATRIX[4] = 2.0 * boundY / dataY
    MATRIX[6] = 2.0 * (bounds[0] - dataBox[0]) / dataX - 1.0
    MATRIX[7] = 2.0 * (bounds[1] - dataBox[1]) / dataY - 1.0

    shader.bind()

    var uniforms = shader.uniforms
    uniforms.viewTransform = MATRIX

    uniforms.shape = this.shape

    var attributes = shader.attributes
    this.positionBuffer.bind()
    attributes.position.pointer()

    this.weightBuffer.bind()
    attributes.weight.pointer(gl.UNSIGNED_BYTE, false)

    this.colorBuffer.bind()
    attributes.color.pointer(gl.UNSIGNED_BYTE, true)

    gl.drawArrays(gl.TRIANGLES, 0, numVertices)
  }
})()

proto.drawPick = (function () {
  var MATRIX = [
    1, 0, 0,
    0, 1, 0,
    0, 0, 1
  ]

  var PICK_VECTOR = [0, 0, 0, 0]

  return function (pickOffset) {
    var plot = this.plot
    var shader = this.pickShader
    var bounds = this.bounds
    var numVertices = this.numVertices

    if (numVertices <= 0) {
      return
    }

    var gl = plot.gl
    var dataBox = plot.dataBox

    var boundX = bounds[2] - bounds[0]
    var boundY = bounds[3] - bounds[1]
    var dataX = dataBox[2] - dataBox[0]
    var dataY = dataBox[3] - dataBox[1]

    MATRIX[0] = 2.0 * boundX / dataX
    MATRIX[4] = 2.0 * boundY / dataY
    MATRIX[6] = 2.0 * (bounds[0] - dataBox[0]) / dataX - 1.0
    MATRIX[7] = 2.0 * (bounds[1] - dataBox[1]) / dataY - 1.0

    for (var i = 0; i < 4; ++i) {
      PICK_VECTOR[i] = (pickOffset >> (i * 8)) & 0xff
    }

    this.pickOffset = pickOffset

    shader.bind()

    var uniforms = shader.uniforms
    uniforms.viewTransform = MATRIX
    uniforms.pickOffset = PICK_VECTOR
    uniforms.shape = this.shape

    var attributes = shader.attributes
    this.positionBuffer.bind()
    attributes.position.pointer()

    this.weightBuffer.bind()
    attributes.weight.pointer(gl.UNSIGNED_BYTE, false)

    this.idBuffer.bind()
    attributes.pickId.pointer(gl.UNSIGNED_BYTE, false)

    gl.drawArrays(gl.TRIANGLES, 0, numVertices)

    return pickOffset + this.shape[0] * this.shape[1]
  }
})()

proto.pick = function (x, y, value) {
  var pickOffset = this.pickOffset
  var pointCount = this.shape[0] * this.shape[1]
  if (value < pickOffset || value >= pickOffset + pointCount) {
    return null
  }
  var pointId = value - pickOffset
  var xData = this.xData
  var yData = this.yData
  return {
    object: this,
    pointId: pointId,
    dataCoord: [
      xData[pointId % this.shape[0]],
      yData[(pointId / this.shape[0]) | 0]]
  }
}

proto.update = function (options) {
  options = options || {}

  var shape = options.shape || [0, 0]

  var x = options.x || iota(shape[0])
  var y = options.y || iota(shape[1])
  var z = options.z || new Float32Array(shape[0] * shape[1])

  var isSmooth = options.zsmooth !== false

  this.xData = x
  this.yData = y

  var colorLevels = options.colorLevels || [0]
  var colorValues = options.colorValues || [0, 0, 0, 1]
  var colorCount = colorLevels.length

  var bounds = this.bounds
  var lox, loy, hix, hiy
  if (isSmooth) {
    lox = bounds[0] = x[0]
    loy = bounds[1] = y[0]
    hix = bounds[2] = x[x.length - 1]
    hiy = bounds[3] = y[y.length - 1]
  } else {
    // To get squares to centre on data values
    lox = bounds[0] = x[0] + (x[1] - x[0]) / 2 // starting x value
    loy = bounds[1] = y[0] + (y[1] - y[0]) / 2 // starting y value

    // Bounds needs to add half a square on each end
    hix = bounds[2] = x[x.length - 1] + (x[x.length - 1] - x[x.length - 2]) / 2
    hiy = bounds[3] = y[y.length - 1] + (y[y.length - 1] - y[y.length - 2]) / 2

    // N.B. Resolution = 1 / range
  }
  var xs = 1.0 / (hix - lox)
  var ys = 1.0 / (hiy - loy)

  var numX = shape[0]
  var numY = shape[1]

  this.shape = [numX, numY]

  var numVerts = (
    isSmooth ? (numX - 1) * (numY - 1) : numX * numY
  ) * (WEIGHTS.length >>> 1)

  this.numVertices = numVerts

  var colors = pool.mallocUint8(numVerts * 4)
  var positions = pool.mallocFloat32(numVerts * 2)
  var weights   = pool.mallocUint8 (numVerts * 2)
  var ids = pool.mallocUint32(numVerts)

  var ptr = 0

  var ni = isSmooth ? numX - 1 : numX
  var nj = isSmooth ? numY - 1 : numY

  for (var j = 0; j < nj; ++j) {
    var yc0, yc1

    if (isSmooth) {
      yc0 =  ys * (y[j] - loy)
      yc1 =  ys * (y[j + 1] - loy)
    } else {
      yc0 = j < numY - 1 ? ys * (y[j] - (y[j + 1] - y[j])/2 - loy) : ys * (y[j] - (y[j] - y[j - 1])/2 - loy)
      yc1 = j < numY - 1 ? ys * (y[j] + (y[j + 1] - y[j])/2 - loy) : ys * (y[j] + (y[j] - y[j - 1])/2 - loy)
    }

    for (var i = 0; i < ni; ++i) {
      var xc0, xc1

      if (isSmooth) {
        xc0 = xs * (x[i] - lox)
        xc1 = xs * (x[i + 1] - lox)
      } else {
        xc0 = i < numX - 1 ? xs * (x[i] - (x[i + 1] - x[i])/2 - lox) : xs * (x[i] - (x[i] - x[i - 1])/2 - lox)
        xc1 = i < numX - 1 ? xs * (x[i] + (x[i + 1] - x[i])/2 - lox) : xs * (x[i] + (x[i] - x[i - 1])/2 - lox)
      }

      for (var dd = 0; dd < WEIGHTS.length; dd += 2) {
        var dx = WEIGHTS[dd]
        var dy = WEIGHTS[dd + 1]
        var offset = isSmooth ? (j + dy) * numX + (i + dx) : j * numX + i
        var zc = z[offset]
        var colorIdx = bsearch.le(colorLevels, zc)
        var r, g, b, a
        if (colorIdx < 0) {
          r = colorValues[0]
          g = colorValues[1]
          b = colorValues[2]
          a = colorValues[3]
        } else if (colorIdx === colorCount - 1) {
          r = colorValues[4 * colorCount - 4]
          g = colorValues[4 * colorCount - 3]
          b = colorValues[4 * colorCount - 2]
          a = colorValues[4 * colorCount - 1]
        } else {
          var t = (zc - colorLevels[colorIdx]) /
            (colorLevels[colorIdx + 1] - colorLevels[colorIdx])
          var ti = 1.0 - t
          var i0 = 4 * colorIdx
          var i1 = 4 * (colorIdx + 1)
          r = ti * colorValues[i0] + t * colorValues[i1]
          g = ti * colorValues[i0 + 1] + t * colorValues[i1 + 1]
          b = ti * colorValues[i0 + 2] + t * colorValues[i1 + 2]
          a = ti * colorValues[i0 + 3] + t * colorValues[i1 + 3]
        }

        colors[4 * ptr] = 255 * r
        colors[4 * ptr + 1] = 255 * g
        colors[4 * ptr + 2] = 255 * b
        colors[4 * ptr + 3] = 255 * a

        positions[2*ptr] = xc0*.5 + xc1*.5;
        positions[2*ptr+1] = yc0*.5 + yc1*.5;

        weights[2*ptr] = dx;
        weights[2*ptr+1] = dy;

        ids[ptr] = j * numX + i

        ptr += 1
      }
    }
  }

  this.positionBuffer.update(positions)
  this.weightBuffer.update(weights)
  this.colorBuffer.update(colors)
  this.idBuffer.update(ids)

  pool.free(positions)
  pool.free(colors)
  pool.free(weights)
  pool.free(ids)
}

proto.dispose = function () {
  this.shader.dispose()
  this.pickShader.dispose()
  this.positionBuffer.dispose()
  this.weightBuffer.dispose()
  this.colorBuffer.dispose()
  this.idBuffer.dispose()
  this.plot.removeObject(this)
}

function createHeatmap2D (plot, options) {
  var gl = plot.gl

  var shader = createShader(gl, shaders.vertex, shaders.fragment)
  var pickShader = createShader(gl, shaders.pickVertex, shaders.pickFragment)

  var positionBuffer = createBuffer(gl)
  var weightBuffer   = createBuffer(gl)
  var colorBuffer = createBuffer(gl)
  var idBuffer = createBuffer(gl)

  var heatmap = new GLHeatmap2D(
    plot,
    shader,
    pickShader,
    positionBuffer,
    weightBuffer,
    colorBuffer,
    idBuffer)

  heatmap.update(options)
  plot.addObject(heatmap)

  return heatmap
}


/***/ }),

/***/ 6768:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

"use strict";


var glslify = __webpack_require__(3236)

module.exports = {
  fragment:     glslify(["precision lowp float;\n#define GLSLIFY 1\nvarying vec4 fragColor;\nvoid main() {\n  gl_FragColor = vec4(fragColor.rgb * fragColor.a, fragColor.a);\n}\n"]),
  vertex:       glslify(["precision mediump float;\n#define GLSLIFY 1\n\nattribute vec2 position;\nattribute vec4 color;\nattribute vec2 weight;\n\nuniform vec2 shape;\nuniform mat3 viewTransform;\n\nvarying vec4 fragColor;\n\nvoid main() {\n  vec3 vPosition = viewTransform * vec3( position + (weight-.5)/(shape-1.) , 1.0);\n  fragColor = color;\n  gl_Position = vec4(vPosition.xy, 0, vPosition.z);\n}\n"]),
  pickFragment: glslify(["precision mediump float;\n#define GLSLIFY 1\n\nvarying vec4 fragId;\nvarying vec2 vWeight;\n\nuniform vec2 shape;\nuniform vec4 pickOffset;\n\nvoid main() {\n  vec2 d = step(.5, vWeight);\n  vec4 id = fragId + pickOffset;\n  id.x += d.x + d.y*shape.x;\n\n  id.y += floor(id.x / 256.0);\n  id.x -= floor(id.x / 256.0) * 256.0;\n\n  id.z += floor(id.y / 256.0);\n  id.y -= floor(id.y / 256.0) * 256.0;\n\n  id.w += floor(id.z / 256.0);\n  id.z -= floor(id.z / 256.0) * 256.0;\n\n  gl_FragColor = id/255.;\n}\n"]),
  pickVertex:   glslify(["precision mediump float;\n#define GLSLIFY 1\n\nattribute vec2 position;\nattribute vec4 pickId;\nattribute vec2 weight;\n\nuniform vec2 shape;\nuniform mat3 viewTransform;\n\nvarying vec4 fragId;\nvarying vec2 vWeight;\n\nvoid main() {\n  vWeight = weight;\n\n  fragId = pickId;\n\n  vec3 vPosition = viewTransform * vec3( position + (weight-.5)/(shape-1.) , 1.0);\n  gl_Position = vec4(vPosition.xy, 0, vPosition.z);\n}\n"])
}


/***/ }),

/***/ 7319:
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {

var glslify       = __webpack_require__(3236)
var createShader  = __webpack_require__(9405)

var vertSrc = glslify(["precision highp float;\n#define GLSLIFY 1\n\nattribute vec3 position, nextPosition;\nattribute float arcLength, lineWidth;\nattribute vec4 color;\n\nuniform vec2 screenShape;\nuniform float pixelRatio;\nuniform mat4 model, view, projection;\n\nvarying vec4 fragColor;\nvarying vec3 worldPosition;\nvarying float pixelArcLength;\n\nvec4 project(vec3 p) {\n  return projection * (view * (model * vec4(p, 1.0)));\n}\n\nvoid main() {\n  vec4 startPoint = project(position);\n  vec4 endPoint   = project(nextPosition);\n\n  vec2 A = startPoint.xy / startPoint.w;\n  vec2 B =   endPoint.xy /   endPoint.w;\n\n  float clipAngle = atan(\n    (B.y - A.y) * screenShape.y,\n    (B.x - A.x) * screenShape.x\n  );\n\n  vec2 offset = 0.5 * pixelRatio * lineWidth * vec2(\n    sin(clipAngle),\n    -cos(clipAngle)\n  ) / screenShape;\n\n  gl_Position = vec4(startPoint.xy + startPoint.w * offset, startPoint.zw);\n\n  worldPosition = position;\n  pixelArcLength = arcLength;\n  fragColor = color;\n}\n"])
var forwardFrag = glslify(["precision highp float;\n#define GLSLIFY 1\n\nbool outOfRange(float a, float b, float p) {\n  return ((p > max(a, b)) || \n          (p < min(a, b)));\n}\n\nbool outOfRange(vec2 a, vec2 b, vec2 p) {\n  return (outOfRange(a.x, b.x, p.x) ||\n          outOfRange(a.y, b.y, p.y));\n}\n\nbool outOfRange(vec3 a, vec3 b, vec3 p) {\n  return (outOfRange(a.x, b.x, p.x) ||\n          outOfRange(a.y, b.y, p.y) ||\n          outOfRange(a.z, b.z, p.z));\n}\n\nbool outOfRange(vec4 a, vec4 b, vec4 p) {\n  return outOfRange(a.xyz, b.xyz, p.xyz);\n}\n\nuniform vec3      clipBounds[2];\nuniform sampler2D dashTexture;\nuniform float     dashScale;\nuniform float     opacity;\n\nvarying vec3    worldPosition;\nvarying float   pixelArcLength;\nvarying vec4    fragColor;\n\nvoid main() {\n  if (\n    outOfRange(clipBounds[0], clipBounds[1], worldPosition) ||\n    fragColor.a * opacity == 0.\n  ) discard;\n\n  float dashWeight = texture2D(dashTexture, vec2(dashScale * pixelArcLength, 0)).r;\n  if(dashWeight < 0.5) {\n    discard;\n  }\n  gl_FragColor = fragColor * opacity;\n}\n"])
var pickFrag = glslify(["precision highp float;\n#define GLSLIFY 1\n\n#define FLOAT_MAX  1.70141184e38\n#define FLOAT_MIN  1.17549435e-38\n\n// https://github.com/mikolalysenko/glsl-read-float/blob/master/index.glsl\nvec4 packFloat(float v) {\n  float av = abs(v);\n\n  //Handle special cases\n  if(av < FLOAT_MIN) {\n    return vec4(0.0, 0.0, 0.0, 0.0);\n  } else if(v > FLOAT_MAX) {\n    return vec4(127.0, 128.0, 0.0, 0.0) / 255.0;\n  } else if(v < -FLOAT_MAX) {\n    return vec4(255.0, 128.0, 0.0, 0.0) / 255.0;\n  }\n\n  vec4 c = vec4(0,0,0,0);\n\n  //Compute exponent and mantissa\n  float e = floor(log2(av));\n  float m = av * pow(2.0, -e) - 1.0;\n\n  //Unpack mantissa\n  c[1] = floor(128.0 * m);\n  m -= c[1] / 128.0;\n  c[2] = floor(32768.0 * m);\n  m -= c[2] / 32768.0;\n  c[3] = floor(8388608.0 * m);\n\n  //Unpack exponent\n  float ebias = e + 127.0;\n  c[0] = floor(ebias / 2.0);\n  ebias -= c[0] * 2.0;\n  c[1] += floor(ebias) * 128.0;\n\n  //Unpack sign bit\n  c[0] += 128.0 * step(0.0, -v);\n\n  //Scale back to range\n  return c / 255.0;\n}\n\nbool outOfRange(float a, float b, float p) {\n  return ((p > max(a, b)) || \n          (p < min(a, b)));\n}\n\nbool outOfRange(vec2 a, vec2 b, vec2 p) {\n  return (outOfRange(a.x, b.x, p.x) ||\n          outOfRange(a.y, b.y, p.y));\n}\n\nbool outOfRange(vec3 a, vec3 b, vec3 p) {\n  return (outOfRange(a.x, b.x, p.x) ||\n          outOfRange(a.y, b.y, p.y) ||\n          outOfRange(a.z, b.z, p.z));\n}\n\nbool outOfRange(vec4 a, vec4 b, vec4 p) {\n  return outOfRange(a.xyz, b.xyz, p.xyz);\n}\n\nuniform float pickId;\nuniform vec3 clipBounds[2];\n\nvarying vec3 worldPosition;\nvarying float pixelArcLength;\nvarying vec4 fragColor;\n\nvoid main() {\n  if (outOfRange(clipBounds[0], clipBounds[1], worldPosition)) discard;\n\n  gl_FragColor = vec4(pickId/255.0, packFloat(pixelArcLength).xyz);\n}"])

var ATTRIBUTES = [
  {name: 'position', type: 'vec3'},
  {name: 'nextPosition', type: 'vec3'},
  {name: 'arcLength', type: 'float'},
  {name: 'lineWidth', type: 'float'},
  {name: 'color', type: 'vec4'}
]

exports.createShader = function(gl) {
  return createShader(gl, vertSrc, forwardFrag, null, ATTRIBUTES)
}

exports.createPickShader = function(gl) {
  return createShader(gl, vertSrc, pickFrag, null, ATTRIBUTES)
}


/***/ }),

/***/ 5714:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

"use strict";


module.exports = createLinePlot

var createBuffer = __webpack_require__(2762)
var createVAO = __webpack_require__(8116)
var createTexture = __webpack_require__(7766)

var UINT8_VIEW = new Uint8Array(4)
var FLOAT_VIEW = new Float32Array(UINT8_VIEW.buffer)
// https://github.com/mikolalysenko/glsl-read-float/blob/master/index.js
function unpackFloat(x, y, z, w) {
  UINT8_VIEW[0] = w
  UINT8_VIEW[1] = z
  UINT8_VIEW[2] = y
  UINT8_VIEW[3] = x
  return FLOAT_VIEW[0]
}

var bsearch = __webpack_require__(2478)
var ndarray = __webpack_require__(9618)
var shaders = __webpack_require__(7319)

var createShader = shaders.createShader
var createPickShader = shaders.createPickShader

var identity = [1, 0, 0, 0,
  0, 1, 0, 0,
  0, 0, 1, 0,
  0, 0, 0, 1]

function distance (a, b) {
  var s = 0.0
  for (var i = 0; i < 3; ++i) {
    var d = a[i] - b[i]
    s += d * d
  }
  return Math.sqrt(s)
}

function filterClipBounds (bounds) {
  var result = [[-1e6, -1e6, -1e6], [1e6, 1e6, 1e6]]
  for (var i = 0; i < 3; ++i) {
    result[0][i] = Math.max(bounds[0][i], result[0][i])
    result[1][i] = Math.min(bounds[1][i], result[1][i])
  }
  return result
}

function PickResult (tau, position, index, dataCoordinate) {
  this.arcLength = tau
  this.position = position
  this.index = index
  this.dataCoordinate = dataCoordinate
}

function LinePlot (gl, shader, pickShader, buffer, vao, texture) {
  this.gl = gl
  this.shader = shader
  this.pickShader = pickShader
  this.buffer = buffer
  this.vao = vao
  this.clipBounds = [
    [ -Infinity, -Infinity, -Infinity ],
    [ Infinity, Infinity, Infinity ]]
  this.points = []
  this.arcLength = []
  this.vertexCount = 0
  this.bounds = [[0, 0, 0], [0, 0, 0]]
  this.pickId = 0
  this.lineWidth = 1
  this.texture = texture
  this.dashScale = 1
  this.opacity = 1
  this.hasAlpha = false
  this.dirty = true
  this.pixelRatio = 1
}

var proto = LinePlot.prototype

proto.isTransparent = function () {
  return this.hasAlpha
}

proto.isOpaque = function () {
  return !this.hasAlpha
}

proto.pickSlots = 1

proto.setPickBase = function (id) {
  this.pickId = id
}

proto.drawTransparent = proto.draw = function (camera) {
  if (!this.vertexCount) return
  var gl = this.gl
  var shader = this.shader
  var vao = this.vao
  shader.bind()
  shader.uniforms = {
    model: camera.model || identity,
    view: camera.view || identity,
    projection: camera.projection || identity,
    clipBounds: filterClipBounds(this.clipBounds),
    dashTexture: this.texture.bind(),
    dashScale: this.dashScale / this.arcLength[this.arcLength.length - 1],
    opacity: this.opacity,
    screenShape: [gl.drawingBufferWidth, gl.drawingBufferHeight],
    pixelRatio: this.pixelRatio
  }
  vao.bind()
  vao.draw(gl.TRIANGLE_STRIP, this.vertexCount)
  vao.unbind()
}

proto.drawPick = function (camera) {
  if (!this.vertexCount) return
  var gl = this.gl
  var shader = this.pickShader
  var vao = this.vao
  shader.bind()
  shader.uniforms = {
    model: camera.model || identity,
    view: camera.view || identity,
    projection: camera.projection || identity,
    pickId: this.pickId,
    clipBounds: filterClipBounds(this.clipBounds),
    screenShape: [gl.drawingBufferWidth, gl.drawingBufferHeight],
    pixelRatio: this.pixelRatio
  }
  vao.bind()
  vao.draw(gl.TRIANGLE_STRIP, this.vertexCount)
  vao.unbind()
}

proto.update = function (options) {
  var i, j

  this.dirty = true

  var connectGaps = !!options.connectGaps

  if ('dashScale' in options) {
    this.dashScale = options.dashScale
  }

  this.hasAlpha = false // default to no transparent draw
  if ('opacity' in options) {
    this.opacity = +options.opacity
    if(this.opacity < 1) {
      this.hasAlpha = true;
    }
  }

  // Recalculate buffer data
  var buffer = []
  var arcLengthArray = []
  var pointArray = []
  var arcLength = 0.0
  var vertexCount = 0
  var bounds = [
    [ Infinity, Infinity, Infinity ],
    [ -Infinity, -Infinity, -Infinity ]]

  var positions = options.position || options.positions
  if (positions) {

    // Default color
    var colors = options.color || options.colors || [0, 0, 0, 1]

    var lineWidth = options.lineWidth || 1

    var hadGap = false

    fill_loop:
    for (i = 1; i < positions.length; ++i) {
      var a = positions[i - 1]
      var b = positions[i]

      arcLengthArray.push(arcLength)
      pointArray.push(a.slice())

      for (j = 0; j < 3; ++j) {
        if (isNaN(a[j]) || isNaN(b[j]) ||
          !isFinite(a[j]) || !isFinite(b[j])) {

          if (!connectGaps && buffer.length > 0) {
            for (var k = 0; k < 24; ++k) {
              buffer.push(buffer[buffer.length - 12])
            }
            vertexCount += 2
            hadGap = true
          }

          continue fill_loop
        }
        bounds[0][j] = Math.min(bounds[0][j], a[j], b[j])
        bounds[1][j] = Math.max(bounds[1][j], a[j], b[j])
      }

      var acolor, bcolor
      if (Array.isArray(colors[0])) {
        acolor = (colors.length > i - 1) ? colors[i - 1] :             // using index value
                 (colors.length > 0)     ? colors[colors.length - 1] : // using last item
                                           [0, 0, 0, 1];               // using black

        bcolor = (colors.length > i) ? colors[i] :                 // using index value
                 (colors.length > 0) ? colors[colors.length - 1] : // using last item
                                       [0, 0, 0, 1];               // using black
      } else {
        acolor = bcolor = colors
      }

      if (acolor.length === 3) {
        acolor = [acolor[0], acolor[1], acolor[2], 1]
      }
      if (bcolor.length === 3) {
        bcolor = [bcolor[0], bcolor[1], bcolor[2], 1]
      }

      if(!this.hasAlpha && acolor[3] < 1) this.hasAlpha = true

      var w0
      if (Array.isArray(lineWidth)) {
        w0 = (lineWidth.length > i - 1) ? lineWidth[i - 1] :                // using index value
             (lineWidth.length > 0)     ? lineWidth[lineWidth.length - 1] : // using last item
                                          [0, 0, 0, 1];                     // using black
      } else {
        w0 = lineWidth
      }

      var t0 = arcLength
      arcLength += distance(a, b)

      if (hadGap) {
        for (j = 0; j < 2; ++j) {
          buffer.push(
            a[0], a[1], a[2], b[0], b[1], b[2], t0, w0, acolor[0], acolor[1], acolor[2], acolor[3])
        }
        vertexCount += 2
        hadGap = false
      }

      buffer.push(
        a[0], a[1], a[2], b[0], b[1], b[2], t0, w0, acolor[0], acolor[1], acolor[2], acolor[3],
        a[0], a[1], a[2], b[0], b[1], b[2], t0, -w0, acolor[0], acolor[1], acolor[2], acolor[3],
        b[0], b[1], b[2], a[0], a[1], a[2], arcLength, -w0, bcolor[0], bcolor[1], bcolor[2], bcolor[3],
        b[0], b[1], b[2], a[0], a[1], a[2], arcLength, w0, bcolor[0], bcolor[1], bcolor[2], bcolor[3])

      vertexCount += 4
    }
  }
  this.buffer.update(buffer)

  arcLengthArray.push(arcLength)
  pointArray.push(positions[positions.length - 1].slice())

  this.bounds = bounds

  this.vertexCount = vertexCount

  this.points = pointArray
  this.arcLength = arcLengthArray

  if ('dashes' in options) {
    var dashArray = options.dashes

    // Calculate prefix sum
    var prefixSum = dashArray.slice()
    prefixSum.unshift(0)
    for (i = 1; i < prefixSum.length; ++i) {
      prefixSum[i] = prefixSum[i - 1] + prefixSum[i]
    }

    var dashTexture = ndarray(new Array(256 * 4), [256, 1, 4])
    for (i = 0; i < 256; ++i) {
      for (j = 0; j < 4; ++j) {
        dashTexture.set(i, 0, j, 0)
      }
      if (bsearch.le(prefixSum, prefixSum[prefixSum.length - 1] * i / 255.0) & 1) {
        dashTexture.set(i, 0, 0, 0)
      } else {
        dashTexture.set(i, 0, 0, 255)
      }
    }

    this.texture.setPixels(dashTexture)
  }
}

proto.dispose = function () {
  this.shader.dispose()
  this.vao.dispose()
  this.buffer.dispose()
}

proto.pick = function (selection) {
  if (!selection) {
    return null
  }
  if (selection.id !== this.pickId) {
    return null
  }
  var tau = unpackFloat(
    selection.value[0],
    selection.value[1],
    selection.value[2],
    0)
  var index = bsearch.le(this.arcLength, tau)
  if (index < 0) {
    return null
  }
  if (index === this.arcLength.length - 1) {
    return new PickResult(
      this.arcLength[this.arcLength.length - 1],
      this.points[this.points.length - 1].slice(),
      index)
  }
  var a = this.points[index]
  var b = this.points[Math.min(index + 1, this.points.length - 1)]
  var t = (tau - this.arcLength[index]) / (this.arcLength[index + 1] - this.arcLength[index])
  var ti = 1.0 - t
  var x = [0, 0, 0]
  for (var i = 0; i < 3; ++i) {
    x[i] = ti * a[i] + t * b[i]
  }
  var dataIndex = Math.min((t < 0.5) ? index : (index + 1), this.points.length - 1)
  return new PickResult(
    tau,
    x,
    dataIndex,
    this.points[dataIndex])
}

function createLinePlot (options) {
  var gl = options.gl || (options.scene && options.scene.gl)

  var shader = createShader(gl)
  shader.attributes.position.location = 0
  shader.attributes.nextPosition.location = 1
  shader.attributes.arcLength.location = 2
  shader.attributes.lineWidth.location = 3
  shader.attributes.color.location = 4

  var pickShader = createPickShader(gl)
  pickShader.attributes.position.location = 0
  pickShader.attributes.nextPosition.location = 1
  pickShader.attributes.arcLength.location = 2
  pickShader.attributes.lineWidth.location = 3
  pickShader.attributes.color.location = 4

  var buffer = createBuffer(gl)
  var vao = createVAO(gl, [
    {
      'buffer': buffer,
      'size': 3,
      'offset': 0,
      'stride': 48
    },
    {
      'buffer': buffer,
      'size': 3,
      'offset': 12,
      'stride': 48
    },
    {
      'buffer': buffer,
      'size': 1,
      'offset': 24,
      'stride': 48
    },
    {
      'buffer': buffer,
      'size': 1,
      'offset': 28,
      'stride': 48
    },
    {
      'buffer': buffer,
      'size': 4,
      'offset': 32,
      'stride': 48
    }
  ])

  // Create texture for dash pattern
  var defaultTexture = ndarray(new Array(256 * 4), [256, 1, 4])
  for (var i = 0; i < 256 * 4; ++i) {
    defaultTexture.data[i] = 255
  }
  var texture = createTexture(gl, defaultTexture)
  texture.wrap = gl.REPEAT

  var linePlot = new LinePlot(gl, shader, pickShader, buffer, vao, texture)
  linePlot.update(options)
  return linePlot
}


/***/ }),

/***/ 1903:
/***/ (function(module) {

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;
};

/***/ }),

/***/ 6864:
/***/ (function(module) {

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;
};

/***/ }),

/***/ 9921:
/***/ (function(module) {

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;
};

/***/ }),

/***/ 7399:
/***/ (function(module) {

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;
};

/***/ }),

/***/ 6743:
/***/ (function(module) {

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;
};

/***/ }),

/***/ 7894:
/***/ (function(module) {

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;
};

/***/ }),

/***/ 7608:
/***/ (function(module) {

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;
};

/***/ }),

/***/ 6582:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

var identity = __webpack_require__(7894);

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;
};

/***/ }),

/***/ 6760:
/***/ (function(module) {

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;
};

/***/ }),

/***/ 4040:
/***/ (function(module) {

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;
};

/***/ }),

/***/ 4772:
/***/ (function(module) {

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;
};

/***/ }),

/***/ 6079:
/***/ (function(module) {

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;
};

/***/ }),

/***/ 5567:
/***/ (function(module) {

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;
};

/***/ }),

/***/ 2408:
/***/ (function(module) {

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;
};

/***/ }),

/***/ 7089:
/***/ (function(module) {

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;
};

/***/ }),

/***/ 2504:
/***/ (function(module) {

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;
};

/***/ }),

/***/ 7656:
/***/ (function(module) {

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;
};

/***/ }),

/***/ 5665:
/***/ (function(module) {

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;
};

/***/ }),

/***/ 7626:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

"use strict";


var barycentric            = __webpack_require__(2642)
var closestPointToTriangle = __webpack_require__(9346)

module.exports = closestPointToPickLocation

function xformMatrix(m, v) {
  var out = [0,0,0,0]
  for(var i=0; i<4; ++i) {
    for(var j=0; j<4; ++j) {
      out[j] += m[4*i + j] * v[i]
    }
  }
  return out
}

function projectVertex(v, model, view, projection, resolution) {
  var p = xformMatrix(projection,
            xformMatrix(view,
              xformMatrix(model, [v[0], v[1], v[2], 1])))
  for(var i=0; i<3; ++i) {
    p[i] /= p[3]
  }
  return [ 0.5 * resolution[0] * (1.0+p[0]), 0.5 * resolution[1] * (1.0-p[1]) ]
}

function barycentricCoord(simplex, point) {
  if(simplex.length === 2) {
    var d0 = 0.0
    var d1 = 0.0
    for(var i=0; i<2; ++i) {
      d0 += Math.pow(point[i] - simplex[0][i], 2)
      d1 += Math.pow(point[i] - simplex[1][i], 2)
    }
    d0 = Math.sqrt(d0)
    d1 = Math.sqrt(d1)
    if(d0+d1 < 1e-6) {
      return [1,0]
    }
    return [d1/(d0+d1),d0/(d1+d0)]
  } else if(simplex.length === 3) {
    var closestPoint = [0,0]
    closestPointToTriangle(simplex[0], simplex[1], simplex[2], point, closestPoint)
    return barycentric(simplex, closestPoint)
  }
  return []
}

function interpolate(simplex, weights) {
  var result = [0,0,0]
  for(var i=0; i 1.0001) {
      return null
    }
    s += weights[i]
  }
  if(Math.abs(s - 1.0) > 0.001) {
    return null
  }
  return [closestIndex, interpolate(simplex, weights), weights]
}

/***/ }),

/***/ 840:
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {

var glslify       = __webpack_require__(3236)

var triVertSrc = glslify(["precision highp float;\n#define GLSLIFY 1\n\nattribute vec3 position, normal;\nattribute vec4 color;\nattribute vec2 uv;\n\nuniform mat4 model\n           , view\n           , projection\n           , inverseModel;\nuniform vec3 eyePosition\n           , lightPosition;\n\nvarying vec3 f_normal\n           , f_lightDirection\n           , f_eyeDirection\n           , f_data;\nvarying vec4 f_color;\nvarying vec2 f_uv;\n\nvec4 project(vec3 p) {\n  return projection * (view * (model * vec4(p, 1.0)));\n}\n\nvoid main() {\n  gl_Position      = project(position);\n\n  //Lighting geometry parameters\n  vec4 cameraCoordinate = view * vec4(position , 1.0);\n  cameraCoordinate.xyz /= cameraCoordinate.w;\n  f_lightDirection = lightPosition - cameraCoordinate.xyz;\n  f_eyeDirection   = eyePosition - cameraCoordinate.xyz;\n  f_normal  = normalize((vec4(normal, 0.0) * inverseModel).xyz);\n\n  f_color          = color;\n  f_data           = position;\n  f_uv             = uv;\n}\n"])
var triFragSrc = glslify(["#extension GL_OES_standard_derivatives : enable\n\nprecision highp float;\n#define GLSLIFY 1\n\nfloat beckmannDistribution(float x, float roughness) {\n  float NdotH = max(x, 0.0001);\n  float cos2Alpha = NdotH * NdotH;\n  float tan2Alpha = (cos2Alpha - 1.0) / cos2Alpha;\n  float roughness2 = roughness * roughness;\n  float denom = 3.141592653589793 * roughness2 * cos2Alpha * cos2Alpha;\n  return exp(tan2Alpha / roughness2) / denom;\n}\n\nfloat cookTorranceSpecular(\n  vec3 lightDirection,\n  vec3 viewDirection,\n  vec3 surfaceNormal,\n  float roughness,\n  float fresnel) {\n\n  float VdotN = max(dot(viewDirection, surfaceNormal), 0.0);\n  float LdotN = max(dot(lightDirection, surfaceNormal), 0.0);\n\n  //Half angle vector\n  vec3 H = normalize(lightDirection + viewDirection);\n\n  //Geometric term\n  float NdotH = max(dot(surfaceNormal, H), 0.0);\n  float VdotH = max(dot(viewDirection, H), 0.000001);\n  float LdotH = max(dot(lightDirection, H), 0.000001);\n  float G1 = (2.0 * NdotH * VdotN) / VdotH;\n  float G2 = (2.0 * NdotH * LdotN) / LdotH;\n  float G = min(1.0, min(G1, G2));\n  \n  //Distribution term\n  float D = beckmannDistribution(NdotH, roughness);\n\n  //Fresnel term\n  float F = pow(1.0 - VdotN, fresnel);\n\n  //Multiply terms and done\n  return  G * F * D / max(3.14159265 * VdotN, 0.000001);\n}\n\n//#pragma glslify: beckmann = require(glsl-specular-beckmann) // used in gl-surface3d\n\nbool outOfRange(float a, float b, float p) {\n  return ((p > max(a, b)) || \n          (p < min(a, b)));\n}\n\nbool outOfRange(vec2 a, vec2 b, vec2 p) {\n  return (outOfRange(a.x, b.x, p.x) ||\n          outOfRange(a.y, b.y, p.y));\n}\n\nbool outOfRange(vec3 a, vec3 b, vec3 p) {\n  return (outOfRange(a.x, b.x, p.x) ||\n          outOfRange(a.y, b.y, p.y) ||\n          outOfRange(a.z, b.z, p.z));\n}\n\nbool outOfRange(vec4 a, vec4 b, vec4 p) {\n  return outOfRange(a.xyz, b.xyz, p.xyz);\n}\n\nuniform vec3 clipBounds[2];\nuniform float roughness\n            , fresnel\n            , kambient\n            , kdiffuse\n            , kspecular;\nuniform sampler2D texture;\n\nvarying vec3 f_normal\n           , f_lightDirection\n           , f_eyeDirection\n           , f_data;\nvarying vec4 f_color;\nvarying vec2 f_uv;\n\nvoid main() {\n  if (f_color.a == 0.0 ||\n    outOfRange(clipBounds[0], clipBounds[1], f_data)\n  ) discard;\n\n  vec3 N = normalize(f_normal);\n  vec3 L = normalize(f_lightDirection);\n  vec3 V = normalize(f_eyeDirection);\n\n  if(gl_FrontFacing) {\n    N = -N;\n  }\n\n  float specular = min(1.0, max(0.0, cookTorranceSpecular(L, V, N, roughness, fresnel)));\n  //float specular = max(0.0, beckmann(L, V, N, roughness)); // used in gl-surface3d\n\n  float diffuse  = min(kambient + kdiffuse * max(dot(N, L), 0.0), 1.0);\n\n  vec4 surfaceColor = vec4(f_color.rgb, 1.0) * texture2D(texture, f_uv);\n  vec4 litColor = surfaceColor.a * vec4(diffuse * surfaceColor.rgb + kspecular * vec3(1,1,1) * specular,  1.0);\n\n  gl_FragColor = litColor * f_color.a;\n}\n"])
var edgeVertSrc = glslify(["precision highp float;\n#define GLSLIFY 1\n\nattribute vec3 position;\nattribute vec4 color;\nattribute vec2 uv;\n\nuniform mat4 model, view, projection;\n\nvarying vec4 f_color;\nvarying vec3 f_data;\nvarying vec2 f_uv;\n\nvoid main() {\n  gl_Position = projection * (view * (model * vec4(position, 1.0)));\n  f_color = color;\n  f_data  = position;\n  f_uv    = uv;\n}"])
var edgeFragSrc = glslify(["precision highp float;\n#define GLSLIFY 1\n\nbool outOfRange(float a, float b, float p) {\n  return ((p > max(a, b)) || \n          (p < min(a, b)));\n}\n\nbool outOfRange(vec2 a, vec2 b, vec2 p) {\n  return (outOfRange(a.x, b.x, p.x) ||\n          outOfRange(a.y, b.y, p.y));\n}\n\nbool outOfRange(vec3 a, vec3 b, vec3 p) {\n  return (outOfRange(a.x, b.x, p.x) ||\n          outOfRange(a.y, b.y, p.y) ||\n          outOfRange(a.z, b.z, p.z));\n}\n\nbool outOfRange(vec4 a, vec4 b, vec4 p) {\n  return outOfRange(a.xyz, b.xyz, p.xyz);\n}\n\nuniform vec3 clipBounds[2];\nuniform sampler2D texture;\nuniform float opacity;\n\nvarying vec4 f_color;\nvarying vec3 f_data;\nvarying vec2 f_uv;\n\nvoid main() {\n  if (outOfRange(clipBounds[0], clipBounds[1], f_data)) discard;\n\n  gl_FragColor = f_color * texture2D(texture, f_uv) * opacity;\n}"])
var pointVertSrc = glslify(["precision highp float;\n#define GLSLIFY 1\n\nbool outOfRange(float a, float b, float p) {\n  return ((p > max(a, b)) || \n          (p < min(a, b)));\n}\n\nbool outOfRange(vec2 a, vec2 b, vec2 p) {\n  return (outOfRange(a.x, b.x, p.x) ||\n          outOfRange(a.y, b.y, p.y));\n}\n\nbool outOfRange(vec3 a, vec3 b, vec3 p) {\n  return (outOfRange(a.x, b.x, p.x) ||\n          outOfRange(a.y, b.y, p.y) ||\n          outOfRange(a.z, b.z, p.z));\n}\n\nbool outOfRange(vec4 a, vec4 b, vec4 p) {\n  return outOfRange(a.xyz, b.xyz, p.xyz);\n}\n\nattribute vec3 position;\nattribute vec4 color;\nattribute vec2 uv;\nattribute float pointSize;\n\nuniform mat4 model, view, projection;\nuniform vec3 clipBounds[2];\n\nvarying vec4 f_color;\nvarying vec2 f_uv;\n\nvoid main() {\n  if (outOfRange(clipBounds[0], clipBounds[1], position)) {\n\n    gl_Position = vec4(0.0, 0.0 ,0.0 ,0.0);\n  } else {\n    gl_Position = projection * (view * (model * vec4(position, 1.0)));\n  }\n  gl_PointSize = pointSize;\n  f_color = color;\n  f_uv = uv;\n}"])
var pointFragSrc = glslify(["precision highp float;\n#define GLSLIFY 1\n\nuniform sampler2D texture;\nuniform float opacity;\n\nvarying vec4 f_color;\nvarying vec2 f_uv;\n\nvoid main() {\n  vec2 pointR = gl_PointCoord.xy - vec2(0.5, 0.5);\n  if(dot(pointR, pointR) > 0.25) {\n    discard;\n  }\n  gl_FragColor = f_color * texture2D(texture, f_uv) * opacity;\n}"])
var pickVertSrc = glslify(["precision highp float;\n#define GLSLIFY 1\n\nattribute vec3 position;\nattribute vec4 id;\n\nuniform mat4 model, view, projection;\n\nvarying vec3 f_position;\nvarying vec4 f_id;\n\nvoid main() {\n  gl_Position = projection * (view * (model * vec4(position, 1.0)));\n  f_id        = id;\n  f_position  = position;\n}"])
var pickFragSrc = glslify(["precision highp float;\n#define GLSLIFY 1\n\nbool outOfRange(float a, float b, float p) {\n  return ((p > max(a, b)) || \n          (p < min(a, b)));\n}\n\nbool outOfRange(vec2 a, vec2 b, vec2 p) {\n  return (outOfRange(a.x, b.x, p.x) ||\n          outOfRange(a.y, b.y, p.y));\n}\n\nbool outOfRange(vec3 a, vec3 b, vec3 p) {\n  return (outOfRange(a.x, b.x, p.x) ||\n          outOfRange(a.y, b.y, p.y) ||\n          outOfRange(a.z, b.z, p.z));\n}\n\nbool outOfRange(vec4 a, vec4 b, vec4 p) {\n  return outOfRange(a.xyz, b.xyz, p.xyz);\n}\n\nuniform vec3  clipBounds[2];\nuniform float pickId;\n\nvarying vec3 f_position;\nvarying vec4 f_id;\n\nvoid main() {\n  if (outOfRange(clipBounds[0], clipBounds[1], f_position)) discard;\n\n  gl_FragColor = vec4(pickId, f_id.xyz);\n}"])
var pickPointVertSrc = glslify(["precision highp float;\n#define GLSLIFY 1\n\nbool outOfRange(float a, float b, float p) {\n  return ((p > max(a, b)) || \n          (p < min(a, b)));\n}\n\nbool outOfRange(vec2 a, vec2 b, vec2 p) {\n  return (outOfRange(a.x, b.x, p.x) ||\n          outOfRange(a.y, b.y, p.y));\n}\n\nbool outOfRange(vec3 a, vec3 b, vec3 p) {\n  return (outOfRange(a.x, b.x, p.x) ||\n          outOfRange(a.y, b.y, p.y) ||\n          outOfRange(a.z, b.z, p.z));\n}\n\nbool outOfRange(vec4 a, vec4 b, vec4 p) {\n  return outOfRange(a.xyz, b.xyz, p.xyz);\n}\n\nattribute vec3  position;\nattribute float pointSize;\nattribute vec4  id;\n\nuniform mat4 model, view, projection;\nuniform vec3 clipBounds[2];\n\nvarying vec3 f_position;\nvarying vec4 f_id;\n\nvoid main() {\n  if (outOfRange(clipBounds[0], clipBounds[1], position)) {\n\n    gl_Position = vec4(0.0, 0.0, 0.0, 0.0);\n  } else {\n    gl_Position  = projection * (view * (model * vec4(position, 1.0)));\n    gl_PointSize = pointSize;\n  }\n  f_id         = id;\n  f_position   = position;\n}"])
var contourVertSrc = glslify(["precision highp float;\n#define GLSLIFY 1\n\nattribute vec3 position;\n\nuniform mat4 model, view, projection;\n\nvoid main() {\n  gl_Position = projection * (view * (model * vec4(position, 1.0)));\n}"])
var contourFragSrc = glslify(["precision highp float;\n#define GLSLIFY 1\n\nuniform vec3 contourColor;\n\nvoid main() {\n  gl_FragColor = vec4(contourColor, 1.0);\n}\n"])

exports.meshShader = {
  vertex:   triVertSrc,
  fragment: triFragSrc,
  attributes: [
    {name: 'position', type: 'vec3'},
    {name: 'normal', type: 'vec3'},
    {name: 'color', type: 'vec4'},
    {name: 'uv', type: 'vec2'}
  ]
}
exports.wireShader = {
  vertex:   edgeVertSrc,
  fragment: edgeFragSrc,
  attributes: [
    {name: 'position', type: 'vec3'},
    {name: 'color', type: 'vec4'},
    {name: 'uv', type: 'vec2'}
  ]
}
exports.pointShader = {
  vertex:   pointVertSrc,
  fragment: pointFragSrc,
  attributes: [
    {name: 'position', type: 'vec3'},
    {name: 'color', type: 'vec4'},
    {name: 'uv', type: 'vec2'},
    {name: 'pointSize', type: 'float'}
  ]
}
exports.pickShader = {
  vertex:   pickVertSrc,
  fragment: pickFragSrc,
  attributes: [
    {name: 'position', type: 'vec3'},
    {name: 'id', type: 'vec4'}
  ]
}
exports.pointPickShader = {
  vertex:   pickPointVertSrc,
  fragment: pickFragSrc,
  attributes: [
    {name: 'position', type: 'vec3'},
    {name: 'pointSize', type: 'float'},
    {name: 'id', type: 'vec4'}
  ]
}
exports.contourShader = {
  vertex:   contourVertSrc,
  fragment: contourFragSrc,
  attributes: [
    {name: 'position', type: 'vec3'}
  ]
}


/***/ }),

/***/ 7201:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

"use strict";


var DEFAULT_VERTEX_NORMALS_EPSILON = 1e-6; // may be too large if triangles are very small
var DEFAULT_FACE_NORMALS_EPSILON = 1e-6;

var createShader  = __webpack_require__(9405)
var createBuffer  = __webpack_require__(2762)
var createVAO     = __webpack_require__(8116)
var createTexture = __webpack_require__(7766)
var normals       = __webpack_require__(8406)
var multiply      = __webpack_require__(6760)
var invert        = __webpack_require__(7608)
var ndarray       = __webpack_require__(9618)
var colormap      = __webpack_require__(6729)
var getContour    = __webpack_require__(7765)
var pool          = __webpack_require__(1888)
var shaders       = __webpack_require__(840)
var closestPoint  = __webpack_require__(7626)

var meshShader    = shaders.meshShader
var wireShader    = shaders.wireShader
var pointShader   = shaders.pointShader
var pickShader    = shaders.pickShader
var pointPickShader = shaders.pointPickShader
var contourShader = shaders.contourShader

var IDENTITY = [
  1,0,0,0,
  0,1,0,0,
  0,0,1,0,
  0,0,0,1]


function SimplicialMesh(gl
  , texture
  , triShader
  , lineShader
  , pointShader
  , pickShader
  , pointPickShader
  , contourShader
  , trianglePositions
  , triangleIds
  , triangleColors
  , triangleUVs
  , triangleNormals
  , triangleVAO
  , edgePositions
  , edgeIds
  , edgeColors
  , edgeUVs
  , edgeVAO
  , pointPositions
  , pointIds
  , pointColors
  , pointUVs
  , pointSizes
  , pointVAO
  , contourPositions
  , contourVAO) {

  this.gl                = gl
  this.pixelRatio         = 1
  this.cells             = []
  this.positions         = []
  this.intensity         = []
  this.texture           = texture
  this.dirty             = true

  this.triShader         = triShader
  this.lineShader        = lineShader
  this.pointShader       = pointShader
  this.pickShader        = pickShader
  this.pointPickShader   = pointPickShader
  this.contourShader     = contourShader

  this.trianglePositions = trianglePositions
  this.triangleColors    = triangleColors
  this.triangleNormals   = triangleNormals
  this.triangleUVs       = triangleUVs
  this.triangleIds       = triangleIds
  this.triangleVAO       = triangleVAO
  this.triangleCount     = 0

  this.lineWidth         = 1
  this.edgePositions     = edgePositions
  this.edgeColors        = edgeColors
  this.edgeUVs           = edgeUVs
  this.edgeIds           = edgeIds
  this.edgeVAO           = edgeVAO
  this.edgeCount         = 0

  this.pointPositions    = pointPositions
  this.pointColors       = pointColors
  this.pointUVs          = pointUVs
  this.pointSizes        = pointSizes
  this.pointIds          = pointIds
  this.pointVAO          = pointVAO
  this.pointCount        = 0

  this.contourLineWidth  = 1
  this.contourPositions  = contourPositions
  this.contourVAO        = contourVAO
  this.contourCount      = 0
  this.contourColor      = [0,0,0]
  this.contourEnable     = true

  this.pickVertex        = true;
  this.pickId            = 1
  this.bounds            = [
    [ Infinity, Infinity, Infinity],
    [-Infinity,-Infinity,-Infinity] ]
  this.clipBounds        = [
    [-Infinity,-Infinity,-Infinity],
    [ Infinity, Infinity, Infinity] ]

  this.lightPosition = [1e5, 1e5, 0]
  this.ambientLight  = 0.8
  this.diffuseLight  = 0.8
  this.specularLight = 2.0
  this.roughness     = 0.5
  this.fresnel       = 1.5

  this.opacity       = 1.0
  this.hasAlpha      = false
  this.opacityscale  = false

  this._model       = IDENTITY
  this._view        = IDENTITY
  this._projection  = IDENTITY
  this._resolution  = [1,1]
}

var proto = SimplicialMesh.prototype

proto.isOpaque = function() {
  return !this.hasAlpha
}

proto.isTransparent = function() {
  return this.hasAlpha
}

proto.pickSlots = 1

proto.setPickBase = function(id) {
  this.pickId = id
}

function getOpacityFromScale(ratio, opacityscale) {

  if(!opacityscale) return 1
  if(!opacityscale.length) return 1

  for(var i = 0; i < opacityscale.length; ++i) {
    if(opacityscale.length < 2) return 1
    if(opacityscale[i][0] === ratio) return opacityscale[i][1]
    if(opacityscale[i][0] > ratio && i > 0) {
      var d = (opacityscale[i][0] - ratio) / (opacityscale[i][0] - opacityscale[i - 1][0])
      return opacityscale[i][1] * (1 - d) + d * opacityscale[i - 1][1]
    }
  }

  return 1
}

function genColormap(param, opacityscale) {
  var colors = colormap({
      colormap: param
    , nshades:  256
    , format:  'rgba'
  })

  var result = new Uint8Array(256*4)
  for(var i=0; i<256; ++i) {
    var c = colors[i]
    for(var j=0; j<3; ++j) {
      result[4*i+j] = c[j]
    }
    if(!opacityscale) {
      result[4*i+3] = 255 * c[3]
    } else {
      result[4*i+3] = 255 * getOpacityFromScale(i / 255.0, opacityscale)
    }
  }

  return ndarray(result, [256,256,4], [4,0,1])
}

function takeZComponent(array) {
  var n = array.length
  var result = new Array(n)
  for(var i=0; i 0) {
    var shader = this.triShader
    shader.bind()
    shader.uniforms = uniforms

    this.triangleVAO.bind()
    gl.drawArrays(gl.TRIANGLES, 0, this.triangleCount*3)
    this.triangleVAO.unbind()
  }

  if(this.edgeCount > 0 && this.lineWidth > 0) {
    var shader = this.lineShader
    shader.bind()
    shader.uniforms = uniforms

    this.edgeVAO.bind()
    gl.lineWidth(this.lineWidth * this.pixelRatio)
    gl.drawArrays(gl.LINES, 0, this.edgeCount*2)
    this.edgeVAO.unbind()
  }

  if(this.pointCount > 0) {
    var shader = this.pointShader
    shader.bind()
    shader.uniforms = uniforms

    this.pointVAO.bind()
    gl.drawArrays(gl.POINTS, 0, this.pointCount)
    this.pointVAO.unbind()
  }

  if(this.contourEnable && this.contourCount > 0 && this.contourLineWidth > 0) {
    var shader = this.contourShader
    shader.bind()
    shader.uniforms = uniforms

    this.contourVAO.bind()
    gl.drawArrays(gl.LINES, 0, this.contourCount)
    this.contourVAO.unbind()
  }
}

proto.drawPick = function(params) {
  params = params || {}

  var gl         = this.gl

  var model      = params.model      || IDENTITY
  var view       = params.view       || IDENTITY
  var projection = params.projection || IDENTITY

  var clipBounds = [[-1e6,-1e6,-1e6],[1e6,1e6,1e6]]
  for(var i=0; i<3; ++i) {
    clipBounds[0][i] = Math.max(clipBounds[0][i], this.clipBounds[0][i])
    clipBounds[1][i] = Math.min(clipBounds[1][i], this.clipBounds[1][i])
  }

  //Save camera parameters
  this._model      = [].slice.call(model)
  this._view       = [].slice.call(view)
  this._projection = [].slice.call(projection)
  this._resolution = [gl.drawingBufferWidth, gl.drawingBufferHeight]

  var uniforms = {
    model:      model,
    view:       view,
    projection: projection,
    clipBounds: clipBounds,
    pickId:     this.pickId / 255.0,
  }

  var shader = this.pickShader
  shader.bind()
  shader.uniforms = uniforms

  if(this.triangleCount > 0) {
    this.triangleVAO.bind()
    gl.drawArrays(gl.TRIANGLES, 0, this.triangleCount*3)
    this.triangleVAO.unbind()
  }

  if(this.edgeCount > 0) {
    this.edgeVAO.bind()
    gl.lineWidth(this.lineWidth * this.pixelRatio)
    gl.drawArrays(gl.LINES, 0, this.edgeCount*2)
    this.edgeVAO.unbind()
  }

  if(this.pointCount > 0) {
    var shader = this.pointPickShader
    shader.bind()
    shader.uniforms = uniforms

    this.pointVAO.bind()
    gl.drawArrays(gl.POINTS, 0, this.pointCount)
    this.pointVAO.unbind()
  }
}


proto.pick = function(pickData) {
  if(!pickData) {
    return null
  }
  if(pickData.id !== this.pickId) {
    return null
  }

  var cellId    = pickData.value[0] + 256*pickData.value[1] + 65536*pickData.value[2]
  var cell      = this.cells[cellId]
  var positions = this.positions

  var simplex   = new Array(cell.length)
  for(var i=0; i tickOffset[start]) {
        shader.uniforms.dataAxis     = DATA_AXIS
        shader.uniforms.screenOffset = SCREEN_OFFSET
        shader.uniforms.color        = textColor[axis]
        shader.uniforms.angle        = textAngle[axis]
        gl.drawArrays(
          gl.TRIANGLES,
          tickOffset[start],
          tickOffset[end] - tickOffset[start])
      }
    }
    if(labelEnable[axis] && labelCount) {
      SCREEN_OFFSET[axis^1] -= screenScale * pixelRatio * labelPad[axis]
      shader.uniforms.dataAxis     = ZERO_2
      shader.uniforms.screenOffset = SCREEN_OFFSET
      shader.uniforms.color        = labelColor[axis]
      shader.uniforms.angle        = labelAngle[axis]
      gl.drawArrays(
        gl.TRIANGLES,
        labelOffset,
        labelCount)
    }

    SCREEN_OFFSET[axis^1] = screenScale * viewBox[2+(axis^1)] - 1.0
    if(tickEnable[axis+2]) {
      SCREEN_OFFSET[axis^1] += screenScale * pixelRatio * tickPad[axis+2]
      if(start < end && tickOffset[end] > tickOffset[start]) {
        shader.uniforms.dataAxis     = DATA_AXIS
        shader.uniforms.screenOffset = SCREEN_OFFSET
        shader.uniforms.color        = textColor[axis+2]
        shader.uniforms.angle        = textAngle[axis+2]
        gl.drawArrays(
          gl.TRIANGLES,
          tickOffset[start],
          tickOffset[end] - tickOffset[start])
      }
    }
    if(labelEnable[axis+2] && labelCount) {
      SCREEN_OFFSET[axis^1] += screenScale * pixelRatio * labelPad[axis+2]
      shader.uniforms.dataAxis     = ZERO_2
      shader.uniforms.screenOffset = SCREEN_OFFSET
      shader.uniforms.color        = labelColor[axis+2]
      shader.uniforms.angle        = labelAngle[axis+2]
      gl.drawArrays(
        gl.TRIANGLES,
        labelOffset,
        labelCount)
    }

  }
})()

proto.drawTitle = (function() {
  var DATA_AXIS = [0,0]
  var SCREEN_OFFSET = [0,0]

  return function() {
    var plot        = this.plot
    var shader      = this.shader
    var gl          = plot.gl
    var screenBox   = plot.screenBox
    var titleCenter = plot.titleCenter
    var titleAngle  = plot.titleAngle
    var titleColor  = plot.titleColor
    var pixelRatio  = plot.pixelRatio

    if(!this.titleCount) {
      return
    }

    for(var i=0; i<2; ++i) {
      SCREEN_OFFSET[i] = 2.0 * (titleCenter[i]*pixelRatio - screenBox[i]) /
        (screenBox[2+i] - screenBox[i]) - 1
    }

    shader.bind()
    shader.uniforms.dataAxis      = DATA_AXIS
    shader.uniforms.screenOffset  = SCREEN_OFFSET
    shader.uniforms.angle         = titleAngle
    shader.uniforms.color         = titleColor

    gl.drawArrays(gl.TRIANGLES, this.titleOffset, this.titleCount)
  }
})()

proto.bind = (function() {
  var DATA_SHIFT = [0,0]
  var DATA_SCALE = [0,0]
  var TEXT_SCALE = [0,0]

  return function() {
    var plot      = this.plot
    var shader    = this.shader
    var bounds    = plot._tickBounds
    var dataBox   = plot.dataBox
    var screenBox = plot.screenBox
    var viewBox   = plot.viewBox

    shader.bind()

    //Set up coordinate scaling uniforms
    for(var i=0; i<2; ++i) {

      var lo = bounds[i]
      var hi = bounds[i+2]
      var boundScale = hi - lo
      var dataCenter  = 0.5 * (dataBox[i+2] + dataBox[i])
      var dataWidth   = (dataBox[i+2] - dataBox[i])

      var viewLo = viewBox[i]
      var viewHi = viewBox[i+2]
      var viewScale = viewHi - viewLo
      var screenLo = screenBox[i]
      var screenHi = screenBox[i+2]
      var screenScale = screenHi - screenLo

      DATA_SCALE[i] = 2.0 * boundScale / dataWidth * viewScale / screenScale
      DATA_SHIFT[i] = 2.0 * (lo - dataCenter) / dataWidth * viewScale / screenScale
    }

    TEXT_SCALE[1] = 2.0 * plot.pixelRatio / (screenBox[3] - screenBox[1])
    TEXT_SCALE[0] = TEXT_SCALE[1] * (screenBox[3] - screenBox[1]) / (screenBox[2] - screenBox[0])

    shader.uniforms.dataScale = DATA_SCALE
    shader.uniforms.dataShift = DATA_SHIFT
    shader.uniforms.textScale = TEXT_SCALE

    //Set attributes
    this.vbo.bind()
    shader.attributes.textCoordinate.pointer()
  }
})()

proto.update = function(options) {
  var vertices  = []
  var axesTicks = options.ticks
  var bounds    = options.bounds
  var i, j, k, data, scale, dimension

  for(dimension=0; dimension<2; ++dimension) {
    var offsets = [Math.floor(vertices.length/3)], tickX = [-Infinity]

    //Copy vertices over to buffer
    var ticks = axesTicks[dimension]
    for(i=0; i= 0)) {
        continue
      }

      var zeroIntercept = screenBox[i] -
        dataBox[i] * (screenBox[i+2] - screenBox[i]) / (dataBox[i+2] - dataBox[i])

      if(i === 0) {
        line.drawLine(
          zeroIntercept, screenBox[1], zeroIntercept, screenBox[3],
          zeroLineWidth[i],
          zeroLineColor[i])
      } else {
        line.drawLine(
          screenBox[0], zeroIntercept, screenBox[2], zeroIntercept,
          zeroLineWidth[i],
          zeroLineColor[i])
      }
    }
  }

  //Draw traces
  for(var i=0; i=0; --i) {
    this.objects[i].dispose()
  }
  this.objects.length = 0
  for(var i=this.overlays.length-1; i>=0; --i) {
    this.overlays[i].dispose()
  }
  this.overlays.length = 0

  this.gl = null
}

proto.addObject = function(object) {
  if(this.objects.indexOf(object) < 0) {
    this.objects.push(object)
    this.setDirty()
  }
}

proto.removeObject = function(object) {
  var objects = this.objects
  for(var i=0; i Math.abs(dy)) {
        view.rotate(t, 0, 0, -dx * flipX * Math.PI * camera.rotateSpeed / window.innerWidth)
      } else {
        if(!camera._ortho) {
          var kzoom = -camera.zoomSpeed * flipY * dy / window.innerHeight * (t - view.lastT()) / 20.0
          view.pan(t, 0, 0, distance * (Math.exp(kzoom) - 1))
        }
      }
    }, true)
  }

  camera.enableMouseListeners()

  return camera
}


/***/ }),

/***/ 799:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

var glslify      = __webpack_require__(3236)
var createShader = __webpack_require__(9405)

var vertSrc = glslify(["precision mediump float;\n#define GLSLIFY 1\nattribute vec2 position;\nvarying vec2 uv;\nvoid main() {\n  uv = position;\n  gl_Position = vec4(position, 0, 1);\n}"])
var fragSrc = glslify(["precision mediump float;\n#define GLSLIFY 1\n\nuniform sampler2D accumBuffer;\nvarying vec2 uv;\n\nvoid main() {\n  vec4 accum = texture2D(accumBuffer, 0.5 * (uv + 1.0));\n  gl_FragColor = min(vec4(1,1,1,1), accum);\n}"])

module.exports = function(gl) {
  return createShader(gl, vertSrc, fragSrc, null, [ { name: 'position', type: 'vec2'}])
}


/***/ }),

/***/ 4100:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

"use strict";


var createCamera = __webpack_require__(4437)
var createAxes   = __webpack_require__(3837)
var axesRanges   = __webpack_require__(5445)
var createSpikes = __webpack_require__(4449)
var createSelect = __webpack_require__(3589)
var createFBO    = __webpack_require__(2260)
var drawTriangle = __webpack_require__(7169)
var mouseChange  = __webpack_require__(351)
var perspective  = __webpack_require__(4772)
var ortho        = __webpack_require__(4040)
var createShader = __webpack_require__(799)
var isMobile = __webpack_require__(9216)({ tablet: true, featureDetect: true })

module.exports = {
  createScene: createScene,
  createCamera: createCamera
}

function MouseSelect() {
  this.mouse          = [-1,-1]
  this.screen         = null
  this.distance       = Infinity
  this.index          = null
  this.dataCoordinate = null
  this.dataPosition   = null
  this.object         = null
  this.data           = null
}

function getContext(canvas, options) {
  var gl = null
  try {
    gl = canvas.getContext('webgl', options)
    if(!gl) {
      gl = canvas.getContext('experimental-webgl', options)
    }
  } catch(e) {
    return null
  }
  return gl
}

function roundUpPow10(x) {
  var y = Math.round(Math.log(Math.abs(x)) / Math.log(10))
  if(y < 0) {
    var base = Math.round(Math.pow(10, -y))
    return Math.ceil(x*base) / base
  } else if(y > 0) {
    var base = Math.round(Math.pow(10, y))
    return Math.ceil(x/base) * base
  }
  return Math.ceil(x)
}

function defaultBool(x) {
  if(typeof x === 'boolean') {
    return x
  }
  return true
}

function createScene(options) {
  options = options || {}
  options.camera = options.camera || {}

  var canvas = options.canvas
  if(!canvas) {
    canvas = document.createElement('canvas')
    if(options.container) {
      var container = options.container
      container.appendChild(canvas)
    } else {
      document.body.appendChild(canvas)
    }
  }

  var gl = options.gl
  if(!gl) {
    if(options.glOptions) {
      isMobile = !!options.glOptions.preserveDrawingBuffer
    }

    gl = getContext(canvas,
      options.glOptions || {
        premultipliedAlpha: true,
        antialias: true,
        preserveDrawingBuffer: isMobile
      })
  }
  if(!gl) {
    throw new Error('webgl not supported')
  }

  //Initial bounds
  var bounds = options.bounds || [[-10,-10,-10], [10,10,10]]

  //Create selection
  var selection = new MouseSelect()

  //Accumulation buffer
  var accumBuffer = createFBO(gl,
    gl.drawingBufferWidth, gl.drawingBufferHeight, {
      preferFloat: !isMobile
    })

  var accumShader = createShader(gl)

  var isOrtho =
    (options.cameraObject && options.cameraObject._ortho === true) ||
    (options.camera.projection && options.camera.projection.type === 'orthographic') ||
    false

  //Create a camera
  var cameraOptions = {
    eye:     options.camera.eye     || [2,0,0],
    center:  options.camera.center  || [0,0,0],
    up:      options.camera.up      || [0,1,0],
    zoomMin: options.camera.zoomMax || 0.1,
    zoomMax: options.camera.zoomMin || 100,
    mode:    options.camera.mode    || 'turntable',
    _ortho:  isOrtho
  }

  //Create axes
  var axesOptions = options.axes || {}
  var axes = createAxes(gl, axesOptions)
  axes.enable = !axesOptions.disable

  //Create spikes
  var spikeOptions = options.spikes || {}
  var spikes = createSpikes(gl, spikeOptions)

  //Object list is empty initially
  var objects         = []
  var pickBufferIds   = []
  var pickBufferCount = []
  var pickBuffers     = []

  //Dirty flag, skip redraw if scene static
  var dirty       = true
  var pickDirty   = true

  var projection     = new Array(16)
  var model          = new Array(16)

  var cameraParams = {
    view:         null,
    projection:   projection,
    model:        model,
    _ortho:       false
  }

  var pickDirty = true

  var viewShape = [ gl.drawingBufferWidth, gl.drawingBufferHeight ]

  var camera = options.cameraObject || createCamera(canvas, cameraOptions)

  //Create scene object
  var scene = {
    gl:           gl,
    contextLost:  false,
    pixelRatio:   options.pixelRatio || 1,
    canvas:       canvas,
    selection:    selection,
    camera:       camera,
    axes:         axes,
    axesPixels:   null,
    spikes:       spikes,
    bounds:       bounds,
    objects:      objects,
    shape:        viewShape,
    aspect:       options.aspectRatio || [1,1,1],
    pickRadius:   options.pickRadius || 10,
    zNear:        options.zNear || 0.01,
    zFar:         options.zFar  || 1000,
    fovy:         options.fovy  || Math.PI/4,
    clearColor:   options.clearColor || [0,0,0,0],
    autoResize:   defaultBool(options.autoResize),
    autoBounds:   defaultBool(options.autoBounds),
    autoScale:    !!options.autoScale,
    autoCenter:   defaultBool(options.autoCenter),
    clipToBounds: defaultBool(options.clipToBounds),
    snapToData:   !!options.snapToData,
    onselect:     options.onselect || null,
    onrender:     options.onrender || null,
    onclick:      options.onclick  || null,
    cameraParams: cameraParams,
    oncontextloss: null,
    mouseListener: null,
    _stopped: false,

    getAspectratio: function() {
      return {
        x: this.aspect[0],
        y: this.aspect[1],
        z: this.aspect[2]
      }
    },

    setAspectratio: function(aspectratio) {
      this.aspect[0] = aspectratio.x
      this.aspect[1] = aspectratio.y
      this.aspect[2] = aspectratio.z
      pickDirty = true
    },

    setBounds: function(axisIndex, range) {
      this.bounds[0][axisIndex] = range.min
      this.bounds[1][axisIndex] = range.max
    },

    setClearColor: function(clearColor) {
      this.clearColor = clearColor
    },

    clearRGBA: function() {
      this.gl.clearColor(
        this.clearColor[0],
        this.clearColor[1],
        this.clearColor[2],
        this.clearColor[3]
      )

      this.gl.clear(
        this.gl.COLOR_BUFFER_BIT |
        this.gl.DEPTH_BUFFER_BIT
      )
    }
  }

  var pickShape = [ (gl.drawingBufferWidth/scene.pixelRatio)|0, (gl.drawingBufferHeight/scene.pixelRatio)|0 ]

  function resizeListener() {
    if(scene._stopped) {
      return
    }
    if(!scene.autoResize) {
      return
    }
    var parent = canvas.parentNode
    var width  = 1
    var height = 1
    if(parent && parent !== document.body) {
      width  = parent.clientWidth
      height = parent.clientHeight
    } else {
      width  = window.innerWidth
      height = window.innerHeight
    }
    var nextWidth  = Math.ceil(width  * scene.pixelRatio)|0
    var nextHeight = Math.ceil(height * scene.pixelRatio)|0
    if(nextWidth !== canvas.width || nextHeight !== canvas.height) {
      canvas.width   = nextWidth
      canvas.height  = nextHeight
      var style = canvas.style
      style.position = style.position || 'absolute'
      style.left     = '0px'
      style.top      = '0px'
      style.width    = width  + 'px'
      style.height   = height + 'px'
      dirty = true
    }
  }
  if(scene.autoResize) {
    resizeListener()
  }
  window.addEventListener('resize', resizeListener)

  function reallocPickIds() {
    var numObjs = objects.length
    var numPick = pickBuffers.length
    for(var i=0; i 0 && pickBufferCount[numPick-1] === 0) {
      pickBufferCount.pop()
      pickBuffers.pop().dispose()
    }
  }

  scene.update = function(options) {

    if(scene._stopped) {
      return
    }
    options = options || {}
    dirty = true
    pickDirty = true
  }

  scene.add = function(obj) {
    if(scene._stopped) {
      return
    }
    obj.axes = axes
    objects.push(obj)
    pickBufferIds.push(-1)
    dirty = true
    pickDirty = true
    reallocPickIds()
  }

  scene.remove = function(obj) {
    if(scene._stopped) {
      return
    }
    var idx = objects.indexOf(obj)
    if(idx < 0) {
      return
    }
    objects.splice(idx, 1)
    pickBufferIds.pop()
    dirty = true
    pickDirty = true
    reallocPickIds()
  }

  scene.dispose = function() {
    if(scene._stopped) {
      return
    }

    scene._stopped = true

    window.removeEventListener('resize', resizeListener)
    canvas.removeEventListener('webglcontextlost', checkContextLoss)
    scene.mouseListener.enabled = false

    if(scene.contextLost) {
      return
    }

    //Destroy objects
    axes.dispose()
    spikes.dispose()
    for(var i=0; i selection.distance) {
              continue
            }
            for(var j=0; j 1.0) {\n      discard;\n    }\n    baseColor = mix(borderColor, color, step(radius, centerFraction));\n    gl_FragColor = vec4(baseColor.rgb * baseColor.a, baseColor.a);\n  }\n}\n"])
exports.pickVertex        = glslify(["precision mediump float;\n#define GLSLIFY 1\n\nattribute vec2 position;\nattribute vec4 pickId;\n\nuniform mat3 matrix;\nuniform float pointSize;\nuniform vec4 pickOffset;\n\nvarying vec4 fragId;\n\nvoid main() {\n  vec3 hgPosition = matrix * vec3(position, 1);\n  gl_Position  = vec4(hgPosition.xy, 0, hgPosition.z);\n  gl_PointSize = pointSize;\n\n  vec4 id = pickId + pickOffset;\n  id.y += floor(id.x / 256.0);\n  id.x -= floor(id.x / 256.0) * 256.0;\n\n  id.z += floor(id.y / 256.0);\n  id.y -= floor(id.y / 256.0) * 256.0;\n\n  id.w += floor(id.z / 256.0);\n  id.z -= floor(id.z / 256.0) * 256.0;\n\n  fragId = id;\n}\n"])
exports.pickFragment      = glslify(["precision mediump float;\n#define GLSLIFY 1\n\nvarying vec4 fragId;\n\nvoid main() {\n  float radius = length(2.0 * gl_PointCoord.xy - 1.0);\n  if(radius > 1.0) {\n    discard;\n  }\n  gl_FragColor = fragId / 255.0;\n}\n"])


/***/ }),

/***/ 4696:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

"use strict";


var createShader = __webpack_require__(9405)
var createBuffer = __webpack_require__(2762)

var pool = __webpack_require__(1888)

var SHADERS = __webpack_require__(6640)

module.exports = createPointcloud2D

function Pointcloud2D(plot, offsetBuffer, pickBuffer, shader, pickShader) {
  this.plot           = plot
  this.offsetBuffer   = offsetBuffer
  this.pickBuffer     = pickBuffer
  this.shader         = shader
  this.pickShader     = pickShader
  this.sizeMin        = 0.5
  this.sizeMinCap     = 2
  this.sizeMax        = 20
  this.areaRatio      = 1.0
  this.pointCount     = 0
  this.color          = [1, 0, 0, 1]
  this.borderColor    = [0, 0, 0, 1]
  this.blend          = false
  this.pickOffset     = 0
  this.points         = null
}

var proto = Pointcloud2D.prototype

proto.dispose = function() {
  this.shader.dispose()
  this.pickShader.dispose()
  this.offsetBuffer.dispose()
  this.pickBuffer.dispose()
  this.plot.removeObject(this)
}

proto.update = function(options) {

  var i

  options = options || {}

  function dflt(opt, value) {
    if(opt in options) {
      return options[opt]
    }
    return value
  }

  this.sizeMin      = dflt('sizeMin', 0.5)
  // this.sizeMinCap      = dflt('sizeMinCap', 2)
  this.sizeMax      = dflt('sizeMax', 20)
  this.color        = dflt('color', [1, 0, 0, 1]).slice()
  this.areaRatio    = dflt('areaRatio', 1)
  this.borderColor  = dflt('borderColor', [0, 0, 0, 1]).slice()
  this.blend        = dflt('blend', false)

  //Update point data

  // Attempt straight-through processing (STP) to avoid allocation and copy
  // TODO eventually abstract out STP logic, maybe into `pool` or a layer above
  var pointCount = options.positions.length >>> 1
  var dataStraightThrough = options.positions instanceof Float32Array
  var idStraightThrough = options.idToIndex instanceof Int32Array && options.idToIndex.length >= pointCount // permit larger to help reuse

  var data          = options.positions
  var packed        = dataStraightThrough ? data : pool.mallocFloat32(data.length)
  var packedId      = idStraightThrough ? options.idToIndex : pool.mallocInt32(pointCount)

  if(!dataStraightThrough) {
    packed.set(data)
  }

  if(!idStraightThrough) {
    packed.set(data)
    for(i = 0; i < pointCount; i++) {
      packedId[i] = i
    }
  }

  this.points       = data

  this.offsetBuffer.update(packed)
  this.pickBuffer.update(packedId)

  if(!dataStraightThrough) {
    pool.free(packed)
  }

  if(!idStraightThrough) {
    pool.free(packedId)
  }

  this.pointCount = pointCount
  this.pickOffset = 0
}

function count(points, dataBox) {
  var visiblePointCountEstimate = 0
  var length = points.length >>> 1
  var i
  for(i = 0; i < length; i++) {
    var x = points[i * 2]
    var y = points[i * 2 + 1]
    if(x >= dataBox[0] && x <= dataBox[2] && y >= dataBox[1] && y <= dataBox[3])
      visiblePointCountEstimate++
  }
  return visiblePointCountEstimate
}

proto.unifiedDraw = (function() {
  var MATRIX = [1, 0, 0,
                0, 1, 0,
                0, 0, 1]
  var PICK_VEC4 = [0, 0, 0, 0]
return function(pickOffset) {
  var pick = pickOffset !== void(0)

  var shader        = pick ? this.pickShader : this.shader
  var gl            = this.plot.gl
  var dataBox       = this.plot.dataBox

  if(this.pointCount === 0) {
    return pickOffset
  }

  var dataX   = dataBox[2] - dataBox[0]
  var dataY   = dataBox[3] - dataBox[1]

  var visiblePointCountEstimate = count(this.points, dataBox)
  var basicPointSize =  this.plot.pickPixelRatio * Math.max(Math.min(this.sizeMinCap, this.sizeMin), Math.min(this.sizeMax, this.sizeMax / Math.pow(visiblePointCountEstimate, 0.33333)))

  MATRIX[0] = 2.0 / dataX
  MATRIX[4] = 2.0 / dataY
  MATRIX[6] = -2.0 * dataBox[0] / dataX - 1.0
  MATRIX[7] = -2.0 * dataBox[1] / dataY - 1.0

  this.offsetBuffer.bind()

  shader.bind()
  shader.attributes.position.pointer()
  shader.uniforms.matrix      = MATRIX
  shader.uniforms.color       = this.color
  shader.uniforms.borderColor = this.borderColor
  shader.uniforms.pointCloud = basicPointSize < 5
  shader.uniforms.pointSize = basicPointSize
  shader.uniforms.centerFraction = Math.min(1, Math.max(0, Math.sqrt(1 - this.areaRatio)))

  if(pick) {

    PICK_VEC4[0] = ( pickOffset        & 0xff)
    PICK_VEC4[1] = ((pickOffset >> 8)  & 0xff)
    PICK_VEC4[2] = ((pickOffset >> 16) & 0xff)
    PICK_VEC4[3] = ((pickOffset >> 24) & 0xff)

    this.pickBuffer.bind()
    shader.attributes.pickId.pointer(gl.UNSIGNED_BYTE)
    shader.uniforms.pickOffset = PICK_VEC4
    this.pickOffset = pickOffset
  }

  // Worth switching these off, but we can't make assumptions about other
  // renderers, so let's restore it after each draw
  var blend = gl.getParameter(gl.BLEND)
  var dither = gl.getParameter(gl.DITHER)

  if(blend && !this.blend)
    gl.disable(gl.BLEND)
  if(dither)
    gl.disable(gl.DITHER)

  gl.drawArrays(gl.POINTS, 0, this.pointCount)

  if(blend && !this.blend)
    gl.enable(gl.BLEND)
  if(dither)
    gl.enable(gl.DITHER)

  return pickOffset + this.pointCount
}
})()

proto.draw = proto.unifiedDraw
proto.drawPick = proto.unifiedDraw

proto.pick = function(x, y, value) {
  var pickOffset = this.pickOffset
  var pointCount = this.pointCount
  if(value < pickOffset || value >= pickOffset + pointCount) {
    return null
  }
  var pointId = value - pickOffset
  var points = this.points
  return {
    object: this,
    pointId: pointId,
    dataCoord: [points[2 * pointId], points[2 * pointId + 1] ]
  }
}

function createPointcloud2D(plot, options) {
  var gl = plot.gl
  var buffer = createBuffer(gl)
  var pickBuffer = createBuffer(gl)
  var shader = createShader(gl, SHADERS.pointVertex, SHADERS.pointFragment)
  var pickShader = createShader(gl, SHADERS.pickVertex, SHADERS.pickFragment)

  var result = new Pointcloud2D(plot, buffer, pickBuffer, shader, pickShader)
  result.update(options)

  //Register with plot
  plot.addObject(result)

  return result
}


/***/ }),

/***/ 783:
/***/ (function(module) {

module.exports = slerp

/**
 * Performs a spherical linear interpolation between two quat
 *
 * @param {quat} out the receiving quaternion
 * @param {quat} a the first operand
 * @param {quat} b the second operand
 * @param {Number} t interpolation amount between the two inputs
 * @returns {quat} out
 */
function slerp (out, a, b, t) {
  // benchmarks:
  //    http://jsperf.com/quaternion-slerp-implementations

  var ax = a[0], ay = a[1], az = a[2], aw = a[3],
    bx = b[0], by = b[1], bz = b[2], bw = b[3]

  var omega, cosom, sinom, scale0, scale1

  // calc cosine
  cosom = ax * bx + ay * by + az * bz + aw * bw
  // adjust signs (if necessary)
  if (cosom < 0.0) {
    cosom = -cosom
    bx = -bx
    by = -by
    bz = -bz
    bw = -bw
  }
  // calculate coefficients
  if ((1.0 - cosom) > 0.000001) {
    // standard case (slerp)
    omega = Math.acos(cosom)
    sinom = Math.sin(omega)
    scale0 = Math.sin((1.0 - t) * omega) / sinom
    scale1 = Math.sin(t * omega) / sinom
  } else {
    // "from" and "to" quaternions are very close
    //  ... so we can do a linear interpolation
    scale0 = 1.0 - t
    scale1 = t
  }
  // calculate final values
  out[0] = scale0 * ax + scale1 * bx
  out[1] = scale0 * ay + scale1 * by
  out[2] = scale0 * az + scale1 * bz
  out[3] = scale0 * aw + scale1 * bw

  return out
}


/***/ }),

/***/ 5964:
/***/ (function(module) {

"use strict";


module.exports = function(a){
  return (!a && a !== 0) ? '' : a.toString();
}


/***/ }),

/***/ 9366:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

"use strict";


var vectorizeText = __webpack_require__(4359)

module.exports = getGlyph

var GLYPH_CACHE = {}

function getGlyph(symbol, font, pixelRatio) {
  var fontKey = [
    font.style,
    font.weight,
    font.variant,
    font.family
  ].join('_')

  var fontCache = GLYPH_CACHE[fontKey]
  if(!fontCache) {
    fontCache = GLYPH_CACHE[fontKey] = {}
  }
  if(symbol in fontCache) {
    return fontCache[symbol]
  }

  var config = {
    textAlign: "center",
    textBaseline: "middle",
    lineHeight: 1.0,
    font: font.family,
    fontStyle: font.style,
    fontWeight: font.weight,
    fontVariant: font.variant,
    lineSpacing: 1.25,
    styletags: {
      breaklines:true,
      bolds: true,
      italics: true,
      subscripts:true,
      superscripts:true
    }
  }

  //Get line and triangle meshes for glyph
  config.triangles = true
  var triSymbol = vectorizeText(symbol, config)
  config.triangles = false
  var lineSymbol = vectorizeText(symbol, config)

  var i, j

  if(pixelRatio && pixelRatio !== 1) {
    for(i = 0; i < triSymbol.positions.length; ++i){
      for(j = 0; j < triSymbol.positions[i].length; ++j){
        triSymbol.positions[i][j] /= pixelRatio;
      }
    }

    for(i = 0; i < lineSymbol.positions.length; ++i){
      for(j = 0; j < lineSymbol.positions[i].length; ++j){
        lineSymbol.positions[i][j] /= pixelRatio;
      }
    }
  }

  //Calculate bounding box
  var bounds = [[Infinity,Infinity], [-Infinity,-Infinity]]
  var n = lineSymbol.positions.length
  for(i = 0; i < n; ++i) {
    var p = lineSymbol.positions[i]
    for(j=0; j<2; ++j) {
      bounds[0][j] = Math.min(bounds[0][j], p[j])
      bounds[1][j] = Math.max(bounds[1][j], p[j])
    }
  }

  //Save cached symbol
  return fontCache[symbol] = [triSymbol, lineSymbol, bounds]
}

/***/ }),

/***/ 1283:
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {

var createShaderWrapper = __webpack_require__(9405)
var glslify = __webpack_require__(3236)

var perspectiveVertSrc = glslify(["precision highp float;\n#define GLSLIFY 1\n\nbool outOfRange(float a, float b, float p) {\n  return ((p > max(a, b)) || \n          (p < min(a, b)));\n}\n\nbool outOfRange(vec2 a, vec2 b, vec2 p) {\n  return (outOfRange(a.x, b.x, p.x) ||\n          outOfRange(a.y, b.y, p.y));\n}\n\nbool outOfRange(vec3 a, vec3 b, vec3 p) {\n  return (outOfRange(a.x, b.x, p.x) ||\n          outOfRange(a.y, b.y, p.y) ||\n          outOfRange(a.z, b.z, p.z));\n}\n\nbool outOfRange(vec4 a, vec4 b, vec4 p) {\n  return outOfRange(a.xyz, b.xyz, p.xyz);\n}\n\nattribute vec3 position;\nattribute vec4 color;\nattribute vec2 glyph;\nattribute vec4 id;\n\nuniform vec4 highlightId;\nuniform float highlightScale;\nuniform mat4 model, view, projection;\nuniform vec3 clipBounds[2];\n\nvarying vec4 interpColor;\nvarying vec4 pickId;\nvarying vec3 dataCoordinate;\n\nvoid main() {\n  if (outOfRange(clipBounds[0], clipBounds[1], position)) {\n\n    gl_Position = vec4(0,0,0,0);\n  } else {\n    float scale = 1.0;\n    if(distance(highlightId, id) < 0.0001) {\n      scale = highlightScale;\n    }\n\n    vec4 worldPosition = model * vec4(position, 1);\n    vec4 viewPosition = view * worldPosition;\n    viewPosition = viewPosition / viewPosition.w;\n    vec4 clipPosition = projection * (viewPosition + scale * vec4(glyph.x, -glyph.y, 0, 0));\n\n    gl_Position = clipPosition;\n    interpColor = color;\n    pickId = id;\n    dataCoordinate = position;\n  }\n}"])
var orthographicVertSrc = glslify(["precision highp float;\n#define GLSLIFY 1\n\nbool outOfRange(float a, float b, float p) {\n  return ((p > max(a, b)) || \n          (p < min(a, b)));\n}\n\nbool outOfRange(vec2 a, vec2 b, vec2 p) {\n  return (outOfRange(a.x, b.x, p.x) ||\n          outOfRange(a.y, b.y, p.y));\n}\n\nbool outOfRange(vec3 a, vec3 b, vec3 p) {\n  return (outOfRange(a.x, b.x, p.x) ||\n          outOfRange(a.y, b.y, p.y) ||\n          outOfRange(a.z, b.z, p.z));\n}\n\nbool outOfRange(vec4 a, vec4 b, vec4 p) {\n  return outOfRange(a.xyz, b.xyz, p.xyz);\n}\n\nattribute vec3 position;\nattribute vec4 color;\nattribute vec2 glyph;\nattribute vec4 id;\n\nuniform mat4 model, view, projection;\nuniform vec2 screenSize;\nuniform vec3 clipBounds[2];\nuniform float highlightScale, pixelRatio;\nuniform vec4 highlightId;\n\nvarying vec4 interpColor;\nvarying vec4 pickId;\nvarying vec3 dataCoordinate;\n\nvoid main() {\n  if (outOfRange(clipBounds[0], clipBounds[1], position)) {\n\n    gl_Position = vec4(0,0,0,0);\n  } else {\n    float scale = pixelRatio;\n    if(distance(highlightId.bgr, id.bgr) < 0.001) {\n      scale *= highlightScale;\n    }\n\n    vec4 worldPosition = model * vec4(position, 1.0);\n    vec4 viewPosition = view * worldPosition;\n    vec4 clipPosition = projection * viewPosition;\n    clipPosition /= clipPosition.w;\n\n    gl_Position = clipPosition + vec4(screenSize * scale * vec2(glyph.x, -glyph.y), 0.0, 0.0);\n    interpColor = color;\n    pickId = id;\n    dataCoordinate = position;\n  }\n}"])
var projectionVertSrc = glslify(["precision highp float;\n#define GLSLIFY 1\n\nbool outOfRange(float a, float b, float p) {\n  return ((p > max(a, b)) || \n          (p < min(a, b)));\n}\n\nbool outOfRange(vec2 a, vec2 b, vec2 p) {\n  return (outOfRange(a.x, b.x, p.x) ||\n          outOfRange(a.y, b.y, p.y));\n}\n\nbool outOfRange(vec3 a, vec3 b, vec3 p) {\n  return (outOfRange(a.x, b.x, p.x) ||\n          outOfRange(a.y, b.y, p.y) ||\n          outOfRange(a.z, b.z, p.z));\n}\n\nbool outOfRange(vec4 a, vec4 b, vec4 p) {\n  return outOfRange(a.xyz, b.xyz, p.xyz);\n}\n\nattribute vec3 position;\nattribute vec4 color;\nattribute vec2 glyph;\nattribute vec4 id;\n\nuniform float highlightScale;\nuniform vec4 highlightId;\nuniform vec3 axes[2];\nuniform mat4 model, view, projection;\nuniform vec2 screenSize;\nuniform vec3 clipBounds[2];\nuniform float scale, pixelRatio;\n\nvarying vec4 interpColor;\nvarying vec4 pickId;\nvarying vec3 dataCoordinate;\n\nvoid main() {\n  if (outOfRange(clipBounds[0], clipBounds[1], position)) {\n\n    gl_Position = vec4(0,0,0,0);\n  } else {\n    float lscale = pixelRatio * scale;\n    if(distance(highlightId, id) < 0.0001) {\n      lscale *= highlightScale;\n    }\n\n    vec4 clipCenter   = projection * (view * (model * vec4(position, 1)));\n    vec3 dataPosition = position + 0.5*lscale*(axes[0] * glyph.x + axes[1] * glyph.y) * clipCenter.w * screenSize.y;\n    vec4 clipPosition = projection * (view * (model * vec4(dataPosition, 1)));\n\n    gl_Position = clipPosition;\n    interpColor = color;\n    pickId = id;\n    dataCoordinate = dataPosition;\n  }\n}\n"])
var drawFragSrc = glslify(["precision highp float;\n#define GLSLIFY 1\n\nbool outOfRange(float a, float b, float p) {\n  return ((p > max(a, b)) || \n          (p < min(a, b)));\n}\n\nbool outOfRange(vec2 a, vec2 b, vec2 p) {\n  return (outOfRange(a.x, b.x, p.x) ||\n          outOfRange(a.y, b.y, p.y));\n}\n\nbool outOfRange(vec3 a, vec3 b, vec3 p) {\n  return (outOfRange(a.x, b.x, p.x) ||\n          outOfRange(a.y, b.y, p.y) ||\n          outOfRange(a.z, b.z, p.z));\n}\n\nbool outOfRange(vec4 a, vec4 b, vec4 p) {\n  return outOfRange(a.xyz, b.xyz, p.xyz);\n}\n\nuniform vec3 fragClipBounds[2];\nuniform float opacity;\n\nvarying vec4 interpColor;\nvarying vec3 dataCoordinate;\n\nvoid main() {\n  if (\n    outOfRange(fragClipBounds[0], fragClipBounds[1], dataCoordinate) ||\n    interpColor.a * opacity == 0.\n  ) discard;\n  gl_FragColor = interpColor * opacity;\n}\n"])
var pickFragSrc = glslify(["precision highp float;\n#define GLSLIFY 1\n\nbool outOfRange(float a, float b, float p) {\n  return ((p > max(a, b)) || \n          (p < min(a, b)));\n}\n\nbool outOfRange(vec2 a, vec2 b, vec2 p) {\n  return (outOfRange(a.x, b.x, p.x) ||\n          outOfRange(a.y, b.y, p.y));\n}\n\nbool outOfRange(vec3 a, vec3 b, vec3 p) {\n  return (outOfRange(a.x, b.x, p.x) ||\n          outOfRange(a.y, b.y, p.y) ||\n          outOfRange(a.z, b.z, p.z));\n}\n\nbool outOfRange(vec4 a, vec4 b, vec4 p) {\n  return outOfRange(a.xyz, b.xyz, p.xyz);\n}\n\nuniform vec3 fragClipBounds[2];\nuniform float pickGroup;\n\nvarying vec4 pickId;\nvarying vec3 dataCoordinate;\n\nvoid main() {\n  if (outOfRange(fragClipBounds[0], fragClipBounds[1], dataCoordinate)) discard;\n\n  gl_FragColor = vec4(pickGroup, pickId.bgr);\n}"])

var ATTRIBUTES = [
  {name: 'position', type: 'vec3'},
  {name: 'color', type: 'vec4'},
  {name: 'glyph', type: 'vec2'},
  {name: 'id', type: 'vec4'}
]

var perspective = {
    vertex: perspectiveVertSrc,
    fragment: drawFragSrc,
    attributes: ATTRIBUTES
  },
  ortho = {
    vertex: orthographicVertSrc,
    fragment: drawFragSrc,
    attributes: ATTRIBUTES
  },
  project = {
    vertex: projectionVertSrc,
    fragment: drawFragSrc,
    attributes: ATTRIBUTES
  },
  pickPerspective = {
    vertex: perspectiveVertSrc,
    fragment: pickFragSrc,
    attributes: ATTRIBUTES
  },
  pickOrtho = {
    vertex: orthographicVertSrc,
    fragment: pickFragSrc,
    attributes: ATTRIBUTES
  },
  pickProject = {
    vertex: projectionVertSrc,
    fragment: pickFragSrc,
    attributes: ATTRIBUTES
  }

function createShader(gl, src) {
  var shader = createShaderWrapper(gl, src)
  var attr = shader.attributes
  attr.position.location = 0
  attr.color.location = 1
  attr.glyph.location = 2
  attr.id.location = 3
  return shader
}

exports.createPerspective = function(gl) {
  return createShader(gl, perspective)
}
exports.createOrtho = function(gl) {
  return createShader(gl, ortho)
}
exports.createProject = function(gl) {
  return createShader(gl, project)
}
exports.createPickPerspective = function(gl) {
  return createShader(gl, pickPerspective)
}
exports.createPickOrtho = function(gl) {
  return createShader(gl, pickOrtho)
}
exports.createPickProject = function(gl) {
  return createShader(gl, pickProject)
}


/***/ }),

/***/ 8418:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

"use strict";


var isAllBlank      = __webpack_require__(5219)
var createBuffer    = __webpack_require__(2762)
var createVAO       = __webpack_require__(8116)
var pool            = __webpack_require__(1888)
var mat4mult        = __webpack_require__(6760)
var shaders         = __webpack_require__(1283)
var getGlyph        = __webpack_require__(9366)
var getSimpleString = __webpack_require__(5964)

var IDENTITY = [1,0,0,0,
                0,1,0,0,
                0,0,1,0,
                0,0,0,1]

var ab = ArrayBuffer
var dv = DataView

function isTypedArray(a) {
    return ab.isView(a) && !(a instanceof dv)
}

function isArrayOrTypedArray(a) {
    return Array.isArray(a) || isTypedArray(a)
}

module.exports = createPointCloud

function transformMat4(x, m) {
  var x0 = x[0]
  var x1 = x[1]
  var x2 = x[2]
  var x3 = x[3]
  x[0] = m[0] * x0 + m[4] * x1 + m[8]  * x2 + m[12] * x3
  x[1] = m[1] * x0 + m[5] * x1 + m[9]  * x2 + m[13] * x3
  x[2] = m[2] * x0 + m[6] * x1 + m[10] * x2 + m[14] * x3
  x[3] = m[3] * x0 + m[7] * x1 + m[11] * x2 + m[15] * x3
  return x
}

function project(p, v, m, x) {
  transformMat4(x, x, m)
  transformMat4(x, x, v)
  return transformMat4(x, x, p)
}

function ScatterPlotPickResult(index, position) {
  this.index = index
  this.dataCoordinate = this.position = position
}

function fixOpacity(a) {
  if(a === true) return 1
  if(a > 1) return 1
  return a
}

function PointCloud(
  gl,
  shader,
  orthoShader,
  projectShader,
  pointBuffer,
  colorBuffer,
  glyphBuffer,
  idBuffer,
  vao,
  pickPerspectiveShader,
  pickOrthoShader,
  pickProjectShader) {

  this.gl              = gl

  this.pixelRatio      = 1

  this.shader          = shader
  this.orthoShader     = orthoShader
  this.projectShader   = projectShader

  this.pointBuffer     = pointBuffer
  this.colorBuffer     = colorBuffer
  this.glyphBuffer     = glyphBuffer
  this.idBuffer        = idBuffer
  this.vao             = vao
  this.vertexCount     = 0
  this.lineVertexCount = 0

  this.opacity         = 1
  this.hasAlpha        = false

  this.lineWidth       = 0
  this.projectScale    = [2.0/3.0, 2.0/3.0, 2.0/3.0]
  this.projectOpacity  = [1, 1, 1]
  this.projectHasAlpha  = false

  this.pickId                = 0
  this.pickPerspectiveShader = pickPerspectiveShader
  this.pickOrthoShader       = pickOrthoShader
  this.pickProjectShader     = pickProjectShader
  this.points                = []

  this._selectResult = new ScatterPlotPickResult(0, [0,0,0])

  this.useOrtho = true
  this.bounds   = [[ Infinity,Infinity,Infinity],
                   [-Infinity,-Infinity,-Infinity]]

  //Axes projections
  this.axesProject = [ true, true, true ]
  this.axesBounds = [[-Infinity,-Infinity,-Infinity],
                     [ Infinity, Infinity, Infinity]]

  this.highlightId    = [1,1,1,1]
  this.highlightScale = 2

  this.clipBounds = [[-Infinity,-Infinity,-Infinity],
                     [ Infinity, Infinity, Infinity]]

  this.dirty = true
}

var proto = PointCloud.prototype

proto.pickSlots = 1

proto.setPickBase = function(pickBase) {
  this.pickId = pickBase
}

proto.isTransparent = function() {
  if(this.hasAlpha)  {
    return true
  }
  for(var i=0; i<3; ++i) {
    if(this.axesProject[i] && this.projectHasAlpha) {
      return true
    }
  }
  return false
}

proto.isOpaque = function() {
  if(!this.hasAlpha)  {
    return true
  }
  for(var i=0; i<3; ++i) {
    if(this.axesProject[i] && !this.projectHasAlpha) {
      return true
    }
  }
  return false
}

var VIEW_SHAPE = [0,0]
var U_VEC = [0,0,0]
var V_VEC = [0,0,0]
var MU_VEC = [0,0,0,1]
var MV_VEC = [0,0,0,1]
var SCRATCH_MATRIX = IDENTITY.slice()
var SCRATCH_VEC = [0,0,0]
var CLIP_BOUNDS = [[0,0,0], [0,0,0]]

function zeroVec(a) {
  a[0] = a[1] = a[2] = 0
  return a
}

function augment(hg, af) {
  hg[0] = af[0]
  hg[1] = af[1]
  hg[2] = af[2]
  hg[3] = 1
  return hg
}

function setComponent(out, v, i, x) {
  out[0] = v[0]
  out[1] = v[1]
  out[2] = v[2]
  out[i] = x
  return out
}

function getClipBounds(bounds) {
  var result = CLIP_BOUNDS
  for(var i=0; i<2; ++i) {
    for(var j=0; j<3; ++j) {
      result[i][j] = Math.max(Math.min(bounds[i][j], 1e8), -1e8)
    }
  }
  return result
}

function drawProject(shader, points, camera, pixelRatio) {
  var axesProject = points.axesProject

  var gl         = points.gl
  var uniforms   = shader.uniforms
  var model      = camera.model      || IDENTITY
  var view       = camera.view       || IDENTITY
  var projection = camera.projection || IDENTITY
  var bounds     = points.axesBounds
  var clipBounds = getClipBounds(points.clipBounds)

  var cubeAxis
  if(points.axes && points.axes.lastCubeProps) {
    cubeAxis = points.axes.lastCubeProps.axis
  } else {
    cubeAxis = [1,1,1]
  }

  VIEW_SHAPE[0] = 2.0/gl.drawingBufferWidth
  VIEW_SHAPE[1] = 2.0/gl.drawingBufferHeight

  shader.bind()
  uniforms.view           = view
  uniforms.projection     = projection
  uniforms.screenSize     = VIEW_SHAPE
  uniforms.highlightId    = points.highlightId
  uniforms.highlightScale = points.highlightScale
  uniforms.clipBounds     = clipBounds
  uniforms.pickGroup      = points.pickId / 255.0
  uniforms.pixelRatio     = pixelRatio

  for(var i=0; i<3; ++i) {
    if(!axesProject[i]) {
      continue
    }

    uniforms.scale          = points.projectScale[i]
    uniforms.opacity        = points.projectOpacity[i]

    //Project model matrix
    var pmodel = SCRATCH_MATRIX
    for(var j=0; j<16; ++j) {
      pmodel[j] = 0
    }
    for(var j=0; j<4; ++j) {
      pmodel[5*j] = 1
    }
    pmodel[5*i] = 0
    if(cubeAxis[i] < 0) {
      pmodel[12+i] = bounds[0][i]
    } else {
      pmodel[12+i] = bounds[1][i]
    }
    mat4mult(pmodel, model, pmodel)
    uniforms.model = pmodel

    //Compute initial axes
    var u = (i+1)%3
    var v = (i+2)%3
    var du = zeroVec(U_VEC)
    var dv = zeroVec(V_VEC)
    du[u] = 1
    dv[v] = 1

    //Align orientation relative to viewer
    var mdu = project(projection, view, model, augment(MU_VEC, du))
    var mdv = project(projection, view, model, augment(MV_VEC, dv))
    if(Math.abs(mdu[1]) > Math.abs(mdv[1])) {
      var tmp = mdu
      mdu = mdv
      mdv = tmp
      tmp = du
      du = dv
      dv = tmp
      var t = u
      u = v
      v = t
    }
    if(mdu[0] < 0) {
      du[u] = -1
    }
    if(mdv[1] > 0) {
      dv[v] = -1
    }
    var su = 0.0
    var sv = 0.0
    for(var j=0; j<4; ++j) {
      su += Math.pow(model[4*u+j], 2)
      sv += Math.pow(model[4*v+j], 2)
    }
    du[u] /= Math.sqrt(su)
    dv[v] /= Math.sqrt(sv)
    uniforms.axes[0] = du
    uniforms.axes[1] = dv

    //Update fragment clip bounds
    uniforms.fragClipBounds[0] = setComponent(SCRATCH_VEC, clipBounds[0], i, -1e8)
    uniforms.fragClipBounds[1] = setComponent(SCRATCH_VEC, clipBounds[1], i, 1e8)

    points.vao.bind()

    //Draw interior
    points.vao.draw(gl.TRIANGLES, points.vertexCount)

    //Draw edges
    if(points.lineWidth > 0) {
      gl.lineWidth(points.lineWidth * pixelRatio)
      points.vao.draw(gl.LINES, points.lineVertexCount, points.vertexCount)
    }

    points.vao.unbind()
  }
}


var NEG_INFINITY3 = [-1e8, -1e8, -1e8]
var POS_INFINITY3 = [1e8, 1e8, 1e8]
var CLIP_GROUP    = [NEG_INFINITY3, POS_INFINITY3]

function drawFull(shader, pshader, points, camera, pixelRatio, transparent, forceDraw) {
  var gl = points.gl

  if(transparent === points.projectHasAlpha || forceDraw) {
    drawProject(pshader, points, camera, pixelRatio)
  }

  if(transparent === points.hasAlpha || forceDraw) {

    shader.bind()
    var uniforms = shader.uniforms

    uniforms.model      = camera.model      || IDENTITY
    uniforms.view       = camera.view       || IDENTITY
    uniforms.projection = camera.projection || IDENTITY

    VIEW_SHAPE[0]       = 2.0/gl.drawingBufferWidth
    VIEW_SHAPE[1]       = 2.0/gl.drawingBufferHeight
    uniforms.screenSize = VIEW_SHAPE

    uniforms.highlightId    = points.highlightId
    uniforms.highlightScale = points.highlightScale

    uniforms.fragClipBounds = CLIP_GROUP
    uniforms.clipBounds     = points.axes.bounds

    uniforms.opacity    = points.opacity
    uniforms.pickGroup  = points.pickId / 255.0

    uniforms.pixelRatio = pixelRatio

    points.vao.bind()

    //Draw interior
    points.vao.draw(gl.TRIANGLES, points.vertexCount)

    //Draw edges
    if(points.lineWidth > 0) {
      gl.lineWidth(points.lineWidth * pixelRatio)
      points.vao.draw(gl.LINES, points.lineVertexCount, points.vertexCount)
    }

    points.vao.unbind()
  }


}

proto.draw = function(camera) {
  var shader = this.useOrtho ? this.orthoShader : this.shader
  drawFull(shader, this.projectShader, this, camera, this.pixelRatio, false, false)
}

proto.drawTransparent = function(camera) {
  var shader = this.useOrtho ? this.orthoShader : this.shader
  drawFull(shader, this.projectShader, this, camera, this.pixelRatio, true, false)
}

proto.drawPick = function(camera) {
  var shader = this.useOrtho ? this.pickOrthoShader : this.pickPerspectiveShader
  drawFull(shader, this.pickProjectShader, this, camera, 1, true, true)
}

proto.pick = function(selected) {
  if(!selected) {
    return null
  }
  if(selected.id !== this.pickId) {
    return null
  }
  var x = selected.value[2] + (selected.value[1]<<8) + (selected.value[0]<<16)
  if(x >= this.pointCount || x < 0) {
    return null
  }

  //Unpack result
  var coord = this.points[x]
  var result = this._selectResult
  result.index = x
  for(var i=0; i<3; ++i) {
    result.position[i] = result.dataCoordinate[i] = coord[i]
  }
  return result
}

proto.highlight = function(selection) {
  if(!selection) {
    this.highlightId = [1,1,1,1]
  } else {
    var pointId = selection.index
    var a0 =  pointId     &0xff
    var a1 = (pointId>>8) &0xff
    var a2 = (pointId>>16)&0xff
    this.highlightId = [a0/255.0, a1/255.0, a2/255.0, 0]
  }
}

function get_glyphData(glyphs, index, font, pixelRatio) {
  var str

  // use the data if presented in an array
  if(isArrayOrTypedArray(glyphs)) {
    if(index < glyphs.length) {
      str = glyphs[index]
    } else {
      str = undefined
    }
  } else {
    str = glyphs
  }

  str = getSimpleString(str) // this would handle undefined cases

  var visible = true
  if(isAllBlank(str)) {
    str = '▼' // Note: this special character may have minimum number of surfaces
    visible = false
  }

  if(!font) font = {}

  var family = font.family
  if(isArrayOrTypedArray(family)) family = family[index]
  if(!family) family = "normal"

  var weight = font.weight
  if(isArrayOrTypedArray(weight)) weight = weight[index]
  if(!weight) weight = "normal"

  var style = font.style
  if(isArrayOrTypedArray(style)) style = style[index]
  if(!style) style = "normal"

  var variant = font.variant
  if(isArrayOrTypedArray(variant)) variant = variant[index]
  if(!variant) variant = "normal"

  var glyph = getGlyph(str, {
    family: family,
    weight: weight,
    style: style,
    variant: variant,
  }, pixelRatio)


  var glyph = getGlyph(str, font, pixelRatio)

  return { mesh:glyph[0],
          lines:glyph[1],
         bounds:glyph[2],
        visible:visible };
}



proto.update = function(options) {

  options = options || {}

  if('perspective' in options) {
    this.useOrtho = !options.perspective
  }
  if('orthographic' in options) {
    this.useOrtho = !!options.orthographic
  }
  if('lineWidth' in options) {
    this.lineWidth = options.lineWidth
  }
  if('project' in options) {
    if(isArrayOrTypedArray(options.project)) {
      this.axesProject = options.project
    } else {
      var v = !!options.project
      this.axesProject = [v,v,v]
    }
  }
  if('projectScale' in options) {
    if(isArrayOrTypedArray(options.projectScale)) {
      this.projectScale = options.projectScale.slice()
    } else {
      var s = +options.projectScale
      this.projectScale = [s,s,s]
    }
  }

  this.projectHasAlpha = false // default to no transparent draw
  if('projectOpacity' in options) {
    if(isArrayOrTypedArray(options.projectOpacity)) {
      this.projectOpacity = options.projectOpacity.slice()
    } else {
      var s = +options.projectOpacity
      this.projectOpacity = [s,s,s]
    }
    for(var i=0; i<3; ++i) {
      this.projectOpacity[i] = fixOpacity(this.projectOpacity[i]);
      if(this.projectOpacity[i] < 1) {
        this.projectHasAlpha = true;
      }
    }
  }

  this.hasAlpha = false // default to no transparent draw
  if('opacity' in options) {
    this.opacity = fixOpacity(options.opacity)
    if(this.opacity < 1) {
      this.hasAlpha = true;
    }
  }

  //Set dirty flag
  this.dirty = true

  //Create new buffers
  var points = options.position

  //Text font
  var font = {
    family: options.font || 'normal',
    style: options.fontStyle || 'normal',
    weight: options.fontWeight || 'normal',
    variant: options.fontVariant || 'normal'
  }

  var alignment = options.alignment || [0,0]

  var alignmentX;
  var alignmentY;
  if (alignment.length === 2) {
    alignmentX = alignment[0]
    alignmentY = alignment[1]
  } else {
    alignmentX = []
    alignmentY = []
    for (var i = 0; i < alignment.length; ++i) {
      alignmentX[i] = alignment[i][0]
      alignmentY[i] = alignment[i][1]
    }
  }

  //Bounds
  var lowerBound = [ Infinity, Infinity, Infinity]
  var upperBound = [-Infinity,-Infinity,-Infinity]

  //Unpack options
  var glyphs     = options.glyph
  var colors     = options.color
  var sizes      = options.size
  var angles     = options.angle
  var lineColors = options.lineColor

  //Picking geometry
  var pickCounter = -1

  //First do pass to compute buffer sizes
  var triVertexCount  = 0
  var lineVertexCount = 0

  var numPoints = 0;

  if(points.length) {

    //Count number of points and buffer size
    numPoints = points.length

  count_loop:
    for(var i=0; i 0) {
    var triOffset  = 0
    var lineOffset = triVertexCount
    var color      = [0,0,0,1]
    var lineColor  = [0,0,0,1]

    var isColorArray      = isArrayOrTypedArray(colors)     && isArrayOrTypedArray(colors[0])
    var isLineColorArray  = isArrayOrTypedArray(lineColors) && isArrayOrTypedArray(lineColors[0])

  fill_loop:
    for(var i=0; i 0) ? (1 - glyphBounds[0][0]) :
                     (textOffsetX < 0) ? (1 + glyphBounds[1][0]) : 1;

      textOffsetY *= (textOffsetY > 0) ? (1 - glyphBounds[0][1]) :
                     (textOffsetY < 0) ? (1 + glyphBounds[1][1]) : 1;

      var textOffset = [textOffsetX, textOffsetY]

      //Write out inner marker
      var cells = glyphMesh.cells || []
      var verts = glyphMesh.positions || []

      for(var j=0; j 0) {

    //Draw border
    var w = lineWidth * pixelRatio
    boxes.drawBox(loX-w, loY-w, hiX+w, loY+w, borderColor)
    boxes.drawBox(loX-w, hiY-w, hiX+w, hiY+w, borderColor)
    boxes.drawBox(loX-w, loY-w, loX+w, hiY+w, borderColor)
    boxes.drawBox(hiX-w, loY-w, hiX+w, hiY+w, borderColor)
  }
}

proto.update = function(options) {
  options = options || {}

  this.innerFill    = !!options.innerFill
  this.outerFill    = !!options.outerFill
  this.innerColor   = (options.innerColor   || [0,0,0,0.5]).slice()
  this.outerColor   = (options.outerColor   || [0,0,0,0.5]).slice()
  this.borderColor  = (options.borderColor || [0,0,0,1]).slice()
  this.borderWidth  = options.borderWidth || 0
  this.selectBox    = (options.selectBox || this.selectBox).slice()
}

proto.dispose = function() {
  this.boxBuffer.dispose()
  this.boxShader.dispose()
  this.plot.removeOverlay(this)
}

function createSelectBox(plot, options) {
  var gl = plot.gl
  var buffer = createBuffer(gl, [
    0, 0,
    0, 1,
    1, 0,
    1, 1 ])
  var shader = createShader(gl, SHADERS.boxVertex, SHADERS.boxFragment)
  var selectBox = new SelectBox(plot, buffer, shader)
  selectBox.update(options)
  plot.addOverlay(selectBox)
  return selectBox
}


/***/ }),

/***/ 3589:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

"use strict";


module.exports = createSelectBuffer

var createFBO = __webpack_require__(2260)
var pool      = __webpack_require__(1888)
var ndarray   = __webpack_require__(9618)
var nextPow2  = (__webpack_require__(8828).nextPow2)

var selectRange = function(arr, x, y) {
  var closestD2 = 1e8
  var closestX = -1
  var closestY = -1

  var ni = arr.shape[0]
  var nj = arr.shape[1]
  for(var i = 0; i < ni; i++) {
    for(var j = 0; j < nj; j++) {
      var r = arr.get(i, j, 0)
      var g = arr.get(i, j, 1)
      var b = arr.get(i, j, 2)
      var a = arr.get(i, j, 3)

      if(r < 255 || g < 255 || b < 255 || a < 255) {
        var dx = x - i
        var dy = y - j
        var d2 = dx*dx + dy*dy
        if(d2 < closestD2) {
          closestD2 = d2
          closestX = i
          closestY = j
        }
      }
    }
  }

  return [closestX, closestY, closestD2]
}

function SelectResult(x, y, id, value, distance) {
  this.coord = [x, y]
  this.id = id
  this.value = value
  this.distance = distance
}

function SelectBuffer(gl, fbo, buffer) {
  this.gl     = gl
  this.fbo    = fbo
  this.buffer = buffer
  this._readTimeout = null
  var self = this

  this._readCallback = function() {
    if(!self.gl) {
      return
    }
    fbo.bind()
    gl.readPixels(0,0,fbo.shape[0],fbo.shape[1],gl.RGBA,gl.UNSIGNED_BYTE,self.buffer)
    self._readTimeout = null
  }
}

var proto = SelectBuffer.prototype

Object.defineProperty(proto, 'shape', {
  get: function() {
    if(!this.gl) {
      return [0,0]
    }
    return this.fbo.shape.slice()
  },
  set: function(v) {
    if(!this.gl) {
      return
    }
    this.fbo.shape = v
    var c = this.fbo.shape[0]
    var r = this.fbo.shape[1]
    if(r*c*4 > this.buffer.length) {
      pool.free(this.buffer)
      var buffer = this.buffer = pool.mallocUint8(nextPow2(r*c*4))
      for(var i=0; i oldAttribCount) {
    for(i = oldAttribCount; i < newAttribCount; i++) {
      this.gl.enableVertexAttribArray(i)
    }
  } else if(oldAttribCount > newAttribCount) {
    for(i = newAttribCount; i < oldAttribCount; i++) {
      this.gl.disableVertexAttribArray(i)
    }
  }

  this.gl.lastAttribCount = newAttribCount

  this.gl.useProgram(this.program)
}

proto.dispose = function() {

  // disabling vertex attributes so new shader starts with zero
  // and it's also useful if all shaders are disposed but the
  // gl context is reused for subsequent replotting
  var oldAttribCount = this.gl.lastAttribCount
  for (var i = 0; i < oldAttribCount; i++) {
    this.gl.disableVertexAttribArray(i)
  }
  this.gl.lastAttribCount = 0

  if(this._fref) {
    this._fref.dispose()
  }
  if(this._vref) {
    this._vref.dispose()
  }
  this.attributes =
  this.types      =
  this.vertShader =
  this.fragShader =
  this.program    =
  this._relink    =
  this._fref      =
  this._vref      = null
}

function compareAttributes(a, b) {
  if(a.name < b.name) {
    return -1
  }
  return 1
}

//Update export hook for glslify-live
proto.update = function(
    vertSource
  , fragSource
  , uniforms
  , attributes) {

  //If only one object passed, assume glslify style output
  if(!fragSource || arguments.length === 1) {
    var obj = vertSource
    vertSource = obj.vertex
    fragSource = obj.fragment
    uniforms   = obj.uniforms
    attributes = obj.attributes
  }

  var wrapper = this
  var gl      = wrapper.gl

  //Compile vertex and fragment shaders
  var pvref = wrapper._vref
  wrapper._vref = shaderCache.shader(gl, gl.VERTEX_SHADER, vertSource)
  if(pvref) {
    pvref.dispose()
  }
  wrapper.vertShader = wrapper._vref.shader
  var pfref = this._fref
  wrapper._fref = shaderCache.shader(gl, gl.FRAGMENT_SHADER, fragSource)
  if(pfref) {
    pfref.dispose()
  }
  wrapper.fragShader = wrapper._fref.shader

  //If uniforms/attributes is not specified, use RT reflection
  if(!uniforms || !attributes) {

    //Create initial test program
    var testProgram = gl.createProgram()
    gl.attachShader(testProgram, wrapper.fragShader)
    gl.attachShader(testProgram, wrapper.vertShader)
    gl.linkProgram(testProgram)
    if(!gl.getProgramParameter(testProgram, gl.LINK_STATUS)) {
      var errLog = gl.getProgramInfoLog(testProgram)
      throw new GLError(errLog, 'Error linking program:' + errLog)
    }

    //Load data from runtime
    uniforms   = uniforms   || runtime.uniforms(gl, testProgram)
    attributes = attributes || runtime.attributes(gl, testProgram)

    //Release test program
    gl.deleteProgram(testProgram)
  }

  //Sort attributes lexicographically
  // overrides undefined WebGL behavior for attribute locations
  attributes = attributes.slice()
  attributes.sort(compareAttributes)

  //Convert attribute types, read out locations
  var attributeUnpacked  = []
  var attributeNames     = []
  var attributeLocations = []
  var i
  for(i=0; i= 0) {
      var size = attr.type.charAt(attr.type.length-1)|0
      var locVector = new Array(size)
      for(var j=0; j= 0) {
        curLocation += 1
      }
      attributeLocations[i] = curLocation
    }
  }

  //Rebuild program and recompute all uniform locations
  var uniformLocations = new Array(uniforms.length)
  function relink() {
    wrapper.program = shaderCache.program(
        gl
      , wrapper._vref
      , wrapper._fref
      , attributeNames
      , attributeLocations)

    for(var i=0; i= 0) {
          var d = type.charCodeAt(type.length-1) - 48
          if(d < 2 || d > 4) {
            throw new GLError('', 'Invalid data type for attribute ' + name + ': ' + type)
          }
          addVectorAttribute(
              gl
            , wrapper
            , locs[0]
            , locations
            , d
            , obj
            , name)
        } else if(type.indexOf('mat') >= 0) {
          var d = type.charCodeAt(type.length-1) - 48
          if(d < 2 || d > 4) {
            throw new GLError('', 'Invalid data type for attribute ' + name + ': ' + type)
          }
          addMatrixAttribute(
              gl
            , wrapper
            , locs
            , locations
            , d
            , obj
            , name)
        } else {
          throw new GLError('', 'Unknown data type for attribute ' + name + ': ' + type)
        }
      break
    }
  }
  return obj
}


/***/ }),

/***/ 3327:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

"use strict";


var coallesceUniforms = __webpack_require__(216)
var GLError = __webpack_require__(8866)

module.exports = createUniformWrapper

//Binds a function and returns a value
function identity(x) {
  return function() {
    return x
  }
}

function makeVector(length, fill) {
  var result = new Array(length)
  for(var i=0; i 4) {
                  throw new GLError('', 'Invalid data type')
                }
                switch(t.charAt(0)) {
                  case 'b':
                  case 'i':
                    gl['uniform' + d + 'iv'](locations[idx], objPath)
                    break
                  case 'v':
                    gl['uniform' + d + 'fv'](locations[idx], objPath)
                    break
                  default:
                    throw new GLError('', 'Unrecognized data type for vector ' + name + ': ' + t)
                }
              } else if(t.indexOf('mat') === 0 && t.length === 4) {
                d = t.charCodeAt(t.length-1) - 48
                if(d < 2 || d > 4) {
                  throw new GLError('', 'Invalid uniform dimension type for matrix ' + name + ': ' + t)
                }
                gl['uniformMatrix' + d + 'fv'](locations[idx], false, objPath)
                break
              } else {
                throw new GLError('', 'Unknown uniform data type for ' + name + ': ' + t)
              }
          }
        }
      }
    }
  }

  function enumerateIndices(prefix, type) {
    if(typeof type !== 'object') {
      return [ [prefix, type] ]
    }
    var indices = []
    for(var id in type) {
      var prop = type[id]
      var tprefix = prefix
      if(parseInt(id) + '' === id) {
        tprefix += '[' + id + ']'
      } else {
        tprefix += '.' + id
      }
      if(typeof prop === 'object') {
        indices.push.apply(indices, enumerateIndices(tprefix, prop))
      } else {
        indices.push([tprefix, prop])
      }
    }
    return indices
  }


  function defaultValue(type) {
    switch(type) {
      case 'bool':
        return false
      case 'int':
      case 'sampler2D':
      case 'samplerCube':
        return 0
      case 'float':
        return 0.0
      default:
        var vidx = type.indexOf('vec')
        if(0 <= vidx && vidx <= 1 && type.length === 4 + vidx) {
          var d = type.charCodeAt(type.length-1) - 48
          if(d < 2 || d > 4) {
            throw new GLError('', 'Invalid data type')
          }
          if(type.charAt(0) === 'b') {
            return makeVector(d, false)
          }
          return makeVector(d, 0)
        } else if(type.indexOf('mat') === 0 && type.length === 4) {
          var d = type.charCodeAt(type.length-1) - 48
          if(d < 2 || d > 4) {
            throw new GLError('', 'Invalid uniform dimension type for matrix ' + name + ': ' + type)
          }
          return makeVector(d*d, 0)
        } else {
          throw new GLError('', 'Unknown uniform data type for ' + name + ': ' + type)
        }
    }
  }

  function storeProperty(obj, prop, type) {
    if(typeof type === 'object') {
      var child = processObject(type)
      Object.defineProperty(obj, prop, {
        get: identity(child),
        set: makeSetter(type),
        enumerable: true,
        configurable: false
      })
    } else {
      if(locations[type]) {
        Object.defineProperty(obj, prop, {
          get: makeGetter(type),
          set: makeSetter(type),
          enumerable: true,
          configurable: false
        })
      } else {
        obj[prop] = defaultValue(uniforms[type].type)
      }
    }
  }

  function processObject(obj) {
    var result
    if(Array.isArray(obj)) {
      result = new Array(obj.length)
      for(var i=0; i 1) {
        if(!(x[0] in o)) {
          o[x[0]] = []
        }
        o = o[x[0]]
        for(var k=1; k 1) {
        for(var j=0; j 0  U  ||b|| > 0.\n  // Assign z = 0, x = -b, y = a:\n  // a*-b + b*a + c*0 = -ba + ba + 0 = 0\n  if (v.x*v.x > v.z*v.z || v.y*v.y > v.z*v.z) {\n    return normalize(vec3(-v.y, v.x, 0.0));\n  } else {\n    return normalize(vec3(0.0, v.z, -v.y));\n  }\n}\n\n// Calculate the tube vertex and normal at the given index.\n//\n// The returned vertex is for a tube ring with its center at origin, radius of length(d), pointing in the direction of d.\n//\n// Each tube segment is made up of a ring of vertices.\n// These vertices are used to make up the triangles of the tube by connecting them together in the vertex array.\n// The indexes of tube segments run from 0 to 8.\n//\nvec3 getTubePosition(vec3 d, float index, out vec3 normal) {\n  float segmentCount = 8.0;\n\n  float angle = 2.0 * 3.14159 * (index / segmentCount);\n\n  vec3 u = getOrthogonalVector(d);\n  vec3 v = normalize(cross(u, d));\n\n  vec3 x = u * cos(angle) * length(d);\n  vec3 y = v * sin(angle) * length(d);\n  vec3 v3 = x + y;\n\n  normal = normalize(v3);\n\n  return v3;\n}\n\nattribute vec4 vector;\nattribute vec4 color, position;\nattribute vec2 uv;\n\nuniform float vectorScale, tubeScale;\nuniform mat4 model, view, projection, inverseModel;\nuniform vec3 eyePosition, lightPosition;\n\nvarying vec3 f_normal, f_lightDirection, f_eyeDirection, f_data, f_position;\nvarying vec4 f_color;\nvarying vec2 f_uv;\n\nvoid main() {\n  // Scale the vector magnitude to stay constant with\n  // model & view changes.\n  vec3 normal;\n  vec3 XYZ = getTubePosition(mat3(model) * (tubeScale * vector.w * normalize(vector.xyz)), position.w, normal);\n  vec4 tubePosition = model * vec4(position.xyz, 1.0) + vec4(XYZ, 0.0);\n\n  //Lighting geometry parameters\n  vec4 cameraCoordinate = view * tubePosition;\n  cameraCoordinate.xyz /= cameraCoordinate.w;\n  f_lightDirection = lightPosition - cameraCoordinate.xyz;\n  f_eyeDirection   = eyePosition - cameraCoordinate.xyz;\n  f_normal = normalize((vec4(normal, 0.0) * inverseModel).xyz);\n\n  // vec4 m_position  = model * vec4(tubePosition, 1.0);\n  vec4 t_position  = view * tubePosition;\n  gl_Position      = projection * t_position;\n\n  f_color          = color;\n  f_data           = tubePosition.xyz;\n  f_position       = position.xyz;\n  f_uv             = uv;\n}\n"])
var triFragSrc = glslify(["#extension GL_OES_standard_derivatives : enable\n\nprecision highp float;\n#define GLSLIFY 1\n\nfloat beckmannDistribution(float x, float roughness) {\n  float NdotH = max(x, 0.0001);\n  float cos2Alpha = NdotH * NdotH;\n  float tan2Alpha = (cos2Alpha - 1.0) / cos2Alpha;\n  float roughness2 = roughness * roughness;\n  float denom = 3.141592653589793 * roughness2 * cos2Alpha * cos2Alpha;\n  return exp(tan2Alpha / roughness2) / denom;\n}\n\nfloat cookTorranceSpecular(\n  vec3 lightDirection,\n  vec3 viewDirection,\n  vec3 surfaceNormal,\n  float roughness,\n  float fresnel) {\n\n  float VdotN = max(dot(viewDirection, surfaceNormal), 0.0);\n  float LdotN = max(dot(lightDirection, surfaceNormal), 0.0);\n\n  //Half angle vector\n  vec3 H = normalize(lightDirection + viewDirection);\n\n  //Geometric term\n  float NdotH = max(dot(surfaceNormal, H), 0.0);\n  float VdotH = max(dot(viewDirection, H), 0.000001);\n  float LdotH = max(dot(lightDirection, H), 0.000001);\n  float G1 = (2.0 * NdotH * VdotN) / VdotH;\n  float G2 = (2.0 * NdotH * LdotN) / LdotH;\n  float G = min(1.0, min(G1, G2));\n  \n  //Distribution term\n  float D = beckmannDistribution(NdotH, roughness);\n\n  //Fresnel term\n  float F = pow(1.0 - VdotN, fresnel);\n\n  //Multiply terms and done\n  return  G * F * D / max(3.14159265 * VdotN, 0.000001);\n}\n\nbool outOfRange(float a, float b, float p) {\n  return ((p > max(a, b)) || \n          (p < min(a, b)));\n}\n\nbool outOfRange(vec2 a, vec2 b, vec2 p) {\n  return (outOfRange(a.x, b.x, p.x) ||\n          outOfRange(a.y, b.y, p.y));\n}\n\nbool outOfRange(vec3 a, vec3 b, vec3 p) {\n  return (outOfRange(a.x, b.x, p.x) ||\n          outOfRange(a.y, b.y, p.y) ||\n          outOfRange(a.z, b.z, p.z));\n}\n\nbool outOfRange(vec4 a, vec4 b, vec4 p) {\n  return outOfRange(a.xyz, b.xyz, p.xyz);\n}\n\nuniform vec3 clipBounds[2];\nuniform float roughness, fresnel, kambient, kdiffuse, kspecular, opacity;\nuniform sampler2D texture;\n\nvarying vec3 f_normal, f_lightDirection, f_eyeDirection, f_data, f_position;\nvarying vec4 f_color;\nvarying vec2 f_uv;\n\nvoid main() {\n  if (outOfRange(clipBounds[0], clipBounds[1], f_position)) discard;\n  vec3 N = normalize(f_normal);\n  vec3 L = normalize(f_lightDirection);\n  vec3 V = normalize(f_eyeDirection);\n\n  if(gl_FrontFacing) {\n    N = -N;\n  }\n\n  float specular = min(1.0, max(0.0, cookTorranceSpecular(L, V, N, roughness, fresnel)));\n  float diffuse  = min(kambient + kdiffuse * max(dot(N, L), 0.0), 1.0);\n\n  vec4 surfaceColor = f_color * texture2D(texture, f_uv);\n  vec4 litColor = surfaceColor.a * vec4(diffuse * surfaceColor.rgb + kspecular * vec3(1,1,1) * specular,  1.0);\n\n  gl_FragColor = litColor * opacity;\n}\n"])
var pickVertSrc = glslify(["precision highp float;\n\nprecision highp float;\n#define GLSLIFY 1\n\nvec3 getOrthogonalVector(vec3 v) {\n  // Return up-vector for only-z vector.\n  // Return ax + by + cz = 0, a point that lies on the plane that has v as a normal and that isn't (0,0,0).\n  // From the above if-statement we have ||a|| > 0  U  ||b|| > 0.\n  // Assign z = 0, x = -b, y = a:\n  // a*-b + b*a + c*0 = -ba + ba + 0 = 0\n  if (v.x*v.x > v.z*v.z || v.y*v.y > v.z*v.z) {\n    return normalize(vec3(-v.y, v.x, 0.0));\n  } else {\n    return normalize(vec3(0.0, v.z, -v.y));\n  }\n}\n\n// Calculate the tube vertex and normal at the given index.\n//\n// The returned vertex is for a tube ring with its center at origin, radius of length(d), pointing in the direction of d.\n//\n// Each tube segment is made up of a ring of vertices.\n// These vertices are used to make up the triangles of the tube by connecting them together in the vertex array.\n// The indexes of tube segments run from 0 to 8.\n//\nvec3 getTubePosition(vec3 d, float index, out vec3 normal) {\n  float segmentCount = 8.0;\n\n  float angle = 2.0 * 3.14159 * (index / segmentCount);\n\n  vec3 u = getOrthogonalVector(d);\n  vec3 v = normalize(cross(u, d));\n\n  vec3 x = u * cos(angle) * length(d);\n  vec3 y = v * sin(angle) * length(d);\n  vec3 v3 = x + y;\n\n  normal = normalize(v3);\n\n  return v3;\n}\n\nattribute vec4 vector;\nattribute vec4 position;\nattribute vec4 id;\n\nuniform mat4 model, view, projection;\nuniform float tubeScale;\n\nvarying vec3 f_position;\nvarying vec4 f_id;\n\nvoid main() {\n  vec3 normal;\n  vec3 XYZ = getTubePosition(mat3(model) * (tubeScale * vector.w * normalize(vector.xyz)), position.w, normal);\n  vec4 tubePosition = model * vec4(position.xyz, 1.0) + vec4(XYZ, 0.0);\n\n  gl_Position = projection * (view * tubePosition);\n  f_id        = id;\n  f_position  = position.xyz;\n}\n"])
var pickFragSrc = glslify(["precision highp float;\n#define GLSLIFY 1\n\nbool outOfRange(float a, float b, float p) {\n  return ((p > max(a, b)) || \n          (p < min(a, b)));\n}\n\nbool outOfRange(vec2 a, vec2 b, vec2 p) {\n  return (outOfRange(a.x, b.x, p.x) ||\n          outOfRange(a.y, b.y, p.y));\n}\n\nbool outOfRange(vec3 a, vec3 b, vec3 p) {\n  return (outOfRange(a.x, b.x, p.x) ||\n          outOfRange(a.y, b.y, p.y) ||\n          outOfRange(a.z, b.z, p.z));\n}\n\nbool outOfRange(vec4 a, vec4 b, vec4 p) {\n  return outOfRange(a.xyz, b.xyz, p.xyz);\n}\n\nuniform vec3  clipBounds[2];\nuniform float pickId;\n\nvarying vec3 f_position;\nvarying vec4 f_id;\n\nvoid main() {\n  if (outOfRange(clipBounds[0], clipBounds[1], f_position)) discard;\n\n  gl_FragColor = vec4(pickId, f_id.xyz);\n}"])

exports.meshShader = {
  vertex:   triVertSrc,
  fragment: triFragSrc,
  attributes: [
    {name: 'position', type: 'vec4'},
    {name: 'color', type: 'vec4'},
    {name: 'uv', type: 'vec2'},
    {name: 'vector', type: 'vec4'}
  ]
}
exports.pickShader = {
  vertex:   pickVertSrc,
  fragment: pickFragSrc,
  attributes: [
    {name: 'position', type: 'vec4'},
    {name: 'id', type: 'vec4'},
    {name: 'vector', type: 'vec4'}
  ]
}


/***/ }),

/***/ 7815:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

"use strict";


var vec3 = __webpack_require__(2931);
var vec4 = __webpack_require__(9970);
var GRID_TYPES = ['xyz', 'xzy', 'yxz', 'yzx', 'zxy', 'zyx'];

var streamToTube = function(stream, maxDivergence, minDistance, maxNorm) {
	var points = stream.points;
	var velocities = stream.velocities;
	var divergences = stream.divergences;

	var verts = [];
	var faces = [];
	var vectors = [];
	var previousVerts = [];
	var currentVerts = [];
	var intensities = [];
	var previousIntensity = 0;
	var currentIntensity = 0;
	var currentVector = vec4.create();
	var previousVector = vec4.create();

	var facets = 8;

	for (var i = 0; i < points.length; i++) {
		var p = points[i];
		var fwd = velocities[i];
		var r = divergences[i];
		if (maxDivergence === 0) {
			r = minDistance * 0.05;
		}
		currentIntensity = vec3.length(fwd) / maxNorm;

		currentVector = vec4.create();
		vec3.copy(currentVector, fwd);
		currentVector[3] = r;

		for (var a = 0; a < facets; a++) {
			currentVerts[a] = [p[0], p[1], p[2], a];
		}
		if (previousVerts.length > 0) {
			for (var a = 0; a < facets; a++) {
				var a1 = (a+1) % facets;
				verts.push(
					previousVerts[a],
					currentVerts[a],
					currentVerts[a1],

					currentVerts[a1],
					previousVerts[a1],
					previousVerts[a]
				);
				vectors.push(
					previousVector,
					currentVector,
					currentVector,

					currentVector,
					previousVector,
					previousVector
				);
				intensities.push(
					previousIntensity,
					currentIntensity,
					currentIntensity,

					currentIntensity,
					previousIntensity,
					previousIntensity
				);

				var len = verts.length;
				faces.push(
					[len-6, len-5, len-4],
					[len-3, len-2, len-1]
				);
			}
		}
		var tmp1 = previousVerts;
		previousVerts = currentVerts;
		currentVerts = tmp1;

		var tmp2 = previousVector;
		previousVector = currentVector;
		currentVector = tmp2;

		var tmp3 = previousIntensity;
		previousIntensity = currentIntensity;
		currentIntensity = tmp3;
	}
	return {
		positions: verts,
		cells: faces,
		vectors: vectors,
		vertexIntensity: intensities
	};
};

var createTubes = function(streams, colormap, maxDivergence, minDistance) {

	var maxNorm = 0;
	for (var i=0; i v) return i-1;
  }
  return i;
};

var clamp = function(v, min, max) {
	return v < min ? min : (v > max ? max : v);
};

var sampleMeshgrid = function(point, vectorField, gridInfo) {
	var vectors = vectorField.vectors;
	var meshgrid = vectorField.meshgrid;

	var x = point[0];
	var y = point[1];
	var z = point[2];

	var w = meshgrid[0].length;
	var h = meshgrid[1].length;
	var d = meshgrid[2].length;

	// Find the index of the nearest smaller value in the meshgrid for each coordinate of (x,y,z).
	// The nearest smaller value index for x is the index x0 such that
	// meshgrid[0][x0] < x and for all x1 > x0, meshgrid[0][x1] >= x.
	var x0 = findLastSmallerIndex(meshgrid[0], x);
	var y0 = findLastSmallerIndex(meshgrid[1], y);
	var z0 = findLastSmallerIndex(meshgrid[2], z);

	// Get the nearest larger meshgrid value indices.
	// From the above "nearest smaller value", we know that
	//   meshgrid[0][x0] < x
	//   meshgrid[0][x0+1] >= x
	var x1 = x0 + 1;
	var y1 = y0 + 1;
	var z1 = z0 + 1;

	x0 = clamp(x0, 0, w-1);
	x1 = clamp(x1, 0, w-1);
	y0 = clamp(y0, 0, h-1);
	y1 = clamp(y1, 0, h-1);
	z0 = clamp(z0, 0, d-1);
	z1 = clamp(z1, 0, d-1);

	// Reject points outside the meshgrid, return a zero vector.
	if (x0 < 0 || y0 < 0 || z0 < 0 || x1 > w-1 || y1 > h-1 || z1 > d-1) {
		return vec3.create();
	}

	// Normalize point coordinates to 0..1 scaling factor between x0 and x1.
	var mX0 = meshgrid[0][x0];
	var mX1 = meshgrid[0][x1];
	var mY0 = meshgrid[1][y0];
	var mY1 = meshgrid[1][y1];
	var mZ0 = meshgrid[2][z0];
	var mZ1 = meshgrid[2][z1];
	var xf = (x - mX0) / (mX1 - mX0);
	var yf = (y - mY0) / (mY1 - mY0);
	var zf = (z - mZ0) / (mZ1 - mZ0);

	if (!isFinite(xf)) xf = 0.5;
	if (!isFinite(yf)) yf = 0.5;
	if (!isFinite(zf)) zf = 0.5;

	var x0off;
	var x1off;
	var y0off;
	var y1off;
	var z0off;
	var z1off;

	if(gridInfo.reversedX) {
		x0 = w - 1 - x0;
		x1 = w - 1 - x1;
	}

	if(gridInfo.reversedY) {
		y0 = h - 1 - y0;
		y1 = h - 1 - y1;
	}

	if(gridInfo.reversedZ) {
		z0 = d - 1 - z0;
		z1 = d - 1 - z1;
	}

	switch(gridInfo.filled) {
		case 5: // 'zyx'
			z0off = z0;
			z1off = z1;
			y0off = y0*d;
			y1off = y1*d;
			x0off = x0*d*h;
			x1off = x1*d*h;
			break;

		case 4: // 'zxy'
			z0off = z0;
			z1off = z1;
			x0off = x0*d;
			x1off = x1*d;
			y0off = y0*d*w;
			y1off = y1*d*w;
			break;

		case 3: // 'yzx'
			y0off = y0;
			y1off = y1;
			z0off = z0*h;
			z1off = z1*h;
			x0off = x0*h*d;
			x1off = x1*h*d;
			break;

		case 2: // 'yxz'
			y0off = y0;
			y1off = y1;
			x0off = x0*h;
			x1off = x1*h;
			z0off = z0*h*w;
			z1off = z1*h*w;
			break;

		case 1: // 'xzy'
			x0off = x0;
			x1off = x1;
			z0off = z0*w;
			z1off = z1*w;
			y0off = y0*w*d;
			y1off = y1*w*d;
			break;

		default: // case 0: // 'xyz'
			x0off = x0;
			x1off = x1;
			y0off = y0*w;
			y1off = y1*w;
			z0off = z0*w*h;
			z1off = z1*w*h;
			break;
	}

	// Sample data vectors around the (x,y,z) point.
	var v000 = vectors[x0off + y0off + z0off];
	var v001 = vectors[x0off + y0off + z1off];
	var v010 = vectors[x0off + y1off + z0off];
	var v011 = vectors[x0off + y1off + z1off];
	var v100 = vectors[x1off + y0off + z0off];
	var v101 = vectors[x1off + y0off + z1off];
	var v110 = vectors[x1off + y1off + z0off];
	var v111 = vectors[x1off + y1off + z1off];

	var c00 = vec3.create();
	var c01 = vec3.create();
	var c10 = vec3.create();
	var c11 = vec3.create();

	vec3.lerp(c00, v000, v100, xf);
	vec3.lerp(c01, v001, v101, xf);
	vec3.lerp(c10, v010, v110, xf);
	vec3.lerp(c11, v011, v111, xf);

	var c0 = vec3.create();
	var c1 = vec3.create();

	vec3.lerp(c0, c00, c10, yf);
	vec3.lerp(c1, c01, c11, yf);

	var c = vec3.create();

	vec3.lerp(c, c0, c1, zf);

	return c;
};


var vabs = function(dst, v) {
	var x = v[0];
	var y = v[1];
	var z = v[2];
	dst[0] = x < 0 ? -x : x;
	dst[1] = y < 0 ? -y : y;
	dst[2] = z < 0 ? -z : z;
	return dst;
};

var findMinSeparation = function(xs) {
	var minSeparation = Infinity;
	xs.sort(function(a, b) { return a - b; });
	var len = xs.length;
	for (var i=1; i maxX ||
			y < minY || y > maxY ||
			z < minZ || z > maxZ
		);
	};

	var boundsSize = vec3.distance(bounds[0], bounds[1]);
	var maxStepSize = 10 * boundsSize / maxLength;
	var maxStepSizeSq = maxStepSize * maxStepSize;

	var minDistance = 1;
	var maxDivergence = 0; // For component-wise divergence vec3.create();

	// In case we need to do component-wise divergence visualization
	// var tmp = vec3.create();

	var len = positions.length;
	if (len > 1) {
		minDistance = calculateMinPositionDistance(positions);
	}

	for (var i = 0; i < len; i++) {
		var p = vec3.create();
		vec3.copy(p, positions[i]);

		var stream = [p];
		var velocities = [];
		var v = getVelocity(p);
		var op = p;
		velocities.push(v);

		var divergences = [];

		var dv = getDivergence(p, v);
		var dvLength = vec3.length(dv);
		if (isFinite(dvLength) && dvLength > maxDivergence) {
			maxDivergence = dvLength;
		}
		// In case we need to do component-wise divergence visualization
		// vec3.max(maxDivergence, maxDivergence, vabs(tmp, dv));
		divergences.push(dvLength);

		streams.push({points: stream, velocities: velocities, divergences: divergences});

		var j = 0;

		while (j < maxLength * 100 && stream.length < maxLength && inBounds(p)) {
			j++;
			var np = vec3.clone(v);
			var sqLen = vec3.squaredLength(np);
			if (sqLen === 0) {
				break;
			} else if (sqLen > maxStepSizeSq) {
				vec3.scale(np, np, maxStepSize / Math.sqrt(sqLen));
			}
			vec3.add(np, np, p);

			v = getVelocity(np);

			if (vec3.squaredDistance(op, np) - maxStepSizeSq > -0.0001 * maxStepSizeSq) {
				stream.push(np);
				op = np;
				velocities.push(v);
				var dv = getDivergence(np, v);
				var dvLength = vec3.length(dv);
				if (isFinite(dvLength) && dvLength > maxDivergence) {
					maxDivergence = dvLength;
				}
				// In case we need to do component-wise divergence visualization
				//vec3.max(maxDivergence, maxDivergence, vabs(tmp, dv));
				divergences.push(dvLength);
			}

			p = np;
		}
	}

	var tubes = createTubes(streams, vectorField.colormap, maxDivergence, minDistance);

	if (absoluteTubeSize) {
		tubes.tubeScale = absoluteTubeSize;
	} else {
		// Avoid division by zero.
		if (maxDivergence === 0) {
			maxDivergence = 1;
		}
		tubes.tubeScale = tubeSize * 0.5 * minDistance / maxDivergence;
	}

	return tubes;
};

var shaders = __webpack_require__(6740);
var createMesh = (__webpack_require__(6405).createMesh);
module.exports.createTubeMesh = function(gl, params) {
	return createMesh(gl, params, {
		shaders: shaders,
		traceType: 'streamtube'
	});
}


/***/ }),

/***/ 990:
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {

var createShader = __webpack_require__(9405)
var glslify = __webpack_require__(3236)

var vertSrc = glslify(["precision highp float;\n#define GLSLIFY 1\n\nattribute vec4 uv;\nattribute vec3 f;\nattribute vec3 normal;\n\nuniform vec3 objectOffset;\nuniform mat4 model, view, projection, inverseModel;\nuniform vec3 lightPosition, eyePosition;\nuniform sampler2D colormap;\n\nvarying float value, kill;\nvarying vec3 worldCoordinate;\nvarying vec2 planeCoordinate;\nvarying vec3 lightDirection, eyeDirection, surfaceNormal;\nvarying vec4 vColor;\n\nvoid main() {\n  vec3 localCoordinate = vec3(uv.zw, f.x);\n  worldCoordinate = objectOffset + localCoordinate;\n  mat4 objectOffsetTranslation = mat4(1.0) + mat4(vec4(0), vec4(0), vec4(0), vec4(objectOffset, 0));\n  vec4 worldPosition = (model * objectOffsetTranslation) * vec4(localCoordinate, 1.0);\n  vec4 clipPosition = projection * (view * worldPosition);\n  gl_Position = clipPosition;\n  kill = f.y;\n  value = f.z;\n  planeCoordinate = uv.xy;\n\n  vColor = texture2D(colormap, vec2(value, value));\n\n  //Lighting geometry parameters\n  vec4 cameraCoordinate = view * worldPosition;\n  cameraCoordinate.xyz /= cameraCoordinate.w;\n  lightDirection = lightPosition - cameraCoordinate.xyz;\n  eyeDirection   = eyePosition - cameraCoordinate.xyz;\n  surfaceNormal  = normalize((vec4(normal,0) * inverseModel).xyz);\n}\n"])
var fragSrc = glslify(["precision highp float;\n#define GLSLIFY 1\n\nfloat beckmannDistribution(float x, float roughness) {\n  float NdotH = max(x, 0.0001);\n  float cos2Alpha = NdotH * NdotH;\n  float tan2Alpha = (cos2Alpha - 1.0) / cos2Alpha;\n  float roughness2 = roughness * roughness;\n  float denom = 3.141592653589793 * roughness2 * cos2Alpha * cos2Alpha;\n  return exp(tan2Alpha / roughness2) / denom;\n}\n\nfloat beckmannSpecular(\n  vec3 lightDirection,\n  vec3 viewDirection,\n  vec3 surfaceNormal,\n  float roughness) {\n  return beckmannDistribution(dot(surfaceNormal, normalize(lightDirection + viewDirection)), roughness);\n}\n\nbool outOfRange(float a, float b, float p) {\n  return ((p > max(a, b)) || \n          (p < min(a, b)));\n}\n\nbool outOfRange(vec2 a, vec2 b, vec2 p) {\n  return (outOfRange(a.x, b.x, p.x) ||\n          outOfRange(a.y, b.y, p.y));\n}\n\nbool outOfRange(vec3 a, vec3 b, vec3 p) {\n  return (outOfRange(a.x, b.x, p.x) ||\n          outOfRange(a.y, b.y, p.y) ||\n          outOfRange(a.z, b.z, p.z));\n}\n\nbool outOfRange(vec4 a, vec4 b, vec4 p) {\n  return outOfRange(a.xyz, b.xyz, p.xyz);\n}\n\nuniform vec3 lowerBound, upperBound;\nuniform float contourTint;\nuniform vec4 contourColor;\nuniform sampler2D colormap;\nuniform vec3 clipBounds[2];\nuniform float roughness, fresnel, kambient, kdiffuse, kspecular, opacity;\nuniform float vertexColor;\n\nvarying float value, kill;\nvarying vec3 worldCoordinate;\nvarying vec3 lightDirection, eyeDirection, surfaceNormal;\nvarying vec4 vColor;\n\nvoid main() {\n  if (\n    kill > 0.0 ||\n    vColor.a == 0.0 ||\n    outOfRange(clipBounds[0], clipBounds[1], worldCoordinate)\n  ) discard;\n\n  vec3 N = normalize(surfaceNormal);\n  vec3 V = normalize(eyeDirection);\n  vec3 L = normalize(lightDirection);\n\n  if(gl_FrontFacing) {\n    N = -N;\n  }\n\n  float specular = max(beckmannSpecular(L, V, N, roughness), 0.);\n  float diffuse  = min(kambient + kdiffuse * max(dot(N, L), 0.0), 1.0);\n\n  //decide how to interpolate color — in vertex or in fragment\n  vec4 surfaceColor =\n    step(vertexColor, .5) * texture2D(colormap, vec2(value, value)) +\n    step(.5, vertexColor) * vColor;\n\n  vec4 litColor = surfaceColor.a * vec4(diffuse * surfaceColor.rgb + kspecular * vec3(1,1,1) * specular,  1.0);\n\n  gl_FragColor = mix(litColor, contourColor, contourTint) * opacity;\n}\n"])
var contourVertSrc = glslify(["precision highp float;\n#define GLSLIFY 1\n\nattribute vec4 uv;\nattribute float f;\n\nuniform vec3 objectOffset;\nuniform mat3 permutation;\nuniform mat4 model, view, projection;\nuniform float height, zOffset;\nuniform sampler2D colormap;\n\nvarying float value, kill;\nvarying vec3 worldCoordinate;\nvarying vec2 planeCoordinate;\nvarying vec3 lightDirection, eyeDirection, surfaceNormal;\nvarying vec4 vColor;\n\nvoid main() {\n  vec3 dataCoordinate = permutation * vec3(uv.xy, height);\n  worldCoordinate = objectOffset + dataCoordinate;\n  mat4 objectOffsetTranslation = mat4(1.0) + mat4(vec4(0), vec4(0), vec4(0), vec4(objectOffset, 0));\n  vec4 worldPosition = (model * objectOffsetTranslation) * vec4(dataCoordinate, 1.0);\n\n  vec4 clipPosition = projection * (view * worldPosition);\n  clipPosition.z += zOffset;\n\n  gl_Position = clipPosition;\n  value = f + objectOffset.z;\n  kill = -1.0;\n  planeCoordinate = uv.zw;\n\n  vColor = texture2D(colormap, vec2(value, value));\n\n  //Don't do lighting for contours\n  surfaceNormal   = vec3(1,0,0);\n  eyeDirection    = vec3(0,1,0);\n  lightDirection  = vec3(0,0,1);\n}\n"])
var pickSrc = glslify(["precision highp float;\n#define GLSLIFY 1\n\nbool outOfRange(float a, float b, float p) {\n  return ((p > max(a, b)) || \n          (p < min(a, b)));\n}\n\nbool outOfRange(vec2 a, vec2 b, vec2 p) {\n  return (outOfRange(a.x, b.x, p.x) ||\n          outOfRange(a.y, b.y, p.y));\n}\n\nbool outOfRange(vec3 a, vec3 b, vec3 p) {\n  return (outOfRange(a.x, b.x, p.x) ||\n          outOfRange(a.y, b.y, p.y) ||\n          outOfRange(a.z, b.z, p.z));\n}\n\nbool outOfRange(vec4 a, vec4 b, vec4 p) {\n  return outOfRange(a.xyz, b.xyz, p.xyz);\n}\n\nuniform vec2 shape;\nuniform vec3 clipBounds[2];\nuniform float pickId;\n\nvarying float value, kill;\nvarying vec3 worldCoordinate;\nvarying vec2 planeCoordinate;\nvarying vec3 surfaceNormal;\n\nvec2 splitFloat(float v) {\n  float vh = 255.0 * v;\n  float upper = floor(vh);\n  float lower = fract(vh);\n  return vec2(upper / 255.0, floor(lower * 16.0) / 16.0);\n}\n\nvoid main() {\n  if ((kill > 0.0) ||\n      (outOfRange(clipBounds[0], clipBounds[1], worldCoordinate))) discard;\n\n  vec2 ux = splitFloat(planeCoordinate.x / shape.x);\n  vec2 uy = splitFloat(planeCoordinate.y / shape.y);\n  gl_FragColor = vec4(pickId, ux.x, uy.x, ux.y + (uy.y/16.0));\n}\n"])

exports.createShader = function (gl) {
  var shader = createShader(gl, vertSrc, fragSrc, null, [
    {name: 'uv', type: 'vec4'},
    {name: 'f', type: 'vec3'},
    {name: 'normal', type: 'vec3'}
  ])
  shader.attributes.uv.location = 0
  shader.attributes.f.location = 1
  shader.attributes.normal.location = 2
  return shader
}
exports.createPickShader = function (gl) {
  var shader = createShader(gl, vertSrc, pickSrc, null, [
    {name: 'uv', type: 'vec4'},
    {name: 'f', type: 'vec3'},
    {name: 'normal', type: 'vec3'}
  ])
  shader.attributes.uv.location = 0
  shader.attributes.f.location = 1
  shader.attributes.normal.location = 2
  return shader
}
exports.createContourShader = function (gl) {
  var shader = createShader(gl, contourVertSrc, fragSrc, null, [
    {name: 'uv', type: 'vec4'},
    {name: 'f', type: 'float'}
  ])
  shader.attributes.uv.location = 0
  shader.attributes.f.location = 1
  return shader
}
exports.createPickContourShader = function (gl) {
  var shader = createShader(gl, contourVertSrc, pickSrc, null, [
    {name: 'uv', type: 'vec4'},
    {name: 'f', type: 'float'}
  ])
  shader.attributes.uv.location = 0
  shader.attributes.f.location = 1
  return shader
}


/***/ }),

/***/ 9499:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

"use strict";


module.exports = createSurfacePlot

var bits = __webpack_require__(8828)
var createBuffer = __webpack_require__(2762)
var createVAO = __webpack_require__(8116)
var createTexture = __webpack_require__(7766)
var pool = __webpack_require__(1888)
var colormap = __webpack_require__(6729)
var ops = __webpack_require__(5298)
var pack = __webpack_require__(9994)
var ndarray = __webpack_require__(9618)
var surfaceNets = __webpack_require__(3711)
var multiply = __webpack_require__(6760)
var invert = __webpack_require__(7608)
var bsearch = __webpack_require__(2478)
var gradient = __webpack_require__(6199)
var shaders = __webpack_require__(990)

var createShader = shaders.createShader
var createContourShader = shaders.createContourShader
var createPickShader = shaders.createPickShader
var createPickContourShader = shaders.createPickContourShader

var SURFACE_VERTEX_SIZE = 4 * (4 + 3 + 3)

var IDENTITY = [
  1, 0, 0, 0,
  0, 1, 0, 0,
  0, 0, 1, 0,
  0, 0, 0, 1 ]

var QUAD = [
  [0, 0],
  [0, 1],
  [1, 0],
  [1, 1],
  [1, 0],
  [0, 1]
]

var PERMUTATIONS = [
  [0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0]
]

;(function () {
  for (var i = 0; i < 3; ++i) {
    var p = PERMUTATIONS[i]
    var u = (i + 1) % 3
    var v = (i + 2) % 3
    p[u + 0] = 1
    p[v + 3] = 1
    p[i + 6] = 1
  }
})()

function SurfacePickResult (position, index, uv, level, dataCoordinate) {
  this.position = position
  this.index = index
  this.uv = uv
  this.level = level
  this.dataCoordinate = dataCoordinate
}

var N_COLORS = 256

function SurfacePlot (
  gl,
  shape,
  bounds,
  shader,
  pickShader,
  coordinates,
  vao,
  colorMap,
  contourShader,
  contourPickShader,
  contourBuffer,
  contourVAO,
  dynamicBuffer,
  dynamicVAO,
  objectOffset) {
  this.gl = gl
  this.shape = shape
  this.bounds = bounds
  this.objectOffset = objectOffset
  this.intensityBounds = []

  this._shader = shader
  this._pickShader = pickShader
  this._coordinateBuffer = coordinates
  this._vao = vao
  this._colorMap = colorMap

  this._contourShader = contourShader
  this._contourPickShader = contourPickShader
  this._contourBuffer = contourBuffer
  this._contourVAO = contourVAO
  this._contourOffsets = [[], [], []]
  this._contourCounts = [[], [], []]
  this._vertexCount = 0

  this._pickResult = new SurfacePickResult([0, 0, 0], [0, 0], [0, 0], [0, 0, 0], [0, 0, 0])

  this._dynamicBuffer = dynamicBuffer
  this._dynamicVAO = dynamicVAO
  this._dynamicOffsets = [0, 0, 0]
  this._dynamicCounts = [0, 0, 0]

  this.contourWidth = [ 1, 1, 1 ]
  this.contourLevels = [[1], [1], [1]]
  this.contourTint = [0, 0, 0]
  this.contourColor = [[0.5, 0.5, 0.5, 1], [0.5, 0.5, 0.5, 1], [0.5, 0.5, 0.5, 1]]

  this.showContour = true
  this.showSurface = true

  this.enableHighlight = [true, true, true]
  this.highlightColor = [[0, 0, 0, 1], [0, 0, 0, 1], [0, 0, 0, 1]]
  this.highlightTint = [ 1, 1, 1 ]
  this.highlightLevel = [-1, -1, -1]

  // Dynamic contour options
  this.enableDynamic = [ true, true, true ]
  this.dynamicLevel = [ NaN, NaN, NaN ]
  this.dynamicColor = [ [0, 0, 0, 1], [0, 0, 0, 1], [0, 0, 0, 1] ]
  this.dynamicTint = [ 1, 1, 1 ]
  this.dynamicWidth = [ 1, 1, 1 ]

  this.axesBounds = [[Infinity, Infinity, Infinity], [-Infinity, -Infinity, -Infinity]]
  this.surfaceProject = [ false, false, false ]
  this.contourProject = [[ false, false, false ],
    [ false, false, false ],
    [ false, false, false ]]

  this.colorBounds = [ false, false ]

  // Store xyz fields, need this for picking
  this._field = [
    ndarray(pool.mallocFloat(1024), [0, 0]),
    ndarray(pool.mallocFloat(1024), [0, 0]),
    ndarray(pool.mallocFloat(1024), [0, 0]) ]

  this.pickId = 1
  this.clipBounds = [[-Infinity, -Infinity, -Infinity], [Infinity, Infinity, Infinity]]

  this.snapToData = false

  this.pixelRatio = 1

  this.opacity = 1.0

  this.lightPosition = [10, 10000, 0]
  this.ambientLight = 0.8
  this.diffuseLight = 0.8
  this.specularLight = 2.0
  this.roughness = 0.5
  this.fresnel = 1.5
  this.vertexColor = 0

  this.dirty = true
}

var proto = SurfacePlot.prototype

proto.genColormap = function (name, opacityscale) {
  var hasAlpha = false

  var x = pack([colormap({
    colormap: name,
    nshades: N_COLORS,
    format: 'rgba'
  }).map(function (c, i) {
    var a = opacityscale ? getOpacityFromScale(i / 255.0, opacityscale) : c[3]
    if(a < 1) hasAlpha = true
    return [c[0], c[1], c[2], 255 * a]
  })])
  ops.divseq(x, 255.0)

  this.hasAlphaScale = hasAlpha
  return x
}

proto.isTransparent = function () {
  return this.opacity < 1 || this.hasAlphaScale
}

proto.isOpaque = function () {
  return !this.isTransparent()
}

proto.pickSlots = 1

proto.setPickBase = function (id) {
  this.pickId = id
}

function getOpacityFromScale(ratio, opacityscale) { // copied form gl-mesh3d
  if(!opacityscale) return 1
  if(!opacityscale.length) return 1

  for(var i = 0; i < opacityscale.length; ++i) {
    if(opacityscale.length < 2) return 1
    if(opacityscale[i][0] === ratio) return opacityscale[i][1]
    if(opacityscale[i][0] > ratio && i > 0) {
      var d = (opacityscale[i][0] - ratio) / (opacityscale[i][0] - opacityscale[i - 1][0])
      return opacityscale[i][1] * (1 - d) + d * opacityscale[i - 1][1]
    }
  }

  return 1
}

var ZERO_VEC = [0, 0, 0]

var PROJECT_DATA = {
  showSurface: false,
  showContour: false,
  projections: [IDENTITY.slice(), IDENTITY.slice(), IDENTITY.slice()],
  clipBounds: [
    [[0, 0, 0], [0, 0, 0]],
    [[0, 0, 0], [0, 0, 0]],
    [[0, 0, 0], [0, 0, 0]]]
}

function computeProjectionData (camera, obj) {
  var i, j, k

  // Compute cube properties
  var cubeAxis = (obj.axes && obj.axes.lastCubeProps.axis) || ZERO_VEC

  var showSurface = obj.showSurface
  var showContour = obj.showContour

  for (i = 0; i < 3; ++i) {
    showSurface = showSurface || obj.surfaceProject[i]
    for (j = 0; j < 3; ++j) {
      showContour = showContour || obj.contourProject[i][j]
    }
  }

  for (i = 0; i < 3; ++i) {
    // Construct projection onto axis
    var axisSquish = PROJECT_DATA.projections[i]
    for (j = 0; j < 16; ++j) {
      axisSquish[j] = 0
    }
    for (j = 0; j < 4; ++j) {
      axisSquish[5 * j] = 1
    }
    axisSquish[5 * i] = 0
    axisSquish[12 + i] = obj.axesBounds[+(cubeAxis[i] > 0)][i]
    multiply(axisSquish, camera.model, axisSquish)

    var nclipBounds = PROJECT_DATA.clipBounds[i]
    for (k = 0; k < 2; ++k) {
      for (j = 0; j < 3; ++j) {
        nclipBounds[k][j] = camera.clipBounds[k][j]
      }
    }
    nclipBounds[0][i] = -1e8
    nclipBounds[1][i] = 1e8
  }

  PROJECT_DATA.showSurface = showSurface
  PROJECT_DATA.showContour = showContour

  return PROJECT_DATA
}

var UNIFORMS = {
  model: IDENTITY,
  view: IDENTITY,
  projection: IDENTITY,
  inverseModel: IDENTITY.slice(),
  lowerBound: [0, 0, 0],
  upperBound: [0, 0, 0],
  colorMap: 0,
  clipBounds: [[0, 0, 0], [0, 0, 0]],
  height: 0.0,
  contourTint: 0,
  contourColor: [0, 0, 0, 1],
  permutation: [1, 0, 0, 0, 1, 0, 0, 0, 1],
  zOffset: -1e-4,
  objectOffset: [0, 0, 0],
  kambient: 1,
  kdiffuse: 1,
  kspecular: 1,
  lightPosition: [1000, 1000, 1000],
  eyePosition: [0, 0, 0],
  roughness: 1,
  fresnel: 1,
  opacity: 1,
  vertexColor: 0
}

var MATRIX_INVERSE = IDENTITY.slice()
var DEFAULT_PERM = [1, 0, 0, 0, 1, 0, 0, 0, 1]

function drawCore (params, transparent) {
  params = params || {}
  var gl = this.gl

  gl.disable(gl.CULL_FACE)

  this._colorMap.bind(0)

  var uniforms = UNIFORMS
  uniforms.model = params.model || IDENTITY
  uniforms.view = params.view || IDENTITY
  uniforms.projection = params.projection || IDENTITY
  uniforms.lowerBound = [this.bounds[0][0], this.bounds[0][1], this.colorBounds[0] || this.bounds[0][2]]
  uniforms.upperBound = [this.bounds[1][0], this.bounds[1][1], this.colorBounds[1] || this.bounds[1][2]]
  uniforms.objectOffset = this.objectOffset
  uniforms.contourColor = this.contourColor[0]

  uniforms.inverseModel = invert(uniforms.inverseModel, uniforms.model)

  for (var i = 0; i < 2; ++i) {
    var clipClamped = uniforms.clipBounds[i]
    for (var j = 0; j < 3; ++j) {
      clipClamped[j] = Math.min(Math.max(this.clipBounds[i][j], -1e8), 1e8)
    }
  }

  uniforms.kambient = this.ambientLight
  uniforms.kdiffuse = this.diffuseLight
  uniforms.kspecular = this.specularLight

  uniforms.roughness = this.roughness
  uniforms.fresnel = this.fresnel
  uniforms.opacity = this.opacity

  uniforms.height = 0.0
  uniforms.permutation = DEFAULT_PERM

  uniforms.vertexColor = this.vertexColor

  // Compute camera matrix inverse
  var invCameraMatrix = MATRIX_INVERSE
  multiply(invCameraMatrix, uniforms.view, uniforms.model)
  multiply(invCameraMatrix, uniforms.projection, invCameraMatrix)
  invert(invCameraMatrix, invCameraMatrix)

  for (i = 0; i < 3; ++i) {
    uniforms.eyePosition[i] = invCameraMatrix[12 + i] / invCameraMatrix[15]
  }

  var w = invCameraMatrix[15]
  for (i = 0; i < 3; ++i) {
    w += this.lightPosition[i] * invCameraMatrix[4 * i + 3]
  }
  for (i = 0; i < 3; ++i) {
    var s = invCameraMatrix[12 + i]
    for (j = 0; j < 3; ++j) {
      s += invCameraMatrix[4 * j + i] * this.lightPosition[j]
    }
    uniforms.lightPosition[i] = s / w
  }

  var projectData = computeProjectionData(uniforms, this)

  if (projectData.showSurface)  {
    // Set up uniforms
    this._shader.bind()
    this._shader.uniforms = uniforms

    // Draw it
    this._vao.bind()

    if (this.showSurface && this._vertexCount) {
      this._vao.draw(gl.TRIANGLES, this._vertexCount)
    }

    // Draw projections of surface
    for (i = 0; i < 3; ++i) {
      if (!this.surfaceProject[i] || !this.vertexCount) {
        continue
      }
      this._shader.uniforms.model = projectData.projections[i]
      this._shader.uniforms.clipBounds = projectData.clipBounds[i]
      this._vao.draw(gl.TRIANGLES, this._vertexCount)
    }

    this._vao.unbind()
  }

  if (projectData.showContour) {
    var shader = this._contourShader

    // Don't apply lighting to contours
    uniforms.kambient = 1.0
    uniforms.kdiffuse = 0.0
    uniforms.kspecular = 0.0
    uniforms.opacity = 1.0

    shader.bind()
    shader.uniforms = uniforms

    // Draw contour lines
    var vao = this._contourVAO
    vao.bind()

    // Draw contour levels
    for (i = 0; i < 3; ++i) {
      shader.uniforms.permutation = PERMUTATIONS[i]
      gl.lineWidth(this.contourWidth[i] * this.pixelRatio)

      for (j = 0; j < this.contourLevels[i].length; ++j) {
        if (j === this.highlightLevel[i]) {
          shader.uniforms.contourColor = this.highlightColor[i]
          shader.uniforms.contourTint = this.highlightTint[i]
        } else if (j === 0 || (j - 1) === this.highlightLevel[i]) {
          shader.uniforms.contourColor = this.contourColor[i]
          shader.uniforms.contourTint = this.contourTint[i]
        }
        if (!this._contourCounts[i][j]) {
          continue
        }

        shader.uniforms.height = this.contourLevels[i][j]
        vao.draw(gl.LINES, this._contourCounts[i][j], this._contourOffsets[i][j])
      }
    }

    // Draw projections of surface
    for (i = 0; i < 3; ++i) {
      shader.uniforms.model = projectData.projections[i]
      shader.uniforms.clipBounds = projectData.clipBounds[i]
      for (j = 0; j < 3; ++j) {
        if (!this.contourProject[i][j]) {
          continue
        }
        shader.uniforms.permutation = PERMUTATIONS[j]
        gl.lineWidth(this.contourWidth[j] * this.pixelRatio)
        for (var k = 0; k < this.contourLevels[j].length; ++k) {
          if (k === this.highlightLevel[j]) {
            shader.uniforms.contourColor = this.highlightColor[j]
            shader.uniforms.contourTint = this.highlightTint[j]
          } else if (k === 0 || (k - 1) === this.highlightLevel[j]) {
            shader.uniforms.contourColor = this.contourColor[j]
            shader.uniforms.contourTint = this.contourTint[j]
          }
          if (!this._contourCounts[j][k]) {
            continue
          }

          shader.uniforms.height = this.contourLevels[j][k]
          vao.draw(gl.LINES, this._contourCounts[j][k], this._contourOffsets[j][k])
        }
      }
    }

    vao.unbind()

    // Draw dynamic contours
    vao = this._dynamicVAO
    vao.bind()

    // Draw contour levels
    for (i = 0; i < 3; ++i) {
      if (this._dynamicCounts[i] === 0) {
        continue
      }

      shader.uniforms.model = uniforms.model
      shader.uniforms.clipBounds = uniforms.clipBounds
      shader.uniforms.permutation = PERMUTATIONS[i]
      gl.lineWidth(this.dynamicWidth[i] * this.pixelRatio)

      shader.uniforms.contourColor = this.dynamicColor[i]
      shader.uniforms.contourTint = this.dynamicTint[i]
      shader.uniforms.height = this.dynamicLevel[i]
      vao.draw(gl.LINES, this._dynamicCounts[i], this._dynamicOffsets[i])

      for (j = 0; j < 3; ++j) {
        if (!this.contourProject[j][i]) {
          continue
        }

        shader.uniforms.model = projectData.projections[j]
        shader.uniforms.clipBounds = projectData.clipBounds[j]
        vao.draw(gl.LINES, this._dynamicCounts[i], this._dynamicOffsets[i])
      }
    }

    vao.unbind()
  }
}

proto.draw = function (params) {
  return drawCore.call(this, params, false)
}

proto.drawTransparent = function (params) {
  return drawCore.call(this, params, true)
}

var PICK_UNIFORMS = {
  model: IDENTITY,
  view: IDENTITY,
  projection: IDENTITY,
  inverseModel: IDENTITY,
  clipBounds: [[0, 0, 0], [0, 0, 0]],
  height: 0.0,
  shape: [0, 0],
  pickId: 0,
  lowerBound: [0, 0, 0],
  upperBound: [0, 0, 0],
  zOffset: 0.0,
  objectOffset: [0, 0, 0],
  permutation: [1, 0, 0, 0, 1, 0, 0, 0, 1],
  lightPosition: [0, 0, 0],
  eyePosition: [0, 0, 0]
}

proto.drawPick = function (params) {
  params = params || {}
  var gl = this.gl
  gl.disable(gl.CULL_FACE)

  var uniforms = PICK_UNIFORMS
  uniforms.model = params.model || IDENTITY
  uniforms.view = params.view || IDENTITY
  uniforms.projection = params.projection || IDENTITY
  uniforms.shape = this._field[2].shape
  uniforms.pickId = this.pickId / 255.0
  uniforms.lowerBound = this.bounds[0]
  uniforms.upperBound = this.bounds[1]
  uniforms.objectOffset = this.objectOffset
  uniforms.permutation = DEFAULT_PERM

  for (var i = 0; i < 2; ++i) {
    var clipClamped = uniforms.clipBounds[i]
    for (var j = 0; j < 3; ++j) {
      clipClamped[j] = Math.min(Math.max(this.clipBounds[i][j], -1e8), 1e8)
    }
  }

  var projectData = computeProjectionData(uniforms, this)

  if (projectData.showSurface) {
    // Set up uniforms
    this._pickShader.bind()
    this._pickShader.uniforms = uniforms

    // Draw it
    this._vao.bind()
    this._vao.draw(gl.TRIANGLES, this._vertexCount)

    // Draw projections of surface
    for (i = 0; i < 3; ++i) {
      if (!this.surfaceProject[i]) {
        continue
      }
      this._pickShader.uniforms.model = projectData.projections[i]
      this._pickShader.uniforms.clipBounds = projectData.clipBounds[i]
      this._vao.draw(gl.TRIANGLES, this._vertexCount)
    }

    this._vao.unbind()
  }

  if (projectData.showContour) {
    var shader = this._contourPickShader

    shader.bind()
    shader.uniforms = uniforms

    var vao = this._contourVAO
    vao.bind()

    for (j = 0; j < 3; ++j) {
      gl.lineWidth(this.contourWidth[j] * this.pixelRatio)
      shader.uniforms.permutation = PERMUTATIONS[j]
      for (i = 0; i < this.contourLevels[j].length; ++i) {
        if (this._contourCounts[j][i]) {
          shader.uniforms.height = this.contourLevels[j][i]
          vao.draw(gl.LINES, this._contourCounts[j][i], this._contourOffsets[j][i])
        }
      }
    }

    // Draw projections of surface
    for (i = 0; i < 3; ++i) {
      shader.uniforms.model = projectData.projections[i]
      shader.uniforms.clipBounds = projectData.clipBounds[i]

      for (j = 0; j < 3; ++j) {
        if (!this.contourProject[i][j]) {
          continue
        }

        shader.uniforms.permutation = PERMUTATIONS[j]
        gl.lineWidth(this.contourWidth[j] * this.pixelRatio)
        for (var k = 0; k < this.contourLevels[j].length; ++k) {
          if (this._contourCounts[j][k]) {
            shader.uniforms.height = this.contourLevels[j][k]
            vao.draw(gl.LINES, this._contourCounts[j][k], this._contourOffsets[j][k])
          }
        }
      }
    }

    vao.unbind()
  }
}

proto.pick = function (selection) {
  if (!selection) {
    return null
  }

  if (selection.id !== this.pickId) {
    return null
  }

  var shape = this._field[2].shape

  var result = this._pickResult

  // Compute uv coordinate
  var x = shape[0] * (selection.value[0] + (selection.value[2] >> 4) / 16.0) / 255.0
  var ix = Math.floor(x)
  var fx = x - ix

  var y = shape[1] * (selection.value[1] + (selection.value[2] & 15) / 16.0) / 255.0
  var iy = Math.floor(y)
  var fy = y - iy

  ix += 1
  iy += 1

  // Compute xyz coordinate
  var pos = result.position
  pos[0] = pos[1] = pos[2] = 0
  for (var dx = 0; dx < 2; ++dx) {
    var s = dx ? fx : 1.0 - fx
    for (var dy = 0; dy < 2; ++dy) {
      var t = dy ? fy : 1.0 - fy

      var r = ix + dx
      var c = iy + dy
      var w = s * t

      for (var i = 0; i < 3; ++i) {
        pos[i] += this._field[i].get(r, c) * w
      }
    }
  }

  // Find closest level
  var levelIndex = this._pickResult.level
  for (var j = 0; j < 3; ++j) {
    levelIndex[j] = bsearch.le(this.contourLevels[j], pos[j])
    if (levelIndex[j] < 0) {
      if (this.contourLevels[j].length > 0) {
        levelIndex[j] = 0
      }
    } else if (levelIndex[j] < this.contourLevels[j].length - 1) {
      var a = this.contourLevels[j][levelIndex[j]]
      var b = this.contourLevels[j][levelIndex[j] + 1]
      if (Math.abs(a - pos[j]) > Math.abs(b - pos[j])) {
        levelIndex[j] += 1
      }
    }
  }

  result.index[0] = fx < 0.5 ? ix : (ix + 1)
  result.index[1] = fy < 0.5 ? iy : (iy + 1)

  result.uv[0] = x / shape[0]
  result.uv[1] = y / shape[1]

  for (i = 0; i < 3; ++i) {
    result.dataCoordinate[i] = this._field[i].get(result.index[0], result.index[1])
  }

  return result
}

proto.padField = function(dstField, srcField) {
  var srcShape = srcField.shape.slice()
  var dstShape = dstField.shape.slice()

  // Center
  ops.assign(dstField.lo(1, 1).hi(srcShape[0], srcShape[1]), srcField)

  // Edges
  ops.assign(dstField.lo(1).hi(srcShape[0], 1),
    srcField.hi(srcShape[0], 1))
  ops.assign(dstField.lo(1, dstShape[1] - 1).hi(srcShape[0], 1),
    srcField.lo(0, srcShape[1] - 1).hi(srcShape[0], 1))
  ops.assign(dstField.lo(0, 1).hi(1, srcShape[1]),
    srcField.hi(1))
  ops.assign(dstField.lo(dstShape[0] - 1, 1).hi(1, srcShape[1]),
    srcField.lo(srcShape[0] - 1))
  // Corners
  dstField.set(0, 0, srcField.get(0, 0))
  dstField.set(0, dstShape[1] - 1, srcField.get(0, srcShape[1] - 1))
  dstField.set(dstShape[0] - 1, 0, srcField.get(srcShape[0] - 1, 0))
  dstField.set(dstShape[0] - 1, dstShape[1] - 1, srcField.get(srcShape[0] - 1, srcShape[1] - 1))
}

function handleArray (param, ctor) {
  if (Array.isArray(param)) {
    return [ ctor(param[0]), ctor(param[1]), ctor(param[2]) ]
  }
  return [ ctor(param), ctor(param), ctor(param) ]
}

function toColor (x) {
  if (Array.isArray(x)) {
    if (x.length === 3) {
      return [x[0], x[1], x[2], 1]
    }
    return [x[0], x[1], x[2], x[3]]
  }
  return [0, 0, 0, 1]
}

function handleColor (param) {
  if (Array.isArray(param)) {
    if (Array.isArray(param)) {
      return [
        toColor(param[0]),
        toColor(param[1]),
        toColor(param[2]) ]
    } else {
      var c = toColor(param)
      return [
        c.slice(),
        c.slice(),
        c.slice() ]
    }
  }
}

proto.update = function (params) {
  params = params || {}

  this.objectOffset = params.objectOffset || this.objectOffset

  this.dirty = true

  if ('contourWidth' in params) {
    this.contourWidth = handleArray(params.contourWidth, Number)
  }
  if ('showContour' in params) {
    this.showContour = handleArray(params.showContour, Boolean)
  }
  if ('showSurface' in params) {
    this.showSurface = !!params.showSurface
  }
  if ('contourTint' in params) {
    this.contourTint = handleArray(params.contourTint, Boolean)
  }
  if ('contourColor' in params) {
    this.contourColor = handleColor(params.contourColor)
  }
  if ('contourProject' in params) {
    this.contourProject = handleArray(params.contourProject, function (x) {
      return handleArray(x, Boolean)
    })
  }
  if ('surfaceProject' in params) {
    this.surfaceProject = params.surfaceProject
  }
  if ('dynamicColor' in params) {
    this.dynamicColor = handleColor(params.dynamicColor)
  }
  if ('dynamicTint' in params) {
    this.dynamicTint = handleArray(params.dynamicTint, Number)
  }
  if ('dynamicWidth' in params) {
    this.dynamicWidth = handleArray(params.dynamicWidth, Number)
  }
  if ('opacity' in params) {
    this.opacity = params.opacity
  }
  if('opacityscale' in params) {
    this.opacityscale = params.opacityscale
  }
  if ('colorBounds' in params) {
    this.colorBounds = params.colorBounds
  }
  if ('vertexColor' in params) {
    this.vertexColor = params.vertexColor ? 1 : 0;
  }
  if ('colormap' in params) {
    this._colorMap.setPixels(this.genColormap(params.colormap, this.opacityscale))
  }

  var field = params.field || (params.coords && params.coords[2]) || null
  var levelsChanged = false

  if (!field) {
    if (this._field[2].shape[0] || this._field[2].shape[2]) {
      field = this._field[2].lo(1, 1).hi(this._field[2].shape[0] - 2, this._field[2].shape[1] - 2)
    } else {
      field = this._field[2].hi(0, 0)
    }
  }

  // Update field
  if ('field' in params || 'coords' in params) {
    var fsize = (field.shape[0] + 2) * (field.shape[1] + 2)

    // Resize if necessary
    if (fsize > this._field[2].data.length) {
      pool.freeFloat(this._field[2].data)
      this._field[2].data = pool.mallocFloat(bits.nextPow2(fsize))
    }

    // Pad field
    this._field[2] = ndarray(this._field[2].data, [field.shape[0] + 2, field.shape[1] + 2])
    this.padField(this._field[2], field)

    // Save shape of field
    this.shape = field.shape.slice()
    var shape = this.shape

    // Resize coordinate fields if necessary
    for (var i = 0; i < 2; ++i) {
      if (this._field[2].size > this._field[i].data.length) {
        pool.freeFloat(this._field[i].data)
        this._field[i].data = pool.mallocFloat(this._field[2].size)
      }
      this._field[i] = ndarray(this._field[i].data, [shape[0] + 2, shape[1] + 2])
    }

    // Generate x/y coordinates
    if (params.coords) {
      var coords = params.coords
      if (!Array.isArray(coords) || coords.length !== 3) {
        throw new Error('gl-surface: invalid coordinates for x/y')
      }
      for (i = 0; i < 2; ++i) {
        var coord = coords[i]
        for (j = 0; j < 2; ++j) {
          if (coord.shape[j] !== shape[j]) {
            throw new Error('gl-surface: coords have incorrect shape')
          }
        }
        this.padField(this._field[i], coord)
      }
    } else if (params.ticks) {
      var ticks = params.ticks
      if (!Array.isArray(ticks) || ticks.length !== 2) {
        throw new Error('gl-surface: invalid ticks')
      }
      for (i = 0; i < 2; ++i) {
        var tick = ticks[i]
        if (Array.isArray(tick) || tick.length) {
          tick = ndarray(tick)
        }
        if (tick.shape[0] !== shape[i]) {
          throw new Error('gl-surface: invalid tick length')
        }
        // Make a copy view of the tick array
        var tick2 = ndarray(tick.data, shape)
        tick2.stride[i] = tick.stride[0]
        tick2.stride[i ^ 1] = 0

        // Fill in field array
        this.padField(this._field[i], tick2)
      }
    } else {
      for (i = 0; i < 2; ++i) {
        var offset = [0, 0]
        offset[i] = 1
        this._field[i] = ndarray(this._field[i].data, [shape[0] + 2, shape[1] + 2], offset, 0)
      }
      this._field[0].set(0, 0, 0)
      for (var j = 0; j < shape[0]; ++j) {
        this._field[0].set(j + 1, 0, j)
      }
      this._field[0].set(shape[0] + 1, 0, shape[0] - 1)
      this._field[1].set(0, 0, 0)
      for (j = 0; j < shape[1]; ++j) {
        this._field[1].set(0, j + 1, j)
      }
      this._field[1].set(0, shape[1] + 1, shape[1] - 1)
    }

    // Save shape
    var fields = this._field

    // Compute surface normals
    var dfields = ndarray(pool.mallocFloat(fields[2].size * 3 * 2), [3, shape[0] + 2, shape[1] + 2, 2])
    for (i = 0; i < 3; ++i) {
      gradient(dfields.pick(i), fields[i], 'mirror')
    }
    var normals = ndarray(pool.mallocFloat(fields[2].size * 3), [shape[0] + 2, shape[1] + 2, 3])
    for (i = 0; i < shape[0] + 2; ++i) {
      for (j = 0; j < shape[1] + 2; ++j) {
        var dxdu = dfields.get(0, i, j, 0)
        var dxdv = dfields.get(0, i, j, 1)
        var dydu = dfields.get(1, i, j, 0)
        var dydv = dfields.get(1, i, j, 1)
        var dzdu = dfields.get(2, i, j, 0)
        var dzdv = dfields.get(2, i, j, 1)

        var nx = dydu * dzdv - dydv * dzdu
        var ny = dzdu * dxdv - dzdv * dxdu
        var nz = dxdu * dydv - dxdv * dydu

        var nl = Math.sqrt(nx * nx + ny * ny + nz * nz)
        if (nl < 1e-8) {
          nl = Math.max(Math.abs(nx), Math.abs(ny), Math.abs(nz))
          if (nl < 1e-8) {
            nz = 1.0
            ny = nx = 0.0
            nl = 1.0
          } else {
            nl = 1.0 / nl
          }
        } else {
          nl = 1.0 / Math.sqrt(nl)
        }

        normals.set(i, j, 0, nx * nl)
        normals.set(i, j, 1, ny * nl)
        normals.set(i, j, 2, nz * nl)
      }
    }
    pool.free(dfields.data)

    // Initialize surface
    var lo = [ Infinity, Infinity, Infinity ]
    var hi = [ -Infinity, -Infinity, -Infinity ]
    var lo_intensity = Infinity
    var hi_intensity = -Infinity
    var count = (shape[0] - 1) * (shape[1] - 1) * 6
    var tverts = pool.mallocFloat(bits.nextPow2(10 * count))
    var tptr = 0
    var vertexCount = 0
    for (i = 0; i < shape[0] - 1; ++i) {
      j_loop:
      for (j = 0; j < shape[1] - 1; ++j) {
        // Test for NaNs
        for (var dx = 0; dx < 2; ++dx) {
          for (var dy = 0; dy < 2; ++dy) {
            for (var k = 0; k < 3; ++k) {
              var f = this._field[k].get(1 + i + dx, 1 + j + dy)
              if (isNaN(f) || !isFinite(f)) {
                continue j_loop
              }
            }
          }
        }
        for (k = 0; k < 6; ++k) {
          var r = i + QUAD[k][0]
          var c = j + QUAD[k][1]

          var tx = this._field[0].get(r + 1, c + 1)
          var ty = this._field[1].get(r + 1, c + 1)
          f =      this._field[2].get(r + 1, c + 1)

          nx = normals.get(r + 1, c + 1, 0)
          ny = normals.get(r + 1, c + 1, 1)
          nz = normals.get(r + 1, c + 1, 2)

          if (params.intensity) {
            vf = params.intensity.get(r, c)
          }

          var vf = (params.intensity) ?
            params.intensity.get(r, c) :
            f + this.objectOffset[2];

          tverts[tptr++] = r
          tverts[tptr++] = c
          tverts[tptr++] = tx
          tverts[tptr++] = ty
          tverts[tptr++] = f
          tverts[tptr++] = 0
          tverts[tptr++] = vf
          tverts[tptr++] = nx
          tverts[tptr++] = ny
          tverts[tptr++] = nz

          lo[0] = Math.min(lo[0], tx + this.objectOffset[0])
          lo[1] = Math.min(lo[1], ty + this.objectOffset[1])
          lo[2] = Math.min(lo[2], f  + this.objectOffset[2])
          lo_intensity = Math.min(lo_intensity, vf)

          hi[0] = Math.max(hi[0], tx + this.objectOffset[0])
          hi[1] = Math.max(hi[1], ty + this.objectOffset[1])
          hi[2] = Math.max(hi[2], f  + this.objectOffset[2])
          hi_intensity = Math.max(hi_intensity, vf)

          vertexCount += 1
        }
      }
    }

    if (params.intensityBounds) {
      lo_intensity = +params.intensityBounds[0]
      hi_intensity = +params.intensityBounds[1]
    }

    // Scale all vertex intensities
    for (i = 6; i < tptr; i += 10) {
      tverts[i] = (tverts[i] - lo_intensity) / (hi_intensity - lo_intensity)
    }

    this._vertexCount = vertexCount
    this._coordinateBuffer.update(tverts.subarray(0, tptr))
    pool.freeFloat(tverts)
    pool.free(normals.data)

    // Update bounds
    this.bounds = [lo, hi]

    // Save intensity
    this.intensity = params.intensity || this._field[2]

    if(this.intensityBounds[0] !== lo_intensity || this.intensityBounds[1] !== hi_intensity) {
        levelsChanged = true
    }

    // Save intensity bound
    this.intensityBounds = [lo_intensity, hi_intensity]
  }

  // Update level crossings
  if ('levels' in params) {
    var levels = params.levels
    if (!Array.isArray(levels[0])) {
      levels = [ [], [], levels ]
    } else {
      levels = levels.slice()
    }
    for (i = 0; i < 3; ++i) {
      levels[i] = levels[i].slice()
      levels[i].sort(function (a, b) {
        return a - b
      })
    }
    for (i = 0; i < 3; ++i) {
      for (j = 0; j < levels[i].length; ++j) {
        levels[i][j] -= this.objectOffset[i]
      }
    }
    change_test:
    for (i = 0; i < 3; ++i) {
      if (levels[i].length !== this.contourLevels[i].length) {
        levelsChanged = true
        break
      }
      for (j = 0; j < levels[i].length; ++j) {
        if (levels[i][j] !== this.contourLevels[i][j]) {
          levelsChanged = true
          break change_test
        }
      }
    }
    this.contourLevels = levels
  }

  if (levelsChanged) {
    fields = this._field
    shape = this.shape

    // Update contour lines
    var contourVerts = []

    for (var dim = 0; dim < 3; ++dim) {
      var contourLevel = this.contourLevels[dim]

      var levelOffsets = []
      var levelCounts = []

      var parts = [0, 0, 0]

      for (i = 0; i < contourLevel.length; ++i) {
        var graph = surfaceNets(this._field[dim], contourLevel[i])

        levelOffsets.push((contourVerts.length / 5) | 0)
        vertexCount = 0

        edge_loop:
        for (j = 0; j < graph.cells.length; ++j) {
          var e = graph.cells[j]
          for (k = 0; k < 2; ++k) {
            var p = graph.positions[e[k]]

            var x = p[0]
            var ix = Math.floor(x) | 0
            var fx = x - ix

            var y = p[1]
            var iy = Math.floor(y) | 0
            var fy = y - iy

            var hole = false
            axis_loop:
            for (var axis = 0; axis < 3; ++axis) {
              parts[axis] = 0.0
              var iu = (dim + axis + 1) % 3
              for (dx = 0; dx < 2; ++dx) {
                var s = dx ? fx : 1.0 - fx
                r = Math.min(Math.max(ix + dx, 0), shape[0]) | 0
                for (dy = 0; dy < 2; ++dy) {
                  var t = dy ? fy : 1.0 - fy
                  c = Math.min(Math.max(iy + dy, 0), shape[1]) | 0

                  if (axis < 2) {
                    f = this._field[iu].get(r, c)
                  } else {
                    f = (this.intensity.get(r, c) - this.intensityBounds[0]) / (this.intensityBounds[1] - this.intensityBounds[0])
                  }
                  if (!isFinite(f) || isNaN(f)) {
                    hole = true
                    break axis_loop
                  }

                  var w = s * t
                  parts[axis] += w * f
                }
              }
            }

            if (!hole) {
              contourVerts.push(
                parts[0],
                parts[1],
                p[0],
                p[1],
                parts[2]
              )
              vertexCount += 1
            } else {
              if (k > 0) {
                // If we already added first edge, pop off verts
                for (var l = 0; l < 5; ++l) {
                  contourVerts.pop()
                }
                vertexCount -= 1
              }
              continue edge_loop
            }
          }
        }
        levelCounts.push(vertexCount)
      }

      // Store results
      this._contourOffsets[dim] = levelOffsets
      this._contourCounts[dim] = levelCounts

    }

    var floatBuffer = pool.mallocFloat(contourVerts.length)
    for (i = 0; i < contourVerts.length; ++i) {
      floatBuffer[i] = contourVerts[i]
    }
    this._contourBuffer.update(floatBuffer)
    pool.freeFloat(floatBuffer)
  }
}

proto.dispose = function () {
  this._shader.dispose()
  this._vao.dispose()
  this._coordinateBuffer.dispose()
  this._colorMap.dispose()
  this._contourBuffer.dispose()
  this._contourVAO.dispose()
  this._contourShader.dispose()
  this._contourPickShader.dispose()
  this._dynamicBuffer.dispose()
  this._dynamicVAO.dispose()
  for (var i = 0; i < 3; ++i) {
    pool.freeFloat(this._field[i].data)
  }
}

proto.highlight = function (selection) {
  var i

  if (!selection) {
    this._dynamicCounts = [0, 0, 0]
    this.dyanamicLevel = [NaN, NaN, NaN]
    this.highlightLevel = [-1, -1, -1]
    return
  }

  for (i = 0; i < 3; ++i) {
    if (this.enableHighlight[i]) {
      this.highlightLevel[i] = selection.level[i]
    } else {
      this.highlightLevel[i] = -1
    }
  }

  var levels
  if (this.snapToData) {
    levels = selection.dataCoordinate
  } else {
    levels = selection.position
  }
  for (i = 0; i < 3; ++i) {
    levels[i] -= this.objectOffset[i]
  }
  if ((!this.enableDynamic[0] || levels[0] === this.dynamicLevel[0]) &&
    (!this.enableDynamic[1] || levels[1] === this.dynamicLevel[1]) &&
    (!this.enableDynamic[2] || levels[2] === this.dynamicLevel[2])) {
    return
  }

  var vertexCount = 0
  var shape = this.shape
  var scratchBuffer = pool.mallocFloat(12 * shape[0] * shape[1])

  for (var d = 0; d < 3; ++d) {
    if (!this.enableDynamic[d]) {
      this.dynamicLevel[d] = NaN
      this._dynamicCounts[d] = 0
      continue
    }

    this.dynamicLevel[d] = levels[d]

    var u = (d + 1) % 3
    var v = (d + 2) % 3

    var f = this._field[d]
    var g = this._field[u]
    var h = this._field[v]

    var graph = surfaceNets(f, levels[d])
    var edges = graph.cells
    var positions = graph.positions

    this._dynamicOffsets[d] = vertexCount

    for (i = 0; i < edges.length; ++i) {
      var e = edges[i]
      for (var j = 0; j < 2; ++j) {
        var p = positions[e[j]]

        var x = +p[0]
        var ix = x | 0
        var jx = Math.min(ix + 1, shape[0]) | 0
        var fx = x - ix
        var hx = 1.0 - fx

        var y = +p[1]
        var iy = y | 0
        var jy = Math.min(iy + 1, shape[1]) | 0
        var fy = y - iy
        var hy = 1.0 - fy

        var w00 = hx * hy
        var w01 = hx * fy
        var w10 = fx * hy
        var w11 = fx * fy

        var cu = w00 * g.get(ix, iy) +
          w01 * g.get(ix, jy) +
          w10 * g.get(jx, iy) +
          w11 * g.get(jx, jy)

        var cv = w00 * h.get(ix, iy) +
          w01 * h.get(ix, jy) +
          w10 * h.get(jx, iy) +
          w11 * h.get(jx, jy)

        if (isNaN(cu) || isNaN(cv)) {
          if (j) {
            vertexCount -= 1
          }
          break
        }

        scratchBuffer[2 * vertexCount + 0] = cu
        scratchBuffer[2 * vertexCount + 1] = cv

        vertexCount += 1
      }
    }

    this._dynamicCounts[d] = vertexCount - this._dynamicOffsets[d]
  }

  this._dynamicBuffer.update(scratchBuffer.subarray(0, 2 * vertexCount))
  pool.freeFloat(scratchBuffer)
}

function createSurfacePlot (params) {
  var gl = params.gl

  var shader = createShader(gl)
  var pickShader = createPickShader(gl)
  var contourShader = createContourShader(gl)
  var contourPickShader = createPickContourShader(gl)

  var coordinateBuffer = createBuffer(gl)
  var vao = createVAO(gl, [
    { buffer: coordinateBuffer,
      size: 4,
      stride: SURFACE_VERTEX_SIZE,
      offset: 0
    },
    { buffer: coordinateBuffer,
      size: 3,
      stride: SURFACE_VERTEX_SIZE,
      offset: 16
    },
    {
      buffer: coordinateBuffer,
      size: 3,
      stride: SURFACE_VERTEX_SIZE,
      offset: 28
    }
  ])

  var contourBuffer = createBuffer(gl)
  var contourVAO = createVAO(gl, [
    {
      buffer: contourBuffer,
      size: 4,
      stride: 20,
      offset: 0
    },
    {
      buffer: contourBuffer,
      size: 1,
      stride: 20,
      offset: 16
    }
  ])

  var dynamicBuffer = createBuffer(gl)
  var dynamicVAO = createVAO(gl, [
    {
      buffer: dynamicBuffer,
      size: 2,
      type: gl.FLOAT
    }])

  var cmap = createTexture(gl, 1, N_COLORS, gl.RGBA, gl.UNSIGNED_BYTE)
  cmap.minFilter = gl.LINEAR
  cmap.magFilter = gl.LINEAR

  var surface = new SurfacePlot(
    gl,
    [0, 0], // shape
    [[0, 0, 0], [0, 0, 0]], // bounds
    shader,
    pickShader,
    coordinateBuffer,
    vao,
    cmap,
    contourShader,
    contourPickShader,
    contourBuffer,
    contourVAO,
    dynamicBuffer,
    dynamicVAO,
    [0, 0, 0] // objectOffset
  )

  var nparams = {
    levels: [[], [], []]
  }
  for (var id in params) {
    nparams[id] = params[id]
  }
  nparams.colormap = nparams.colormap || 'jet'

  surface.update(nparams)

  return surface
}


/***/ }),

/***/ 7766:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

"use strict";


var ndarray = __webpack_require__(9618)
var ops     = __webpack_require__(5298)
var pool    = __webpack_require__(1888)

module.exports = createTexture2D

var linearTypes = null
var filterTypes = null
var wrapTypes   = null

function lazyInitLinearTypes(gl) {
  linearTypes = [
    gl.LINEAR,
    gl.NEAREST_MIPMAP_LINEAR,
    gl.LINEAR_MIPMAP_NEAREST,
    gl.LINEAR_MIPMAP_NEAREST
  ]
  filterTypes = [
    gl.NEAREST,
    gl.LINEAR,
    gl.NEAREST_MIPMAP_NEAREST,
    gl.NEAREST_MIPMAP_LINEAR,
    gl.LINEAR_MIPMAP_NEAREST,
    gl.LINEAR_MIPMAP_LINEAR
  ]
  wrapTypes = [
    gl.REPEAT,
    gl.CLAMP_TO_EDGE,
    gl.MIRRORED_REPEAT
  ]
}

function acceptTextureDOM (obj) {
  return (
    ('undefined' != typeof HTMLCanvasElement && obj instanceof HTMLCanvasElement) ||
    ('undefined' != typeof HTMLImageElement && obj instanceof HTMLImageElement) ||
    ('undefined' != typeof HTMLVideoElement && obj instanceof HTMLVideoElement) ||
    ('undefined' != typeof ImageData && obj instanceof ImageData))
}

var convertFloatToUint8 = function(out, inp) {
  ops.muls(out, inp, 255.0)
}

function reshapeTexture(tex, w, h) {
  var gl = tex.gl
  var maxSize = gl.getParameter(gl.MAX_TEXTURE_SIZE)
  if(w < 0 || w > maxSize || h < 0 || h > maxSize) {
    throw new Error('gl-texture2d: Invalid texture size')
  }
  tex._shape = [w, h]
  tex.bind()
  gl.texImage2D(gl.TEXTURE_2D, 0, tex.format, w, h, 0, tex.format, tex.type, null)
  tex._mipLevels = [0]
  return tex
}

function Texture2D(gl, handle, width, height, format, type) {
  this.gl = gl
  this.handle = handle
  this.format = format
  this.type = type
  this._shape = [width, height]
  this._mipLevels = [0]
  this._magFilter = gl.NEAREST
  this._minFilter = gl.NEAREST
  this._wrapS = gl.CLAMP_TO_EDGE
  this._wrapT = gl.CLAMP_TO_EDGE
  this._anisoSamples = 1

  var parent = this
  var wrapVector = [this._wrapS, this._wrapT]
  Object.defineProperties(wrapVector, [
    {
      get: function() {
        return parent._wrapS
      },
      set: function(v) {
        return parent.wrapS = v
      }
    },
    {
      get: function() {
        return parent._wrapT
      },
      set: function(v) {
        return parent.wrapT = v
      }
    }
  ])
  this._wrapVector = wrapVector

  var shapeVector = [this._shape[0], this._shape[1]]
  Object.defineProperties(shapeVector, [
    {
      get: function() {
        return parent._shape[0]
      },
      set: function(v) {
        return parent.width = v
      }
    },
    {
      get: function() {
        return parent._shape[1]
      },
      set: function(v) {
        return parent.height = v
      }
    }
  ])
  this._shapeVector = shapeVector
}

var proto = Texture2D.prototype

Object.defineProperties(proto, {
  minFilter: {
    get: function() {
      return this._minFilter
    },
    set: function(v) {
      this.bind()
      var gl = this.gl
      if(this.type === gl.FLOAT && linearTypes.indexOf(v) >= 0) {
        if(!gl.getExtension('OES_texture_float_linear')) {
          v = gl.NEAREST
        }
      }
      if(filterTypes.indexOf(v) < 0) {
        throw new Error('gl-texture2d: Unknown filter mode ' + v)
      }
      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, v)
      return this._minFilter = v
    }
  },
  magFilter: {
    get: function() {
      return this._magFilter
    },
    set: function(v) {
      this.bind()
      var gl = this.gl
      if(this.type === gl.FLOAT && linearTypes.indexOf(v) >= 0) {
        if(!gl.getExtension('OES_texture_float_linear')) {
          v = gl.NEAREST
        }
      }
      if(filterTypes.indexOf(v) < 0) {
        throw new Error('gl-texture2d: Unknown filter mode ' + v)
      }
      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, v)
      return this._magFilter = v
    }
  },
  mipSamples: {
    get: function() {
      return this._anisoSamples
    },
    set: function(i) {
      var psamples = this._anisoSamples
      this._anisoSamples = Math.max(i, 1)|0
      if(psamples !== this._anisoSamples) {
        var ext = this.gl.getExtension('EXT_texture_filter_anisotropic')
        if(ext) {
          this.gl.texParameterf(this.gl.TEXTURE_2D, ext.TEXTURE_MAX_ANISOTROPY_EXT, this._anisoSamples)
        }
      }
      return this._anisoSamples
    }
  },
  wrapS: {
    get: function() {
      return this._wrapS
    },
    set: function(v) {
      this.bind()
      if(wrapTypes.indexOf(v) < 0) {
        throw new Error('gl-texture2d: Unknown wrap mode ' + v)
      }
      this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_S, v)
      return this._wrapS = v
    }
  },
  wrapT: {
    get: function() {
      return this._wrapT
    },
    set: function(v) {
      this.bind()
      if(wrapTypes.indexOf(v) < 0) {
        throw new Error('gl-texture2d: Unknown wrap mode ' + v)
      }
      this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_T, v)
      return this._wrapT = v
    }
  },
  wrap: {
    get: function() {
      return this._wrapVector
    },
    set: function(v) {
      if(!Array.isArray(v)) {
        v = [v,v]
      }
      if(v.length !== 2) {
        throw new Error('gl-texture2d: Must specify wrap mode for rows and columns')
      }
      for(var i=0; i<2; ++i) {
        if(wrapTypes.indexOf(v[i]) < 0) {
          throw new Error('gl-texture2d: Unknown wrap mode ' + v)
        }
      }
      this._wrapS = v[0]
      this._wrapT = v[1]

      var gl = this.gl
      this.bind()
      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, this._wrapS)
      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, this._wrapT)

      return v
    }
  },
  shape: {
    get: function() {
      return this._shapeVector
    },
    set: function(x) {
      if(!Array.isArray(x)) {
        x = [x|0,x|0]
      } else {
        if(x.length !== 2) {
          throw new Error('gl-texture2d: Invalid texture shape')
        }
      }
      reshapeTexture(this, x[0]|0, x[1]|0)
      return [x[0]|0, x[1]|0]
    }
  },
  width: {
    get: function() {
      return this._shape[0]
    },
    set: function(w) {
      w = w|0
      reshapeTexture(this, w, this._shape[1])
      return w
    }
  },
  height: {
    get: function() {
      return this._shape[1]
    },
    set: function(h) {
      h = h|0
      reshapeTexture(this, this._shape[0], h)
      return h
    }
  }
})

proto.bind = function(unit) {
  var gl = this.gl
  if(unit !== undefined) {
    gl.activeTexture(gl.TEXTURE0 + (unit|0))
  }
  gl.bindTexture(gl.TEXTURE_2D, this.handle)
  if(unit !== undefined) {
    return (unit|0)
  }
  return gl.getParameter(gl.ACTIVE_TEXTURE) - gl.TEXTURE0
}

proto.dispose = function() {
  this.gl.deleteTexture(this.handle)
}

proto.generateMipmap = function() {
  this.bind()
  this.gl.generateMipmap(this.gl.TEXTURE_2D)

  //Update mip levels
  var l = Math.min(this._shape[0], this._shape[1])
  for(var i=0; l>0; ++i, l>>>=1) {
    if(this._mipLevels.indexOf(i) < 0) {
      this._mipLevels.push(i)
    }
  }
}

proto.setPixels = function(data, x_off, y_off, mip_level) {
  var gl = this.gl
  this.bind()
  if(Array.isArray(x_off)) {
    mip_level = y_off
    y_off = x_off[1]|0
    x_off = x_off[0]|0
  } else {
    x_off = x_off || 0
    y_off = y_off || 0
  }
  mip_level = mip_level || 0
  var directData = acceptTextureDOM(data) ? data : data.raw
  if(directData) {
    var needsMip = this._mipLevels.indexOf(mip_level) < 0
    if(needsMip) {
      gl.texImage2D(gl.TEXTURE_2D, 0, this.format, this.format, this.type, directData)
      this._mipLevels.push(mip_level)
    } else {
      gl.texSubImage2D(gl.TEXTURE_2D, mip_level, x_off, y_off, this.format, this.type, directData)
    }
  } else if(data.shape && data.stride && data.data) {
    if(data.shape.length < 2 ||
       x_off + data.shape[1] > this._shape[1]>>>mip_level ||
       y_off + data.shape[0] > this._shape[0]>>>mip_level ||
       x_off < 0 ||
       y_off < 0) {
      throw new Error('gl-texture2d: Texture dimensions are out of bounds')
    }
    texSubImageArray(gl, x_off, y_off, mip_level, this.format, this.type, this._mipLevels, data)
  } else {
    throw new Error('gl-texture2d: Unsupported data type')
  }
}


function isPacked(shape, stride) {
  if(shape.length === 3) {
    return  (stride[2] === 1) &&
            (stride[1] === shape[0]*shape[2]) &&
            (stride[0] === shape[2])
  }
  return  (stride[0] === 1) &&
          (stride[1] === shape[0])
}

function texSubImageArray(gl, x_off, y_off, mip_level, cformat, ctype, mipLevels, array) {
  var dtype = array.dtype
  var shape = array.shape.slice()
  if(shape.length < 2 || shape.length > 3) {
    throw new Error('gl-texture2d: Invalid ndarray, must be 2d or 3d')
  }
  var type = 0, format = 0
  var packed = isPacked(shape, array.stride.slice())
  if(dtype === 'float32') {
    type = gl.FLOAT
  } else if(dtype === 'float64') {
    type = gl.FLOAT
    packed = false
    dtype = 'float32'
  } else if(dtype === 'uint8') {
    type = gl.UNSIGNED_BYTE
  } else {
    type = gl.UNSIGNED_BYTE
    packed = false
    dtype = 'uint8'
  }
  var channels = 1
  if(shape.length === 2) {
    format = gl.LUMINANCE
    shape = [shape[0], shape[1], 1]
    array = ndarray(array.data, shape, [array.stride[0], array.stride[1], 1], array.offset)
  } else if(shape.length === 3) {
    if(shape[2] === 1) {
      format = gl.ALPHA
    } else if(shape[2] === 2) {
      format = gl.LUMINANCE_ALPHA
    } else if(shape[2] === 3) {
      format = gl.RGB
    } else if(shape[2] === 4) {
      format = gl.RGBA
    } else {
      throw new Error('gl-texture2d: Invalid shape for pixel coords')
    }
    channels = shape[2]
  } else {
    throw new Error('gl-texture2d: Invalid shape for texture')
  }
  //For 1-channel textures allow conversion between formats
  if((format  === gl.LUMINANCE || format  === gl.ALPHA) &&
     (cformat === gl.LUMINANCE || cformat === gl.ALPHA)) {
    format = cformat
  }
  if(format !== cformat) {
    throw new Error('gl-texture2d: Incompatible texture format for setPixels')
  }
  var size = array.size
  var needsMip = mipLevels.indexOf(mip_level) < 0
  if(needsMip) {
    mipLevels.push(mip_level)
  }
  if(type === ctype && packed) {
    //Array data types are compatible, can directly copy into texture
    if(array.offset === 0 && array.data.length === size) {
      if(needsMip) {
        gl.texImage2D(gl.TEXTURE_2D, mip_level, cformat, shape[0], shape[1], 0, cformat, ctype, array.data)
      } else {
        gl.texSubImage2D(gl.TEXTURE_2D, mip_level, x_off, y_off, shape[0], shape[1], cformat, ctype, array.data)
      }
    } else {
      if(needsMip) {
        gl.texImage2D(gl.TEXTURE_2D, mip_level, cformat, shape[0], shape[1], 0, cformat, ctype, array.data.subarray(array.offset, array.offset+size))
      } else {
        gl.texSubImage2D(gl.TEXTURE_2D, mip_level, x_off, y_off, shape[0], shape[1], cformat, ctype, array.data.subarray(array.offset, array.offset+size))
      }
    }
  } else {
    //Need to do type conversion to pack data into buffer
    var pack_buffer
    if(ctype === gl.FLOAT) {
      pack_buffer = pool.mallocFloat32(size)
    } else {
      pack_buffer = pool.mallocUint8(size)
    }
    var pack_view = ndarray(pack_buffer, shape, [shape[2], shape[2]*shape[0], 1])
    if(type === gl.FLOAT && ctype === gl.UNSIGNED_BYTE) {
      convertFloatToUint8(pack_view, array)
    } else {
      ops.assign(pack_view, array)
    }
    if(needsMip) {
      gl.texImage2D(gl.TEXTURE_2D, mip_level, cformat, shape[0], shape[1], 0, cformat, ctype, pack_buffer.subarray(0, size))
    } else {
      gl.texSubImage2D(gl.TEXTURE_2D, mip_level, x_off, y_off, shape[0], shape[1], cformat, ctype, pack_buffer.subarray(0, size))
    }
    if(ctype === gl.FLOAT) {
      pool.freeFloat32(pack_buffer)
    } else {
      pool.freeUint8(pack_buffer)
    }
  }
}

function initTexture(gl) {
  var tex = gl.createTexture()
  gl.bindTexture(gl.TEXTURE_2D, tex)
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST)
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST)
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE)
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE)
  return tex
}

function createTextureShape(gl, width, height, format, type) {
  var maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE)
  if(width < 0 || width > maxTextureSize || height < 0 || height  > maxTextureSize) {
    throw new Error('gl-texture2d: Invalid texture shape')
  }
  if(type === gl.FLOAT && !gl.getExtension('OES_texture_float')) {
    throw new Error('gl-texture2d: Floating point textures not supported on this platform')
  }
  var tex = initTexture(gl)
  gl.texImage2D(gl.TEXTURE_2D, 0, format, width, height, 0, format, type, null)
  return new Texture2D(gl, tex, width, height, format, type)
}

function createTextureDOM(gl, directData, width, height, format, type) {
  var tex = initTexture(gl)
  gl.texImage2D(gl.TEXTURE_2D, 0, format, format, type, directData)
  return new Texture2D(gl, tex, width, height, format, type)
}

//Creates a texture from an ndarray
function createTextureArray(gl, array) {
  var dtype = array.dtype
  var shape = array.shape.slice()
  var maxSize = gl.getParameter(gl.MAX_TEXTURE_SIZE)
  if(shape[0] < 0 || shape[0] > maxSize || shape[1] < 0 || shape[1] > maxSize) {
    throw new Error('gl-texture2d: Invalid texture size')
  }
  var packed = isPacked(shape, array.stride.slice())
  var type = 0
  if(dtype === 'float32') {
    type = gl.FLOAT
  } else if(dtype === 'float64') {
    type = gl.FLOAT
    packed = false
    dtype = 'float32'
  } else if(dtype === 'uint8') {
    type = gl.UNSIGNED_BYTE
  } else {
    type = gl.UNSIGNED_BYTE
    packed = false
    dtype = 'uint8'
  }
  var format = 0
  if(shape.length === 2) {
    format = gl.LUMINANCE
    shape = [shape[0], shape[1], 1]
    array = ndarray(array.data, shape, [array.stride[0], array.stride[1], 1], array.offset)
  } else if(shape.length === 3) {
    if(shape[2] === 1) {
      format = gl.ALPHA
    } else if(shape[2] === 2) {
      format = gl.LUMINANCE_ALPHA
    } else if(shape[2] === 3) {
      format = gl.RGB
    } else if(shape[2] === 4) {
      format = gl.RGBA
    } else {
      throw new Error('gl-texture2d: Invalid shape for pixel coords')
    }
  } else {
    throw new Error('gl-texture2d: Invalid shape for texture')
  }
  if(type === gl.FLOAT && !gl.getExtension('OES_texture_float')) {
    type = gl.UNSIGNED_BYTE
    packed = false
  }
  var buffer, buf_store
  var size = array.size
  if(!packed) {
    var stride = [shape[2], shape[2]*shape[0], 1]
    buf_store = pool.malloc(size, dtype)
    var buf_array = ndarray(buf_store, shape, stride, 0)
    if((dtype === 'float32' || dtype === 'float64') && type === gl.UNSIGNED_BYTE) {
      convertFloatToUint8(buf_array, array)
    } else {
      ops.assign(buf_array, array)
    }
    buffer = buf_store.subarray(0, size)
  } else if (array.offset === 0 && array.data.length === size) {
    buffer = array.data
  } else {
    buffer = array.data.subarray(array.offset, array.offset + size)
  }
  var tex = initTexture(gl)
  gl.texImage2D(gl.TEXTURE_2D, 0, format, shape[0], shape[1], 0, format, type, buffer)
  if(!packed) {
    pool.free(buf_store)
  }
  return new Texture2D(gl, tex, shape[0], shape[1], format, type)
}

function createTexture2D(gl) {
  if(arguments.length <= 1) {
    throw new Error('gl-texture2d: Missing arguments for texture2d constructor')
  }
  if(!linearTypes) {
    lazyInitLinearTypes(gl)
  }
  if(typeof arguments[1] === 'number') {
    return createTextureShape(gl, arguments[1], arguments[2], arguments[3]||gl.RGBA, arguments[4]||gl.UNSIGNED_BYTE)
  }
  if(Array.isArray(arguments[1])) {
    return createTextureShape(gl, arguments[1][0]|0, arguments[1][1]|0, arguments[2]||gl.RGBA, arguments[3]||gl.UNSIGNED_BYTE)
  }
  if(typeof arguments[1] === 'object') {
    var obj = arguments[1]
    var directData = acceptTextureDOM(obj) ? obj : obj.raw
    if (directData) {
      return createTextureDOM(gl, directData, obj.width|0, obj.height|0, arguments[2]||gl.RGBA, arguments[3]||gl.UNSIGNED_BYTE)
    } else if(obj.shape && obj.data && obj.stride) {
      return createTextureArray(gl, obj)
    }
  }
  throw new Error('gl-texture2d: Invalid arguments for texture2d constructor')
}


/***/ }),

/***/ 1433:
/***/ (function(module) {

"use strict";


function doBind(gl, elements, attributes) {
  if(elements) {
    elements.bind()
  } else {
    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null)
  }
  var nattribs = gl.getParameter(gl.MAX_VERTEX_ATTRIBS)|0
  if(attributes) {
    if(attributes.length > nattribs) {
      throw new Error("gl-vao: Too many vertex attributes")
    }
    for(var i=0; i 1.0){
        return 0
    } else {
        return Math.acos(cosine)
    }     
}


/***/ }),

/***/ 9226:
/***/ (function(module) {

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
}


/***/ }),

/***/ 3126:
/***/ (function(module) {

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
}

/***/ }),

/***/ 3990:
/***/ (function(module) {

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
}

/***/ }),

/***/ 1091:
/***/ (function(module) {

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
}

/***/ }),

/***/ 5911:
/***/ (function(module) {

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
}

/***/ }),

/***/ 5455:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

module.exports = __webpack_require__(7056)


/***/ }),

/***/ 7056:
/***/ (function(module) {

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)
}

/***/ }),

/***/ 4008:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

module.exports = __webpack_require__(6690)


/***/ }),

/***/ 6690:
/***/ (function(module) {

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
}

/***/ }),

/***/ 244:
/***/ (function(module) {

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]
}

/***/ }),

/***/ 2613:
/***/ (function(module) {

module.exports = 0.000001


/***/ }),

/***/ 9922:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

module.exports = equals

var EPSILON = __webpack_require__(2613)

/**
 * 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)))
}


/***/ }),

/***/ 9265:
/***/ (function(module) {

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]
}


/***/ }),

/***/ 2681:
/***/ (function(module) {

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
}


/***/ }),

/***/ 5137:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

module.exports = forEach;

var vec = __webpack_require__(1091)()

/**
 * 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
}

/***/ }),

/***/ 2825:
/***/ (function(module) {

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
}

/***/ }),

/***/ 2931:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

module.exports = {
  EPSILON: __webpack_require__(2613)
  , create: __webpack_require__(1091)
  , clone: __webpack_require__(3126)
  , angle: __webpack_require__(8192)
  , fromValues: __webpack_require__(2825)
  , copy: __webpack_require__(3990)
  , set: __webpack_require__(1463)
  , equals: __webpack_require__(9922)
  , exactEquals: __webpack_require__(9265)
  , add: __webpack_require__(5632)
  , subtract: __webpack_require__(6843)
  , sub: __webpack_require__(2229)
  , multiply: __webpack_require__(5847)
  , mul: __webpack_require__(4505)
  , divide: __webpack_require__(6690)
  , div: __webpack_require__(4008)
  , min: __webpack_require__(8107)
  , max: __webpack_require__(7417)
  , floor: __webpack_require__(2681)
  , ceil: __webpack_require__(9226)
  , round: __webpack_require__(2447)
  , scale: __webpack_require__(6621)
  , scaleAndAdd: __webpack_require__(8489)
  , distance: __webpack_require__(7056)
  , dist: __webpack_require__(5455)
  , squaredDistance: __webpack_require__(2953)
  , sqrDist: __webpack_require__(6141)
  , length: __webpack_require__(1387)
  , len: __webpack_require__(868)
  , squaredLength: __webpack_require__(3066)
  , sqrLen: __webpack_require__(5486)
  , negate: __webpack_require__(5093)
  , inverse: __webpack_require__(811)
  , normalize: __webpack_require__(3536)
  , dot: __webpack_require__(244)
  , cross: __webpack_require__(5911)
  , lerp: __webpack_require__(6658)
  , random: __webpack_require__(7636)
  , transformMat4: __webpack_require__(5673)
  , transformMat3: __webpack_require__(492)
  , transformQuat: __webpack_require__(264)
  , rotateX: __webpack_require__(6894)
  , rotateY: __webpack_require__(109)
  , rotateZ: __webpack_require__(8692)
  , forEach: __webpack_require__(5137)
}


/***/ }),

/***/ 811:
/***/ (function(module) {

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
}

/***/ }),

/***/ 868:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

module.exports = __webpack_require__(1387)


/***/ }),

/***/ 1387:
/***/ (function(module) {

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)
}

/***/ }),

/***/ 6658:
/***/ (function(module) {

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
}

/***/ }),

/***/ 7417:
/***/ (function(module) {

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
}

/***/ }),

/***/ 8107:
/***/ (function(module) {

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
}

/***/ }),

/***/ 4505:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

module.exports = __webpack_require__(5847)


/***/ }),

/***/ 5847:
/***/ (function(module) {

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
}

/***/ }),

/***/ 5093:
/***/ (function(module) {

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
}

/***/ }),

/***/ 3536:
/***/ (function(module) {

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
}

/***/ }),

/***/ 7636:
/***/ (function(module) {

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
}

/***/ }),

/***/ 6894:
/***/ (function(module) {

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
}


/***/ }),

/***/ 109:
/***/ (function(module) {

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
}


/***/ }),

/***/ 8692:
/***/ (function(module) {

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
}


/***/ }),

/***/ 2447:
/***/ (function(module) {

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
}


/***/ }),

/***/ 6621:
/***/ (function(module) {

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
}

/***/ }),

/***/ 8489:
/***/ (function(module) {

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
}

/***/ }),

/***/ 1463:
/***/ (function(module) {

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
}

/***/ }),

/***/ 6141:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

module.exports = __webpack_require__(2953)


/***/ }),

/***/ 5486:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

module.exports = __webpack_require__(3066)


/***/ }),

/***/ 2953:
/***/ (function(module) {

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
}

/***/ }),

/***/ 3066:
/***/ (function(module) {

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
}

/***/ }),

/***/ 2229:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

module.exports = __webpack_require__(6843)


/***/ }),

/***/ 6843:
/***/ (function(module) {

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
}

/***/ }),

/***/ 492:
/***/ (function(module) {

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
}

/***/ }),

/***/ 5673:
/***/ (function(module) {

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
}

/***/ }),

/***/ 264:
/***/ (function(module) {

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
}

/***/ }),

/***/ 4361:
/***/ (function(module) {

module.exports = add

/**
 * Adds two vec4's
 *
 * @param {vec4} out the receiving vector
 * @param {vec4} a the first operand
 * @param {vec4} b the second operand
 * @returns {vec4} out
 */
function add (out, a, b) {
  out[0] = a[0] + b[0]
  out[1] = a[1] + b[1]
  out[2] = a[2] + b[2]
  out[3] = a[3] + b[3]
  return out
}


/***/ }),

/***/ 2335:
/***/ (function(module) {

module.exports = clone

/**
 * Creates a new vec4 initialized with values from an existing vector
 *
 * @param {vec4} a vector to clone
 * @returns {vec4} a new 4D vector
 */
function clone (a) {
  var out = new Float32Array(4)
  out[0] = a[0]
  out[1] = a[1]
  out[2] = a[2]
  out[3] = a[3]
  return out
}


/***/ }),

/***/ 2933:
/***/ (function(module) {

module.exports = copy

/**
 * Copy the values from one vec4 to another
 *
 * @param {vec4} out the receiving vector
 * @param {vec4} a the source vector
 * @returns {vec4} out
 */
function copy (out, a) {
  out[0] = a[0]
  out[1] = a[1]
  out[2] = a[2]
  out[3] = a[3]
  return out
}


/***/ }),

/***/ 7536:
/***/ (function(module) {

module.exports = create

/**
 * Creates a new, empty vec4
 *
 * @returns {vec4} a new 4D vector
 */
function create () {
  var out = new Float32Array(4)
  out[0] = 0
  out[1] = 0
  out[2] = 0
  out[3] = 0
  return out
}


/***/ }),

/***/ 4691:
/***/ (function(module) {

module.exports = distance

/**
 * Calculates the euclidian distance between two vec4's
 *
 * @param {vec4} a the first operand
 * @param {vec4} 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],
    w = b[3] - a[3]
  return Math.sqrt(x * x + y * y + z * z + w * w)
}


/***/ }),

/***/ 1373:
/***/ (function(module) {

module.exports = divide

/**
 * Divides two vec4's
 *
 * @param {vec4} out the receiving vector
 * @param {vec4} a the first operand
 * @param {vec4} b the second operand
 * @returns {vec4} out
 */
function divide (out, a, b) {
  out[0] = a[0] / b[0]
  out[1] = a[1] / b[1]
  out[2] = a[2] / b[2]
  out[3] = a[3] / b[3]
  return out
}


/***/ }),

/***/ 3750:
/***/ (function(module) {

module.exports = dot

/**
 * Calculates the dot product of two vec4's
 *
 * @param {vec4} a the first operand
 * @param {vec4} 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] + a[3] * b[3]
}


/***/ }),

/***/ 3390:
/***/ (function(module) {

module.exports = fromValues

/**
 * Creates a new vec4 initialized with the given values
 *
 * @param {Number} x X component
 * @param {Number} y Y component
 * @param {Number} z Z component
 * @param {Number} w W component
 * @returns {vec4} a new 4D vector
 */
function fromValues (x, y, z, w) {
  var out = new Float32Array(4)
  out[0] = x
  out[1] = y
  out[2] = z
  out[3] = w
  return out
}


/***/ }),

/***/ 9970:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

module.exports = {
  create: __webpack_require__(7536),
  clone: __webpack_require__(2335),
  fromValues: __webpack_require__(3390),
  copy: __webpack_require__(2933),
  set: __webpack_require__(4578),
  add: __webpack_require__(4361),
  subtract: __webpack_require__(6860),
  multiply: __webpack_require__(3576),
  divide: __webpack_require__(1373),
  min: __webpack_require__(2334),
  max: __webpack_require__(160),
  scale: __webpack_require__(9288),
  scaleAndAdd: __webpack_require__(4844),
  distance: __webpack_require__(4691),
  squaredDistance: __webpack_require__(7960),
  length: __webpack_require__(6808),
  squaredLength: __webpack_require__(483),
  negate: __webpack_require__(1498),
  inverse: __webpack_require__(4494),
  normalize: __webpack_require__(5177),
  dot: __webpack_require__(3750),
  lerp: __webpack_require__(2573),
  random: __webpack_require__(9131),
  transformMat4: __webpack_require__(5352),
  transformQuat: __webpack_require__(4041)
}


/***/ }),

/***/ 4494:
/***/ (function(module) {

module.exports = inverse

/**
 * Returns the inverse of the components of a vec4
 *
 * @param {vec4} out the receiving vector
 * @param {vec4} a vector to invert
 * @returns {vec4} out
 */
function inverse (out, a) {
  out[0] = 1.0 / a[0]
  out[1] = 1.0 / a[1]
  out[2] = 1.0 / a[2]
  out[3] = 1.0 / a[3]
  return out
}


/***/ }),

/***/ 6808:
/***/ (function(module) {

module.exports = length

/**
 * Calculates the length of a vec4
 *
 * @param {vec4} a vector to calculate length of
 * @returns {Number} length of a
 */
function length (a) {
  var x = a[0],
    y = a[1],
    z = a[2],
    w = a[3]
  return Math.sqrt(x * x + y * y + z * z + w * w)
}


/***/ }),

/***/ 2573:
/***/ (function(module) {

module.exports = lerp

/**
 * Performs a linear interpolation between two vec4's
 *
 * @param {vec4} out the receiving vector
 * @param {vec4} a the first operand
 * @param {vec4} b the second operand
 * @param {Number} t interpolation amount between the two inputs
 * @returns {vec4} out
 */
function lerp (out, a, b, t) {
  var ax = a[0],
    ay = a[1],
    az = a[2],
    aw = a[3]
  out[0] = ax + t * (b[0] - ax)
  out[1] = ay + t * (b[1] - ay)
  out[2] = az + t * (b[2] - az)
  out[3] = aw + t * (b[3] - aw)
  return out
}


/***/ }),

/***/ 160:
/***/ (function(module) {

module.exports = max

/**
 * Returns the maximum of two vec4's
 *
 * @param {vec4} out the receiving vector
 * @param {vec4} a the first operand
 * @param {vec4} b the second operand
 * @returns {vec4} 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])
  out[3] = Math.max(a[3], b[3])
  return out
}


/***/ }),

/***/ 2334:
/***/ (function(module) {

module.exports = min

/**
 * Returns the minimum of two vec4's
 *
 * @param {vec4} out the receiving vector
 * @param {vec4} a the first operand
 * @param {vec4} b the second operand
 * @returns {vec4} 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])
  out[3] = Math.min(a[3], b[3])
  return out
}


/***/ }),

/***/ 3576:
/***/ (function(module) {

module.exports = multiply

/**
 * Multiplies two vec4's
 *
 * @param {vec4} out the receiving vector
 * @param {vec4} a the first operand
 * @param {vec4} b the second operand
 * @returns {vec4} out
 */
function multiply (out, a, b) {
  out[0] = a[0] * b[0]
  out[1] = a[1] * b[1]
  out[2] = a[2] * b[2]
  out[3] = a[3] * b[3]
  return out
}


/***/ }),

/***/ 1498:
/***/ (function(module) {

module.exports = negate

/**
 * Negates the components of a vec4
 *
 * @param {vec4} out the receiving vector
 * @param {vec4} a vector to negate
 * @returns {vec4} out
 */
function negate (out, a) {
  out[0] = -a[0]
  out[1] = -a[1]
  out[2] = -a[2]
  out[3] = -a[3]
  return out
}


/***/ }),

/***/ 5177:
/***/ (function(module) {

module.exports = normalize

/**
 * Normalize a vec4
 *
 * @param {vec4} out the receiving vector
 * @param {vec4} a vector to normalize
 * @returns {vec4} out
 */
function normalize (out, a) {
  var x = a[0],
    y = a[1],
    z = a[2],
    w = a[3]
  var len = x * x + y * y + z * z + w * w
  if (len > 0) {
    len = 1 / Math.sqrt(len)
    out[0] = x * len
    out[1] = y * len
    out[2] = z * len
    out[3] = w * len
  }
  return out
}


/***/ }),

/***/ 9131:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

var vecNormalize = __webpack_require__(5177)
var vecScale = __webpack_require__(9288)

module.exports = random

/**
 * Generates a random vector with the given scale
 *
 * @param {vec4} out the receiving vector
 * @param {Number} [scale] Length of the resulting vector. If ommitted, a unit vector will be returned
 * @returns {vec4} out
 */
function random (out, scale) {
  scale = scale || 1.0

  // TODO: This is a pretty awful way of doing this. Find something better.
  out[0] = Math.random()
  out[1] = Math.random()
  out[2] = Math.random()
  out[3] = Math.random()
  vecNormalize(out, out)
  vecScale(out, out, scale)
  return out
}


/***/ }),

/***/ 9288:
/***/ (function(module) {

module.exports = scale

/**
 * Scales a vec4 by a scalar number
 *
 * @param {vec4} out the receiving vector
 * @param {vec4} a the vector to scale
 * @param {Number} b amount to scale the vector by
 * @returns {vec4} out
 */
function scale (out, a, b) {
  out[0] = a[0] * b
  out[1] = a[1] * b
  out[2] = a[2] * b
  out[3] = a[3] * b
  return out
}


/***/ }),

/***/ 4844:
/***/ (function(module) {

module.exports = scaleAndAdd

/**
 * Adds two vec4's after scaling the second operand by a scalar value
 *
 * @param {vec4} out the receiving vector
 * @param {vec4} a the first operand
 * @param {vec4} b the second operand
 * @param {Number} scale the amount to scale b by before adding
 * @returns {vec4} 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)
  out[3] = a[3] + (b[3] * scale)
  return out
}


/***/ }),

/***/ 4578:
/***/ (function(module) {

module.exports = set

/**
 * Set the components of a vec4 to the given values
 *
 * @param {vec4} out the receiving vector
 * @param {Number} x X component
 * @param {Number} y Y component
 * @param {Number} z Z component
 * @param {Number} w W component
 * @returns {vec4} out
 */
function set (out, x, y, z, w) {
  out[0] = x
  out[1] = y
  out[2] = z
  out[3] = w
  return out
}


/***/ }),

/***/ 7960:
/***/ (function(module) {

module.exports = squaredDistance

/**
 * Calculates the squared euclidian distance between two vec4's
 *
 * @param {vec4} a the first operand
 * @param {vec4} 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],
    w = b[3] - a[3]
  return x * x + y * y + z * z + w * w
}


/***/ }),

/***/ 483:
/***/ (function(module) {

module.exports = squaredLength

/**
 * Calculates the squared length of a vec4
 *
 * @param {vec4} 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],
    w = a[3]
  return x * x + y * y + z * z + w * w
}


/***/ }),

/***/ 6860:
/***/ (function(module) {

module.exports = subtract

/**
 * Subtracts vector b from vector a
 *
 * @param {vec4} out the receiving vector
 * @param {vec4} a the first operand
 * @param {vec4} b the second operand
 * @returns {vec4} out
 */
function subtract (out, a, b) {
  out[0] = a[0] - b[0]
  out[1] = a[1] - b[1]
  out[2] = a[2] - b[2]
  out[3] = a[3] - b[3]
  return out
}


/***/ }),

/***/ 5352:
/***/ (function(module) {

module.exports = transformMat4

/**
 * Transforms the vec4 with a mat4.
 *
 * @param {vec4} out the receiving vector
 * @param {vec4} a the vector to transform
 * @param {mat4} m matrix to transform with
 * @returns {vec4} out
 */
function transformMat4 (out, a, m) {
  var x = a[0], y = a[1], z = a[2], w = a[3]
  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
  out[3] = m[3] * x + m[7] * y + m[11] * z + m[15] * w
  return out
}


/***/ }),

/***/ 4041:
/***/ (function(module) {

module.exports = transformQuat

/**
 * Transforms the vec4 with a quat
 *
 * @param {vec4} out the receiving vector
 * @param {vec4} a the vector to transform
 * @param {quat} q quaternion to transform with
 * @returns {vec4} out
 */
function transformQuat (out, a, q) {
  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
  out[3] = a[3]
  return out
}


/***/ }),

/***/ 1848:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

var tokenize = __webpack_require__(4905)
var atob     = __webpack_require__(6468)

module.exports = getName

function getName(src) {
  var tokens = Array.isArray(src)
    ? src
    : tokenize(src)

  for (var i = 0; i < tokens.length; i++) {
    var token = tokens[i]
    if (token.type !== 'preprocessor') continue
    var match = token.data.match(/\#define\s+SHADER_NAME(_B64)?\s+(.+)$/)
    if (!match) continue
    if (!match[2]) continue

    var b64  = match[1]
    var name = match[2]

    return (b64 ? atob(name) : name).trim()
  }
}


/***/ }),

/***/ 5874:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

module.exports = tokenize

var literals100 = __webpack_require__(620)
  , operators = __webpack_require__(7827)
  , builtins100 = __webpack_require__(6852)
  , literals300es = __webpack_require__(7932)
  , builtins300es = __webpack_require__(3508)

var NORMAL = 999          // <-- never emitted
  , TOKEN = 9999          // <-- never emitted
  , BLOCK_COMMENT = 0
  , LINE_COMMENT = 1
  , PREPROCESSOR = 2
  , OPERATOR = 3
  , INTEGER = 4
  , FLOAT = 5
  , IDENT = 6
  , BUILTIN = 7
  , KEYWORD = 8
  , WHITESPACE = 9
  , EOF = 10
  , HEX = 11

var map = [
    'block-comment'
  , 'line-comment'
  , 'preprocessor'
  , 'operator'
  , 'integer'
  , 'float'
  , 'ident'
  , 'builtin'
  , 'keyword'
  , 'whitespace'
  , 'eof'
  , 'integer'
]

function tokenize(opt) {
  var i = 0
    , total = 0
    , mode = NORMAL
    , c
    , last
    , content = []
    , tokens = []
    , token_idx = 0
    , token_offs = 0
    , line = 1
    , col = 0
    , start = 0
    , isnum = false
    , isoperator = false
    , input = ''
    , len

  opt = opt || {}
  var allBuiltins = builtins100
  var allLiterals = literals100
  if (opt.version === '300 es') {
    allBuiltins = builtins300es
    allLiterals = literals300es
  }

  // cache by name
  var builtinsDict = {}, literalsDict = {}
  for (var i = 0; i < allBuiltins.length; i++) {
    builtinsDict[allBuiltins[i]] = true
  }
  for (var i = 0; i < allLiterals.length; i++) {
    literalsDict[allLiterals[i]] = true
  }

  return function(data) {
    tokens = []
    if (data !== null) return write(data)
    return end()
  }

  function token(data) {
    if (data.length) {
      tokens.push({
        type: map[mode]
      , data: data
      , position: start
      , line: line
      , column: col
      })
    }
  }

  function write(chunk) {
    i = 0

    if (chunk.toString) chunk = chunk.toString()

    input += chunk.replace(/\r\n/g, '\n')
    len = input.length


    var last

    while(c = input[i], i < len) {
      last = i

      switch(mode) {
        case BLOCK_COMMENT: i = block_comment(); break
        case LINE_COMMENT: i = line_comment(); break
        case PREPROCESSOR: i = preprocessor(); break
        case OPERATOR: i = operator(); break
        case INTEGER: i = integer(); break
        case HEX: i = hex(); break
        case FLOAT: i = decimal(); break
        case TOKEN: i = readtoken(); break
        case WHITESPACE: i = whitespace(); break
        case NORMAL: i = normal(); break
      }

      if(last !== i) {
        switch(input[last]) {
          case '\n': col = 0; ++line; break
          default: ++col; break
        }
      }
    }

    total += i
    input = input.slice(i)
    return tokens
  }

  function end(chunk) {
    if(content.length) {
      token(content.join(''))
    }

    mode = EOF
    token('(eof)')
    return tokens
  }

  function normal() {
    content = content.length ? [] : content

    if(last === '/' && c === '*') {
      start = total + i - 1
      mode = BLOCK_COMMENT
      last = c
      return i + 1
    }

    if(last === '/' && c === '/') {
      start = total + i - 1
      mode = LINE_COMMENT
      last = c
      return i + 1
    }

    if(c === '#') {
      mode = PREPROCESSOR
      start = total + i
      return i
    }

    if(/\s/.test(c)) {
      mode = WHITESPACE
      start = total + i
      return i
    }

    isnum = /\d/.test(c)
    isoperator = /[^\w_]/.test(c)

    start = total + i
    mode = isnum ? INTEGER : isoperator ? OPERATOR : TOKEN
    return i
  }

  function whitespace() {
    if(/[^\s]/g.test(c)) {
      token(content.join(''))
      mode = NORMAL
      return i
    }
    content.push(c)
    last = c
    return i + 1
  }

  function preprocessor() {
    if((c === '\r' || c === '\n') && last !== '\\') {
      token(content.join(''))
      mode = NORMAL
      return i
    }
    content.push(c)
    last = c
    return i + 1
  }

  function line_comment() {
    return preprocessor()
  }

  function block_comment() {
    if(c === '/' && last === '*') {
      content.push(c)
      token(content.join(''))
      mode = NORMAL
      return i + 1
    }

    content.push(c)
    last = c
    return i + 1
  }

  function operator() {
    if(last === '.' && /\d/.test(c)) {
      mode = FLOAT
      return i
    }

    if(last === '/' && c === '*') {
      mode = BLOCK_COMMENT
      return i
    }

    if(last === '/' && c === '/') {
      mode = LINE_COMMENT
      return i
    }

    if(c === '.' && content.length) {
      while(determine_operator(content));

      mode = FLOAT
      return i
    }

    if(c === ';' || c === ')' || c === '(') {
      if(content.length) while(determine_operator(content));
      token(c)
      mode = NORMAL
      return i + 1
    }

    var is_composite_operator = content.length === 2 && c !== '='
    if(/[\w_\d\s]/.test(c) || is_composite_operator) {
      while(determine_operator(content));
      mode = NORMAL
      return i
    }

    content.push(c)
    last = c
    return i + 1
  }

  function determine_operator(buf) {
    var j = 0
      , idx
      , res

    do {
      idx = operators.indexOf(buf.slice(0, buf.length + j).join(''))
      res = operators[idx]

      if(idx === -1) {
        if(j-- + buf.length > 0) continue
        res = buf.slice(0, 1).join('')
      }

      token(res)

      start += res.length
      content = content.slice(res.length)
      return content.length
    } while(1)
  }

  function hex() {
    if(/[^a-fA-F0-9]/.test(c)) {
      token(content.join(''))
      mode = NORMAL
      return i
    }

    content.push(c)
    last = c
    return i + 1
  }

  function integer() {
    if(c === '.') {
      content.push(c)
      mode = FLOAT
      last = c
      return i + 1
    }

    if(/[eE]/.test(c)) {
      content.push(c)
      mode = FLOAT
      last = c
      return i + 1
    }

    if(c === 'x' && content.length === 1 && content[0] === '0') {
      mode = HEX
      content.push(c)
      last = c
      return i + 1
    }

    if(/[^\d]/.test(c)) {
      token(content.join(''))
      mode = NORMAL
      return i
    }

    content.push(c)
    last = c
    return i + 1
  }

  function decimal() {
    if(c === 'f') {
      content.push(c)
      last = c
      i += 1
    }

    if(/[eE]/.test(c)) {
      content.push(c)
      last = c
      return i + 1
    }

    if ((c === '-' || c === '+') && /[eE]/.test(last)) {
      content.push(c)
      last = c
      return i + 1
    }

    if(/[^\d]/.test(c)) {
      token(content.join(''))
      mode = NORMAL
      return i
    }

    content.push(c)
    last = c
    return i + 1
  }

  function readtoken() {
    if(/[^\d\w_]/.test(c)) {
      var contentstr = content.join('')
      if(literalsDict[contentstr]) {
        mode = KEYWORD
      } else if(builtinsDict[contentstr]) {
        mode = BUILTIN
      } else {
        mode = IDENT
      }
      token(content.join(''))
      mode = NORMAL
      return i
    }
    content.push(c)
    last = c
    return i + 1
  }
}


/***/ }),

/***/ 3508:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

// 300es builtins/reserved words that were previously valid in v100
var v100 = __webpack_require__(6852)

// The texture2D|Cube functions have been removed
// And the gl_ features are updated
v100 = v100.slice().filter(function (b) {
  return !/^(gl\_|texture)/.test(b)
})

module.exports = v100.concat([
  // the updated gl_ constants
    'gl_VertexID'
  , 'gl_InstanceID'
  , 'gl_Position'
  , 'gl_PointSize'
  , 'gl_FragCoord'
  , 'gl_FrontFacing'
  , 'gl_FragDepth'
  , 'gl_PointCoord'
  , 'gl_MaxVertexAttribs'
  , 'gl_MaxVertexUniformVectors'
  , 'gl_MaxVertexOutputVectors'
  , 'gl_MaxFragmentInputVectors'
  , 'gl_MaxVertexTextureImageUnits'
  , 'gl_MaxCombinedTextureImageUnits'
  , 'gl_MaxTextureImageUnits'
  , 'gl_MaxFragmentUniformVectors'
  , 'gl_MaxDrawBuffers'
  , 'gl_MinProgramTexelOffset'
  , 'gl_MaxProgramTexelOffset'
  , 'gl_DepthRangeParameters'
  , 'gl_DepthRange'

  // other builtins
  , 'trunc'
  , 'round'
  , 'roundEven'
  , 'isnan'
  , 'isinf'
  , 'floatBitsToInt'
  , 'floatBitsToUint'
  , 'intBitsToFloat'
  , 'uintBitsToFloat'
  , 'packSnorm2x16'
  , 'unpackSnorm2x16'
  , 'packUnorm2x16'
  , 'unpackUnorm2x16'
  , 'packHalf2x16'
  , 'unpackHalf2x16'
  , 'outerProduct'
  , 'transpose'
  , 'determinant'
  , 'inverse'
  , 'texture'
  , 'textureSize'
  , 'textureProj'
  , 'textureLod'
  , 'textureOffset'
  , 'texelFetch'
  , 'texelFetchOffset'
  , 'textureProjOffset'
  , 'textureLodOffset'
  , 'textureProjLod'
  , 'textureProjLodOffset'
  , 'textureGrad'
  , 'textureGradOffset'
  , 'textureProjGrad'
  , 'textureProjGradOffset'
])


/***/ }),

/***/ 6852:
/***/ (function(module) {

module.exports = [
  // Keep this list sorted
  'abs'
  , 'acos'
  , 'all'
  , 'any'
  , 'asin'
  , 'atan'
  , 'ceil'
  , 'clamp'
  , 'cos'
  , 'cross'
  , 'dFdx'
  , 'dFdy'
  , 'degrees'
  , 'distance'
  , 'dot'
  , 'equal'
  , 'exp'
  , 'exp2'
  , 'faceforward'
  , 'floor'
  , 'fract'
  , 'gl_BackColor'
  , 'gl_BackLightModelProduct'
  , 'gl_BackLightProduct'
  , 'gl_BackMaterial'
  , 'gl_BackSecondaryColor'
  , 'gl_ClipPlane'
  , 'gl_ClipVertex'
  , 'gl_Color'
  , 'gl_DepthRange'
  , 'gl_DepthRangeParameters'
  , 'gl_EyePlaneQ'
  , 'gl_EyePlaneR'
  , 'gl_EyePlaneS'
  , 'gl_EyePlaneT'
  , 'gl_Fog'
  , 'gl_FogCoord'
  , 'gl_FogFragCoord'
  , 'gl_FogParameters'
  , 'gl_FragColor'
  , 'gl_FragCoord'
  , 'gl_FragData'
  , 'gl_FragDepth'
  , 'gl_FragDepthEXT'
  , 'gl_FrontColor'
  , 'gl_FrontFacing'
  , 'gl_FrontLightModelProduct'
  , 'gl_FrontLightProduct'
  , 'gl_FrontMaterial'
  , 'gl_FrontSecondaryColor'
  , 'gl_LightModel'
  , 'gl_LightModelParameters'
  , 'gl_LightModelProducts'
  , 'gl_LightProducts'
  , 'gl_LightSource'
  , 'gl_LightSourceParameters'
  , 'gl_MaterialParameters'
  , 'gl_MaxClipPlanes'
  , 'gl_MaxCombinedTextureImageUnits'
  , 'gl_MaxDrawBuffers'
  , 'gl_MaxFragmentUniformComponents'
  , 'gl_MaxLights'
  , 'gl_MaxTextureCoords'
  , 'gl_MaxTextureImageUnits'
  , 'gl_MaxTextureUnits'
  , 'gl_MaxVaryingFloats'
  , 'gl_MaxVertexAttribs'
  , 'gl_MaxVertexTextureImageUnits'
  , 'gl_MaxVertexUniformComponents'
  , 'gl_ModelViewMatrix'
  , 'gl_ModelViewMatrixInverse'
  , 'gl_ModelViewMatrixInverseTranspose'
  , 'gl_ModelViewMatrixTranspose'
  , 'gl_ModelViewProjectionMatrix'
  , 'gl_ModelViewProjectionMatrixInverse'
  , 'gl_ModelViewProjectionMatrixInverseTranspose'
  , 'gl_ModelViewProjectionMatrixTranspose'
  , 'gl_MultiTexCoord0'
  , 'gl_MultiTexCoord1'
  , 'gl_MultiTexCoord2'
  , 'gl_MultiTexCoord3'
  , 'gl_MultiTexCoord4'
  , 'gl_MultiTexCoord5'
  , 'gl_MultiTexCoord6'
  , 'gl_MultiTexCoord7'
  , 'gl_Normal'
  , 'gl_NormalMatrix'
  , 'gl_NormalScale'
  , 'gl_ObjectPlaneQ'
  , 'gl_ObjectPlaneR'
  , 'gl_ObjectPlaneS'
  , 'gl_ObjectPlaneT'
  , 'gl_Point'
  , 'gl_PointCoord'
  , 'gl_PointParameters'
  , 'gl_PointSize'
  , 'gl_Position'
  , 'gl_ProjectionMatrix'
  , 'gl_ProjectionMatrixInverse'
  , 'gl_ProjectionMatrixInverseTranspose'
  , 'gl_ProjectionMatrixTranspose'
  , 'gl_SecondaryColor'
  , 'gl_TexCoord'
  , 'gl_TextureEnvColor'
  , 'gl_TextureMatrix'
  , 'gl_TextureMatrixInverse'
  , 'gl_TextureMatrixInverseTranspose'
  , 'gl_TextureMatrixTranspose'
  , 'gl_Vertex'
  , 'greaterThan'
  , 'greaterThanEqual'
  , 'inversesqrt'
  , 'length'
  , 'lessThan'
  , 'lessThanEqual'
  , 'log'
  , 'log2'
  , 'matrixCompMult'
  , 'max'
  , 'min'
  , 'mix'
  , 'mod'
  , 'normalize'
  , 'not'
  , 'notEqual'
  , 'pow'
  , 'radians'
  , 'reflect'
  , 'refract'
  , 'sign'
  , 'sin'
  , 'smoothstep'
  , 'sqrt'
  , 'step'
  , 'tan'
  , 'texture2D'
  , 'texture2DLod'
  , 'texture2DProj'
  , 'texture2DProjLod'
  , 'textureCube'
  , 'textureCubeLod'
  , 'texture2DLodEXT'
  , 'texture2DProjLodEXT'
  , 'textureCubeLodEXT'
  , 'texture2DGradEXT'
  , 'texture2DProjGradEXT'
  , 'textureCubeGradEXT'
]


/***/ }),

/***/ 7932:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

var v100 = __webpack_require__(620)

module.exports = v100.slice().concat([
   'layout'
  , 'centroid'
  , 'smooth'
  , 'case'
  , 'mat2x2'
  , 'mat2x3'
  , 'mat2x4'
  , 'mat3x2'
  , 'mat3x3'
  , 'mat3x4'
  , 'mat4x2'
  , 'mat4x3'
  , 'mat4x4'
  , 'uvec2'
  , 'uvec3'
  , 'uvec4'
  , 'samplerCubeShadow'
  , 'sampler2DArray'
  , 'sampler2DArrayShadow'
  , 'isampler2D'
  , 'isampler3D'
  , 'isamplerCube'
  , 'isampler2DArray'
  , 'usampler2D'
  , 'usampler3D'
  , 'usamplerCube'
  , 'usampler2DArray'
  , 'coherent'
  , 'restrict'
  , 'readonly'
  , 'writeonly'
  , 'resource'
  , 'atomic_uint'
  , 'noperspective'
  , 'patch'
  , 'sample'
  , 'subroutine'
  , 'common'
  , 'partition'
  , 'active'
  , 'filter'
  , 'image1D'
  , 'image2D'
  , 'image3D'
  , 'imageCube'
  , 'iimage1D'
  , 'iimage2D'
  , 'iimage3D'
  , 'iimageCube'
  , 'uimage1D'
  , 'uimage2D'
  , 'uimage3D'
  , 'uimageCube'
  , 'image1DArray'
  , 'image2DArray'
  , 'iimage1DArray'
  , 'iimage2DArray'
  , 'uimage1DArray'
  , 'uimage2DArray'
  , 'image1DShadow'
  , 'image2DShadow'
  , 'image1DArrayShadow'
  , 'image2DArrayShadow'
  , 'imageBuffer'
  , 'iimageBuffer'
  , 'uimageBuffer'
  , 'sampler1DArray'
  , 'sampler1DArrayShadow'
  , 'isampler1D'
  , 'isampler1DArray'
  , 'usampler1D'
  , 'usampler1DArray'
  , 'isampler2DRect'
  , 'usampler2DRect'
  , 'samplerBuffer'
  , 'isamplerBuffer'
  , 'usamplerBuffer'
  , 'sampler2DMS'
  , 'isampler2DMS'
  , 'usampler2DMS'
  , 'sampler2DMSArray'
  , 'isampler2DMSArray'
  , 'usampler2DMSArray'
])


/***/ }),

/***/ 620:
/***/ (function(module) {

module.exports = [
  // current
    'precision'
  , 'highp'
  , 'mediump'
  , 'lowp'
  , 'attribute'
  , 'const'
  , 'uniform'
  , 'varying'
  , 'break'
  , 'continue'
  , 'do'
  , 'for'
  , 'while'
  , 'if'
  , 'else'
  , 'in'
  , 'out'
  , 'inout'
  , 'float'
  , 'int'
  , 'uint'
  , 'void'
  , 'bool'
  , 'true'
  , 'false'
  , 'discard'
  , 'return'
  , 'mat2'
  , 'mat3'
  , 'mat4'
  , 'vec2'
  , 'vec3'
  , 'vec4'
  , 'ivec2'
  , 'ivec3'
  , 'ivec4'
  , 'bvec2'
  , 'bvec3'
  , 'bvec4'
  , 'sampler1D'
  , 'sampler2D'
  , 'sampler3D'
  , 'samplerCube'
  , 'sampler1DShadow'
  , 'sampler2DShadow'
  , 'struct'

  // future
  , 'asm'
  , 'class'
  , 'union'
  , 'enum'
  , 'typedef'
  , 'template'
  , 'this'
  , 'packed'
  , 'goto'
  , 'switch'
  , 'default'
  , 'inline'
  , 'noinline'
  , 'volatile'
  , 'public'
  , 'static'
  , 'extern'
  , 'external'
  , 'interface'
  , 'long'
  , 'short'
  , 'double'
  , 'half'
  , 'fixed'
  , 'unsigned'
  , 'input'
  , 'output'
  , 'hvec2'
  , 'hvec3'
  , 'hvec4'
  , 'dvec2'
  , 'dvec3'
  , 'dvec4'
  , 'fvec2'
  , 'fvec3'
  , 'fvec4'
  , 'sampler2DRect'
  , 'sampler3DRect'
  , 'sampler2DRectShadow'
  , 'sizeof'
  , 'cast'
  , 'namespace'
  , 'using'
]


/***/ }),

/***/ 7827:
/***/ (function(module) {

module.exports = [
    '<<='
  , '>>='
  , '++'
  , '--'
  , '<<'
  , '>>'
  , '<='
  , '>='
  , '=='
  , '!='
  , '&&'
  , '||'
  , '+='
  , '-='
  , '*='
  , '/='
  , '%='
  , '&='
  , '^^'
  , '^='
  , '|='
  , '('
  , ')'
  , '['
  , ']'
  , '.'
  , '!'
  , '~'
  , '*'
  , '/'
  , '%'
  , '+'
  , '-'
  , '<'
  , '>'
  , '&'
  , '^'
  , '|'
  , '?'
  , ':'
  , '='
  , ','
  , ';'
  , '{'
  , '}'
]


/***/ }),

/***/ 4905:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

var tokenize = __webpack_require__(5874)

module.exports = tokenizeString

function tokenizeString(str, opt) {
  var generator = tokenize(opt)
  var tokens = []

  tokens = tokens.concat(generator(str))
  tokens = tokens.concat(generator(null))

  return tokens
}


/***/ }),

/***/ 3236:
/***/ (function(module) {

module.exports = function(strings) {
  if (typeof strings === 'string') strings = [strings]
  var exprs = [].slice.call(arguments,1)
  var parts = []
  for (var i = 0; i < strings.length-1; i++) {
    parts.push(strings[i], exprs[i] || '')
  }
  parts.push(strings[i])
  return parts.join('')
}


/***/ }),

/***/ 7520:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

"use strict";


var isBrowser = __webpack_require__(9507)

function detect() {
	var supported = false

	try {
		var opts = Object.defineProperty({}, 'passive', {
			get: function() {
				supported = true
			}
		})

		window.addEventListener('test', null, opts)
		window.removeEventListener('test', null, opts)
	} catch(e) {
		supported = false
	}

	return supported
}

module.exports = isBrowser && detect()


/***/ }),

/***/ 3778:
/***/ (function(__unused_webpack_module, exports) {

/*! ieee754. BSD-3-Clause License. Feross Aboukhadijeh  */
exports.read = function (buffer, offset, isLE, mLen, nBytes) {
  var e, m
  var eLen = (nBytes * 8) - mLen - 1
  var eMax = (1 << eLen) - 1
  var eBias = eMax >> 1
  var nBits = -7
  var i = isLE ? (nBytes - 1) : 0
  var d = isLE ? -1 : 1
  var s = buffer[offset + i]

  i += d

  e = s & ((1 << (-nBits)) - 1)
  s >>= (-nBits)
  nBits += eLen
  for (; nBits > 0; e = (e * 256) + buffer[offset + i], i += d, nBits -= 8) {}

  m = e & ((1 << (-nBits)) - 1)
  e >>= (-nBits)
  nBits += mLen
  for (; nBits > 0; m = (m * 256) + buffer[offset + i], i += d, nBits -= 8) {}

  if (e === 0) {
    e = 1 - eBias
  } else if (e === eMax) {
    return m ? NaN : ((s ? -1 : 1) * Infinity)
  } else {
    m = m + Math.pow(2, mLen)
    e = e - eBias
  }
  return (s ? -1 : 1) * m * Math.pow(2, e - mLen)
}

exports.write = function (buffer, value, offset, isLE, mLen, nBytes) {
  var e, m, c
  var eLen = (nBytes * 8) - mLen - 1
  var eMax = (1 << eLen) - 1
  var eBias = eMax >> 1
  var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0)
  var i = isLE ? 0 : (nBytes - 1)
  var d = isLE ? 1 : -1
  var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0

  value = Math.abs(value)

  if (isNaN(value) || value === Infinity) {
    m = isNaN(value) ? 1 : 0
    e = eMax
  } else {
    e = Math.floor(Math.log(value) / Math.LN2)
    if (value * (c = Math.pow(2, -e)) < 1) {
      e--
      c *= 2
    }
    if (e + eBias >= 1) {
      value += rt / c
    } else {
      value += rt * Math.pow(2, 1 - eBias)
    }
    if (value * c >= 2) {
      e++
      c /= 2
    }

    if (e + eBias >= eMax) {
      m = 0
      e = eMax
    } else if (e + eBias >= 1) {
      m = ((value * c) - 1) * Math.pow(2, mLen)
      e = e + eBias
    } else {
      m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen)
      e = 0
    }
  }

  for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}

  e = (e << mLen) | m
  eLen += mLen
  for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}

  buffer[offset + i - d] |= s * 128
}


/***/ }),

/***/ 8954:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

"use strict";


//High level idea:
// 1. Use Clarkson's incremental construction to find convex hull
// 2. Point location in triangulation by jump and walk

module.exports = incrementalConvexHull

var orient = __webpack_require__(3250)
var compareCell = (__webpack_require__(6803)/* .compareCells */ .Fw)

function Simplex(vertices, adjacent, boundary) {
  this.vertices = vertices
  this.adjacent = adjacent
  this.boundary = boundary
  this.lastVisited = -1
}

Simplex.prototype.flip = function() {
  var t = this.vertices[0]
  this.vertices[0] = this.vertices[1]
  this.vertices[1] = t
  var u = this.adjacent[0]
  this.adjacent[0] = this.adjacent[1]
  this.adjacent[1] = u
}

function GlueFacet(vertices, cell, index) {
  this.vertices = vertices
  this.cell = cell
  this.index = index
}

function compareGlue(a, b) {
  return compareCell(a.vertices, b.vertices)
}

function wrapper(test) {
  return function() {
    var tuple = this.tuple
    return test.apply(this, tuple)
  }
}

function bakeOrient(d) {
  var test = orient[d+1]
  if(!test) {
    test = orient
  }
  return wrapper(test)
}

var BAKED = []

function Triangulation(dimension, vertices, simplices) {
  this.dimension = dimension
  this.vertices = vertices
  this.simplices = simplices
  this.interior = simplices.filter(function(c) {
    return !c.boundary
  })

  this.tuple = new Array(dimension+1)
  for(var i=0; i<=dimension; ++i) {
    this.tuple[i] = this.vertices[i]
  }

  var o = BAKED[dimension]
  if(!o) {
    o = BAKED[dimension] = bakeOrient(dimension)
  }
  this.orient = o
}

var proto = Triangulation.prototype

//Degenerate situation where we are on boundary, but coplanar to face
proto.handleBoundaryDegeneracy = function(cell, point) {
  var d = this.dimension
  var n = this.vertices.length - 1
  var tuple = this.tuple
  var verts = this.vertices

  //Dumb solution: Just do dfs from boundary cell until we find any peak, or terminate
  var toVisit = [ cell ]
  cell.lastVisited = -n
  while(toVisit.length > 0) {
    cell = toVisit.pop()
    var cellAdj = cell.adjacent
    for(var i=0; i<=d; ++i) {
      var neighbor = cellAdj[i]
      if(!neighbor.boundary || neighbor.lastVisited <= -n) {
        continue
      }
      var nv = neighbor.vertices
      for(var j=0; j<=d; ++j) {
        var vv = nv[j]
        if(vv < 0) {
          tuple[j] = point
        } else {
          tuple[j] = verts[vv]
        }
      }
      var o = this.orient()
      if(o > 0) {
        return neighbor
      }
      neighbor.lastVisited = -n
      if(o === 0) {
        toVisit.push(neighbor)
      }
    }
  }
  return null
}

proto.walk = function(point, random) {
  //Alias local properties
  var n = this.vertices.length - 1
  var d = this.dimension
  var verts = this.vertices
  var tuple = this.tuple

  //Compute initial jump cell
  var initIndex = random ? (this.interior.length * Math.random())|0 : (this.interior.length-1)
  var cell = this.interior[ initIndex ]

  //Start walking
outerLoop:
  while(!cell.boundary) {
    var cellVerts = cell.vertices
    var cellAdj = cell.adjacent

    for(var i=0; i<=d; ++i) {
      tuple[i] = verts[cellVerts[i]]
    }
    cell.lastVisited = n

    //Find farthest adjacent cell
    for(var i=0; i<=d; ++i) {
      var neighbor = cellAdj[i]
      if(neighbor.lastVisited >= n) {
        continue
      }
      var prev = tuple[i]
      tuple[i] = point
      var o = this.orient()
      tuple[i] = prev
      if(o < 0) {
        cell = neighbor
        continue outerLoop
      } else {
        if(!neighbor.boundary) {
          neighbor.lastVisited = n
        } else {
          neighbor.lastVisited = -n
        }
      }
    }
    return
  }

  return cell
}

proto.addPeaks = function(point, cell) {
  var n = this.vertices.length - 1
  var d = this.dimension
  var verts = this.vertices
  var tuple = this.tuple
  var interior = this.interior
  var simplices = this.simplices

  //Walking finished at boundary, time to add peaks
  var tovisit = [ cell ]

  //Stretch initial boundary cell into a peak
  cell.lastVisited = n
  cell.vertices[cell.vertices.indexOf(-1)] = n
  cell.boundary = false
  interior.push(cell)

  //Record a list of all new boundaries created by added peaks so we can glue them together when we are all done
  var glueFacets = []

  //Do a traversal of the boundary walking outward from starting peak
  while(tovisit.length > 0) {
    //Pop off peak and walk over adjacent cells
    var cell = tovisit.pop()
    var cellVerts = cell.vertices
    var cellAdj = cell.adjacent
    var indexOfN = cellVerts.indexOf(n)
    if(indexOfN < 0) {
      continue
    }

    for(var i=0; i<=d; ++i) {
      if(i === indexOfN) {
        continue
      }

      //For each boundary neighbor of the cell
      var neighbor = cellAdj[i]
      if(!neighbor.boundary || neighbor.lastVisited >= n) {
        continue
      }

      var nv = neighbor.vertices

      //Test if neighbor is a peak
      if(neighbor.lastVisited !== -n) {
        //Compute orientation of p relative to each boundary peak
        var indexOfNeg1 = 0
        for(var j=0; j<=d; ++j) {
          if(nv[j] < 0) {
            indexOfNeg1 = j
            tuple[j] = point
          } else {
            tuple[j] = verts[nv[j]]
          }
        }
        var o = this.orient()

        //Test if neighbor cell is also a peak
        if(o > 0) {
          nv[indexOfNeg1] = n
          neighbor.boundary = false
          interior.push(neighbor)
          tovisit.push(neighbor)
          neighbor.lastVisited = n
          continue
        } else {
          neighbor.lastVisited = -n
        }
      }

      var na = neighbor.adjacent

      //Otherwise, replace neighbor with new face
      var vverts = cellVerts.slice()
      var vadj = cellAdj.slice()
      var ncell = new Simplex(vverts, vadj, true)
      simplices.push(ncell)

      //Connect to neighbor
      var opposite = na.indexOf(cell)
      if(opposite < 0) {
        continue
      }
      na[opposite] = ncell
      vadj[indexOfN] = neighbor

      //Connect to cell
      vverts[i] = -1
      vadj[i] = cell
      cellAdj[i] = ncell

      //Flip facet
      ncell.flip()

      //Add to glue list
      for(var j=0; j<=d; ++j) {
        var uu = vverts[j]
        if(uu < 0 || uu === n) {
          continue
        }
        var nface = new Array(d-1)
        var nptr = 0
        for(var k=0; k<=d; ++k) {
          var vv = vverts[k]
          if(vv < 0 || k === j) {
            continue
          }
          nface[nptr++] = vv
        }
        glueFacets.push(new GlueFacet(nface, ncell, j))
      }
    }
  }

  //Glue boundary facets together
  glueFacets.sort(compareGlue)

  for(var i=0; i+1= 0) {
          bcell[ptr++] = cv[j]
        } else {
          parity = j&1
        }
      }
      if(parity === (d&1)) {
        var t = bcell[0]
        bcell[0] = bcell[1]
        bcell[1] = t
      }
      boundary.push(bcell)
    }
  }
  return boundary
}

function incrementalConvexHull(points, randomSearch) {
  var n = points.length
  if(n === 0) {
    throw new Error("Must have at least d+1 points")
  }
  var d = points[0].length
  if(n <= d) {
    throw new Error("Must input at least d+1 points")
  }

  //FIXME: This could be degenerate, but need to select d+1 non-coplanar points to bootstrap process
  var initialSimplex = points.slice(0, d+1)

  //Make sure initial simplex is positively oriented
  var o = orient.apply(void 0, initialSimplex)
  if(o === 0) {
    throw new Error("Input not in general position")
  }
  var initialCoords = new Array(d+1)
  for(var i=0; i<=d; ++i) {
    initialCoords[i] = i
  }
  if(o < 0) {
    initialCoords[0] = 1
    initialCoords[1] = 0
  }

  //Create initial topological index, glue pointers together (kind of messy)
  var initialCell = new Simplex(initialCoords, new Array(d+1), false)
  var boundary = initialCell.adjacent
  var list = new Array(d+2)
  for(var i=0; i<=d; ++i) {
    var verts = initialCoords.slice()
    for(var j=0; j<=d; ++j) {
      if(j === i) {
        verts[j] = -1
      }
    }
    var t = verts[0]
    verts[0] = verts[1]
    verts[1] = t
    var cell = new Simplex(verts, new Array(d+1), true)
    boundary[i] = cell
    list[i] = cell
  }
  list[d+1] = initialCell
  for(var i=0; i<=d; ++i) {
    var verts = boundary[i].vertices
    var adj = boundary[i].adjacent
    for(var j=0; j<=d; ++j) {
      var v = verts[j]
      if(v < 0) {
        adj[j] = initialCell
        continue
      }
      for(var k=0; k<=d; ++k) {
        if(boundary[k].vertices.indexOf(v) < 0) {
          adj[j] = boundary[k]
        }
      }
    }
  }

  //Initialize triangles
  var triangles = new Triangulation(d, initialSimplex, list)

  //Insert remaining points
  var useRandom = !!randomSearch
  for(var i=d+1; i 3*(weight+1)) {
        rebuildWithInterval(this, interval)
      } else {
        this.left.insert(interval)
      }
    } else {
      this.left = createIntervalTree([interval])
    }
  } else if(interval[0] > this.mid) {
    if(this.right) {
      if(4*(this.right.count+1) > 3*(weight+1)) {
        rebuildWithInterval(this, interval)
      } else {
        this.right.insert(interval)
      }
    } else {
      this.right = createIntervalTree([interval])
    }
  } else {
    var l = bounds.ge(this.leftPoints, interval, compareBegin)
    var r = bounds.ge(this.rightPoints, interval, compareEnd)
    this.leftPoints.splice(l, 0, interval)
    this.rightPoints.splice(r, 0, interval)
  }
}

proto.remove = function(interval) {
  var weight = this.count - this.leftPoints
  if(interval[1] < this.mid) {
    if(!this.left) {
      return NOT_FOUND
    }
    var rw = this.right ? this.right.count : 0
    if(4 * rw > 3 * (weight-1)) {
      return rebuildWithoutInterval(this, interval)
    }
    var r = this.left.remove(interval)
    if(r === EMPTY) {
      this.left = null
      this.count -= 1
      return SUCCESS
    } else if(r === SUCCESS) {
      this.count -= 1
    }
    return r
  } else if(interval[0] > this.mid) {
    if(!this.right) {
      return NOT_FOUND
    }
    var lw = this.left ? this.left.count : 0
    if(4 * lw > 3 * (weight-1)) {
      return rebuildWithoutInterval(this, interval)
    }
    var r = this.right.remove(interval)
    if(r === EMPTY) {
      this.right = null
      this.count -= 1
      return SUCCESS
    } else if(r === SUCCESS) {
      this.count -= 1
    }
    return r
  } else {
    if(this.count === 1) {
      if(this.leftPoints[0] === interval) {
        return EMPTY
      } else {
        return NOT_FOUND
      }
    }
    if(this.leftPoints.length === 1 && this.leftPoints[0] === interval) {
      if(this.left && this.right) {
        var p = this
        var n = this.left
        while(n.right) {
          p = n
          n = n.right
        }
        if(p === this) {
          n.right = this.right
        } else {
          var l = this.left
          var r = this.right
          p.count -= n.count
          p.right = n.left
          n.left = l
          n.right = r
        }
        copy(this, n)
        this.count = (this.left?this.left.count:0) + (this.right?this.right.count:0) + this.leftPoints.length
      } else if(this.left) {
        copy(this, this.left)
      } else {
        copy(this, this.right)
      }
      return SUCCESS
    }
    for(var l = bounds.ge(this.leftPoints, interval, compareBegin); l=0 && arr[i][1] >= lo; --i) {
    var r = cb(arr[i])
    if(r) { return r }
  }
}

function reportRange(arr, cb) {
  for(var i=0; i this.mid) {
    if(this.right) {
      var r = this.right.queryPoint(x, cb)
      if(r) { return r }
    }
    return reportRightRange(this.rightPoints, x, cb)
  } else {
    return reportRange(this.leftPoints, cb)
  }
}

proto.queryInterval = function(lo, hi, cb) {
  if(lo < this.mid && this.left) {
    var r = this.left.queryInterval(lo, hi, cb)
    if(r) { return r }
  }
  if(hi > this.mid && this.right) {
    var r = this.right.queryInterval(lo, hi, cb)
    if(r) { return r }
  }
  if(hi < this.mid) {
    return reportLeftRange(this.leftPoints, hi, cb)
  } else if(lo > this.mid) {
    return reportRightRange(this.rightPoints, lo, cb)
  } else {
    return reportRange(this.leftPoints, cb)
  }
}

function compareNumbers(a, b) {
  return a - b
}

function compareBegin(a, b) {
  var d = a[0] - b[0]
  if(d) { return d }
  return a[1] - b[1]
}

function compareEnd(a, b) {
  var d = a[1] - b[1]
  if(d) { return d }
  return a[0] - b[0]
}

function createIntervalTree(intervals) {
  if(intervals.length === 0) {
    return null
  }
  var pts = []
  for(var i=0; i>1]

  var leftIntervals = []
  var rightIntervals = []
  var centerIntervals = []
  for(var i=0; i
 * @license  MIT
 */

// The _isBuffer check is for Safari 5-7 support, because it's missing
// Object.prototype.constructor. Remove this eventually
module.exports = function (obj) {
  return obj != null && (isBuffer(obj) || isSlowBuffer(obj) || !!obj._isBuffer)
}

function isBuffer (obj) {
  return !!obj.constructor && typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj)
}

// For Node v0.10 support. Remove this eventually.
function isSlowBuffer (obj) {
  return typeof obj.readFloatLE === 'function' && typeof obj.slice === 'function' && isBuffer(obj.slice(0, 0))
}


/***/ }),

/***/ 5219:
/***/ (function(module) {

"use strict";


/**
 * Is this string all whitespace?
 * This solution kind of makes my brain hurt, but it's significantly faster
 * than !str.trim() or any other solution I could find.
 *
 * whitespace codes from: http://en.wikipedia.org/wiki/Whitespace_character
 * and verified with:
 *
 *  for(var i = 0; i < 65536; i++) {
 *      var s = String.fromCharCode(i);
 *      if(+s===0 && !s.trim()) console.log(i, s);
 *  }
 *
 * which counts a couple of these as *not* whitespace, but finds nothing else
 * that *is* whitespace. Note that charCodeAt stops at 16 bits, but it appears
 * that there are no whitespace characters above this, and code points above
 * this do not map onto white space characters.
 */

module.exports = function(str){
    var l = str.length,
        a;
    for(var i = 0; i < l; i++) {
        a = str.charCodeAt(i);
        if((a < 9 || a > 13) && (a !== 32) && (a !== 133) && (a !== 160) &&
            (a !== 5760) && (a !== 6158) && (a < 8192 || a > 8205) &&
            (a !== 8232) && (a !== 8233) && (a !== 8239) && (a !== 8287) &&
            (a !== 8288) && (a !== 12288) && (a !== 65279)) {
                return false;
        }
    }
    return true;
}


/***/ }),

/***/ 395:
/***/ (function(module) {

function lerp(v0, v1, t) {
    return v0*(1-t)+v1*t
}
module.exports = lerp

/***/ }),

/***/ 2652:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

/*jshint unused:true*/
/*
Input:  matrix      ; a 4x4 matrix
Output: translation ; a 3 component vector
        scale       ; a 3 component vector
        skew        ; skew factors XY,XZ,YZ represented as a 3 component vector
        perspective ; a 4 component vector
        quaternion  ; a 4 component vector
Returns false if the matrix cannot be decomposed, true if it can


References:
https://github.com/kamicane/matrix3d/blob/master/lib/Matrix3d.js
https://github.com/ChromiumWebApps/chromium/blob/master/ui/gfx/transform_util.cc
http://www.w3.org/TR/css3-transforms/#decomposing-a-3d-matrix
*/

var normalize = __webpack_require__(4335)

var create = __webpack_require__(6864)
var clone = __webpack_require__(1903)
var determinant = __webpack_require__(9921)
var invert = __webpack_require__(7608)
var transpose = __webpack_require__(5665)
var vec3 = {
    length: __webpack_require__(1387),
    normalize: __webpack_require__(3536),
    dot: __webpack_require__(244),
    cross: __webpack_require__(5911)
}

var tmp = create()
var perspectiveMatrix = create()
var tmpVec4 = [0, 0, 0, 0]
var row = [ [0,0,0], [0,0,0], [0,0,0] ]
var pdum3 = [0,0,0]

module.exports = function decomposeMat4(matrix, translation, scale, skew, perspective, quaternion) {
    if (!translation) translation = [0,0,0]
    if (!scale) scale = [0,0,0]
    if (!skew) skew = [0,0,0]
    if (!perspective) perspective = [0,0,0,1]
    if (!quaternion) quaternion = [0,0,0,1]

    //normalize, if not possible then bail out early
    if (!normalize(tmp, matrix))
        return false

    // perspectiveMatrix is used to solve for perspective, but it also provides
    // an easy way to test for singularity of the upper 3x3 component.
    clone(perspectiveMatrix, tmp)

    perspectiveMatrix[3] = 0
    perspectiveMatrix[7] = 0
    perspectiveMatrix[11] = 0
    perspectiveMatrix[15] = 1

    // If the perspectiveMatrix is not invertible, we are also unable to
    // decompose, so we'll bail early. Constant taken from SkMatrix44::invert.
    if (Math.abs(determinant(perspectiveMatrix) < 1e-8))
        return false

    var a03 = tmp[3], a13 = tmp[7], a23 = tmp[11],
            a30 = tmp[12], a31 = tmp[13], a32 = tmp[14], a33 = tmp[15]

    // First, isolate perspective.
    if (a03 !== 0 || a13 !== 0 || a23 !== 0) {
        tmpVec4[0] = a03
        tmpVec4[1] = a13
        tmpVec4[2] = a23
        tmpVec4[3] = a33

        // Solve the equation by inverting perspectiveMatrix and multiplying
        // rightHandSide by the inverse.
        // resuing the perspectiveMatrix here since it's no longer needed
        var ret = invert(perspectiveMatrix, perspectiveMatrix)
        if (!ret) return false
        transpose(perspectiveMatrix, perspectiveMatrix)

        //multiply by transposed inverse perspective matrix, into perspective vec4
        vec4multMat4(perspective, tmpVec4, perspectiveMatrix)
    } else { 
        //no perspective
        perspective[0] = perspective[1] = perspective[2] = 0
        perspective[3] = 1
    }

    // Next take care of translation
    translation[0] = a30
    translation[1] = a31
    translation[2] = a32

    // Now get scale and shear. 'row' is a 3 element array of 3 component vectors
    mat3from4(row, tmp)

    // Compute X scale factor and normalize first row.
    scale[0] = vec3.length(row[0])
    vec3.normalize(row[0], row[0])

    // Compute XY shear factor and make 2nd row orthogonal to 1st.
    skew[0] = vec3.dot(row[0], row[1])
    combine(row[1], row[1], row[0], 1.0, -skew[0])

    // Now, compute Y scale and normalize 2nd row.
    scale[1] = vec3.length(row[1])
    vec3.normalize(row[1], row[1])
    skew[0] /= scale[1]

    // Compute XZ and YZ shears, orthogonalize 3rd row
    skew[1] = vec3.dot(row[0], row[2])
    combine(row[2], row[2], row[0], 1.0, -skew[1])
    skew[2] = vec3.dot(row[1], row[2])
    combine(row[2], row[2], row[1], 1.0, -skew[2])

    // Next, get Z scale and normalize 3rd row.
    scale[2] = vec3.length(row[2])
    vec3.normalize(row[2], row[2])
    skew[1] /= scale[2]
    skew[2] /= scale[2]


    // At this point, the matrix (in rows) is orthonormal.
    // Check for a coordinate system flip.  If the determinant
    // is -1, then negate the matrix and the scaling factors.
    vec3.cross(pdum3, row[1], row[2])
    if (vec3.dot(row[0], pdum3) < 0) {
        for (var i = 0; i < 3; i++) {
            scale[i] *= -1;
            row[i][0] *= -1
            row[i][1] *= -1
            row[i][2] *= -1
        }
    }

    // Now, get the rotations out
    quaternion[0] = 0.5 * Math.sqrt(Math.max(1 + row[0][0] - row[1][1] - row[2][2], 0))
    quaternion[1] = 0.5 * Math.sqrt(Math.max(1 - row[0][0] + row[1][1] - row[2][2], 0))
    quaternion[2] = 0.5 * Math.sqrt(Math.max(1 - row[0][0] - row[1][1] + row[2][2], 0))
    quaternion[3] = 0.5 * Math.sqrt(Math.max(1 + row[0][0] + row[1][1] + row[2][2], 0))

    if (row[2][1] > row[1][2])
        quaternion[0] = -quaternion[0]
    if (row[0][2] > row[2][0])
        quaternion[1] = -quaternion[1]
    if (row[1][0] > row[0][1])
        quaternion[2] = -quaternion[2]
    return true
}

//will be replaced by gl-vec4 eventually
function vec4multMat4(out, a, m) {
    var x = a[0], y = a[1], z = a[2], w = a[3];
    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;
    out[3] = m[3] * x + m[7] * y + m[11] * z + m[15] * w;
    return out;
}

//gets upper-left of a 4x4 matrix into a 3x3 of vectors
function mat3from4(out, mat4x4) {
    out[0][0] = mat4x4[0]
    out[0][1] = mat4x4[1]
    out[0][2] = mat4x4[2]
    
    out[1][0] = mat4x4[4]
    out[1][1] = mat4x4[5]
    out[1][2] = mat4x4[6]

    out[2][0] = mat4x4[8]
    out[2][1] = mat4x4[9]
    out[2][2] = mat4x4[10]
}

function combine(out, a, b, scale1, scale2) {
    out[0] = a[0] * scale1 + b[0] * scale2
    out[1] = a[1] * scale1 + b[1] * scale2
    out[2] = a[2] * scale1 + b[2] * scale2
}

/***/ }),

/***/ 4335:
/***/ (function(module) {

module.exports = function normalize(out, mat) {
    var m44 = mat[15]
    // Cannot normalize.
    if (m44 === 0) 
        return false
    var scale = 1 / m44
    for (var i=0; i<16; i++)
        out[i] = mat[i] * scale
    return true
}

/***/ }),

/***/ 7442:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

var lerp = __webpack_require__(6658)

var recompose = __webpack_require__(7182)
var decompose = __webpack_require__(2652)
var determinant = __webpack_require__(9921)
var slerp = __webpack_require__(8648)

var state0 = state()
var state1 = state()
var tmp = state()

module.exports = interpolate
function interpolate(out, start, end, alpha) {
    if (determinant(start) === 0 || determinant(end) === 0)
        return false

    //decompose the start and end matrices into individual components
    var r0 = decompose(start, state0.translate, state0.scale, state0.skew, state0.perspective, state0.quaternion)
    var r1 = decompose(end, state1.translate, state1.scale, state1.skew, state1.perspective, state1.quaternion)
    if (!r0 || !r1)
        return false    


    //now lerp/slerp the start and end components into a temporary     lerp(tmptranslate, state0.translate, state1.translate, alpha)
    lerp(tmp.translate, state0.translate, state1.translate, alpha)
    lerp(tmp.skew, state0.skew, state1.skew, alpha)
    lerp(tmp.scale, state0.scale, state1.scale, alpha)
    lerp(tmp.perspective, state0.perspective, state1.perspective, alpha)
    slerp(tmp.quaternion, state0.quaternion, state1.quaternion, alpha)

    //and recompose into our 'out' matrix
    recompose(out, tmp.translate, tmp.scale, tmp.skew, tmp.perspective, tmp.quaternion)
    return true
}

function state() {
    return {
        translate: vec3(),
        scale: vec3(1),
        skew: vec3(),
        perspective: vec4(),
        quaternion: vec4()
    }
}

function vec3(n) {
    return [n||0,n||0,n||0]
}

function vec4() {
    return [0,0,0,1]
}

/***/ }),

/***/ 7182:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

/*
Input:  translation ; a 3 component vector
        scale       ; a 3 component vector
        skew        ; skew factors XY,XZ,YZ represented as a 3 component vector
        perspective ; a 4 component vector
        quaternion  ; a 4 component vector
Output: matrix      ; a 4x4 matrix

From: http://www.w3.org/TR/css3-transforms/#recomposing-to-a-3d-matrix
*/

var mat4 = {
    identity: __webpack_require__(7894),
    translate: __webpack_require__(7656),
    multiply: __webpack_require__(6760),
    create: __webpack_require__(6864),
    scale: __webpack_require__(2504),
    fromRotationTranslation: __webpack_require__(6743)
}

var rotationMatrix = mat4.create()
var temp = mat4.create()

module.exports = function recomposeMat4(matrix, translation, scale, skew, perspective, quaternion) {
    mat4.identity(matrix)

    //apply translation & rotation
    mat4.fromRotationTranslation(matrix, quaternion, translation)

    //apply perspective
    matrix[3] = perspective[0]
    matrix[7] = perspective[1]
    matrix[11] = perspective[2]
    matrix[15] = perspective[3]
        
    // apply skew
    // temp is a identity 4x4 matrix initially
    mat4.identity(temp)

    if (skew[2] !== 0) {
        temp[9] = skew[2]
        mat4.multiply(matrix, matrix, temp)
    }

    if (skew[1] !== 0) {
        temp[9] = 0
        temp[8] = skew[1]
        mat4.multiply(matrix, matrix, temp)
    }

    if (skew[0] !== 0) {
        temp[8] = 0
        temp[4] = skew[0]
        mat4.multiply(matrix, matrix, temp)
    }

    //apply scale
    mat4.scale(matrix, matrix, scale)
    return matrix
}

/***/ }),

/***/ 4192:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

"use strict";


var bsearch   = __webpack_require__(2478)
var m4interp  = __webpack_require__(7442)
var invert44  = __webpack_require__(7608)
var rotateX   = __webpack_require__(5567)
var rotateY   = __webpack_require__(2408)
var rotateZ   = __webpack_require__(7089)
var lookAt    = __webpack_require__(6582)
var translate = __webpack_require__(7656)
var scale     = __webpack_require__(2504)
var normalize = __webpack_require__(3536)

var DEFAULT_CENTER = [0,0,0]

module.exports = createMatrixCameraController

function MatrixCameraController(initialMatrix) {
  this._components    = initialMatrix.slice()
  this._time          = [0]
  this.prevMatrix     = initialMatrix.slice()
  this.nextMatrix     = initialMatrix.slice()
  this.computedMatrix = initialMatrix.slice()
  this.computedInverse = initialMatrix.slice()
  this.computedEye    = [0,0,0]
  this.computedUp     = [0,0,0]
  this.computedCenter = [0,0,0]
  this.computedRadius = [0]
  this._limits        = [-Infinity, Infinity]
}

var proto = MatrixCameraController.prototype

proto.recalcMatrix = function(t) {
  var time = this._time
  var tidx = bsearch.le(time, t)
  var mat = this.computedMatrix
  if(tidx < 0) {
    return
  }
  var comps = this._components
  if(tidx === time.length-1) {
    var ptr = 16*tidx
    for(var i=0; i<16; ++i) {
      mat[i] = comps[ptr++]
    }
  } else {
    var dt = (time[tidx+1] - time[tidx])
    var ptr = 16*tidx
    var prev = this.prevMatrix
    var allEqual = true
    for(var i=0; i<16; ++i) {
      prev[i] = comps[ptr++]
    }
    var next = this.nextMatrix
    for(var i=0; i<16; ++i) {
      next[i] = comps[ptr++]
      allEqual = allEqual && (prev[i] === next[i])
    }
    if(dt < 1e-6 || allEqual) {
      for(var i=0; i<16; ++i) {
        mat[i] = prev[i]
      }
    } else {
      m4interp(mat, prev, next, (t - time[tidx])/dt)
    }
  }

  var up = this.computedUp
  up[0] = mat[1]
  up[1] = mat[5]
  up[2] = mat[9]
  normalize(up, up)

  var imat = this.computedInverse
  invert44(imat, mat)
  var eye = this.computedEye
  var w = imat[15]
  eye[0] = imat[12]/w
  eye[1] = imat[13]/w
  eye[2] = imat[14]/w

  var center = this.computedCenter
  var radius = Math.exp(this.computedRadius[0])
  for(var i=0; i<3; ++i) {
    center[i] = eye[i] - mat[2+4*i] * radius
  }
}

proto.idle = function(t) {
  if(t < this.lastT()) {
    return
  }
  var mc = this._components
  var ptr = mc.length-16
  for(var i=0; i<16; ++i) {
    mc.push(mc[ptr++])
  }
  this._time.push(t)
}

proto.flush = function(t) {
  var idx = bsearch.gt(this._time, t) - 2
  if(idx < 0) {
    return
  }
  this._time.splice(0, idx)
  this._components.splice(0, 16*idx)
}

proto.lastT = function() {
  return this._time[this._time.length-1]
}

proto.lookAt = function(t, eye, center, up) {
  this.recalcMatrix(t)
  eye    = eye || this.computedEye
  center = center || DEFAULT_CENTER
  up     = up || this.computedUp
  this.setMatrix(t, lookAt(this.computedMatrix, eye, center, up))
  var d2 = 0.0
  for(var i=0; i<3; ++i) {
    d2 += Math.pow(center[i] - eye[i], 2)
  }
  d2 = Math.log(Math.sqrt(d2))
  this.computedRadius[0] = d2
}

proto.rotate = function(t, yaw, pitch, roll) {
  this.recalcMatrix(t)
  var mat = this.computedInverse
  if(yaw)   rotateY(mat, mat, yaw)
  if(pitch) rotateX(mat, mat, pitch)
  if(roll)  rotateZ(mat, mat, roll)
  this.setMatrix(t, invert44(this.computedMatrix, mat))
}

var tvec = [0,0,0]

proto.pan = function(t, dx, dy, dz) {
  tvec[0] = -(dx || 0.0)
  tvec[1] = -(dy || 0.0)
  tvec[2] = -(dz || 0.0)
  this.recalcMatrix(t)
  var mat = this.computedInverse
  translate(mat, mat, tvec)
  this.setMatrix(t, invert44(mat, mat))
}

proto.translate = function(t, dx, dy, dz) {
  tvec[0] = dx || 0.0
  tvec[1] = dy || 0.0
  tvec[2] = dz || 0.0
  this.recalcMatrix(t)
  var mat = this.computedMatrix
  translate(mat, mat, tvec)
  this.setMatrix(t, mat)
}

proto.setMatrix = function(t, mat) {
  if(t < this.lastT()) {
    return
  }
  this._time.push(t)
  for(var i=0; i<16; ++i) {
    this._components.push(mat[i])
  }
}

proto.setDistance = function(t, d) {
  this.computedRadius[0] = d
}

proto.setDistanceLimits = function(a,b) {
  var lim = this._limits
  lim[0] = a
  lim[1] = b
}

proto.getDistanceLimits = function(out) {
  var lim = this._limits
  if(out) {
    out[0] = lim[0]
    out[1] = lim[1]
    return out
  }
  return lim
}

function createMatrixCameraController(options) {
  options = options || {}
  var matrix = options.matrix || 
              [1,0,0,0,
               0,1,0,0,
               0,0,1,0,
               0,0,0,1]
  return new MatrixCameraController(matrix)
}


/***/ }),

/***/ 3090:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

"use strict";


module.exports = monotoneConvexHull2D

var orient = (__webpack_require__(3250)[3])

function monotoneConvexHull2D(points) {
  var n = points.length

  if(n < 3) {
    var result = new Array(n)
    for(var i=0; i 1 && orient(
        points[lower[m-2]], 
        points[lower[m-1]], 
        p) <= 0) {
      m -= 1
      lower.pop()
    }
    lower.push(idx)

    //Insert into upper list
    m = upper.length
    while(m > 1 && orient(
        points[upper[m-2]], 
        points[upper[m-1]], 
        p) >= 0) {
      m -= 1
      upper.pop()
    }
    upper.push(idx)
  }

  //Merge lists together
  var result = new Array(upper.length + lower.length - 2)
  var ptr    = 0
  for(var i=0, nl=lower.length; i0; --j) {
    result[ptr++] = upper[j]
  }

  //Return result
  return result
}

/***/ }),

/***/ 351:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

"use strict";


module.exports = mouseListen

var mouse = __webpack_require__(4687)

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
}


/***/ }),

/***/ 24:
/***/ (function(module) {

var rootPosition = { left: 0, top: 0 }

module.exports = mouseEventOffset
function mouseEventOffset (ev, target, out) {
  target = target || ev.currentTarget || ev.srcElement
  if (!Array.isArray(out)) {
    out = [ 0, 0 ]
  }
  var cx = ev.clientX || 0
  var cy = ev.clientY || 0
  var rect = getBoundingClientOffset(target)
  out[0] = cx - rect.left
  out[1] = cy - rect.top
  return out
}

function getBoundingClientOffset (element) {
  if (element === window ||
      element === document ||
      element === document.body) {
    return rootPosition
  } else {
    return element.getBoundingClientRect()
  }
}


/***/ }),

/***/ 4687:
/***/ (function(__unused_webpack_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< 0) {
        i1 = 1
        P[X++] = phase(d0[p0], x0, x1, x2)
        p0 += u0_0
        if (s0 > 0) {
          i0 = 1
          c0_0 = d0[p0]
          b0 = P[X] = phase(c0_0, x0, x1, x2)
          b1 = P[X + e1]
          b2 = P[X + e2]
          b3 = P[X + e3]
          if (b0 !== b1 || b0 !== b2 || b0 !== b3) {
            c0_1 = d0[p0 + d0_1]
            c0_2 = d0[p0 + d0_2]
            c0_3 = d0[p0 + d0_3]
            vertex(i0, i1, c0_0, c0_1, c0_2, c0_3, b0, b1, b2, b3, x0, x1, x2)
            v0 = V[X] = N++
          }
          X += 1
          p0 += u0_0
          for (i0 = 2; i0 < s0; ++i0) {
            c0_0 = d0[p0]
            b0 = P[X] = phase(c0_0, x0, x1, x2)
            b1 = P[X + e1]
            b2 = P[X + e2]
            b3 = P[X + e3]
            if (b0 !== b1 || b0 !== b2 || b0 !== b3) {
              c0_1 = d0[p0 + d0_1]
              c0_2 = d0[p0 + d0_2]
              c0_3 = d0[p0 + d0_3]
              vertex(i0, i1, c0_0, c0_1, c0_2, c0_3, b0, b1, b2, b3, x0, x1, x2)
              v0 = V[X] = N++
              if (b3 !== b1) {
                face(V[X + e1], v0, c0_3, c0_1, b3, b1, x0, x1, x2)
              }
            }
            X += 1
            p0 += u0_0
          }
        }
        p0 += u0_1
        X = 0
        T = e1
        e1 = y1
        y1 = T
        T = e2
        e2 = y2
        y2 = T
        T = e3
        e3 = y3
        y3 = T
        for (i1 = 2; i1 < s1; ++i1) {
          P[X++] = phase(d0[p0], x0, x1, x2)
          p0 += u0_0
          if (s0 > 0) {
            i0 = 1
            c0_0 = d0[p0]
            b0 = P[X] = phase(c0_0, x0, x1, x2)
            b1 = P[X + e1]
            b2 = P[X + e2]
            b3 = P[X + e3]
            if (b0 !== b1 || b0 !== b2 || b0 !== b3) {
              c0_1 = d0[p0 + d0_1]
              c0_2 = d0[p0 + d0_2]
              c0_3 = d0[p0 + d0_3]
              vertex(i0, i1, c0_0, c0_1, c0_2, c0_3, b0, b1, b2, b3, x0, x1, x2)
              v0 = V[X] = N++
              if (b3 !== b2) {
                face(V[X + e2], v0, c0_2, c0_3, b2, b3, x0, x1, x2)
              }
            }
            X += 1
            p0 += u0_0
            for (i0 = 2; i0 < s0; ++i0) {
              c0_0 = d0[p0]
              b0 = P[X] = phase(c0_0, x0, x1, x2)
              b1 = P[X + e1]
              b2 = P[X + e2]
              b3 = P[X + e3]
              if (b0 !== b1 || b0 !== b2 || b0 !== b3) {
                c0_1 = d0[p0 + d0_1]
                c0_2 = d0[p0 + d0_2]
                c0_3 = d0[p0 + d0_3]
                vertex(i0, i1, c0_0, c0_1, c0_2, c0_3, b0, b1, b2, b3, x0, x1, x2)
                v0 = V[X] = N++
                if (b3 !== b2) {
                  face(V[X + e2], v0, c0_2, c0_3, b2, b3, x0, x1, x2)
                }
                if (b3 !== b1) {
                  face(V[X + e1], v0, c0_3, c0_1, b3, b1, x0, x1, x2)
                }
              }
              X += 1
              p0 += u0_0
            }
          }
          if (i1 & 1) {
            X = 0
          }
          T = e1
          e1 = y1
          y1 = T
          T = e2
          e2 = y2
          y2 = T
          T = e3
          e3 = y3
          y3 = T
          p0 += u0_1
        }
      }
      freeUint32(V)
      freeUint32(P)
    }
  },
  "false,1,0": function anonymous(vertex, face, phase, mallocUint32, freeUint32) {
    return function extractContour1_0(a0, x0, x1, x2) {
      var s0 = a0.shape[0] | 0,
        s1 = a0.shape[1] | 0,
        d0 = a0.data,
        o0 = a0.offset | 0,
        t0_0 = a0.stride[0] | 0,
        t0_1 = a0.stride[1] | 0,
        p0 = o0,
        c0_0,
        d0_1 = -t0_0 | 0,
        c0_1 = 0,
        d0_2 = -t0_1 | 0,
        c0_2 = 0,
        d0_3 = (-t0_0 - t0_1) | 0,
        c0_3 = 0,
        u0_1 = t0_1 | 0,
        u0_0 = (t0_0 - t0_1 * s1) | 0,
        i0 = 0,
        i1 = 0,
        N = 0,
        Q = (2 * s1) | 0,
        P = mallocUint32(Q),
        V = mallocUint32(Q),
        X = 0,
        b0 = 0,
        e2 = -1 | 0,
        y2 = -1 | 0,
        b2 = 0,
        e1 = -s1 | 0,
        y1 = s1 | 0,
        b1 = 0,
        e3 = (-s1 - 1) | 0,
        y3 = (s1 - 1) | 0,
        b3 = 0,
        v0 = 0,
        T = 0
      for (i1 = 0; i1 < s1; ++i1) {
        P[X++] = phase(d0[p0], x0, x1, x2)
        p0 += u0_1
      }
      p0 += u0_0
      if (s0 > 0) {
        i0 = 1
        P[X++] = phase(d0[p0], x0, x1, x2)
        p0 += u0_1
        if (s1 > 0) {
          i1 = 1
          c0_0 = d0[p0]
          b0 = P[X] = phase(c0_0, x0, x1, x2)
          b1 = P[X + e1]
          b2 = P[X + e2]
          b3 = P[X + e3]
          if (b0 !== b1 || b0 !== b2 || b0 !== b3) {
            c0_1 = d0[p0 + d0_1]
            c0_2 = d0[p0 + d0_2]
            c0_3 = d0[p0 + d0_3]
            vertex(i0, i1, c0_0, c0_1, c0_2, c0_3, b0, b1, b2, b3, x0, x1, x2)
            v0 = V[X] = N++
          }
          X += 1
          p0 += u0_1
          for (i1 = 2; i1 < s1; ++i1) {
            c0_0 = d0[p0]
            b0 = P[X] = phase(c0_0, x0, x1, x2)
            b1 = P[X + e1]
            b2 = P[X + e2]
            b3 = P[X + e3]
            if (b0 !== b1 || b0 !== b2 || b0 !== b3) {
              c0_1 = d0[p0 + d0_1]
              c0_2 = d0[p0 + d0_2]
              c0_3 = d0[p0 + d0_3]
              vertex(i0, i1, c0_0, c0_1, c0_2, c0_3, b0, b1, b2, b3, x0, x1, x2)
              v0 = V[X] = N++
              if (b3 !== b2) {
                face(V[X + e2], v0, c0_2, c0_3, b2, b3, x0, x1, x2)
              }
            }
            X += 1
            p0 += u0_1
          }
        }
        p0 += u0_0
        X = 0
        T = e1
        e1 = y1
        y1 = T
        T = e2
        e2 = y2
        y2 = T
        T = e3
        e3 = y3
        y3 = T
        for (i0 = 2; i0 < s0; ++i0) {
          P[X++] = phase(d0[p0], x0, x1, x2)
          p0 += u0_1
          if (s1 > 0) {
            i1 = 1
            c0_0 = d0[p0]
            b0 = P[X] = phase(c0_0, x0, x1, x2)
            b1 = P[X + e1]
            b2 = P[X + e2]
            b3 = P[X + e3]
            if (b0 !== b1 || b0 !== b2 || b0 !== b3) {
              c0_1 = d0[p0 + d0_1]
              c0_2 = d0[p0 + d0_2]
              c0_3 = d0[p0 + d0_3]
              vertex(i0, i1, c0_0, c0_1, c0_2, c0_3, b0, b1, b2, b3, x0, x1, x2)
              v0 = V[X] = N++
              if (b3 !== b1) {
                face(V[X + e1], v0, c0_3, c0_1, b3, b1, x0, x1, x2)
              }
            }
            X += 1
            p0 += u0_1
            for (i1 = 2; i1 < s1; ++i1) {
              c0_0 = d0[p0]
              b0 = P[X] = phase(c0_0, x0, x1, x2)
              b1 = P[X + e1]
              b2 = P[X + e2]
              b3 = P[X + e3]
              if (b0 !== b1 || b0 !== b2 || b0 !== b3) {
                c0_1 = d0[p0 + d0_1]
                c0_2 = d0[p0 + d0_2]
                c0_3 = d0[p0 + d0_3]
                vertex(i0, i1, c0_0, c0_1, c0_2, c0_3, b0, b1, b2, b3, x0, x1, x2)
                v0 = V[X] = N++
                if (b3 !== b2) {
                  face(V[X + e2], v0, c0_2, c0_3, b2, b3, x0, x1, x2)
                }
                if (b3 !== b1) {
                  face(V[X + e1], v0, c0_3, c0_1, b3, b1, x0, x1, x2)
                }
              }
              X += 1
              p0 += u0_1
            }
          }
          if (i0 & 1) {
            X = 0
          }
          T = e1
          e1 = y1
          y1 = T
          T = e2
          e2 = y2
          y2 = T
          T = e3
          e3 = y3
          y3 = T
          p0 += u0_0
        }
      }
      freeUint32(V)
      freeUint32(P)
    }
  },
}

//Generates the surface procedure
function compileSurfaceProcedure(vertexFunc, faceFunc, phaseFunc, scalarArgs, order, typesig) {
  var key = [typesig, order].join(',')
  var proc = allFns[key]

  return proc(
    vertexFunc,
    faceFunc,
    phaseFunc,
    pool.mallocUint32,
    pool.freeUint32)
}

function createSurfaceExtractor(args) {
  function error(msg) {
    throw new Error("ndarray-extract-contour: " + msg)
  }
  if(typeof args !== "object") {
    error("Must specify arguments")
  }
  var order = args.order
  if(!Array.isArray(order)) {
    error("Must specify order")
  }
  var arrays = args.arrayArguments||1
  if(arrays < 1) {
    error("Must have at least one array argument")
  }
  var scalars = args.scalarArguments||0
  if(scalars < 0) {
    error("Scalar arg count must be > 0")
  }
  if(typeof args.vertex !== "function") {
    error("Must specify vertex creation function")
  }
  if(typeof args.cell !== "function") {
    error("Must specify cell creation function")
  }
  if(typeof args.phase !== "function") {
    error("Must specify phase function")
  }
  var getters = args.getters || []
  var typesig = new Array(arrays)
  for(var i=0; i= 0) {
      typesig[i] = true
    } else {
      typesig[i] = false
    }
  }
  return compileSurfaceProcedure(
    args.vertex,
    args.cell,
    args.phase,
    scalars,
    order,
    typesig)
}

/***/ }),

/***/ 6199:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

"use strict";


var dup = __webpack_require__(1338)

var CACHED_CWiseOp = {
  zero: function(SS, a0, t0, p0) {
      var s0 = SS[0], t0p0 = t0[0]
      p0 |= 0
      var i0 = 0, d0s0 = t0p0
      for (i0 = 0; i0 < s0; ++i0) {
        a0[p0] = 0
        p0 += d0s0
      }
    },

    fdTemplate1: function(SS, a0, t0, p0, a1, t1, p1) {
    var s0 = SS[0], t0p0 = t0[0], t1p0 = t1[0], q0 = -1 * t0p0, q1 = t0p0
    p0 |= 0
    p1 |= 0
    var i0 = 0, d0s0 = t0p0, d1s0 = t1p0
    for (i0 = 0; i0 < s0; ++i0) {
      a1[p1] = 0.5 * (a0[p0 + q0] - a0[p0 + q1])
      p0 += d0s0
      p1 += d1s0
    }
  },

  fdTemplate2: function(SS, a0, t0, p0, a1, t1, p1, a2, t2, p2) {
    var s0 = SS[0], s1 = SS[1], t0p0 = t0[0], t0p1 = t0[1], t1p0 = t1[0], t1p1 = t1[1], t2p0 = t2[0], t2p1 = t2[1], q0 = -1 * t0p0, q1 = t0p0, q2 = -1 * t0p1, q3 = t0p1
    p0 |= 0
    p1 |= 0
    p2 |= 0
    var i0 = 0, i1 = 0, d0s0 = t0p1, d0s1 = (t0p0 - s1 * t0p1), d1s0 = t1p1, d1s1 = (t1p0 - s1 * t1p1), d2s0 = t2p1, d2s1 = (t2p0 - s1 * t2p1)
    for (i1 = 0; i1 < s0; ++i1) {
      for (i0 = 0; i0 < s1; ++i0) {
        a1[p1] = 0.5 * (a0[p0 + q0] - a0[p0 + q1]); a2[p2] = 0.5 * (a0[p0 + q2] - a0[p0 + q3])
        p0 += d0s0
        p1 += d1s0
        p2 += d2s0
      }
      p0 += d0s1
      p1 += d1s1
      p2 += d2s1
    }
  }
}

var CACHED_thunk = {
  cdiff: function(compile) {
    var CACHED = {}
    return function cdiff_cwise_thunk(array0, array1, array2) {
      var t0 = array0.dtype, r0 = array0.order, t1 = array1.dtype, r1 = array1.order, t2 = array2.dtype, r2 = array2.order, type = [t0, r0.join(), t1, r1.join(), t2, r2.join()].join(), proc = CACHED[type]
      if (!proc) { CACHED[type] = proc = compile([t0, r0, t1, r1, t2, r2]) } return proc(array0.shape.slice(0), array0.data, array0.stride, array0.offset | 0, array1.data, array1.stride, array1.offset | 0, array2.data, array2.stride, array2.offset | 0)
    }
  },

  zero: function(compile) {
    var CACHED = {}
    return function zero_cwise_thunk(array0) {
      var t0 = array0.dtype, r0 = array0.order, type = [t0, r0.join()].join(), proc = CACHED[type]
      if (!proc) { CACHED[type] = proc = compile([t0, r0]) } return proc(array0.shape.slice(0), array0.data, array0.stride, array0.offset | 0)
    }
  },

  fdTemplate1: function(compile) {
    var CACHED = {}
    return function fdTemplate1_cwise_thunk(array0, array1) {
      var t0 = array0.dtype, r0 = array0.order, t1 = array1.dtype, r1 = array1.order, type = [t0, r0.join(), t1, r1.join()].join(), proc = CACHED[type]
      if (!proc) { CACHED[type] = proc = compile([t0, r0, t1, r1]) } return proc(array0.shape.slice(0), array0.data, array0.stride, array0.offset | 0, array1.data, array1.stride, array1.offset | 0)
    }
  },

  fdTemplate2: function(compile) {
    var CACHED = {}
    return function fdTemplate2_cwise_thunk(array0, array1, array4) {
      var t0 = array0.dtype, r0 = array0.order, t1 = array1.dtype, r1 = array1.order, t4 = array4.dtype, r4 = array4.order, type = [t0, r0.join(), t1, r1.join(), t4, r4.join()].join(), proc = CACHED[type]
      if (!proc) { CACHED[type] = proc = compile([t0, r0, t1, r1, t4, r4]) } return proc(array0.shape.slice(0), array0.data, array0.stride, array0.offset | 0, array1.data, array1.stride, array1.offset | 0, array4.data, array4.stride, array4.offset | 0)
    }
  },
}

function createThunk(proc) {
  var thunk = CACHED_thunk[proc.funcName]
  return thunk(compile.bind(undefined, proc))
}

function compile(proc) {
  return CACHED_CWiseOp[proc.funcName]
}

function cwiseCompiler(user_args) {
  return createThunk({
    funcName: user_args.funcName
  })
}


var TEMPLATE_CACHE  = {}
var GRADIENT_CACHE  = {}

var EmptyProc = {
  body: "",
  args: [],
  thisVars: [],
  localVars: []
}

var centralDiff = cwiseCompiler({
  funcName: 'cdiff'
})

var zeroOut = cwiseCompiler({
  funcName: 'zero'
})

function generateTemplate(d) {
  if(d in TEMPLATE_CACHE) {
    return TEMPLATE_CACHE[d]
  }
  return TEMPLATE_CACHE[d] = cwiseCompiler({
    funcName: 'fdTemplate' + d
  })
}

function CACHED_link(diff, zero, grad1, grad2) {
  return function(dst, src) {
    var s = src.shape.slice()
    if ( true && s[0] > 2 && s[1] > 2) {
      grad2(
        src
          .pick(-1, -1)
          .lo(1, 1)
          .hi(s[0] - 2, s[1] - 2),
        dst
          .pick(-1, -1, 0)
          .lo(1, 1)
          .hi(s[0] - 2, s[1] - 2),
        dst
          .pick(-1, -1, 1)
          .lo(1, 1)
          .hi(s[0] - 2, s[1] - 2)
      )
    }
    if ( true && s[1] > 2) {
      grad1(
        src
          .pick(0, -1)
          .lo(1)
          .hi(s[1] - 2),
        dst
          .pick(0, -1, 1)
          .lo(1)
          .hi(s[1] - 2)
      )
      zero(
        dst
          .pick(0, -1, 0)
          .lo(1)
          .hi(s[1] - 2)
      )
    }
    if ( true && s[1] > 2) {
      grad1(
        src
          .pick(s[0] - 1, -1)
          .lo(1)
          .hi(s[1] - 2),
        dst
          .pick(s[0] - 1, -1, 1)
          .lo(1)
          .hi(s[1] - 2)
      )
      zero(
        dst
          .pick(s[0] - 1, -1, 0)
          .lo(1)
          .hi(s[1] - 2)
      )
    }
    if ( true && s[0] > 2) {
      grad1(
        src
          .pick(-1, 0)
          .lo(1)
          .hi(s[0] - 2),
        dst
          .pick(-1, 0, 0)
          .lo(1)
          .hi(s[0] - 2)
      )
      zero(
        dst
          .pick(-1, 0, 1)
          .lo(1)
          .hi(s[0] - 2)
      )
    }
    if ( true && s[0] > 2) {
      grad1(
        src
          .pick(-1, s[1] - 1)
          .lo(1)
          .hi(s[0] - 2),
        dst
          .pick(-1, s[1] - 1, 0)
          .lo(1)
          .hi(s[0] - 2)
      )
      zero(
        dst
          .pick(-1, s[1] - 1, 1)
          .lo(1)
          .hi(s[0] - 2)
      )
    }
    dst.set(0, 0, 0, 0)
    dst.set(0, 0, 1, 0)
    dst.set(s[0] - 1, 0, 0, 0)
    dst.set(s[0] - 1, 0, 1, 0)
    dst.set(0, s[1] - 1, 0, 0)
    dst.set(0, s[1] - 1, 1, 0)
    dst.set(s[0] - 1, s[1] - 1, 0, 0)
    dst.set(s[0] - 1, s[1] - 1, 1, 0)
    return dst
  }
}


function generateGradient(boundaryConditions) {
  var token = boundaryConditions.join()
  var proc = GRADIENT_CACHE[token]
  if(proc) {
    return proc
  }

  var d = boundaryConditions.length

  var linkArgs  = [ centralDiff, zeroOut ]
  for(var i=1; i<=d; ++i) {
    linkArgs.push(generateTemplate(i))
  }

  var link = CACHED_link

  var proc = link.apply(void 0, linkArgs)

  GRADIENT_CACHE[token] = proc
  return proc
}

module.exports = function gradient(out, inp, bc) {
  if(!Array.isArray(bc)) {
    if(typeof bc === 'string') {
      bc = dup(inp.dimension, bc)
    } else {
      bc = dup(inp.dimension, 'clamp')
    }
  }
  if(inp.size === 0) {
    return out
  }
  if(inp.dimension === 0) {
    out.set(0)
    return out
  }
  var cached = generateGradient(bc)
  return cached(out, inp)
}

/***/ }),

/***/ 4317:
/***/ (function(module) {

"use strict";


function interp1d(arr, x) {
  var ix = Math.floor(x)
    , fx = x - ix
    , s0 = 0 <= ix   && ix   < arr.shape[0]
    , s1 = 0 <= ix+1 && ix+1 < arr.shape[0]
    , w0 = s0 ? +arr.get(ix)   : 0.0
    , w1 = s1 ? +arr.get(ix+1) : 0.0
  return (1.0-fx)*w0 + fx*w1
}

function interp2d(arr, x, y) {
  var ix = Math.floor(x)
    , fx = x - ix
    , s0 = 0 <= ix   && ix   < arr.shape[0]
    , s1 = 0 <= ix+1 && ix+1 < arr.shape[0]
    , iy = Math.floor(y)
    , fy = y - iy
    , t0 = 0 <= iy   && iy   < arr.shape[1]
    , t1 = 0 <= iy+1 && iy+1 < arr.shape[1]
    , w00 = s0&&t0 ? arr.get(ix  ,iy  ) : 0.0
    , w01 = s0&&t1 ? arr.get(ix  ,iy+1) : 0.0
    , w10 = s1&&t0 ? arr.get(ix+1,iy  ) : 0.0
    , w11 = s1&&t1 ? arr.get(ix+1,iy+1) : 0.0
  return (1.0-fy) * ((1.0-fx)*w00 + fx*w10) + fy * ((1.0-fx)*w01 + fx*w11)
}

function interp3d(arr, x, y, z) {
  var ix = Math.floor(x)
    , fx = x - ix
    , s0 = 0 <= ix   && ix   < arr.shape[0]
    , s1 = 0 <= ix+1 && ix+1 < arr.shape[0]
    , iy = Math.floor(y)
    , fy = y - iy
    , t0 = 0 <= iy   && iy   < arr.shape[1]
    , t1 = 0 <= iy+1 && iy+1 < arr.shape[1]
    , iz = Math.floor(z)
    , fz = z - iz
    , u0 = 0 <= iz   && iz   < arr.shape[2]
    , u1 = 0 <= iz+1 && iz+1 < arr.shape[2]
    , w000 = s0&&t0&&u0 ? arr.get(ix,iy,iz)       : 0.0
    , w010 = s0&&t1&&u0 ? arr.get(ix,iy+1,iz)     : 0.0
    , w100 = s1&&t0&&u0 ? arr.get(ix+1,iy,iz)     : 0.0
    , w110 = s1&&t1&&u0 ? arr.get(ix+1,iy+1,iz)   : 0.0
    , w001 = s0&&t0&&u1 ? arr.get(ix,iy,iz+1)     : 0.0
    , w011 = s0&&t1&&u1 ? arr.get(ix,iy+1,iz+1)   : 0.0
    , w101 = s1&&t0&&u1 ? arr.get(ix+1,iy,iz+1)   : 0.0
    , w111 = s1&&t1&&u1 ? arr.get(ix+1,iy+1,iz+1) : 0.0
  return (1.0-fz) * ((1.0-fy) * ((1.0-fx)*w000 + fx*w100) + fy * ((1.0-fx)*w010 + fx*w110)) + fz * ((1.0-fy) * ((1.0-fx)*w001 + fx*w101) + fy * ((1.0-fx)*w011 + fx*w111))
}

function interpNd(arr) {
  var d = arr.shape.length|0
    , ix = new Array(d)
    , fx = new Array(d)
    , s0 = new Array(d)
    , s1 = new Array(d)
    , i, t
  for(i=0; i 0;) {
        if (j1 < 64) {
          s0 = j1
          j1 = 0
        } else {
          s0 = 64
          j1 -= 64
        }
        for (var j2 = SS[1] | 0; j2 > 0;) {
          if (j2 < 64) {
            s1 = j2
            j2 = 0
          } else {
            s1 = 64
            j2 -= 64
          }
          p0 = (offset0 + j1 * t0p0 + j2 * t0p1)
          p1 = (offset1 + j1 * t1p0 + j2 * t1p1)
          var i0 = 0, i1 = 0, i2 = 0, d0s0 = t0p2, d0s1 = (t0p0 - s2 * t0p2), d0s2 = (t0p1 - s0 * t0p0), d1s0 = t1p2, d1s1 = (t1p0 - s2 * t1p2), d1s2 = (t1p1 - s0 * t1p0)
          for (i2 = 0; i2 < s1; ++i2) {
            for (i1 = 0; i1 < s0; ++i1) {
              for (i0 = 0; i0 < s2; ++i0) {
                a0[p0] = a1[p1] * Y0
                p0 += d0s0
                p1 += d1s0
              }
              p0 += d0s1
              p1 += d1s1
            }
            p0 += d0s2
            p1 += d1s2
          }
        }
      }
    }
  },
  'float32,1,0,float32,1,0': function () {
    return function assign_cwise_loop_1s0m2f32(SS, a0, t0, p0, a1, t1, p1) {
      var s0 = SS[0], s1 = SS[1], t0p0 = t0[0], t0p1 = t0[1], t1p0 = t1[0], t1p1 = t1[1]
      p0 |= 0
      p1 |= 0
      var i0 = 0, i1 = 0, d0s0 = t0p1, d0s1 = (t0p0 - s1 * t0p1), d1s0 = t1p1, d1s1 = (t1p0 - s1 * t1p1)
      for (i1 = 0; i1 < s0; ++i1) {
        for (i0 = 0; i0 < s1; ++i0) {
          a0[p0] = a1[p1]
          p0 += d0s0
          p1 += d1s0
        }
        p0 += d0s1
        p1 += d1s1
      }
    }
  },
  'float32,1,0,float32,0,1': function () {
    return function assign_cwise_loop_1s0m0f32(SS, a0, t0, p0, a1, t1, p1) {
      var s0 = SS[0], s1 = SS[1], t0p0 = t0[0], t0p1 = t0[1], t1p0 = t1[0], t1p1 = t1[1]
      p0 |= 0
      p1 |= 0
      var offset0 = p0
      var offset1 = p1
      for (var j0 = SS[1] | 0; j0 > 0;) {
        if (j0 < 64) {
          s1 = j0
          j0 = 0
        } else {
          s1 = 64
          j0 -= 64
        }
        for (var j1 = SS[0] | 0; j1 > 0;) {
          if (j1 < 64) {
            s0 = j1
            j1 = 0
          } else {
            s0 = 64
            j1 -= 64
          }
          p0 = (offset0 + j0 * t0p1 + j1 * t0p0)
          p1 = (offset1 + j0 * t1p1 + j1 * t1p0)
          var i0 = 0, i1 = 0, d0s0 = t0p1, d0s1 = (t0p0 - s1 * t0p1), d1s0 = t1p1, d1s1 = (t1p0 - s1 * t1p1)
          for (i1 = 0; i1 < s0; ++i1) {
            for (i0 = 0; i0 < s1; ++i0) {
              a0[p0] = a1[p1]
              p0 += d0s0
              p1 += d1s0
            }
            p0 += d0s1
            p1 += d1s1
          }
        }
      }
    }
  },
  'uint8,2,0,1,uint8,1,2,0': function () {
    return function assign_cwise_loop_2s0s1m0u8(SS, a0, t0, p0, a1, t1, p1) {
      var s0 = SS[0], s1 = SS[1], s2 = SS[2], t0p0 = t0[0], t0p1 = t0[1], t0p2 = t0[2], t1p0 = t1[0], t1p1 = t1[1], t1p2 = t1[2]
      p0 |= 0
      p1 |= 0
      var offset0 = p0
      var offset1 = p1
      for (var j0 = SS[2] | 0; j0 > 0;) {
        if (j0 < 64) {
          s2 = j0
          j0 = 0
        } else {
          s2 = 64
          j0 -= 64
        }
        for (var j1 = SS[0] | 0; j1 > 0;) {
          if (j1 < 64) {
            s0 = j1
            j1 = 0
          } else {
            s0 = 64
            j1 -= 64
          }
          for (var j2 = SS[1] | 0; j2 > 0;) {
            if (j2 < 64) {
              s1 = j2
              j2 = 0
            } else {
              s1 = 64
              j2 -= 64
            }
            p0 = (offset0 + j0 * t0p2 + j1 * t0p0 + j2 * t0p1)
            p1 = (offset1 + j0 * t1p2 + j1 * t1p0 + j2 * t1p1)
            var i0 = 0, i1 = 0, i2 = 0, d0s0 = t0p2, d0s1 = (t0p0 - s2 * t0p2), d0s2 = (t0p1 - s0 * t0p0), d1s0 = t1p2, d1s1 = (t1p0 - s2 * t1p2), d1s2 = (t1p1 - s0 * t1p0)
            for (i2 = 0; i2 < s1; ++i2) {
              for (i1 = 0; i1 < s0; ++i1) {
                for (i0 = 0; i0 < s2; ++i0) {
                  a0[p0] = a1[p1]
                  p0 += d0s0
                  p1 += d1s0
                }
                p0 += d0s1
                p1 += d1s1
              }
              p0 += d0s2
              p1 += d1s2
            }
          }
        }
      }
    }
  },
  'uint8,2,0,1,array,2,0,1': function () {
    return function assign_cwise_loop_2s0s1m3u8a(SS, a0, t0, p0, a1, t1, p1) {
      var s0 = SS[0], s1 = SS[1], s2 = SS[2], t0p0 = t0[0], t0p1 = t0[1], t0p2 = t0[2], t1p0 = t1[0], t1p1 = t1[1], t1p2 = t1[2]
      p0 |= 0
      p1 |= 0
      var i0 = 0, i1 = 0, i2 = 0, d0s0 = t0p2, d0s1 = (t0p0 - s2 * t0p2), d0s2 = (t0p1 - s0 * t0p0), d1s0 = t1p2, d1s1 = (t1p0 - s2 * t1p2), d1s2 = (t1p1 - s0 * t1p0)
      for (i2 = 0; i2 < s1; ++i2) {
        for (i1 = 0; i1 < s0; ++i1) {
          for (i0 = 0; i0 < s2; ++i0) {
            a0[p0] = a1[p1]
            p0 += d0s0
            p1 += d1s0
          }
          p0 += d0s1
          p1 += d1s1
        }
        p0 += d0s2
        p1 += d1s2
      }
    }
  },
}

//Generates a cwise operator
function generateCWiseOp(proc, typesig) {
  var key = typesig.join(',')
  var f = CACHED_CWiseOp[key]
  return f()
}

var compile = generateCWiseOp

var CACHED_thunk = {
  mul: function (compile) {
    var CACHED = {}
    return function mul_cwise_thunk(array0, array1, array2) {
      var t0 = array0.dtype,
        r0 = array0.order,
        t1 = array1.dtype,
        r1 = array1.order,
        t2 = array2.dtype,
        r2 = array2.order,
        type = [t0, r0.join(), t1, r1.join(), t2, r2.join()].join(),
        proc = CACHED[type]
      if (!proc) {
        CACHED[type] = proc = compile([t0, r0, t1, r1, t2, r2])
      }
      return proc(
        array0.shape.slice(0),
        array0.data,
        array0.stride,
        array0.offset | 0,
        array1.data,
        array1.stride,
        array1.offset | 0,
        array2.data,
        array2.stride,
        array2.offset | 0
      )
    }
  },
  muls: function (compile) {
    var CACHED = {}
    return function muls_cwise_thunk(array0, array1, scalar2) {
      var t0 = array0.dtype,
        r0 = array0.order,
        t1 = array1.dtype,
        r1 = array1.order,
        type = [t0, r0.join(), t1, r1.join()].join(),
        proc = CACHED[type]
      if (!proc) {
        CACHED[type] = proc = compile([t0, r0, t1, r1])
      }
      return proc(
        array0.shape.slice(0),
        array0.data,
        array0.stride,
        array0.offset | 0,
        array1.data,
        array1.stride,
        array1.offset | 0,
        scalar2
      )
    }
  },
  mulseq: function (compile) {
    var CACHED = {}
    return function mulseq_cwise_thunk(array0, scalar1) {
      var t0 = array0.dtype,
        r0 = array0.order,
        type = [t0, r0.join()].join(),
        proc = CACHED[type]
      if (!proc) {
        CACHED[type] = proc = compile([t0, r0])
      }
      return proc(array0.shape.slice(0), array0.data, array0.stride, array0.offset | 0, scalar1)
    }
  },
  div: function (compile) {
    var CACHED = {}
    return function div_cwise_thunk(array0, array1, array2) {
      var t0 = array0.dtype,
        r0 = array0.order,
        t1 = array1.dtype,
        r1 = array1.order,
        t2 = array2.dtype,
        r2 = array2.order,
        type = [t0, r0.join(), t1, r1.join(), t2, r2.join()].join(),
        proc = CACHED[type]
      if (!proc) {
        CACHED[type] = proc = compile([t0, r0, t1, r1, t2, r2])
      }
      return proc(
        array0.shape.slice(0),
        array0.data,
        array0.stride,
        array0.offset | 0,
        array1.data,
        array1.stride,
        array1.offset | 0,
        array2.data,
        array2.stride,
        array2.offset | 0
      )
    }
  },
  divs: function (compile) {
    var CACHED = {}
    return function divs_cwise_thunk(array0, array1, scalar2) {
      var t0 = array0.dtype,
        r0 = array0.order,
        t1 = array1.dtype,
        r1 = array1.order,
        type = [t0, r0.join(), t1, r1.join()].join(),
        proc = CACHED[type]
      if (!proc) {
        CACHED[type] = proc = compile([t0, r0, t1, r1])
      }
      return proc(
        array0.shape.slice(0),
        array0.data,
        array0.stride,
        array0.offset | 0,
        array1.data,
        array1.stride,
        array1.offset | 0,
        scalar2
      )
    }
  },
  divseq: function (compile) {
    var CACHED = {}
    return function divseq_cwise_thunk(array0, scalar1) {
      var t0 = array0.dtype,
        r0 = array0.order,
        type = [t0, r0.join()].join(),
        proc = CACHED[type]
      if (!proc) {
        CACHED[type] = proc = compile([t0, r0])
      }
      return proc(array0.shape.slice(0), array0.data, array0.stride, array0.offset | 0, scalar1)
    }
  },
  assign: function (compile) {
    var CACHED = {}
    return function assign_cwise_thunk(array0, array1) {
      var t0 = array0.dtype,
        r0 = array0.order,
        t1 = array1.dtype,
        r1 = array1.order,
        type = [t0, r0.join(), t1, r1.join()].join(),
        proc = CACHED[type]
      if (!proc) {
        CACHED[type] = proc = compile([t0, r0, t1, r1])
      }
      return proc(
        array0.shape.slice(0),
        array0.data,
        array0.stride,
        array0.offset | 0,
        array1.data,
        array1.stride,
        array1.offset | 0
      )
    }
  },
}

function createThunk(proc) {
  var thunk = CACHED_thunk[proc.funcName]
  return thunk(compile.bind(undefined, proc))
}

function makeOp(user_args) {
  return createThunk({
    funcName: user_args.funcName
  })
}

var assign_ops = {
  mul:  "*",
  div:  "/",
}
;(function(){
  for(var id in assign_ops) {
    exports[id] = makeOp({
      funcName: id
    })
    exports[id+"s"] = makeOp({
      funcName: id+"s"
    })
    exports[id+"seq"] = makeOp({
      funcName: id+"seq"
    })
  }
})();

exports.assign = makeOp({
  funcName: "assign" })


/***/ }),

/***/ 9994:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

"use strict";


var ndarray = __webpack_require__(9618)
var do_convert = __webpack_require__(8277)

module.exports = function convert(arr, result) {
  var shape = [], c = arr, sz = 1
  while(Array.isArray(c)) {
    shape.push(c.length)
    sz *= c.length
    c = c[0]
  }
  if(shape.length === 0) {
    return ndarray()
  }
  if(!result) {
    result = ndarray(new Float64Array(sz), shape)
  }
  do_convert(result, arr)
  return result
}


/***/ }),

/***/ 8277:
/***/ (function(module) {

"use strict";


function CwiseOp() {
  return function (SS, a0, t0, p0, Y0) {
    var s0 = SS[0],
      s1 = SS[1],
      s2 = SS[2],
      t0p0 = t0[0],
      t0p1 = t0[1],
      t0p2 = t0[2],
      index = [0, 0, 0];
    p0 |= 0;
    var i0 = 0,
      i1 = 0,
      i2 = 0,
      d0s0 = t0p2,
      d0s1 = t0p1 - s2 * t0p2,
      d0s2 = t0p0 - s1 * t0p1;
    for (i2 = 0; i2 < s0; ++i2) {
      for (i1 = 0; i1 < s1; ++i1) {
        for (i0 = 0; i0 < s2; ++i0) {
          {
            var _inline_1_v = Y0,
              _inline_1_i;
            for (
              _inline_1_i = 0;
              _inline_1_i < index.length - 1;
              ++_inline_1_i
            ) {
              _inline_1_v = _inline_1_v[index[_inline_1_i]];
            }
            a0[p0] = _inline_1_v[index[index.length - 1]];
          }
          p0 += d0s0;
          ++index[2];
        }
        p0 += d0s1;
        index[2] -= s2;
        ++index[1];
      }
      p0 += d0s2;
      index[1] -= s1;
      ++index[0];
    }
  };
}

//Generates a cwise operator
function generateCWiseOp() {
  return CwiseOp()
}

var compile = generateCWiseOp

function thunk(compile) {
  var CACHED = {};
  return function convert_cwise_thunk(array0, scalar1) {
    var t0 = array0.dtype,
      r0 = array0.order,
      type = [t0, r0.join()].join(),
      proc = CACHED[type];
    if (!proc) {
      CACHED[type] = proc = compile([t0, r0]);
    }
    return proc(
      array0.shape.slice(0),
      array0.data,
      array0.stride,
      array0.offset | 0,
      scalar1
    );
  };
}

function createThunk(proc) {
  return thunk(compile.bind(undefined, proc))
}

function compileCwise(user_args) {
  return createThunk({
    funcName: user_args.funcName
  })
}

module.exports = compileCwise({
  funcName: "convert"
});


/***/ }),

/***/ 7640:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

"use strict";


var pool = __webpack_require__(1888)

function getMallocFree(dtype) {
  switch(dtype) {
    case "uint32":
      return [pool.mallocUint32, pool.freeUint32]
    default:
      return null
  }
}

var CACHED_insertionSort = {
  "uint32,1,0": function (malloc, free) {
    return function ndarrayInsertionSort1d0uint32(left, right, data, offset, s0, s1, n0, n1, d1, e1, f1) {
      var i,
        j,
        cptr,
        ptr = left * s0 + offset,
        i1,
        scratch = malloc(n1),
        dptr,
        sptr,
        a,
        b
      for (i = left + 1; i <= right; ++i) {
        j = i
        ptr += s0
        cptr = ptr
        dptr = 0
        sptr = ptr
        for (i1 = 0; i1 < n1; ++i1) {
          scratch[dptr++] = data[sptr]
          sptr += d1
        }
        __g: while (j-- > left) {
          dptr = 0
          sptr = cptr - s0
          __l: for (i1 = 0; i1 < n1; ++i1) {
            a = data[sptr]
            b = scratch[dptr]
            if (a < b) {
              break __g
            }
            if (a > b) {
              break __l
            }
            sptr += e1
            dptr += f1
          }
          dptr = cptr
          sptr = cptr - s0
          for (i1 = 0; i1 < n1; ++i1) {
            data[dptr] = data[sptr]
            dptr += d1
            sptr += d1
          }
          cptr -= s0
        }
        dptr = cptr
        sptr = 0
        for (i1 = 0; i1 < n1; ++i1) {
          data[dptr] = scratch[sptr++]
          dptr += d1
        }
      }
      free(scratch)
    }
  },
}

function createInsertionSort(order, dtype) {
  var allocator = getMallocFree(dtype)
  var key = [dtype, order].join(',')
  var result = CACHED_insertionSort[key]

  if(allocator) {
    return result(allocator[0], allocator[1])
  } else {
    return result()
  }
}

var CACHED_quickSort = {
  "uint32,1,0": function (insertionSort, malloc, free) {
    return function ndarrayQuickSort1d0uint32(left, right, data, offset, s0, s1, n0, n1, d1, e1, f1) {
      var sixth = ((right - left + 1) / 6) | 0,
        index1 = left + sixth,
        index5 = right - sixth,
        index3 = (left + right) >> 1,
        index2 = index3 - sixth,
        index4 = index3 + sixth,
        el1 = index1,
        el2 = index2,
        el3 = index3,
        el4 = index4,
        el5 = index5,
        less = left + 1,
        great = right - 1,
        pivots_are_equal = true,
        tmp,
        tmp0,
        x,
        y,
        z,
        k,
        ptr0,
        ptr1,
        ptr2,
        comp_pivot1 = 0,
        comp_pivot2 = 0,
        comp = 0,
        i1,
        b_ptr0,
        b_ptr1,
        b_ptr2,
        b_ptr3,
        b_ptr4,
        b_ptr5,
        b_ptr6,
        b_ptr7,
        ptr3,
        ptr4,
        ptr5,
        ptr6,
        ptr7,
        pivot_ptr,
        ptr_shift,
        elementSize = n1,
        pivot1 = malloc(elementSize),
        pivot2 = malloc(elementSize)
      b_ptr0 = s0 * el1
      b_ptr1 = s0 * el2
      ptr_shift = offset
      __l1: for (i1 = 0; i1 < n1; ++i1) {
        ptr0 = b_ptr0 + ptr_shift
        ptr1 = b_ptr1 + ptr_shift
        comp = data[ptr0] - data[ptr1]
        if (comp > 0) {
          tmp0 = el1
          el1 = el2
          el2 = tmp0
          break __l1
        }
        if (comp < 0) {
          break __l1
        }
        ptr_shift += e1
      }
      b_ptr0 = s0 * el4
      b_ptr1 = s0 * el5
      ptr_shift = offset
      __l2: for (i1 = 0; i1 < n1; ++i1) {
        ptr0 = b_ptr0 + ptr_shift
        ptr1 = b_ptr1 + ptr_shift
        comp = data[ptr0] - data[ptr1]
        if (comp > 0) {
          tmp0 = el4
          el4 = el5
          el5 = tmp0
          break __l2
        }
        if (comp < 0) {
          break __l2
        }
        ptr_shift += e1
      }
      b_ptr0 = s0 * el1
      b_ptr1 = s0 * el3
      ptr_shift = offset
      __l3: for (i1 = 0; i1 < n1; ++i1) {
        ptr0 = b_ptr0 + ptr_shift
        ptr1 = b_ptr1 + ptr_shift
        comp = data[ptr0] - data[ptr1]
        if (comp > 0) {
          tmp0 = el1
          el1 = el3
          el3 = tmp0
          break __l3
        }
        if (comp < 0) {
          break __l3
        }
        ptr_shift += e1
      }
      b_ptr0 = s0 * el2
      b_ptr1 = s0 * el3
      ptr_shift = offset
      __l4: for (i1 = 0; i1 < n1; ++i1) {
        ptr0 = b_ptr0 + ptr_shift
        ptr1 = b_ptr1 + ptr_shift
        comp = data[ptr0] - data[ptr1]
        if (comp > 0) {
          tmp0 = el2
          el2 = el3
          el3 = tmp0
          break __l4
        }
        if (comp < 0) {
          break __l4
        }
        ptr_shift += e1
      }
      b_ptr0 = s0 * el1
      b_ptr1 = s0 * el4
      ptr_shift = offset
      __l5: for (i1 = 0; i1 < n1; ++i1) {
        ptr0 = b_ptr0 + ptr_shift
        ptr1 = b_ptr1 + ptr_shift
        comp = data[ptr0] - data[ptr1]
        if (comp > 0) {
          tmp0 = el1
          el1 = el4
          el4 = tmp0
          break __l5
        }
        if (comp < 0) {
          break __l5
        }
        ptr_shift += e1
      }
      b_ptr0 = s0 * el3
      b_ptr1 = s0 * el4
      ptr_shift = offset
      __l6: for (i1 = 0; i1 < n1; ++i1) {
        ptr0 = b_ptr0 + ptr_shift
        ptr1 = b_ptr1 + ptr_shift
        comp = data[ptr0] - data[ptr1]
        if (comp > 0) {
          tmp0 = el3
          el3 = el4
          el4 = tmp0
          break __l6
        }
        if (comp < 0) {
          break __l6
        }
        ptr_shift += e1
      }
      b_ptr0 = s0 * el2
      b_ptr1 = s0 * el5
      ptr_shift = offset
      __l7: for (i1 = 0; i1 < n1; ++i1) {
        ptr0 = b_ptr0 + ptr_shift
        ptr1 = b_ptr1 + ptr_shift
        comp = data[ptr0] - data[ptr1]
        if (comp > 0) {
          tmp0 = el2
          el2 = el5
          el5 = tmp0
          break __l7
        }
        if (comp < 0) {
          break __l7
        }
        ptr_shift += e1
      }
      b_ptr0 = s0 * el2
      b_ptr1 = s0 * el3
      ptr_shift = offset
      __l8: for (i1 = 0; i1 < n1; ++i1) {
        ptr0 = b_ptr0 + ptr_shift
        ptr1 = b_ptr1 + ptr_shift
        comp = data[ptr0] - data[ptr1]
        if (comp > 0) {
          tmp0 = el2
          el2 = el3
          el3 = tmp0
          break __l8
        }
        if (comp < 0) {
          break __l8
        }
        ptr_shift += e1
      }
      b_ptr0 = s0 * el4
      b_ptr1 = s0 * el5
      ptr_shift = offset
      __l9: for (i1 = 0; i1 < n1; ++i1) {
        ptr0 = b_ptr0 + ptr_shift
        ptr1 = b_ptr1 + ptr_shift
        comp = data[ptr0] - data[ptr1]
        if (comp > 0) {
          tmp0 = el4
          el4 = el5
          el5 = tmp0
          break __l9
        }
        if (comp < 0) {
          break __l9
        }
        ptr_shift += e1
      }
      b_ptr0 = s0 * el1
      b_ptr1 = s0 * el2
      b_ptr2 = s0 * el3
      b_ptr3 = s0 * el4
      b_ptr4 = s0 * el5
      b_ptr5 = s0 * index1
      b_ptr6 = s0 * index3
      b_ptr7 = s0 * index5
      pivot_ptr = 0
      ptr_shift = offset
      for (i1 = 0; i1 < n1; ++i1) {
        ptr0 = b_ptr0 + ptr_shift
        ptr1 = b_ptr1 + ptr_shift
        ptr2 = b_ptr2 + ptr_shift
        ptr3 = b_ptr3 + ptr_shift
        ptr4 = b_ptr4 + ptr_shift
        ptr5 = b_ptr5 + ptr_shift
        ptr6 = b_ptr6 + ptr_shift
        ptr7 = b_ptr7 + ptr_shift
        pivot1[pivot_ptr] = data[ptr1]
        pivot2[pivot_ptr] = data[ptr3]
        pivots_are_equal = pivots_are_equal && pivot1[pivot_ptr] === pivot2[pivot_ptr]
        x = data[ptr0]
        y = data[ptr2]
        z = data[ptr4]
        data[ptr5] = x
        data[ptr6] = y
        data[ptr7] = z
        ++pivot_ptr
        ptr_shift += d1
      }
      b_ptr0 = s0 * index2
      b_ptr1 = s0 * left
      ptr_shift = offset
      for (i1 = 0; i1 < n1; ++i1) {
        ptr0 = b_ptr0 + ptr_shift
        ptr1 = b_ptr1 + ptr_shift
        data[ptr0] = data[ptr1]
        ptr_shift += d1
      }
      b_ptr0 = s0 * index4
      b_ptr1 = s0 * right
      ptr_shift = offset
      for (i1 = 0; i1 < n1; ++i1) {
        ptr0 = b_ptr0 + ptr_shift
        ptr1 = b_ptr1 + ptr_shift
        data[ptr0] = data[ptr1]
        ptr_shift += d1
      }
      if (pivots_are_equal) {
        for (k = less; k <= great; ++k) {
          ptr0 = offset + k * s0
          pivot_ptr = 0
          __l10: for (i1 = 0; i1 < n1; ++i1) {
            comp = data[ptr0] - pivot1[pivot_ptr]
            if (comp !== 0) {
              break __l10
            }
            pivot_ptr += f1
            ptr0 += e1
          }
          if (comp === 0) {
            continue
          }
          if (comp < 0) {
            if (k !== less) {
              b_ptr0 = s0 * k
              b_ptr1 = s0 * less
              ptr_shift = offset
              for (i1 = 0; i1 < n1; ++i1) {
                ptr0 = b_ptr0 + ptr_shift
                ptr1 = b_ptr1 + ptr_shift
                tmp = data[ptr0]
                data[ptr0] = data[ptr1]
                data[ptr1] = tmp
                ptr_shift += d1
              }
            }
            ++less
          } else {
            while (true) {
              ptr0 = offset + great * s0
              pivot_ptr = 0
              __l11: for (i1 = 0; i1 < n1; ++i1) {
                comp = data[ptr0] - pivot1[pivot_ptr]
                if (comp !== 0) {
                  break __l11
                }
                pivot_ptr += f1
                ptr0 += e1
              }
              if (comp > 0) {
                great--
              } else if (comp < 0) {
                b_ptr0 = s0 * k
                b_ptr1 = s0 * less
                b_ptr2 = s0 * great
                ptr_shift = offset
                for (i1 = 0; i1 < n1; ++i1) {
                  ptr0 = b_ptr0 + ptr_shift
                  ptr1 = b_ptr1 + ptr_shift
                  ptr2 = b_ptr2 + ptr_shift
                  tmp = data[ptr0]
                  data[ptr0] = data[ptr1]
                  data[ptr1] = data[ptr2]
                  data[ptr2] = tmp
                  ptr_shift += d1
                }
                ++less
                --great
                break
              } else {
                b_ptr0 = s0 * k
                b_ptr1 = s0 * great
                ptr_shift = offset
                for (i1 = 0; i1 < n1; ++i1) {
                  ptr0 = b_ptr0 + ptr_shift
                  ptr1 = b_ptr1 + ptr_shift
                  tmp = data[ptr0]
                  data[ptr0] = data[ptr1]
                  data[ptr1] = tmp
                  ptr_shift += d1
                }
                --great
                break
              }
            }
          }
        }
      } else {
        for (k = less; k <= great; ++k) {
          ptr0 = offset + k * s0
          pivot_ptr = 0
          __l12: for (i1 = 0; i1 < n1; ++i1) {
            comp_pivot1 = data[ptr0] - pivot1[pivot_ptr]
            if (comp_pivot1 !== 0) {
              break __l12
            }
            pivot_ptr += f1
            ptr0 += e1
          }
          if (comp_pivot1 < 0) {
            if (k !== less) {
              b_ptr0 = s0 * k
              b_ptr1 = s0 * less
              ptr_shift = offset
              for (i1 = 0; i1 < n1; ++i1) {
                ptr0 = b_ptr0 + ptr_shift
                ptr1 = b_ptr1 + ptr_shift
                tmp = data[ptr0]
                data[ptr0] = data[ptr1]
                data[ptr1] = tmp
                ptr_shift += d1
              }
            }
            ++less
          } else {
            ptr0 = offset + k * s0
            pivot_ptr = 0
            __l13: for (i1 = 0; i1 < n1; ++i1) {
              comp_pivot2 = data[ptr0] - pivot2[pivot_ptr]
              if (comp_pivot2 !== 0) {
                break __l13
              }
              pivot_ptr += f1
              ptr0 += e1
            }
            if (comp_pivot2 > 0) {
              while (true) {
                ptr0 = offset + great * s0
                pivot_ptr = 0
                __l14: for (i1 = 0; i1 < n1; ++i1) {
                  comp = data[ptr0] - pivot2[pivot_ptr]
                  if (comp !== 0) {
                    break __l14
                  }
                  pivot_ptr += f1
                  ptr0 += e1
                }
                if (comp > 0) {
                  if (--great < k) {
                    break
                  }
                  continue
                } else {
                  ptr0 = offset + great * s0
                  pivot_ptr = 0
                  __l15: for (i1 = 0; i1 < n1; ++i1) {
                    comp = data[ptr0] - pivot1[pivot_ptr]
                    if (comp !== 0) {
                      break __l15
                    }
                    pivot_ptr += f1
                    ptr0 += e1
                  }
                  if (comp < 0) {
                    b_ptr0 = s0 * k
                    b_ptr1 = s0 * less
                    b_ptr2 = s0 * great
                    ptr_shift = offset
                    for (i1 = 0; i1 < n1; ++i1) {
                      ptr0 = b_ptr0 + ptr_shift
                      ptr1 = b_ptr1 + ptr_shift
                      ptr2 = b_ptr2 + ptr_shift
                      tmp = data[ptr0]
                      data[ptr0] = data[ptr1]
                      data[ptr1] = data[ptr2]
                      data[ptr2] = tmp
                      ptr_shift += d1
                    }
                    ++less
                    --great
                  } else {
                    b_ptr0 = s0 * k
                    b_ptr1 = s0 * great
                    ptr_shift = offset
                    for (i1 = 0; i1 < n1; ++i1) {
                      ptr0 = b_ptr0 + ptr_shift
                      ptr1 = b_ptr1 + ptr_shift
                      tmp = data[ptr0]
                      data[ptr0] = data[ptr1]
                      data[ptr1] = tmp
                      ptr_shift += d1
                    }
                    --great
                  }
                  break
                }
              }
            }
          }
        }
      }
      b_ptr0 = s0 * left
      b_ptr1 = s0 * (less - 1)
      pivot_ptr = 0
      ptr_shift = offset
      for (i1 = 0; i1 < n1; ++i1) {
        ptr0 = b_ptr0 + ptr_shift
        ptr1 = b_ptr1 + ptr_shift
        data[ptr0] = data[ptr1]
        data[ptr1] = pivot1[pivot_ptr]
        ++pivot_ptr
        ptr_shift += d1
      }
      b_ptr0 = s0 * right
      b_ptr1 = s0 * (great + 1)
      pivot_ptr = 0
      ptr_shift = offset
      for (i1 = 0; i1 < n1; ++i1) {
        ptr0 = b_ptr0 + ptr_shift
        ptr1 = b_ptr1 + ptr_shift
        data[ptr0] = data[ptr1]
        data[ptr1] = pivot2[pivot_ptr]
        ++pivot_ptr
        ptr_shift += d1
      }
      if (less - 2 - left <= 32) {
        insertionSort(left, less - 2, data, offset, s0, s1, n0, n1, d1, e1, f1)
      } else {
        ndarrayQuickSort1d0uint32(left, less - 2, data, offset, s0, s1, n0, n1, d1, e1, f1)
      }
      if (right - (great + 2) <= 32) {
        insertionSort(great + 2, right, data, offset, s0, s1, n0, n1, d1, e1, f1)
      } else {
        ndarrayQuickSort1d0uint32(great + 2, right, data, offset, s0, s1, n0, n1, d1, e1, f1)
      }
      if (pivots_are_equal) {
        free(pivot1)
        free(pivot2)
        return
      }
      if (less < index1 && great > index5) {
        __l16: while (true) {
          ptr0 = offset + less * s0
          pivot_ptr = 0
          ptr_shift = offset
          for (i1 = 0; i1 < n1; ++i1) {
            if (data[ptr0] !== pivot1[pivot_ptr]) {
              break __l16
            }
            ++pivot_ptr
            ptr0 += d1
          }
          ++less
        }
        __l17: while (true) {
          ptr0 = offset + great * s0
          pivot_ptr = 0
          ptr_shift = offset
          for (i1 = 0; i1 < n1; ++i1) {
            if (data[ptr0] !== pivot2[pivot_ptr]) {
              break __l17
            }
            ++pivot_ptr
            ptr0 += d1
          }
          --great
        }
        for (k = less; k <= great; ++k) {
          ptr0 = offset + k * s0
          pivot_ptr = 0
          __l18: for (i1 = 0; i1 < n1; ++i1) {
            comp_pivot1 = data[ptr0] - pivot1[pivot_ptr]
            if (comp_pivot1 !== 0) {
              break __l18
            }
            pivot_ptr += f1
            ptr0 += e1
          }
          if (comp_pivot1 === 0) {
            if (k !== less) {
              b_ptr0 = s0 * k
              b_ptr1 = s0 * less
              ptr_shift = offset
              for (i1 = 0; i1 < n1; ++i1) {
                ptr0 = b_ptr0 + ptr_shift
                ptr1 = b_ptr1 + ptr_shift
                tmp = data[ptr0]
                data[ptr0] = data[ptr1]
                data[ptr1] = tmp
                ptr_shift += d1
              }
            }
            ++less
          } else {
            ptr0 = offset + k * s0
            pivot_ptr = 0
            __l19: for (i1 = 0; i1 < n1; ++i1) {
              comp_pivot2 = data[ptr0] - pivot2[pivot_ptr]
              if (comp_pivot2 !== 0) {
                break __l19
              }
              pivot_ptr += f1
              ptr0 += e1
            }
            if (comp_pivot2 === 0) {
              while (true) {
                ptr0 = offset + great * s0
                pivot_ptr = 0
                __l20: for (i1 = 0; i1 < n1; ++i1) {
                  comp = data[ptr0] - pivot2[pivot_ptr]
                  if (comp !== 0) {
                    break __l20
                  }
                  pivot_ptr += f1
                  ptr0 += e1
                }
                if (comp === 0) {
                  if (--great < k) {
                    break
                  }
                  continue
                } else {
                  ptr0 = offset + great * s0
                  pivot_ptr = 0
                  __l21: for (i1 = 0; i1 < n1; ++i1) {
                    comp = data[ptr0] - pivot1[pivot_ptr]
                    if (comp !== 0) {
                      break __l21
                    }
                    pivot_ptr += f1
                    ptr0 += e1
                  }
                  if (comp < 0) {
                    b_ptr0 = s0 * k
                    b_ptr1 = s0 * less
                    b_ptr2 = s0 * great
                    ptr_shift = offset
                    for (i1 = 0; i1 < n1; ++i1) {
                      ptr0 = b_ptr0 + ptr_shift
                      ptr1 = b_ptr1 + ptr_shift
                      ptr2 = b_ptr2 + ptr_shift
                      tmp = data[ptr0]
                      data[ptr0] = data[ptr1]
                      data[ptr1] = data[ptr2]
                      data[ptr2] = tmp
                      ptr_shift += d1
                    }
                    ++less
                    --great
                  } else {
                    b_ptr0 = s0 * k
                    b_ptr1 = s0 * great
                    ptr_shift = offset
                    for (i1 = 0; i1 < n1; ++i1) {
                      ptr0 = b_ptr0 + ptr_shift
                      ptr1 = b_ptr1 + ptr_shift
                      tmp = data[ptr0]
                      data[ptr0] = data[ptr1]
                      data[ptr1] = tmp
                      ptr_shift += d1
                    }
                    --great
                  }
                  break
                }
              }
            }
          }
        }
      }
      free(pivot1)
      free(pivot2)
      if (great - less <= 32) {
        insertionSort(less, great, data, offset, s0, s1, n0, n1, d1, e1, f1)
      } else {
        ndarrayQuickSort1d0uint32(less, great, data, offset, s0, s1, n0, n1, d1, e1, f1)
      }
    }
  },
}

function createQuickSort(order, dtype, insertionSort) {
  var allocator = getMallocFree(dtype)
  var key = [dtype, order].join(',')
  var result = CACHED_quickSort[key]

  if(order.length > 1 && allocator) {
    return result(insertionSort, allocator[0], allocator[1])
  } else {
    return result(insertionSort)
  }
}

var CACHED_sort = {
  "uint32,1,0": function (insertionSort, quickSort) {
    return function (array) {
      var data = array.data,
        offset = array.offset | 0,
        shape = array.shape,
        stride = array.stride,
        s0 = stride[0] | 0,
        n0 = shape[0] | 0,
        s1 = stride[1] | 0,
        n1 = shape[1] | 0,
        d1 = s1,
        e1 = s1,
        f1 = 1
      if (n0 <= 32) {
        insertionSort(0, n0 - 1, data, offset, s0, s1, n0, n1, d1, e1, f1)
      } else {
        quickSort(0, n0 - 1, data, offset, s0, s1, n0, n1, d1, e1, f1)
      }
    }
  },
}

function compileSort(order, dtype) {
  var key = [dtype, order].join(',')
  var result = CACHED_sort[key]

  var insertionSort = createInsertionSort(order, dtype)
  var quickSort = createQuickSort(order, dtype, insertionSort)
  return result(insertionSort, quickSort)
}

module.exports = compileSort

/***/ }),

/***/ 446:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

"use strict";


var compile = __webpack_require__(7640)
var CACHE = {}

function sort(array) {
  var order = array.order
  var dtype = array.dtype
  var typeSig = [order, dtype ]
  var typeName = typeSig.join(":")
  var compiled = CACHE[typeName]
  if(!compiled) {
    CACHE[typeName] = compiled = compile(order, dtype)
  }
  compiled(array)
  return array
}

module.exports = sort

/***/ }),

/***/ 9618:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

var isBuffer = __webpack_require__(7163)

var hasTypedArrays  = ((typeof Float64Array) !== "undefined")

function compare1st(a, b) {
  return a[0] - b[0]
}

function order() {
  var stride = this.stride
  var terms = new Array(stride.length)
  var i
  for(i=0; i= 0) {
        d = i0 | 0
        b += c0 * d
        a0 -= d
      }
      return new View(this.data, a0, c0, b)
    }
    proto.step = function step(i0) {
      var a0 = this.shape[0],
        b0 = this.stride[0],
        c = this.offset,
        d = 0,
        ceil = Math.ceil
      if (typeof i0 === "number") {
        d = i0 | 0
        if (d < 0) {
          c += b0 * (a0 - 1)
          a0 = ceil(-a0 / d)
        } else {
          a0 = ceil(a0 / d)
        }
        b0 *= d
      }
      return new View(this.data, a0, b0, c)
    }
    proto.transpose = function transpose(i0) {
      i0 = i0 === undefined ? 0 : i0 | 0
      var a = this.shape,
        b = this.stride
      return new View(this.data, a[i0], b[i0], this.offset)
    }
    proto.pick = function pick(i0) {
      var a = [],
        b = [],
        c = this.offset
      if (typeof i0 === "number" && i0 >= 0) {
        c = (c + this.stride[0] * i0) | 0
      } else {
        a.push(this.shape[0])
        b.push(this.stride[0])
      }
      var ctor = CTOR_LIST[a.length + 1]
      return ctor(this.data, a, b, c)
    }
    return function construct(data, shape, stride, offset) {
      return new View(data, shape[0], stride[0], offset)
    }
  },
  2: function (dtype, CTOR_LIST, ORDER) {
    function View(a, b0, b1, c0, c1, d) {
      this.data = a
      this.shape = [b0, b1]
      this.stride = [c0, c1]
      this.offset = d | 0
    }
    var proto = View.prototype
    proto.dtype = dtype
    proto.dimension = 2
    Object.defineProperty(proto, "size", {
      get: function size() {
        return this.shape[0] * this.shape[1]
      },
    })
    Object.defineProperty(proto, "order", {
      get: function order() {
        return Math.abs(this.stride[0]) > Math.abs(this.stride[1]) ? [1, 0] : [0, 1]
      },
    })
    proto.set = function set(i0, i1, v) {
      return dtype === "generic"
        ? this.data.set(this.offset + this.stride[0] * i0 + this.stride[1] * i1, v)
        : (this.data[this.offset + this.stride[0] * i0 + this.stride[1] * i1] = v)
    }
    proto.get = function get(i0, i1) {
      return dtype === "generic"
        ? this.data.get(this.offset + this.stride[0] * i0 + this.stride[1] * i1)
        : this.data[this.offset + this.stride[0] * i0 + this.stride[1] * i1]
    }
    proto.index = function index(i0, i1) {
      return this.offset + this.stride[0] * i0 + this.stride[1] * i1
    }
    proto.hi = function hi(i0, i1) {
      return new View(
        this.data,
        typeof i0 !== "number" || i0 < 0 ? this.shape[0] : i0 | 0,
        typeof i1 !== "number" || i1 < 0 ? this.shape[1] : i1 | 0,
        this.stride[0],
        this.stride[1],
        this.offset
      )
    }
    proto.lo = function lo(i0, i1) {
      var b = this.offset,
        d = 0,
        a0 = this.shape[0],
        a1 = this.shape[1],
        c0 = this.stride[0],
        c1 = this.stride[1]
      if (typeof i0 === "number" && i0 >= 0) {
        d = i0 | 0
        b += c0 * d
        a0 -= d
      }
      if (typeof i1 === "number" && i1 >= 0) {
        d = i1 | 0
        b += c1 * d
        a1 -= d
      }
      return new View(this.data, a0, a1, c0, c1, b)
    }
    proto.step = function step(i0, i1) {
      var a0 = this.shape[0],
        a1 = this.shape[1],
        b0 = this.stride[0],
        b1 = this.stride[1],
        c = this.offset,
        d = 0,
        ceil = Math.ceil
      if (typeof i0 === "number") {
        d = i0 | 0
        if (d < 0) {
          c += b0 * (a0 - 1)
          a0 = ceil(-a0 / d)
        } else {
          a0 = ceil(a0 / d)
        }
        b0 *= d
      }
      if (typeof i1 === "number") {
        d = i1 | 0
        if (d < 0) {
          c += b1 * (a1 - 1)
          a1 = ceil(-a1 / d)
        } else {
          a1 = ceil(a1 / d)
        }
        b1 *= d
      }
      return new View(this.data, a0, a1, b0, b1, c)
    }
    proto.transpose = function transpose(i0, i1) {
      i0 = i0 === undefined ? 0 : i0 | 0
      i1 = i1 === undefined ? 1 : i1 | 0
      var a = this.shape,
        b = this.stride
      return new View(this.data, a[i0], a[i1], b[i0], b[i1], this.offset)
    }
    proto.pick = function pick(i0, i1) {
      var a = [],
        b = [],
        c = this.offset
      if (typeof i0 === "number" && i0 >= 0) {
        c = (c + this.stride[0] * i0) | 0
      } else {
        a.push(this.shape[0])
        b.push(this.stride[0])
      }
      if (typeof i1 === "number" && i1 >= 0) {
        c = (c + this.stride[1] * i1) | 0
      } else {
        a.push(this.shape[1])
        b.push(this.stride[1])
      }
      var ctor = CTOR_LIST[a.length + 1]
      return ctor(this.data, a, b, c)
    }
    return function construct(data, shape, stride, offset) {
      return new View(data, shape[0], shape[1], stride[0], stride[1], offset)
    }
  },
  3: function (dtype, CTOR_LIST, ORDER) {
    function View(a, b0, b1, b2, c0, c1, c2, d) {
      this.data = a
      this.shape = [b0, b1, b2]
      this.stride = [c0, c1, c2]
      this.offset = d | 0
    }
    var proto = View.prototype
    proto.dtype = dtype
    proto.dimension = 3
    Object.defineProperty(proto, "size", {
      get: function size() {
        return this.shape[0] * this.shape[1] * this.shape[2]
      },
    })
    Object.defineProperty(proto, "order", {
      get: function order() {
        var s0 = Math.abs(this.stride[0]),
          s1 = Math.abs(this.stride[1]),
          s2 = Math.abs(this.stride[2])
        if (s0 > s1) {
          if (s1 > s2) {
            return [2, 1, 0]
          } else if (s0 > s2) {
            return [1, 2, 0]
          } else {
            return [1, 0, 2]
          }
        } else if (s0 > s2) {
          return [2, 0, 1]
        } else if (s2 > s1) {
          return [0, 1, 2]
        } else {
          return [0, 2, 1]
        }
      },
    })
    proto.set = function set(i0, i1, i2, v) {
      return dtype === "generic"
        ? this.data.set(this.offset + this.stride[0] * i0 + this.stride[1] * i1 + this.stride[2] * i2, v)
        : (this.data[this.offset + this.stride[0] * i0 + this.stride[1] * i1 + this.stride[2] * i2] = v)
    }
    proto.get = function get(i0, i1, i2) {
      return dtype === "generic"
        ? this.data.get(this.offset + this.stride[0] * i0 + this.stride[1] * i1 + this.stride[2] * i2)
        : this.data[this.offset + this.stride[0] * i0 + this.stride[1] * i1 + this.stride[2] * i2]
    }
    proto.index = function index(i0, i1, i2) {
      return this.offset + this.stride[0] * i0 + this.stride[1] * i1 + this.stride[2] * i2
    }
    proto.hi = function hi(i0, i1, i2) {
      return new View(
        this.data,
        typeof i0 !== "number" || i0 < 0 ? this.shape[0] : i0 | 0,
        typeof i1 !== "number" || i1 < 0 ? this.shape[1] : i1 | 0,
        typeof i2 !== "number" || i2 < 0 ? this.shape[2] : i2 | 0,
        this.stride[0],
        this.stride[1],
        this.stride[2],
        this.offset
      )
    }
    proto.lo = function lo(i0, i1, i2) {
      var b = this.offset,
        d = 0,
        a0 = this.shape[0],
        a1 = this.shape[1],
        a2 = this.shape[2],
        c0 = this.stride[0],
        c1 = this.stride[1],
        c2 = this.stride[2]
      if (typeof i0 === "number" && i0 >= 0) {
        d = i0 | 0
        b += c0 * d
        a0 -= d
      }
      if (typeof i1 === "number" && i1 >= 0) {
        d = i1 | 0
        b += c1 * d
        a1 -= d
      }
      if (typeof i2 === "number" && i2 >= 0) {
        d = i2 | 0
        b += c2 * d
        a2 -= d
      }
      return new View(this.data, a0, a1, a2, c0, c1, c2, b)
    }
    proto.step = function step(i0, i1, i2) {
      var a0 = this.shape[0],
        a1 = this.shape[1],
        a2 = this.shape[2],
        b0 = this.stride[0],
        b1 = this.stride[1],
        b2 = this.stride[2],
        c = this.offset,
        d = 0,
        ceil = Math.ceil
      if (typeof i0 === "number") {
        d = i0 | 0
        if (d < 0) {
          c += b0 * (a0 - 1)
          a0 = ceil(-a0 / d)
        } else {
          a0 = ceil(a0 / d)
        }
        b0 *= d
      }
      if (typeof i1 === "number") {
        d = i1 | 0
        if (d < 0) {
          c += b1 * (a1 - 1)
          a1 = ceil(-a1 / d)
        } else {
          a1 = ceil(a1 / d)
        }
        b1 *= d
      }
      if (typeof i2 === "number") {
        d = i2 | 0
        if (d < 0) {
          c += b2 * (a2 - 1)
          a2 = ceil(-a2 / d)
        } else {
          a2 = ceil(a2 / d)
        }
        b2 *= d
      }
      return new View(this.data, a0, a1, a2, b0, b1, b2, c)
    }
    proto.transpose = function transpose(i0, i1, i2) {
      i0 = i0 === undefined ? 0 : i0 | 0
      i1 = i1 === undefined ? 1 : i1 | 0
      i2 = i2 === undefined ? 2 : i2 | 0
      var a = this.shape,
        b = this.stride
      return new View(this.data, a[i0], a[i1], a[i2], b[i0], b[i1], b[i2], this.offset)
    }
    proto.pick = function pick(i0, i1, i2) {
      var a = [],
        b = [],
        c = this.offset
      if (typeof i0 === "number" && i0 >= 0) {
        c = (c + this.stride[0] * i0) | 0
      } else {
        a.push(this.shape[0])
        b.push(this.stride[0])
      }
      if (typeof i1 === "number" && i1 >= 0) {
        c = (c + this.stride[1] * i1) | 0
      } else {
        a.push(this.shape[1])
        b.push(this.stride[1])
      }
      if (typeof i2 === "number" && i2 >= 0) {
        c = (c + this.stride[2] * i2) | 0
      } else {
        a.push(this.shape[2])
        b.push(this.stride[2])
      }
      var ctor = CTOR_LIST[a.length + 1]
      return ctor(this.data, a, b, c)
    }
    return function construct(data, shape, stride, offset) {
      return new View(data, shape[0], shape[1], shape[2], stride[0], stride[1], stride[2], offset)
    }
  },
  4: function (dtype, CTOR_LIST, ORDER) {
    function View(a, b0, b1, b2, b3, c0, c1, c2, c3, d) {
      this.data = a
      this.shape = [b0, b1, b2, b3]
      this.stride = [c0, c1, c2, c3]
      this.offset = d | 0
    }
    var proto = View.prototype
    proto.dtype = dtype
    proto.dimension = 4
    Object.defineProperty(proto, "size", {
      get: function size() {
        return this.shape[0] * this.shape[1] * this.shape[2] * this.shape[3]
      },
    })
    Object.defineProperty(proto, "order", { get: ORDER })
    proto.set = function set(i0, i1, i2, i3, v) {
      return dtype === "generic"
        ? this.data.set(this.offset + this.stride[0] * i0 + this.stride[1] * i1 + this.stride[2] * i2 + this.stride[3] * i3, v)
        : (this.data[this.offset + this.stride[0] * i0 + this.stride[1] * i1 + this.stride[2] * i2 + this.stride[3] * i3] = v)
    }
    proto.get = function get(i0, i1, i2, i3) {
      return dtype === "generic"
        ? this.data.get(this.offset + this.stride[0] * i0 + this.stride[1] * i1 + this.stride[2] * i2 + this.stride[3] * i3)
        : this.data[this.offset + this.stride[0] * i0 + this.stride[1] * i1 + this.stride[2] * i2 + this.stride[3] * i3]
    }
    proto.index = function index(i0, i1, i2, i3) {
      return this.offset + this.stride[0] * i0 + this.stride[1] * i1 + this.stride[2] * i2 + this.stride[3] * i3
    }
    proto.hi = function hi(i0, i1, i2, i3) {
      return new View(
        this.data,
        typeof i0 !== "number" || i0 < 0 ? this.shape[0] : i0 | 0,
        typeof i1 !== "number" || i1 < 0 ? this.shape[1] : i1 | 0,
        typeof i2 !== "number" || i2 < 0 ? this.shape[2] : i2 | 0,
        typeof i3 !== "number" || i3 < 0 ? this.shape[3] : i3 | 0,
        this.stride[0],
        this.stride[1],
        this.stride[2],
        this.stride[3],
        this.offset
      )
    }
    proto.lo = function lo(i0, i1, i2, i3) {
      var b = this.offset,
        d = 0,
        a0 = this.shape[0],
        a1 = this.shape[1],
        a2 = this.shape[2],
        a3 = this.shape[3],
        c0 = this.stride[0],
        c1 = this.stride[1],
        c2 = this.stride[2],
        c3 = this.stride[3]
      if (typeof i0 === "number" && i0 >= 0) {
        d = i0 | 0
        b += c0 * d
        a0 -= d
      }
      if (typeof i1 === "number" && i1 >= 0) {
        d = i1 | 0
        b += c1 * d
        a1 -= d
      }
      if (typeof i2 === "number" && i2 >= 0) {
        d = i2 | 0
        b += c2 * d
        a2 -= d
      }
      if (typeof i3 === "number" && i3 >= 0) {
        d = i3 | 0
        b += c3 * d
        a3 -= d
      }
      return new View(this.data, a0, a1, a2, a3, c0, c1, c2, c3, b)
    }
    proto.step = function step(i0, i1, i2, i3) {
      var a0 = this.shape[0],
        a1 = this.shape[1],
        a2 = this.shape[2],
        a3 = this.shape[3],
        b0 = this.stride[0],
        b1 = this.stride[1],
        b2 = this.stride[2],
        b3 = this.stride[3],
        c = this.offset,
        d = 0,
        ceil = Math.ceil
      if (typeof i0 === "number") {
        d = i0 | 0
        if (d < 0) {
          c += b0 * (a0 - 1)
          a0 = ceil(-a0 / d)
        } else {
          a0 = ceil(a0 / d)
        }
        b0 *= d
      }
      if (typeof i1 === "number") {
        d = i1 | 0
        if (d < 0) {
          c += b1 * (a1 - 1)
          a1 = ceil(-a1 / d)
        } else {
          a1 = ceil(a1 / d)
        }
        b1 *= d
      }
      if (typeof i2 === "number") {
        d = i2 | 0
        if (d < 0) {
          c += b2 * (a2 - 1)
          a2 = ceil(-a2 / d)
        } else {
          a2 = ceil(a2 / d)
        }
        b2 *= d
      }
      if (typeof i3 === "number") {
        d = i3 | 0
        if (d < 0) {
          c += b3 * (a3 - 1)
          a3 = ceil(-a3 / d)
        } else {
          a3 = ceil(a3 / d)
        }
        b3 *= d
      }
      return new View(this.data, a0, a1, a2, a3, b0, b1, b2, b3, c)
    }
    proto.transpose = function transpose(i0, i1, i2, i3) {
      i0 = i0 === undefined ? 0 : i0 | 0
      i1 = i1 === undefined ? 1 : i1 | 0
      i2 = i2 === undefined ? 2 : i2 | 0
      i3 = i3 === undefined ? 3 : i3 | 0
      var a = this.shape,
        b = this.stride
      return new View(this.data, a[i0], a[i1], a[i2], a[i3], b[i0], b[i1], b[i2], b[i3], this.offset)
    }
    proto.pick = function pick(i0, i1, i2, i3) {
      var a = [],
        b = [],
        c = this.offset
      if (typeof i0 === "number" && i0 >= 0) {
        c = (c + this.stride[0] * i0) | 0
      } else {
        a.push(this.shape[0])
        b.push(this.stride[0])
      }
      if (typeof i1 === "number" && i1 >= 0) {
        c = (c + this.stride[1] * i1) | 0
      } else {
        a.push(this.shape[1])
        b.push(this.stride[1])
      }
      if (typeof i2 === "number" && i2 >= 0) {
        c = (c + this.stride[2] * i2) | 0
      } else {
        a.push(this.shape[2])
        b.push(this.stride[2])
      }
      if (typeof i3 === "number" && i3 >= 0) {
        c = (c + this.stride[3] * i3) | 0
      } else {
        a.push(this.shape[3])
        b.push(this.stride[3])
      }
      var ctor = CTOR_LIST[a.length + 1]
      return ctor(this.data, a, b, c)
    }
    return function construct(data, shape, stride, offset) {
      return new View(data, shape[0], shape[1], shape[2], shape[3], stride[0], stride[1], stride[2], stride[3], offset)
    }
  },
  5: function anonymous(dtype, CTOR_LIST, ORDER) {
    function View(a, b0, b1, b2, b3, b4, c0, c1, c2, c3, c4, d) {
      this.data = a
      this.shape = [b0, b1, b2, b3, b4]
      this.stride = [c0, c1, c2, c3, c4]
      this.offset = d | 0
    }
    var proto = View.prototype
    proto.dtype = dtype
    proto.dimension = 5
    Object.defineProperty(proto, "size", {
      get: function size() {
        return this.shape[0] * this.shape[1] * this.shape[2] * this.shape[3] * this.shape[4]
      },
    })
    Object.defineProperty(proto, "order", { get: ORDER })
    proto.set = function set(i0, i1, i2, i3, i4, v) {
      return dtype === "generic"
        ? this.data.set(
            this.offset +
              this.stride[0] * i0 +
              this.stride[1] * i1 +
              this.stride[2] * i2 +
              this.stride[3] * i3 +
              this.stride[4] * i4,
            v
          )
        : (this.data[
            this.offset +
              this.stride[0] * i0 +
              this.stride[1] * i1 +
              this.stride[2] * i2 +
              this.stride[3] * i3 +
              this.stride[4] * i4
          ] = v)
    }
    proto.get = function get(i0, i1, i2, i3, i4) {
      return dtype === "generic"
        ? this.data.get(
            this.offset +
              this.stride[0] * i0 +
              this.stride[1] * i1 +
              this.stride[2] * i2 +
              this.stride[3] * i3 +
              this.stride[4] * i4
          )
        : this.data[
            this.offset +
              this.stride[0] * i0 +
              this.stride[1] * i1 +
              this.stride[2] * i2 +
              this.stride[3] * i3 +
              this.stride[4] * i4
          ]
    }
    proto.index = function index(i0, i1, i2, i3, i4) {
      return (
        this.offset +
        this.stride[0] * i0 +
        this.stride[1] * i1 +
        this.stride[2] * i2 +
        this.stride[3] * i3 +
        this.stride[4] * i4
      )
    }
    proto.hi = function hi(i0, i1, i2, i3, i4) {
      return new View(
        this.data,
        typeof i0 !== "number" || i0 < 0 ? this.shape[0] : i0 | 0,
        typeof i1 !== "number" || i1 < 0 ? this.shape[1] : i1 | 0,
        typeof i2 !== "number" || i2 < 0 ? this.shape[2] : i2 | 0,
        typeof i3 !== "number" || i3 < 0 ? this.shape[3] : i3 | 0,
        typeof i4 !== "number" || i4 < 0 ? this.shape[4] : i4 | 0,
        this.stride[0],
        this.stride[1],
        this.stride[2],
        this.stride[3],
        this.stride[4],
        this.offset
      )
    }
    proto.lo = function lo(i0, i1, i2, i3, i4) {
      var b = this.offset,
        d = 0,
        a0 = this.shape[0],
        a1 = this.shape[1],
        a2 = this.shape[2],
        a3 = this.shape[3],
        a4 = this.shape[4],
        c0 = this.stride[0],
        c1 = this.stride[1],
        c2 = this.stride[2],
        c3 = this.stride[3],
        c4 = this.stride[4]
      if (typeof i0 === "number" && i0 >= 0) {
        d = i0 | 0
        b += c0 * d
        a0 -= d
      }
      if (typeof i1 === "number" && i1 >= 0) {
        d = i1 | 0
        b += c1 * d
        a1 -= d
      }
      if (typeof i2 === "number" && i2 >= 0) {
        d = i2 | 0
        b += c2 * d
        a2 -= d
      }
      if (typeof i3 === "number" && i3 >= 0) {
        d = i3 | 0
        b += c3 * d
        a3 -= d
      }
      if (typeof i4 === "number" && i4 >= 0) {
        d = i4 | 0
        b += c4 * d
        a4 -= d
      }
      return new View(this.data, a0, a1, a2, a3, a4, c0, c1, c2, c3, c4, b)
    }
    proto.step = function step(i0, i1, i2, i3, i4) {
      var a0 = this.shape[0],
        a1 = this.shape[1],
        a2 = this.shape[2],
        a3 = this.shape[3],
        a4 = this.shape[4],
        b0 = this.stride[0],
        b1 = this.stride[1],
        b2 = this.stride[2],
        b3 = this.stride[3],
        b4 = this.stride[4],
        c = this.offset,
        d = 0,
        ceil = Math.ceil
      if (typeof i0 === "number") {
        d = i0 | 0
        if (d < 0) {
          c += b0 * (a0 - 1)
          a0 = ceil(-a0 / d)
        } else {
          a0 = ceil(a0 / d)
        }
        b0 *= d
      }
      if (typeof i1 === "number") {
        d = i1 | 0
        if (d < 0) {
          c += b1 * (a1 - 1)
          a1 = ceil(-a1 / d)
        } else {
          a1 = ceil(a1 / d)
        }
        b1 *= d
      }
      if (typeof i2 === "number") {
        d = i2 | 0
        if (d < 0) {
          c += b2 * (a2 - 1)
          a2 = ceil(-a2 / d)
        } else {
          a2 = ceil(a2 / d)
        }
        b2 *= d
      }
      if (typeof i3 === "number") {
        d = i3 | 0
        if (d < 0) {
          c += b3 * (a3 - 1)
          a3 = ceil(-a3 / d)
        } else {
          a3 = ceil(a3 / d)
        }
        b3 *= d
      }
      if (typeof i4 === "number") {
        d = i4 | 0
        if (d < 0) {
          c += b4 * (a4 - 1)
          a4 = ceil(-a4 / d)
        } else {
          a4 = ceil(a4 / d)
        }
        b4 *= d
      }
      return new View(this.data, a0, a1, a2, a3, a4, b0, b1, b2, b3, b4, c)
    }
    proto.transpose = function transpose(i0, i1, i2, i3, i4) {
      i0 = i0 === undefined ? 0 : i0 | 0
      i1 = i1 === undefined ? 1 : i1 | 0
      i2 = i2 === undefined ? 2 : i2 | 0
      i3 = i3 === undefined ? 3 : i3 | 0
      i4 = i4 === undefined ? 4 : i4 | 0
      var a = this.shape,
        b = this.stride
      return new View(this.data, a[i0], a[i1], a[i2], a[i3], a[i4], b[i0], b[i1], b[i2], b[i3], b[i4], this.offset)
    }
    proto.pick = function pick(i0, i1, i2, i3, i4) {
      var a = [],
        b = [],
        c = this.offset
      if (typeof i0 === "number" && i0 >= 0) {
        c = (c + this.stride[0] * i0) | 0
      } else {
        a.push(this.shape[0])
        b.push(this.stride[0])
      }
      if (typeof i1 === "number" && i1 >= 0) {
        c = (c + this.stride[1] * i1) | 0
      } else {
        a.push(this.shape[1])
        b.push(this.stride[1])
      }
      if (typeof i2 === "number" && i2 >= 0) {
        c = (c + this.stride[2] * i2) | 0
      } else {
        a.push(this.shape[2])
        b.push(this.stride[2])
      }
      if (typeof i3 === "number" && i3 >= 0) {
        c = (c + this.stride[3] * i3) | 0
      } else {
        a.push(this.shape[3])
        b.push(this.stride[3])
      }
      if (typeof i4 === "number" && i4 >= 0) {
        c = (c + this.stride[4] * i4) | 0
      } else {
        a.push(this.shape[4])
        b.push(this.stride[4])
      }
      var ctor = CTOR_LIST[a.length + 1]
      return ctor(this.data, a, b, c)
    }
    return function construct(data, shape, stride, offset) {
      return new View(
        data,
        shape[0],
        shape[1],
        shape[2],
        shape[3],
        shape[4],
        stride[0],
        stride[1],
        stride[2],
        stride[3],
        stride[4],
        offset
      )
    }
  },
}


function compileConstructor(inType, inDimension) {
  var dKey = inDimension === -1 ? 'T' : String(inDimension)

  var procedure = allFns[dKey]
  if(inDimension === -1) {
    return procedure(inType)
  } else if(inDimension === 0) {
    return procedure(inType, CACHED_CONSTRUCTORS[inType][0])
  }
  return procedure(inType, CACHED_CONSTRUCTORS[inType], order)
}

function arrayDType(data) {
  if(isBuffer(data)) {
    return "buffer"
  }
  if(hasTypedArrays) {
    switch(Object.prototype.toString.call(data)) {
      case "[object Float64Array]":
        return "float64"
      case "[object Float32Array]":
        return "float32"
      case "[object Int8Array]":
        return "int8"
      case "[object Int16Array]":
        return "int16"
      case "[object Int32Array]":
        return "int32"
      case "[object Uint8ClampedArray]":
        return "uint8_clamped"
      case "[object Uint8Array]":
        return "uint8"
      case "[object Uint16Array]":
        return "uint16"
      case "[object Uint32Array]":
        return "uint32"
      case "[object BigInt64Array]":
        return "bigint64"
      case "[object BigUint64Array]":
        return "biguint64"
    }
  }
  if(Array.isArray(data)) {
    return "array"
  }
  return "generic"
}

var CACHED_CONSTRUCTORS = {
  "generic":[],
  "buffer":[],
  "array":[],

  // typed arrays
  "float32":[],
  "float64":[],
  "int8":[],
  "int16":[],
  "int32":[],
  "uint8_clamped":[],
  "uint8":[],
  "uint16":[],
  "uint32":[],
  "bigint64": [],
  "biguint64": []
}

;(function() {
  for(var id in CACHED_CONSTRUCTORS) {
    CACHED_CONSTRUCTORS[id].push(compileConstructor(id, -1))
  }
});

function wrappedNDArrayCtor(data, shape, stride, offset) {
  if(data === undefined) {
    var ctor = CACHED_CONSTRUCTORS.array[0]
    return ctor([])
  } else if(typeof data === "number") {
    data = [data]
  }
  if(shape === undefined) {
    shape = [ data.length ]
  }
  var d = shape.length
  if(stride === undefined) {
    stride = new Array(d)
    for(var i=d-1, sz=1; i>=0; --i) {
      stride[i] = sz
      sz *= shape[i]
    }
  }
  if(offset === undefined) {
    offset = 0
    for(var i=0; i>>0

module.exports = nextafter

function nextafter(x, y) {
  if(isNaN(x) || isNaN(y)) {
    return NaN
  }
  if(x === y) {
    return x
  }
  if(x === 0) {
    if(y < 0) {
      return -SMALLEST_DENORM
    } else {
      return SMALLEST_DENORM
    }
  }
  var hi = doubleBits.hi(x)
  var lo = doubleBits.lo(x)
  if((y > x) === (x > 0)) {
    if(lo === UINT_MAX) {
      hi += 1
      lo = 0
    } else {
      lo += 1
    }
  } else {
    if(lo === 0) {
      lo = UINT_MAX
      hi -= 1
    } else {
      lo -= 1
    }
  }
  return doubleBits.pack(lo, hi)
}

/***/ }),

/***/ 8406:
/***/ (function(__unused_webpack_module, exports) {

var DEFAULT_NORMALS_EPSILON = 1e-6;
var DEFAULT_FACE_EPSILON = 1e-6;

//Estimate the vertex normals of a mesh
exports.vertexNormals = function(faces, positions, specifiedEpsilon) {

  var N         = positions.length;
  var normals   = new Array(N);
  var epsilon   = specifiedEpsilon === void(0) ? DEFAULT_NORMALS_EPSILON : specifiedEpsilon;

  //Initialize normal array
  for(var i=0; i epsilon) {
        var norm = normals[c];
        var w = 1.0 / Math.sqrt(m01 * m21);
        for(var k=0; k<3; ++k) {
          var u = (k+1)%3;
          var v = (k+2)%3;
          norm[k] += w * (d21[u] * d01[v] - d21[v] * d01[u]);
        }
      }
    }
  }

  //Scale all normals to unit length
  for(var i=0; i epsilon) {
      var w = 1.0 / Math.sqrt(m);
      for(var k=0; k<3; ++k) {
        norm[k] *= w;
      }
    } else {
      for(var k=0; k<3; ++k) {
        norm[k] = 0.0;
      }
    }
  }

  //Return the resulting set of patches
  return normals;
}

//Compute face normals of a mesh
exports.faceNormals = function(faces, positions, specifiedEpsilon) {

  var N         = faces.length;
  var normals   = new Array(N);
  var epsilon   = specifiedEpsilon === void(0) ? DEFAULT_FACE_EPSILON : specifiedEpsilon;

  for(var i=0; i epsilon) {
      l = 1.0 / Math.sqrt(l);
    } else {
      l = 0.0;
    }
    for(var j=0; j<3; ++j) {
      n[j] *= l;
    }
    normals[i] = n;
  }
  return normals;
}




/***/ }),

/***/ 4081:
/***/ (function(module) {

"use strict";


module.exports = quatFromFrame

function quatFromFrame(
  out,
  rx, ry, rz,
  ux, uy, uz,
  fx, fy, fz) {
  var tr = rx + uy + fz
  if(l > 0) {
    var l = Math.sqrt(tr + 1.0)
    out[0] = 0.5 * (uz - fy) / l
    out[1] = 0.5 * (fx - rz) / l
    out[2] = 0.5 * (ry - uy) / l
    out[3] = 0.5 * l
  } else {
    var tf = Math.max(rx, uy, fz)
    var l = Math.sqrt(2 * tf - tr + 1.0)
    if(rx >= tf) {
      //x y z  order
      out[0] = 0.5 * l
      out[1] = 0.5 * (ux + ry) / l
      out[2] = 0.5 * (fx + rz) / l
      out[3] = 0.5 * (uz - fy) / l
    } else if(uy >= tf) {
      //y z x  order
      out[0] = 0.5 * (ry + ux) / l
      out[1] = 0.5 * l
      out[2] = 0.5 * (fy + uz) / l
      out[3] = 0.5 * (fx - rz) / l
    } else {
      //z x y  order
      out[0] = 0.5 * (rz + fx) / l
      out[1] = 0.5 * (uz + fy) / l
      out[2] = 0.5 * l
      out[3] = 0.5 * (ry - ux) / l
    }
  }
  return out
}

/***/ }),

/***/ 9977:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

"use strict";


module.exports = createOrbitController

var filterVector  = __webpack_require__(9215)
var lookAt        = __webpack_require__(6582)
var mat4FromQuat  = __webpack_require__(7399)
var invert44      = __webpack_require__(7608)
var quatFromFrame = __webpack_require__(4081)

function len3(x,y,z) {
  return Math.sqrt(Math.pow(x,2) + Math.pow(y,2) + Math.pow(z,2))
}

function len4(w,x,y,z) {
  return Math.sqrt(Math.pow(w,2) + Math.pow(x,2) + Math.pow(y,2) + Math.pow(z,2))
}

function normalize4(out, a) {
  var ax = a[0]
  var ay = a[1]
  var az = a[2]
  var aw = a[3]
  var al = len4(ax, ay, az, aw)
  if(al > 1e-6) {
    out[0] = ax/al
    out[1] = ay/al
    out[2] = az/al
    out[3] = aw/al
  } else {
    out[0] = out[1] = out[2] = 0.0
    out[3] = 1.0
  }
}

function OrbitCameraController(initQuat, initCenter, initRadius) {
  this.radius    = filterVector([initRadius])
  this.center    = filterVector(initCenter)
  this.rotation  = filterVector(initQuat)

  this.computedRadius   = this.radius.curve(0)
  this.computedCenter   = this.center.curve(0)
  this.computedRotation = this.rotation.curve(0)
  this.computedUp       = [0.1,0,0]
  this.computedEye      = [0.1,0,0]
  this.computedMatrix   = [0.1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]

  this.recalcMatrix(0)
}

var proto = OrbitCameraController.prototype

proto.lastT = function() {
  return Math.max(
    this.radius.lastT(),
    this.center.lastT(),
    this.rotation.lastT())
}

proto.recalcMatrix = function(t) {
  this.radius.curve(t)
  this.center.curve(t)
  this.rotation.curve(t)

  var quat = this.computedRotation
  normalize4(quat, quat)

  var mat = this.computedMatrix
  mat4FromQuat(mat, quat)

  var center = this.computedCenter
  var eye    = this.computedEye
  var up     = this.computedUp
  var radius = Math.exp(this.computedRadius[0])

  eye[0] = center[0] + radius * mat[2]
  eye[1] = center[1] + radius * mat[6]
  eye[2] = center[2] + radius * mat[10]
  up[0] = mat[1]
  up[1] = mat[5]
  up[2] = mat[9]

  for(var i=0; i<3; ++i) {
    var rr = 0.0
    for(var j=0; j<3; ++j) {
      rr += mat[i+4*j] * eye[j]
    }
    mat[12+i] = -rr
  }
}

proto.getMatrix = function(t, result) {
  this.recalcMatrix(t)
  var m = this.computedMatrix
  if(result) {
    for(var i=0; i<16; ++i) {
      result[i] = m[i]
    }
    return result
  }
  return m
}

proto.idle = function(t) {
  this.center.idle(t)
  this.radius.idle(t)
  this.rotation.idle(t)
}

proto.flush = function(t) {
  this.center.flush(t)
  this.radius.flush(t)
  this.rotation.flush(t)
}

proto.pan = function(t, dx, dy, dz) {
  dx = dx || 0.0
  dy = dy || 0.0
  dz = dz || 0.0

  this.recalcMatrix(t)
  var mat = this.computedMatrix

  var ux = mat[1]
  var uy = mat[5]
  var uz = mat[9]
  var ul = len3(ux, uy, uz)
  ux /= ul
  uy /= ul
  uz /= ul

  var rx = mat[0]
  var ry = mat[4]
  var rz = mat[8]
  var ru = rx * ux + ry * uy + rz * uz
  rx -= ux * ru
  ry -= uy * ru
  rz -= uz * ru
  var rl = len3(rx, ry, rz)
  rx /= rl
  ry /= rl
  rz /= rl

  var fx = mat[2]
  var fy = mat[6]
  var fz = mat[10]
  var fu = fx * ux + fy * uy + fz * uz
  var fr = fx * rx + fy * ry + fz * rz
  fx -= fu * ux + fr * rx
  fy -= fu * uy + fr * ry
  fz -= fu * uz + fr * rz
  var fl = len3(fx, fy, fz)
  fx /= fl
  fy /= fl
  fz /= fl

  var vx = rx * dx + ux * dy
  var vy = ry * dx + uy * dy
  var vz = rz * dx + uz * dy

  this.center.move(t, vx, vy, vz)

  //Update z-component of radius
  var radius = Math.exp(this.computedRadius[0])
  radius = Math.max(1e-4, radius + dz)
  this.radius.set(t, Math.log(radius))
}

proto.rotate = function(t, dx, dy, dz) {
  this.recalcMatrix(t)

  dx = dx||0.0
  dy = dy||0.0

  var mat = this.computedMatrix

  var rx = mat[0]
  var ry = mat[4]
  var rz = mat[8]

  var ux = mat[1]
  var uy = mat[5]
  var uz = mat[9]

  var fx = mat[2]
  var fy = mat[6]
  var fz = mat[10]

  var qx = dx * rx + dy * ux
  var qy = dx * ry + dy * uy
  var qz = dx * rz + dy * uz

  var bx = -(fy * qz - fz * qy)
  var by = -(fz * qx - fx * qz)
  var bz = -(fx * qy - fy * qx)  
  var bw = Math.sqrt(Math.max(0.0, 1.0 - Math.pow(bx,2) - Math.pow(by,2) - Math.pow(bz,2)))
  var bl = len4(bx, by, bz, bw)
  if(bl > 1e-6) {
    bx /= bl
    by /= bl
    bz /= bl
    bw /= bl
  } else {
    bx = by = bz = 0.0
    bw = 1.0
  }

  var rotation = this.computedRotation
  var ax = rotation[0]
  var ay = rotation[1]
  var az = rotation[2]
  var aw = rotation[3]

  var cx = ax*bw + aw*bx + ay*bz - az*by
  var cy = ay*bw + aw*by + az*bx - ax*bz
  var cz = az*bw + aw*bz + ax*by - ay*bx
  var cw = aw*bw - ax*bx - ay*by - az*bz
  
  //Apply roll
  if(dz) {
    bx = fx
    by = fy
    bz = fz
    var s = Math.sin(dz) / len3(bx, by, bz)
    bx *= s
    by *= s
    bz *= s
    bw = Math.cos(dx)
    cx = cx*bw + cw*bx + cy*bz - cz*by
    cy = cy*bw + cw*by + cz*bx - cx*bz
    cz = cz*bw + cw*bz + cx*by - cy*bx
    cw = cw*bw - cx*bx - cy*by - cz*bz
  }

  var cl = len4(cx, cy, cz, cw)
  if(cl > 1e-6) {
    cx /= cl
    cy /= cl
    cz /= cl
    cw /= cl
  } else {
    cx = cy = cz = 0.0
    cw = 1.0
  }

  this.rotation.set(t, cx, cy, cz, cw)
}

proto.lookAt = function(t, eye, center, up) {
  this.recalcMatrix(t)

  center = center || this.computedCenter
  eye    = eye    || this.computedEye
  up     = up     || this.computedUp

  var mat = this.computedMatrix
  lookAt(mat, eye, center, up)

  var rotation = this.computedRotation
  quatFromFrame(rotation,
    mat[0], mat[1], mat[2],
    mat[4], mat[5], mat[6],
    mat[8], mat[9], mat[10])
  normalize4(rotation, rotation)
  this.rotation.set(t, rotation[0], rotation[1], rotation[2], rotation[3])

  var fl = 0.0
  for(var i=0; i<3; ++i) {
    fl += Math.pow(center[i] - eye[i], 2)
  }
  this.radius.set(t, 0.5 * Math.log(Math.max(fl, 1e-6)))

  this.center.set(t, center[0], center[1], center[2])
}

proto.translate = function(t, dx, dy, dz) {
  this.center.move(t,
    dx||0.0,
    dy||0.0,
    dz||0.0)
}

proto.setMatrix = function(t, matrix) {

  var rotation = this.computedRotation
  quatFromFrame(rotation,
    matrix[0], matrix[1], matrix[2],
    matrix[4], matrix[5], matrix[6],
    matrix[8], matrix[9], matrix[10])
  normalize4(rotation, rotation)
  this.rotation.set(t, rotation[0], rotation[1], rotation[2], rotation[3])

  var mat = this.computedMatrix
  invert44(mat, matrix)
  var w = mat[15]
  if(Math.abs(w) > 1e-6) {
    var cx = mat[12]/w
    var cy = mat[13]/w
    var cz = mat[14]/w

    this.recalcMatrix(t)  
    var r = Math.exp(this.computedRadius[0])
    this.center.set(t, cx-mat[2]*r, cy-mat[6]*r, cz-mat[10]*r)
    this.radius.idle(t)
  } else {
    this.center.idle(t)
    this.radius.idle(t)
  }
}

proto.setDistance = function(t, d) {
  if(d > 0) {
    this.radius.set(t, Math.log(d))
  }
}

proto.setDistanceLimits = function(lo, hi) {
  if(lo > 0) {
    lo = Math.log(lo)
  } else {
    lo = -Infinity    
  }
  if(hi > 0) {
    hi = Math.log(hi)
  } else {
    hi = Infinity
  }
  hi = Math.max(hi, lo)
  this.radius.bounds[0][0] = lo
  this.radius.bounds[1][0] = hi
}

proto.getDistanceLimits = function(out) {
  var bounds = this.radius.bounds
  if(out) {
    out[0] = Math.exp(bounds[0][0])
    out[1] = Math.exp(bounds[1][0])
    return out
  }
  return [ Math.exp(bounds[0][0]), Math.exp(bounds[1][0]) ]
}

proto.toJSON = function() {
  this.recalcMatrix(this.lastT())
  return {
    center:   this.computedCenter.slice(),
    rotation: this.computedRotation.slice(),
    distance: Math.log(this.computedRadius[0]),
    zoomMin:  this.radius.bounds[0][0],
    zoomMax:  this.radius.bounds[1][0]
  }
}

proto.fromJSON = function(options) {
  var t = this.lastT()
  var c = options.center
  if(c) {
    this.center.set(t, c[0], c[1], c[2])
  }
  var r = options.rotation
  if(r) {
    this.rotation.set(t, r[0], r[1], r[2], r[3])
  }
  var d = options.distance
  if(d && d > 0) {
    this.radius.set(t, Math.log(d))
  }
  this.setDistanceLimits(options.zoomMin, options.zoomMax)
}

function createOrbitController(options) {
  options = options || {}
  var center   = options.center   || [0,0,0]
  var rotation = options.rotation || [0,0,0,1]
  var radius   = options.radius   || 1.0

  center = [].slice.call(center, 0, 3)
  rotation = [].slice.call(rotation, 0, 4)
  normalize4(rotation, rotation)

  var result = new OrbitCameraController(
    rotation,
    center,
    Math.log(radius))

  result.setDistanceLimits(options.zoomMin, options.zoomMax)

  if('eye' in options || 'up' in options) {
    result.lookAt(0, options.eye, options.center, options.up)
  }

  return result
}

/***/ }),

/***/ 1371:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

"use strict";
/*!
 * pad-left 
 *
 * Copyright (c) 2014-2015, Jon Schlinkert.
 * Licensed under the MIT license.
 */



var repeat = __webpack_require__(3233);

module.exports = function padLeft(str, num, ch) {
  ch = typeof ch !== 'undefined' ? (ch + '') : ' ';
  return repeat(ch, num) + str;
};

/***/ }),

/***/ 3202:
/***/ (function(module) {

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
}

/***/ }),

/***/ 3088:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

"use strict";


module.exports = planarDual

var compareAngle = __webpack_require__(3140)

function planarDual(cells, positions) {

  var numVertices = positions.length|0
  var numEdges = cells.length
  var adj = [new Array(numVertices), new Array(numVertices)]
  for(var i=0; i 0) {
        nextCell = adj[i][b][0]
        nextDir = i
        break
      }
    }
    nextVertex = nextCell[nextDir^1]

    for(var dir=0; dir<2; ++dir) {
      var nbhd = adj[dir][b]
      for(var k=0; k 0) {
          nextCell = e
          nextVertex = p
          nextDir = dir
        }
      }
    }
    if(noCut) {
      return nextVertex
    }
    if(nextCell) {
      cut(nextCell, nextDir)
    }
    return nextVertex
  }

  function extractCycle(v, dir) {
    var e0 = adj[dir][v][0]
    var cycle = [v]
    cut(e0, dir)
    var u = e0[dir^1]
    var d0 = dir
    while(true) {
      while(u !== v) {
        cycle.push(u)
        u = next(cycle[cycle.length-2], u, false)
      }
      if(adj[0][v].length + adj[1][v].length === 0) {
        break
      }
      var a = cycle[cycle.length-1]
      var b = v
      var c = cycle[1]
      var d = next(a, b, true)
      if(compareAngle(positions[a], positions[b], positions[c], positions[d]) < 0) {
        break
      }
      cycle.push(v)
      u = next(a, b)
    }
    return cycle
  }

  function shouldGlue(pcycle, ncycle) {
    return (ncycle[1] === ncycle[ncycle.length-1])
  }

  for(var i=0; i 0) {
        var ni = adj[0][i].length
        var ncycle = extractCycle(i,j)
        if(shouldGlue(pcycle, ncycle)) {
          //Glue together trivial cycles
          pcycle.push.apply(pcycle, ncycle)
        } else {
          if(pcycle.length > 0) {
            cycles.push(pcycle)
          }
          pcycle = ncycle
        }
      }
      if(pcycle.length > 0) {
        cycles.push(pcycle)
      }
    }
  }

  //Combine paths and loops together
  return cycles
}

/***/ }),

/***/ 5609:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

"use strict";


module.exports = trimLeaves

var e2a = __webpack_require__(3134)

function trimLeaves(edges, positions) {
  var adj = e2a(edges, positions.length)
  var live = new Array(positions.length)
  var nbhd = new Array(positions.length)

  var dead = []
  for(var i=0; i 0) {
    var v = dead.pop()
    live[v] = false
    var n = adj[v]
    for(var i=0; i 0
  }

  //Extract all clockwise faces
  faces = faces.filter(ccw)

  //Detect which loops are contained in one another to handle parent-of relation
  var numFaces = faces.length
  var parent = new Array(numFaces)
  var containment = new Array(numFaces)
  for(var i=0; i 0) {
    var top = toVisit.pop()
    var nbhd = fadj[top]
    uniq(nbhd, function(a,b) {
      return a-b
    })
    var nnbhr = nbhd.length
    var p = parity[top]
    var polyline
    if(p === 0) {
      var c = faces[top]
      polyline = [c]
    }
    for(var i=0; i= 0) {
        continue
      }
      parity[f] = p^1
      toVisit.push(f)
      if(p === 0) {
        var c = faces[f]
        if(!sharedBoundary(c)) {
          c.reverse()
          polyline.push(c)
        }
      }
    }
    if(p === 0) {
      result.push(polyline)
    }
  }

  return result
}

/***/ }),

/***/ 5085:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

module.exports = preprocessPolygon

var orient = (__webpack_require__(3250)[3])
var makeSlabs = __webpack_require__(4209)
var makeIntervalTree = __webpack_require__(3352)
var bsearch = __webpack_require__(2478)

function visitInterval() {
  return true
}

function intervalSearch(table) {
  return function(x, y) {
    var tree = table[x]
    if(tree) {
      return !!tree.queryPoint(y, visitInterval)
    }
    return false
  }
}

function buildVerticalIndex(segments) {
  var table = {}
  for(var i=0; i 0 && coordinates[bucket] === p[0]) {
        root = slabs[bucket-1]
      } else {
        return 1
      }
    }
    var lastOrientation = 1
    while(root) {
      var s = root.key
      var o = orient(p, s[0], s[1])
      if(s[0][0] < s[1][0]) {
        if(o < 0) {
          root = root.left
        } else if(o > 0) {
          lastOrientation = -1
          root = root.right
        } else {
          return 0
        }
      } else {
        if(o > 0) {
          root = root.left
        } else if(o < 0) {
          lastOrientation = 1
          root = root.right
        } else {
          return 0
        }
      }
    }
    return lastOrientation
  }
}

function classifyEmpty(p) {
  return 1
}

function createClassifyVertical(testVertical) {
  return function classify(p) {
    if(testVertical(p[0], p[1])) {
      return 0
    }
    return 1
  }
}

function createClassifyPointDegen(testVertical, testNormal) {
  return function classify(p) {
    if(testVertical(p[0], p[1])) {
      return 0
    }
    return testNormal(p)
  }
}

function preprocessPolygon(loops) {
  //Compute number of loops
  var numLoops = loops.length

  //Unpack segments
  var segments = []
  var vsegments = []
  var ptr = 0
  for(var i=0; i= a00) {
            s = 1.0;
            sqrDistance = a00 + 2.0*b0 + c;
          } else {
            s = -b0/a00;
            sqrDistance = b0*s + c;
          }
        } else {
          s = 0;
          if (b1 >= 0) {
            t = 0;
            sqrDistance = c;
          } else if (-b1 >= a11) {
            t = 1;
            sqrDistance = a11 + 2.0*b1 + c;
          } else {
            t = -b1/a11;
            sqrDistance = b1*t + c;
          }
        }
      } else {  // region 3
        s = 0;
        if (b1 >= 0) {
          t = 0;
          sqrDistance = c;
        } else if (-b1 >= a11) {
          t = 1;
          sqrDistance = a11 + 2.0*b1 + c;
        } else {
          t = -b1/a11;
          sqrDistance = b1*t + c;
        }
      }
    } else if (t < 0) { // region 5
      t = 0;
      if (b0 >= 0) {
        s = 0;
        sqrDistance = c;
      } else if (-b0 >= a00) {
        s = 1;
        sqrDistance = a00 + 2.0*b0 + c;
      } else {
        s = -b0/a00;
        sqrDistance = b0*s + c;
      }
    } else {  // region 0
      // minimum at interior point
      var invDet = 1.0 / det;
      s *= invDet;
      t *= invDet;
      sqrDistance = s*(a00*s + a01*t + 2.0*b0) + t*(a01*s + a11*t + 2.0*b1) + c;
    }
  } else {
    var tmp0, tmp1, numer, denom;
    
    if (s < 0) {  // region 2
      tmp0 = a01 + b0;
      tmp1 = a11 + b1;
      if (tmp1 > tmp0) {
        numer = tmp1 - tmp0;
        denom = a00 - 2.0*a01 + a11;
        if (numer >= denom) {
          s = 1;
          t = 0;
          sqrDistance = a00 + 2.0*b0 + c;
        } else {
          s = numer/denom;
          t = 1 - s;
          sqrDistance = s*(a00*s + a01*t + 2.0*b0) +
          t*(a01*s + a11*t + 2.0*b1) + c;
        }
      } else {
        s = 0;
        if (tmp1 <= 0) {
          t = 1;
          sqrDistance = a11 + 2.0*b1 + c;
        } else if (b1 >= 0) {
          t = 0;
          sqrDistance = c;
        } else {
          t = -b1/a11;
          sqrDistance = b1*t + c;
        }
      }
    } else if (t < 0) {  // region 6
      tmp0 = a01 + b1;
      tmp1 = a00 + b0;
      if (tmp1 > tmp0) {
        numer = tmp1 - tmp0;
        denom = a00 - 2.0*a01 + a11;
        if (numer >= denom) {
          t = 1;
          s = 0;
          sqrDistance = a11 + 2.0*b1 + c;
        } else {
          t = numer/denom;
          s = 1 - t;
          sqrDistance = s*(a00*s + a01*t + 2.0*b0) +
          t*(a01*s + a11*t + 2.0*b1) + c;
        }
      } else {
        t = 0;
        if (tmp1 <= 0) {
          s = 1;
          sqrDistance = a00 + 2.0*b0 + c;
        } else if (b0 >= 0) {
          s = 0;
          sqrDistance = c;
        } else {
          s = -b0/a00;
          sqrDistance = b0*s + c;
        }
      }
    } else {  // region 1
      numer = a11 + b1 - a01 - b0;
      if (numer <= 0) {
        s = 0;
        t = 1;
        sqrDistance = a11 + 2.0*b1 + c;
      } else {
        denom = a00 - 2.0*a01 + a11;
        if (numer >= denom) {
          s = 1;
          t = 0;
          sqrDistance = a00 + 2.0*b0 + c;
        } else {
          s = numer/denom;
          t = 1 - s;
          sqrDistance = s*(a00*s + a01*t + 2.0*b0) +
          t*(a01*s + a11*t + 2.0*b1) + c;
        }
      }
    }
  }
  var u = 1.0 - s - t;
  for(var i=0; i 0) {
      var f = cells[ptr-1]
      if(compareCell(c, f) === 0 &&
         orientation(f)    !== o) {
        ptr -= 1
        continue
      }
    }
    cells[ptr++] = c
  }
  cells.length = ptr
  return cells
}


/***/ }),

/***/ 3233:
/***/ (function(module) {

"use strict";
/*!
 * repeat-string 
 *
 * Copyright (c) 2014-2015, Jon Schlinkert.
 * Licensed under the MIT License.
 */



/**
 * Results cache
 */

var res = '';
var cache;

/**
 * Expose `repeat`
 */

module.exports = repeat;

/**
 * Repeat the given `string` the specified `number`
 * of times.
 *
 * **Example:**
 *
 * ```js
 * var repeat = require('repeat-string');
 * repeat('A', 5);
 * //=> AAAAA
 * ```
 *
 * @param {String} `string` The string to repeat
 * @param {Number} `number` The number of times to repeat the string
 * @return {String} Repeated string
 * @api public
 */

function repeat(str, num) {
  if (typeof str !== 'string') {
    throw new TypeError('expected a string');
  }

  // cover common, quick use cases
  if (num === 1) return str;
  if (num === 2) return str + str;

  var max = str.length * num;
  if (cache !== str || typeof cache === 'undefined') {
    cache = str;
    res = '';
  } else if (res.length >= max) {
    return res.substr(0, max);
  }

  while (max > res.length && num > 1) {
    if (num & 1) {
      res += str;
    }

    num >>= 1;
    str += str;
  }

  res += str;
  res = res.substr(0, max);
  return res;
}


/***/ }),

/***/ 3025:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

module.exports =
  __webpack_require__.g.performance &&
  __webpack_require__.g.performance.now ? function now() {
    return performance.now()
  } : Date.now || function now() {
    return +new Date
  }


/***/ }),

/***/ 7004:
/***/ (function(module) {

"use strict";


module.exports = compressExpansion

function compressExpansion(e) {
  var m = e.length
  var Q = e[e.length-1]
  var bottom = m
  for(var i=m-2; i>=0; --i) {
    var a = Q
    var b = e[i]
    Q = a + b
    var bv = Q - a
    var q = b - bv
    if(q) {
      e[--bottom] = Q
      Q = q
    }
  }
  var top = 0
  for(var i=bottom; i 0) {
      if(r <= 0) {
        return det
      } else {
        s = l + r
      }
    } else if(l < 0) {
      if(r >= 0) {
        return det
      } else {
        s = -(l + r)
      }
    } else {
      return det
    }
    var tol = ERRBOUND3 * s
    if(det >= tol || det <= -tol) {
      return det
    }
    return orientation3Exact(a, b, c)
  },
  function orientation4(a,b,c,d) {
    var adx = a[0] - d[0]
    var bdx = b[0] - d[0]
    var cdx = c[0] - d[0]
    var ady = a[1] - d[1]
    var bdy = b[1] - d[1]
    var cdy = c[1] - d[1]
    var adz = a[2] - d[2]
    var bdz = b[2] - d[2]
    var cdz = c[2] - d[2]
    var bdxcdy = bdx * cdy
    var cdxbdy = cdx * bdy
    var cdxady = cdx * ady
    var adxcdy = adx * cdy
    var adxbdy = adx * bdy
    var bdxady = bdx * ady
    var det = adz * (bdxcdy - cdxbdy)
            + bdz * (cdxady - adxcdy)
            + cdz * (adxbdy - bdxady)
    var permanent = (Math.abs(bdxcdy) + Math.abs(cdxbdy)) * Math.abs(adz)
                  + (Math.abs(cdxady) + Math.abs(adxcdy)) * Math.abs(bdz)
                  + (Math.abs(adxbdy) + Math.abs(bdxady)) * Math.abs(cdz)
    var tol = ERRBOUND4 * permanent
    if ((det > tol) || (-det > tol)) {
      return det
    }
    return orientation4Exact(a,b,c,d)
  }
]

function slowOrient(args) {
  var proc = CACHED[args.length]
  if(!proc) {
    proc = CACHED[args.length] = orientation(args.length)
  }
  return proc.apply(undefined, args)
}

function proc (slow, o0, o1, o2, o3, o4, o5) {
  return function getOrientation(a0, a1, a2, a3, a4) {
    switch (arguments.length) {
      case 0:
      case 1:
        return 0;
      case 2:
        return o2(a0, a1)
      case 3:
        return o3(a0, a1, a2)
      case 4:
        return o4(a0, a1, a2, a3)
      case 5:
        return o5(a0, a1, a2, a3, a4)
    }

    var s = new Array(arguments.length)
    for (var i = 0; i < arguments.length; ++i) {
      s[i] = arguments[i]
    }
    return slow(s)
  }
}

function generateOrientationProc() {
  while(CACHED.length <= NUM_EXPAND) {
    CACHED.push(orientation(CACHED.length))
  }
  module.exports = proc.apply(undefined, [slowOrient].concat(CACHED))
  for(var i=0; i<=NUM_EXPAND; ++i) {
    module.exports[i] = CACHED[i]
  }
}

generateOrientationProc()

/***/ }),

/***/ 5382:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

"use strict";


var robustSum = __webpack_require__(8210)
var robustScale = __webpack_require__(3012)

module.exports = robustProduct

function robustProduct(a, b) {
  if(a.length === 1) {
    return robustScale(b, a[0])
  }
  if(b.length === 1) {
    return robustScale(a, b[0])
  }
  if(a.length === 0 || b.length === 0) {
    return [0]
  }
  var r = [0]
  if(a.length < b.length) {
    for(var i=0; i 0 && y0 > 0) || (x0 < 0 && y0 < 0)) {
    return false
  }

  var x1 = orient(b0, a0, a1)
  var y1 = orient(b1, a0, a1)
  if((x1 > 0 && y1 > 0) || (x1 < 0 && y1 < 0)) {
    return false
  }

  //Check for degenerate collinear case
  if(x0 === 0 && y0 === 0 && x1 === 0 && y1 === 0) {
    return checkCollinear(a0, a1, b0, b1)
  }

  return true
}

/***/ }),

/***/ 8545:
/***/ (function(module) {

"use strict";


module.exports = robustSubtract

//Easy case: Add two scalars
function scalarScalar(a, b) {
  var x = a + b
  var bv = x - a
  var av = x - bv
  var br = b - bv
  var ar = a - av
  var y = ar + br
  if(y) {
    return [y, x]
  }
  return [x]
}

function robustSubtract(e, f) {
  var ne = e.length|0
  var nf = f.length|0
  if(ne === 1 && nf === 1) {
    return scalarScalar(e[0], -f[0])
  }
  var n = ne + nf
  var g = new Array(n)
  var count = 0
  var eptr = 0
  var fptr = 0
  var abs = Math.abs
  var ei = e[eptr]
  var ea = abs(ei)
  var fi = -f[fptr]
  var fa = abs(fi)
  var a, b
  if(ea < fa) {
    b = ei
    eptr += 1
    if(eptr < ne) {
      ei = e[eptr]
      ea = abs(ei)
    }
  } else {
    b = fi
    fptr += 1
    if(fptr < nf) {
      fi = -f[fptr]
      fa = abs(fi)
    }
  }
  if((eptr < ne && ea < fa) || (fptr >= nf)) {
    a = ei
    eptr += 1
    if(eptr < ne) {
      ei = e[eptr]
      ea = abs(ei)
    }
  } else {
    a = fi
    fptr += 1
    if(fptr < nf) {
      fi = -f[fptr]
      fa = abs(fi)
    }
  }
  var x = a + b
  var bv = x - a
  var y = b - bv
  var q0 = y
  var q1 = x
  var _x, _bv, _av, _br, _ar
  while(eptr < ne && fptr < nf) {
    if(ea < fa) {
      a = ei
      eptr += 1
      if(eptr < ne) {
        ei = e[eptr]
        ea = abs(ei)
      }
    } else {
      a = fi
      fptr += 1
      if(fptr < nf) {
        fi = -f[fptr]
        fa = abs(fi)
      }
    }
    b = q0
    x = a + b
    bv = x - a
    y = b - bv
    if(y) {
      g[count++] = y
    }
    _x = q1 + x
    _bv = _x - q1
    _av = _x - _bv
    _br = x - _bv
    _ar = q1 - _av
    q0 = _ar + _br
    q1 = _x
  }
  while(eptr < ne) {
    a = ei
    b = q0
    x = a + b
    bv = x - a
    y = b - bv
    if(y) {
      g[count++] = y
    }
    _x = q1 + x
    _bv = _x - q1
    _av = _x - _bv
    _br = x - _bv
    _ar = q1 - _av
    q0 = _ar + _br
    q1 = _x
    eptr += 1
    if(eptr < ne) {
      ei = e[eptr]
    }
  }
  while(fptr < nf) {
    a = fi
    b = q0
    x = a + b
    bv = x - a
    y = b - bv
    if(y) {
      g[count++] = y
    } 
    _x = q1 + x
    _bv = _x - q1
    _av = _x - _bv
    _br = x - _bv
    _ar = q1 - _av
    q0 = _ar + _br
    q1 = _x
    fptr += 1
    if(fptr < nf) {
      fi = -f[fptr]
    }
  }
  if(q0) {
    g[count++] = q0
  }
  if(q1) {
    g[count++] = q1
  }
  if(!count) {
    g[count++] = 0.0  
  }
  g.length = count
  return g
}

/***/ }),

/***/ 8210:
/***/ (function(module) {

"use strict";


module.exports = linearExpansionSum

//Easy case: Add two scalars
function scalarScalar(a, b) {
  var x = a + b
  var bv = x - a
  var av = x - bv
  var br = b - bv
  var ar = a - av
  var y = ar + br
  if(y) {
    return [y, x]
  }
  return [x]
}

function linearExpansionSum(e, f) {
  var ne = e.length|0
  var nf = f.length|0
  if(ne === 1 && nf === 1) {
    return scalarScalar(e[0], f[0])
  }
  var n = ne + nf
  var g = new Array(n)
  var count = 0
  var eptr = 0
  var fptr = 0
  var abs = Math.abs
  var ei = e[eptr]
  var ea = abs(ei)
  var fi = f[fptr]
  var fa = abs(fi)
  var a, b
  if(ea < fa) {
    b = ei
    eptr += 1
    if(eptr < ne) {
      ei = e[eptr]
      ea = abs(ei)
    }
  } else {
    b = fi
    fptr += 1
    if(fptr < nf) {
      fi = f[fptr]
      fa = abs(fi)
    }
  }
  if((eptr < ne && ea < fa) || (fptr >= nf)) {
    a = ei
    eptr += 1
    if(eptr < ne) {
      ei = e[eptr]
      ea = abs(ei)
    }
  } else {
    a = fi
    fptr += 1
    if(fptr < nf) {
      fi = f[fptr]
      fa = abs(fi)
    }
  }
  var x = a + b
  var bv = x - a
  var y = b - bv
  var q0 = y
  var q1 = x
  var _x, _bv, _av, _br, _ar
  while(eptr < ne && fptr < nf) {
    if(ea < fa) {
      a = ei
      eptr += 1
      if(eptr < ne) {
        ei = e[eptr]
        ea = abs(ei)
      }
    } else {
      a = fi
      fptr += 1
      if(fptr < nf) {
        fi = f[fptr]
        fa = abs(fi)
      }
    }
    b = q0
    x = a + b
    bv = x - a
    y = b - bv
    if(y) {
      g[count++] = y
    }
    _x = q1 + x
    _bv = _x - q1
    _av = _x - _bv
    _br = x - _bv
    _ar = q1 - _av
    q0 = _ar + _br
    q1 = _x
  }
  while(eptr < ne) {
    a = ei
    b = q0
    x = a + b
    bv = x - a
    y = b - bv
    if(y) {
      g[count++] = y
    }
    _x = q1 + x
    _bv = _x - q1
    _av = _x - _bv
    _br = x - _bv
    _ar = q1 - _av
    q0 = _ar + _br
    q1 = _x
    eptr += 1
    if(eptr < ne) {
      ei = e[eptr]
    }
  }
  while(fptr < nf) {
    a = fi
    b = q0
    x = a + b
    bv = x - a
    y = b - bv
    if(y) {
      g[count++] = y
    } 
    _x = q1 + x
    _bv = _x - q1
    _av = _x - _bv
    _br = x - _bv
    _ar = q1 - _av
    q0 = _ar + _br
    q1 = _x
    fptr += 1
    if(fptr < nf) {
      fi = f[fptr]
    }
  }
  if(q0) {
    g[count++] = q0
  }
  if(q1) {
    g[count++] = q1
  }
  if(!count) {
    g[count++] = 0.0  
  }
  g.length = count
  return g
}

/***/ }),

/***/ 9127:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

"use strict";


module.exports = boundary

var bnd = __webpack_require__(6204)
var reduce = __webpack_require__(5771)

function boundary(cells) {
  return reduce(bnd(cells))
}


/***/ }),

/***/ 7765:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

"use strict";


module.exports = extractContour

var ndarray = __webpack_require__(9618)
var pool    = __webpack_require__(1888)
var ndsort  = __webpack_require__(446)

var contourAlgorithm = __webpack_require__(1570)

function getDimension(cells) {
  var numCells = cells.length
  var d = 0
  for(var i=0; i> 1,
          v = E[2 * m + 1]
        if (v === b) {
          return m
        }
        if (b < v) {
          h = m
        } else {
          l = m + 1
        }
      }
      return l
    }
    function getContour0d(F, E, C, S) {
      var n = F.length,
        R = []
      for (var i = 0; i < n; ++i) {
        var c = F[i],
          l = c.length
      }
      return R
    }
    return getContour0d
  },
  function cellPolygonizer_1() {
    function B(C, E, i, j) {
      var a = Math.min(i, j) | 0,
        b = Math.max(i, j) | 0,
        l = C[2 * a],
        h = C[2 * a + 1]
      while (l < h) {
        var m = (l + h) >> 1,
          v = E[2 * m + 1]
        if (v === b) {
          return m
        }
        if (b < v) {
          h = m
        } else {
          l = m + 1
        }
      }
      return l
    }
    function getContour1d(F, E, C, S) {
      var n = F.length,
        R = []
      for (var i = 0; i < n; ++i) {
        var c = F[i],
          l = c.length
        if (l === 2) {
          var M = (S[c[0]] << 0) + (S[c[1]] << 1)
          if (M === 0 || M === 3) {
            continue
          }
          switch (M) {
            case 0:
              break
            case 1:
              R.push([B(C, E, c[0], c[1])])
              break
            case 2:
              R.push([B(C, E, c[1], c[0])])
              break
            case 3:
              break
          }
        }
      }
      return R
    }
    return getContour1d
  },
  function cellPolygonizer_2() {
    function B(C, E, i, j) {
      var a = Math.min(i, j) | 0,
        b = Math.max(i, j) | 0,
        l = C[2 * a],
        h = C[2 * a + 1]
      while (l < h) {
        var m = (l + h) >> 1,
          v = E[2 * m + 1]
        if (v === b) {
          return m
        }
        if (b < v) {
          h = m
        } else {
          l = m + 1
        }
      }
      return l
    }
    function getContour2d(F, E, C, S) {
      var n = F.length,
        R = []
      for (var i = 0; i < n; ++i) {
        var c = F[i],
          l = c.length
        if (l === 3) {
          var M = (S[c[0]] << 0) + (S[c[1]] << 1) + (S[c[2]] << 2)
          if (M === 0 || M === 7) {
            continue
          }
          switch (M) {
            case 0:
              break
            case 1:
              R.push([B(C, E, c[0], c[2]), B(C, E, c[0], c[1])])
              break
            case 2:
              R.push([B(C, E, c[1], c[0]), B(C, E, c[1], c[2])])
              break
            case 3:
              R.push([B(C, E, c[0], c[2]), B(C, E, c[1], c[2])])
              break
            case 4:
              R.push([B(C, E, c[2], c[1]), B(C, E, c[2], c[0])])
              break
            case 5:
              R.push([B(C, E, c[2], c[1]), B(C, E, c[0], c[1])])
              break
            case 6:
              R.push([B(C, E, c[1], c[0]), B(C, E, c[2], c[0])])
              break
            case 7:
              break
          }
        } else if (l === 2) {
          var M = (S[c[0]] << 0) + (S[c[1]] << 1)
          if (M === 0 || M === 3) {
            continue
          }
          switch (M) {
            case 0:
              break
            case 1:
              R.push([B(C, E, c[0], c[1])])
              break
            case 2:
              R.push([B(C, E, c[1], c[0])])
              break
            case 3:
              break
          }
        }
      }
      return R
    }
    return getContour2d
  },
  function cellPolygonizer_3() {
    function B(C, E, i, j) {
      var a = Math.min(i, j) | 0,
        b = Math.max(i, j) | 0,
        l = C[2 * a],
        h = C[2 * a + 1]
      while (l < h) {
        var m = (l + h) >> 1,
          v = E[2 * m + 1]
        if (v === b) {
          return m
        }
        if (b < v) {
          h = m
        } else {
          l = m + 1
        }
      }
      return l
    }
    function getContour3d(F, E, C, S) {
      var n = F.length,
        R = []
      for (var i = 0; i < n; ++i) {
        var c = F[i],
          l = c.length
        if (l === 4) {
          var M = (S[c[0]] << 0) + (S[c[1]] << 1) + (S[c[2]] << 2) + (S[c[3]] << 3)
          if (M === 0 || M === 15) {
            continue
          }
          switch (M) {
            case 0:
              break
            case 1:
              R.push([B(C, E, c[0], c[1]), B(C, E, c[0], c[2]), B(C, E, c[0], c[3])])
              break
            case 2:
              R.push([B(C, E, c[1], c[2]), B(C, E, c[1], c[0]), B(C, E, c[1], c[3])])
              break
            case 3:
              R.push([B(C, E, c[1], c[2]), B(C, E, c[0], c[2]), B(C, E, c[0], c[3])], [B(C, E, c[1], c[3]), B(C, E, c[1], c[2]), B(C, E, c[0], c[3])])
              break
            case 4:
              R.push([B(C, E, c[2], c[0]), B(C, E, c[2], c[1]), B(C, E, c[2], c[3])])
              break
            case 5:
              R.push([B(C, E, c[0], c[1]), B(C, E, c[2], c[1]), B(C, E, c[0], c[3])], [B(C, E, c[2], c[1]), B(C, E, c[2], c[3]), B(C, E, c[0], c[3])])
              break
            case 6:
              R.push([B(C, E, c[2], c[0]), B(C, E, c[1], c[0]), B(C, E, c[1], c[3])], [B(C, E, c[2], c[3]), B(C, E, c[2], c[0]), B(C, E, c[1], c[3])])
              break
            case 7:
              R.push([B(C, E, c[0], c[3]), B(C, E, c[1], c[3]), B(C, E, c[2], c[3])])
              break
            case 8:
              R.push([B(C, E, c[3], c[1]), B(C, E, c[3], c[0]), B(C, E, c[3], c[2])])
              break
            case 9:
              R.push([B(C, E, c[3], c[1]), B(C, E, c[0], c[1]), B(C, E, c[0], c[2])], [B(C, E, c[3], c[2]), B(C, E, c[3], c[1]), B(C, E, c[0], c[2])])
              break
            case 10:
              R.push([B(C, E, c[1], c[0]), B(C, E, c[3], c[0]), B(C, E, c[1], c[2])], [B(C, E, c[3], c[0]), B(C, E, c[3], c[2]), B(C, E, c[1], c[2])])
              break
            case 11:
              R.push([B(C, E, c[1], c[2]), B(C, E, c[0], c[2]), B(C, E, c[3], c[2])])
              break
            case 12:
              R.push([B(C, E, c[3], c[0]), B(C, E, c[2], c[0]), B(C, E, c[2], c[1])], [B(C, E, c[3], c[1]), B(C, E, c[3], c[0]), B(C, E, c[2], c[1])])
              break
            case 13:
              R.push([B(C, E, c[0], c[1]), B(C, E, c[2], c[1]), B(C, E, c[3], c[1])])
              break
            case 14:
              R.push([B(C, E, c[2], c[0]), B(C, E, c[1], c[0]), B(C, E, c[3], c[0])])
              break
            case 15:
              break
          }
        } else if (l === 3) {
          var M = (S[c[0]] << 0) + (S[c[1]] << 1) + (S[c[2]] << 2)
          if (M === 0 || M === 7) {
            continue
          }
          switch (M) {
            case 0:
              break
            case 1:
              R.push([B(C, E, c[0], c[2]), B(C, E, c[0], c[1])])
              break
            case 2:
              R.push([B(C, E, c[1], c[0]), B(C, E, c[1], c[2])])
              break
            case 3:
              R.push([B(C, E, c[0], c[2]), B(C, E, c[1], c[2])])
              break
            case 4:
              R.push([B(C, E, c[2], c[1]), B(C, E, c[2], c[0])])
              break
            case 5:
              R.push([B(C, E, c[2], c[1]), B(C, E, c[0], c[1])])
              break
            case 6:
              R.push([B(C, E, c[1], c[0]), B(C, E, c[2], c[0])])
              break
            case 7:
              break
          }
        } else if (l === 2) {
          var M = (S[c[0]] << 0) + (S[c[1]] << 1)
          if (M === 0 || M === 3) {
            continue
          }
          switch (M) {
            case 0:
              break
            case 1:
              R.push([B(C, E, c[0], c[1])])
              break
            case 2:
              R.push([B(C, E, c[1], c[0])])
              break
            case 3:
              break
          }
        }
      }
      return R
    }
    return getContour3d
  }
]

function getPolygonizer(d) {
  return allFns[d]();
}


/***/ }),

/***/ 6803:
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {

"use strict";
var __webpack_unused_export__;
 "use restrict";

var bits      = __webpack_require__(8828)
  , UnionFind = __webpack_require__(1755)

//Returns the dimension of a cell complex
function dimension(cells) {
  var d = 0
    , max = Math.max
  for(var i=0, il=cells.length; i> 1
      , s   = compareCells(cells[mid], c)
    if(s <= 0) {
      if(s === 0) {
        r = mid
      }
      lo = mid + 1
    } else if(s > 0) {
      hi = mid - 1
    }
  }
  return r
}
__webpack_unused_export__ = findCell;

//Builds an index for an n-cell.  This is more general than dual, but less efficient
function incidence(from_cells, to_cells) {
  var index = new Array(from_cells.length)
  for(var i=0, il=index.length; i= from_cells.length || compareCells(from_cells[idx], b) !== 0) {
          break
        }
      }
    }
  }
  return index
}
__webpack_unused_export__ = incidence

//Computes the dual of the mesh.  This is basically an optimized version of buildIndex for the situation where from_cells is just the list of vertices
function dual(cells, vertex_count) {
  if(!vertex_count) {
    return incidence(unique(skeleton(cells, 0)), cells, 0)
  }
  var res = new Array(vertex_count)
  for(var i=0; i>> k) & 1) {
          b.push(c[k])
        }
      }
      result.push(b)
    }
  }
  return normalize(result)
}
__webpack_unused_export__ = explode

//Enumerates all of the n-cells of a cell complex
function skeleton(cells, n) {
  if(n < 0) {
    return []
  }
  var result = []
    , k0     = (1<<(n+1))-1
  for(var i=0; i 0) - (v < 0);
}

//Computes absolute value of integer
exports.abs = function(v) {
  var mask = v >> (INT_BITS-1);
  return (v ^ mask) - mask;
}

//Computes minimum of integers x and y
exports.min = function(x, y) {
  return y ^ ((x ^ y) & -(x < y));
}

//Computes maximum of integers x and y
exports.max = function(x, y) {
  return x ^ ((x ^ y) & -(x < y));
}

//Checks if a number is a power of two
exports.isPow2 = function(v) {
  return !(v & (v-1)) && (!!v);
}

//Computes log base 2 of v
exports.log2 = function(v) {
  var r, shift;
  r =     (v > 0xFFFF) << 4; v >>>= r;
  shift = (v > 0xFF  ) << 3; v >>>= shift; r |= shift;
  shift = (v > 0xF   ) << 2; v >>>= shift; r |= shift;
  shift = (v > 0x3   ) << 1; v >>>= shift; r |= shift;
  return r | (v >> 1);
}

//Computes log base 10 of v
exports.log10 = function(v) {
  return  (v >= 1000000000) ? 9 : (v >= 100000000) ? 8 : (v >= 10000000) ? 7 :
          (v >= 1000000) ? 6 : (v >= 100000) ? 5 : (v >= 10000) ? 4 :
          (v >= 1000) ? 3 : (v >= 100) ? 2 : (v >= 10) ? 1 : 0;
}

//Counts number of bits
exports.popCount = function(v) {
  v = v - ((v >>> 1) & 0x55555555);
  v = (v & 0x33333333) + ((v >>> 2) & 0x33333333);
  return ((v + (v >>> 4) & 0xF0F0F0F) * 0x1010101) >>> 24;
}

//Counts number of trailing zeros
function countTrailingZeros(v) {
  var c = 32;
  v &= -v;
  if (v) c--;
  if (v & 0x0000FFFF) c -= 16;
  if (v & 0x00FF00FF) c -= 8;
  if (v & 0x0F0F0F0F) c -= 4;
  if (v & 0x33333333) c -= 2;
  if (v & 0x55555555) c -= 1;
  return c;
}
exports.countTrailingZeros = countTrailingZeros;

//Rounds to next power of 2
exports.nextPow2 = function(v) {
  v += v === 0;
  --v;
  v |= v >>> 1;
  v |= v >>> 2;
  v |= v >>> 4;
  v |= v >>> 8;
  v |= v >>> 16;
  return v + 1;
}

//Rounds down to previous power of 2
exports.prevPow2 = function(v) {
  v |= v >>> 1;
  v |= v >>> 2;
  v |= v >>> 4;
  v |= v >>> 8;
  v |= v >>> 16;
  return v - (v>>>1);
}

//Computes parity of word
exports.parity = function(v) {
  v ^= v >>> 16;
  v ^= v >>> 8;
  v ^= v >>> 4;
  v &= 0xf;
  return (0x6996 >>> v) & 1;
}

var REVERSE_TABLE = new Array(256);

(function(tab) {
  for(var i=0; i<256; ++i) {
    var v = i, r = i, s = 7;
    for (v >>>= 1; v; v >>>= 1) {
      r <<= 1;
      r |= v & 1;
      --s;
    }
    tab[i] = (r << s) & 0xff;
  }
})(REVERSE_TABLE);

//Reverse bits in a 32 bit word
exports.reverse = function(v) {
  return  (REVERSE_TABLE[ v         & 0xff] << 24) |
          (REVERSE_TABLE[(v >>> 8)  & 0xff] << 16) |
          (REVERSE_TABLE[(v >>> 16) & 0xff] << 8)  |
           REVERSE_TABLE[(v >>> 24) & 0xff];
}

//Interleave bits of 2 coordinates with 16 bits.  Useful for fast quadtree codes
exports.interleave2 = function(x, y) {
  x &= 0xFFFF;
  x = (x | (x << 8)) & 0x00FF00FF;
  x = (x | (x << 4)) & 0x0F0F0F0F;
  x = (x | (x << 2)) & 0x33333333;
  x = (x | (x << 1)) & 0x55555555;

  y &= 0xFFFF;
  y = (y | (y << 8)) & 0x00FF00FF;
  y = (y | (y << 4)) & 0x0F0F0F0F;
  y = (y | (y << 2)) & 0x33333333;
  y = (y | (y << 1)) & 0x55555555;

  return x | (y << 1);
}

//Extracts the nth interleaved component
exports.deinterleave2 = function(v, n) {
  v = (v >>> n) & 0x55555555;
  v = (v | (v >>> 1))  & 0x33333333;
  v = (v | (v >>> 2))  & 0x0F0F0F0F;
  v = (v | (v >>> 4))  & 0x00FF00FF;
  v = (v | (v >>> 16)) & 0x000FFFF;
  return (v << 16) >> 16;
}


//Interleave bits of 3 coordinates, each with 10 bits.  Useful for fast octree codes
exports.interleave3 = function(x, y, z) {
  x &= 0x3FF;
  x  = (x | (x<<16)) & 4278190335;
  x  = (x | (x<<8))  & 251719695;
  x  = (x | (x<<4))  & 3272356035;
  x  = (x | (x<<2))  & 1227133513;

  y &= 0x3FF;
  y  = (y | (y<<16)) & 4278190335;
  y  = (y | (y<<8))  & 251719695;
  y  = (y | (y<<4))  & 3272356035;
  y  = (y | (y<<2))  & 1227133513;
  x |= (y << 1);
  
  z &= 0x3FF;
  z  = (z | (z<<16)) & 4278190335;
  z  = (z | (z<<8))  & 251719695;
  z  = (z | (z<<4))  & 3272356035;
  z  = (z | (z<<2))  & 1227133513;
  
  return x | (z << 2);
}

//Extracts nth interleaved component of a 3-tuple
exports.deinterleave3 = function(v, n) {
  v = (v >>> n)       & 1227133513;
  v = (v | (v>>>2))   & 3272356035;
  v = (v | (v>>>4))   & 251719695;
  v = (v | (v>>>8))   & 4278190335;
  v = (v | (v>>>16))  & 0x3FF;
  return (v<<22)>>22;
}

//Computes next combination in colexicographic order (this is mistakenly called nextPermutation on the bit twiddling hacks page)
exports.nextCombination = function(v) {
  var t = v | (v - 1);
  return (t + 1) | (((~t & -~t) - 1) >>> (countTrailingZeros(v) + 1));
}



/***/ }),

/***/ 2014:
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {

"use strict";
 "use restrict";

var bits      = __webpack_require__(3105)
  , UnionFind = __webpack_require__(4623)

//Returns the dimension of a cell complex
function dimension(cells) {
  var d = 0
    , max = Math.max
  for(var i=0, il=cells.length; i> 1
      , s   = compareCells(cells[mid], c)
    if(s <= 0) {
      if(s === 0) {
        r = mid
      }
      lo = mid + 1
    } else if(s > 0) {
      hi = mid - 1
    }
  }
  return r
}
exports.findCell = findCell;

//Builds an index for an n-cell.  This is more general than dual, but less efficient
function incidence(from_cells, to_cells) {
  var index = new Array(from_cells.length)
  for(var i=0, il=index.length; i= from_cells.length || compareCells(from_cells[idx], b) !== 0) {
          break
        }
      }
    }
  }
  return index
}
exports.incidence = incidence

//Computes the dual of the mesh.  This is basically an optimized version of buildIndex for the situation where from_cells is just the list of vertices
function dual(cells, vertex_count) {
  if(!vertex_count) {
    return incidence(unique(skeleton(cells, 0)), cells, 0)
  }
  var res = new Array(vertex_count)
  for(var i=0; i>> k) & 1) {
          b.push(c[k])
        }
      }
      result.push(b)
    }
  }
  return normalize(result)
}
exports.explode = explode

//Enumerates all of the n-cells of a cell complex
function skeleton(cells, n) {
  if(n < 0) {
    return []
  }
  var result = []
    , k0     = (1<<(n+1))-1
  for(var i=0; i> 1
    }
    return (i >> 1) - 1
  }

  //Bubble element i down the heap
  function heapDown(i) {
    var w = heapWeight(i)
    while(true) {
      var tw = w
      var left  = 2*i + 1
      var right = 2*(i + 1)
      var next = i
      if(left < heapCount) {
        var lw = heapWeight(left)
        if(lw < tw) {
          next = left
          tw = lw
        }
      }
      if(right < heapCount) {
        var rw = heapWeight(right)
        if(rw < tw) {
          next = right
        }
      }
      if(next === i) {
        return i
      }
      heapSwap(i, next)
      i = next      
    }
  }

  //Bubbles element i up the heap
  function heapUp(i) {
    var w = heapWeight(i)
    while(i > 0) {
      var parent = heapParent(i)
      if(parent >= 0) {
        var pw = heapWeight(parent)
        if(w < pw) {
          heapSwap(i, parent)
          i = parent
          continue
        }
      }
      return i
    }
  }

  //Pop minimum element
  function heapPop() {
    if(heapCount > 0) {
      var head = heap[0]
      heapSwap(0, heapCount-1)
      heapCount -= 1
      heapDown(0)
      return head
    }
    return -1
  }

  //Update heap item i
  function heapUpdate(i, w) {
    var a = heap[i]
    if(weights[a] === w) {
      return i
    }
    weights[a] = -Infinity
    heapUp(i)
    heapPop()
    weights[a] = w
    heapCount += 1
    return heapUp(heapCount-1)
  }

  //Kills a vertex (assume vertex already removed from heap)
  function kill(i) {
    if(dead[i]) {
      return
    }
    //Kill vertex
    dead[i] = true
    //Fixup topology
    var s = inv[i]
    var t = outv[i]
    if(inv[t] >= 0) {
      inv[t] = s
    }
    if(outv[s] >= 0) {
      outv[s] = t
    }

    //Update weights on s and t
    if(index[s] >= 0) {
      heapUpdate(index[s], computeWeight(s))
    }
    if(index[t] >= 0) {
      heapUpdate(index[t], computeWeight(t))
    }
  }

  //Initialize weights and heap
  var heap = []
  var index = new Array(n)
  for(var i=0; i>1; i>=0; --i) {
    heapDown(i)
  }
  
  //Kill vertices
  while(true) {
    var hmin = heapPop()
    if((hmin < 0) || (weights[hmin] > minArea)) {
      break
    }
    kill(hmin)
  }

  //Build collapsed vertex table
  var npositions = []
  for(var i=0; i= 0 && tout >= 0 && tin !== tout) {
      var cin = index[tin]
      var cout = index[tout]
      if(cin !== cout) {
        ncells.push([ cin, cout ])
      }
    }
  })

  //Normalize result
  sc.unique(sc.normalize(ncells))

  //Return final list of cells
  return {
    positions: npositions,
    edges: ncells
  }
}

/***/ }),

/***/ 1303:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

"use strict";


module.exports = orderSegments

var orient = __webpack_require__(3250)

function horizontalOrder(a, b) {
  var bl, br
  if(b[0][0] < b[1][0]) {
    bl = b[0]
    br = b[1]
  } else if(b[0][0] > b[1][0]) {
    bl = b[1]
    br = b[0]
  } else {
    var alo = Math.min(a[0][1], a[1][1])
    var ahi = Math.max(a[0][1], a[1][1])
    var blo = Math.min(b[0][1], b[1][1])
    var bhi = Math.max(b[0][1], b[1][1])
    if(ahi < blo) {
      return ahi - blo
    }
    if(alo > bhi) {
      return alo - bhi
    }
    return ahi - bhi
  }
  var al, ar
  if(a[0][1] < a[1][1]) {
    al = a[0]
    ar = a[1]
  } else {
    al = a[1]
    ar = a[0]
  }
  var d = orient(br, bl, al)
  if(d) {
    return d
  }
  d = orient(br, bl, ar)
  if(d) {
    return d
  }
  return ar - br
}

function orderSegments(b, a) {
  var al, ar
  if(a[0][0] < a[1][0]) {
    al = a[0]
    ar = a[1]
  } else if(a[0][0] > a[1][0]) {
    al = a[1]
    ar = a[0]
  } else {
    return horizontalOrder(a, b)
  }
  var bl, br
  if(b[0][0] < b[1][0]) {
    bl = b[0]
    br = b[1]
  } else if(b[0][0] > b[1][0]) {
    bl = b[1]
    br = b[0]
  } else {
    return -horizontalOrder(b, a)
  }
  var d1 = orient(al, ar, br)
  var d2 = orient(al, ar, bl)
  if(d1 < 0) {
    if(d2 <= 0) {
      return d1
    }
  } else if(d1 > 0) {
    if(d2 >= 0) {
      return d1
    }
  } else if(d2) {
    return d2
  }
  d1 = orient(br, bl, ar)
  d2 = orient(br, bl, al)
  if(d1 < 0) {
    if(d2 <= 0) {
      return d1
    }
  } else if(d1 > 0) {
    if(d2 >= 0) {
      return d1
    }
  } else if(d2) {
    return d2
  }
  return ar[0] - br[0]
}

/***/ }),

/***/ 4209:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

"use strict";


module.exports = createSlabDecomposition

var bounds = __webpack_require__(2478)
var createRBTree = __webpack_require__(3840)
var orient = __webpack_require__(3250)
var orderSegments = __webpack_require__(1303)

function SlabDecomposition(slabs, coordinates, horizontal) {
  this.slabs = slabs
  this.coordinates = coordinates
  this.horizontal = horizontal
}

var proto = SlabDecomposition.prototype

function compareHorizontal(e, y) {
  return e.y - y
}

function searchBucket(root, p) {
  var lastNode = null
  while(root) {
    var seg = root.key
    var l, r
    if(seg[0][0] < seg[1][0]) {
      l = seg[0]
      r = seg[1]
    } else {
      l = seg[1]
      r = seg[0]
    }
    var o = orient(l, r, p)
    if(o < 0) {
      root = root.left
    } else if(o > 0) {
      if(p[0] !== seg[1][0]) {
        lastNode = root
        root = root.right
      } else {
        var val = searchBucket(root.right, p)
        if(val) {
          return val
        }
        root = root.left
      }
    } else {
      if(p[0] !== seg[1][0]) {
        return root
      } else {
        var val = searchBucket(root.right, p)
        if(val) {
          return val
        }
        root = root.left
      }
    }
  }
  return lastNode
}

proto.castUp = function(p) {
  var bucket = bounds.le(this.coordinates, p[0])
  if(bucket < 0) {
    return -1
  }
  var root = this.slabs[bucket]
  var hitNode = searchBucket(this.slabs[bucket], p)
  var lastHit = -1
  if(hitNode) {
    lastHit = hitNode.value
  }
  //Edge case: need to handle horizontal segments (sucks)
  if(this.coordinates[bucket] === p[0]) {
    var lastSegment = null
    if(hitNode) {
      lastSegment = hitNode.key
    }
    if(bucket > 0) {
      var otherHitNode = searchBucket(this.slabs[bucket-1], p)
      if(otherHitNode) {
        if(lastSegment) {
          if(orderSegments(otherHitNode.key, lastSegment) > 0) {
            lastSegment = otherHitNode.key
            lastHit = otherHitNode.value
          }
        } else {
          lastHit = otherHitNode.value
          lastSegment = otherHitNode.key
        }
      }
    }
    var horiz = this.horizontal[bucket]
    if(horiz.length > 0) {
      var hbucket = bounds.ge(horiz, p[1], compareHorizontal)
      if(hbucket < horiz.length) {
        var e = horiz[hbucket]
        if(p[1] === e.y) {
          if(e.closed) {
            return e.index
          } else {
            while(hbucket < horiz.length-1 && horiz[hbucket+1].y === p[1]) {
              hbucket = hbucket+1
              e = horiz[hbucket]
              if(e.closed) {
                return e.index
              }
            }
            if(e.y === p[1] && !e.start) {
              hbucket = hbucket+1
              if(hbucket >= horiz.length) {
                return lastHit
              }
              e = horiz[hbucket]
            }
          }
        }
        //Check if e is above/below last segment
        if(e.start) {
          if(lastSegment) {
            var o = orient(lastSegment[0], lastSegment[1], [p[0], e.y])
            if(lastSegment[0][0] > lastSegment[1][0]) {
              o = -o
            }
            if(o > 0) {
              lastHit = e.index
            }
          } else {
            lastHit = e.index
          }
        } else if(e.y !== p[1]) {
          lastHit = e.index
        }
      }
    }
  }
  return lastHit
}

function IntervalSegment(y, index, start, closed) {
  this.y = y
  this.index = index
  this.start = start
  this.closed = closed
}

function Event(x, segment, create, index) {
  this.x = x
  this.segment = segment
  this.create = create
  this.index = index
}


function createSlabDecomposition(segments) {
  var numSegments = segments.length
  var numEvents = 2 * numSegments
  var events = new Array(numEvents)
  for(var i=0; i 1.0) {
    t = 1.0
  }
  var ti = 1.0 - t
  var n = a.length
  var r = new Array(n)
  for(var i=0; i 0) || (a > 0 && b < 0)) {
      var p = lerpW(s, b, t, a)
      pos.push(p)
      neg.push(p.slice())
    }
    if(b < 0) {
      neg.push(t.slice())
    } else if(b > 0) {
      pos.push(t.slice())
    } else {
      pos.push(t.slice())
      neg.push(t.slice())
    }
    a = b
  }
  return { positive: pos, negative: neg }
}

function positive(points, plane) {
  var pos = []
  var a = planeT(points[points.length-1], plane)
  for(var s=points[points.length-1], t=points[0], i=0; i 0) || (a > 0 && b < 0)) {
      pos.push(lerpW(s, b, t, a))
    }
    if(b >= 0) {
      pos.push(t.slice())
    }
    a = b
  }
  return pos
}

function negative(points, plane) {
  var neg = []
  var a = planeT(points[points.length-1], plane)
  for(var s=points[points.length-1], t=points[0], i=0; i 0) || (a > 0 && b < 0)) {
      neg.push(lerpW(s, b, t, a))
    }
    if(b <= 0) {
      neg.push(t.slice())
    }
    a = b
  }
  return neg
}

/***/ }),

/***/ 3387:
/***/ (function(module, exports, __webpack_require__) {

var __WEBPACK_AMD_DEFINE_RESULT__;/* global window, exports, define */

!function() {
    'use strict'

    var re = {
        not_string: /[^s]/,
        not_bool: /[^t]/,
        not_type: /[^T]/,
        not_primitive: /[^v]/,
        number: /[diefg]/,
        numeric_arg: /[bcdiefguxX]/,
        json: /[j]/,
        not_json: /[^j]/,
        text: /^[^\x25]+/,
        modulo: /^\x25{2}/,
        placeholder: /^\x25(?:([1-9]\d*)\$|\(([^)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-gijostTuvxX])/,
        key: /^([a-z_][a-z_\d]*)/i,
        key_access: /^\.([a-z_][a-z_\d]*)/i,
        index_access: /^\[(\d+)\]/,
        sign: /^[+-]/
    }

    function sprintf(key) {
        // `arguments` is not an array, but should be fine for this call
        return sprintf_format(sprintf_parse(key), arguments)
    }

    function vsprintf(fmt, argv) {
        return sprintf.apply(null, [fmt].concat(argv || []))
    }

    function sprintf_format(parse_tree, argv) {
        var cursor = 1, tree_length = parse_tree.length, arg, output = '', i, k, ph, pad, pad_character, pad_length, is_positive, sign
        for (i = 0; i < tree_length; i++) {
            if (typeof parse_tree[i] === 'string') {
                output += parse_tree[i]
            }
            else if (typeof parse_tree[i] === 'object') {
                ph = parse_tree[i] // convenience purposes only
                if (ph.keys) { // keyword argument
                    arg = argv[cursor]
                    for (k = 0; k < ph.keys.length; k++) {
                        if (arg == undefined) {
                            throw new Error(sprintf('[sprintf] Cannot access property "%s" of undefined value "%s"', ph.keys[k], ph.keys[k-1]))
                        }
                        arg = arg[ph.keys[k]]
                    }
                }
                else if (ph.param_no) { // positional argument (explicit)
                    arg = argv[ph.param_no]
                }
                else { // positional argument (implicit)
                    arg = argv[cursor++]
                }

                if (re.not_type.test(ph.type) && re.not_primitive.test(ph.type) && arg instanceof Function) {
                    arg = arg()
                }

                if (re.numeric_arg.test(ph.type) && (typeof arg !== 'number' && isNaN(arg))) {
                    throw new TypeError(sprintf('[sprintf] expecting number but found %T', arg))
                }

                if (re.number.test(ph.type)) {
                    is_positive = arg >= 0
                }

                switch (ph.type) {
                    case 'b':
                        arg = parseInt(arg, 10).toString(2)
                        break
                    case 'c':
                        arg = String.fromCharCode(parseInt(arg, 10))
                        break
                    case 'd':
                    case 'i':
                        arg = parseInt(arg, 10)
                        break
                    case 'j':
                        arg = JSON.stringify(arg, null, ph.width ? parseInt(ph.width) : 0)
                        break
                    case 'e':
                        arg = ph.precision ? parseFloat(arg).toExponential(ph.precision) : parseFloat(arg).toExponential()
                        break
                    case 'f':
                        arg = ph.precision ? parseFloat(arg).toFixed(ph.precision) : parseFloat(arg)
                        break
                    case 'g':
                        arg = ph.precision ? String(Number(arg.toPrecision(ph.precision))) : parseFloat(arg)
                        break
                    case 'o':
                        arg = (parseInt(arg, 10) >>> 0).toString(8)
                        break
                    case 's':
                        arg = String(arg)
                        arg = (ph.precision ? arg.substring(0, ph.precision) : arg)
                        break
                    case 't':
                        arg = String(!!arg)
                        arg = (ph.precision ? arg.substring(0, ph.precision) : arg)
                        break
                    case 'T':
                        arg = Object.prototype.toString.call(arg).slice(8, -1).toLowerCase()
                        arg = (ph.precision ? arg.substring(0, ph.precision) : arg)
                        break
                    case 'u':
                        arg = parseInt(arg, 10) >>> 0
                        break
                    case 'v':
                        arg = arg.valueOf()
                        arg = (ph.precision ? arg.substring(0, ph.precision) : arg)
                        break
                    case 'x':
                        arg = (parseInt(arg, 10) >>> 0).toString(16)
                        break
                    case 'X':
                        arg = (parseInt(arg, 10) >>> 0).toString(16).toUpperCase()
                        break
                }
                if (re.json.test(ph.type)) {
                    output += arg
                }
                else {
                    if (re.number.test(ph.type) && (!is_positive || ph.sign)) {
                        sign = is_positive ? '+' : '-'
                        arg = arg.toString().replace(re.sign, '')
                    }
                    else {
                        sign = ''
                    }
                    pad_character = ph.pad_char ? ph.pad_char === '0' ? '0' : ph.pad_char.charAt(1) : ' '
                    pad_length = ph.width - (sign + arg).length
                    pad = ph.width ? (pad_length > 0 ? pad_character.repeat(pad_length) : '') : ''
                    output += ph.align ? sign + arg + pad : (pad_character === '0' ? sign + pad + arg : pad + sign + arg)
                }
            }
        }
        return output
    }

    var sprintf_cache = Object.create(null)

    function sprintf_parse(fmt) {
        if (sprintf_cache[fmt]) {
            return sprintf_cache[fmt]
        }

        var _fmt = fmt, match, parse_tree = [], arg_names = 0
        while (_fmt) {
            if ((match = re.text.exec(_fmt)) !== null) {
                parse_tree.push(match[0])
            }
            else if ((match = re.modulo.exec(_fmt)) !== null) {
                parse_tree.push('%')
            }
            else if ((match = re.placeholder.exec(_fmt)) !== null) {
                if (match[2]) {
                    arg_names |= 1
                    var field_list = [], replacement_field = match[2], field_match = []
                    if ((field_match = re.key.exec(replacement_field)) !== null) {
                        field_list.push(field_match[1])
                        while ((replacement_field = replacement_field.substring(field_match[0].length)) !== '') {
                            if ((field_match = re.key_access.exec(replacement_field)) !== null) {
                                field_list.push(field_match[1])
                            }
                            else if ((field_match = re.index_access.exec(replacement_field)) !== null) {
                                field_list.push(field_match[1])
                            }
                            else {
                                throw new SyntaxError('[sprintf] failed to parse named argument key')
                            }
                        }
                    }
                    else {
                        throw new SyntaxError('[sprintf] failed to parse named argument key')
                    }
                    match[2] = field_list
                }
                else {
                    arg_names |= 2
                }
                if (arg_names === 3) {
                    throw new Error('[sprintf] mixing positional and named placeholders is not (yet) supported')
                }

                parse_tree.push(
                    {
                        placeholder: match[0],
                        param_no:    match[1],
                        keys:        match[2],
                        sign:        match[3],
                        pad_char:    match[4],
                        align:       match[5],
                        width:       match[6],
                        precision:   match[7],
                        type:        match[8]
                    }
                )
            }
            else {
                throw new SyntaxError('[sprintf] unexpected placeholder')
            }
            _fmt = _fmt.substring(match[0].length)
        }
        return sprintf_cache[fmt] = parse_tree
    }

    /**
     * export to either browser or node.js
     */
    /* eslint-disable quote-props */
    if (true) {
        exports.sprintf = sprintf
        exports.vsprintf = vsprintf
    }
    if (typeof window !== 'undefined') {
        window['sprintf'] = sprintf
        window['vsprintf'] = vsprintf

        if (true) {
            !(__WEBPACK_AMD_DEFINE_RESULT__ = (function() {
                return {
                    'sprintf': sprintf,
                    'vsprintf': vsprintf
                }
            }).call(exports, __webpack_require__, exports, module),
		__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__))
        }
    }
    /* eslint-enable quote-props */
}(); // eslint-disable-line


/***/ }),

/***/ 3711:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

"use strict";


module.exports = surfaceNets

var generateContourExtractor = __webpack_require__(2640)
var zeroCrossings = __webpack_require__(781)

var allFns = {
  "2d": function (genContour, order, dtype) {
    var contour = genContour({
      order: order,
      scalarArguments: 3,
      getters: dtype === "generic" ? [0] : undefined,
      phase: function phaseFunc(p, a, b, c) {
        return (p > c) | 0;
      },
      vertex: function vertexFunc(d0, d1, v0, v1, v2, v3, p0, p1, p2, p3, a, b, c) {
        var m = ((p0 << 0) + (p1 << 1) + (p2 << 2) + (p3 << 3)) | 0;
        if (m === 0 || m === 15) {
          return;
        }
        switch (m) {
          case 0:
            a.push([d0 - 0.5, d1 - 0.5]);
            break;
          case 1:
            a.push([d0 - 0.25 - (0.25 * (v1 + v0 - 2 * c)) / (v0 - v1), d1 - 0.25 - (0.25 * (v2 + v0 - 2 * c)) / (v0 - v2)]);
            break;
          case 2:
            a.push([d0 - 0.75 - (0.25 * (-v1 - v0 + 2 * c)) / (v1 - v0), d1 - 0.25 - (0.25 * (v3 + v1 - 2 * c)) / (v1 - v3)]);
            break;
          case 3:
            a.push([d0 - 0.5, d1 - 0.5 - (0.5 * (v2 + v0 + v3 + v1 - 4 * c)) / (v0 - v2 + v1 - v3)]);
            break;
          case 4:
            a.push([d0 - 0.25 - (0.25 * (v3 + v2 - 2 * c)) / (v2 - v3), d1 - 0.75 - (0.25 * (-v2 - v0 + 2 * c)) / (v2 - v0)]);
            break;
          case 5:
            a.push([d0 - 0.5 - (0.5 * (v1 + v0 + v3 + v2 - 4 * c)) / (v0 - v1 + v2 - v3), d1 - 0.5]);
            break;
          case 6:
            a.push([d0 - 0.5 - (0.25 * (-v1 - v0 + v3 + v2)) / (v1 - v0 + v2 - v3), d1 - 0.5 - (0.25 * (-v2 - v0 + v3 + v1)) / (v2 - v0 + v1 - v3)]);
            break;
          case 7:
            a.push([d0 - 0.75 - (0.25 * (v3 + v2 - 2 * c)) / (v2 - v3), d1 - 0.75 - (0.25 * (v3 + v1 - 2 * c)) / (v1 - v3)]);
            break;
          case 8:
            a.push([d0 - 0.75 - (0.25 * (-v3 - v2 + 2 * c)) / (v3 - v2), d1 - 0.75 - (0.25 * (-v3 - v1 + 2 * c)) / (v3 - v1)]);
            break;
          case 9:
            a.push([d0 - 0.5 - (0.25 * (v1 + v0 + -v3 - v2)) / (v0 - v1 + v3 - v2), d1 - 0.5 - (0.25 * (v2 + v0 + -v3 - v1)) / (v0 - v2 + v3 - v1)]);
            break;
          case 10:
            a.push([d0 - 0.5 - (0.5 * (-v1 - v0 + -v3 - v2 + 4 * c)) / (v1 - v0 + v3 - v2), d1 - 0.5]);
            break;
          case 11:
            a.push([d0 - 0.25 - (0.25 * (-v3 - v2 + 2 * c)) / (v3 - v2), d1 - 0.75 - (0.25 * (v2 + v0 - 2 * c)) / (v0 - v2)]);
            break;
          case 12:
            a.push([d0 - 0.5, d1 - 0.5 - (0.5 * (-v2 - v0 + -v3 - v1 + 4 * c)) / (v2 - v0 + v3 - v1)]);
            break;
          case 13:
            a.push([d0 - 0.75 - (0.25 * (v1 + v0 - 2 * c)) / (v0 - v1), d1 - 0.25 - (0.25 * (-v3 - v1 + 2 * c)) / (v3 - v1)]);
            break;
          case 14:
            a.push([d0 - 0.25 - (0.25 * (-v1 - v0 + 2 * c)) / (v1 - v0), d1 - 0.25 - (0.25 * (-v2 - v0 + 2 * c)) / (v2 - v0)]);
            break;
          case 15:
            a.push([d0 - 0.5, d1 - 0.5]);
            break;
        }
      },
      cell: function cellFunc(v0, v1, c0, c1, p0, p1, a, b, c) {
        if (p0) {
          b.push([v0, v1]);
        } else {
          b.push([v1, v0]);
        }
      },
    });
    return function (array, level) {
      var verts = [],
        cells = [];
      contour(array, verts, cells, level);
      return { positions: verts, cells: cells };
    };
  }
}

function buildSurfaceNets(order, dtype) {
  var inKey = order.length + 'd'
  var fn = allFns[inKey]
  if(fn) return fn(generateContourExtractor, order, dtype)
}

//1D case: Need to handle specially
function mesh1D(array, level) {
  var zc = zeroCrossings(array, level)
  var n = zc.length
  var npos = new Array(n)
  var ncel = new Array(n)
  for(var i=0; i0) {
          shapeX += 0.02
        }
      }

      var data = new Float32Array(bufferSize)
      var ptr     = 0
      var xOffset = -0.5 * shapeX
      for(var i=0; i Math.max(vy, vz)) {
    u[2] = 1
  } else if(vy > Math.max(vx, vz)) {
    u[0] = 1
  } else {
    u[1] = 1
  }

  var vv = 0
  var uv = 0
  for(var i=0; i<3; ++i ) {
    vv += v[i] * v[i]
    uv += u[i] * v[i]
  }
  for(var i=0; i<3; ++i) {
    u[i] -= (uv / vv) *  v[i]
  }
  normalize3(u, u)
  return u
}

function TurntableController(zoomMin, zoomMax, center, up, right, radius, theta, phi) {
  this.center = filterVector(center)
  this.up     = filterVector(up)
  this.right  = filterVector(right)
  this.radius = filterVector([radius])
  this.angle  = filterVector([theta, phi])
  this.angle.bounds = [[-Infinity,-Math.PI/2], [Infinity,Math.PI/2]]
  this.setDistanceLimits(zoomMin, zoomMax)

  this.computedCenter = this.center.curve(0)
  this.computedUp     = this.up.curve(0)
  this.computedRight  = this.right.curve(0)
  this.computedRadius = this.radius.curve(0)
  this.computedAngle  = this.angle.curve(0)
  this.computedToward = [0,0,0]
  this.computedEye    = [0,0,0]
  this.computedMatrix = new Array(16)
  for(var i=0; i<16; ++i) {
    this.computedMatrix[i] = 0.5
  }

  this.recalcMatrix(0)
}

var proto = TurntableController.prototype

proto.setDistanceLimits = function(minDist, maxDist) {
  if(minDist > 0) {
    minDist = Math.log(minDist)
  } else {
    minDist = -Infinity
  }
  if(maxDist > 0) {
    maxDist = Math.log(maxDist)
  } else {
    maxDist = Infinity
  }
  maxDist = Math.max(maxDist, minDist)
  this.radius.bounds[0][0] = minDist
  this.radius.bounds[1][0] = maxDist
}

proto.getDistanceLimits = function(out) {
  var bounds = this.radius.bounds[0]
  if(out) {
    out[0] = Math.exp(bounds[0][0])
    out[1] = Math.exp(bounds[1][0])
    return out
  }
  return [ Math.exp(bounds[0][0]), Math.exp(bounds[1][0]) ]
}

proto.recalcMatrix = function(t) {
  //Recompute curves
  this.center.curve(t)
  this.up.curve(t)
  this.right.curve(t)
  this.radius.curve(t)
  this.angle.curve(t)

  //Compute frame for camera matrix
  var up     = this.computedUp
  var right  = this.computedRight
  var uu = 0.0
  var ur = 0.0
  for(var i=0; i<3; ++i) {
    ur += up[i] * right[i]
    uu += up[i] * up[i]
  }
  var ul = Math.sqrt(uu)
  var rr = 0.0
  for(var i=0; i<3; ++i) {
    right[i] -= up[i] * ur / uu
    rr       += right[i] * right[i]
    up[i]    /= ul
  }
  var rl = Math.sqrt(rr)
  for(var i=0; i<3; ++i) {
    right[i] /= rl
  }

  //Compute toward vector
  var toward = this.computedToward
  cross(toward, up, right)
  normalize3(toward, toward)

  //Compute angular parameters
  var radius = Math.exp(this.computedRadius[0])
  var theta  = this.computedAngle[0]
  var phi    = this.computedAngle[1]

  var ctheta = Math.cos(theta)
  var stheta = Math.sin(theta)
  var cphi   = Math.cos(phi)
  var sphi   = Math.sin(phi)

  var center = this.computedCenter

  var wx = ctheta * cphi 
  var wy = stheta * cphi
  var wz = sphi

  var sx = -ctheta * sphi
  var sy = -stheta * sphi
  var sz = cphi

  var eye = this.computedEye
  var mat = this.computedMatrix
  for(var i=0; i<3; ++i) {
    var x      = wx * right[i] + wy * toward[i] + wz * up[i]
    mat[4*i+1] = sx * right[i] + sy * toward[i] + sz * up[i]
    mat[4*i+2] = x
    mat[4*i+3] = 0.0
  }

  var ax = mat[1]
  var ay = mat[5]
  var az = mat[9]
  var bx = mat[2]
  var by = mat[6]
  var bz = mat[10]
  var cx = ay * bz - az * by
  var cy = az * bx - ax * bz
  var cz = ax * by - ay * bx
  var cl = len3(cx, cy, cz)
  cx /= cl
  cy /= cl
  cz /= cl
  mat[0] = cx
  mat[4] = cy
  mat[8] = cz

  for(var i=0; i<3; ++i) {
    eye[i] = center[i] + mat[2+4*i]*radius
  }

  for(var i=0; i<3; ++i) {
    var rr = 0.0
    for(var j=0; j<3; ++j) {
      rr += mat[i+4*j] * eye[j]
    }
    mat[12+i] = -rr
  }
  mat[15] = 1.0
}

proto.getMatrix = function(t, result) {
  this.recalcMatrix(t)
  var mat = this.computedMatrix
  if(result) {
    for(var i=0; i<16; ++i) {
      result[i] = mat[i]
    }
    return result
  }
  return mat
}

var zAxis = [0,0,0]
proto.rotate = function(t, dtheta, dphi, droll) {
  this.angle.move(t, dtheta, dphi)
  if(droll) {
    this.recalcMatrix(t)

    var mat = this.computedMatrix
    zAxis[0] = mat[2]
    zAxis[1] = mat[6]
    zAxis[2] = mat[10]

    var up     = this.computedUp
    var right  = this.computedRight
    var toward = this.computedToward

    for(var i=0; i<3; ++i) {
      mat[4*i]   = up[i]
      mat[4*i+1] = right[i]
      mat[4*i+2] = toward[i]
    }
    rotateM(mat, mat, droll, zAxis)
    for(var i=0; i<3; ++i) {
      up[i] =    mat[4*i]
      right[i] = mat[4*i+1]
    }

    this.up.set(t, up[0], up[1], up[2])
    this.right.set(t, right[0], right[1], right[2])
  }
}

proto.pan = function(t, dx, dy, dz) {
  dx = dx || 0.0
  dy = dy || 0.0
  dz = dz || 0.0

  this.recalcMatrix(t)
  var mat = this.computedMatrix

  var dist = Math.exp(this.computedRadius[0])

  var ux = mat[1]
  var uy = mat[5]
  var uz = mat[9]
  var ul = len3(ux, uy, uz)
  ux /= ul
  uy /= ul
  uz /= ul

  var rx = mat[0]
  var ry = mat[4]
  var rz = mat[8]
  var ru = rx * ux + ry * uy + rz * uz
  rx -= ux * ru
  ry -= uy * ru
  rz -= uz * ru
  var rl = len3(rx, ry, rz)
  rx /= rl
  ry /= rl
  rz /= rl

  var vx = rx * dx + ux * dy
  var vy = ry * dx + uy * dy
  var vz = rz * dx + uz * dy
  this.center.move(t, vx, vy, vz)

  //Update z-component of radius
  var radius = Math.exp(this.computedRadius[0])
  radius = Math.max(1e-4, radius + dz)
  this.radius.set(t, Math.log(radius))
}

proto.translate = function(t, dx, dy, dz) {
  this.center.move(t,
    dx||0.0,
    dy||0.0,
    dz||0.0)
}

//Recenters the coordinate axes
proto.setMatrix = function(t, mat, axes, noSnap) {
  
  //Get the axes for tare
  var ushift = 1
  if(typeof axes === 'number') {
    ushift = (axes)|0
  } 
  if(ushift < 0 || ushift > 3) {
    ushift = 1
  }
  var vshift = (ushift + 2) % 3
  var fshift = (ushift + 1) % 3

  //Recompute state for new t value
  if(!mat) { 
    this.recalcMatrix(t)
    mat = this.computedMatrix
  }

  //Get right and up vectors
  var ux = mat[ushift]
  var uy = mat[ushift+4]
  var uz = mat[ushift+8]
  if(!noSnap) {
    var ul = len3(ux, uy, uz)
    ux /= ul
    uy /= ul
    uz /= ul
  } else {
    var ax = Math.abs(ux)
    var ay = Math.abs(uy)
    var az = Math.abs(uz)
    var am = Math.max(ax,ay,az)
    if(ax === am) {
      ux = (ux < 0) ? -1 : 1
      uy = uz = 0
    } else if(az === am) {
      uz = (uz < 0) ? -1 : 1
      ux = uy = 0
    } else {
      uy = (uy < 0) ? -1 : 1
      ux = uz = 0
    }
  }

  var rx = mat[vshift]
  var ry = mat[vshift+4]
  var rz = mat[vshift+8]
  var ru = rx * ux + ry * uy + rz * uz
  rx -= ux * ru
  ry -= uy * ru
  rz -= uz * ru
  var rl = len3(rx, ry, rz)
  rx /= rl
  ry /= rl
  rz /= rl
  
  var fx = uy * rz - uz * ry
  var fy = uz * rx - ux * rz
  var fz = ux * ry - uy * rx
  var fl = len3(fx, fy, fz)
  fx /= fl
  fy /= fl
  fz /= fl

  this.center.jump(t, ex, ey, ez)
  this.radius.idle(t)
  this.up.jump(t, ux, uy, uz)
  this.right.jump(t, rx, ry, rz)

  var phi, theta
  if(ushift === 2) {
    var cx = mat[1]
    var cy = mat[5]
    var cz = mat[9]
    var cr = cx * rx + cy * ry + cz * rz
    var cf = cx * fx + cy * fy + cz * fz
    if(tu < 0) {
      phi = -Math.PI/2
    } else {
      phi = Math.PI/2
    }
    theta = Math.atan2(cf, cr)
  } else {
    var tx = mat[2]
    var ty = mat[6]
    var tz = mat[10]
    var tu = tx * ux + ty * uy + tz * uz
    var tr = tx * rx + ty * ry + tz * rz
    var tf = tx * fx + ty * fy + tz * fz

    phi = Math.asin(clamp1(tu))
    theta = Math.atan2(tf, tr)
  }

  this.angle.jump(t, theta, phi)

  this.recalcMatrix(t)
  var dx = mat[2]
  var dy = mat[6]
  var dz = mat[10]

  var imat = this.computedMatrix
  invert44(imat, mat)
  var w  = imat[15]
  var ex = imat[12] / w
  var ey = imat[13] / w
  var ez = imat[14] / w

  var gs = Math.exp(this.computedRadius[0])
  this.center.jump(t, ex-dx*gs, ey-dy*gs, ez-dz*gs)
}

proto.lastT = function() {
  return Math.max(
    this.center.lastT(),
    this.up.lastT(),
    this.right.lastT(),
    this.radius.lastT(),
    this.angle.lastT())
}

proto.idle = function(t) {
  this.center.idle(t)
  this.up.idle(t)
  this.right.idle(t)
  this.radius.idle(t)
  this.angle.idle(t)
}

proto.flush = function(t) {
  this.center.flush(t)
  this.up.flush(t)
  this.right.flush(t)
  this.radius.flush(t)
  this.angle.flush(t)
}

proto.setDistance = function(t, d) {
  if(d > 0) {
    this.radius.set(t, Math.log(d))
  }
}

proto.lookAt = function(t, eye, center, up) {
  this.recalcMatrix(t)

  eye    = eye    || this.computedEye
  center = center || this.computedCenter
  up     = up     || this.computedUp

  var ux = up[0]
  var uy = up[1]
  var uz = up[2]
  var ul = len3(ux, uy, uz)
  if(ul < 1e-6) {
    return
  }
  ux /= ul
  uy /= ul
  uz /= ul

  var tx = eye[0] - center[0]
  var ty = eye[1] - center[1]
  var tz = eye[2] - center[2]
  var tl = len3(tx, ty, tz)
  if(tl < 1e-6) {
    return
  }
  tx /= tl
  ty /= tl
  tz /= tl

  var right = this.computedRight
  var rx = right[0]
  var ry = right[1]
  var rz = right[2]
  var ru = ux*rx + uy*ry + uz*rz
  rx -= ru * ux
  ry -= ru * uy
  rz -= ru * uz
  var rl = len3(rx, ry, rz)

  if(rl < 0.01) {
    rx = uy * tz - uz * ty
    ry = uz * tx - ux * tz
    rz = ux * ty - uy * tx
    rl = len3(rx, ry, rz)
    if(rl < 1e-6) {
      return
    }
  }
  rx /= rl
  ry /= rl
  rz /= rl

  this.up.set(t, ux, uy, uz)
  this.right.set(t, rx, ry, rz)
  this.center.set(t, center[0], center[1], center[2])
  this.radius.set(t, Math.log(tl))

  var fx = uy * rz - uz * ry
  var fy = uz * rx - ux * rz
  var fz = ux * ry - uy * rx
  var fl = len3(fx, fy, fz)
  fx /= fl
  fy /= fl
  fz /= fl

  var tu = ux*tx + uy*ty + uz*tz
  var tr = rx*tx + ry*ty + rz*tz
  var tf = fx*tx + fy*ty + fz*tz

  var phi   = Math.asin(clamp1(tu))
  var theta = Math.atan2(tf, tr)

  var angleState = this.angle._state
  var lastTheta  = angleState[angleState.length-1]
  var lastPhi    = angleState[angleState.length-2]
  lastTheta      = lastTheta % (2.0 * Math.PI)
  var dp = Math.abs(lastTheta + 2.0 * Math.PI - theta)
  var d0 = Math.abs(lastTheta - theta)
  var dn = Math.abs(lastTheta - 2.0 * Math.PI - theta)
  if(dp < d0) {
    lastTheta += 2.0 * Math.PI
  }
  if(dn < d0) {
    lastTheta -= 2.0 * Math.PI
  }

  this.angle.jump(this.angle.lastT(), lastTheta, lastPhi)
  this.angle.set(t, theta, phi)
}

function createTurntableController(options) {
  options = options || {}

  var center = options.center || [0,0,0]
  var up     = options.up     || [0,1,0]
  var right  = options.right  || findOrthoPair(up)
  var radius = options.radius || 1.0
  var theta  = options.theta  || 0.0
  var phi    = options.phi    || 0.0

  center = [].slice.call(center, 0, 3)

  up = [].slice.call(up, 0, 3)
  normalize3(up, up)

  right = [].slice.call(right, 0, 3)
  normalize3(right, right)

  if('eye' in options) {
    var eye = options.eye
    var toward = [
      eye[0]-center[0],
      eye[1]-center[1],
      eye[2]-center[2]
    ]
    cross(right, toward, up)
    if(len3(right[0], right[1], right[2]) < 1e-6) {
      right = findOrthoPair(up)
    } else {
      normalize3(right, right)
    }

    radius = len3(toward[0], toward[1], toward[2])

    var ut = dot3(up, toward) / radius
    var rt = dot3(right, toward) / radius
    phi    = Math.acos(ut)
    theta  = Math.acos(rt)
  }

  //Use logarithmic coordinates for radius
  radius = Math.log(radius)

  //Return the controller
  return new TurntableController(
    options.zoomMin,
    options.zoomMax,
    center,
    up,
    right,
    radius,
    theta,
    phi)
}

/***/ }),

/***/ 5250:
/***/ (function(module) {

"use strict";


module.exports = twoProduct

var SPLITTER = +(Math.pow(2, 27) + 1.0)

function twoProduct(a, b, result) {
  var x = a * b

  var c = SPLITTER * a
  var abig = c - a
  var ahi = c - abig
  var alo = a - ahi

  var d = SPLITTER * b
  var bbig = d - b
  var bhi = d - bbig
  var blo = b - bhi

  var err1 = x - (ahi * bhi)
  var err2 = err1 - (alo * bhi)
  var err3 = err2 - (ahi * blo)

  var y = alo * blo - err3

  if(result) {
    result[0] = y
    result[1] = x
    return result
  }

  return [ y, x ]
}

/***/ }),

/***/ 9362:
/***/ (function(module) {

"use strict";


module.exports = fastTwoSum

function fastTwoSum(a, b, result) {
	var x = a + b
	var bv = x - a
	var av = x - bv
	var br = b - bv
	var ar = a - av
	if(result) {
		result[0] = ar + br
		result[1] = x
		return result
	}
	return [ar+br, x]
}

/***/ }),

/***/ 1888:
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {

"use strict";


var bits = __webpack_require__(8828)
var dup = __webpack_require__(1338)
var Buffer = (__webpack_require__(4793)/* .Buffer */ .hp)

//Legacy pool support
if(!__webpack_require__.g.__TYPEDARRAY_POOL) {
  __webpack_require__.g.__TYPEDARRAY_POOL = {
      UINT8     : dup([32, 0])
    , UINT16    : dup([32, 0])
    , UINT32    : dup([32, 0])
    , BIGUINT64 : dup([32, 0])
    , INT8      : dup([32, 0])
    , INT16     : dup([32, 0])
    , INT32     : dup([32, 0])
    , BIGINT64  : dup([32, 0])
    , FLOAT     : dup([32, 0])
    , DOUBLE    : dup([32, 0])
    , DATA      : dup([32, 0])
    , UINT8C    : dup([32, 0])
    , BUFFER    : dup([32, 0])
  }
}

var hasUint8C = (typeof Uint8ClampedArray) !== 'undefined'
var hasBigUint64 = (typeof BigUint64Array) !== 'undefined'
var hasBigInt64 = (typeof BigInt64Array) !== 'undefined'
var POOL = __webpack_require__.g.__TYPEDARRAY_POOL

//Upgrade pool
if(!POOL.UINT8C) {
  POOL.UINT8C = dup([32, 0])
}
if(!POOL.BIGUINT64) {
  POOL.BIGUINT64 = dup([32, 0])
}
if(!POOL.BIGINT64) {
  POOL.BIGINT64 = dup([32, 0])
}
if(!POOL.BUFFER) {
  POOL.BUFFER = dup([32, 0])
}

//New technique: Only allocate from ArrayBufferView and Buffer
var DATA    = POOL.DATA
  , BUFFER  = POOL.BUFFER

exports.free = function free(array) {
  if(Buffer.isBuffer(array)) {
    BUFFER[bits.log2(array.length)].push(array)
  } else {
    if(Object.prototype.toString.call(array) !== '[object ArrayBuffer]') {
      array = array.buffer
    }
    if(!array) {
      return
    }
    var n = array.length || array.byteLength
    var log_n = bits.log2(n)|0
    DATA[log_n].push(array)
  }
}

function freeArrayBuffer(buffer) {
  if(!buffer) {
    return
  }
  var n = buffer.length || buffer.byteLength
  var log_n = bits.log2(n)
  DATA[log_n].push(buffer)
}

function freeTypedArray(array) {
  freeArrayBuffer(array.buffer)
}

exports.freeUint8 =
exports.freeUint16 =
exports.freeUint32 =
exports.freeBigUint64 =
exports.freeInt8 =
exports.freeInt16 =
exports.freeInt32 =
exports.freeBigInt64 =
exports.freeFloat32 = 
exports.freeFloat =
exports.freeFloat64 = 
exports.freeDouble = 
exports.freeUint8Clamped = 
exports.freeDataView = freeTypedArray

exports.freeArrayBuffer = freeArrayBuffer

exports.freeBuffer = function freeBuffer(array) {
  BUFFER[bits.log2(array.length)].push(array)
}

exports.malloc = function malloc(n, dtype) {
  if(dtype === undefined || dtype === 'arraybuffer') {
    return mallocArrayBuffer(n)
  } else {
    switch(dtype) {
      case 'uint8':
        return mallocUint8(n)
      case 'uint16':
        return mallocUint16(n)
      case 'uint32':
        return mallocUint32(n)
      case 'int8':
        return mallocInt8(n)
      case 'int16':
        return mallocInt16(n)
      case 'int32':
        return mallocInt32(n)
      case 'float':
      case 'float32':
        return mallocFloat(n)
      case 'double':
      case 'float64':
        return mallocDouble(n)
      case 'uint8_clamped':
        return mallocUint8Clamped(n)
      case 'bigint64':
        return mallocBigInt64(n)
      case 'biguint64':
        return mallocBigUint64(n)
      case 'buffer':
        return mallocBuffer(n)
      case 'data':
      case 'dataview':
        return mallocDataView(n)

      default:
        return null
    }
  }
  return null
}

function mallocArrayBuffer(n) {
  var n = bits.nextPow2(n)
  var log_n = bits.log2(n)
  var d = DATA[log_n]
  if(d.length > 0) {
    return d.pop()
  }
  return new ArrayBuffer(n)
}
exports.mallocArrayBuffer = mallocArrayBuffer

function mallocUint8(n) {
  return new Uint8Array(mallocArrayBuffer(n), 0, n)
}
exports.mallocUint8 = mallocUint8

function mallocUint16(n) {
  return new Uint16Array(mallocArrayBuffer(2*n), 0, n)
}
exports.mallocUint16 = mallocUint16

function mallocUint32(n) {
  return new Uint32Array(mallocArrayBuffer(4*n), 0, n)
}
exports.mallocUint32 = mallocUint32

function mallocInt8(n) {
  return new Int8Array(mallocArrayBuffer(n), 0, n)
}
exports.mallocInt8 = mallocInt8

function mallocInt16(n) {
  return new Int16Array(mallocArrayBuffer(2*n), 0, n)
}
exports.mallocInt16 = mallocInt16

function mallocInt32(n) {
  return new Int32Array(mallocArrayBuffer(4*n), 0, n)
}
exports.mallocInt32 = mallocInt32

function mallocFloat(n) {
  return new Float32Array(mallocArrayBuffer(4*n), 0, n)
}
exports.mallocFloat32 = exports.mallocFloat = mallocFloat

function mallocDouble(n) {
  return new Float64Array(mallocArrayBuffer(8*n), 0, n)
}
exports.mallocFloat64 = exports.mallocDouble = mallocDouble

function mallocUint8Clamped(n) {
  if(hasUint8C) {
    return new Uint8ClampedArray(mallocArrayBuffer(n), 0, n)
  } else {
    return mallocUint8(n)
  }
}
exports.mallocUint8Clamped = mallocUint8Clamped

function mallocBigUint64(n) {
  if(hasBigUint64) {
    return new BigUint64Array(mallocArrayBuffer(8*n), 0, n)
  } else {
    return null;
  }
}
exports.mallocBigUint64 = mallocBigUint64

function mallocBigInt64(n) {
  if (hasBigInt64) {
    return new BigInt64Array(mallocArrayBuffer(8*n), 0, n)
  } else {
    return null;
  }
}
exports.mallocBigInt64 = mallocBigInt64

function mallocDataView(n) {
  return new DataView(mallocArrayBuffer(n), 0, n)
}
exports.mallocDataView = mallocDataView

function mallocBuffer(n) {
  n = bits.nextPow2(n)
  var log_n = bits.log2(n)
  var cache = BUFFER[log_n]
  if(cache.length > 0) {
    return cache.pop()
  }
  return new Buffer(n)
}
exports.mallocBuffer = mallocBuffer

exports.clearCache = function clearCache() {
  for(var i=0; i<32; ++i) {
    POOL.UINT8[i].length = 0
    POOL.UINT16[i].length = 0
    POOL.UINT32[i].length = 0
    POOL.INT8[i].length = 0
    POOL.INT16[i].length = 0
    POOL.INT32[i].length = 0
    POOL.FLOAT[i].length = 0
    POOL.DOUBLE[i].length = 0
    POOL.BIGUINT64[i].length = 0
    POOL.BIGINT64[i].length = 0
    POOL.UINT8C[i].length = 0
    DATA[i].length = 0
    BUFFER[i].length = 0
  }
}


/***/ }),

/***/ 1755:
/***/ (function(module) {

"use strict";
 "use restrict";

module.exports = UnionFind;

function UnionFind(count) {
  this.roots = new Array(count);
  this.ranks = new Array(count);
  
  for(var i=0; i"
  var clsTag =  ""

  var nOPN = opnTag.length
  var nCLS = clsTag.length

  var isRecursive = (TAG_CHR[0] === CHR_super0) ||
                    (TAG_CHR[0] === CHR_sub0);

  var a = 0
  var b = -nCLS
  while (a > -1) {
    a = str.indexOf(opnTag, a)
    if(a === -1) break

    b = str.indexOf(clsTag, a + nOPN)
    if(b === -1) break

    if(b <= a) break

    for(var i = a; i < b + nCLS; ++i){
      if((i < a + nOPN) || (i >= b)) {
        map[i] = null
        str = str.substr(0, i) + " " + str.substr(i + 1)
      } else {
        if(map[i] !== null) {
          var pos = map[i].indexOf(TAG_CHR[0])
          if(pos === -1) {
            map[i] += TAG_CHR
          } else { // i.e. to handle multiple sub/super-scripts
            if(isRecursive) {
              // i.e to increase the sub/sup number
              map[i] = map[i].substr(0, pos + 1) + (1 + parseInt(map[i][pos + 1])) + map[i].substr(pos + 2)
            }
          }
        }
      }
    }

    var start = a + nOPN
    var remainingStr = str.substr(start, b - start)

    var c = remainingStr.indexOf(opnTag)
    if(c !== -1) a = c
    else a = b + nCLS
  }

  return map
}

function transformPositions(positions, options, size) {
  var align = options.textAlign || "start"
  var baseline = options.textBaseline || "alphabetic"

  var lo = [1<<30, 1<<30]
  var hi = [0,0]
  var n = positions.length
  for(var i=0; i/g, '\n') // replace 
tags with \n in the string } else { rawString = rawString.replace(/\/g, ' ') // don't accept
tags in the input and replace with space in this case } var activeStyle = "" var map = [] for(j = 0; j < rawString.length; ++j) { map[j] = activeStyle } if(styletags.bolds === true) map = parseTag(TAG_bold, CHR_bold, rawString, map) if(styletags.italics === true) map = parseTag(TAG_italic, CHR_italic, rawString, map) if(styletags.superscripts === true) map = parseTag(TAG_super, CHR_super, rawString, map) if(styletags.subscripts === true) map = parseTag(TAG_sub, CHR_sub, rawString, map) var allStyles = [] var plainText = "" for(j = 0; j < rawString.length; ++j) { if(map[j] !== null) { plainText += rawString[j] allStyles.push(map[j]) } } var allTexts = plainText.split('\n') var numberOfLines = allTexts.length var lineHeight = Math.round(lineSpacing * fontSize) var offsetX = fontSize var offsetY = fontSize * 2 var maxWidth = 0 var minHeight = numberOfLines * lineHeight + offsetY if(canvas.height < minHeight) { canvas.height = minHeight } context.fillStyle = "#000" context.fillRect(0, 0, canvas.width, canvas.height) context.fillStyle = "#fff" var i, j, xPos, yPos, zPos var nDone = 0 var buffer = "" function writeBuffer() { if(buffer !== "") { var delta = context.measureText(buffer).width context.fillText(buffer, offsetX + xPos, offsetY + yPos) xPos += delta } } function getTextFontSize() { return "" + Math.round(zPos) + "px "; } function changeStyle(oldStyle, newStyle) { var ctxFont = "" + context.font; if(styletags.subscripts === true) { var oldIndex_Sub = oldStyle.indexOf(CHR_sub0); var newIndex_Sub = newStyle.indexOf(CHR_sub0); var oldSub = (oldIndex_Sub > -1) ? parseInt(oldStyle[1 + oldIndex_Sub]) : 0; var newSub = (newIndex_Sub > -1) ? parseInt(newStyle[1 + newIndex_Sub]) : 0; if(oldSub !== newSub) { ctxFont = ctxFont.replace(getTextFontSize(), "?px ") zPos *= Math.pow(0.75, (newSub - oldSub)) ctxFont = ctxFont.replace("?px ", getTextFontSize()) } yPos += 0.25 * lineHeight * (newSub - oldSub); } if(styletags.superscripts === true) { var oldIndex_Super = oldStyle.indexOf(CHR_super0); var newIndex_Super = newStyle.indexOf(CHR_super0); var oldSuper = (oldIndex_Super > -1) ? parseInt(oldStyle[1 + oldIndex_Super]) : 0; var newSuper = (newIndex_Super > -1) ? parseInt(newStyle[1 + newIndex_Super]) : 0; if(oldSuper !== newSuper) { ctxFont = ctxFont.replace(getTextFontSize(), "?px ") zPos *= Math.pow(0.75, (newSuper - oldSuper)) ctxFont = ctxFont.replace("?px ", getTextFontSize()) } yPos -= 0.25 * lineHeight * (newSuper - oldSuper); } if(styletags.bolds === true) { var wasBold = (oldStyle.indexOf(CHR_bold) > -1) var is_Bold = (newStyle.indexOf(CHR_bold) > -1) if(!wasBold && is_Bold) { if(wasItalic) { ctxFont = ctxFont.replace("italic ", "italic bold ") } else { ctxFont = "bold " + ctxFont } } if(wasBold && !is_Bold) { ctxFont = ctxFont.replace("bold ", '') } } if(styletags.italics === true) { var wasItalic = (oldStyle.indexOf(CHR_italic) > -1) var is_Italic = (newStyle.indexOf(CHR_italic) > -1) if(!wasItalic && is_Italic) { ctxFont = "italic " + ctxFont } if(wasItalic && !is_Italic) { ctxFont = ctxFont.replace("italic ", '') } } context.font = ctxFont } for(i = 0; i < numberOfLines; ++i) { var txt = allTexts[i] + '\n' xPos = 0 yPos = i * lineHeight zPos = fontSize buffer = "" for(j = 0; j < txt.length; ++j) { var style = (j + nDone < allStyles.length) ? allStyles[j + nDone] : allStyles[allStyles.length - 1] if(activeStyle === style) { buffer += txt[j] } else { writeBuffer() buffer = txt[j] if(style !== undefined) { changeStyle(activeStyle, style) activeStyle = style } } } writeBuffer() nDone += txt.length var width = Math.round(xPos + 2 * offsetX) | 0 if(maxWidth < width) maxWidth = width } //Cut pixels from image var xCut = maxWidth var yCut = offsetY + lineHeight * numberOfLines var pixels = ndarray(context.getImageData(0, 0, xCut, yCut).data, [yCut, xCut, 4]) return pixels.pick(-1, -1, 0).transpose(1, 0) } function getContour(pixels, doSimplify) { var contour = surfaceNets(pixels, 128) if(doSimplify) { return simplify(contour.cells, contour.positions, 0.25) } return { edges: contour.cells, positions: contour.positions } } function processPixelsImpl(pixels, options, size, simplify) { //Extract contour var contour = getContour(pixels, simplify) //Apply warp to positions var positions = transformPositions(contour.positions, options, size) var edges = contour.edges var flip = "ccw" === options.orientation //Clean up the PSLG, resolve self intersections, etc. cleanPSLG(positions, edges) //If triangulate flag passed, triangulate the result if(options.polygons || options.polygon || options.polyline) { var result = toPolygonCrappy(edges, positions) var nresult = new Array(result.length) for(var i=0; i 0) size = options.size if(options.lineSpacing && options.lineSpacing > 0) lineSpacing = options.lineSpacing if(options.styletags && options.styletags.breaklines) styletags.breaklines = options.styletags.breaklines ? true : false if(options.styletags && options.styletags.bolds) styletags.bolds = options.styletags.bolds ? true : false if(options.styletags && options.styletags.italics) styletags.italics = options.styletags.italics ? true : false if(options.styletags && options.styletags.subscripts) styletags.subscripts = options.styletags.subscripts ? true : false if(options.styletags && options.styletags.superscripts) styletags.superscripts = options.styletags.superscripts ? true : false } context.font = [ options.fontStyle, options.fontVariant, options.fontWeight, size + "px", options.font ].filter(function(d) {return d}).join(" ") context.textAlign = "start" context.textBaseline = "alphabetic" context.direction = "ltr" var pixels = getPixels(canvas, context, str, size, lineSpacing, styletags) return processPixels(pixels, options, size) } /***/ }), /***/ 1538: /***/ (function(module) { // Copyright (C) 2011 Google Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. /** * @fileoverview Install a leaky WeakMap emulation on platforms that * don't provide a built-in one. * *

Assumes that an ES5 platform where, if {@code WeakMap} is * already present, then it conforms to the anticipated ES6 * specification. To run this file on an ES5 or almost ES5 * implementation where the {@code WeakMap} specification does not * quite conform, run repairES5.js first. * *

Even though WeakMapModule is not global, the linter thinks it * is, which is why it is in the overrides list below. * *

NOTE: Before using this WeakMap emulation in a non-SES * environment, see the note below about hiddenRecord. * * @author Mark S. Miller * @requires crypto, ArrayBuffer, Uint8Array, navigator, console * @overrides WeakMap, ses, Proxy * @overrides WeakMapModule */ /** * This {@code WeakMap} emulation is observably equivalent to the * ES-Harmony WeakMap, but with leakier garbage collection properties. * *

As with true WeakMaps, in this emulation, a key does not * retain maps indexed by that key and (crucially) a map does not * retain the keys it indexes. A map by itself also does not retain * the values associated with that map. * *

However, the values associated with a key in some map are * retained so long as that key is retained and those associations are * not overridden. For example, when used to support membranes, all * values exported from a given membrane will live for the lifetime * they would have had in the absence of an interposed membrane. Even * when the membrane is revoked, all objects that would have been * reachable in the absence of revocation will still be reachable, as * far as the GC can tell, even though they will no longer be relevant * to ongoing computation. * *

The API implemented here is approximately the API as implemented * in FF6.0a1 and agreed to by MarkM, Andreas Gal, and Dave Herman, * rather than the offially approved proposal page. TODO(erights): * upgrade the ecmascript WeakMap proposal page to explain this API * change and present to EcmaScript committee for their approval. * *

The first difference between the emulation here and that in * FF6.0a1 is the presence of non enumerable {@code get___, has___, * set___, and delete___} methods on WeakMap instances to represent * what would be the hidden internal properties of a primitive * implementation. Whereas the FF6.0a1 WeakMap.prototype methods * require their {@code this} to be a genuine WeakMap instance (i.e., * an object of {@code [[Class]]} "WeakMap}), since there is nothing * unforgeable about the pseudo-internal method names used here, * nothing prevents these emulated prototype methods from being * applied to non-WeakMaps with pseudo-internal methods of the same * names. * *

Another difference is that our emulated {@code * WeakMap.prototype} is not itself a WeakMap. A problem with the * current FF6.0a1 API is that WeakMap.prototype is itself a WeakMap * providing ambient mutability and an ambient communications * channel. Thus, if a WeakMap is already present and has this * problem, repairES5.js wraps it in a safe wrappper in order to * prevent access to this channel. (See * PATCH_MUTABLE_FROZEN_WEAKMAP_PROTO in repairES5.js). */ /** * If this is a full secureable ES5 platform and the ES-Harmony {@code WeakMap} is * absent, install an approximate emulation. * *

If WeakMap is present but cannot store some objects, use our approximate * emulation as a wrapper. * *

If this is almost a secureable ES5 platform, then WeakMap.js * should be run after repairES5.js. * *

See {@code WeakMap} for documentation of the garbage collection * properties of this WeakMap emulation. */ (function WeakMapModule() { "use strict"; if (typeof ses !== 'undefined' && ses.ok && !ses.ok()) { // already too broken, so give up return; } /** * In some cases (current Firefox), we must make a choice betweeen a * WeakMap which is capable of using all varieties of host objects as * keys and one which is capable of safely using proxies as keys. See * comments below about HostWeakMap and DoubleWeakMap for details. * * This function (which is a global, not exposed to guests) marks a * WeakMap as permitted to do what is necessary to index all host * objects, at the cost of making it unsafe for proxies. * * Do not apply this function to anything which is not a genuine * fresh WeakMap. */ function weakMapPermitHostObjects(map) { // identity of function used as a secret -- good enough and cheap if (map.permitHostObjects___) { map.permitHostObjects___(weakMapPermitHostObjects); } } if (typeof ses !== 'undefined') { ses.weakMapPermitHostObjects = weakMapPermitHostObjects; } // IE 11 has no Proxy but has a broken WeakMap such that we need to patch // it using DoubleWeakMap; this flag tells DoubleWeakMap so. var doubleWeakMapCheckSilentFailure = false; // Check if there is already a good-enough WeakMap implementation, and if so // exit without replacing it. if (typeof WeakMap === 'function') { var HostWeakMap = WeakMap; // There is a WeakMap -- is it good enough? if (typeof navigator !== 'undefined' && /Firefox/.test(navigator.userAgent)) { // We're now *assuming not*, because as of this writing (2013-05-06) // Firefox's WeakMaps have a miscellany of objects they won't accept, and // we don't want to make an exhaustive list, and testing for just one // will be a problem if that one is fixed alone (as they did for Event). // If there is a platform that we *can* reliably test on, here's how to // do it: // var problematic = ... ; // var testHostMap = new HostWeakMap(); // try { // testHostMap.set(problematic, 1); // Firefox 20 will throw here // if (testHostMap.get(problematic) === 1) { // return; // } // } catch (e) {} } else { // IE 11 bug: WeakMaps silently fail to store frozen objects. var testMap = new HostWeakMap(); var testObject = Object.freeze({}); testMap.set(testObject, 1); if (testMap.get(testObject) !== 1) { doubleWeakMapCheckSilentFailure = true; // Fall through to installing our WeakMap. } else { module.exports = WeakMap; return; } } } var hop = Object.prototype.hasOwnProperty; var gopn = Object.getOwnPropertyNames; var defProp = Object.defineProperty; var isExtensible = Object.isExtensible; /** * Security depends on HIDDEN_NAME being both unguessable and * undiscoverable by untrusted code. * *

Given the known weaknesses of Math.random() on existing * browsers, it does not generate unguessability we can be confident * of. * *

It is the monkey patching logic in this file that is intended * to ensure undiscoverability. The basic idea is that there are * three fundamental means of discovering properties of an object: * The for/in loop, Object.keys(), and Object.getOwnPropertyNames(), * as well as some proposed ES6 extensions that appear on our * whitelist. The first two only discover enumerable properties, and * we only use HIDDEN_NAME to name a non-enumerable property, so the * only remaining threat should be getOwnPropertyNames and some * proposed ES6 extensions that appear on our whitelist. We monkey * patch them to remove HIDDEN_NAME from the list of properties they * returns. * *

TODO(erights): On a platform with built-in Proxies, proxies * could be used to trap and thereby discover the HIDDEN_NAME, so we * need to monkey patch Proxy.create, Proxy.createFunction, etc, in * order to wrap the provided handler with the real handler which * filters out all traps using HIDDEN_NAME. * *

TODO(erights): Revisit Mike Stay's suggestion that we use an * encapsulated function at a not-necessarily-secret name, which * uses the Stiegler shared-state rights amplification pattern to * reveal the associated value only to the WeakMap in which this key * is associated with that value. Since only the key retains the * function, the function can also remember the key without causing * leakage of the key, so this doesn't violate our general gc * goals. In addition, because the name need not be a guarded * secret, we could efficiently handle cross-frame frozen keys. */ var HIDDEN_NAME_PREFIX = 'weakmap:'; var HIDDEN_NAME = HIDDEN_NAME_PREFIX + 'ident:' + Math.random() + '___'; if (typeof crypto !== 'undefined' && typeof crypto.getRandomValues === 'function' && typeof ArrayBuffer === 'function' && typeof Uint8Array === 'function') { var ab = new ArrayBuffer(25); var u8s = new Uint8Array(ab); crypto.getRandomValues(u8s); HIDDEN_NAME = HIDDEN_NAME_PREFIX + 'rand:' + Array.prototype.map.call(u8s, function(u8) { return (u8 % 36).toString(36); }).join('') + '___'; } function isNotHiddenName(name) { return !( name.substr(0, HIDDEN_NAME_PREFIX.length) == HIDDEN_NAME_PREFIX && name.substr(name.length - 3) === '___'); } /** * Monkey patch getOwnPropertyNames to avoid revealing the * HIDDEN_NAME. * *

The ES5.1 spec requires each name to appear only once, but as * of this writing, this requirement is controversial for ES6, so we * made this code robust against this case. If the resulting extra * search turns out to be expensive, we can probably relax this once * ES6 is adequately supported on all major browsers, iff no browser * versions we support at that time have relaxed this constraint * without providing built-in ES6 WeakMaps. */ defProp(Object, 'getOwnPropertyNames', { value: function fakeGetOwnPropertyNames(obj) { return gopn(obj).filter(isNotHiddenName); } }); /** * getPropertyNames is not in ES5 but it is proposed for ES6 and * does appear in our whitelist, so we need to clean it too. */ if ('getPropertyNames' in Object) { var originalGetPropertyNames = Object.getPropertyNames; defProp(Object, 'getPropertyNames', { value: function fakeGetPropertyNames(obj) { return originalGetPropertyNames(obj).filter(isNotHiddenName); } }); } /** *

To treat objects as identity-keys with reasonable efficiency * on ES5 by itself (i.e., without any object-keyed collections), we * need to add a hidden property to such key objects when we * can. This raises several issues: *

    *
  • Arranging to add this property to objects before we lose the * chance, and *
  • Hiding the existence of this new property from most * JavaScript code. *
  • Preventing certification theft, where one object is * created falsely claiming to be the key of an association * actually keyed by another object. *
  • Preventing value theft, where untrusted code with * access to a key object but not a weak map nevertheless * obtains access to the value associated with that key in that * weak map. *
* We do so by *
    *
  • Making the name of the hidden property unguessable, so "[]" * indexing, which we cannot intercept, cannot be used to access * a property without knowing the name. *
  • Making the hidden property non-enumerable, so we need not * worry about for-in loops or {@code Object.keys}, *
  • monkey patching those reflective methods that would * prevent extensions, to add this hidden property first, *
  • monkey patching those methods that would reveal this * hidden property. *
* Unfortunately, because of same-origin iframes, we cannot reliably * add this hidden property before an object becomes * non-extensible. Instead, if we encounter a non-extensible object * without a hidden record that we can detect (whether or not it has * a hidden record stored under a name secret to us), then we just * use the key object itself to represent its identity in a brute * force leaky map stored in the weak map, losing all the advantages * of weakness for these. */ function getHiddenRecord(key) { if (key !== Object(key)) { throw new TypeError('Not an object: ' + key); } var hiddenRecord = key[HIDDEN_NAME]; if (hiddenRecord && hiddenRecord.key === key) { return hiddenRecord; } if (!isExtensible(key)) { // Weak map must brute force, as explained in doc-comment above. return void 0; } // The hiddenRecord and the key point directly at each other, via // the "key" and HIDDEN_NAME properties respectively. The key // field is for quickly verifying that this hidden record is an // own property, not a hidden record from up the prototype chain. // // NOTE: Because this WeakMap emulation is meant only for systems like // SES where Object.prototype is frozen without any numeric // properties, it is ok to use an object literal for the hiddenRecord. // This has two advantages: // * It is much faster in a performance critical place // * It avoids relying on Object.create(null), which had been // problematic on Chrome 28.0.1480.0. See // https://code.google.com/p/google-caja/issues/detail?id=1687 hiddenRecord = { key: key }; // When using this WeakMap emulation on platforms where // Object.prototype might not be frozen and Object.create(null) is // reliable, use the following two commented out lines instead. // hiddenRecord = Object.create(null); // hiddenRecord.key = key; // Please contact us if you need this to work on platforms where // Object.prototype might not be frozen and // Object.create(null) might not be reliable. try { defProp(key, HIDDEN_NAME, { value: hiddenRecord, writable: false, enumerable: false, configurable: false }); return hiddenRecord; } catch (error) { // Under some circumstances, isExtensible seems to misreport whether // the HIDDEN_NAME can be defined. // The circumstances have not been isolated, but at least affect // Node.js v0.10.26 on TravisCI / Linux, but not the same version of // Node.js on OS X. return void 0; } } /** * Monkey patch operations that would make their argument * non-extensible. * *

The monkey patched versions throw a TypeError if their * argument is not an object, so it should only be done to functions * that should throw a TypeError anyway if their argument is not an * object. */ (function(){ var oldFreeze = Object.freeze; defProp(Object, 'freeze', { value: function identifyingFreeze(obj) { getHiddenRecord(obj); return oldFreeze(obj); } }); var oldSeal = Object.seal; defProp(Object, 'seal', { value: function identifyingSeal(obj) { getHiddenRecord(obj); return oldSeal(obj); } }); var oldPreventExtensions = Object.preventExtensions; defProp(Object, 'preventExtensions', { value: function identifyingPreventExtensions(obj) { getHiddenRecord(obj); return oldPreventExtensions(obj); } }); })(); function constFunc(func) { func.prototype = null; return Object.freeze(func); } var calledAsFunctionWarningDone = false; function calledAsFunctionWarning() { // Future ES6 WeakMap is currently (2013-09-10) expected to reject WeakMap() // but we used to permit it and do it ourselves, so warn only. if (!calledAsFunctionWarningDone && typeof console !== 'undefined') { calledAsFunctionWarningDone = true; console.warn('WeakMap should be invoked as new WeakMap(), not ' + 'WeakMap(). This will be an error in the future.'); } } var nextId = 0; var OurWeakMap = function() { if (!(this instanceof OurWeakMap)) { // approximate test for new ...() calledAsFunctionWarning(); } // We are currently (12/25/2012) never encountering any prematurely // non-extensible keys. var keys = []; // brute force for prematurely non-extensible keys. var values = []; // brute force for corresponding values. var id = nextId++; function get___(key, opt_default) { var index; var hiddenRecord = getHiddenRecord(key); if (hiddenRecord) { return id in hiddenRecord ? hiddenRecord[id] : opt_default; } else { index = keys.indexOf(key); return index >= 0 ? values[index] : opt_default; } } function has___(key) { var hiddenRecord = getHiddenRecord(key); if (hiddenRecord) { return id in hiddenRecord; } else { return keys.indexOf(key) >= 0; } } function set___(key, value) { var index; var hiddenRecord = getHiddenRecord(key); if (hiddenRecord) { hiddenRecord[id] = value; } else { index = keys.indexOf(key); if (index >= 0) { values[index] = value; } else { // Since some browsers preemptively terminate slow turns but // then continue computing with presumably corrupted heap // state, we here defensively get keys.length first and then // use it to update both the values and keys arrays, keeping // them in sync. index = keys.length; values[index] = value; // If we crash here, values will be one longer than keys. keys[index] = key; } } return this; } function delete___(key) { var hiddenRecord = getHiddenRecord(key); var index, lastIndex; if (hiddenRecord) { return id in hiddenRecord && delete hiddenRecord[id]; } else { index = keys.indexOf(key); if (index < 0) { return false; } // Since some browsers preemptively terminate slow turns but // then continue computing with potentially corrupted heap // state, we here defensively get keys.length first and then use // it to update both the keys and the values array, keeping // them in sync. We update the two with an order of assignments, // such that any prefix of these assignments will preserve the // key/value correspondence, either before or after the delete. // Note that this needs to work correctly when index === lastIndex. lastIndex = keys.length - 1; keys[index] = void 0; // If we crash here, there's a void 0 in the keys array, but // no operation will cause a "keys.indexOf(void 0)", since // getHiddenRecord(void 0) will always throw an error first. values[index] = values[lastIndex]; // If we crash here, values[index] cannot be found here, // because keys[index] is void 0. keys[index] = keys[lastIndex]; // If index === lastIndex and we crash here, then keys[index] // is still void 0, since the aliasing killed the previous key. keys.length = lastIndex; // If we crash here, keys will be one shorter than values. values.length = lastIndex; return true; } } return Object.create(OurWeakMap.prototype, { get___: { value: constFunc(get___) }, has___: { value: constFunc(has___) }, set___: { value: constFunc(set___) }, delete___: { value: constFunc(delete___) } }); }; OurWeakMap.prototype = Object.create(Object.prototype, { get: { /** * Return the value most recently associated with key, or * opt_default if none. */ value: function get(key, opt_default) { return this.get___(key, opt_default); }, writable: true, configurable: true }, has: { /** * Is there a value associated with key in this WeakMap? */ value: function has(key) { return this.has___(key); }, writable: true, configurable: true }, set: { /** * Associate value with key in this WeakMap, overwriting any * previous association if present. */ value: function set(key, value) { return this.set___(key, value); }, writable: true, configurable: true }, 'delete': { /** * Remove any association for key in this WeakMap, returning * whether there was one. * *

Note that the boolean return here does not work like the * {@code delete} operator. The {@code delete} operator returns * whether the deletion succeeds at bringing about a state in * which the deleted property is absent. The {@code delete} * operator therefore returns true if the property was already * absent, whereas this {@code delete} method returns false if * the association was already absent. */ value: function remove(key) { return this.delete___(key); }, writable: true, configurable: true } }); if (typeof HostWeakMap === 'function') { (function() { // If we got here, then the platform has a WeakMap but we are concerned // that it may refuse to store some key types. Therefore, make a map // implementation which makes use of both as possible. // In this mode we are always using double maps, so we are not proxy-safe. // This combination does not occur in any known browser, but we had best // be safe. if (doubleWeakMapCheckSilentFailure && typeof Proxy !== 'undefined') { Proxy = undefined; } function DoubleWeakMap() { if (!(this instanceof OurWeakMap)) { // approximate test for new ...() calledAsFunctionWarning(); } // Preferable, truly weak map. var hmap = new HostWeakMap(); // Our hidden-property-based pseudo-weak-map. Lazily initialized in the // 'set' implementation; thus we can avoid performing extra lookups if // we know all entries actually stored are entered in 'hmap'. var omap = undefined; // Hidden-property maps are not compatible with proxies because proxies // can observe the hidden name and either accidentally expose it or fail // to allow the hidden property to be set. Therefore, we do not allow // arbitrary WeakMaps to switch to using hidden properties, but only // those which need the ability, and unprivileged code is not allowed // to set the flag. // // (Except in doubleWeakMapCheckSilentFailure mode in which case we // disable proxies.) var enableSwitching = false; function dget(key, opt_default) { if (omap) { return hmap.has(key) ? hmap.get(key) : omap.get___(key, opt_default); } else { return hmap.get(key, opt_default); } } function dhas(key) { return hmap.has(key) || (omap ? omap.has___(key) : false); } var dset; if (doubleWeakMapCheckSilentFailure) { dset = function(key, value) { hmap.set(key, value); if (!hmap.has(key)) { if (!omap) { omap = new OurWeakMap(); } omap.set(key, value); } return this; }; } else { dset = function(key, value) { if (enableSwitching) { try { hmap.set(key, value); } catch (e) { if (!omap) { omap = new OurWeakMap(); } omap.set___(key, value); } } else { hmap.set(key, value); } return this; }; } function ddelete(key) { var result = !!hmap['delete'](key); if (omap) { return omap.delete___(key) || result; } return result; } return Object.create(OurWeakMap.prototype, { get___: { value: constFunc(dget) }, has___: { value: constFunc(dhas) }, set___: { value: constFunc(dset) }, delete___: { value: constFunc(ddelete) }, permitHostObjects___: { value: constFunc(function(token) { if (token === weakMapPermitHostObjects) { enableSwitching = true; } else { throw new Error('bogus call to permitHostObjects___'); } })} }); } DoubleWeakMap.prototype = OurWeakMap.prototype; module.exports = DoubleWeakMap; // define .constructor to hide OurWeakMap ctor Object.defineProperty(WeakMap.prototype, 'constructor', { value: WeakMap, enumerable: false, // as default .constructor is configurable: true, writable: true }); })(); } else { // There is no host WeakMap, so we must use the emulation. // Emulated WeakMaps are incompatible with native proxies (because proxies // can observe the hidden name), so we must disable Proxy usage (in // ArrayLike and Domado, currently). if (typeof Proxy !== 'undefined') { Proxy = undefined; } module.exports = OurWeakMap; } })(); /***/ }), /***/ 236: /***/ (function(module, __unused_webpack_exports, __webpack_require__) { var hiddenStore = __webpack_require__(8284); module.exports = createStore; function createStore() { var key = {}; return function (obj) { if ((typeof obj !== 'object' || obj === null) && typeof obj !== 'function' ) { throw new Error('Weakmap-shim: Key must be object') } var store = obj.valueOf(key); return store && store.identity === key ? store : hiddenStore(obj, key); }; } /***/ }), /***/ 8284: /***/ (function(module) { module.exports = hiddenStore; function hiddenStore(obj, key) { var store = { identity: key }; var valueOf = obj.valueOf; Object.defineProperty(obj, "valueOf", { value: function (value) { return value !== key ? valueOf.apply(this, arguments) : store; }, writable: true }); return store; } /***/ }), /***/ 606: /***/ (function(module, __unused_webpack_exports, __webpack_require__) { // Original - @Gozola. // https://gist.github.com/Gozala/1269991 // This is a reimplemented version (with a few bug fixes). var createStore = __webpack_require__(236); module.exports = weakMap; function weakMap() { var privates = createStore(); return { 'get': function (key, fallback) { var store = privates(key) return store.hasOwnProperty('value') ? store.value : fallback }, 'set': function (key, value) { privates(key).value = value; return this; }, 'has': function(key) { return 'value' in privates(key); }, 'delete': function (key) { return delete privates(key).value; } } } /***/ }), /***/ 3349: /***/ (function(module) { "use strict"; function CWiseOp() { return function(SS, a0, t0, p0, Y0, Y1) { var s0 = SS[0], t0p0 = t0[0], index = [0], q0 = t0p0 p0 |= 0 var i0 = 0, d0s0 = t0p0 for (i0 = 0; i0 < s0; ++i0) { { var da = a0[p0] - Y1 var db = a0[p0 + q0] - Y1 if (da >= 0 !== db >= 0) { Y0.push(index[0] + 0.5 + (0.5 * (da + db)) / (da - db)) } } p0 += d0s0 ++index[0] } } } //Generates a cwise operator function generateCWiseOp() { return CWiseOp() } var compile = generateCWiseOp function thunk(compile) { var CACHED = {} return function zeroCrossings_cwise_thunk(array0, scalar2, scalar3) { var t0 = array0.dtype, r0 = array0.order, type = [t0, r0.join()].join(), proc = CACHED[type] if (!proc) { CACHED[type] = proc = compile([t0, r0]) } return proc(array0.shape.slice(0), array0.data, array0.stride, array0.offset | 0, scalar2, scalar3) } } function createThunk(proc) { return thunk(compile.bind(undefined, proc)) } function compileCwise(user_args) { return createThunk({ funcName: user_args.funcName }) } module.exports = compileCwise({ funcName: 'zeroCrossings' }) /***/ }), /***/ 781: /***/ (function(module, __unused_webpack_exports, __webpack_require__) { "use strict"; module.exports = findZeroCrossings var core = __webpack_require__(3349) function findZeroCrossings(array, level) { var cross = [] level = +level || 0.0 core(array.hi(array.shape[0]-1), cross, level) return cross } /***/ }), /***/ 7790: /***/ (function() { /* (ignored) */ /***/ }) /******/ }); /************************************************************************/ /******/ // The module cache /******/ var __webpack_module_cache__ = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ // Check if module is in cache /******/ var cachedModule = __webpack_module_cache__[moduleId]; /******/ if (cachedModule !== undefined) { /******/ return cachedModule.exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = __webpack_module_cache__[moduleId] = { /******/ id: moduleId, /******/ loaded: false, /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ /******/ // Flag the module as loaded /******/ module.loaded = true; /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /************************************************************************/ /******/ /* webpack/runtime/global */ /******/ !function() { /******/ __webpack_require__.g = (function() { /******/ if (typeof globalThis === 'object') return globalThis; /******/ try { /******/ return this || new Function('return this')(); /******/ } catch (e) { /******/ if (typeof window === 'object') return window; /******/ } /******/ })(); /******/ }(); /******/ /******/ /* webpack/runtime/node module decorator */ /******/ !function() { /******/ __webpack_require__.nmd = function(module) { /******/ module.paths = []; /******/ if (!module.children) module.children = []; /******/ return module; /******/ }; /******/ }(); /******/ /************************************************************************/ /******/ /******/ // startup /******/ // Load entry module and return exports /******/ // This entry module is referenced by other modules so it can't be inlined /******/ var __webpack_exports__ = __webpack_require__(1964); /******/ module.exports = __webpack_exports__; /******/ /******/ })() ;





© 2015 - 2024 Weber Informatics LLC | Privacy Policy