Last active
November 4, 2015 12:16
-
-
Save darosh/4360c8ac1dcaee373113 to your computer and use it in GitHub Desktop.
2D with stacksgl
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<meta charset="UTF-8"> | |
<body style="font-family: sans-serif;"> | |
<div style="float: left;"> | |
<div style="width: 478px; height: 478px; position: relative; border: 1px solid #ccc; overflow: hidden;"> | |
<div style="background-color: rgba(255,0,0,0.5); width: 250px; height: 250px; position: absolute;"></div> | |
<div style="background-color: rgba(0,0,255,0.25); width: 250px; height: 250px; position: absolute; left: 125px; top: 125px;"></div> | |
<div style="background-color: rgba(0,0,0,0.12); width: 125px; height: 125px; position: absolute; left: 375px; top: 375px;"></div> | |
<div style="background-color: rgba(255,255,0,0.5); width: 250px; height: 250px; position: absolute; left: 125px; top: 0; border-radius: 125px;"></div> | |
<div style="position: absolute; left: 375px; bottom: 0; color: rgba(0, 0, 0, 0.25); font-size: 36px; line-height: 28px; font-family: Arial; height: 28px;"> | |
A | |
</div> | |
</div> | |
<b>HTML+CSS</b> | |
</div> | |
<div> | |
<canvas width="478" height="478" style="border: 1px solid #ccc; display: block;"></canvas> | |
<b>WebGL</b> | |
</div> | |
<script src="stackgl.min.js"></script> | |
<script> | |
demo(); | |
function demo() { | |
var canvas = document.getElementsByTagName('canvas')[0]; | |
canvas.style.border = '1px solid #ccc'; | |
stackgl.init(canvas, [1, 1, 1, 1]); | |
var scene = []; | |
var object; | |
object = stackgl.rectangle(250, 250, [1, 0, 0, 0.5]); | |
object.t = [0, 0, 0]; | |
scene.push(object); | |
object = stackgl.rectangle(250, 250, [0, 0, 1, 0.25]); | |
object.t = [125, 125, 0]; | |
scene.push(object); | |
object = stackgl.rectangle(125, 125, [0, 0, 0, 0.12]); | |
object.t = [375, 375, 0]; | |
scene.push(object); | |
object = stackgl.circle(125, 48, [1, 1, 0, 0.5]); | |
object.t = [250, 125, 0]; | |
scene.push(object); | |
object = stackgl.text('A', 36, 'Arial', [0, 0, 0, 0.25]); | |
object.t = [375, 478 - 28, 0]; | |
scene.push(object); | |
stackgl.update(scene); | |
stackgl.dispose(); | |
} | |
</script> | |
</body> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var glslify = require('glslify'); | |
var glBuffer = require('gl-buffer'); | |
var vectorizeText = require("vectorize-text"); | |
var mat4 = { | |
create: require('gl-mat4/create'), | |
identity: require('gl-mat4/identity'), | |
translate: require('gl-mat4/translate'), | |
scale: require('gl-mat4/scale'), | |
ortho: require('gl-mat4/ortho') | |
}; | |
var gl; | |
var clear; | |
var projectionMatrix = mat4.create(); | |
var shader; | |
var matrix = mat4.create(); | |
var cache; | |
function init(canvas, bg) { | |
cache = {}; | |
clear = require('gl-clear')({color: bg}); | |
gl = require('gl-context')(canvas, {premultipliedAlpha: false, alpha: false, antialias: false}); | |
shader = glslify({ | |
frag: './shader.frag', | |
vert: './shader.vert' | |
})(gl); | |
shader.attributes.aPosition.location = 0; | |
var width = gl.drawingBufferWidth; | |
var height = gl.drawingBufferHeight; | |
clear(gl); | |
gl.viewport(0, 0, width, height); | |
mat4.ortho(projectionMatrix, 0, width, height, 0, 0, 1); | |
shader.bind(); | |
shader.uniforms.uProjection = projectionMatrix; | |
cache.square = glBuffer(gl, new Float32Array([ | |
+1.0, +1.0, | |
-0.0, +1.0, | |
+1.0, -0.0, | |
-0.0, -0.0 | |
])); | |
gl.enable(gl.BLEND); | |
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA); | |
gl.disable(gl.DEPTH_TEST); | |
} | |
function rectangle(w, h, c) { | |
return { | |
vertices: cache.square, | |
length: 4, | |
c: c, | |
s: [w, h, 1], | |
t: [0, 0, 0], | |
d: gl.TRIANGLE_STRIP, | |
l: 4 | |
}; | |
} | |
// based on hughsk/unindex-mesh | |
function unindex2D(positions, cells, out) { | |
if (positions.positions && positions.cells) { | |
out = cells; | |
cells = positions.cells; | |
positions = positions.positions; | |
} | |
out = out || new Float32Array(cells.length * 6); | |
for (var i = 0, n = 0, l = cells.length; i < l; i += 1) { | |
out[n++] = positions[cells[i][0]][0]; | |
out[n++] = positions[cells[i][0]][1]; | |
out[n++] = positions[cells[i][1]][0]; | |
out[n++] = positions[cells[i][1]][1]; | |
out[n++] = positions[cells[i][2]][0]; | |
out[n++] = positions[cells[i][2]][1]; | |
} | |
return out; | |
} | |
function circle(r, s, c) { | |
if (!cache[s]) { | |
var e = s + 2; | |
var fan = new Float32Array(e * 2); | |
var pi2 = 2 * Math.PI; | |
var j = 0; | |
fan[j++] = 0; | |
fan[j++] = 0; | |
for (var i = 0; i <= e; i++) { | |
fan[j++] = Math.cos(i * pi2 / s); | |
fan[j++] = Math.sin(i * pi2 / s); | |
} | |
cache[s] = glBuffer(gl, fan); | |
} | |
return { | |
c: c, | |
s: [r, r, 0], | |
t: [0, 0, 0], | |
vertices: cache[s], | |
d: gl.TRIANGLE_FAN, | |
l: s + 2 | |
}; | |
} | |
function text(text, s, font, c) { | |
if (!cache[text + font]) { | |
var geo = vectorizeText(text, { | |
font: font, | |
triangles: true, | |
orientation: 'ccw', | |
textAlign: 'start', | |
textBaseline: 'top' | |
}); | |
cache[text + font] = glBuffer(gl, unindex2D(geo)); | |
} | |
return { | |
c: c, | |
t: [0, 0, 0], | |
s: [s, s, 0], | |
vertices: cache[text + font], | |
d: gl.TRIANGLES, | |
l: cache[text + font].length / 2 / 4 | |
} | |
} | |
function update(objects) { | |
clear(gl); | |
for (var i = 0; i < objects.length; i++) { | |
var o = objects[i]; | |
mat4.identity(matrix); | |
mat4.translate(matrix, matrix, o.t); | |
mat4.scale(matrix, matrix, o.s); | |
shader.uniforms.uModelView = matrix; | |
shader.uniforms.uModelColor = o.c; | |
o.vertices.bind(); | |
shader.attributes.aPosition.pointer(); | |
gl.drawArrays(o.d, 0, o.l); | |
} | |
} | |
function dispose() { | |
Object.keys(cache).forEach(function (k) { | |
cache[k].unbind(); | |
cache[k].dispose(); | |
delete cache[k]; | |
}); | |
shader.dispose(); | |
} | |
window.stackgl = { | |
init: init, | |
update: update, | |
dispose: dispose, | |
rectangle: rectangle, | |
circle: circle, | |
text: text, | |
version: '0.0.12' | |
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"name": "stackgl-test", | |
"version": "0.0.8", | |
"private": true, | |
"scripts": { | |
"start": "wzrd index.js:stackgl.min.js", | |
"build": "browserify index.js | uglifyjs -cm > stackgl.min.js", | |
"debug": "browserify index.js > stackgl.js" | |
}, | |
"browserify": { | |
"transform": [ | |
"glslify" | |
] | |
}, | |
"dependencies": { | |
"gl-buffer": "^2.1.2", | |
"gl-clear": "^2.0.0", | |
"gl-context": "^0.1.1", | |
"gl-mat4": "^1.1.4", | |
"glslify": "^1.6.0", | |
"vectorize-text": "^3.0.2" | |
}, | |
"devDependencies": { | |
"browserify": "^8.0.3", | |
"uglify-js": "^2.4.16", | |
"wzrd": "^1.1.0" | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module.exports = function (width, height, radius, cornerSlices) { | |
var p = []; | |
p.push(radius, 0); | |
p.push(width - radius, 0); | |
p.push(width - radius, radius); | |
p.push(radius, 0); | |
p.push(width - radius, radius); | |
p.push(radius, radius); | |
p.push(radius, radius); | |
p.push(width - radius, radius); | |
p.push(width - radius, height - radius); | |
p.push(radius, radius); | |
p.push(width - radius, height - radius); | |
p.push(radius, height - radius); | |
return new Float32Array(p); | |
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
precision mediump float; | |
uniform vec4 uModelColor; | |
void main() { | |
gl_FragColor = uModelColor; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
precision mediump float; | |
attribute vec2 aPosition; | |
uniform mat4 uModelView; | |
uniform mat4 uProjection; | |
void main() { | |
gl_Position = uProjection * uModelView * vec4(aPosition, 0.0, 1.0); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ | |
var round = require("./rounded-rectangle"); | |
var glslify = require("glslify"); | |
var glBuffer = require("gl-buffer"); | |
var vectorizeText = require("vectorize-text"); | |
var mat4 = { | |
create: require("gl-mat4/create"), | |
identity: require("gl-mat4/identity"), | |
translate: require("gl-mat4/translate"), | |
scale: require("gl-mat4/scale"), | |
ortho: require("gl-mat4/ortho") | |
}; | |
var gl; | |
var clear; | |
var projectionMatrix = mat4.create(); | |
var shader; | |
var matrix = mat4.create(); | |
var cache; | |
function init(canvas, bg) { | |
cache = {}; | |
clear = require("gl-clear")({ | |
color: bg | |
}); | |
gl = require("gl-context")(canvas, { | |
premultipliedAlpha: false, | |
alpha: false, | |
antialias: false | |
}); | |
gl.linkProgram(gl.createProgram()); | |
shader = require("glslify/adapter.js")("\n#define GLSLIFY 1\n\nprecision mediump float;\nattribute vec2 aPosition;\nuniform mat4 uModelView;\nuniform mat4 uProjection;\nvoid main() {\n gl_Position = uProjection * uModelView * vec4(aPosition, 0.0, 1.0);\n}", "\n#define GLSLIFY 1\n\nprecision mediump float;\nuniform vec4 uModelColor;\nvoid main() {\n gl_FragColor = uModelColor;\n}", [{"name":"uModelView","type":"mat4"},{"name":"uProjection","type":"mat4"},{"name":"uModelColor","type":"vec4"}], [{"name":"aPosition","type":"vec2"}])(gl); | |
shader.attributes.aPosition.location = 0; | |
var width = gl.drawingBufferWidth; | |
var height = gl.drawingBufferHeight; | |
clear(gl); | |
gl.viewport(0, 0, width, height); | |
mat4.ortho(projectionMatrix, 0, width, height, 0, 0, 1); | |
shader.bind(); | |
shader.uniforms.uProjection = projectionMatrix; | |
cache.square = glBuffer(gl, new Float32Array([+1, +1, -0, +1, +1, -0, -0, -0])); | |
gl.enable(gl.BLEND); | |
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA); | |
gl.disable(gl.DEPTH_TEST); | |
} | |
function rectangle(w, h, c) { | |
return { | |
vertices: cache.square, | |
length: 4, | |
c: c, | |
s: [w, h, 1], | |
t: [0, 0, 0], | |
d: gl.TRIANGLE_STRIP, | |
l: 4 | |
}; | |
} | |
function unindex2D(positions, cells, out) { | |
if (positions.positions && positions.cells) { | |
out = cells; | |
cells = positions.cells; | |
positions = positions.positions; | |
} | |
out = out || new Float32Array(cells.length * 6); | |
for (var i = 0, n = 0, l = cells.length; i < l; i += 1) { | |
out[n++] = positions[cells[i][0]][0]; | |
out[n++] = positions[cells[i][0]][1]; | |
out[n++] = positions[cells[i][1]][0]; | |
out[n++] = positions[cells[i][1]][1]; | |
out[n++] = positions[cells[i][2]][0]; | |
out[n++] = positions[cells[i][2]][1]; | |
} | |
return out; | |
} | |
function circle(r, s, c) { | |
if (!cache[s]) { | |
var e = s + 2; | |
var fan = new Float32Array(e * 2); | |
var pi2 = 2 * Math.PI; | |
var j = 0; | |
fan[j++] = 0; | |
fan[j++] = 0; | |
for (var i = 0; i <= e; i++) { | |
fan[j++] = Math.cos(i * pi2 / s); | |
fan[j++] = Math.sin(i * pi2 / s); | |
} | |
cache[s] = glBuffer(gl, fan); | |
} | |
return { | |
c: c, | |
s: [r, r, 0], | |
t: [0, 0, 0], | |
vertices: cache[s], | |
d: gl.TRIANGLE_FAN, | |
l: s + 2 | |
}; | |
} | |
function rounded(w, h, r, s, c) { | |
if (!cache[w + "," + h + "," + r]) { | |
cache[w + "," + h + "," + r] = glBuffer(gl, round(w, h, r, s)); | |
} | |
return { | |
c: c, | |
s: [1, 1, 0], | |
t: [0, 0, 0], | |
vertices: cache[w + "," + h + "," + r], | |
d: gl.TRIANGLES | |
}; | |
} | |
function text(text, s, font, c) { | |
if (!cache[text + font]) { | |
var geo = vectorizeText(text, { | |
font: font, | |
triangles: true, | |
orientation: "ccw", | |
textAlign: "start", | |
textBaseline: "top" | |
}); | |
cache[text + font] = glBuffer(gl, unindex2D(geo)); | |
} | |
return { | |
c: c, | |
t: [0, 0, 0], | |
s: [s, s, 0], | |
vertices: cache[text + font], | |
d: gl.TRIANGLES, | |
l: cache[text + font].length / 2 / 4 | |
}; | |
} | |
function update(objects) { | |
clear(gl); | |
for (var i = 0; i < objects.length; i++) { | |
var o = objects[i]; | |
mat4.identity(matrix); | |
mat4.translate(matrix, matrix, o.t); | |
mat4.scale(matrix, matrix, o.s); | |
shader.uniforms.uModelView = matrix; | |
shader.uniforms.uModelColor = o.c; | |
o.vertices.bind(); | |
shader.attributes.aPosition.pointer(); | |
gl.getVertexAttrib(1, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING); | |
gl.drawArrays(o.d, 0, o.l); | |
} | |
} | |
function dispose() { | |
Object.keys(cache).forEach(function(k) { | |
cache[k].unbind(); | |
cache[k].dispose(); | |
delete cache[k]; | |
}); | |
shader.dispose(); | |
} | |
window.stackgl = { | |
init: init, | |
update: update, | |
dispose: dispose, | |
rectangle: rectangle, | |
circle: circle, | |
rounded: rounded, | |
text: text, | |
version: "0.0.9" | |
}; | |
},{"./rounded-rectangle":157,"gl-buffer":6,"gl-clear":19,"gl-context":20,"gl-mat4/create":22,"gl-mat4/identity":23,"gl-mat4/ortho":24,"gl-mat4/scale":25,"gl-mat4/translate":26,"glslify":28,"glslify/adapter.js":27,"vectorize-text":34}],2:[function(require,module,exports){ | |
(function (global){ | |
/*! | |
* The buffer module from node.js, for the browser. | |
* | |
* @author Feross Aboukhadijeh <[email protected]> <http://feross.org> | |
* @license MIT | |
*/ | |
/* eslint-disable no-proto */ | |
var base64 = require('base64-js') | |
var ieee754 = require('ieee754') | |
var isArray = require('is-array') | |
exports.Buffer = Buffer | |
exports.SlowBuffer = SlowBuffer | |
exports.INSPECT_MAX_BYTES = 50 | |
Buffer.poolSize = 8192 // not used by this implementation | |
var rootParent = {} | |
/** | |
* If `Buffer.TYPED_ARRAY_SUPPORT`: | |
* === true Use Uint8Array implementation (fastest) | |
* === false Use 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+. | |
* | |
* Due to various browser bugs, sometimes the Object implementation will be used even | |
* when the browser supports typed arrays. | |
* | |
* Note: | |
* | |
* - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances, | |
* See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438. | |
* | |
* - Safari 5-7 lacks support for changing the `Object.prototype.constructor` property | |
* on objects. | |
* | |
* - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function. | |
* | |
* - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of | |
* incorrect length in some situations. | |
* We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they | |
* get the Object implementation, which is slower but behaves correctly. | |
*/ | |
Buffer.TYPED_ARRAY_SUPPORT = global.TYPED_ARRAY_SUPPORT !== undefined | |
? global.TYPED_ARRAY_SUPPORT | |
: typedArraySupport() | |
function typedArraySupport () { | |
function Bar () {} | |
try { | |
var arr = new Uint8Array(1) | |
arr.foo = function () { return 42 } | |
arr.constructor = Bar | |
return arr.foo() === 42 && // typed array instances can be augmented | |
arr.constructor === Bar && // constructor can be set | |
typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray` | |
arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray` | |
} catch (e) { | |
return false | |
} | |
} | |
function kMaxLength () { | |
return Buffer.TYPED_ARRAY_SUPPORT | |
? 0x7fffffff | |
: 0x3fffffff | |
} | |
/** | |
* Class: Buffer | |
* ============= | |
* | |
* The Buffer constructor returns instances of `Uint8Array` that are augmented | |
* with function properties for all the node `Buffer` API functions. We use | |
* `Uint8Array` so that square bracket notation works as expected -- it returns | |
* a single octet. | |
* | |
* By augmenting the instances, we can avoid modifying the `Uint8Array` | |
* prototype. | |
*/ | |
function Buffer (arg) { | |
if (!(this instanceof Buffer)) { | |
// Avoid going through an ArgumentsAdaptorTrampoline in the common case. | |
if (arguments.length > 1) return new Buffer(arg, arguments[1]) | |
return new Buffer(arg) | |
} | |
this.length = 0 | |
this.parent = undefined | |
// Common case. | |
if (typeof arg === 'number') { | |
return fromNumber(this, arg) | |
} | |
// Slightly less common case. | |
if (typeof arg === 'string') { | |
return fromString(this, arg, arguments.length > 1 ? arguments[1] : 'utf8') | |
} | |
// Unusual. | |
return fromObject(this, arg) | |
} | |
function fromNumber (that, length) { | |
that = allocate(that, length < 0 ? 0 : checked(length) | 0) | |
if (!Buffer.TYPED_ARRAY_SUPPORT) { | |
for (var i = 0; i < length; i++) { | |
that[i] = 0 | |
} | |
} | |
return that | |
} | |
function fromString (that, string, encoding) { | |
if (typeof encoding !== 'string' || encoding === '') encoding = 'utf8' | |
// Assumption: byteLength() return value is always < kMaxLength. | |
var length = byteLength(string, encoding) | 0 | |
that = allocate(that, length) | |
that.write(string, encoding) | |
return that | |
} | |
function fromObject (that, object) { | |
if (Buffer.isBuffer(object)) return fromBuffer(that, object) | |
if (isArray(object)) return fromArray(that, object) | |
if (object == null) { | |
throw new TypeError('must start with number, buffer, array or string') | |
} | |
if (typeof ArrayBuffer !== 'undefined') { | |
if (object.buffer instanceof ArrayBuffer) { | |
return fromTypedArray(that, object) | |
} | |
if (object instanceof ArrayBuffer) { | |
return fromArrayBuffer(that, object) | |
} | |
} | |
if (object.length) return fromArrayLike(that, object) | |
return fromJsonObject(that, object) | |
} | |
function fromBuffer (that, buffer) { | |
var length = checked(buffer.length) | 0 | |
that = allocate(that, length) | |
buffer.copy(that, 0, 0, length) | |
return that | |
} | |
function fromArray (that, array) { | |
var length = checked(array.length) | 0 | |
that = allocate(that, length) | |
for (var i = 0; i < length; i += 1) { | |
that[i] = array[i] & 255 | |
} | |
return that | |
} | |
// Duplicate of fromArray() to keep fromArray() monomorphic. | |
function fromTypedArray (that, array) { | |
var length = checked(array.length) | 0 | |
that = allocate(that, length) | |
// Truncating the elements is probably not what people expect from typed | |
// arrays with BYTES_PER_ELEMENT > 1 but it's compatible with the behavior | |
// of the old Buffer constructor. | |
for (var i = 0; i < length; i += 1) { | |
that[i] = array[i] & 255 | |
} | |
return that | |
} | |
function fromArrayBuffer (that, array) { | |
if (Buffer.TYPED_ARRAY_SUPPORT) { | |
// Return an augmented `Uint8Array` instance, for best performance | |
array.byteLength | |
that = Buffer._augment(new Uint8Array(array)) | |
} else { | |
// Fallback: Return an object instance of the Buffer class | |
that = fromTypedArray(that, new Uint8Array(array)) | |
} | |
return that | |
} | |
function fromArrayLike (that, array) { | |
var length = checked(array.length) | 0 | |
that = allocate(that, length) | |
for (var i = 0; i < length; i += 1) { | |
that[i] = array[i] & 255 | |
} | |
return that | |
} | |
// Deserialize { type: 'Buffer', data: [1,2,3,...] } into a Buffer object. | |
// Returns a zero-length buffer for inputs that don't conform to the spec. | |
function fromJsonObject (that, object) { | |
var array | |
var length = 0 | |
if (object.type === 'Buffer' && isArray(object.data)) { | |
array = object.data | |
length = checked(array.length) | 0 | |
} | |
that = allocate(that, length) | |
for (var i = 0; i < length; i += 1) { | |
that[i] = array[i] & 255 | |
} | |
return that | |
} | |
if (Buffer.TYPED_ARRAY_SUPPORT) { | |
Buffer.prototype.__proto__ = Uint8Array.prototype | |
Buffer.__proto__ = Uint8Array | |
} | |
function allocate (that, length) { | |
if (Buffer.TYPED_ARRAY_SUPPORT) { | |
// Return an augmented `Uint8Array` instance, for best performance | |
that = Buffer._augment(new Uint8Array(length)) | |
that.__proto__ = Buffer.prototype | |
} else { | |
// Fallback: Return an object instance of the Buffer class | |
that.length = length | |
that._isBuffer = true | |
} | |
var fromPool = length !== 0 && length <= Buffer.poolSize >>> 1 | |
if (fromPool) that.parent = rootParent | |
return that | |
} | |
function checked (length) { | |
// Note: cannot use `length < kMaxLength` here because that fails when | |
// length is NaN (which is otherwise coerced to zero.) | |
if (length >= kMaxLength()) { | |
throw new RangeError('Attempt to allocate Buffer larger than maximum ' + | |
'size: 0x' + kMaxLength().toString(16) + ' bytes') | |
} | |
return length | 0 | |
} | |
function SlowBuffer (subject, encoding) { | |
if (!(this instanceof SlowBuffer)) return new SlowBuffer(subject, encoding) | |
var buf = new Buffer(subject, encoding) | |
delete buf.parent | |
return buf | |
} | |
Buffer.isBuffer = function isBuffer (b) { | |
return !!(b != null && b._isBuffer) | |
} | |
Buffer.compare = function compare (a, b) { | |
if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) { | |
throw new TypeError('Arguments must be Buffers') | |
} | |
if (a === b) return 0 | |
var x = a.length | |
var y = b.length | |
var i = 0 | |
var len = Math.min(x, y) | |
while (i < len) { | |
if (a[i] !== b[i]) break | |
++i | |
} | |
if (i !== len) { | |
x = a[i] | |
y = b[i] | |
} | |
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 'binary': | |
case 'base64': | |
case 'raw': | |
case 'ucs2': | |
case 'ucs-2': | |
case 'utf16le': | |
case 'utf-16le': | |
return true | |
default: | |
return false | |
} | |
} | |
Buffer.concat = function concat (list, length) { | |
if (!isArray(list)) throw new TypeError('list argument must be an Array of Buffers.') | |
if (list.length === 0) { | |
return new Buffer(0) | |
} | |
var i | |
if (length === undefined) { | |
length = 0 | |
for (i = 0; i < list.length; i++) { | |
length += list[i].length | |
} | |
} | |
var buf = new Buffer(length) | |
var pos = 0 | |
for (i = 0; i < list.length; i++) { | |
var item = list[i] | |
item.copy(buf, pos) | |
pos += item.length | |
} | |
return buf | |
} | |
function byteLength (string, encoding) { | |
if (typeof string !== 'string') string = '' + string | |
var len = string.length | |
if (len === 0) return 0 | |
// Use a for loop to avoid recursion | |
var loweredCase = false | |
for (;;) { | |
switch (encoding) { | |
case 'ascii': | |
case 'binary': | |
// Deprecated | |
case 'raw': | |
case 'raws': | |
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 utf8ToBytes(string).length // assume utf8 | |
encoding = ('' + encoding).toLowerCase() | |
loweredCase = true | |
} | |
} | |
} | |
Buffer.byteLength = byteLength | |
// pre-set for values that may exist in the future | |
Buffer.prototype.length = undefined | |
Buffer.prototype.parent = undefined | |
function slowToString (encoding, start, end) { | |
var loweredCase = false | |
start = start | 0 | |
end = end === undefined || end === Infinity ? this.length : end | 0 | |
if (!encoding) encoding = 'utf8' | |
if (start < 0) start = 0 | |
if (end > this.length) end = this.length | |
if (end <= start) return '' | |
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 'binary': | |
return binarySlice(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 | |
} | |
} | |
} | |
Buffer.prototype.toString = function toString () { | |
var length = this.length | 0 | |
if (length === 0) return '' | |
if (arguments.length === 0) return utf8Slice(this, 0, length) | |
return slowToString.apply(this, arguments) | |
} | |
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.INSPECT_MAX_BYTES | |
if (this.length > 0) { | |
str = this.toString('hex', 0, max).match(/.{2}/g).join(' ') | |
if (this.length > max) str += ' ... ' | |
} | |
return '<Buffer ' + str + '>' | |
} | |
Buffer.prototype.compare = function compare (b) { | |
if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer') | |
if (this === b) return 0 | |
return Buffer.compare(this, b) | |
} | |
Buffer.prototype.indexOf = function indexOf (val, byteOffset) { | |
if (byteOffset > 0x7fffffff) byteOffset = 0x7fffffff | |
else if (byteOffset < -0x80000000) byteOffset = -0x80000000 | |
byteOffset >>= 0 | |
if (this.length === 0) return -1 | |
if (byteOffset >= this.length) return -1 | |
// Negative offsets start from the end of the buffer | |
if (byteOffset < 0) byteOffset = Math.max(this.length + byteOffset, 0) | |
if (typeof val === 'string') { | |
if (val.length === 0) return -1 // special case: looking for empty string always fails | |
return String.prototype.indexOf.call(this, val, byteOffset) | |
} | |
if (Buffer.isBuffer(val)) { | |
return arrayIndexOf(this, val, byteOffset) | |
} | |
if (typeof val === 'number') { | |
if (Buffer.TYPED_ARRAY_SUPPORT && Uint8Array.prototype.indexOf === 'function') { | |
return Uint8Array.prototype.indexOf.call(this, val, byteOffset) | |
} | |
return arrayIndexOf(this, [ val ], byteOffset) | |
} | |
function arrayIndexOf (arr, val, byteOffset) { | |
var foundIndex = -1 | |
for (var i = 0; byteOffset + i < arr.length; i++) { | |
if (arr[byteOffset + i] === val[foundIndex === -1 ? 0 : i - foundIndex]) { | |
if (foundIndex === -1) foundIndex = i | |
if (i - foundIndex + 1 === val.length) return byteOffset + foundIndex | |
} else { | |
foundIndex = -1 | |
} | |
} | |
return -1 | |
} | |
throw new TypeError('val must be string, number or Buffer') | |
} | |
// `get` is deprecated | |
Buffer.prototype.get = function get (offset) { | |
console.log('.get() is deprecated. Access using array indexes instead.') | |
return this.readUInt8(offset) | |
} | |
// `set` is deprecated | |
Buffer.prototype.set = function set (v, offset) { | |
console.log('.set() is deprecated. Access using array indexes instead.') | |
return this.writeUInt8(v, offset) | |
} | |
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 | |
} | |
} | |
// must be an even number of digits | |
var strLen = string.length | |
if (strLen % 2 !== 0) throw new Error('Invalid hex string') | |
if (length > strLen / 2) { | |
length = strLen / 2 | |
} | |
for (var i = 0; i < length; i++) { | |
var parsed = parseInt(string.substr(i * 2, 2), 16) | |
if (isNaN(parsed)) throw new Error('Invalid hex string') | |
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 binaryWrite (buf, string, offset, length) { | |
return asciiWrite(buf, string, 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 | |
} | |
// legacy write(string, encoding, offset, length) - remove in v0.13 | |
} else { | |
var swap = encoding | |
encoding = offset | |
offset = length | 0 | |
length = swap | |
} | |
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': | |
return asciiWrite(this, string, offset, length) | |
case 'binary': | |
return binaryWrite(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, thirdByte, fourthByte, tempCodePoint | |
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 binarySlice (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 += toHex(buf[i]) | |
} | |
return out | |
} | |
function utf16leSlice (buf, start, end) { | |
var bytes = buf.slice(start, end) | |
var res = '' | |
for (var i = 0; i < bytes.length; 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 | |
if (Buffer.TYPED_ARRAY_SUPPORT) { | |
newBuf = Buffer._augment(this.subarray(start, end)) | |
} else { | |
var sliceLen = end - start | |
newBuf = new Buffer(sliceLen, undefined) | |
for (var i = 0; i < sliceLen; i++) { | |
newBuf[i] = this[i + start] | |
} | |
} | |
if (newBuf.length) newBuf.parent = this.parent || this | |
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 = 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 = 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 = function readUInt8 (offset, noAssert) { | |
if (!noAssert) checkOffset(offset, 1, this.length) | |
return this[offset] | |
} | |
Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) { | |
if (!noAssert) checkOffset(offset, 2, this.length) | |
return this[offset] | (this[offset + 1] << 8) | |
} | |
Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) { | |
if (!noAssert) checkOffset(offset, 2, this.length) | |
return (this[offset] << 8) | this[offset + 1] | |
} | |
Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) { | |
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 = function readUInt32BE (offset, noAssert) { | |
if (!noAssert) checkOffset(offset, 4, this.length) | |
return (this[offset] * 0x1000000) + | |
((this[offset + 1] << 16) | | |
(this[offset + 2] << 8) | | |
this[offset + 3]) | |
} | |
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) { | |
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) { | |
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) { | |
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) { | |
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) { | |
if (!noAssert) checkOffset(offset, 4, this.length) | |
return (this[offset] << 24) | | |
(this[offset + 1] << 16) | | |
(this[offset + 2] << 8) | | |
(this[offset + 3]) | |
} | |
Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) { | |
if (!noAssert) checkOffset(offset, 4, this.length) | |
return ieee754.read(this, offset, true, 23, 4) | |
} | |
Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) { | |
if (!noAssert) checkOffset(offset, 4, this.length) | |
return ieee754.read(this, offset, false, 23, 4) | |
} | |
Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) { | |
if (!noAssert) checkOffset(offset, 8, this.length) | |
return ieee754.read(this, offset, true, 52, 8) | |
} | |
Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) { | |
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 must be a Buffer instance') | |
if (value > max || value < min) throw new RangeError('value is out of bounds') | |
if (offset + ext > buf.length) throw new RangeError('index out of range') | |
} | |
Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) { | |
value = +value | |
offset = offset | 0 | |
byteLength = byteLength | 0 | |
if (!noAssert) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 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 = function writeUIntBE (value, offset, byteLength, noAssert) { | |
value = +value | |
offset = offset | 0 | |
byteLength = byteLength | 0 | |
if (!noAssert) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 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 = function writeUInt8 (value, offset, noAssert) { | |
value = +value | |
offset = offset | 0 | |
if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0) | |
if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value) | |
this[offset] = (value & 0xff) | |
return offset + 1 | |
} | |
function objectWriteUInt16 (buf, value, offset, littleEndian) { | |
if (value < 0) value = 0xffff + value + 1 | |
for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; i++) { | |
buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>> | |
(littleEndian ? i : 1 - i) * 8 | |
} | |
} | |
Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) { | |
value = +value | |
offset = offset | 0 | |
if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) | |
if (Buffer.TYPED_ARRAY_SUPPORT) { | |
this[offset] = (value & 0xff) | |
this[offset + 1] = (value >>> 8) | |
} else { | |
objectWriteUInt16(this, value, offset, true) | |
} | |
return offset + 2 | |
} | |
Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) { | |
value = +value | |
offset = offset | 0 | |
if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) | |
if (Buffer.TYPED_ARRAY_SUPPORT) { | |
this[offset] = (value >>> 8) | |
this[offset + 1] = (value & 0xff) | |
} else { | |
objectWriteUInt16(this, value, offset, false) | |
} | |
return offset + 2 | |
} | |
function objectWriteUInt32 (buf, value, offset, littleEndian) { | |
if (value < 0) value = 0xffffffff + value + 1 | |
for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; i++) { | |
buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff | |
} | |
} | |
Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) { | |
value = +value | |
offset = offset | 0 | |
if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0) | |
if (Buffer.TYPED_ARRAY_SUPPORT) { | |
this[offset + 3] = (value >>> 24) | |
this[offset + 2] = (value >>> 16) | |
this[offset + 1] = (value >>> 8) | |
this[offset] = (value & 0xff) | |
} else { | |
objectWriteUInt32(this, value, offset, true) | |
} | |
return offset + 4 | |
} | |
Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) { | |
value = +value | |
offset = offset | 0 | |
if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0) | |
if (Buffer.TYPED_ARRAY_SUPPORT) { | |
this[offset] = (value >>> 24) | |
this[offset + 1] = (value >>> 16) | |
this[offset + 2] = (value >>> 8) | |
this[offset + 3] = (value & 0xff) | |
} else { | |
objectWriteUInt32(this, value, offset, false) | |
} | |
return offset + 4 | |
} | |
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 = value < 0 ? 1 : 0 | |
this[offset] = value & 0xFF | |
while (++i < byteLength && (mul *= 0x100)) { | |
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 = value < 0 ? 1 : 0 | |
this[offset + i] = value & 0xFF | |
while (--i >= 0 && (mul *= 0x100)) { | |
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 (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value) | |
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) | |
if (Buffer.TYPED_ARRAY_SUPPORT) { | |
this[offset] = (value & 0xff) | |
this[offset + 1] = (value >>> 8) | |
} else { | |
objectWriteUInt16(this, value, offset, true) | |
} | |
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) | |
if (Buffer.TYPED_ARRAY_SUPPORT) { | |
this[offset] = (value >>> 8) | |
this[offset + 1] = (value & 0xff) | |
} else { | |
objectWriteUInt16(this, value, offset, false) | |
} | |
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) | |
if (Buffer.TYPED_ARRAY_SUPPORT) { | |
this[offset] = (value & 0xff) | |
this[offset + 1] = (value >>> 8) | |
this[offset + 2] = (value >>> 16) | |
this[offset + 3] = (value >>> 24) | |
} else { | |
objectWriteUInt32(this, value, offset, true) | |
} | |
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 | |
if (Buffer.TYPED_ARRAY_SUPPORT) { | |
this[offset] = (value >>> 24) | |
this[offset + 1] = (value >>> 16) | |
this[offset + 2] = (value >>> 8) | |
this[offset + 3] = (value & 0xff) | |
} else { | |
objectWriteUInt32(this, value, offset, false) | |
} | |
return offset + 4 | |
} | |
function checkIEEE754 (buf, value, offset, ext, max, min) { | |
if (value > max || value < min) throw new RangeError('value is out of bounds') | |
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) { | |
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) { | |
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 (!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('sourceStart out of bounds') | |
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 | |
var i | |
if (this === target && start < targetStart && targetStart < end) { | |
// descending copy from end | |
for (i = len - 1; i >= 0; i--) { | |
target[i + targetStart] = this[i + start] | |
} | |
} else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) { | |
// ascending copy from start | |
for (i = 0; i < len; i++) { | |
target[i + targetStart] = this[i + start] | |
} | |
} else { | |
target._set(this.subarray(start, start + len), targetStart) | |
} | |
return len | |
} | |
// fill(value, start=0, end=buffer.length) | |
Buffer.prototype.fill = function fill (value, start, end) { | |
if (!value) value = 0 | |
if (!start) start = 0 | |
if (!end) end = this.length | |
if (end < start) throw new RangeError('end < start') | |
// Fill 0 bytes; we're done | |
if (end === start) return | |
if (this.length === 0) return | |
if (start < 0 || start >= this.length) throw new RangeError('start out of bounds') | |
if (end < 0 || end > this.length) throw new RangeError('end out of bounds') | |
var i | |
if (typeof value === 'number') { | |
for (i = start; i < end; i++) { | |
this[i] = value | |
} | |
} else { | |
var bytes = utf8ToBytes(value.toString()) | |
var len = bytes.length | |
for (i = start; i < end; i++) { | |
this[i] = bytes[i % len] | |
} | |
} | |
return this | |
} | |
/** | |
* Creates a new `ArrayBuffer` with the *copied* memory of the buffer instance. | |
* Added in Node 0.12. Only available in browsers that support ArrayBuffer. | |
*/ | |
Buffer.prototype.toArrayBuffer = function toArrayBuffer () { | |
if (typeof Uint8Array !== 'undefined') { | |
if (Buffer.TYPED_ARRAY_SUPPORT) { | |
return (new Buffer(this)).buffer | |
} else { | |
var buf = new Uint8Array(this.length) | |
for (var i = 0, len = buf.length; i < len; i += 1) { | |
buf[i] = this[i] | |
} | |
return buf.buffer | |
} | |
} else { | |
throw new TypeError('Buffer.toArrayBuffer not supported in this browser') | |
} | |
} | |
// HELPER FUNCTIONS | |
// ================ | |
var BP = Buffer.prototype | |
/** | |
* Augment a Uint8Array *instance* (not the Uint8Array class!) with Buffer methods | |
*/ | |
Buffer._augment = function _augment (arr) { | |
arr.constructor = Buffer | |
arr._isBuffer = true | |
// save reference to original Uint8Array set method before overwriting | |
arr._set = arr.set | |
// deprecated | |
arr.get = BP.get | |
arr.set = BP.set | |
arr.write = BP.write | |
arr.toString = BP.toString | |
arr.toLocaleString = BP.toString | |
arr.toJSON = BP.toJSON | |
arr.equals = BP.equals | |
arr.compare = BP.compare | |
arr.indexOf = BP.indexOf | |
arr.copy = BP.copy | |
arr.slice = BP.slice | |
arr.readUIntLE = BP.readUIntLE | |
arr.readUIntBE = BP.readUIntBE | |
arr.readUInt8 = BP.readUInt8 | |
arr.readUInt16LE = BP.readUInt16LE | |
arr.readUInt16BE = BP.readUInt16BE | |
arr.readUInt32LE = BP.readUInt32LE | |
arr.readUInt32BE = BP.readUInt32BE | |
arr.readIntLE = BP.readIntLE | |
arr.readIntBE = BP.readIntBE | |
arr.readInt8 = BP.readInt8 | |
arr.readInt16LE = BP.readInt16LE | |
arr.readInt16BE = BP.readInt16BE | |
arr.readInt32LE = BP.readInt32LE | |
arr.readInt32BE = BP.readInt32BE | |
arr.readFloatLE = BP.readFloatLE | |
arr.readFloatBE = BP.readFloatBE | |
arr.readDoubleLE = BP.readDoubleLE | |
arr.readDoubleBE = BP.readDoubleBE | |
arr.writeUInt8 = BP.writeUInt8 | |
arr.writeUIntLE = BP.writeUIntLE | |
arr.writeUIntBE = BP.writeUIntBE | |
arr.writeUInt16LE = BP.writeUInt16LE | |
arr.writeUInt16BE = BP.writeUInt16BE | |
arr.writeUInt32LE = BP.writeUInt32LE | |
arr.writeUInt32BE = BP.writeUInt32BE | |
arr.writeIntLE = BP.writeIntLE | |
arr.writeIntBE = BP.writeIntBE | |
arr.writeInt8 = BP.writeInt8 | |
arr.writeInt16LE = BP.writeInt16LE | |
arr.writeInt16BE = BP.writeInt16BE | |
arr.writeInt32LE = BP.writeInt32LE | |
arr.writeInt32BE = BP.writeInt32BE | |
arr.writeFloatLE = BP.writeFloatLE | |
arr.writeFloatBE = BP.writeFloatBE | |
arr.writeDoubleLE = BP.writeDoubleLE | |
arr.writeDoubleBE = BP.writeDoubleBE | |
arr.fill = BP.fill | |
arr.inspect = BP.inspect | |
arr.toArrayBuffer = BP.toArrayBuffer | |
return arr | |
} | |
var INVALID_BASE64_RE = /[^+\/0-9A-Za-z-_]/g | |
function base64clean (str) { | |
// Node strips out invalid characters like \n and \t from the string, base64-js does not | |
str = stringtrim(str).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 stringtrim (str) { | |
if (str.trim) return str.trim() | |
return str.replace(/^\s+|\s+$/g, '') | |
} | |
function toHex (n) { | |
if (n < 16) return '0' + n.toString(16) | |
return n.toString(16) | |
} | |
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) { | |
for (var i = 0; i < length; i++) { | |
if ((i + offset >= dst.length) || (i >= src.length)) break | |
dst[i + offset] = src[i] | |
} | |
return i | |
} | |
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) | |
},{"base64-js":3,"ieee754":4,"is-array":5}],3:[function(require,module,exports){ | |
var lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; | |
;(function (exports) { | |
'use strict'; | |
var Arr = (typeof Uint8Array !== 'undefined') | |
? Uint8Array | |
: Array | |
var PLUS = '+'.charCodeAt(0) | |
var SLASH = '/'.charCodeAt(0) | |
var NUMBER = '0'.charCodeAt(0) | |
var LOWER = 'a'.charCodeAt(0) | |
var UPPER = 'A'.charCodeAt(0) | |
var PLUS_URL_SAFE = '-'.charCodeAt(0) | |
var SLASH_URL_SAFE = '_'.charCodeAt(0) | |
function decode (elt) { | |
var code = elt.charCodeAt(0) | |
if (code === PLUS || | |
code === PLUS_URL_SAFE) | |
return 62 // '+' | |
if (code === SLASH || | |
code === SLASH_URL_SAFE) | |
return 63 // '/' | |
if (code < NUMBER) | |
return -1 //no match | |
if (code < NUMBER + 10) | |
return code - NUMBER + 26 + 26 | |
if (code < UPPER + 26) | |
return code - UPPER | |
if (code < LOWER + 26) | |
return code - LOWER + 26 | |
} | |
function b64ToByteArray (b64) { | |
var i, j, l, tmp, placeHolders, arr | |
if (b64.length % 4 > 0) { | |
throw new Error('Invalid string. Length must be a multiple of 4') | |
} | |
// the number of equal signs (place holders) | |
// if there are two placeholders, than the two characters before it | |
// represent one byte | |
// if there is only one, then the three characters before it represent 2 bytes | |
// this is just a cheap hack to not do indexOf twice | |
var len = b64.length | |
placeHolders = '=' === b64.charAt(len - 2) ? 2 : '=' === b64.charAt(len - 1) ? 1 : 0 | |
// base64 is 4/3 + up to two characters of the original data | |
arr = new Arr(b64.length * 3 / 4 - placeHolders) | |
// if there are placeholders, only get up to the last complete 4 chars | |
l = placeHolders > 0 ? b64.length - 4 : b64.length | |
var L = 0 | |
function push (v) { | |
arr[L++] = v | |
} | |
for (i = 0, j = 0; i < l; i += 4, j += 3) { | |
tmp = (decode(b64.charAt(i)) << 18) | (decode(b64.charAt(i + 1)) << 12) | (decode(b64.charAt(i + 2)) << 6) | decode(b64.charAt(i + 3)) | |
push((tmp & 0xFF0000) >> 16) | |
push((tmp & 0xFF00) >> 8) | |
push(tmp & 0xFF) | |
} | |
if (placeHolders === 2) { | |
tmp = (decode(b64.charAt(i)) << 2) | (decode(b64.charAt(i + 1)) >> 4) | |
push(tmp & 0xFF) | |
} else if (placeHolders === 1) { | |
tmp = (decode(b64.charAt(i)) << 10) | (decode(b64.charAt(i + 1)) << 4) | (decode(b64.charAt(i + 2)) >> 2) | |
push((tmp >> 8) & 0xFF) | |
push(tmp & 0xFF) | |
} | |
return arr | |
} | |
function uint8ToBase64 (uint8) { | |
var i, | |
extraBytes = uint8.length % 3, // if we have 1 byte left, pad 2 bytes | |
output = "", | |
temp, length | |
function encode (num) { | |
return lookup.charAt(num) | |
} | |
function tripletToBase64 (num) { | |
return encode(num >> 18 & 0x3F) + encode(num >> 12 & 0x3F) + encode(num >> 6 & 0x3F) + encode(num & 0x3F) | |
} | |
// go through the array every three bytes, we'll deal with trailing stuff later | |
for (i = 0, length = uint8.length - extraBytes; i < length; i += 3) { | |
temp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2]) | |
output += tripletToBase64(temp) | |
} | |
// pad the end with zeros, but make sure to not forget the extra bytes | |
switch (extraBytes) { | |
case 1: | |
temp = uint8[uint8.length - 1] | |
output += encode(temp >> 2) | |
output += encode((temp << 4) & 0x3F) | |
output += '==' | |
break | |
case 2: | |
temp = (uint8[uint8.length - 2] << 8) + (uint8[uint8.length - 1]) | |
output += encode(temp >> 10) | |
output += encode((temp >> 4) & 0x3F) | |
output += encode((temp << 2) & 0x3F) | |
output += '=' | |
break | |
} | |
return output | |
} | |
exports.toByteArray = b64ToByteArray | |
exports.fromByteArray = uint8ToBase64 | |
}(typeof exports === 'undefined' ? (this.base64js = {}) : exports)) | |
},{}],4:[function(require,module,exports){ | |
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 | |
} | |
},{}],5:[function(require,module,exports){ | |
/** | |
* isArray | |
*/ | |
var isArray = Array.isArray; | |
/** | |
* toString | |
*/ | |
var str = Object.prototype.toString; | |
/** | |
* Whether or not the given `val` | |
* is an array. | |
* | |
* example: | |
* | |
* isArray([]); | |
* // > true | |
* isArray(arguments); | |
* // > false | |
* isArray(''); | |
* // > false | |
* | |
* @param {mixed} val | |
* @return {bool} | |
*/ | |
module.exports = isArray || function (val) { | |
return !! val && '[object Array]' == str.call(val); | |
}; | |
},{}],6:[function(require,module,exports){ | |
"use strict" | |
var pool = require("typedarray-pool") | |
var ops = require("ndarray-ops") | |
var ndarray = require("ndarray") | |
var SUPPORTED_TYPES = [ | |
"uint8", | |
"uint8_clamped", | |
"uint16", | |
"uint32", | |
"int8", | |
"int16", | |
"int32", | |
"float32" ] | |
function GLBuffer(gl, type, handle, length, usage) { | |
this.gl = gl | |
this.type = type | |
this.handle = handle | |
this.length = length | |
this.usage = usage | |
} | |
var proto = GLBuffer.prototype | |
proto.bind = function() { | |
this.gl.bindBuffer(this.type, this.handle) | |
} | |
proto.unbind = function() { | |
this.gl.bindBuffer(this.type, null) | |
} | |
proto.dispose = function() { | |
this.gl.deleteBuffer(this.handle) | |
} | |
function updateTypeArray(gl, type, len, usage, data, offset) { | |
var dataLen = data.length * data.BYTES_PER_ELEMENT | |
if(offset < 0) { | |
gl.bufferData(type, data, usage) | |
return dataLen | |
} | |
if(dataLen + offset > 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<n; ++i) { | |
res[i] = array[i] | |
} | |
return res | |
} | |
function isPacked(shape, stride) { | |
var n = 1 | |
for(var i=stride.length-1; 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 | |
},{"ndarray":12,"ndarray-ops":7,"typedarray-pool":17}],7:[function(require,module,exports){ | |
"use strict" | |
var compile = require("cwise-compiler") | |
var EmptyProc = { | |
body: "", | |
args: [], | |
thisVars: [], | |
localVars: [] | |
} | |
function fixup(x) { | |
if(!x) { | |
return EmptyProc | |
} | |
for(var i=0; i<x.args.length; ++i) { | |
var a = x.args[i] | |
if(i === 0) { | |
x.args[i] = {name: a, lvalue:true, rvalue: !!x.rvalue, count:x.count||1 } | |
} else { | |
x.args[i] = {name: a, lvalue:false, rvalue:true, count: 1} | |
} | |
} | |
if(!x.thisVars) { | |
x.thisVars = [] | |
} | |
if(!x.localVars) { | |
x.localVars = [] | |
} | |
return x | |
} | |
function pcompile(user_args) { | |
return compile({ | |
args: user_args.args, | |
pre: fixup(user_args.pre), | |
body: fixup(user_args.body), | |
post: fixup(user_args.proc), | |
funcName: user_args.funcName | |
}) | |
} | |
function makeOp(user_args) { | |
var args = [] | |
for(var i=0; i<user_args.args.length; ++i) { | |
args.push("a"+i) | |
} | |
var wrapper = new Function("P", [ | |
"return function ", user_args.funcName, "_ndarrayops(", args.join(","), ") {P(", args.join(","), ");return a0}" | |
].join("")) | |
return wrapper(pcompile(user_args)) | |
} | |
var assign_ops = { | |
add: "+", | |
sub: "-", | |
mul: "*", | |
div: "/", | |
mod: "%", | |
band: "&", | |
bor: "|", | |
bxor: "^", | |
lshift: "<<", | |
rshift: ">>", | |
rrshift: ">>>" | |
} | |
;(function(){ | |
for(var id in assign_ops) { | |
var op = assign_ops[id] | |
exports[id] = makeOp({ | |
args: ["array","array","array"], | |
body: {args:["a","b","c"], | |
body: "a=b"+op+"c"}, | |
funcName: id | |
}) | |
exports[id+"eq"] = makeOp({ | |
args: ["array","array"], | |
body: {args:["a","b"], | |
body:"a"+op+"=b"}, | |
rvalue: true, | |
funcName: id+"eq" | |
}) | |
exports[id+"s"] = makeOp({ | |
args: ["array", "array", "scalar"], | |
body: {args:["a","b","s"], | |
body:"a=b"+op+"s"}, | |
funcName: id+"s" | |
}) | |
exports[id+"seq"] = makeOp({ | |
args: ["array","scalar"], | |
body: {args:["a","s"], | |
body:"a"+op+"=s"}, | |
rvalue: true, | |
funcName: id+"seq" | |
}) | |
} | |
})(); | |
var unary_ops = { | |
not: "!", | |
bnot: "~", | |
neg: "-", | |
recip: "1.0/" | |
} | |
;(function(){ | |
for(var id in unary_ops) { | |
var op = unary_ops[id] | |
exports[id] = makeOp({ | |
args: ["array", "array"], | |
body: {args:["a","b"], | |
body:"a="+op+"b"}, | |
funcName: id | |
}) | |
exports[id+"eq"] = makeOp({ | |
args: ["array"], | |
body: {args:["a"], | |
body:"a="+op+"a"}, | |
rvalue: true, | |
count: 2, | |
funcName: id+"eq" | |
}) | |
} | |
})(); | |
var binary_ops = { | |
and: "&&", | |
or: "||", | |
eq: "===", | |
neq: "!==", | |
lt: "<", | |
gt: ">", | |
leq: "<=", | |
geq: ">=" | |
} | |
;(function() { | |
for(var id in binary_ops) { | |
var op = binary_ops[id] | |
exports[id] = makeOp({ | |
args: ["array","array","array"], | |
body: {args:["a", "b", "c"], | |
body:"a=b"+op+"c"}, | |
funcName: id | |
}) | |
exports[id+"s"] = makeOp({ | |
args: ["array","array","scalar"], | |
body: {args:["a", "b", "s"], | |
body:"a=b"+op+"s"}, | |
funcName: id+"s" | |
}) | |
exports[id+"eq"] = makeOp({ | |
args: ["array", "array"], | |
body: {args:["a", "b"], | |
body:"a=a"+op+"b"}, | |
rvalue:true, | |
count:2, | |
funcName: id+"eq" | |
}) | |
exports[id+"seq"] = makeOp({ | |
args: ["array", "scalar"], | |
body: {args:["a","s"], | |
body:"a=a"+op+"s"}, | |
rvalue:true, | |
count:2, | |
funcName: id+"seq" | |
}) | |
} | |
})(); | |
var math_unary = [ | |
"abs", | |
"acos", | |
"asin", | |
"atan", | |
"ceil", | |
"cos", | |
"exp", | |
"floor", | |
"log", | |
"round", | |
"sin", | |
"sqrt", | |
"tan" | |
] | |
;(function() { | |
for(var i=0; i<math_unary.length; ++i) { | |
var f = math_unary[i] | |
exports[f] = makeOp({ | |
args: ["array", "array"], | |
pre: {args:[], body:"this_f=Math."+f, thisVars:["this_f"]}, | |
body: {args:["a","b"], body:"a=this_f(b)", thisVars:["this_f"]}, | |
funcName: f | |
}) | |
exports[f+"eq"] = makeOp({ | |
args: ["array"], | |
pre: {args:[], body:"this_f=Math."+f, thisVars:["this_f"]}, | |
body: {args: ["a"], body:"a=this_f(a)", thisVars:["this_f"]}, | |
rvalue: true, | |
count: 2, | |
funcName: f+"eq" | |
}) | |
} | |
})(); | |
var math_comm = [ | |
"max", | |
"min", | |
"atan2", | |
"pow" | |
] | |
;(function(){ | |
for(var i=0; i<math_comm.length; ++i) { | |
var f= math_comm[i] | |
exports[f] = makeOp({ | |
args:["array", "array", "array"], | |
pre: {args:[], body:"this_f=Math."+f, thisVars:["this_f"]}, | |
body: {args:["a","b","c"], body:"a=this_f(b,c)", thisVars:["this_f"]}, | |
funcName: f | |
}) | |
exports[f+"s"] = makeOp({ | |
args:["array", "array", "scalar"], | |
pre: {args:[], body:"this_f=Math."+f, thisVars:["this_f"]}, | |
body: {args:["a","b","c"], body:"a=this_f(b,c)", thisVars:["this_f"]}, | |
funcName: f+"s" | |
}) | |
exports[f+"eq"] = makeOp({ args:["array", "array"], | |
pre: {args:[], body:"this_f=Math."+f, thisVars:["this_f"]}, | |
body: {args:["a","b"], body:"a=this_f(a,b)", thisVars:["this_f"]}, | |
rvalue: true, | |
count: 2, | |
funcName: f+"eq" | |
}) | |
exports[f+"seq"] = makeOp({ args:["array", "scalar"], | |
pre: {args:[], body:"this_f=Math."+f, thisVars:["this_f"]}, | |
body: {args:["a","b"], body:"a=this_f(a,b)", thisVars:["this_f"]}, | |
rvalue:true, | |
count:2, | |
funcName: f+"seq" | |
}) | |
} | |
})(); | |
var math_noncomm = [ | |
"atan2", | |
"pow" | |
] | |
;(function(){ | |
for(var i=0; i<math_noncomm.length; ++i) { | |
var f= math_noncomm[i] | |
exports[f+"op"] = makeOp({ | |
args:["array", "array", "array"], | |
pre: {args:[], body:"this_f=Math."+f, thisVars:["this_f"]}, | |
body: {args:["a","b","c"], body:"a=this_f(c,b)", thisVars:["this_f"]}, | |
funcName: f+"op" | |
}) | |
exports[f+"ops"] = makeOp({ | |
args:["array", "array", "scalar"], | |
pre: {args:[], body:"this_f=Math."+f, thisVars:["this_f"]}, | |
body: {args:["a","b","c"], body:"a=this_f(c,b)", thisVars:["this_f"]}, | |
funcName: f+"ops" | |
}) | |
exports[f+"opeq"] = makeOp({ args:["array", "array"], | |
pre: {args:[], body:"this_f=Math."+f, thisVars:["this_f"]}, | |
body: {args:["a","b"], body:"a=this_f(b,a)", thisVars:["this_f"]}, | |
rvalue: true, | |
count: 2, | |
funcName: f+"opeq" | |
}) | |
exports[f+"opseq"] = makeOp({ args:["array", "scalar"], | |
pre: {args:[], body:"this_f=Math."+f, thisVars:["this_f"]}, | |
body: {args:["a","b"], body:"a=this_f(b,a)", thisVars:["this_f"]}, | |
rvalue:true, | |
count:2, | |
funcName: f+"opseq" | |
}) | |
} | |
})(); | |
exports.any = compile({ | |
args:["array"], | |
pre: EmptyProc, | |
body: {args:[{name:"a", lvalue:false, rvalue:true, count:1}], body: "if(a){return true}", localVars: [], thisVars: []}, | |
post: {args:[], localVars:[], thisVars:[], body:"return false"}, | |
funcName: "any" | |
}) | |
exports.all = compile({ | |
args:["array"], | |
pre: EmptyProc, | |
body: {args:[{name:"x", lvalue:false, rvalue:true, count:1}], body: "if(!x){return false}", localVars: [], thisVars: []}, | |
post: {args:[], localVars:[], thisVars:[], body:"return true"}, | |
funcName: "all" | |
}) | |
exports.sum = compile({ | |
args:["array"], | |
pre: {args:[], localVars:[], thisVars:["this_s"], body:"this_s=0"}, | |
body: {args:[{name:"a", lvalue:false, rvalue:true, count:1}], body: "this_s+=a", localVars: [], thisVars: ["this_s"]}, | |
post: {args:[], localVars:[], thisVars:["this_s"], body:"return this_s"}, | |
funcName: "sum" | |
}) | |
exports.prod = compile({ | |
args:["array"], | |
pre: {args:[], localVars:[], thisVars:["this_s"], body:"this_s=1"}, | |
body: {args:[{name:"a", lvalue:false, rvalue:true, count:1}], body: "this_s*=a", localVars: [], thisVars: ["this_s"]}, | |
post: {args:[], localVars:[], thisVars:["this_s"], body:"return this_s"}, | |
funcName: "prod" | |
}) | |
exports.norm2squared = compile({ | |
args:["array"], | |
pre: {args:[], localVars:[], thisVars:["this_s"], body:"this_s=0"}, | |
body: {args:[{name:"a", lvalue:false, rvalue:true, count:2}], body: "this_s+=a*a", localVars: [], thisVars: ["this_s"]}, | |
post: {args:[], localVars:[], thisVars:["this_s"], body:"return this_s"}, | |
funcName: "norm2squared" | |
}) | |
exports.norm2 = compile({ | |
args:["array"], | |
pre: {args:[], localVars:[], thisVars:["this_s"], body:"this_s=0"}, | |
body: {args:[{name:"a", lvalue:false, rvalue:true, count:2}], body: "this_s+=a*a", localVars: [], thisVars: ["this_s"]}, | |
post: {args:[], localVars:[], thisVars:["this_s"], body:"return Math.sqrt(this_s)"}, | |
funcName: "norm2" | |
}) | |
exports.norminf = compile({ | |
args:["array"], | |
pre: {args:[], localVars:[], thisVars:["this_s"], body:"this_s=0"}, | |
body: {args:[{name:"a", lvalue:false, rvalue:true, count:4}], body:"if(-a>this_s){this_s=-a}else if(a>this_s){this_s=a}", localVars: [], thisVars: ["this_s"]}, | |
post: {args:[], localVars:[], thisVars:["this_s"], body:"return this_s"}, | |
funcName: "norminf" | |
}) | |
exports.norm1 = compile({ | |
args:["array"], | |
pre: {args:[], localVars:[], thisVars:["this_s"], body:"this_s=0"}, | |
body: {args:[{name:"a", lvalue:false, rvalue:true, count:3}], body: "this_s+=a<0?-a:a", localVars: [], thisVars: ["this_s"]}, | |
post: {args:[], localVars:[], thisVars:["this_s"], body:"return this_s"}, | |
funcName: "norm1" | |
}) | |
exports.sup = compile({ | |
args: [ "array" ], | |
pre: | |
{ body: "this_h=-Infinity", | |
args: [], | |
thisVars: [ "this_h" ], | |
localVars: [] }, | |
body: | |
{ body: "if(_inline_1_arg0_>this_h)this_h=_inline_1_arg0_", | |
args: [{"name":"_inline_1_arg0_","lvalue":false,"rvalue":true,"count":2} ], | |
thisVars: [ "this_h" ], | |
localVars: [] }, | |
post: | |
{ body: "return this_h", | |
args: [], | |
thisVars: [ "this_h" ], | |
localVars: [] } | |
}) | |
exports.inf = compile({ | |
args: [ "array" ], | |
pre: | |
{ body: "this_h=Infinity", | |
args: [], | |
thisVars: [ "this_h" ], | |
localVars: [] }, | |
body: | |
{ body: "if(_inline_1_arg0_<this_h)this_h=_inline_1_arg0_", | |
args: [{"name":"_inline_1_arg0_","lvalue":false,"rvalue":true,"count":2} ], | |
thisVars: [ "this_h" ], | |
localVars: [] }, | |
post: | |
{ body: "return this_h", | |
args: [], | |
thisVars: [ "this_h" ], | |
localVars: [] } | |
}) | |
exports.argmin = compile({ | |
args:["index","array","shape"], | |
pre:{ | |
body:"{this_v=Infinity;this_i=_inline_0_arg2_.slice(0)}", | |
args:[ | |
{name:"_inline_0_arg0_",lvalue:false,rvalue:false,count:0}, | |
{name:"_inline_0_arg1_",lvalue:false,rvalue:false,count:0}, | |
{name:"_inline_0_arg2_",lvalue:false,rvalue:true,count:1} | |
], | |
thisVars:["this_i","this_v"], | |
localVars:[]}, | |
body:{ | |
body:"{if(_inline_1_arg1_<this_v){this_v=_inline_1_arg1_;for(var _inline_1_k=0;_inline_1_k<_inline_1_arg0_.length;++_inline_1_k){this_i[_inline_1_k]=_inline_1_arg0_[_inline_1_k]}}}", | |
args:[ | |
{name:"_inline_1_arg0_",lvalue:false,rvalue:true,count:2}, | |
{name:"_inline_1_arg1_",lvalue:false,rvalue:true,count:2}], | |
thisVars:["this_i","this_v"], | |
localVars:["_inline_1_k"]}, | |
post:{ | |
body:"{return this_i}", | |
args:[], | |
thisVars:["this_i"], | |
localVars:[]} | |
}) | |
exports.argmax = compile({ | |
args:["index","array","shape"], | |
pre:{ | |
body:"{this_v=-Infinity;this_i=_inline_0_arg2_.slice(0)}", | |
args:[ | |
{name:"_inline_0_arg0_",lvalue:false,rvalue:false,count:0}, | |
{name:"_inline_0_arg1_",lvalue:false,rvalue:false,count:0}, | |
{name:"_inline_0_arg2_",lvalue:false,rvalue:true,count:1} | |
], | |
thisVars:["this_i","this_v"], | |
localVars:[]}, | |
body:{ | |
body:"{if(_inline_1_arg1_>this_v){this_v=_inline_1_arg1_;for(var _inline_1_k=0;_inline_1_k<_inline_1_arg0_.length;++_inline_1_k){this_i[_inline_1_k]=_inline_1_arg0_[_inline_1_k]}}}", | |
args:[ | |
{name:"_inline_1_arg0_",lvalue:false,rvalue:true,count:2}, | |
{name:"_inline_1_arg1_",lvalue:false,rvalue:true,count:2}], | |
thisVars:["this_i","this_v"], | |
localVars:["_inline_1_k"]}, | |
post:{ | |
body:"{return this_i}", | |
args:[], | |
thisVars:["this_i"], | |
localVars:[]} | |
}) | |
exports.random = makeOp({ | |
args: ["array"], | |
pre: {args:[], body:"this_f=Math.random", thisVars:["this_f"]}, | |
body: {args: ["a"], body:"a=this_f()", thisVars:["this_f"]}, | |
funcName: "random" | |
}) | |
exports.assign = makeOp({ | |
args:["array", "array"], | |
body: {args:["a", "b"], body:"a=b"}, | |
funcName: "assign" }) | |
exports.assigns = makeOp({ | |
args:["array", "scalar"], | |
body: {args:["a", "b"], body:"a=b"}, | |
funcName: "assigns" }) | |
exports.equals = compile({ | |
args:["array", "array"], | |
pre: EmptyProc, | |
body: {args:[{name:"x", lvalue:false, rvalue:true, count:1}, | |
{name:"y", lvalue:false, rvalue:true, count:1}], | |
body: "if(x!==y){return false}", | |
localVars: [], | |
thisVars: []}, | |
post: {args:[], localVars:[], thisVars:[], body:"return true"}, | |
funcName: "equals" | |
}) | |
},{"cwise-compiler":8}],8:[function(require,module,exports){ | |
"use strict" | |
var createThunk = require("./lib/thunk.js") | |
function Procedure() { | |
this.argTypes = [] | |
this.shimArgs = [] | |
this.arrayArgs = [] | |
this.arrayBlockIndices = [] | |
this.scalarArgs = [] | |
this.offsetArgs = [] | |
this.offsetArgIndex = [] | |
this.indexArgs = [] | |
this.shapeArgs = [] | |
this.funcName = "" | |
this.pre = null | |
this.body = null | |
this.post = null | |
this.debug = false | |
} | |
function compileCwise(user_args) { | |
//Create procedure | |
var proc = new Procedure() | |
//Parse blocks | |
proc.pre = user_args.pre | |
proc.body = user_args.body | |
proc.post = user_args.post | |
//Parse arguments | |
var proc_args = user_args.args.slice(0) | |
proc.argTypes = proc_args | |
for(var i=0; i<proc_args.length; ++i) { | |
var arg_type = proc_args[i] | |
if(arg_type === "array" || (typeof arg_type === "object" && arg_type.blockIndices)) { | |
proc.argTypes[i] = "array" | |
proc.arrayArgs.push(i) | |
proc.arrayBlockIndices.push(arg_type.blockIndices ? arg_type.blockIndices : 0) | |
proc.shimArgs.push("array" + i) | |
if(i < proc.pre.args.length && proc.pre.args[i].count>0) { | |
throw new Error("cwise: pre() block may not reference array args") | |
} | |
if(i < proc.post.args.length && proc.post.args[i].count>0) { | |
throw new Error("cwise: post() block may not reference array args") | |
} | |
} else if(arg_type === "scalar") { | |
proc.scalarArgs.push(i) | |
proc.shimArgs.push("scalar" + i) | |
} else if(arg_type === "index") { | |
proc.indexArgs.push(i) | |
if(i < proc.pre.args.length && proc.pre.args[i].count > 0) { | |
throw new Error("cwise: pre() block may not reference array index") | |
} | |
if(i < proc.body.args.length && proc.body.args[i].lvalue) { | |
throw new Error("cwise: body() block may not write to array index") | |
} | |
if(i < proc.post.args.length && proc.post.args[i].count > 0) { | |
throw new Error("cwise: post() block may not reference array index") | |
} | |
} else if(arg_type === "shape") { | |
proc.shapeArgs.push(i) | |
if(i < proc.pre.args.length && proc.pre.args[i].lvalue) { | |
throw new Error("cwise: pre() block may not write to array shape") | |
} | |
if(i < proc.body.args.length && proc.body.args[i].lvalue) { | |
throw new Error("cwise: body() block may not write to array shape") | |
} | |
if(i < proc.post.args.length && proc.post.args[i].lvalue) { | |
throw new Error("cwise: post() block may not write to array shape") | |
} | |
} else if(typeof arg_type === "object" && arg_type.offset) { | |
proc.argTypes[i] = "offset" | |
proc.offsetArgs.push({ array: arg_type.array, offset:arg_type.offset }) | |
proc.offsetArgIndex.push(i) | |
} else { | |
throw new Error("cwise: Unknown argument type " + proc_args[i]) | |
} | |
} | |
//Make sure at least one array argument was specified | |
if(proc.arrayArgs.length <= 0) { | |
throw new Error("cwise: No array arguments specified") | |
} | |
//Make sure arguments are correct | |
if(proc.pre.args.length > proc_args.length) { | |
throw new Error("cwise: Too many arguments in pre() block") | |
} | |
if(proc.body.args.length > proc_args.length) { | |
throw new Error("cwise: Too many arguments in body() block") | |
} | |
if(proc.post.args.length > proc_args.length) { | |
throw new Error("cwise: Too many arguments in post() block") | |
} | |
//Check debug flag | |
proc.debug = !!user_args.printCode || !!user_args.debug | |
//Retrieve name | |
proc.funcName = user_args.funcName || "cwise" | |
//Read in block size | |
proc.blockSize = user_args.blockSize || 64 | |
return createThunk(proc) | |
} | |
module.exports = compileCwise | |
},{"./lib/thunk.js":10}],9:[function(require,module,exports){ | |
"use strict" | |
var uniq = require("uniq") | |
// This function generates very simple loops analogous to how you typically traverse arrays (the outermost loop corresponds to the slowest changing index, the innermost loop to the fastest changing index) | |
// TODO: If two arrays have the same strides (and offsets) there is potential for decreasing the number of "pointers" and related variables. The drawback is that the type signature would become more specific and that there would thus be less potential for caching, but it might still be worth it, especially when dealing with large numbers of arguments. | |
function innerFill(order, proc, body) { | |
var dimension = order.length | |
, nargs = proc.arrayArgs.length | |
, has_index = proc.indexArgs.length>0 | |
, code = [] | |
, vars = [] | |
, idx=0, pidx=0, i, j | |
for(i=0; i<dimension; ++i) { // Iteration variables | |
vars.push(["i",i,"=0"].join("")) | |
} | |
//Compute scan deltas | |
for(j=0; j<nargs; ++j) { | |
for(i=0; i<dimension; ++i) { | |
pidx = idx | |
idx = order[i] | |
if(i === 0) { // The innermost/fastest dimension's delta is simply its stride | |
vars.push(["d",j,"s",i,"=t",j,"p",idx].join("")) | |
} else { // For other dimensions the delta is basically the stride minus something which essentially "rewinds" the previous (more inner) dimension | |
vars.push(["d",j,"s",i,"=(t",j,"p",idx,"-s",pidx,"*t",j,"p",pidx,")"].join("")) | |
} | |
} | |
} | |
code.push("var " + vars.join(",")) | |
//Scan loop | |
for(i=dimension-1; i>=0; --i) { // Start at largest stride and work your way inwards | |
idx = order[i] | |
code.push(["for(i",i,"=0;i",i,"<s",idx,";++i",i,"){"].join("")) | |
} | |
//Push body of inner loop | |
code.push(body) | |
//Advance scan pointers | |
for(i=0; i<dimension; ++i) { | |
pidx = idx | |
idx = order[i] | |
for(j=0; j<nargs; ++j) { | |
code.push(["p",j,"+=d",j,"s",i].join("")) | |
} | |
if(has_index) { | |
if(i > 0) { | |
code.push(["index[",pidx,"]-=s",pidx].join("")) | |
} | |
code.push(["++index[",idx,"]"].join("")) | |
} | |
code.push("}") | |
} | |
return code.join("\n") | |
} | |
// Generate "outer" loops that loop over blocks of data, applying "inner" loops to the blocks by manipulating the local variables in such a way that the inner loop only "sees" the current block. | |
// TODO: If this is used, then the previous declaration (done by generateCwiseOp) of s* is essentially unnecessary. | |
// I believe the s* are not used elsewhere (in particular, I don't think they're used in the pre/post parts and "shape" is defined independently), so it would be possible to make defining the s* dependent on what loop method is being used. | |
function outerFill(matched, order, proc, body) { | |
var dimension = order.length | |
, nargs = proc.arrayArgs.length | |
, blockSize = proc.blockSize | |
, has_index = proc.indexArgs.length > 0 | |
, code = [] | |
for(var i=0; i<nargs; ++i) { | |
code.push(["var offset",i,"=p",i].join("")) | |
} | |
//Generate loops for unmatched dimensions | |
// The order in which these dimensions are traversed is fairly arbitrary (from small stride to large stride, for the first argument) | |
// TODO: It would be nice if the order in which these loops are placed would also be somehow "optimal" (at the very least we should check that it really doesn't hurt us if they're not). | |
for(var i=matched; i<dimension; ++i) { | |
code.push(["for(var j"+i+"=SS[", order[i], "]|0;j", i, ">0;){"].join("")) // Iterate back to front | |
code.push(["if(j",i,"<",blockSize,"){"].join("")) // Either decrease j by blockSize (s = blockSize), or set it to zero (after setting s = j). | |
code.push(["s",order[i],"=j",i].join("")) | |
code.push(["j",i,"=0"].join("")) | |
code.push(["}else{s",order[i],"=",blockSize].join("")) | |
code.push(["j",i,"-=",blockSize,"}"].join("")) | |
if(has_index) { | |
code.push(["index[",order[i],"]=j",i].join("")) | |
} | |
} | |
for(var i=0; i<nargs; ++i) { | |
var indexStr = ["offset"+i] | |
for(var j=matched; j<dimension; ++j) { | |
indexStr.push(["j",j,"*t",i,"p",order[j]].join("")) | |
} | |
code.push(["p",i,"=(",indexStr.join("+"),")"].join("")) | |
} | |
code.push(innerFill(order, proc, body)) | |
for(var i=matched; i<dimension; ++i) { | |
code.push("}") | |
} | |
return code.join("\n") | |
} | |
//Count the number of compatible inner orders | |
// This is the length of the longest common prefix of the arrays in orders. | |
// Each array in orders lists the dimensions of the correspond ndarray in order of increasing stride. | |
// This is thus the maximum number of dimensions that can be efficiently traversed by simple nested loops for all arrays. | |
function countMatches(orders) { | |
var matched = 0, dimension = orders[0].length | |
while(matched < dimension) { | |
for(var j=1; j<orders.length; ++j) { | |
if(orders[j][matched] !== orders[0][matched]) { | |
return matched | |
} | |
} | |
++matched | |
} | |
return matched | |
} | |
//Processes a block according to the given data types | |
// Replaces variable names by different ones, either "local" ones (that are then ferried in and out of the given array) or ones matching the arguments that the function performing the ultimate loop will accept. | |
function processBlock(block, proc, dtypes) { | |
var code = block.body | |
var pre = [] | |
var post = [] | |
for(var i=0; i<block.args.length; ++i) { | |
var carg = block.args[i] | |
if(carg.count <= 0) { | |
continue | |
} | |
var re = new RegExp(carg.name, "g") | |
var ptrStr = "" | |
var arrNum = proc.arrayArgs.indexOf(i) | |
switch(proc.argTypes[i]) { | |
case "offset": | |
var offArgIndex = proc.offsetArgIndex.indexOf(i) | |
var offArg = proc.offsetArgs[offArgIndex] | |
arrNum = offArg.array | |
ptrStr = "+q" + offArgIndex // Adds offset to the "pointer" in the array | |
case "array": | |
ptrStr = "p" + arrNum + ptrStr | |
var localStr = "l" + i | |
var arrStr = "a" + arrNum | |
if (proc.arrayBlockIndices[arrNum] === 0) { // Argument to body is just a single value from this array | |
if(carg.count === 1) { // Argument/array used only once(?) | |
if(dtypes[arrNum] === "generic") { | |
if(carg.lvalue) { | |
pre.push(["var ", localStr, "=", arrStr, ".get(", ptrStr, ")"].join("")) // Is this necessary if the argument is ONLY used as an lvalue? (keep in mind that we can have a += something, so we would actually need to check carg.rvalue) | |
code = code.replace(re, localStr) | |
post.push([arrStr, ".set(", ptrStr, ",", localStr,")"].join("")) | |
} else { | |
code = code.replace(re, [arrStr, ".get(", ptrStr, ")"].join("")) | |
} | |
} else { | |
code = code.replace(re, [arrStr, "[", ptrStr, "]"].join("")) | |
} | |
} else if(dtypes[arrNum] === "generic") { | |
pre.push(["var ", localStr, "=", arrStr, ".get(", ptrStr, ")"].join("")) // TODO: Could we optimize by checking for carg.rvalue? | |
code = code.replace(re, localStr) | |
if(carg.lvalue) { | |
post.push([arrStr, ".set(", ptrStr, ",", localStr,")"].join("")) | |
} | |
} else { | |
pre.push(["var ", localStr, "=", arrStr, "[", ptrStr, "]"].join("")) // TODO: Could we optimize by checking for carg.rvalue? | |
code = code.replace(re, localStr) | |
if(carg.lvalue) { | |
post.push([arrStr, "[", ptrStr, "]=", localStr].join("")) | |
} | |
} | |
} else { // Argument to body is a "block" | |
var reStrArr = [carg.name], ptrStrArr = [ptrStr] | |
for(var j=0; j<Math.abs(proc.arrayBlockIndices[arrNum]); j++) { | |
reStrArr.push("\\s*\\[([^\\]]+)\\]") | |
ptrStrArr.push("$" + (j+1) + "*t" + arrNum + "b" + j) // Matched index times stride | |
} | |
re = new RegExp(reStrArr.join(""), "g") | |
ptrStr = ptrStrArr.join("+") | |
if(dtypes[arrNum] === "generic") { | |
/*if(carg.lvalue) { | |
pre.push(["var ", localStr, "=", arrStr, ".get(", ptrStr, ")"].join("")) // Is this necessary if the argument is ONLY used as an lvalue? (keep in mind that we can have a += something, so we would actually need to check carg.rvalue) | |
code = code.replace(re, localStr) | |
post.push([arrStr, ".set(", ptrStr, ",", localStr,")"].join("")) | |
} else { | |
code = code.replace(re, [arrStr, ".get(", ptrStr, ")"].join("")) | |
}*/ | |
throw new Error("cwise: Generic arrays not supported in combination with blocks!") | |
} else { | |
// This does not produce any local variables, even if variables are used multiple times. It would be possible to do so, but it would complicate things quite a bit. | |
code = code.replace(re, [arrStr, "[", ptrStr, "]"].join("")) | |
} | |
} | |
break | |
case "scalar": | |
code = code.replace(re, "Y" + proc.scalarArgs.indexOf(i)) | |
break | |
case "index": | |
code = code.replace(re, "index") | |
break | |
case "shape": | |
code = code.replace(re, "shape") | |
break | |
} | |
} | |
return [pre.join("\n"), code, post.join("\n")].join("\n").trim() | |
} | |
function typeSummary(dtypes) { | |
var summary = new Array(dtypes.length) | |
var allEqual = true | |
for(var i=0; i<dtypes.length; ++i) { | |
var t = dtypes[i] | |
var digits = t.match(/\d+/) | |
if(!digits) { | |
digits = "" | |
} else { | |
digits = digits[0] | |
} | |
if(t.charAt(0) === 0) { | |
summary[i] = "u" + t.charAt(1) + digits | |
} else { | |
summary[i] = t.charAt(0) + digits | |
} | |
if(i > 0) { | |
allEqual = allEqual && summary[i] === summary[i-1] | |
} | |
} | |
if(allEqual) { | |
return summary[0] | |
} | |
return summary.join("") | |
} | |
//Generates a cwise operator | |
function generateCWiseOp(proc, typesig) { | |
//Compute dimension | |
// Arrays get put first in typesig, and there are two entries per array (dtype and order), so this gets the number of dimensions in the first array arg. | |
var dimension = (typesig[1].length - Math.abs(proc.arrayBlockIndices[0]))|0 | |
var orders = new Array(proc.arrayArgs.length) | |
var dtypes = new Array(proc.arrayArgs.length) | |
for(var i=0; i<proc.arrayArgs.length; ++i) { | |
dtypes[i] = typesig[2*i] | |
orders[i] = typesig[2*i+1] | |
} | |
//Determine where block and loop indices start and end | |
var blockBegin = [], blockEnd = [] // These indices are exposed as blocks | |
var loopBegin = [], loopEnd = [] // These indices are iterated over | |
var loopOrders = [] // orders restricted to the loop indices | |
for(var i=0; i<proc.arrayArgs.length; ++i) { | |
if (proc.arrayBlockIndices[i]<0) { | |
loopBegin.push(0) | |
loopEnd.push(dimension) | |
blockBegin.push(dimension) | |
blockEnd.push(dimension+proc.arrayBlockIndices[i]) | |
} else { | |
loopBegin.push(proc.arrayBlockIndices[i]) // Non-negative | |
loopEnd.push(proc.arrayBlockIndices[i]+dimension) | |
blockBegin.push(0) | |
blockEnd.push(proc.arrayBlockIndices[i]) | |
} | |
var newOrder = [] | |
for(var j=0; j<orders[i].length; j++) { | |
if (loopBegin[i]<=orders[i][j] && orders[i][j]<loopEnd[i]) { | |
newOrder.push(orders[i][j]-loopBegin[i]) // If this is a loop index, put it in newOrder, subtracting loopBegin, to make sure that all loopOrders are using a common set of indices. | |
} | |
} | |
loopOrders.push(newOrder) | |
} | |
//First create arguments for procedure | |
var arglist = ["SS"] // SS is the overall shape over which we iterate | |
var code = ["'use strict'"] | |
var vars = [] | |
for(var j=0; j<dimension; ++j) { | |
vars.push(["s", j, "=SS[", j, "]"].join("")) // The limits for each dimension. | |
} | |
for(var i=0; i<proc.arrayArgs.length; ++i) { | |
arglist.push("a"+i) // Actual data array | |
arglist.push("t"+i) // Strides | |
arglist.push("p"+i) // Offset in the array at which the data starts (also used for iterating over the data) | |
for(var j=0; j<dimension; ++j) { // Unpack the strides into vars for looping | |
vars.push(["t",i,"p",j,"=t",i,"[",loopBegin[i]+j,"]"].join("")) | |
} | |
for(var j=0; j<Math.abs(proc.arrayBlockIndices[i]); ++j) { // Unpack the strides into vars for block iteration | |
vars.push(["t",i,"b",j,"=t",i,"[",blockBegin[i]+j,"]"].join("")) | |
} | |
} | |
for(var i=0; i<proc.scalarArgs.length; ++i) { | |
arglist.push("Y" + i) | |
} | |
if(proc.shapeArgs.length > 0) { | |
vars.push("shape=SS.slice(0)") // Makes the shape over which we iterate available to the user defined functions (so you can use width/height for example) | |
} | |
if(proc.indexArgs.length > 0) { | |
// Prepare an array to keep track of the (logical) indices, initialized to dimension zeroes. | |
var zeros = new Array(dimension) | |
for(var i=0; i<dimension; ++i) { | |
zeros[i] = "0" | |
} | |
vars.push(["index=[", zeros.join(","), "]"].join("")) | |
} | |
for(var i=0; i<proc.offsetArgs.length; ++i) { // Offset arguments used for stencil operations | |
var off_arg = proc.offsetArgs[i] | |
var init_string = [] | |
for(var j=0; j<off_arg.offset.length; ++j) { | |
if(off_arg.offset[j] === 0) { | |
continue | |
} else if(off_arg.offset[j] === 1) { | |
init_string.push(["t", off_arg.array, "p", j].join("")) | |
} else { | |
init_string.push([off_arg.offset[j], "*t", off_arg.array, "p", j].join("")) | |
} | |
} | |
if(init_string.length === 0) { | |
vars.push("q" + i + "=0") | |
} else { | |
vars.push(["q", i, "=", init_string.join("+")].join("")) | |
} | |
} | |
//Prepare this variables | |
var thisVars = uniq([].concat(proc.pre.thisVars) | |
.concat(proc.body.thisVars) | |
.concat(proc.post.thisVars)) | |
vars = vars.concat(thisVars) | |
code.push("var " + vars.join(",")) | |
for(var i=0; i<proc.arrayArgs.length; ++i) { | |
code.push("p"+i+"|=0") | |
} | |
//Inline prelude | |
if(proc.pre.body.length > 3) { | |
code.push(processBlock(proc.pre, proc, dtypes)) | |
} | |
//Process body | |
var body = processBlock(proc.body, proc, dtypes) | |
var matched = countMatches(loopOrders) | |
if(matched < dimension) { | |
code.push(outerFill(matched, loopOrders[0], proc, body)) // TODO: Rather than passing loopOrders[0], it might be interesting to look at passing an order that represents the majority of the arguments for example. | |
} else { | |
code.push(innerFill(loopOrders[0], proc, body)) | |
} | |
//Inline epilog | |
if(proc.post.body.length > 3) { | |
code.push(processBlock(proc.post, proc, dtypes)) | |
} | |
if(proc.debug) { | |
console.log("-----Generated cwise routine for ", typesig, ":\n" + code.join("\n") + "\n----------") | |
} | |
var loopName = [(proc.funcName||"unnamed"), "_cwise_loop_", orders[0].join("s"),"m",matched,typeSummary(dtypes)].join("") | |
var f = new Function(["function ",loopName,"(", arglist.join(","),"){", code.join("\n"),"} return ", loopName].join("")) | |
return f() | |
} | |
module.exports = generateCWiseOp | |
},{"uniq":11}],10:[function(require,module,exports){ | |
"use strict" | |
// The function below is called when constructing a cwise function object, and does the following: | |
// A function object is constructed which accepts as argument a compilation function and returns another function. | |
// It is this other function that is eventually returned by createThunk, and this function is the one that actually | |
// checks whether a certain pattern of arguments has already been used before and compiles new loops as needed. | |
// The compilation passed to the first function object is used for compiling new functions. | |
// Once this function object is created, it is called with compile as argument, where the first argument of compile | |
// is bound to "proc" (essentially containing a preprocessed version of the user arguments to cwise). | |
// So createThunk roughly works like this: | |
// function createThunk(proc) { | |
// var thunk = function(compileBound) { | |
// var CACHED = {} | |
// return function(arrays and scalars) { | |
// if (dtype and order of arrays in CACHED) { | |
// var func = CACHED[dtype and order of arrays] | |
// } else { | |
// var func = CACHED[dtype and order of arrays] = compileBound(dtype and order of arrays) | |
// } | |
// return func(arrays and scalars) | |
// } | |
// } | |
// return thunk(compile.bind1(proc)) | |
// } | |
var compile = require("./compile.js") | |
function createThunk(proc) { | |
var code = ["'use strict'", "var CACHED={}"] | |
var vars = [] | |
var thunkName = proc.funcName + "_cwise_thunk" | |
//Build thunk | |
code.push(["return function ", thunkName, "(", proc.shimArgs.join(","), "){"].join("")) | |
var typesig = [] | |
var string_typesig = [] | |
var proc_args = [["array",proc.arrayArgs[0],".shape.slice(", // Slice shape so that we only retain the shape over which we iterate (which gets passed to the cwise operator as SS). | |
Math.max(0,proc.arrayBlockIndices[0]),proc.arrayBlockIndices[0]<0?(","+proc.arrayBlockIndices[0]+")"):")"].join("")] | |
var shapeLengthConditions = [], shapeConditions = [] | |
// Process array arguments | |
for(var i=0; i<proc.arrayArgs.length; ++i) { | |
var j = proc.arrayArgs[i] | |
vars.push(["t", j, "=array", j, ".dtype,", | |
"r", j, "=array", j, ".order"].join("")) | |
typesig.push("t" + j) | |
typesig.push("r" + j) | |
string_typesig.push("t"+j) | |
string_typesig.push("r"+j+".join()") | |
proc_args.push("array" + j + ".data") | |
proc_args.push("array" + j + ".stride") | |
proc_args.push("array" + j + ".offset|0") | |
if (i>0) { // Gather conditions to check for shape equality (ignoring block indices) | |
shapeLengthConditions.push("array" + proc.arrayArgs[0] + ".shape.length===array" + j + ".shape.length+" + (Math.abs(proc.arrayBlockIndices[0])-Math.abs(proc.arrayBlockIndices[i]))) | |
shapeConditions.push("array" + proc.arrayArgs[0] + ".shape[shapeIndex+" + Math.max(0,proc.arrayBlockIndices[0]) + "]===array" + j + ".shape[shapeIndex+" + Math.max(0,proc.arrayBlockIndices[i]) + "]") | |
} | |
} | |
// Check for shape equality | |
if (proc.arrayArgs.length > 1) { | |
code.push("if (!(" + shapeLengthConditions.join(" && ") + ")) throw new Error('cwise: Arrays do not all have the same dimensionality!')") | |
code.push("for(var shapeIndex=array" + proc.arrayArgs[0] + ".shape.length-" + Math.abs(proc.arrayBlockIndices[0]) + "; shapeIndex-->0;) {") | |
code.push("if (!(" + shapeConditions.join(" && ") + ")) throw new Error('cwise: Arrays do not all have the same shape!')") | |
code.push("}") | |
} | |
// Process scalar arguments | |
for(var i=0; i<proc.scalarArgs.length; ++i) { | |
proc_args.push("scalar" + proc.scalarArgs[i]) | |
} | |
// Check for cached function (and if not present, generate it) | |
vars.push(["type=[", string_typesig.join(","), "].join()"].join("")) | |
vars.push("proc=CACHED[type]") | |
code.push("var " + vars.join(",")) | |
code.push(["if(!proc){", | |
"CACHED[type]=proc=compile([", typesig.join(","), "])}", | |
"return proc(", proc_args.join(","), ")}"].join("")) | |
if(proc.debug) { | |
console.log("-----Generated thunk:\n" + code.join("\n") + "\n----------") | |
} | |
//Compile thunk | |
var thunk = new Function("compile", code.join("\n")) | |
return thunk(compile.bind(undefined, proc)) | |
} | |
module.exports = createThunk | |
},{"./compile.js":9}],11:[function(require,module,exports){ | |
"use strict" | |
function unique_pred(list, compare) { | |
var ptr = 1 | |
, len = list.length | |
, a=list[0], b=list[0] | |
for(var i=1; i<len; ++i) { | |
b = a | |
a = list[i] | |
if(compare(a, b)) { | |
if(i === ptr) { | |
ptr++ | |
continue | |
} | |
list[ptr++] = a | |
} | |
} | |
list.length = ptr | |
return list | |
} | |
function unique_eq(list) { | |
var ptr = 1 | |
, len = list.length | |
, a=list[0], b = list[0] | |
for(var i=1; i<len; ++i, b=a) { | |
b = a | |
a = list[i] | |
if(a !== b) { | |
if(i === ptr) { | |
ptr++ | |
continue | |
} | |
list[ptr++] = a | |
} | |
} | |
list.length = ptr | |
return list | |
} | |
function unique(list, compare, sorted) { | |
if(list.length === 0) { | |
return list | |
} | |
if(compare) { | |
if(!sorted) { | |
list.sort(compare) | |
} | |
return unique_pred(list, compare) | |
} | |
if(!sorted) { | |
list.sort() | |
} | |
return unique_eq(list) | |
} | |
module.exports = unique | |
},{}],12:[function(require,module,exports){ | |
var iota = require("iota-array") | |
var isBuffer = require("is-buffer") | |
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<terms.length; ++i) { | |
terms[i] = [Math.abs(stride[i]), i] | |
} | |
terms.sort(compare1st) | |
var result = new Array(terms.length) | |
for(i=0; i<result.length; ++i) { | |
result[i] = terms[i][1] | |
} | |
return result | |
} | |
function compileConstructor(dtype, dimension) { | |
var className = ["View", dimension, "d", dtype].join("") | |
if(dimension < 0) { | |
className = "View_Nil" + dtype | |
} | |
var useGetters = (dtype === "generic") | |
if(dimension === -1) { | |
//Special case for trivial arrays | |
var code = | |
"function "+className+"(a){this.data=a;};\ | |
var proto="+className+".prototype;\ | |
proto.dtype='"+dtype+"';\ | |
proto.index=function(){return -1};\ | |
proto.size=0;\ | |
proto.dimension=-1;\ | |
proto.shape=proto.stride=proto.order=[];\ | |
proto.lo=proto.hi=proto.transpose=proto.step=\ | |
function(){return new "+className+"(this.data);};\ | |
proto.get=proto.set=function(){};\ | |
proto.pick=function(){return null};\ | |
return function construct_"+className+"(a){return new "+className+"(a);}" | |
var procedure = new Function(code) | |
return procedure() | |
} else if(dimension === 0) { | |
//Special case for 0d arrays | |
var code = | |
"function "+className+"(a,d) {\ | |
this.data = a;\ | |
this.offset = d\ | |
};\ | |
var proto="+className+".prototype;\ | |
proto.dtype='"+dtype+"';\ | |
proto.index=function(){return this.offset};\ | |
proto.dimension=0;\ | |
proto.size=1;\ | |
proto.shape=\ | |
proto.stride=\ | |
proto.order=[];\ | |
proto.lo=\ | |
proto.hi=\ | |
proto.transpose=\ | |
proto.step=function "+className+"_copy() {\ | |
return new "+className+"(this.data,this.offset)\ | |
};\ | |
proto.pick=function "+className+"_pick(){\ | |
return TrivialArray(this.data);\ | |
};\ | |
proto.valueOf=proto.get=function "+className+"_get(){\ | |
return "+(useGetters ? "this.data.get(this.offset)" : "this.data[this.offset]")+ | |
"};\ | |
proto.set=function "+className+"_set(v){\ | |
return "+(useGetters ? "this.data.set(this.offset,v)" : "this.data[this.offset]=v")+"\ | |
};\ | |
return function construct_"+className+"(a,b,c,d){return new "+className+"(a,d)}" | |
var procedure = new Function("TrivialArray", code) | |
return procedure(CACHED_CONSTRUCTORS[dtype][0]) | |
} | |
var code = ["'use strict'"] | |
//Create constructor for view | |
var indices = iota(dimension) | |
var args = indices.map(function(i) { return "i"+i }) | |
var index_str = "this.offset+" + indices.map(function(i) { | |
return "this.stride[" + i + "]*i" + i | |
}).join("+") | |
var shapeArg = indices.map(function(i) { | |
return "b"+i | |
}).join(",") | |
var strideArg = indices.map(function(i) { | |
return "c"+i | |
}).join(",") | |
code.push( | |
"function "+className+"(a," + shapeArg + "," + strideArg + ",d){this.data=a", | |
"this.shape=[" + shapeArg + "]", | |
"this.stride=[" + strideArg + "]", | |
"this.offset=d|0}", | |
"var proto="+className+".prototype", | |
"proto.dtype='"+dtype+"'", | |
"proto.dimension="+dimension) | |
//view.size: | |
code.push("Object.defineProperty(proto,'size',{get:function "+className+"_size(){\ | |
return "+indices.map(function(i) { return "this.shape["+i+"]" }).join("*"), | |
"}})") | |
//view.order: | |
if(dimension === 1) { | |
code.push("proto.order=[0]") | |
} else { | |
code.push("Object.defineProperty(proto,'order',{get:") | |
if(dimension < 4) { | |
code.push("function "+className+"_order(){") | |
if(dimension === 2) { | |
code.push("return (Math.abs(this.stride[0])>Math.abs(this.stride[1]))?[1,0]:[0,1]}})") | |
} else if(dimension === 3) { | |
code.push( | |
"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];\ | |
}}})") | |
} | |
} else { | |
code.push("ORDER})") | |
} | |
} | |
//view.set(i0, ..., v): | |
code.push( | |
"proto.set=function "+className+"_set("+args.join(",")+",v){") | |
if(useGetters) { | |
code.push("return this.data.set("+index_str+",v)}") | |
} else { | |
code.push("return this.data["+index_str+"]=v}") | |
} | |
//view.get(i0, ...): | |
code.push("proto.get=function "+className+"_get("+args.join(",")+"){") | |
if(useGetters) { | |
code.push("return this.data.get("+index_str+")}") | |
} else { | |
code.push("return this.data["+index_str+"]}") | |
} | |
//view.index: | |
code.push( | |
"proto.index=function "+className+"_index(", args.join(), "){return "+index_str+"}") | |
//view.hi(): | |
code.push("proto.hi=function "+className+"_hi("+args.join(",")+"){return new "+className+"(this.data,"+ | |
indices.map(function(i) { | |
return ["(typeof i",i,"!=='number'||i",i,"<0)?this.shape[", i, "]:i", i,"|0"].join("") | |
}).join(",")+","+ | |
indices.map(function(i) { | |
return "this.stride["+i + "]" | |
}).join(",")+",this.offset)}") | |
//view.lo(): | |
var a_vars = indices.map(function(i) { return "a"+i+"=this.shape["+i+"]" }) | |
var c_vars = indices.map(function(i) { return "c"+i+"=this.stride["+i+"]" }) | |
code.push("proto.lo=function "+className+"_lo("+args.join(",")+"){var b=this.offset,d=0,"+a_vars.join(",")+","+c_vars.join(",")) | |
for(var i=0; i<dimension; ++i) { | |
code.push( | |
"if(typeof i"+i+"==='number'&&i"+i+">=0){\ | |
d=i"+i+"|0;\ | |
b+=c"+i+"*d;\ | |
a"+i+"-=d}") | |
} | |
code.push("return new "+className+"(this.data,"+ | |
indices.map(function(i) { | |
return "a"+i | |
}).join(",")+","+ | |
indices.map(function(i) { | |
return "c"+i | |
}).join(",")+",b)}") | |
//view.step(): | |
code.push("proto.step=function "+className+"_step("+args.join(",")+"){var "+ | |
indices.map(function(i) { | |
return "a"+i+"=this.shape["+i+"]" | |
}).join(",")+","+ | |
indices.map(function(i) { | |
return "b"+i+"=this.stride["+i+"]" | |
}).join(",")+",c=this.offset,d=0,ceil=Math.ceil") | |
for(var i=0; i<dimension; ++i) { | |
code.push( | |
"if(typeof i"+i+"==='number'){\ | |
d=i"+i+"|0;\ | |
if(d<0){\ | |
c+=b"+i+"*(a"+i+"-1);\ | |
a"+i+"=ceil(-a"+i+"/d)\ | |
}else{\ | |
a"+i+"=ceil(a"+i+"/d)\ | |
}\ | |
b"+i+"*=d\ | |
}") | |
} | |
code.push("return new "+className+"(this.data,"+ | |
indices.map(function(i) { | |
return "a" + i | |
}).join(",")+","+ | |
indices.map(function(i) { | |
return "b" + i | |
}).join(",")+",c)}") | |
//view.transpose(): | |
var tShape = new Array(dimension) | |
var tStride = new Array(dimension) | |
for(var i=0; i<dimension; ++i) { | |
tShape[i] = "a[i"+i+"]" | |
tStride[i] = "b[i"+i+"]" | |
} | |
code.push("proto.transpose=function "+className+"_transpose("+args+"){"+ | |
args.map(function(n,idx) { return n + "=(" + n + "===undefined?" + idx + ":" + n + "|0)"}).join(";"), | |
"var a=this.shape,b=this.stride;return new "+className+"(this.data,"+tShape.join(",")+","+tStride.join(",")+",this.offset)}") | |
//view.pick(): | |
code.push("proto.pick=function "+className+"_pick("+args+"){var a=[],b=[],c=this.offset") | |
for(var i=0; i<dimension; ++i) { | |
code.push("if(typeof i"+i+"==='number'&&i"+i+">=0){c=(c+this.stride["+i+"]*i"+i+")|0}else{a.push(this.shape["+i+"]);b.push(this.stride["+i+"])}") | |
} | |
code.push("var ctor=CTOR_LIST[a.length+1];return ctor(this.data,a,b,c)}") | |
//Add return statement | |
code.push("return function construct_"+className+"(data,shape,stride,offset){return new "+className+"(data,"+ | |
indices.map(function(i) { | |
return "shape["+i+"]" | |
}).join(",")+","+ | |
indices.map(function(i) { | |
return "stride["+i+"]" | |
}).join(",")+",offset)}") | |
//Compile procedure | |
var procedure = new Function("CTOR_LIST", "ORDER", code.join("\n")) | |
return procedure(CACHED_CONSTRUCTORS[dtype], 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 Uint8Array]": | |
return "uint8" | |
case "[object Uint16Array]": | |
return "uint16" | |
case "[object Uint32Array]": | |
return "uint32" | |
case "[object Uint8ClampedArray]": | |
return "uint8_clamped" | |
} | |
} | |
if(Array.isArray(data)) { | |
return "array" | |
} | |
return "generic" | |
} | |
var CACHED_CONSTRUCTORS = { | |
"float32":[], | |
"float64":[], | |
"int8":[], | |
"int16":[], | |
"int32":[], | |
"uint8":[], | |
"uint16":[], | |
"uint32":[], | |
"array":[], | |
"uint8_clamped":[], | |
"buffer":[], | |
"generic":[] | |
} | |
;(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<d; ++i) { | |
if(stride[i] < 0) { | |
offset -= (shape[i]-1)*stride[i] | |
} | |
} | |
} | |
var dtype = arrayDType(data) | |
var ctor_list = CACHED_CONSTRUCTORS[dtype] | |
while(ctor_list.length <= d+1) { | |
ctor_list.push(compileConstructor(dtype, ctor_list.length-1)) | |
} | |
var ctor = ctor_list[d+1] | |
return ctor(data, shape, stride, offset) | |
} | |
module.exports = wrappedNDArrayCtor | |
},{"iota-array":13,"is-buffer":14}],13:[function(require,module,exports){ | |
"use strict" | |
function iota(n) { | |
var result = new Array(n) | |
for(var i=0; i<n; ++i) { | |
result[i] = i | |
} | |
return result | |
} | |
module.exports = iota | |
},{}],14:[function(require,module,exports){ | |
/** | |
* Determine if an object is Buffer | |
* | |
* Author: Feross Aboukhadijeh <[email protected]> <http://feross.org> | |
* License: MIT | |
* | |
* `npm install is-buffer` | |
*/ | |
module.exports = function (obj) { | |
return !!(obj != null && | |
(obj._isBuffer || // For Safari 5-7 (missing Object.prototype.constructor) | |
(obj.constructor && | |
typeof obj.constructor.isBuffer === 'function' && | |
obj.constructor.isBuffer(obj)) | |
)) | |
} | |
},{}],15:[function(require,module,exports){ | |
/** | |
* Bit twiddling hacks for JavaScript. | |
* | |
* Author: Mikola Lysenko | |
* | |
* Ported from Stanford bit twiddling hack library: | |
* http://graphics.stanford.edu/~seander/bithacks.html | |
*/ | |
"use strict"; "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)); | |
} | |
},{}],16:[function(require,module,exports){ | |
"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<c; ++j) { | |
result[j] = value | |
} | |
} else { | |
for(j=0; j<c; ++j) { | |
result[j] = dupe_array(count, value, i+1) | |
} | |
} | |
return result | |
} | |
function dupe_number(count, value) { | |
var result, i | |
result = new Array(count) | |
for(i=0; i<count; ++i) { | |
result[i] = value | |
} | |
return result | |
} | |
function dupe(count, value) { | |
if(typeof value === "undefined") { | |
value = 0 | |
} | |
switch(typeof count) { | |
case "number": | |
if(count > 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 | |
},{}],17:[function(require,module,exports){ | |
(function (global,Buffer){ | |
'use strict' | |
var bits = require('bit-twiddle') | |
var dup = require('dup') | |
//Legacy pool support | |
if(!global.__TYPEDARRAY_POOL) { | |
global.__TYPEDARRAY_POOL = { | |
UINT8 : dup([32, 0]) | |
, UINT16 : dup([32, 0]) | |
, UINT32 : dup([32, 0]) | |
, INT8 : dup([32, 0]) | |
, INT16 : dup([32, 0]) | |
, INT32 : 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 POOL = global.__TYPEDARRAY_POOL | |
//Upgrade pool | |
if(!POOL.UINT8C) { | |
POOL.UINT8C = 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.freeInt8 = | |
exports.freeInt16 = | |
exports.freeInt32 = | |
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 '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 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.UINT8C[i].length = 0 | |
DATA[i].length = 0 | |
BUFFER[i].length = 0 | |
} | |
} | |
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer) | |
},{"bit-twiddle":15,"buffer":2,"dup":16}],18:[function(require,module,exports){ | |
exports.color = function(color) { | |
return array(color, [0, 0, 0, 1]) | |
} | |
exports.depth = function(depth) { | |
return number(depth, 1) | |
} | |
exports.stencil = function(stencil) { | |
return number(stencil, false) | |
} | |
function number(n, def) { | |
if (n === false) return false | |
if (typeof n === 'undefined') return def | |
return n + 0 | |
} | |
function array(a, def) { | |
if (a === false) return false | |
if (Array.isArray(a)) return a || def | |
return def | |
} | |
},{}],19:[function(require,module,exports){ | |
var defaults = require('./defaults') | |
module.exports = clear | |
function clear(opts) { | |
opts = opts || {} | |
var color = defaults.color(opts.color) | |
Object.defineProperty(clear, 'color', { | |
get: function() { return color }, | |
set: function(value) { | |
return color = defaults.color(value) | |
} | |
}) | |
var depth = defaults.depth(opts.depth) | |
Object.defineProperty(clear, 'depth', { | |
get: function() { return depth }, | |
set: function(value) { | |
return depth = defaults.depth(value) | |
} | |
}) | |
var stencil = defaults.stencil(opts.stencil) | |
Object.defineProperty(clear, 'stencil', { | |
get: function() { return stencil }, | |
set: function(value) { | |
return stencil = defaults.stencil(value) | |
} | |
}) | |
return clear | |
function clear(gl) { | |
var flags = 0 | |
if (color !== false) { | |
gl.clearColor(color[0], color[1], color[2], color[3]) | |
flags |= gl.COLOR_BUFFER_BIT | |
} | |
if (depth !== false) { | |
gl.clearDepth(depth) | |
flags |= gl.DEPTH_BUFFER_BIT | |
} | |
if (stencil !== false) { | |
gl.clearStencil(stencil) | |
flags |= gl.STENCIL_BUFFER_BIT | |
} | |
gl.clear(flags) | |
return gl | |
} | |
} | |
},{"./defaults":18}],20:[function(require,module,exports){ | |
var raf = require('raf-component') | |
module.exports = createContext | |
function createContext(canvas, opts, render) { | |
if (typeof opts === 'function') { | |
render = opts | |
opts = {} | |
} else { | |
opts = opts || {} | |
} | |
var gl = ( | |
canvas.getContext('webgl', opts) || | |
canvas.getContext('webgl-experimental', opts) || | |
canvas.getContext('experimental-webgl', opts) | |
) | |
if (!gl) { | |
throw new Error('Unable to initialize WebGL') | |
} | |
if (render) raf(tick) | |
return gl | |
function tick() { | |
render(gl) | |
raf(tick) | |
} | |
} | |
},{"raf-component":21}],21:[function(require,module,exports){ | |
/** | |
* Expose `requestAnimationFrame()`. | |
*/ | |
exports = module.exports = window.requestAnimationFrame | |
|| window.webkitRequestAnimationFrame | |
|| window.mozRequestAnimationFrame | |
|| window.oRequestAnimationFrame | |
|| window.msRequestAnimationFrame | |
|| fallback; | |
/** | |
* Fallback implementation. | |
*/ | |
var prev = new Date().getTime(); | |
function fallback(fn) { | |
var curr = new Date().getTime(); | |
var ms = Math.max(0, 16 - (curr - prev)); | |
var req = setTimeout(fn, ms); | |
prev = curr; | |
return req; | |
} | |
/** | |
* Cancel. | |
*/ | |
var cancel = window.cancelAnimationFrame | |
|| window.webkitCancelAnimationFrame | |
|| window.mozCancelAnimationFrame | |
|| window.oCancelAnimationFrame | |
|| window.msCancelAnimationFrame | |
|| window.clearTimeout; | |
exports.cancel = function(id){ | |
cancel.call(window, id); | |
}; | |
},{}],22:[function(require,module,exports){ | |
module.exports = create; | |
/** | |
* Creates a new identity mat4 | |
* | |
* @returns {mat4} a new 4x4 matrix | |
*/ | |
function create() { | |
var out = new Float32Array(16); | |
out[0] = 1; | |
out[1] = 0; | |
out[2] = 0; | |
out[3] = 0; | |
out[4] = 0; | |
out[5] = 1; | |
out[6] = 0; | |
out[7] = 0; | |
out[8] = 0; | |
out[9] = 0; | |
out[10] = 1; | |
out[11] = 0; | |
out[12] = 0; | |
out[13] = 0; | |
out[14] = 0; | |
out[15] = 1; | |
return out; | |
}; | |
},{}],23:[function(require,module,exports){ | |
module.exports = identity; | |
/** | |
* Set a mat4 to the identity matrix | |
* | |
* @param {mat4} out the receiving matrix | |
* @returns {mat4} out | |
*/ | |
function identity(out) { | |
out[0] = 1; | |
out[1] = 0; | |
out[2] = 0; | |
out[3] = 0; | |
out[4] = 0; | |
out[5] = 1; | |
out[6] = 0; | |
out[7] = 0; | |
out[8] = 0; | |
out[9] = 0; | |
out[10] = 1; | |
out[11] = 0; | |
out[12] = 0; | |
out[13] = 0; | |
out[14] = 0; | |
out[15] = 1; | |
return out; | |
}; | |
},{}],24:[function(require,module,exports){ | |
module.exports = ortho; | |
/** | |
* Generates a orthogonal projection matrix with the given bounds | |
* | |
* @param {mat4} out mat4 frustum matrix will be written into | |
* @param {number} left Left bound of the frustum | |
* @param {number} right Right bound of the frustum | |
* @param {number} bottom Bottom bound of the frustum | |
* @param {number} top Top bound of the frustum | |
* @param {number} near Near bound of the frustum | |
* @param {number} far Far bound of the frustum | |
* @returns {mat4} out | |
*/ | |
function ortho(out, left, right, bottom, top, near, far) { | |
var lr = 1 / (left - right), | |
bt = 1 / (bottom - top), | |
nf = 1 / (near - far); | |
out[0] = -2 * lr; | |
out[1] = 0; | |
out[2] = 0; | |
out[3] = 0; | |
out[4] = 0; | |
out[5] = -2 * bt; | |
out[6] = 0; | |
out[7] = 0; | |
out[8] = 0; | |
out[9] = 0; | |
out[10] = 2 * nf; | |
out[11] = 0; | |
out[12] = (left + right) * lr; | |
out[13] = (top + bottom) * bt; | |
out[14] = (far + near) * nf; | |
out[15] = 1; | |
return out; | |
}; | |
},{}],25:[function(require,module,exports){ | |
module.exports = 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; | |
}; | |
},{}],26:[function(require,module,exports){ | |
module.exports = translate; | |
/** | |
* Translate a mat4 by the given vector | |
* | |
* @param {mat4} out the receiving matrix | |
* @param {mat4} a the matrix to translate | |
* @param {vec3} v vector to translate by | |
* @returns {mat4} out | |
*/ | |
function translate(out, a, v) { | |
var x = v[0], y = v[1], z = v[2], | |
a00, a01, a02, a03, | |
a10, a11, a12, a13, | |
a20, a21, a22, a23; | |
if (a === out) { | |
out[12] = a[0] * x + a[4] * y + a[8] * z + a[12]; | |
out[13] = a[1] * x + a[5] * y + a[9] * z + a[13]; | |
out[14] = a[2] * x + a[6] * y + a[10] * z + a[14]; | |
out[15] = a[3] * x + a[7] * y + a[11] * z + a[15]; | |
} else { | |
a00 = a[0]; a01 = a[1]; a02 = a[2]; a03 = a[3]; | |
a10 = a[4]; a11 = a[5]; a12 = a[6]; a13 = a[7]; | |
a20 = a[8]; a21 = a[9]; a22 = a[10]; a23 = a[11]; | |
out[0] = a00; out[1] = a01; out[2] = a02; out[3] = a03; | |
out[4] = a10; out[5] = a11; out[6] = a12; out[7] = a13; | |
out[8] = a20; out[9] = a21; out[10] = a22; out[11] = a23; | |
out[12] = a00 * x + a10 * y + a20 * z + a[12]; | |
out[13] = a01 * x + a11 * y + a21 * z + a[13]; | |
out[14] = a02 * x + a12 * y + a22 * z + a[14]; | |
out[15] = a03 * x + a13 * y + a23 * z + a[15]; | |
} | |
return out; | |
}; | |
},{}],27:[function(require,module,exports){ | |
module.exports = programify | |
var shader = require('gl-shader-core') | |
function programify(vertex, fragment, uniforms, attributes) { | |
return function(gl) { | |
return shader(gl, vertex, fragment, uniforms, attributes) | |
} | |
} | |
},{"gl-shader-core":33}],28:[function(require,module,exports){ | |
module.exports = noop | |
function noop() { | |
throw new Error( | |
'You should bundle your code ' + | |
'using `glslify` as a transform.' | |
) | |
} | |
},{}],29:[function(require,module,exports){ | |
'use strict' | |
module.exports = createAttributeWrapper | |
//Shader attribute class | |
function ShaderAttribute(gl, program, location, dimension, name, constFunc, relink) { | |
this._gl = gl | |
this._program = program | |
this._location = location | |
this._dimension = dimension | |
this._name = name | |
this._constFunc = constFunc | |
this._relink = relink | |
} | |
var proto = ShaderAttribute.prototype | |
proto.pointer = function setAttribPointer(type, normalized, stride, offset) { | |
var gl = this._gl | |
gl.vertexAttribPointer(this._location, this._dimension, type||gl.FLOAT, !!normalized, stride||0, offset||0) | |
this._gl.enableVertexAttribArray(this._location) | |
} | |
Object.defineProperty(proto, 'location', { | |
get: function() { | |
return this._location | |
} | |
, set: function(v) { | |
if(v !== this._location) { | |
this._location = v | |
this._gl.bindAttribLocation(this._program, v, this._name) | |
this._gl.linkProgram(this._program) | |
this._relink() | |
} | |
} | |
}) | |
//Adds a vector attribute to obj | |
function addVectorAttribute(gl, program, location, dimension, obj, name, doLink) { | |
var constFuncArgs = [ 'gl', 'v' ] | |
var varNames = [] | |
for(var i=0; i<dimension; ++i) { | |
constFuncArgs.push('x'+i) | |
varNames.push('x'+i) | |
} | |
constFuncArgs.push([ | |
'if(x0.length===void 0){return gl.vertexAttrib', dimension, 'f(v,', varNames.join(), ')}else{return gl.vertexAttrib', dimension, 'fv(v,x0)}' | |
].join('')) | |
var constFunc = Function.apply(undefined, constFuncArgs) | |
var attr = new ShaderAttribute(gl, program, location, dimension, name, constFunc, doLink) | |
Object.defineProperty(obj, name, { | |
set: function(x) { | |
gl.disableVertexAttribArray(attr._location) | |
constFunc(gl, attr._location, x) | |
return x | |
} | |
, get: function() { | |
return attr | |
} | |
, enumerable: true | |
}) | |
} | |
//Create shims for attributes | |
function createAttributeWrapper(gl, program, attributes, doLink) { | |
var obj = {} | |
for(var i=0, n=attributes.length; i<n; ++i) { | |
var a = attributes[i] | |
var name = a.name | |
var type = a.type | |
var location = gl.getAttribLocation(program, name) | |
switch(type) { | |
case 'bool': | |
case 'int': | |
case 'float': | |
addVectorAttribute(gl, program, location, 1, obj, name, doLink) | |
break | |
default: | |
if(type.indexOf('vec') >= 0) { | |
var d = type.charCodeAt(type.length-1) - 48 | |
if(d < 2 || d > 4) { | |
throw new Error('gl-shader: Invalid data type for attribute ' + name + ': ' + type) | |
} | |
addVectorAttribute(gl, program, location, d, obj, name, doLink) | |
} else { | |
throw new Error('gl-shader: Unknown data type for attribute ' + name + ': ' + type) | |
} | |
break | |
} | |
} | |
return obj | |
} | |
},{}],30:[function(require,module,exports){ | |
'use strict' | |
var dup = require('dup') | |
var coallesceUniforms = require('./reflect') | |
module.exports = createUniformWrapper | |
//Binds a function and returns a value | |
function identity(x) { | |
var c = new Function('y', 'return function(){return y}') | |
return c(x) | |
} | |
//Create shims for uniforms | |
function createUniformWrapper(gl, program, uniforms, locations) { | |
function makeGetter(index) { | |
var proc = new Function('gl', 'prog', 'locations', | |
'return function(){return gl.getUniform(prog,locations[' + index + '])}') | |
return proc(gl, program, locations) | |
} | |
function makePropSetter(path, index, type) { | |
switch(type) { | |
case 'bool': | |
case 'int': | |
case 'sampler2D': | |
case 'samplerCube': | |
return 'gl.uniform1i(locations[' + index + '],obj' + path + ')' | |
case 'float': | |
return 'gl.uniform1f(locations[' + index + '],obj' + path + ')' | |
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 Error('gl-shader: Invalid data type') | |
} | |
switch(type.charAt(0)) { | |
case 'b': | |
case 'i': | |
return 'gl.uniform' + d + 'iv(locations[' + index + '],obj' + path + ')' | |
case 'v': | |
return 'gl.uniform' + d + 'fv(locations[' + index + '],obj' + path + ')' | |
default: | |
throw new Error('gl-shader: Unrecognized data type for vector ' + name + ': ' + type) | |
} | |
} else if(type.indexOf('mat') === 0 && type.length === 4) { | |
var d = type.charCodeAt(type.length-1) - 48 | |
if(d < 2 || d > 4) { | |
throw new Error('gl-shader: Invalid uniform dimension type for matrix ' + name + ': ' + type) | |
} | |
return 'gl.uniformMatrix' + d + 'fv(locations[' + index + '],false,obj' + path + ')' | |
} else { | |
throw new Error('gl-shader: Unknown uniform data type for ' + name + ': ' + type) | |
} | |
break | |
} | |
} | |
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 makeSetter(type) { | |
var code = [ 'return function updateProperty(obj){' ] | |
var indices = enumerateIndices('', type) | |
for(var i=0; i<indices.length; ++i) { | |
var item = indices[i] | |
var path = item[0] | |
var idx = item[1] | |
if(locations[idx]) { | |
code.push(makePropSetter(path, idx, uniforms[idx].type)) | |
} | |
} | |
code.push('return obj}') | |
var proc = new Function('gl', 'prog', 'locations', code.join('\n')) | |
return proc(gl, program, locations) | |
} | |
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 Error('gl-shader: Invalid data type') | |
} | |
if(type.charAt(0) === 'b') { | |
return dup(d, false) | |
} | |
return dup(d) | |
} else if(type.indexOf('mat') === 0 && type.length === 4) { | |
var d = type.charCodeAt(type.length-1) - 48 | |
if(d < 2 || d > 4) { | |
throw new Error('gl-shader: Invalid uniform dimension type for matrix ' + name + ': ' + type) | |
} | |
return dup([d,d]) | |
} else { | |
throw new Error('gl-shader: Unknown uniform data type for ' + name + ': ' + type) | |
} | |
break | |
} | |
} | |
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<obj.length; ++i) { | |
storeProperty(result, i, obj[i]) | |
} | |
} else { | |
result = {} | |
for(var id in obj) { | |
storeProperty(result, id, obj[id]) | |
} | |
} | |
return result | |
} | |
//Return data | |
var coallesced = coallesceUniforms(uniforms, true) | |
return { | |
get: identity(processObject(coallesced)), | |
set: makeSetter(coallesced), | |
enumerable: true, | |
configurable: true | |
} | |
} | |
},{"./reflect":31,"dup":32}],31:[function(require,module,exports){ | |
'use strict' | |
module.exports = makeReflectTypes | |
//Construct type info for reflection. | |
// | |
// This iterates over the flattened list of uniform type values and smashes them into a JSON object. | |
// | |
// The leaves of the resulting object are either indices or type strings representing primitive glslify types | |
function makeReflectTypes(uniforms, useIndex) { | |
var obj = {} | |
for(var i=0; i<uniforms.length; ++i) { | |
var n = uniforms[i].name | |
var parts = n.split(".") | |
var o = obj | |
for(var j=0; j<parts.length; ++j) { | |
var x = parts[j].split("[") | |
if(x.length > 1) { | |
if(!(x[0] in o)) { | |
o[x[0]] = [] | |
} | |
o = o[x[0]] | |
for(var k=1; k<x.length; ++k) { | |
var y = parseInt(x[k]) | |
if(k<x.length-1 || j<parts.length-1) { | |
if(!(y in o)) { | |
if(k < x.length-1) { | |
o[y] = [] | |
} else { | |
o[y] = {} | |
} | |
} | |
o = o[y] | |
} else { | |
if(useIndex) { | |
o[y] = i | |
} else { | |
o[y] = uniforms[i].type | |
} | |
} | |
} | |
} else if(j < parts.length-1) { | |
if(!(x[0] in o)) { | |
o[x[0]] = {} | |
} | |
o = o[x[0]] | |
} else { | |
if(useIndex) { | |
o[x[0]] = i | |
} else { | |
o[x[0]] = uniforms[i].type | |
} | |
} | |
} | |
} | |
return obj | |
} | |
},{}],32:[function(require,module,exports){ | |
arguments[4][16][0].apply(exports,arguments) | |
},{"dup":16}],33:[function(require,module,exports){ | |
'use strict' | |
var createUniformWrapper = require('./lib/create-uniforms') | |
var createAttributeWrapper = require('./lib/create-attributes') | |
var makeReflect = require('./lib/reflect') | |
//Shader object | |
function Shader(gl, prog, vertShader, fragShader) { | |
this.gl = gl | |
this.handle = prog | |
this.attributes = null | |
this.uniforms = null | |
this.types = null | |
this.vertexShader = vertShader | |
this.fragmentShader = fragShader | |
} | |
//Binds the shader | |
Shader.prototype.bind = function() { | |
this.gl.useProgram(this.handle) | |
} | |
//Destroy shader, release resources | |
Shader.prototype.dispose = function() { | |
var gl = this.gl | |
gl.deleteShader(this.vertexShader) | |
gl.deleteShader(this.fragmentShader) | |
gl.deleteProgram(this.handle) | |
} | |
Shader.prototype.updateExports = function(uniforms, attributes) { | |
var locations = new Array(uniforms.length) | |
var program = this.handle | |
var gl = this.gl | |
var doLink = relinkUniforms.bind(void 0, | |
gl, | |
program, | |
locations, | |
uniforms | |
) | |
doLink() | |
this.types = { | |
uniforms: makeReflect(uniforms), | |
attributes: makeReflect(attributes) | |
} | |
this.attributes = createAttributeWrapper( | |
gl, | |
program, | |
attributes, | |
doLink | |
) | |
Object.defineProperty(this, 'uniforms', createUniformWrapper( | |
gl, | |
program, | |
uniforms, | |
locations | |
)) | |
} | |
//Relinks all uniforms | |
function relinkUniforms(gl, program, locations, uniforms) { | |
for(var i=0; i<uniforms.length; ++i) { | |
locations[i] = gl.getUniformLocation(program, uniforms[i].name) | |
} | |
} | |
//Compiles and links a shader program with the given attribute and vertex list | |
function createShader( | |
gl | |
, vertSource | |
, fragSource | |
, uniforms | |
, attributes) { | |
//Compile vertex shader | |
var vertShader = gl.createShader(gl.VERTEX_SHADER) | |
gl.shaderSource(vertShader, vertSource) | |
gl.compileShader(vertShader) | |
if(!gl.getShaderParameter(vertShader, gl.COMPILE_STATUS)) { | |
var errLog = gl.getShaderInfoLog(vertShader) | |
console.error('gl-shader: Error compling vertex shader:', errLog) | |
throw new Error('gl-shader: Error compiling vertex shader:' + errLog) | |
} | |
//Compile fragment shader | |
var fragShader = gl.createShader(gl.FRAGMENT_SHADER) | |
gl.shaderSource(fragShader, fragSource) | |
gl.compileShader(fragShader) | |
if(!gl.getShaderParameter(fragShader, gl.COMPILE_STATUS)) { | |
var errLog = gl.getShaderInfoLog(fragShader) | |
console.error('gl-shader: Error compiling fragment shader:', errLog) | |
throw new Error('gl-shader: Error compiling fragment shader:' + errLog) | |
} | |
//Link program | |
var program = gl.createProgram() | |
gl.attachShader(program, fragShader) | |
gl.attachShader(program, vertShader) | |
//Optional default attriubte locations | |
attributes.forEach(function(a) { | |
if (typeof a.location === 'number') | |
gl.bindAttribLocation(program, a.location, a.name) | |
}) | |
gl.linkProgram(program) | |
if(!gl.getProgramParameter(program, gl.LINK_STATUS)) { | |
var errLog = gl.getProgramInfoLog(program) | |
console.error('gl-shader: Error linking shader program:', errLog) | |
throw new Error('gl-shader: Error linking shader program:' + errLog) | |
} | |
//Return final linked shader object | |
var shader = new Shader( | |
gl, | |
program, | |
vertShader, | |
fragShader | |
) | |
shader.updateExports(uniforms, attributes) | |
return shader | |
} | |
module.exports = createShader | |
},{"./lib/create-attributes":29,"./lib/create-uniforms":30,"./lib/reflect":31}],34:[function(require,module,exports){ | |
"use strict" | |
module.exports = createText | |
var vectorizeText = require("./lib/vtext") | |
var defaultCanvas = null | |
var defaultContext = null | |
if(typeof document !== 'undefined') { | |
defaultCanvas = document.createElement('canvas') | |
defaultCanvas.width = 8192 | |
defaultCanvas.height = 1024 | |
defaultContext = defaultCanvas.getContext("2d") | |
} | |
function createText(str, options) { | |
if((typeof options !== "object") || (options === null)) { | |
options = {} | |
} | |
return vectorizeText( | |
str, | |
options.canvas || defaultCanvas, | |
options.context || defaultContext, | |
options) | |
} | |
},{"./lib/vtext":35}],35:[function(require,module,exports){ | |
"use strict" | |
module.exports = vectorizeText | |
module.exports.processPixels = processPixels | |
var surfaceNets = require('surface-nets') | |
var ndarray = require('ndarray') | |
var simplify = require('simplify-planar-graph') | |
var cleanPSLG = require('clean-pslg') | |
var cdt2d = require('cdt2d') | |
var toPolygonCrappy = require('planar-graph-to-polyline') | |
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<n; ++i) { | |
var p = positions[i] | |
for(var j=0; j<2; ++j) { | |
lo[j] = Math.min(lo[j], p[j])|0 | |
hi[j] = Math.max(hi[j], p[j])|0 | |
} | |
} | |
var xShift = 0 | |
switch(align) { | |
case "center": | |
xShift = -0.5 * (lo[0] + hi[0]) | |
break | |
case "right": | |
case "end": | |
xShift = -hi[0] | |
break | |
case "left": | |
case "start": | |
xShift = -lo[0] | |
break | |
default: | |
throw new Error("vectorize-text: Unrecognized textAlign: '" + align + "'") | |
} | |
var yShift = 0 | |
switch(baseline) { | |
case "hanging": | |
case "top": | |
yShift = -lo[1] | |
break | |
case "middle": | |
yShift = -0.5 * (lo[1] + hi[1]) | |
break | |
case "alphabetic": | |
case "ideographic": | |
yShift = -3 * size | |
break | |
case "bottom": | |
yShift = -hi[1] | |
break | |
default: | |
throw new Error("vectorize-text: Unrecoginized textBaseline: '" + baseline + "'") | |
} | |
var scale = 1.0 / size | |
if("lineHeight" in options) { | |
scale *= +options.lineHeight | |
} else if("width" in options) { | |
scale = options.width / (hi[0] - lo[0]) | |
} else if("height" in options) { | |
scale = options.height / (hi[1] - lo[1]) | |
} | |
return positions.map(function(p) { | |
return [ scale * (p[0] + xShift), scale * (p[1] + yShift) ] | |
}) | |
} | |
function getPixels(canvas, context, str, size) { | |
var width = Math.ceil(context.measureText(str).width + 2*size)|0 | |
if(width > 8192) { | |
throw new Error("vectorize-text: String too long (sorry, this will get fixed later)") | |
} | |
var height = 3 * size | |
if(canvas.height < height) { | |
canvas.height = height | |
} | |
context.fillStyle = "#000" | |
context.fillRect(0, 0, canvas.width, canvas.height) | |
context.fillStyle = "#fff" | |
context.fillText(str, size, 2*size) | |
//Cut pixels from image | |
var pixelData = context.getImageData(0, 0, width, height) | |
var pixels = ndarray(pixelData.data, [height, width, 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<result.length; ++i) { | |
var loops = result[i] | |
var nloops = new Array(loops.length) | |
for(var j=0; j<loops.length; ++j) { | |
var loop = loops[j] | |
var nloop = new Array(loop.length) | |
for(var k=0; k<loop.length; ++k) { | |
nloop[k] = positions[loop[k]].slice() | |
} | |
if(flip) { | |
nloop.reverse() | |
} | |
nloops[j] = nloop | |
} | |
nresult[i] = nloops | |
} | |
return nresult | |
} else if(options.triangles || options.triangulate || options.triangle) { | |
return { | |
cells: cdt2d(positions, edges, { | |
delaunay: false, | |
exterior: false, | |
interior: true | |
}), | |
positions: positions | |
} | |
} else { | |
return { | |
edges: edges, | |
positions: positions | |
} | |
} | |
} | |
function processPixels(pixels, options, size) { | |
try { | |
return processPixelsImpl(pixels, options, size, true) | |
} catch(e) {} | |
try { | |
return processPixelsImpl(pixels, options, size, false) | |
} catch(e) {} | |
if(options.polygons || options.polyline || options.polygon) { | |
return [] | |
} | |
if(options.triangles || options.triangulate || options.triangle) { | |
return { | |
cells: [], | |
positions: [] | |
} | |
} | |
return { | |
edges: [], | |
positions: [] | |
} | |
} | |
function vectorizeText(str, canvas, context, options) { | |
var size = options.size || 64 | |
var family = options.font || "normal" | |
context.font = size + "px " + family | |
context.textAlign = "start" | |
context.textBaseline = "alphabetic" | |
context.direction = "ltr" | |
var pixels = getPixels(canvas, context, str, size) | |
return processPixels(pixels, options, size) | |
} | |
},{"cdt2d":36,"clean-pslg":54,"ndarray":100,"planar-graph-to-polyline":124,"simplify-planar-graph":134,"surface-nets":156}],36:[function(require,module,exports){ | |
'use strict' | |
var monotoneTriangulate = require('./lib/monotone') | |
var makeIndex = require('./lib/triangulation') | |
var delaunayFlip = require('./lib/delaunay') | |
var filterTriangulation = require('./lib/filter') | |
module.exports = cdt2d | |
function canonicalizeEdge(e) { | |
return [Math.min(e[0], e[1]), Math.max(e[0], e[1])] | |
} | |
function compareEdge(a, b) { | |
return a[0]-b[0] || a[1]-b[1] | |
} | |
function canonicalizeEdges(edges) { | |
return edges.map(canonicalizeEdge).sort(compareEdge) | |
} | |
function getDefault(options, property, dflt) { | |
if(property in options) { | |
return options[property] | |
} | |
return dflt | |
} | |
function cdt2d(points, edges, options) { | |
if(!Array.isArray(edges)) { | |
options = edges || {} | |
edges = [] | |
} else { | |
options = options || {} | |
edges = edges || [] | |
} | |
//Parse out options | |
var delaunay = !!getDefault(options, 'delaunay', true) | |
var interior = !!getDefault(options, 'interior', true) | |
var exterior = !!getDefault(options, 'exterior', true) | |
var infinity = !!getDefault(options, 'infinity', false) | |
//Handle trivial case | |
if((!interior && !exterior) || points.length === 0) { | |
return [] | |
} | |
//Construct initial triangulation | |
var cells = monotoneTriangulate(points, edges) | |
//If delaunay refinement needed, then improve quality by edge flipping | |
if(delaunay || interior !== exterior || infinity) { | |
//Index all of the cells to support fast neighborhood queries | |
var triangulation = makeIndex(points.length, canonicalizeEdges(edges)) | |
for(var i=0; i<cells.length; ++i) { | |
var f = cells[i] | |
triangulation.addTriangle(f[0], f[1], f[2]) | |
} | |
//Run edge flipping | |
if(delaunay) { | |
delaunayFlip(points, triangulation) | |
} | |
//Filter points | |
if(!exterior) { | |
return filterTriangulation(triangulation, -1) | |
} else if(!interior) { | |
return filterTriangulation(triangulation, 1, infinity) | |
} else if(infinity) { | |
return filterTriangulation(triangulation, 0, infinity) | |
} else { | |
return triangulation.cells() | |
} | |
} else { | |
return cells | |
} | |
} | |
},{"./lib/delaunay":37,"./lib/filter":38,"./lib/monotone":39,"./lib/triangulation":40}],37:[function(require,module,exports){ | |
'use strict' | |
var inCircle = require('robust-in-sphere')[4] | |
var bsearch = require('binary-search-bounds') | |
module.exports = delaunayRefine | |
function testFlip(points, triangulation, stack, a, b, x) { | |
var y = triangulation.opposite(a, b) | |
//Test boundary edge | |
if(y < 0) { | |
return | |
} | |
//Swap edge if order flipped | |
if(b < a) { | |
var tmp = a | |
a = b | |
b = tmp | |
tmp = x | |
x = y | |
y = tmp | |
} | |
//Test if edge is constrained | |
if(triangulation.isConstraint(a, b)) { | |
return | |
} | |
//Test if edge is delaunay | |
if(inCircle(points[a], points[b], points[x], points[y]) < 0) { | |
stack.push(a, b) | |
} | |
} | |
//Assume edges are sorted lexicographically | |
function delaunayRefine(points, triangulation) { | |
var stack = [] | |
var numPoints = points.length | |
var stars = triangulation.stars | |
for(var a=0; a<numPoints; ++a) { | |
var star = stars[a] | |
for(var j=1; j<star.length; j+=2) { | |
var b = star[j] | |
//If order is not consistent, then skip edge | |
if(b < a) { | |
continue | |
} | |
//Check if edge is constrained | |
if(triangulation.isConstraint(a, b)) { | |
continue | |
} | |
//Find opposite edge | |
var x = star[j-1], y = -1 | |
for(var k=1; k<star.length; k+=2) { | |
if(star[k-1] === b) { | |
y = star[k] | |
break | |
} | |
} | |
//If this is a boundary edge, don't flip it | |
if(y < 0) { | |
continue | |
} | |
//If edge is in circle, flip it | |
if(inCircle(points[a], points[b], points[x], points[y]) < 0) { | |
stack.push(a, b) | |
} | |
} | |
} | |
while(stack.length > 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<star.length; i+=2) { | |
var s = star[i-1] | |
var t = star[i] | |
if(s === b) { | |
y = t | |
} else if(t === b) { | |
x = s | |
} | |
} | |
//If x/y are both valid then skip edge | |
if(x < 0 || y < 0) { | |
continue | |
} | |
//If edge is now delaunay, then don't flip it | |
if(inCircle(points[a], points[b], points[x], points[y]) >= 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) | |
} | |
} | |
},{"binary-search-bounds":41,"robust-in-sphere":42}],38:[function(require,module,exports){ | |
'use strict' | |
var bsearch = require('binary-search-bounds') | |
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<nc; ++i) { | |
var c = cells[i] | |
var x = c[0], y = c[1], z = c[2] | |
if(y < z) { | |
if(y < x) { | |
c[0] = y | |
c[1] = z | |
c[2] = x | |
} | |
} else if(z < x) { | |
c[0] = z | |
c[1] = x | |
c[2] = y | |
} | |
} | |
cells.sort(compareCell) | |
//Initialize flag array | |
var flags = new Array(nc) | |
for(var i=0; i<flags.length; ++i) { | |
flags[i] = 0 | |
} | |
//Build neighbor index, initialize queues | |
var active = [] | |
var next = [] | |
var neighbor = new Array(3*nc) | |
var constraint = new Array(3*nc) | |
var boundary = null | |
if(infinity) { | |
boundary = [] | |
} | |
var index = new FaceIndex( | |
cells, | |
neighbor, | |
constraint, | |
flags, | |
active, | |
next, | |
boundary) | |
for(var i=0; i<nc; ++i) { | |
var c = cells[i] | |
for(var j=0; j<3; ++j) { | |
var x = c[j], y = c[(j+1)%3] | |
var a = neighbor[3*i+j] = index.locate(y, x, triangulation.opposite(y, x)) | |
var b = constraint[3*i+j] = triangulation.isConstraint(x, y) | |
if(a < 0) { | |
if(b) { | |
next.push(i) | |
} else { | |
active.push(i) | |
flags[i] = 1 | |
} | |
if(infinity) { | |
boundary.push([y, x, -1]) | |
} | |
} | |
} | |
} | |
return index | |
} | |
function filterCells(cells, flags, target) { | |
var ptr = 0 | |
for(var i=0; i<cells.length; ++i) { | |
if(flags[i] === target) { | |
cells[ptr++] = cells[i] | |
} | |
} | |
cells.length = ptr | |
return cells | |
} | |
function classifyFaces(triangulation, target, infinity) { | |
var index = indexCells(triangulation, infinity) | |
if(target === 0) { | |
if(infinity) { | |
return index.cells.concat(index.boundary) | |
} else { | |
return index.cells | |
} | |
} | |
var side = 1 | |
var active = index.active | |
var next = index.next | |
var flags = index.flags | |
var cells = index.cells | |
var constraint = index.constraint | |
var neighbor = index.neighbor | |
while(active.length > 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 | |
} | |
},{"binary-search-bounds":41}],39:[function(require,module,exports){ | |
'use strict' | |
var bsearch = require('binary-search-bounds') | |
var orient = require('robust-orientation')[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<hi; ++i) { | |
var hull = hulls[i] | |
//Insert p into lower hull | |
var lowerIds = hull.lowerIds | |
var m = lowerIds.length | |
while(m > 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<numPoints; ++i) { | |
events.push(new Event( | |
points[i], | |
null, | |
EVENT_POINT, | |
i)) | |
} | |
//Create edge events | |
for(var i=0; i<numEdges; ++i) { | |
var e = edges[i] | |
var a = points[e[0]] | |
var b = points[e[1]] | |
if(a[0] < b[0]) { | |
events.push( | |
new Event(a, b, EVENT_START, i), | |
new Event(b, a, EVENT_END, i)) | |
} else if(a[0] > 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<numEvents; ++i) { | |
var event = events[i] | |
var type = event.type | |
if(type === EVENT_POINT) { | |
addPoint(cells, hull, points, event.a, event.idx) | |
} else if(type === EVENT_START) { | |
splitHulls(hull, points, event) | |
} else { | |
mergeHulls(hull, points, event) | |
} | |
} | |
//Return triangulation | |
return cells | |
} | |
},{"binary-search-bounds":41,"robust-orientation":53}],40:[function(require,module,exports){ | |
'use strict' | |
var bsearch = require('binary-search-bounds') | |
module.exports = createTriangulation | |
function Triangulation(stars, edges) { | |
this.stars = stars | |
this.edges = edges | |
} | |
var proto = Triangulation.prototype | |
function removePair(list, j, k) { | |
for(var i=1, n=list.length; i<n; i+=2) { | |
if(list[i-1] === j && list[i] === k) { | |
list[i-1] = list[n-2] | |
list[i] = list[n-1] | |
list.length = n - 2 | |
return | |
} | |
} | |
} | |
proto.isConstraint = (function() { | |
var e = [0,0] | |
function compareLex(a, b) { | |
return a[0] - b[0] || a[1] - b[1] | |
} | |
return function(i, j) { | |
e[0] = Math.min(i,j) | |
e[1] = Math.max(i,j) | |
return bsearch.eq(this.edges, e, compareLex) >= 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<n; k+=2) { | |
if(list[k] === j) { | |
return list[k-1] | |
} | |
} | |
return -1 | |
} | |
proto.flip = function(i, j) { | |
var a = this.opposite(i, j) | |
var b = this.opposite(j, i) | |
this.removeTriangle(i, j, a) | |
this.removeTriangle(j, i, b) | |
this.addTriangle(i, b, a) | |
this.addTriangle(j, a, b) | |
} | |
proto.edges = function() { | |
var stars = this.stars | |
var result = [] | |
for(var i=0, n=stars.length; i<n; ++i) { | |
var list = stars[i] | |
for(var j=0, m=list.length; j<m; j+=2) { | |
result.push([list[j], list[j+1]]) | |
} | |
} | |
return result | |
} | |
proto.cells = function() { | |
var stars = this.stars | |
var result = [] | |
for(var i=0, n=stars.length; i<n; ++i) { | |
var list = stars[i] | |
for(var j=0, m=list.length; j<m; j+=2) { | |
var s = list[j] | |
var t = list[j+1] | |
if(i < Math.min(s, t)) { | |
result.push([i, s, t]) | |
} | |
} | |
} | |
return result | |
} | |
function createTriangulation(numVerts, edges) { | |
var stars = new Array(numVerts) | |
for(var i=0; i<numVerts; ++i) { | |
stars[i] = [] | |
} | |
return new Triangulation(stars, edges) | |
} | |
},{"binary-search-bounds":41}],41:[function(require,module,exports){ | |
"use strict" | |
function compileSearch(funcName, predicate, reversed, extraArgs, earlyOut) { | |
var code = [ | |
"function ", funcName, "(a,l,h,", extraArgs.join(","), "){", | |
earlyOut ? "" : "var i=", (reversed ? "l-1" : "h+1"), | |
";while(l<=h){\ | |
var m=(l+h)>>>1,x=a[m]"] | |
if(earlyOut) { | |
if(predicate.indexOf("c") < 0) { | |
code.push(";if(x===y){return m}else if(x<=y){") | |
} else { | |
code.push(";var p=c(x,y);if(p===0){return m}else if(p<=0){") | |
} | |
} else { | |
code.push(";if(", predicate, "){i=m;") | |
} | |
if(reversed) { | |
code.push("l=m+1}else{h=m-1}") | |
} else { | |
code.push("h=m-1}else{l=m+1}") | |
} | |
code.push("}") | |
if(earlyOut) { | |
code.push("return -1};") | |
} else { | |
code.push("return i};") | |
} | |
return code.join("") | |
} | |
function compileBoundsSearch(predicate, reversed, suffix, earlyOut) { | |
var result = new Function([ | |
compileSearch("A", "x" + predicate + "y", reversed, ["y"], earlyOut), | |
compileSearch("P", "c(x,y)" + predicate + "0", reversed, ["y", "c"], earlyOut), | |
"function dispatchBsearch", suffix, "(a,y,c,l,h){\ | |
if(typeof(c)==='function'){\ | |
return P(a,(l===void 0)?0:l|0,(h===void 0)?a.length-1:h|0,y,c)\ | |
}else{\ | |
return A(a,(c===void 0)?0:c|0,(l===void 0)?a.length-1:l|0,y)\ | |
}}\ | |
return dispatchBsearch", suffix].join("")) | |
return result() | |
} | |
module.exports = { | |
ge: compileBoundsSearch(">=", false, "GE"), | |
gt: compileBoundsSearch(">", false, "GT"), | |
lt: compileBoundsSearch("<", true, "LT"), | |
le: compileBoundsSearch("<=", true, "LE"), | |
eq: compileBoundsSearch("-", true, "EQ", true) | |
} | |
},{}],42:[function(require,module,exports){ | |
"use strict" | |
var twoProduct = require("two-product") | |
var robustSum = require("robust-sum") | |
var robustDiff = require("robust-subtract") | |
var robustScale = require("robust-scale") | |
var NUM_EXPAND = 6 | |
function cofactor(m, c) { | |
var result = new Array(m.length-1) | |
for(var i=1; i<m.length; ++i) { | |
var r = result[i-1] = new Array(m.length-1) | |
for(var j=0,k=0; j<m.length; ++j) { | |
if(j === c) { | |
continue | |
} | |
r[k++] = m[i][j] | |
} | |
} | |
return result | |
} | |
function matrix(n) { | |
var result = new Array(n) | |
for(var i=0; i<n; ++i) { | |
result[i] = new Array(n) | |
for(var j=0; j<n; ++j) { | |
result[i][j] = ["m", j, "[", (n-i-2), "]"].join("") | |
} | |
} | |
return result | |
} | |
function generateSum(expr) { | |
if(expr.length === 1) { | |
return expr[0] | |
} else if(expr.length === 2) { | |
return ["sum(", expr[0], ",", expr[1], ")"].join("") | |
} else { | |
var m = expr.length>>1 | |
return ["sum(", generateSum(expr.slice(0, m)), ",", generateSum(expr.slice(m)), ")"].join("") | |
} | |
} | |
function makeProduct(a, b) { | |
if(a.charAt(0) === "m") { | |
if(b.charAt(0) === "w") { | |
var toks = a.split("[") | |
return ["w", b.substr(1), "m", toks[0].substr(1)].join("") | |
} else { | |
return ["prod(", a, ",", b, ")"].join("") | |
} | |
} else { | |
return makeProduct(b, a) | |
} | |
} | |
function sign(s) { | |
if(s & 1 !== 0) { | |
return "-" | |
} | |
return "" | |
} | |
function determinant(m) { | |
if(m.length === 2) { | |
return [["diff(", makeProduct(m[0][0], m[1][1]), ",", makeProduct(m[1][0], m[0][1]), ")"].join("")] | |
} else { | |
var expr = [] | |
for(var i=0; i<m.length; ++i) { | |
expr.push(["scale(", generateSum(determinant(cofactor(m, i))), ",", sign(i), m[0][i], ")"].join("")) | |
} | |
return expr | |
} | |
} | |
function makeSquare(d, n) { | |
var terms = [] | |
for(var i=0; i<n-2; ++i) { | |
terms.push(["prod(m", d, "[", i, "],m", d, "[", i, "])"].join("")) | |
} | |
return generateSum(terms) | |
} | |
function orientation(n) { | |
var pos = [] | |
var neg = [] | |
var m = matrix(n) | |
for(var i=0; i<n; ++i) { | |
m[0][i] = "1" | |
m[n-1][i] = "w"+i | |
} | |
for(var i=0; i<n; ++i) { | |
if((i&1)===0) { | |
pos.push.apply(pos,determinant(cofactor(m, i))) | |
} else { | |
neg.push.apply(neg,determinant(cofactor(m, i))) | |
} | |
} | |
var posExpr = generateSum(pos) | |
var negExpr = generateSum(neg) | |
var funcName = "exactInSphere" + n | |
var funcArgs = [] | |
for(var i=0; i<n; ++i) { | |
funcArgs.push("m" + i) | |
} | |
var code = ["function ", funcName, "(", funcArgs.join(), "){"] | |
for(var i=0; i<n; ++i) { | |
code.push("var w",i,"=",makeSquare(i,n),";") | |
for(var j=0; j<n; ++j) { | |
if(j !== i) { | |
code.push("var w",i,"m",j,"=scale(w",i,",m",j,"[0]);") | |
} | |
} | |
} | |
code.push("var p=", posExpr, ",n=", negExpr, ",d=diff(p,n);return d[d.length-1];}return ", funcName) | |
var proc = new Function("sum", "diff", "prod", "scale", code.join("")) | |
return proc(robustSum, robustDiff, twoProduct, robustScale) | |
} | |
function inSphere0() { return 0 } | |
function inSphere1() { return 0 } | |
function inSphere2() { return 0 } | |
var CACHED = [ | |
inSphere0, | |
inSphere1, | |
inSphere2 | |
] | |
function slowInSphere(args) { | |
var proc = CACHED[args.length] | |
if(!proc) { | |
proc = CACHED[args.length] = orientation(args.length) | |
} | |
return proc.apply(undefined, args) | |
} | |
function generateInSphereTest() { | |
while(CACHED.length <= NUM_EXPAND) { | |
CACHED.push(orientation(CACHED.length)) | |
} | |
var args = [] | |
var procArgs = ["slow"] | |
for(var i=0; i<=NUM_EXPAND; ++i) { | |
args.push("a" + i) | |
procArgs.push("o" + i) | |
} | |
var code = [ | |
"function testInSphere(", args.join(), "){switch(arguments.length){case 0:case 1:return 0;" | |
] | |
for(var i=2; i<=NUM_EXPAND; ++i) { | |
code.push("case ", i, ":return o", i, "(", args.slice(0, i).join(), ");") | |
} | |
code.push("}var s=new Array(arguments.length);for(var i=0;i<arguments.length;++i){s[i]=arguments[i]};return slow(s);}return testInSphere") | |
procArgs.push(code.join("")) | |
var proc = Function.apply(undefined, procArgs) | |
module.exports = proc.apply(undefined, [slowInSphere].concat(CACHED)) | |
for(var i=0; i<=NUM_EXPAND; ++i) { | |
module.exports[i] = CACHED[i] | |
} | |
} | |
generateInSphereTest() | |
},{"robust-scale":44,"robust-subtract":45,"robust-sum":46,"two-product":47}],43:[function(require,module,exports){ | |
"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] | |
} | |
},{}],44:[function(require,module,exports){ | |
"use strict" | |
var twoProduct = require("two-product") | |
var twoSum = require("two-sum") | |
module.exports = scaleLinearExpansion | |
function scaleLinearExpansion(e, scale) { | |
var n = e.length | |
if(n === 1) { | |
var ts = twoProduct(e[0], scale) | |
if(ts[0]) { | |
return ts | |
} | |
return [ ts[1] ] | |
} | |
var g = new Array(2 * n) | |
var q = [0.1, 0.1] | |
var t = [0.1, 0.1] | |
var count = 0 | |
twoProduct(e[0], scale, q) | |
if(q[0]) { | |
g[count++] = q[0] | |
} | |
for(var i=1; i<n; ++i) { | |
twoProduct(e[i], scale, t) | |
var pq = q[1] | |
twoSum(pq, t[0], q) | |
if(q[0]) { | |
g[count++] = q[0] | |
} | |
var a = t[1] | |
var b = q[1] | |
var x = a + b | |
var bv = x - a | |
var y = b - bv | |
q[1] = x | |
if(y) { | |
g[count++] = y | |
} | |
} | |
if(q[1]) { | |
g[count++] = q[1] | |
} | |
if(count === 0) { | |
g[count++] = 0.0 | |
} | |
g.length = count | |
return g | |
} | |
},{"two-product":47,"two-sum":43}],45:[function(require,module,exports){ | |
"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 | |
} | |
},{}],46:[function(require,module,exports){ | |
"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 | |
} | |
},{}],47:[function(require,module,exports){ | |
"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 ] | |
} | |
},{}],48:[function(require,module,exports){ | |
arguments[4][43][0].apply(exports,arguments) | |
},{"dup":43}],49:[function(require,module,exports){ | |
arguments[4][44][0].apply(exports,arguments) | |
},{"dup":44,"two-product":52,"two-sum":48}],50:[function(require,module,exports){ | |
arguments[4][45][0].apply(exports,arguments) | |
},{"dup":45}],51:[function(require,module,exports){ | |
arguments[4][46][0].apply(exports,arguments) | |
},{"dup":46}],52:[function(require,module,exports){ | |
arguments[4][47][0].apply(exports,arguments) | |
},{"dup":47}],53:[function(require,module,exports){ | |
"use strict" | |
var twoProduct = require("two-product") | |
var robustSum = require("robust-sum") | |
var robustScale = require("robust-scale") | |
var robustSubtract = require("robust-subtract") | |
var NUM_EXPAND = 5 | |
var EPSILON = 1.1102230246251565e-16 | |
var ERRBOUND3 = (3.0 + 16.0 * EPSILON) * EPSILON | |
var ERRBOUND4 = (7.0 + 56.0 * EPSILON) * EPSILON | |
function cofactor(m, c) { | |
var result = new Array(m.length-1) | |
for(var i=1; i<m.length; ++i) { | |
var r = result[i-1] = new Array(m.length-1) | |
for(var j=0,k=0; j<m.length; ++j) { | |
if(j === c) { | |
continue | |
} | |
r[k++] = m[i][j] | |
} | |
} | |
return result | |
} | |
function matrix(n) { | |
var result = new Array(n) | |
for(var i=0; i<n; ++i) { | |
result[i] = new Array(n) | |
for(var j=0; j<n; ++j) { | |
result[i][j] = ["m", j, "[", (n-i-1), "]"].join("") | |
} | |
} | |
return result | |
} | |
function sign(n) { | |
if(n & 1) { | |
return "-" | |
} | |
return "" | |
} | |
function generateSum(expr) { | |
if(expr.length === 1) { | |
return expr[0] | |
} else if(expr.length === 2) { | |
return ["sum(", expr[0], ",", expr[1], ")"].join("") | |
} else { | |
var m = expr.length>>1 | |
return ["sum(", generateSum(expr.slice(0, m)), ",", generateSum(expr.slice(m)), ")"].join("") | |
} | |
} | |
function determinant(m) { | |
if(m.length === 2) { | |
return [["sum(prod(", m[0][0], ",", m[1][1], "),prod(-", m[0][1], ",", m[1][0], "))"].join("")] | |
} else { | |
var expr = [] | |
for(var i=0; i<m.length; ++i) { | |
expr.push(["scale(", generateSum(determinant(cofactor(m, i))), ",", sign(i), m[0][i], ")"].join("")) | |
} | |
return expr | |
} | |
} | |
function orientation(n) { | |
var pos = [] | |
var neg = [] | |
var m = matrix(n) | |
var args = [] | |
for(var i=0; i<n; ++i) { | |
if((i&1)===0) { | |
pos.push.apply(pos, determinant(cofactor(m, i))) | |
} else { | |
neg.push.apply(neg, determinant(cofactor(m, i))) | |
} | |
args.push("m" + i) | |
} | |
var posExpr = generateSum(pos) | |
var negExpr = generateSum(neg) | |
var funcName = "orientation" + n + "Exact" | |
var code = ["function ", funcName, "(", args.join(), "){var p=", posExpr, ",n=", negExpr, ",d=sub(p,n);\ | |
return d[d.length-1];};return ", funcName].join("") | |
var proc = new Function("sum", "prod", "scale", "sub", code) | |
return proc(robustSum, twoProduct, robustScale, robustSubtract) | |
} | |
var orientation3Exact = orientation(3) | |
var orientation4Exact = orientation(4) | |
var CACHED = [ | |
function orientation0() { return 0 }, | |
function orientation1() { return 0 }, | |
function orientation2(a, b) { | |
return b[0] - a[0] | |
}, | |
function orientation3(a, b, c) { | |
var l = (a[1] - c[1]) * (b[0] - c[0]) | |
var r = (a[0] - c[0]) * (b[1] - c[1]) | |
var det = l - r | |
var s | |
if(l > 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 generateOrientationProc() { | |
while(CACHED.length <= NUM_EXPAND) { | |
CACHED.push(orientation(CACHED.length)) | |
} | |
var args = [] | |
var procArgs = ["slow"] | |
for(var i=0; i<=NUM_EXPAND; ++i) { | |
args.push("a" + i) | |
procArgs.push("o" + i) | |
} | |
var code = [ | |
"function getOrientation(", args.join(), "){switch(arguments.length){case 0:case 1:return 0;" | |
] | |
for(var i=2; i<=NUM_EXPAND; ++i) { | |
code.push("case ", i, ":return o", i, "(", args.slice(0, i).join(), ");") | |
} | |
code.push("}var s=new Array(arguments.length);for(var i=0;i<arguments.length;++i){s[i]=arguments[i]};return slow(s);}return getOrientation") | |
procArgs.push(code.join("")) | |
var proc = Function.apply(undefined, procArgs) | |
module.exports = proc.apply(undefined, [slowOrient].concat(CACHED)) | |
for(var i=0; i<=NUM_EXPAND; ++i) { | |
module.exports[i] = CACHED[i] | |
} | |
} | |
generateOrientationProc() | |
},{"robust-scale":49,"robust-subtract":50,"robust-sum":51,"two-product":52}],54:[function(require,module,exports){ | |
'use strict' | |
module.exports = cleanPSLG | |
var UnionFind = require('union-find') | |
var boxIntersect = require('box-intersect') | |
var compareCell = require('compare-cell') | |
var segseg = require('robust-segment-intersect') | |
var rat = require('big-rat') | |
var ratCmp = require('big-rat/cmp') | |
var ratToFloat = require('big-rat/to-float') | |
var ratVec = require('rat-vec') | |
var nextafter = require('nextafter') | |
var solveIntersection = require('./lib/rat-seg-intersect') | |
//Bounds on a rational number when rounded to a float | |
function boundRat(r) { | |
var f = ratToFloat(r) | |
var cmp = ratCmp(rat(f), r) | |
if(cmp < 0) { | |
return [f, nextafter(f, Infinity)] | |
} else if(cmp > 0) { | |
return [nextafter(f, -Infinity), f] | |
} else { | |
return [f, f] | |
} | |
} | |
//Convert a list of edges in a pslg to bounding boxes | |
function boundEdges(points, edges) { | |
var bounds = new Array(edges.length) | |
for(var i=0; i<edges.length; ++i) { | |
var e = edges[i] | |
var a = points[e[0]] | |
var b = points[e[1]] | |
bounds[i] = [ | |
Math.min(a[0], b[0]), | |
Math.min(a[1], b[1]), | |
Math.max(a[0], b[0]), | |
Math.max(a[1], b[1]) ] | |
} | |
return bounds | |
} | |
//Convert a list of points into bounding boxes by duplicating coords | |
function boundPoints(points) { | |
var bounds = new Array(points.length) | |
for(var i=0; i<points.length; ++i) { | |
var p = points[i] | |
bounds[i] = [ p[0], p[1], p[0], p[1] ] | |
} | |
return bounds | |
} | |
//Find all pairs of crossing edges in a pslg (given edge bounds) | |
function getCrossings(points, edges, edgeBounds) { | |
var result = [] | |
boxIntersect(edgeBounds, function(i, j) { | |
var e = edges[i] | |
var f = edges[j] | |
if(e[0] === f[0] || e[0] === f[1] || | |
e[1] === f[0] || e[1] === f[1]) { | |
return | |
} | |
var a = points[e[0]] | |
var b = points[e[1]] | |
var c = points[f[0]] | |
var d = points[f[1]] | |
if(segseg(a, b, c, d)) { | |
result.push([i, j]) | |
} | |
}) | |
return result | |
} | |
//Find all pairs of crossing vertices in a pslg (given edge/vert bounds) | |
function getTJunctions(points, edges, edgeBounds, vertBounds) { | |
var result = [] | |
boxIntersect(edgeBounds, vertBounds, function(i, v) { | |
var e = edges[i] | |
if(e[0] === v || e[1] === v) { | |
return | |
} | |
var p = points[v] | |
var a = points[e[0]] | |
var b = points[e[1]] | |
if(segseg(a, b, p, p)) { | |
result.push([i, v]) | |
} | |
}) | |
return result | |
} | |
//Cut edges along crossings/tjunctions | |
function cutEdges(floatPoints, edges, crossings, junctions, useColor) { | |
//Convert crossings into tjunctions by constructing rational points | |
var ratPoints = [] | |
for(var i=0; i<crossings.length; ++i) { | |
var crossing = crossings[i] | |
var e = crossing[0] | |
var f = crossing[1] | |
var ee = edges[e] | |
var ef = edges[f] | |
var x = solveIntersection( | |
ratVec(floatPoints[ee[0]]), | |
ratVec(floatPoints[ee[1]]), | |
ratVec(floatPoints[ef[0]]), | |
ratVec(floatPoints[ef[1]])) | |
if(!x) { | |
//Segments are parallel, should already be handled by t-junctions | |
continue | |
} | |
var idx = ratPoints.length + floatPoints.length | |
ratPoints.push(x) | |
junctions.push([e, idx], [f, idx]) | |
} | |
//Sort tjunctions | |
function getPoint(idx) { | |
if(idx >= floatPoints.length) { | |
return ratPoints[idx-floatPoints.length] | |
} | |
var p = floatPoints[idx] | |
return [ rat(p[0]), rat(p[1]) ] | |
} | |
junctions.sort(function(a, b) { | |
if(a[0] !== b[0]) { | |
return a[0] - b[0] | |
} | |
var u = getPoint(a[1]) | |
var v = getPoint(b[1]) | |
return ratCmp(u[0], v[0]) || ratCmp(u[1], v[1]) | |
}) | |
//Split edges along junctions | |
for(var i=junctions.length-1; i>=0; --i) { | |
var junction = junctions[i] | |
var 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 = floatPoints.length + ratPoints.length | |
var uf = new UnionFind(numPoints) | |
//Compute rational bounds | |
var bounds = floatBounds | |
for(var i=0; i<ratPoints.length; ++i) { | |
var p = ratPoints[i] | |
var xb = boundRat(p[0]) | |
var yb = boundRat(p[1]) | |
bounds.push([ xb[0], yb[0], xb[1], yb[1] ]) | |
floatPoints.push([ ratToFloat(p[0]), ratToFloat(p[1]) ]) | |
} | |
//Link all points with over lapping boxes | |
boxIntersect(bounds, function(i, j) { | |
uf.link(i, j) | |
}) | |
//Call find on each point to get a relabeling | |
var ptr = 0 | |
var noDupes = true | |
var labels = new Array(numPoints) | |
for(var i=0; i<numPoints; ++i) { | |
var j = uf.find(i) | |
if(j === i) { | |
//If not a duplicate, then don't bother | |
labels[i] = ptr | |
floatPoints[ptr++] = floatPoints[i] | |
} else { | |
//Clear no-dupes flag, zero out label | |
noDupes = false | |
labels[i] = -1 | |
} | |
} | |
floatPoints.length = ptr | |
//If no duplicates, return null to signal termination | |
if(noDupes) { | |
return null | |
} | |
//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 | |
} | |
//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) | |
// 6. dedupe edges | |
dedupEdges(edges, labels, useColor) | |
// 5. 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) { | |
var modified = false | |
//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 | |
} | |
//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 | |
} | |
},{"./lib/rat-seg-intersect":55,"big-rat":59,"big-rat/cmp":57,"big-rat/to-float":74,"box-intersect":75,"compare-cell":85,"nextafter":86,"rat-vec":89,"robust-segment-intersect":98,"union-find":99}],55:[function(require,module,exports){ | |
'use strict' | |
//TODO: Move this to a separate module | |
module.exports = solveIntersection | |
var ratMul = require('big-rat/mul') | |
var ratDiv = require('big-rat/div') | |
var ratSub = require('big-rat/sub') | |
var ratSign = require('big-rat/sign') | |
var rvSub = require('rat-vec/sub') | |
var rvAdd = require('rat-vec/add') | |
var rvMuls = require('rat-vec/muls') | |
var toFloat = require('big-rat/to-float') | |
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) | |
return rvAdd(a, rvMuls(ba, t)) | |
} | |
},{"big-rat/div":58,"big-rat/mul":68,"big-rat/sign":72,"big-rat/sub":73,"big-rat/to-float":74,"rat-vec/add":88,"rat-vec/muls":90,"rat-vec/sub":91}],56:[function(require,module,exports){ | |
'use strict' | |
var rationalize = require('./lib/rationalize') | |
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])) | |
} | |
},{"./lib/rationalize":66}],57:[function(require,module,exports){ | |
'use strict' | |
module.exports = cmp | |
function cmp(a, b) { | |
return a[0].mul(b[1]).cmp(b[0].mul(a[1])) | |
} | |
},{}],58:[function(require,module,exports){ | |
'use strict' | |
var rationalize = require('./lib/rationalize') | |
module.exports = div | |
function div(a, b) { | |
return rationalize(a[0].mul(b[1]), a[1].mul(b[0])) | |
} | |
},{"./lib/rationalize":66}],59:[function(require,module,exports){ | |
'use strict' | |
var isRat = require('./is-rat') | |
var isBN = require('./lib/is-bn') | |
var num2bn = require('./lib/num-to-bn') | |
var str2bn = require('./lib/str-to-bn') | |
var rationalize = require('./lib/rationalize') | |
var div = require('./div') | |
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.shln(shift) | |
} else if(shift < 0) { | |
b = b.shln(-shift) | |
} | |
return rationalize(a, b) | |
} | |
},{"./div":58,"./is-rat":60,"./lib/is-bn":64,"./lib/num-to-bn":65,"./lib/rationalize":66,"./lib/str-to-bn":67}],60:[function(require,module,exports){ | |
'use strict' | |
var isBN = require('./lib/is-bn') | |
module.exports = isRat | |
function isRat(x) { | |
return Array.isArray(x) && x.length === 2 && isBN(x[0]) && isBN(x[1]) | |
} | |
},{"./lib/is-bn":64}],61:[function(require,module,exports){ | |
'use strict' | |
var bn = require('bn.js') | |
module.exports = sign | |
function sign(x) { | |
return x.cmp(new bn(0)) | |
} | |
},{"bn.js":70}],62:[function(require,module,exports){ | |
'use strict' | |
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 { | |
var out = 0 | |
for (var i = 0; i < l; i++) { | |
var w = words[i] | |
out += w * Math.pow(0x4000000, i) | |
} | |
} | |
return b.sign ? -out : out | |
} | |
},{}],63:[function(require,module,exports){ | |
'use strict' | |
var db = require('double-bits') | |
var ctz = require('bit-twiddle').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 | |
} | |
},{"bit-twiddle":69,"double-bits":71}],64:[function(require,module,exports){ | |
'use strict' | |
var BN = require('bn.js') | |
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) | |
} | |
},{"bn.js":70}],65:[function(require,module,exports){ | |
'use strict' | |
var BN = require('bn.js') | |
var db = require('double-bits') | |
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))).shln(e-52) | |
} | |
} | |
},{"bn.js":70,"double-bits":71}],66:[function(require,module,exports){ | |
'use strict' | |
var num2bn = require('./num-to-bn') | |
var sign = require('./bn-sign') | |
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 ] | |
} | |
},{"./bn-sign":61,"./num-to-bn":65}],67:[function(require,module,exports){ | |
'use strict' | |
var BN = require('bn.js') | |
module.exports = str2BN | |
function str2BN(x) { | |
return new BN(x) | |
} | |
},{"bn.js":70}],68:[function(require,module,exports){ | |
'use strict' | |
var rationalize = require('./lib/rationalize') | |
module.exports = mul | |
function mul(a, b) { | |
return rationalize(a[0].mul(b[0]), a[1].mul(b[1])) | |
} | |
},{"./lib/rationalize":66}],69:[function(require,module,exports){ | |
arguments[4][15][0].apply(exports,arguments) | |
},{"dup":15}],70:[function(require,module,exports){ | |
(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) { | |
// May be `new BN(bn)` ? | |
if (number !== null && | |
typeof number === 'object' && | |
Array.isArray(number.words)) { | |
return number; | |
} | |
this.sign = false; | |
this.words = null; | |
this.length = 0; | |
// Reduction context | |
this.red = null; | |
if (base === 'le' || base === 'be') { | |
endian = base; | |
base = 10; | |
} | |
if (number !== null) | |
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; | |
BN.prototype._init = function init(number, base, endian) { | |
if (typeof number === 'number') { | |
return this._initNumber(number, base, endian); | |
} else 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++; | |
if (base === 16) | |
this._parseHex(number, start); | |
else | |
this._parseBase(number, base, start); | |
if (number[0] === '-') | |
this.sign = true; | |
this.strip(); | |
if (endian !== 'le') | |
return; | |
this._initArray(this.toArray(), base, endian); | |
}; | |
BN.prototype._initNumber = function _initNumber(number, base, endian) { | |
if (number < 0) { | |
this.sign = true; | |
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 off = 0; | |
if (endian === 'be') { | |
for (var i = number.length - 1, j = 0; i >= 0; i -= 3) { | |
var 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 (var i = 0, j = 0; i < number.length; i += 3) { | |
var 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 parseHex(str, start, end) { | |
var r = 0; | |
var len = Math.min(str.length, end); | |
for (var i = start; i < len; i++) { | |
var c = str.charCodeAt(i) - 48; | |
r <<= 4; | |
// 'a' - 'f' | |
if (c >= 49 && c <= 54) | |
r |= c - 49 + 0xa; | |
// 'A' - 'F' | |
else if (c >= 17 && c <= 22) | |
r |= c - 17 + 0xa; | |
// '0' - '9' | |
else | |
r |= c & 0xf; | |
} | |
return r; | |
} | |
BN.prototype._parseHex = function _parseHex(number, start) { | |
// 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; | |
// Scan 24-bit chunks and add them to the number | |
var off = 0; | |
for (var i = number.length - 6, j = 0; i >= start; i -= 6) { | |
var w = parseHex(number, i, i + 6); | |
this.words[j] |= (w << off) & 0x3ffffff; | |
this.words[j + 1] |= w >>> (26 - off) & 0x3fffff; | |
off += 24; | |
if (off >= 26) { | |
off -= 26; | |
j++; | |
} | |
} | |
if (i + 6 !== start) { | |
var w = parseHex(number, start, i + 6); | |
this.words[j] |= (w << off) & 0x3ffffff; | |
this.words[j + 1] |= w >>> (26 - off) & 0x3fffff; | |
} | |
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; | |
var word = parseBase(number, i, number.length, base); | |
for (var i = 0; i < mod; i++) | |
pow *= base; | |
this.imuln(pow); | |
if (this.words[0] + word < 0x4000000) | |
this.words[0] += word; | |
else | |
this._iaddn(word); | |
} | |
}; | |
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.sign = this.sign; | |
dest.red = this.red; | |
}; | |
BN.prototype.clone = function clone() { | |
var r = new BN(null); | |
this.copy(r); | |
return r; | |
}; | |
// 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.sign = false; | |
return this; | |
}; | |
BN.prototype.inspect = function inspect() { | |
return (this.red ? '<BN-R: ' : '<BN: ') + this.toString(16) + '>'; | |
}; | |
/* | |
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; | |
if (base === 16 || base === 'hex') { | |
var out = ''; | |
var off = 0; | |
var padding = padding | 0 || 1; | |
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.sign) | |
out = '-' + out; | |
return out; | |
} else 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]; | |
var out = ''; | |
var c = this.clone(); | |
c.sign = false; | |
while (c.cmpn(0) !== 0) { | |
var r = c.modn(groupBase).toString(base); | |
c = c.idivn(groupBase); | |
if (c.cmpn(0) !== 0) | |
out = zeros[groupSize - r.length] + r + out; | |
else | |
out = r + out; | |
} | |
if (this.cmpn(0) === 0) | |
out = '0' + out; | |
if (this.sign) | |
out = '-' + out; | |
return out; | |
} else { | |
assert(false, 'Base should be between 2 and 36'); | |
} | |
}; | |
BN.prototype.toJSON = function toJSON() { | |
return this.toString(16); | |
}; | |
BN.prototype.toArray = function toArray(endian) { | |
this.strip(); | |
var res = new Array(this.byteLength()); | |
res[0] = 0; | |
var q = this.clone(); | |
if (endian !== 'le') { | |
// Assume big-endian | |
for (var i = 0; q.cmpn(0) !== 0; i++) { | |
var b = q.andln(0xff); | |
q.ishrn(8); | |
res[res.length - i - 1] = b; | |
} | |
} else { | |
// Assume little-endian | |
for (var i = 0; q.cmpn(0) !== 0; i++) { | |
var b = q.andln(0xff); | |
q.ishrn(8); | |
res[i] = b; | |
} | |
} | |
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 hi = 0; | |
var w = this.words[this.length - 1]; | |
var hi = this._countBits(w); | |
return (this.length - 1) * 26 + hi; | |
}; | |
// Number of trailing zero bits | |
BN.prototype.zeroBits = function zeroBits() { | |
if (this.cmpn(0) === 0) | |
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); | |
}; | |
// Return negative clone of `this` | |
BN.prototype.neg = function neg() { | |
if (this.cmpn(0) === 0) | |
return this.clone(); | |
var r = this.clone(); | |
r.sign = !this.sign; | |
return r; | |
}; | |
// Or `num` with `this` in-place | |
BN.prototype.ior = function ior(num) { | |
this.sign = this.sign || num.sign; | |
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(); | |
}; | |
// Or `num` with `this` | |
BN.prototype.or = function or(num) { | |
if (this.length > num.length) | |
return this.clone().ior(num); | |
else | |
return num.clone().ior(this); | |
}; | |
// And `num` with `this` in-place | |
BN.prototype.iand = function iand(num) { | |
this.sign = this.sign && num.sign; | |
// 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(); | |
}; | |
// And `num` with `this` | |
BN.prototype.and = function and(num) { | |
if (this.length > num.length) | |
return this.clone().iand(num); | |
else | |
return num.clone().iand(this); | |
}; | |
// Xor `num` with `this` in-place | |
BN.prototype.ixor = function ixor(num) { | |
this.sign = this.sign || num.sign; | |
// 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(); | |
}; | |
// Xor `num` with `this` | |
BN.prototype.xor = function xor(num) { | |
if (this.length > num.length) | |
return this.clone().ixor(num); | |
else | |
return num.clone().ixor(this); | |
}; | |
// 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; | |
while (this.length <= off) | |
this.words[this.length++] = 0; | |
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) { | |
// negative + positive | |
if (this.sign && !num.sign) { | |
this.sign = false; | |
var r = this.isub(num); | |
this.sign = !this.sign; | |
return this._normSign(); | |
// positive + negative | |
} else if (!this.sign && num.sign) { | |
num.sign = false; | |
var r = this.isub(num); | |
num.sign = true; | |
return r._normSign(); | |
} | |
// a.length > b.length | |
var a; | |
var 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++) { | |
var r = a.words[i] + b.words[i] + carry; | |
this.words[i] = r & 0x3ffffff; | |
carry = r >>> 26; | |
} | |
for (; carry !== 0 && i < a.length; i++) { | |
var r = a.words[i] + 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) { | |
if (num.sign && !this.sign) { | |
num.sign = false; | |
var res = this.sub(num); | |
num.sign = true; | |
return res; | |
} else if (!num.sign && this.sign) { | |
this.sign = false; | |
var res = num.sub(this); | |
this.sign = true; | |
return res; | |
} | |
if (this.length > num.length) | |
return this.clone().iadd(num); | |
else | |
return num.clone().iadd(this); | |
}; | |
// Subtract `num` from `this` in-place | |
BN.prototype.isub = function isub(num) { | |
// this - (-num) = this + num | |
if (num.sign) { | |
num.sign = false; | |
var r = this.iadd(num); | |
num.sign = true; | |
return r._normSign(); | |
// -this - num = -(this + num) | |
} else if (this.sign) { | |
this.sign = false; | |
this.iadd(num); | |
this.sign = true; | |
return this._normSign(); | |
} | |
// At this point both numbers are positive | |
var cmp = this.cmp(num); | |
// Optimization - zeroify | |
if (cmp === 0) { | |
this.sign = false; | |
this.length = 1; | |
this.words[0] = 0; | |
return this; | |
} | |
// a > b | |
var a; | |
var b; | |
if (cmp > 0) { | |
a = this; | |
b = num; | |
} else { | |
a = num; | |
b = this; | |
} | |
var carry = 0; | |
for (var i = 0; i < b.length; i++) { | |
var r = a.words[i] - b.words[i] + carry; | |
carry = r >> 26; | |
this.words[i] = r & 0x3ffffff; | |
} | |
for (; carry !== 0 && i < a.length; i++) { | |
var r = a.words[i] + 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.sign = true; | |
return this.strip(); | |
}; | |
// Subtract `num` from `this` | |
BN.prototype.sub = function sub(num) { | |
return this.clone().isub(num); | |
}; | |
/* | |
// NOTE: This could be potentionally used to generate loop-less multiplications | |
function _genCombMulTo(alen, blen) { | |
var len = alen + blen - 1; | |
var src = [ | |
'var a = this.words, b = num.words, o = out.words, c = 0, w, ' + | |
'mask = 0x3ffffff, shift = 0x4000000;', | |
'out.length = ' + len + ';' | |
]; | |
for (var k = 0; k < len; k++) { | |
var minJ = Math.max(0, k - alen + 1); | |
var maxJ = Math.min(k, blen - 1); | |
for (var j = minJ; j <= maxJ; j++) { | |
var i = k - j; | |
var mul = 'a[' + i + '] * b[' + j + ']'; | |
if (j === minJ) { | |
src.push('w = ' + mul + ' + c;'); | |
src.push('c = (w / shift) | 0;'); | |
} else { | |
src.push('w += ' + mul + ';'); | |
src.push('c += (w / shift) | 0;'); | |
} | |
src.push('w &= mask;'); | |
} | |
src.push('o[' + k + '] = w;'); | |
} | |
src.push('if (c !== 0) {', | |
' o[' + k + '] = c;', | |
' out.length++;', | |
'}', | |
'return out;'); | |
return src.join('\n'); | |
} | |
*/ | |
BN.prototype._smallMulTo = function _smallMulTo(num, out) { | |
out.sign = num.sign !== this.sign; | |
out.length = this.length + num.length; | |
var carry = 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 = carry >>> 26; | |
var rword = carry & 0x3ffffff; | |
var maxJ = Math.min(k, num.length - 1); | |
for (var j = Math.max(0, k - this.length + 1); j <= maxJ; j++) { | |
var i = k - j; | |
var a = this.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; | |
} | |
out.words[k] = rword; | |
carry = ncarry; | |
} | |
if (carry !== 0) { | |
out.words[k] = carry; | |
} else { | |
out.length--; | |
} | |
return out.strip(); | |
}; | |
BN.prototype._bigMulTo = function _bigMulTo(num, out) { | |
out.sign = num.sign !== this.sign; | |
out.length = this.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 - this.length + 1); j <= maxJ; j++) { | |
var i = k - j; | |
var a = this.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(); | |
}; | |
BN.prototype.mulTo = function mulTo(num, out) { | |
var res; | |
if (this.length + num.length < 63) | |
res = this._smallMulTo(num, out); | |
else | |
res = this._bigMulTo(num, out); | |
return res; | |
}; | |
// 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); | |
}; | |
// In-place Multiplication | |
BN.prototype.imul = function imul(num) { | |
if (this.cmpn(0) === 0 || num.cmpn(0) === 0) { | |
this.words[0] = 0; | |
this.length = 1; | |
return this; | |
} | |
var tlen = this.length; | |
var nlen = num.length; | |
this.sign = num.sign !== this.sign; | |
this.length = this.length + num.length; | |
this.words[this.length - 1] = 0; | |
for (var k = this.length - 2; k >= 0; k--) { | |
// Sum all words with the same `i + j = k` and accumulate `carry`, | |
// note that carry could be >= 0x3ffffff | |
var carry = 0; | |
var rword = 0; | |
var maxJ = Math.min(k, nlen - 1); | |
for (var j = Math.max(0, k - tlen + 1); j <= maxJ; j++) { | |
var i = k - j; | |
var a = this.words[i]; | |
var b = num.words[j]; | |
var r = a * b; | |
var lo = r & 0x3ffffff; | |
carry += (r / 0x4000000) | 0; | |
lo += rword; | |
rword = lo & 0x3ffffff; | |
carry += lo >>> 26; | |
} | |
this.words[k] = rword; | |
this.words[k + 1] += carry; | |
carry = 0; | |
} | |
// Propagate overflows | |
var carry = 0; | |
for (var i = 1; i < this.length; i++) { | |
var w = this.words[i] + carry; | |
this.words[i] = w & 0x3ffffff; | |
carry = w >>> 26; | |
} | |
return this.strip(); | |
}; | |
BN.prototype.imuln = function imuln(num) { | |
assert(typeof num === 'number'); | |
// Carry | |
var carry = 0; | |
for (var i = 0; i < this.length; i++) { | |
var w = this.words[i] * 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.mul(this); | |
}; | |
// Shift-left in-place | |
BN.prototype.ishln = function ishln(bits) { | |
assert(typeof bits === 'number' && bits >= 0); | |
var r = bits % 26; | |
var s = (bits - r) / 26; | |
var carryMask = (0x3ffffff >>> (26 - r)) << (26 - r); | |
if (r !== 0) { | |
var carry = 0; | |
for (var i = 0; i < this.length; i++) { | |
var newCarry = this.words[i] & carryMask; | |
var c = (this.words[i] - newCarry) << r; | |
this.words[i] = c | carry; | |
carry = newCarry >>> (26 - r); | |
} | |
if (carry) { | |
this.words[i] = carry; | |
this.length++; | |
} | |
} | |
if (s !== 0) { | |
for (var i = this.length - 1; i >= 0; i--) | |
this.words[i + s] = this.words[i]; | |
for (var i = 0; i < s; i++) | |
this.words[i] = 0; | |
this.length += s; | |
} | |
return this.strip(); | |
}; | |
// 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.ishrn = function ishrn(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 (var 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 (var i = this.length - 1; i >= 0 && (carry !== 0 || i >= h); i--) { | |
var word = this.words[i]; | |
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; | |
} | |
this.strip(); | |
return this; | |
}; | |
// Shift-left | |
BN.prototype.shln = function shln(bits) { | |
return this.clone().ishln(bits); | |
}; | |
// Shift-right | |
BN.prototype.shrn = function shrn(bits) { | |
return this.clone().ishrn(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.sign, 'imaskn works only with positive numbers'); | |
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'); | |
if (num < 0) | |
return this.isubn(-num); | |
// Possible sign change | |
if (this.sign) { | |
if (this.length === 1 && this.words[0] < num) { | |
this.words[0] = num - this.words[0]; | |
this.sign = false; | |
return this; | |
} | |
this.sign = false; | |
this.isubn(num); | |
this.sign = true; | |
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'); | |
if (num < 0) | |
return this.iaddn(-num); | |
if (this.sign) { | |
this.sign = false; | |
this.iaddn(num); | |
this.sign = true; | |
return this; | |
} | |
this.words[0] -= num; | |
// 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.sign = false; | |
return this; | |
}; | |
BN.prototype.abs = function abs() { | |
return this.clone().iabs(); | |
}; | |
BN.prototype._ishlnsubmul = function _ishlnsubmul(num, mul, shift) { | |
// Bigger storage is needed | |
var len = num.length + shift; | |
var i; | |
if (this.words.length < len) { | |
var t = new Array(len); | |
for (var i = 0; i < this.length; i++) | |
t[i] = this.words[i]; | |
this.words = t; | |
} else { | |
i = this.length; | |
} | |
// Zeroify rest | |
this.length = Math.max(this.length, len); | |
for (; i < this.length; i++) | |
this.words[i] = 0; | |
var carry = 0; | |
for (var i = 0; i < num.length; i++) { | |
var w = this.words[i + shift] + carry; | |
var right = num.words[i] * mul; | |
w -= right & 0x3ffffff; | |
carry = (w >> 26) - ((right / 0x4000000) | 0); | |
this.words[i + shift] = w & 0x3ffffff; | |
} | |
for (; i < this.length - shift; i++) { | |
var w = this.words[i + shift] + carry; | |
carry = w >> 26; | |
this.words[i + shift] = w & 0x3ffffff; | |
} | |
if (carry === 0) | |
return this.strip(); | |
// Subtraction overflow | |
assert(carry === -1); | |
carry = 0; | |
for (var i = 0; i < this.length; i++) { | |
var w = -this.words[i] + carry; | |
carry = w >> 26; | |
this.words[i] = w & 0x3ffffff; | |
} | |
this.sign = true; | |
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]; | |
var bhiBits = this._countBits(bhi); | |
shift = 26 - bhiBits; | |
if (shift !== 0) { | |
b = b.shln(shift); | |
a.ishln(shift); | |
bhi = b.words[b.length - 1]; | |
} | |
// 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.sign) { | |
a = diff; | |
if (q) | |
q.words[m] = 1; | |
} | |
for (var j = m - 1; j >= 0; j--) { | |
var qj = a.words[b.length + j] * 0x4000000 + a.words[b.length + j - 1]; | |
// NOTE: (qj / bhi) is (0x3ffffff * 0x4000000 + 0x3ffffff) / 0x2000000 max | |
// (0x7ffffff) | |
qj = Math.min((qj / bhi) | 0, 0x3ffffff); | |
a._ishlnsubmul(b, qj, j); | |
while (a.sign) { | |
qj--; | |
a.sign = false; | |
a._ishlnsubmul(b, 1, j); | |
if (a.cmpn(0) !== 0) | |
a.sign = !a.sign; | |
} | |
if (q) | |
q.words[j] = qj; | |
} | |
if (q) | |
q.strip(); | |
a.strip(); | |
// Denormalize | |
if (mode !== 'div' && shift !== 0) | |
a.ishrn(shift); | |
return { div: q ? q : null, mod: a }; | |
}; | |
BN.prototype.divmod = function divmod(num, mode) { | |
assert(num.cmpn(0) !== 0); | |
if (this.sign && !num.sign) { | |
var res = this.neg().divmod(num, mode); | |
var div; | |
var mod; | |
if (mode !== 'mod') | |
div = res.div.neg(); | |
if (mode !== 'div') | |
mod = res.mod.cmpn(0) === 0 ? res.mod : num.sub(res.mod); | |
return { | |
div: div, | |
mod: mod | |
}; | |
} else if (!this.sign && num.sign) { | |
var res = this.divmod(num.neg(), mode); | |
var div; | |
if (mode !== 'mod') | |
div = res.div.neg(); | |
return { div: div, mod: res.mod }; | |
} else if (this.sign && num.sign) { | |
return this.neg().divmod(num.neg(), mode); | |
} | |
// 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 }; | |
else 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').div; | |
}; | |
// Find `this` % `num` | |
BN.prototype.mod = function mod(num) { | |
return this.divmod(num, 'mod').mod; | |
}; | |
// Find Round(`this` / `num`) | |
BN.prototype.divRound = function divRound(num) { | |
var dm = this.divmod(num); | |
// Fast case - exact division | |
if (dm.mod.cmpn(0) === 0) | |
return dm.div; | |
var mod = dm.div.sign ? dm.mod.isub(num) : dm.mod; | |
var half = num.shrn(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.sign ? 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]) % 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] + 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.sign); | |
assert(p.cmpn(0) !== 0); | |
var x = this; | |
var y = p.clone(); | |
if (x.sign) | |
x = x.mod(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.ishrn(1); | |
y.ishrn(1); | |
++g; | |
} | |
var yp = y.clone(); | |
var xp = x.clone(); | |
while (x.cmpn(0) !== 0) { | |
while (x.isEven()) { | |
x.ishrn(1); | |
if (A.isEven() && B.isEven()) { | |
A.ishrn(1); | |
B.ishrn(1); | |
} else { | |
A.iadd(yp).ishrn(1); | |
B.isub(xp).ishrn(1); | |
} | |
} | |
while (y.isEven()) { | |
y.ishrn(1); | |
if (C.isEven() && D.isEven()) { | |
C.ishrn(1); | |
D.ishrn(1); | |
} else { | |
C.iadd(yp).ishrn(1); | |
D.isub(xp).ishrn(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.ishln(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.sign); | |
assert(p.cmpn(0) !== 0); | |
var a = this; | |
var b = p.clone(); | |
if (a.sign) | |
a = a.mod(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) { | |
while (a.isEven()) { | |
a.ishrn(1); | |
if (x1.isEven()) | |
x1.ishrn(1); | |
else | |
x1.iadd(delta).ishrn(1); | |
} | |
while (b.isEven()) { | |
b.ishrn(1); | |
if (x2.isEven()) | |
x2.ishrn(1); | |
else | |
x2.iadd(delta).ishrn(1); | |
} | |
if (a.cmp(b) >= 0) { | |
a.isub(b); | |
x1.isub(x2); | |
} else { | |
b.isub(a); | |
x2.isub(x1); | |
} | |
} | |
if (a.cmpn(1) === 0) | |
return x1; | |
else | |
return x2; | |
}; | |
BN.prototype.gcd = function gcd(num) { | |
if (this.cmpn(0) === 0) | |
return num.clone(); | |
if (num.cmpn(0) === 0) | |
return this.clone(); | |
var a = this.clone(); | |
var b = num.clone(); | |
a.sign = false; | |
b.sign = false; | |
// Remove common factor of two | |
for (var shift = 0; a.isEven() && b.isEven(); shift++) { | |
a.ishrn(1); | |
b.ishrn(1); | |
} | |
do { | |
while (a.isEven()) | |
a.ishrn(1); | |
while (b.isEven()) | |
b.ishrn(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.ishln(shift); | |
}; | |
// Invert number in the field F(num) | |
BN.prototype.invm = function invm(num) { | |
return this.egcd(num).a.mod(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) { | |
for (var i = this.length; i < s + 1; i++) | |
this.words[i] = 0; | |
this.words[s] |= q; | |
this.length = s + 1; | |
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]; | |
w += carry; | |
carry = w >>> 26; | |
w &= 0x3ffffff; | |
this.words[i] = w; | |
} | |
if (carry !== 0) { | |
this.words[i] = carry; | |
this.length++; | |
} | |
return this; | |
}; | |
BN.prototype.cmpn = function cmpn(num) { | |
var sign = num < 0; | |
if (sign) | |
num = -num; | |
if (this.sign && !sign) | |
return -1; | |
else if (!this.sign && sign) | |
return 1; | |
num &= 0x3ffffff; | |
this.strip(); | |
var res; | |
if (this.length > 1) { | |
res = 1; | |
} else { | |
var w = this.words[0]; | |
res = w === num ? 0 : w < num ? -1 : 1; | |
} | |
if (this.sign) | |
res = -res; | |
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.sign && !num.sign) | |
return -1; | |
else if (!this.sign && num.sign) | |
return 1; | |
var res = this.ucmp(num); | |
if (this.sign) | |
return -res; | |
else | |
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; | |
else if (this.length < num.length) | |
return -1; | |
var res = 0; | |
for (var i = this.length - 1; i >= 0; i--) { | |
var a = this.words[i]; | |
var b = num.words[i]; | |
if (a === b) | |
continue; | |
if (a < b) | |
res = -1; | |
else if (a > b) | |
res = 1; | |
break; | |
} | |
return res; | |
}; | |
// | |
// 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.sign, '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).ishln(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 { | |
r.strip(); | |
} | |
return r; | |
}; | |
MPrime.prototype.split = function split(input, out) { | |
input.ishrn(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 (var i = 10; i < input.length; i++) { | |
var next = input.words[i]; | |
input.words[i - 10] = ((next & mask) << 4) | (prev >>> 22); | |
prev = next; | |
} | |
input.words[i - 10] = prev >>> 22; | |
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 hi; | |
var lo = 0; | |
for (var i = 0; i < num.length; i++) { | |
var w = num.words[i]; | |
hi = w * 0x40; | |
lo += w * 0x3d1; | |
hi += (lo / 0x4000000) | 0; | |
lo &= 0x3ffffff; | |
num.words[i] = lo; | |
lo = hi; | |
} | |
// 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] * 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 { | |
this.m = m; | |
this.prime = null; | |
} | |
} | |
Red.prototype._verify1 = function _verify1(a) { | |
assert(!a.sign, 'red works only with positives'); | |
assert(a.red, 'red works only with red numbers'); | |
}; | |
Red.prototype._verify2 = function _verify2(a, b) { | |
assert(!a.sign && !b.sign, '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.mod(this.m)._forceRed(this); | |
}; | |
Red.prototype.neg = function neg(a) { | |
var r = a.clone(); | |
r.sign = !r.sign; | |
return r.iadd(this.m)._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.shln(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); | |
}; | |
Red.prototype.sqr = function sqr(a) { | |
return this.mul(a, a); | |
}; | |
Red.prototype.sqrt = function sqrt(a) { | |
if (a.cmpn(0) === 0) | |
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)).ishrn(2); | |
var r = this.pow(a, pow); | |
return r; | |
} | |
// 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.cmpn(0) !== 0 && q.andln(1) === 0) { | |
s++; | |
q.ishrn(1); | |
} | |
assert(q.cmpn(0) !== 0); | |
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).ishrn(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).ishrn(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).ishln(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.sign) { | |
inv.sign = false; | |
return this.imod(inv).redNeg(); | |
} else { | |
return this.imod(inv); | |
} | |
}; | |
Red.prototype.pow = function pow(a, num) { | |
var w = []; | |
if (num.cmpn(0) === 0) | |
return new BN(1); | |
var q = num.clone(); | |
while (q.cmpn(0) !== 0) { | |
w.push(q.andln(1)); | |
q.ishrn(1); | |
} | |
// Skip leading zeroes | |
var res = a; | |
for (var i = 0; i < w.length; i++, res = this.sqr(res)) | |
if (w[i] !== 0) | |
break; | |
if (++i < w.length) { | |
for (var q = this.sqr(res); i < w.length; i++, q = this.sqr(q)) { | |
if (w[i] === 0) | |
continue; | |
res = this.mul(res, q); | |
} | |
} | |
return res; | |
}; | |
Red.prototype.convertTo = function convertTo(num) { | |
var r = num.mod(this.m); | |
if (r === num) | |
return r.clone(); | |
else | |
return 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).ishln(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.sign = true; | |
this.minv = this.minv.mod(this.r); | |
} | |
inherits(Mont, Red); | |
Mont.prototype.convertTo = function convertTo(num) { | |
return this.imod(num.shln(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.cmpn(0) === 0 || b.cmpn(0) === 0) { | |
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).ishrn(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.cmpn(0) === 0 || b.cmpn(0) === 0) | |
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).ishrn(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); | |
}; | |
})(typeof module === 'undefined' || module, this); | |
},{}],71:[function(require,module,exports){ | |
(function (Buffer){ | |
var hasTypedArrays = false | |
if(typeof Float64Array !== "undefined") { | |
var DOUBLE_VIEW = new Float64Array(1) | |
, UINT_VIEW = new Uint32Array(DOUBLE_VIEW.buffer) | |
DOUBLE_VIEW[0] = 1.0 | |
hasTypedArrays = true | |
if(UINT_VIEW[1] === 0x3ff00000) { | |
//Use little endian | |
module.exports = function doubleBitsLE(n) { | |
DOUBLE_VIEW[0] = n | |
return [ UINT_VIEW[0], UINT_VIEW[1] ] | |
} | |
function toDoubleLE(lo, hi) { | |
UINT_VIEW[0] = lo | |
UINT_VIEW[1] = hi | |
return DOUBLE_VIEW[0] | |
} | |
module.exports.pack = toDoubleLE | |
function lowUintLE(n) { | |
DOUBLE_VIEW[0] = n | |
return UINT_VIEW[0] | |
} | |
module.exports.lo = lowUintLE | |
function highUintLE(n) { | |
DOUBLE_VIEW[0] = n | |
return UINT_VIEW[1] | |
} | |
module.exports.hi = highUintLE | |
} else if(UINT_VIEW[0] === 0x3ff00000) { | |
//Use big endian | |
module.exports = function doubleBitsBE(n) { | |
DOUBLE_VIEW[0] = n | |
return [ UINT_VIEW[1], UINT_VIEW[0] ] | |
} | |
function toDoubleBE(lo, hi) { | |
UINT_VIEW[1] = lo | |
UINT_VIEW[0] = hi | |
return DOUBLE_VIEW[0] | |
} | |
module.exports.pack = toDoubleBE | |
function lowUintBE(n) { | |
DOUBLE_VIEW[0] = n | |
return UINT_VIEW[1] | |
} | |
module.exports.lo = lowUintBE | |
function highUintBE(n) { | |
DOUBLE_VIEW[0] = n | |
return UINT_VIEW[0] | |
} | |
module.exports.hi = highUintBE | |
} else { | |
hasTypedArrays = false | |
} | |
} | |
if(!hasTypedArrays) { | |
var buffer = new Buffer(8) | |
module.exports = function doubleBits(n) { | |
buffer.writeDoubleLE(n, 0, true) | |
return [ buffer.readUInt32LE(0, true), buffer.readUInt32LE(4, true) ] | |
} | |
function toDouble(lo, hi) { | |
buffer.writeUInt32LE(lo, 0, true) | |
buffer.writeUInt32LE(hi, 4, true) | |
return buffer.readDoubleLE(0, true) | |
} | |
module.exports.pack = toDouble | |
function lowUint(n) { | |
buffer.writeDoubleLE(n, 0, true) | |
return buffer.readUInt32LE(0, true) | |
} | |
module.exports.lo = lowUint | |
function highUint(n) { | |
buffer.writeDoubleLE(n, 0, true) | |
return buffer.readUInt32LE(4, true) | |
} | |
module.exports.hi = highUint | |
} | |
module.exports.sign = function(n) { | |
return module.exports.hi(n) >>> 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) | |
} | |
}).call(this,require("buffer").Buffer) | |
},{"buffer":2}],72:[function(require,module,exports){ | |
'use strict' | |
var bnsign = require('./lib/bn-sign') | |
module.exports = sign | |
function sign(x) { | |
return bnsign(x[0]) * bnsign(x[1]) | |
} | |
},{"./lib/bn-sign":61}],73:[function(require,module,exports){ | |
'use strict' | |
var rationalize = require('./lib/rationalize') | |
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])) | |
} | |
},{"./lib/rationalize":66}],74:[function(require,module,exports){ | |
'use strict' | |
var bn2num = require('./lib/bn-to-num') | |
var ctz = require('./lib/ctz') | |
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.divmod(b) | |
var iv = h.div | |
var x = bn2num(iv) | |
var ir = h.mod | |
if(ir.cmpn(0) === 0) { | |
return x | |
} | |
if(x) { | |
var s = ctz(x) + 4 | |
var y = bn2num(ir.shln(s).divRound(b)) | |
// flip the sign of y if x is negative | |
if (x<0) { | |
y = -y; | |
} | |
return x + y * Math.pow(2, -s) | |
} else { | |
var ybits = b.bitLength() - ir.bitLength() + 53 | |
var y = bn2num(ir.shln(ybits).divRound(b)) | |
if(ybits < 1023) { | |
return y * Math.pow(2, -ybits) | |
} | |
y *= Math.pow(2, -1023) | |
return y * Math.pow(2, 1023-ybits) | |
} | |
} | |
},{"./lib/bn-to-num":62,"./lib/ctz":63}],75:[function(require,module,exports){ | |
'use strict' | |
module.exports = boxIntersectWrapper | |
var pool = require('typedarray-pool') | |
var sweep = require('./lib/sweep') | |
var boxIntersectIter = require('./lib/intersect') | |
function boxEmpty(d, box) { | |
for(var j=0; j<d; ++j) { | |
if(!(box[j] <= box[j+d])) { | |
return true | |
} | |
} | |
return false | |
} | |
//Unpack boxes into a flat typed array, remove empty boxes | |
function convertBoxes(boxes, d, data, ids) { | |
var ptr = 0 | |
var count = 0 | |
for(var i=0, n=boxes.length; i<n; ++i) { | |
var b = boxes[i] | |
if(boxEmpty(d, b)) { | |
continue | |
} | |
for(var j=0; j<2*d; ++j) { | |
data[ptr++] = b[j] | |
} | |
ids[count++] = i | |
} | |
return count | |
} | |
//Perform type conversions, check bounds | |
function boxIntersect(red, blue, visit, full) { | |
var n = red.length | |
var m = blue.length | |
//If either array is empty, then we can skip this whole thing | |
if(n <= 0 || m <= 0) { | |
return | |
} | |
//Compute dimension, if it is 0 then we skip | |
var d = (red[0].length)>>>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) { | |
var result | |
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') | |
} | |
} | |
},{"./lib/intersect":77,"./lib/sweep":81,"typedarray-pool":84}],76:[function(require,module,exports){ | |
'use strict' | |
var DIMENSION = 'd' | |
var AXIS = 'ax' | |
var VISIT = 'vv' | |
var FLIP = 'fp' | |
var ELEM_SIZE = 'es' | |
var RED_START = 'rs' | |
var RED_END = 're' | |
var RED_BOXES = 'rb' | |
var RED_INDEX = 'ri' | |
var RED_PTR = 'rp' | |
var BLUE_START = 'bs' | |
var BLUE_END = 'be' | |
var BLUE_BOXES = 'bb' | |
var BLUE_INDEX = 'bi' | |
var BLUE_PTR = 'bp' | |
var RETVAL = 'rv' | |
var INNER_LABEL = 'Q' | |
var ARGS = [ | |
DIMENSION, | |
AXIS, | |
VISIT, | |
RED_START, | |
RED_END, | |
RED_BOXES, | |
RED_INDEX, | |
BLUE_START, | |
BLUE_END, | |
BLUE_BOXES, | |
BLUE_INDEX | |
] | |
function generateBruteForce(redMajor, flip, full) { | |
var funcName = 'bruteForce' + | |
(redMajor ? 'Red' : 'Blue') + | |
(flip ? 'Flip' : '') + | |
(full ? 'Full' : '') | |
var code = ['function ', funcName, '(', ARGS.join(), '){', | |
'var ', ELEM_SIZE, '=2*', DIMENSION, ';'] | |
var redLoop = | |
'for(var i=' + RED_START + ',' + RED_PTR + '=' + ELEM_SIZE + '*' + RED_START + ';' + | |
'i<' + RED_END +';' + | |
'++i,' + RED_PTR + '+=' + ELEM_SIZE + '){' + | |
'var x0=' + RED_BOXES + '[' + AXIS + '+' + RED_PTR + '],' + | |
'x1=' + RED_BOXES + '[' + AXIS + '+' + RED_PTR + '+' + DIMENSION + '],' + | |
'xi=' + RED_INDEX + '[i];' | |
var blueLoop = | |
'for(var j=' + BLUE_START + ',' + BLUE_PTR + '=' + ELEM_SIZE + '*' + BLUE_START + ';' + | |
'j<' + BLUE_END + ';' + | |
'++j,' + BLUE_PTR + '+=' + ELEM_SIZE + '){' + | |
'var y0=' + BLUE_BOXES + '[' + AXIS + '+' + BLUE_PTR + '],' + | |
(full ? 'y1=' + BLUE_BOXES + '[' + AXIS + '+' + BLUE_PTR + '+' + DIMENSION + '],' : '') + | |
'yi=' + BLUE_INDEX + '[j];' | |
if(redMajor) { | |
code.push(redLoop, INNER_LABEL, ':', blueLoop) | |
} else { | |
code.push(blueLoop, INNER_LABEL, ':', redLoop) | |
} | |
if(full) { | |
code.push('if(y1<x0||x1<y0)continue;') | |
} else if(flip) { | |
code.push('if(y0<=x0||x1<y0)continue;') | |
} else { | |
code.push('if(y0<x0||x1<y0)continue;') | |
} | |
code.push('for(var k='+AXIS+'+1;k<'+DIMENSION+';++k){'+ | |
'var r0='+RED_BOXES+'[k+'+RED_PTR+'],'+ | |
'r1='+RED_BOXES+'[k+'+DIMENSION+'+'+RED_PTR+'],'+ | |
'b0='+BLUE_BOXES+'[k+'+BLUE_PTR+'],'+ | |
'b1='+BLUE_BOXES+'[k+'+DIMENSION+'+'+BLUE_PTR+'];'+ | |
'if(r1<b0||b1<r0)continue ' + INNER_LABEL + ';}' + | |
'var ' + RETVAL + '=' + VISIT + '(') | |
if(flip) { | |
code.push('yi,xi') | |
} else { | |
code.push('xi,yi') | |
} | |
code.push(');if(' + RETVAL + '!==void 0)return ' + RETVAL + ';}}}') | |
return { | |
name: funcName, | |
code: code.join('') | |
} | |
} | |
function bruteForcePlanner(full) { | |
var funcName = 'bruteForce' + (full ? 'Full' : 'Partial') | |
var prefix = [] | |
var fargs = ARGS.slice() | |
if(!full) { | |
fargs.splice(3, 0, FLIP) | |
} | |
var code = ['function ' + funcName + '(' + fargs.join() + '){'] | |
function invoke(redMajor, flip) { | |
var res = generateBruteForce(redMajor, flip, full) | |
prefix.push(res.code) | |
code.push('return ' + res.name + '(' + ARGS.join() + ');') | |
} | |
code.push('if(' + RED_END + '-' + RED_START + '>' + | |
BLUE_END + '-' + BLUE_START + '){') | |
if(full) { | |
invoke(true, false) | |
code.push('}else{') | |
invoke(false, false) | |
} else { | |
code.push('if(' + FLIP + '){') | |
invoke(true, true) | |
code.push('}else{') | |
invoke(true, false) | |
code.push('}}else{if(' + FLIP + '){') | |
invoke(false, true) | |
code.push('}else{') | |
invoke(false, false) | |
code.push('}') | |
} | |
code.push('}}return ' + funcName) | |
var codeStr = prefix.join('') + code.join('') | |
var proc = new Function(codeStr) | |
return proc() | |
} | |
exports.partial = bruteForcePlanner(false) | |
exports.full = bruteForcePlanner(true) | |
},{}],77:[function(require,module,exports){ | |
'use strict' | |
module.exports = boxIntersectIter | |
var pool = require('typedarray-pool') | |
var bits = require('bit-twiddle') | |
var bruteForce = require('./brute') | |
var bruteForcePartial = bruteForce.partial | |
var bruteForceFull = bruteForce.full | |
var sweep = require('./sweep') | |
var findMedian = require('./median') | |
var genPartition = require('./partition') | |
//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)', | |
['p0', 'p1']) | |
var partitionStartEqual = genPartition( | |
'lo===p0', | |
['p0']) | |
var partitionStartLessThan = genPartition( | |
'lo<p0', | |
['p0']) | |
var partitionEndLessThanEqual = genPartition( | |
'hi<=p0', | |
['p0']) | |
var partitionContainsPoint = genPartition( | |
'lo<=p0&&p0<=hi', | |
['p0']) | |
var partitionContainsPointProper = genPartition( | |
'lo<p0&&p0<=hi', | |
['p0']) | |
//Frame size for iterative loop | |
var IFRAME_SIZE = 6 | |
var DFRAME_SIZE = 2 | |
//Data for box statck | |
var INIT_CAPACITY = 1024 | |
var BOX_ISTACK = pool.mallocInt32(INIT_CAPACITY) | |
var BOX_DSTACK = pool.mallocDouble(INIT_CAPACITY) | |
//Initialize iterative loop queue | |
function iterInit(d, count) { | |
var levels = (8 * bits.log2(count+1) * (d+1))|0 | |
var maxInts = bits.nextPow2(IFRAME_SIZE*levels) | |
if(BOX_ISTACK.length < maxInts) { | |
pool.free(BOX_ISTACK) | |
BOX_ISTACK = pool.mallocInt32(maxInts) | |
} | |
var maxDoubles = bits.nextPow2(DFRAME_SIZE*levels) | |
if(BOX_DSTACK < maxDoubles) { | |
pool.free(BOX_DSTACK) | |
BOX_DSTACK = pool.mallocDouble(maxDoubles) | |
} | |
} | |
//Append item to queue | |
function iterPush(ptr, | |
axis, | |
redStart, redEnd, | |
blueStart, blueEnd, | |
state, | |
lo, hi) { | |
var iptr = IFRAME_SIZE * ptr | |
BOX_ISTACK[iptr] = axis | |
BOX_ISTACK[iptr+1] = redStart | |
BOX_ISTACK[iptr+2] = redEnd | |
BOX_ISTACK[iptr+3] = blueStart | |
BOX_ISTACK[iptr+4] = blueEnd | |
BOX_ISTACK[iptr+5] = state | |
var dptr = DFRAME_SIZE * ptr | |
BOX_DSTACK[dptr] = lo | |
BOX_DSTACK[dptr+1] = hi | |
} | |
//Special case: Intersect single point with list of intervals | |
function onePointPartial( | |
d, axis, visit, flip, | |
redStart, redEnd, red, redIndex, | |
blueOffset, blue, blueId) { | |
var elemSize = 2 * d | |
var bluePtr = blueOffset * elemSize | |
var blueX = blue[bluePtr + axis] | |
red_loop: | |
for(var i=redStart, redPtr=redStart*elemSize; i<redEnd; ++i, redPtr+=elemSize) { | |
var r0 = red[redPtr+axis] | |
var r1 = red[redPtr+axis+d] | |
if(blueX < r0 || r1 < blueX) { | |
continue | |
} | |
if(flip && blueX === r0) { | |
continue | |
} | |
var redId = redIndex[i] | |
for(var j=axis+1; j<d; ++j) { | |
var r0 = red[redPtr+j] | |
var r1 = red[redPtr+j+d] | |
var b0 = blue[bluePtr+j] | |
var b1 = blue[bluePtr+j+d] | |
if(r1 < b0 || b1 < r0) { | |
continue red_loop | |
} | |
} | |
var retval | |
if(flip) { | |
retval = visit(blueId, redId) | |
} else { | |
retval = visit(redId, blueId) | |
} | |
if(retval !== void 0) { | |
return retval | |
} | |
} | |
} | |
//Special case: Intersect one point with list of intervals | |
function onePointFull( | |
d, axis, visit, | |
redStart, redEnd, red, redIndex, | |
blueOffset, blue, blueId) { | |
var elemSize = 2 * d | |
var bluePtr = blueOffset * elemSize | |
var blueX = blue[bluePtr + axis] | |
red_loop: | |
for(var i=redStart, redPtr=redStart*elemSize; i<redEnd; ++i, redPtr+=elemSize) { | |
var redId = redIndex[i] | |
if(redId === blueId) { | |
continue | |
} | |
var r0 = red[redPtr+axis] | |
var r1 = red[redPtr+axis+d] | |
if(blueX < r0 || r1 < blueX) { | |
continue | |
} | |
for(var j=axis+1; j<d; ++j) { | |
var r0 = red[redPtr+j] | |
var r1 = red[redPtr+j+d] | |
var b0 = blue[bluePtr+j] | |
var b1 = blue[bluePtr+j+d] | |
if(r1 < b0 || b1 < r0) { | |
continue red_loop | |
} | |
} | |
var retval = visit(redId, blueId) | |
if(retval !== void 0) { | |
return retval | |
} | |
} | |
} | |
//The main box intersection routine | |
function boxIntersectIter( | |
d, visit, initFull, | |
xSize, xBoxes, xIndex, | |
ySize, yBoxes, yIndex) { | |
//Reserve memory for stack | |
iterInit(d, xSize + ySize) | |
var top = 0 | |
var elemSize = 2 * d | |
var retval | |
iterPush(top++, | |
0, | |
0, xSize, | |
0, ySize, | |
initFull ? 16 : 0, | |
-Infinity, Infinity) | |
if(!initFull) { | |
iterPush(top++, | |
0, | |
0, ySize, | |
0, xSize, | |
1, | |
-Infinity, Infinity) | |
} | |
while(top > 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) | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
},{"./brute":76,"./median":78,"./partition":79,"./sweep":81,"bit-twiddle":82,"typedarray-pool":84}],78:[function(require,module,exports){ | |
'use strict' | |
module.exports = findMedian | |
var genPartition = require('./partition') | |
var partitionStartLessThan = genPartition('lo<p0', ['p0']) | |
var PARTITION_THRESHOLD = 8 //Cut off for using insertion sort in findMedian | |
//Base case for median finding: Use insertion sort | |
function insertionSort(d, axis, start, end, boxes, ids) { | |
var elemSize = 2 * d | |
var boxPtr = elemSize * (start+1) + axis | |
for(var i=start+1; i<end; ++i, boxPtr+=elemSize) { | |
var x = boxes[boxPtr] | |
for(var j=i, ptr=elemSize*(i-1); | |
j>start && boxes[ptr+axis] > x; | |
--j, ptr-=elemSize) { | |
//Swap | |
var aPtr = ptr | |
var bPtr = ptr+elemSize | |
for(var k=0; k<elemSize; ++k, ++aPtr, ++bPtr) { | |
var y = boxes[aPtr] | |
boxes[aPtr] = boxes[bPtr] | |
boxes[bPtr] = y | |
} | |
var tmp = ids[j] | |
ids[j] = ids[j-1] | |
ids[j-1] = tmp | |
} | |
} | |
} | |
//Find median using quick select algorithm | |
// takes O(n) time with high probability | |
function findMedian(d, axis, start, end, boxes, ids) { | |
if(end <= start+1) { | |
return start | |
} | |
var lo = start | |
var hi = end | |
var mid = ((end + start) >>> 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<elemSize; ++i, ++aPtr, ++bPtr) { | |
var x = boxes[aPtr] | |
boxes[aPtr] = boxes[bPtr] | |
boxes[bPtr] = x | |
} | |
var y = ids[hi-1] | |
ids[hi-1] = ids[pivot] | |
ids[pivot] = y | |
//Partition using pivot | |
pivot = partitionStartLessThan( | |
d, axis, | |
lo, hi-1, boxes, ids, | |
value) | |
//Swap pivot back | |
var aPtr = elemSize * (hi-1) | |
var bPtr = elemSize * pivot | |
for(var i=0; i<elemSize; ++i, ++aPtr, ++bPtr) { | |
var x = boxes[aPtr] | |
boxes[aPtr] = boxes[bPtr] | |
boxes[bPtr] = x | |
} | |
var y = ids[hi-1] | |
ids[hi-1] = ids[pivot] | |
ids[pivot] = y | |
//Swap pivot to last pivot | |
if(mid < pivot) { | |
hi = pivot-1 | |
while(lo < hi && | |
boxes[elemSize*(hi-1)+axis] === value) { | |
hi -= 1 | |
} | |
hi += 1 | |
} else if(pivot < mid) { | |
lo = pivot + 1 | |
while(lo < hi && | |
boxes[elemSize*lo+axis] === value) { | |
lo += 1 | |
} | |
} else { | |
break | |
} | |
} | |
//Make sure pivot is at start | |
return partitionStartLessThan( | |
d, axis, | |
start, mid, boxes, ids, | |
boxes[elemSize*mid+axis]) | |
} | |
},{"./partition":79}],79:[function(require,module,exports){ | |
'use strict' | |
module.exports = genPartition | |
var code = '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 _;if($)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' | |
function genPartition(predicate, args) { | |
var fargs ='abcdef'.split('').concat(args) | |
var reads = [] | |
if(predicate.indexOf('lo') >= 0) { | |
reads.push('lo=e[k+n]') | |
} | |
if(predicate.indexOf('hi') >= 0) { | |
reads.push('hi=e[k+o]') | |
} | |
fargs.push( | |
code.replace('_', reads.join()) | |
.replace('$', predicate)) | |
return Function.apply(void 0, fargs) | |
} | |
},{}],80:[function(require,module,exports){ | |
'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); | |
} | |
} | |
},{}],81:[function(require,module,exports){ | |
'use strict' | |
module.exports = { | |
init: sqInit, | |
sweepBipartite: sweepBipartite, | |
sweepComplete: sweepComplete, | |
scanBipartite: scanBipartite, | |
scanComplete: scanComplete | |
} | |
var pool = require('typedarray-pool') | |
var bits = require('bit-twiddle') | |
var isort = require('./sort') | |
//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; i<redEnd; ++i) { | |
var idx = redIndex[i] | |
var redOffset = elemSize*i | |
SWEEP_EVENTS[ptr++] = red[redOffset+istart] | |
SWEEP_EVENTS[ptr++] = -(idx+1) | |
SWEEP_EVENTS[ptr++] = red[redOffset+iend] | |
SWEEP_EVENTS[ptr++] = idx | |
} | |
for(var i=blueStart; i<blueEnd; ++i) { | |
var idx = blueIndex[i]+BLUE_FLAG | |
var blueOffset = elemSize*i | |
SWEEP_EVENTS[ptr++] = blue[blueOffset+istart] | |
SWEEP_EVENTS[ptr++] = -idx | |
SWEEP_EVENTS[ptr++] = blue[blueOffset+iend] | |
SWEEP_EVENTS[ptr++] = idx | |
} | |
//process events from left->right | |
var n = ptr >>> 1 | |
isort(SWEEP_EVENTS, n) | |
var redActive = 0 | |
var blueActive = 0 | |
for(var i=0; i<n; ++i) { | |
var e = SWEEP_EVENTS[2*i+1]|0 | |
if(e >= 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; j<redActive; ++j) { | |
var retval = visit(RED_SWEEP_QUEUE[j], e) | |
if(retval !== void 0) { | |
return retval | |
} | |
} | |
sqPush(BLUE_SWEEP_QUEUE, BLUE_SWEEP_INDEX, blueActive++, e) | |
} else { | |
//red create event | |
e = (-e-1)|0 | |
for(var j=0; j<blueActive; ++j) { | |
var retval = visit(e, BLUE_SWEEP_QUEUE[j]) | |
if(retval !== void 0) { | |
return retval | |
} | |
} | |
sqPush(RED_SWEEP_QUEUE, RED_SWEEP_INDEX, redActive++, e) | |
} | |
} | |
} | |
//Complete sweep | |
function sweepComplete(d, visit, | |
redStart, redEnd, red, redIndex, | |
blueStart, blueEnd, blue, blueIndex) { | |
var ptr = 0 | |
var elemSize = 2*d | |
var istart = d-1 | |
var iend = elemSize-1 | |
for(var i=redStart; i<redEnd; ++i) { | |
var idx = (redIndex[i]+1)<<1 | |
var redOffset = elemSize*i | |
SWEEP_EVENTS[ptr++] = red[redOffset+istart] | |
SWEEP_EVENTS[ptr++] = -idx | |
SWEEP_EVENTS[ptr++] = red[redOffset+iend] | |
SWEEP_EVENTS[ptr++] = idx | |
} | |
for(var i=blueStart; i<blueEnd; ++i) { | |
var idx = (blueIndex[i]+1)<<1 | |
var blueOffset = elemSize*i | |
SWEEP_EVENTS[ptr++] = blue[blueOffset+istart] | |
SWEEP_EVENTS[ptr++] = (-idx)|1 | |
SWEEP_EVENTS[ptr++] = blue[blueOffset+iend] | |
SWEEP_EVENTS[ptr++] = idx|1 | |
} | |
//process events from left->right | |
var n = ptr >>> 1 | |
isort(SWEEP_EVENTS, n) | |
var redActive = 0 | |
var blueActive = 0 | |
var commonActive = 0 | |
for(var i=0; i<n; ++i) { | |
var e = SWEEP_EVENTS[2*i+1]|0 | |
var color = e&1 | |
if(i < n-1 && (e>>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<commonActive; ++j) { | |
var retval = visit(COMMON_SWEEP_QUEUE[j], id) | |
if(retval !== void 0) { | |
return retval | |
} | |
} | |
if(color !== 0) { | |
//Intersect with red | |
for(var j=0; j<redActive; ++j) { | |
var retval = visit(RED_SWEEP_QUEUE[j], id) | |
if(retval !== void 0) { | |
return retval | |
} | |
} | |
} | |
if(color !== 1) { | |
//Intersect with blue | |
for(var j=0; j<blueActive; ++j) { | |
var retval = visit(BLUE_SWEEP_QUEUE[j], id) | |
if(retval !== void 0) { | |
return retval | |
} | |
} | |
} | |
if(color === 0) { | |
//Red | |
sqPush(RED_SWEEP_QUEUE, RED_SWEEP_INDEX, redActive++, id) | |
} else if(color === 1) { | |
//Blue | |
sqPush(BLUE_SWEEP_QUEUE, BLUE_SWEEP_INDEX, blueActive++, id) | |
} else if(color === 2) { | |
//Both | |
sqPush(COMMON_SWEEP_QUEUE, COMMON_SWEEP_INDEX, commonActive++, id) | |
} | |
} else { | |
//Destroy event | |
var id = (e>>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; i<redEnd; ++i) { | |
var idx = i + redShift | |
var redOffset = elemSize*i | |
SWEEP_EVENTS[ptr++] = red[redOffset+istart] | |
SWEEP_EVENTS[ptr++] = -idx | |
SWEEP_EVENTS[ptr++] = red[redOffset+iend] | |
SWEEP_EVENTS[ptr++] = idx | |
} | |
for(var i=blueStart; i<blueEnd; ++i) { | |
var idx = i + blueShift | |
var blueOffset = elemSize*i | |
SWEEP_EVENTS[ptr++] = blue[blueOffset+istart] | |
SWEEP_EVENTS[ptr++] = -idx | |
} | |
//process events from left->right | |
var n = ptr >>> 1 | |
isort(SWEEP_EVENTS, n) | |
var redActive = 0 | |
for(var i=0; i<n; ++i) { | |
var e = SWEEP_EVENTS[2*i+1]|0 | |
if(e < 0) { | |
var idx = -e | |
var isRed = false | |
if(idx >= 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; j<redActive; ++j) { | |
var oidx = RED_SWEEP_QUEUE[j] | |
var redPtr = elemSize * oidx | |
if(b1 < red[redPtr+axis+1] || | |
red[redPtr+axis+1+d] < b0) { | |
continue | |
} | |
for(var k=axis+2; k<d; ++k) { | |
if(blue[bluePtr + k + d] < red[redPtr + k] || | |
red[redPtr + k + d] < blue[bluePtr + k]) { | |
continue red_loop | |
} | |
} | |
var redId = redIndex[oidx] | |
var retval | |
if(flip) { | |
retval = visit(blueId, redId) | |
} else { | |
retval = visit(redId, blueId) | |
} | |
if(retval !== void 0) { | |
return retval | |
} | |
} | |
} | |
} else { | |
sqPop(RED_SWEEP_QUEUE, RED_SWEEP_INDEX, redActive--, e - redShift) | |
} | |
} | |
} | |
function scanComplete( | |
d, axis, visit, | |
redStart, redEnd, red, redIndex, | |
blueStart, blueEnd, blue, blueIndex) { | |
var ptr = 0 | |
var elemSize = 2*d | |
var istart = axis | |
var iend = axis+d | |
for(var i=redStart; i<redEnd; ++i) { | |
var idx = i + BLUE_FLAG | |
var redOffset = elemSize*i | |
SWEEP_EVENTS[ptr++] = red[redOffset+istart] | |
SWEEP_EVENTS[ptr++] = -idx | |
SWEEP_EVENTS[ptr++] = red[redOffset+iend] | |
SWEEP_EVENTS[ptr++] = idx | |
} | |
for(var i=blueStart; i<blueEnd; ++i) { | |
var idx = i + 1 | |
var blueOffset = elemSize*i | |
SWEEP_EVENTS[ptr++] = blue[blueOffset+istart] | |
SWEEP_EVENTS[ptr++] = -idx | |
} | |
//process events from left->right | |
var n = ptr >>> 1 | |
isort(SWEEP_EVENTS, n) | |
var redActive = 0 | |
for(var i=0; i<n; ++i) { | |
var e = SWEEP_EVENTS[2*i+1]|0 | |
if(e < 0) { | |
var idx = -e | |
if(idx >= 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<redActive; ++j) { | |
var oidx = RED_SWEEP_QUEUE[j] | |
var redId = redIndex[oidx] | |
if(redId === blueId) { | |
break | |
} | |
var redPtr = elemSize * oidx | |
if(b1 < red[redPtr+axis+1] || | |
red[redPtr+axis+1+d] < b0) { | |
continue | |
} | |
for(var k=axis+2; k<d; ++k) { | |
if(blue[bluePtr + k + d] < red[redPtr + k] || | |
red[redPtr + k + d] < blue[bluePtr + k]) { | |
continue red_loop | |
} | |
} | |
var retval = visit(redId, blueId) | |
if(retval !== void 0) { | |
return retval | |
} | |
} | |
} | |
} else { | |
var idx = e - BLUE_FLAG | |
for(var j=redActive-1; j>=0; --j) { | |
if(RED_SWEEP_QUEUE[j] === idx) { | |
for(var k=j+1; k<redActive; ++k) { | |
RED_SWEEP_QUEUE[k-1] = RED_SWEEP_QUEUE[k] | |
} | |
break | |
} | |
} | |
--redActive | |
} | |
} | |
} | |
},{"./sort":80,"bit-twiddle":82,"typedarray-pool":84}],82:[function(require,module,exports){ | |
arguments[4][15][0].apply(exports,arguments) | |
},{"dup":15}],83:[function(require,module,exports){ | |
arguments[4][16][0].apply(exports,arguments) | |
},{"dup":16}],84:[function(require,module,exports){ | |
arguments[4][17][0].apply(exports,arguments) | |
},{"bit-twiddle":82,"buffer":2,"dup":17}],85:[function(require,module,exports){ | |
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<n; ++i) { | |
t = as[i] - bs[i] | |
if(t) { | |
return t | |
} | |
} | |
return 0 | |
} | |
} | |
},{}],86:[function(require,module,exports){ | |
"use strict" | |
var doubleBits = require("double-bits") | |
var SMALLEST_DENORM = Math.pow(2, -1074) | |
var UINT_MAX = (-1)>>>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) | |
} | |
},{"double-bits":87}],87:[function(require,module,exports){ | |
arguments[4][71][0].apply(exports,arguments) | |
},{"buffer":2,"dup":71}],88:[function(require,module,exports){ | |
'use strict' | |
var bnadd = require('big-rat/add') | |
module.exports = add | |
function add(a, b) { | |
var n = a.length | |
var r = new Array(n) | |
for(var i=0; i<n; ++i) { | |
r[i] = bnadd(a[i], b[i]) | |
} | |
return r | |
} | |
},{"big-rat/add":56}],89:[function(require,module,exports){ | |
'use strict' | |
module.exports = float2rat | |
var rat = require('big-rat') | |
function float2rat(v) { | |
var result = new Array(v.length) | |
for(var i=0; i<v.length; ++i) { | |
result[i] = rat(v[i]) | |
} | |
return result | |
} | |
},{"big-rat":59}],90:[function(require,module,exports){ | |
'use strict' | |
var rat = require('big-rat') | |
var mul = require('big-rat/mul') | |
module.exports = muls | |
function muls(a, x) { | |
var s = rat(x) | |
var n = a.length | |
var r = new Array(n) | |
for(var i=0; i<n; ++i) { | |
r[i] = mul(a[i], s) | |
} | |
return r | |
} | |
},{"big-rat":59,"big-rat/mul":68}],91:[function(require,module,exports){ | |
'use strict' | |
var bnsub = require('big-rat/sub') | |
module.exports = sub | |
function sub(a, b) { | |
var n = a.length | |
var r = new Array(n) | |
for(var i=0; i<n; ++i) { | |
r[i] = bnsub(a[i], b[i]) | |
} | |
return r | |
} | |
},{"big-rat/sub":73}],92:[function(require,module,exports){ | |
arguments[4][43][0].apply(exports,arguments) | |
},{"dup":43}],93:[function(require,module,exports){ | |
arguments[4][44][0].apply(exports,arguments) | |
},{"dup":44,"two-product":96,"two-sum":92}],94:[function(require,module,exports){ | |
arguments[4][45][0].apply(exports,arguments) | |
},{"dup":45}],95:[function(require,module,exports){ | |
arguments[4][46][0].apply(exports,arguments) | |
},{"dup":46}],96:[function(require,module,exports){ | |
arguments[4][47][0].apply(exports,arguments) | |
},{"dup":47}],97:[function(require,module,exports){ | |
arguments[4][53][0].apply(exports,arguments) | |
},{"dup":53,"robust-scale":93,"robust-subtract":94,"robust-sum":95,"two-product":96}],98:[function(require,module,exports){ | |
"use strict" | |
module.exports = segmentsIntersect | |
var orient = require("robust-orientation")[3] | |
function checkCollinear(a0, a1, b0, b1) { | |
for(var d=0; d<2; ++d) { | |
var x0 = a0[d] | |
var y0 = a1[d] | |
var l0 = Math.min(x0, y0) | |
var h0 = Math.max(x0, y0) | |
var x1 = b0[d] | |
var y1 = b1[d] | |
var l1 = Math.min(x1, y1) | |
var h1 = Math.max(x1, y1) | |
if(h1 < l0 || h0 < l1) { | |
return false | |
} | |
} | |
return true | |
} | |
function segmentsIntersect(a0, a1, b0, b1) { | |
var x0 = orient(a0, b0, b1) | |
var y0 = orient(a1, b0, b1) | |
if((x0 > 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 | |
} | |
},{"robust-orientation":97}],99:[function(require,module,exports){ | |
"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<count; ++i) { | |
this.roots[i] = i; | |
this.ranks[i] = 0; | |
} | |
} | |
var proto = UnionFind.prototype | |
Object.defineProperty(proto, "length", { | |
"get": function() { | |
return this.roots.length | |
} | |
}) | |
proto.makeSet = function() { | |
var n = this.roots.length; | |
this.roots.push(n); | |
this.ranks.push(0); | |
return n; | |
} | |
proto.find = function(x) { | |
var x0 = x | |
var roots = this.roots; | |
while(roots[x] !== x) { | |
x = roots[x] | |
} | |
while(roots[x0] !== x) { | |
var y = roots[x0] | |
roots[x0] = x | |
x0 = y | |
} | |
return x; | |
} | |
proto.link = function(x, y) { | |
var xr = this.find(x) | |
, yr = this.find(y); | |
if(xr === yr) { | |
return; | |
} | |
var ranks = this.ranks | |
, roots = this.roots | |
, xd = ranks[xr] | |
, yd = ranks[yr]; | |
if(xd < yd) { | |
roots[xr] = yr; | |
} else if(yd < xd) { | |
roots[yr] = xr; | |
} else { | |
roots[yr] = xr; | |
++ranks[xr]; | |
} | |
} | |
},{}],100:[function(require,module,exports){ | |
arguments[4][12][0].apply(exports,arguments) | |
},{"dup":12,"iota-array":101,"is-buffer":102}],101:[function(require,module,exports){ | |
arguments[4][13][0].apply(exports,arguments) | |
},{"dup":13}],102:[function(require,module,exports){ | |
arguments[4][14][0].apply(exports,arguments) | |
},{"dup":14}],103:[function(require,module,exports){ | |
'use strict' | |
module.exports = trimLeaves | |
var e2a = require('edges-to-adjacency-list') | |
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<positions.length; ++i) { | |
var count = adj[i].length | |
nbhd[i] = count | |
live[i] = true | |
if(count <= 1) { | |
dead.push(i) | |
} | |
} | |
while(dead.length > 0) { | |
var v = dead.pop() | |
live[v] = false | |
var n = adj[v] | |
for(var i=0; i<n.length; ++i) { | |
var u = n[i] | |
if(--nbhd[u] === 0) { | |
dead.push(u) | |
} | |
} | |
} | |
var newIndex = new Array(positions.length) | |
var npositions = [] | |
for(var i=0; i<positions.length; ++i) { | |
if(live[i]) { | |
var v = npositions.length | |
newIndex[i] = v | |
npositions.push(positions[i]) | |
} else { | |
newIndex[i] = -1 | |
} | |
} | |
var nedges = [] | |
for(var i=0; i<edges.length; ++i) { | |
var e = edges[i] | |
if(live[e[0]] && live[e[1]]) { | |
nedges.push([ newIndex[e[0]], newIndex[e[1]] ]) | |
} | |
} | |
return [ nedges, npositions ] | |
} | |
},{"edges-to-adjacency-list":104}],104:[function(require,module,exports){ | |
"use strict" | |
module.exports = edgeToAdjacency | |
var uniq = require("uniq") | |
function edgeToAdjacency(edges, numVertices) { | |
var numEdges = edges.length | |
if(typeof numVertices !== "number") { | |
numVertices = 0 | |
for(var i=0; i<numEdges; ++i) { | |
var e = edges[i] | |
numVertices = Math.max(numVertices, e[0], e[1]) | |
} | |
numVertices = (numVertices|0) + 1 | |
} | |
numVertices = numVertices|0 | |
var adj = new Array(numVertices) | |
for(var i=0; i<numVertices; ++i) { | |
adj[i] = [] | |
} | |
for(var i=0; i<numEdges; ++i) { | |
var e = edges[i] | |
adj[e[0]].push(e[1]) | |
adj[e[1]].push(e[0]) | |
} | |
for(var j=0; j<numVertices; ++j) { | |
uniq(adj[j], function(a, b) { | |
return a - b | |
}) | |
} | |
return adj | |
} | |
},{"uniq":123}],105:[function(require,module,exports){ | |
"use strict" | |
module.exports = planarDual | |
var compareAngle = require("compare-angle") | |
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<numVertices; ++i) { | |
adj[0][i] = [] | |
adj[1][i] = [] | |
} | |
for(var i=0; i<numEdges; ++i) { | |
var c = cells[i] | |
adj[0][c[0]].push(c) | |
adj[1][c[1]].push(c) | |
} | |
var cycles = [] | |
//Add isolated vertices as trivial case | |
for(var i=0; i<numVertices; ++i) { | |
if(adj[0][i].length + adj[1][i].length === 0) { | |
cycles.push( [i] ) | |
} | |
} | |
//Remove a half edge | |
function cut(c, i) { | |
var a = adj[i][c[i]] | |
a.splice(a.indexOf(c), 1) | |
} | |
//Find next vertex and cut edge | |
function next(a, b, noCut) { | |
var nextCell, nextVertex, nextDir | |
for(var i=0; i<2; ++i) { | |
if(adj[i][b].length > 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<nbhd.length; ++k) { | |
var e = nbhd[k] | |
var p = e[dir^1] | |
var cmp = compareAngle( | |
positions[a], | |
positions[b], | |
positions[nextVertex], | |
positions[p]) | |
if(cmp > 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<numVertices; ++i) { | |
for(var j=0; j<2; ++j) { | |
var pcycle = [] | |
while(adj[j][i].length > 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 | |
} | |
},{"compare-angle":106}],106:[function(require,module,exports){ | |
"use strict" | |
module.exports = compareAngle | |
var orient = require("robust-orientation") | |
var sgn = require("signum") | |
var twoSum = require("two-sum") | |
var robustProduct = require("robust-product") | |
var robustSum = require("robust-sum") | |
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 | |
} | |
} | |
} | |
} | |
},{"robust-orientation":120,"robust-product":108,"robust-sum":121,"signum":109,"two-sum":110}],107:[function(require,module,exports){ | |
arguments[4][44][0].apply(exports,arguments) | |
},{"dup":44,"two-product":122,"two-sum":110}],108:[function(require,module,exports){ | |
"use strict" | |
var robustSum = require("robust-sum") | |
var robustScale = require("robust-scale") | |
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<a.length; ++i) { | |
r = robustSum(r, robustScale(b, a[i])) | |
} | |
} else { | |
for(var i=0; i<b.length; ++i) { | |
r = robustSum(r, robustScale(a, b[i])) | |
} | |
} | |
return r | |
} | |
},{"robust-scale":107,"robust-sum":121}],109:[function(require,module,exports){ | |
"use strict" | |
module.exports = function signum(x) { | |
if(x < 0) { return -1 } | |
if(x > 0) { return 1 } | |
return 0.0 | |
} | |
},{}],110:[function(require,module,exports){ | |
arguments[4][43][0].apply(exports,arguments) | |
},{"dup":43}],111:[function(require,module,exports){ | |
"use strict" | |
function compileSearch(funcName, predicate, reversed, extraArgs, useNdarray, earlyOut) { | |
var code = [ | |
"function ", funcName, "(a,l,h,", extraArgs.join(","), "){", | |
earlyOut ? "" : "var i=", (reversed ? "l-1" : "h+1"), | |
";while(l<=h){\ | |
var m=(l+h)>>>1,x=a", useNdarray ? ".get(m)" : "[m]"] | |
if(earlyOut) { | |
if(predicate.indexOf("c") < 0) { | |
code.push(";if(x===y){return m}else if(x<=y){") | |
} else { | |
code.push(";var p=c(x,y);if(p===0){return m}else if(p<=0){") | |
} | |
} else { | |
code.push(";if(", predicate, "){i=m;") | |
} | |
if(reversed) { | |
code.push("l=m+1}else{h=m-1}") | |
} else { | |
code.push("h=m-1}else{l=m+1}") | |
} | |
code.push("}") | |
if(earlyOut) { | |
code.push("return -1};") | |
} else { | |
code.push("return i};") | |
} | |
return code.join("") | |
} | |
function compileBoundsSearch(predicate, reversed, suffix, earlyOut) { | |
var result = new Function([ | |
compileSearch("A", "x" + predicate + "y", reversed, ["y"], false, earlyOut), | |
compileSearch("B", "x" + predicate + "y", reversed, ["y"], true, earlyOut), | |
compileSearch("P", "c(x,y)" + predicate + "0", reversed, ["y", "c"], false, earlyOut), | |
compileSearch("Q", "c(x,y)" + predicate + "0", reversed, ["y", "c"], true, earlyOut), | |
"function dispatchBsearch", suffix, "(a,y,c,l,h){\ | |
if(a.shape){\ | |
if(typeof(c)==='function'){\ | |
return Q(a,(l===undefined)?0:l|0,(h===undefined)?a.shape[0]-1:h|0,y,c)\ | |
}else{\ | |
return B(a,(c===undefined)?0:c|0,(l===undefined)?a.shape[0]-1:l|0,y)\ | |
}}else{\ | |
if(typeof(c)==='function'){\ | |
return P(a,(l===undefined)?0:l|0,(h===undefined)?a.length-1:h|0,y,c)\ | |
}else{\ | |
return A(a,(c===undefined)?0:c|0,(l===undefined)?a.length-1:l|0,y)\ | |
}}}\ | |
return dispatchBsearch", suffix].join("")) | |
return result() | |
} | |
module.exports = { | |
ge: compileBoundsSearch(">=", false, "GE"), | |
gt: compileBoundsSearch(">", false, "GT"), | |
lt: compileBoundsSearch("<", true, "LT"), | |
le: compileBoundsSearch("<=", true, "LE"), | |
eq: compileBoundsSearch("-", true, "EQ", true) | |
} | |
},{}],112:[function(require,module,exports){ | |
"use strict" | |
var bounds = require("binary-search-bounds") | |
var NOT_FOUND = 0 | |
var SUCCESS = 1 | |
var EMPTY = 2 | |
module.exports = createWrapper | |
function IntervalTreeNode(mid, left, right, leftPoints, rightPoints) { | |
this.mid = mid | |
this.left = left | |
this.right = right | |
this.leftPoints = leftPoints | |
this.rightPoints = rightPoints | |
this.count = (left ? left.count : 0) + (right ? right.count : 0) + leftPoints.length | |
} | |
var proto = IntervalTreeNode.prototype | |
function copy(a, b) { | |
a.mid = b.mid | |
a.left = b.left | |
a.right = b.right | |
a.leftPoints = b.leftPoints | |
a.rightPoints = b.rightPoints | |
a.count = b.count | |
} | |
function rebuild(node, intervals) { | |
var ntree = createIntervalTree(intervals) | |
node.mid = ntree.mid | |
node.left = ntree.left | |
node.right = ntree.right | |
node.leftPoints = ntree.leftPoints | |
node.rightPoints = ntree.rightPoints | |
node.count = ntree.count | |
} | |
function rebuildWithInterval(node, interval) { | |
var intervals = node.intervals([]) | |
intervals.push(interval) | |
rebuild(node, intervals) | |
} | |
function rebuildWithoutInterval(node, interval) { | |
var intervals = node.intervals([]) | |
var idx = intervals.indexOf(interval) | |
if(idx < 0) { | |
return NOT_FOUND | |
} | |
intervals.splice(idx, 1) | |
rebuild(node, intervals) | |
return SUCCESS | |
} | |
proto.intervals = function(result) { | |
result.push.apply(result, this.leftPoints) | |
if(this.left) { | |
this.left.intervals(result) | |
} | |
if(this.right) { | |
this.right.intervals(result) | |
} | |
return result | |
} | |
proto.insert = function(interval) { | |
var weight = this.count - this.leftPoints.length | |
this.count += 1 | |
if(interval[1] < this.mid) { | |
if(this.left) { | |
if(4*(this.left.count+1) > 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<this.leftPoints.length; ++l) { | |
if(this.leftPoints[l][0] !== interval[0]) { | |
break | |
} | |
if(this.leftPoints[l] === interval) { | |
this.count -= 1 | |
this.leftPoints.splice(l, 1) | |
for(var r = bounds.ge(this.rightPoints, interval, compareEnd); r<this.rightPoints.length; ++r) { | |
if(this.rightPoints[r][1] !== interval[1]) { | |
break | |
} else if(this.rightPoints[r] === interval) { | |
this.rightPoints.splice(r, 1) | |
return SUCCESS | |
} | |
} | |
} | |
} | |
return NOT_FOUND | |
} | |
} | |
function reportLeftRange(arr, hi, cb) { | |
for(var i=0; i<arr.length && arr[i][0] <= hi; ++i) { | |
var r = cb(arr[i]) | |
if(r) { return r } | |
} | |
} | |
function reportRightRange(arr, lo, cb) { | |
for(var i=arr.length-1; i>=0 && arr[i][1] >= lo; --i) { | |
var r = cb(arr[i]) | |
if(r) { return r } | |
} | |
} | |
function reportRange(arr, cb) { | |
for(var i=0; i<arr.length; ++i) { | |
var r = cb(arr[i]) | |
if(r) { return r } | |
} | |
} | |
proto.queryPoint = function(x, cb) { | |
if(x < this.mid) { | |
if(this.left) { | |
var r = this.left.queryPoint(x, cb) | |
if(r) { return r } | |
} | |
return reportLeftRange(this.leftPoints, x, cb) | |
} else if(x > 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<intervals.length; ++i) { | |
pts.push(intervals[i][0], intervals[i][1]) | |
} | |
pts.sort(compareNumbers) | |
var mid = pts[pts.length>>1] | |
var leftIntervals = [] | |
var rightIntervals = [] | |
var centerIntervals = [] | |
for(var i=0; i<intervals.length; ++i) { | |
var s = intervals[i] | |
if(s[1] < mid) { | |
leftIntervals.push(s) | |
} else if(mid < s[0]) { | |
rightIntervals.push(s) | |
} else { | |
centerIntervals.push(s) | |
} | |
} | |
//Split center intervals | |
var leftPoints = centerIntervals | |
var rightPoints = centerIntervals.slice() | |
leftPoints.sort(compareBegin) | |
rightPoints.sort(compareEnd) | |
return new IntervalTreeNode(mid, | |
createIntervalTree(leftIntervals), | |
createIntervalTree(rightIntervals), | |
leftPoints, | |
rightPoints) | |
} | |
//User friendly wrapper that makes it possible to support empty trees | |
function IntervalTree(root) { | |
this.root = root | |
} | |
var tproto = IntervalTree.prototype | |
tproto.insert = function(interval) { | |
if(this.root) { | |
this.root.insert(interval) | |
} else { | |
this.root = new IntervalTreeNode(interval[0], null, null, [interval], [interval]) | |
} | |
} | |
tproto.remove = function(interval) { | |
if(this.root) { | |
var r = this.root.remove(interval) | |
if(r === EMPTY) { | |
this.root = null | |
} | |
return r !== NOT_FOUND | |
} | |
return false | |
} | |
tproto.queryPoint = function(p, cb) { | |
if(this.root) { | |
return this.root.queryPoint(p, cb) | |
} | |
} | |
tproto.queryInterval = function(lo, hi, cb) { | |
if(lo <= hi && this.root) { | |
return this.root.queryInterval(lo, hi, cb) | |
} | |
} | |
Object.defineProperty(tproto, "count", { | |
get: function() { | |
if(this.root) { | |
return this.root.count | |
} | |
return 0 | |
} | |
}) | |
Object.defineProperty(tproto, "intervals", { | |
get: function() { | |
if(this.root) { | |
return this.root.intervals([]) | |
} | |
return [] | |
} | |
}) | |
function createWrapper(intervals) { | |
if(!intervals || intervals.length === 0) { | |
return new IntervalTree(null) | |
} | |
return new IntervalTree(createIntervalTree(intervals)) | |
} | |
},{"binary-search-bounds":111}],113:[function(require,module,exports){ | |
"use strict" | |
module.exports = orderSegments | |
var orient = require("robust-orientation") | |
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] | |
} | |
},{"robust-orientation":120}],114:[function(require,module,exports){ | |
"use strict" | |
module.exports = createRBTree | |
var RED = 0 | |
var BLACK = 1 | |
function RBNode(color, key, value, left, right, count) { | |
this._color = color | |
this.key = key | |
this.value = value | |
this.left = left | |
this.right = right | |
this._count = count | |
} | |
function cloneNode(node) { | |
return new RBNode(node._color, node.key, node.value, node.left, node.right, node._count) | |
} | |
function repaint(color, node) { | |
return new RBNode(color, node.key, node.value, node.left, node.right, node._count) | |
} | |
function recount(node) { | |
node._count = 1 + (node.left ? node.left._count : 0) + (node.right ? node.right._count : 0) | |
} | |
function RedBlackTree(compare, root) { | |
this._compare = compare | |
this.root = root | |
} | |
var proto = RedBlackTree.prototype | |
Object.defineProperty(proto, "keys", { | |
get: function() { | |
var result = [] | |
this.forEach(function(k,v) { | |
result.push(k) | |
}) | |
return result | |
} | |
}) | |
Object.defineProperty(proto, "values", { | |
get: function() { | |
var result = [] | |
this.forEach(function(k,v) { | |
result.push(v) | |
}) | |
return result | |
} | |
}) | |
//Returns the number of nodes in the tree | |
Object.defineProperty(proto, "length", { | |
get: function() { | |
if(this.root) { | |
return this.root._count | |
} | |
return 0 | |
} | |
}) | |
//Insert a new item into the tree | |
proto.insert = function(key, value) { | |
var cmp = this._compare | |
//Find point to insert new node at | |
var n = this.root | |
var n_stack = [] | |
var d_stack = [] | |
while(n) { | |
var d = cmp(key, n.key) | |
n_stack.push(n) | |
d_stack.push(d) | |
if(d <= 0) { | |
n = n.left | |
} else { | |
n = n.right | |
} | |
} | |
//Rebuild path to leaf node | |
n_stack.push(new RBNode(RED, key, value, null, null, 1)) | |
for(var s=n_stack.length-2; s>=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<cstack.length; ++i) { | |
cstack[i]._count-- | |
} | |
return new RedBlackTree(this.tree._compare, cstack[0]) | |
} else { | |
if(n.left || n.right) { | |
//Second easy case: Single child black parent | |
//console.log("BLACK single child") | |
if(n.left) { | |
swapNode(n, n.left) | |
} else if(n.right) { | |
swapNode(n, n.right) | |
} | |
//Child must be red, so repaint it black to balance color | |
n._color = BLACK | |
for(var i=0; i<cstack.length-1; ++i) { | |
cstack[i]._count-- | |
} | |
return new RedBlackTree(this.tree._compare, cstack[0]) | |
} else if(cstack.length === 1) { | |
//Third easy case: root | |
//console.log("ROOT") | |
return new RedBlackTree(this.tree._compare, null) | |
} else { | |
//Hard case: Repaint n, and then do some nasty stuff | |
//console.log("BLACK leaf no children") | |
for(var i=0; i<cstack.length; ++i) { | |
cstack[i]._count-- | |
} | |
var parent = cstack[cstack.length-2] | |
fixDoubleBlack(cstack) | |
//Fix up links | |
if(parent.left === n) { | |
parent.left = null | |
} else { | |
parent.right = null | |
} | |
} | |
} | |
return new RedBlackTree(this.tree._compare, cstack[0]) | |
} | |
//Returns key | |
Object.defineProperty(iproto, "key", { | |
get: function() { | |
if(this._stack.length > 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) | |
} | |
},{}],115:[function(require,module,exports){ | |
"use strict" | |
module.exports = createSlabDecomposition | |
var bounds = require("binary-search-bounds") | |
var createRBTree = require("functional-red-black-tree") | |
var orient = require("robust-orientation") | |
var orderSegments = require("./lib/order-segments") | |
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<numSegments; ++i) { | |
var s = segments[i] | |
var f = s[0][0] < s[1][0] | |
events[2*i] = new Event(s[0][0], s, f, i) | |
events[2*i+1] = new Event(s[1][0], s, !f, i) | |
} | |
events.sort(function(a,b) { | |
var d = a.x - b.x | |
if(d) { | |
return d | |
} | |
d = a.create - b.create | |
if(d) { | |
return d | |
} | |
return Math.min(a.segment[0][1], a.segment[1][1]) - Math.min(b.segment[0][1], b.segment[1][1]) | |
}) | |
var tree = createRBTree(orderSegments) | |
var slabs = [] | |
var lines = [] | |
var horizontal = [] | |
var lastX = -Infinity | |
for(var i=0; i<numEvents; ) { | |
var x = events[i].x | |
var horiz = [] | |
while(i < numEvents) { | |
var e = events[i] | |
if(e.x !== x) { | |
break | |
} | |
i += 1 | |
if(e.segment[0][0] === e.x && e.segment[1][0] === e.x) { | |
if(e.create) { | |
if(e.segment[0][1] < e.segment[1][1]) { | |
horiz.push(new IntervalSegment( | |
e.segment[0][1], | |
e.index, | |
true, | |
true)) | |
horiz.push(new IntervalSegment( | |
e.segment[1][1], | |
e.index, | |
false, | |
false)) | |
} else { | |
horiz.push(new IntervalSegment( | |
e.segment[1][1], | |
e.index, | |
true, | |
false)) | |
horiz.push(new IntervalSegment( | |
e.segment[0][1], | |
e.index, | |
false, | |
true)) | |
} | |
} | |
} else { | |
if(e.create) { | |
tree = tree.insert(e.segment, e.index) | |
} else { | |
tree = tree.remove(e.segment) | |
} | |
} | |
} | |
slabs.push(tree.root) | |
lines.push(x) | |
horizontal.push(horiz) | |
} | |
return new SlabDecomposition(slabs, lines, horizontal) | |
} | |
},{"./lib/order-segments":113,"binary-search-bounds":111,"functional-red-black-tree":114,"robust-orientation":120}],116:[function(require,module,exports){ | |
module.exports = preprocessPolygon | |
var orient = require('robust-orientation')[3] | |
var makeSlabs = require('slab-decomposition') | |
var makeIntervalTree = require('interval-tree-1d') | |
var bsearch = require('binary-search-bounds') | |
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<segments.length; ++i) { | |
var s = segments[i] | |
var x = s[0][0] | |
var y0 = s[0][1] | |
var y1 = s[1][1] | |
var p = [ Math.min(y0, y1), Math.max(y0, y1) ] | |
if(x in table) { | |
table[x].push(p) | |
} else { | |
table[x] = [ p ] | |
} | |
} | |
var intervalTable = {} | |
var keys = Object.keys(table) | |
for(var i=0; i<keys.length; ++i) { | |
var segs = table[keys[i]] | |
intervalTable[keys[i]] = makeIntervalTree(segs) | |
} | |
return intervalSearch(intervalTable) | |
} | |
function buildSlabSearch(slabs, coordinates) { | |
return function(p) { | |
var bucket = bsearch.le(coordinates, p[0]) | |
if(bucket < 0) { | |
return 1 | |
} | |
var root = slabs[bucket] | |
if(!root) { | |
if(bucket > 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<numLoops; ++i) { | |
var loop = loops[i] | |
var numVertices = loop.length | |
for(var s=numVertices-1,t=0; t<numVertices; s=(t++)) { | |
var a = loop[s] | |
var b = loop[t] | |
if(a[0] === b[0]) { | |
vsegments.push([a,b]) | |
} else { | |
segments.push([a,b]) | |
} | |
} | |
} | |
//Degenerate case: All loops are empty | |
if(segments.length === 0) { | |
if(vsegments.length === 0) { | |
return classifyEmpty | |
} else { | |
return createClassifyVertical(buildVerticalIndex(vsegments)) | |
} | |
} | |
//Build slab decomposition | |
var slabs = makeSlabs(segments) | |
var testSlab = buildSlabSearch(slabs.slabs, slabs.coordinates) | |
if(vsegments.length === 0) { | |
return testSlab | |
} else { | |
return createClassifyPointDegen( | |
buildVerticalIndex(vsegments), | |
testSlab) | |
} | |
} | |
},{"binary-search-bounds":111,"interval-tree-1d":112,"robust-orientation":120,"slab-decomposition":115}],117:[function(require,module,exports){ | |
arguments[4][43][0].apply(exports,arguments) | |
},{"dup":43}],118:[function(require,module,exports){ | |
arguments[4][44][0].apply(exports,arguments) | |
},{"dup":44,"two-product":122,"two-sum":117}],119:[function(require,module,exports){ | |
arguments[4][45][0].apply(exports,arguments) | |
},{"dup":45}],120:[function(require,module,exports){ | |
arguments[4][53][0].apply(exports,arguments) | |
},{"dup":53,"robust-scale":118,"robust-subtract":119,"robust-sum":121,"two-product":122}],121:[function(require,module,exports){ | |
arguments[4][46][0].apply(exports,arguments) | |
},{"dup":46}],122:[function(require,module,exports){ | |
arguments[4][47][0].apply(exports,arguments) | |
},{"dup":47}],123:[function(require,module,exports){ | |
arguments[4][11][0].apply(exports,arguments) | |
},{"dup":11}],124:[function(require,module,exports){ | |
'use strict' | |
module.exports = planarGraphToPolyline | |
var e2a = require('edges-to-adjacency-list') | |
var planarDual = require('planar-dual') | |
var preprocessPolygon = require('point-in-big-polygon') | |
var twoProduct = require('two-product') | |
var robustSum = require('robust-sum') | |
var uniq = require('uniq') | |
var trimLeaves = require('./lib/trim-leaves') | |
function makeArray(length, fill) { | |
var result = new Array(length) | |
for(var i=0; i<length; ++i) { | |
result[i] = fill | |
} | |
return result | |
} | |
function makeArrayOfArrays(length) { | |
var result = new Array(length) | |
for(var i=0; i<length; ++i) { | |
result[i] = [] | |
} | |
return result | |
} | |
function planarGraphToPolyline(edges, positions) { | |
//Trim leaves | |
var result = trimLeaves(edges, positions) | |
edges = result[0] | |
positions = result[1] | |
var numVertices = positions.length | |
var numEdges = edges.length | |
//Calculate adjacency list, check manifold | |
var adj = e2a(edges, positions.length) | |
for(var i=0; i<numVertices; ++i) { | |
if(adj[i].length % 2 === 1) { | |
throw new Error('planar-graph-to-polyline: graph must be manifold') | |
} | |
} | |
//Get faces | |
var faces = planarDual(edges, positions) | |
//Check orientation of a polygon using exact arithmetic | |
function ccw(c) { | |
var n = c.length | |
var area = [0] | |
for(var j=0; j<n; ++j) { | |
var a = positions[c[j]] | |
var b = positions[c[(j+1)%n]] | |
var t00 = twoProduct(-a[0], a[1]) | |
var t01 = twoProduct(-a[0], b[1]) | |
var t10 = twoProduct( b[0], a[1]) | |
var t11 = twoProduct( b[0], b[1]) | |
area = robustSum(area, robustSum(robustSum(t00, t01), robustSum(t10, t11))) | |
} | |
return area[area.length-1] > 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<numFaces; ++i) { | |
parent[i] = i | |
var row = new Array(numFaces) | |
var loopVertices = faces[i].map(function(v) { | |
return positions[v] | |
}) | |
var pmc = preprocessPolygon([loopVertices]) | |
var count = 0 | |
outer: | |
for(var j=0; j<numFaces; ++j) { | |
row[j] = 0 | |
if(i === j) { | |
continue | |
} | |
var c = faces[j] | |
var n = c.length | |
for(var k=0; k<n; ++k) { | |
var d = pmc(positions[c[k]]) | |
if(d !== 0) { | |
if(d < 0) { | |
row[j] = 1 | |
count += 1 | |
} | |
continue outer | |
} | |
} | |
row[j] = 1 | |
count += 1 | |
} | |
containment[i] = [count, i, row] | |
} | |
containment.sort(function(a,b) { | |
return b[0] - a[0] | |
}) | |
for(var i=0; i<numFaces; ++i) { | |
var row = containment[i] | |
var idx = row[1] | |
var children = row[2] | |
for(var j=0; j<numFaces; ++j) { | |
if(children[j]) { | |
parent[j] = idx | |
} | |
} | |
} | |
//Initialize face adjacency list | |
var fadj = makeArrayOfArrays(numFaces) | |
for(var i=0; i<numFaces; ++i) { | |
fadj[i].push(parent[i]) | |
fadj[parent[i]].push(i) | |
} | |
//Build adjacency matrix for edges | |
var edgeAdjacency = {} | |
var internalVertices = makeArray(numVertices, false) | |
for(var i=0; i<numFaces; ++i) { | |
var c = faces[i] | |
var n = c.length | |
for(var j=0; j<n; ++j) { | |
var a = c[j] | |
var b = c[(j+1)%n] | |
var key = Math.min(a,b) + ":" + Math.max(a,b) | |
if(key in edgeAdjacency) { | |
var neighbor = edgeAdjacency[key] | |
fadj[neighbor].push(i) | |
fadj[i].push(neighbor) | |
internalVertices[a] = internalVertices[b] = true | |
} else { | |
edgeAdjacency[key] = i | |
} | |
} | |
} | |
function sharedBoundary(c) { | |
var n = c.length | |
for(var i=0; i<n; ++i) { | |
if(!internalVertices[c[i]]) { | |
return false | |
} | |
} | |
return true | |
} | |
var toVisit = [] | |
var parity = makeArray(numFaces, -1) | |
for(var i=0; i<numFaces; ++i) { | |
if(parent[i] === i && !sharedBoundary(faces[i])) { | |
toVisit.push(i) | |
parity[i] = 0 | |
} else { | |
parity[i] = -1 | |
} | |
} | |
//Using face adjacency, classify faces as in/out | |
var result = [] | |
while(toVisit.length > 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<nnbhr; ++i) { | |
var f = nbhd[i] | |
if(parity[f] >= 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 | |
} | |
},{"./lib/trim-leaves":103,"edges-to-adjacency-list":104,"planar-dual":105,"point-in-big-polygon":116,"robust-sum":121,"two-product":122,"uniq":123}],125:[function(require,module,exports){ | |
arguments[4][43][0].apply(exports,arguments) | |
},{"dup":43}],126:[function(require,module,exports){ | |
arguments[4][44][0].apply(exports,arguments) | |
},{"dup":44,"two-product":129,"two-sum":125}],127:[function(require,module,exports){ | |
arguments[4][45][0].apply(exports,arguments) | |
},{"dup":45}],128:[function(require,module,exports){ | |
arguments[4][46][0].apply(exports,arguments) | |
},{"dup":46}],129:[function(require,module,exports){ | |
arguments[4][47][0].apply(exports,arguments) | |
},{"dup":47}],130:[function(require,module,exports){ | |
arguments[4][53][0].apply(exports,arguments) | |
},{"dup":53,"robust-scale":126,"robust-subtract":127,"robust-sum":128,"two-product":129}],131:[function(require,module,exports){ | |
arguments[4][15][0].apply(exports,arguments) | |
},{"dup":15}],132:[function(require,module,exports){ | |
"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<count; ++i) { | |
this.roots[i] = i; | |
this.ranks[i] = 0; | |
} | |
} | |
UnionFind.prototype.length = function() { | |
return this.roots.length; | |
} | |
UnionFind.prototype.makeSet = function() { | |
var n = this.roots.length; | |
this.roots.push(n); | |
this.ranks.push(0); | |
return n; | |
} | |
UnionFind.prototype.find = function(x) { | |
var roots = this.roots; | |
while(roots[x] !== x) { | |
var y = roots[x]; | |
roots[x] = roots[y]; | |
x = y; | |
} | |
return x; | |
} | |
UnionFind.prototype.link = function(x, y) { | |
var xr = this.find(x) | |
, yr = this.find(y); | |
if(xr === yr) { | |
return; | |
} | |
var ranks = this.ranks | |
, roots = this.roots | |
, xd = ranks[xr] | |
, yd = ranks[yr]; | |
if(xd < yd) { | |
roots[xr] = yr; | |
} else if(yd < xd) { | |
roots[yr] = xr; | |
} else { | |
roots[yr] = xr; | |
++ranks[xr]; | |
} | |
} | |
},{}],133:[function(require,module,exports){ | |
"use strict"; "use restrict"; | |
var bits = require("bit-twiddle") | |
, UnionFind = require("union-find") | |
//Returns the dimension of a cell complex | |
function dimension(cells) { | |
var d = 0 | |
, max = Math.max | |
for(var i=0, il=cells.length; i<il; ++i) { | |
d = max(d, cells[i].length) | |
} | |
return d-1 | |
} | |
exports.dimension = dimension | |
//Counts the number of vertices in faces | |
function countVertices(cells) { | |
var vc = -1 | |
, max = Math.max | |
for(var i=0, il=cells.length; i<il; ++i) { | |
var c = cells[i] | |
for(var j=0, jl=c.length; j<jl; ++j) { | |
vc = max(vc, c[j]) | |
} | |
} | |
return vc+1 | |
} | |
exports.countVertices = countVertices | |
//Returns a deep copy of cells | |
function cloneCells(cells) { | |
var ncells = new Array(cells.length) | |
for(var i=0, il=cells.length; i<il; ++i) { | |
ncells[i] = cells[i].slice(0) | |
} | |
return ncells | |
} | |
exports.cloneCells = cloneCells | |
//Ranks a pair of cells up to permutation | |
function compareCells(a, b) { | |
var n = a.length | |
, t = a.length - b.length | |
, min = Math.min | |
if(t) { | |
return t | |
} | |
switch(n) { | |
case 0: | |
return 0; | |
case 1: | |
return a[0] - b[0]; | |
case 2: | |
var d = a[0]+a[1]-b[0]-b[1] | |
if(d) { | |
return d | |
} | |
return min(a[0],a[1]) - min(b[0],b[1]) | |
case 3: | |
var l1 = a[0]+a[1] | |
, m1 = b[0]+b[1] | |
d = l1+a[2] - (m1+b[2]) | |
if(d) { | |
return d | |
} | |
var l0 = min(a[0], a[1]) | |
, m0 = min(b[0], b[1]) | |
, d = min(l0, a[2]) - min(m0, b[2]) | |
if(d) { | |
return d | |
} | |
return min(l0+a[2], l1) - min(m0+b[2], m1) | |
//TODO: Maybe optimize n=4 as well? | |
default: | |
var as = a.slice(0) | |
as.sort() | |
var bs = b.slice(0) | |
bs.sort() | |
for(var i=0; i<n; ++i) { | |
t = as[i] - bs[i] | |
if(t) { | |
return t | |
} | |
} | |
return 0 | |
} | |
} | |
exports.compareCells = compareCells | |
function compareZipped(a, b) { | |
return compareCells(a[0], b[0]) | |
} | |
//Puts a cell complex into normal order for the purposes of findCell queries | |
function normalize(cells, attr) { | |
if(attr) { | |
var len = cells.length | |
var zipped = new Array(len) | |
for(var i=0; i<len; ++i) { | |
zipped[i] = [cells[i], attr[i]] | |
} | |
zipped.sort(compareZipped) | |
for(var i=0; i<len; ++i) { | |
cells[i] = zipped[i][0] | |
attr[i] = zipped[i][1] | |
} | |
return cells | |
} else { | |
cells.sort(compareCells) | |
return cells | |
} | |
} | |
exports.normalize = normalize | |
//Removes all duplicate cells in the complex | |
function unique(cells) { | |
if(cells.length === 0) { | |
return [] | |
} | |
var ptr = 1 | |
, len = cells.length | |
for(var i=1; i<len; ++i) { | |
var a = cells[i] | |
if(compareCells(a, cells[i-1])) { | |
if(i === ptr) { | |
ptr++ | |
continue | |
} | |
cells[ptr++] = a | |
} | |
} | |
cells.length = ptr | |
return cells | |
} | |
exports.unique = unique; | |
//Finds a cell in a normalized cell complex | |
function findCell(cells, c) { | |
var lo = 0 | |
, hi = cells.length-1 | |
, r = -1 | |
while (lo <= hi) { | |
var mid = (lo + hi) >> 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<il; ++i) { | |
index[i] = [] | |
} | |
var b = [] | |
for(var i=0, n=to_cells.length; i<n; ++i) { | |
var c = to_cells[i] | |
var cl = c.length | |
for(var k=1, kn=(1<<cl); k<kn; ++k) { | |
b.length = bits.popCount(k) | |
var l = 0 | |
for(var j=0; j<cl; ++j) { | |
if(k & (1<<j)) { | |
b[l++] = c[j] | |
} | |
} | |
var idx=findCell(from_cells, b) | |
if(idx < 0) { | |
continue | |
} | |
while(true) { | |
index[idx++].push(i) | |
if(idx >= 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<vertex_count; ++i) { | |
res[i] = [] | |
} | |
for(var i=0, len=cells.length; i<len; ++i) { | |
var c = cells[i] | |
for(var j=0, cl=c.length; j<cl; ++j) { | |
res[c[j]].push(i) | |
} | |
} | |
return res | |
} | |
exports.dual = dual | |
//Enumerates all cells in the complex | |
function explode(cells) { | |
var result = [] | |
for(var i=0, il=cells.length; i<il; ++i) { | |
var c = cells[i] | |
, cl = c.length|0 | |
for(var j=1, jl=(1<<cl); j<jl; ++j) { | |
var b = [] | |
for(var k=0; k<cl; ++k) { | |
if((j >>> 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<cells.length; ++i) { | |
var c = cells[i] | |
for(var k=k0; k<(1<<c.length); k=bits.nextCombination(k)) { | |
var b = new Array(n+1) | |
, l = 0 | |
for(var j=0; j<c.length; ++j) { | |
if(k & (1<<j)) { | |
b[l++] = c[j] | |
} | |
} | |
result.push(b) | |
} | |
} | |
return normalize(result) | |
} | |
exports.skeleton = skeleton; | |
//Computes the boundary of all cells, does not remove duplicates | |
function boundary(cells) { | |
var res = [] | |
for(var i=0,il=cells.length; i<il; ++i) { | |
var c = cells[i] | |
for(var j=0,cl=c.length; j<cl; ++j) { | |
var b = new Array(c.length-1) | |
for(var k=0, l=0; k<cl; ++k) { | |
if(k !== j) { | |
b[l++] = c[k] | |
} | |
} | |
res.push(b) | |
} | |
} | |
return normalize(res) | |
} | |
exports.boundary = boundary; | |
//Computes connected components for a dense cell complex | |
function connectedComponents_dense(cells, vertex_count) { | |
var labels = new UnionFind(vertex_count) | |
for(var i=0; i<cells.length; ++i) { | |
var c = cells[i] | |
for(var j=0; j<c.length; ++j) { | |
for(var k=j+1; k<c.length; ++k) { | |
labels.link(c[j], c[k]) | |
} | |
} | |
} | |
var components = [] | |
, component_labels = labels.ranks | |
for(var i=0; i<component_labels.length; ++i) { | |
component_labels[i] = -1 | |
} | |
for(var i=0; i<cells.length; ++i) { | |
var l = labels.find(cells[i][0]) | |
if(component_labels[l] < 0) { | |
component_labels[l] = components.length | |
components.push([cells[i].slice(0)]) | |
} else { | |
components[component_labels[l]].push(cells[i].slice(0)) | |
} | |
} | |
return components | |
} | |
//Computes connected components for a sparse graph | |
function connectedComponents_sparse(cells) { | |
var vertices = unique(normalize(skeleton(cells, 0))) | |
, labels = new UnionFind(vertices.length) | |
for(var i=0; i<cells.length; ++i) { | |
var c = cells[i] | |
for(var j=0; j<c.length; ++j) { | |
var vj = findCell(vertices, [c[j]]) | |
for(var k=j+1; k<c.length; ++k) { | |
labels.link(vj, findCell(vertices, [c[k]])) | |
} | |
} | |
} | |
var components = [] | |
, component_labels = labels.ranks | |
for(var i=0; i<component_labels.length; ++i) { | |
component_labels[i] = -1 | |
} | |
for(var i=0; i<cells.length; ++i) { | |
var l = labels.find(findCell(vertices, [cells[i][0]])); | |
if(component_labels[l] < 0) { | |
component_labels[l] = components.length | |
components.push([cells[i].slice(0)]) | |
} else { | |
components[component_labels[l]].push(cells[i].slice(0)) | |
} | |
} | |
return components | |
} | |
//Computes connected components for a cell complex | |
function connectedComponents(cells, vertex_count) { | |
if(vertex_count) { | |
return connectedComponents_dense(cells, vertex_count) | |
} | |
return connectedComponents_sparse(cells) | |
} | |
exports.connectedComponents = connectedComponents | |
},{"bit-twiddle":131,"union-find":132}],134:[function(require,module,exports){ | |
"use strict" | |
module.exports = simplifyPolygon | |
var orient = require("robust-orientation") | |
var sc = require("simplicial-complex") | |
function errorWeight(base, a, b) { | |
var area = Math.abs(orient(base, a, b)) | |
var perim = Math.sqrt(Math.pow(a[0] - b[0], 2) + Math.pow(a[1]-b[1], 2)) | |
return area / perim | |
} | |
function simplifyPolygon(cells, positions, minArea) { | |
var n = positions.length | |
var nc = cells.length | |
var inv = new Array(n) | |
var outv = new Array(n) | |
var weights = new Array(n) | |
var dead = new Array(n) | |
//Initialize tables | |
for(var i=0; i<n; ++i) { | |
inv[i] = outv[i] = -1 | |
weights[i] = Infinity | |
dead[i] = false | |
} | |
//Compute neighbors | |
for(var i=0; i<nc; ++i) { | |
var c = cells[i] | |
if(c.length !== 2) { | |
throw new Error("Input must be a graph") | |
} | |
var s = c[1] | |
var t = c[0] | |
if(outv[t] !== -1) { | |
outv[t] = -2 | |
} else { | |
outv[t] = s | |
} | |
if(inv[s] !== -1) { | |
inv[s] = -2 | |
} else { | |
inv[s] = t | |
} | |
} | |
//Updates the weight for vertex i | |
function computeWeight(i) { | |
if(dead[i]) { | |
return Infinity | |
} | |
//TODO: Check that the line segment doesn't cross once simplified | |
var s = inv[i] | |
var t = outv[i] | |
if((s<0) || (t<0)) { | |
return Infinity | |
} else { | |
return errorWeight(positions[i], positions[s], positions[t]) | |
} | |
} | |
//Swaps two nodes on the heap (i,j) are the index of the nodes | |
function heapSwap(i,j) { | |
var a = heap[i] | |
var b = heap[j] | |
heap[i] = b | |
heap[j] = a | |
index[a] = j | |
index[b] = i | |
} | |
//Returns the weight of node i on the heap | |
function heapWeight(i) { | |
return weights[heap[i]] | |
} | |
function heapParent(i) { | |
if(i & 1) { | |
return (i - 1) >> 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<n; ++i) { | |
var w = weights[i] = computeWeight(i) | |
if(w < Infinity) { | |
index[i] = heap.length | |
heap.push(i) | |
} else { | |
index[i] = -1 | |
} | |
} | |
var heapCount = heap.length | |
for(var i=heapCount>>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<n; ++i) { | |
if(!dead[i]) { | |
index[i] = npositions.length | |
npositions.push(positions[i].slice()) | |
} | |
} | |
var nv = npositions.length | |
function tortoiseHare(seq, start) { | |
if(seq[start] < 0) { | |
return start | |
} | |
var t = start | |
var h = start | |
do { | |
//Walk two steps with h | |
var nh = seq[h] | |
if(!dead[h] || nh < 0 || nh === h) { | |
break | |
} | |
h = nh | |
nh = seq[h] | |
if(!dead[h] || nh < 0 || nh === h) { | |
break | |
} | |
h = nh | |
//Walk one step with t | |
t = seq[t] | |
} while(t !== h) | |
//Compress cycles | |
for(var v=start; v!==h; v = seq[v]) { | |
seq[v] = h | |
} | |
return h | |
} | |
var ncells = [] | |
cells.forEach(function(c) { | |
var tin = tortoiseHare(inv, c[0]) | |
var tout = tortoiseHare(outv, c[1]) | |
if(tin >= 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 | |
} | |
} | |
},{"robust-orientation":130,"simplicial-complex":133}],135:[function(require,module,exports){ | |
"use strict" | |
var pool = require("typedarray-pool") | |
module.exports = createSurfaceExtractor | |
//Helper macros | |
function array(i) { | |
return "a" + i | |
} | |
function data(i) { | |
return "d" + i | |
} | |
function cube(i,bitmask) { | |
return "c" + i + "_" + bitmask | |
} | |
function shape(i) { | |
return "s" + i | |
} | |
function stride(i,j) { | |
return "t" + i + "_" + j | |
} | |
function offset(i) { | |
return "o" + i | |
} | |
function scalar(i) { | |
return "x" + i | |
} | |
function pointer(i) { | |
return "p" + i | |
} | |
function delta(i,bitmask) { | |
return "d" + i + "_" + bitmask | |
} | |
function index(i) { | |
return "i" + i | |
} | |
function step(i,j) { | |
return "u" + i + "_" + j | |
} | |
function pcube(bitmask) { | |
return "b" + bitmask | |
} | |
function qcube(bitmask) { | |
return "y" + bitmask | |
} | |
function pdelta(bitmask) { | |
return "e" + bitmask | |
} | |
function vert(i) { | |
return "v" + i | |
} | |
var VERTEX_IDS = "V" | |
var PHASES = "P" | |
var VERTEX_COUNT = "N" | |
var POOL_SIZE = "Q" | |
var POINTER = "X" | |
var TEMPORARY = "T" | |
function permBitmask(dimension, mask, order) { | |
var r = 0 | |
for(var i=0; i<dimension; ++i) { | |
if(mask & (1<<i)) { | |
r |= (1<<order[i]) | |
} | |
} | |
return r | |
} | |
//Generates the surface procedure | |
function compileSurfaceProcedure(vertexFunc, faceFunc, phaseFunc, scalarArgs, order, typesig) { | |
var arrayArgs = typesig.length | |
var dimension = order.length | |
if(dimension < 2) { | |
throw new Error("ndarray-extract-contour: Dimension must be at least 2") | |
} | |
var funcName = "extractContour" + order.join("_") | |
var code = [] | |
var vars = [] | |
var args = [] | |
//Assemble arguments | |
for(var i=0; i<arrayArgs; ++i) { | |
args.push(array(i)) | |
} | |
for(var i=0; i<scalarArgs; ++i) { | |
args.push(scalar(i)) | |
} | |
//Shape | |
for(var i=0; i<dimension; ++i) { | |
vars.push(shape(i) + "=" + array(0) + ".shape[" + i + "]|0") | |
} | |
//Data, stride, offset pointers | |
for(var i=0; i<arrayArgs; ++i) { | |
vars.push(data(i) + "=" + array(i) + ".data", | |
offset(i) + "=" + array(i) + ".offset|0") | |
for(var j=0; j<dimension; ++j) { | |
vars.push(stride(i,j) + "=" + array(i) + ".stride[" + j + "]|0") | |
} | |
} | |
//Pointer, delta and cube variables | |
for(var i=0; i<arrayArgs; ++i) { | |
vars.push(pointer(i) + "=" + offset(i)) | |
vars.push(cube(i,0)) | |
for(var j=1; j<(1<<dimension); ++j) { | |
var ptrStr = [] | |
for(var k=0; k<dimension; ++k) { | |
if(j & (1<<k)) { | |
ptrStr.push("-" + stride(i,k)) | |
} | |
} | |
vars.push(delta(i,j) + "=(" + ptrStr.join("") + ")|0") | |
vars.push(cube(i,j) + "=0") | |
} | |
} | |
//Create step variables | |
for(var i=0; i<arrayArgs; ++i) { | |
for(var j=0; j<dimension; ++j) { | |
var stepVal = [ stride(i,order[j]) ] | |
if(j > 0) { | |
stepVal.push(stride(i, order[j-1]) + "*" + shape(order[j-1]) ) | |
} | |
vars.push(step(i,order[j]) + "=(" + stepVal.join("-") + ")|0") | |
} | |
} | |
//Create index variables | |
for(var i=0; i<dimension; ++i) { | |
vars.push(index(i) + "=0") | |
} | |
//Vertex count | |
vars.push(VERTEX_COUNT + "=0") | |
//Compute pool size, initialize pool step | |
var sizeVariable = ["2"] | |
for(var i=dimension-2; i>=0; --i) { | |
sizeVariable.push(shape(order[i])) | |
} | |
//Previous phases and vertex_ids | |
vars.push(POOL_SIZE + "=(" + sizeVariable.join("*") + ")|0", | |
PHASES + "=mallocUint32(" + POOL_SIZE + ")", | |
VERTEX_IDS + "=mallocUint32(" + POOL_SIZE + ")", | |
POINTER + "=0") | |
//Create cube variables for phases | |
vars.push(pcube(0) + "=0") | |
for(var j=1; j<(1<<dimension); ++j) { | |
var cubeDelta = [] | |
var cubeStep = [ ] | |
for(var k=0; k<dimension; ++k) { | |
if(j & (1<<k)) { | |
if(cubeStep.length === 0) { | |
cubeDelta.push("1") | |
} else { | |
cubeDelta.unshift(cubeStep.join("*")) | |
} | |
} | |
cubeStep.push(shape(order[k])) | |
} | |
var signFlag = "" | |
if(cubeDelta[0].indexOf(shape(order[dimension-2])) < 0) { | |
signFlag = "-" | |
} | |
var jperm = permBitmask(dimension, j, order) | |
vars.push(pdelta(jperm) + "=(-" + cubeDelta.join("-") + ")|0", | |
qcube(jperm) + "=(" + signFlag + cubeDelta.join("-") + ")|0", | |
pcube(jperm) + "=0") | |
} | |
vars.push(vert(0) + "=0", TEMPORARY + "=0") | |
function forLoopBegin(i, start) { | |
code.push("for(", index(order[i]), "=", start, ";", | |
index(order[i]), "<", shape(order[i]), ";", | |
"++", index(order[i]), "){") | |
} | |
function forLoopEnd(i) { | |
for(var j=0; j<arrayArgs; ++j) { | |
code.push(pointer(j), "+=", step(j,order[i]), ";") | |
} | |
code.push("}") | |
} | |
function fillEmptySlice(k) { | |
for(var i=k-1; i>=0; --i) { | |
forLoopBegin(i, 0) | |
} | |
var phaseFuncArgs = [] | |
for(var i=0; i<arrayArgs; ++i) { | |
if(typesig[i]) { | |
phaseFuncArgs.push(data(i) + ".get(" + pointer(i) + ")") | |
} else { | |
phaseFuncArgs.push(data(i) + "[" + pointer(i) + "]") | |
} | |
} | |
for(var i=0; i<scalarArgs; ++i) { | |
phaseFuncArgs.push(scalar(i)) | |
} | |
code.push(PHASES, "[", POINTER, "++]=phase(", phaseFuncArgs.join(), ");") | |
for(var i=0; i<k; ++i) { | |
forLoopEnd(i) | |
} | |
for(var j=0; j<arrayArgs; ++j) { | |
code.push(pointer(j), "+=", step(j,order[k]), ";") | |
} | |
} | |
function processGridCell(mask) { | |
//Read in local data | |
for(var i=0; i<arrayArgs; ++i) { | |
if(typesig[i]) { | |
code.push(cube(i,0), "=", data(i), ".get(", pointer(i), ");") | |
} else { | |
code.push(cube(i,0), "=", data(i), "[", pointer(i), "];") | |
} | |
} | |
//Read in phase | |
var phaseFuncArgs = [] | |
for(var i=0; i<arrayArgs; ++i) { | |
phaseFuncArgs.push(cube(i,0)) | |
} | |
for(var i=0; i<scalarArgs; ++i) { | |
phaseFuncArgs.push(scalar(i)) | |
} | |
code.push(pcube(0), "=", PHASES, "[", POINTER, "]=phase(", phaseFuncArgs.join(), ");") | |
//Read in other cube data | |
for(var j=1; j<(1<<dimension); ++j) { | |
code.push(pcube(j), "=", PHASES, "[", POINTER, "+", pdelta(j), "];") | |
} | |
//Check for boundary crossing | |
var vertexPredicate = [] | |
for(var j=1; j<(1<<dimension); ++j) { | |
vertexPredicate.push("(" + pcube(0) + "!==" + pcube(j) + ")") | |
} | |
code.push("if(", vertexPredicate.join("||"), "){") | |
//Read in boundary data | |
var vertexArgs = [] | |
for(var i=0; i<dimension; ++i) { | |
vertexArgs.push(index(i)) | |
} | |
for(var i=0; i<arrayArgs; ++i) { | |
vertexArgs.push(cube(i,0)) | |
for(var j=1; j<(1<<dimension); ++j) { | |
if(typesig[i]) { | |
code.push(cube(i,j), "=", data(i), ".get(", pointer(i), "+", delta(i,j), ");") | |
} else { | |
code.push(cube(i,j), "=", data(i), "[", pointer(i), "+", delta(i,j), "];") | |
} | |
vertexArgs.push(cube(i,j)) | |
} | |
} | |
for(var i=0; i<(1<<dimension); ++i) { | |
vertexArgs.push(pcube(i)) | |
} | |
for(var i=0; i<scalarArgs; ++i) { | |
vertexArgs.push(scalar(i)) | |
} | |
//Generate vertex | |
code.push("vertex(", vertexArgs.join(), ");", | |
vert(0), "=", VERTEX_IDS, "[", POINTER, "]=", VERTEX_COUNT, "++;") | |
//Check for face crossings | |
var base = (1<<dimension)-1 | |
var corner = pcube(base) | |
for(var j=0; j<dimension; ++j) { | |
if((mask & ~(1<<j))===0) { | |
//Check face | |
var subset = base^(1<<j) | |
var edge = pcube(subset) | |
var faceArgs = [ ] | |
for(var k=subset; k>0; k=(k-1)&subset) { | |
faceArgs.push(VERTEX_IDS + "[" + POINTER + "+" + pdelta(k) + "]") | |
} | |
faceArgs.push(vert(0)) | |
for(var k=0; k<arrayArgs; ++k) { | |
if(j&1) { | |
faceArgs.push(cube(k,base), cube(k,subset)) | |
} else { | |
faceArgs.push(cube(k,subset), cube(k,base)) | |
} | |
} | |
if(j&1) { | |
faceArgs.push(corner, edge) | |
} else { | |
faceArgs.push(edge, corner) | |
} | |
for(var k=0; k<scalarArgs; ++k) { | |
faceArgs.push(scalar(k)) | |
} | |
code.push("if(", corner, "!==", edge, "){", | |
"face(", faceArgs.join(), ")}") | |
} | |
} | |
//Increment pointer, close off if statement | |
code.push("}", | |
POINTER, "+=1;") | |
} | |
function flip() { | |
for(var j=1; j<(1<<dimension); ++j) { | |
code.push(TEMPORARY, "=", pdelta(j), ";", | |
pdelta(j), "=", qcube(j), ";", | |
qcube(j), "=", TEMPORARY, ";") | |
} | |
} | |
function createLoop(i, mask) { | |
if(i < 0) { | |
processGridCell(mask) | |
return | |
} | |
fillEmptySlice(i) | |
code.push("if(", shape(order[i]), ">0){", | |
index(order[i]), "=1;") | |
createLoop(i-1, mask|(1<<order[i])) | |
for(var j=0; j<arrayArgs; ++j) { | |
code.push(pointer(j), "+=", step(j,order[i]), ";") | |
} | |
if(i === dimension-1) { | |
code.push(POINTER, "=0;") | |
flip() | |
} | |
forLoopBegin(i, 2) | |
createLoop(i-1, mask) | |
if(i === dimension-1) { | |
code.push("if(", index(order[dimension-1]), "&1){", | |
POINTER, "=0;}") | |
flip() | |
} | |
forLoopEnd(i) | |
code.push("}") | |
} | |
createLoop(dimension-1, 0) | |
//Release scratch memory | |
code.push("freeUint32(", VERTEX_IDS, ");freeUint32(", PHASES, ");") | |
//Compile and link procedure | |
var procedureCode = [ | |
"'use strict';", | |
"function ", funcName, "(", args.join(), "){", | |
"var ", vars.join(), ";", | |
code.join(""), | |
"}", | |
"return ", funcName ].join("") | |
var proc = new Function( | |
"vertex", | |
"face", | |
"phase", | |
"mallocUint32", | |
"freeUint32", | |
procedureCode) | |
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<arrays; ++i) { | |
if(getters.indexOf(i) >= 0) { | |
typesig[i] = true | |
} else { | |
typesig[i] = false | |
} | |
} | |
return compileSurfaceProcedure( | |
args.vertex, | |
args.cell, | |
args.phase, | |
scalars, | |
order, | |
typesig) | |
} | |
},{"typedarray-pool":138}],136:[function(require,module,exports){ | |
arguments[4][15][0].apply(exports,arguments) | |
},{"dup":15}],137:[function(require,module,exports){ | |
arguments[4][16][0].apply(exports,arguments) | |
},{"dup":16}],138:[function(require,module,exports){ | |
arguments[4][17][0].apply(exports,arguments) | |
},{"bit-twiddle":136,"buffer":2,"dup":17}],139:[function(require,module,exports){ | |
// transliterated from the python snippet here: | |
// http://en.wikipedia.org/wiki/Lanczos_approximation | |
var g = 7; | |
var p = [ | |
0.99999999999980993, | |
676.5203681218851, | |
-1259.1392167224028, | |
771.32342877765313, | |
-176.61502916214059, | |
12.507343278686905, | |
-0.13857109526572012, | |
9.9843695780195716e-6, | |
1.5056327351493116e-7 | |
]; | |
var g_ln = 607/128; | |
var p_ln = [ | |
0.99999999999999709182, | |
57.156235665862923517, | |
-59.597960355475491248, | |
14.136097974741747174, | |
-0.49191381609762019978, | |
0.33994649984811888699e-4, | |
0.46523628927048575665e-4, | |
-0.98374475304879564677e-4, | |
0.15808870322491248884e-3, | |
-0.21026444172410488319e-3, | |
0.21743961811521264320e-3, | |
-0.16431810653676389022e-3, | |
0.84418223983852743293e-4, | |
-0.26190838401581408670e-4, | |
0.36899182659531622704e-5 | |
]; | |
// Spouge approximation (suitable for large arguments) | |
function lngamma(z) { | |
if(z < 0) return Number('0/0'); | |
var x = p_ln[0]; | |
for(var i = p_ln.length - 1; i > 0; --i) x += p_ln[i] / (z + i); | |
var t = z + g_ln + 0.5; | |
return .5*Math.log(2*Math.PI)+(z+.5)*Math.log(t)-t+Math.log(x)-Math.log(z); | |
} | |
module.exports = function gamma (z) { | |
if (z < 0.5) { | |
return Math.PI / (Math.sin(Math.PI * z) * gamma(1 - z)); | |
} | |
else if(z > 100) return Math.exp(lngamma(z)); | |
else { | |
z -= 1; | |
var x = p[0]; | |
for (var i = 1; i < g + 2; i++) { | |
x += p[i] / (z + i); | |
} | |
var t = z + g + 0.5; | |
return Math.sqrt(2 * Math.PI) | |
* Math.pow(t, z + 0.5) | |
* Math.exp(-t) | |
* x | |
; | |
} | |
}; | |
module.exports.log = lngamma; | |
},{}],140:[function(require,module,exports){ | |
arguments[4][15][0].apply(exports,arguments) | |
},{"dup":15}],141:[function(require,module,exports){ | |
arguments[4][16][0].apply(exports,arguments) | |
},{"dup":16}],142:[function(require,module,exports){ | |
arguments[4][17][0].apply(exports,arguments) | |
},{"bit-twiddle":140,"buffer":2,"dup":17}],143:[function(require,module,exports){ | |
"use strict" | |
module.exports = permutationSign | |
var BRUTE_FORCE_CUTOFF = 32 | |
var pool = require("typedarray-pool") | |
function permutationSign(p) { | |
var n = p.length | |
if(n < BRUTE_FORCE_CUTOFF) { | |
//Use quadratic algorithm for small n | |
var sgn = 1 | |
for(var i=0; i<n; ++i) { | |
for(var j=0; j<i; ++j) { | |
if(p[i] < p[j]) { | |
sgn = -sgn | |
} else if(p[i] === p[j]) { | |
return 0 | |
} | |
} | |
} | |
return sgn | |
} else { | |
//Otherwise use linear time algorithm | |
var visited = pool.mallocUint8(n) | |
for(var i=0; i<n; ++i) { | |
visited[i] = 0 | |
} | |
var sgn = 1 | |
for(var i=0; i<n; ++i) { | |
if(!visited[i]) { | |
var count = 1 | |
visited[i] = 1 | |
for(var j=p[i]; j!==i; j=p[j]) { | |
if(visited[j]) { | |
pool.freeUint8(visited) | |
return 0 | |
} | |
count += 1 | |
visited[j] = 1 | |
} | |
if(!(count & 1)) { | |
sgn = -sgn | |
} | |
} | |
} | |
pool.freeUint8(visited) | |
return sgn | |
} | |
} | |
},{"typedarray-pool":142}],144:[function(require,module,exports){ | |
"use strict" | |
var pool = require("typedarray-pool") | |
var inverse = require("invert-permutation") | |
function rank(permutation) { | |
var n = permutation.length | |
switch(n) { | |
case 0: | |
case 1: | |
return 0 | |
case 2: | |
return permutation[1] | |
default: | |
break | |
} | |
var p = pool.mallocUint32(n) | |
var pinv = pool.mallocUint32(n) | |
var r = 0, s, t, i | |
inverse(permutation, pinv) | |
for(i=0; i<n; ++i) { | |
p[i] = permutation[i] | |
} | |
for(i=n-1; i>0; --i) { | |
t = pinv[i] | |
s = p[i] | |
p[i] = p[t] | |
p[t] = s | |
pinv[i] = pinv[s] | |
pinv[s] = t | |
r = (r + s) * i | |
} | |
pool.freeUint32(pinv) | |
pool.freeUint32(p) | |
return r | |
} | |
function unrank(n, r, p) { | |
switch(n) { | |
case 0: | |
if(p) { return p } | |
return [] | |
case 1: | |
if(p) { | |
p[0] = 0 | |
return p | |
} else { | |
return [0] | |
} | |
case 2: | |
if(p) { | |
if(r) { | |
p[0] = 0 | |
p[1] = 1 | |
} else { | |
p[0] = 1 | |
p[1] = 0 | |
} | |
return p | |
} else { | |
return r ? [0,1] : [1,0] | |
} | |
default: | |
break | |
} | |
p = p || new Array(n) | |
var s, t, i, nf=1 | |
p[0] = 0 | |
for(i=1; i<n; ++i) { | |
p[i] = i | |
nf = (nf*i)|0 | |
} | |
for(i=n-1; i>0; --i) { | |
s = (r / nf)|0 | |
r = (r - s * nf)|0 | |
nf = (nf / i)|0 | |
t = p[i]|0 | |
p[i] = p[s]|0 | |
p[s] = t|0 | |
} | |
return p | |
} | |
exports.rank = rank | |
exports.unrank = unrank | |
},{"invert-permutation":145,"typedarray-pool":148}],145:[function(require,module,exports){ | |
"use strict" | |
function invertPermutation(pi, result) { | |
result = result || new Array(pi.length) | |
for(var i=0; i<pi.length; ++i) { | |
result[pi[i]] = i | |
} | |
return result | |
} | |
module.exports = invertPermutation | |
},{}],146:[function(require,module,exports){ | |
arguments[4][15][0].apply(exports,arguments) | |
},{"dup":15}],147:[function(require,module,exports){ | |
arguments[4][16][0].apply(exports,arguments) | |
},{"dup":16}],148:[function(require,module,exports){ | |
arguments[4][17][0].apply(exports,arguments) | |
},{"bit-twiddle":146,"buffer":2,"dup":17}],149:[function(require,module,exports){ | |
"use strict" | |
module.exports = triangulateCube | |
var perm = require("permutation-rank") | |
var sgn = require("permutation-parity") | |
var gamma = require("gamma") | |
function triangulateCube(dimension) { | |
if(dimension < 0) { | |
return [ ] | |
} | |
if(dimension === 0) { | |
return [ [0] ] | |
} | |
var dfactorial = Math.round(gamma(dimension+1))|0 | |
var result = [] | |
for(var i=0; i<dfactorial; ++i) { | |
var p = perm.unrank(dimension, i) | |
var cell = [ 0 ] | |
var v = 0 | |
for(var j=0; j<p.length; ++j) { | |
v += (1<<p[j]) | |
cell.push(v) | |
} | |
if(sgn(p) < 1) { | |
cell[0] = v | |
cell[dimension] = 0 | |
} | |
result.push(cell) | |
} | |
return result | |
} | |
},{"gamma":139,"permutation-parity":143,"permutation-rank":144}],150:[function(require,module,exports){ | |
module.exports = require('cwise-compiler')({ | |
args: ['array', { | |
offset: [1], | |
array: 0 | |
}, 'scalar', 'scalar', 'index'], | |
pre: { | |
"body": "{}", | |
"args": [], | |
"thisVars": [], | |
"localVars": [] | |
}, | |
post: { | |
"body": "{}", | |
"args": [], | |
"thisVars": [], | |
"localVars": [] | |
}, | |
body: { | |
"body": "{\n var _inline_1_da = _inline_1_arg0_ - _inline_1_arg3_\n var _inline_1_db = _inline_1_arg1_ - _inline_1_arg3_\n if((_inline_1_da >= 0) !== (_inline_1_db >= 0)) {\n _inline_1_arg2_.push(_inline_1_arg4_[0] + 0.5 + 0.5 * (_inline_1_da + _inline_1_db) / (_inline_1_da - _inline_1_db))\n }\n }", | |
"args": [{ | |
"name": "_inline_1_arg0_", | |
"lvalue": false, | |
"rvalue": true, | |
"count": 1 | |
}, { | |
"name": "_inline_1_arg1_", | |
"lvalue": false, | |
"rvalue": true, | |
"count": 1 | |
}, { | |
"name": "_inline_1_arg2_", | |
"lvalue": false, | |
"rvalue": true, | |
"count": 1 | |
}, { | |
"name": "_inline_1_arg3_", | |
"lvalue": false, | |
"rvalue": true, | |
"count": 2 | |
}, { | |
"name": "_inline_1_arg4_", | |
"lvalue": false, | |
"rvalue": true, | |
"count": 1 | |
}], | |
"thisVars": [], | |
"localVars": ["_inline_1_da", "_inline_1_db"] | |
}, | |
funcName: 'zeroCrossings' | |
}) | |
},{"cwise-compiler":151}],151:[function(require,module,exports){ | |
arguments[4][8][0].apply(exports,arguments) | |
},{"./lib/thunk.js":153,"dup":8}],152:[function(require,module,exports){ | |
arguments[4][9][0].apply(exports,arguments) | |
},{"dup":9,"uniq":154}],153:[function(require,module,exports){ | |
arguments[4][10][0].apply(exports,arguments) | |
},{"./compile.js":152,"dup":10}],154:[function(require,module,exports){ | |
arguments[4][11][0].apply(exports,arguments) | |
},{"dup":11}],155:[function(require,module,exports){ | |
"use strict" | |
module.exports = findZeroCrossings | |
var core = require("./lib/zc-core") | |
function findZeroCrossings(array, level) { | |
var cross = [] | |
level = +level || 0.0 | |
core(array.hi(array.shape[0]-1), cross, level) | |
return cross | |
} | |
},{"./lib/zc-core":150}],156:[function(require,module,exports){ | |
"use strict" | |
module.exports = surfaceNets | |
var generateContourExtractor = require("ndarray-extract-contour") | |
var triangulateCube = require("triangulate-hypercube") | |
var zeroCrossings = require("zero-crossings") | |
function buildSurfaceNets(order, dtype) { | |
var dimension = order.length | |
var code = ["'use strict';"] | |
var funcName = "surfaceNets" + order.join("_") + "d" + dtype | |
//Contour extraction function | |
code.push( | |
"var contour=genContour({", | |
"order:[", order.join(), "],", | |
"scalarArguments: 3,", | |
"phase:function phaseFunc(p,a,b,c) { return (p > c)|0 },") | |
if(dtype === "generic") { | |
code.push("getters:[0],") | |
} | |
//Generate vertex function | |
var cubeArgs = [] | |
var extraArgs = [] | |
for(var i=0; i<dimension; ++i) { | |
cubeArgs.push("d" + i) | |
extraArgs.push("d" + i) | |
} | |
for(var i=0; i<(1<<dimension); ++i) { | |
cubeArgs.push("v" + i) | |
extraArgs.push("v" + i) | |
} | |
for(var i=0; i<(1<<dimension); ++i) { | |
cubeArgs.push("p" + i) | |
extraArgs.push("p" + i) | |
} | |
cubeArgs.push("a", "b", "c") | |
extraArgs.push("a", "c") | |
code.push("vertex:function vertexFunc(", cubeArgs.join(), "){") | |
//Mask args together | |
var maskStr = [] | |
for(var i=0; i<(1<<dimension); ++i) { | |
maskStr.push("(p" + i + "<<" + i + ")") | |
} | |
//Generate variables and giganto switch statement | |
code.push("var m=(", maskStr.join("+"), ")|0;if(m===0||m===", (1<<(1<<dimension))-1, "){return}") | |
var extraFuncs = [] | |
var currentFunc = [] | |
if(1<<(1<<dimension) <= 128) { | |
code.push("switch(m){") | |
currentFunc = code | |
} else { | |
code.push("switch(m>>>7){") | |
} | |
for(var i=0; i<1<<(1<<dimension); ++i) { | |
if(1<<(1<<dimension) > 128) { | |
if((i%128)===0) { | |
if(extraFuncs.length > 0) { | |
currentFunc.push("}}") | |
} | |
var efName = "vExtra" + extraFuncs.length | |
code.push("case ", (i>>>7), ":", efName, "(m&0x7f,", extraArgs.join(), ");break;") | |
currentFunc = [ | |
"function ", efName, "(m,", extraArgs.join(), "){switch(m){" | |
] | |
extraFuncs.push(currentFunc) | |
} | |
} | |
currentFunc.push("case ", (i&0x7f), ":") | |
var crossings = new Array(dimension) | |
var denoms = new Array(dimension) | |
var crossingCount = new Array(dimension) | |
var bias = new Array(dimension) | |
var totalCrossings = 0 | |
for(var j=0; j<dimension; ++j) { | |
crossings[j] = [] | |
denoms[j] = [] | |
crossingCount[j] = 0 | |
bias[j] = 0 | |
} | |
for(var j=0; j<(1<<dimension); ++j) { | |
for(var k=0; k<dimension; ++k) { | |
var u = j ^ (1<<k) | |
if(u > j) { | |
continue | |
} | |
if(!(i&(1<<u)) !== !(i&(1<<j))) { | |
var sign = 1 | |
if(i&(1<<u)) { | |
denoms[k].push("v" + u + "-v" + j) | |
} else { | |
denoms[k].push("v" + j + "-v" + u) | |
sign = -sign | |
} | |
if(sign < 0) { | |
crossings[k].push("-v" + j + "-v" + u) | |
crossingCount[k] += 2 | |
} else { | |
crossings[k].push("v" + j + "+v" + u) | |
crossingCount[k] -= 2 | |
} | |
totalCrossings += 1 | |
for(var l=0; l<dimension; ++l) { | |
if(l === k) { | |
continue | |
} | |
if(u&(1<<l)) { | |
bias[l] += 1 | |
} else { | |
bias[l] -= 1 | |
} | |
} | |
} | |
} | |
} | |
var vertexStr = [] | |
for(var k=0; k<dimension; ++k) { | |
if(crossings[k].length === 0) { | |
vertexStr.push("d" + k + "-0.5") | |
} else { | |
var cStr = "" | |
if(crossingCount[k] < 0) { | |
cStr = crossingCount[k] + "*c" | |
} else if(crossingCount[k] > 0) { | |
cStr = "+" + crossingCount[k] + "*c" | |
} | |
var weight = 0.5 * (crossings[k].length / totalCrossings) | |
var shift = 0.5 + 0.5 * (bias[k] / totalCrossings) | |
vertexStr.push("d" + k + "-" + shift + "-" + weight + "*(" + crossings[k].join("+") + cStr + ")/(" + denoms[k].join("+") + ")") | |
} | |
} | |
currentFunc.push("a.push([", vertexStr.join(), "]);", | |
"break;") | |
} | |
code.push("}},") | |
if(extraFuncs.length > 0) { | |
currentFunc.push("}}") | |
} | |
//Create face function | |
var faceArgs = [] | |
for(var i=0; i<(1<<(dimension-1)); ++i) { | |
faceArgs.push("v" + i) | |
} | |
faceArgs.push("c0", "c1", "p0", "p1", "a", "b", "c") | |
code.push("cell:function cellFunc(", faceArgs.join(), "){") | |
var facets = triangulateCube(dimension-1) | |
code.push("if(p0){b.push(", | |
facets.map(function(f) { | |
return "[" + f.map(function(v) { | |
return "v" + v | |
}) + "]" | |
}).join(), ")}else{b.push(", | |
facets.map(function(f) { | |
var e = f.slice() | |
e.reverse() | |
return "[" + e.map(function(v) { | |
return "v" + v | |
}) + "]" | |
}).join(), | |
")}}});function ", funcName, "(array,level){var verts=[],cells=[];contour(array,verts,cells,level);return {positions:verts,cells:cells};} return ", funcName, ";") | |
for(var i=0; i<extraFuncs.length; ++i) { | |
code.push(extraFuncs[i].join("")) | |
} | |
//Compile and link | |
var proc = new Function("genContour", code.join("")) | |
return proc(generateContourExtractor) | |
} | |
//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; i<n; ++i) { | |
npos[i] = [ zc[i] ] | |
ncel[i] = [ i ] | |
} | |
return { | |
positions: npos, | |
cells: ncel | |
} | |
} | |
var CACHE = {} | |
function surfaceNets(array,level) { | |
if(array.dimension <= 0) { | |
return { positions: [], cells: [] } | |
} else if(array.dimension === 1) { | |
return mesh1D(array, level) | |
} | |
var typesig = array.order.join() + "-" + array.dtype | |
var proc = CACHE[typesig] | |
var level = (+level) || 0.0 | |
if(!proc) { | |
proc = CACHE[typesig] = buildSurfaceNets(array.order, array.dtype) | |
} | |
return proc(array,level) | |
} | |
},{"ndarray-extract-contour":135,"triangulate-hypercube":149,"zero-crossings":155}],157:[function(require,module,exports){ | |
module.exports = function (width, height, radius, cornerSlices) { | |
var p = []; | |
p.push(radius, 0); | |
p.push(width - radius, 0); | |
p.push(width - radius, radius); | |
p.push(radius, 0); | |
p.push(width - radius, radius); | |
p.push(radius, radius); | |
p.push(radius, radius); | |
p.push(width - radius, radius); | |
p.push(width - radius, height - radius); | |
p.push(radius, radius); | |
p.push(width - radius, height - radius); | |
p.push(radius, height - radius); | |
return new Float32Array(p); | |
}; | |
},{}]},{},[1]); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
!function r(t,n,e){function i(s,a){if(!n[s]){if(!t[s]){var u="function"==typeof require&&require;if(!a&&u)return u(s,!0);if(o)return o(s,!0);var h=new Error("Cannot find module '"+s+"'");throw h.code="MODULE_NOT_FOUND",h}var f=n[s]={exports:{}};t[s][0].call(f.exports,function(r){var n=t[s][1][r];return i(n?n:r)},f,f.exports,r,t,n,e)}return n[s].exports}for(var o="function"==typeof require&&require,s=0;s<e.length;s++)i(e[s]);return i}({1:[function(r,t,n){function e(t,n){p={},l=r("gl-clear")({color:n}),f=r("gl-context")(t,{premultipliedAlpha:!1,alpha:!1,antialias:!1}),c=r("glslify/adapter.js")("\n#define GLSLIFY 1\n\nprecision mediump float;\nattribute vec2 aPosition;\nuniform mat4 uModelView;\nuniform mat4 uProjection;\nvoid main() {\n gl_Position = uProjection * uModelView * vec4(aPosition, 0.0, 1.0);\n}","\n#define GLSLIFY 1\n\nprecision mediump float;\nuniform vec4 uModelColor;\nvoid main() {\n gl_FragColor = uModelColor;\n}",[{name:"uModelView",type:"mat4"},{name:"uProjection",type:"mat4"},{name:"uModelColor",type:"vec4"}],[{name:"aPosition",type:"vec2"}])(f),c.attributes.aPosition.location=0;var e=f.drawingBufferWidth,i=f.drawingBufferHeight;l(f),f.viewport(0,0,e,i),d.ortho(y,0,e,i,0,0,1),c.bind(),c.uniforms.uProjection=y,p.square=g(f,new Float32Array([1,1,-0,1,1,-0,-0,-0])),f.enable(f.BLEND),f.blendFunc(f.SRC_ALPHA,f.ONE_MINUS_SRC_ALPHA),f.disable(f.DEPTH_TEST)}function i(r,t,n){return{vertices:p.square,length:4,c:n,s:[r,t,1],t:[0,0,0],d:f.TRIANGLE_STRIP,l:4}}function o(r,t,n){r.positions&&r.cells&&(n=t,t=r.cells,r=r.positions),n=n||new Float32Array(6*t.length);for(var e=0,i=0,o=t.length;o>e;e+=1)n[i++]=r[t[e][0]][0],n[i++]=r[t[e][0]][1],n[i++]=r[t[e][1]][0],n[i++]=r[t[e][1]][1],n[i++]=r[t[e][2]][0],n[i++]=r[t[e][2]][1];return n}function s(r,t,n){if(!p[t]){var e=t+2,i=new Float32Array(2*e),o=2*Math.PI,s=0;i[s++]=0,i[s++]=0;for(var a=0;e>=a;a++)i[s++]=Math.cos(a*o/t),i[s++]=Math.sin(a*o/t);p[t]=g(f,i)}return{c:n,s:[r,r,0],t:[0,0,0],vertices:p[t],d:f.TRIANGLE_FAN,l:t+2}}function a(r,t,n,e){if(!p[r+n]){var i=v(r,{font:n,triangles:!0,orientation:"ccw",textAlign:"start",textBaseline:"top"});p[r+n]=g(f,o(i))}return{c:e,t:[0,0,0],s:[t,t,0],vertices:p[r+n],d:f.TRIANGLES,l:p[r+n].length/2/4}}function u(r){l(f);for(var t=0;t<r.length;t++){var n=r[t];d.identity(m),d.translate(m,m,n.t),d.scale(m,m,n.s),c.uniforms.uModelView=m,c.uniforms.uModelColor=n.c,n.vertices.bind(),c.attributes.aPosition.pointer(),f.drawArrays(n.d,0,n.l)}}function h(){Object.keys(p).forEach(function(r){p[r].unbind(),p[r].dispose(),delete p[r]}),c.dispose()}var f,l,c,p,g=(r("glslify"),r("gl-buffer")),v=r("vectorize-text"),d={create:r("gl-mat4/create"),identity:r("gl-mat4/identity"),translate:r("gl-mat4/translate"),scale:r("gl-mat4/scale"),ortho:r("gl-mat4/ortho")},y=d.create(),m=d.create();window.stackgl={init:e,update:u,dispose:h,rectangle:i,circle:s,text:a,version:"0.0.12"}},{"gl-buffer":6,"gl-clear":19,"gl-context":20,"gl-mat4/create":22,"gl-mat4/identity":23,"gl-mat4/ortho":24,"gl-mat4/scale":25,"gl-mat4/translate":26,glslify:28,"glslify/adapter.js":27,"vectorize-text":34}],2:[function(r,t,n){(function(t){function e(){function r(){}try{var t=new Uint8Array(1);return t.foo=function(){return 42},t.constructor=r,42===t.foo()&&t.constructor===r&&"function"==typeof t.subarray&&0===t.subarray(1,1).byteLength}catch(n){return!1}}function i(){return o.TYPED_ARRAY_SUPPORT?2147483647:1073741823}function o(r){return this instanceof o?(this.length=0,this.parent=void 0,"number"==typeof r?s(this,r):"string"==typeof r?a(this,r,arguments.length>1?arguments[1]:"utf8"):u(this,r)):arguments.length>1?new o(r,arguments[1]):new o(r)}function s(r,t){if(r=v(r,0>t?0:0|d(t)),!o.TYPED_ARRAY_SUPPORT)for(var n=0;t>n;n++)r[n]=0;return r}function a(r,t,n){("string"!=typeof n||""===n)&&(n="utf8");var e=0|m(t,n);return r=v(r,e),r.write(t,n),r}function u(r,t){if(o.isBuffer(t))return h(r,t);if(X(t))return f(r,t);if(null==t)throw new TypeError("must start with number, buffer, array or string");if("undefined"!=typeof ArrayBuffer){if(t.buffer instanceof ArrayBuffer)return l(r,t);if(t instanceof ArrayBuffer)return c(r,t)}return t.length?p(r,t):g(r,t)}function h(r,t){var n=0|d(t.length);return r=v(r,n),t.copy(r,0,0,n),r}function f(r,t){var n=0|d(t.length);r=v(r,n);for(var e=0;n>e;e+=1)r[e]=255&t[e];return r}function l(r,t){var n=0|d(t.length);r=v(r,n);for(var e=0;n>e;e+=1)r[e]=255&t[e];return r}function c(r,t){return o.TYPED_ARRAY_SUPPORT?(t.byteLength,r=o._augment(new Uint8Array(t))):r=l(r,new Uint8Array(t)),r}function p(r,t){var n=0|d(t.length);r=v(r,n);for(var e=0;n>e;e+=1)r[e]=255&t[e];return r}function g(r,t){var n,e=0;"Buffer"===t.type&&X(t.data)&&(n=t.data,e=0|d(n.length)),r=v(r,e);for(var i=0;e>i;i+=1)r[i]=255&n[i];return r}function v(r,t){o.TYPED_ARRAY_SUPPORT?(r=o._augment(new Uint8Array(t)),r.__proto__=o.prototype):(r.length=t,r._isBuffer=!0);var n=0!==t&&t<=o.poolSize>>>1;return n&&(r.parent=J),r}function d(r){if(r>=i())throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+i().toString(16)+" bytes");return 0|r}function y(r,t){if(!(this instanceof y))return new y(r,t);var n=new o(r,t);return delete n.parent,n}function m(r,t){"string"!=typeof r&&(r=""+r);var n=r.length;if(0===n)return 0;for(var e=!1;;)switch(t){case"ascii":case"binary":case"raw":case"raws":return n;case"utf8":case"utf-8":return Y(r).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*n;case"hex":return n>>>1;case"base64":return H(r).length;default:if(e)return Y(r).length;t=(""+t).toLowerCase(),e=!0}}function b(r,t,n){var e=!1;if(t=0|t,n=void 0===n||n===1/0?this.length:0|n,r||(r="utf8"),0>t&&(t=0),n>this.length&&(n=this.length),t>=n)return"";for(;;)switch(r){case"hex":return R(this,t,n);case"utf8":case"utf-8":return I(this,t,n);case"ascii":return P(this,t,n);case"binary":return B(this,t,n);case"base64":return k(this,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return T(this,t,n);default:if(e)throw new TypeError("Unknown encoding: "+r);r=(r+"").toLowerCase(),e=!0}}function w(r,t,n,e){n=Number(n)||0;var i=r.length-n;e?(e=Number(e),e>i&&(e=i)):e=i;var o=t.length;if(o%2!==0)throw new Error("Invalid hex string");e>o/2&&(e=o/2);for(var s=0;e>s;s++){var a=parseInt(t.substr(2*s,2),16);if(isNaN(a))throw new Error("Invalid hex string");r[n+s]=a}return s}function _(r,t,n,e){return W(Y(t,r.length-n),r,n,e)}function A(r,t,n,e){return W(z(t),r,n,e)}function x(r,t,n,e){return A(r,t,n,e)}function E(r,t,n,e){return W(H(t),r,n,e)}function j(r,t,n,e){return W(G(t,r.length-n),r,n,e)}function k(r,t,n){return 0===t&&n===r.length?Q.fromByteArray(r):Q.fromByteArray(r.slice(t,n))}function I(r,t,n){n=Math.min(r.length,n);for(var e=[],i=t;n>i;){var o=r[i],s=null,a=o>239?4:o>223?3:o>191?2:1;if(n>=i+a){var u,h,f,l;switch(a){case 1:128>o&&(s=o);break;case 2:u=r[i+1],128===(192&u)&&(l=(31&o)<<6|63&u,l>127&&(s=l));break;case 3:u=r[i+1],h=r[i+2],128===(192&u)&&128===(192&h)&&(l=(15&o)<<12|(63&u)<<6|63&h,l>2047&&(55296>l||l>57343)&&(s=l));break;case 4:u=r[i+1],h=r[i+2],f=r[i+3],128===(192&u)&&128===(192&h)&&128===(192&f)&&(l=(15&o)<<18|(63&u)<<12|(63&h)<<6|63&f,l>65535&&1114112>l&&(s=l))}}null===s?(s=65533,a=1):s>65535&&(s-=65536,e.push(s>>>10&1023|55296),s=56320|1023&s),e.push(s),i+=a}return M(e)}function M(r){var t=r.length;if(Z>=t)return String.fromCharCode.apply(String,r);for(var n="",e=0;t>e;)n+=String.fromCharCode.apply(String,r.slice(e,e+=Z));return n}function P(r,t,n){var e="";n=Math.min(r.length,n);for(var i=t;n>i;i++)e+=String.fromCharCode(127&r[i]);return e}function B(r,t,n){var e="";n=Math.min(r.length,n);for(var i=t;n>i;i++)e+=String.fromCharCode(r[i]);return e}function R(r,t,n){var e=r.length;(!t||0>t)&&(t=0),(!n||0>n||n>e)&&(n=e);for(var i="",o=t;n>o;o++)i+=D(r[o]);return i}function T(r,t,n){for(var e=r.slice(t,n),i="",o=0;o<e.length;o+=2)i+=String.fromCharCode(e[o]+256*e[o+1]);return i}function U(r,t,n){if(r%1!==0||0>r)throw new RangeError("offset is not uint");if(r+t>n)throw new RangeError("Trying to access beyond buffer length")}function S(r,t,n,e,i,s){if(!o.isBuffer(r))throw new TypeError("buffer must be a Buffer instance");if(t>i||s>t)throw new RangeError("value is out of bounds");if(n+e>r.length)throw new RangeError("index out of range")}function L(r,t,n,e){0>t&&(t=65535+t+1);for(var i=0,o=Math.min(r.length-n,2);o>i;i++)r[n+i]=(t&255<<8*(e?i:1-i))>>>8*(e?i:1-i)}function V(r,t,n,e){0>t&&(t=4294967295+t+1);for(var i=0,o=Math.min(r.length-n,4);o>i;i++)r[n+i]=t>>>8*(e?i:3-i)&255}function N(r,t,n,e,i,o){if(t>i||o>t)throw new RangeError("value is out of bounds");if(n+e>r.length)throw new RangeError("index out of range");if(0>n)throw new RangeError("index out of range")}function F(r,t,n,e,i){return i||N(r,t,n,4,3.4028234663852886e38,-3.4028234663852886e38),K.write(r,t,n,e,23,4),n+4}function O(r,t,n,e,i){return i||N(r,t,n,8,1.7976931348623157e308,-1.7976931348623157e308),K.write(r,t,n,e,52,8),n+8}function C(r){if(r=q(r).replace(rr,""),r.length<2)return"";for(;r.length%4!==0;)r+="=";return r}function q(r){return r.trim?r.trim():r.replace(/^\s+|\s+$/g,"")}function D(r){return 16>r?"0"+r.toString(16):r.toString(16)}function Y(r,t){t=t||1/0;for(var n,e=r.length,i=null,o=[],s=0;e>s;s++){if(n=r.charCodeAt(s),n>55295&&57344>n){if(!i){if(n>56319){(t-=3)>-1&&o.push(239,191,189);continue}if(s+1===e){(t-=3)>-1&&o.push(239,191,189);continue}i=n;continue}if(56320>n){(t-=3)>-1&&o.push(239,191,189),i=n;continue}n=i-55296<<10|n-56320|65536}else i&&(t-=3)>-1&&o.push(239,191,189);if(i=null,128>n){if((t-=1)<0)break;o.push(n)}else if(2048>n){if((t-=2)<0)break;o.push(n>>6|192,63&n|128)}else if(65536>n){if((t-=3)<0)break;o.push(n>>12|224,n>>6&63|128,63&n|128)}else{if(!(1114112>n))throw new Error("Invalid code point");if((t-=4)<0)break;o.push(n>>18|240,n>>12&63|128,n>>6&63|128,63&n|128)}}return o}function z(r){for(var t=[],n=0;n<r.length;n++)t.push(255&r.charCodeAt(n));return t}function G(r,t){for(var n,e,i,o=[],s=0;s<r.length&&!((t-=2)<0);s++)n=r.charCodeAt(s),e=n>>8,i=n%256,o.push(i),o.push(e);return o}function H(r){return Q.toByteArray(C(r))}function W(r,t,n,e){for(var i=0;e>i&&!(i+n>=t.length||i>=r.length);i++)t[i+n]=r[i];return i}var Q=r("base64-js"),K=r("ieee754"),X=r("is-array");n.Buffer=o,n.SlowBuffer=y,n.INSPECT_MAX_BYTES=50,o.poolSize=8192;var J={};o.TYPED_ARRAY_SUPPORT=void 0!==t.TYPED_ARRAY_SUPPORT?t.TYPED_ARRAY_SUPPORT:e(),o.TYPED_ARRAY_SUPPORT&&(o.prototype.__proto__=Uint8Array.prototype,o.__proto__=Uint8Array),o.isBuffer=function(r){return!(null==r||!r._isBuffer)},o.compare=function(r,t){if(!o.isBuffer(r)||!o.isBuffer(t))throw new TypeError("Arguments must be Buffers");if(r===t)return 0;for(var n=r.length,e=t.length,i=0,s=Math.min(n,e);s>i&&r[i]===t[i];)++i;return i!==s&&(n=r[i],e=t[i]),e>n?-1:n>e?1:0},o.isEncoding=function(r){switch(String(r).toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"binary":case"base64":case"raw":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return!0;default:return!1}},o.concat=function(r,t){if(!X(r))throw new TypeError("list argument must be an Array of Buffers.");if(0===r.length)return new o(0);var n;if(void 0===t)for(t=0,n=0;n<r.length;n++)t+=r[n].length;var e=new o(t),i=0;for(n=0;n<r.length;n++){var s=r[n];s.copy(e,i),i+=s.length}return e},o.byteLength=m,o.prototype.length=void 0,o.prototype.parent=void 0,o.prototype.toString=function(){var r=0|this.length;return 0===r?"":0===arguments.length?I(this,0,r):b.apply(this,arguments)},o.prototype.equals=function(r){if(!o.isBuffer(r))throw new TypeError("Argument must be a Buffer");return this===r?!0:0===o.compare(this,r)},o.prototype.inspect=function(){var r="",t=n.INSPECT_MAX_BYTES;return this.length>0&&(r=this.toString("hex",0,t).match(/.{2}/g).join(" "),this.length>t&&(r+=" ... ")),"<Buffer "+r+">"},o.prototype.compare=function(r){if(!o.isBuffer(r))throw new TypeError("Argument must be a Buffer");return this===r?0:o.compare(this,r)},o.prototype.indexOf=function(r,t){function n(r,t,n){for(var e=-1,i=0;n+i<r.length;i++)if(r[n+i]===t[-1===e?0:i-e]){if(-1===e&&(e=i),i-e+1===t.length)return n+e}else e=-1;return-1}if(t>2147483647?t=2147483647:-2147483648>t&&(t=-2147483648),t>>=0,0===this.length)return-1;if(t>=this.length)return-1;if(0>t&&(t=Math.max(this.length+t,0)),"string"==typeof r)return 0===r.length?-1:String.prototype.indexOf.call(this,r,t);if(o.isBuffer(r))return n(this,r,t);if("number"==typeof r)return o.TYPED_ARRAY_SUPPORT&&"function"===Uint8Array.prototype.indexOf?Uint8Array.prototype.indexOf.call(this,r,t):n(this,[r],t);throw new TypeError("val must be string, number or Buffer")},o.prototype.get=function(r){return console.log(".get() is deprecated. Access using array indexes instead."),this.readUInt8(r)},o.prototype.set=function(r,t){return console.log(".set() is deprecated. Access using array indexes instead."),this.writeUInt8(r,t)},o.prototype.write=function(r,t,n,e){if(void 0===t)e="utf8",n=this.length,t=0;else if(void 0===n&&"string"==typeof t)e=t,n=this.length,t=0;else if(isFinite(t))t=0|t,isFinite(n)?(n=0|n,void 0===e&&(e="utf8")):(e=n,n=void 0);else{var i=e;e=t,t=0|n,n=i}var o=this.length-t;if((void 0===n||n>o)&&(n=o),r.length>0&&(0>n||0>t)||t>this.length)throw new RangeError("attempt to write outside buffer bounds");e||(e="utf8");for(var s=!1;;)switch(e){case"hex":return w(this,r,t,n);case"utf8":case"utf-8":return _(this,r,t,n);case"ascii":return A(this,r,t,n);case"binary":return x(this,r,t,n);case"base64":return E(this,r,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return j(this,r,t,n);default:if(s)throw new TypeError("Unknown encoding: "+e);e=(""+e).toLowerCase(),s=!0}},o.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};var Z=4096;o.prototype.slice=function(r,t){var n=this.length;r=~~r,t=void 0===t?n:~~t,0>r?(r+=n,0>r&&(r=0)):r>n&&(r=n),0>t?(t+=n,0>t&&(t=0)):t>n&&(t=n),r>t&&(t=r);var e;if(o.TYPED_ARRAY_SUPPORT)e=o._augment(this.subarray(r,t));else{var i=t-r;e=new o(i,void 0);for(var s=0;i>s;s++)e[s]=this[s+r]}return e.length&&(e.parent=this.parent||this),e},o.prototype.readUIntLE=function(r,t,n){r=0|r,t=0|t,n||U(r,t,this.length);for(var e=this[r],i=1,o=0;++o<t&&(i*=256);)e+=this[r+o]*i;return e},o.prototype.readUIntBE=function(r,t,n){r=0|r,t=0|t,n||U(r,t,this.length);for(var e=this[r+--t],i=1;t>0&&(i*=256);)e+=this[r+--t]*i;return e},o.prototype.readUInt8=function(r,t){return t||U(r,1,this.length),this[r]},o.prototype.readUInt16LE=function(r,t){return t||U(r,2,this.length),this[r]|this[r+1]<<8},o.prototype.readUInt16BE=function(r,t){return t||U(r,2,this.length),this[r]<<8|this[r+1]},o.prototype.readUInt32LE=function(r,t){return t||U(r,4,this.length),(this[r]|this[r+1]<<8|this[r+2]<<16)+16777216*this[r+3]},o.prototype.readUInt32BE=function(r,t){return t||U(r,4,this.length),16777216*this[r]+(this[r+1]<<16|this[r+2]<<8|this[r+3])},o.prototype.readIntLE=function(r,t,n){r=0|r,t=0|t,n||U(r,t,this.length);for(var e=this[r],i=1,o=0;++o<t&&(i*=256);)e+=this[r+o]*i;return i*=128,e>=i&&(e-=Math.pow(2,8*t)),e},o.prototype.readIntBE=function(r,t,n){r=0|r,t=0|t,n||U(r,t,this.length);for(var e=t,i=1,o=this[r+--e];e>0&&(i*=256);)o+=this[r+--e]*i;return i*=128,o>=i&&(o-=Math.pow(2,8*t)),o},o.prototype.readInt8=function(r,t){return t||U(r,1,this.length),128&this[r]?-1*(255-this[r]+1):this[r]},o.prototype.readInt16LE=function(r,t){t||U(r,2,this.length);var n=this[r]|this[r+1]<<8;return 32768&n?4294901760|n:n},o.prototype.readInt16BE=function(r,t){t||U(r,2,this.length);var n=this[r+1]|this[r]<<8;return 32768&n?4294901760|n:n},o.prototype.readInt32LE=function(r,t){return t||U(r,4,this.length),this[r]|this[r+1]<<8|this[r+2]<<16|this[r+3]<<24},o.prototype.readInt32BE=function(r,t){return t||U(r,4,this.length),this[r]<<24|this[r+1]<<16|this[r+2]<<8|this[r+3]},o.prototype.readFloatLE=function(r,t){return t||U(r,4,this.length),K.read(this,r,!0,23,4)},o.prototype.readFloatBE=function(r,t){return t||U(r,4,this.length),K.read(this,r,!1,23,4)},o.prototype.readDoubleLE=function(r,t){return t||U(r,8,this.length),K.read(this,r,!0,52,8)},o.prototype.readDoubleBE=function(r,t){return t||U(r,8,this.length),K.read(this,r,!1,52,8)},o.prototype.writeUIntLE=function(r,t,n,e){r=+r,t=0|t,n=0|n,e||S(this,r,t,n,Math.pow(2,8*n),0);var i=1,o=0;for(this[t]=255&r;++o<n&&(i*=256);)this[t+o]=r/i&255;return t+n},o.prototype.writeUIntBE=function(r,t,n,e){r=+r,t=0|t,n=0|n,e||S(this,r,t,n,Math.pow(2,8*n),0);var i=n-1,o=1;for(this[t+i]=255&r;--i>=0&&(o*=256);)this[t+i]=r/o&255;return t+n},o.prototype.writeUInt8=function(r,t,n){return r=+r,t=0|t,n||S(this,r,t,1,255,0),o.TYPED_ARRAY_SUPPORT||(r=Math.floor(r)),this[t]=255&r,t+1},o.prototype.writeUInt16LE=function(r,t,n){return r=+r,t=0|t,n||S(this,r,t,2,65535,0),o.TYPED_ARRAY_SUPPORT?(this[t]=255&r,this[t+1]=r>>>8):L(this,r,t,!0),t+2},o.prototype.writeUInt16BE=function(r,t,n){return r=+r,t=0|t,n||S(this,r,t,2,65535,0),o.TYPED_ARRAY_SUPPORT?(this[t]=r>>>8,this[t+1]=255&r):L(this,r,t,!1),t+2},o.prototype.writeUInt32LE=function(r,t,n){return r=+r,t=0|t,n||S(this,r,t,4,4294967295,0),o.TYPED_ARRAY_SUPPORT?(this[t+3]=r>>>24,this[t+2]=r>>>16,this[t+1]=r>>>8,this[t]=255&r):V(this,r,t,!0),t+4},o.prototype.writeUInt32BE=function(r,t,n){return r=+r,t=0|t,n||S(this,r,t,4,4294967295,0),o.TYPED_ARRAY_SUPPORT?(this[t]=r>>>24,this[t+1]=r>>>16,this[t+2]=r>>>8,this[t+3]=255&r):V(this,r,t,!1),t+4},o.prototype.writeIntLE=function(r,t,n,e){if(r=+r,t=0|t,!e){var i=Math.pow(2,8*n-1);S(this,r,t,n,i-1,-i)}var o=0,s=1,a=0>r?1:0;for(this[t]=255&r;++o<n&&(s*=256);)this[t+o]=(r/s>>0)-a&255;return t+n},o.prototype.writeIntBE=function(r,t,n,e){if(r=+r,t=0|t,!e){var i=Math.pow(2,8*n-1);S(this,r,t,n,i-1,-i)}var o=n-1,s=1,a=0>r?1:0;for(this[t+o]=255&r;--o>=0&&(s*=256);)this[t+o]=(r/s>>0)-a&255;return t+n},o.prototype.writeInt8=function(r,t,n){return r=+r,t=0|t,n||S(this,r,t,1,127,-128),o.TYPED_ARRAY_SUPPORT||(r=Math.floor(r)),0>r&&(r=255+r+1),this[t]=255&r,t+1},o.prototype.writeInt16LE=function(r,t,n){return r=+r,t=0|t,n||S(this,r,t,2,32767,-32768),o.TYPED_ARRAY_SUPPORT?(this[t]=255&r,this[t+1]=r>>>8):L(this,r,t,!0),t+2},o.prototype.writeInt16BE=function(r,t,n){return r=+r,t=0|t,n||S(this,r,t,2,32767,-32768),o.TYPED_ARRAY_SUPPORT?(this[t]=r>>>8,this[t+1]=255&r):L(this,r,t,!1),t+2},o.prototype.writeInt32LE=function(r,t,n){return r=+r,t=0|t,n||S(this,r,t,4,2147483647,-2147483648),o.TYPED_ARRAY_SUPPORT?(this[t]=255&r,this[t+1]=r>>>8,this[t+2]=r>>>16,this[t+3]=r>>>24):V(this,r,t,!0),t+4},o.prototype.writeInt32BE=function(r,t,n){return r=+r,t=0|t,n||S(this,r,t,4,2147483647,-2147483648),0>r&&(r=4294967295+r+1),o.TYPED_ARRAY_SUPPORT?(this[t]=r>>>24,this[t+1]=r>>>16,this[t+2]=r>>>8,this[t+3]=255&r):V(this,r,t,!1),t+4},o.prototype.writeFloatLE=function(r,t,n){return F(this,r,t,!0,n)},o.prototype.writeFloatBE=function(r,t,n){return F(this,r,t,!1,n)},o.prototype.writeDoubleLE=function(r,t,n){return O(this,r,t,!0,n)},o.prototype.writeDoubleBE=function(r,t,n){return O(this,r,t,!1,n)},o.prototype.copy=function(r,t,n,e){if(n||(n=0),e||0===e||(e=this.length),t>=r.length&&(t=r.length),t||(t=0),e>0&&n>e&&(e=n),e===n)return 0;if(0===r.length||0===this.length)return 0;if(0>t)throw new RangeError("targetStart out of bounds");if(0>n||n>=this.length)throw new RangeError("sourceStart out of bounds");if(0>e)throw new RangeError("sourceEnd out of bounds");e>this.length&&(e=this.length),r.length-t<e-n&&(e=r.length-t+n);var i,s=e-n;if(this===r&&t>n&&e>t)for(i=s-1;i>=0;i--)r[i+t]=this[i+n];else if(1e3>s||!o.TYPED_ARRAY_SUPPORT)for(i=0;s>i;i++)r[i+t]=this[i+n];else r._set(this.subarray(n,n+s),t);return s},o.prototype.fill=function(r,t,n){if(r||(r=0),t||(t=0),n||(n=this.length),t>n)throw new RangeError("end < start");if(n!==t&&0!==this.length){if(0>t||t>=this.length)throw new RangeError("start out of bounds");if(0>n||n>this.length)throw new RangeError("end out of bounds");var e;if("number"==typeof r)for(e=t;n>e;e++)this[e]=r;else{var i=Y(r.toString()),o=i.length;for(e=t;n>e;e++)this[e]=i[e%o]}return this}},o.prototype.toArrayBuffer=function(){if("undefined"!=typeof Uint8Array){if(o.TYPED_ARRAY_SUPPORT)return new o(this).buffer;for(var r=new Uint8Array(this.length),t=0,n=r.length;n>t;t+=1)r[t]=this[t];return r.buffer}throw new TypeError("Buffer.toArrayBuffer not supported in this browser")};var $=o.prototype;o._augment=function(r){return r.constructor=o,r._isBuffer=!0,r._set=r.set,r.get=$.get,r.set=$.set,r.write=$.write,r.toString=$.toString,r.toLocaleString=$.toString,r.toJSON=$.toJSON,r.equals=$.equals,r.compare=$.compare,r.indexOf=$.indexOf,r.copy=$.copy,r.slice=$.slice,r.readUIntLE=$.readUIntLE,r.readUIntBE=$.readUIntBE,r.readUInt8=$.readUInt8,r.readUInt16LE=$.readUInt16LE,r.readUInt16BE=$.readUInt16BE,r.readUInt32LE=$.readUInt32LE,r.readUInt32BE=$.readUInt32BE,r.readIntLE=$.readIntLE,r.readIntBE=$.readIntBE,r.readInt8=$.readInt8,r.readInt16LE=$.readInt16LE,r.readInt16BE=$.readInt16BE,r.readInt32LE=$.readInt32LE,r.readInt32BE=$.readInt32BE,r.readFloatLE=$.readFloatLE,r.readFloatBE=$.readFloatBE,r.readDoubleLE=$.readDoubleLE,r.readDoubleBE=$.readDoubleBE,r.writeUInt8=$.writeUInt8,r.writeUIntLE=$.writeUIntLE,r.writeUIntBE=$.writeUIntBE,r.writeUInt16LE=$.writeUInt16LE,r.writeUInt16BE=$.writeUInt16BE,r.writeUInt32LE=$.writeUInt32LE,r.writeUInt32BE=$.writeUInt32BE,r.writeIntLE=$.writeIntLE,r.writeIntBE=$.writeIntBE,r.writeInt8=$.writeInt8,r.writeInt16LE=$.writeInt16LE,r.writeInt16BE=$.writeInt16BE,r.writeInt32LE=$.writeInt32LE,r.writeInt32BE=$.writeInt32BE,r.writeFloatLE=$.writeFloatLE,r.writeFloatBE=$.writeFloatBE,r.writeDoubleLE=$.writeDoubleLE,r.writeDoubleBE=$.writeDoubleBE,r.fill=$.fill,r.inspect=$.inspect,r.toArrayBuffer=$.toArrayBuffer,r};var rr=/[^+\/0-9A-Za-z-_]/g}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"base64-js":3,ieee754:4,"is-array":5}],3:[function(r,t,n){var e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";!function(r){"use strict";function t(r){var t=r.charCodeAt(0);return t===s||t===l?62:t===a||t===c?63:u>t?-1:u+10>t?t-u+26+26:f+26>t?t-f:h+26>t?t-h+26:void 0}function n(r){function n(r){h[l++]=r}var e,i,s,a,u,h;if(r.length%4>0)throw new Error("Invalid string. Length must be a multiple of 4");var f=r.length;u="="===r.charAt(f-2)?2:"="===r.charAt(f-1)?1:0,h=new o(3*r.length/4-u),s=u>0?r.length-4:r.length;var l=0;for(e=0,i=0;s>e;e+=4,i+=3)a=t(r.charAt(e))<<18|t(r.charAt(e+1))<<12|t(r.charAt(e+2))<<6|t(r.charAt(e+3)),n((16711680&a)>>16),n((65280&a)>>8),n(255&a);return 2===u?(a=t(r.charAt(e))<<2|t(r.charAt(e+1))>>4,n(255&a)):1===u&&(a=t(r.charAt(e))<<10|t(r.charAt(e+1))<<4|t(r.charAt(e+2))>>2,n(a>>8&255),n(255&a)),h}function i(r){function t(r){return e.charAt(r)}function n(r){return t(r>>18&63)+t(r>>12&63)+t(r>>6&63)+t(63&r)}var i,o,s,a=r.length%3,u="";for(i=0,s=r.length-a;s>i;i+=3)o=(r[i]<<16)+(r[i+1]<<8)+r[i+2],u+=n(o);switch(a){case 1:o=r[r.length-1],u+=t(o>>2),u+=t(o<<4&63),u+="==";break;case 2:o=(r[r.length-2]<<8)+r[r.length-1],u+=t(o>>10),u+=t(o>>4&63),u+=t(o<<2&63),u+="="}return u}var o="undefined"!=typeof Uint8Array?Uint8Array:Array,s="+".charCodeAt(0),a="/".charCodeAt(0),u="0".charCodeAt(0),h="a".charCodeAt(0),f="A".charCodeAt(0),l="-".charCodeAt(0),c="_".charCodeAt(0);r.toByteArray=n,r.fromByteArray=i}("undefined"==typeof n?this.base64js={}:n)},{}],4:[function(r,t,n){n.read=function(r,t,n,e,i){var o,s,a=8*i-e-1,u=(1<<a)-1,h=u>>1,f=-7,l=n?i-1:0,c=n?-1:1,p=r[t+l];for(l+=c,o=p&(1<<-f)-1,p>>=-f,f+=a;f>0;o=256*o+r[t+l],l+=c,f-=8);for(s=o&(1<<-f)-1,o>>=-f,f+=e;f>0;s=256*s+r[t+l],l+=c,f-=8);if(0===o)o=1-h;else{if(o===u)return s?NaN:(p?-1:1)*(1/0);s+=Math.pow(2,e),o-=h}return(p?-1:1)*s*Math.pow(2,o-e)},n.write=function(r,t,n,e,i,o){var s,a,u,h=8*o-i-1,f=(1<<h)-1,l=f>>1,c=23===i?Math.pow(2,-24)-Math.pow(2,-77):0,p=e?0:o-1,g=e?1:-1,v=0>t||0===t&&0>1/t?1:0;for(t=Math.abs(t),isNaN(t)||t===1/0?(a=isNaN(t)?1:0,s=f):(s=Math.floor(Math.log(t)/Math.LN2),t*(u=Math.pow(2,-s))<1&&(s--,u*=2),t+=s+l>=1?c/u:c*Math.pow(2,1-l),t*u>=2&&(s++,u/=2),s+l>=f?(a=0,s=f):s+l>=1?(a=(t*u-1)*Math.pow(2,i),s+=l):(a=t*Math.pow(2,l-1)*Math.pow(2,i),s=0));i>=8;r[n+p]=255&a,p+=g,a/=256,i-=8);for(s=s<<i|a,h+=i;h>0;r[n+p]=255&s,p+=g,s/=256,h-=8);r[n+p-g]|=128*v}},{}],5:[function(r,t,n){var e=Array.isArray,i=Object.prototype.toString;t.exports=e||function(r){return!!r&&"[object Array]"==i.call(r)}},{}],6:[function(r,t,n){"use strict";function e(r,t,n,e,i){this.gl=r,this.type=t,this.handle=n,this.length=e,this.usage=i}function i(r,t,n,e,i,o){var s=i.length*i.BYTES_PER_ELEMENT;if(0>o)return r.bufferData(t,i,e),s;if(s+o>n)throw new Error("gl-buffer: If resizing buffer, must not specify offset");return r.bufferSubData(t,o,i),n}function o(r,t){for(var n=u.malloc(r.length,t),e=r.length,i=0;e>i;++i)n[i]=r[i];return n}function s(r,t){for(var n=1,e=t.length-1;e>=0;--e){if(t[e]!==n)return!1;n*=r[e]}return!0}function a(r,t,n,i){if(n=n||r.ARRAY_BUFFER,i=i||r.DYNAMIC_DRAW,n!==r.ARRAY_BUFFER&&n!==r.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(i!==r.DYNAMIC_DRAW&&i!==r.STATIC_DRAW&&i!==r.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 o=r.createBuffer(),s=new e(r,n,o,0,i);return s.update(t),s}var u=r("typedarray-pool"),h=r("ndarray-ops"),f=r("ndarray"),l=["uint8","uint8_clamped","uint16","uint32","int8","int16","int32","float32"],c=e.prototype;c.bind=function(){this.gl.bindBuffer(this.type,this.handle)},c.unbind=function(){this.gl.bindBuffer(this.type,null)},c.dispose=function(){this.gl.deleteBuffer(this.handle)},c.update=function(r,t){if("number"!=typeof t&&(t=-1),this.bind(),"object"==typeof r&&"undefined"!=typeof r.shape){var n=r.dtype;if(l.indexOf(n)<0&&(n="float32"),this.type===this.gl.ELEMENT_ARRAY_BUFFER){var e=gl.getExtension("OES_element_index_uint");n=e&&"uint16"!==n?"uint32":"uint16"}if(n===r.dtype&&s(r.shape,r.stride))0===r.offset&&r.data.length===r.shape[0]?this.length=i(this.gl,this.type,this.length,this.usage,r.data,t):this.length=i(this.gl,this.type,this.length,this.usage,r.data.subarray(r.offset,r.shape[0]),t);else{var a=u.malloc(r.size,n),c=f(a,r.shape);h.assign(c,r),0>t?this.length=i(this.gl,this.type,this.length,this.usage,a,t):this.length=i(this.gl,this.type,this.length,this.usage,a.subarray(0,r.size),t),u.free(a)}}else if(Array.isArray(r)){var p;p=this.type===this.gl.ELEMENT_ARRAY_BUFFER?o(r,"uint16"):o(r,"float32"),0>t?this.length=i(this.gl,this.type,this.length,this.usage,p,t):this.length=i(this.gl,this.type,this.length,this.usage,p.subarray(0,r.length),t),u.free(p)}else if("object"==typeof r&&"number"==typeof r.length)this.length=i(this.gl,this.type,this.length,this.usage,r,t);else{if("number"!=typeof r&&void 0!==r)throw new Error("gl-buffer: Invalid data type");if(t>=0)throw new Error("gl-buffer: Cannot specify offset when resizing buffer");r=0|r,0>=r&&(r=1),this.gl.bufferData(this.type,0|r,this.usage),this.length=r}},t.exports=a},{ndarray:12,"ndarray-ops":7,"typedarray-pool":17}],7:[function(r,t,n){"use strict";function e(r){if(!r)return a;for(var t=0;t<r.args.length;++t){var n=r.args[t];0===t?r.args[t]={name:n,lvalue:!0,rvalue:!!r.rvalue,count:r.count||1}:r.args[t]={name:n,lvalue:!1,rvalue:!0,count:1}}return r.thisVars||(r.thisVars=[]),r.localVars||(r.localVars=[]),r}function i(r){return s({args:r.args,pre:e(r.pre),body:e(r.body),post:e(r.proc),funcName:r.funcName})}function o(r){for(var t=[],n=0;n<r.args.length;++n)t.push("a"+n);var e=new Function("P",["return function ",r.funcName,"_ndarrayops(",t.join(","),") {P(",t.join(","),");return a0}"].join(""));return e(i(r))}var s=r("cwise-compiler"),a={body:"",args:[],thisVars:[],localVars:[]},u={add:"+",sub:"-",mul:"*",div:"/",mod:"%",band:"&",bor:"|",bxor:"^",lshift:"<<",rshift:">>",rrshift:">>>"};!function(){for(var r in u){var t=u[r];n[r]=o({args:["array","array","array"],body:{args:["a","b","c"],body:"a=b"+t+"c"},funcName:r}),n[r+"eq"]=o({args:["array","array"],body:{args:["a","b"],body:"a"+t+"=b"},rvalue:!0,funcName:r+"eq"}),n[r+"s"]=o({args:["array","array","scalar"],body:{args:["a","b","s"],body:"a=b"+t+"s"},funcName:r+"s"}),n[r+"seq"]=o({args:["array","scalar"],body:{args:["a","s"],body:"a"+t+"=s"},rvalue:!0,funcName:r+"seq"})}}();var h={not:"!",bnot:"~",neg:"-",recip:"1.0/"};!function(){for(var r in h){var t=h[r];n[r]=o({args:["array","array"],body:{args:["a","b"],body:"a="+t+"b"},funcName:r}),n[r+"eq"]=o({args:["array"],body:{args:["a"],body:"a="+t+"a"},rvalue:!0,count:2,funcName:r+"eq"})}}();var f={and:"&&",or:"||",eq:"===",neq:"!==",lt:"<",gt:">",leq:"<=",geq:">="};!function(){for(var r in f){var t=f[r];n[r]=o({args:["array","array","array"],body:{args:["a","b","c"],body:"a=b"+t+"c"},funcName:r}),n[r+"s"]=o({args:["array","array","scalar"],body:{args:["a","b","s"],body:"a=b"+t+"s"},funcName:r+"s"}),n[r+"eq"]=o({args:["array","array"],body:{args:["a","b"],body:"a=a"+t+"b"},rvalue:!0,count:2,funcName:r+"eq"}),n[r+"seq"]=o({args:["array","scalar"],body:{args:["a","s"],body:"a=a"+t+"s"},rvalue:!0,count:2,funcName:r+"seq"})}}();var l=["abs","acos","asin","atan","ceil","cos","exp","floor","log","round","sin","sqrt","tan"];!function(){for(var r=0;r<l.length;++r){var t=l[r];n[t]=o({args:["array","array"],pre:{args:[],body:"this_f=Math."+t,thisVars:["this_f"]},body:{args:["a","b"],body:"a=this_f(b)",thisVars:["this_f"]},funcName:t}),n[t+"eq"]=o({args:["array"],pre:{args:[],body:"this_f=Math."+t,thisVars:["this_f"]},body:{args:["a"],body:"a=this_f(a)",thisVars:["this_f"]},rvalue:!0,count:2,funcName:t+"eq"})}}();var c=["max","min","atan2","pow"];!function(){for(var r=0;r<c.length;++r){var t=c[r];n[t]=o({args:["array","array","array"],pre:{args:[],body:"this_f=Math."+t,thisVars:["this_f"]},body:{args:["a","b","c"],body:"a=this_f(b,c)",thisVars:["this_f"]},funcName:t}),n[t+"s"]=o({args:["array","array","scalar"],pre:{args:[],body:"this_f=Math."+t,thisVars:["this_f"]},body:{args:["a","b","c"],body:"a=this_f(b,c)",thisVars:["this_f"]},funcName:t+"s"}),n[t+"eq"]=o({args:["array","array"],pre:{args:[],body:"this_f=Math."+t,thisVars:["this_f"]},body:{args:["a","b"],body:"a=this_f(a,b)",thisVars:["this_f"]},rvalue:!0,count:2,funcName:t+"eq"}),n[t+"seq"]=o({args:["array","scalar"],pre:{args:[],body:"this_f=Math."+t,thisVars:["this_f"]},body:{args:["a","b"],body:"a=this_f(a,b)",thisVars:["this_f"]},rvalue:!0,count:2,funcName:t+"seq"})}}();var p=["atan2","pow"];!function(){for(var r=0;r<p.length;++r){var t=p[r];n[t+"op"]=o({args:["array","array","array"],pre:{args:[],body:"this_f=Math."+t,thisVars:["this_f"]},body:{args:["a","b","c"],body:"a=this_f(c,b)",thisVars:["this_f"]},funcName:t+"op"}),n[t+"ops"]=o({args:["array","array","scalar"],pre:{args:[],body:"this_f=Math."+t,thisVars:["this_f"]},body:{args:["a","b","c"],body:"a=this_f(c,b)",thisVars:["this_f"]},funcName:t+"ops"}),n[t+"opeq"]=o({args:["array","array"],pre:{args:[],body:"this_f=Math."+t,thisVars:["this_f"]},body:{args:["a","b"],body:"a=this_f(b,a)",thisVars:["this_f"]},rvalue:!0,count:2,funcName:t+"opeq"}),n[t+"opseq"]=o({args:["array","scalar"],pre:{args:[],body:"this_f=Math."+t,thisVars:["this_f"]},body:{args:["a","b"],body:"a=this_f(b,a)",thisVars:["this_f"]},rvalue:!0,count:2,funcName:t+"opseq"})}}(),n.any=s({args:["array"],pre:a,body:{args:[{name:"a",lvalue:!1,rvalue:!0,count:1}],body:"if(a){return true}",localVars:[],thisVars:[]},post:{args:[],localVars:[],thisVars:[],body:"return false"},funcName:"any"}),n.all=s({args:["array"],pre:a,body:{args:[{name:"x",lvalue:!1,rvalue:!0,count:1}],body:"if(!x){return false}",localVars:[],thisVars:[]},post:{args:[],localVars:[],thisVars:[],body:"return true"},funcName:"all"}),n.sum=s({args:["array"],pre:{args:[],localVars:[],thisVars:["this_s"],body:"this_s=0"},body:{args:[{name:"a",lvalue:!1,rvalue:!0,count:1}],body:"this_s+=a",localVars:[],thisVars:["this_s"]},post:{args:[],localVars:[],thisVars:["this_s"],body:"return this_s"},funcName:"sum"}),n.prod=s({args:["array"],pre:{args:[],localVars:[],thisVars:["this_s"],body:"this_s=1"},body:{ | |
args:[{name:"a",lvalue:!1,rvalue:!0,count:1}],body:"this_s*=a",localVars:[],thisVars:["this_s"]},post:{args:[],localVars:[],thisVars:["this_s"],body:"return this_s"},funcName:"prod"}),n.norm2squared=s({args:["array"],pre:{args:[],localVars:[],thisVars:["this_s"],body:"this_s=0"},body:{args:[{name:"a",lvalue:!1,rvalue:!0,count:2}],body:"this_s+=a*a",localVars:[],thisVars:["this_s"]},post:{args:[],localVars:[],thisVars:["this_s"],body:"return this_s"},funcName:"norm2squared"}),n.norm2=s({args:["array"],pre:{args:[],localVars:[],thisVars:["this_s"],body:"this_s=0"},body:{args:[{name:"a",lvalue:!1,rvalue:!0,count:2}],body:"this_s+=a*a",localVars:[],thisVars:["this_s"]},post:{args:[],localVars:[],thisVars:["this_s"],body:"return Math.sqrt(this_s)"},funcName:"norm2"}),n.norminf=s({args:["array"],pre:{args:[],localVars:[],thisVars:["this_s"],body:"this_s=0"},body:{args:[{name:"a",lvalue:!1,rvalue:!0,count:4}],body:"if(-a>this_s){this_s=-a}else if(a>this_s){this_s=a}",localVars:[],thisVars:["this_s"]},post:{args:[],localVars:[],thisVars:["this_s"],body:"return this_s"},funcName:"norminf"}),n.norm1=s({args:["array"],pre:{args:[],localVars:[],thisVars:["this_s"],body:"this_s=0"},body:{args:[{name:"a",lvalue:!1,rvalue:!0,count:3}],body:"this_s+=a<0?-a:a",localVars:[],thisVars:["this_s"]},post:{args:[],localVars:[],thisVars:["this_s"],body:"return this_s"},funcName:"norm1"}),n.sup=s({args:["array"],pre:{body:"this_h=-Infinity",args:[],thisVars:["this_h"],localVars:[]},body:{body:"if(_inline_1_arg0_>this_h)this_h=_inline_1_arg0_",args:[{name:"_inline_1_arg0_",lvalue:!1,rvalue:!0,count:2}],thisVars:["this_h"],localVars:[]},post:{body:"return this_h",args:[],thisVars:["this_h"],localVars:[]}}),n.inf=s({args:["array"],pre:{body:"this_h=Infinity",args:[],thisVars:["this_h"],localVars:[]},body:{body:"if(_inline_1_arg0_<this_h)this_h=_inline_1_arg0_",args:[{name:"_inline_1_arg0_",lvalue:!1,rvalue:!0,count:2}],thisVars:["this_h"],localVars:[]},post:{body:"return this_h",args:[],thisVars:["this_h"],localVars:[]}}),n.argmin=s({args:["index","array","shape"],pre:{body:"{this_v=Infinity;this_i=_inline_0_arg2_.slice(0)}",args:[{name:"_inline_0_arg0_",lvalue:!1,rvalue:!1,count:0},{name:"_inline_0_arg1_",lvalue:!1,rvalue:!1,count:0},{name:"_inline_0_arg2_",lvalue:!1,rvalue:!0,count:1}],thisVars:["this_i","this_v"],localVars:[]},body:{body:"{if(_inline_1_arg1_<this_v){this_v=_inline_1_arg1_;for(var _inline_1_k=0;_inline_1_k<_inline_1_arg0_.length;++_inline_1_k){this_i[_inline_1_k]=_inline_1_arg0_[_inline_1_k]}}}",args:[{name:"_inline_1_arg0_",lvalue:!1,rvalue:!0,count:2},{name:"_inline_1_arg1_",lvalue:!1,rvalue:!0,count:2}],thisVars:["this_i","this_v"],localVars:["_inline_1_k"]},post:{body:"{return this_i}",args:[],thisVars:["this_i"],localVars:[]}}),n.argmax=s({args:["index","array","shape"],pre:{body:"{this_v=-Infinity;this_i=_inline_0_arg2_.slice(0)}",args:[{name:"_inline_0_arg0_",lvalue:!1,rvalue:!1,count:0},{name:"_inline_0_arg1_",lvalue:!1,rvalue:!1,count:0},{name:"_inline_0_arg2_",lvalue:!1,rvalue:!0,count:1}],thisVars:["this_i","this_v"],localVars:[]},body:{body:"{if(_inline_1_arg1_>this_v){this_v=_inline_1_arg1_;for(var _inline_1_k=0;_inline_1_k<_inline_1_arg0_.length;++_inline_1_k){this_i[_inline_1_k]=_inline_1_arg0_[_inline_1_k]}}}",args:[{name:"_inline_1_arg0_",lvalue:!1,rvalue:!0,count:2},{name:"_inline_1_arg1_",lvalue:!1,rvalue:!0,count:2}],thisVars:["this_i","this_v"],localVars:["_inline_1_k"]},post:{body:"{return this_i}",args:[],thisVars:["this_i"],localVars:[]}}),n.random=o({args:["array"],pre:{args:[],body:"this_f=Math.random",thisVars:["this_f"]},body:{args:["a"],body:"a=this_f()",thisVars:["this_f"]},funcName:"random"}),n.assign=o({args:["array","array"],body:{args:["a","b"],body:"a=b"},funcName:"assign"}),n.assigns=o({args:["array","scalar"],body:{args:["a","b"],body:"a=b"},funcName:"assigns"}),n.equals=s({args:["array","array"],pre:a,body:{args:[{name:"x",lvalue:!1,rvalue:!0,count:1},{name:"y",lvalue:!1,rvalue:!0,count:1}],body:"if(x!==y){return false}",localVars:[],thisVars:[]},post:{args:[],localVars:[],thisVars:[],body:"return true"},funcName:"equals"})},{"cwise-compiler":8}],8:[function(r,t,n){"use strict";function e(){this.argTypes=[],this.shimArgs=[],this.arrayArgs=[],this.arrayBlockIndices=[],this.scalarArgs=[],this.offsetArgs=[],this.offsetArgIndex=[],this.indexArgs=[],this.shapeArgs=[],this.funcName="",this.pre=null,this.body=null,this.post=null,this.debug=!1}function i(r){var t=new e;t.pre=r.pre,t.body=r.body,t.post=r.post;var n=r.args.slice(0);t.argTypes=n;for(var i=0;i<n.length;++i){var s=n[i];if("array"===s||"object"==typeof s&&s.blockIndices){if(t.argTypes[i]="array",t.arrayArgs.push(i),t.arrayBlockIndices.push(s.blockIndices?s.blockIndices:0),t.shimArgs.push("array"+i),i<t.pre.args.length&&t.pre.args[i].count>0)throw new Error("cwise: pre() block may not reference array args");if(i<t.post.args.length&&t.post.args[i].count>0)throw new Error("cwise: post() block may not reference array args")}else if("scalar"===s)t.scalarArgs.push(i),t.shimArgs.push("scalar"+i);else if("index"===s){if(t.indexArgs.push(i),i<t.pre.args.length&&t.pre.args[i].count>0)throw new Error("cwise: pre() block may not reference array index");if(i<t.body.args.length&&t.body.args[i].lvalue)throw new Error("cwise: body() block may not write to array index");if(i<t.post.args.length&&t.post.args[i].count>0)throw new Error("cwise: post() block may not reference array index")}else if("shape"===s){if(t.shapeArgs.push(i),i<t.pre.args.length&&t.pre.args[i].lvalue)throw new Error("cwise: pre() block may not write to array shape");if(i<t.body.args.length&&t.body.args[i].lvalue)throw new Error("cwise: body() block may not write to array shape");if(i<t.post.args.length&&t.post.args[i].lvalue)throw new Error("cwise: post() block may not write to array shape")}else{if("object"!=typeof s||!s.offset)throw new Error("cwise: Unknown argument type "+n[i]);t.argTypes[i]="offset",t.offsetArgs.push({array:s.array,offset:s.offset}),t.offsetArgIndex.push(i)}}if(t.arrayArgs.length<=0)throw new Error("cwise: No array arguments specified");if(t.pre.args.length>n.length)throw new Error("cwise: Too many arguments in pre() block");if(t.body.args.length>n.length)throw new Error("cwise: Too many arguments in body() block");if(t.post.args.length>n.length)throw new Error("cwise: Too many arguments in post() block");return t.debug=!!r.printCode||!!r.debug,t.funcName=r.funcName||"cwise",t.blockSize=r.blockSize||64,o(t)}var o=r("./lib/thunk.js");t.exports=i},{"./lib/thunk.js":10}],9:[function(r,t,n){"use strict";function e(r,t,n){var e,i,o=r.length,s=t.arrayArgs.length,a=t.indexArgs.length>0,u=[],h=[],f=0,l=0;for(e=0;o>e;++e)h.push(["i",e,"=0"].join(""));for(i=0;s>i;++i)for(e=0;o>e;++e)l=f,f=r[e],0===e?h.push(["d",i,"s",e,"=t",i,"p",f].join("")):h.push(["d",i,"s",e,"=(t",i,"p",f,"-s",l,"*t",i,"p",l,")"].join(""));for(u.push("var "+h.join(",")),e=o-1;e>=0;--e)f=r[e],u.push(["for(i",e,"=0;i",e,"<s",f,";++i",e,"){"].join(""));for(u.push(n),e=0;o>e;++e){for(l=f,f=r[e],i=0;s>i;++i)u.push(["p",i,"+=d",i,"s",e].join(""));a&&(e>0&&u.push(["index[",l,"]-=s",l].join("")),u.push(["++index[",f,"]"].join(""))),u.push("}")}return u.join("\n")}function i(r,t,n,i){for(var o=t.length,s=n.arrayArgs.length,a=n.blockSize,u=n.indexArgs.length>0,h=[],f=0;s>f;++f)h.push(["var offset",f,"=p",f].join(""));for(var f=r;o>f;++f)h.push(["for(var j"+f+"=SS[",t[f],"]|0;j",f,">0;){"].join("")),h.push(["if(j",f,"<",a,"){"].join("")),h.push(["s",t[f],"=j",f].join("")),h.push(["j",f,"=0"].join("")),h.push(["}else{s",t[f],"=",a].join("")),h.push(["j",f,"-=",a,"}"].join("")),u&&h.push(["index[",t[f],"]=j",f].join(""));for(var f=0;s>f;++f){for(var l=["offset"+f],c=r;o>c;++c)l.push(["j",c,"*t",f,"p",t[c]].join(""));h.push(["p",f,"=(",l.join("+"),")"].join(""))}h.push(e(t,n,i));for(var f=r;o>f;++f)h.push("}");return h.join("\n")}function o(r){for(var t=0,n=r[0].length;n>t;){for(var e=1;e<r.length;++e)if(r[e][t]!==r[0][t])return t;++t}return t}function s(r,t,n){for(var e=r.body,i=[],o=[],s=0;s<r.args.length;++s){var a=r.args[s];if(!(a.count<=0)){var u=new RegExp(a.name,"g"),h="",f=t.arrayArgs.indexOf(s);switch(t.argTypes[s]){case"offset":var l=t.offsetArgIndex.indexOf(s),c=t.offsetArgs[l];f=c.array,h="+q"+l;case"array":h="p"+f+h;var p="l"+s,g="a"+f;if(0===t.arrayBlockIndices[f])1===a.count?"generic"===n[f]?a.lvalue?(i.push(["var ",p,"=",g,".get(",h,")"].join("")),e=e.replace(u,p),o.push([g,".set(",h,",",p,")"].join(""))):e=e.replace(u,[g,".get(",h,")"].join("")):e=e.replace(u,[g,"[",h,"]"].join("")):"generic"===n[f]?(i.push(["var ",p,"=",g,".get(",h,")"].join("")),e=e.replace(u,p),a.lvalue&&o.push([g,".set(",h,",",p,")"].join(""))):(i.push(["var ",p,"=",g,"[",h,"]"].join("")),e=e.replace(u,p),a.lvalue&&o.push([g,"[",h,"]=",p].join("")));else{for(var v=[a.name],d=[h],y=0;y<Math.abs(t.arrayBlockIndices[f]);y++)v.push("\\s*\\[([^\\]]+)\\]"),d.push("$"+(y+1)+"*t"+f+"b"+y);if(u=new RegExp(v.join(""),"g"),h=d.join("+"),"generic"===n[f])throw new Error("cwise: Generic arrays not supported in combination with blocks!");e=e.replace(u,[g,"[",h,"]"].join(""))}break;case"scalar":e=e.replace(u,"Y"+t.scalarArgs.indexOf(s));break;case"index":e=e.replace(u,"index");break;case"shape":e=e.replace(u,"shape")}}}return[i.join("\n"),e,o.join("\n")].join("\n").trim()}function a(r){for(var t=new Array(r.length),n=!0,e=0;e<r.length;++e){var i=r[e],o=i.match(/\d+/);o=o?o[0]:"",0===i.charAt(0)?t[e]="u"+i.charAt(1)+o:t[e]=i.charAt(0)+o,e>0&&(n=n&&t[e]===t[e-1])}return n?t[0]:t.join("")}function u(r,t){for(var n=t[1].length-Math.abs(r.arrayBlockIndices[0])|0,u=new Array(r.arrayArgs.length),f=new Array(r.arrayArgs.length),l=0;l<r.arrayArgs.length;++l)f[l]=t[2*l],u[l]=t[2*l+1];for(var c=[],p=[],g=[],v=[],d=[],l=0;l<r.arrayArgs.length;++l){r.arrayBlockIndices[l]<0?(g.push(0),v.push(n),c.push(n),p.push(n+r.arrayBlockIndices[l])):(g.push(r.arrayBlockIndices[l]),v.push(r.arrayBlockIndices[l]+n),c.push(0),p.push(r.arrayBlockIndices[l]));for(var y=[],m=0;m<u[l].length;m++)g[l]<=u[l][m]&&u[l][m]<v[l]&&y.push(u[l][m]-g[l]);d.push(y)}for(var b=["SS"],w=["'use strict'"],_=[],m=0;n>m;++m)_.push(["s",m,"=SS[",m,"]"].join(""));for(var l=0;l<r.arrayArgs.length;++l){b.push("a"+l),b.push("t"+l),b.push("p"+l);for(var m=0;n>m;++m)_.push(["t",l,"p",m,"=t",l,"[",g[l]+m,"]"].join(""));for(var m=0;m<Math.abs(r.arrayBlockIndices[l]);++m)_.push(["t",l,"b",m,"=t",l,"[",c[l]+m,"]"].join(""))}for(var l=0;l<r.scalarArgs.length;++l)b.push("Y"+l);if(r.shapeArgs.length>0&&_.push("shape=SS.slice(0)"),r.indexArgs.length>0){for(var A=new Array(n),l=0;n>l;++l)A[l]="0";_.push(["index=[",A.join(","),"]"].join(""))}for(var l=0;l<r.offsetArgs.length;++l){for(var x=r.offsetArgs[l],E=[],m=0;m<x.offset.length;++m)0!==x.offset[m]&&(1===x.offset[m]?E.push(["t",x.array,"p",m].join("")):E.push([x.offset[m],"*t",x.array,"p",m].join("")));0===E.length?_.push("q"+l+"=0"):_.push(["q",l,"=",E.join("+")].join(""))}var j=h([].concat(r.pre.thisVars).concat(r.body.thisVars).concat(r.post.thisVars));_=_.concat(j),w.push("var "+_.join(","));for(var l=0;l<r.arrayArgs.length;++l)w.push("p"+l+"|=0");r.pre.body.length>3&&w.push(s(r.pre,r,f));var k=s(r.body,r,f),I=o(d);n>I?w.push(i(I,d[0],r,k)):w.push(e(d[0],r,k)),r.post.body.length>3&&w.push(s(r.post,r,f)),r.debug&&console.log("-----Generated cwise routine for ",t,":\n"+w.join("\n")+"\n----------");var M=[r.funcName||"unnamed","_cwise_loop_",u[0].join("s"),"m",I,a(f)].join(""),P=new Function(["function ",M,"(",b.join(","),"){",w.join("\n"),"} return ",M].join(""));return P()}var h=r("uniq");t.exports=u},{uniq:11}],10:[function(r,t,n){"use strict";function e(r){var t=["'use strict'","var CACHED={}"],n=[],e=r.funcName+"_cwise_thunk";t.push(["return function ",e,"(",r.shimArgs.join(","),"){"].join(""));for(var o=[],s=[],a=[["array",r.arrayArgs[0],".shape.slice(",Math.max(0,r.arrayBlockIndices[0]),r.arrayBlockIndices[0]<0?","+r.arrayBlockIndices[0]+")":")"].join("")],u=[],h=[],f=0;f<r.arrayArgs.length;++f){var l=r.arrayArgs[f];n.push(["t",l,"=array",l,".dtype,","r",l,"=array",l,".order"].join("")),o.push("t"+l),o.push("r"+l),s.push("t"+l),s.push("r"+l+".join()"),a.push("array"+l+".data"),a.push("array"+l+".stride"),a.push("array"+l+".offset|0"),f>0&&(u.push("array"+r.arrayArgs[0]+".shape.length===array"+l+".shape.length+"+(Math.abs(r.arrayBlockIndices[0])-Math.abs(r.arrayBlockIndices[f]))),h.push("array"+r.arrayArgs[0]+".shape[shapeIndex+"+Math.max(0,r.arrayBlockIndices[0])+"]===array"+l+".shape[shapeIndex+"+Math.max(0,r.arrayBlockIndices[f])+"]"))}r.arrayArgs.length>1&&(t.push("if (!("+u.join(" && ")+")) throw new Error('cwise: Arrays do not all have the same dimensionality!')"),t.push("for(var shapeIndex=array"+r.arrayArgs[0]+".shape.length-"+Math.abs(r.arrayBlockIndices[0])+"; shapeIndex-->0;) {"),t.push("if (!("+h.join(" && ")+")) throw new Error('cwise: Arrays do not all have the same shape!')"),t.push("}"));for(var f=0;f<r.scalarArgs.length;++f)a.push("scalar"+r.scalarArgs[f]);n.push(["type=[",s.join(","),"].join()"].join("")),n.push("proc=CACHED[type]"),t.push("var "+n.join(",")),t.push(["if(!proc){","CACHED[type]=proc=compile([",o.join(","),"])}","return proc(",a.join(","),")}"].join("")),r.debug&&console.log("-----Generated thunk:\n"+t.join("\n")+"\n----------");var c=new Function("compile",t.join("\n"));return c(i.bind(void 0,r))}var i=r("./compile.js");t.exports=e},{"./compile.js":9}],11:[function(r,t,n){"use strict";function e(r,t){for(var n=1,e=r.length,i=r[0],o=r[0],s=1;e>s;++s)if(o=i,i=r[s],t(i,o)){if(s===n){n++;continue}r[n++]=i}return r.length=n,r}function i(r){for(var t=1,n=r.length,e=r[0],i=r[0],o=1;n>o;++o,i=e)if(i=e,e=r[o],e!==i){if(o===t){t++;continue}r[t++]=e}return r.length=t,r}function o(r,t,n){return 0===r.length?r:t?(n||r.sort(t),e(r,t)):(n||r.sort(),i(r))}t.exports=o},{}],12:[function(r,t,n){function e(r,t){return r[0]-t[0]}function i(){var r,t=this.stride,n=new Array(t.length);for(r=0;r<n.length;++r)n[r]=[Math.abs(t[r]),r];n.sort(e);var i=new Array(n.length);for(r=0;r<i.length;++r)i[r]=n[r][1];return i}function o(r,t){var n=["View",t,"d",r].join("");0>t&&(n="View_Nil"+r);var e="generic"===r;if(-1===t){var o="function "+n+"(a){this.data=a;};var proto="+n+".prototype;proto.dtype='"+r+"';proto.index=function(){return -1};proto.size=0;proto.dimension=-1;proto.shape=proto.stride=proto.order=[];proto.lo=proto.hi=proto.transpose=proto.step=function(){return new "+n+"(this.data);};proto.get=proto.set=function(){};proto.pick=function(){return null};return function construct_"+n+"(a){return new "+n+"(a);}",s=new Function(o);return s()}if(0===t){var o="function "+n+"(a,d) {this.data = a;this.offset = d};var proto="+n+".prototype;proto.dtype='"+r+"';proto.index=function(){return this.offset};proto.dimension=0;proto.size=1;proto.shape=proto.stride=proto.order=[];proto.lo=proto.hi=proto.transpose=proto.step=function "+n+"_copy() {return new "+n+"(this.data,this.offset)};proto.pick=function "+n+"_pick(){return TrivialArray(this.data);};proto.valueOf=proto.get=function "+n+"_get(){return "+(e?"this.data.get(this.offset)":"this.data[this.offset]")+"};proto.set=function "+n+"_set(v){return "+(e?"this.data.set(this.offset,v)":"this.data[this.offset]=v")+"};return function construct_"+n+"(a,b,c,d){return new "+n+"(a,d)}",s=new Function("TrivialArray",o);return s(l[r][0])}var o=["'use strict'"],a=u(t),h=a.map(function(r){return"i"+r}),f="this.offset+"+a.map(function(r){return"this.stride["+r+"]*i"+r}).join("+"),c=a.map(function(r){return"b"+r}).join(","),p=a.map(function(r){return"c"+r}).join(",");o.push("function "+n+"(a,"+c+","+p+",d){this.data=a","this.shape=["+c+"]","this.stride=["+p+"]","this.offset=d|0}","var proto="+n+".prototype","proto.dtype='"+r+"'","proto.dimension="+t),o.push("Object.defineProperty(proto,'size',{get:function "+n+"_size(){return "+a.map(function(r){return"this.shape["+r+"]"}).join("*"),"}})"),1===t?o.push("proto.order=[0]"):(o.push("Object.defineProperty(proto,'order',{get:"),4>t?(o.push("function "+n+"_order(){"),2===t?o.push("return (Math.abs(this.stride[0])>Math.abs(this.stride[1]))?[1,0]:[0,1]}})"):3===t&&o.push("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];}}})")):o.push("ORDER})")),o.push("proto.set=function "+n+"_set("+h.join(",")+",v){"),e?o.push("return this.data.set("+f+",v)}"):o.push("return this.data["+f+"]=v}"),o.push("proto.get=function "+n+"_get("+h.join(",")+"){"),e?o.push("return this.data.get("+f+")}"):o.push("return this.data["+f+"]}"),o.push("proto.index=function "+n+"_index(",h.join(),"){return "+f+"}"),o.push("proto.hi=function "+n+"_hi("+h.join(",")+"){return new "+n+"(this.data,"+a.map(function(r){return["(typeof i",r,"!=='number'||i",r,"<0)?this.shape[",r,"]:i",r,"|0"].join("")}).join(",")+","+a.map(function(r){return"this.stride["+r+"]"}).join(",")+",this.offset)}");var g=a.map(function(r){return"a"+r+"=this.shape["+r+"]"}),v=a.map(function(r){return"c"+r+"=this.stride["+r+"]"});o.push("proto.lo=function "+n+"_lo("+h.join(",")+"){var b=this.offset,d=0,"+g.join(",")+","+v.join(","));for(var d=0;t>d;++d)o.push("if(typeof i"+d+"==='number'&&i"+d+">=0){d=i"+d+"|0;b+=c"+d+"*d;a"+d+"-=d}");o.push("return new "+n+"(this.data,"+a.map(function(r){return"a"+r}).join(",")+","+a.map(function(r){return"c"+r}).join(",")+",b)}"),o.push("proto.step=function "+n+"_step("+h.join(",")+"){var "+a.map(function(r){return"a"+r+"=this.shape["+r+"]"}).join(",")+","+a.map(function(r){return"b"+r+"=this.stride["+r+"]"}).join(",")+",c=this.offset,d=0,ceil=Math.ceil");for(var d=0;t>d;++d)o.push("if(typeof i"+d+"==='number'){d=i"+d+"|0;if(d<0){c+=b"+d+"*(a"+d+"-1);a"+d+"=ceil(-a"+d+"/d)}else{a"+d+"=ceil(a"+d+"/d)}b"+d+"*=d}");o.push("return new "+n+"(this.data,"+a.map(function(r){return"a"+r}).join(",")+","+a.map(function(r){return"b"+r}).join(",")+",c)}");for(var y=new Array(t),m=new Array(t),d=0;t>d;++d)y[d]="a[i"+d+"]",m[d]="b[i"+d+"]";o.push("proto.transpose=function "+n+"_transpose("+h+"){"+h.map(function(r,t){return r+"=("+r+"===undefined?"+t+":"+r+"|0)"}).join(";"),"var a=this.shape,b=this.stride;return new "+n+"(this.data,"+y.join(",")+","+m.join(",")+",this.offset)}"),o.push("proto.pick=function "+n+"_pick("+h+"){var a=[],b=[],c=this.offset");for(var d=0;t>d;++d)o.push("if(typeof i"+d+"==='number'&&i"+d+">=0){c=(c+this.stride["+d+"]*i"+d+")|0}else{a.push(this.shape["+d+"]);b.push(this.stride["+d+"])}");o.push("var ctor=CTOR_LIST[a.length+1];return ctor(this.data,a,b,c)}"),o.push("return function construct_"+n+"(data,shape,stride,offset){return new "+n+"(data,"+a.map(function(r){return"shape["+r+"]"}).join(",")+","+a.map(function(r){return"stride["+r+"]"}).join(",")+",offset)}");var s=new Function("CTOR_LIST","ORDER",o.join("\n"));return s(l[r],i)}function s(r){if(h(r))return"buffer";if(f)switch(Object.prototype.toString.call(r)){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 Uint8Array]":return"uint8";case"[object Uint16Array]":return"uint16";case"[object Uint32Array]":return"uint32";case"[object Uint8ClampedArray]":return"uint8_clamped"}return Array.isArray(r)?"array":"generic"}function a(r,t,n,e){if(void 0===r){var i=l.array[0];return i([])}"number"==typeof r&&(r=[r]),void 0===t&&(t=[r.length]);var a=t.length;if(void 0===n){n=new Array(a);for(var u=a-1,h=1;u>=0;--u)n[u]=h,h*=t[u]}if(void 0===e){e=0;for(var u=0;a>u;++u)n[u]<0&&(e-=(t[u]-1)*n[u])}for(var f=s(r),c=l[f];c.length<=a+1;)c.push(o(f,c.length-1));var i=c[a+1];return i(r,t,n,e)}var u=r("iota-array"),h=r("is-buffer"),f="undefined"!=typeof Float64Array,l={float32:[],float64:[],int8:[],int16:[],int32:[],uint8:[],uint16:[],uint32:[],array:[],uint8_clamped:[],buffer:[],generic:[]};t.exports=a},{"iota-array":13,"is-buffer":14}],13:[function(r,t,n){"use strict";function e(r){for(var t=new Array(r),n=0;r>n;++n)t[n]=n;return t}t.exports=e},{}],14:[function(r,t,n){t.exports=function(r){return!(null==r||!(r._isBuffer||r.constructor&&"function"==typeof r.constructor.isBuffer&&r.constructor.isBuffer(r)))}},{}],15:[function(r,t,n){"use strict";"use restrict";function e(r){var t=32;return r&=-r,r&&t--,65535&r&&(t-=16),16711935&r&&(t-=8),252645135&r&&(t-=4),858993459&r&&(t-=2),1431655765&r&&(t-=1),t}var i=32;n.INT_BITS=i,n.INT_MAX=2147483647,n.INT_MIN=-1<<i-1,n.sign=function(r){return(r>0)-(0>r)},n.abs=function(r){var t=r>>i-1;return(r^t)-t},n.min=function(r,t){return t^(r^t)&-(t>r)},n.max=function(r,t){return r^(r^t)&-(t>r)},n.isPow2=function(r){return!(r&r-1||!r)},n.log2=function(r){var t,n;return t=(r>65535)<<4,r>>>=t,n=(r>255)<<3,r>>>=n,t|=n,n=(r>15)<<2,r>>>=n,t|=n,n=(r>3)<<1,r>>>=n,t|=n,t|r>>1},n.log10=function(r){return r>=1e9?9:r>=1e8?8:r>=1e7?7:r>=1e6?6:r>=1e5?5:r>=1e4?4:r>=1e3?3:r>=100?2:r>=10?1:0},n.popCount=function(r){return r-=r>>>1&1431655765,r=(858993459&r)+(r>>>2&858993459),16843009*(r+(r>>>4)&252645135)>>>24},n.countTrailingZeros=e,n.nextPow2=function(r){return r+=0===r,--r,r|=r>>>1,r|=r>>>2,r|=r>>>4,r|=r>>>8,r|=r>>>16,r+1},n.prevPow2=function(r){return r|=r>>>1,r|=r>>>2,r|=r>>>4,r|=r>>>8,r|=r>>>16,r-(r>>>1)},n.parity=function(r){return r^=r>>>16,r^=r>>>8,r^=r>>>4,r&=15,27030>>>r&1};var o=new Array(256);!function(r){for(var t=0;256>t;++t){var n=t,e=t,i=7;for(n>>>=1;n;n>>>=1)e<<=1,e|=1&n,--i;r[t]=e<<i&255}}(o),n.reverse=function(r){return o[255&r]<<24|o[r>>>8&255]<<16|o[r>>>16&255]<<8|o[r>>>24&255]},n.interleave2=function(r,t){return r&=65535,r=16711935&(r|r<<8),r=252645135&(r|r<<4),r=858993459&(r|r<<2),r=1431655765&(r|r<<1),t&=65535,t=16711935&(t|t<<8),t=252645135&(t|t<<4),t=858993459&(t|t<<2),t=1431655765&(t|t<<1),r|t<<1},n.deinterleave2=function(r,t){return r=r>>>t&1431655765,r=858993459&(r|r>>>1),r=252645135&(r|r>>>2),r=16711935&(r|r>>>4),r=65535&(r|r>>>16),r<<16>>16},n.interleave3=function(r,t,n){return r&=1023,r=4278190335&(r|r<<16),r=251719695&(r|r<<8),r=3272356035&(r|r<<4),r=1227133513&(r|r<<2),t&=1023,t=4278190335&(t|t<<16),t=251719695&(t|t<<8),t=3272356035&(t|t<<4),t=1227133513&(t|t<<2),r|=t<<1,n&=1023,n=4278190335&(n|n<<16),n=251719695&(n|n<<8),n=3272356035&(n|n<<4),n=1227133513&(n|n<<2),r|n<<2},n.deinterleave3=function(r,t){return r=r>>>t&1227133513,r=3272356035&(r|r>>>2),r=251719695&(r|r>>>4),r=4278190335&(r|r>>>8),r=1023&(r|r>>>16),r<<22>>22},n.nextCombination=function(r){var t=r|r-1;return t+1|(~t&-~t)-1>>>e(r)+1}},{}],16:[function(r,t,n){"use strict";function e(r,t,n){var i=0|r[n];if(0>=i)return[];var o,s=new Array(i);if(n===r.length-1)for(o=0;i>o;++o)s[o]=t;else for(o=0;i>o;++o)s[o]=e(r,t,n+1);return s}function i(r,t){var n,e;for(n=new Array(r),e=0;r>e;++e)n[e]=t;return n}function o(r,t){switch("undefined"==typeof t&&(t=0),typeof r){case"number":if(r>0)return i(0|r,t);break;case"object":if("number"==typeof r.length)return e(r,t,0)}return[]}t.exports=o},{}],17:[function(r,t,n){(function(t,e){"use strict";function i(r){if(r){var t=r.length||r.byteLength,n=m.log2(t);A[n].push(r)}}function o(r){i(r.buffer)}function s(r){var r=m.nextPow2(r),t=m.log2(r),n=A[t];return n.length>0?n.pop():new ArrayBuffer(r)}function a(r){return new Uint8Array(s(r),0,r)}function u(r){return new Uint16Array(s(2*r),0,r)}function h(r){return new Uint32Array(s(4*r),0,r)}function f(r){return new Int8Array(s(r),0,r)}function l(r){return new Int16Array(s(2*r),0,r)}function c(r){return new Int32Array(s(4*r),0,r)}function p(r){return new Float32Array(s(4*r),0,r)}function g(r){return new Float64Array(s(8*r),0,r)}function v(r){return w?new Uint8ClampedArray(s(r),0,r):a(r)}function d(r){return new DataView(s(r),0,r)}function y(r){r=m.nextPow2(r);var t=m.log2(r),n=x[t];return n.length>0?n.pop():new e(r)}var m=r("bit-twiddle"),b=r("dup");t.__TYPEDARRAY_POOL||(t.__TYPEDARRAY_POOL={UINT8:b([32,0]),UINT16:b([32,0]),UINT32:b([32,0]),INT8:b([32,0]),INT16:b([32,0]),INT32:b([32,0]),FLOAT:b([32,0]),DOUBLE:b([32,0]),DATA:b([32,0]),UINT8C:b([32,0]),BUFFER:b([32,0])});var w="undefined"!=typeof Uint8ClampedArray,_=t.__TYPEDARRAY_POOL;_.UINT8C||(_.UINT8C=b([32,0])),_.BUFFER||(_.BUFFER=b([32,0]));var A=_.DATA,x=_.BUFFER;n.free=function(r){if(e.isBuffer(r))x[m.log2(r.length)].push(r);else{if("[object ArrayBuffer]"!==Object.prototype.toString.call(r)&&(r=r.buffer),!r)return;var t=r.length||r.byteLength,n=0|m.log2(t);A[n].push(r)}},n.freeUint8=n.freeUint16=n.freeUint32=n.freeInt8=n.freeInt16=n.freeInt32=n.freeFloat32=n.freeFloat=n.freeFloat64=n.freeDouble=n.freeUint8Clamped=n.freeDataView=o,n.freeArrayBuffer=i,n.freeBuffer=function(r){x[m.log2(r.length)].push(r)},n.malloc=function(r,t){if(void 0===t||"arraybuffer"===t)return s(r);switch(t){case"uint8":return a(r);case"uint16":return u(r);case"uint32":return h(r);case"int8":return f(r);case"int16":return l(r);case"int32":return c(r);case"float":case"float32":return p(r);case"double":case"float64":return g(r);case"uint8_clamped":return v(r);case"buffer":return y(r);case"data":case"dataview":return d(r);default:return null}return null},n.mallocArrayBuffer=s,n.mallocUint8=a,n.mallocUint16=u,n.mallocUint32=h,n.mallocInt8=f,n.mallocInt16=l,n.mallocInt32=c,n.mallocFloat32=n.mallocFloat=p,n.mallocFloat64=n.mallocDouble=g,n.mallocUint8Clamped=v,n.mallocDataView=d,n.mallocBuffer=y,n.clearCache=function(){for(var r=0;32>r;++r)_.UINT8[r].length=0,_.UINT16[r].length=0,_.UINT32[r].length=0,_.INT8[r].length=0,_.INT16[r].length=0,_.INT32[r].length=0,_.FLOAT[r].length=0,_.DOUBLE[r].length=0,_.UINT8C[r].length=0,A[r].length=0,x[r].length=0}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{},r("buffer").Buffer)},{"bit-twiddle":15,buffer:2,dup:16}],18:[function(r,t,n){function e(r,t){return r===!1?!1:"undefined"==typeof r?t:r+0}function i(r,t){return r===!1?!1:Array.isArray(r)?r||t:t}n.color=function(r){return i(r,[0,0,0,1])},n.depth=function(r){return e(r,1)},n.stencil=function(r){return e(r,!1)}},{}],19:[function(r,t,n){function e(r){function t(r){var t=0;return n!==!1&&(r.clearColor(n[0],n[1],n[2],n[3]),t|=r.COLOR_BUFFER_BIT),e!==!1&&(r.clearDepth(e),t|=r.DEPTH_BUFFER_BIT),o!==!1&&(r.clearStencil(o),t|=r.STENCIL_BUFFER_BIT),r.clear(t),r}r=r||{};var n=i.color(r.color);Object.defineProperty(t,"color",{get:function(){return n},set:function(r){return n=i.color(r)}});var e=i.depth(r.depth);Object.defineProperty(t,"depth",{get:function(){return e},set:function(r){return e=i.depth(r)}});var o=i.stencil(r.stencil);return Object.defineProperty(t,"stencil",{get:function(){return o},set:function(r){return o=i.stencil(r)}}),t}var i=r("./defaults");t.exports=e},{"./defaults":18}],20:[function(r,t,n){function e(r,t,n){function e(){n(o),i(e)}"function"==typeof t?(n=t,t={}):t=t||{};var o=r.getContext("webgl",t)||r.getContext("webgl-experimental",t)||r.getContext("experimental-webgl",t);if(!o)throw new Error("Unable to initialize WebGL");return n&&i(e),o}var i=r("raf-component");t.exports=e},{"raf-component":21}],21:[function(r,t,n){function e(r){var t=(new Date).getTime(),n=Math.max(0,16-(t-i)),e=setTimeout(r,n);return i=t,e}n=t.exports=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||e;var i=(new Date).getTime(),o=window.cancelAnimationFrame||window.webkitCancelAnimationFrame||window.mozCancelAnimationFrame||window.oCancelAnimationFrame||window.msCancelAnimationFrame||window.clearTimeout;n.cancel=function(r){o.call(window,r)}},{}],22:[function(r,t,n){function e(){var r=new Float32Array(16);return r[0]=1,r[1]=0,r[2]=0,r[3]=0,r[4]=0,r[5]=1,r[6]=0,r[7]=0,r[8]=0,r[9]=0,r[10]=1,r[11]=0,r[12]=0,r[13]=0,r[14]=0,r[15]=1,r}t.exports=e},{}],23:[function(r,t,n){function e(r){return r[0]=1,r[1]=0,r[2]=0,r[3]=0,r[4]=0,r[5]=1,r[6]=0,r[7]=0,r[8]=0,r[9]=0,r[10]=1,r[11]=0,r[12]=0,r[13]=0,r[14]=0,r[15]=1,r}t.exports=e},{}],24:[function(r,t,n){function e(r,t,n,e,i,o,s){var a=1/(t-n),u=1/(e-i),h=1/(o-s);return r[0]=-2*a,r[1]=0,r[2]=0,r[3]=0,r[4]=0,r[5]=-2*u,r[6]=0,r[7]=0,r[8]=0,r[9]=0,r[10]=2*h,r[11]=0,r[12]=(t+n)*a,r[13]=(i+e)*u,r[14]=(s+o)*h,r[15]=1,r}t.exports=e},{}],25:[function(r,t,n){function e(r,t,n){var e=n[0],i=n[1],o=n[2];return r[0]=t[0]*e,r[1]=t[1]*e,r[2]=t[2]*e,r[3]=t[3]*e,r[4]=t[4]*i,r[5]=t[5]*i,r[6]=t[6]*i,r[7]=t[7]*i,r[8]=t[8]*o,r[9]=t[9]*o,r[10]=t[10]*o,r[11]=t[11]*o,r[12]=t[12],r[13]=t[13],r[14]=t[14],r[15]=t[15],r}t.exports=e},{}],26:[function(r,t,n){function e(r,t,n){var e,i,o,s,a,u,h,f,l,c,p,g,v=n[0],d=n[1],y=n[2];return t===r?(r[12]=t[0]*v+t[4]*d+t[8]*y+t[12],r[13]=t[1]*v+t[5]*d+t[9]*y+t[13],r[14]=t[2]*v+t[6]*d+t[10]*y+t[14],r[15]=t[3]*v+t[7]*d+t[11]*y+t[15]):(e=t[0],i=t[1],o=t[2],s=t[3],a=t[4],u=t[5],h=t[6],f=t[7],l=t[8],c=t[9],p=t[10],g=t[11],r[0]=e,r[1]=i,r[2]=o,r[3]=s,r[4]=a,r[5]=u,r[6]=h,r[7]=f,r[8]=l,r[9]=c,r[10]=p,r[11]=g,r[12]=e*v+a*d+l*y+t[12],r[13]=i*v+u*d+c*y+t[13],r[14]=o*v+h*d+p*y+t[14],r[15]=s*v+f*d+g*y+t[15]),r}t.exports=e},{}],27:[function(r,t,n){function e(r,t,n,e){return function(o){return i(o,r,t,n,e)}}t.exports=e;var i=r("gl-shader-core")},{"gl-shader-core":33}],28:[function(r,t,n){function e(){throw new Error("You should bundle your code using `glslify` as a transform.")}t.exports=e},{}],29:[function(r,t,n){"use strict";function e(r,t,n,e,i,o,s){this._gl=r,this._program=t,this._location=n,this._dimension=e,this._name=i,this._constFunc=o,this._relink=s}function i(r,t,n,i,o,s,a){for(var u=["gl","v"],h=[],f=0;i>f;++f)u.push("x"+f),h.push("x"+f);u.push(["if(x0.length===void 0){return gl.vertexAttrib",i,"f(v,",h.join(),")}else{return gl.vertexAttrib",i,"fv(v,x0)}"].join(""));var l=Function.apply(void 0,u),c=new e(r,t,n,i,s,l,a);Object.defineProperty(o,s,{set:function(t){return r.disableVertexAttribArray(c._location),l(r,c._location,t),t},get:function(){return c},enumerable:!0})}function o(r,t,n,e){for(var o={},s=0,a=n.length;a>s;++s){var u=n[s],h=u.name,f=u.type,l=r.getAttribLocation(t,h);switch(f){case"bool":case"int":case"float":i(r,t,l,1,o,h,e);break;default:if(!(f.indexOf("vec")>=0))throw new Error("gl-shader: Unknown data type for attribute "+h+": "+f);var c=f.charCodeAt(f.length-1)-48;if(2>c||c>4)throw new Error("gl-shader: Invalid data type for attribute "+h+": "+f);i(r,t,l,c,o,h,e)}}return o}t.exports=o;var s=e.prototype;s.pointer=function(r,t,n,e){var i=this._gl;i.vertexAttribPointer(this._location,this._dimension,r||i.FLOAT,!!t,n||0,e||0),this._gl.enableVertexAttribArray(this._location)},Object.defineProperty(s,"location",{get:function(){return this._location},set:function(r){r!==this._location&&(this._location=r,this._gl.bindAttribLocation(this._program,r,this._name),this._gl.linkProgram(this._program),this._relink())}})},{}],30:[function(r,t,n){"use strict";function e(r){var t=new Function("y","return function(){return y}");return t(r)}function i(r,t,n,i){function a(n){var e=new Function("gl","prog","locations","return function(){return gl.getUniform(prog,locations["+n+"])}");return e(r,t,i)}function u(r,t,n){switch(n){case"bool":case"int":case"sampler2D":case"samplerCube":return"gl.uniform1i(locations["+t+"],obj"+r+")";case"float":return"gl.uniform1f(locations["+t+"],obj"+r+")";default:var e=n.indexOf("vec");if(!(e>=0&&1>=e&&n.length===4+e)){if(0===n.indexOf("mat")&&4===n.length){var i=n.charCodeAt(n.length-1)-48;if(2>i||i>4)throw new Error("gl-shader: Invalid uniform dimension type for matrix "+name+": "+n);return"gl.uniformMatrix"+i+"fv(locations["+t+"],false,obj"+r+")"}throw new Error("gl-shader: Unknown uniform data type for "+name+": "+n)}var i=n.charCodeAt(n.length-1)-48;if(2>i||i>4)throw new Error("gl-shader: Invalid data type");switch(n.charAt(0)){case"b":case"i":return"gl.uniform"+i+"iv(locations["+t+"],obj"+r+")";case"v":return"gl.uniform"+i+"fv(locations["+t+"],obj"+r+")";default:throw new Error("gl-shader: Unrecognized data type for vector "+name+": "+n); | |
}}}function h(r,t){if("object"!=typeof t)return[[r,t]];var n=[];for(var e in t){var i=t[e],o=r;o+=parseInt(e)+""===e?"["+e+"]":"."+e,"object"==typeof i?n.push.apply(n,h(o,i)):n.push([o,i])}return n}function f(e){for(var o=["return function updateProperty(obj){"],s=h("",e),a=0;a<s.length;++a){var f=s[a],l=f[0],c=f[1];i[c]&&o.push(u(l,c,n[c].type))}o.push("return obj}");var p=new Function("gl","prog","locations",o.join("\n"));return p(r,t,i)}function l(r){switch(r){case"bool":return!1;case"int":case"sampler2D":case"samplerCube":return 0;case"float":return 0;default:var t=r.indexOf("vec");if(t>=0&&1>=t&&r.length===4+t){var n=r.charCodeAt(r.length-1)-48;if(2>n||n>4)throw new Error("gl-shader: Invalid data type");return"b"===r.charAt(0)?o(n,!1):o(n)}if(0===r.indexOf("mat")&&4===r.length){var n=r.charCodeAt(r.length-1)-48;if(2>n||n>4)throw new Error("gl-shader: Invalid uniform dimension type for matrix "+name+": "+r);return o([n,n])}throw new Error("gl-shader: Unknown uniform data type for "+name+": "+r)}}function c(r,t,o){if("object"==typeof o){var s=p(o);Object.defineProperty(r,t,{get:e(s),set:f(o),enumerable:!0,configurable:!1})}else i[o]?Object.defineProperty(r,t,{get:a(o),set:f(o),enumerable:!0,configurable:!1}):r[t]=l(n[o].type)}function p(r){var t;if(Array.isArray(r)){t=new Array(r.length);for(var n=0;n<r.length;++n)c(t,n,r[n])}else{t={};for(var e in r)c(t,e,r[e])}return t}var g=s(n,!0);return{get:e(p(g)),set:f(g),enumerable:!0,configurable:!0}}var o=r("dup"),s=r("./reflect");t.exports=i},{"./reflect":31,dup:32}],31:[function(r,t,n){"use strict";function e(r,t){for(var n={},e=0;e<r.length;++e)for(var i=r[e].name,o=i.split("."),s=n,a=0;a<o.length;++a){var u=o[a].split("[");if(u.length>1){u[0]in s||(s[u[0]]=[]),s=s[u[0]];for(var h=1;h<u.length;++h){var f=parseInt(u[h]);h<u.length-1||a<o.length-1?(f in s||(h<u.length-1?s[f]=[]:s[f]={}),s=s[f]):t?s[f]=e:s[f]=r[e].type}}else a<o.length-1?(u[0]in s||(s[u[0]]={}),s=s[u[0]]):t?s[u[0]]=e:s[u[0]]=r[e].type}return n}t.exports=e},{}],32:[function(r,t,n){arguments[4][16][0].apply(n,arguments)},{dup:16}],33:[function(r,t,n){"use strict";function e(r,t,n,e){this.gl=r,this.handle=t,this.attributes=null,this.uniforms=null,this.types=null,this.vertexShader=n,this.fragmentShader=e}function i(r,t,n,e){for(var i=0;i<e.length;++i)n[i]=r.getUniformLocation(t,e[i].name)}function o(r,t,n,i,o){var s=r.createShader(r.VERTEX_SHADER);if(r.shaderSource(s,t),r.compileShader(s),!r.getShaderParameter(s,r.COMPILE_STATUS)){var a=r.getShaderInfoLog(s);throw console.error("gl-shader: Error compling vertex shader:",a),new Error("gl-shader: Error compiling vertex shader:"+a)}var u=r.createShader(r.FRAGMENT_SHADER);if(r.shaderSource(u,n),r.compileShader(u),!r.getShaderParameter(u,r.COMPILE_STATUS)){var a=r.getShaderInfoLog(u);throw console.error("gl-shader: Error compiling fragment shader:",a),new Error("gl-shader: Error compiling fragment shader:"+a)}var h=r.createProgram();if(r.attachShader(h,u),r.attachShader(h,s),o.forEach(function(t){"number"==typeof t.location&&r.bindAttribLocation(h,t.location,t.name)}),r.linkProgram(h),!r.getProgramParameter(h,r.LINK_STATUS)){var a=r.getProgramInfoLog(h);throw console.error("gl-shader: Error linking shader program:",a),new Error("gl-shader: Error linking shader program:"+a)}var f=new e(r,h,s,u);return f.updateExports(i,o),f}var s=r("./lib/create-uniforms"),a=r("./lib/create-attributes"),u=r("./lib/reflect");e.prototype.bind=function(){this.gl.useProgram(this.handle)},e.prototype.dispose=function(){var r=this.gl;r.deleteShader(this.vertexShader),r.deleteShader(this.fragmentShader),r.deleteProgram(this.handle)},e.prototype.updateExports=function(r,t){var n=new Array(r.length),e=this.handle,o=this.gl,h=i.bind(void 0,o,e,n,r);h(),this.types={uniforms:u(r),attributes:u(t)},this.attributes=a(o,e,t,h),Object.defineProperty(this,"uniforms",s(o,e,r,n))},t.exports=o},{"./lib/create-attributes":29,"./lib/create-uniforms":30,"./lib/reflect":31}],34:[function(r,t,n){"use strict";function e(r,t){return("object"!=typeof t||null===t)&&(t={}),i(r,t.canvas||o,t.context||s,t)}t.exports=e;var i=r("./lib/vtext"),o=null,s=null;"undefined"!=typeof document&&(o=document.createElement("canvas"),o.width=8192,o.height=1024,s=o.getContext("2d"))},{"./lib/vtext":35}],35:[function(r,t,n){"use strict";function e(r,t,n){for(var e=t.textAlign||"start",i=t.textBaseline||"alphabetic",o=[1<<30,1<<30],s=[0,0],a=r.length,u=0;a>u;++u)for(var h=r[u],f=0;2>f;++f)o[f]=0|Math.min(o[f],h[f]),s[f]=0|Math.max(s[f],h[f]);var l=0;switch(e){case"center":l=-.5*(o[0]+s[0]);break;case"right":case"end":l=-s[0];break;case"left":case"start":l=-o[0];break;default:throw new Error("vectorize-text: Unrecognized textAlign: '"+e+"'")}var c=0;switch(i){case"hanging":case"top":c=-o[1];break;case"middle":c=-.5*(o[1]+s[1]);break;case"alphabetic":case"ideographic":c=-3*n;break;case"bottom":c=-s[1];break;default:throw new Error("vectorize-text: Unrecoginized textBaseline: '"+i+"'")}var p=1/n;return"lineHeight"in t?p*=+t.lineHeight:"width"in t?p=t.width/(s[0]-o[0]):"height"in t&&(p=t.height/(s[1]-o[1])),r.map(function(r){return[p*(r[0]+l),p*(r[1]+c)]})}function i(r,t,n,e){var i=0|Math.ceil(t.measureText(n).width+2*e);if(i>8192)throw new Error("vectorize-text: String too long (sorry, this will get fixed later)");var o=3*e;r.height<o&&(r.height=o),t.fillStyle="#000",t.fillRect(0,0,r.width,r.height),t.fillStyle="#fff",t.fillText(n,e,2*e);var s=t.getImageData(0,0,i,o),a=f(s.data,[o,i,4]);return a.pick(-1,-1,0).transpose(1,0)}function o(r,t){var n=h(r,128);return t?l(n.cells,n.positions,.25):{edges:n.cells,positions:n.positions}}function s(r,t,n,i){var s=o(r,i),a=e(s.positions,t,n),u=s.edges,h="ccw"===t.orientation;if(c(a,u),t.polygons||t.polygon||t.polyline){for(var f=g(u,a),l=new Array(f.length),v=0;v<f.length;++v){for(var d=f[v],y=new Array(d.length),m=0;m<d.length;++m){for(var b=d[m],w=new Array(b.length),_=0;_<b.length;++_)w[_]=a[b[_]].slice();h&&w.reverse(),y[m]=w}l[v]=y}return l}return t.triangles||t.triangulate||t.triangle?{cells:p(a,u,{delaunay:!1,exterior:!1,interior:!0}),positions:a}:{edges:u,positions:a}}function a(r,t,n){try{return s(r,t,n,!0)}catch(e){}try{return s(r,t,n,!1)}catch(e){}return t.polygons||t.polyline||t.polygon?[]:t.triangles||t.triangulate||t.triangle?{cells:[],positions:[]}:{edges:[],positions:[]}}function u(r,t,n,e){var o=e.size||64,s=e.font||"normal";n.font=o+"px "+s,n.textAlign="start",n.textBaseline="alphabetic",n.direction="ltr";var u=i(t,n,r,o);return a(u,e,o)}t.exports=u,t.exports.processPixels=a;var h=r("surface-nets"),f=r("ndarray"),l=r("simplify-planar-graph"),c=r("clean-pslg"),p=r("cdt2d"),g=r("planar-graph-to-polyline")},{cdt2d:36,"clean-pslg":54,ndarray:100,"planar-graph-to-polyline":124,"simplify-planar-graph":134,"surface-nets":156}],36:[function(r,t,n){"use strict";function e(r){return[Math.min(r[0],r[1]),Math.max(r[0],r[1])]}function i(r,t){return r[0]-t[0]||r[1]-t[1]}function o(r){return r.map(e).sort(i)}function s(r,t,n){return t in r?r[t]:n}function a(r,t,n){Array.isArray(t)?(n=n||{},t=t||[]):(n=t||{},t=[]);var e=!!s(n,"delaunay",!0),i=!!s(n,"interior",!0),a=!!s(n,"exterior",!0),c=!!s(n,"infinity",!1);if(!i&&!a||0===r.length)return[];var p=u(r,t);if(e||i!==a||c){for(var g=h(r.length,o(t)),v=0;v<p.length;++v){var d=p[v];g.addTriangle(d[0],d[1],d[2])}return e&&f(r,g),a?i?c?l(g,0,c):g.cells():l(g,1,c):l(g,-1)}return p}var u=r("./lib/monotone"),h=r("./lib/triangulation"),f=r("./lib/delaunay"),l=r("./lib/filter");t.exports=a},{"./lib/delaunay":37,"./lib/filter":38,"./lib/monotone":39,"./lib/triangulation":40}],37:[function(r,t,n){"use strict";function e(r,t,n,e,i,s){var a=t.opposite(e,i);if(!(0>a)){if(e>i){var u=e;e=i,i=u,u=s,s=a,a=u}t.isConstraint(e,i)||o(r[e],r[i],r[s],r[a])<0&&n.push(e,i)}}function i(r,t){for(var n=[],i=r.length,s=t.stars,a=0;i>a;++a)for(var u=s[a],h=1;h<u.length;h+=2){var f=u[h];if(!(a>f||t.isConstraint(a,f))){for(var l=u[h-1],c=-1,p=1;p<u.length;p+=2)if(u[p-1]===f){c=u[p];break}0>c||o(r[a],r[f],r[l],r[c])<0&&n.push(a,f)}}for(;n.length>0;){for(var f=n.pop(),a=n.pop(),l=-1,c=-1,u=s[a],g=1;g<u.length;g+=2){var v=u[g-1],d=u[g];v===f?c=d:d===f&&(l=v)}0>l||0>c||o(r[a],r[f],r[l],r[c])>=0||(t.flip(a,f),e(r,t,n,l,a,c),e(r,t,n,a,c,l),e(r,t,n,c,f,l),e(r,t,n,f,l,c))}}var o=r("robust-in-sphere")[4];r("binary-search-bounds");t.exports=i},{"binary-search-bounds":41,"robust-in-sphere":42}],38:[function(r,t,n){"use strict";function e(r,t,n,e,i,o,s){this.cells=r,this.neighbor=t,this.flags=e,this.constraint=n,this.active=i,this.next=o,this.boundary=s}function i(r,t){return r[0]-t[0]||r[1]-t[1]||r[2]-t[2]}function o(r,t){for(var n=r.cells(),o=n.length,s=0;o>s;++s){var a=n[s],u=a[0],h=a[1],f=a[2];f>h?u>h&&(a[0]=h,a[1]=f,a[2]=u):u>f&&(a[0]=f,a[1]=u,a[2]=h)}n.sort(i);for(var l=new Array(o),s=0;s<l.length;++s)l[s]=0;var c=[],p=[],g=new Array(3*o),v=new Array(3*o),d=null;t&&(d=[]);for(var y=new e(n,g,v,l,c,p,d),s=0;o>s;++s)for(var a=n[s],m=0;3>m;++m){var u=a[m],h=a[(m+1)%3],b=g[3*s+m]=y.locate(h,u,r.opposite(h,u)),w=v[3*s+m]=r.isConstraint(u,h);0>b&&(w?p.push(s):(c.push(s),l[s]=1),t&&d.push([h,u,-1]))}return y}function s(r,t,n){for(var e=0,i=0;i<r.length;++i)t[i]===n&&(r[e++]=r[i]);return r.length=e,r}function a(r,t,n){var e=o(r,n);if(0===t)return n?e.cells.concat(e.boundary):e.cells;for(var i=1,a=e.active,u=e.next,h=e.flags,f=e.cells,l=e.constraint,c=e.neighbor;a.length>0||u.length>0;){for(;a.length>0;){var p=a.pop();if(h[p]!==-i){h[p]=i;for(var g=(f[p],0);3>g;++g){var v=c[3*p+g];v>=0&&0===h[v]&&(l[3*p+g]?u.push(v):(a.push(v),h[v]=i))}}}var d=u;u=a,a=d,u.length=0,i=-i}var y=s(f,h,t);return n?y.concat(e.boundary):y}var u=r("binary-search-bounds");t.exports=a;var h=e.prototype;h.locate=function(){var r=[0,0,0];return function(t,n,e){var o=t,s=n,a=e;return e>n?t>n&&(o=n,s=e,a=t):t>e&&(o=e,s=t,a=n),0>o?-1:(r[0]=o,r[1]=s,r[2]=a,u.eq(this.cells,r,i))}}()},{"binary-search-bounds":41}],39:[function(r,t,n){"use strict";function e(r,t,n,e,i){this.a=r,this.b=t,this.idx=n,this.lowerIds=e,this.upperIds=i}function i(r,t,n,e){this.a=r,this.b=t,this.type=n,this.idx=e}function o(r,t){var n=r.a[0]-t.a[0]||r.a[1]-t.a[1]||r.type-t.type;return n?n:r.type!==g&&(n=p(r.a,r.b,t.b))?n:r.idx-t.idx}function s(r,t){return p(r.a,r.b,t)}function a(r,t,n,e,i){for(var o=c.lt(t,e,s),a=c.gt(t,e,s),u=o;a>u;++u){for(var h=t[u],f=h.lowerIds,l=f.length;l>1&&p(n[f[l-2]],n[f[l-1]],e)>0;)r.push([f[l-1],f[l-2],i]),l-=1;f.length=l,f.push(i);for(var g=h.upperIds,l=g.length;l>1&&p(n[g[l-2]],n[g[l-1]],e)<0;)r.push([g[l-2],g[l-1],i]),l-=1;g.length=l,g.push(i)}}function u(r,t){var n;return(n=r.a[0]<t.a[0]?p(r.a,r.b,t.a):p(t.b,t.a,r.a))?n:(n=t.b[0]<r.b[0]?p(r.a,r.b,t.b):p(t.b,t.a,r.b),n||r.idx-t.idx)}function h(r,t,n){var i=c.le(r,n,u),o=r[i],s=o.upperIds,a=s[s.length-1];o.upperIds=[a],r.splice(i+1,0,new e(n.a,n.b,n.idx,[a],s))}function f(r,t,n){var e=n.a;n.a=n.b,n.b=e;var i=c.eq(r,n,u),o=r[i],s=r[i-1];s.upperIds=o.upperIds,r.splice(i,1)}function l(r,t){for(var n=r.length,s=t.length,u=[],l=0;n>l;++l)u.push(new i(r[l],null,g,l));for(var l=0;s>l;++l){var c=t[l],p=r[c[0]],y=r[c[1]];p[0]<y[0]?u.push(new i(p,y,d,l),new i(y,p,v,l)):p[0]>y[0]&&u.push(new i(y,p,d,l),new i(p,y,v,l))}u.sort(o);for(var m=u[0].a[0]-(1+Math.abs(u[0].a[0]))*Math.pow(2,-52),b=[new e([m,1],[m,0],-1,[],[],[],[])],w=[],l=0,_=u.length;_>l;++l){var A=u[l],x=A.type;x===g?a(w,b,r,A.a,A.idx):x===d?h(b,r,A):f(b,r,A)}return w}var c=r("binary-search-bounds"),p=r("robust-orientation")[3],g=0,v=1,d=2;t.exports=l},{"binary-search-bounds":41,"robust-orientation":53}],40:[function(r,t,n){"use strict";function e(r,t){this.stars=r,this.edges=t}function i(r,t,n){for(var e=1,i=r.length;i>e;e+=2)if(r[e-1]===t&&r[e]===n)return r[e-1]=r[i-2],r[e]=r[i-1],void(r.length=i-2)}function o(r,t){for(var n=new Array(r),i=0;r>i;++i)n[i]=[];return new e(n,t)}var s=r("binary-search-bounds");t.exports=o;var a=e.prototype;a.isConstraint=function(){function r(r,t){return r[0]-t[0]||r[1]-t[1]}var t=[0,0];return function(n,e){return t[0]=Math.min(n,e),t[1]=Math.max(n,e),s.eq(this.edges,t,r)>=0}}(),a.removeTriangle=function(r,t,n){var e=this.stars;i(e[r],t,n),i(e[t],n,r),i(e[n],r,t)},a.addTriangle=function(r,t,n){var e=this.stars;e[r].push(t,n),e[t].push(n,r),e[n].push(r,t)},a.opposite=function(r,t){for(var n=this.stars[t],e=1,i=n.length;i>e;e+=2)if(n[e]===r)return n[e-1];return-1},a.flip=function(r,t){var n=this.opposite(r,t),e=this.opposite(t,r);this.removeTriangle(r,t,n),this.removeTriangle(t,r,e),this.addTriangle(r,e,n),this.addTriangle(t,n,e)},a.edges=function(){for(var r=this.stars,t=[],n=0,e=r.length;e>n;++n)for(var i=r[n],o=0,s=i.length;s>o;o+=2)t.push([i[o],i[o+1]]);return t},a.cells=function(){for(var r=this.stars,t=[],n=0,e=r.length;e>n;++n)for(var i=r[n],o=0,s=i.length;s>o;o+=2){var a=i[o],u=i[o+1];n<Math.min(a,u)&&t.push([n,a,u])}return t}},{"binary-search-bounds":41}],41:[function(r,t,n){"use strict";function e(r,t,n,e,i){var o=["function ",r,"(a,l,h,",e.join(","),"){",i?"":"var i=",n?"l-1":"h+1",";while(l<=h){var m=(l+h)>>>1,x=a[m]"];return i?t.indexOf("c")<0?o.push(";if(x===y){return m}else if(x<=y){"):o.push(";var p=c(x,y);if(p===0){return m}else if(p<=0){"):o.push(";if(",t,"){i=m;"),n?o.push("l=m+1}else{h=m-1}"):o.push("h=m-1}else{l=m+1}"),o.push("}"),i?o.push("return -1};"):o.push("return i};"),o.join("")}function i(r,t,n,i){var o=new Function([e("A","x"+r+"y",t,["y"],i),e("P","c(x,y)"+r+"0",t,["y","c"],i),"function dispatchBsearch",n,"(a,y,c,l,h){if(typeof(c)==='function'){return P(a,(l===void 0)?0:l|0,(h===void 0)?a.length-1:h|0,y,c)}else{return A(a,(c===void 0)?0:c|0,(l===void 0)?a.length-1:l|0,y)}}return dispatchBsearch",n].join(""));return o()}t.exports={ge:i(">=",!1,"GE"),gt:i(">",!1,"GT"),lt:i("<",!0,"LT"),le:i("<=",!0,"LE"),eq:i("-",!0,"EQ",!0)}},{}],42:[function(r,t,n){"use strict";function e(r,t){for(var n=new Array(r.length-1),e=1;e<r.length;++e)for(var i=n[e-1]=new Array(r.length-1),o=0,s=0;o<r.length;++o)o!==t&&(i[s++]=r[e][o]);return n}function i(r){for(var t=new Array(r),n=0;r>n;++n){t[n]=new Array(r);for(var e=0;r>e;++e)t[n][e]=["m",e,"[",r-n-2,"]"].join("")}return t}function o(r){if(1===r.length)return r[0];if(2===r.length)return["sum(",r[0],",",r[1],")"].join("");var t=r.length>>1;return["sum(",o(r.slice(0,t)),",",o(r.slice(t)),")"].join("")}function s(r,t){if("m"===r.charAt(0)){if("w"===t.charAt(0)){var n=r.split("[");return["w",t.substr(1),"m",n[0].substr(1)].join("")}return["prod(",r,",",t,")"].join("")}return s(t,r)}function a(r){return r&!0?"-":""}function u(r){if(2===r.length)return[["diff(",s(r[0][0],r[1][1]),",",s(r[1][0],r[0][1]),")"].join("")];for(var t=[],n=0;n<r.length;++n)t.push(["scale(",o(u(e(r,n))),",",a(n),r[0][n],")"].join(""));return t}function h(r,t){for(var n=[],e=0;t-2>e;++e)n.push(["prod(m",r,"[",e,"],m",r,"[",e,"])"].join(""));return o(n)}function f(r){for(var t=[],n=[],s=i(r),a=0;r>a;++a)s[0][a]="1",s[r-1][a]="w"+a;for(var a=0;r>a;++a)0===(1&a)?t.push.apply(t,u(e(s,a))):n.push.apply(n,u(e(s,a)));for(var f=o(t),l=o(n),c="exactInSphere"+r,p=[],a=0;r>a;++a)p.push("m"+a);for(var g=["function ",c,"(",p.join(),"){"],a=0;r>a;++a){g.push("var w",a,"=",h(a,r),";");for(var v=0;r>v;++v)v!==a&&g.push("var w",a,"m",v,"=scale(w",a,",m",v,"[0]);")}g.push("var p=",f,",n=",l,",d=diff(p,n);return d[d.length-1];}return ",c);var w=new Function("sum","diff","prod","scale",g.join(""));return w(y,m,d,b)}function l(){return 0}function c(){return 0}function p(){return 0}function g(r){var t=_[r.length];return t||(t=_[r.length]=f(r.length)),t.apply(void 0,r)}function v(){for(;_.length<=w;)_.push(f(_.length));for(var r=[],n=["slow"],e=0;w>=e;++e)r.push("a"+e),n.push("o"+e);for(var i=["function testInSphere(",r.join(),"){switch(arguments.length){case 0:case 1:return 0;"],e=2;w>=e;++e)i.push("case ",e,":return o",e,"(",r.slice(0,e).join(),");");i.push("}var s=new Array(arguments.length);for(var i=0;i<arguments.length;++i){s[i]=arguments[i]};return slow(s);}return testInSphere"),n.push(i.join(""));var o=Function.apply(void 0,n);t.exports=o.apply(void 0,[g].concat(_));for(var e=0;w>=e;++e)t.exports[e]=_[e]}var d=r("two-product"),y=r("robust-sum"),m=r("robust-subtract"),b=r("robust-scale"),w=6,_=[l,c,p];v()},{"robust-scale":44,"robust-subtract":45,"robust-sum":46,"two-product":47}],43:[function(r,t,n){"use strict";function e(r,t,n){var e=r+t,i=e-r,o=e-i,s=t-i,a=r-o;return n?(n[0]=a+s,n[1]=e,n):[a+s,e]}t.exports=e},{}],44:[function(r,t,n){"use strict";function e(r,t){var n=r.length;if(1===n){var e=i(r[0],t);return e[0]?e:[e[1]]}var s=new Array(2*n),a=[.1,.1],u=[.1,.1],h=0;i(r[0],t,a),a[0]&&(s[h++]=a[0]);for(var f=1;n>f;++f){i(r[f],t,u);var l=a[1];o(l,u[0],a),a[0]&&(s[h++]=a[0]);var c=u[1],p=a[1],g=c+p,v=g-c,d=p-v;a[1]=g,d&&(s[h++]=d)}return a[1]&&(s[h++]=a[1]),0===h&&(s[h++]=0),s.length=h,s}var i=r("two-product"),o=r("two-sum");t.exports=e},{"two-product":47,"two-sum":43}],45:[function(r,t,n){"use strict";function e(r,t){var n=r+t,e=n-r,i=n-e,o=t-e,s=r-i,a=s+o;return a?[a,n]:[n]}function i(r,t){var n=0|r.length,i=0|t.length;if(1===n&&1===i)return e(r[0],-t[0]);var o,s,a=n+i,u=new Array(a),h=0,f=0,l=0,c=Math.abs,p=r[f],g=c(p),v=-t[l],d=c(v);d>g?(s=p,f+=1,n>f&&(p=r[f],g=c(p))):(s=v,l+=1,i>l&&(v=-t[l],d=c(v))),n>f&&d>g||l>=i?(o=p,f+=1,n>f&&(p=r[f],g=c(p))):(o=v,l+=1,i>l&&(v=-t[l],d=c(v)));for(var y,m,b,w,_,A=o+s,x=A-o,E=s-x,j=E,k=A;n>f&&i>l;)d>g?(o=p,f+=1,n>f&&(p=r[f],g=c(p))):(o=v,l+=1,i>l&&(v=-t[l],d=c(v))),s=j,A=o+s,x=A-o,E=s-x,E&&(u[h++]=E),y=k+A,m=y-k,b=y-m,w=A-m,_=k-b,j=_+w,k=y;for(;n>f;)o=p,s=j,A=o+s,x=A-o,E=s-x,E&&(u[h++]=E),y=k+A,m=y-k,b=y-m,w=A-m,_=k-b,j=_+w,k=y,f+=1,n>f&&(p=r[f]);for(;i>l;)o=v,s=j,A=o+s,x=A-o,E=s-x,E&&(u[h++]=E),y=k+A,m=y-k,b=y-m,w=A-m,_=k-b,j=_+w,k=y,l+=1,i>l&&(v=-t[l]);return j&&(u[h++]=j),k&&(u[h++]=k),h||(u[h++]=0),u.length=h,u}t.exports=i},{}],46:[function(r,t,n){"use strict";function e(r,t){var n=r+t,e=n-r,i=n-e,o=t-e,s=r-i,a=s+o;return a?[a,n]:[n]}function i(r,t){var n=0|r.length,i=0|t.length;if(1===n&&1===i)return e(r[0],t[0]);var o,s,a=n+i,u=new Array(a),h=0,f=0,l=0,c=Math.abs,p=r[f],g=c(p),v=t[l],d=c(v);d>g?(s=p,f+=1,n>f&&(p=r[f],g=c(p))):(s=v,l+=1,i>l&&(v=t[l],d=c(v))),n>f&&d>g||l>=i?(o=p,f+=1,n>f&&(p=r[f],g=c(p))):(o=v,l+=1,i>l&&(v=t[l],d=c(v)));for(var y,m,b,w,_,A=o+s,x=A-o,E=s-x,j=E,k=A;n>f&&i>l;)d>g?(o=p,f+=1,n>f&&(p=r[f],g=c(p))):(o=v,l+=1,i>l&&(v=t[l],d=c(v))),s=j,A=o+s,x=A-o,E=s-x,E&&(u[h++]=E),y=k+A,m=y-k,b=y-m,w=A-m,_=k-b,j=_+w,k=y;for(;n>f;)o=p,s=j,A=o+s,x=A-o,E=s-x,E&&(u[h++]=E),y=k+A,m=y-k,b=y-m,w=A-m,_=k-b,j=_+w,k=y,f+=1,n>f&&(p=r[f]);for(;i>l;)o=v,s=j,A=o+s,x=A-o,E=s-x,E&&(u[h++]=E),y=k+A,m=y-k,b=y-m,w=A-m,_=k-b,j=_+w,k=y,l+=1,i>l&&(v=t[l]);return j&&(u[h++]=j),k&&(u[h++]=k),h||(u[h++]=0),u.length=h,u}t.exports=i},{}],47:[function(r,t,n){"use strict";function e(r,t,n){var e=r*t,o=i*r,s=o-r,a=o-s,u=r-a,h=i*t,f=h-t,l=h-f,c=t-l,p=e-a*l,g=p-u*l,v=g-a*c,d=u*c-v;return n?(n[0]=d,n[1]=e,n):[d,e]}t.exports=e;var i=+(Math.pow(2,27)+1)},{}],48:[function(r,t,n){arguments[4][43][0].apply(n,arguments)},{dup:43}],49:[function(r,t,n){arguments[4][44][0].apply(n,arguments)},{dup:44,"two-product":52,"two-sum":48}],50:[function(r,t,n){arguments[4][45][0].apply(n,arguments)},{dup:45}],51:[function(r,t,n){arguments[4][46][0].apply(n,arguments)},{dup:46}],52:[function(r,t,n){arguments[4][47][0].apply(n,arguments)},{dup:47}],53:[function(r,t,n){"use strict";function e(r,t){for(var n=new Array(r.length-1),e=1;e<r.length;++e)for(var i=n[e-1]=new Array(r.length-1),o=0,s=0;o<r.length;++o)o!==t&&(i[s++]=r[e][o]);return n}function i(r){for(var t=new Array(r),n=0;r>n;++n){t[n]=new Array(r);for(var e=0;r>e;++e)t[n][e]=["m",e,"[",r-n-1,"]"].join("")}return t}function o(r){return 1&r?"-":""}function s(r){if(1===r.length)return r[0];if(2===r.length)return["sum(",r[0],",",r[1],")"].join("");var t=r.length>>1;return["sum(",s(r.slice(0,t)),",",s(r.slice(t)),")"].join("")}function a(r){if(2===r.length)return[["sum(prod(",r[0][0],",",r[1][1],"),prod(-",r[0][1],",",r[1][0],"))"].join("")];for(var t=[],n=0;n<r.length;++n)t.push(["scale(",s(a(e(r,n))),",",o(n),r[0][n],")"].join(""));return t}function u(r){for(var t=[],n=[],o=i(r),u=[],h=0;r>h;++h)0===(1&h)?t.push.apply(t,a(e(o,h))):n.push.apply(n,a(e(o,h))),u.push("m"+h);var f=s(t),v=s(n),d="orientation"+r+"Exact",y=["function ",d,"(",u.join(),"){var p=",f,",n=",v,",d=sub(p,n);return d[d.length-1];};return ",d].join(""),m=new Function("sum","prod","scale","sub",y);return m(c,l,p,g)}function h(r){var t=_[r.length];return t||(t=_[r.length]=u(r.length)),t.apply(void 0,r)}function f(){for(;_.length<=v;)_.push(u(_.length));for(var r=[],n=["slow"],e=0;v>=e;++e)r.push("a"+e),n.push("o"+e);for(var i=["function getOrientation(",r.join(),"){switch(arguments.length){case 0:case 1:return 0;"],e=2;v>=e;++e)i.push("case ",e,":return o",e,"(",r.slice(0,e).join(),");");i.push("}var s=new Array(arguments.length);for(var i=0;i<arguments.length;++i){s[i]=arguments[i]};return slow(s);}return getOrientation"),n.push(i.join(""));var o=Function.apply(void 0,n);t.exports=o.apply(void 0,[h].concat(_));for(var e=0;v>=e;++e)t.exports[e]=_[e]}var l=r("two-product"),c=r("robust-sum"),p=r("robust-scale"),g=r("robust-subtract"),v=5,d=1.1102230246251565e-16,y=(3+16*d)*d,m=(7+56*d)*d,b=u(3),w=u(4),_=[function(){return 0},function(){return 0},function(r,t){return t[0]-r[0]},function(r,t,n){var e,i=(r[1]-n[1])*(t[0]-n[0]),o=(r[0]-n[0])*(t[1]-n[1]),s=i-o;if(i>0){if(0>=o)return s;e=i+o}else{if(!(0>i))return s;if(o>=0)return s;e=-(i+o)}var a=y*e;return s>=a||-a>=s?s:b(r,t,n)},function(r,t,n,e){var i=r[0]-e[0],o=t[0]-e[0],s=n[0]-e[0],a=r[1]-e[1],u=t[1]-e[1],h=n[1]-e[1],f=r[2]-e[2],l=t[2]-e[2],c=n[2]-e[2],p=o*h,g=s*u,v=s*a,d=i*h,y=i*u,b=o*a,_=f*(p-g)+l*(v-d)+c*(y-b),A=(Math.abs(p)+Math.abs(g))*Math.abs(f)+(Math.abs(v)+Math.abs(d))*Math.abs(l)+(Math.abs(y)+Math.abs(b))*Math.abs(c),x=m*A;return _>x||-_>x?_:w(r,t,n,e)}];f()},{"robust-scale":49,"robust-subtract":50,"robust-sum":51,"two-product":52}],54:[function(r,t,n){"use strict";function e(r){var t=w(r),n=b(m(t),r);return 0>n?[t,A(t,1/0)]:n>0?[A(t,-(1/0)),t]:[t,t]}function i(r,t){for(var n=new Array(t.length),e=0;e<t.length;++e){var i=t[e],o=r[i[0]],s=r[i[1]];n[e]=[Math.min(o[0],s[0]),Math.min(o[1],s[1]),Math.max(o[0],s[0]),Math.max(o[1],s[1])]}return n}function o(r){for(var t=new Array(r.length),n=0;n<r.length;++n){var e=r[n];t[n]=[e[0],e[1],e[0],e[1]]}return t}function s(r,t,n){var e=[];return d(n,function(n,i){var o=t[n],s=t[i];if(o[0]!==s[0]&&o[0]!==s[1]&&o[1]!==s[0]&&o[1]!==s[1]){var a=r[o[0]],u=r[o[1]],h=r[s[0]],f=r[s[1]];y(a,u,h,f)&&e.push([n,i])}}),e}function a(r,t,n,e){var i=[];return d(n,e,function(n,e){var o=t[n];if(o[0]!==e&&o[1]!==e){var s=r[e],a=r[o[0]],u=r[o[1]];y(a,u,s,s)&&i.push([n,e])}}),i}function u(r,t,n,e,i){function o(t){if(t>=r.length)return s[t-r.length];var n=r[t];return[m(n[0]),m(n[1])]}for(var s=[],a=0;a<n.length;++a){var u=n[a],h=u[0],f=u[1],l=t[h],c=t[f],p=x(_(r[l[0]]),_(r[l[1]]),_(r[c[0]]),_(r[c[1]]));if(p){var g=s.length+r.length;s.push(p),e.push([h,g],[f,g])}}e.sort(function(r,t){if(r[0]!==t[0])return r[0]-t[0];var n=o(r[1]),e=o(t[1]);return b(n[0],e[0])||b(n[1],e[1])});for(var a=e.length-1;a>=0;--a){var v=e[a],h=v[0],d=t[h],y=d[0],w=d[1],A=r[y],E=r[w];if((A[0]-E[0]||A[1]-E[1])<0){var j=y;y=w,w=j}d[0]=y;var k,I=d[1]=v[1];for(i&&(k=d[2]);a>0&&e[a-1][0]===h;){var v=e[--a],M=v[1];i?t.push([I,M,k]):t.push([I,M]),I=M}i?t.push([I,w,k]):t.push([I,w])}return s}function h(r,t,n){for(var i=r.length+t.length,o=new v(i),s=n,a=0;a<t.length;++a){var u=t[a],h=e(u[0]),f=e(u[1]);s.push([h[0],f[0],h[1],f[1]]),r.push([w(u[0]),w(u[1])])}d(s,function(r,t){o.link(r,t)});for(var l=0,c=!0,p=new Array(i),a=0;i>a;++a){var g=o.find(a);g===a?(p[a]=l,r[l++]=r[a]):(c=!1,p[a]=-1)}if(r.length=l,c)return null;for(var a=0;i>a;++a)p[a]<0&&(p[a]=p[o.find(a)]);return p}function f(r,t){return r[0]-t[0]||r[1]-t[1]}function l(r,t){var n=r[0]-t[0]||r[1]-t[1];return n?n:r[2]<t[2]?-1:r[2]>t[2]?1:0}function c(r,t,n){if(0!==r.length){if(t)for(var e=0;e<r.length;++e){var i=r[e],o=t[i[0]],s=t[i[1]];i[0]=Math.min(o,s),i[1]=Math.max(o,s)}else for(var e=0;e<r.length;++e){var i=r[e],o=i[0],s=i[1];i[0]=Math.min(o,s),i[1]=Math.max(o,s)}n?r.sort(l):r.sort(f);for(var a=1,e=1;e<r.length;++e){var u=r[e-1],h=r[e];(h[0]!==u[0]||h[1]!==u[1]||n&&h[2]!==u[2])&&(r[a++]=h)}r.length=a}}function p(r,t,n){var e=i(r,t),f=s(r,t,e),l=o(r),p=a(r,t,e,l),g=u(r,t,f,p,n),v=h(r,g,l);return c(t,v,n),v?!0:f.length>0||p.length>0}function g(r,t,n){var e,i=!1;if(n){e=t;for(var o=new Array(t.length),s=0;s<t.length;++s){var a=t[s];o[s]=[a[0],a[1],n[s]]}t=o}for(;p(r,t,!!n);)i=!0;if(n&&i){e.length=0,n.length=0;for(var s=0;s<t.length;++s){var a=t[s];e.push([a[0],a[1]]),n.push(a[2])}}return i}t.exports=g;var v=r("union-find"),d=r("box-intersect"),y=(r("compare-cell"),r("robust-segment-intersect")),m=r("big-rat"),b=r("big-rat/cmp"),w=r("big-rat/to-float"),_=r("rat-vec"),A=r("nextafter"),x=r("./lib/rat-seg-intersect")},{"./lib/rat-seg-intersect":55,"big-rat":59,"big-rat/cmp":57,"big-rat/to-float":74,"box-intersect":75,"compare-cell":85,nextafter:86,"rat-vec":89,"robust-segment-intersect":98,"union-find":99}],55:[function(r,t,n){"use strict";function e(r,t){return a(o(r[0],t[1]),o(r[1],t[0]))}function i(r,t,n,i){var o=h(t,r),a=h(i,n),c=e(o,a);if(0===u(c))return null;var p=h(r,n),g=e(a,p),v=s(g,c);return f(r,l(o,v))}t.exports=i;var o=r("big-rat/mul"),s=r("big-rat/div"),a=r("big-rat/sub"),u=r("big-rat/sign"),h=r("rat-vec/sub"),f=r("rat-vec/add"),l=r("rat-vec/muls");r("big-rat/to-float")},{"big-rat/div":58,"big-rat/mul":68,"big-rat/sign":72,"big-rat/sub":73,"big-rat/to-float":74,"rat-vec/add":88,"rat-vec/muls":90,"rat-vec/sub":91}],56:[function(r,t,n){"use strict";function e(r,t){return i(r[0].mul(t[1]).add(t[0].mul(r[1])),r[1].mul(t[1]))}var i=r("./lib/rationalize");t.exports=e},{"./lib/rationalize":66}],57:[function(r,t,n){"use strict";function e(r,t){return r[0].mul(t[1]).cmp(t[0].mul(r[1]))}t.exports=e},{}],58:[function(r,t,n){"use strict";function e(r,t){return i(r[0].mul(t[1]),r[1].mul(t[0]))}var i=r("./lib/rationalize");t.exports=e},{"./lib/rationalize":66}],59:[function(r,t,n){"use strict";function e(r,t){if(i(r))return t?h(r,e(t)):[r[0].clone(),r[1].clone()];var n,f,l=0;if(o(r))n=r.clone();else if("string"==typeof r)n=a(r);else{if(0===r)return[s(0),s(1)];if(r===Math.floor(r))n=s(r);else{for(;r!==Math.floor(r);)r*=Math.pow(2,256),l-=256;n=s(r)}}if(i(t))n.mul(t[1]),f=t[0].clone();else if(o(t))f=t.clone();else if("string"==typeof t)f=a(t);else if(t)if(t===Math.floor(t))f=s(t);else{for(;t!==Math.floor(t);)t*=Math.pow(2,256),l+=256;f=s(t)}else f=s(1);return l>0?n=n.shln(l):0>l&&(f=f.shln(-l)),u(n,f)}var i=r("./is-rat"),o=r("./lib/is-bn"),s=r("./lib/num-to-bn"),a=r("./lib/str-to-bn"),u=r("./lib/rationalize"),h=r("./div");t.exports=e},{"./div":58,"./is-rat":60,"./lib/is-bn":64,"./lib/num-to-bn":65,"./lib/rationalize":66,"./lib/str-to-bn":67}],60:[function(r,t,n){"use strict";function e(r){return Array.isArray(r)&&2===r.length&&i(r[0])&&i(r[1])}var i=r("./lib/is-bn");t.exports=e},{"./lib/is-bn":64}],61:[function(r,t,n){"use strict";function e(r){return r.cmp(new i(0))}var i=r("bn.js");t.exports=e},{"bn.js":70}],62:[function(r,t,n){"use strict";function e(r){var t=r.length,n=r.words,e=0;if(1===t)e=n[0];else if(2===t)e=n[0]+67108864*n[1];else for(var e=0,i=0;t>i;i++){var o=n[i];e+=o*Math.pow(67108864,i)}return r.sign?-e:e}t.exports=e},{}],63:[function(r,t,n){"use strict";function e(r){var t=o(i.lo(r));if(32>t)return t;var n=o(i.hi(r));return n>20?52:n+32}var i=r("double-bits"),o=r("bit-twiddle").countTrailingZeros;t.exports=e},{"bit-twiddle":69,"double-bits":71}],64:[function(r,t,n){"use strict";function e(r){return r&&"object"==typeof r&&Boolean(r.words)}r("bn.js");t.exports=e},{"bn.js":70}],65:[function(r,t,n){"use strict";function e(r){var t=o.exponent(r);return 52>t?new i(r):new i(r*Math.pow(2,52-t)).shln(t-52)}var i=r("bn.js"),o=r("double-bits");t.exports=e},{"bn.js":70,"double-bits":71}],66:[function(r,t,n){"use strict";function e(r,t){var n=o(r),e=o(t);if(0===n)return[i(0),i(1)];if(0===e)return[i(0),i(0)];0>e&&(r=r.neg(),t=t.neg());var s=r.gcd(t);return s.cmpn(1)?[r.div(s),t.div(s)]:[r,t]}var i=r("./num-to-bn"),o=r("./bn-sign");t.exports=e},{"./bn-sign":61,"./num-to-bn":65}],67:[function(r,t,n){"use strict";function e(r){return new i(r)}var i=r("bn.js");t.exports=e},{"bn.js":70}],68:[function(r,t,n){"use strict";function e(r,t){return i(r[0].mul(t[0]),r[1].mul(t[1]))}var i=r("./lib/rationalize");t.exports=e},{"./lib/rationalize":66}],69:[function(r,t,n){arguments[4][15][0].apply(n,arguments)},{dup:15}],70:[function(r,t,n){!function(r,t){"use strict";function n(r,t){if(!r)throw new Error(t||"Assertion failed")}function e(r,t){r.super_=t;var n=function(){};n.prototype=t.prototype,r.prototype=new n,r.prototype.constructor=r}function i(r,t,n){return null!==r&&"object"==typeof r&&Array.isArray(r.words)?r:(this.sign=!1,this.words=null,this.length=0,this.red=null,("le"===t||"be"===t)&&(n=t,t=10),void(null!==r&&this._init(r||0,t||10,n||"be")))}function o(r,t,n){for(var e=0,i=Math.min(r.length,n),o=t;i>o;o++){var s=r.charCodeAt(o)-48;e<<=4,e|=s>=49&&54>=s?s-49+10:s>=17&&22>=s?s-17+10:15&s}return e}function s(r,t,n,e){for(var i=0,o=Math.min(r.length,n),s=t;o>s;s++){var a=r.charCodeAt(s)-48;i*=e,i+=a>=49?a-49+10:a>=17?a-17+10:a}return i}function a(r,t){this.name=r,this.p=new i(t,16),this.n=this.p.bitLength(),this.k=new i(1).ishln(this.n).isub(this.p),this.tmp=this._tmp()}function u(){a.call(this,"k256","ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f")}function h(){a.call(this,"p224","ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001")}function f(){a.call(this,"p192","ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff")}function l(){a.call(this,"25519","7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed")}function c(r){if("string"==typeof r){var t=i._prime(r);this.m=t.p,this.prime=t}else this.m=r,this.prime=null}function p(r){c.call(this,r),this.shift=this.m.bitLength(),this.shift%26!==0&&(this.shift+=26-this.shift%26),this.r=new i(1).ishln(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.sign=!0,this.minv=this.minv.mod(this.r)}"object"==typeof r?r.exports=i:t.BN=i,i.BN=i,i.wordSize=26,i.prototype._init=function(r,t,e){if("number"==typeof r)return this._initNumber(r,t,e);if("object"==typeof r)return this._initArray(r,t,e);"hex"===t&&(t=16),n(t===(0|t)&&t>=2&&36>=t),r=r.toString().replace(/\s+/g,"");var i=0;"-"===r[0]&&i++,16===t?this._parseHex(r,i):this._parseBase(r,t,i),"-"===r[0]&&(this.sign=!0),this.strip(),"le"===e&&this._initArray(this.toArray(),t,e)},i.prototype._initNumber=function(r,t,e){0>r&&(this.sign=!0,r=-r),67108864>r?(this.words=[67108863&r],this.length=1):4503599627370496>r?(this.words=[67108863&r,r/67108864&67108863],this.length=2):(n(9007199254740992>r),this.words=[67108863&r,r/67108864&67108863,1],this.length=3),"le"===e&&this._initArray(this.toArray(),t,e)},i.prototype._initArray=function(r,t,e){if(n("number"==typeof r.length),r.length<=0)return this.words=[0],this.length=1,this;this.length=Math.ceil(r.length/3),this.words=new Array(this.length);for(var i=0;i<this.length;i++)this.words[i]=0;var o=0;if("be"===e)for(var i=r.length-1,s=0;i>=0;i-=3){var a=r[i]|r[i-1]<<8|r[i-2]<<16;this.words[s]|=a<<o&67108863,this.words[s+1]=a>>>26-o&67108863,o+=24,o>=26&&(o-=26,s++)}else if("le"===e)for(var i=0,s=0;i<r.length;i+=3){var a=r[i]|r[i+1]<<8|r[i+2]<<16;this.words[s]|=a<<o&67108863,this.words[s+1]=a>>>26-o&67108863,o+=24,o>=26&&(o-=26,s++)}return this.strip()},i.prototype._parseHex=function(r,t){this.length=Math.ceil((r.length-t)/6),this.words=new Array(this.length);for(var n=0;n<this.length;n++)this.words[n]=0;for(var e=0,n=r.length-6,i=0;n>=t;n-=6){var s=o(r,n,n+6);this.words[i]|=s<<e&67108863,this.words[i+1]|=s>>>26-e&4194303,e+=24,e>=26&&(e-=26,i++)}if(n+6!==t){var s=o(r,t,n+6);this.words[i]|=s<<e&67108863,this.words[i+1]|=s>>>26-e&4194303}this.strip()},i.prototype._parseBase=function(r,t,n){ | |
this.words=[0],this.length=1;for(var e=0,i=1;67108863>=i;i*=t)e++;e--,i=i/t|0;for(var o=r.length-n,a=o%e,u=Math.min(o,o-a)+n,h=0,f=n;u>f;f+=e)h=s(r,f,f+e,t),this.imuln(i),this.words[0]+h<67108864?this.words[0]+=h:this._iaddn(h);if(0!==a){for(var l=1,h=s(r,f,r.length,t),f=0;a>f;f++)l*=t;this.imuln(l),this.words[0]+h<67108864?this.words[0]+=h:this._iaddn(h)}},i.prototype.copy=function(r){r.words=new Array(this.length);for(var t=0;t<this.length;t++)r.words[t]=this.words[t];r.length=this.length,r.sign=this.sign,r.red=this.red},i.prototype.clone=function(){var r=new i(null);return this.copy(r),r},i.prototype.strip=function(){for(;this.length>1&&0===this.words[this.length-1];)this.length--;return this._normSign()},i.prototype._normSign=function(){return 1===this.length&&0===this.words[0]&&(this.sign=!1),this},i.prototype.inspect=function(){return(this.red?"<BN-R: ":"<BN: ")+this.toString(16)+">"};var g=["","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"],v=[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],d=[0,0,33554432,43046721,16777216,48828125,60466176,40353607,16777216,43046721,1e7,19487171,35831808,62748517,7529536,11390625,16777216,24137569,34012224,47045881,64e6,4084101,5153632,6436343,7962624,9765625,11881376,14348907,17210368,20511149,243e5,28629151,33554432,39135393,45435424,52521875,60466176];i.prototype.toString=function(r,t){if(r=r||10,16===r||"hex"===r){for(var e="",i=0,t=0|t||1,o=0,s=0;s<this.length;s++){var a=this.words[s],u=(16777215&(a<<i|o)).toString(16);o=a>>>24-i&16777215,e=0!==o||s!==this.length-1?g[6-u.length]+u+e:u+e,i+=2,i>=26&&(i-=26,s--)}for(0!==o&&(e=o.toString(16)+e);e.length%t!==0;)e="0"+e;return this.sign&&(e="-"+e),e}if(r===(0|r)&&r>=2&&36>=r){var h=v[r],f=d[r],e="",l=this.clone();for(l.sign=!1;0!==l.cmpn(0);){var c=l.modn(f).toString(r);l=l.idivn(f),e=0!==l.cmpn(0)?g[h-c.length]+c+e:c+e}return 0===this.cmpn(0)&&(e="0"+e),this.sign&&(e="-"+e),e}n(!1,"Base should be between 2 and 36")},i.prototype.toJSON=function(){return this.toString(16)},i.prototype.toArray=function(r){this.strip();var t=new Array(this.byteLength());t[0]=0;var n=this.clone();if("le"!==r)for(var e=0;0!==n.cmpn(0);e++){var i=n.andln(255);n.ishrn(8),t[t.length-e-1]=i}else for(var e=0;0!==n.cmpn(0);e++){var i=n.andln(255);n.ishrn(8),t[e]=i}return t},Math.clz32?i.prototype._countBits=function(r){return 32-Math.clz32(r)}:i.prototype._countBits=function(r){var t=r,n=0;return t>=4096&&(n+=13,t>>>=13),t>=64&&(n+=7,t>>>=7),t>=8&&(n+=4,t>>>=4),t>=2&&(n+=2,t>>>=2),n+t},i.prototype._zeroBits=function(r){if(0===r)return 26;var t=r,n=0;return 0===(8191&t)&&(n+=13,t>>>=13),0===(127&t)&&(n+=7,t>>>=7),0===(15&t)&&(n+=4,t>>>=4),0===(3&t)&&(n+=2,t>>>=2),0===(1&t)&&n++,n},i.prototype.bitLength=function(){var r=0,t=this.words[this.length-1],r=this._countBits(t);return 26*(this.length-1)+r},i.prototype.zeroBits=function(){if(0===this.cmpn(0))return 0;for(var r=0,t=0;t<this.length;t++){var n=this._zeroBits(this.words[t]);if(r+=n,26!==n)break}return r},i.prototype.byteLength=function(){return Math.ceil(this.bitLength()/8)},i.prototype.neg=function(){if(0===this.cmpn(0))return this.clone();var r=this.clone();return r.sign=!this.sign,r},i.prototype.ior=function(r){for(this.sign=this.sign||r.sign;this.length<r.length;)this.words[this.length++]=0;for(var t=0;t<r.length;t++)this.words[t]=this.words[t]|r.words[t];return this.strip()},i.prototype.or=function(r){return this.length>r.length?this.clone().ior(r):r.clone().ior(this)},i.prototype.iand=function(r){this.sign=this.sign&&r.sign;var t;t=this.length>r.length?r:this;for(var n=0;n<t.length;n++)this.words[n]=this.words[n]&r.words[n];return this.length=t.length,this.strip()},i.prototype.and=function(r){return this.length>r.length?this.clone().iand(r):r.clone().iand(this)},i.prototype.ixor=function(r){this.sign=this.sign||r.sign;var t,n;this.length>r.length?(t=this,n=r):(t=r,n=this);for(var e=0;e<n.length;e++)this.words[e]=t.words[e]^n.words[e];if(this!==t)for(;e<t.length;e++)this.words[e]=t.words[e];return this.length=t.length,this.strip()},i.prototype.xor=function(r){return this.length>r.length?this.clone().ixor(r):r.clone().ixor(this)},i.prototype.setn=function(r,t){n("number"==typeof r&&r>=0);for(var e=r/26|0,i=r%26;this.length<=e;)this.words[this.length++]=0;return t?this.words[e]=this.words[e]|1<<i:this.words[e]=this.words[e]&~(1<<i),this.strip()},i.prototype.iadd=function(r){if(this.sign&&!r.sign){this.sign=!1;var t=this.isub(r);return this.sign=!this.sign,this._normSign()}if(!this.sign&&r.sign){r.sign=!1;var t=this.isub(r);return r.sign=!0,t._normSign()}var n,e;this.length>r.length?(n=this,e=r):(n=r,e=this);for(var i=0,o=0;o<e.length;o++){var t=n.words[o]+e.words[o]+i;this.words[o]=67108863&t,i=t>>>26}for(;0!==i&&o<n.length;o++){var t=n.words[o]+i;this.words[o]=67108863&t,i=t>>>26}if(this.length=n.length,0!==i)this.words[this.length]=i,this.length++;else if(n!==this)for(;o<n.length;o++)this.words[o]=n.words[o];return this},i.prototype.add=function(r){if(r.sign&&!this.sign){r.sign=!1;var t=this.sub(r);return r.sign=!0,t}if(!r.sign&&this.sign){this.sign=!1;var t=r.sub(this);return this.sign=!0,t}return this.length>r.length?this.clone().iadd(r):r.clone().iadd(this)},i.prototype.isub=function(r){if(r.sign){r.sign=!1;var t=this.iadd(r);return r.sign=!0,t._normSign()}if(this.sign)return this.sign=!1,this.iadd(r),this.sign=!0,this._normSign();var n=this.cmp(r);if(0===n)return this.sign=!1,this.length=1,this.words[0]=0,this;var e,i;n>0?(e=this,i=r):(e=r,i=this);for(var o=0,s=0;s<i.length;s++){var t=e.words[s]-i.words[s]+o;o=t>>26,this.words[s]=67108863&t}for(;0!==o&&s<e.length;s++){var t=e.words[s]+o;o=t>>26,this.words[s]=67108863&t}if(0===o&&s<e.length&&e!==this)for(;s<e.length;s++)this.words[s]=e.words[s];return this.length=Math.max(this.length,s),e!==this&&(this.sign=!0),this.strip()},i.prototype.sub=function(r){return this.clone().isub(r)},i.prototype._smallMulTo=function(r,t){t.sign=r.sign!==this.sign,t.length=this.length+r.length;for(var n=0,e=0;e<t.length-1;e++){for(var i=n>>>26,o=67108863&n,s=Math.min(e,r.length-1),a=Math.max(0,e-this.length+1);s>=a;a++){var u=e-a,h=0|this.words[u],f=0|r.words[a],l=h*f,c=67108863&l;i=i+(l/67108864|0)|0,c=c+o|0,o=67108863&c,i=i+(c>>>26)|0}t.words[e]=o,n=i}return 0!==n?t.words[e]=n:t.length--,t.strip()},i.prototype._bigMulTo=function(r,t){t.sign=r.sign!==this.sign,t.length=this.length+r.length;for(var n=0,e=0,i=0;i<t.length-1;i++){var o=e;e=0;for(var s=67108863&n,a=Math.min(i,r.length-1),u=Math.max(0,i-this.length+1);a>=u;u++){var h=i-u,f=0|this.words[h],l=0|r.words[u],c=f*l,p=67108863&c;o=o+(c/67108864|0)|0,p=p+s|0,s=67108863&p,o=o+(p>>>26)|0,e+=o>>>26,o&=67108863}t.words[i]=s,n=o,o=e}return 0!==n?t.words[i]=n:t.length--,t.strip()},i.prototype.mulTo=function(r,t){var n;return n=this.length+r.length<63?this._smallMulTo(r,t):this._bigMulTo(r,t)},i.prototype.mul=function(r){var t=new i(null);return t.words=new Array(this.length+r.length),this.mulTo(r,t)},i.prototype.imul=function(r){if(0===this.cmpn(0)||0===r.cmpn(0))return this.words[0]=0,this.length=1,this;var t=this.length,n=r.length;this.sign=r.sign!==this.sign,this.length=this.length+r.length,this.words[this.length-1]=0;for(var e=this.length-2;e>=0;e--){for(var i=0,o=0,s=Math.min(e,n-1),a=Math.max(0,e-t+1);s>=a;a++){var u=e-a,h=this.words[u],f=r.words[a],l=h*f,c=67108863&l;i+=l/67108864|0,c+=o,o=67108863&c,i+=c>>>26}this.words[e]=o,this.words[e+1]+=i,i=0}for(var i=0,u=1;u<this.length;u++){var p=this.words[u]+i;this.words[u]=67108863&p,i=p>>>26}return this.strip()},i.prototype.imuln=function(r){n("number"==typeof r);for(var t=0,e=0;e<this.length;e++){var i=this.words[e]*r,o=(67108863&i)+(67108863&t);t>>=26,t+=i/67108864|0,t+=o>>>26,this.words[e]=67108863&o}return 0!==t&&(this.words[e]=t,this.length++),this},i.prototype.muln=function(r){return this.clone().imuln(r)},i.prototype.sqr=function(){return this.mul(this)},i.prototype.isqr=function(){return this.mul(this)},i.prototype.ishln=function(r){n("number"==typeof r&&r>=0);var t=r%26,e=(r-t)/26,i=67108863>>>26-t<<26-t;if(0!==t){for(var o=0,s=0;s<this.length;s++){var a=this.words[s]&i,u=this.words[s]-a<<t;this.words[s]=u|o,o=a>>>26-t}o&&(this.words[s]=o,this.length++)}if(0!==e){for(var s=this.length-1;s>=0;s--)this.words[s+e]=this.words[s];for(var s=0;e>s;s++)this.words[s]=0;this.length+=e}return this.strip()},i.prototype.ishrn=function(r,t,e){n("number"==typeof r&&r>=0);var i;i=t?(t-t%26)/26:0;var o=r%26,s=Math.min((r-o)/26,this.length),a=67108863^67108863>>>o<<o,u=e;if(i-=s,i=Math.max(0,i),u){for(var h=0;s>h;h++)u.words[h]=this.words[h];u.length=s}if(0===s);else if(this.length>s){this.length-=s;for(var h=0;h<this.length;h++)this.words[h]=this.words[h+s]}else this.words[0]=0,this.length=1;for(var f=0,h=this.length-1;h>=0&&(0!==f||h>=i);h--){var l=this.words[h];this.words[h]=f<<26-o|l>>>o,f=l&a}return u&&0!==f&&(u.words[u.length++]=f),0===this.length&&(this.words[0]=0,this.length=1),this.strip(),this},i.prototype.shln=function(r){return this.clone().ishln(r)},i.prototype.shrn=function(r){return this.clone().ishrn(r)},i.prototype.testn=function(r){n("number"==typeof r&&r>=0);var t=r%26,e=(r-t)/26,i=1<<t;if(this.length<=e)return!1;var o=this.words[e];return!!(o&i)},i.prototype.imaskn=function(r){n("number"==typeof r&&r>=0);var t=r%26,e=(r-t)/26;if(n(!this.sign,"imaskn works only with positive numbers"),0!==t&&e++,this.length=Math.min(e,this.length),0!==t){var i=67108863^67108863>>>t<<t;this.words[this.length-1]&=i}return this.strip()},i.prototype.maskn=function(r){return this.clone().imaskn(r)},i.prototype.iaddn=function(r){return n("number"==typeof r),0>r?this.isubn(-r):this.sign?1===this.length&&this.words[0]<r?(this.words[0]=r-this.words[0],this.sign=!1,this):(this.sign=!1,this.isubn(r),this.sign=!0,this):this._iaddn(r)},i.prototype._iaddn=function(r){this.words[0]+=r;for(var t=0;t<this.length&&this.words[t]>=67108864;t++)this.words[t]-=67108864,t===this.length-1?this.words[t+1]=1:this.words[t+1]++;return this.length=Math.max(this.length,t+1),this},i.prototype.isubn=function(r){if(n("number"==typeof r),0>r)return this.iaddn(-r);if(this.sign)return this.sign=!1,this.iaddn(r),this.sign=!0,this;this.words[0]-=r;for(var t=0;t<this.length&&this.words[t]<0;t++)this.words[t]+=67108864,this.words[t+1]-=1;return this.strip()},i.prototype.addn=function(r){return this.clone().iaddn(r)},i.prototype.subn=function(r){return this.clone().isubn(r)},i.prototype.iabs=function(){return this.sign=!1,this},i.prototype.abs=function(){return this.clone().iabs()},i.prototype._ishlnsubmul=function(r,t,e){var i,o=r.length+e;if(this.words.length<o){for(var s=new Array(o),i=0;i<this.length;i++)s[i]=this.words[i];this.words=s}else i=this.length;for(this.length=Math.max(this.length,o);i<this.length;i++)this.words[i]=0;for(var a=0,i=0;i<r.length;i++){var u=this.words[i+e]+a,h=r.words[i]*t;u-=67108863&h,a=(u>>26)-(h/67108864|0),this.words[i+e]=67108863&u}for(;i<this.length-e;i++){var u=this.words[i+e]+a;a=u>>26,this.words[i+e]=67108863&u}if(0===a)return this.strip();n(-1===a),a=0;for(var i=0;i<this.length;i++){var u=-this.words[i]+a;a=u>>26,this.words[i]=67108863&u}return this.sign=!0,this.strip()},i.prototype._wordDiv=function(r,t){var n=this.length-r.length,e=this.clone(),o=r,s=o.words[o.length-1],a=this._countBits(s);n=26-a,0!==n&&(o=o.shln(n),e.ishln(n),s=o.words[o.length-1]);var u,h=e.length-o.length;if("mod"!==t){u=new i(null),u.length=h+1,u.words=new Array(u.length);for(var f=0;f<u.length;f++)u.words[f]=0}var l=e.clone()._ishlnsubmul(o,1,h);l.sign||(e=l,u&&(u.words[h]=1));for(var c=h-1;c>=0;c--){var p=67108864*e.words[o.length+c]+e.words[o.length+c-1];for(p=Math.min(p/s|0,67108863),e._ishlnsubmul(o,p,c);e.sign;)p--,e.sign=!1,e._ishlnsubmul(o,1,c),0!==e.cmpn(0)&&(e.sign=!e.sign);u&&(u.words[c]=p)}return u&&u.strip(),e.strip(),"div"!==t&&0!==n&&e.ishrn(n),{div:u?u:null,mod:e}},i.prototype.divmod=function(r,t){if(n(0!==r.cmpn(0)),this.sign&&!r.sign){var e,o,s=this.neg().divmod(r,t);return"mod"!==t&&(e=s.div.neg()),"div"!==t&&(o=0===s.mod.cmpn(0)?s.mod:r.sub(s.mod)),{div:e,mod:o}}if(!this.sign&&r.sign){var e,s=this.divmod(r.neg(),t);return"mod"!==t&&(e=s.div.neg()),{div:e,mod:s.mod}}return this.sign&&r.sign?this.neg().divmod(r.neg(),t):r.length>this.length||this.cmp(r)<0?{div:new i(0),mod:this}:1===r.length?"div"===t?{div:this.divn(r.words[0]),mod:null}:"mod"===t?{div:null,mod:new i(this.modn(r.words[0]))}:{div:this.divn(r.words[0]),mod:new i(this.modn(r.words[0]))}:this._wordDiv(r,t)},i.prototype.div=function(r){return this.divmod(r,"div").div},i.prototype.mod=function(r){return this.divmod(r,"mod").mod},i.prototype.divRound=function(r){var t=this.divmod(r);if(0===t.mod.cmpn(0))return t.div;var n=t.div.sign?t.mod.isub(r):t.mod,e=r.shrn(1),i=r.andln(1),o=n.cmp(e);return 0>o||1===i&&0===o?t.div:t.div.sign?t.div.isubn(1):t.div.iaddn(1)},i.prototype.modn=function(r){n(67108863>=r);for(var t=(1<<26)%r,e=0,i=this.length-1;i>=0;i--)e=(t*e+this.words[i])%r;return e},i.prototype.idivn=function(r){n(67108863>=r);for(var t=0,e=this.length-1;e>=0;e--){var i=this.words[e]+67108864*t;this.words[e]=i/r|0,t=i%r}return this.strip()},i.prototype.divn=function(r){return this.clone().idivn(r)},i.prototype.egcd=function(r){n(!r.sign),n(0!==r.cmpn(0));var t=this,e=r.clone();t=t.sign?t.mod(r):t.clone();for(var o=new i(1),s=new i(0),a=new i(0),u=new i(1),h=0;t.isEven()&&e.isEven();)t.ishrn(1),e.ishrn(1),++h;for(var f=e.clone(),l=t.clone();0!==t.cmpn(0);){for(;t.isEven();)t.ishrn(1),o.isEven()&&s.isEven()?(o.ishrn(1),s.ishrn(1)):(o.iadd(f).ishrn(1),s.isub(l).ishrn(1));for(;e.isEven();)e.ishrn(1),a.isEven()&&u.isEven()?(a.ishrn(1),u.ishrn(1)):(a.iadd(f).ishrn(1),u.isub(l).ishrn(1));t.cmp(e)>=0?(t.isub(e),o.isub(a),s.isub(u)):(e.isub(t),a.isub(o),u.isub(s))}return{a:a,b:u,gcd:e.ishln(h)}},i.prototype._invmp=function(r){n(!r.sign),n(0!==r.cmpn(0));var t=this,e=r.clone();t=t.sign?t.mod(r):t.clone();for(var o=new i(1),s=new i(0),a=e.clone();t.cmpn(1)>0&&e.cmpn(1)>0;){for(;t.isEven();)t.ishrn(1),o.isEven()?o.ishrn(1):o.iadd(a).ishrn(1);for(;e.isEven();)e.ishrn(1),s.isEven()?s.ishrn(1):s.iadd(a).ishrn(1);t.cmp(e)>=0?(t.isub(e),o.isub(s)):(e.isub(t),s.isub(o))}return 0===t.cmpn(1)?o:s},i.prototype.gcd=function(r){if(0===this.cmpn(0))return r.clone();if(0===r.cmpn(0))return this.clone();var t=this.clone(),n=r.clone();t.sign=!1,n.sign=!1;for(var e=0;t.isEven()&&n.isEven();e++)t.ishrn(1),n.ishrn(1);for(;;){for(;t.isEven();)t.ishrn(1);for(;n.isEven();)n.ishrn(1);var i=t.cmp(n);if(0>i){var o=t;t=n,n=o}else if(0===i||0===n.cmpn(1))break;t.isub(n)}return n.ishln(e)},i.prototype.invm=function(r){return this.egcd(r).a.mod(r)},i.prototype.isEven=function(){return 0===(1&this.words[0])},i.prototype.isOdd=function(){return 1===(1&this.words[0])},i.prototype.andln=function(r){return this.words[0]&r},i.prototype.bincn=function(r){n("number"==typeof r);var t=r%26,e=(r-t)/26,i=1<<t;if(this.length<=e){for(var o=this.length;e+1>o;o++)this.words[o]=0;return this.words[e]|=i,this.length=e+1,this}for(var s=i,o=e;0!==s&&o<this.length;o++){var a=this.words[o];a+=s,s=a>>>26,a&=67108863,this.words[o]=a}return 0!==s&&(this.words[o]=s,this.length++),this},i.prototype.cmpn=function(r){var t=0>r;if(t&&(r=-r),this.sign&&!t)return-1;if(!this.sign&&t)return 1;r&=67108863,this.strip();var n;if(this.length>1)n=1;else{var e=this.words[0];n=e===r?0:r>e?-1:1}return this.sign&&(n=-n),n},i.prototype.cmp=function(r){if(this.sign&&!r.sign)return-1;if(!this.sign&&r.sign)return 1;var t=this.ucmp(r);return this.sign?-t:t},i.prototype.ucmp=function(r){if(this.length>r.length)return 1;if(this.length<r.length)return-1;for(var t=0,n=this.length-1;n>=0;n--){var e=this.words[n],i=r.words[n];if(e!==i){i>e?t=-1:e>i&&(t=1);break}}return t},i.red=function(r){return new c(r)},i.prototype.toRed=function(r){return n(!this.red,"Already a number in reduction context"),n(!this.sign,"red works only with positives"),r.convertTo(this)._forceRed(r)},i.prototype.fromRed=function(){return n(this.red,"fromRed works only with numbers in reduction context"),this.red.convertFrom(this)},i.prototype._forceRed=function(r){return this.red=r,this},i.prototype.forceRed=function(r){return n(!this.red,"Already a number in reduction context"),this._forceRed(r)},i.prototype.redAdd=function(r){return n(this.red,"redAdd works only with red numbers"),this.red.add(this,r)},i.prototype.redIAdd=function(r){return n(this.red,"redIAdd works only with red numbers"),this.red.iadd(this,r)},i.prototype.redSub=function(r){return n(this.red,"redSub works only with red numbers"),this.red.sub(this,r)},i.prototype.redISub=function(r){return n(this.red,"redISub works only with red numbers"),this.red.isub(this,r)},i.prototype.redShl=function(r){return n(this.red,"redShl works only with red numbers"),this.red.shl(this,r)},i.prototype.redMul=function(r){return n(this.red,"redMul works only with red numbers"),this.red._verify2(this,r),this.red.mul(this,r)},i.prototype.redIMul=function(r){return n(this.red,"redMul works only with red numbers"),this.red._verify2(this,r),this.red.imul(this,r)},i.prototype.redSqr=function(){return n(this.red,"redSqr works only with red numbers"),this.red._verify1(this),this.red.sqr(this)},i.prototype.redISqr=function(){return n(this.red,"redISqr works only with red numbers"),this.red._verify1(this),this.red.isqr(this)},i.prototype.redSqrt=function(){return n(this.red,"redSqrt works only with red numbers"),this.red._verify1(this),this.red.sqrt(this)},i.prototype.redInvm=function(){return n(this.red,"redInvm works only with red numbers"),this.red._verify1(this),this.red.invm(this)},i.prototype.redNeg=function(){return n(this.red,"redNeg works only with red numbers"),this.red._verify1(this),this.red.neg(this)},i.prototype.redPow=function(r){return n(this.red&&!r.red,"redPow(normalNum)"),this.red._verify1(this),this.red.pow(this,r)};var y={k256:null,p224:null,p192:null,p25519:null};a.prototype._tmp=function(){var r=new i(null);return r.words=new Array(Math.ceil(this.n/13)),r},a.prototype.ireduce=function(r){var t,n=r;do this.split(n,this.tmp),n=this.imulK(n),n=n.iadd(this.tmp),t=n.bitLength();while(t>this.n);var e=t<this.n?-1:n.ucmp(this.p);return 0===e?(n.words[0]=0,n.length=1):e>0?n.isub(this.p):n.strip(),n},a.prototype.split=function(r,t){r.ishrn(this.n,0,t)},a.prototype.imulK=function(r){return r.imul(this.k)},e(u,a),u.prototype.split=function(r,t){for(var n=4194303,e=Math.min(r.length,9),i=0;e>i;i++)t.words[i]=r.words[i];if(t.length=e,r.length<=9)return r.words[0]=0,void(r.length=1);var o=r.words[9];t.words[t.length++]=o&n;for(var i=10;i<r.length;i++){var s=r.words[i];r.words[i-10]=(s&n)<<4|o>>>22,o=s}r.words[i-10]=o>>>22,r.length-=9},u.prototype.imulK=function(r){r.words[r.length]=0,r.words[r.length+1]=0,r.length+=2;for(var t,n=0,e=0;e<r.length;e++){var i=r.words[e];t=64*i,n+=977*i,t+=n/67108864|0,n&=67108863,r.words[e]=n,n=t}return 0===r.words[r.length-1]&&(r.length--,0===r.words[r.length-1]&&r.length--),r},e(h,a),e(f,a),e(l,a),l.prototype.imulK=function(r){for(var t=0,n=0;n<r.length;n++){var e=19*r.words[n]+t,i=67108863&e;e>>>=26,r.words[n]=i,t=e}return 0!==t&&(r.words[r.length++]=t),r},i._prime=function m(r){if(y[r])return y[r];var m;if("k256"===r)m=new u;else if("p224"===r)m=new h;else if("p192"===r)m=new f;else{if("p25519"!==r)throw new Error("Unknown prime "+r);m=new l}return y[r]=m,m},c.prototype._verify1=function(r){n(!r.sign,"red works only with positives"),n(r.red,"red works only with red numbers")},c.prototype._verify2=function(r,t){n(!r.sign&&!t.sign,"red works only with positives"),n(r.red&&r.red===t.red,"red works only with red numbers")},c.prototype.imod=function(r){return this.prime?this.prime.ireduce(r)._forceRed(this):r.mod(this.m)._forceRed(this)},c.prototype.neg=function(r){var t=r.clone();return t.sign=!t.sign,t.iadd(this.m)._forceRed(this)},c.prototype.add=function(r,t){this._verify2(r,t);var n=r.add(t);return n.cmp(this.m)>=0&&n.isub(this.m),n._forceRed(this)},c.prototype.iadd=function(r,t){this._verify2(r,t);var n=r.iadd(t);return n.cmp(this.m)>=0&&n.isub(this.m),n},c.prototype.sub=function(r,t){this._verify2(r,t);var n=r.sub(t);return n.cmpn(0)<0&&n.iadd(this.m),n._forceRed(this)},c.prototype.isub=function(r,t){this._verify2(r,t);var n=r.isub(t);return n.cmpn(0)<0&&n.iadd(this.m),n},c.prototype.shl=function(r,t){return this._verify1(r),this.imod(r.shln(t))},c.prototype.imul=function(r,t){return this._verify2(r,t),this.imod(r.imul(t))},c.prototype.mul=function(r,t){return this._verify2(r,t),this.imod(r.mul(t))},c.prototype.isqr=function(r){return this.imul(r,r)},c.prototype.sqr=function(r){return this.mul(r,r)},c.prototype.sqrt=function(r){if(0===r.cmpn(0))return r.clone();var t=this.m.andln(3);if(n(t%2===1),3===t){var e=this.m.add(new i(1)).ishrn(2),o=this.pow(r,e);return o}for(var s=this.m.subn(1),a=0;0!==s.cmpn(0)&&0===s.andln(1);)a++,s.ishrn(1);n(0!==s.cmpn(0));var u=new i(1).toRed(this),h=u.redNeg(),f=this.m.subn(1).ishrn(1),l=this.m.bitLength();for(l=new i(2*l*l).toRed(this);0!==this.pow(l,f).cmp(h);)l.redIAdd(h);for(var c=this.pow(l,s),o=this.pow(r,s.addn(1).ishrn(1)),p=this.pow(r,s),g=a;0!==p.cmp(u);){for(var v=p,d=0;0!==v.cmp(u);d++)v=v.redSqr();n(g>d);var y=this.pow(c,new i(1).ishln(g-d-1));o=o.redMul(y),c=y.redSqr(),p=p.redMul(c),g=d}return o},c.prototype.invm=function(r){var t=r._invmp(this.m);return t.sign?(t.sign=!1,this.imod(t).redNeg()):this.imod(t)},c.prototype.pow=function(r,t){var n=[];if(0===t.cmpn(0))return new i(1);for(var e=t.clone();0!==e.cmpn(0);)n.push(e.andln(1)),e.ishrn(1);for(var o=r,s=0;s<n.length&&0===n[s];s++,o=this.sqr(o));if(++s<n.length)for(var e=this.sqr(o);s<n.length;s++,e=this.sqr(e))0!==n[s]&&(o=this.mul(o,e));return o},c.prototype.convertTo=function(r){var t=r.mod(this.m);return t===r?t.clone():t},c.prototype.convertFrom=function(r){var t=r.clone();return t.red=null,t},i.mont=function(r){return new p(r)},e(p,c),p.prototype.convertTo=function(r){return this.imod(r.shln(this.shift))},p.prototype.convertFrom=function(r){var t=this.imod(r.mul(this.rinv));return t.red=null,t},p.prototype.imul=function(r,t){if(0===r.cmpn(0)||0===t.cmpn(0))return r.words[0]=0,r.length=1,r;var n=r.imul(t),e=n.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m),i=n.isub(e).ishrn(this.shift),o=i;return i.cmp(this.m)>=0?o=i.isub(this.m):i.cmpn(0)<0&&(o=i.iadd(this.m)),o._forceRed(this)},p.prototype.mul=function(r,t){if(0===r.cmpn(0)||0===t.cmpn(0))return new i(0)._forceRed(this);var n=r.mul(t),e=n.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m),o=n.isub(e).ishrn(this.shift),s=o;return o.cmp(this.m)>=0?s=o.isub(this.m):o.cmpn(0)<0&&(s=o.iadd(this.m)),s._forceRed(this)},p.prototype.invm=function(r){var t=this.imod(r._invmp(this.m).mul(this.r2));return t._forceRed(this)}}("undefined"==typeof t||t,this)},{}],71:[function(r,t,n){(function(r){function n(r,t){return p[0]=r,p[1]=t,c[0]}function e(r){return c[0]=r,p[0]}function i(r){return c[0]=r,p[1]}function o(r,t){return p[1]=r,p[0]=t,c[0]}function s(r){return c[0]=r,p[1]}function a(r){return c[0]=r,p[0]}function u(r,t){return g.writeUInt32LE(r,0,!0),g.writeUInt32LE(t,4,!0),g.readDoubleLE(0,!0)}function h(r){return g.writeDoubleLE(r,0,!0),g.readUInt32LE(0,!0)}function f(r){return g.writeDoubleLE(r,0,!0),g.readUInt32LE(4,!0)}var l=!1;if("undefined"!=typeof Float64Array){var c=new Float64Array(1),p=new Uint32Array(c.buffer);c[0]=1,l=!0,1072693248===p[1]?(t.exports=function(r){return c[0]=r,[p[0],p[1]]},t.exports.pack=n,t.exports.lo=e,t.exports.hi=i):1072693248===p[0]?(t.exports=function(r){return c[0]=r,[p[1],p[0]]},t.exports.pack=o,t.exports.lo=s,t.exports.hi=a):l=!1}if(!l){var g=new r(8);t.exports=function(r){return g.writeDoubleLE(r,0,!0),[g.readUInt32LE(0,!0),g.readUInt32LE(4,!0)]},t.exports.pack=u,t.exports.lo=h,t.exports.hi=f}t.exports.sign=function(r){return t.exports.hi(r)>>>31},t.exports.exponent=function(r){var n=t.exports.hi(r);return(n<<1>>>21)-1023},t.exports.fraction=function(r){var n=t.exports.lo(r),e=t.exports.hi(r),i=1048575&e;return 2146435072&e&&(i+=1<<20),[n,i]},t.exports.denormalized=function(r){var n=t.exports.hi(r);return!(2146435072&n)}}).call(this,r("buffer").Buffer)},{buffer:2}],72:[function(r,t,n){"use strict";function e(r){return i(r[0])*i(r[1])}var i=r("./lib/bn-sign");t.exports=e},{"./lib/bn-sign":61}],73:[function(r,t,n){"use strict";function e(r,t){return i(r[0].mul(t[1]).sub(r[1].mul(t[0])),r[1].mul(t[1]))}var i=r("./lib/rationalize");t.exports=e},{"./lib/rationalize":66}],74:[function(r,t,n){"use strict";function e(r){var t=r[0],n=r[1];if(0===t.cmpn(0))return 0;var e=t.divmod(n),s=e.div,a=i(s),u=e.mod;if(0===u.cmpn(0))return a;if(a){var h=o(a)+4,f=i(u.shln(h).divRound(n));return 0>a&&(f=-f),a+f*Math.pow(2,-h)}var l=n.bitLength()-u.bitLength()+53,f=i(u.shln(l).divRound(n));return 1023>l?f*Math.pow(2,-l):(f*=Math.pow(2,-1023),f*Math.pow(2,1023-l))}var i=r("./lib/bn-to-num"),o=r("./lib/ctz");t.exports=e},{"./lib/bn-to-num":62,"./lib/ctz":63}],75:[function(r,t,n){"use strict";function e(r,t){for(var n=0;r>n;++n)if(!(t[n]<=t[n+r]))return!0;return!1}function i(r,t,n,i){for(var o=0,s=0,a=0,u=r.length;u>a;++a){var h=r[a];if(!e(t,h)){for(var f=0;2*t>f;++f)n[o++]=h[f];i[s++]=a}}return s}function o(r,t,n,e){var o=r.length,s=t.length;if(!(0>=o||0>=s)){var a=r[0].length>>>1;if(!(0>=a)){var u,h=l.mallocDouble(2*a*o),f=l.mallocInt32(o);if(o=i(r,a,h,f),o>0){if(1===a&&e)c.init(o),u=c.sweepComplete(a,n,0,o,h,f,0,o,h,f);else{var g=l.mallocDouble(2*a*s),v=l.mallocInt32(s);s=i(t,a,g,v),s>0&&(c.init(o+s),u=1===a?c.sweepBipartite(a,n,0,o,h,f,0,s,g,v):p(a,n,e,o,h,f,s,g,v),l.free(g),l.free(v))}l.free(h),l.free(f)}return u}}}function s(r,t){f.push([r,t])}function a(r){return f=[],o(r,r,s,!0),f}function u(r,t){return f=[],o(r,t,s,!1),f}function h(r,t,n){switch(arguments.length){case 1:return a(r);case 2:return"function"==typeof t?o(r,r,t,!0):u(r,t);case 3:return o(r,t,n,!1);default:throw new Error("box-intersect: Invalid arguments")}}t.exports=h;var f,l=r("typedarray-pool"),c=r("./lib/sweep"),p=r("./lib/intersect")},{"./lib/intersect":77,"./lib/sweep":81,"typedarray-pool":84}],76:[function(r,t,n){"use strict";function e(r,t,n){var e="bruteForce"+(r?"Red":"Blue")+(t?"Flip":"")+(n?"Full":""),i=["function ",e,"(",A.join(),"){","var ",h,"=2*",o,";"],u="for(var i="+f+","+g+"="+h+"*"+f+";i<"+l+";++i,"+g+"+="+h+"){var x0="+c+"["+s+"+"+g+"],x1="+c+"["+s+"+"+g+"+"+o+"],xi="+p+"[i];",x="for(var j="+v+","+b+"="+h+"*"+v+";j<"+d+";++j,"+b+"+="+h+"){var y0="+y+"["+s+"+"+b+"],"+(n?"y1="+y+"["+s+"+"+b+"+"+o+"],":"")+"yi="+m+"[j];";return r?i.push(u,_,":",x):i.push(x,_,":",u),n?i.push("if(y1<x0||x1<y0)continue;"):t?i.push("if(y0<=x0||x1<y0)continue;"):i.push("if(y0<x0||x1<y0)continue;"),i.push("for(var k="+s+"+1;k<"+o+";++k){var r0="+c+"[k+"+g+"],r1="+c+"[k+"+o+"+"+g+"],b0="+y+"[k+"+b+"],b1="+y+"[k+"+o+"+"+b+"];if(r1<b0||b1<r0)continue "+_+";}var "+w+"="+a+"("),t?i.push("yi,xi"):i.push("xi,yi"),i.push(");if("+w+"!==void 0)return "+w+";}}}"),{name:e,code:i.join("")}}function i(r){function t(t,n){var o=e(t,n,r);i.push(o.code),s.push("return "+o.name+"("+A.join()+");")}var n="bruteForce"+(r?"Full":"Partial"),i=[],o=A.slice();r||o.splice(3,0,u);var s=["function "+n+"("+o.join()+"){"];s.push("if("+l+"-"+f+">"+d+"-"+v+"){"),r?(t(!0,!1),s.push("}else{"),t(!1,!1)):(s.push("if("+u+"){"),t(!0,!0),s.push("}else{"),t(!0,!1),s.push("}}else{if("+u+"){"),t(!1,!0),s.push("}else{"),t(!1,!1),s.push("}")),s.push("}}return "+n);var a=i.join("")+s.join(""),h=new Function(a);return h()}var o="d",s="ax",a="vv",u="fp",h="es",f="rs",l="re",c="rb",p="ri",g="rp",v="bs",d="be",y="bb",m="bi",b="bp",w="rv",_="Q",A=[o,s,a,f,l,c,p,v,d,y,m];n.partial=i(!1),n.full=i(!0)},{}],77:[function(r,t,n){"use strict";function e(r,t){var n=8*h.log2(t+1)*(r+1)|0,e=h.nextPow2(j*n);M.length<e&&(u.free(M),M=u.mallocInt32(e));var i=h.nextPow2(k*n);i>P&&(u.free(P),P=u.mallocDouble(i))}function i(r,t,n,e,i,o,s,a,u){var h=j*r;M[h]=t,M[h+1]=n,M[h+2]=e,M[h+3]=i,M[h+4]=o,M[h+5]=s;var f=k*r;P[f]=a,P[f+1]=u}function o(r,t,n,e,i,o,s,a,u,h,f){var l=2*r,c=u*l,p=h[c+t];r:for(var g=i,v=i*l;o>g;++g,v+=l){var d=s[v+t],y=s[v+t+r];if(!(d>p||p>y||e&&p===d)){for(var m=a[g],b=t+1;r>b;++b){var d=s[v+b],y=s[v+b+r],w=h[c+b],_=h[c+b+r];if(w>y||d>_)continue r}var A;if(A=e?n(f,m):n(m,f),void 0!==A)return A}}}function s(r,t,n,e,i,o,s,a,u,h){var f=2*r,l=a*f,c=u[l+t];r:for(var p=e,g=e*f;i>p;++p,g+=f){var v=s[p];if(v!==h){var d=o[g+t],y=o[g+t+r];if(!(d>c||c>y)){for(var m=t+1;r>m;++m){var d=o[g+m],y=o[g+m+r],b=u[l+m],w=u[l+m+r];if(b>y||d>w)continue r}var _=n(v,h);if(void 0!==_)return _}}}}function a(r,t,n,a,u,h,f,v,I){e(r,a+f);var B,R=0,T=2*r;for(i(R++,0,0,a,0,f,n?16:0,-(1/0),1/0),n||i(R++,0,0,f,0,a,1,-(1/0),1/0);R>0;){R-=1;var U=R*j,S=M[U],L=M[U+1],V=M[U+2],N=M[U+3],F=M[U+4],O=M[U+5],C=R*k,q=P[C],D=P[C+1],Y=1&O,z=!!(16&O),G=u,H=h,W=v,Q=I;if(Y&&(G=v,H=I,W=u,Q=h),!(2&O&&(V=_(r,S,L,V,G,H,D),L>=V)||4&O&&(L=A(r,S,L,V,G,H,q),L>=V))){var K=V-L,X=F-N;if(z){if(m>r*K*(K+X)){if(B=p.scanComplete(r,S,t,L,V,G,H,N,F,W,Q),void 0!==B)return B;continue}}else{if(r*Math.min(K,X)<d){if(B=l(r,S,t,Y,L,V,G,H,N,F,W,Q),void 0!==B)return B;continue}if(y>r*K*X){if(B=p.scanBipartite(r,S,t,Y,L,V,G,H,N,F,W,Q),void 0!==B)return B;continue}}var J=b(r,S,L,V,G,H,q,D);if(J>L)if(d>r*(J-L)){if(B=c(r,S+1,t,L,J,G,H,N,F,W,Q),void 0!==B)return B}else if(S===r-2){if(B=Y?p.sweepBipartite(r,t,N,F,W,Q,L,J,G,H):p.sweepBipartite(r,t,L,J,G,H,N,F,W,Q),void 0!==B)return B}else i(R++,S+1,L,J,N,F,Y,-(1/0),1/0),i(R++,S+1,N,F,L,J,1^Y,-(1/0),1/0);if(V>J){var Z=g(r,S,N,F,W,Q),$=W[T*Z+S],rr=w(r,S,Z,F,W,Q,$);if(F>rr&&i(R++,S,J,V,rr,F,(4|Y)+(z?16:0),$,D),Z>N&&i(R++,S,J,V,N,Z,(2|Y)+(z?16:0),q,$),Z+1===rr){if(B=z?s(r,S,t,J,V,G,H,Z,W,Q[Z]):o(r,S,t,Y,J,V,G,H,Z,W,Q[Z]),void 0!==B)return B}else if(rr>Z){var tr;if(z){if(tr=x(r,S,J,V,G,H,$),tr>J){var nr=w(r,S,J,tr,G,H,$);if(S===r-2){if(nr>J&&(B=p.sweepComplete(r,t,J,nr,G,H,Z,rr,W,Q),void 0!==B))return B;if(tr>nr&&(B=p.sweepBipartite(r,t,nr,tr,G,H,Z,rr,W,Q),void 0!==B))return B}else nr>J&&i(R++,S+1,J,nr,Z,rr,16,-(1/0),1/0),tr>nr&&(i(R++,S+1,nr,tr,Z,rr,0,-(1/0),1/0),i(R++,S+1,Z,rr,nr,tr,1,-(1/0),1/0))}}else tr=Y?E(r,S,J,V,G,H,$):x(r,S,J,V,G,H,$),tr>J&&(S===r-2?B=Y?p.sweepBipartite(r,t,Z,rr,W,Q,J,tr,G,H):p.sweepBipartite(r,t,J,tr,G,H,Z,rr,W,Q):(i(R++,S+1,J,tr,Z,rr,Y,-(1/0),1/0),i(R++,S+1,Z,rr,J,tr,1^Y,-(1/0),1/0)))}}}}}t.exports=a;var u=r("typedarray-pool"),h=r("bit-twiddle"),f=r("./brute"),l=f.partial,c=f.full,p=r("./sweep"),g=r("./median"),v=r("./partition"),d=128,y=1<<22,m=1<<22,b=v("!(lo>=p0)&&!(p1>=hi)",["p0","p1"]),w=v("lo===p0",["p0"]),_=v("lo<p0",["p0"]),A=v("hi<=p0",["p0"]),x=v("lo<=p0&&p0<=hi",["p0"]),E=v("lo<p0&&p0<=hi",["p0"]),j=6,k=2,I=1024,M=u.mallocInt32(I),P=u.mallocDouble(I)},{"./brute":76,"./median":78,"./partition":79,"./sweep":81,"bit-twiddle":82,"typedarray-pool":84}],78:[function(r,t,n){"use strict";function e(r,t,n,e,i,o){for(var s=2*r,a=s*(n+1)+t,u=n+1;e>u;++u,a+=s)for(var h=i[a],f=u,l=s*(u-1);f>n&&i[l+t]>h;--f,l-=s){for(var c=l,p=l+s,g=0;s>g;++g,++c,++p){var v=i[c];i[c]=i[p],i[p]=v}var d=o[f];o[f]=o[f-1],o[f-1]=d}}function i(r,t,n,i,o,u){if(n+1>=i)return n;for(var h=n,f=i,l=i+n>>>1,c=2*r,p=l,g=o[c*l+t];f>h;){if(a>f-h){e(r,t,h,f,o,u),g=o[c*l+t];break}var v=f-h,d=Math.random()*v+h|0,y=o[c*d+t],m=Math.random()*v+h|0,b=o[c*m+t],w=Math.random()*v+h|0,_=o[c*w+t];b>=y?_>=b?(p=m,g=b):y>=_?(p=d,g=y):(p=w,g=_):b>=_?(p=m,g=b):_>=y?(p=d,g=y):(p=w,g=_);for(var A=c*(f-1),x=c*p,E=0;c>E;++E,++A,++x){var j=o[A];o[A]=o[x],o[x]=j}var k=u[f-1];u[f-1]=u[p],u[p]=k,p=s(r,t,h,f-1,o,u,g);for(var A=c*(f-1),x=c*p,E=0;c>E;++E,++A,++x){var j=o[A];o[A]=o[x],o[x]=j}var k=u[f-1];if(u[f-1]=u[p],u[p]=k,p>l){for(f=p-1;f>h&&o[c*(f-1)+t]===g;)f-=1;f+=1}else{if(!(l>p))break;for(h=p+1;f>h&&o[c*h+t]===g;)h+=1; | |
}}return s(r,t,n,l,o,u,o[c*l+t])}t.exports=i;var o=r("./partition"),s=o("lo<p0",["p0"]),a=8},{"./partition":79}],79:[function(r,t,n){"use strict";function e(r,t){var n="abcdef".split("").concat(t),e=[];return r.indexOf("lo")>=0&&e.push("lo=e[k+n]"),r.indexOf("hi")>=0&&e.push("hi=e[k+o]"),n.push(i.replace("_",e.join()).replace("$",r)),Function.apply(void 0,n)}t.exports=e;var i="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 _;if($)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"},{}],80:[function(r,t,n){"use strict";function e(r,t){4*c>=t?i(0,t-1,r):l(0,t-1,r)}function i(r,t,n){for(var e=2*(r+1),i=r+1;t>=i;++i){for(var o=n[e++],s=n[e++],a=i,u=e-2;a-->r;){var h=n[u-2],f=n[u-1];if(o>h)break;if(h===o&&s>f)break;n[u]=h,n[u+1]=f,u-=2}n[u]=o,n[u+1]=s}}function o(r,t,n){r*=2,t*=2;var e=n[r],i=n[r+1];n[r]=n[t],n[r+1]=n[t+1],n[t]=e,n[t+1]=i}function s(r,t,n){r*=2,t*=2,n[r]=n[t],n[r+1]=n[t+1]}function a(r,t,n,e){r*=2,t*=2,n*=2;var i=e[r],o=e[r+1];e[r]=e[t],e[r+1]=e[t+1],e[t]=e[n],e[t+1]=e[n+1],e[n]=i,e[n+1]=o}function u(r,t,n,e,i){r*=2,t*=2,i[r]=i[t],i[t]=n,i[r+1]=i[t+1],i[t+1]=e}function h(r,t,n){r*=2,t*=2;var e=n[r],i=n[t];return i>e?!1:e===i?n[r+1]>n[t+1]:!0}function f(r,t,n,e){r*=2;var i=e[r];return t>i?!0:i===t?e[r+1]<n:!1}function l(r,t,n){var e=(t-r+1)/6|0,p=r+e,g=t-e,v=r+t>>1,d=v-e,y=v+e,m=p,b=d,w=v,_=y,A=g,x=r+1,E=t-1,j=0;h(m,b,n)&&(j=m,m=b,b=j),h(_,A,n)&&(j=_,_=A,A=j),h(m,w,n)&&(j=m,m=w,w=j),h(b,w,n)&&(j=b,b=w,w=j),h(m,_,n)&&(j=m,m=_,_=j),h(w,_,n)&&(j=w,w=_,_=j),h(b,A,n)&&(j=b,b=A,A=j),h(b,w,n)&&(j=b,b=w,w=j),h(_,A,n)&&(j=_,_=A,A=j);for(var k=n[2*b],I=n[2*b+1],M=n[2*_],P=n[2*_+1],B=2*m,R=2*w,T=2*A,U=2*p,S=2*v,L=2*g,V=0;2>V;++V){var N=n[B+V],F=n[R+V],O=n[T+V];n[U+V]=N,n[S+V]=F,n[L+V]=O}s(d,r,n),s(y,t,n);for(var C=x;E>=C;++C)if(f(C,k,I,n))C!==x&&o(C,x,n),++x;else if(!f(C,M,P,n))for(;;){if(f(E,M,P,n)){f(E,k,I,n)?(a(C,x,E,n),++x,--E):(o(C,E,n),--E);break}if(--E<C)break}u(r,x-1,k,I,n),u(t,E+1,M,P,n),c>=x-2-r?i(r,x-2,n):l(r,x-2,n),c>=t-(E+2)?i(E+2,t,n):l(E+2,t,n),c>=E-x?i(x,E,n):l(x,E,n)}t.exports=e;var c=32},{}],81:[function(r,t,n){"use strict";function e(r){var t=l.nextPow2(r);v.length<t&&(f.free(v),v=f.mallocInt32(t)),d.length<t&&(f.free(d),d=f.mallocInt32(t)),y.length<t&&(f.free(y),y=f.mallocInt32(t)),m.length<t&&(f.free(m),m=f.mallocInt32(t)),b.length<t&&(f.free(b),b=f.mallocInt32(t)),w.length<t&&(f.free(w),w=f.mallocInt32(t));var n=8*t;_.length<n&&(f.free(_),_=f.mallocDouble(n))}function i(r,t,n,e){var i=t[e],o=r[n-1];r[i]=o,t[o]=i}function o(r,t,n,e){r[n]=e,t[e]=n}function s(r,t,n,e,s,a,u,h,f,l){for(var g=0,b=2*r,w=r-1,A=b-1,x=n;e>x;++x){var E=a[x],j=b*x;_[g++]=s[j+w],_[g++]=-(E+1),_[g++]=s[j+A],_[g++]=E}for(var x=u;h>x;++x){var E=l[x]+p,k=b*x;_[g++]=f[k+w],_[g++]=-E,_[g++]=f[k+A],_[g++]=E}var I=g>>>1;c(_,I);for(var M=0,P=0,x=0;I>x;++x){var B=0|_[2*x+1];if(B>=p)B=B-p|0,i(y,m,P--,B);else if(B>=0)i(v,d,M--,B);else if(-p>=B){B=-B-p|0;for(var R=0;M>R;++R){var T=t(v[R],B);if(void 0!==T)return T}o(y,m,P++,B)}else{B=-B-1|0;for(var R=0;P>R;++R){var T=t(B,y[R]);if(void 0!==T)return T}o(v,d,M++,B)}}}function a(r,t,n,e,s,a,u,h,f,l){for(var p=0,g=2*r,A=r-1,x=g-1,E=n;e>E;++E){var j=a[E]+1<<1,k=g*E;_[p++]=s[k+A],_[p++]=-j,_[p++]=s[k+x],_[p++]=j}for(var E=u;h>E;++E){var j=l[E]+1<<1,I=g*E;_[p++]=f[I+A],_[p++]=1|-j,_[p++]=f[I+x],_[p++]=1|j}var M=p>>>1;c(_,M);for(var P=0,B=0,R=0,E=0;M>E;++E){var T=0|_[2*E+1],U=1&T;if(M-1>E&&T>>1===_[2*E+3]>>1&&(U=2,E+=1),0>T){for(var S=-(T>>1)-1,L=0;R>L;++L){var V=t(b[L],S);if(void 0!==V)return V}if(0!==U)for(var L=0;P>L;++L){var V=t(v[L],S);if(void 0!==V)return V}if(1!==U)for(var L=0;B>L;++L){var V=t(y[L],S);if(void 0!==V)return V}0===U?o(v,d,P++,S):1===U?o(y,m,B++,S):2===U&&o(b,w,R++,S)}else{var S=(T>>1)-1;0===U?i(v,d,P--,S):1===U?i(y,m,B--,S):2===U&&i(b,w,R--,S)}}}function u(r,t,n,e,s,a,u,h,f,l,g,y){var m=0,b=2*r,w=t,A=t+r,x=1,E=1;e?E=p:x=p;for(var j=s;a>j;++j){var k=j+x,I=b*j;_[m++]=u[I+w],_[m++]=-k,_[m++]=u[I+A],_[m++]=k}for(var j=f;l>j;++j){var k=j+E,M=b*j;_[m++]=g[M+w],_[m++]=-k}var P=m>>>1;c(_,P);for(var B=0,j=0;P>j;++j){var R=0|_[2*j+1];if(0>R){var k=-R,T=!1;if(k>=p?(T=!e,k-=p):(T=!!e,k-=1),T)o(v,d,B++,k);else{var U=y[k],S=b*k,L=g[S+t+1],V=g[S+t+1+r];r:for(var N=0;B>N;++N){var F=v[N],O=b*F;if(!(V<u[O+t+1]||u[O+t+1+r]<L)){for(var C=t+2;r>C;++C)if(g[S+C+r]<u[O+C]||u[O+C+r]<g[S+C])continue r;var q,D=h[F];if(q=e?n(U,D):n(D,U),void 0!==q)return q}}}}else i(v,d,B--,R-x)}}function h(r,t,n,e,i,o,s,a,u,h,f){for(var l=0,g=2*r,d=t,y=t+r,m=e;i>m;++m){var b=m+p,w=g*m;_[l++]=o[w+d],_[l++]=-b,_[l++]=o[w+y],_[l++]=b}for(var m=a;u>m;++m){var b=m+1,A=g*m;_[l++]=h[A+d],_[l++]=-b}var x=l>>>1;c(_,x);for(var E=0,m=0;x>m;++m){var j=0|_[2*m+1];if(0>j){var b=-j;if(b>=p)v[E++]=b-p;else{b-=1;var k=f[b],I=g*b,M=h[I+t+1],P=h[I+t+1+r];r:for(var B=0;E>B;++B){var R=v[B],T=s[R];if(T===k)break;var U=g*R;if(!(P<o[U+t+1]||o[U+t+1+r]<M)){for(var S=t+2;r>S;++S)if(h[I+S+r]<o[U+S]||o[U+S+r]<h[I+S])continue r;var L=n(T,k);if(void 0!==L)return L}}}}else{for(var b=j-p,B=E-1;B>=0;--B)if(v[B]===b){for(var S=B+1;E>S;++S)v[S-1]=v[S];break}--E}}}t.exports={init:e,sweepBipartite:s,sweepComplete:a,scanBipartite:u,scanComplete:h};var f=r("typedarray-pool"),l=r("bit-twiddle"),c=r("./sort"),p=1<<28,g=1024,v=f.mallocInt32(g),d=f.mallocInt32(g),y=f.mallocInt32(g),m=f.mallocInt32(g),b=f.mallocInt32(g),w=f.mallocInt32(g),_=f.mallocDouble(8*g)},{"./sort":80,"bit-twiddle":82,"typedarray-pool":84}],82:[function(r,t,n){arguments[4][15][0].apply(n,arguments)},{dup:15}],83:[function(r,t,n){arguments[4][16][0].apply(n,arguments)},{dup:16}],84:[function(r,t,n){arguments[4][17][0].apply(n,arguments)},{"bit-twiddle":82,buffer:2,dup:17}],85:[function(r,t,n){function e(r,t){return r-t}function i(r,t){var n=r.length,i=r.length-t.length;if(i)return i;switch(n){case 0:return 0;case 1:return r[0]-t[0];case 2:return r[0]+r[1]-t[0]-t[1]||o(r[0],r[1])-o(t[0],t[1]);case 3:var s=r[0]+r[1],a=t[0]+t[1];if(i=s+r[2]-(a+t[2]))return i;var u=o(r[0],r[1]),h=o(t[0],t[1]);return o(u,r[2])-o(h,t[2])||o(u+r[2],s)-o(h+t[2],a);case 4:var f=r[0],l=r[1],c=r[2],p=r[3],g=t[0],v=t[1],d=t[2],y=t[3];return f+l+c+p-(g+v+d+y)||o(f,l,c,p)-o(g,v,d,y,g)||o(f+l,f+c,f+p,l+c,l+p,c+p)-o(g+v,g+d,g+y,v+d,v+y,d+y)||o(f+l+c,f+l+p,f+c+p,l+c+p)-o(g+v+d,g+v+y,g+d+y,v+d+y);default:for(var m=r.slice().sort(e),b=t.slice().sort(e),w=0;n>w;++w)if(i=m[w]-b[w])return i;return 0}}t.exports=i;var o=Math.min},{}],86:[function(r,t,n){"use strict";function e(r,t){if(isNaN(r)||isNaN(t))return NaN;if(r===t)return r;if(0===r)return 0>t?-o:o;var n=i.hi(r),e=i.lo(r);return t>r==r>0?e===s?(n+=1,e=0):e+=1:0===e?(e=s,n-=1):e-=1,i.pack(e,n)}var i=r("double-bits"),o=Math.pow(2,-1074),s=-1>>>0;t.exports=e},{"double-bits":87}],87:[function(r,t,n){arguments[4][71][0].apply(n,arguments)},{buffer:2,dup:71}],88:[function(r,t,n){"use strict";function e(r,t){for(var n=r.length,e=new Array(n),o=0;n>o;++o)e[o]=i(r[o],t[o]);return e}var i=r("big-rat/add");t.exports=e},{"big-rat/add":56}],89:[function(r,t,n){"use strict";function e(r){for(var t=new Array(r.length),n=0;n<r.length;++n)t[n]=i(r[n]);return t}t.exports=e;var i=r("big-rat")},{"big-rat":59}],90:[function(r,t,n){"use strict";function e(r,t){for(var n=i(t),e=r.length,s=new Array(e),a=0;e>a;++a)s[a]=o(r[a],n);return s}var i=r("big-rat"),o=r("big-rat/mul");t.exports=e},{"big-rat":59,"big-rat/mul":68}],91:[function(r,t,n){"use strict";function e(r,t){for(var n=r.length,e=new Array(n),o=0;n>o;++o)e[o]=i(r[o],t[o]);return e}var i=r("big-rat/sub");t.exports=e},{"big-rat/sub":73}],92:[function(r,t,n){arguments[4][43][0].apply(n,arguments)},{dup:43}],93:[function(r,t,n){arguments[4][44][0].apply(n,arguments)},{dup:44,"two-product":96,"two-sum":92}],94:[function(r,t,n){arguments[4][45][0].apply(n,arguments)},{dup:45}],95:[function(r,t,n){arguments[4][46][0].apply(n,arguments)},{dup:46}],96:[function(r,t,n){arguments[4][47][0].apply(n,arguments)},{dup:47}],97:[function(r,t,n){arguments[4][53][0].apply(n,arguments)},{dup:53,"robust-scale":93,"robust-subtract":94,"robust-sum":95,"two-product":96}],98:[function(r,t,n){"use strict";function e(r,t,n,e){for(var i=0;2>i;++i){var o=r[i],s=t[i],a=Math.min(o,s),u=Math.max(o,s),h=n[i],f=e[i],l=Math.min(h,f),c=Math.max(h,f);if(a>c||l>u)return!1}return!0}function i(r,t,n,i){var s=o(r,n,i),a=o(t,n,i);if(s>0&&a>0||0>s&&0>a)return!1;var u=o(n,r,t),h=o(i,r,t);return u>0&&h>0||0>u&&0>h?!1:0===s&&0===a&&0===u&&0===h?e(r,t,n,i):!0}t.exports=i;var o=r("robust-orientation")[3]},{"robust-orientation":97}],99:[function(r,t,n){"use strict";"use restrict";function e(r){this.roots=new Array(r),this.ranks=new Array(r);for(var t=0;r>t;++t)this.roots[t]=t,this.ranks[t]=0}t.exports=e;var i=e.prototype;Object.defineProperty(i,"length",{get:function(){return this.roots.length}}),i.makeSet=function(){var r=this.roots.length;return this.roots.push(r),this.ranks.push(0),r},i.find=function(r){for(var t=r,n=this.roots;n[r]!==r;)r=n[r];for(;n[t]!==r;){var e=n[t];n[t]=r,t=e}return r},i.link=function(r,t){var n=this.find(r),e=this.find(t);if(n!==e){var i=this.ranks,o=this.roots,s=i[n],a=i[e];a>s?o[n]=e:s>a?o[e]=n:(o[e]=n,++i[n])}}},{}],100:[function(r,t,n){arguments[4][12][0].apply(n,arguments)},{dup:12,"iota-array":101,"is-buffer":102}],101:[function(r,t,n){arguments[4][13][0].apply(n,arguments)},{dup:13}],102:[function(r,t,n){arguments[4][14][0].apply(n,arguments)},{dup:14}],103:[function(r,t,n){"use strict";function e(r,t){for(var n=i(r,t.length),e=new Array(t.length),o=new Array(t.length),s=[],a=0;a<t.length;++a){var u=n[a].length;o[a]=u,e[a]=!0,1>=u&&s.push(a)}for(;s.length>0;){var h=s.pop();e[h]=!1;for(var f=n[h],a=0;a<f.length;++a){var l=f[a];0===--o[l]&&s.push(l)}}for(var c=new Array(t.length),p=[],a=0;a<t.length;++a)if(e[a]){var h=p.length;c[a]=h,p.push(t[a])}else c[a]=-1;for(var g=[],a=0;a<r.length;++a){var v=r[a];e[v[0]]&&e[v[1]]&&g.push([c[v[0]],c[v[1]]])}return[g,p]}t.exports=e;var i=r("edges-to-adjacency-list")},{"edges-to-adjacency-list":104}],104:[function(r,t,n){"use strict";function e(r,t){var n=r.length;if("number"!=typeof t){t=0;for(var e=0;n>e;++e){var o=r[e];t=Math.max(t,o[0],o[1])}t=(0|t)+1}t=0|t;for(var s=new Array(t),e=0;t>e;++e)s[e]=[];for(var e=0;n>e;++e){var o=r[e];s[o[0]].push(o[1]),s[o[1]].push(o[0])}for(var a=0;t>a;++a)i(s[a],function(r,t){return r-t});return s}t.exports=e;var i=r("uniq")},{uniq:123}],105:[function(r,t,n){"use strict";function e(r,t){function n(r,t){var n=h[t][r[t]];n.splice(n.indexOf(r),1)}function e(r,e,o){for(var s,a,u,f=0;2>f;++f)if(h[f][e].length>0){s=h[f][e][0],u=f;break}a=s[1^u];for(var l=0;2>l;++l)for(var c=h[l][e],p=0;p<c.length;++p){var g=c[p],v=g[1^l],d=i(t[r],t[e],t[a],t[v]);d>0&&(s=g,a=v,u=l)}return o?a:(s&&n(s,u),a)}function o(r,o){var s=h[o][r][0],a=[r];n(s,o);for(var u=s[1^o];;){for(;u!==r;)a.push(u),u=e(a[a.length-2],u,!1);if(h[0][r].length+h[1][r].length===0)break;var f=a[a.length-1],l=r,c=a[1],p=e(f,l,!0);if(i(t[f],t[l],t[c],t[p])<0)break;a.push(r),u=e(f,l)}return a}function s(r,t){return t[1]===t[t.length-1]}for(var a=0|t.length,u=r.length,h=[new Array(a),new Array(a)],f=0;a>f;++f)h[0][f]=[],h[1][f]=[];for(var f=0;u>f;++f){var l=r[f];h[0][l[0]].push(l),h[1][l[1]].push(l)}for(var c=[],f=0;a>f;++f)h[0][f].length+h[1][f].length===0&&c.push([f]);for(var f=0;a>f;++f)for(var p=0;2>p;++p){for(var g=[];h[p][f].length>0;){var v=(h[0][f].length,o(f,p));s(g,v)?g.push.apply(g,v):(g.length>0&&c.push(g),g=v)}g.length>0&&c.push(g)}return c}t.exports=e;var i=r("compare-angle")},{"compare-angle":106}],106:[function(r,t,n){"use strict";function e(r,t,n){var e=a(r[0],-t[0]),i=a(r[1],-t[1]),o=a(n[0],-t[0]),s=a(n[1],-t[1]),f=h(u(e,o),u(i,s));return f[f.length-1]>=0}function i(r,t,n,i){var a=o(t,n,i);if(0===a){var u=s(o(r,t,n)),h=s(o(r,t,i));if(u===h){if(0===u){var f=e(r,t,n),l=e(r,t,i);return f===l?0:f?1:-1}return 0}return 0===h?u>0?-1:e(r,t,i)?-1:1:0===u?h>0?1:e(r,t,n)?1:-1:s(h-u)}var c=o(r,t,n);if(c>0)return a>0&&o(r,t,i)>0?1:-1;if(0>c)return a>0||o(r,t,i)>0?1:-1;var p=o(r,t,i);return p>0?1:e(r,t,n)?1:-1}t.exports=i;var o=r("robust-orientation"),s=r("signum"),a=r("two-sum"),u=r("robust-product"),h=r("robust-sum")},{"robust-orientation":120,"robust-product":108,"robust-sum":121,signum:109,"two-sum":110}],107:[function(r,t,n){arguments[4][44][0].apply(n,arguments)},{dup:44,"two-product":122,"two-sum":110}],108:[function(r,t,n){"use strict";function e(r,t){if(1===r.length)return o(t,r[0]);if(1===t.length)return o(r,t[0]);if(0===r.length||0===t.length)return[0];var n=[0];if(r.length<t.length)for(var e=0;e<r.length;++e)n=i(n,o(t,r[e]));else for(var e=0;e<t.length;++e)n=i(n,o(r,t[e]));return n}var i=r("robust-sum"),o=r("robust-scale");t.exports=e},{"robust-scale":107,"robust-sum":121}],109:[function(r,t,n){"use strict";t.exports=function(r){return 0>r?-1:r>0?1:0}},{}],110:[function(r,t,n){arguments[4][43][0].apply(n,arguments)},{dup:43}],111:[function(r,t,n){"use strict";function e(r,t,n,e,i,o){var s=["function ",r,"(a,l,h,",e.join(","),"){",o?"":"var i=",n?"l-1":"h+1",";while(l<=h){var m=(l+h)>>>1,x=a",i?".get(m)":"[m]"];return o?t.indexOf("c")<0?s.push(";if(x===y){return m}else if(x<=y){"):s.push(";var p=c(x,y);if(p===0){return m}else if(p<=0){"):s.push(";if(",t,"){i=m;"),n?s.push("l=m+1}else{h=m-1}"):s.push("h=m-1}else{l=m+1}"),s.push("}"),o?s.push("return -1};"):s.push("return i};"),s.join("")}function i(r,t,n,i){var o=new Function([e("A","x"+r+"y",t,["y"],!1,i),e("B","x"+r+"y",t,["y"],!0,i),e("P","c(x,y)"+r+"0",t,["y","c"],!1,i),e("Q","c(x,y)"+r+"0",t,["y","c"],!0,i),"function dispatchBsearch",n,"(a,y,c,l,h){if(a.shape){if(typeof(c)==='function'){return Q(a,(l===undefined)?0:l|0,(h===undefined)?a.shape[0]-1:h|0,y,c)}else{return B(a,(c===undefined)?0:c|0,(l===undefined)?a.shape[0]-1:l|0,y)}}else{if(typeof(c)==='function'){return P(a,(l===undefined)?0:l|0,(h===undefined)?a.length-1:h|0,y,c)}else{return A(a,(c===undefined)?0:c|0,(l===undefined)?a.length-1:l|0,y)}}}return dispatchBsearch",n].join(""));return o()}t.exports={ge:i(">=",!1,"GE"),gt:i(">",!1,"GT"),lt:i("<",!0,"LT"),le:i("<=",!0,"LE"),eq:i("-",!0,"EQ",!0)}},{}],112:[function(r,t,n){"use strict";function e(r,t,n,e,i){this.mid=r,this.left=t,this.right=n,this.leftPoints=e,this.rightPoints=i,this.count=(t?t.count:0)+(n?n.count:0)+e.length}function i(r,t){r.mid=t.mid,r.left=t.left,r.right=t.right,r.leftPoints=t.leftPoints,r.rightPoints=t.rightPoints,r.count=t.count}function o(r,t){var n=g(t);r.mid=n.mid,r.left=n.left,r.right=n.right,r.leftPoints=n.leftPoints,r.rightPoints=n.rightPoints,r.count=n.count}function s(r,t){var n=r.intervals([]);n.push(t),o(r,n)}function a(r,t){var n=r.intervals([]),e=n.indexOf(t);return 0>e?m:(n.splice(e,1),o(r,n),b)}function u(r,t,n){for(var e=0;e<r.length&&r[e][0]<=t;++e){var i=n(r[e]);if(i)return i}}function h(r,t,n){for(var e=r.length-1;e>=0&&r[e][1]>=t;--e){var i=n(r[e]);if(i)return i}}function f(r,t){for(var n=0;n<r.length;++n){var e=t(r[n]);if(e)return e}}function l(r,t){return r-t}function c(r,t){var n=r[0]-t[0];return n?n:r[1]-t[1]}function p(r,t){var n=r[1]-t[1];return n?n:r[0]-t[0]}function g(r){if(0===r.length)return null;for(var t=[],n=0;n<r.length;++n)t.push(r[n][0],r[n][1]);t.sort(l);for(var i=t[t.length>>1],o=[],s=[],a=[],n=0;n<r.length;++n){var u=r[n];u[1]<i?o.push(u):i<u[0]?s.push(u):a.push(u)}var h=a,f=a.slice();return h.sort(c),f.sort(p),new e(i,g(o),g(s),h,f)}function v(r){this.root=r}function d(r){return new v(r&&0!==r.length?g(r):null)}var y=r("binary-search-bounds"),m=0,b=1,w=2;t.exports=d;var _=e.prototype;_.intervals=function(r){return r.push.apply(r,this.leftPoints),this.left&&this.left.intervals(r),this.right&&this.right.intervals(r),r},_.insert=function(r){var t=this.count-this.leftPoints.length;if(this.count+=1,r[1]<this.mid)this.left?4*(this.left.count+1)>3*(t+1)?s(this,r):this.left.insert(r):this.left=g([r]);else if(r[0]>this.mid)this.right?4*(this.right.count+1)>3*(t+1)?s(this,r):this.right.insert(r):this.right=g([r]);else{var n=y.ge(this.leftPoints,r,c),e=y.ge(this.rightPoints,r,p);this.leftPoints.splice(n,0,r),this.rightPoints.splice(e,0,r)}},_.remove=function(r){var t=this.count-this.leftPoints;if(r[1]<this.mid){if(!this.left)return m;var n=this.right?this.right.count:0;if(4*n>3*(t-1))return a(this,r);var e=this.left.remove(r);return e===w?(this.left=null,this.count-=1,b):(e===b&&(this.count-=1),e)}if(r[0]>this.mid){if(!this.right)return m;var o=this.left?this.left.count:0;if(4*o>3*(t-1))return a(this,r);var e=this.right.remove(r);return e===w?(this.right=null,this.count-=1,b):(e===b&&(this.count-=1),e)}if(1===this.count)return this.leftPoints[0]===r?w:m;if(1===this.leftPoints.length&&this.leftPoints[0]===r){if(this.left&&this.right){for(var s=this,u=this.left;u.right;)s=u,u=u.right;if(s===this)u.right=this.right;else{var h=this.left,e=this.right;s.count-=u.count,s.right=u.left,u.left=h,u.right=e}i(this,u),this.count=(this.left?this.left.count:0)+(this.right?this.right.count:0)+this.leftPoints.length}else this.left?i(this,this.left):i(this,this.right);return b}for(var h=y.ge(this.leftPoints,r,c);h<this.leftPoints.length&&this.leftPoints[h][0]===r[0];++h)if(this.leftPoints[h]===r){this.count-=1,this.leftPoints.splice(h,1);for(var e=y.ge(this.rightPoints,r,p);e<this.rightPoints.length&&this.rightPoints[e][1]===r[1];++e)if(this.rightPoints[e]===r)return this.rightPoints.splice(e,1),b}return m},_.queryPoint=function(r,t){if(r<this.mid){if(this.left){var n=this.left.queryPoint(r,t);if(n)return n}return u(this.leftPoints,r,t)}if(r>this.mid){if(this.right){var n=this.right.queryPoint(r,t);if(n)return n}return h(this.rightPoints,r,t)}return f(this.leftPoints,t)},_.queryInterval=function(r,t,n){if(r<this.mid&&this.left){var e=this.left.queryInterval(r,t,n);if(e)return e}if(t>this.mid&&this.right){var e=this.right.queryInterval(r,t,n);if(e)return e}return t<this.mid?u(this.leftPoints,t,n):r>this.mid?h(this.rightPoints,r,n):f(this.leftPoints,n)};var A=v.prototype;A.insert=function(r){this.root?this.root.insert(r):this.root=new e(r[0],null,null,[r],[r])},A.remove=function(r){if(this.root){var t=this.root.remove(r);return t===w&&(this.root=null),t!==m}return!1},A.queryPoint=function(r,t){return this.root?this.root.queryPoint(r,t):void 0},A.queryInterval=function(r,t,n){return t>=r&&this.root?this.root.queryInterval(r,t,n):void 0},Object.defineProperty(A,"count",{get:function(){return this.root?this.root.count:0}}),Object.defineProperty(A,"intervals",{get:function(){return this.root?this.root.intervals([]):[]}})},{"binary-search-bounds":111}],113:[function(r,t,n){"use strict";function e(r,t){var n,e;if(t[0][0]<t[1][0])n=t[0],e=t[1];else{if(!(t[0][0]>t[1][0])){var i=Math.min(r[0][1],r[1][1]),s=Math.max(r[0][1],r[1][1]),a=Math.min(t[0][1],t[1][1]),u=Math.max(t[0][1],t[1][1]);return a>s?s-a:i>u?i-u:s-u}n=t[1],e=t[0]}var h,f;r[0][1]<r[1][1]?(h=r[0],f=r[1]):(h=r[1],f=r[0]);var l=o(e,n,h);return l?l:(l=o(e,n,f),l?l:f-e)}function i(r,t){var n,i;if(t[0][0]<t[1][0])n=t[0],i=t[1];else{if(!(t[0][0]>t[1][0]))return e(t,r);n=t[1],i=t[0]}var s,a;if(r[0][0]<r[1][0])s=r[0],a=r[1];else{if(!(r[0][0]>r[1][0]))return-e(r,t);s=r[1],a=r[0]}var u=o(n,i,a),h=o(n,i,s);if(0>u){if(0>=h)return u}else if(u>0){if(h>=0)return u}else if(h)return h;if(u=o(a,s,i),h=o(a,s,n),0>u){if(0>=h)return u}else if(u>0){if(h>=0)return u}else if(h)return h;return i[0]-a[0]}t.exports=i;var o=r("robust-orientation")},{"robust-orientation":120}],114:[function(r,t,n){"use strict";function e(r,t,n,e,i,o){this._color=r,this.key=t,this.value=n,this.left=e,this.right=i,this._count=o}function i(r){return new e(r._color,r.key,r.value,r.left,r.right,r._count)}function o(r,t){return new e(r,t.key,t.value,t.left,t.right,t._count)}function s(r){r._count=1+(r.left?r.left._count:0)+(r.right?r.right._count:0)}function a(r,t){this._compare=r,this.root=t}function u(r,t){if(t.left){var n=u(r,t.left);if(n)return n}var n=r(t.key,t.value);return n?n:t.right?u(r,t.right):void 0}function h(r,t,n,e){var i=t(r,e.key);if(0>=i){if(e.left){var o=h(r,t,n,e.left);if(o)return o}var o=n(e.key,e.value);if(o)return o}return e.right?h(r,t,n,e.right):void 0}function f(r,t,n,e,i){var o,s=n(r,i.key),a=n(t,i.key);if(0>=s){if(i.left&&(o=f(r,t,n,e,i.left)))return o;if(a>0&&(o=e(i.key,i.value)))return o}return a>0&&i.right?f(r,t,n,e,i.right):void 0}function l(r,t){this.tree=r,this._stack=t}function c(r,t){r.key=t.key,r.value=t.value,r.left=t.left,r.right=t.right,r._color=t._color,r._count=t._count}function p(r){for(var t,n,e,a,u=r.length-1;u>=0;--u){if(t=r[u],0===u)return void(t._color=y);if(n=r[u-1],n.left===t){if(e=n.right,e.right&&e.right._color===d){if(e=n.right=i(e),a=e.right=i(e.right),n.right=e.left,e.left=n,e.right=a,e._color=n._color,t._color=y,n._color=y,a._color=y,s(n),s(e),u>1){var h=r[u-2];h.left===n?h.left=e:h.right=e}return void(r[u-1]=e)}if(e.left&&e.left._color===d){if(e=n.right=i(e),a=e.left=i(e.left),n.right=a.left,e.left=a.right,a.left=n,a.right=e,a._color=n._color,n._color=y,e._color=y,t._color=y,s(n),s(e),s(a),u>1){var h=r[u-2];h.left===n?h.left=a:h.right=a}return void(r[u-1]=a)}if(e._color===y){if(n._color===d)return n._color=y,void(n.right=o(d,e));n.right=o(d,e);continue}if(e=i(e),n.right=e.left,e.left=n,e._color=n._color,n._color=d,s(n),s(e),u>1){var h=r[u-2];h.left===n?h.left=e:h.right=e}r[u-1]=e,r[u]=n,u+1<r.length?r[u+1]=t:r.push(t),u+=2}else{if(e=n.left,e.left&&e.left._color===d){if(e=n.left=i(e),a=e.left=i(e.left),n.left=e.right,e.right=n,e.left=a,e._color=n._color,t._color=y,n._color=y,a._color=y,s(n),s(e),u>1){var h=r[u-2];h.right===n?h.right=e:h.left=e}return void(r[u-1]=e)}if(e.right&&e.right._color===d){if(e=n.left=i(e),a=e.right=i(e.right),n.left=a.right,e.right=a.left,a.right=n,a.left=e,a._color=n._color,n._color=y,e._color=y,t._color=y,s(n),s(e),s(a),u>1){var h=r[u-2];h.right===n?h.right=a:h.left=a}return void(r[u-1]=a)}if(e._color===y){if(n._color===d)return n._color=y,void(n.left=o(d,e));n.left=o(d,e);continue}if(e=i(e),n.left=e.right,e.right=n,e._color=n._color,n._color=d,s(n),s(e),u>1){var h=r[u-2];h.right===n?h.right=e:h.left=e}r[u-1]=e,r[u]=n,u+1<r.length?r[u+1]=t:r.push(t),u+=2}}}function g(r,t){return t>r?-1:r>t?1:0}function v(r){return new a(r||g,null)}t.exports=v;var d=0,y=1,m=a.prototype;Object.defineProperty(m,"keys",{get:function(){var r=[];return this.forEach(function(t,n){r.push(t)}),r}}),Object.defineProperty(m,"values",{get:function(){var r=[];return this.forEach(function(t,n){r.push(n)}),r}}),Object.defineProperty(m,"length",{get:function(){return this.root?this.root._count:0}}),m.insert=function(r,t){for(var n=this._compare,i=this.root,u=[],h=[];i;){var f=n(r,i.key);u.push(i),h.push(f),i=0>=f?i.left:i.right}u.push(new e(d,r,t,null,null,1));for(var l=u.length-2;l>=0;--l){var i=u[l];h[l]<=0?u[l]=new e(i._color,i.key,i.value,u[l+1],i.right,i._count+1):u[l]=new e(i._color,i.key,i.value,i.left,u[l+1],i._count+1)}for(var l=u.length-1;l>1;--l){var c=u[l-1],i=u[l];if(c._color===y||i._color===y)break;var p=u[l-2];if(p.left===c)if(c.left===i){var g=p.right;if(!g||g._color!==d){if(p._color=d,p.left=c.right,c._color=y,c.right=p,u[l-2]=c,u[l-1]=i,s(p),s(c),l>=3){var v=u[l-3];v.left===p?v.left=c:v.right=c}break}c._color=y,p.right=o(y,g),p._color=d,l-=1}else{var g=p.right;if(!g||g._color!==d){if(c.right=i.left,p._color=d,p.left=i.right,i._color=y,i.left=c,i.right=p,u[l-2]=i,u[l-1]=c,s(p),s(c),s(i),l>=3){var v=u[l-3];v.left===p?v.left=i:v.right=i}break}c._color=y,p.right=o(y,g),p._color=d,l-=1}else if(c.right===i){var g=p.left;if(!g||g._color!==d){if(p._color=d,p.right=c.left,c._color=y,c.left=p,u[l-2]=c,u[l-1]=i,s(p),s(c),l>=3){var v=u[l-3];v.right===p?v.right=c:v.left=c}break}c._color=y,p.left=o(y,g),p._color=d,l-=1}else{var g=p.left;if(!g||g._color!==d){if(c.left=i.right,p._color=d,p.right=i.left,i._color=y,i.right=c,i.left=p,u[l-2]=i,u[l-1]=c,s(p),s(c),s(i),l>=3){var v=u[l-3];v.right===p?v.right=i:v.left=i}break}c._color=y,p.left=o(y,g),p._color=d,l-=1}}return u[0]._color=y,new a(n,u[0])},m.forEach=function(r,t,n){if(this.root)switch(arguments.length){case 1:return u(r,this.root);case 2:return h(t,this._compare,r,this.root);case 3:if(this._compare(t,n)>=0)return;return f(t,n,this._compare,r,this.root)}},Object.defineProperty(m,"begin",{get:function(){for(var r=[],t=this.root;t;)r.push(t),t=t.left;return new l(this,r)}}),Object.defineProperty(m,"end",{get:function(){for(var r=[],t=this.root;t;)r.push(t),t=t.right;return new l(this,r)}}),m.at=function(r){if(0>r)return new l(this,[]);for(var t=this.root,n=[];;){if(n.push(t),t.left){if(r<t.left._count){t=t.left;continue}r-=t.left._count}if(!r)return new l(this,n);if(r-=1,!t.right)break;if(r>=t.right._count)break;t=t.right}return new l(this,[])},m.ge=function(r){for(var t=this._compare,n=this.root,e=[],i=0;n;){var o=t(r,n.key);e.push(n),0>=o&&(i=e.length),n=0>=o?n.left:n.right}return e.length=i,new l(this,e)},m.gt=function(r){for(var t=this._compare,n=this.root,e=[],i=0;n;){var o=t(r,n.key);e.push(n),0>o&&(i=e.length),n=0>o?n.left:n.right}return e.length=i,new l(this,e)},m.lt=function(r){for(var t=this._compare,n=this.root,e=[],i=0;n;){var o=t(r,n.key);e.push(n),o>0&&(i=e.length),n=0>=o?n.left:n.right}return e.length=i,new l(this,e)},m.le=function(r){for(var t=this._compare,n=this.root,e=[],i=0;n;){var o=t(r,n.key);e.push(n),o>=0&&(i=e.length),n=0>o?n.left:n.right}return e.length=i,new l(this,e)},m.find=function(r){for(var t=this._compare,n=this.root,e=[];n;){var i=t(r,n.key);if(e.push(n),0===i)return new l(this,e);n=0>=i?n.left:n.right}return new l(this,[])},m.remove=function(r){var t=this.find(r);return t?t.remove():this},m.get=function(r){for(var t=this._compare,n=this.root;n;){var e=t(r,n.key);if(0===e)return n.value;n=0>=e?n.left:n.right}};var b=l.prototype;Object.defineProperty(b,"valid",{get:function(){return this._stack.length>0}}),Object.defineProperty(b,"node",{get:function(){return this._stack.length>0?this._stack[this._stack.length-1]:null},enumerable:!0}),b.clone=function(){return new l(this.tree,this._stack.slice())},b.remove=function(){var r=this._stack;if(0===r.length)return this.tree;var t=new Array(r.length),n=r[r.length-1];t[t.length-1]=new e(n._color,n.key,n.value,n.left,n.right,n._count);for(var i=r.length-2;i>=0;--i){var n=r[i];n.left===r[i+1]?t[i]=new e(n._color,n.key,n.value,t[i+1],n.right,n._count):t[i]=new e(n._color,n.key,n.value,n.left,t[i+1],n._count)}if(n=t[t.length-1],n.left&&n.right){var o=t.length;for(n=n.left;n.right;)t.push(n),n=n.right;var s=t[o-1];t.push(new e(n._color,s.key,s.value,n.left,n.right,n._count)),t[o-1].key=n.key,t[o-1].value=n.value;for(var i=t.length-2;i>=o;--i)n=t[i],t[i]=new e(n._color,n.key,n.value,n.left,t[i+1],n._count);t[o-1].left=t[o]}if(n=t[t.length-1],n._color===d){var u=t[t.length-2];u.left===n?u.left=null:u.right===n&&(u.right=null),t.pop();for(var i=0;i<t.length;++i)t[i]._count--;return new a(this.tree._compare,t[0])}if(n.left||n.right){n.left?c(n,n.left):n.right&&c(n,n.right),n._color=y;for(var i=0;i<t.length-1;++i)t[i]._count--;return new a(this.tree._compare,t[0])}if(1===t.length)return new a(this.tree._compare,null);for(var i=0;i<t.length;++i)t[i]._count--;var h=t[t.length-2];return p(t),h.left===n?h.left=null:h.right=null,new a(this.tree._compare,t[0])},Object.defineProperty(b,"key",{get:function(){return this._stack.length>0?this._stack[this._stack.length-1].key:void 0},enumerable:!0}),Object.defineProperty(b,"value",{get:function(){return this._stack.length>0?this._stack[this._stack.length-1].value:void 0},enumerable:!0}),Object.defineProperty(b,"index",{get:function(){var r=0,t=this._stack;if(0===t.length){var n=this.tree.root;return n?n._count:0}t[t.length-1].left&&(r=t[t.length-1].left._count);for(var e=t.length-2;e>=0;--e)t[e+1]===t[e].right&&(++r,t[e].left&&(r+=t[e].left._count));return r},enumerable:!0}),b.next=function(){var r=this._stack;if(0!==r.length){var t=r[r.length-1];if(t.right)for(t=t.right;t;)r.push(t),t=t.left;else for(r.pop();r.length>0&&r[r.length-1].right===t;)t=r[r.length-1],r.pop()}},Object.defineProperty(b,"hasNext",{get:function(){var r=this._stack;if(0===r.length)return!1;if(r[r.length-1].right)return!0;for(var t=r.length-1;t>0;--t)if(r[t-1].left===r[t])return!0;return!1}}),b.update=function(r){var t=this._stack;if(0===t.length)throw new Error("Can't update empty node!");var n=new Array(t.length),i=t[t.length-1];n[n.length-1]=new e(i._color,i.key,r,i.left,i.right,i._count);for(var o=t.length-2;o>=0;--o)i=t[o],i.left===t[o+1]?n[o]=new e(i._color,i.key,i.value,n[o+1],i.right,i._count):n[o]=new e(i._color,i.key,i.value,i.left,n[o+1],i._count);return new a(this.tree._compare,n[0])},b.prev=function(){var r=this._stack;if(0!==r.length){var t=r[r.length-1];if(t.left)for(t=t.left;t;)r.push(t),t=t.right;else for(r.pop();r.length>0&&r[r.length-1].left===t;)t=r[r.length-1],r.pop()}},Object.defineProperty(b,"hasPrev",{get:function(){var r=this._stack;if(0===r.length)return!1;if(r[r.length-1].left)return!0;for(var t=r.length-1;t>0;--t)if(r[t-1].right===r[t])return!0;return!1}})},{}],115:[function(r,t,n){"use strict";function e(r,t,n){this.slabs=r,this.coordinates=t,this.horizontal=n}function i(r,t){return r.y-t}function o(r,t){for(var n=null;r;){var e,i,s=r.key;s[0][0]<s[1][0]?(e=s[0],i=s[1]):(e=s[1],i=s[0]);var a=l(e,i,t);if(0>a)r=r.left;else if(a>0)if(t[0]!==s[1][0])n=r,r=r.right;else{var u=o(r.right,t);if(u)return u;r=r.left}else{if(t[0]!==s[1][0])return r;var u=o(r.right,t);if(u)return u;r=r.left}}return n}function s(r,t,n,e){this.y=r,this.index=t,this.start=n,this.closed=e}function a(r,t,n,e){this.x=r,this.segment=t,this.create=n,this.index=e}function u(r){for(var t=r.length,n=2*t,i=new Array(n),o=0;t>o;++o){var u=r[o],h=u[0][0]<u[1][0];i[2*o]=new a(u[0][0],u,h,o),i[2*o+1]=new a(u[1][0],u,!h,o)}i.sort(function(r,t){var n=r.x-t.x;return n?n:(n=r.create-t.create,n?n:Math.min(r.segment[0][1],r.segment[1][1])-Math.min(t.segment[0][1],t.segment[1][1]))});for(var l=f(c),p=[],g=[],v=[],o=0;n>o;){for(var d=i[o].x,y=[];n>o;){var m=i[o];if(m.x!==d)break;o+=1,m.segment[0][0]===m.x&&m.segment[1][0]===m.x?m.create&&(m.segment[0][1]<m.segment[1][1]?(y.push(new s(m.segment[0][1],m.index,!0,!0)),y.push(new s(m.segment[1][1],m.index,!1,!1))):(y.push(new s(m.segment[1][1],m.index,!0,!1)),y.push(new s(m.segment[0][1],m.index,!1,!0)))):l=m.create?l.insert(m.segment,m.index):l.remove(m.segment)}p.push(l.root),g.push(d),v.push(y)}return new e(p,g,v)}t.exports=u;var h=r("binary-search-bounds"),f=r("functional-red-black-tree"),l=r("robust-orientation"),c=r("./lib/order-segments"),p=e.prototype;p.castUp=function(r){var t=h.le(this.coordinates,r[0]);if(0>t)return-1;var n=(this.slabs[t],o(this.slabs[t],r)),e=-1;if(n&&(e=n.value),this.coordinates[t]===r[0]){var s=null;if(n&&(s=n.key),t>0){var a=o(this.slabs[t-1],r);a&&(s?c(a.key,s)>0&&(s=a.key,e=a.value):(e=a.value,s=a.key))}var u=this.horizontal[t];if(u.length>0){var f=h.ge(u,r[1],i);if(f<u.length){var p=u[f];if(r[1]===p.y){if(p.closed)return p.index;for(;f<u.length-1&&u[f+1].y===r[1];)if(f+=1,p=u[f],p.closed)return p.index;if(p.y===r[1]&&!p.start){if(f+=1,f>=u.length)return e;p=u[f]}}if(p.start)if(s){var g=l(s[0],s[1],[r[0],p.y]);s[0][0]>s[1][0]&&(g=-g),g>0&&(e=p.index)}else e=p.index;else p.y!==r[1]&&(e=p.index)}}}return e}},{"./lib/order-segments":113,"binary-search-bounds":111,"functional-red-black-tree":114,"robust-orientation":120}],116:[function(r,t,n){function e(){return!0}function i(r){return function(t,n){var i=r[t];return i?!!i.queryPoint(n,e):!1}}function o(r){for(var t={},n=0;n<r.length;++n){var e=r[n],o=e[0][0],s=e[0][1],a=e[1][1],u=[Math.min(s,a),Math.max(s,a)];o in t?t[o].push(u):t[o]=[u]}for(var h={},f=Object.keys(t),n=0;n<f.length;++n){var l=t[f[n]];h[f[n]]=p(l)}return i(h)}function s(r,t){return function(n){var e=g.le(t,n[0]);if(0>e)return 1;var i=r[e];if(!i){if(!(e>0&&t[e]===n[0]))return 1;i=r[e-1]}for(var o=1;i;){var s=i.key,a=l(n,s[0],s[1]);if(s[0][0]<s[1][0])if(0>a)i=i.left;else{if(!(a>0))return 0;o=-1,i=i.right}else if(a>0)i=i.left;else{if(!(0>a))return 0;o=1,i=i.right}}return o}}function a(r){return 1}function u(r){return function(t){return r(t[0],t[1])?0:1}}function h(r,t){return function(n){ | |
return r(n[0],n[1])?0:t(n)}}function f(r){for(var t=r.length,n=[],e=[],i=0;t>i;++i)for(var f=r[i],l=f.length,p=l-1,g=0;l>g;p=g++){var v=f[p],d=f[g];v[0]===d[0]?e.push([v,d]):n.push([v,d])}if(0===n.length)return 0===e.length?a:u(o(e));var y=c(n),m=s(y.slabs,y.coordinates);return 0===e.length?m:h(o(e),m)}t.exports=f;var l=r("robust-orientation")[3],c=r("slab-decomposition"),p=r("interval-tree-1d"),g=r("binary-search-bounds")},{"binary-search-bounds":111,"interval-tree-1d":112,"robust-orientation":120,"slab-decomposition":115}],117:[function(r,t,n){arguments[4][43][0].apply(n,arguments)},{dup:43}],118:[function(r,t,n){arguments[4][44][0].apply(n,arguments)},{dup:44,"two-product":122,"two-sum":117}],119:[function(r,t,n){arguments[4][45][0].apply(n,arguments)},{dup:45}],120:[function(r,t,n){arguments[4][53][0].apply(n,arguments)},{dup:53,"robust-scale":118,"robust-subtract":119,"robust-sum":121,"two-product":122}],121:[function(r,t,n){arguments[4][46][0].apply(n,arguments)},{dup:46}],122:[function(r,t,n){arguments[4][47][0].apply(n,arguments)},{dup:47}],123:[function(r,t,n){arguments[4][11][0].apply(n,arguments)},{dup:11}],124:[function(r,t,n){"use strict";function e(r,t){for(var n=new Array(r),e=0;r>e;++e)n[e]=t;return n}function i(r){for(var t=new Array(r),n=0;r>n;++n)t[n]=[];return t}function o(r,t){function n(r){for(var n=r.length,e=[0],i=0;n>i;++i){var o=t[r[i]],s=t[r[(i+1)%n]],a=h(-o[0],o[1]),u=h(-o[0],s[1]),l=h(s[0],o[1]),c=h(s[0],s[1]);e=f(e,f(f(a,u),f(l,c)))}return e[e.length-1]>0}function o(r){for(var t=r.length,n=0;t>n;++n)if(!S[r[n]])return!1;return!0}var p=c(r,t);r=p[0],t=p[1];for(var g=t.length,v=(r.length,s(r,t.length)),d=0;g>d;++d)if(v[d].length%2===1)throw new Error("planar-graph-to-polyline: graph must be manifold");var y=a(r,t);y=y.filter(n);for(var m=y.length,b=new Array(m),w=new Array(m),d=0;m>d;++d){b[d]=d;var _=new Array(m),A=y[d].map(function(r){return t[r]}),x=u([A]),E=0;r:for(var j=0;m>j;++j)if(_[j]=0,d!==j){for(var k=y[j],I=k.length,M=0;I>M;++M){var P=x(t[k[M]]);if(0!==P){0>P&&(_[j]=1,E+=1);continue r}}_[j]=1,E+=1}w[d]=[E,d,_]}w.sort(function(r,t){return t[0]-r[0]});for(var d=0;m>d;++d)for(var _=w[d],B=_[1],R=_[2],j=0;m>j;++j)R[j]&&(b[j]=B);for(var T=i(m),d=0;m>d;++d)T[d].push(b[d]),T[b[d]].push(d);for(var U={},S=e(g,!1),d=0;m>d;++d)for(var k=y[d],I=k.length,j=0;I>j;++j){var L=k[j],V=k[(j+1)%I],N=Math.min(L,V)+":"+Math.max(L,V);if(N in U){var F=U[N];T[F].push(d),T[d].push(F),S[L]=S[V]=!0}else U[N]=d}for(var O=[],C=e(m,-1),d=0;m>d;++d)b[d]!==d||o(y[d])?C[d]=-1:(O.push(d),C[d]=0);for(var p=[];O.length>0;){var q=O.pop(),D=T[q];l(D,function(r,t){return r-t});var Y,z=D.length,G=C[q];if(0===G){var k=y[q];Y=[k]}for(var d=0;z>d;++d){var H=D[d];if(!(C[H]>=0)&&(C[H]=1^G,O.push(H),0===G)){var k=y[H];o(k)||(k.reverse(),Y.push(k))}}0===G&&p.push(Y)}return p}t.exports=o;var s=r("edges-to-adjacency-list"),a=r("planar-dual"),u=r("point-in-big-polygon"),h=r("two-product"),f=r("robust-sum"),l=r("uniq"),c=r("./lib/trim-leaves")},{"./lib/trim-leaves":103,"edges-to-adjacency-list":104,"planar-dual":105,"point-in-big-polygon":116,"robust-sum":121,"two-product":122,uniq:123}],125:[function(r,t,n){arguments[4][43][0].apply(n,arguments)},{dup:43}],126:[function(r,t,n){arguments[4][44][0].apply(n,arguments)},{dup:44,"two-product":129,"two-sum":125}],127:[function(r,t,n){arguments[4][45][0].apply(n,arguments)},{dup:45}],128:[function(r,t,n){arguments[4][46][0].apply(n,arguments)},{dup:46}],129:[function(r,t,n){arguments[4][47][0].apply(n,arguments)},{dup:47}],130:[function(r,t,n){arguments[4][53][0].apply(n,arguments)},{dup:53,"robust-scale":126,"robust-subtract":127,"robust-sum":128,"two-product":129}],131:[function(r,t,n){arguments[4][15][0].apply(n,arguments)},{dup:15}],132:[function(r,t,n){"use strict";"use restrict";function e(r){this.roots=new Array(r),this.ranks=new Array(r);for(var t=0;r>t;++t)this.roots[t]=t,this.ranks[t]=0}t.exports=e,e.prototype.length=function(){return this.roots.length},e.prototype.makeSet=function(){var r=this.roots.length;return this.roots.push(r),this.ranks.push(0),r},e.prototype.find=function(r){for(var t=this.roots;t[r]!==r;){var n=t[r];t[r]=t[n],r=n}return r},e.prototype.link=function(r,t){var n=this.find(r),e=this.find(t);if(n!==e){var i=this.ranks,o=this.roots,s=i[n],a=i[e];a>s?o[n]=e:s>a?o[e]=n:(o[e]=n,++i[n])}}},{}],133:[function(r,t,n){"use strict";"use restrict";function e(r){for(var t=0,n=Math.max,e=0,i=r.length;i>e;++e)t=n(t,r[e].length);return t-1}function i(r){for(var t=-1,n=Math.max,e=0,i=r.length;i>e;++e)for(var o=r[e],s=0,a=o.length;a>s;++s)t=n(t,o[s]);return t+1}function o(r){for(var t=new Array(r.length),n=0,e=r.length;e>n;++n)t[n]=r[n].slice(0);return t}function s(r,t){var n=r.length,e=r.length-t.length,i=Math.min;if(e)return e;switch(n){case 0:return 0;case 1:return r[0]-t[0];case 2:var o=r[0]+r[1]-t[0]-t[1];return o?o:i(r[0],r[1])-i(t[0],t[1]);case 3:var s=r[0]+r[1],a=t[0]+t[1];if(o=s+r[2]-(a+t[2]))return o;var u=i(r[0],r[1]),h=i(t[0],t[1]),o=i(u,r[2])-i(h,t[2]);return o?o:i(u+r[2],s)-i(h+t[2],a);default:var f=r.slice(0);f.sort();var l=t.slice(0);l.sort();for(var c=0;n>c;++c)if(e=f[c]-l[c])return e;return 0}}function a(r,t){return s(r[0],t[0])}function u(r,t){if(t){for(var n=r.length,e=new Array(n),i=0;n>i;++i)e[i]=[r[i],t[i]];e.sort(a);for(var i=0;n>i;++i)r[i]=e[i][0],t[i]=e[i][1];return r}return r.sort(s),r}function h(r){if(0===r.length)return[];for(var t=1,n=r.length,e=1;n>e;++e){var i=r[e];if(s(i,r[e-1])){if(e===t){t++;continue}r[t++]=i}}return r.length=t,r}function f(r,t){for(var n=0,e=r.length-1,i=-1;e>=n;){var o=n+e>>1,a=s(r[o],t);0>=a?(0===a&&(i=o),n=o+1):a>0&&(e=o-1)}return i}function l(r,t){for(var n=new Array(r.length),e=0,i=n.length;i>e;++e)n[e]=[];for(var o=[],e=0,a=t.length;a>e;++e)for(var u=t[e],h=u.length,l=1,c=1<<h;c>l;++l){o.length=b.popCount(l);for(var p=0,g=0;h>g;++g)l&1<<g&&(o[p++]=u[g]);var v=f(r,o);if(!(0>v))for(;;)if(n[v++].push(e),v>=r.length||0!==s(r[v],o))break}return n}function c(r,t){if(!t)return l(h(g(r,0)),r,0);for(var n=new Array(t),e=0;t>e;++e)n[e]=[];for(var e=0,i=r.length;i>e;++e)for(var o=r[e],s=0,a=o.length;a>s;++s)n[o[s]].push(e);return n}function p(r){for(var t=[],n=0,e=r.length;e>n;++n)for(var i=r[n],o=0|i.length,s=1,a=1<<o;a>s;++s){for(var h=[],f=0;o>f;++f)s>>>f&1&&h.push(i[f]);t.push(h)}return u(t)}function g(r,t){if(0>t)return[];for(var n=[],e=(1<<t+1)-1,i=0;i<r.length;++i)for(var o=r[i],s=e;s<1<<o.length;s=b.nextCombination(s)){for(var a=new Array(t+1),h=0,f=0;f<o.length;++f)s&1<<f&&(a[h++]=o[f]);n.push(a)}return u(n)}function v(r){for(var t=[],n=0,e=r.length;e>n;++n)for(var i=r[n],o=0,s=i.length;s>o;++o){for(var a=new Array(i.length-1),h=0,f=0;s>h;++h)h!==o&&(a[f++]=i[h]);t.push(a)}return u(t)}function d(r,t){for(var n=new w(t),e=0;e<r.length;++e)for(var i=r[e],o=0;o<i.length;++o)for(var s=o+1;s<i.length;++s)n.link(i[o],i[s]);for(var a=[],u=n.ranks,e=0;e<u.length;++e)u[e]=-1;for(var e=0;e<r.length;++e){var h=n.find(r[e][0]);u[h]<0?(u[h]=a.length,a.push([r[e].slice(0)])):a[u[h]].push(r[e].slice(0))}return a}function y(r){for(var t=h(u(g(r,0))),n=new w(t.length),e=0;e<r.length;++e)for(var i=r[e],o=0;o<i.length;++o)for(var s=f(t,[i[o]]),a=o+1;a<i.length;++a)n.link(s,f(t,[i[a]]));for(var l=[],c=n.ranks,e=0;e<c.length;++e)c[e]=-1;for(var e=0;e<r.length;++e){var p=n.find(f(t,[r[e][0]]));c[p]<0?(c[p]=l.length,l.push([r[e].slice(0)])):l[c[p]].push(r[e].slice(0))}return l}function m(r,t){return t?d(r,t):y(r)}var b=r("bit-twiddle"),w=r("union-find");n.dimension=e,n.countVertices=i,n.cloneCells=o,n.compareCells=s,n.normalize=u,n.unique=h,n.findCell=f,n.incidence=l,n.dual=c,n.explode=p,n.skeleton=g,n.boundary=v,n.connectedComponents=m},{"bit-twiddle":131,"union-find":132}],134:[function(r,t,n){"use strict";function e(r,t,n){var e=Math.abs(o(r,t,n)),i=Math.sqrt(Math.pow(t[0]-n[0],2)+Math.pow(t[1]-n[1],2));return e/i}function i(r,t,n){function i(r){if(w[r])return 1/0;var n=y[r],i=m[r];return 0>n||0>i?1/0:e(t[r],t[n],t[i])}function o(r,t){var n=j[r],e=j[t];j[r]=e,j[t]=n,k[n]=t,k[e]=r}function a(r){return b[j[r]]}function u(r){return 1&r?r-1>>1:(r>>1)-1}function h(r){for(var t=a(r);;){var n=t,e=2*r+1,i=2*(r+1),s=r;if(M>e){var u=a(e);n>u&&(s=e,n=u)}if(M>i){var h=a(i);n>h&&(s=i)}if(s===r)return r;o(r,s),r=s}}function f(r){for(var t=a(r);r>0;){var n=u(r);if(n>=0){var e=a(n);if(e>t){o(r,n),r=n;continue}}return r}}function l(){if(M>0){var r=j[0];return o(0,M-1),M-=1,h(0),r}return-1}function c(r,t){var n=j[r];return b[n]===t?r:(b[n]=-(1/0),f(r),l(),b[n]=t,M+=1,f(M-1))}function p(r){if(!w[r]){w[r]=!0;var t=y[r],n=m[r];y[n]>=0&&(y[n]=t),m[t]>=0&&(m[t]=n),k[t]>=0&&c(k[t],i(t)),k[n]>=0&&c(k[n],i(n))}}function g(r,t){if(r[t]<0)return t;var n=t,e=t;do{var i=r[e];if(!w[e]||0>i||i===e)break;if(e=i,i=r[e],!w[e]||0>i||i===e)break;e=i,n=r[n]}while(n!==e);for(var o=t;o!==e;o=r[o])r[o]=e;return e}for(var v=t.length,d=r.length,y=new Array(v),m=new Array(v),b=new Array(v),w=new Array(v),_=0;v>_;++_)y[_]=m[_]=-1,b[_]=1/0,w[_]=!1;for(var _=0;d>_;++_){var A=r[_];if(2!==A.length)throw new Error("Input must be a graph");var x=A[1],E=A[0];-1!==m[E]?m[E]=-2:m[E]=x,-1!==y[x]?y[x]=-2:y[x]=E}for(var j=[],k=new Array(v),_=0;v>_;++_){var I=b[_]=i(_);1/0>I?(k[_]=j.length,j.push(_)):k[_]=-1}for(var M=j.length,_=M>>1;_>=0;--_)h(_);for(;;){var P=l();if(0>P||b[P]>n)break;p(P)}for(var B=[],_=0;v>_;++_)w[_]||(k[_]=B.length,B.push(t[_].slice()));var R=(B.length,[]);return r.forEach(function(r){var t=g(y,r[0]),n=g(m,r[1]);if(t>=0&&n>=0&&t!==n){var e=k[t],i=k[n];e!==i&&R.push([e,i])}}),s.unique(s.normalize(R)),{positions:B,edges:R}}t.exports=i;var o=r("robust-orientation"),s=r("simplicial-complex")},{"robust-orientation":130,"simplicial-complex":133}],135:[function(r,t,n){"use strict";function e(r){return"a"+r}function i(r){return"d"+r}function o(r,t){return"c"+r+"_"+t}function s(r){return"s"+r}function a(r,t){return"t"+r+"_"+t}function u(r){return"o"+r}function h(r){return"x"+r}function f(r){return"p"+r}function l(r,t){return"d"+r+"_"+t}function c(r){return"i"+r}function p(r,t){return"u"+r+"_"+t}function g(r){return"b"+r}function v(r){return"y"+r}function d(r){return"e"+r}function y(r){return"v"+r}function m(r,t,n){for(var e=0,i=0;r>i;++i)t&1<<i&&(e|=1<<n[i]);return e}function b(r,t,n,b,w,M){function P(r,t){F.push("for(",c(w[r]),"=",t,";",c(w[r]),"<",s(w[r]),";","++",c(w[r]),"){")}function B(r){for(var t=0;L>t;++t)F.push(f(t),"+=",p(t,w[r]),";");F.push("}")}function R(r){for(var t=r-1;t>=0;--t)P(t,0);for(var n=[],t=0;L>t;++t)M[t]?n.push(i(t)+".get("+f(t)+")"):n.push(i(t)+"["+f(t)+"]");for(var t=0;b>t;++t)n.push(h(t));F.push(x,"[",k,"++]=phase(",n.join(),");");for(var t=0;r>t;++t)B(t);for(var e=0;L>e;++e)F.push(f(e),"+=",p(e,w[r]),";")}function T(r){for(var t=0;L>t;++t)M[t]?F.push(o(t,0),"=",i(t),".get(",f(t),");"):F.push(o(t,0),"=",i(t),"[",f(t),"];");for(var n=[],t=0;L>t;++t)n.push(o(t,0));for(var t=0;b>t;++t)n.push(h(t));F.push(g(0),"=",x,"[",k,"]=phase(",n.join(),");");for(var e=1;1<<V>e;++e)F.push(g(e),"=",x,"[",k,"+",d(e),"];");for(var s=[],e=1;1<<V>e;++e)s.push("("+g(0)+"!=="+g(e)+")");F.push("if(",s.join("||"),"){");for(var a=[],t=0;V>t;++t)a.push(c(t));for(var t=0;L>t;++t){a.push(o(t,0));for(var e=1;1<<V>e;++e)M[t]?F.push(o(t,e),"=",i(t),".get(",f(t),"+",l(t,e),");"):F.push(o(t,e),"=",i(t),"[",f(t),"+",l(t,e),"];"),a.push(o(t,e))}for(var t=0;1<<V>t;++t)a.push(g(t));for(var t=0;b>t;++t)a.push(h(t));F.push("vertex(",a.join(),");",y(0),"=",A,"[",k,"]=",E,"++;");for(var u=(1<<V)-1,p=g(u),e=0;V>e;++e)if(0===(r&~(1<<e))){for(var v=u^1<<e,m=g(v),w=[],_=v;_>0;_=_-1&v)w.push(A+"["+k+"+"+d(_)+"]");w.push(y(0));for(var _=0;L>_;++_)1&e?w.push(o(_,u),o(_,v)):w.push(o(_,v),o(_,u));1&e?w.push(p,m):w.push(m,p);for(var _=0;b>_;++_)w.push(h(_));F.push("if(",p,"!==",m,"){","face(",w.join(),")}")}F.push("}",k,"+=1;")}function U(){for(var r=1;1<<V>r;++r)F.push(I,"=",d(r),";",d(r),"=",v(r),";",v(r),"=",I,";")}function S(r,t){if(0>r)return void T(t);R(r),F.push("if(",s(w[r]),">0){",c(w[r]),"=1;"),S(r-1,t|1<<w[r]);for(var n=0;L>n;++n)F.push(f(n),"+=",p(n,w[r]),";");r===V-1&&(F.push(k,"=0;"),U()),P(r,2),S(r-1,t),r===V-1&&(F.push("if(",c(w[V-1]),"&1){",k,"=0;}"),U()),B(r),F.push("}")}var L=M.length,V=w.length;if(2>V)throw new Error("ndarray-extract-contour: Dimension must be at least 2");for(var N="extractContour"+w.join("_"),F=[],O=[],C=[],q=0;L>q;++q)C.push(e(q));for(var q=0;b>q;++q)C.push(h(q));for(var q=0;V>q;++q)O.push(s(q)+"="+e(0)+".shape["+q+"]|0");for(var q=0;L>q;++q){O.push(i(q)+"="+e(q)+".data",u(q)+"="+e(q)+".offset|0");for(var D=0;V>D;++D)O.push(a(q,D)+"="+e(q)+".stride["+D+"]|0")}for(var q=0;L>q;++q){O.push(f(q)+"="+u(q)),O.push(o(q,0));for(var D=1;1<<V>D;++D){for(var Y=[],z=0;V>z;++z)D&1<<z&&Y.push("-"+a(q,z));O.push(l(q,D)+"=("+Y.join("")+")|0"),O.push(o(q,D)+"=0")}}for(var q=0;L>q;++q)for(var D=0;V>D;++D){var G=[a(q,w[D])];D>0&&G.push(a(q,w[D-1])+"*"+s(w[D-1])),O.push(p(q,w[D])+"=("+G.join("-")+")|0")}for(var q=0;V>q;++q)O.push(c(q)+"=0");O.push(E+"=0");for(var H=["2"],q=V-2;q>=0;--q)H.push(s(w[q]));O.push(j+"=("+H.join("*")+")|0",x+"=mallocUint32("+j+")",A+"=mallocUint32("+j+")",k+"=0"),O.push(g(0)+"=0");for(var D=1;1<<V>D;++D){for(var W=[],Q=[],z=0;V>z;++z)D&1<<z&&(0===Q.length?W.push("1"):W.unshift(Q.join("*"))),Q.push(s(w[z]));var K="";W[0].indexOf(s(w[V-2]))<0&&(K="-");var X=m(V,D,w);O.push(d(X)+"=(-"+W.join("-")+")|0",v(X)+"=("+K+W.join("-")+")|0",g(X)+"=0")}O.push(y(0)+"=0",I+"=0"),S(V-1,0),F.push("freeUint32(",A,");freeUint32(",x,");");var J=["'use strict';","function ",N,"(",C.join(),"){","var ",O.join(),";",F.join(""),"}","return ",N].join(""),Z=new Function("vertex","face","phase","mallocUint32","freeUint32",J);return Z(r,t,n,_.mallocUint32,_.freeUint32)}function w(r){function t(r){throw new Error("ndarray-extract-contour: "+r)}"object"!=typeof r&&t("Must specify arguments");var n=r.order;Array.isArray(n)||t("Must specify order");var e=r.arrayArguments||1;1>e&&t("Must have at least one array argument");var i=r.scalarArguments||0;0>i&&t("Scalar arg count must be > 0"),"function"!=typeof r.vertex&&t("Must specify vertex creation function"),"function"!=typeof r.cell&&t("Must specify cell creation function"),"function"!=typeof r.phase&&t("Must specify phase function");for(var o=r.getters||[],s=new Array(e),a=0;e>a;++a)o.indexOf(a)>=0?s[a]=!0:s[a]=!1;return b(r.vertex,r.cell,r.phase,i,n,s)}var _=r("typedarray-pool");t.exports=w;var A="V",x="P",E="N",j="Q",k="X",I="T"},{"typedarray-pool":138}],136:[function(r,t,n){arguments[4][15][0].apply(n,arguments)},{dup:15}],137:[function(r,t,n){arguments[4][16][0].apply(n,arguments)},{dup:16}],138:[function(r,t,n){arguments[4][17][0].apply(n,arguments)},{"bit-twiddle":136,buffer:2,dup:17}],139:[function(r,t,n){function e(r){if(0>r)return Number("0/0");for(var t=a[0],n=a.length-1;n>0;--n)t+=a[n]/(r+n);var e=r+s+.5;return.5*Math.log(2*Math.PI)+(r+.5)*Math.log(e)-e+Math.log(t)-Math.log(r)}var i=7,o=[.9999999999998099,676.5203681218851,-1259.1392167224028,771.3234287776531,-176.6150291621406,12.507343278686905,-.13857109526572012,9984369578019572e-21,1.5056327351493116e-7],s=607/128,a=[.9999999999999971,57.15623566586292,-59.59796035547549,14.136097974741746,-.4919138160976202,3399464998481189e-20,4652362892704858e-20,-9837447530487956e-20,.0001580887032249125,-.00021026444172410488,.00021743961811521265,-.0001643181065367639,8441822398385275e-20,-26190838401581408e-21,36899182659531625e-22];t.exports=function u(r){if(.5>r)return Math.PI/(Math.sin(Math.PI*r)*u(1-r));if(r>100)return Math.exp(e(r));r-=1;for(var t=o[0],n=1;i+2>n;n++)t+=o[n]/(r+n);var s=r+i+.5;return Math.sqrt(2*Math.PI)*Math.pow(s,r+.5)*Math.exp(-s)*t},t.exports.log=e},{}],140:[function(r,t,n){arguments[4][15][0].apply(n,arguments)},{dup:15}],141:[function(r,t,n){arguments[4][16][0].apply(n,arguments)},{dup:16}],142:[function(r,t,n){arguments[4][17][0].apply(n,arguments)},{"bit-twiddle":140,buffer:2,dup:17}],143:[function(r,t,n){"use strict";function e(r){var t=r.length;if(i>t){for(var n=1,e=0;t>e;++e)for(var s=0;e>s;++s)if(r[e]<r[s])n=-n;else if(r[e]===r[s])return 0;return n}for(var a=o.mallocUint8(t),e=0;t>e;++e)a[e]=0;for(var n=1,e=0;t>e;++e)if(!a[e]){var u=1;a[e]=1;for(var s=r[e];s!==e;s=r[s]){if(a[s])return o.freeUint8(a),0;u+=1,a[s]=1}1&u||(n=-n)}return o.freeUint8(a),n}t.exports=e;var i=32,o=r("typedarray-pool")},{"typedarray-pool":142}],144:[function(r,t,n){"use strict";function e(r){var t=r.length;switch(t){case 0:case 1:return 0;case 2:return r[1]}var n,e,i,a=o.mallocUint32(t),u=o.mallocUint32(t),h=0;for(s(r,u),i=0;t>i;++i)a[i]=r[i];for(i=t-1;i>0;--i)e=u[i],n=a[i],a[i]=a[e],a[e]=n,u[i]=u[n],u[n]=e,h=(h+n)*i;return o.freeUint32(u),o.freeUint32(a),h}function i(r,t,n){switch(r){case 0:return n?n:[];case 1:return n?(n[0]=0,n):[0];case 2:return n?(t?(n[0]=0,n[1]=1):(n[0]=1,n[1]=0),n):t?[0,1]:[1,0]}n=n||new Array(r);var e,i,o,s=1;for(n[0]=0,o=1;r>o;++o)n[o]=o,s=s*o|0;for(o=r-1;o>0;--o)e=t/s|0,t=t-e*s|0,s=s/o|0,i=0|n[o],n[o]=0|n[e],n[e]=0|i;return n}var o=r("typedarray-pool"),s=r("invert-permutation");n.rank=e,n.unrank=i},{"invert-permutation":145,"typedarray-pool":148}],145:[function(r,t,n){"use strict";function e(r,t){t=t||new Array(r.length);for(var n=0;n<r.length;++n)t[r[n]]=n;return t}t.exports=e},{}],146:[function(r,t,n){arguments[4][15][0].apply(n,arguments)},{dup:15}],147:[function(r,t,n){arguments[4][16][0].apply(n,arguments)},{dup:16}],148:[function(r,t,n){arguments[4][17][0].apply(n,arguments)},{"bit-twiddle":146,buffer:2,dup:17}],149:[function(r,t,n){"use strict";function e(r){if(0>r)return[];if(0===r)return[[0]];for(var t=0|Math.round(s(r+1)),n=[],e=0;t>e;++e){for(var a=i.unrank(r,e),u=[0],h=0,f=0;f<a.length;++f)h+=1<<a[f],u.push(h);o(a)<1&&(u[0]=h,u[r]=0),n.push(u)}return n}t.exports=e;var i=r("permutation-rank"),o=r("permutation-parity"),s=r("gamma")},{gamma:139,"permutation-parity":143,"permutation-rank":144}],150:[function(r,t,n){t.exports=r("cwise-compiler")({args:["array",{offset:[1],array:0},"scalar","scalar","index"],pre:{body:"{}",args:[],thisVars:[],localVars:[]},post:{body:"{}",args:[],thisVars:[],localVars:[]},body:{body:"{\n var _inline_1_da = _inline_1_arg0_ - _inline_1_arg3_\n var _inline_1_db = _inline_1_arg1_ - _inline_1_arg3_\n if((_inline_1_da >= 0) !== (_inline_1_db >= 0)) {\n _inline_1_arg2_.push(_inline_1_arg4_[0] + 0.5 + 0.5 * (_inline_1_da + _inline_1_db) / (_inline_1_da - _inline_1_db))\n }\n }",args:[{name:"_inline_1_arg0_",lvalue:!1,rvalue:!0,count:1},{name:"_inline_1_arg1_",lvalue:!1,rvalue:!0,count:1},{name:"_inline_1_arg2_",lvalue:!1,rvalue:!0,count:1},{name:"_inline_1_arg3_",lvalue:!1,rvalue:!0,count:2},{name:"_inline_1_arg4_",lvalue:!1,rvalue:!0,count:1}],thisVars:[],localVars:["_inline_1_da","_inline_1_db"]},funcName:"zeroCrossings"})},{"cwise-compiler":151}],151:[function(r,t,n){arguments[4][8][0].apply(n,arguments)},{"./lib/thunk.js":153,dup:8}],152:[function(r,t,n){arguments[4][9][0].apply(n,arguments)},{dup:9,uniq:154}],153:[function(r,t,n){arguments[4][10][0].apply(n,arguments)},{"./compile.js":152,dup:10}],154:[function(r,t,n){arguments[4][11][0].apply(n,arguments)},{dup:11}],155:[function(r,t,n){"use strict";function e(r,t){var n=[];return t=+t||0,i(r.hi(r.shape[0]-1),n,t),n}t.exports=e;var i=r("./lib/zc-core")},{"./lib/zc-core":150}],156:[function(r,t,n){"use strict";function e(r,t){var n=r.length,e=["'use strict';"],i="surfaceNets"+r.join("_")+"d"+t;e.push("var contour=genContour({","order:[",r.join(),"],","scalarArguments: 3,","phase:function phaseFunc(p,a,b,c) { return (p > c)|0 },"),"generic"===t&&e.push("getters:[0],");for(var o=[],u=[],h=0;n>h;++h)o.push("d"+h),u.push("d"+h);for(var h=0;1<<n>h;++h)o.push("v"+h),u.push("v"+h);for(var h=0;1<<n>h;++h)o.push("p"+h),u.push("p"+h);o.push("a","b","c"),u.push("a","c"),e.push("vertex:function vertexFunc(",o.join(),"){");for(var f=[],h=0;1<<n>h;++h)f.push("(p"+h+"<<"+h+")");e.push("var m=(",f.join("+"),")|0;if(m===0||m===",(1<<(1<<n))-1,"){return}");var l=[],c=[];128>=1<<(1<<n)?(e.push("switch(m){"),c=e):e.push("switch(m>>>7){");for(var h=0;1<<(1<<n)>h;++h){if(1<<(1<<n)>128&&h%128===0){l.length>0&&c.push("}}");var p="vExtra"+l.length;e.push("case ",h>>>7,":",p,"(m&0x7f,",u.join(),");break;"),c=["function ",p,"(m,",u.join(),"){switch(m){"],l.push(c)}c.push("case ",127&h,":");for(var g=new Array(n),v=new Array(n),d=new Array(n),y=new Array(n),m=0,b=0;n>b;++b)g[b]=[],v[b]=[],d[b]=0,y[b]=0;for(var b=0;1<<n>b;++b)for(var w=0;n>w;++w){var _=b^1<<w;if(!(_>b)&&!(h&1<<_)!=!(h&1<<b)){var A=1;h&1<<_?v[w].push("v"+_+"-v"+b):(v[w].push("v"+b+"-v"+_),A=-A),0>A?(g[w].push("-v"+b+"-v"+_),d[w]+=2):(g[w].push("v"+b+"+v"+_),d[w]-=2),m+=1;for(var x=0;n>x;++x)x!==w&&(_&1<<x?y[x]+=1:y[x]-=1)}}for(var E=[],w=0;n>w;++w)if(0===g[w].length)E.push("d"+w+"-0.5");else{var j="";d[w]<0?j=d[w]+"*c":d[w]>0&&(j="+"+d[w]+"*c");var k=.5*(g[w].length/m),I=.5+.5*(y[w]/m);E.push("d"+w+"-"+I+"-"+k+"*("+g[w].join("+")+j+")/("+v[w].join("+")+")")}c.push("a.push([",E.join(),"]);","break;")}e.push("}},"),l.length>0&&c.push("}}");for(var M=[],h=0;1<<n-1>h;++h)M.push("v"+h);M.push("c0","c1","p0","p1","a","b","c"),e.push("cell:function cellFunc(",M.join(),"){");var P=a(n-1);e.push("if(p0){b.push(",P.map(function(r){return"["+r.map(function(r){return"v"+r})+"]"}).join(),")}else{b.push(",P.map(function(r){var t=r.slice();return t.reverse(),"["+t.map(function(r){return"v"+r})+"]"}).join(),")}}});function ",i,"(array,level){var verts=[],cells=[];contour(array,verts,cells,level);return {positions:verts,cells:cells};} return ",i,";");for(var h=0;h<l.length;++h)e.push(l[h].join(""));var B=new Function("genContour",e.join(""));return B(s)}function i(r,t){for(var n=u(r,t),e=n.length,i=new Array(e),o=new Array(e),s=0;e>s;++s)i[s]=[n[s]],o[s]=[s];return{positions:i,cells:o}}function o(r,t){if(r.dimension<=0)return{positions:[],cells:[]};if(1===r.dimension)return i(r,t);var n=r.order.join()+"-"+r.dtype,o=h[n],t=+t||0;return o||(o=h[n]=e(r.order,r.dtype)),o(r,t)}t.exports=o;var s=r("ndarray-extract-contour"),a=r("triangulate-hypercube"),u=r("zero-crossings"),h={}},{"ndarray-extract-contour":135,"triangulate-hypercube":149,"zero-crossings":155}]},{},[1]); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment