(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 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 return b64[len - 2] === '=' ? 2 : b64[len - 1] === '=' ? 1 : 0 } function byteLength (b64) { // base64 is 4/3 + up to two characters of the original data return b64.length * 3 / 4 - placeHoldersCount(b64) } function toByteArray (b64) { var i, j, l, tmp, placeHolders, arr var len = b64.length placeHolders = placeHoldersCount(b64) arr = new Arr(len * 3 / 4 - placeHolders) // if there are placeholders, only get up to the last complete 4 chars l = placeHolders > 0 ? len - 4 : len var L = 0 for (i = 0, j = 0; i < l; i += 4, j += 3) { tmp = (revLookup[b64.charCodeAt(i)] << 18) | (revLookup[b64.charCodeAt(i + 1)] << 12) | (revLookup[b64.charCodeAt(i + 2)] << 6) | revLookup[b64.charCodeAt(i + 3)] arr[L++] = (tmp >> 16) & 0xFF arr[L++] = (tmp >> 8) & 0xFF arr[L++] = tmp & 0xFF } if (placeHolders === 2) { tmp = (revLookup[b64.charCodeAt(i)] << 2) | (revLookup[b64.charCodeAt(i + 1)] >> 4) arr[L++] = tmp & 0xFF } else if (placeHolders === 1) { tmp = (revLookup[b64.charCodeAt(i)] << 10) | (revLookup[b64.charCodeAt(i + 1)] << 4) | (revLookup[b64.charCodeAt(i + 2)] >> 2) arr[L++] = (tmp >> 8) & 0xFF arr[L++] = tmp & 0xFF } return arr } function tripletToBase64 (num) { return lookup[num >> 18 & 0x3F] + lookup[num >> 12 & 0x3F] + lookup[num >> 6 & 0x3F] + lookup[num & 0x3F] } function encodeChunk (uint8, start, end) { var tmp var output = [] for (var i = start; i < end; i += 3) { tmp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2]) output.push(tripletToBase64(tmp)) } return output.join('') } function fromByteArray (uint8) { var tmp var len = uint8.length var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes var output = '' var parts = [] var maxChunkLength = 16383 // must be multiple of 3 // go through the array every three bytes, we'll deal with trailing stuff later for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) { parts.push(encodeChunk(uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength))) } // pad the end with zeros, but make sure to not forget the extra bytes if (extraBytes === 1) { tmp = uint8[len - 1] output += lookup[tmp >> 2] output += lookup[(tmp << 4) & 0x3F] output += '==' } else if (extraBytes === 2) { tmp = (uint8[len - 2] << 8) + (uint8[len - 1]) output += lookup[tmp >> 10] output += lookup[(tmp >> 4) & 0x3F] output += lookup[(tmp << 2) & 0x3F] output += '=' } parts.push(output) return parts.join('') } },{}],3:[function(require,module,exports){ },{}],4:[function(require,module,exports){ arguments[4][3][0].apply(exports,arguments) },{"dup":3}],5:[function(require,module,exports){ (function (global){ 'use strict'; var buffer = require('buffer'); var Buffer = buffer.Buffer; var SlowBuffer = buffer.SlowBuffer; var MAX_LEN = buffer.kMaxLength || 2147483647; exports.alloc = function alloc(size, fill, encoding) { if (typeof Buffer.alloc === 'function') { return Buffer.alloc(size, fill, encoding); } if (typeof encoding === 'number') { throw new TypeError('encoding must not be number'); } if (typeof size !== 'number') { throw new TypeError('size must be a number'); } if (size > MAX_LEN) { throw new RangeError('size is too large'); } var enc = encoding; var _fill = fill; if (_fill === undefined) { enc = undefined; _fill = 0; } var buf = new Buffer(size); if (typeof _fill === 'string') { var fillBuf = new Buffer(_fill, enc); var flen = fillBuf.length; var i = -1; while (++i < size) { buf[i] = fillBuf[i % flen]; } } else { buf.fill(_fill); } return buf; } exports.allocUnsafe = function allocUnsafe(size) { if (typeof Buffer.allocUnsafe === 'function') { return Buffer.allocUnsafe(size); } if (typeof size !== 'number') { throw new TypeError('size must be a number'); } if (size > MAX_LEN) { throw new RangeError('size is too large'); } return new Buffer(size); } exports.from = function from(value, encodingOrOffset, length) { if (typeof Buffer.from === 'function' && (!global.Uint8Array || Uint8Array.from !== Buffer.from)) { return Buffer.from(value, encodingOrOffset, length); } if (typeof value === 'number') { throw new TypeError('"value" argument must not be a number'); } if (typeof value === 'string') { return new Buffer(value, encodingOrOffset); } if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) { var offset = encodingOrOffset; if (arguments.length === 1) { return new Buffer(value); } if (typeof offset === 'undefined') { offset = 0; } var len = length; if (typeof len === 'undefined') { len = value.byteLength - offset; } if (offset >= value.byteLength) { throw new RangeError('\'offset\' is out of bounds'); } if (len > value.byteLength - offset) { throw new RangeError('\'length\' is out of bounds'); } return new Buffer(value.slice(offset, offset + len)); } if (Buffer.isBuffer(value)) { var out = new Buffer(value.length); value.copy(out, 0, 0, value.length); return out; } if (value) { if (Array.isArray(value) || (typeof ArrayBuffer !== 'undefined' && value.buffer instanceof ArrayBuffer) || 'length' in value) { return new Buffer(value); } if (value.type === 'Buffer' && Array.isArray(value.data)) { return new Buffer(value.data); } } throw new TypeError('First argument must be a string, Buffer, ' + 'ArrayBuffer, Array, or array-like object.'); } exports.allocUnsafeSlow = function allocUnsafeSlow(size) { if (typeof Buffer.allocUnsafeSlow === 'function') { return Buffer.allocUnsafeSlow(size); } if (typeof size !== 'number') { throw new TypeError('size must be a number'); } if (size >= MAX_LEN) { throw new RangeError('size is too large'); } return new SlowBuffer(size); } }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{"buffer":6}],6:[function(require,module,exports){ /*! * The buffer module from node.js, for the browser. * * @author Feross Aboukhadijeh * @license MIT */ /* eslint-disable no-proto */ 'use strict' var base64 = require('base64-js') var ieee754 = require('ieee754') exports.Buffer = Buffer exports.SlowBuffer = SlowBuffer exports.INSPECT_MAX_BYTES = 50 var K_MAX_LENGTH = 0x7fffffff exports.kMaxLength = K_MAX_LENGTH /** * If `Buffer.TYPED_ARRAY_SUPPORT`: * === true Use Uint8Array implementation (fastest) * === false Print warning and recommend using `buffer` v4.x which has an Object * implementation (most compatible, even IE6) * * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+, * Opera 11.6+, iOS 4.2+. * * We report that the browser does not support typed arrays if the are not subclassable * using __proto__. Firefox 4-29 lacks support for adding new properties to `Uint8Array` * (See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438). IE 10 lacks support * for __proto__ and has a buggy typed array implementation. */ Buffer.TYPED_ARRAY_SUPPORT = typedArraySupport() if (!Buffer.TYPED_ARRAY_SUPPORT && typeof console !== 'undefined' && typeof console.error === 'function') { console.error( 'This browser lacks typed array (Uint8Array) support which is required by ' + '`buffer` v5.x. Use `buffer` v4.x if you require old browser support.' ) } function typedArraySupport () { // Can typed array instances can be augmented? try { var arr = new Uint8Array(1) arr.__proto__ = {__proto__: Uint8Array.prototype, foo: function () { return 42 }} return arr.foo() === 42 } catch (e) { return false } } function createBuffer (length) { if (length > K_MAX_LENGTH) { throw new RangeError('Invalid typed array length') } // Return an augmented `Uint8Array` instance var buf = new Uint8Array(length) buf.__proto__ = Buffer.prototype return buf } /** * The Buffer constructor returns instances of `Uint8Array` that have their * prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of * `Uint8Array`, so the returned instances will have all the node `Buffer` methods * and the `Uint8Array` methods. Square bracket notation works as expected -- it * returns a single octet. * * The `Uint8Array` prototype remains unmodified. */ function Buffer (arg, encodingOrOffset, length) { // Common case. if (typeof arg === 'number') { if (typeof encodingOrOffset === 'string') { throw new Error( 'If encoding is specified then the first argument must be a string' ) } return allocUnsafe(arg) } return from(arg, encodingOrOffset, length) } // Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97 if (typeof Symbol !== 'undefined' && Symbol.species && Buffer[Symbol.species] === Buffer) { Object.defineProperty(Buffer, Symbol.species, { value: null, configurable: true, enumerable: false, writable: false }) } Buffer.poolSize = 8192 // not used by this implementation function from (value, encodingOrOffset, length) { if (typeof value === 'number') { throw new TypeError('"value" argument must not be a number') } if (value instanceof ArrayBuffer) { return fromArrayBuffer(value, encodingOrOffset, length) } if (typeof value === 'string') { return fromString(value, encodingOrOffset) } return fromObject(value) } /** * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError * if value is a number. * Buffer.from(str[, encoding]) * Buffer.from(array) * Buffer.from(buffer) * Buffer.from(arrayBuffer[, byteOffset[, length]]) **/ Buffer.from = function (value, encodingOrOffset, length) { return from(value, encodingOrOffset, length) } // Note: Change prototype *after* Buffer.from is defined to workaround Chrome bug: // https://github.com/feross/buffer/pull/148 Buffer.prototype.__proto__ = Uint8Array.prototype Buffer.__proto__ = Uint8Array function assertSize (size) { if (typeof size !== 'number') { throw new TypeError('"size" argument must be a number') } else if (size < 0) { throw new RangeError('"size" argument must not be negative') } } function alloc (size, fill, encoding) { assertSize(size) if (size <= 0) { return createBuffer(size) } if (fill !== undefined) { // Only pay attention to encoding if it's a string. This // prevents accidentally sending in a number that would // be interpretted as a start offset. return typeof encoding === 'string' ? createBuffer(size).fill(fill, encoding) : createBuffer(size).fill(fill) } return createBuffer(size) } /** * Creates a new filled Buffer instance. * alloc(size[, fill[, encoding]]) **/ Buffer.alloc = function (size, fill, encoding) { return alloc(size, fill, encoding) } function allocUnsafe (size) { assertSize(size) return createBuffer(size < 0 ? 0 : checked(size) | 0) } /** * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance. * */ Buffer.allocUnsafe = function (size) { return allocUnsafe(size) } /** * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance. */ Buffer.allocUnsafeSlow = function (size) { return allocUnsafe(size) } function fromString (string, encoding) { if (typeof encoding !== 'string' || encoding === '') { encoding = 'utf8' } if (!Buffer.isEncoding(encoding)) { throw new TypeError('"encoding" must be a valid string encoding') } var length = byteLength(string, encoding) | 0 var buf = createBuffer(length) var actual = buf.write(string, encoding) if (actual !== length) { // Writing a hex string, for example, that contains invalid characters will // cause everything after the first invalid character to be ignored. (e.g. // 'abxxcd' will be treated as 'ab') buf = buf.slice(0, actual) } return buf } function fromArrayLike (array) { var length = array.length < 0 ? 0 : checked(array.length) | 0 var buf = createBuffer(length) for (var i = 0; i < length; i += 1) { buf[i] = array[i] & 255 } return buf } function fromArrayBuffer (array, byteOffset, length) { if (byteOffset < 0 || array.byteLength < byteOffset) { throw new RangeError('\'offset\' is out of bounds') } if (array.byteLength < byteOffset + (length || 0)) { throw new RangeError('\'length\' is out of bounds') } var buf if (byteOffset === undefined && length === undefined) { buf = new Uint8Array(array) } else if (length === undefined) { buf = new Uint8Array(array, byteOffset) } else { buf = new Uint8Array(array, byteOffset, length) } // Return an augmented `Uint8Array` instance buf.__proto__ = Buffer.prototype return buf } function fromObject (obj) { if (Buffer.isBuffer(obj)) { var len = checked(obj.length) | 0 var buf = createBuffer(len) if (buf.length === 0) { return buf } obj.copy(buf, 0, 0, len) return buf } if (obj) { if (isArrayBufferView(obj) || 'length' in obj) { if (typeof obj.length !== 'number' || numberIsNaN(obj.length)) { return createBuffer(0) } return fromArrayLike(obj) } if (obj.type === 'Buffer' && Array.isArray(obj.data)) { return fromArrayLike(obj.data) } } throw new TypeError('First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.') } function checked (length) { // Note: cannot use `length < K_MAX_LENGTH` here because that fails when // length is NaN (which is otherwise coerced to zero.) if (length >= K_MAX_LENGTH) { throw new RangeError('Attempt to allocate Buffer larger than maximum ' + 'size: 0x' + K_MAX_LENGTH.toString(16) + ' bytes') } return length | 0 } function SlowBuffer (length) { if (+length != length) { // eslint-disable-line eqeqeq length = 0 } return Buffer.alloc(+length) } Buffer.isBuffer = function isBuffer (b) { return b != null && b._isBuffer === true } 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 for (var i = 0, len = Math.min(x, y); i < len; ++i) { if (a[i] !== b[i]) { x = a[i] y = b[i] break } } if (x < y) return -1 if (y < x) return 1 return 0 } Buffer.isEncoding = function isEncoding (encoding) { switch (String(encoding).toLowerCase()) { case 'hex': case 'utf8': case 'utf-8': case 'ascii': case 'latin1': case 'binary': case 'base64': case 'ucs2': case 'ucs-2': case 'utf16le': case 'utf-16le': return true default: return false } } Buffer.concat = function concat (list, length) { if (!Array.isArray(list)) { throw new TypeError('"list" argument must be an Array of Buffers') } if (list.length === 0) { return Buffer.alloc(0) } var i if (length === undefined) { length = 0 for (i = 0; i < list.length; ++i) { length += list[i].length } } var buffer = Buffer.allocUnsafe(length) var pos = 0 for (i = 0; i < list.length; ++i) { var buf = list[i] if (!Buffer.isBuffer(buf)) { throw new TypeError('"list" argument must be an Array of Buffers') } buf.copy(buffer, pos) pos += buf.length } return buffer } function byteLength (string, encoding) { if (Buffer.isBuffer(string)) { return string.length } if (isArrayBufferView(string) || string instanceof ArrayBuffer) { return string.byteLength } 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 'latin1': case 'binary': return len case 'utf8': case 'utf-8': case undefined: 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 function slowToString (encoding, start, end) { var loweredCase = false // No need to verify that "this.length <= MAX_UINT32" since it's a read-only // property of a typed array. // This behaves neither like String nor Uint8Array in that we set start/end // to their upper/lower bounds if the value passed is out of range. // undefined is handled specially as per ECMA-262 6th Edition, // Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization. if (start === undefined || start < 0) { start = 0 } // Return early if start > this.length. Done here to prevent potential uint32 // coercion fail below. if (start > this.length) { return '' } if (end === undefined || end > this.length) { end = this.length } if (end <= 0) { return '' } // Force coersion to uint32. This will also coerce falsey/NaN values to 0. end >>>= 0 start >>>= 0 if (end <= start) { return '' } if (!encoding) encoding = 'utf8' while (true) { switch (encoding) { case 'hex': return hexSlice(this, start, end) case 'utf8': case 'utf-8': return utf8Slice(this, start, end) case 'ascii': return asciiSlice(this, start, end) case 'latin1': case 'binary': return latin1Slice(this, start, end) case 'base64': return base64Slice(this, start, end) case 'ucs2': case 'ucs-2': case 'utf16le': case 'utf-16le': return utf16leSlice(this, start, end) default: if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding) encoding = (encoding + '').toLowerCase() loweredCase = true } } } // This property is used by `Buffer.isBuffer` (and the `is-buffer` npm package) // to detect a Buffer instance. It's not possible to use `instanceof Buffer` // reliably in a browserify context because there could be multiple different // copies of the 'buffer' package in use. This method works even for Buffer // instances that were created from another copy of the `buffer` package. // See: https://github.com/feross/buffer/issues/154 Buffer.prototype._isBuffer = true function swap (b, n, m) { var i = b[n] b[n] = b[m] b[m] = i } Buffer.prototype.swap16 = function swap16 () { var len = this.length if (len % 2 !== 0) { throw new RangeError('Buffer size must be a multiple of 16-bits') } for (var i = 0; i < len; i += 2) { swap(this, i, i + 1) } return this } Buffer.prototype.swap32 = function swap32 () { var len = this.length if (len % 4 !== 0) { throw new RangeError('Buffer size must be a multiple of 32-bits') } for (var i = 0; i < len; i += 4) { swap(this, i, i + 3) swap(this, i + 1, i + 2) } return this } Buffer.prototype.swap64 = function swap64 () { var len = this.length if (len % 8 !== 0) { throw new RangeError('Buffer size must be a multiple of 64-bits') } for (var i = 0; i < len; i += 8) { swap(this, i, i + 7) swap(this, i + 1, i + 6) swap(this, i + 2, i + 5) swap(this, i + 3, i + 4) } return this } Buffer.prototype.toString = function toString () { var length = this.length if (length === 0) return '' if (arguments.length === 0) return utf8Slice(this, 0, length) return slowToString.apply(this, arguments) } Buffer.prototype.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.prototype.compare = function compare (target, start, end, thisStart, thisEnd) { if (!Buffer.isBuffer(target)) { throw new TypeError('Argument must be a Buffer') } if (start === undefined) { start = 0 } if (end === undefined) { end = target ? target.length : 0 } if (thisStart === undefined) { thisStart = 0 } if (thisEnd === undefined) { thisEnd = this.length } if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) { throw new RangeError('out of range index') } if (thisStart >= thisEnd && start >= end) { return 0 } if (thisStart >= thisEnd) { return -1 } if (start >= end) { return 1 } start >>>= 0 end >>>= 0 thisStart >>>= 0 thisEnd >>>= 0 if (this === target) return 0 var x = thisEnd - thisStart var y = end - start var len = Math.min(x, y) var thisCopy = this.slice(thisStart, thisEnd) var targetCopy = target.slice(start, end) for (var i = 0; i < len; ++i) { if (thisCopy[i] !== targetCopy[i]) { x = thisCopy[i] y = targetCopy[i] break } } if (x < y) return -1 if (y < x) return 1 return 0 } // Finds either the first index of `val` in `buffer` at offset >= `byteOffset`, // OR the last index of `val` in `buffer` at offset <= `byteOffset`. // // Arguments: // - buffer - a Buffer to search // - val - a string, Buffer, or number // - byteOffset - an index into `buffer`; will be clamped to an int32 // - encoding - an optional encoding, relevant is val is a string // - dir - true for indexOf, false for lastIndexOf function bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) { // Empty buffer means no match if (buffer.length === 0) return -1 // Normalize byteOffset if (typeof byteOffset === 'string') { encoding = byteOffset byteOffset = 0 } else if (byteOffset > 0x7fffffff) { byteOffset = 0x7fffffff } else if (byteOffset < -0x80000000) { byteOffset = -0x80000000 } byteOffset = +byteOffset // Coerce to Number. if (numberIsNaN(byteOffset)) { // byteOffset: it it's undefined, null, NaN, "foo", etc, search whole buffer byteOffset = dir ? 0 : (buffer.length - 1) } // Normalize byteOffset: negative offsets start from the end of the buffer if (byteOffset < 0) byteOffset = buffer.length + byteOffset if (byteOffset >= buffer.length) { if (dir) return -1 else byteOffset = buffer.length - 1 } else if (byteOffset < 0) { if (dir) byteOffset = 0 else return -1 } // Normalize val if (typeof val === 'string') { val = Buffer.from(val, encoding) } // Finally, search either indexOf (if dir is true) or lastIndexOf if (Buffer.isBuffer(val)) { // Special case: looking for empty string/buffer always fails if (val.length === 0) { return -1 } return arrayIndexOf(buffer, val, byteOffset, encoding, dir) } else if (typeof val === 'number') { val = val & 0xFF // Search for a byte value [0-255] if (typeof Uint8Array.prototype.indexOf === 'function') { if (dir) { return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset) } else { return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset) } } return arrayIndexOf(buffer, [ val ], byteOffset, encoding, dir) } throw new TypeError('val must be string, number or Buffer') } function arrayIndexOf (arr, val, byteOffset, encoding, dir) { var indexSize = 1 var arrLength = arr.length var valLength = val.length if (encoding !== undefined) { encoding = String(encoding).toLowerCase() if (encoding === 'ucs2' || encoding === 'ucs-2' || encoding === 'utf16le' || encoding === 'utf-16le') { if (arr.length < 2 || val.length < 2) { return -1 } indexSize = 2 arrLength /= 2 valLength /= 2 byteOffset /= 2 } } function read (buf, i) { if (indexSize === 1) { return buf[i] } else { return buf.readUInt16BE(i * indexSize) } } var i if (dir) { var foundIndex = -1 for (i = byteOffset; i < arrLength; i++) { if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) { if (foundIndex === -1) foundIndex = i if (i - foundIndex + 1 === valLength) return foundIndex * indexSize } else { if (foundIndex !== -1) i -= i - foundIndex foundIndex = -1 } } } else { if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength for (i = byteOffset; i >= 0; i--) { var found = true for (var j = 0; j < valLength; j++) { if (read(arr, i + j) !== read(val, j)) { found = false break } } if (found) return i } } return -1 } Buffer.prototype.includes = function includes (val, byteOffset, encoding) { return this.indexOf(val, byteOffset, encoding) !== -1 } Buffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) { return bidirectionalIndexOf(this, val, byteOffset, encoding, true) } Buffer.prototype.lastIndexOf = function lastIndexOf (val, byteOffset, encoding) { return bidirectionalIndexOf(this, val, byteOffset, encoding, false) } function hexWrite (buf, string, offset, length) { offset = Number(offset) || 0 var remaining = buf.length - offset if (!length) { length = remaining } else { length = Number(length) if (length > remaining) { length = remaining } } // must be an even number of digits var strLen = string.length if (strLen % 2 !== 0) throw new TypeError('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 (numberIsNaN(parsed)) return i buf[offset + i] = parsed } return i } function utf8Write (buf, string, offset, length) { return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length) } function asciiWrite (buf, string, offset, length) { return blitBuffer(asciiToBytes(string), buf, offset, length) } function latin1Write (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 } } else { throw new Error( 'Buffer.write(string, encoding, offset[, length]) is no longer supported' ) } var remaining = this.length - offset if (length === undefined || length > remaining) length = remaining if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) { throw new RangeError('Attempt to write outside buffer bounds') } if (!encoding) encoding = 'utf8' var loweredCase = false for (;;) { switch (encoding) { case 'hex': return hexWrite(this, string, offset, length) case 'utf8': case 'utf-8': return utf8Write(this, string, offset, length) case 'ascii': return asciiWrite(this, string, offset, length) case 'latin1': case 'binary': return latin1Write(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 latin1Slice (buf, start, end) { var ret = '' end = Math.min(buf.length, end) for (var i = start; i < end; ++i) { ret += String.fromCharCode(buf[i]) } return ret } function hexSlice (buf, start, end) { var len = buf.length if (!start || start < 0) start = 0 if (!end || end < 0 || end > len) end = len var out = '' for (var i = start; i < end; ++i) { out += 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 = this.subarray(start, end) // Return an augmented `Uint8Array` instance newBuf.__proto__ = Buffer.prototype return newBuf } /* * Need to make sure that buffer isn't trying to write out of bounds. */ function checkOffset (offset, ext, length) { if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint') if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length') } Buffer.prototype.readUIntLE = 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) { offset = offset >>> 0 if (!noAssert) checkOffset(offset, 1, this.length) return this[offset] } Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) { offset = offset >>> 0 if (!noAssert) checkOffset(offset, 2, this.length) return this[offset] | (this[offset + 1] << 8) } Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) { offset = offset >>> 0 if (!noAssert) checkOffset(offset, 2, this.length) return (this[offset] << 8) | this[offset + 1] } Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) { offset = offset >>> 0 if (!noAssert) checkOffset(offset, 4, this.length) return ((this[offset]) | (this[offset + 1] << 8) | (this[offset + 2] << 16)) + (this[offset + 3] * 0x1000000) } Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) { offset = offset >>> 0 if (!noAssert) checkOffset(offset, 4, this.length) return (this[offset] * 0x1000000) + ((this[offset + 1] << 16) | (this[offset + 2] << 8) | this[offset + 3]) } Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) { offset = offset >>> 0 byteLength = byteLength >>> 0 if (!noAssert) checkOffset(offset, byteLength, this.length) var val = this[offset] var mul = 1 var i = 0 while (++i < byteLength && (mul *= 0x100)) { val += this[offset + i] * mul } mul *= 0x80 if (val >= mul) val -= Math.pow(2, 8 * byteLength) return val } Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) { offset = offset >>> 0 byteLength = byteLength >>> 0 if (!noAssert) checkOffset(offset, byteLength, this.length) var i = byteLength var mul = 1 var val = this[offset + --i] while (i > 0 && (mul *= 0x100)) { val += this[offset + --i] * mul } mul *= 0x80 if (val >= mul) val -= Math.pow(2, 8 * byteLength) return val } Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) { offset = offset >>> 0 if (!noAssert) checkOffset(offset, 1, this.length) if (!(this[offset] & 0x80)) return (this[offset]) return ((0xff - this[offset] + 1) * -1) } Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) { offset = offset >>> 0 if (!noAssert) checkOffset(offset, 2, this.length) var val = this[offset] | (this[offset + 1] << 8) return (val & 0x8000) ? val | 0xFFFF0000 : val } Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) { offset = offset >>> 0 if (!noAssert) checkOffset(offset, 2, this.length) var val = this[offset + 1] | (this[offset] << 8) return (val & 0x8000) ? val | 0xFFFF0000 : val } Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) { offset = offset >>> 0 if (!noAssert) checkOffset(offset, 4, this.length) return (this[offset]) | (this[offset + 1] << 8) | (this[offset + 2] << 16) | (this[offset + 3] << 24) } Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) { offset = offset >>> 0 if (!noAssert) checkOffset(offset, 4, this.length) return (this[offset] << 24) | (this[offset + 1] << 16) | (this[offset + 2] << 8) | (this[offset + 3]) } Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) { offset = offset >>> 0 if (!noAssert) checkOffset(offset, 4, this.length) return ieee754.read(this, offset, true, 23, 4) } Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) { offset = offset >>> 0 if (!noAssert) checkOffset(offset, 4, this.length) return ieee754.read(this, offset, false, 23, 4) } Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) { offset = offset >>> 0 if (!noAssert) checkOffset(offset, 8, this.length) return ieee754.read(this, offset, true, 52, 8) } Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) { offset = offset >>> 0 if (!noAssert) checkOffset(offset, 8, this.length) return ieee754.read(this, offset, false, 52, 8) } function checkInt (buf, value, offset, ext, max, min) { if (!Buffer.isBuffer(buf)) throw new TypeError('"buffer" argument must be a Buffer instance') if (value > max || value < min) throw new RangeError('"value" argument is out of bounds') if (offset + ext > buf.length) throw new RangeError('Index out of range') } Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) { value = +value offset = offset >>> 0 byteLength = byteLength >>> 0 if (!noAssert) { var maxBytes = Math.pow(2, 8 * byteLength) - 1 checkInt(this, value, offset, byteLength, maxBytes, 0) } var mul = 1 var i = 0 this[offset] = value & 0xFF while (++i < byteLength && (mul *= 0x100)) { this[offset + i] = (value / mul) & 0xFF } return offset + byteLength } Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) { value = +value offset = offset >>> 0 byteLength = byteLength >>> 0 if (!noAssert) { var maxBytes = Math.pow(2, 8 * byteLength) - 1 checkInt(this, value, offset, byteLength, maxBytes, 0) } var i = byteLength - 1 var mul = 1 this[offset + i] = value & 0xFF while (--i >= 0 && (mul *= 0x100)) { this[offset + i] = (value / mul) & 0xFF } return offset + byteLength } Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) { value = +value offset = offset >>> 0 if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0) this[offset] = (value & 0xff) return offset + 1 } Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) { value = +value offset = offset >>> 0 if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) this[offset] = (value & 0xff) this[offset + 1] = (value >>> 8) return offset + 2 } Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) { value = +value offset = offset >>> 0 if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) this[offset] = (value >>> 8) this[offset + 1] = (value & 0xff) return offset + 2 } Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) { value = +value offset = offset >>> 0 if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0) this[offset + 3] = (value >>> 24) this[offset + 2] = (value >>> 16) this[offset + 1] = (value >>> 8) this[offset] = (value & 0xff) return offset + 4 } Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) { value = +value offset = offset >>> 0 if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0) this[offset] = (value >>> 24) this[offset + 1] = (value >>> 16) this[offset + 2] = (value >>> 8) this[offset + 3] = (value & 0xff) return offset + 4 } Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) { value = +value offset = offset >>> 0 if (!noAssert) { var limit = Math.pow(2, (8 * byteLength) - 1) checkInt(this, value, offset, byteLength, limit - 1, -limit) } var i = 0 var mul = 1 var sub = 0 this[offset] = value & 0xFF while (++i < byteLength && (mul *= 0x100)) { if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) { sub = 1 } this[offset + i] = ((value / mul) >> 0) - sub & 0xFF } return offset + byteLength } Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) { value = +value offset = offset >>> 0 if (!noAssert) { var limit = Math.pow(2, (8 * byteLength) - 1) checkInt(this, value, offset, byteLength, limit - 1, -limit) } var i = byteLength - 1 var mul = 1 var sub = 0 this[offset + i] = value & 0xFF while (--i >= 0 && (mul *= 0x100)) { if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) { sub = 1 } this[offset + i] = ((value / mul) >> 0) - sub & 0xFF } return offset + byteLength } Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) { value = +value offset = offset >>> 0 if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80) if (value < 0) value = 0xff + value + 1 this[offset] = (value & 0xff) return offset + 1 } Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) { value = +value offset = offset >>> 0 if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000) this[offset] = (value & 0xff) this[offset + 1] = (value >>> 8) return offset + 2 } Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) { value = +value offset = offset >>> 0 if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000) this[offset] = (value >>> 8) this[offset + 1] = (value & 0xff) return offset + 2 } Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) { value = +value offset = offset >>> 0 if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) this[offset] = (value & 0xff) this[offset + 1] = (value >>> 8) this[offset + 2] = (value >>> 16) this[offset + 3] = (value >>> 24) return offset + 4 } Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) { value = +value offset = offset >>> 0 if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) if (value < 0) value = 0xffffffff + value + 1 this[offset] = (value >>> 24) this[offset + 1] = (value >>> 16) this[offset + 2] = (value >>> 8) this[offset + 3] = (value & 0xff) return offset + 4 } function checkIEEE754 (buf, value, offset, ext, max, min) { if (offset + ext > buf.length) throw new RangeError('Index out of range') if (offset < 0) throw new RangeError('Index out of range') } function writeFloat (buf, value, offset, littleEndian, noAssert) { value = +value offset = offset >>> 0 if (!noAssert) { checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38) } ieee754.write(buf, value, offset, littleEndian, 23, 4) return offset + 4 } Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) { return writeFloat(this, value, offset, true, noAssert) } Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) { return writeFloat(this, value, offset, false, noAssert) } function writeDouble (buf, value, offset, littleEndian, noAssert) { value = +value offset = offset >>> 0 if (!noAssert) { checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308) } ieee754.write(buf, value, offset, littleEndian, 52, 8) return offset + 8 } Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) { return writeDouble(this, value, offset, true, noAssert) } Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) { return writeDouble(this, value, offset, false, noAssert) } // copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length) Buffer.prototype.copy = function copy (target, targetStart, start, end) { if (!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) { // ascending copy from start for (i = 0; i < len; ++i) { target[i + targetStart] = this[i + start] } } else { Uint8Array.prototype.set.call( target, this.subarray(start, start + len), targetStart ) } return len } // Usage: // buffer.fill(number[, offset[, end]]) // buffer.fill(buffer[, offset[, end]]) // buffer.fill(string[, offset[, end]][, encoding]) Buffer.prototype.fill = function fill (val, start, end, encoding) { // Handle string cases: if (typeof val === 'string') { if (typeof start === 'string') { encoding = start start = 0 end = this.length } else if (typeof end === 'string') { encoding = end end = this.length } if (val.length === 1) { var code = val.charCodeAt(0) if (code < 256) { val = code } } if (encoding !== undefined && typeof encoding !== 'string') { throw new TypeError('encoding must be a string') } if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) { throw new TypeError('Unknown encoding: ' + encoding) } } else if (typeof val === 'number') { val = val & 255 } // Invalid ranges are not set to a default, so can range check early. if (start < 0 || this.length < start || this.length < end) { throw new RangeError('Out of range index') } if (end <= start) { return this } start = start >>> 0 end = end === undefined ? this.length : end >>> 0 if (!val) val = 0 var i if (typeof val === 'number') { for (i = start; i < end; ++i) { this[i] = val } } else { var bytes = Buffer.isBuffer(val) ? val : new Buffer(val, encoding) var len = bytes.length for (i = 0; i < end - start; ++i) { this[i + start] = bytes[i % len] } } return this } // HELPER FUNCTIONS // ================ 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 = str.trim().replace(INVALID_BASE64_RE, '') // Node converts strings with length < 2 to '' if (str.length < 2) return '' // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not while (str.length % 4 !== 0) { str = str + '=' } return str } function 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 } // Node 0.10 supports `ArrayBuffer` but lacks `ArrayBuffer.isView` function isArrayBufferView (obj) { return (typeof ArrayBuffer.isView === 'function') && ArrayBuffer.isView(obj) } function numberIsNaN (obj) { return obj !== obj // eslint-disable-line no-self-compare } },{"base64-js":2,"ieee754":51}],7:[function(require,module,exports){ module.exports = { "100": "Continue", "101": "Switching Protocols", "102": "Processing", "200": "OK", "201": "Created", "202": "Accepted", "203": "Non-Authoritative Information", "204": "No Content", "205": "Reset Content", "206": "Partial Content", "207": "Multi-Status", "208": "Already Reported", "226": "IM Used", "300": "Multiple Choices", "301": "Moved Permanently", "302": "Found", "303": "See Other", "304": "Not Modified", "305": "Use Proxy", "307": "Temporary Redirect", "308": "Permanent Redirect", "400": "Bad Request", "401": "Unauthorized", "402": "Payment Required", "403": "Forbidden", "404": "Not Found", "405": "Method Not Allowed", "406": "Not Acceptable", "407": "Proxy Authentication Required", "408": "Request Timeout", "409": "Conflict", "410": "Gone", "411": "Length Required", "412": "Precondition Failed", "413": "Payload Too Large", "414": "URI Too Long", "415": "Unsupported Media Type", "416": "Range Not Satisfiable", "417": "Expectation Failed", "418": "I'm a teapot", "421": "Misdirected Request", "422": "Unprocessable Entity", "423": "Locked", "424": "Failed Dependency", "425": "Unordered Collection", "426": "Upgrade Required", "428": "Precondition Required", "429": "Too Many Requests", "431": "Request Header Fields Too Large", "451": "Unavailable For Legal Reasons", "500": "Internal Server Error", "501": "Not Implemented", "502": "Bad Gateway", "503": "Service Unavailable", "504": "Gateway Timeout", "505": "HTTP Version Not Supported", "506": "Variant Also Negotiates", "507": "Insufficient Storage", "508": "Loop Detected", "509": "Bandwidth Limit Exceeded", "510": "Not Extended", "511": "Network Authentication Required" } },{}],8:[function(require,module,exports){ (function (Buffer){ // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to permit // persons to whom the Software is furnished to do so, subject to the // following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. // NOTE: These type checking functions intentionally don't use `instanceof` // because it is fragile and can be easily faked with `Object.create()`. function isArray(arg) { if (Array.isArray) { return Array.isArray(arg); } return objectToString(arg) === '[object Array]'; } exports.isArray = isArray; function isBoolean(arg) { return typeof arg === 'boolean'; } exports.isBoolean = isBoolean; function isNull(arg) { return arg === null; } exports.isNull = isNull; function isNullOrUndefined(arg) { return arg == null; } exports.isNullOrUndefined = isNullOrUndefined; function isNumber(arg) { return typeof arg === 'number'; } exports.isNumber = isNumber; function isString(arg) { return typeof arg === 'string'; } exports.isString = isString; function isSymbol(arg) { return typeof arg === 'symbol'; } exports.isSymbol = isSymbol; function isUndefined(arg) { return arg === void 0; } exports.isUndefined = isUndefined; function isRegExp(re) { return objectToString(re) === '[object RegExp]'; } exports.isRegExp = isRegExp; function isObject(arg) { return typeof arg === 'object' && arg !== null; } exports.isObject = isObject; function isDate(d) { return objectToString(d) === '[object Date]'; } exports.isDate = isDate; function isError(e) { return (objectToString(e) === '[object Error]' || e instanceof Error); } exports.isError = isError; function isFunction(arg) { return typeof arg === 'function'; } exports.isFunction = isFunction; function isPrimitive(arg) { return arg === null || typeof arg === 'boolean' || typeof arg === 'number' || typeof arg === 'string' || typeof arg === 'symbol' || // ES6 symbol typeof arg === 'undefined'; } exports.isPrimitive = isPrimitive; exports.isBuffer = Buffer.isBuffer; function objectToString(o) { return Object.prototype.toString.call(o); } }).call(this,{"isBuffer":require("../../is-buffer/index.js")}) },{"../../is-buffer/index.js":54}],9:[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; i0) { 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":11}],10:[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=0; --i) { // Start at largest stride and work your way inwards idx = order[i] code.push(["for(i",i,"=0;i",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; i0;){"].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 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 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 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":82}],11:[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; i0) { // 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= 0) { var carg = compiledArgs[argNo] var usage = getUsage(node) if(usage & LVALUE) { carg.lvalue = true } if(usage & RVALUE) { carg.rvalue = true } ++carg.count rewrite(node, carg.name) } else if(isGlobal(name)) { //Don't rewrite globals } else { rewrite(node, createLocal(name)) } } else if(node.type === "Literal") { if(typeof node.value === "string") { rewrite(node, escapeString(node.value)) } } else if(node.type === "WithStatement") { throw new Error("cwise-parser: with() statements not allowed") } else { //Visit all children var keys = Object.keys(node) for(var i=0, n=keys.length; i b ? 1 : a >= b ? 0 : NaN; }; var bisector = function(compare) { if (compare.length === 1) compare = ascendingComparator(compare); return { left: function(a, x, lo, hi) { if (lo == null) lo = 0; if (hi == null) hi = a.length; while (lo < hi) { var mid = lo + hi >>> 1; if (compare(a[mid], x) < 0) lo = mid + 1; else hi = mid; } return lo; }, right: function(a, x, lo, hi) { if (lo == null) lo = 0; if (hi == null) hi = a.length; while (lo < hi) { var mid = lo + hi >>> 1; if (compare(a[mid], x) > 0) hi = mid; else lo = mid + 1; } return lo; } }; }; function ascendingComparator(f) { return function(d, x) { return ascending(f(d), x); }; } var ascendingBisect = bisector(ascending); var bisectRight = ascendingBisect.right; var bisectLeft = ascendingBisect.left; var pairs = function(array, f) { if (f == null) f = pair; var i = 0, n = array.length - 1, p = array[0], pairs = new Array(n < 0 ? 0 : n); while (i < n) pairs[i] = f(p, p = array[++i]); return pairs; }; function pair(a, b) { return [a, b]; } var cross = function(values0, values1, reduce) { var n0 = values0.length, n1 = values1.length, values = new Array(n0 * n1), i0, i1, i, value0; if (reduce == null) reduce = pair; for (i0 = i = 0; i0 < n0; ++i0) { for (value0 = values0[i0], i1 = 0; i1 < n1; ++i1, ++i) { values[i] = reduce(value0, values1[i1]); } } return values; }; var descending = function(a, b) { return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN; }; var number = function(x) { return x === null ? NaN : +x; }; var variance = function(values, valueof) { var n = values.length, m = 0, i = -1, mean = 0, value, delta, sum = 0; if (valueof == null) { while (++i < n) { if (!isNaN(value = number(values[i]))) { delta = value - mean; mean += delta / ++m; sum += delta * (value - mean); } } } else { while (++i < n) { if (!isNaN(value = number(valueof(values[i], i, values)))) { delta = value - mean; mean += delta / ++m; sum += delta * (value - mean); } } } if (m > 1) return sum / (m - 1); }; var deviation = function(array, f) { var v = variance(array, f); return v ? Math.sqrt(v) : v; }; var extent = function(values, valueof) { var n = values.length, i = -1, value, min, max; if (valueof == null) { while (++i < n) { // Find the first comparable value. if ((value = values[i]) != null && value >= value) { min = max = value; while (++i < n) { // Compare the remaining values. if ((value = values[i]) != null) { if (min > value) min = value; if (max < value) max = value; } } } } } else { while (++i < n) { // Find the first comparable value. if ((value = valueof(values[i], i, values)) != null && value >= value) { min = max = value; while (++i < n) { // Compare the remaining values. if ((value = valueof(values[i], i, values)) != null) { if (min > value) min = value; if (max < value) max = value; } } } } } return [min, max]; }; var array = Array.prototype; var slice = array.slice; var map = array.map; var constant = function(x) { return function() { return x; }; }; var identity = function(x) { return x; }; var range = function(start, stop, step) { start = +start, stop = +stop, step = (n = arguments.length) < 2 ? (stop = start, start = 0, 1) : n < 3 ? 1 : +step; var i = -1, n = Math.max(0, Math.ceil((stop - start) / step)) | 0, range = new Array(n); while (++i < n) { range[i] = start + i * step; } return range; }; var e10 = Math.sqrt(50); var e5 = Math.sqrt(10); var e2 = Math.sqrt(2); var ticks = function(start, stop, count) { var reverse = stop < start, i = -1, n, ticks, step; if (reverse) n = start, start = stop, stop = n; if ((step = tickIncrement(start, stop, count)) === 0 || !isFinite(step)) return []; if (step > 0) { start = Math.ceil(start / step); stop = Math.floor(stop / step); ticks = new Array(n = Math.ceil(stop - start + 1)); while (++i < n) ticks[i] = (start + i) * step; } else { start = Math.floor(start * step); stop = Math.ceil(stop * step); ticks = new Array(n = Math.ceil(start - stop + 1)); while (++i < n) ticks[i] = (start - i) / step; } if (reverse) ticks.reverse(); return ticks; }; function tickIncrement(start, stop, count) { var step = (stop - start) / Math.max(0, count), power = Math.floor(Math.log(step) / Math.LN10), error = step / Math.pow(10, power); return power >= 0 ? (error >= e10 ? 10 : error >= e5 ? 5 : error >= e2 ? 2 : 1) * Math.pow(10, power) : -Math.pow(10, -power) / (error >= e10 ? 10 : error >= e5 ? 5 : error >= e2 ? 2 : 1); } function tickStep(start, stop, count) { var step0 = Math.abs(stop - start) / Math.max(0, count), step1 = Math.pow(10, Math.floor(Math.log(step0) / Math.LN10)), error = step0 / step1; if (error >= e10) step1 *= 10; else if (error >= e5) step1 *= 5; else if (error >= e2) step1 *= 2; return stop < start ? -step1 : step1; } var sturges = function(values) { return Math.ceil(Math.log(values.length) / Math.LN2) + 1; }; var histogram = function() { var value = identity, domain = extent, threshold = sturges; function histogram(data) { var i, n = data.length, x, values = new Array(n); for (i = 0; i < n; ++i) { values[i] = value(data[i], i, data); } var xz = domain(values), x0 = xz[0], x1 = xz[1], tz = threshold(values, x0, x1); // Convert number of thresholds into uniform thresholds. if (!Array.isArray(tz)) { tz = tickStep(x0, x1, tz); tz = range(Math.ceil(x0 / tz) * tz, Math.floor(x1 / tz) * tz, tz); // exclusive } // Remove any thresholds outside the domain. var m = tz.length; while (tz[0] <= x0) tz.shift(), --m; while (tz[m - 1] > x1) tz.pop(), --m; var bins = new Array(m + 1), bin; // Initialize bins. for (i = 0; i <= m; ++i) { bin = bins[i] = []; bin.x0 = i > 0 ? tz[i - 1] : x0; bin.x1 = i < m ? tz[i] : x1; } // Assign data to bins by value, ignoring any outside the domain. for (i = 0; i < n; ++i) { x = values[i]; if (x0 <= x && x <= x1) { bins[bisectRight(tz, x, 0, m)].push(data[i]); } } return bins; } histogram.value = function(_) { return arguments.length ? (value = typeof _ === "function" ? _ : constant(_), histogram) : value; }; histogram.domain = function(_) { return arguments.length ? (domain = typeof _ === "function" ? _ : constant([_[0], _[1]]), histogram) : domain; }; histogram.thresholds = function(_) { return arguments.length ? (threshold = typeof _ === "function" ? _ : Array.isArray(_) ? constant(slice.call(_)) : constant(_), histogram) : threshold; }; return histogram; }; var quantile = function(values, p, valueof) { if (valueof == null) valueof = number; if (!(n = values.length)) return; if ((p = +p) <= 0 || n < 2) return +valueof(values[0], 0, values); if (p >= 1) return +valueof(values[n - 1], n - 1, values); var n, i = (n - 1) * p, i0 = Math.floor(i), value0 = +valueof(values[i0], i0, values), value1 = +valueof(values[i0 + 1], i0 + 1, values); return value0 + (value1 - value0) * (i - i0); }; var freedmanDiaconis = function(values, min, max) { values = map.call(values, number).sort(ascending); return Math.ceil((max - min) / (2 * (quantile(values, 0.75) - quantile(values, 0.25)) * Math.pow(values.length, -1 / 3))); }; var scott = function(values, min, max) { return Math.ceil((max - min) / (3.5 * deviation(values) * Math.pow(values.length, -1 / 3))); }; var max = function(values, valueof) { var n = values.length, i = -1, value, max; if (valueof == null) { while (++i < n) { // Find the first comparable value. if ((value = values[i]) != null && value >= value) { max = value; while (++i < n) { // Compare the remaining values. if ((value = values[i]) != null && value > max) { max = value; } } } } } else { while (++i < n) { // Find the first comparable value. if ((value = valueof(values[i], i, values)) != null && value >= value) { max = value; while (++i < n) { // Compare the remaining values. if ((value = valueof(values[i], i, values)) != null && value > max) { max = value; } } } } } return max; }; var mean = function(values, valueof) { var n = values.length, m = n, i = -1, value, sum = 0; if (valueof == null) { while (++i < n) { if (!isNaN(value = number(values[i]))) sum += value; else --m; } } else { while (++i < n) { if (!isNaN(value = number(valueof(values[i], i, values)))) sum += value; else --m; } } if (m) return sum / m; }; var median = function(values, valueof) { var n = values.length, i = -1, value, numbers = []; if (valueof == null) { while (++i < n) { if (!isNaN(value = number(values[i]))) { numbers.push(value); } } } else { while (++i < n) { if (!isNaN(value = number(valueof(values[i], i, values)))) { numbers.push(value); } } } return quantile(numbers.sort(ascending), 0.5); }; var merge = function(arrays) { var n = arrays.length, m, i = -1, j = 0, merged, array; while (++i < n) j += arrays[i].length; merged = new Array(j); while (--n >= 0) { array = arrays[n]; m = array.length; while (--m >= 0) { merged[--j] = array[m]; } } return merged; }; var min = function(values, valueof) { var n = values.length, i = -1, value, min; if (valueof == null) { while (++i < n) { // Find the first comparable value. if ((value = values[i]) != null && value >= value) { min = value; while (++i < n) { // Compare the remaining values. if ((value = values[i]) != null && min > value) { min = value; } } } } } else { while (++i < n) { // Find the first comparable value. if ((value = valueof(values[i], i, values)) != null && value >= value) { min = value; while (++i < n) { // Compare the remaining values. if ((value = valueof(values[i], i, values)) != null && min > value) { min = value; } } } } } return min; }; var permute = function(array, indexes) { var i = indexes.length, permutes = new Array(i); while (i--) permutes[i] = array[indexes[i]]; return permutes; }; var scan = function(values, compare) { if (!(n = values.length)) return; var n, i = 0, j = 0, xi, xj = values[j]; if (compare == null) compare = ascending; while (++i < n) { if (compare(xi = values[i], xj) < 0 || compare(xj, xj) !== 0) { xj = xi, j = i; } } if (compare(xj, xj) === 0) return j; }; var shuffle = function(array, i0, i1) { var m = (i1 == null ? array.length : i1) - (i0 = i0 == null ? 0 : +i0), t, i; while (m) { i = Math.random() * m-- | 0; t = array[m + i0]; array[m + i0] = array[i + i0]; array[i + i0] = t; } return array; }; var sum = function(values, valueof) { var n = values.length, i = -1, value, sum = 0; if (valueof == null) { while (++i < n) { if (value = +values[i]) sum += value; // Note: zero and null are equivalent. } } else { while (++i < n) { if (value = +valueof(values[i], i, values)) sum += value; } } return sum; }; var transpose = function(matrix) { if (!(n = matrix.length)) return []; for (var i = -1, m = min(matrix, length), transpose = new Array(m); ++i < m;) { for (var j = -1, n, row = transpose[i] = new Array(n); ++j < n;) { row[j] = matrix[j][i]; } } return transpose; }; function length(d) { return d.length; } var zip = function() { return transpose(arguments); }; exports.bisect = bisectRight; exports.bisectRight = bisectRight; exports.bisectLeft = bisectLeft; exports.ascending = ascending; exports.bisector = bisector; exports.cross = cross; exports.descending = descending; exports.deviation = deviation; exports.extent = extent; exports.histogram = histogram; exports.thresholdFreedmanDiaconis = freedmanDiaconis; exports.thresholdScott = scott; exports.thresholdSturges = sturges; exports.max = max; exports.mean = mean; exports.median = median; exports.merge = merge; exports.min = min; exports.pairs = pairs; exports.permute = permute; exports.quantile = quantile; exports.range = range; exports.scan = scan; exports.shuffle = shuffle; exports.sum = sum; exports.ticks = ticks; exports.tickIncrement = tickIncrement; exports.tickStep = tickStep; exports.transpose = transpose; exports.variance = variance; exports.zip = zip; Object.defineProperty(exports, '__esModule', { value: true }); }))); },{}],16:[function(require,module,exports){ // https://d3js.org/d3-axis/ Version 1.0.8. Copyright 2017 Mike Bostock. (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (factory((global.d3 = global.d3 || {}))); }(this, (function (exports) { 'use strict'; var slice = Array.prototype.slice; var identity = function(x) { return x; }; var top = 1; var right = 2; var bottom = 3; var left = 4; var epsilon = 1e-6; function translateX(x) { return "translate(" + (x + 0.5) + ",0)"; } function translateY(y) { return "translate(0," + (y + 0.5) + ")"; } function number(scale) { return function(d) { return +scale(d); }; } function center(scale) { var offset = Math.max(0, scale.bandwidth() - 1) / 2; // Adjust for 0.5px offset. if (scale.round()) offset = Math.round(offset); return function(d) { return +scale(d) + offset; }; } function entering() { return !this.__axis; } function axis(orient, scale) { var tickArguments = [], tickValues = null, tickFormat = null, tickSizeInner = 6, tickSizeOuter = 6, tickPadding = 3, k = orient === top || orient === left ? -1 : 1, x = orient === left || orient === right ? "x" : "y", transform = orient === top || orient === bottom ? translateX : translateY; function axis(context) { var values = tickValues == null ? (scale.ticks ? scale.ticks.apply(scale, tickArguments) : scale.domain()) : tickValues, format = tickFormat == null ? (scale.tickFormat ? scale.tickFormat.apply(scale, tickArguments) : identity) : tickFormat, spacing = Math.max(tickSizeInner, 0) + tickPadding, range = scale.range(), range0 = +range[0] + 0.5, range1 = +range[range.length - 1] + 0.5, position = (scale.bandwidth ? center : number)(scale.copy()), selection = context.selection ? context.selection() : context, path = selection.selectAll(".domain").data([null]), tick = selection.selectAll(".tick").data(values, scale).order(), tickExit = tick.exit(), tickEnter = tick.enter().append("g").attr("class", "tick"), line = tick.select("line"), text = tick.select("text"); path = path.merge(path.enter().insert("path", ".tick") .attr("class", "domain") .attr("stroke", "#000")); tick = tick.merge(tickEnter); line = line.merge(tickEnter.append("line") .attr("stroke", "#000") .attr(x + "2", k * tickSizeInner)); text = text.merge(tickEnter.append("text") .attr("fill", "#000") .attr(x, k * spacing) .attr("dy", orient === top ? "0em" : orient === bottom ? "0.71em" : "0.32em")); if (context !== selection) { path = path.transition(context); tick = tick.transition(context); line = line.transition(context); text = text.transition(context); tickExit = tickExit.transition(context) .attr("opacity", epsilon) .attr("transform", function(d) { return isFinite(d = position(d)) ? transform(d) : this.getAttribute("transform"); }); tickEnter .attr("opacity", epsilon) .attr("transform", function(d) { var p = this.parentNode.__axis; return transform(p && isFinite(p = p(d)) ? p : position(d)); }); } tickExit.remove(); path .attr("d", orient === left || orient == right ? "M" + k * tickSizeOuter + "," + range0 + "H0.5V" + range1 + "H" + k * tickSizeOuter : "M" + range0 + "," + k * tickSizeOuter + "V0.5H" + range1 + "V" + k * tickSizeOuter); tick .attr("opacity", 1) .attr("transform", function(d) { return transform(position(d)); }); line .attr(x + "2", k * tickSizeInner); text .attr(x, k * spacing) .text(format); selection.filter(entering) .attr("fill", "none") .attr("font-size", 10) .attr("font-family", "sans-serif") .attr("text-anchor", orient === right ? "start" : orient === left ? "end" : "middle"); selection .each(function() { this.__axis = position; }); } axis.scale = function(_) { return arguments.length ? (scale = _, axis) : scale; }; axis.ticks = function() { return tickArguments = slice.call(arguments), axis; }; axis.tickArguments = function(_) { return arguments.length ? (tickArguments = _ == null ? [] : slice.call(_), axis) : tickArguments.slice(); }; axis.tickValues = function(_) { return arguments.length ? (tickValues = _ == null ? null : slice.call(_), axis) : tickValues && tickValues.slice(); }; axis.tickFormat = function(_) { return arguments.length ? (tickFormat = _, axis) : tickFormat; }; axis.tickSize = function(_) { return arguments.length ? (tickSizeInner = tickSizeOuter = +_, axis) : tickSizeInner; }; axis.tickSizeInner = function(_) { return arguments.length ? (tickSizeInner = +_, axis) : tickSizeInner; }; axis.tickSizeOuter = function(_) { return arguments.length ? (tickSizeOuter = +_, axis) : tickSizeOuter; }; axis.tickPadding = function(_) { return arguments.length ? (tickPadding = +_, axis) : tickPadding; }; return axis; } function axisTop(scale) { return axis(top, scale); } function axisRight(scale) { return axis(right, scale); } function axisBottom(scale) { return axis(bottom, scale); } function axisLeft(scale) { return axis(left, scale); } exports.axisTop = axisTop; exports.axisRight = axisRight; exports.axisBottom = axisBottom; exports.axisLeft = axisLeft; Object.defineProperty(exports, '__esModule', { value: true }); }))); },{}],17:[function(require,module,exports){ // https://d3js.org/d3-brush/ Version 1.0.4. Copyright 2017 Mike Bostock. (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('d3-dispatch'), require('d3-drag'), require('d3-interpolate'), require('d3-selection'), require('d3-transition')) : typeof define === 'function' && define.amd ? define(['exports', 'd3-dispatch', 'd3-drag', 'd3-interpolate', 'd3-selection', 'd3-transition'], factory) : (factory((global.d3 = global.d3 || {}),global.d3,global.d3,global.d3,global.d3,global.d3)); }(this, (function (exports,d3Dispatch,d3Drag,d3Interpolate,d3Selection,d3Transition) { 'use strict'; var constant = function(x) { return function() { return x; }; }; var BrushEvent = function(target, type, selection) { this.target = target; this.type = type; this.selection = selection; }; function nopropagation() { d3Selection.event.stopImmediatePropagation(); } var noevent = function() { d3Selection.event.preventDefault(); d3Selection.event.stopImmediatePropagation(); }; var MODE_DRAG = {name: "drag"}; var MODE_SPACE = {name: "space"}; var MODE_HANDLE = {name: "handle"}; var MODE_CENTER = {name: "center"}; var X = { name: "x", handles: ["e", "w"].map(type), input: function(x, e) { return x && [[x[0], e[0][1]], [x[1], e[1][1]]]; }, output: function(xy) { return xy && [xy[0][0], xy[1][0]]; } }; var Y = { name: "y", handles: ["n", "s"].map(type), input: function(y, e) { return y && [[e[0][0], y[0]], [e[1][0], y[1]]]; }, output: function(xy) { return xy && [xy[0][1], xy[1][1]]; } }; var XY = { name: "xy", handles: ["n", "e", "s", "w", "nw", "ne", "se", "sw"].map(type), input: function(xy) { return xy; }, output: function(xy) { return xy; } }; var cursors = { overlay: "crosshair", selection: "move", n: "ns-resize", e: "ew-resize", s: "ns-resize", w: "ew-resize", nw: "nwse-resize", ne: "nesw-resize", se: "nwse-resize", sw: "nesw-resize" }; var flipX = { e: "w", w: "e", nw: "ne", ne: "nw", se: "sw", sw: "se" }; var flipY = { n: "s", s: "n", nw: "sw", ne: "se", se: "ne", sw: "nw" }; var signsX = { overlay: +1, selection: +1, n: null, e: +1, s: null, w: -1, nw: -1, ne: +1, se: +1, sw: -1 }; var signsY = { overlay: +1, selection: +1, n: -1, e: null, s: +1, w: null, nw: -1, ne: -1, se: +1, sw: +1 }; function type(t) { return {type: t}; } // Ignore right-click, since that should open the context menu. function defaultFilter() { return !d3Selection.event.button; } function defaultExtent() { var svg = this.ownerSVGElement || this; return [[0, 0], [svg.width.baseVal.value, svg.height.baseVal.value]]; } // Like d3.local, but with the name “__brush” rather than auto-generated. function local(node) { while (!node.__brush) if (!(node = node.parentNode)) return; return node.__brush; } function empty(extent) { return extent[0][0] === extent[1][0] || extent[0][1] === extent[1][1]; } function brushSelection(node) { var state = node.__brush; return state ? state.dim.output(state.selection) : null; } function brushX() { return brush$1(X); } function brushY() { return brush$1(Y); } var brush = function() { return brush$1(XY); }; function brush$1(dim) { var extent = defaultExtent, filter = defaultFilter, listeners = d3Dispatch.dispatch(brush, "start", "brush", "end"), handleSize = 6, touchending; function brush(group) { var overlay = group .property("__brush", initialize) .selectAll(".overlay") .data([type("overlay")]); overlay.enter().append("rect") .attr("class", "overlay") .attr("pointer-events", "all") .attr("cursor", cursors.overlay) .merge(overlay) .each(function() { var extent = local(this).extent; d3Selection.select(this) .attr("x", extent[0][0]) .attr("y", extent[0][1]) .attr("width", extent[1][0] - extent[0][0]) .attr("height", extent[1][1] - extent[0][1]); }); group.selectAll(".selection") .data([type("selection")]) .enter().append("rect") .attr("class", "selection") .attr("cursor", cursors.selection) .attr("fill", "#777") .attr("fill-opacity", 0.3) .attr("stroke", "#fff") .attr("shape-rendering", "crispEdges"); var handle = group.selectAll(".handle") .data(dim.handles, function(d) { return d.type; }); handle.exit().remove(); handle.enter().append("rect") .attr("class", function(d) { return "handle handle--" + d.type; }) .attr("cursor", function(d) { return cursors[d.type]; }); group .each(redraw) .attr("fill", "none") .attr("pointer-events", "all") .style("-webkit-tap-highlight-color", "rgba(0,0,0,0)") .on("mousedown.brush touchstart.brush", started); } brush.move = function(group, selection) { if (group.selection) { group .on("start.brush", function() { emitter(this, arguments).beforestart().start(); }) .on("interrupt.brush end.brush", function() { emitter(this, arguments).end(); }) .tween("brush", function() { var that = this, state = that.__brush, emit = emitter(that, arguments), selection0 = state.selection, selection1 = dim.input(typeof selection === "function" ? selection.apply(this, arguments) : selection, state.extent), i = d3Interpolate.interpolate(selection0, selection1); function tween(t) { state.selection = t === 1 && empty(selection1) ? null : i(t); redraw.call(that); emit.brush(); } return selection0 && selection1 ? tween : tween(1); }); } else { group .each(function() { var that = this, args = arguments, state = that.__brush, selection1 = dim.input(typeof selection === "function" ? selection.apply(that, args) : selection, state.extent), emit = emitter(that, args).beforestart(); d3Transition.interrupt(that); state.selection = selection1 == null || empty(selection1) ? null : selection1; redraw.call(that); emit.start().brush().end(); }); } }; function redraw() { var group = d3Selection.select(this), selection = local(this).selection; if (selection) { group.selectAll(".selection") .style("display", null) .attr("x", selection[0][0]) .attr("y", selection[0][1]) .attr("width", selection[1][0] - selection[0][0]) .attr("height", selection[1][1] - selection[0][1]); group.selectAll(".handle") .style("display", null) .attr("x", function(d) { return d.type[d.type.length - 1] === "e" ? selection[1][0] - handleSize / 2 : selection[0][0] - handleSize / 2; }) .attr("y", function(d) { return d.type[0] === "s" ? selection[1][1] - handleSize / 2 : selection[0][1] - handleSize / 2; }) .attr("width", function(d) { return d.type === "n" || d.type === "s" ? selection[1][0] - selection[0][0] + handleSize : handleSize; }) .attr("height", function(d) { return d.type === "e" || d.type === "w" ? selection[1][1] - selection[0][1] + handleSize : handleSize; }); } else { group.selectAll(".selection,.handle") .style("display", "none") .attr("x", null) .attr("y", null) .attr("width", null) .attr("height", null); } } function emitter(that, args) { return that.__brush.emitter || new Emitter(that, args); } function Emitter(that, args) { this.that = that; this.args = args; this.state = that.__brush; this.active = 0; } Emitter.prototype = { beforestart: function() { if (++this.active === 1) this.state.emitter = this, this.starting = true; return this; }, start: function() { if (this.starting) this.starting = false, this.emit("start"); return this; }, brush: function() { this.emit("brush"); return this; }, end: function() { if (--this.active === 0) delete this.state.emitter, this.emit("end"); return this; }, emit: function(type) { d3Selection.customEvent(new BrushEvent(brush, type, dim.output(this.state.selection)), listeners.apply, listeners, [type, this.that, this.args]); } }; function started() { if (d3Selection.event.touches) { if (d3Selection.event.changedTouches.length < d3Selection.event.touches.length) return noevent(); } else if (touchending) return; if (!filter.apply(this, arguments)) return; var that = this, type = d3Selection.event.target.__data__.type, mode = (d3Selection.event.metaKey ? type = "overlay" : type) === "selection" ? MODE_DRAG : (d3Selection.event.altKey ? MODE_CENTER : MODE_HANDLE), signX = dim === Y ? null : signsX[type], signY = dim === X ? null : signsY[type], state = local(that), extent = state.extent, selection = state.selection, W = extent[0][0], w0, w1, N = extent[0][1], n0, n1, E = extent[1][0], e0, e1, S = extent[1][1], s0, s1, dx, dy, moving, shifting = signX && signY && d3Selection.event.shiftKey, lockX, lockY, point0 = d3Selection.mouse(that), point = point0, emit = emitter(that, arguments).beforestart(); if (type === "overlay") { state.selection = selection = [ [w0 = dim === Y ? W : point0[0], n0 = dim === X ? N : point0[1]], [e0 = dim === Y ? E : w0, s0 = dim === X ? S : n0] ]; } else { w0 = selection[0][0]; n0 = selection[0][1]; e0 = selection[1][0]; s0 = selection[1][1]; } w1 = w0; n1 = n0; e1 = e0; s1 = s0; var group = d3Selection.select(that) .attr("pointer-events", "none"); var overlay = group.selectAll(".overlay") .attr("cursor", cursors[type]); if (d3Selection.event.touches) { group .on("touchmove.brush", moved, true) .on("touchend.brush touchcancel.brush", ended, true); } else { var view = d3Selection.select(d3Selection.event.view) .on("keydown.brush", keydowned, true) .on("keyup.brush", keyupped, true) .on("mousemove.brush", moved, true) .on("mouseup.brush", ended, true); d3Drag.dragDisable(d3Selection.event.view); } nopropagation(); d3Transition.interrupt(that); redraw.call(that); emit.start(); function moved() { var point1 = d3Selection.mouse(that); if (shifting && !lockX && !lockY) { if (Math.abs(point1[0] - point[0]) > Math.abs(point1[1] - point[1])) lockY = true; else lockX = true; } point = point1; moving = true; noevent(); move(); } function move() { var t; dx = point[0] - point0[0]; dy = point[1] - point0[1]; switch (mode) { case MODE_SPACE: case MODE_DRAG: { if (signX) dx = Math.max(W - w0, Math.min(E - e0, dx)), w1 = w0 + dx, e1 = e0 + dx; if (signY) dy = Math.max(N - n0, Math.min(S - s0, dy)), n1 = n0 + dy, s1 = s0 + dy; break; } case MODE_HANDLE: { if (signX < 0) dx = Math.max(W - w0, Math.min(E - w0, dx)), w1 = w0 + dx, e1 = e0; else if (signX > 0) dx = Math.max(W - e0, Math.min(E - e0, dx)), w1 = w0, e1 = e0 + dx; if (signY < 0) dy = Math.max(N - n0, Math.min(S - n0, dy)), n1 = n0 + dy, s1 = s0; else if (signY > 0) dy = Math.max(N - s0, Math.min(S - s0, dy)), n1 = n0, s1 = s0 + dy; break; } case MODE_CENTER: { if (signX) w1 = Math.max(W, Math.min(E, w0 - dx * signX)), e1 = Math.max(W, Math.min(E, e0 + dx * signX)); if (signY) n1 = Math.max(N, Math.min(S, n0 - dy * signY)), s1 = Math.max(N, Math.min(S, s0 + dy * signY)); break; } } if (e1 < w1) { signX *= -1; t = w0, w0 = e0, e0 = t; t = w1, w1 = e1, e1 = t; if (type in flipX) overlay.attr("cursor", cursors[type = flipX[type]]); } if (s1 < n1) { signY *= -1; t = n0, n0 = s0, s0 = t; t = n1, n1 = s1, s1 = t; if (type in flipY) overlay.attr("cursor", cursors[type = flipY[type]]); } if (state.selection) selection = state.selection; // May be set by brush.move! if (lockX) w1 = selection[0][0], e1 = selection[1][0]; if (lockY) n1 = selection[0][1], s1 = selection[1][1]; if (selection[0][0] !== w1 || selection[0][1] !== n1 || selection[1][0] !== e1 || selection[1][1] !== s1) { state.selection = [[w1, n1], [e1, s1]]; redraw.call(that); emit.brush(); } } function ended() { nopropagation(); if (d3Selection.event.touches) { if (d3Selection.event.touches.length) return; if (touchending) clearTimeout(touchending); touchending = setTimeout(function() { touchending = null; }, 500); // Ghost clicks are delayed! group.on("touchmove.brush touchend.brush touchcancel.brush", null); } else { d3Drag.dragEnable(d3Selection.event.view, moving); view.on("keydown.brush keyup.brush mousemove.brush mouseup.brush", null); } group.attr("pointer-events", "all"); overlay.attr("cursor", cursors.overlay); if (state.selection) selection = state.selection; // May be set by brush.move (on start)! if (empty(selection)) state.selection = null, redraw.call(that); emit.end(); } function keydowned() { switch (d3Selection.event.keyCode) { case 16: { // SHIFT shifting = signX && signY; break; } case 18: { // ALT if (mode === MODE_HANDLE) { if (signX) e0 = e1 - dx * signX, w0 = w1 + dx * signX; if (signY) s0 = s1 - dy * signY, n0 = n1 + dy * signY; mode = MODE_CENTER; move(); } break; } case 32: { // SPACE; takes priority over ALT if (mode === MODE_HANDLE || mode === MODE_CENTER) { if (signX < 0) e0 = e1 - dx; else if (signX > 0) w0 = w1 - dx; if (signY < 0) s0 = s1 - dy; else if (signY > 0) n0 = n1 - dy; mode = MODE_SPACE; overlay.attr("cursor", cursors.selection); move(); } break; } default: return; } noevent(); } function keyupped() { switch (d3Selection.event.keyCode) { case 16: { // SHIFT if (shifting) { lockX = lockY = shifting = false; move(); } break; } case 18: { // ALT if (mode === MODE_CENTER) { if (signX < 0) e0 = e1; else if (signX > 0) w0 = w1; if (signY < 0) s0 = s1; else if (signY > 0) n0 = n1; mode = MODE_HANDLE; move(); } break; } case 32: { // SPACE if (mode === MODE_SPACE) { if (d3Selection.event.altKey) { if (signX) e0 = e1 - dx * signX, w0 = w1 + dx * signX; if (signY) s0 = s1 - dy * signY, n0 = n1 + dy * signY; mode = MODE_CENTER; } else { if (signX < 0) e0 = e1; else if (signX > 0) w0 = w1; if (signY < 0) s0 = s1; else if (signY > 0) n0 = n1; mode = MODE_HANDLE; } overlay.attr("cursor", cursors[type]); move(); } break; } default: return; } noevent(); } } function initialize() { var state = this.__brush || {selection: null}; state.extent = extent.apply(this, arguments); state.dim = dim; return state; } brush.extent = function(_) { return arguments.length ? (extent = typeof _ === "function" ? _ : constant([[+_[0][0], +_[0][1]], [+_[1][0], +_[1][1]]]), brush) : extent; }; brush.filter = function(_) { return arguments.length ? (filter = typeof _ === "function" ? _ : constant(!!_), brush) : filter; }; brush.handleSize = function(_) { return arguments.length ? (handleSize = +_, brush) : handleSize; }; brush.on = function() { var value = listeners.on.apply(listeners, arguments); return value === listeners ? brush : value; }; return brush; } exports.brush = brush; exports.brushX = brushX; exports.brushY = brushY; exports.brushSelection = brushSelection; Object.defineProperty(exports, '__esModule', { value: true }); }))); },{"d3-dispatch":21,"d3-drag":22,"d3-interpolate":29,"d3-selection":37,"d3-transition":42}],18:[function(require,module,exports){ // https://d3js.org/d3-chord/ Version 1.0.4. Copyright 2017 Mike Bostock. (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('d3-array'), require('d3-path')) : typeof define === 'function' && define.amd ? define(['exports', 'd3-array', 'd3-path'], factory) : (factory((global.d3 = global.d3 || {}),global.d3,global.d3)); }(this, (function (exports,d3Array,d3Path) { 'use strict'; var cos = Math.cos; var sin = Math.sin; var pi = Math.PI; var halfPi = pi / 2; var tau = pi * 2; var max = Math.max; function compareValue(compare) { return function(a, b) { return compare( a.source.value + a.target.value, b.source.value + b.target.value ); }; } var chord = function() { var padAngle = 0, sortGroups = null, sortSubgroups = null, sortChords = null; function chord(matrix) { var n = matrix.length, groupSums = [], groupIndex = d3Array.range(n), subgroupIndex = [], chords = [], groups = chords.groups = new Array(n), subgroups = new Array(n * n), k, x, x0, dx, i, j; // Compute the sum. k = 0, i = -1; while (++i < n) { x = 0, j = -1; while (++j < n) { x += matrix[i][j]; } groupSums.push(x); subgroupIndex.push(d3Array.range(n)); k += x; } // Sort groups… if (sortGroups) groupIndex.sort(function(a, b) { return sortGroups(groupSums[a], groupSums[b]); }); // Sort subgroups… if (sortSubgroups) subgroupIndex.forEach(function(d, i) { d.sort(function(a, b) { return sortSubgroups(matrix[i][a], matrix[i][b]); }); }); // Convert the sum to scaling factor for [0, 2pi]. // TODO Allow start and end angle to be specified? // TODO Allow padding to be specified as percentage? k = max(0, tau - padAngle * n) / k; dx = k ? padAngle : tau / n; // Compute the start and end angle for each group and subgroup. // Note: Opera has a bug reordering object literal properties! x = 0, i = -1; while (++i < n) { x0 = x, j = -1; while (++j < n) { var di = groupIndex[i], dj = subgroupIndex[di][j], v = matrix[di][dj], a0 = x, a1 = x += v * k; subgroups[dj * n + di] = { index: di, subindex: dj, startAngle: a0, endAngle: a1, value: v }; } groups[di] = { index: di, startAngle: x0, endAngle: x, value: groupSums[di] }; x += dx; } // Generate chords for each (non-empty) subgroup-subgroup link. i = -1; while (++i < n) { j = i - 1; while (++j < n) { var source = subgroups[j * n + i], target = subgroups[i * n + j]; if (source.value || target.value) { chords.push(source.value < target.value ? {source: target, target: source} : {source: source, target: target}); } } } return sortChords ? chords.sort(sortChords) : chords; } chord.padAngle = function(_) { return arguments.length ? (padAngle = max(0, _), chord) : padAngle; }; chord.sortGroups = function(_) { return arguments.length ? (sortGroups = _, chord) : sortGroups; }; chord.sortSubgroups = function(_) { return arguments.length ? (sortSubgroups = _, chord) : sortSubgroups; }; chord.sortChords = function(_) { return arguments.length ? (_ == null ? sortChords = null : (sortChords = compareValue(_))._ = _, chord) : sortChords && sortChords._; }; return chord; }; var slice = Array.prototype.slice; var constant = function(x) { return function() { return x; }; }; function defaultSource(d) { return d.source; } function defaultTarget(d) { return d.target; } function defaultRadius(d) { return d.radius; } function defaultStartAngle(d) { return d.startAngle; } function defaultEndAngle(d) { return d.endAngle; } var ribbon = function() { var source = defaultSource, target = defaultTarget, radius = defaultRadius, startAngle = defaultStartAngle, endAngle = defaultEndAngle, context = null; function ribbon() { var buffer, argv = slice.call(arguments), s = source.apply(this, argv), t = target.apply(this, argv), sr = +radius.apply(this, (argv[0] = s, argv)), sa0 = startAngle.apply(this, argv) - halfPi, sa1 = endAngle.apply(this, argv) - halfPi, sx0 = sr * cos(sa0), sy0 = sr * sin(sa0), tr = +radius.apply(this, (argv[0] = t, argv)), ta0 = startAngle.apply(this, argv) - halfPi, ta1 = endAngle.apply(this, argv) - halfPi; if (!context) context = buffer = d3Path.path(); context.moveTo(sx0, sy0); context.arc(0, 0, sr, sa0, sa1); if (sa0 !== ta0 || sa1 !== ta1) { // TODO sr !== tr? context.quadraticCurveTo(0, 0, tr * cos(ta0), tr * sin(ta0)); context.arc(0, 0, tr, ta0, ta1); } context.quadraticCurveTo(0, 0, sx0, sy0); context.closePath(); if (buffer) return context = null, buffer + "" || null; } ribbon.radius = function(_) { return arguments.length ? (radius = typeof _ === "function" ? _ : constant(+_), ribbon) : radius; }; ribbon.startAngle = function(_) { return arguments.length ? (startAngle = typeof _ === "function" ? _ : constant(+_), ribbon) : startAngle; }; ribbon.endAngle = function(_) { return arguments.length ? (endAngle = typeof _ === "function" ? _ : constant(+_), ribbon) : endAngle; }; ribbon.source = function(_) { return arguments.length ? (source = _, ribbon) : source; }; ribbon.target = function(_) { return arguments.length ? (target = _, ribbon) : target; }; ribbon.context = function(_) { return arguments.length ? ((context = _ == null ? null : _), ribbon) : context; }; return ribbon; }; exports.chord = chord; exports.ribbon = ribbon; Object.defineProperty(exports, '__esModule', { value: true }); }))); },{"d3-array":15,"d3-path":30}],19:[function(require,module,exports){ // https://d3js.org/d3-collection/ Version 1.0.4. Copyright 2017 Mike Bostock. (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (factory((global.d3 = global.d3 || {}))); }(this, (function (exports) { 'use strict'; var prefix = "$"; function Map() {} Map.prototype = map.prototype = { constructor: Map, has: function(key) { return (prefix + key) in this; }, get: function(key) { return this[prefix + key]; }, set: function(key, value) { this[prefix + key] = value; return this; }, remove: function(key) { var property = prefix + key; return property in this && delete this[property]; }, clear: function() { for (var property in this) if (property[0] === prefix) delete this[property]; }, keys: function() { var keys = []; for (var property in this) if (property[0] === prefix) keys.push(property.slice(1)); return keys; }, values: function() { var values = []; for (var property in this) if (property[0] === prefix) values.push(this[property]); return values; }, entries: function() { var entries = []; for (var property in this) if (property[0] === prefix) entries.push({key: property.slice(1), value: this[property]}); return entries; }, size: function() { var size = 0; for (var property in this) if (property[0] === prefix) ++size; return size; }, empty: function() { for (var property in this) if (property[0] === prefix) return false; return true; }, each: function(f) { for (var property in this) if (property[0] === prefix) f(this[property], property.slice(1), this); } }; function map(object, f) { var map = new Map; // Copy constructor. if (object instanceof Map) object.each(function(value, key) { map.set(key, value); }); // Index array by numeric index or specified key function. else if (Array.isArray(object)) { var i = -1, n = object.length, o; if (f == null) while (++i < n) map.set(i, object[i]); else while (++i < n) map.set(f(o = object[i], i, object), o); } // Convert object to map. else if (object) for (var key in object) map.set(key, object[key]); return map; } var nest = function() { var keys = [], sortKeys = [], sortValues, rollup, nest; function apply(array, depth, createResult, setResult) { if (depth >= keys.length) { if (sortValues != null) array.sort(sortValues); return rollup != null ? rollup(array) : array; } var i = -1, n = array.length, key = keys[depth++], keyValue, value, valuesByKey = map(), values, result = createResult(); while (++i < n) { if (values = valuesByKey.get(keyValue = key(value = array[i]) + "")) { values.push(value); } else { valuesByKey.set(keyValue, [value]); } } valuesByKey.each(function(values, key) { setResult(result, key, apply(values, depth, createResult, setResult)); }); return result; } function entries(map$$1, depth) { if (++depth > keys.length) return map$$1; var array, sortKey = sortKeys[depth - 1]; if (rollup != null && depth >= keys.length) array = map$$1.entries(); else array = [], map$$1.each(function(v, k) { array.push({key: k, values: entries(v, depth)}); }); return sortKey != null ? array.sort(function(a, b) { return sortKey(a.key, b.key); }) : array; } return nest = { object: function(array) { return apply(array, 0, createObject, setObject); }, map: function(array) { return apply(array, 0, createMap, setMap); }, entries: function(array) { return entries(apply(array, 0, createMap, setMap), 0); }, key: function(d) { keys.push(d); return nest; }, sortKeys: function(order) { sortKeys[keys.length - 1] = order; return nest; }, sortValues: function(order) { sortValues = order; return nest; }, rollup: function(f) { rollup = f; return nest; } }; }; function createObject() { return {}; } function setObject(object, key, value) { object[key] = value; } function createMap() { return map(); } function setMap(map$$1, key, value) { map$$1.set(key, value); } function Set() {} var proto = map.prototype; Set.prototype = set.prototype = { constructor: Set, has: proto.has, add: function(value) { value += ""; this[prefix + value] = value; return this; }, remove: proto.remove, clear: proto.clear, values: proto.keys, size: proto.size, empty: proto.empty, each: proto.each }; function set(object, f) { var set = new Set; // Copy constructor. if (object instanceof Set) object.each(function(value) { set.add(value); }); // Otherwise, assume it’s an array. else if (object) { var i = -1, n = object.length; if (f == null) while (++i < n) set.add(object[i]); else while (++i < n) set.add(f(object[i], i, object)); } return set; } var keys = function(map) { var keys = []; for (var key in map) keys.push(key); return keys; }; var values = function(map) { var values = []; for (var key in map) values.push(map[key]); return values; }; var entries = function(map) { var entries = []; for (var key in map) entries.push({key: key, value: map[key]}); return entries; }; exports.nest = nest; exports.set = set; exports.map = map; exports.keys = keys; exports.values = values; exports.entries = entries; Object.defineProperty(exports, '__esModule', { value: true }); }))); },{}],20:[function(require,module,exports){ // https://d3js.org/d3-color/ Version 1.0.3. Copyright 2017 Mike Bostock. (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (factory((global.d3 = global.d3 || {}))); }(this, (function (exports) { 'use strict'; var define = function(constructor, factory, prototype) { constructor.prototype = factory.prototype = prototype; prototype.constructor = constructor; }; function extend(parent, definition) { var prototype = Object.create(parent.prototype); for (var key in definition) prototype[key] = definition[key]; return prototype; } function Color() {} var darker = 0.7; var brighter = 1 / darker; var reI = "\\s*([+-]?\\d+)\\s*"; var reN = "\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)\\s*"; var reP = "\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)%\\s*"; var reHex3 = /^#([0-9a-f]{3})$/; var reHex6 = /^#([0-9a-f]{6})$/; var reRgbInteger = new RegExp("^rgb\\(" + [reI, reI, reI] + "\\)$"); var reRgbPercent = new RegExp("^rgb\\(" + [reP, reP, reP] + "\\)$"); var reRgbaInteger = new RegExp("^rgba\\(" + [reI, reI, reI, reN] + "\\)$"); var reRgbaPercent = new RegExp("^rgba\\(" + [reP, reP, reP, reN] + "\\)$"); var reHslPercent = new RegExp("^hsl\\(" + [reN, reP, reP] + "\\)$"); var reHslaPercent = new RegExp("^hsla\\(" + [reN, reP, reP, reN] + "\\)$"); var named = { aliceblue: 0xf0f8ff, antiquewhite: 0xfaebd7, aqua: 0x00ffff, aquamarine: 0x7fffd4, azure: 0xf0ffff, beige: 0xf5f5dc, bisque: 0xffe4c4, black: 0x000000, blanchedalmond: 0xffebcd, blue: 0x0000ff, blueviolet: 0x8a2be2, brown: 0xa52a2a, burlywood: 0xdeb887, cadetblue: 0x5f9ea0, chartreuse: 0x7fff00, chocolate: 0xd2691e, coral: 0xff7f50, cornflowerblue: 0x6495ed, cornsilk: 0xfff8dc, crimson: 0xdc143c, cyan: 0x00ffff, darkblue: 0x00008b, darkcyan: 0x008b8b, darkgoldenrod: 0xb8860b, darkgray: 0xa9a9a9, darkgreen: 0x006400, darkgrey: 0xa9a9a9, darkkhaki: 0xbdb76b, darkmagenta: 0x8b008b, darkolivegreen: 0x556b2f, darkorange: 0xff8c00, darkorchid: 0x9932cc, darkred: 0x8b0000, darksalmon: 0xe9967a, darkseagreen: 0x8fbc8f, darkslateblue: 0x483d8b, darkslategray: 0x2f4f4f, darkslategrey: 0x2f4f4f, darkturquoise: 0x00ced1, darkviolet: 0x9400d3, deeppink: 0xff1493, deepskyblue: 0x00bfff, dimgray: 0x696969, dimgrey: 0x696969, dodgerblue: 0x1e90ff, firebrick: 0xb22222, floralwhite: 0xfffaf0, forestgreen: 0x228b22, fuchsia: 0xff00ff, gainsboro: 0xdcdcdc, ghostwhite: 0xf8f8ff, gold: 0xffd700, goldenrod: 0xdaa520, gray: 0x808080, green: 0x008000, greenyellow: 0xadff2f, grey: 0x808080, honeydew: 0xf0fff0, hotpink: 0xff69b4, indianred: 0xcd5c5c, indigo: 0x4b0082, ivory: 0xfffff0, khaki: 0xf0e68c, lavender: 0xe6e6fa, lavenderblush: 0xfff0f5, lawngreen: 0x7cfc00, lemonchiffon: 0xfffacd, lightblue: 0xadd8e6, lightcoral: 0xf08080, lightcyan: 0xe0ffff, lightgoldenrodyellow: 0xfafad2, lightgray: 0xd3d3d3, lightgreen: 0x90ee90, lightgrey: 0xd3d3d3, lightpink: 0xffb6c1, lightsalmon: 0xffa07a, lightseagreen: 0x20b2aa, lightskyblue: 0x87cefa, lightslategray: 0x778899, lightslategrey: 0x778899, lightsteelblue: 0xb0c4de, lightyellow: 0xffffe0, lime: 0x00ff00, limegreen: 0x32cd32, linen: 0xfaf0e6, magenta: 0xff00ff, maroon: 0x800000, mediumaquamarine: 0x66cdaa, mediumblue: 0x0000cd, mediumorchid: 0xba55d3, mediumpurple: 0x9370db, mediumseagreen: 0x3cb371, mediumslateblue: 0x7b68ee, mediumspringgreen: 0x00fa9a, mediumturquoise: 0x48d1cc, mediumvioletred: 0xc71585, midnightblue: 0x191970, mintcream: 0xf5fffa, mistyrose: 0xffe4e1, moccasin: 0xffe4b5, navajowhite: 0xffdead, navy: 0x000080, oldlace: 0xfdf5e6, olive: 0x808000, olivedrab: 0x6b8e23, orange: 0xffa500, orangered: 0xff4500, orchid: 0xda70d6, palegoldenrod: 0xeee8aa, palegreen: 0x98fb98, paleturquoise: 0xafeeee, palevioletred: 0xdb7093, papayawhip: 0xffefd5, peachpuff: 0xffdab9, peru: 0xcd853f, pink: 0xffc0cb, plum: 0xdda0dd, powderblue: 0xb0e0e6, purple: 0x800080, rebeccapurple: 0x663399, red: 0xff0000, rosybrown: 0xbc8f8f, royalblue: 0x4169e1, saddlebrown: 0x8b4513, salmon: 0xfa8072, sandybrown: 0xf4a460, seagreen: 0x2e8b57, seashell: 0xfff5ee, sienna: 0xa0522d, silver: 0xc0c0c0, skyblue: 0x87ceeb, slateblue: 0x6a5acd, slategray: 0x708090, slategrey: 0x708090, snow: 0xfffafa, springgreen: 0x00ff7f, steelblue: 0x4682b4, tan: 0xd2b48c, teal: 0x008080, thistle: 0xd8bfd8, tomato: 0xff6347, turquoise: 0x40e0d0, violet: 0xee82ee, wheat: 0xf5deb3, white: 0xffffff, whitesmoke: 0xf5f5f5, yellow: 0xffff00, yellowgreen: 0x9acd32 }; define(Color, color, { displayable: function() { return this.rgb().displayable(); }, toString: function() { return this.rgb() + ""; } }); function color(format) { var m; format = (format + "").trim().toLowerCase(); return (m = reHex3.exec(format)) ? (m = parseInt(m[1], 16), new Rgb((m >> 8 & 0xf) | (m >> 4 & 0x0f0), (m >> 4 & 0xf) | (m & 0xf0), ((m & 0xf) << 4) | (m & 0xf), 1)) // #f00 : (m = reHex6.exec(format)) ? rgbn(parseInt(m[1], 16)) // #ff0000 : (m = reRgbInteger.exec(format)) ? new Rgb(m[1], m[2], m[3], 1) // rgb(255, 0, 0) : (m = reRgbPercent.exec(format)) ? new Rgb(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, 1) // rgb(100%, 0%, 0%) : (m = reRgbaInteger.exec(format)) ? rgba(m[1], m[2], m[3], m[4]) // rgba(255, 0, 0, 1) : (m = reRgbaPercent.exec(format)) ? rgba(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, m[4]) // rgb(100%, 0%, 0%, 1) : (m = reHslPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, 1) // hsl(120, 50%, 50%) : (m = reHslaPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, m[4]) // hsla(120, 50%, 50%, 1) : named.hasOwnProperty(format) ? rgbn(named[format]) : format === "transparent" ? new Rgb(NaN, NaN, NaN, 0) : null; } function rgbn(n) { return new Rgb(n >> 16 & 0xff, n >> 8 & 0xff, n & 0xff, 1); } function rgba(r, g, b, a) { if (a <= 0) r = g = b = NaN; return new Rgb(r, g, b, a); } function rgbConvert(o) { if (!(o instanceof Color)) o = color(o); if (!o) return new Rgb; o = o.rgb(); return new Rgb(o.r, o.g, o.b, o.opacity); } function rgb(r, g, b, opacity) { return arguments.length === 1 ? rgbConvert(r) : new Rgb(r, g, b, opacity == null ? 1 : opacity); } function Rgb(r, g, b, opacity) { this.r = +r; this.g = +g; this.b = +b; this.opacity = +opacity; } define(Rgb, rgb, extend(Color, { brighter: function(k) { k = k == null ? brighter : Math.pow(brighter, k); return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity); }, darker: function(k) { k = k == null ? darker : Math.pow(darker, k); return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity); }, rgb: function() { return this; }, displayable: function() { return (0 <= this.r && this.r <= 255) && (0 <= this.g && this.g <= 255) && (0 <= this.b && this.b <= 255) && (0 <= this.opacity && this.opacity <= 1); }, toString: function() { var a = this.opacity; a = isNaN(a) ? 1 : Math.max(0, Math.min(1, a)); return (a === 1 ? "rgb(" : "rgba(") + Math.max(0, Math.min(255, Math.round(this.r) || 0)) + ", " + Math.max(0, Math.min(255, Math.round(this.g) || 0)) + ", " + Math.max(0, Math.min(255, Math.round(this.b) || 0)) + (a === 1 ? ")" : ", " + a + ")"); } })); function hsla(h, s, l, a) { if (a <= 0) h = s = l = NaN; else if (l <= 0 || l >= 1) h = s = NaN; else if (s <= 0) h = NaN; return new Hsl(h, s, l, a); } function hslConvert(o) { if (o instanceof Hsl) return new Hsl(o.h, o.s, o.l, o.opacity); if (!(o instanceof Color)) o = color(o); if (!o) return new Hsl; if (o instanceof Hsl) return o; o = o.rgb(); var r = o.r / 255, g = o.g / 255, b = o.b / 255, min = Math.min(r, g, b), max = Math.max(r, g, b), h = NaN, s = max - min, l = (max + min) / 2; if (s) { if (r === max) h = (g - b) / s + (g < b) * 6; else if (g === max) h = (b - r) / s + 2; else h = (r - g) / s + 4; s /= l < 0.5 ? max + min : 2 - max - min; h *= 60; } else { s = l > 0 && l < 1 ? 0 : h; } return new Hsl(h, s, l, o.opacity); } function hsl(h, s, l, opacity) { return arguments.length === 1 ? hslConvert(h) : new Hsl(h, s, l, opacity == null ? 1 : opacity); } function Hsl(h, s, l, opacity) { this.h = +h; this.s = +s; this.l = +l; this.opacity = +opacity; } define(Hsl, hsl, extend(Color, { brighter: function(k) { k = k == null ? brighter : Math.pow(brighter, k); return new Hsl(this.h, this.s, this.l * k, this.opacity); }, darker: function(k) { k = k == null ? darker : Math.pow(darker, k); return new Hsl(this.h, this.s, this.l * k, this.opacity); }, rgb: function() { var h = this.h % 360 + (this.h < 0) * 360, s = isNaN(h) || isNaN(this.s) ? 0 : this.s, l = this.l, m2 = l + (l < 0.5 ? l : 1 - l) * s, m1 = 2 * l - m2; return new Rgb( hsl2rgb(h >= 240 ? h - 240 : h + 120, m1, m2), hsl2rgb(h, m1, m2), hsl2rgb(h < 120 ? h + 240 : h - 120, m1, m2), this.opacity ); }, displayable: function() { return (0 <= this.s && this.s <= 1 || isNaN(this.s)) && (0 <= this.l && this.l <= 1) && (0 <= this.opacity && this.opacity <= 1); } })); /* From FvD 13.37, CSS Color Module Level 3 */ function hsl2rgb(h, m1, m2) { return (h < 60 ? m1 + (m2 - m1) * h / 60 : h < 180 ? m2 : h < 240 ? m1 + (m2 - m1) * (240 - h) / 60 : m1) * 255; } var deg2rad = Math.PI / 180; var rad2deg = 180 / Math.PI; var Kn = 18; var Xn = 0.950470; var Yn = 1; var Zn = 1.088830; var t0 = 4 / 29; var t1 = 6 / 29; var t2 = 3 * t1 * t1; var t3 = t1 * t1 * t1; function labConvert(o) { if (o instanceof Lab) return new Lab(o.l, o.a, o.b, o.opacity); if (o instanceof Hcl) { var h = o.h * deg2rad; return new Lab(o.l, Math.cos(h) * o.c, Math.sin(h) * o.c, o.opacity); } if (!(o instanceof Rgb)) o = rgbConvert(o); var b = rgb2xyz(o.r), a = rgb2xyz(o.g), l = rgb2xyz(o.b), x = xyz2lab((0.4124564 * b + 0.3575761 * a + 0.1804375 * l) / Xn), y = xyz2lab((0.2126729 * b + 0.7151522 * a + 0.0721750 * l) / Yn), z = xyz2lab((0.0193339 * b + 0.1191920 * a + 0.9503041 * l) / Zn); return new Lab(116 * y - 16, 500 * (x - y), 200 * (y - z), o.opacity); } function lab(l, a, b, opacity) { return arguments.length === 1 ? labConvert(l) : new Lab(l, a, b, opacity == null ? 1 : opacity); } function Lab(l, a, b, opacity) { this.l = +l; this.a = +a; this.b = +b; this.opacity = +opacity; } define(Lab, lab, extend(Color, { brighter: function(k) { return new Lab(this.l + Kn * (k == null ? 1 : k), this.a, this.b, this.opacity); }, darker: function(k) { return new Lab(this.l - Kn * (k == null ? 1 : k), this.a, this.b, this.opacity); }, rgb: function() { var y = (this.l + 16) / 116, x = isNaN(this.a) ? y : y + this.a / 500, z = isNaN(this.b) ? y : y - this.b / 200; y = Yn * lab2xyz(y); x = Xn * lab2xyz(x); z = Zn * lab2xyz(z); return new Rgb( xyz2rgb( 3.2404542 * x - 1.5371385 * y - 0.4985314 * z), // D65 -> sRGB xyz2rgb(-0.9692660 * x + 1.8760108 * y + 0.0415560 * z), xyz2rgb( 0.0556434 * x - 0.2040259 * y + 1.0572252 * z), this.opacity ); } })); function xyz2lab(t) { return t > t3 ? Math.pow(t, 1 / 3) : t / t2 + t0; } function lab2xyz(t) { return t > t1 ? t * t * t : t2 * (t - t0); } function xyz2rgb(x) { return 255 * (x <= 0.0031308 ? 12.92 * x : 1.055 * Math.pow(x, 1 / 2.4) - 0.055); } function rgb2xyz(x) { return (x /= 255) <= 0.04045 ? x / 12.92 : Math.pow((x + 0.055) / 1.055, 2.4); } function hclConvert(o) { if (o instanceof Hcl) return new Hcl(o.h, o.c, o.l, o.opacity); if (!(o instanceof Lab)) o = labConvert(o); var h = Math.atan2(o.b, o.a) * rad2deg; return new Hcl(h < 0 ? h + 360 : h, Math.sqrt(o.a * o.a + o.b * o.b), o.l, o.opacity); } function hcl(h, c, l, opacity) { return arguments.length === 1 ? hclConvert(h) : new Hcl(h, c, l, opacity == null ? 1 : opacity); } function Hcl(h, c, l, opacity) { this.h = +h; this.c = +c; this.l = +l; this.opacity = +opacity; } define(Hcl, hcl, extend(Color, { brighter: function(k) { return new Hcl(this.h, this.c, this.l + Kn * (k == null ? 1 : k), this.opacity); }, darker: function(k) { return new Hcl(this.h, this.c, this.l - Kn * (k == null ? 1 : k), this.opacity); }, rgb: function() { return labConvert(this).rgb(); } })); var A = -0.14861; var B = +1.78277; var C = -0.29227; var D = -0.90649; var E = +1.97294; var ED = E * D; var EB = E * B; var BC_DA = B * C - D * A; function cubehelixConvert(o) { if (o instanceof Cubehelix) return new Cubehelix(o.h, o.s, o.l, o.opacity); if (!(o instanceof Rgb)) o = rgbConvert(o); var r = o.r / 255, g = o.g / 255, b = o.b / 255, l = (BC_DA * b + ED * r - EB * g) / (BC_DA + ED - EB), bl = b - l, k = (E * (g - l) - C * bl) / D, s = Math.sqrt(k * k + bl * bl) / (E * l * (1 - l)), // NaN if l=0 or l=1 h = s ? Math.atan2(k, bl) * rad2deg - 120 : NaN; return new Cubehelix(h < 0 ? h + 360 : h, s, l, o.opacity); } function cubehelix(h, s, l, opacity) { return arguments.length === 1 ? cubehelixConvert(h) : new Cubehelix(h, s, l, opacity == null ? 1 : opacity); } function Cubehelix(h, s, l, opacity) { this.h = +h; this.s = +s; this.l = +l; this.opacity = +opacity; } define(Cubehelix, cubehelix, extend(Color, { brighter: function(k) { k = k == null ? brighter : Math.pow(brighter, k); return new Cubehelix(this.h, this.s, this.l * k, this.opacity); }, darker: function(k) { k = k == null ? darker : Math.pow(darker, k); return new Cubehelix(this.h, this.s, this.l * k, this.opacity); }, rgb: function() { var h = isNaN(this.h) ? 0 : (this.h + 120) * deg2rad, l = +this.l, a = isNaN(this.s) ? 0 : this.s * l * (1 - l), cosh = Math.cos(h), sinh = Math.sin(h); return new Rgb( 255 * (l + a * (A * cosh + B * sinh)), 255 * (l + a * (C * cosh + D * sinh)), 255 * (l + a * (E * cosh)), this.opacity ); } })); exports.color = color; exports.rgb = rgb; exports.hsl = hsl; exports.lab = lab; exports.hcl = hcl; exports.cubehelix = cubehelix; Object.defineProperty(exports, '__esModule', { value: true }); }))); },{}],21:[function(require,module,exports){ // https://d3js.org/d3-dispatch/ Version 1.0.3. Copyright 2017 Mike Bostock. (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (factory((global.d3 = global.d3 || {}))); }(this, (function (exports) { 'use strict'; var noop = {value: function() {}}; function dispatch() { for (var i = 0, n = arguments.length, _ = {}, t; i < n; ++i) { if (!(t = arguments[i] + "") || (t in _)) throw new Error("illegal type: " + t); _[t] = []; } return new Dispatch(_); } function Dispatch(_) { this._ = _; } function parseTypenames(typenames, types) { return typenames.trim().split(/^|\s+/).map(function(t) { var name = "", i = t.indexOf("."); if (i >= 0) name = t.slice(i + 1), t = t.slice(0, i); if (t && !types.hasOwnProperty(t)) throw new Error("unknown type: " + t); return {type: t, name: name}; }); } Dispatch.prototype = dispatch.prototype = { constructor: Dispatch, on: function(typename, callback) { var _ = this._, T = parseTypenames(typename + "", _), t, i = -1, n = T.length; // If no callback was specified, return the callback of the given type and name. if (arguments.length < 2) { while (++i < n) if ((t = (typename = T[i]).type) && (t = get(_[t], typename.name))) return t; return; } // If a type was specified, set the callback for the given type and name. // Otherwise, if a null callback was specified, remove callbacks of the given name. if (callback != null && typeof callback !== "function") throw new Error("invalid callback: " + callback); while (++i < n) { if (t = (typename = T[i]).type) _[t] = set(_[t], typename.name, callback); else if (callback == null) for (t in _) _[t] = set(_[t], typename.name, null); } return this; }, copy: function() { var copy = {}, _ = this._; for (var t in _) copy[t] = _[t].slice(); return new Dispatch(copy); }, call: function(type, that) { if ((n = arguments.length - 2) > 0) for (var args = new Array(n), i = 0, n, t; i < n; ++i) args[i] = arguments[i + 2]; if (!this._.hasOwnProperty(type)) throw new Error("unknown type: " + type); for (t = this._[type], i = 0, n = t.length; i < n; ++i) t[i].value.apply(that, args); }, apply: function(type, that, args) { if (!this._.hasOwnProperty(type)) throw new Error("unknown type: " + type); for (var t = this._[type], i = 0, n = t.length; i < n; ++i) t[i].value.apply(that, args); } }; function get(type, name) { for (var i = 0, n = type.length, c; i < n; ++i) { if ((c = type[i]).name === name) { return c.value; } } } function set(type, name, callback) { for (var i = 0, n = type.length; i < n; ++i) { if (type[i].name === name) { type[i] = noop, type = type.slice(0, i).concat(type.slice(i + 1)); break; } } if (callback != null) type.push({name: name, value: callback}); return type; } exports.dispatch = dispatch; Object.defineProperty(exports, '__esModule', { value: true }); }))); },{}],22:[function(require,module,exports){ // https://d3js.org/d3-drag/ Version 1.1.1. Copyright 2017 Mike Bostock. (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('d3-dispatch'), require('d3-selection')) : typeof define === 'function' && define.amd ? define(['exports', 'd3-dispatch', 'd3-selection'], factory) : (factory((global.d3 = global.d3 || {}),global.d3,global.d3)); }(this, (function (exports,d3Dispatch,d3Selection) { 'use strict'; function nopropagation() { d3Selection.event.stopImmediatePropagation(); } var noevent = function() { d3Selection.event.preventDefault(); d3Selection.event.stopImmediatePropagation(); }; var nodrag = function(view) { var root = view.document.documentElement, selection = d3Selection.select(view).on("dragstart.drag", noevent, true); if ("onselectstart" in root) { selection.on("selectstart.drag", noevent, true); } else { root.__noselect = root.style.MozUserSelect; root.style.MozUserSelect = "none"; } }; function yesdrag(view, noclick) { var root = view.document.documentElement, selection = d3Selection.select(view).on("dragstart.drag", null); if (noclick) { selection.on("click.drag", noevent, true); setTimeout(function() { selection.on("click.drag", null); }, 0); } if ("onselectstart" in root) { selection.on("selectstart.drag", null); } else { root.style.MozUserSelect = root.__noselect; delete root.__noselect; } } var constant = function(x) { return function() { return x; }; }; function DragEvent(target, type, subject, id, active, x, y, dx, dy, dispatch$$1) { this.target = target; this.type = type; this.subject = subject; this.identifier = id; this.active = active; this.x = x; this.y = y; this.dx = dx; this.dy = dy; this._ = dispatch$$1; } DragEvent.prototype.on = function() { var value = this._.on.apply(this._, arguments); return value === this._ ? this : value; }; // Ignore right-click, since that should open the context menu. function defaultFilter() { return !d3Selection.event.button; } function defaultContainer() { return this.parentNode; } function defaultSubject(d) { return d == null ? {x: d3Selection.event.x, y: d3Selection.event.y} : d; } function touchable() { return "ontouchstart" in this; } var drag = function() { var filter = defaultFilter, container = defaultContainer, subject = defaultSubject, gestures = {}, listeners = d3Dispatch.dispatch("start", "drag", "end"), active = 0, mousedownx, mousedowny, mousemoving, touchending, clickDistance2 = 0; function drag(selection) { selection .on("mousedown.drag", mousedowned) .filter(touchable) .on("touchstart.drag", touchstarted) .on("touchmove.drag", touchmoved) .on("touchend.drag touchcancel.drag", touchended) .style("touch-action", "none") .style("-webkit-tap-highlight-color", "rgba(0,0,0,0)"); } function mousedowned() { if (touchending || !filter.apply(this, arguments)) return; var gesture = beforestart("mouse", container.apply(this, arguments), d3Selection.mouse, this, arguments); if (!gesture) return; d3Selection.select(d3Selection.event.view).on("mousemove.drag", mousemoved, true).on("mouseup.drag", mouseupped, true); nodrag(d3Selection.event.view); nopropagation(); mousemoving = false; mousedownx = d3Selection.event.clientX; mousedowny = d3Selection.event.clientY; gesture("start"); } function mousemoved() { noevent(); if (!mousemoving) { var dx = d3Selection.event.clientX - mousedownx, dy = d3Selection.event.clientY - mousedowny; mousemoving = dx * dx + dy * dy > clickDistance2; } gestures.mouse("drag"); } function mouseupped() { d3Selection.select(d3Selection.event.view).on("mousemove.drag mouseup.drag", null); yesdrag(d3Selection.event.view, mousemoving); noevent(); gestures.mouse("end"); } function touchstarted() { if (!filter.apply(this, arguments)) return; var touches = d3Selection.event.changedTouches, c = container.apply(this, arguments), n = touches.length, i, gesture; for (i = 0; i < n; ++i) { if (gesture = beforestart(touches[i].identifier, c, d3Selection.touch, this, arguments)) { nopropagation(); gesture("start"); } } } function touchmoved() { var touches = d3Selection.event.changedTouches, n = touches.length, i, gesture; for (i = 0; i < n; ++i) { if (gesture = gestures[touches[i].identifier]) { noevent(); gesture("drag"); } } } function touchended() { var touches = d3Selection.event.changedTouches, n = touches.length, i, gesture; if (touchending) clearTimeout(touchending); touchending = setTimeout(function() { touchending = null; }, 500); // Ghost clicks are delayed! for (i = 0; i < n; ++i) { if (gesture = gestures[touches[i].identifier]) { nopropagation(); gesture("end"); } } } function beforestart(id, container, point, that, args) { var p = point(container, id), s, dx, dy, sublisteners = listeners.copy(); if (!d3Selection.customEvent(new DragEvent(drag, "beforestart", s, id, active, p[0], p[1], 0, 0, sublisteners), function() { if ((d3Selection.event.subject = s = subject.apply(that, args)) == null) return false; dx = s.x - p[0] || 0; dy = s.y - p[1] || 0; return true; })) return; return function gesture(type) { var p0 = p, n; switch (type) { case "start": gestures[id] = gesture, n = active++; break; case "end": delete gestures[id], --active; // nobreak case "drag": p = point(container, id), n = active; break; } d3Selection.customEvent(new DragEvent(drag, type, s, id, n, p[0] + dx, p[1] + dy, p[0] - p0[0], p[1] - p0[1], sublisteners), sublisteners.apply, sublisteners, [type, that, args]); }; } drag.filter = function(_) { return arguments.length ? (filter = typeof _ === "function" ? _ : constant(!!_), drag) : filter; }; drag.container = function(_) { return arguments.length ? (container = typeof _ === "function" ? _ : constant(_), drag) : container; }; drag.subject = function(_) { return arguments.length ? (subject = typeof _ === "function" ? _ : constant(_), drag) : subject; }; drag.on = function() { var value = listeners.on.apply(listeners, arguments); return value === listeners ? drag : value; }; drag.clickDistance = function(_) { return arguments.length ? (clickDistance2 = (_ = +_) * _, drag) : Math.sqrt(clickDistance2); }; return drag; }; exports.drag = drag; exports.dragDisable = nodrag; exports.dragEnable = yesdrag; Object.defineProperty(exports, '__esModule', { value: true }); }))); },{"d3-dispatch":21,"d3-selection":37}],23:[function(require,module,exports){ // https://d3js.org/d3-dsv/ Version 1.0.7. Copyright 2017 Mike Bostock. (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (factory((global.d3 = global.d3 || {}))); }(this, (function (exports) { 'use strict'; var EOL = {}; var EOF = {}; var QUOTE = 34; var NEWLINE = 10; var RETURN = 13; function objectConverter(columns) { return new Function("d", "return {" + columns.map(function(name, i) { return JSON.stringify(name) + ": d[" + i + "]"; }).join(",") + "}"); } function customConverter(columns, f) { var object = objectConverter(columns); return function(row, i) { return f(object(row), i, columns); }; } // Compute unique columns in order of discovery. function inferColumns(rows) { var columnSet = Object.create(null), columns = []; rows.forEach(function(row) { for (var column in row) { if (!(column in columnSet)) { columns.push(columnSet[column] = column); } } }); return columns; } var dsv = function(delimiter) { var reFormat = new RegExp("[\"" + delimiter + "\n\r]"), DELIMITER = delimiter.charCodeAt(0); function parse(text, f) { var convert, columns, rows = parseRows(text, function(row, i) { if (convert) return convert(row, i - 1); columns = row, convert = f ? customConverter(row, f) : objectConverter(row); }); rows.columns = columns; return rows; } function parseRows(text, f) { var rows = [], // output rows N = text.length, I = 0, // current character index n = 0, // current line number t, // current token eof = N <= 0, // current token followed by EOF? eol = false; // current token followed by EOL? // Strip the trailing newline. if (text.charCodeAt(N - 1) === NEWLINE) --N; if (text.charCodeAt(N - 1) === RETURN) --N; function token() { if (eof) return EOF; if (eol) return eol = false, EOL; // Unescape quotes. var i, j = I, c; if (text.charCodeAt(j) === QUOTE) { while (I++ < N && text.charCodeAt(I) !== QUOTE || text.charCodeAt(++I) === QUOTE); if ((i = I) >= N) eof = true; else if ((c = text.charCodeAt(I++)) === NEWLINE) eol = true; else if (c === RETURN) { eol = true; if (text.charCodeAt(I) === NEWLINE) ++I; } return text.slice(j + 1, i - 1).replace(/""/g, "\""); } // Find next delimiter or newline. while (I < N) { if ((c = text.charCodeAt(i = I++)) === NEWLINE) eol = true; else if (c === RETURN) { eol = true; if (text.charCodeAt(I) === NEWLINE) ++I; } else if (c !== DELIMITER) continue; return text.slice(j, i); } // Return last token before EOF. return eof = true, text.slice(j, N); } while ((t = token()) !== EOF) { var row = []; while (t !== EOL && t !== EOF) row.push(t), t = token(); if (f && (row = f(row, n++)) == null) continue; rows.push(row); } return rows; } function format(rows, columns) { if (columns == null) columns = inferColumns(rows); return [columns.map(formatValue).join(delimiter)].concat(rows.map(function(row) { return columns.map(function(column) { return formatValue(row[column]); }).join(delimiter); })).join("\n"); } function formatRows(rows) { return rows.map(formatRow).join("\n"); } function formatRow(row) { return row.map(formatValue).join(delimiter); } function formatValue(text) { return text == null ? "" : reFormat.test(text += "") ? "\"" + text.replace(/"/g, "\"\"") + "\"" : text; } return { parse: parse, parseRows: parseRows, format: format, formatRows: formatRows }; }; var csv = dsv(","); var csvParse = csv.parse; var csvParseRows = csv.parseRows; var csvFormat = csv.format; var csvFormatRows = csv.formatRows; var tsv = dsv("\t"); var tsvParse = tsv.parse; var tsvParseRows = tsv.parseRows; var tsvFormat = tsv.format; var tsvFormatRows = tsv.formatRows; exports.dsvFormat = dsv; exports.csvParse = csvParse; exports.csvParseRows = csvParseRows; exports.csvFormat = csvFormat; exports.csvFormatRows = csvFormatRows; exports.tsvParse = tsvParse; exports.tsvParseRows = tsvParseRows; exports.tsvFormat = tsvFormat; exports.tsvFormatRows = tsvFormatRows; Object.defineProperty(exports, '__esModule', { value: true }); }))); },{}],24:[function(require,module,exports){ // https://d3js.org/d3-ease/ Version 1.0.3. Copyright 2017 Mike Bostock. (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (factory((global.d3 = global.d3 || {}))); }(this, (function (exports) { 'use strict'; function linear(t) { return +t; } function quadIn(t) { return t * t; } function quadOut(t) { return t * (2 - t); } function quadInOut(t) { return ((t *= 2) <= 1 ? t * t : --t * (2 - t) + 1) / 2; } function cubicIn(t) { return t * t * t; } function cubicOut(t) { return --t * t * t + 1; } function cubicInOut(t) { return ((t *= 2) <= 1 ? t * t * t : (t -= 2) * t * t + 2) / 2; } var exponent = 3; var polyIn = (function custom(e) { e = +e; function polyIn(t) { return Math.pow(t, e); } polyIn.exponent = custom; return polyIn; })(exponent); var polyOut = (function custom(e) { e = +e; function polyOut(t) { return 1 - Math.pow(1 - t, e); } polyOut.exponent = custom; return polyOut; })(exponent); var polyInOut = (function custom(e) { e = +e; function polyInOut(t) { return ((t *= 2) <= 1 ? Math.pow(t, e) : 2 - Math.pow(2 - t, e)) / 2; } polyInOut.exponent = custom; return polyInOut; })(exponent); var pi = Math.PI; var halfPi = pi / 2; function sinIn(t) { return 1 - Math.cos(t * halfPi); } function sinOut(t) { return Math.sin(t * halfPi); } function sinInOut(t) { return (1 - Math.cos(pi * t)) / 2; } function expIn(t) { return Math.pow(2, 10 * t - 10); } function expOut(t) { return 1 - Math.pow(2, -10 * t); } function expInOut(t) { return ((t *= 2) <= 1 ? Math.pow(2, 10 * t - 10) : 2 - Math.pow(2, 10 - 10 * t)) / 2; } function circleIn(t) { return 1 - Math.sqrt(1 - t * t); } function circleOut(t) { return Math.sqrt(1 - --t * t); } function circleInOut(t) { return ((t *= 2) <= 1 ? 1 - Math.sqrt(1 - t * t) : Math.sqrt(1 - (t -= 2) * t) + 1) / 2; } var b1 = 4 / 11; var b2 = 6 / 11; var b3 = 8 / 11; var b4 = 3 / 4; var b5 = 9 / 11; var b6 = 10 / 11; var b7 = 15 / 16; var b8 = 21 / 22; var b9 = 63 / 64; var b0 = 1 / b1 / b1; function bounceIn(t) { return 1 - bounceOut(1 - t); } function bounceOut(t) { return (t = +t) < b1 ? b0 * t * t : t < b3 ? b0 * (t -= b2) * t + b4 : t < b6 ? b0 * (t -= b5) * t + b7 : b0 * (t -= b8) * t + b9; } function bounceInOut(t) { return ((t *= 2) <= 1 ? 1 - bounceOut(1 - t) : bounceOut(t - 1) + 1) / 2; } var overshoot = 1.70158; var backIn = (function custom(s) { s = +s; function backIn(t) { return t * t * ((s + 1) * t - s); } backIn.overshoot = custom; return backIn; })(overshoot); var backOut = (function custom(s) { s = +s; function backOut(t) { return --t * t * ((s + 1) * t + s) + 1; } backOut.overshoot = custom; return backOut; })(overshoot); var backInOut = (function custom(s) { s = +s; function backInOut(t) { return ((t *= 2) < 1 ? t * t * ((s + 1) * t - s) : (t -= 2) * t * ((s + 1) * t + s) + 2) / 2; } backInOut.overshoot = custom; return backInOut; })(overshoot); var tau = 2 * Math.PI; var amplitude = 1; var period = 0.3; var elasticIn = (function custom(a, p) { var s = Math.asin(1 / (a = Math.max(1, a))) * (p /= tau); function elasticIn(t) { return a * Math.pow(2, 10 * --t) * Math.sin((s - t) / p); } elasticIn.amplitude = function(a) { return custom(a, p * tau); }; elasticIn.period = function(p) { return custom(a, p); }; return elasticIn; })(amplitude, period); var elasticOut = (function custom(a, p) { var s = Math.asin(1 / (a = Math.max(1, a))) * (p /= tau); function elasticOut(t) { return 1 - a * Math.pow(2, -10 * (t = +t)) * Math.sin((t + s) / p); } elasticOut.amplitude = function(a) { return custom(a, p * tau); }; elasticOut.period = function(p) { return custom(a, p); }; return elasticOut; })(amplitude, period); var elasticInOut = (function custom(a, p) { var s = Math.asin(1 / (a = Math.max(1, a))) * (p /= tau); function elasticInOut(t) { return ((t = t * 2 - 1) < 0 ? a * Math.pow(2, 10 * t) * Math.sin((s - t) / p) : 2 - a * Math.pow(2, -10 * t) * Math.sin((s + t) / p)) / 2; } elasticInOut.amplitude = function(a) { return custom(a, p * tau); }; elasticInOut.period = function(p) { return custom(a, p); }; return elasticInOut; })(amplitude, period); exports.easeLinear = linear; exports.easeQuad = quadInOut; exports.easeQuadIn = quadIn; exports.easeQuadOut = quadOut; exports.easeQuadInOut = quadInOut; exports.easeCubic = cubicInOut; exports.easeCubicIn = cubicIn; exports.easeCubicOut = cubicOut; exports.easeCubicInOut = cubicInOut; exports.easePoly = polyInOut; exports.easePolyIn = polyIn; exports.easePolyOut = polyOut; exports.easePolyInOut = polyInOut; exports.easeSin = sinInOut; exports.easeSinIn = sinIn; exports.easeSinOut = sinOut; exports.easeSinInOut = sinInOut; exports.easeExp = expInOut; exports.easeExpIn = expIn; exports.easeExpOut = expOut; exports.easeExpInOut = expInOut; exports.easeCircle = circleInOut; exports.easeCircleIn = circleIn; exports.easeCircleOut = circleOut; exports.easeCircleInOut = circleInOut; exports.easeBounce = bounceOut; exports.easeBounceIn = bounceIn; exports.easeBounceOut = bounceOut; exports.easeBounceInOut = bounceInOut; exports.easeBack = backInOut; exports.easeBackIn = backIn; exports.easeBackOut = backOut; exports.easeBackInOut = backInOut; exports.easeElastic = elasticOut; exports.easeElasticIn = elasticIn; exports.easeElasticOut = elasticOut; exports.easeElasticInOut = elasticInOut; Object.defineProperty(exports, '__esModule', { value: true }); }))); },{}],25:[function(require,module,exports){ // https://d3js.org/d3-force/ Version 1.0.6. Copyright 2017 Mike Bostock. (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('d3-quadtree'), require('d3-collection'), require('d3-dispatch'), require('d3-timer')) : typeof define === 'function' && define.amd ? define(['exports', 'd3-quadtree', 'd3-collection', 'd3-dispatch', 'd3-timer'], factory) : (factory((global.d3 = global.d3 || {}),global.d3,global.d3,global.d3,global.d3)); }(this, (function (exports,d3Quadtree,d3Collection,d3Dispatch,d3Timer) { 'use strict'; var center = function(x, y) { var nodes; if (x == null) x = 0; if (y == null) y = 0; function force() { var i, n = nodes.length, node, sx = 0, sy = 0; for (i = 0; i < n; ++i) { node = nodes[i], sx += node.x, sy += node.y; } for (sx = sx / n - x, sy = sy / n - y, i = 0; i < n; ++i) { node = nodes[i], node.x -= sx, node.y -= sy; } } force.initialize = function(_) { nodes = _; }; force.x = function(_) { return arguments.length ? (x = +_, force) : x; }; force.y = function(_) { return arguments.length ? (y = +_, force) : y; }; return force; }; var constant = function(x) { return function() { return x; }; }; var jiggle = function() { return (Math.random() - 0.5) * 1e-6; }; function x(d) { return d.x + d.vx; } function y(d) { return d.y + d.vy; } var collide = function(radius) { var nodes, radii, strength = 1, iterations = 1; if (typeof radius !== "function") radius = constant(radius == null ? 1 : +radius); function force() { var i, n = nodes.length, tree, node, xi, yi, ri, ri2; for (var k = 0; k < iterations; ++k) { tree = d3Quadtree.quadtree(nodes, x, y).visitAfter(prepare); for (i = 0; i < n; ++i) { node = nodes[i]; ri = radii[node.index], ri2 = ri * ri; xi = node.x + node.vx; yi = node.y + node.vy; tree.visit(apply); } } function apply(quad, x0, y0, x1, y1) { var data = quad.data, rj = quad.r, r = ri + rj; if (data) { if (data.index > node.index) { var x = xi - data.x - data.vx, y = yi - data.y - data.vy, l = x * x + y * y; if (l < r * r) { if (x === 0) x = jiggle(), l += x * x; if (y === 0) y = jiggle(), l += y * y; l = (r - (l = Math.sqrt(l))) / l * strength; node.vx += (x *= l) * (r = (rj *= rj) / (ri2 + rj)); node.vy += (y *= l) * r; data.vx -= x * (r = 1 - r); data.vy -= y * r; } } return; } return x0 > xi + r || x1 < xi - r || y0 > yi + r || y1 < yi - r; } } function prepare(quad) { if (quad.data) return quad.r = radii[quad.data.index]; for (var i = quad.r = 0; i < 4; ++i) { if (quad[i] && quad[i].r > quad.r) { quad.r = quad[i].r; } } } function initialize() { if (!nodes) return; var i, n = nodes.length, node; radii = new Array(n); for (i = 0; i < n; ++i) node = nodes[i], radii[node.index] = +radius(node, i, nodes); } force.initialize = function(_) { nodes = _; initialize(); }; force.iterations = function(_) { return arguments.length ? (iterations = +_, force) : iterations; }; force.strength = function(_) { return arguments.length ? (strength = +_, force) : strength; }; force.radius = function(_) { return arguments.length ? (radius = typeof _ === "function" ? _ : constant(+_), initialize(), force) : radius; }; return force; }; function index(d) { return d.index; } function find(nodeById, nodeId) { var node = nodeById.get(nodeId); if (!node) throw new Error("missing: " + nodeId); return node; } var link = function(links) { var id = index, strength = defaultStrength, strengths, distance = constant(30), distances, nodes, count, bias, iterations = 1; if (links == null) links = []; function defaultStrength(link) { return 1 / Math.min(count[link.source.index], count[link.target.index]); } function force(alpha) { for (var k = 0, n = links.length; k < iterations; ++k) { for (var i = 0, link, source, target, x, y, l, b; i < n; ++i) { link = links[i], source = link.source, target = link.target; x = target.x + target.vx - source.x - source.vx || jiggle(); y = target.y + target.vy - source.y - source.vy || jiggle(); l = Math.sqrt(x * x + y * y); l = (l - distances[i]) / l * alpha * strengths[i]; x *= l, y *= l; target.vx -= x * (b = bias[i]); target.vy -= y * b; source.vx += x * (b = 1 - b); source.vy += y * b; } } } function initialize() { if (!nodes) return; var i, n = nodes.length, m = links.length, nodeById = d3Collection.map(nodes, id), link; for (i = 0, count = new Array(n); i < m; ++i) { link = links[i], link.index = i; if (typeof link.source !== "object") link.source = find(nodeById, link.source); if (typeof link.target !== "object") link.target = find(nodeById, link.target); count[link.source.index] = (count[link.source.index] || 0) + 1; count[link.target.index] = (count[link.target.index] || 0) + 1; } for (i = 0, bias = new Array(m); i < m; ++i) { link = links[i], bias[i] = count[link.source.index] / (count[link.source.index] + count[link.target.index]); } strengths = new Array(m), initializeStrength(); distances = new Array(m), initializeDistance(); } function initializeStrength() { if (!nodes) return; for (var i = 0, n = links.length; i < n; ++i) { strengths[i] = +strength(links[i], i, links); } } function initializeDistance() { if (!nodes) return; for (var i = 0, n = links.length; i < n; ++i) { distances[i] = +distance(links[i], i, links); } } force.initialize = function(_) { nodes = _; initialize(); }; force.links = function(_) { return arguments.length ? (links = _, initialize(), force) : links; }; force.id = function(_) { return arguments.length ? (id = _, force) : id; }; force.iterations = function(_) { return arguments.length ? (iterations = +_, force) : iterations; }; force.strength = function(_) { return arguments.length ? (strength = typeof _ === "function" ? _ : constant(+_), initializeStrength(), force) : strength; }; force.distance = function(_) { return arguments.length ? (distance = typeof _ === "function" ? _ : constant(+_), initializeDistance(), force) : distance; }; return force; }; function x$1(d) { return d.x; } function y$1(d) { return d.y; } var initialRadius = 10; var initialAngle = Math.PI * (3 - Math.sqrt(5)); var simulation = function(nodes) { var simulation, alpha = 1, alphaMin = 0.001, alphaDecay = 1 - Math.pow(alphaMin, 1 / 300), alphaTarget = 0, velocityDecay = 0.6, forces = d3Collection.map(), stepper = d3Timer.timer(step), event = d3Dispatch.dispatch("tick", "end"); if (nodes == null) nodes = []; function step() { tick(); event.call("tick", simulation); if (alpha < alphaMin) { stepper.stop(); event.call("end", simulation); } } function tick() { var i, n = nodes.length, node; alpha += (alphaTarget - alpha) * alphaDecay; forces.each(function(force) { force(alpha); }); for (i = 0; i < n; ++i) { node = nodes[i]; if (node.fx == null) node.x += node.vx *= velocityDecay; else node.x = node.fx, node.vx = 0; if (node.fy == null) node.y += node.vy *= velocityDecay; else node.y = node.fy, node.vy = 0; } } function initializeNodes() { for (var i = 0, n = nodes.length, node; i < n; ++i) { node = nodes[i], node.index = i; if (isNaN(node.x) || isNaN(node.y)) { var radius = initialRadius * Math.sqrt(i), angle = i * initialAngle; node.x = radius * Math.cos(angle); node.y = radius * Math.sin(angle); } if (isNaN(node.vx) || isNaN(node.vy)) { node.vx = node.vy = 0; } } } function initializeForce(force) { if (force.initialize) force.initialize(nodes); return force; } initializeNodes(); return simulation = { tick: tick, restart: function() { return stepper.restart(step), simulation; }, stop: function() { return stepper.stop(), simulation; }, nodes: function(_) { return arguments.length ? (nodes = _, initializeNodes(), forces.each(initializeForce), simulation) : nodes; }, alpha: function(_) { return arguments.length ? (alpha = +_, simulation) : alpha; }, alphaMin: function(_) { return arguments.length ? (alphaMin = +_, simulation) : alphaMin; }, alphaDecay: function(_) { return arguments.length ? (alphaDecay = +_, simulation) : +alphaDecay; }, alphaTarget: function(_) { return arguments.length ? (alphaTarget = +_, simulation) : alphaTarget; }, velocityDecay: function(_) { return arguments.length ? (velocityDecay = 1 - _, simulation) : 1 - velocityDecay; }, force: function(name, _) { return arguments.length > 1 ? ((_ == null ? forces.remove(name) : forces.set(name, initializeForce(_))), simulation) : forces.get(name); }, find: function(x, y, radius) { var i = 0, n = nodes.length, dx, dy, d2, node, closest; if (radius == null) radius = Infinity; else radius *= radius; for (i = 0; i < n; ++i) { node = nodes[i]; dx = x - node.x; dy = y - node.y; d2 = dx * dx + dy * dy; if (d2 < radius) closest = node, radius = d2; } return closest; }, on: function(name, _) { return arguments.length > 1 ? (event.on(name, _), simulation) : event.on(name); } }; }; var manyBody = function() { var nodes, node, alpha, strength = constant(-30), strengths, distanceMin2 = 1, distanceMax2 = Infinity, theta2 = 0.81; function force(_) { var i, n = nodes.length, tree = d3Quadtree.quadtree(nodes, x$1, y$1).visitAfter(accumulate); for (alpha = _, i = 0; i < n; ++i) node = nodes[i], tree.visit(apply); } function initialize() { if (!nodes) return; var i, n = nodes.length, node; strengths = new Array(n); for (i = 0; i < n; ++i) node = nodes[i], strengths[node.index] = +strength(node, i, nodes); } function accumulate(quad) { var strength = 0, q, c, x$$1, y$$1, i; // For internal nodes, accumulate forces from child quadrants. if (quad.length) { for (x$$1 = y$$1 = i = 0; i < 4; ++i) { if ((q = quad[i]) && (c = q.value)) { strength += c, x$$1 += c * q.x, y$$1 += c * q.y; } } quad.x = x$$1 / strength; quad.y = y$$1 / strength; } // For leaf nodes, accumulate forces from coincident quadrants. else { q = quad; q.x = q.data.x; q.y = q.data.y; do strength += strengths[q.data.index]; while (q = q.next); } quad.value = strength; } function apply(quad, x1, _, x2) { if (!quad.value) return true; var x$$1 = quad.x - node.x, y$$1 = quad.y - node.y, w = x2 - x1, l = x$$1 * x$$1 + y$$1 * y$$1; // Apply the Barnes-Hut approximation if possible. // Limit forces for very close nodes; randomize direction if coincident. if (w * w / theta2 < l) { if (l < distanceMax2) { if (x$$1 === 0) x$$1 = jiggle(), l += x$$1 * x$$1; if (y$$1 === 0) y$$1 = jiggle(), l += y$$1 * y$$1; if (l < distanceMin2) l = Math.sqrt(distanceMin2 * l); node.vx += x$$1 * quad.value * alpha / l; node.vy += y$$1 * quad.value * alpha / l; } return true; } // Otherwise, process points directly. else if (quad.length || l >= distanceMax2) return; // Limit forces for very close nodes; randomize direction if coincident. if (quad.data !== node || quad.next) { if (x$$1 === 0) x$$1 = jiggle(), l += x$$1 * x$$1; if (y$$1 === 0) y$$1 = jiggle(), l += y$$1 * y$$1; if (l < distanceMin2) l = Math.sqrt(distanceMin2 * l); } do if (quad.data !== node) { w = strengths[quad.data.index] * alpha / l; node.vx += x$$1 * w; node.vy += y$$1 * w; } while (quad = quad.next); } force.initialize = function(_) { nodes = _; initialize(); }; force.strength = function(_) { return arguments.length ? (strength = typeof _ === "function" ? _ : constant(+_), initialize(), force) : strength; }; force.distanceMin = function(_) { return arguments.length ? (distanceMin2 = _ * _, force) : Math.sqrt(distanceMin2); }; force.distanceMax = function(_) { return arguments.length ? (distanceMax2 = _ * _, force) : Math.sqrt(distanceMax2); }; force.theta = function(_) { return arguments.length ? (theta2 = _ * _, force) : Math.sqrt(theta2); }; return force; }; var x$2 = function(x) { var strength = constant(0.1), nodes, strengths, xz; if (typeof x !== "function") x = constant(x == null ? 0 : +x); function force(alpha) { for (var i = 0, n = nodes.length, node; i < n; ++i) { node = nodes[i], node.vx += (xz[i] - node.x) * strengths[i] * alpha; } } function initialize() { if (!nodes) return; var i, n = nodes.length; strengths = new Array(n); xz = new Array(n); for (i = 0; i < n; ++i) { strengths[i] = isNaN(xz[i] = +x(nodes[i], i, nodes)) ? 0 : +strength(nodes[i], i, nodes); } } force.initialize = function(_) { nodes = _; initialize(); }; force.strength = function(_) { return arguments.length ? (strength = typeof _ === "function" ? _ : constant(+_), initialize(), force) : strength; }; force.x = function(_) { return arguments.length ? (x = typeof _ === "function" ? _ : constant(+_), initialize(), force) : x; }; return force; }; var y$2 = function(y) { var strength = constant(0.1), nodes, strengths, yz; if (typeof y !== "function") y = constant(y == null ? 0 : +y); function force(alpha) { for (var i = 0, n = nodes.length, node; i < n; ++i) { node = nodes[i], node.vy += (yz[i] - node.y) * strengths[i] * alpha; } } function initialize() { if (!nodes) return; var i, n = nodes.length; strengths = new Array(n); yz = new Array(n); for (i = 0; i < n; ++i) { strengths[i] = isNaN(yz[i] = +y(nodes[i], i, nodes)) ? 0 : +strength(nodes[i], i, nodes); } } force.initialize = function(_) { nodes = _; initialize(); }; force.strength = function(_) { return arguments.length ? (strength = typeof _ === "function" ? _ : constant(+_), initialize(), force) : strength; }; force.y = function(_) { return arguments.length ? (y = typeof _ === "function" ? _ : constant(+_), initialize(), force) : y; }; return force; }; exports.forceCenter = center; exports.forceCollide = collide; exports.forceLink = link; exports.forceManyBody = manyBody; exports.forceSimulation = simulation; exports.forceX = x$2; exports.forceY = y$2; Object.defineProperty(exports, '__esModule', { value: true }); }))); },{"d3-collection":19,"d3-dispatch":21,"d3-quadtree":32,"d3-timer":41}],26:[function(require,module,exports){ // https://d3js.org/d3-format/ Version 1.2.0. Copyright 2017 Mike Bostock. (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (factory((global.d3 = global.d3 || {}))); }(this, (function (exports) { 'use strict'; // Computes the decimal coefficient and exponent of the specified number x with // significant digits p, where x is positive and p is in [1, 21] or undefined. // For example, formatDecimal(1.23) returns ["123", 0]. var formatDecimal = function(x, p) { if ((i = (x = p ? x.toExponential(p - 1) : x.toExponential()).indexOf("e")) < 0) return null; // NaN, ±Infinity var i, coefficient = x.slice(0, i); // The string returned by toExponential either has the form \d\.\d+e[-+]\d+ // (e.g., 1.2e+3) or the form \de[-+]\d+ (e.g., 1e+3). return [ coefficient.length > 1 ? coefficient[0] + coefficient.slice(2) : coefficient, +x.slice(i + 1) ]; }; var exponent = function(x) { return x = formatDecimal(Math.abs(x)), x ? x[1] : NaN; }; var formatGroup = function(grouping, thousands) { return function(value, width) { var i = value.length, t = [], j = 0, g = grouping[0], length = 0; while (i > 0 && g > 0) { if (length + g + 1 > width) g = Math.max(1, width - length); t.push(value.substring(i -= g, i + g)); if ((length += g + 1) > width) break; g = grouping[j = (j + 1) % grouping.length]; } return t.reverse().join(thousands); }; }; var formatNumerals = function(numerals) { return function(value) { return value.replace(/[0-9]/g, function(i) { return numerals[+i]; }); }; }; var formatDefault = function(x, p) { x = x.toPrecision(p); out: for (var n = x.length, i = 1, i0 = -1, i1; i < n; ++i) { switch (x[i]) { case ".": i0 = i1 = i; break; case "0": if (i0 === 0) i0 = i; i1 = i; break; case "e": break out; default: if (i0 > 0) i0 = 0; break; } } return i0 > 0 ? x.slice(0, i0) + x.slice(i1 + 1) : x; }; var prefixExponent; var formatPrefixAuto = function(x, p) { var d = formatDecimal(x, p); if (!d) return x + ""; var coefficient = d[0], exponent = d[1], i = exponent - (prefixExponent = Math.max(-8, Math.min(8, Math.floor(exponent / 3))) * 3) + 1, n = coefficient.length; return i === n ? coefficient : i > n ? coefficient + new Array(i - n + 1).join("0") : i > 0 ? coefficient.slice(0, i) + "." + coefficient.slice(i) : "0." + new Array(1 - i).join("0") + formatDecimal(x, Math.max(0, p + i - 1))[0]; // less than 1y! }; var formatRounded = function(x, p) { var d = formatDecimal(x, p); if (!d) return x + ""; var coefficient = d[0], exponent = d[1]; return exponent < 0 ? "0." + new Array(-exponent).join("0") + coefficient : coefficient.length > exponent + 1 ? coefficient.slice(0, exponent + 1) + "." + coefficient.slice(exponent + 1) : coefficient + new Array(exponent - coefficient.length + 2).join("0"); }; var formatTypes = { "": formatDefault, "%": function(x, p) { return (x * 100).toFixed(p); }, "b": function(x) { return Math.round(x).toString(2); }, "c": function(x) { return x + ""; }, "d": function(x) { return Math.round(x).toString(10); }, "e": function(x, p) { return x.toExponential(p); }, "f": function(x, p) { return x.toFixed(p); }, "g": function(x, p) { return x.toPrecision(p); }, "o": function(x) { return Math.round(x).toString(8); }, "p": function(x, p) { return formatRounded(x * 100, p); }, "r": formatRounded, "s": formatPrefixAuto, "X": function(x) { return Math.round(x).toString(16).toUpperCase(); }, "x": function(x) { return Math.round(x).toString(16); } }; // [[fill]align][sign][symbol][0][width][,][.precision][type] var re = /^(?:(.)?([<>=^]))?([+\-\( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?([a-z%])?$/i; function formatSpecifier(specifier) { return new FormatSpecifier(specifier); } formatSpecifier.prototype = FormatSpecifier.prototype; // instanceof function FormatSpecifier(specifier) { if (!(match = re.exec(specifier))) throw new Error("invalid format: " + specifier); var match, fill = match[1] || " ", align = match[2] || ">", sign = match[3] || "-", symbol = match[4] || "", zero = !!match[5], width = match[6] && +match[6], comma = !!match[7], precision = match[8] && +match[8].slice(1), type = match[9] || ""; // The "n" type is an alias for ",g". if (type === "n") comma = true, type = "g"; // Map invalid types to the default format. else if (!formatTypes[type]) type = ""; // If zero fill is specified, padding goes after sign and before digits. if (zero || (fill === "0" && align === "=")) zero = true, fill = "0", align = "="; this.fill = fill; this.align = align; this.sign = sign; this.symbol = symbol; this.zero = zero; this.width = width; this.comma = comma; this.precision = precision; this.type = type; } FormatSpecifier.prototype.toString = function() { return this.fill + this.align + this.sign + this.symbol + (this.zero ? "0" : "") + (this.width == null ? "" : Math.max(1, this.width | 0)) + (this.comma ? "," : "") + (this.precision == null ? "" : "." + Math.max(0, this.precision | 0)) + this.type; }; var identity = function(x) { return x; }; var prefixes = ["y","z","a","f","p","n","µ","m","","k","M","G","T","P","E","Z","Y"]; var formatLocale = function(locale) { var group = locale.grouping && locale.thousands ? formatGroup(locale.grouping, locale.thousands) : identity, currency = locale.currency, decimal = locale.decimal, numerals = locale.numerals ? formatNumerals(locale.numerals) : identity, percent = locale.percent || "%"; function newFormat(specifier) { specifier = formatSpecifier(specifier); var fill = specifier.fill, align = specifier.align, sign = specifier.sign, symbol = specifier.symbol, zero = specifier.zero, width = specifier.width, comma = specifier.comma, precision = specifier.precision, type = specifier.type; // Compute the prefix and suffix. // For SI-prefix, the suffix is lazily computed. var prefix = symbol === "$" ? currency[0] : symbol === "#" && /[boxX]/.test(type) ? "0" + type.toLowerCase() : "", suffix = symbol === "$" ? currency[1] : /[%p]/.test(type) ? percent : ""; // What format function should we use? // Is this an integer type? // Can this type generate exponential notation? var formatType = formatTypes[type], maybeSuffix = !type || /[defgprs%]/.test(type); // Set the default precision if not specified, // or clamp the specified precision to the supported range. // For significant precision, it must be in [1, 21]. // For fixed precision, it must be in [0, 20]. precision = precision == null ? (type ? 6 : 12) : /[gprs]/.test(type) ? Math.max(1, Math.min(21, precision)) : Math.max(0, Math.min(20, precision)); function format(value) { var valuePrefix = prefix, valueSuffix = suffix, i, n, c; if (type === "c") { valueSuffix = formatType(value) + valueSuffix; value = ""; } else { value = +value; // Perform the initial formatting. var valueNegative = value < 0; value = formatType(Math.abs(value), precision); // If a negative value rounds to zero during formatting, treat as positive. if (valueNegative && +value === 0) valueNegative = false; // Compute the prefix and suffix. valuePrefix = (valueNegative ? (sign === "(" ? sign : "-") : sign === "-" || sign === "(" ? "" : sign) + valuePrefix; valueSuffix = valueSuffix + (type === "s" ? prefixes[8 + prefixExponent / 3] : "") + (valueNegative && sign === "(" ? ")" : ""); // Break the formatted value into the integer “value” part that can be // grouped, and fractional or exponential “suffix” part that is not. if (maybeSuffix) { i = -1, n = value.length; while (++i < n) { if (c = value.charCodeAt(i), 48 > c || c > 57) { valueSuffix = (c === 46 ? decimal + value.slice(i + 1) : value.slice(i)) + valueSuffix; value = value.slice(0, i); break; } } } } // If the fill character is not "0", grouping is applied before padding. if (comma && !zero) value = group(value, Infinity); // Compute the padding. var length = valuePrefix.length + value.length + valueSuffix.length, padding = length < width ? new Array(width - length + 1).join(fill) : ""; // If the fill character is "0", grouping is applied after padding. if (comma && zero) value = group(padding + value, padding.length ? width - valueSuffix.length : Infinity), padding = ""; // Reconstruct the final output based on the desired alignment. switch (align) { case "<": value = valuePrefix + value + valueSuffix + padding; break; case "=": value = valuePrefix + padding + value + valueSuffix; break; case "^": value = padding.slice(0, length = padding.length >> 1) + valuePrefix + value + valueSuffix + padding.slice(length); break; default: value = padding + valuePrefix + value + valueSuffix; break; } return numerals(value); } format.toString = function() { return specifier + ""; }; return format; } function formatPrefix(specifier, value) { var f = newFormat((specifier = formatSpecifier(specifier), specifier.type = "f", specifier)), e = Math.max(-8, Math.min(8, Math.floor(exponent(value) / 3))) * 3, k = Math.pow(10, -e), prefix = prefixes[8 + e / 3]; return function(value) { return f(k * value) + prefix; }; } return { format: newFormat, formatPrefix: formatPrefix }; }; var locale; defaultLocale({ decimal: ".", thousands: ",", grouping: [3], currency: ["$", ""] }); function defaultLocale(definition) { locale = formatLocale(definition); exports.format = locale.format; exports.formatPrefix = locale.formatPrefix; return locale; } var precisionFixed = function(step) { return Math.max(0, -exponent(Math.abs(step))); }; var precisionPrefix = function(step, value) { return Math.max(0, Math.max(-8, Math.min(8, Math.floor(exponent(value) / 3))) * 3 - exponent(Math.abs(step))); }; var precisionRound = function(step, max) { step = Math.abs(step), max = Math.abs(max) - step; return Math.max(0, exponent(max) - exponent(step)) + 1; }; exports.formatDefaultLocale = defaultLocale; exports.formatLocale = formatLocale; exports.formatSpecifier = formatSpecifier; exports.precisionFixed = precisionFixed; exports.precisionPrefix = precisionPrefix; exports.precisionRound = precisionRound; Object.defineProperty(exports, '__esModule', { value: true }); }))); },{}],27:[function(require,module,exports){ // https://d3js.org/d3-geo/ Version 1.6.4. Copyright 2017 Mike Bostock. (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('d3-array')) : typeof define === 'function' && define.amd ? define(['exports', 'd3-array'], factory) : (factory((global.d3 = global.d3 || {}),global.d3)); }(this, (function (exports,d3Array) { 'use strict'; // Adds floating point numbers with twice the normal precision. // Reference: J. R. Shewchuk, Adaptive Precision Floating-Point Arithmetic and // Fast Robust Geometric Predicates, Discrete & Computational Geometry 18(3) // 305–363 (1997). // Code adapted from GeographicLib by Charles F. F. Karney, // http://geographiclib.sourceforge.net/ var adder = function() { return new Adder; }; function Adder() { this.reset(); } Adder.prototype = { constructor: Adder, reset: function() { this.s = // rounded value this.t = 0; // exact error }, add: function(y) { add(temp, y, this.t); add(this, temp.s, this.s); if (this.s) this.t += temp.t; else this.s = temp.t; }, valueOf: function() { return this.s; } }; var temp = new Adder; function add(adder, a, b) { var x = adder.s = a + b, bv = x - a, av = x - bv; adder.t = (a - av) + (b - bv); } var epsilon = 1e-6; var epsilon2 = 1e-12; var pi = Math.PI; var halfPi = pi / 2; var quarterPi = pi / 4; var tau = pi * 2; var degrees = 180 / pi; var radians = pi / 180; var abs = Math.abs; var atan = Math.atan; var atan2 = Math.atan2; var cos = Math.cos; var ceil = Math.ceil; var exp = Math.exp; var log = Math.log; var pow = Math.pow; var sin = Math.sin; var sign = Math.sign || function(x) { return x > 0 ? 1 : x < 0 ? -1 : 0; }; var sqrt = Math.sqrt; var tan = Math.tan; function acos(x) { return x > 1 ? 0 : x < -1 ? pi : Math.acos(x); } function asin(x) { return x > 1 ? halfPi : x < -1 ? -halfPi : Math.asin(x); } function haversin(x) { return (x = sin(x / 2)) * x; } function noop() {} function streamGeometry(geometry, stream) { if (geometry && streamGeometryType.hasOwnProperty(geometry.type)) { streamGeometryType[geometry.type](geometry, stream); } } var streamObjectType = { Feature: function(object, stream) { streamGeometry(object.geometry, stream); }, FeatureCollection: function(object, stream) { var features = object.features, i = -1, n = features.length; while (++i < n) streamGeometry(features[i].geometry, stream); } }; var streamGeometryType = { Sphere: function(object, stream) { stream.sphere(); }, Point: function(object, stream) { object = object.coordinates; stream.point(object[0], object[1], object[2]); }, MultiPoint: function(object, stream) { var coordinates = object.coordinates, i = -1, n = coordinates.length; while (++i < n) object = coordinates[i], stream.point(object[0], object[1], object[2]); }, LineString: function(object, stream) { streamLine(object.coordinates, stream, 0); }, MultiLineString: function(object, stream) { var coordinates = object.coordinates, i = -1, n = coordinates.length; while (++i < n) streamLine(coordinates[i], stream, 0); }, Polygon: function(object, stream) { streamPolygon(object.coordinates, stream); }, MultiPolygon: function(object, stream) { var coordinates = object.coordinates, i = -1, n = coordinates.length; while (++i < n) streamPolygon(coordinates[i], stream); }, GeometryCollection: function(object, stream) { var geometries = object.geometries, i = -1, n = geometries.length; while (++i < n) streamGeometry(geometries[i], stream); } }; function streamLine(coordinates, stream, closed) { var i = -1, n = coordinates.length - closed, coordinate; stream.lineStart(); while (++i < n) coordinate = coordinates[i], stream.point(coordinate[0], coordinate[1], coordinate[2]); stream.lineEnd(); } function streamPolygon(coordinates, stream) { var i = -1, n = coordinates.length; stream.polygonStart(); while (++i < n) streamLine(coordinates[i], stream, 1); stream.polygonEnd(); } var geoStream = function(object, stream) { if (object && streamObjectType.hasOwnProperty(object.type)) { streamObjectType[object.type](object, stream); } else { streamGeometry(object, stream); } }; var areaRingSum = adder(); var areaSum = adder(); var lambda00; var phi00; var lambda0; var cosPhi0; var sinPhi0; var areaStream = { point: noop, lineStart: noop, lineEnd: noop, polygonStart: function() { areaRingSum.reset(); areaStream.lineStart = areaRingStart; areaStream.lineEnd = areaRingEnd; }, polygonEnd: function() { var areaRing = +areaRingSum; areaSum.add(areaRing < 0 ? tau + areaRing : areaRing); this.lineStart = this.lineEnd = this.point = noop; }, sphere: function() { areaSum.add(tau); } }; function areaRingStart() { areaStream.point = areaPointFirst; } function areaRingEnd() { areaPoint(lambda00, phi00); } function areaPointFirst(lambda, phi) { areaStream.point = areaPoint; lambda00 = lambda, phi00 = phi; lambda *= radians, phi *= radians; lambda0 = lambda, cosPhi0 = cos(phi = phi / 2 + quarterPi), sinPhi0 = sin(phi); } function areaPoint(lambda, phi) { lambda *= radians, phi *= radians; phi = phi / 2 + quarterPi; // half the angular distance from south pole // Spherical excess E for a spherical triangle with vertices: south pole, // previous point, current point. Uses a formula derived from Cagnoli’s // theorem. See Todhunter, Spherical Trig. (1871), Sec. 103, Eq. (2). var dLambda = lambda - lambda0, sdLambda = dLambda >= 0 ? 1 : -1, adLambda = sdLambda * dLambda, cosPhi = cos(phi), sinPhi = sin(phi), k = sinPhi0 * sinPhi, u = cosPhi0 * cosPhi + k * cos(adLambda), v = k * sdLambda * sin(adLambda); areaRingSum.add(atan2(v, u)); // Advance the previous points. lambda0 = lambda, cosPhi0 = cosPhi, sinPhi0 = sinPhi; } var area = function(object) { areaSum.reset(); geoStream(object, areaStream); return areaSum * 2; }; function spherical(cartesian) { return [atan2(cartesian[1], cartesian[0]), asin(cartesian[2])]; } function cartesian(spherical) { var lambda = spherical[0], phi = spherical[1], cosPhi = cos(phi); return [cosPhi * cos(lambda), cosPhi * sin(lambda), sin(phi)]; } function cartesianDot(a, b) { return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; } function cartesianCross(a, b) { return [a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0]]; } // TODO return a function cartesianAddInPlace(a, b) { a[0] += b[0], a[1] += b[1], a[2] += b[2]; } function cartesianScale(vector, k) { return [vector[0] * k, vector[1] * k, vector[2] * k]; } // TODO return d function cartesianNormalizeInPlace(d) { var l = sqrt(d[0] * d[0] + d[1] * d[1] + d[2] * d[2]); d[0] /= l, d[1] /= l, d[2] /= l; } var lambda0$1; var phi0; var lambda1; var phi1; var lambda2; var lambda00$1; var phi00$1; var p0; var deltaSum = adder(); var ranges; var range$1; var boundsStream = { point: boundsPoint, lineStart: boundsLineStart, lineEnd: boundsLineEnd, polygonStart: function() { boundsStream.point = boundsRingPoint; boundsStream.lineStart = boundsRingStart; boundsStream.lineEnd = boundsRingEnd; deltaSum.reset(); areaStream.polygonStart(); }, polygonEnd: function() { areaStream.polygonEnd(); boundsStream.point = boundsPoint; boundsStream.lineStart = boundsLineStart; boundsStream.lineEnd = boundsLineEnd; if (areaRingSum < 0) lambda0$1 = -(lambda1 = 180), phi0 = -(phi1 = 90); else if (deltaSum > epsilon) phi1 = 90; else if (deltaSum < -epsilon) phi0 = -90; range$1[0] = lambda0$1, range$1[1] = lambda1; } }; function boundsPoint(lambda, phi) { ranges.push(range$1 = [lambda0$1 = lambda, lambda1 = lambda]); if (phi < phi0) phi0 = phi; if (phi > phi1) phi1 = phi; } function linePoint(lambda, phi) { var p = cartesian([lambda * radians, phi * radians]); if (p0) { var normal = cartesianCross(p0, p), equatorial = [normal[1], -normal[0], 0], inflection = cartesianCross(equatorial, normal); cartesianNormalizeInPlace(inflection); inflection = spherical(inflection); var delta = lambda - lambda2, sign$$1 = delta > 0 ? 1 : -1, lambdai = inflection[0] * degrees * sign$$1, phii, antimeridian = abs(delta) > 180; if (antimeridian ^ (sign$$1 * lambda2 < lambdai && lambdai < sign$$1 * lambda)) { phii = inflection[1] * degrees; if (phii > phi1) phi1 = phii; } else if (lambdai = (lambdai + 360) % 360 - 180, antimeridian ^ (sign$$1 * lambda2 < lambdai && lambdai < sign$$1 * lambda)) { phii = -inflection[1] * degrees; if (phii < phi0) phi0 = phii; } else { if (phi < phi0) phi0 = phi; if (phi > phi1) phi1 = phi; } if (antimeridian) { if (lambda < lambda2) { if (angle(lambda0$1, lambda) > angle(lambda0$1, lambda1)) lambda1 = lambda; } else { if (angle(lambda, lambda1) > angle(lambda0$1, lambda1)) lambda0$1 = lambda; } } else { if (lambda1 >= lambda0$1) { if (lambda < lambda0$1) lambda0$1 = lambda; if (lambda > lambda1) lambda1 = lambda; } else { if (lambda > lambda2) { if (angle(lambda0$1, lambda) > angle(lambda0$1, lambda1)) lambda1 = lambda; } else { if (angle(lambda, lambda1) > angle(lambda0$1, lambda1)) lambda0$1 = lambda; } } } } else { ranges.push(range$1 = [lambda0$1 = lambda, lambda1 = lambda]); } if (phi < phi0) phi0 = phi; if (phi > phi1) phi1 = phi; p0 = p, lambda2 = lambda; } function boundsLineStart() { boundsStream.point = linePoint; } function boundsLineEnd() { range$1[0] = lambda0$1, range$1[1] = lambda1; boundsStream.point = boundsPoint; p0 = null; } function boundsRingPoint(lambda, phi) { if (p0) { var delta = lambda - lambda2; deltaSum.add(abs(delta) > 180 ? delta + (delta > 0 ? 360 : -360) : delta); } else { lambda00$1 = lambda, phi00$1 = phi; } areaStream.point(lambda, phi); linePoint(lambda, phi); } function boundsRingStart() { areaStream.lineStart(); } function boundsRingEnd() { boundsRingPoint(lambda00$1, phi00$1); areaStream.lineEnd(); if (abs(deltaSum) > epsilon) lambda0$1 = -(lambda1 = 180); range$1[0] = lambda0$1, range$1[1] = lambda1; p0 = null; } // Finds the left-right distance between two longitudes. // This is almost the same as (lambda1 - lambda0 + 360°) % 360°, except that we want // the distance between ±180° to be 360°. function angle(lambda0, lambda1) { return (lambda1 -= lambda0) < 0 ? lambda1 + 360 : lambda1; } function rangeCompare(a, b) { return a[0] - b[0]; } function rangeContains(range$$1, x) { return range$$1[0] <= range$$1[1] ? range$$1[0] <= x && x <= range$$1[1] : x < range$$1[0] || range$$1[1] < x; } var bounds = function(feature) { var i, n, a, b, merged, deltaMax, delta; phi1 = lambda1 = -(lambda0$1 = phi0 = Infinity); ranges = []; geoStream(feature, boundsStream); // First, sort ranges by their minimum longitudes. if (n = ranges.length) { ranges.sort(rangeCompare); // Then, merge any ranges that overlap. for (i = 1, a = ranges[0], merged = [a]; i < n; ++i) { b = ranges[i]; if (rangeContains(a, b[0]) || rangeContains(a, b[1])) { if (angle(a[0], b[1]) > angle(a[0], a[1])) a[1] = b[1]; if (angle(b[0], a[1]) > angle(a[0], a[1])) a[0] = b[0]; } else { merged.push(a = b); } } // Finally, find the largest gap between the merged ranges. // The final bounding box will be the inverse of this gap. for (deltaMax = -Infinity, n = merged.length - 1, i = 0, a = merged[n]; i <= n; a = b, ++i) { b = merged[i]; if ((delta = angle(a[1], b[0])) > deltaMax) deltaMax = delta, lambda0$1 = b[0], lambda1 = a[1]; } } ranges = range$1 = null; return lambda0$1 === Infinity || phi0 === Infinity ? [[NaN, NaN], [NaN, NaN]] : [[lambda0$1, phi0], [lambda1, phi1]]; }; var W0; var W1; var X0; var Y0; var Z0; var X1; var Y1; var Z1; var X2; var Y2; var Z2; var lambda00$2; var phi00$2; var x0; var y0; var z0; // previous point var centroidStream = { sphere: noop, point: centroidPoint, lineStart: centroidLineStart, lineEnd: centroidLineEnd, polygonStart: function() { centroidStream.lineStart = centroidRingStart; centroidStream.lineEnd = centroidRingEnd; }, polygonEnd: function() { centroidStream.lineStart = centroidLineStart; centroidStream.lineEnd = centroidLineEnd; } }; // Arithmetic mean of Cartesian vectors. function centroidPoint(lambda, phi) { lambda *= radians, phi *= radians; var cosPhi = cos(phi); centroidPointCartesian(cosPhi * cos(lambda), cosPhi * sin(lambda), sin(phi)); } function centroidPointCartesian(x, y, z) { ++W0; X0 += (x - X0) / W0; Y0 += (y - Y0) / W0; Z0 += (z - Z0) / W0; } function centroidLineStart() { centroidStream.point = centroidLinePointFirst; } function centroidLinePointFirst(lambda, phi) { lambda *= radians, phi *= radians; var cosPhi = cos(phi); x0 = cosPhi * cos(lambda); y0 = cosPhi * sin(lambda); z0 = sin(phi); centroidStream.point = centroidLinePoint; centroidPointCartesian(x0, y0, z0); } function centroidLinePoint(lambda, phi) { lambda *= radians, phi *= radians; var cosPhi = cos(phi), x = cosPhi * cos(lambda), y = cosPhi * sin(lambda), z = sin(phi), w = atan2(sqrt((w = y0 * z - z0 * y) * w + (w = z0 * x - x0 * z) * w + (w = x0 * y - y0 * x) * w), x0 * x + y0 * y + z0 * z); W1 += w; X1 += w * (x0 + (x0 = x)); Y1 += w * (y0 + (y0 = y)); Z1 += w * (z0 + (z0 = z)); centroidPointCartesian(x0, y0, z0); } function centroidLineEnd() { centroidStream.point = centroidPoint; } // See J. E. Brock, The Inertia Tensor for a Spherical Triangle, // J. Applied Mechanics 42, 239 (1975). function centroidRingStart() { centroidStream.point = centroidRingPointFirst; } function centroidRingEnd() { centroidRingPoint(lambda00$2, phi00$2); centroidStream.point = centroidPoint; } function centroidRingPointFirst(lambda, phi) { lambda00$2 = lambda, phi00$2 = phi; lambda *= radians, phi *= radians; centroidStream.point = centroidRingPoint; var cosPhi = cos(phi); x0 = cosPhi * cos(lambda); y0 = cosPhi * sin(lambda); z0 = sin(phi); centroidPointCartesian(x0, y0, z0); } function centroidRingPoint(lambda, phi) { lambda *= radians, phi *= radians; var cosPhi = cos(phi), x = cosPhi * cos(lambda), y = cosPhi * sin(lambda), z = sin(phi), cx = y0 * z - z0 * y, cy = z0 * x - x0 * z, cz = x0 * y - y0 * x, m = sqrt(cx * cx + cy * cy + cz * cz), w = asin(m), // line weight = angle v = m && -w / m; // area weight multiplier X2 += v * cx; Y2 += v * cy; Z2 += v * cz; W1 += w; X1 += w * (x0 + (x0 = x)); Y1 += w * (y0 + (y0 = y)); Z1 += w * (z0 + (z0 = z)); centroidPointCartesian(x0, y0, z0); } var centroid = function(object) { W0 = W1 = X0 = Y0 = Z0 = X1 = Y1 = Z1 = X2 = Y2 = Z2 = 0; geoStream(object, centroidStream); var x = X2, y = Y2, z = Z2, m = x * x + y * y + z * z; // If the area-weighted ccentroid is undefined, fall back to length-weighted ccentroid. if (m < epsilon2) { x = X1, y = Y1, z = Z1; // If the feature has zero length, fall back to arithmetic mean of point vectors. if (W1 < epsilon) x = X0, y = Y0, z = Z0; m = x * x + y * y + z * z; // If the feature still has an undefined ccentroid, then return. if (m < epsilon2) return [NaN, NaN]; } return [atan2(y, x) * degrees, asin(z / sqrt(m)) * degrees]; }; var constant = function(x) { return function() { return x; }; }; var compose = function(a, b) { function compose(x, y) { return x = a(x, y), b(x[0], x[1]); } if (a.invert && b.invert) compose.invert = function(x, y) { return x = b.invert(x, y), x && a.invert(x[0], x[1]); }; return compose; }; function rotationIdentity(lambda, phi) { return [lambda > pi ? lambda - tau : lambda < -pi ? lambda + tau : lambda, phi]; } rotationIdentity.invert = rotationIdentity; function rotateRadians(deltaLambda, deltaPhi, deltaGamma) { return (deltaLambda %= tau) ? (deltaPhi || deltaGamma ? compose(rotationLambda(deltaLambda), rotationPhiGamma(deltaPhi, deltaGamma)) : rotationLambda(deltaLambda)) : (deltaPhi || deltaGamma ? rotationPhiGamma(deltaPhi, deltaGamma) : rotationIdentity); } function forwardRotationLambda(deltaLambda) { return function(lambda, phi) { return lambda += deltaLambda, [lambda > pi ? lambda - tau : lambda < -pi ? lambda + tau : lambda, phi]; }; } function rotationLambda(deltaLambda) { var rotation = forwardRotationLambda(deltaLambda); rotation.invert = forwardRotationLambda(-deltaLambda); return rotation; } function rotationPhiGamma(deltaPhi, deltaGamma) { var cosDeltaPhi = cos(deltaPhi), sinDeltaPhi = sin(deltaPhi), cosDeltaGamma = cos(deltaGamma), sinDeltaGamma = sin(deltaGamma); function rotation(lambda, phi) { var cosPhi = cos(phi), x = cos(lambda) * cosPhi, y = sin(lambda) * cosPhi, z = sin(phi), k = z * cosDeltaPhi + x * sinDeltaPhi; return [ atan2(y * cosDeltaGamma - k * sinDeltaGamma, x * cosDeltaPhi - z * sinDeltaPhi), asin(k * cosDeltaGamma + y * sinDeltaGamma) ]; } rotation.invert = function(lambda, phi) { var cosPhi = cos(phi), x = cos(lambda) * cosPhi, y = sin(lambda) * cosPhi, z = sin(phi), k = z * cosDeltaGamma - y * sinDeltaGamma; return [ atan2(y * cosDeltaGamma + z * sinDeltaGamma, x * cosDeltaPhi + k * sinDeltaPhi), asin(k * cosDeltaPhi - x * sinDeltaPhi) ]; }; return rotation; } var rotation = function(rotate) { rotate = rotateRadians(rotate[0] * radians, rotate[1] * radians, rotate.length > 2 ? rotate[2] * radians : 0); function forward(coordinates) { coordinates = rotate(coordinates[0] * radians, coordinates[1] * radians); return coordinates[0] *= degrees, coordinates[1] *= degrees, coordinates; } forward.invert = function(coordinates) { coordinates = rotate.invert(coordinates[0] * radians, coordinates[1] * radians); return coordinates[0] *= degrees, coordinates[1] *= degrees, coordinates; }; return forward; }; // Generates a circle centered at [0°, 0°], with a given radius and precision. function circleStream(stream, radius, delta, direction, t0, t1) { if (!delta) return; var cosRadius = cos(radius), sinRadius = sin(radius), step = direction * delta; if (t0 == null) { t0 = radius + direction * tau; t1 = radius - step / 2; } else { t0 = circleRadius(cosRadius, t0); t1 = circleRadius(cosRadius, t1); if (direction > 0 ? t0 < t1 : t0 > t1) t0 += direction * tau; } for (var point, t = t0; direction > 0 ? t > t1 : t < t1; t -= step) { point = spherical([cosRadius, -sinRadius * cos(t), -sinRadius * sin(t)]); stream.point(point[0], point[1]); } } // Returns the signed angle of a cartesian point relative to [cosRadius, 0, 0]. function circleRadius(cosRadius, point) { point = cartesian(point), point[0] -= cosRadius; cartesianNormalizeInPlace(point); var radius = acos(-point[1]); return ((-point[2] < 0 ? -radius : radius) + tau - epsilon) % tau; } var circle = function() { var center = constant([0, 0]), radius = constant(90), precision = constant(6), ring, rotate, stream = {point: point}; function point(x, y) { ring.push(x = rotate(x, y)); x[0] *= degrees, x[1] *= degrees; } function circle() { var c = center.apply(this, arguments), r = radius.apply(this, arguments) * radians, p = precision.apply(this, arguments) * radians; ring = []; rotate = rotateRadians(-c[0] * radians, -c[1] * radians, 0).invert; circleStream(stream, r, p, 1); c = {type: "Polygon", coordinates: [ring]}; ring = rotate = null; return c; } circle.center = function(_) { return arguments.length ? (center = typeof _ === "function" ? _ : constant([+_[0], +_[1]]), circle) : center; }; circle.radius = function(_) { return arguments.length ? (radius = typeof _ === "function" ? _ : constant(+_), circle) : radius; }; circle.precision = function(_) { return arguments.length ? (precision = typeof _ === "function" ? _ : constant(+_), circle) : precision; }; return circle; }; var clipBuffer = function() { var lines = [], line; return { point: function(x, y) { line.push([x, y]); }, lineStart: function() { lines.push(line = []); }, lineEnd: noop, rejoin: function() { if (lines.length > 1) lines.push(lines.pop().concat(lines.shift())); }, result: function() { var result = lines; lines = []; line = null; return result; } }; }; var clipLine = function(a, b, x0, y0, x1, y1) { var ax = a[0], ay = a[1], bx = b[0], by = b[1], t0 = 0, t1 = 1, dx = bx - ax, dy = by - ay, r; r = x0 - ax; if (!dx && r > 0) return; r /= dx; if (dx < 0) { if (r < t0) return; if (r < t1) t1 = r; } else if (dx > 0) { if (r > t1) return; if (r > t0) t0 = r; } r = x1 - ax; if (!dx && r < 0) return; r /= dx; if (dx < 0) { if (r > t1) return; if (r > t0) t0 = r; } else if (dx > 0) { if (r < t0) return; if (r < t1) t1 = r; } r = y0 - ay; if (!dy && r > 0) return; r /= dy; if (dy < 0) { if (r < t0) return; if (r < t1) t1 = r; } else if (dy > 0) { if (r > t1) return; if (r > t0) t0 = r; } r = y1 - ay; if (!dy && r < 0) return; r /= dy; if (dy < 0) { if (r > t1) return; if (r > t0) t0 = r; } else if (dy > 0) { if (r < t0) return; if (r < t1) t1 = r; } if (t0 > 0) a[0] = ax + t0 * dx, a[1] = ay + t0 * dy; if (t1 < 1) b[0] = ax + t1 * dx, b[1] = ay + t1 * dy; return true; }; var pointEqual = function(a, b) { return abs(a[0] - b[0]) < epsilon && abs(a[1] - b[1]) < epsilon; }; function Intersection(point, points, other, entry) { this.x = point; this.z = points; this.o = other; // another intersection this.e = entry; // is an entry? this.v = false; // visited this.n = this.p = null; // next & previous } // A generalized polygon clipping algorithm: given a polygon that has been cut // into its visible line segments, and rejoins the segments by interpolating // along the clip edge. var clipPolygon = function(segments, compareIntersection, startInside, interpolate, stream) { var subject = [], clip = [], i, n; segments.forEach(function(segment) { if ((n = segment.length - 1) <= 0) return; var n, p0 = segment[0], p1 = segment[n], x; // If the first and last points of a segment are coincident, then treat as a // closed ring. TODO if all rings are closed, then the winding order of the // exterior ring should be checked. if (pointEqual(p0, p1)) { stream.lineStart(); for (i = 0; i < n; ++i) stream.point((p0 = segment[i])[0], p0[1]); stream.lineEnd(); return; } subject.push(x = new Intersection(p0, segment, null, true)); clip.push(x.o = new Intersection(p0, null, x, false)); subject.push(x = new Intersection(p1, segment, null, false)); clip.push(x.o = new Intersection(p1, null, x, true)); }); if (!subject.length) return; clip.sort(compareIntersection); link(subject); link(clip); for (i = 0, n = clip.length; i < n; ++i) { clip[i].e = startInside = !startInside; } var start = subject[0], points, point; while (1) { // Find first unvisited intersection. var current = start, isSubject = true; while (current.v) if ((current = current.n) === start) return; points = current.z; stream.lineStart(); do { current.v = current.o.v = true; if (current.e) { if (isSubject) { for (i = 0, n = points.length; i < n; ++i) stream.point((point = points[i])[0], point[1]); } else { interpolate(current.x, current.n.x, 1, stream); } current = current.n; } else { if (isSubject) { points = current.p.z; for (i = points.length - 1; i >= 0; --i) stream.point((point = points[i])[0], point[1]); } else { interpolate(current.x, current.p.x, -1, stream); } current = current.p; } current = current.o; points = current.z; isSubject = !isSubject; } while (!current.v); stream.lineEnd(); } }; function link(array) { if (!(n = array.length)) return; var n, i = 0, a = array[0], b; while (++i < n) { a.n = b = array[i]; b.p = a; a = b; } a.n = b = array[0]; b.p = a; } var clipMax = 1e9; var clipMin = -clipMax; // TODO Use d3-polygon’s polygonContains here for the ring check? // TODO Eliminate duplicate buffering in clipBuffer and polygon.push? function clipExtent(x0, y0, x1, y1) { function visible(x, y) { return x0 <= x && x <= x1 && y0 <= y && y <= y1; } function interpolate(from, to, direction, stream) { var a = 0, a1 = 0; if (from == null || (a = corner(from, direction)) !== (a1 = corner(to, direction)) || comparePoint(from, to) < 0 ^ direction > 0) { do stream.point(a === 0 || a === 3 ? x0 : x1, a > 1 ? y1 : y0); while ((a = (a + direction + 4) % 4) !== a1); } else { stream.point(to[0], to[1]); } } function corner(p, direction) { return abs(p[0] - x0) < epsilon ? direction > 0 ? 0 : 3 : abs(p[0] - x1) < epsilon ? direction > 0 ? 2 : 1 : abs(p[1] - y0) < epsilon ? direction > 0 ? 1 : 0 : direction > 0 ? 3 : 2; // abs(p[1] - y1) < epsilon } function compareIntersection(a, b) { return comparePoint(a.x, b.x); } function comparePoint(a, b) { var ca = corner(a, 1), cb = corner(b, 1); return ca !== cb ? ca - cb : ca === 0 ? b[1] - a[1] : ca === 1 ? a[0] - b[0] : ca === 2 ? a[1] - b[1] : b[0] - a[0]; } return function(stream) { var activeStream = stream, bufferStream = clipBuffer(), segments, polygon, ring, x__, y__, v__, // first point x_, y_, v_, // previous point first, clean; var clipStream = { point: point, lineStart: lineStart, lineEnd: lineEnd, polygonStart: polygonStart, polygonEnd: polygonEnd }; function point(x, y) { if (visible(x, y)) activeStream.point(x, y); } function polygonInside() { var winding = 0; for (var i = 0, n = polygon.length; i < n; ++i) { for (var ring = polygon[i], j = 1, m = ring.length, point = ring[0], a0, a1, b0 = point[0], b1 = point[1]; j < m; ++j) { a0 = b0, a1 = b1, point = ring[j], b0 = point[0], b1 = point[1]; if (a1 <= y1) { if (b1 > y1 && (b0 - a0) * (y1 - a1) > (b1 - a1) * (x0 - a0)) ++winding; } else { if (b1 <= y1 && (b0 - a0) * (y1 - a1) < (b1 - a1) * (x0 - a0)) --winding; } } } return winding; } // Buffer geometry within a polygon and then clip it en masse. function polygonStart() { activeStream = bufferStream, segments = [], polygon = [], clean = true; } function polygonEnd() { var startInside = polygonInside(), cleanInside = clean && startInside, visible = (segments = d3Array.merge(segments)).length; if (cleanInside || visible) { stream.polygonStart(); if (cleanInside) { stream.lineStart(); interpolate(null, null, 1, stream); stream.lineEnd(); } if (visible) { clipPolygon(segments, compareIntersection, startInside, interpolate, stream); } stream.polygonEnd(); } activeStream = stream, segments = polygon = ring = null; } function lineStart() { clipStream.point = linePoint; if (polygon) polygon.push(ring = []); first = true; v_ = false; x_ = y_ = NaN; } // TODO rather than special-case polygons, simply handle them separately. // Ideally, coincident intersection points should be jittered to avoid // clipping issues. function lineEnd() { if (segments) { linePoint(x__, y__); if (v__ && v_) bufferStream.rejoin(); segments.push(bufferStream.result()); } clipStream.point = point; if (v_) activeStream.lineEnd(); } function linePoint(x, y) { var v = visible(x, y); if (polygon) ring.push([x, y]); if (first) { x__ = x, y__ = y, v__ = v; first = false; if (v) { activeStream.lineStart(); activeStream.point(x, y); } } else { if (v && v_) activeStream.point(x, y); else { var a = [x_ = Math.max(clipMin, Math.min(clipMax, x_)), y_ = Math.max(clipMin, Math.min(clipMax, y_))], b = [x = Math.max(clipMin, Math.min(clipMax, x)), y = Math.max(clipMin, Math.min(clipMax, y))]; if (clipLine(a, b, x0, y0, x1, y1)) { if (!v_) { activeStream.lineStart(); activeStream.point(a[0], a[1]); } activeStream.point(b[0], b[1]); if (!v) activeStream.lineEnd(); clean = false; } else if (v) { activeStream.lineStart(); activeStream.point(x, y); clean = false; } } } x_ = x, y_ = y, v_ = v; } return clipStream; }; } var extent = function() { var x0 = 0, y0 = 0, x1 = 960, y1 = 500, cache, cacheStream, clip; return clip = { stream: function(stream) { return cache && cacheStream === stream ? cache : cache = clipExtent(x0, y0, x1, y1)(cacheStream = stream); }, extent: function(_) { return arguments.length ? (x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1], cache = cacheStream = null, clip) : [[x0, y0], [x1, y1]]; } }; }; var sum = adder(); var polygonContains = function(polygon, point) { var lambda = point[0], phi = point[1], normal = [sin(lambda), -cos(lambda), 0], angle = 0, winding = 0; sum.reset(); for (var i = 0, n = polygon.length; i < n; ++i) { if (!(m = (ring = polygon[i]).length)) continue; var ring, m, point0 = ring[m - 1], lambda0 = point0[0], phi0 = point0[1] / 2 + quarterPi, sinPhi0 = sin(phi0), cosPhi0 = cos(phi0); for (var j = 0; j < m; ++j, lambda0 = lambda1, sinPhi0 = sinPhi1, cosPhi0 = cosPhi1, point0 = point1) { var point1 = ring[j], lambda1 = point1[0], phi1 = point1[1] / 2 + quarterPi, sinPhi1 = sin(phi1), cosPhi1 = cos(phi1), delta = lambda1 - lambda0, sign$$1 = delta >= 0 ? 1 : -1, absDelta = sign$$1 * delta, antimeridian = absDelta > pi, k = sinPhi0 * sinPhi1; sum.add(atan2(k * sign$$1 * sin(absDelta), cosPhi0 * cosPhi1 + k * cos(absDelta))); angle += antimeridian ? delta + sign$$1 * tau : delta; // Are the longitudes either side of the point’s meridian (lambda), // and are the latitudes smaller than the parallel (phi)? if (antimeridian ^ lambda0 >= lambda ^ lambda1 >= lambda) { var arc = cartesianCross(cartesian(point0), cartesian(point1)); cartesianNormalizeInPlace(arc); var intersection = cartesianCross(normal, arc); cartesianNormalizeInPlace(intersection); var phiArc = (antimeridian ^ delta >= 0 ? -1 : 1) * asin(intersection[2]); if (phi > phiArc || phi === phiArc && (arc[0] || arc[1])) { winding += antimeridian ^ delta >= 0 ? 1 : -1; } } } } // First, determine whether the South pole is inside or outside: // // It is inside if: // * the polygon winds around it in a clockwise direction. // * the polygon does not (cumulatively) wind around it, but has a negative // (counter-clockwise) area. // // Second, count the (signed) number of times a segment crosses a lambda // from the point to the South pole. If it is zero, then the point is the // same side as the South pole. return (angle < -epsilon || angle < epsilon && sum < -epsilon) ^ (winding & 1); }; var lengthSum = adder(); var lambda0$2; var sinPhi0$1; var cosPhi0$1; var lengthStream = { sphere: noop, point: noop, lineStart: lengthLineStart, lineEnd: noop, polygonStart: noop, polygonEnd: noop }; function lengthLineStart() { lengthStream.point = lengthPointFirst; lengthStream.lineEnd = lengthLineEnd; } function lengthLineEnd() { lengthStream.point = lengthStream.lineEnd = noop; } function lengthPointFirst(lambda, phi) { lambda *= radians, phi *= radians; lambda0$2 = lambda, sinPhi0$1 = sin(phi), cosPhi0$1 = cos(phi); lengthStream.point = lengthPoint; } function lengthPoint(lambda, phi) { lambda *= radians, phi *= radians; var sinPhi = sin(phi), cosPhi = cos(phi), delta = abs(lambda - lambda0$2), cosDelta = cos(delta), sinDelta = sin(delta), x = cosPhi * sinDelta, y = cosPhi0$1 * sinPhi - sinPhi0$1 * cosPhi * cosDelta, z = sinPhi0$1 * sinPhi + cosPhi0$1 * cosPhi * cosDelta; lengthSum.add(atan2(sqrt(x * x + y * y), z)); lambda0$2 = lambda, sinPhi0$1 = sinPhi, cosPhi0$1 = cosPhi; } var length = function(object) { lengthSum.reset(); geoStream(object, lengthStream); return +lengthSum; }; var coordinates = [null, null]; var object = {type: "LineString", coordinates: coordinates}; var distance = function(a, b) { coordinates[0] = a; coordinates[1] = b; return length(object); }; var containsObjectType = { Feature: function(object, point) { return containsGeometry(object.geometry, point); }, FeatureCollection: function(object, point) { var features = object.features, i = -1, n = features.length; while (++i < n) if (containsGeometry(features[i].geometry, point)) return true; return false; } }; var containsGeometryType = { Sphere: function() { return true; }, Point: function(object, point) { return containsPoint(object.coordinates, point); }, MultiPoint: function(object, point) { var coordinates = object.coordinates, i = -1, n = coordinates.length; while (++i < n) if (containsPoint(coordinates[i], point)) return true; return false; }, LineString: function(object, point) { return containsLine(object.coordinates, point); }, MultiLineString: function(object, point) { var coordinates = object.coordinates, i = -1, n = coordinates.length; while (++i < n) if (containsLine(coordinates[i], point)) return true; return false; }, Polygon: function(object, point) { return containsPolygon(object.coordinates, point); }, MultiPolygon: function(object, point) { var coordinates = object.coordinates, i = -1, n = coordinates.length; while (++i < n) if (containsPolygon(coordinates[i], point)) return true; return false; }, GeometryCollection: function(object, point) { var geometries = object.geometries, i = -1, n = geometries.length; while (++i < n) if (containsGeometry(geometries[i], point)) return true; return false; } }; function containsGeometry(geometry, point) { return geometry && containsGeometryType.hasOwnProperty(geometry.type) ? containsGeometryType[geometry.type](geometry, point) : false; } function containsPoint(coordinates, point) { return distance(coordinates, point) === 0; } function containsLine(coordinates, point) { var ab = distance(coordinates[0], coordinates[1]), ao = distance(coordinates[0], point), ob = distance(point, coordinates[1]); return ao + ob <= ab + epsilon; } function containsPolygon(coordinates, point) { return !!polygonContains(coordinates.map(ringRadians), pointRadians(point)); } function ringRadians(ring) { return ring = ring.map(pointRadians), ring.pop(), ring; } function pointRadians(point) { return [point[0] * radians, point[1] * radians]; } var contains = function(object, point) { return (object && containsObjectType.hasOwnProperty(object.type) ? containsObjectType[object.type] : containsGeometry)(object, point); }; function graticuleX(y0, y1, dy) { var y = d3Array.range(y0, y1 - epsilon, dy).concat(y1); return function(x) { return y.map(function(y) { return [x, y]; }); }; } function graticuleY(x0, x1, dx) { var x = d3Array.range(x0, x1 - epsilon, dx).concat(x1); return function(y) { return x.map(function(x) { return [x, y]; }); }; } function graticule() { var x1, x0, X1, X0, y1, y0, Y1, Y0, dx = 10, dy = dx, DX = 90, DY = 360, x, y, X, Y, precision = 2.5; function graticule() { return {type: "MultiLineString", coordinates: lines()}; } function lines() { return d3Array.range(ceil(X0 / DX) * DX, X1, DX).map(X) .concat(d3Array.range(ceil(Y0 / DY) * DY, Y1, DY).map(Y)) .concat(d3Array.range(ceil(x0 / dx) * dx, x1, dx).filter(function(x) { return abs(x % DX) > epsilon; }).map(x)) .concat(d3Array.range(ceil(y0 / dy) * dy, y1, dy).filter(function(y) { return abs(y % DY) > epsilon; }).map(y)); } graticule.lines = function() { return lines().map(function(coordinates) { return {type: "LineString", coordinates: coordinates}; }); }; graticule.outline = function() { return { type: "Polygon", coordinates: [ X(X0).concat( Y(Y1).slice(1), X(X1).reverse().slice(1), Y(Y0).reverse().slice(1)) ] }; }; graticule.extent = function(_) { if (!arguments.length) return graticule.extentMinor(); return graticule.extentMajor(_).extentMinor(_); }; graticule.extentMajor = function(_) { if (!arguments.length) return [[X0, Y0], [X1, Y1]]; X0 = +_[0][0], X1 = +_[1][0]; Y0 = +_[0][1], Y1 = +_[1][1]; if (X0 > X1) _ = X0, X0 = X1, X1 = _; if (Y0 > Y1) _ = Y0, Y0 = Y1, Y1 = _; return graticule.precision(precision); }; graticule.extentMinor = function(_) { if (!arguments.length) return [[x0, y0], [x1, y1]]; x0 = +_[0][0], x1 = +_[1][0]; y0 = +_[0][1], y1 = +_[1][1]; if (x0 > x1) _ = x0, x0 = x1, x1 = _; if (y0 > y1) _ = y0, y0 = y1, y1 = _; return graticule.precision(precision); }; graticule.step = function(_) { if (!arguments.length) return graticule.stepMinor(); return graticule.stepMajor(_).stepMinor(_); }; graticule.stepMajor = function(_) { if (!arguments.length) return [DX, DY]; DX = +_[0], DY = +_[1]; return graticule; }; graticule.stepMinor = function(_) { if (!arguments.length) return [dx, dy]; dx = +_[0], dy = +_[1]; return graticule; }; graticule.precision = function(_) { if (!arguments.length) return precision; precision = +_; x = graticuleX(y0, y1, 90); y = graticuleY(x0, x1, precision); X = graticuleX(Y0, Y1, 90); Y = graticuleY(X0, X1, precision); return graticule; }; return graticule .extentMajor([[-180, -90 + epsilon], [180, 90 - epsilon]]) .extentMinor([[-180, -80 - epsilon], [180, 80 + epsilon]]); } function graticule10() { return graticule()(); } var interpolate = function(a, b) { var x0 = a[0] * radians, y0 = a[1] * radians, x1 = b[0] * radians, y1 = b[1] * radians, cy0 = cos(y0), sy0 = sin(y0), cy1 = cos(y1), sy1 = sin(y1), kx0 = cy0 * cos(x0), ky0 = cy0 * sin(x0), kx1 = cy1 * cos(x1), ky1 = cy1 * sin(x1), d = 2 * asin(sqrt(haversin(y1 - y0) + cy0 * cy1 * haversin(x1 - x0))), k = sin(d); var interpolate = d ? function(t) { var B = sin(t *= d) / k, A = sin(d - t) / k, x = A * kx0 + B * kx1, y = A * ky0 + B * ky1, z = A * sy0 + B * sy1; return [ atan2(y, x) * degrees, atan2(z, sqrt(x * x + y * y)) * degrees ]; } : function() { return [x0 * degrees, y0 * degrees]; }; interpolate.distance = d; return interpolate; }; var identity = function(x) { return x; }; var areaSum$1 = adder(); var areaRingSum$1 = adder(); var x00; var y00; var x0$1; var y0$1; var areaStream$1 = { point: noop, lineStart: noop, lineEnd: noop, polygonStart: function() { areaStream$1.lineStart = areaRingStart$1; areaStream$1.lineEnd = areaRingEnd$1; }, polygonEnd: function() { areaStream$1.lineStart = areaStream$1.lineEnd = areaStream$1.point = noop; areaSum$1.add(abs(areaRingSum$1)); areaRingSum$1.reset(); }, result: function() { var area = areaSum$1 / 2; areaSum$1.reset(); return area; } }; function areaRingStart$1() { areaStream$1.point = areaPointFirst$1; } function areaPointFirst$1(x, y) { areaStream$1.point = areaPoint$1; x00 = x0$1 = x, y00 = y0$1 = y; } function areaPoint$1(x, y) { areaRingSum$1.add(y0$1 * x - x0$1 * y); x0$1 = x, y0$1 = y; } function areaRingEnd$1() { areaPoint$1(x00, y00); } var x0$2 = Infinity; var y0$2 = x0$2; var x1 = -x0$2; var y1 = x1; var boundsStream$1 = { point: boundsPoint$1, lineStart: noop, lineEnd: noop, polygonStart: noop, polygonEnd: noop, result: function() { var bounds = [[x0$2, y0$2], [x1, y1]]; x1 = y1 = -(y0$2 = x0$2 = Infinity); return bounds; } }; function boundsPoint$1(x, y) { if (x < x0$2) x0$2 = x; if (x > x1) x1 = x; if (y < y0$2) y0$2 = y; if (y > y1) y1 = y; } // TODO Enforce positive area for exterior, negative area for interior? var X0$1 = 0; var Y0$1 = 0; var Z0$1 = 0; var X1$1 = 0; var Y1$1 = 0; var Z1$1 = 0; var X2$1 = 0; var Y2$1 = 0; var Z2$1 = 0; var x00$1; var y00$1; var x0$3; var y0$3; var centroidStream$1 = { point: centroidPoint$1, lineStart: centroidLineStart$1, lineEnd: centroidLineEnd$1, polygonStart: function() { centroidStream$1.lineStart = centroidRingStart$1; centroidStream$1.lineEnd = centroidRingEnd$1; }, polygonEnd: function() { centroidStream$1.point = centroidPoint$1; centroidStream$1.lineStart = centroidLineStart$1; centroidStream$1.lineEnd = centroidLineEnd$1; }, result: function() { var centroid = Z2$1 ? [X2$1 / Z2$1, Y2$1 / Z2$1] : Z1$1 ? [X1$1 / Z1$1, Y1$1 / Z1$1] : Z0$1 ? [X0$1 / Z0$1, Y0$1 / Z0$1] : [NaN, NaN]; X0$1 = Y0$1 = Z0$1 = X1$1 = Y1$1 = Z1$1 = X2$1 = Y2$1 = Z2$1 = 0; return centroid; } }; function centroidPoint$1(x, y) { X0$1 += x; Y0$1 += y; ++Z0$1; } function centroidLineStart$1() { centroidStream$1.point = centroidPointFirstLine; } function centroidPointFirstLine(x, y) { centroidStream$1.point = centroidPointLine; centroidPoint$1(x0$3 = x, y0$3 = y); } function centroidPointLine(x, y) { var dx = x - x0$3, dy = y - y0$3, z = sqrt(dx * dx + dy * dy); X1$1 += z * (x0$3 + x) / 2; Y1$1 += z * (y0$3 + y) / 2; Z1$1 += z; centroidPoint$1(x0$3 = x, y0$3 = y); } function centroidLineEnd$1() { centroidStream$1.point = centroidPoint$1; } function centroidRingStart$1() { centroidStream$1.point = centroidPointFirstRing; } function centroidRingEnd$1() { centroidPointRing(x00$1, y00$1); } function centroidPointFirstRing(x, y) { centroidStream$1.point = centroidPointRing; centroidPoint$1(x00$1 = x0$3 = x, y00$1 = y0$3 = y); } function centroidPointRing(x, y) { var dx = x - x0$3, dy = y - y0$3, z = sqrt(dx * dx + dy * dy); X1$1 += z * (x0$3 + x) / 2; Y1$1 += z * (y0$3 + y) / 2; Z1$1 += z; z = y0$3 * x - x0$3 * y; X2$1 += z * (x0$3 + x); Y2$1 += z * (y0$3 + y); Z2$1 += z * 3; centroidPoint$1(x0$3 = x, y0$3 = y); } function PathContext(context) { this._context = context; } PathContext.prototype = { _radius: 4.5, pointRadius: function(_) { return this._radius = _, this; }, polygonStart: function() { this._line = 0; }, polygonEnd: function() { this._line = NaN; }, lineStart: function() { this._point = 0; }, lineEnd: function() { if (this._line === 0) this._context.closePath(); this._point = NaN; }, point: function(x, y) { switch (this._point) { case 0: { this._context.moveTo(x, y); this._point = 1; break; } case 1: { this._context.lineTo(x, y); break; } default: { this._context.moveTo(x + this._radius, y); this._context.arc(x, y, this._radius, 0, tau); break; } } }, result: noop }; var lengthSum$1 = adder(); var lengthRing; var x00$2; var y00$2; var x0$4; var y0$4; var lengthStream$1 = { point: noop, lineStart: function() { lengthStream$1.point = lengthPointFirst$1; }, lineEnd: function() { if (lengthRing) lengthPoint$1(x00$2, y00$2); lengthStream$1.point = noop; }, polygonStart: function() { lengthRing = true; }, polygonEnd: function() { lengthRing = null; }, result: function() { var length = +lengthSum$1; lengthSum$1.reset(); return length; } }; function lengthPointFirst$1(x, y) { lengthStream$1.point = lengthPoint$1; x00$2 = x0$4 = x, y00$2 = y0$4 = y; } function lengthPoint$1(x, y) { x0$4 -= x, y0$4 -= y; lengthSum$1.add(sqrt(x0$4 * x0$4 + y0$4 * y0$4)); x0$4 = x, y0$4 = y; } function PathString() { this._string = []; } PathString.prototype = { _radius: 4.5, _circle: circle$1(4.5), pointRadius: function(_) { if ((_ = +_) !== this._radius) this._radius = _, this._circle = null; return this; }, polygonStart: function() { this._line = 0; }, polygonEnd: function() { this._line = NaN; }, lineStart: function() { this._point = 0; }, lineEnd: function() { if (this._line === 0) this._string.push("Z"); this._point = NaN; }, point: function(x, y) { switch (this._point) { case 0: { this._string.push("M", x, ",", y); this._point = 1; break; } case 1: { this._string.push("L", x, ",", y); break; } default: { if (this._circle == null) this._circle = circle$1(this._radius); this._string.push("M", x, ",", y, this._circle); break; } } }, result: function() { if (this._string.length) { var result = this._string.join(""); this._string = []; return result; } else { return null; } } }; function circle$1(radius) { return "m0," + radius + "a" + radius + "," + radius + " 0 1,1 0," + -2 * radius + "a" + radius + "," + radius + " 0 1,1 0," + 2 * radius + "z"; } var index = function(projection, context) { var pointRadius = 4.5, projectionStream, contextStream; function path(object) { if (object) { if (typeof pointRadius === "function") contextStream.pointRadius(+pointRadius.apply(this, arguments)); geoStream(object, projectionStream(contextStream)); } return contextStream.result(); } path.area = function(object) { geoStream(object, projectionStream(areaStream$1)); return areaStream$1.result(); }; path.measure = function(object) { geoStream(object, projectionStream(lengthStream$1)); return lengthStream$1.result(); }; path.bounds = function(object) { geoStream(object, projectionStream(boundsStream$1)); return boundsStream$1.result(); }; path.centroid = function(object) { geoStream(object, projectionStream(centroidStream$1)); return centroidStream$1.result(); }; path.projection = function(_) { return arguments.length ? (projectionStream = _ == null ? (projection = null, identity) : (projection = _).stream, path) : projection; }; path.context = function(_) { if (!arguments.length) return context; contextStream = _ == null ? (context = null, new PathString) : new PathContext(context = _); if (typeof pointRadius !== "function") contextStream.pointRadius(pointRadius); return path; }; path.pointRadius = function(_) { if (!arguments.length) return pointRadius; pointRadius = typeof _ === "function" ? _ : (contextStream.pointRadius(+_), +_); return path; }; return path.projection(projection).context(context); }; var clip = function(pointVisible, clipLine, interpolate, start) { return function(rotate, sink) { var line = clipLine(sink), rotatedStart = rotate.invert(start[0], start[1]), ringBuffer = clipBuffer(), ringSink = clipLine(ringBuffer), polygonStarted = false, polygon, segments, ring; var clip = { point: point, lineStart: lineStart, lineEnd: lineEnd, polygonStart: function() { clip.point = pointRing; clip.lineStart = ringStart; clip.lineEnd = ringEnd; segments = []; polygon = []; }, polygonEnd: function() { clip.point = point; clip.lineStart = lineStart; clip.lineEnd = lineEnd; segments = d3Array.merge(segments); var startInside = polygonContains(polygon, rotatedStart); if (segments.length) { if (!polygonStarted) sink.polygonStart(), polygonStarted = true; clipPolygon(segments, compareIntersection, startInside, interpolate, sink); } else if (startInside) { if (!polygonStarted) sink.polygonStart(), polygonStarted = true; sink.lineStart(); interpolate(null, null, 1, sink); sink.lineEnd(); } if (polygonStarted) sink.polygonEnd(), polygonStarted = false; segments = polygon = null; }, sphere: function() { sink.polygonStart(); sink.lineStart(); interpolate(null, null, 1, sink); sink.lineEnd(); sink.polygonEnd(); } }; function point(lambda, phi) { var point = rotate(lambda, phi); if (pointVisible(lambda = point[0], phi = point[1])) sink.point(lambda, phi); } function pointLine(lambda, phi) { var point = rotate(lambda, phi); line.point(point[0], point[1]); } function lineStart() { clip.point = pointLine; line.lineStart(); } function lineEnd() { clip.point = point; line.lineEnd(); } function pointRing(lambda, phi) { ring.push([lambda, phi]); var point = rotate(lambda, phi); ringSink.point(point[0], point[1]); } function ringStart() { ringSink.lineStart(); ring = []; } function ringEnd() { pointRing(ring[0][0], ring[0][1]); ringSink.lineEnd(); var clean = ringSink.clean(), ringSegments = ringBuffer.result(), i, n = ringSegments.length, m, segment, point; ring.pop(); polygon.push(ring); ring = null; if (!n) return; // No intersections. if (clean & 1) { segment = ringSegments[0]; if ((m = segment.length - 1) > 0) { if (!polygonStarted) sink.polygonStart(), polygonStarted = true; sink.lineStart(); for (i = 0; i < m; ++i) sink.point((point = segment[i])[0], point[1]); sink.lineEnd(); } return; } // Rejoin connected segments. // TODO reuse ringBuffer.rejoin()? if (n > 1 && clean & 2) ringSegments.push(ringSegments.pop().concat(ringSegments.shift())); segments.push(ringSegments.filter(validSegment)); } return clip; }; }; function validSegment(segment) { return segment.length > 1; } // Intersections are sorted along the clip edge. For both antimeridian cutting // and circle clipping, the same comparison is used. function compareIntersection(a, b) { return ((a = a.x)[0] < 0 ? a[1] - halfPi - epsilon : halfPi - a[1]) - ((b = b.x)[0] < 0 ? b[1] - halfPi - epsilon : halfPi - b[1]); } var clipAntimeridian = clip( function() { return true; }, clipAntimeridianLine, clipAntimeridianInterpolate, [-pi, -halfPi] ); // Takes a line and cuts into visible segments. Return values: 0 - there were // intersections or the line was empty; 1 - no intersections; 2 - there were // intersections, and the first and last segments should be rejoined. function clipAntimeridianLine(stream) { var lambda0 = NaN, phi0 = NaN, sign0 = NaN, clean; // no intersections return { lineStart: function() { stream.lineStart(); clean = 1; }, point: function(lambda1, phi1) { var sign1 = lambda1 > 0 ? pi : -pi, delta = abs(lambda1 - lambda0); if (abs(delta - pi) < epsilon) { // line crosses a pole stream.point(lambda0, phi0 = (phi0 + phi1) / 2 > 0 ? halfPi : -halfPi); stream.point(sign0, phi0); stream.lineEnd(); stream.lineStart(); stream.point(sign1, phi0); stream.point(lambda1, phi0); clean = 0; } else if (sign0 !== sign1 && delta >= pi) { // line crosses antimeridian if (abs(lambda0 - sign0) < epsilon) lambda0 -= sign0 * epsilon; // handle degeneracies if (abs(lambda1 - sign1) < epsilon) lambda1 -= sign1 * epsilon; phi0 = clipAntimeridianIntersect(lambda0, phi0, lambda1, phi1); stream.point(sign0, phi0); stream.lineEnd(); stream.lineStart(); stream.point(sign1, phi0); clean = 0; } stream.point(lambda0 = lambda1, phi0 = phi1); sign0 = sign1; }, lineEnd: function() { stream.lineEnd(); lambda0 = phi0 = NaN; }, clean: function() { return 2 - clean; // if intersections, rejoin first and last segments } }; } function clipAntimeridianIntersect(lambda0, phi0, lambda1, phi1) { var cosPhi0, cosPhi1, sinLambda0Lambda1 = sin(lambda0 - lambda1); return abs(sinLambda0Lambda1) > epsilon ? atan((sin(phi0) * (cosPhi1 = cos(phi1)) * sin(lambda1) - sin(phi1) * (cosPhi0 = cos(phi0)) * sin(lambda0)) / (cosPhi0 * cosPhi1 * sinLambda0Lambda1)) : (phi0 + phi1) / 2; } function clipAntimeridianInterpolate(from, to, direction, stream) { var phi; if (from == null) { phi = direction * halfPi; stream.point(-pi, phi); stream.point(0, phi); stream.point(pi, phi); stream.point(pi, 0); stream.point(pi, -phi); stream.point(0, -phi); stream.point(-pi, -phi); stream.point(-pi, 0); stream.point(-pi, phi); } else if (abs(from[0] - to[0]) > epsilon) { var lambda = from[0] < to[0] ? pi : -pi; phi = direction * lambda / 2; stream.point(-lambda, phi); stream.point(0, phi); stream.point(lambda, phi); } else { stream.point(to[0], to[1]); } } var clipCircle = function(radius, delta) { var cr = cos(radius), smallRadius = cr > 0, notHemisphere = abs(cr) > epsilon; // TODO optimise for this common case function interpolate(from, to, direction, stream) { circleStream(stream, radius, delta, direction, from, to); } function visible(lambda, phi) { return cos(lambda) * cos(phi) > cr; } // Takes a line and cuts into visible segments. Return values used for polygon // clipping: 0 - there were intersections or the line was empty; 1 - no // intersections 2 - there were intersections, and the first and last segments // should be rejoined. function clipLine(stream) { var point0, // previous point c0, // code for previous point v0, // visibility of previous point v00, // visibility of first point clean; // no intersections return { lineStart: function() { v00 = v0 = false; clean = 1; }, point: function(lambda, phi) { var point1 = [lambda, phi], point2, v = visible(lambda, phi), c = smallRadius ? v ? 0 : code(lambda, phi) : v ? code(lambda + (lambda < 0 ? pi : -pi), phi) : 0; if (!point0 && (v00 = v0 = v)) stream.lineStart(); // Handle degeneracies. // TODO ignore if not clipping polygons. if (v !== v0) { point2 = intersect(point0, point1); if (!point2 || pointEqual(point0, point2) || pointEqual(point1, point2)) { point1[0] += epsilon; point1[1] += epsilon; v = visible(point1[0], point1[1]); } } if (v !== v0) { clean = 0; if (v) { // outside going in stream.lineStart(); point2 = intersect(point1, point0); stream.point(point2[0], point2[1]); } else { // inside going out point2 = intersect(point0, point1); stream.point(point2[0], point2[1]); stream.lineEnd(); } point0 = point2; } else if (notHemisphere && point0 && smallRadius ^ v) { var t; // If the codes for two points are different, or are both zero, // and there this segment intersects with the small circle. if (!(c & c0) && (t = intersect(point1, point0, true))) { clean = 0; if (smallRadius) { stream.lineStart(); stream.point(t[0][0], t[0][1]); stream.point(t[1][0], t[1][1]); stream.lineEnd(); } else { stream.point(t[1][0], t[1][1]); stream.lineEnd(); stream.lineStart(); stream.point(t[0][0], t[0][1]); } } } if (v && (!point0 || !pointEqual(point0, point1))) { stream.point(point1[0], point1[1]); } point0 = point1, v0 = v, c0 = c; }, lineEnd: function() { if (v0) stream.lineEnd(); point0 = null; }, // Rejoin first and last segments if there were intersections and the first // and last points were visible. clean: function() { return clean | ((v00 && v0) << 1); } }; } // Intersects the great circle between a and b with the clip circle. function intersect(a, b, two) { var pa = cartesian(a), pb = cartesian(b); // We have two planes, n1.p = d1 and n2.p = d2. // Find intersection line p(t) = c1 n1 + c2 n2 + t (n1 ⨯ n2). var n1 = [1, 0, 0], // normal n2 = cartesianCross(pa, pb), n2n2 = cartesianDot(n2, n2), n1n2 = n2[0], // cartesianDot(n1, n2), determinant = n2n2 - n1n2 * n1n2; // Two polar points. if (!determinant) return !two && a; var c1 = cr * n2n2 / determinant, c2 = -cr * n1n2 / determinant, n1xn2 = cartesianCross(n1, n2), A = cartesianScale(n1, c1), B = cartesianScale(n2, c2); cartesianAddInPlace(A, B); // Solve |p(t)|^2 = 1. var u = n1xn2, w = cartesianDot(A, u), uu = cartesianDot(u, u), t2 = w * w - uu * (cartesianDot(A, A) - 1); if (t2 < 0) return; var t = sqrt(t2), q = cartesianScale(u, (-w - t) / uu); cartesianAddInPlace(q, A); q = spherical(q); if (!two) return q; // Two intersection points. var lambda0 = a[0], lambda1 = b[0], phi0 = a[1], phi1 = b[1], z; if (lambda1 < lambda0) z = lambda0, lambda0 = lambda1, lambda1 = z; var delta = lambda1 - lambda0, polar = abs(delta - pi) < epsilon, meridian = polar || delta < epsilon; if (!polar && phi1 < phi0) z = phi0, phi0 = phi1, phi1 = z; // Check that the first point is between a and b. if (meridian ? polar ? phi0 + phi1 > 0 ^ q[1] < (abs(q[0] - lambda0) < epsilon ? phi0 : phi1) : phi0 <= q[1] && q[1] <= phi1 : delta > pi ^ (lambda0 <= q[0] && q[0] <= lambda1)) { var q1 = cartesianScale(u, (-w + t) / uu); cartesianAddInPlace(q1, A); return [q, spherical(q1)]; } } // Generates a 4-bit vector representing the location of a point relative to // the small circle's bounding box. function code(lambda, phi) { var r = smallRadius ? radius : pi - radius, code = 0; if (lambda < -r) code |= 1; // left else if (lambda > r) code |= 2; // right if (phi < -r) code |= 4; // below else if (phi > r) code |= 8; // above return code; } return clip(visible, clipLine, interpolate, smallRadius ? [0, -radius] : [-pi, radius - pi]); }; var transform = function(methods) { return { stream: transformer(methods) }; }; function transformer(methods) { return function(stream) { var s = new TransformStream; for (var key in methods) s[key] = methods[key]; s.stream = stream; return s; }; } function TransformStream() {} TransformStream.prototype = { constructor: TransformStream, point: function(x, y) { this.stream.point(x, y); }, sphere: function() { this.stream.sphere(); }, lineStart: function() { this.stream.lineStart(); }, lineEnd: function() { this.stream.lineEnd(); }, polygonStart: function() { this.stream.polygonStart(); }, polygonEnd: function() { this.stream.polygonEnd(); } }; function fitExtent(projection, extent, object) { var w = extent[1][0] - extent[0][0], h = extent[1][1] - extent[0][1], clip = projection.clipExtent && projection.clipExtent(); projection .scale(150) .translate([0, 0]); if (clip != null) projection.clipExtent(null); geoStream(object, projection.stream(boundsStream$1)); var b = boundsStream$1.result(), k = Math.min(w / (b[1][0] - b[0][0]), h / (b[1][1] - b[0][1])), x = +extent[0][0] + (w - k * (b[1][0] + b[0][0])) / 2, y = +extent[0][1] + (h - k * (b[1][1] + b[0][1])) / 2; if (clip != null) projection.clipExtent(clip); return projection .scale(k * 150) .translate([x, y]); } function fitSize(projection, size, object) { return fitExtent(projection, [[0, 0], size], object); } var maxDepth = 16; var cosMinDistance = cos(30 * radians); // cos(minimum angular distance) var resample = function(project, delta2) { return +delta2 ? resample$1(project, delta2) : resampleNone(project); }; function resampleNone(project) { return transformer({ point: function(x, y) { x = project(x, y); this.stream.point(x[0], x[1]); } }); } function resample$1(project, delta2) { function resampleLineTo(x0, y0, lambda0, a0, b0, c0, x1, y1, lambda1, a1, b1, c1, depth, stream) { var dx = x1 - x0, dy = y1 - y0, d2 = dx * dx + dy * dy; if (d2 > 4 * delta2 && depth--) { var a = a0 + a1, b = b0 + b1, c = c0 + c1, m = sqrt(a * a + b * b + c * c), phi2 = asin(c /= m), lambda2 = abs(abs(c) - 1) < epsilon || abs(lambda0 - lambda1) < epsilon ? (lambda0 + lambda1) / 2 : atan2(b, a), p = project(lambda2, phi2), x2 = p[0], y2 = p[1], dx2 = x2 - x0, dy2 = y2 - y0, dz = dy * dx2 - dx * dy2; if (dz * dz / d2 > delta2 // perpendicular projected distance || abs((dx * dx2 + dy * dy2) / d2 - 0.5) > 0.3 // midpoint close to an end || a0 * a1 + b0 * b1 + c0 * c1 < cosMinDistance) { // angular distance resampleLineTo(x0, y0, lambda0, a0, b0, c0, x2, y2, lambda2, a /= m, b /= m, c, depth, stream); stream.point(x2, y2); resampleLineTo(x2, y2, lambda2, a, b, c, x1, y1, lambda1, a1, b1, c1, depth, stream); } } } return function(stream) { var lambda00, x00, y00, a00, b00, c00, // first point lambda0, x0, y0, a0, b0, c0; // previous point var resampleStream = { point: point, lineStart: lineStart, lineEnd: lineEnd, polygonStart: function() { stream.polygonStart(); resampleStream.lineStart = ringStart; }, polygonEnd: function() { stream.polygonEnd(); resampleStream.lineStart = lineStart; } }; function point(x, y) { x = project(x, y); stream.point(x[0], x[1]); } function lineStart() { x0 = NaN; resampleStream.point = linePoint; stream.lineStart(); } function linePoint(lambda, phi) { var c = cartesian([lambda, phi]), p = project(lambda, phi); resampleLineTo(x0, y0, lambda0, a0, b0, c0, x0 = p[0], y0 = p[1], lambda0 = lambda, a0 = c[0], b0 = c[1], c0 = c[2], maxDepth, stream); stream.point(x0, y0); } function lineEnd() { resampleStream.point = point; stream.lineEnd(); } function ringStart() { lineStart(); resampleStream.point = ringPoint; resampleStream.lineEnd = ringEnd; } function ringPoint(lambda, phi) { linePoint(lambda00 = lambda, phi), x00 = x0, y00 = y0, a00 = a0, b00 = b0, c00 = c0; resampleStream.point = linePoint; } function ringEnd() { resampleLineTo(x0, y0, lambda0, a0, b0, c0, x00, y00, lambda00, a00, b00, c00, maxDepth, stream); resampleStream.lineEnd = lineEnd; lineEnd(); } return resampleStream; }; } var transformRadians = transformer({ point: function(x, y) { this.stream.point(x * radians, y * radians); } }); function projection(project) { return projectionMutator(function() { return project; })(); } function projectionMutator(projectAt) { var project, k = 150, // scale x = 480, y = 250, // translate dx, dy, lambda = 0, phi = 0, // center deltaLambda = 0, deltaPhi = 0, deltaGamma = 0, rotate, projectRotate, // rotate theta = null, preclip = clipAntimeridian, // clip angle x0 = null, y0, x1, y1, postclip = identity, // clip extent delta2 = 0.5, projectResample = resample(projectTransform, delta2), // precision cache, cacheStream; function projection(point) { point = projectRotate(point[0] * radians, point[1] * radians); return [point[0] * k + dx, dy - point[1] * k]; } function invert(point) { point = projectRotate.invert((point[0] - dx) / k, (dy - point[1]) / k); return point && [point[0] * degrees, point[1] * degrees]; } function projectTransform(x, y) { return x = project(x, y), [x[0] * k + dx, dy - x[1] * k]; } projection.stream = function(stream) { return cache && cacheStream === stream ? cache : cache = transformRadians(preclip(rotate, projectResample(postclip(cacheStream = stream)))); }; projection.clipAngle = function(_) { return arguments.length ? (preclip = +_ ? clipCircle(theta = _ * radians, 6 * radians) : (theta = null, clipAntimeridian), reset()) : theta * degrees; }; projection.clipExtent = function(_) { return arguments.length ? (postclip = _ == null ? (x0 = y0 = x1 = y1 = null, identity) : clipExtent(x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1]), reset()) : x0 == null ? null : [[x0, y0], [x1, y1]]; }; projection.scale = function(_) { return arguments.length ? (k = +_, recenter()) : k; }; projection.translate = function(_) { return arguments.length ? (x = +_[0], y = +_[1], recenter()) : [x, y]; }; projection.center = function(_) { return arguments.length ? (lambda = _[0] % 360 * radians, phi = _[1] % 360 * radians, recenter()) : [lambda * degrees, phi * degrees]; }; projection.rotate = function(_) { return arguments.length ? (deltaLambda = _[0] % 360 * radians, deltaPhi = _[1] % 360 * radians, deltaGamma = _.length > 2 ? _[2] % 360 * radians : 0, recenter()) : [deltaLambda * degrees, deltaPhi * degrees, deltaGamma * degrees]; }; projection.precision = function(_) { return arguments.length ? (projectResample = resample(projectTransform, delta2 = _ * _), reset()) : sqrt(delta2); }; projection.fitExtent = function(extent, object) { return fitExtent(projection, extent, object); }; projection.fitSize = function(size, object) { return fitSize(projection, size, object); }; function recenter() { projectRotate = compose(rotate = rotateRadians(deltaLambda, deltaPhi, deltaGamma), project); var center = project(lambda, phi); dx = x - center[0] * k; dy = y + center[1] * k; return reset(); } function reset() { cache = cacheStream = null; return projection; } return function() { project = projectAt.apply(this, arguments); projection.invert = project.invert && invert; return recenter(); }; } function conicProjection(projectAt) { var phi0 = 0, phi1 = pi / 3, m = projectionMutator(projectAt), p = m(phi0, phi1); p.parallels = function(_) { return arguments.length ? m(phi0 = _[0] * radians, phi1 = _[1] * radians) : [phi0 * degrees, phi1 * degrees]; }; return p; } function cylindricalEqualAreaRaw(phi0) { var cosPhi0 = cos(phi0); function forward(lambda, phi) { return [lambda * cosPhi0, sin(phi) / cosPhi0]; } forward.invert = function(x, y) { return [x / cosPhi0, asin(y * cosPhi0)]; }; return forward; } function conicEqualAreaRaw(y0, y1) { var sy0 = sin(y0), n = (sy0 + sin(y1)) / 2; // Are the parallels symmetrical around the Equator? if (abs(n) < epsilon) return cylindricalEqualAreaRaw(y0); var c = 1 + sy0 * (2 * n - sy0), r0 = sqrt(c) / n; function project(x, y) { var r = sqrt(c - 2 * n * sin(y)) / n; return [r * sin(x *= n), r0 - r * cos(x)]; } project.invert = function(x, y) { var r0y = r0 - y; return [atan2(x, abs(r0y)) / n * sign(r0y), asin((c - (x * x + r0y * r0y) * n * n) / (2 * n))]; }; return project; } var conicEqualArea = function() { return conicProjection(conicEqualAreaRaw) .scale(155.424) .center([0, 33.6442]); }; var albers = function() { return conicEqualArea() .parallels([29.5, 45.5]) .scale(1070) .translate([480, 250]) .rotate([96, 0]) .center([-0.6, 38.7]); }; // The projections must have mutually exclusive clip regions on the sphere, // as this will avoid emitting interleaving lines and polygons. function multiplex(streams) { var n = streams.length; return { point: function(x, y) { var i = -1; while (++i < n) streams[i].point(x, y); }, sphere: function() { var i = -1; while (++i < n) streams[i].sphere(); }, lineStart: function() { var i = -1; while (++i < n) streams[i].lineStart(); }, lineEnd: function() { var i = -1; while (++i < n) streams[i].lineEnd(); }, polygonStart: function() { var i = -1; while (++i < n) streams[i].polygonStart(); }, polygonEnd: function() { var i = -1; while (++i < n) streams[i].polygonEnd(); } }; } // A composite projection for the United States, configured by default for // 960×500. The projection also works quite well at 960×600 if you change the // scale to 1285 and adjust the translate accordingly. The set of standard // parallels for each region comes from USGS, which is published here: // http://egsc.usgs.gov/isb/pubs/MapProjections/projections.html#albers var albersUsa = function() { var cache, cacheStream, lower48 = albers(), lower48Point, alaska = conicEqualArea().rotate([154, 0]).center([-2, 58.5]).parallels([55, 65]), alaskaPoint, // EPSG:3338 hawaii = conicEqualArea().rotate([157, 0]).center([-3, 19.9]).parallels([8, 18]), hawaiiPoint, // ESRI:102007 point, pointStream = {point: function(x, y) { point = [x, y]; }}; function albersUsa(coordinates) { var x = coordinates[0], y = coordinates[1]; return point = null, (lower48Point.point(x, y), point) || (alaskaPoint.point(x, y), point) || (hawaiiPoint.point(x, y), point); } albersUsa.invert = function(coordinates) { var k = lower48.scale(), t = lower48.translate(), x = (coordinates[0] - t[0]) / k, y = (coordinates[1] - t[1]) / k; return (y >= 0.120 && y < 0.234 && x >= -0.425 && x < -0.214 ? alaska : y >= 0.166 && y < 0.234 && x >= -0.214 && x < -0.115 ? hawaii : lower48).invert(coordinates); }; albersUsa.stream = function(stream) { return cache && cacheStream === stream ? cache : cache = multiplex([lower48.stream(cacheStream = stream), alaska.stream(stream), hawaii.stream(stream)]); }; albersUsa.precision = function(_) { if (!arguments.length) return lower48.precision(); lower48.precision(_), alaska.precision(_), hawaii.precision(_); return reset(); }; albersUsa.scale = function(_) { if (!arguments.length) return lower48.scale(); lower48.scale(_), alaska.scale(_ * 0.35), hawaii.scale(_); return albersUsa.translate(lower48.translate()); }; albersUsa.translate = function(_) { if (!arguments.length) return lower48.translate(); var k = lower48.scale(), x = +_[0], y = +_[1]; lower48Point = lower48 .translate(_) .clipExtent([[x - 0.455 * k, y - 0.238 * k], [x + 0.455 * k, y + 0.238 * k]]) .stream(pointStream); alaskaPoint = alaska .translate([x - 0.307 * k, y + 0.201 * k]) .clipExtent([[x - 0.425 * k + epsilon, y + 0.120 * k + epsilon], [x - 0.214 * k - epsilon, y + 0.234 * k - epsilon]]) .stream(pointStream); hawaiiPoint = hawaii .translate([x - 0.205 * k, y + 0.212 * k]) .clipExtent([[x - 0.214 * k + epsilon, y + 0.166 * k + epsilon], [x - 0.115 * k - epsilon, y + 0.234 * k - epsilon]]) .stream(pointStream); return reset(); }; albersUsa.fitExtent = function(extent, object) { return fitExtent(albersUsa, extent, object); }; albersUsa.fitSize = function(size, object) { return fitSize(albersUsa, size, object); }; function reset() { cache = cacheStream = null; return albersUsa; } return albersUsa.scale(1070); }; function azimuthalRaw(scale) { return function(x, y) { var cx = cos(x), cy = cos(y), k = scale(cx * cy); return [ k * cy * sin(x), k * sin(y) ]; } } function azimuthalInvert(angle) { return function(x, y) { var z = sqrt(x * x + y * y), c = angle(z), sc = sin(c), cc = cos(c); return [ atan2(x * sc, z * cc), asin(z && y * sc / z) ]; } } var azimuthalEqualAreaRaw = azimuthalRaw(function(cxcy) { return sqrt(2 / (1 + cxcy)); }); azimuthalEqualAreaRaw.invert = azimuthalInvert(function(z) { return 2 * asin(z / 2); }); var azimuthalEqualArea = function() { return projection(azimuthalEqualAreaRaw) .scale(124.75) .clipAngle(180 - 1e-3); }; var azimuthalEquidistantRaw = azimuthalRaw(function(c) { return (c = acos(c)) && c / sin(c); }); azimuthalEquidistantRaw.invert = azimuthalInvert(function(z) { return z; }); var azimuthalEquidistant = function() { return projection(azimuthalEquidistantRaw) .scale(79.4188) .clipAngle(180 - 1e-3); }; function mercatorRaw(lambda, phi) { return [lambda, log(tan((halfPi + phi) / 2))]; } mercatorRaw.invert = function(x, y) { return [x, 2 * atan(exp(y)) - halfPi]; }; var mercator = function() { return mercatorProjection(mercatorRaw) .scale(961 / tau); }; function mercatorProjection(project) { var m = projection(project), center = m.center, scale = m.scale, translate = m.translate, clipExtent = m.clipExtent, x0 = null, y0, x1, y1; // clip extent m.scale = function(_) { return arguments.length ? (scale(_), reclip()) : scale(); }; m.translate = function(_) { return arguments.length ? (translate(_), reclip()) : translate(); }; m.center = function(_) { return arguments.length ? (center(_), reclip()) : center(); }; m.clipExtent = function(_) { return arguments.length ? ((_ == null ? x0 = y0 = x1 = y1 = null : (x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1])), reclip()) : x0 == null ? null : [[x0, y0], [x1, y1]]; }; function reclip() { var k = pi * scale(), t = m(rotation(m.rotate()).invert([0, 0])); return clipExtent(x0 == null ? [[t[0] - k, t[1] - k], [t[0] + k, t[1] + k]] : project === mercatorRaw ? [[Math.max(t[0] - k, x0), y0], [Math.min(t[0] + k, x1), y1]] : [[x0, Math.max(t[1] - k, y0)], [x1, Math.min(t[1] + k, y1)]]); } return reclip(); } function tany(y) { return tan((halfPi + y) / 2); } function conicConformalRaw(y0, y1) { var cy0 = cos(y0), n = y0 === y1 ? sin(y0) : log(cy0 / cos(y1)) / log(tany(y1) / tany(y0)), f = cy0 * pow(tany(y0), n) / n; if (!n) return mercatorRaw; function project(x, y) { if (f > 0) { if (y < -halfPi + epsilon) y = -halfPi + epsilon; } else { if (y > halfPi - epsilon) y = halfPi - epsilon; } var r = f / pow(tany(y), n); return [r * sin(n * x), f - r * cos(n * x)]; } project.invert = function(x, y) { var fy = f - y, r = sign(n) * sqrt(x * x + fy * fy); return [atan2(x, abs(fy)) / n * sign(fy), 2 * atan(pow(f / r, 1 / n)) - halfPi]; }; return project; } var conicConformal = function() { return conicProjection(conicConformalRaw) .scale(109.5) .parallels([30, 30]); }; function equirectangularRaw(lambda, phi) { return [lambda, phi]; } equirectangularRaw.invert = equirectangularRaw; var equirectangular = function() { return projection(equirectangularRaw) .scale(152.63); }; function conicEquidistantRaw(y0, y1) { var cy0 = cos(y0), n = y0 === y1 ? sin(y0) : (cy0 - cos(y1)) / (y1 - y0), g = cy0 / n + y0; if (abs(n) < epsilon) return equirectangularRaw; function project(x, y) { var gy = g - y, nx = n * x; return [gy * sin(nx), g - gy * cos(nx)]; } project.invert = function(x, y) { var gy = g - y; return [atan2(x, abs(gy)) / n * sign(gy), g - sign(n) * sqrt(x * x + gy * gy)]; }; return project; } var conicEquidistant = function() { return conicProjection(conicEquidistantRaw) .scale(131.154) .center([0, 13.9389]); }; function gnomonicRaw(x, y) { var cy = cos(y), k = cos(x) * cy; return [cy * sin(x) / k, sin(y) / k]; } gnomonicRaw.invert = azimuthalInvert(atan); var gnomonic = function() { return projection(gnomonicRaw) .scale(144.049) .clipAngle(60); }; function scaleTranslate(kx, ky, tx, ty) { return kx === 1 && ky === 1 && tx === 0 && ty === 0 ? identity : transformer({ point: function(x, y) { this.stream.point(x * kx + tx, y * ky + ty); } }); } var identity$1 = function() { var k = 1, tx = 0, ty = 0, sx = 1, sy = 1, transform = identity, // scale, translate and reflect x0 = null, y0, x1, y1, clip = identity, // clip extent cache, cacheStream, projection; function reset() { cache = cacheStream = null; return projection; } return projection = { stream: function(stream) { return cache && cacheStream === stream ? cache : cache = transform(clip(cacheStream = stream)); }, clipExtent: function(_) { return arguments.length ? (clip = _ == null ? (x0 = y0 = x1 = y1 = null, identity) : clipExtent(x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1]), reset()) : x0 == null ? null : [[x0, y0], [x1, y1]]; }, scale: function(_) { return arguments.length ? (transform = scaleTranslate((k = +_) * sx, k * sy, tx, ty), reset()) : k; }, translate: function(_) { return arguments.length ? (transform = scaleTranslate(k * sx, k * sy, tx = +_[0], ty = +_[1]), reset()) : [tx, ty]; }, reflectX: function(_) { return arguments.length ? (transform = scaleTranslate(k * (sx = _ ? -1 : 1), k * sy, tx, ty), reset()) : sx < 0; }, reflectY: function(_) { return arguments.length ? (transform = scaleTranslate(k * sx, k * (sy = _ ? -1 : 1), tx, ty), reset()) : sy < 0; }, fitExtent: function(extent, object) { return fitExtent(projection, extent, object); }, fitSize: function(size, object) { return fitSize(projection, size, object); } }; }; function orthographicRaw(x, y) { return [cos(y) * sin(x), sin(y)]; } orthographicRaw.invert = azimuthalInvert(asin); var orthographic = function() { return projection(orthographicRaw) .scale(249.5) .clipAngle(90 + epsilon); }; function stereographicRaw(x, y) { var cy = cos(y), k = 1 + cos(x) * cy; return [cy * sin(x) / k, sin(y) / k]; } stereographicRaw.invert = azimuthalInvert(function(z) { return 2 * atan(z); }); var stereographic = function() { return projection(stereographicRaw) .scale(250) .clipAngle(142); }; function transverseMercatorRaw(lambda, phi) { return [log(tan((halfPi + phi) / 2)), -lambda]; } transverseMercatorRaw.invert = function(x, y) { return [-y, 2 * atan(exp(x)) - halfPi]; }; var transverseMercator = function() { var m = mercatorProjection(transverseMercatorRaw), center = m.center, rotate = m.rotate; m.center = function(_) { return arguments.length ? center([-_[1], _[0]]) : (_ = center(), [_[1], -_[0]]); }; m.rotate = function(_) { return arguments.length ? rotate([_[0], _[1], _.length > 2 ? _[2] + 90 : 90]) : (_ = rotate(), [_[0], _[1], _[2] - 90]); }; return rotate([0, 0, 90]) .scale(159.155); }; exports.geoArea = area; exports.geoBounds = bounds; exports.geoCentroid = centroid; exports.geoCircle = circle; exports.geoClipExtent = extent; exports.geoContains = contains; exports.geoDistance = distance; exports.geoGraticule = graticule; exports.geoGraticule10 = graticule10; exports.geoInterpolate = interpolate; exports.geoLength = length; exports.geoPath = index; exports.geoAlbers = albers; exports.geoAlbersUsa = albersUsa; exports.geoAzimuthalEqualArea = azimuthalEqualArea; exports.geoAzimuthalEqualAreaRaw = azimuthalEqualAreaRaw; exports.geoAzimuthalEquidistant = azimuthalEquidistant; exports.geoAzimuthalEquidistantRaw = azimuthalEquidistantRaw; exports.geoConicConformal = conicConformal; exports.geoConicConformalRaw = conicConformalRaw; exports.geoConicEqualArea = conicEqualArea; exports.geoConicEqualAreaRaw = conicEqualAreaRaw; exports.geoConicEquidistant = conicEquidistant; exports.geoConicEquidistantRaw = conicEquidistantRaw; exports.geoEquirectangular = equirectangular; exports.geoEquirectangularRaw = equirectangularRaw; exports.geoGnomonic = gnomonic; exports.geoGnomonicRaw = gnomonicRaw; exports.geoIdentity = identity$1; exports.geoProjection = projection; exports.geoProjectionMutator = projectionMutator; exports.geoMercator = mercator; exports.geoMercatorRaw = mercatorRaw; exports.geoOrthographic = orthographic; exports.geoOrthographicRaw = orthographicRaw; exports.geoStereographic = stereographic; exports.geoStereographicRaw = stereographicRaw; exports.geoTransverseMercator = transverseMercator; exports.geoTransverseMercatorRaw = transverseMercatorRaw; exports.geoRotation = rotation; exports.geoStream = geoStream; exports.geoTransform = transform; Object.defineProperty(exports, '__esModule', { value: true }); }))); },{"d3-array":15}],28:[function(require,module,exports){ // https://d3js.org/d3-hierarchy/ Version 1.1.5. Copyright 2017 Mike Bostock. (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (factory((global.d3 = global.d3 || {}))); }(this, (function (exports) { 'use strict'; function defaultSeparation(a, b) { return a.parent === b.parent ? 1 : 2; } function meanX(children) { return children.reduce(meanXReduce, 0) / children.length; } function meanXReduce(x, c) { return x + c.x; } function maxY(children) { return 1 + children.reduce(maxYReduce, 0); } function maxYReduce(y, c) { return Math.max(y, c.y); } function leafLeft(node) { var children; while (children = node.children) node = children[0]; return node; } function leafRight(node) { var children; while (children = node.children) node = children[children.length - 1]; return node; } var cluster = function() { var separation = defaultSeparation, dx = 1, dy = 1, nodeSize = false; function cluster(root) { var previousNode, x = 0; // First walk, computing the initial x & y values. root.eachAfter(function(node) { var children = node.children; if (children) { node.x = meanX(children); node.y = maxY(children); } else { node.x = previousNode ? x += separation(node, previousNode) : 0; node.y = 0; previousNode = node; } }); var left = leafLeft(root), right = leafRight(root), x0 = left.x - separation(left, right) / 2, x1 = right.x + separation(right, left) / 2; // Second walk, normalizing x & y to the desired size. return root.eachAfter(nodeSize ? function(node) { node.x = (node.x - root.x) * dx; node.y = (root.y - node.y) * dy; } : function(node) { node.x = (node.x - x0) / (x1 - x0) * dx; node.y = (1 - (root.y ? node.y / root.y : 1)) * dy; }); } cluster.separation = function(x) { return arguments.length ? (separation = x, cluster) : separation; }; cluster.size = function(x) { return arguments.length ? (nodeSize = false, dx = +x[0], dy = +x[1], cluster) : (nodeSize ? null : [dx, dy]); }; cluster.nodeSize = function(x) { return arguments.length ? (nodeSize = true, dx = +x[0], dy = +x[1], cluster) : (nodeSize ? [dx, dy] : null); }; return cluster; }; function count(node) { var sum = 0, children = node.children, i = children && children.length; if (!i) sum = 1; else while (--i >= 0) sum += children[i].value; node.value = sum; } var node_count = function() { return this.eachAfter(count); }; var node_each = function(callback) { var node = this, current, next = [node], children, i, n; do { current = next.reverse(), next = []; while (node = current.pop()) { callback(node), children = node.children; if (children) for (i = 0, n = children.length; i < n; ++i) { next.push(children[i]); } } } while (next.length); return this; }; var node_eachBefore = function(callback) { var node = this, nodes = [node], children, i; while (node = nodes.pop()) { callback(node), children = node.children; if (children) for (i = children.length - 1; i >= 0; --i) { nodes.push(children[i]); } } return this; }; var node_eachAfter = function(callback) { var node = this, nodes = [node], next = [], children, i, n; while (node = nodes.pop()) { next.push(node), children = node.children; if (children) for (i = 0, n = children.length; i < n; ++i) { nodes.push(children[i]); } } while (node = next.pop()) { callback(node); } return this; }; var node_sum = function(value) { return this.eachAfter(function(node) { var sum = +value(node.data) || 0, children = node.children, i = children && children.length; while (--i >= 0) sum += children[i].value; node.value = sum; }); }; var node_sort = function(compare) { return this.eachBefore(function(node) { if (node.children) { node.children.sort(compare); } }); }; var node_path = function(end) { var start = this, ancestor = leastCommonAncestor(start, end), nodes = [start]; while (start !== ancestor) { start = start.parent; nodes.push(start); } var k = nodes.length; while (end !== ancestor) { nodes.splice(k, 0, end); end = end.parent; } return nodes; }; function leastCommonAncestor(a, b) { if (a === b) return a; var aNodes = a.ancestors(), bNodes = b.ancestors(), c = null; a = aNodes.pop(); b = bNodes.pop(); while (a === b) { c = a; a = aNodes.pop(); b = bNodes.pop(); } return c; } var node_ancestors = function() { var node = this, nodes = [node]; while (node = node.parent) { nodes.push(node); } return nodes; }; var node_descendants = function() { var nodes = []; this.each(function(node) { nodes.push(node); }); return nodes; }; var node_leaves = function() { var leaves = []; this.eachBefore(function(node) { if (!node.children) { leaves.push(node); } }); return leaves; }; var node_links = function() { var root = this, links = []; root.each(function(node) { if (node !== root) { // Don’t include the root’s parent, if any. links.push({source: node.parent, target: node}); } }); return links; }; function hierarchy(data, children) { var root = new Node(data), valued = +data.value && (root.value = data.value), node, nodes = [root], child, childs, i, n; if (children == null) children = defaultChildren; while (node = nodes.pop()) { if (valued) node.value = +node.data.value; if ((childs = children(node.data)) && (n = childs.length)) { node.children = new Array(n); for (i = n - 1; i >= 0; --i) { nodes.push(child = node.children[i] = new Node(childs[i])); child.parent = node; child.depth = node.depth + 1; } } } return root.eachBefore(computeHeight); } function node_copy() { return hierarchy(this).eachBefore(copyData); } function defaultChildren(d) { return d.children; } function copyData(node) { node.data = node.data.data; } function computeHeight(node) { var height = 0; do node.height = height; while ((node = node.parent) && (node.height < ++height)); } function Node(data) { this.data = data; this.depth = this.height = 0; this.parent = null; } Node.prototype = hierarchy.prototype = { constructor: Node, count: node_count, each: node_each, eachAfter: node_eachAfter, eachBefore: node_eachBefore, sum: node_sum, sort: node_sort, path: node_path, ancestors: node_ancestors, descendants: node_descendants, leaves: node_leaves, links: node_links, copy: node_copy }; var slice = Array.prototype.slice; function shuffle(array) { var m = array.length, t, i; while (m) { i = Math.random() * m-- | 0; t = array[m]; array[m] = array[i]; array[i] = t; } return array; } var enclose = function(circles) { var i = 0, n = (circles = shuffle(slice.call(circles))).length, B = [], p, e; while (i < n) { p = circles[i]; if (e && enclosesWeak(e, p)) ++i; else e = encloseBasis(B = extendBasis(B, p)), i = 0; } return e; }; function extendBasis(B, p) { var i, j; if (enclosesWeakAll(p, B)) return [p]; // If we get here then B must have at least one element. for (i = 0; i < B.length; ++i) { if (enclosesNot(p, B[i]) && enclosesWeakAll(encloseBasis2(B[i], p), B)) { return [B[i], p]; } } // If we get here then B must have at least two elements. for (i = 0; i < B.length - 1; ++i) { for (j = i + 1; j < B.length; ++j) { if (enclosesNot(encloseBasis2(B[i], B[j]), p) && enclosesNot(encloseBasis2(B[i], p), B[j]) && enclosesNot(encloseBasis2(B[j], p), B[i]) && enclosesWeakAll(encloseBasis3(B[i], B[j], p), B)) { return [B[i], B[j], p]; } } } // If we get here then something is very wrong. throw new Error; } function enclosesNot(a, b) { var dr = a.r - b.r, dx = b.x - a.x, dy = b.y - a.y; return dr < 0 || dr * dr < dx * dx + dy * dy; } function enclosesWeak(a, b) { var dr = a.r - b.r + 1e-6, dx = b.x - a.x, dy = b.y - a.y; return dr > 0 && dr * dr > dx * dx + dy * dy; } function enclosesWeakAll(a, B) { for (var i = 0; i < B.length; ++i) { if (!enclosesWeak(a, B[i])) { return false; } } return true; } function encloseBasis(B) { switch (B.length) { case 1: return encloseBasis1(B[0]); case 2: return encloseBasis2(B[0], B[1]); case 3: return encloseBasis3(B[0], B[1], B[2]); } } function encloseBasis1(a) { return { x: a.x, y: a.y, r: a.r }; } function encloseBasis2(a, b) { var x1 = a.x, y1 = a.y, r1 = a.r, x2 = b.x, y2 = b.y, r2 = b.r, x21 = x2 - x1, y21 = y2 - y1, r21 = r2 - r1, l = Math.sqrt(x21 * x21 + y21 * y21); return { x: (x1 + x2 + x21 / l * r21) / 2, y: (y1 + y2 + y21 / l * r21) / 2, r: (l + r1 + r2) / 2 }; } function encloseBasis3(a, b, c) { var x1 = a.x, y1 = a.y, r1 = a.r, x2 = b.x, y2 = b.y, r2 = b.r, x3 = c.x, y3 = c.y, r3 = c.r, a2 = x1 - x2, a3 = x1 - x3, b2 = y1 - y2, b3 = y1 - y3, c2 = r2 - r1, c3 = r3 - r1, d1 = x1 * x1 + y1 * y1 - r1 * r1, d2 = d1 - x2 * x2 - y2 * y2 + r2 * r2, d3 = d1 - x3 * x3 - y3 * y3 + r3 * r3, ab = a3 * b2 - a2 * b3, xa = (b2 * d3 - b3 * d2) / (ab * 2) - x1, xb = (b3 * c2 - b2 * c3) / ab, ya = (a3 * d2 - a2 * d3) / (ab * 2) - y1, yb = (a2 * c3 - a3 * c2) / ab, A = xb * xb + yb * yb - 1, B = 2 * (r1 + xa * xb + ya * yb), C = xa * xa + ya * ya - r1 * r1, r = -(A ? (B + Math.sqrt(B * B - 4 * A * C)) / (2 * A) : C / B); return { x: x1 + xa + xb * r, y: y1 + ya + yb * r, r: r }; } function place(a, b, c) { var ax = a.x, ay = a.y, da = b.r + c.r, db = a.r + c.r, dx = b.x - ax, dy = b.y - ay, dc = dx * dx + dy * dy; if (dc) { var x = 0.5 + ((db *= db) - (da *= da)) / (2 * dc), y = Math.sqrt(Math.max(0, 2 * da * (db + dc) - (db -= dc) * db - da * da)) / (2 * dc); c.x = ax + x * dx + y * dy; c.y = ay + x * dy - y * dx; } else { c.x = ax + db; c.y = ay; } } function intersects(a, b) { var dx = b.x - a.x, dy = b.y - a.y, dr = a.r + b.r; return dr * dr - 1e-6 > dx * dx + dy * dy; } function score(node) { var a = node._, b = node.next._, ab = a.r + b.r, dx = (a.x * b.r + b.x * a.r) / ab, dy = (a.y * b.r + b.y * a.r) / ab; return dx * dx + dy * dy; } function Node$1(circle) { this._ = circle; this.next = null; this.previous = null; } function packEnclose(circles) { if (!(n = circles.length)) return 0; var a, b, c, n, aa, ca, i, j, k, sj, sk; // Place the first circle. a = circles[0], a.x = 0, a.y = 0; if (!(n > 1)) return a.r; // Place the second circle. b = circles[1], a.x = -b.r, b.x = a.r, b.y = 0; if (!(n > 2)) return a.r + b.r; // Place the third circle. place(b, a, c = circles[2]); // Initialize the front-chain using the first three circles a, b and c. a = new Node$1(a), b = new Node$1(b), c = new Node$1(c); a.next = c.previous = b; b.next = a.previous = c; c.next = b.previous = a; // Attempt to place each remaining circle… pack: for (i = 3; i < n; ++i) { place(a._, b._, c = circles[i]), c = new Node$1(c); // Find the closest intersecting circle on the front-chain, if any. // “Closeness” is determined by linear distance along the front-chain. // “Ahead” or “behind” is likewise determined by linear distance. j = b.next, k = a.previous, sj = b._.r, sk = a._.r; do { if (sj <= sk) { if (intersects(j._, c._)) { b = j, a.next = b, b.previous = a, --i; continue pack; } sj += j._.r, j = j.next; } else { if (intersects(k._, c._)) { a = k, a.next = b, b.previous = a, --i; continue pack; } sk += k._.r, k = k.previous; } } while (j !== k.next); // Success! Insert the new circle c between a and b. c.previous = a, c.next = b, a.next = b.previous = b = c; // Compute the new closest circle pair to the centroid. aa = score(a); while ((c = c.next) !== b) { if ((ca = score(c)) < aa) { a = c, aa = ca; } } b = a.next; } // Compute the enclosing circle of the front chain. a = [b._], c = b; while ((c = c.next) !== b) a.push(c._); c = enclose(a); // Translate the circles to put the enclosing circle around the origin. for (i = 0; i < n; ++i) a = circles[i], a.x -= c.x, a.y -= c.y; return c.r; } var siblings = function(circles) { packEnclose(circles); return circles; }; function optional(f) { return f == null ? null : required(f); } function required(f) { if (typeof f !== "function") throw new Error; return f; } function constantZero() { return 0; } var constant = function(x) { return function() { return x; }; }; function defaultRadius(d) { return Math.sqrt(d.value); } var index = function() { var radius = null, dx = 1, dy = 1, padding = constantZero; function pack(root) { root.x = dx / 2, root.y = dy / 2; if (radius) { root.eachBefore(radiusLeaf(radius)) .eachAfter(packChildren(padding, 0.5)) .eachBefore(translateChild(1)); } else { root.eachBefore(radiusLeaf(defaultRadius)) .eachAfter(packChildren(constantZero, 1)) .eachAfter(packChildren(padding, root.r / Math.min(dx, dy))) .eachBefore(translateChild(Math.min(dx, dy) / (2 * root.r))); } return root; } pack.radius = function(x) { return arguments.length ? (radius = optional(x), pack) : radius; }; pack.size = function(x) { return arguments.length ? (dx = +x[0], dy = +x[1], pack) : [dx, dy]; }; pack.padding = function(x) { return arguments.length ? (padding = typeof x === "function" ? x : constant(+x), pack) : padding; }; return pack; }; function radiusLeaf(radius) { return function(node) { if (!node.children) { node.r = Math.max(0, +radius(node) || 0); } }; } function packChildren(padding, k) { return function(node) { if (children = node.children) { var children, i, n = children.length, r = padding(node) * k || 0, e; if (r) for (i = 0; i < n; ++i) children[i].r += r; e = packEnclose(children); if (r) for (i = 0; i < n; ++i) children[i].r -= r; node.r = e + r; } }; } function translateChild(k) { return function(node) { var parent = node.parent; node.r *= k; if (parent) { node.x = parent.x + k * node.x; node.y = parent.y + k * node.y; } }; } var roundNode = function(node) { node.x0 = Math.round(node.x0); node.y0 = Math.round(node.y0); node.x1 = Math.round(node.x1); node.y1 = Math.round(node.y1); }; var treemapDice = function(parent, x0, y0, x1, y1) { var nodes = parent.children, node, i = -1, n = nodes.length, k = parent.value && (x1 - x0) / parent.value; while (++i < n) { node = nodes[i], node.y0 = y0, node.y1 = y1; node.x0 = x0, node.x1 = x0 += node.value * k; } }; var partition = function() { var dx = 1, dy = 1, padding = 0, round = false; function partition(root) { var n = root.height + 1; root.x0 = root.y0 = padding; root.x1 = dx; root.y1 = dy / n; root.eachBefore(positionNode(dy, n)); if (round) root.eachBefore(roundNode); return root; } function positionNode(dy, n) { return function(node) { if (node.children) { treemapDice(node, node.x0, dy * (node.depth + 1) / n, node.x1, dy * (node.depth + 2) / n); } var x0 = node.x0, y0 = node.y0, x1 = node.x1 - padding, y1 = node.y1 - padding; if (x1 < x0) x0 = x1 = (x0 + x1) / 2; if (y1 < y0) y0 = y1 = (y0 + y1) / 2; node.x0 = x0; node.y0 = y0; node.x1 = x1; node.y1 = y1; }; } partition.round = function(x) { return arguments.length ? (round = !!x, partition) : round; }; partition.size = function(x) { return arguments.length ? (dx = +x[0], dy = +x[1], partition) : [dx, dy]; }; partition.padding = function(x) { return arguments.length ? (padding = +x, partition) : padding; }; return partition; }; var keyPrefix = "$"; var preroot = {depth: -1}; var ambiguous = {}; function defaultId(d) { return d.id; } function defaultParentId(d) { return d.parentId; } var stratify = function() { var id = defaultId, parentId = defaultParentId; function stratify(data) { var d, i, n = data.length, root, parent, node, nodes = new Array(n), nodeId, nodeKey, nodeByKey = {}; for (i = 0; i < n; ++i) { d = data[i], node = nodes[i] = new Node(d); if ((nodeId = id(d, i, data)) != null && (nodeId += "")) { nodeKey = keyPrefix + (node.id = nodeId); nodeByKey[nodeKey] = nodeKey in nodeByKey ? ambiguous : node; } } for (i = 0; i < n; ++i) { node = nodes[i], nodeId = parentId(data[i], i, data); if (nodeId == null || !(nodeId += "")) { if (root) throw new Error("multiple roots"); root = node; } else { parent = nodeByKey[keyPrefix + nodeId]; if (!parent) throw new Error("missing: " + nodeId); if (parent === ambiguous) throw new Error("ambiguous: " + nodeId); if (parent.children) parent.children.push(node); else parent.children = [node]; node.parent = parent; } } if (!root) throw new Error("no root"); root.parent = preroot; root.eachBefore(function(node) { node.depth = node.parent.depth + 1; --n; }).eachBefore(computeHeight); root.parent = null; if (n > 0) throw new Error("cycle"); return root; } stratify.id = function(x) { return arguments.length ? (id = required(x), stratify) : id; }; stratify.parentId = function(x) { return arguments.length ? (parentId = required(x), stratify) : parentId; }; return stratify; }; function defaultSeparation$1(a, b) { return a.parent === b.parent ? 1 : 2; } // function radialSeparation(a, b) { // return (a.parent === b.parent ? 1 : 2) / a.depth; // } // This function is used to traverse the left contour of a subtree (or // subforest). It returns the successor of v on this contour. This successor is // either given by the leftmost child of v or by the thread of v. The function // returns null if and only if v is on the highest level of its subtree. function nextLeft(v) { var children = v.children; return children ? children[0] : v.t; } // This function works analogously to nextLeft. function nextRight(v) { var children = v.children; return children ? children[children.length - 1] : v.t; } // Shifts the current subtree rooted at w+. This is done by increasing // prelim(w+) and mod(w+) by shift. function moveSubtree(wm, wp, shift) { var change = shift / (wp.i - wm.i); wp.c -= change; wp.s += shift; wm.c += change; wp.z += shift; wp.m += shift; } // All other shifts, applied to the smaller subtrees between w- and w+, are // performed by this function. To prepare the shifts, we have to adjust // change(w+), shift(w+), and change(w-). function executeShifts(v) { var shift = 0, change = 0, children = v.children, i = children.length, w; while (--i >= 0) { w = children[i]; w.z += shift; w.m += shift; shift += w.s + (change += w.c); } } // If vi-’s ancestor is a sibling of v, returns vi-’s ancestor. Otherwise, // returns the specified (default) ancestor. function nextAncestor(vim, v, ancestor) { return vim.a.parent === v.parent ? vim.a : ancestor; } function TreeNode(node, i) { this._ = node; this.parent = null; this.children = null; this.A = null; // default ancestor this.a = this; // ancestor this.z = 0; // prelim this.m = 0; // mod this.c = 0; // change this.s = 0; // shift this.t = null; // thread this.i = i; // number } TreeNode.prototype = Object.create(Node.prototype); function treeRoot(root) { var tree = new TreeNode(root, 0), node, nodes = [tree], child, children, i, n; while (node = nodes.pop()) { if (children = node._.children) { node.children = new Array(n = children.length); for (i = n - 1; i >= 0; --i) { nodes.push(child = node.children[i] = new TreeNode(children[i], i)); child.parent = node; } } } (tree.parent = new TreeNode(null, 0)).children = [tree]; return tree; } // Node-link tree diagram using the Reingold-Tilford "tidy" algorithm var tree = function() { var separation = defaultSeparation$1, dx = 1, dy = 1, nodeSize = null; function tree(root) { var t = treeRoot(root); // Compute the layout using Buchheim et al.’s algorithm. t.eachAfter(firstWalk), t.parent.m = -t.z; t.eachBefore(secondWalk); // If a fixed node size is specified, scale x and y. if (nodeSize) root.eachBefore(sizeNode); // If a fixed tree size is specified, scale x and y based on the extent. // Compute the left-most, right-most, and depth-most nodes for extents. else { var left = root, right = root, bottom = root; root.eachBefore(function(node) { if (node.x < left.x) left = node; if (node.x > right.x) right = node; if (node.depth > bottom.depth) bottom = node; }); var s = left === right ? 1 : separation(left, right) / 2, tx = s - left.x, kx = dx / (right.x + s + tx), ky = dy / (bottom.depth || 1); root.eachBefore(function(node) { node.x = (node.x + tx) * kx; node.y = node.depth * ky; }); } return root; } // Computes a preliminary x-coordinate for v. Before that, FIRST WALK is // applied recursively to the children of v, as well as the function // APPORTION. After spacing out the children by calling EXECUTE SHIFTS, the // node v is placed to the midpoint of its outermost children. function firstWalk(v) { var children = v.children, siblings = v.parent.children, w = v.i ? siblings[v.i - 1] : null; if (children) { executeShifts(v); var midpoint = (children[0].z + children[children.length - 1].z) / 2; if (w) { v.z = w.z + separation(v._, w._); v.m = v.z - midpoint; } else { v.z = midpoint; } } else if (w) { v.z = w.z + separation(v._, w._); } v.parent.A = apportion(v, w, v.parent.A || siblings[0]); } // Computes all real x-coordinates by summing up the modifiers recursively. function secondWalk(v) { v._.x = v.z + v.parent.m; v.m += v.parent.m; } // The core of the algorithm. Here, a new subtree is combined with the // previous subtrees. Threads are used to traverse the inside and outside // contours of the left and right subtree up to the highest common level. The // vertices used for the traversals are vi+, vi-, vo-, and vo+, where the // superscript o means outside and i means inside, the subscript - means left // subtree and + means right subtree. For summing up the modifiers along the // contour, we use respective variables si+, si-, so-, and so+. Whenever two // nodes of the inside contours conflict, we compute the left one of the // greatest uncommon ancestors using the function ANCESTOR and call MOVE // SUBTREE to shift the subtree and prepare the shifts of smaller subtrees. // Finally, we add a new thread (if necessary). function apportion(v, w, ancestor) { if (w) { var vip = v, vop = v, vim = w, vom = vip.parent.children[0], sip = vip.m, sop = vop.m, sim = vim.m, som = vom.m, shift; while (vim = nextRight(vim), vip = nextLeft(vip), vim && vip) { vom = nextLeft(vom); vop = nextRight(vop); vop.a = v; shift = vim.z + sim - vip.z - sip + separation(vim._, vip._); if (shift > 0) { moveSubtree(nextAncestor(vim, v, ancestor), v, shift); sip += shift; sop += shift; } sim += vim.m; sip += vip.m; som += vom.m; sop += vop.m; } if (vim && !nextRight(vop)) { vop.t = vim; vop.m += sim - sop; } if (vip && !nextLeft(vom)) { vom.t = vip; vom.m += sip - som; ancestor = v; } } return ancestor; } function sizeNode(node) { node.x *= dx; node.y = node.depth * dy; } tree.separation = function(x) { return arguments.length ? (separation = x, tree) : separation; }; tree.size = function(x) { return arguments.length ? (nodeSize = false, dx = +x[0], dy = +x[1], tree) : (nodeSize ? null : [dx, dy]); }; tree.nodeSize = function(x) { return arguments.length ? (nodeSize = true, dx = +x[0], dy = +x[1], tree) : (nodeSize ? [dx, dy] : null); }; return tree; }; var treemapSlice = function(parent, x0, y0, x1, y1) { var nodes = parent.children, node, i = -1, n = nodes.length, k = parent.value && (y1 - y0) / parent.value; while (++i < n) { node = nodes[i], node.x0 = x0, node.x1 = x1; node.y0 = y0, node.y1 = y0 += node.value * k; } }; var phi = (1 + Math.sqrt(5)) / 2; function squarifyRatio(ratio, parent, x0, y0, x1, y1) { var rows = [], nodes = parent.children, row, nodeValue, i0 = 0, i1 = 0, n = nodes.length, dx, dy, value = parent.value, sumValue, minValue, maxValue, newRatio, minRatio, alpha, beta; while (i0 < n) { dx = x1 - x0, dy = y1 - y0; // Find the next non-empty node. do sumValue = nodes[i1++].value; while (!sumValue && i1 < n); minValue = maxValue = sumValue; alpha = Math.max(dy / dx, dx / dy) / (value * ratio); beta = sumValue * sumValue * alpha; minRatio = Math.max(maxValue / beta, beta / minValue); // Keep adding nodes while the aspect ratio maintains or improves. for (; i1 < n; ++i1) { sumValue += nodeValue = nodes[i1].value; if (nodeValue < minValue) minValue = nodeValue; if (nodeValue > maxValue) maxValue = nodeValue; beta = sumValue * sumValue * alpha; newRatio = Math.max(maxValue / beta, beta / minValue); if (newRatio > minRatio) { sumValue -= nodeValue; break; } minRatio = newRatio; } // Position and record the row orientation. rows.push(row = {value: sumValue, dice: dx < dy, children: nodes.slice(i0, i1)}); if (row.dice) treemapDice(row, x0, y0, x1, value ? y0 += dy * sumValue / value : y1); else treemapSlice(row, x0, y0, value ? x0 += dx * sumValue / value : x1, y1); value -= sumValue, i0 = i1; } return rows; } var squarify = ((function custom(ratio) { function squarify(parent, x0, y0, x1, y1) { squarifyRatio(ratio, parent, x0, y0, x1, y1); } squarify.ratio = function(x) { return custom((x = +x) > 1 ? x : 1); }; return squarify; }))(phi); var index$1 = function() { var tile = squarify, round = false, dx = 1, dy = 1, paddingStack = [0], paddingInner = constantZero, paddingTop = constantZero, paddingRight = constantZero, paddingBottom = constantZero, paddingLeft = constantZero; function treemap(root) { root.x0 = root.y0 = 0; root.x1 = dx; root.y1 = dy; root.eachBefore(positionNode); paddingStack = [0]; if (round) root.eachBefore(roundNode); return root; } function positionNode(node) { var p = paddingStack[node.depth], x0 = node.x0 + p, y0 = node.y0 + p, x1 = node.x1 - p, y1 = node.y1 - p; if (x1 < x0) x0 = x1 = (x0 + x1) / 2; if (y1 < y0) y0 = y1 = (y0 + y1) / 2; node.x0 = x0; node.y0 = y0; node.x1 = x1; node.y1 = y1; if (node.children) { p = paddingStack[node.depth + 1] = paddingInner(node) / 2; x0 += paddingLeft(node) - p; y0 += paddingTop(node) - p; x1 -= paddingRight(node) - p; y1 -= paddingBottom(node) - p; if (x1 < x0) x0 = x1 = (x0 + x1) / 2; if (y1 < y0) y0 = y1 = (y0 + y1) / 2; tile(node, x0, y0, x1, y1); } } treemap.round = function(x) { return arguments.length ? (round = !!x, treemap) : round; }; treemap.size = function(x) { return arguments.length ? (dx = +x[0], dy = +x[1], treemap) : [dx, dy]; }; treemap.tile = function(x) { return arguments.length ? (tile = required(x), treemap) : tile; }; treemap.padding = function(x) { return arguments.length ? treemap.paddingInner(x).paddingOuter(x) : treemap.paddingInner(); }; treemap.paddingInner = function(x) { return arguments.length ? (paddingInner = typeof x === "function" ? x : constant(+x), treemap) : paddingInner; }; treemap.paddingOuter = function(x) { return arguments.length ? treemap.paddingTop(x).paddingRight(x).paddingBottom(x).paddingLeft(x) : treemap.paddingTop(); }; treemap.paddingTop = function(x) { return arguments.length ? (paddingTop = typeof x === "function" ? x : constant(+x), treemap) : paddingTop; }; treemap.paddingRight = function(x) { return arguments.length ? (paddingRight = typeof x === "function" ? x : constant(+x), treemap) : paddingRight; }; treemap.paddingBottom = function(x) { return arguments.length ? (paddingBottom = typeof x === "function" ? x : constant(+x), treemap) : paddingBottom; }; treemap.paddingLeft = function(x) { return arguments.length ? (paddingLeft = typeof x === "function" ? x : constant(+x), treemap) : paddingLeft; }; return treemap; }; var binary = function(parent, x0, y0, x1, y1) { var nodes = parent.children, i, n = nodes.length, sum, sums = new Array(n + 1); for (sums[0] = sum = i = 0; i < n; ++i) { sums[i + 1] = sum += nodes[i].value; } partition(0, n, parent.value, x0, y0, x1, y1); function partition(i, j, value, x0, y0, x1, y1) { if (i >= j - 1) { var node = nodes[i]; node.x0 = x0, node.y0 = y0; node.x1 = x1, node.y1 = y1; return; } var valueOffset = sums[i], valueTarget = (value / 2) + valueOffset, k = i + 1, hi = j - 1; while (k < hi) { var mid = k + hi >>> 1; if (sums[mid] < valueTarget) k = mid + 1; else hi = mid; } if ((valueTarget - sums[k - 1]) < (sums[k] - valueTarget) && i + 1 < k) --k; var valueLeft = sums[k] - valueOffset, valueRight = value - valueLeft; if ((x1 - x0) > (y1 - y0)) { var xk = (x0 * valueRight + x1 * valueLeft) / value; partition(i, k, valueLeft, x0, y0, xk, y1); partition(k, j, valueRight, xk, y0, x1, y1); } else { var yk = (y0 * valueRight + y1 * valueLeft) / value; partition(i, k, valueLeft, x0, y0, x1, yk); partition(k, j, valueRight, x0, yk, x1, y1); } } }; var sliceDice = function(parent, x0, y0, x1, y1) { (parent.depth & 1 ? treemapSlice : treemapDice)(parent, x0, y0, x1, y1); }; var resquarify = ((function custom(ratio) { function resquarify(parent, x0, y0, x1, y1) { if ((rows = parent._squarify) && (rows.ratio === ratio)) { var rows, row, nodes, i, j = -1, n, m = rows.length, value = parent.value; while (++j < m) { row = rows[j], nodes = row.children; for (i = row.value = 0, n = nodes.length; i < n; ++i) row.value += nodes[i].value; if (row.dice) treemapDice(row, x0, y0, x1, y0 += (y1 - y0) * row.value / value); else treemapSlice(row, x0, y0, x0 += (x1 - x0) * row.value / value, y1); value -= row.value; } } else { parent._squarify = rows = squarifyRatio(ratio, parent, x0, y0, x1, y1); rows.ratio = ratio; } } resquarify.ratio = function(x) { return custom((x = +x) > 1 ? x : 1); }; return resquarify; }))(phi); exports.cluster = cluster; exports.hierarchy = hierarchy; exports.pack = index; exports.packSiblings = siblings; exports.packEnclose = enclose; exports.partition = partition; exports.stratify = stratify; exports.tree = tree; exports.treemap = index$1; exports.treemapBinary = binary; exports.treemapDice = treemapDice; exports.treemapSlice = treemapSlice; exports.treemapSliceDice = sliceDice; exports.treemapSquarify = squarify; exports.treemapResquarify = resquarify; Object.defineProperty(exports, '__esModule', { value: true }); }))); },{}],29:[function(require,module,exports){ // https://d3js.org/d3-interpolate/ Version 1.1.5. Copyright 2017 Mike Bostock. (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('d3-color')) : typeof define === 'function' && define.amd ? define(['exports', 'd3-color'], factory) : (factory((global.d3 = global.d3 || {}),global.d3)); }(this, (function (exports,d3Color) { 'use strict'; function basis(t1, v0, v1, v2, v3) { var t2 = t1 * t1, t3 = t2 * t1; return ((1 - 3 * t1 + 3 * t2 - t3) * v0 + (4 - 6 * t2 + 3 * t3) * v1 + (1 + 3 * t1 + 3 * t2 - 3 * t3) * v2 + t3 * v3) / 6; } var basis$1 = function(values) { var n = values.length - 1; return function(t) { var i = t <= 0 ? (t = 0) : t >= 1 ? (t = 1, n - 1) : Math.floor(t * n), v1 = values[i], v2 = values[i + 1], v0 = i > 0 ? values[i - 1] : 2 * v1 - v2, v3 = i < n - 1 ? values[i + 2] : 2 * v2 - v1; return basis((t - i / n) * n, v0, v1, v2, v3); }; }; var basisClosed = function(values) { var n = values.length; return function(t) { var i = Math.floor(((t %= 1) < 0 ? ++t : t) * n), v0 = values[(i + n - 1) % n], v1 = values[i % n], v2 = values[(i + 1) % n], v3 = values[(i + 2) % n]; return basis((t - i / n) * n, v0, v1, v2, v3); }; }; var constant = function(x) { return function() { return x; }; }; function linear(a, d) { return function(t) { return a + t * d; }; } function exponential(a, b, y) { return a = Math.pow(a, y), b = Math.pow(b, y) - a, y = 1 / y, function(t) { return Math.pow(a + t * b, y); }; } function hue(a, b) { var d = b - a; return d ? linear(a, d > 180 || d < -180 ? d - 360 * Math.round(d / 360) : d) : constant(isNaN(a) ? b : a); } function gamma(y) { return (y = +y) === 1 ? nogamma : function(a, b) { return b - a ? exponential(a, b, y) : constant(isNaN(a) ? b : a); }; } function nogamma(a, b) { var d = b - a; return d ? linear(a, d) : constant(isNaN(a) ? b : a); } var rgb$1 = ((function rgbGamma(y) { var color$$1 = gamma(y); function rgb$$1(start, end) { var r = color$$1((start = d3Color.rgb(start)).r, (end = d3Color.rgb(end)).r), g = color$$1(start.g, end.g), b = color$$1(start.b, end.b), opacity = nogamma(start.opacity, end.opacity); return function(t) { start.r = r(t); start.g = g(t); start.b = b(t); start.opacity = opacity(t); return start + ""; }; } rgb$$1.gamma = rgbGamma; return rgb$$1; }))(1); function rgbSpline(spline) { return function(colors) { var n = colors.length, r = new Array(n), g = new Array(n), b = new Array(n), i, color$$1; for (i = 0; i < n; ++i) { color$$1 = d3Color.rgb(colors[i]); r[i] = color$$1.r || 0; g[i] = color$$1.g || 0; b[i] = color$$1.b || 0; } r = spline(r); g = spline(g); b = spline(b); color$$1.opacity = 1; return function(t) { color$$1.r = r(t); color$$1.g = g(t); color$$1.b = b(t); return color$$1 + ""; }; }; } var rgbBasis = rgbSpline(basis$1); var rgbBasisClosed = rgbSpline(basisClosed); var array = function(a, b) { var nb = b ? b.length : 0, na = a ? Math.min(nb, a.length) : 0, x = new Array(nb), c = new Array(nb), i; for (i = 0; i < na; ++i) x[i] = value(a[i], b[i]); for (; i < nb; ++i) c[i] = b[i]; return function(t) { for (i = 0; i < na; ++i) c[i] = x[i](t); return c; }; }; var date = function(a, b) { var d = new Date; return a = +a, b -= a, function(t) { return d.setTime(a + b * t), d; }; }; var number = function(a, b) { return a = +a, b -= a, function(t) { return a + b * t; }; }; var object = function(a, b) { var i = {}, c = {}, k; if (a === null || typeof a !== "object") a = {}; if (b === null || typeof b !== "object") b = {}; for (k in b) { if (k in a) { i[k] = value(a[k], b[k]); } else { c[k] = b[k]; } } return function(t) { for (k in i) c[k] = i[k](t); return c; }; }; var reA = /[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g; var reB = new RegExp(reA.source, "g"); function zero(b) { return function() { return b; }; } function one(b) { return function(t) { return b(t) + ""; }; } var string = function(a, b) { var bi = reA.lastIndex = reB.lastIndex = 0, // scan index for next number in b am, // current match in a bm, // current match in b bs, // string preceding current number in b, if any i = -1, // index in s s = [], // string constants and placeholders q = []; // number interpolators // Coerce inputs to strings. a = a + "", b = b + ""; // Interpolate pairs of numbers in a & b. while ((am = reA.exec(a)) && (bm = reB.exec(b))) { if ((bs = bm.index) > bi) { // a string precedes the next number in b bs = b.slice(bi, bs); if (s[i]) s[i] += bs; // coalesce with previous string else s[++i] = bs; } if ((am = am[0]) === (bm = bm[0])) { // numbers in a & b match if (s[i]) s[i] += bm; // coalesce with previous string else s[++i] = bm; } else { // interpolate non-matching numbers s[++i] = null; q.push({i: i, x: number(am, bm)}); } bi = reB.lastIndex; } // Add remains of b. if (bi < b.length) { bs = b.slice(bi); if (s[i]) s[i] += bs; // coalesce with previous string else s[++i] = bs; } // Special optimization for only a single match. // Otherwise, interpolate each of the numbers and rejoin the string. return s.length < 2 ? (q[0] ? one(q[0].x) : zero(b)) : (b = q.length, function(t) { for (var i = 0, o; i < b; ++i) s[(o = q[i]).i] = o.x(t); return s.join(""); }); }; var value = function(a, b) { var t = typeof b, c; return b == null || t === "boolean" ? constant(b) : (t === "number" ? number : t === "string" ? ((c = d3Color.color(b)) ? (b = c, rgb$1) : string) : b instanceof d3Color.color ? rgb$1 : b instanceof Date ? date : Array.isArray(b) ? array : typeof b.valueOf !== "function" && typeof b.toString !== "function" || isNaN(b) ? object : number)(a, b); }; var round = function(a, b) { return a = +a, b -= a, function(t) { return Math.round(a + b * t); }; }; var degrees = 180 / Math.PI; var identity = { translateX: 0, translateY: 0, rotate: 0, skewX: 0, scaleX: 1, scaleY: 1 }; var decompose = function(a, b, c, d, e, f) { var scaleX, scaleY, skewX; if (scaleX = Math.sqrt(a * a + b * b)) a /= scaleX, b /= scaleX; if (skewX = a * c + b * d) c -= a * skewX, d -= b * skewX; if (scaleY = Math.sqrt(c * c + d * d)) c /= scaleY, d /= scaleY, skewX /= scaleY; if (a * d < b * c) a = -a, b = -b, skewX = -skewX, scaleX = -scaleX; return { translateX: e, translateY: f, rotate: Math.atan2(b, a) * degrees, skewX: Math.atan(skewX) * degrees, scaleX: scaleX, scaleY: scaleY }; }; var cssNode; var cssRoot; var cssView; var svgNode; function parseCss(value) { if (value === "none") return identity; if (!cssNode) cssNode = document.createElement("DIV"), cssRoot = document.documentElement, cssView = document.defaultView; cssNode.style.transform = value; value = cssView.getComputedStyle(cssRoot.appendChild(cssNode), null).getPropertyValue("transform"); cssRoot.removeChild(cssNode); value = value.slice(7, -1).split(","); return decompose(+value[0], +value[1], +value[2], +value[3], +value[4], +value[5]); } function parseSvg(value) { if (value == null) return identity; if (!svgNode) svgNode = document.createElementNS("http://www.w3.org/2000/svg", "g"); svgNode.setAttribute("transform", value); if (!(value = svgNode.transform.baseVal.consolidate())) return identity; value = value.matrix; return decompose(value.a, value.b, value.c, value.d, value.e, value.f); } function interpolateTransform(parse, pxComma, pxParen, degParen) { function pop(s) { return s.length ? s.pop() + " " : ""; } function translate(xa, ya, xb, yb, s, q) { if (xa !== xb || ya !== yb) { var i = s.push("translate(", null, pxComma, null, pxParen); q.push({i: i - 4, x: number(xa, xb)}, {i: i - 2, x: number(ya, yb)}); } else if (xb || yb) { s.push("translate(" + xb + pxComma + yb + pxParen); } } function rotate(a, b, s, q) { if (a !== b) { if (a - b > 180) b += 360; else if (b - a > 180) a += 360; // shortest path q.push({i: s.push(pop(s) + "rotate(", null, degParen) - 2, x: number(a, b)}); } else if (b) { s.push(pop(s) + "rotate(" + b + degParen); } } function skewX(a, b, s, q) { if (a !== b) { q.push({i: s.push(pop(s) + "skewX(", null, degParen) - 2, x: number(a, b)}); } else if (b) { s.push(pop(s) + "skewX(" + b + degParen); } } function scale(xa, ya, xb, yb, s, q) { if (xa !== xb || ya !== yb) { var i = s.push(pop(s) + "scale(", null, ",", null, ")"); q.push({i: i - 4, x: number(xa, xb)}, {i: i - 2, x: number(ya, yb)}); } else if (xb !== 1 || yb !== 1) { s.push(pop(s) + "scale(" + xb + "," + yb + ")"); } } return function(a, b) { var s = [], // string constants and placeholders q = []; // number interpolators a = parse(a), b = parse(b); translate(a.translateX, a.translateY, b.translateX, b.translateY, s, q); rotate(a.rotate, b.rotate, s, q); skewX(a.skewX, b.skewX, s, q); scale(a.scaleX, a.scaleY, b.scaleX, b.scaleY, s, q); a = b = null; // gc return function(t) { var i = -1, n = q.length, o; while (++i < n) s[(o = q[i]).i] = o.x(t); return s.join(""); }; }; } var interpolateTransformCss = interpolateTransform(parseCss, "px, ", "px)", "deg)"); var interpolateTransformSvg = interpolateTransform(parseSvg, ", ", ")", ")"); var rho = Math.SQRT2; var rho2 = 2; var rho4 = 4; var epsilon2 = 1e-12; function cosh(x) { return ((x = Math.exp(x)) + 1 / x) / 2; } function sinh(x) { return ((x = Math.exp(x)) - 1 / x) / 2; } function tanh(x) { return ((x = Math.exp(2 * x)) - 1) / (x + 1); } // p0 = [ux0, uy0, w0] // p1 = [ux1, uy1, w1] var zoom = function(p0, p1) { var ux0 = p0[0], uy0 = p0[1], w0 = p0[2], ux1 = p1[0], uy1 = p1[1], w1 = p1[2], dx = ux1 - ux0, dy = uy1 - uy0, d2 = dx * dx + dy * dy, i, S; // Special case for u0 ≅ u1. if (d2 < epsilon2) { S = Math.log(w1 / w0) / rho; i = function(t) { return [ ux0 + t * dx, uy0 + t * dy, w0 * Math.exp(rho * t * S) ]; }; } // General case. else { var d1 = Math.sqrt(d2), b0 = (w1 * w1 - w0 * w0 + rho4 * d2) / (2 * w0 * rho2 * d1), b1 = (w1 * w1 - w0 * w0 - rho4 * d2) / (2 * w1 * rho2 * d1), r0 = Math.log(Math.sqrt(b0 * b0 + 1) - b0), r1 = Math.log(Math.sqrt(b1 * b1 + 1) - b1); S = (r1 - r0) / rho; i = function(t) { var s = t * S, coshr0 = cosh(r0), u = w0 / (rho2 * d1) * (coshr0 * tanh(rho * s + r0) - sinh(r0)); return [ ux0 + u * dx, uy0 + u * dy, w0 * coshr0 / cosh(rho * s + r0) ]; }; } i.duration = S * 1000; return i; }; function hsl$1(hue$$1) { return function(start, end) { var h = hue$$1((start = d3Color.hsl(start)).h, (end = d3Color.hsl(end)).h), s = nogamma(start.s, end.s), l = nogamma(start.l, end.l), opacity = nogamma(start.opacity, end.opacity); return function(t) { start.h = h(t); start.s = s(t); start.l = l(t); start.opacity = opacity(t); return start + ""; }; } } var hsl$2 = hsl$1(hue); var hslLong = hsl$1(nogamma); function lab$1(start, end) { var l = nogamma((start = d3Color.lab(start)).l, (end = d3Color.lab(end)).l), a = nogamma(start.a, end.a), b = nogamma(start.b, end.b), opacity = nogamma(start.opacity, end.opacity); return function(t) { start.l = l(t); start.a = a(t); start.b = b(t); start.opacity = opacity(t); return start + ""; }; } function hcl$1(hue$$1) { return function(start, end) { var h = hue$$1((start = d3Color.hcl(start)).h, (end = d3Color.hcl(end)).h), c = nogamma(start.c, end.c), l = nogamma(start.l, end.l), opacity = nogamma(start.opacity, end.opacity); return function(t) { start.h = h(t); start.c = c(t); start.l = l(t); start.opacity = opacity(t); return start + ""; }; } } var hcl$2 = hcl$1(hue); var hclLong = hcl$1(nogamma); function cubehelix$1(hue$$1) { return (function cubehelixGamma(y) { y = +y; function cubehelix$$1(start, end) { var h = hue$$1((start = d3Color.cubehelix(start)).h, (end = d3Color.cubehelix(end)).h), s = nogamma(start.s, end.s), l = nogamma(start.l, end.l), opacity = nogamma(start.opacity, end.opacity); return function(t) { start.h = h(t); start.s = s(t); start.l = l(Math.pow(t, y)); start.opacity = opacity(t); return start + ""; }; } cubehelix$$1.gamma = cubehelixGamma; return cubehelix$$1; })(1); } var cubehelix$2 = cubehelix$1(hue); var cubehelixLong = cubehelix$1(nogamma); var quantize = function(interpolator, n) { var samples = new Array(n); for (var i = 0; i < n; ++i) samples[i] = interpolator(i / (n - 1)); return samples; }; exports.interpolate = value; exports.interpolateArray = array; exports.interpolateBasis = basis$1; exports.interpolateBasisClosed = basisClosed; exports.interpolateDate = date; exports.interpolateNumber = number; exports.interpolateObject = object; exports.interpolateRound = round; exports.interpolateString = string; exports.interpolateTransformCss = interpolateTransformCss; exports.interpolateTransformSvg = interpolateTransformSvg; exports.interpolateZoom = zoom; exports.interpolateRgb = rgb$1; exports.interpolateRgbBasis = rgbBasis; exports.interpolateRgbBasisClosed = rgbBasisClosed; exports.interpolateHsl = hsl$2; exports.interpolateHslLong = hslLong; exports.interpolateLab = lab$1; exports.interpolateHcl = hcl$2; exports.interpolateHclLong = hclLong; exports.interpolateCubehelix = cubehelix$2; exports.interpolateCubehelixLong = cubehelixLong; exports.quantize = quantize; Object.defineProperty(exports, '__esModule', { value: true }); }))); },{"d3-color":20}],30:[function(require,module,exports){ // https://d3js.org/d3-path/ Version 1.0.5. Copyright 2017 Mike Bostock. (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (factory((global.d3 = global.d3 || {}))); }(this, (function (exports) { 'use strict'; var pi = Math.PI; var tau = 2 * pi; var epsilon = 1e-6; var tauEpsilon = tau - epsilon; function Path() { this._x0 = this._y0 = // start of current subpath this._x1 = this._y1 = null; // end of current subpath this._ = ""; } function path() { return new Path; } Path.prototype = path.prototype = { constructor: Path, moveTo: function(x, y) { this._ += "M" + (this._x0 = this._x1 = +x) + "," + (this._y0 = this._y1 = +y); }, closePath: function() { if (this._x1 !== null) { this._x1 = this._x0, this._y1 = this._y0; this._ += "Z"; } }, lineTo: function(x, y) { this._ += "L" + (this._x1 = +x) + "," + (this._y1 = +y); }, quadraticCurveTo: function(x1, y1, x, y) { this._ += "Q" + (+x1) + "," + (+y1) + "," + (this._x1 = +x) + "," + (this._y1 = +y); }, bezierCurveTo: function(x1, y1, x2, y2, x, y) { this._ += "C" + (+x1) + "," + (+y1) + "," + (+x2) + "," + (+y2) + "," + (this._x1 = +x) + "," + (this._y1 = +y); }, arcTo: function(x1, y1, x2, y2, r) { x1 = +x1, y1 = +y1, x2 = +x2, y2 = +y2, r = +r; var x0 = this._x1, y0 = this._y1, x21 = x2 - x1, y21 = y2 - y1, x01 = x0 - x1, y01 = y0 - y1, l01_2 = x01 * x01 + y01 * y01; // Is the radius negative? Error. if (r < 0) throw new Error("negative radius: " + r); // Is this path empty? Move to (x1,y1). if (this._x1 === null) { this._ += "M" + (this._x1 = x1) + "," + (this._y1 = y1); } // Or, is (x1,y1) coincident with (x0,y0)? Do nothing. else if (!(l01_2 > epsilon)) {} // Or, are (x0,y0), (x1,y1) and (x2,y2) collinear? // Equivalently, is (x1,y1) coincident with (x2,y2)? // Or, is the radius zero? Line to (x1,y1). else if (!(Math.abs(y01 * x21 - y21 * x01) > epsilon) || !r) { this._ += "L" + (this._x1 = x1) + "," + (this._y1 = y1); } // Otherwise, draw an arc! else { var x20 = x2 - x0, y20 = y2 - y0, l21_2 = x21 * x21 + y21 * y21, l20_2 = x20 * x20 + y20 * y20, l21 = Math.sqrt(l21_2), l01 = Math.sqrt(l01_2), l = r * Math.tan((pi - Math.acos((l21_2 + l01_2 - l20_2) / (2 * l21 * l01))) / 2), t01 = l / l01, t21 = l / l21; // If the start tangent is not coincident with (x0,y0), line to. if (Math.abs(t01 - 1) > epsilon) { this._ += "L" + (x1 + t01 * x01) + "," + (y1 + t01 * y01); } this._ += "A" + r + "," + r + ",0,0," + (+(y01 * x20 > x01 * y20)) + "," + (this._x1 = x1 + t21 * x21) + "," + (this._y1 = y1 + t21 * y21); } }, arc: function(x, y, r, a0, a1, ccw) { x = +x, y = +y, r = +r; var dx = r * Math.cos(a0), dy = r * Math.sin(a0), x0 = x + dx, y0 = y + dy, cw = 1 ^ ccw, da = ccw ? a0 - a1 : a1 - a0; // Is the radius negative? Error. if (r < 0) throw new Error("negative radius: " + r); // Is this path empty? Move to (x0,y0). if (this._x1 === null) { this._ += "M" + x0 + "," + y0; } // Or, is (x0,y0) not coincident with the previous point? Line to (x0,y0). else if (Math.abs(this._x1 - x0) > epsilon || Math.abs(this._y1 - y0) > epsilon) { this._ += "L" + x0 + "," + y0; } // Is this arc empty? We’re done. if (!r) return; // Does the angle go the wrong way? Flip the direction. if (da < 0) da = da % tau + tau; // Is this a complete circle? Draw two arcs to complete the circle. if (da > tauEpsilon) { this._ += "A" + r + "," + r + ",0,1," + cw + "," + (x - dx) + "," + (y - dy) + "A" + r + "," + r + ",0,1," + cw + "," + (this._x1 = x0) + "," + (this._y1 = y0); } // Is this arc non-empty? Draw an arc! else if (da > epsilon) { this._ += "A" + r + "," + r + ",0," + (+(da >= pi)) + "," + cw + "," + (this._x1 = x + r * Math.cos(a1)) + "," + (this._y1 = y + r * Math.sin(a1)); } }, rect: function(x, y, w, h) { this._ += "M" + (this._x0 = this._x1 = +x) + "," + (this._y0 = this._y1 = +y) + "h" + (+w) + "v" + (+h) + "h" + (-w) + "Z"; }, toString: function() { return this._; } }; exports.path = path; Object.defineProperty(exports, '__esModule', { value: true }); }))); },{}],31:[function(require,module,exports){ // https://d3js.org/d3-polygon/ Version 1.0.3. Copyright 2017 Mike Bostock. (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (factory((global.d3 = global.d3 || {}))); }(this, (function (exports) { 'use strict'; var area = function(polygon) { var i = -1, n = polygon.length, a, b = polygon[n - 1], area = 0; while (++i < n) { a = b; b = polygon[i]; area += a[1] * b[0] - a[0] * b[1]; } return area / 2; }; var centroid = function(polygon) { var i = -1, n = polygon.length, x = 0, y = 0, a, b = polygon[n - 1], c, k = 0; while (++i < n) { a = b; b = polygon[i]; k += c = a[0] * b[1] - b[0] * a[1]; x += (a[0] + b[0]) * c; y += (a[1] + b[1]) * c; } return k *= 3, [x / k, y / k]; }; // Returns the 2D cross product of AB and AC vectors, i.e., the z-component of // the 3D cross product in a quadrant I Cartesian coordinate system (+x is // right, +y is up). Returns a positive value if ABC is counter-clockwise, // negative if clockwise, and zero if the points are collinear. var cross = function(a, b, c) { return (b[0] - a[0]) * (c[1] - a[1]) - (b[1] - a[1]) * (c[0] - a[0]); }; function lexicographicOrder(a, b) { return a[0] - b[0] || a[1] - b[1]; } // Computes the upper convex hull per the monotone chain algorithm. // Assumes points.length >= 3, is sorted by x, unique in y. // Returns an array of indices into points in left-to-right order. function computeUpperHullIndexes(points) { var n = points.length, indexes = [0, 1], size = 2; for (var i = 2; i < n; ++i) { while (size > 1 && cross(points[indexes[size - 2]], points[indexes[size - 1]], points[i]) <= 0) --size; indexes[size++] = i; } return indexes.slice(0, size); // remove popped points } var hull = function(points) { if ((n = points.length) < 3) return null; var i, n, sortedPoints = new Array(n), flippedPoints = new Array(n); for (i = 0; i < n; ++i) sortedPoints[i] = [+points[i][0], +points[i][1], i]; sortedPoints.sort(lexicographicOrder); for (i = 0; i < n; ++i) flippedPoints[i] = [sortedPoints[i][0], -sortedPoints[i][1]]; var upperIndexes = computeUpperHullIndexes(sortedPoints), lowerIndexes = computeUpperHullIndexes(flippedPoints); // Construct the hull polygon, removing possible duplicate endpoints. var skipLeft = lowerIndexes[0] === upperIndexes[0], skipRight = lowerIndexes[lowerIndexes.length - 1] === upperIndexes[upperIndexes.length - 1], hull = []; // Add upper hull in right-to-l order. // Then add lower hull in left-to-right order. for (i = upperIndexes.length - 1; i >= 0; --i) hull.push(points[sortedPoints[upperIndexes[i]][2]]); for (i = +skipLeft; i < lowerIndexes.length - skipRight; ++i) hull.push(points[sortedPoints[lowerIndexes[i]][2]]); return hull; }; var contains = function(polygon, point) { var n = polygon.length, p = polygon[n - 1], x = point[0], y = point[1], x0 = p[0], y0 = p[1], x1, y1, inside = false; for (var i = 0; i < n; ++i) { p = polygon[i], x1 = p[0], y1 = p[1]; if (((y1 > y) !== (y0 > y)) && (x < (x0 - x1) * (y - y1) / (y0 - y1) + x1)) inside = !inside; x0 = x1, y0 = y1; } return inside; }; var length = function(polygon) { var i = -1, n = polygon.length, b = polygon[n - 1], xa, ya, xb = b[0], yb = b[1], perimeter = 0; while (++i < n) { xa = xb; ya = yb; b = polygon[i]; xb = b[0]; yb = b[1]; xa -= xb; ya -= yb; perimeter += Math.sqrt(xa * xa + ya * ya); } return perimeter; }; exports.polygonArea = area; exports.polygonCentroid = centroid; exports.polygonHull = hull; exports.polygonContains = contains; exports.polygonLength = length; Object.defineProperty(exports, '__esModule', { value: true }); }))); },{}],32:[function(require,module,exports){ // https://d3js.org/d3-quadtree/ Version 1.0.3. Copyright 2017 Mike Bostock. (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (factory((global.d3 = global.d3 || {}))); }(this, (function (exports) { 'use strict'; var tree_add = function(d) { var x = +this._x.call(null, d), y = +this._y.call(null, d); return add(this.cover(x, y), x, y, d); }; function add(tree, x, y, d) { if (isNaN(x) || isNaN(y)) return tree; // ignore invalid points var parent, node = tree._root, leaf = {data: d}, x0 = tree._x0, y0 = tree._y0, x1 = tree._x1, y1 = tree._y1, xm, ym, xp, yp, right, bottom, i, j; // If the tree is empty, initialize the root as a leaf. if (!node) return tree._root = leaf, tree; // Find the existing leaf for the new point, or add it. while (node.length) { if (right = x >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm; if (bottom = y >= (ym = (y0 + y1) / 2)) y0 = ym; else y1 = ym; if (parent = node, !(node = node[i = bottom << 1 | right])) return parent[i] = leaf, tree; } // Is the new point is exactly coincident with the existing point? xp = +tree._x.call(null, node.data); yp = +tree._y.call(null, node.data); if (x === xp && y === yp) return leaf.next = node, parent ? parent[i] = leaf : tree._root = leaf, tree; // Otherwise, split the leaf node until the old and new point are separated. do { parent = parent ? parent[i] = new Array(4) : tree._root = new Array(4); if (right = x >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm; if (bottom = y >= (ym = (y0 + y1) / 2)) y0 = ym; else y1 = ym; } while ((i = bottom << 1 | right) === (j = (yp >= ym) << 1 | (xp >= xm))); return parent[j] = node, parent[i] = leaf, tree; } function addAll(data) { var d, i, n = data.length, x, y, xz = new Array(n), yz = new Array(n), x0 = Infinity, y0 = Infinity, x1 = -Infinity, y1 = -Infinity; // Compute the points and their extent. for (i = 0; i < n; ++i) { if (isNaN(x = +this._x.call(null, d = data[i])) || isNaN(y = +this._y.call(null, d))) continue; xz[i] = x; yz[i] = y; if (x < x0) x0 = x; if (x > x1) x1 = x; if (y < y0) y0 = y; if (y > y1) y1 = y; } // If there were no (valid) points, inherit the existing extent. if (x1 < x0) x0 = this._x0, x1 = this._x1; if (y1 < y0) y0 = this._y0, y1 = this._y1; // Expand the tree to cover the new points. this.cover(x0, y0).cover(x1, y1); // Add the new points. for (i = 0; i < n; ++i) { add(this, xz[i], yz[i], data[i]); } return this; } var tree_cover = function(x, y) { if (isNaN(x = +x) || isNaN(y = +y)) return this; // ignore invalid points var x0 = this._x0, y0 = this._y0, x1 = this._x1, y1 = this._y1; // If the quadtree has no extent, initialize them. // Integer extent are necessary so that if we later double the extent, // the existing quadrant boundaries don’t change due to floating point error! if (isNaN(x0)) { x1 = (x0 = Math.floor(x)) + 1; y1 = (y0 = Math.floor(y)) + 1; } // Otherwise, double repeatedly to cover. else if (x0 > x || x > x1 || y0 > y || y > y1) { var z = x1 - x0, node = this._root, parent, i; switch (i = (y < (y0 + y1) / 2) << 1 | (x < (x0 + x1) / 2)) { case 0: { do parent = new Array(4), parent[i] = node, node = parent; while (z *= 2, x1 = x0 + z, y1 = y0 + z, x > x1 || y > y1); break; } case 1: { do parent = new Array(4), parent[i] = node, node = parent; while (z *= 2, x0 = x1 - z, y1 = y0 + z, x0 > x || y > y1); break; } case 2: { do parent = new Array(4), parent[i] = node, node = parent; while (z *= 2, x1 = x0 + z, y0 = y1 - z, x > x1 || y0 > y); break; } case 3: { do parent = new Array(4), parent[i] = node, node = parent; while (z *= 2, x0 = x1 - z, y0 = y1 - z, x0 > x || y0 > y); break; } } if (this._root && this._root.length) this._root = node; } // If the quadtree covers the point already, just return. else return this; this._x0 = x0; this._y0 = y0; this._x1 = x1; this._y1 = y1; return this; }; var tree_data = function() { var data = []; this.visit(function(node) { if (!node.length) do data.push(node.data); while (node = node.next) }); return data; }; var tree_extent = function(_) { return arguments.length ? this.cover(+_[0][0], +_[0][1]).cover(+_[1][0], +_[1][1]) : isNaN(this._x0) ? undefined : [[this._x0, this._y0], [this._x1, this._y1]]; }; var Quad = function(node, x0, y0, x1, y1) { this.node = node; this.x0 = x0; this.y0 = y0; this.x1 = x1; this.y1 = y1; }; var tree_find = function(x, y, radius) { var data, x0 = this._x0, y0 = this._y0, x1, y1, x2, y2, x3 = this._x1, y3 = this._y1, quads = [], node = this._root, q, i; if (node) quads.push(new Quad(node, x0, y0, x3, y3)); if (radius == null) radius = Infinity; else { x0 = x - radius, y0 = y - radius; x3 = x + radius, y3 = y + radius; radius *= radius; } while (q = quads.pop()) { // Stop searching if this quadrant can’t contain a closer node. if (!(node = q.node) || (x1 = q.x0) > x3 || (y1 = q.y0) > y3 || (x2 = q.x1) < x0 || (y2 = q.y1) < y0) continue; // Bisect the current quadrant. if (node.length) { var xm = (x1 + x2) / 2, ym = (y1 + y2) / 2; quads.push( new Quad(node[3], xm, ym, x2, y2), new Quad(node[2], x1, ym, xm, y2), new Quad(node[1], xm, y1, x2, ym), new Quad(node[0], x1, y1, xm, ym) ); // Visit the closest quadrant first. if (i = (y >= ym) << 1 | (x >= xm)) { q = quads[quads.length - 1]; quads[quads.length - 1] = quads[quads.length - 1 - i]; quads[quads.length - 1 - i] = q; } } // Visit this point. (Visiting coincident points isn’t necessary!) else { var dx = x - +this._x.call(null, node.data), dy = y - +this._y.call(null, node.data), d2 = dx * dx + dy * dy; if (d2 < radius) { var d = Math.sqrt(radius = d2); x0 = x - d, y0 = y - d; x3 = x + d, y3 = y + d; data = node.data; } } } return data; }; var tree_remove = function(d) { if (isNaN(x = +this._x.call(null, d)) || isNaN(y = +this._y.call(null, d))) return this; // ignore invalid points var parent, node = this._root, retainer, previous, next, x0 = this._x0, y0 = this._y0, x1 = this._x1, y1 = this._y1, x, y, xm, ym, right, bottom, i, j; // If the tree is empty, initialize the root as a leaf. if (!node) return this; // Find the leaf node for the point. // While descending, also retain the deepest parent with a non-removed sibling. if (node.length) while (true) { if (right = x >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm; if (bottom = y >= (ym = (y0 + y1) / 2)) y0 = ym; else y1 = ym; if (!(parent = node, node = node[i = bottom << 1 | right])) return this; if (!node.length) break; if (parent[(i + 1) & 3] || parent[(i + 2) & 3] || parent[(i + 3) & 3]) retainer = parent, j = i; } // Find the point to remove. while (node.data !== d) if (!(previous = node, node = node.next)) return this; if (next = node.next) delete node.next; // If there are multiple coincident points, remove just the point. if (previous) return (next ? previous.next = next : delete previous.next), this; // If this is the root point, remove it. if (!parent) return this._root = next, this; // Remove this leaf. next ? parent[i] = next : delete parent[i]; // If the parent now contains exactly one leaf, collapse superfluous parents. if ((node = parent[0] || parent[1] || parent[2] || parent[3]) && node === (parent[3] || parent[2] || parent[1] || parent[0]) && !node.length) { if (retainer) retainer[j] = node; else this._root = node; } return this; }; function removeAll(data) { for (var i = 0, n = data.length; i < n; ++i) this.remove(data[i]); return this; } var tree_root = function() { return this._root; }; var tree_size = function() { var size = 0; this.visit(function(node) { if (!node.length) do ++size; while (node = node.next) }); return size; }; var tree_visit = function(callback) { var quads = [], q, node = this._root, child, x0, y0, x1, y1; if (node) quads.push(new Quad(node, this._x0, this._y0, this._x1, this._y1)); while (q = quads.pop()) { if (!callback(node = q.node, x0 = q.x0, y0 = q.y0, x1 = q.x1, y1 = q.y1) && node.length) { var xm = (x0 + x1) / 2, ym = (y0 + y1) / 2; if (child = node[3]) quads.push(new Quad(child, xm, ym, x1, y1)); if (child = node[2]) quads.push(new Quad(child, x0, ym, xm, y1)); if (child = node[1]) quads.push(new Quad(child, xm, y0, x1, ym)); if (child = node[0]) quads.push(new Quad(child, x0, y0, xm, ym)); } } return this; }; var tree_visitAfter = function(callback) { var quads = [], next = [], q; if (this._root) quads.push(new Quad(this._root, this._x0, this._y0, this._x1, this._y1)); while (q = quads.pop()) { var node = q.node; if (node.length) { var child, x0 = q.x0, y0 = q.y0, x1 = q.x1, y1 = q.y1, xm = (x0 + x1) / 2, ym = (y0 + y1) / 2; if (child = node[0]) quads.push(new Quad(child, x0, y0, xm, ym)); if (child = node[1]) quads.push(new Quad(child, xm, y0, x1, ym)); if (child = node[2]) quads.push(new Quad(child, x0, ym, xm, y1)); if (child = node[3]) quads.push(new Quad(child, xm, ym, x1, y1)); } next.push(q); } while (q = next.pop()) { callback(q.node, q.x0, q.y0, q.x1, q.y1); } return this; }; function defaultX(d) { return d[0]; } var tree_x = function(_) { return arguments.length ? (this._x = _, this) : this._x; }; function defaultY(d) { return d[1]; } var tree_y = function(_) { return arguments.length ? (this._y = _, this) : this._y; }; function quadtree(nodes, x, y) { var tree = new Quadtree(x == null ? defaultX : x, y == null ? defaultY : y, NaN, NaN, NaN, NaN); return nodes == null ? tree : tree.addAll(nodes); } function Quadtree(x, y, x0, y0, x1, y1) { this._x = x; this._y = y; this._x0 = x0; this._y0 = y0; this._x1 = x1; this._y1 = y1; this._root = undefined; } function leaf_copy(leaf) { var copy = {data: leaf.data}, next = copy; while (leaf = leaf.next) next = next.next = {data: leaf.data}; return copy; } var treeProto = quadtree.prototype = Quadtree.prototype; treeProto.copy = function() { var copy = new Quadtree(this._x, this._y, this._x0, this._y0, this._x1, this._y1), node = this._root, nodes, child; if (!node) return copy; if (!node.length) return copy._root = leaf_copy(node), copy; nodes = [{source: node, target: copy._root = new Array(4)}]; while (node = nodes.pop()) { for (var i = 0; i < 4; ++i) { if (child = node.source[i]) { if (child.length) nodes.push({source: child, target: node.target[i] = new Array(4)}); else node.target[i] = leaf_copy(child); } } } return copy; }; treeProto.add = tree_add; treeProto.addAll = addAll; treeProto.cover = tree_cover; treeProto.data = tree_data; treeProto.extent = tree_extent; treeProto.find = tree_find; treeProto.remove = tree_remove; treeProto.removeAll = removeAll; treeProto.root = tree_root; treeProto.size = tree_size; treeProto.visit = tree_visit; treeProto.visitAfter = tree_visitAfter; treeProto.x = tree_x; treeProto.y = tree_y; exports.quadtree = quadtree; Object.defineProperty(exports, '__esModule', { value: true }); }))); },{}],33:[function(require,module,exports){ // https://d3js.org/d3-queue/ Version 3.0.7. Copyright 2017 Mike Bostock. (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (factory((global.d3 = global.d3 || {}))); }(this, (function (exports) { 'use strict'; var slice = [].slice; var noabort = {}; function Queue(size) { this._size = size; this._call = this._error = null; this._tasks = []; this._data = []; this._waiting = this._active = this._ended = this._start = 0; // inside a synchronous task callback? } Queue.prototype = queue.prototype = { constructor: Queue, defer: function(callback) { if (typeof callback !== "function") throw new Error("invalid callback"); if (this._call) throw new Error("defer after await"); if (this._error != null) return this; var t = slice.call(arguments, 1); t.push(callback); ++this._waiting, this._tasks.push(t); poke(this); return this; }, abort: function() { if (this._error == null) abort(this, new Error("abort")); return this; }, await: function(callback) { if (typeof callback !== "function") throw new Error("invalid callback"); if (this._call) throw new Error("multiple await"); this._call = function(error, results) { callback.apply(null, [error].concat(results)); }; maybeNotify(this); return this; }, awaitAll: function(callback) { if (typeof callback !== "function") throw new Error("invalid callback"); if (this._call) throw new Error("multiple await"); this._call = callback; maybeNotify(this); return this; } }; function poke(q) { if (!q._start) { try { start(q); } // let the current task complete catch (e) { if (q._tasks[q._ended + q._active - 1]) abort(q, e); // task errored synchronously else if (!q._data) throw e; // await callback errored synchronously } } } function start(q) { while (q._start = q._waiting && q._active < q._size) { var i = q._ended + q._active, t = q._tasks[i], j = t.length - 1, c = t[j]; t[j] = end(q, i); --q._waiting, ++q._active; t = c.apply(null, t); if (!q._tasks[i]) continue; // task finished synchronously q._tasks[i] = t || noabort; } } function end(q, i) { return function(e, r) { if (!q._tasks[i]) return; // ignore multiple callbacks --q._active, ++q._ended; q._tasks[i] = null; if (q._error != null) return; // ignore secondary errors if (e != null) { abort(q, e); } else { q._data[i] = r; if (q._waiting) poke(q); else maybeNotify(q); } }; } function abort(q, e) { var i = q._tasks.length, t; q._error = e; // ignore active callbacks q._data = undefined; // allow gc q._waiting = NaN; // prevent starting while (--i >= 0) { if (t = q._tasks[i]) { q._tasks[i] = null; if (t.abort) { try { t.abort(); } catch (e) { /* ignore */ } } } } q._active = NaN; // allow notification maybeNotify(q); } function maybeNotify(q) { if (!q._active && q._call) { var d = q._data; q._data = undefined; // allow gc q._call(q._error, d); } } function queue(concurrency) { if (concurrency == null) concurrency = Infinity; else if (!((concurrency = +concurrency) >= 1)) throw new Error("invalid concurrency"); return new Queue(concurrency); } exports.queue = queue; Object.defineProperty(exports, '__esModule', { value: true }); }))); },{}],34:[function(require,module,exports){ // https://d3js.org/d3-random/ Version 1.1.0. Copyright 2017 Mike Bostock. (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (factory((global.d3 = global.d3 || {}))); }(this, (function (exports) { 'use strict'; var defaultSource = function() { return Math.random(); }; var uniform = ((function sourceRandomUniform(source) { function randomUniform(min, max) { min = min == null ? 0 : +min; max = max == null ? 1 : +max; if (arguments.length === 1) max = min, min = 0; else max -= min; return function() { return source() * max + min; }; } randomUniform.source = sourceRandomUniform; return randomUniform; }))(defaultSource); var normal = ((function sourceRandomNormal(source) { function randomNormal(mu, sigma) { var x, r; mu = mu == null ? 0 : +mu; sigma = sigma == null ? 1 : +sigma; return function() { var y; // If available, use the second previously-generated uniform random. if (x != null) y = x, x = null; // Otherwise, generate a new x and y. else do { x = source() * 2 - 1; y = source() * 2 - 1; r = x * x + y * y; } while (!r || r > 1); return mu + sigma * y * Math.sqrt(-2 * Math.log(r) / r); }; } randomNormal.source = sourceRandomNormal; return randomNormal; }))(defaultSource); var logNormal = ((function sourceRandomLogNormal(source) { function randomLogNormal() { var randomNormal = normal.source(source).apply(this, arguments); return function() { return Math.exp(randomNormal()); }; } randomLogNormal.source = sourceRandomLogNormal; return randomLogNormal; }))(defaultSource); var irwinHall = ((function sourceRandomIrwinHall(source) { function randomIrwinHall(n) { return function() { for (var sum = 0, i = 0; i < n; ++i) sum += source(); return sum; }; } randomIrwinHall.source = sourceRandomIrwinHall; return randomIrwinHall; }))(defaultSource); var bates = ((function sourceRandomBates(source) { function randomBates(n) { var randomIrwinHall = irwinHall.source(source)(n); return function() { return randomIrwinHall() / n; }; } randomBates.source = sourceRandomBates; return randomBates; }))(defaultSource); var exponential = ((function sourceRandomExponential(source) { function randomExponential(lambda) { return function() { return -Math.log(1 - source()) / lambda; }; } randomExponential.source = sourceRandomExponential; return randomExponential; }))(defaultSource); exports.randomUniform = uniform; exports.randomNormal = normal; exports.randomLogNormal = logNormal; exports.randomBates = bates; exports.randomIrwinHall = irwinHall; exports.randomExponential = exponential; Object.defineProperty(exports, '__esModule', { value: true }); }))); },{}],35:[function(require,module,exports){ 'use strict'; var XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest; Object.defineProperty(exports, '__esModule', { value: true }); var d3Collection = require('d3-collection'); var d3Dispatch = require('d3-dispatch'); var d3Dsv = require('d3-dsv'); var request = function(url, callback) { var request, event = d3Dispatch.dispatch("beforesend", "progress", "load", "error"), mimeType, headers = d3Collection.map(), xhr = new XMLHttpRequest, user = null, password = null, response, responseType, timeout = 0; // If IE does not support CORS, use XDomainRequest. if (typeof XDomainRequest !== "undefined" && !("withCredentials" in xhr) && /^(http(s)?:)?\/\//.test(url)) xhr = new XDomainRequest; "onload" in xhr ? xhr.onload = xhr.onerror = xhr.ontimeout = respond : xhr.onreadystatechange = function(o) { xhr.readyState > 3 && respond(o); }; function respond(o) { var status = xhr.status, result; if (!status && hasResponse(xhr) || status >= 200 && status < 300 || status === 304) { if (response) { try { result = response.call(request, xhr); } catch (e) { event.call("error", request, e); return; } } else { result = xhr; } event.call("load", request, result); } else { event.call("error", request, o); } } xhr.onprogress = function(e) { event.call("progress", request, e); }; request = { header: function(name, value) { name = (name + "").toLowerCase(); if (arguments.length < 2) return headers.get(name); if (value == null) headers.remove(name); else headers.set(name, value + ""); return request; }, // If mimeType is non-null and no Accept header is set, a default is used. mimeType: function(value) { if (!arguments.length) return mimeType; mimeType = value == null ? null : value + ""; return request; }, // Specifies what type the response value should take; // for instance, arraybuffer, blob, document, or text. responseType: function(value) { if (!arguments.length) return responseType; responseType = value; return request; }, timeout: function(value) { if (!arguments.length) return timeout; timeout = +value; return request; }, user: function(value) { return arguments.length < 1 ? user : (user = value == null ? null : value + "", request); }, password: function(value) { return arguments.length < 1 ? password : (password = value == null ? null : value + "", request); }, // Specify how to convert the response content to a specific type; // changes the callback value on "load" events. response: function(value) { response = value; return request; }, // Alias for send("GET", …). get: function(data, callback) { return request.send("GET", data, callback); }, // Alias for send("POST", …). post: function(data, callback) { return request.send("POST", data, callback); }, // If callback is non-null, it will be used for error and load events. send: function(method, data, callback) { xhr.open(method, url, true, user, password); if (mimeType != null && !headers.has("accept")) headers.set("accept", mimeType + ",*/*"); if (xhr.setRequestHeader) headers.each(function(value, name) { xhr.setRequestHeader(name, value); }); if (mimeType != null && xhr.overrideMimeType) xhr.overrideMimeType(mimeType); if (responseType != null) xhr.responseType = responseType; if (timeout > 0) xhr.timeout = timeout; if (callback == null && typeof data === "function") callback = data, data = null; if (callback != null && callback.length === 1) callback = fixCallback(callback); if (callback != null) request.on("error", callback).on("load", function(xhr) { callback(null, xhr); }); event.call("beforesend", request, xhr); xhr.send(data == null ? null : data); return request; }, abort: function() { xhr.abort(); return request; }, on: function() { var value = event.on.apply(event, arguments); return value === event ? request : value; } }; if (callback != null) { if (typeof callback !== "function") throw new Error("invalid callback: " + callback); return request.get(callback); } return request; }; function fixCallback(callback) { return function(error, xhr) { callback(error == null ? xhr : null); }; } function hasResponse(xhr) { var type = xhr.responseType; return type && type !== "text" ? xhr.response // null on error : xhr.responseText; // "" on error } var type = function(defaultMimeType, response) { return function(url, callback) { var r = request(url).mimeType(defaultMimeType).response(response); if (callback != null) { if (typeof callback !== "function") throw new Error("invalid callback: " + callback); return r.get(callback); } return r; }; }; var html = type("text/html", function(xhr) { return document.createRange().createContextualFragment(xhr.responseText); }); var json = type("application/json", function(xhr) { return JSON.parse(xhr.responseText); }); var text = type("text/plain", function(xhr) { return xhr.responseText; }); var xml = type("application/xml", function(xhr) { var xml = xhr.responseXML; if (!xml) throw new Error("parse error"); return xml; }); var dsv = function(defaultMimeType, parse) { return function(url, row, callback) { if (arguments.length < 3) callback = row, row = null; var r = request(url).mimeType(defaultMimeType); r.row = function(_) { return arguments.length ? r.response(responseOf(parse, row = _)) : row; }; r.row(row); return callback ? r.get(callback) : r; }; }; function responseOf(parse, row) { return function(request$$1) { return parse(request$$1.responseText, row); }; } var csv = dsv("text/csv", d3Dsv.csvParse); var tsv = dsv("text/tab-separated-values", d3Dsv.tsvParse); exports.request = request; exports.html = html; exports.json = json; exports.text = text; exports.xml = xml; exports.csv = csv; exports.tsv = tsv; },{"d3-collection":19,"d3-dispatch":21,"d3-dsv":23,"xmlhttprequest":90}],36:[function(require,module,exports){ // https://d3js.org/d3-scale/ Version 1.0.6. Copyright 2017 Mike Bostock. (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('d3-array'), require('d3-collection'), require('d3-interpolate'), require('d3-format'), require('d3-time'), require('d3-time-format'), require('d3-color')) : typeof define === 'function' && define.amd ? define(['exports', 'd3-array', 'd3-collection', 'd3-interpolate', 'd3-format', 'd3-time', 'd3-time-format', 'd3-color'], factory) : (factory((global.d3 = global.d3 || {}),global.d3,global.d3,global.d3,global.d3,global.d3,global.d3,global.d3)); }(this, (function (exports,d3Array,d3Collection,d3Interpolate,d3Format,d3Time,d3TimeFormat,d3Color) { 'use strict'; var array = Array.prototype; var map$1 = array.map; var slice = array.slice; var implicit = {name: "implicit"}; function ordinal(range$$1) { var index = d3Collection.map(), domain = [], unknown = implicit; range$$1 = range$$1 == null ? [] : slice.call(range$$1); function scale(d) { var key = d + "", i = index.get(key); if (!i) { if (unknown !== implicit) return unknown; index.set(key, i = domain.push(d)); } return range$$1[(i - 1) % range$$1.length]; } scale.domain = function(_) { if (!arguments.length) return domain.slice(); domain = [], index = d3Collection.map(); var i = -1, n = _.length, d, key; while (++i < n) if (!index.has(key = (d = _[i]) + "")) index.set(key, domain.push(d)); return scale; }; scale.range = function(_) { return arguments.length ? (range$$1 = slice.call(_), scale) : range$$1.slice(); }; scale.unknown = function(_) { return arguments.length ? (unknown = _, scale) : unknown; }; scale.copy = function() { return ordinal() .domain(domain) .range(range$$1) .unknown(unknown); }; return scale; } function band() { var scale = ordinal().unknown(undefined), domain = scale.domain, ordinalRange = scale.range, range$$1 = [0, 1], step, bandwidth, round = false, paddingInner = 0, paddingOuter = 0, align = 0.5; delete scale.unknown; function rescale() { var n = domain().length, reverse = range$$1[1] < range$$1[0], start = range$$1[reverse - 0], stop = range$$1[1 - reverse]; step = (stop - start) / Math.max(1, n - paddingInner + paddingOuter * 2); if (round) step = Math.floor(step); start += (stop - start - step * (n - paddingInner)) * align; bandwidth = step * (1 - paddingInner); if (round) start = Math.round(start), bandwidth = Math.round(bandwidth); var values = d3Array.range(n).map(function(i) { return start + step * i; }); return ordinalRange(reverse ? values.reverse() : values); } scale.domain = function(_) { return arguments.length ? (domain(_), rescale()) : domain(); }; scale.range = function(_) { return arguments.length ? (range$$1 = [+_[0], +_[1]], rescale()) : range$$1.slice(); }; scale.rangeRound = function(_) { return range$$1 = [+_[0], +_[1]], round = true, rescale(); }; scale.bandwidth = function() { return bandwidth; }; scale.step = function() { return step; }; scale.round = function(_) { return arguments.length ? (round = !!_, rescale()) : round; }; scale.padding = function(_) { return arguments.length ? (paddingInner = paddingOuter = Math.max(0, Math.min(1, _)), rescale()) : paddingInner; }; scale.paddingInner = function(_) { return arguments.length ? (paddingInner = Math.max(0, Math.min(1, _)), rescale()) : paddingInner; }; scale.paddingOuter = function(_) { return arguments.length ? (paddingOuter = Math.max(0, Math.min(1, _)), rescale()) : paddingOuter; }; scale.align = function(_) { return arguments.length ? (align = Math.max(0, Math.min(1, _)), rescale()) : align; }; scale.copy = function() { return band() .domain(domain()) .range(range$$1) .round(round) .paddingInner(paddingInner) .paddingOuter(paddingOuter) .align(align); }; return rescale(); } function pointish(scale) { var copy = scale.copy; scale.padding = scale.paddingOuter; delete scale.paddingInner; delete scale.paddingOuter; scale.copy = function() { return pointish(copy()); }; return scale; } function point() { return pointish(band().paddingInner(1)); } var constant = function(x) { return function() { return x; }; }; var number = function(x) { return +x; }; var unit = [0, 1]; function deinterpolateLinear(a, b) { return (b -= (a = +a)) ? function(x) { return (x - a) / b; } : constant(b); } function deinterpolateClamp(deinterpolate) { return function(a, b) { var d = deinterpolate(a = +a, b = +b); return function(x) { return x <= a ? 0 : x >= b ? 1 : d(x); }; }; } function reinterpolateClamp(reinterpolate) { return function(a, b) { var r = reinterpolate(a = +a, b = +b); return function(t) { return t <= 0 ? a : t >= 1 ? b : r(t); }; }; } function bimap(domain, range$$1, deinterpolate, reinterpolate) { var d0 = domain[0], d1 = domain[1], r0 = range$$1[0], r1 = range$$1[1]; if (d1 < d0) d0 = deinterpolate(d1, d0), r0 = reinterpolate(r1, r0); else d0 = deinterpolate(d0, d1), r0 = reinterpolate(r0, r1); return function(x) { return r0(d0(x)); }; } function polymap(domain, range$$1, deinterpolate, reinterpolate) { var j = Math.min(domain.length, range$$1.length) - 1, d = new Array(j), r = new Array(j), i = -1; // Reverse descending domains. if (domain[j] < domain[0]) { domain = domain.slice().reverse(); range$$1 = range$$1.slice().reverse(); } while (++i < j) { d[i] = deinterpolate(domain[i], domain[i + 1]); r[i] = reinterpolate(range$$1[i], range$$1[i + 1]); } return function(x) { var i = d3Array.bisect(domain, x, 1, j) - 1; return r[i](d[i](x)); }; } function copy(source, target) { return target .domain(source.domain()) .range(source.range()) .interpolate(source.interpolate()) .clamp(source.clamp()); } // deinterpolate(a, b)(x) takes a domain value x in [a,b] and returns the corresponding parameter t in [0,1]. // reinterpolate(a, b)(t) takes a parameter t in [0,1] and returns the corresponding domain value x in [a,b]. function continuous(deinterpolate, reinterpolate) { var domain = unit, range$$1 = unit, interpolate$$1 = d3Interpolate.interpolate, clamp = false, piecewise, output, input; function rescale() { piecewise = Math.min(domain.length, range$$1.length) > 2 ? polymap : bimap; output = input = null; return scale; } function scale(x) { return (output || (output = piecewise(domain, range$$1, clamp ? deinterpolateClamp(deinterpolate) : deinterpolate, interpolate$$1)))(+x); } scale.invert = function(y) { return (input || (input = piecewise(range$$1, domain, deinterpolateLinear, clamp ? reinterpolateClamp(reinterpolate) : reinterpolate)))(+y); }; scale.domain = function(_) { return arguments.length ? (domain = map$1.call(_, number), rescale()) : domain.slice(); }; scale.range = function(_) { return arguments.length ? (range$$1 = slice.call(_), rescale()) : range$$1.slice(); }; scale.rangeRound = function(_) { return range$$1 = slice.call(_), interpolate$$1 = d3Interpolate.interpolateRound, rescale(); }; scale.clamp = function(_) { return arguments.length ? (clamp = !!_, rescale()) : clamp; }; scale.interpolate = function(_) { return arguments.length ? (interpolate$$1 = _, rescale()) : interpolate$$1; }; return rescale(); } var tickFormat = function(domain, count, specifier) { var start = domain[0], stop = domain[domain.length - 1], step = d3Array.tickStep(start, stop, count == null ? 10 : count), precision; specifier = d3Format.formatSpecifier(specifier == null ? ",f" : specifier); switch (specifier.type) { case "s": { var value = Math.max(Math.abs(start), Math.abs(stop)); if (specifier.precision == null && !isNaN(precision = d3Format.precisionPrefix(step, value))) specifier.precision = precision; return d3Format.formatPrefix(specifier, value); } case "": case "e": case "g": case "p": case "r": { if (specifier.precision == null && !isNaN(precision = d3Format.precisionRound(step, Math.max(Math.abs(start), Math.abs(stop))))) specifier.precision = precision - (specifier.type === "e"); break; } case "f": case "%": { if (specifier.precision == null && !isNaN(precision = d3Format.precisionFixed(step))) specifier.precision = precision - (specifier.type === "%") * 2; break; } } return d3Format.format(specifier); }; function linearish(scale) { var domain = scale.domain; scale.ticks = function(count) { var d = domain(); return d3Array.ticks(d[0], d[d.length - 1], count == null ? 10 : count); }; scale.tickFormat = function(count, specifier) { return tickFormat(domain(), count, specifier); }; scale.nice = function(count) { if (count == null) count = 10; var d = domain(), i0 = 0, i1 = d.length - 1, start = d[i0], stop = d[i1], step; if (stop < start) { step = start, start = stop, stop = step; step = i0, i0 = i1, i1 = step; } step = d3Array.tickIncrement(start, stop, count); if (step > 0) { start = Math.floor(start / step) * step; stop = Math.ceil(stop / step) * step; step = d3Array.tickIncrement(start, stop, count); } else if (step < 0) { start = Math.ceil(start * step) / step; stop = Math.floor(stop * step) / step; step = d3Array.tickIncrement(start, stop, count); } if (step > 0) { d[i0] = Math.floor(start / step) * step; d[i1] = Math.ceil(stop / step) * step; domain(d); } else if (step < 0) { d[i0] = Math.ceil(start * step) / step; d[i1] = Math.floor(stop * step) / step; domain(d); } return scale; }; return scale; } function linear() { var scale = continuous(deinterpolateLinear, d3Interpolate.interpolateNumber); scale.copy = function() { return copy(scale, linear()); }; return linearish(scale); } function identity() { var domain = [0, 1]; function scale(x) { return +x; } scale.invert = scale; scale.domain = scale.range = function(_) { return arguments.length ? (domain = map$1.call(_, number), scale) : domain.slice(); }; scale.copy = function() { return identity().domain(domain); }; return linearish(scale); } var nice = function(domain, interval) { domain = domain.slice(); var i0 = 0, i1 = domain.length - 1, x0 = domain[i0], x1 = domain[i1], t; if (x1 < x0) { t = i0, i0 = i1, i1 = t; t = x0, x0 = x1, x1 = t; } domain[i0] = interval.floor(x0); domain[i1] = interval.ceil(x1); return domain; }; function deinterpolate(a, b) { return (b = Math.log(b / a)) ? function(x) { return Math.log(x / a) / b; } : constant(b); } function reinterpolate(a, b) { return a < 0 ? function(t) { return -Math.pow(-b, t) * Math.pow(-a, 1 - t); } : function(t) { return Math.pow(b, t) * Math.pow(a, 1 - t); }; } function pow10(x) { return isFinite(x) ? +("1e" + x) : x < 0 ? 0 : x; } function powp(base) { return base === 10 ? pow10 : base === Math.E ? Math.exp : function(x) { return Math.pow(base, x); }; } function logp(base) { return base === Math.E ? Math.log : base === 10 && Math.log10 || base === 2 && Math.log2 || (base = Math.log(base), function(x) { return Math.log(x) / base; }); } function reflect(f) { return function(x) { return -f(-x); }; } function log() { var scale = continuous(deinterpolate, reinterpolate).domain([1, 10]), domain = scale.domain, base = 10, logs = logp(10), pows = powp(10); function rescale() { logs = logp(base), pows = powp(base); if (domain()[0] < 0) logs = reflect(logs), pows = reflect(pows); return scale; } scale.base = function(_) { return arguments.length ? (base = +_, rescale()) : base; }; scale.domain = function(_) { return arguments.length ? (domain(_), rescale()) : domain(); }; scale.ticks = function(count) { var d = domain(), u = d[0], v = d[d.length - 1], r; if (r = v < u) i = u, u = v, v = i; var i = logs(u), j = logs(v), p, k, t, n = count == null ? 10 : +count, z = []; if (!(base % 1) && j - i < n) { i = Math.round(i) - 1, j = Math.round(j) + 1; if (u > 0) for (; i < j; ++i) { for (k = 1, p = pows(i); k < base; ++k) { t = p * k; if (t < u) continue; if (t > v) break; z.push(t); } } else for (; i < j; ++i) { for (k = base - 1, p = pows(i); k >= 1; --k) { t = p * k; if (t < u) continue; if (t > v) break; z.push(t); } } } else { z = d3Array.ticks(i, j, Math.min(j - i, n)).map(pows); } return r ? z.reverse() : z; }; scale.tickFormat = function(count, specifier) { if (specifier == null) specifier = base === 10 ? ".0e" : ","; if (typeof specifier !== "function") specifier = d3Format.format(specifier); if (count === Infinity) return specifier; if (count == null) count = 10; var k = Math.max(1, base * count / scale.ticks().length); // TODO fast estimate? return function(d) { var i = d / pows(Math.round(logs(d))); if (i * base < base - 0.5) i *= base; return i <= k ? specifier(d) : ""; }; }; scale.nice = function() { return domain(nice(domain(), { floor: function(x) { return pows(Math.floor(logs(x))); }, ceil: function(x) { return pows(Math.ceil(logs(x))); } })); }; scale.copy = function() { return copy(scale, log().base(base)); }; return scale; } function raise(x, exponent) { return x < 0 ? -Math.pow(-x, exponent) : Math.pow(x, exponent); } function pow() { var exponent = 1, scale = continuous(deinterpolate, reinterpolate), domain = scale.domain; function deinterpolate(a, b) { return (b = raise(b, exponent) - (a = raise(a, exponent))) ? function(x) { return (raise(x, exponent) - a) / b; } : constant(b); } function reinterpolate(a, b) { b = raise(b, exponent) - (a = raise(a, exponent)); return function(t) { return raise(a + b * t, 1 / exponent); }; } scale.exponent = function(_) { return arguments.length ? (exponent = +_, domain(domain())) : exponent; }; scale.copy = function() { return copy(scale, pow().exponent(exponent)); }; return linearish(scale); } function sqrt() { return pow().exponent(0.5); } function quantile$1() { var domain = [], range$$1 = [], thresholds = []; function rescale() { var i = 0, n = Math.max(1, range$$1.length); thresholds = new Array(n - 1); while (++i < n) thresholds[i - 1] = d3Array.quantile(domain, i / n); return scale; } function scale(x) { if (!isNaN(x = +x)) return range$$1[d3Array.bisect(thresholds, x)]; } scale.invertExtent = function(y) { var i = range$$1.indexOf(y); return i < 0 ? [NaN, NaN] : [ i > 0 ? thresholds[i - 1] : domain[0], i < thresholds.length ? thresholds[i] : domain[domain.length - 1] ]; }; scale.domain = function(_) { if (!arguments.length) return domain.slice(); domain = []; for (var i = 0, n = _.length, d; i < n; ++i) if (d = _[i], d != null && !isNaN(d = +d)) domain.push(d); domain.sort(d3Array.ascending); return rescale(); }; scale.range = function(_) { return arguments.length ? (range$$1 = slice.call(_), rescale()) : range$$1.slice(); }; scale.quantiles = function() { return thresholds.slice(); }; scale.copy = function() { return quantile$1() .domain(domain) .range(range$$1); }; return scale; } function quantize() { var x0 = 0, x1 = 1, n = 1, domain = [0.5], range$$1 = [0, 1]; function scale(x) { if (x <= x) return range$$1[d3Array.bisect(domain, x, 0, n)]; } function rescale() { var i = -1; domain = new Array(n); while (++i < n) domain[i] = ((i + 1) * x1 - (i - n) * x0) / (n + 1); return scale; } scale.domain = function(_) { return arguments.length ? (x0 = +_[0], x1 = +_[1], rescale()) : [x0, x1]; }; scale.range = function(_) { return arguments.length ? (n = (range$$1 = slice.call(_)).length - 1, rescale()) : range$$1.slice(); }; scale.invertExtent = function(y) { var i = range$$1.indexOf(y); return i < 0 ? [NaN, NaN] : i < 1 ? [x0, domain[0]] : i >= n ? [domain[n - 1], x1] : [domain[i - 1], domain[i]]; }; scale.copy = function() { return quantize() .domain([x0, x1]) .range(range$$1); }; return linearish(scale); } function threshold() { var domain = [0.5], range$$1 = [0, 1], n = 1; function scale(x) { if (x <= x) return range$$1[d3Array.bisect(domain, x, 0, n)]; } scale.domain = function(_) { return arguments.length ? (domain = slice.call(_), n = Math.min(domain.length, range$$1.length - 1), scale) : domain.slice(); }; scale.range = function(_) { return arguments.length ? (range$$1 = slice.call(_), n = Math.min(domain.length, range$$1.length - 1), scale) : range$$1.slice(); }; scale.invertExtent = function(y) { var i = range$$1.indexOf(y); return [domain[i - 1], domain[i]]; }; scale.copy = function() { return threshold() .domain(domain) .range(range$$1); }; return scale; } var durationSecond = 1000; var durationMinute = durationSecond * 60; var durationHour = durationMinute * 60; var durationDay = durationHour * 24; var durationWeek = durationDay * 7; var durationMonth = durationDay * 30; var durationYear = durationDay * 365; function date(t) { return new Date(t); } function number$1(t) { return t instanceof Date ? +t : +new Date(+t); } function calendar(year, month, week, day, hour, minute, second, millisecond, format$$1) { var scale = continuous(deinterpolateLinear, d3Interpolate.interpolateNumber), invert = scale.invert, domain = scale.domain; var formatMillisecond = format$$1(".%L"), formatSecond = format$$1(":%S"), formatMinute = format$$1("%I:%M"), formatHour = format$$1("%I %p"), formatDay = format$$1("%a %d"), formatWeek = format$$1("%b %d"), formatMonth = format$$1("%B"), formatYear = format$$1("%Y"); var tickIntervals = [ [second, 1, durationSecond], [second, 5, 5 * durationSecond], [second, 15, 15 * durationSecond], [second, 30, 30 * durationSecond], [minute, 1, durationMinute], [minute, 5, 5 * durationMinute], [minute, 15, 15 * durationMinute], [minute, 30, 30 * durationMinute], [ hour, 1, durationHour ], [ hour, 3, 3 * durationHour ], [ hour, 6, 6 * durationHour ], [ hour, 12, 12 * durationHour ], [ day, 1, durationDay ], [ day, 2, 2 * durationDay ], [ week, 1, durationWeek ], [ month, 1, durationMonth ], [ month, 3, 3 * durationMonth ], [ year, 1, durationYear ] ]; function tickFormat(date) { return (second(date) < date ? formatMillisecond : minute(date) < date ? formatSecond : hour(date) < date ? formatMinute : day(date) < date ? formatHour : month(date) < date ? (week(date) < date ? formatDay : formatWeek) : year(date) < date ? formatMonth : formatYear)(date); } function tickInterval(interval, start, stop, step) { if (interval == null) interval = 10; // If a desired tick count is specified, pick a reasonable tick interval // based on the extent of the domain and a rough estimate of tick size. // Otherwise, assume interval is already a time interval and use it. if (typeof interval === "number") { var target = Math.abs(stop - start) / interval, i = d3Array.bisector(function(i) { return i[2]; }).right(tickIntervals, target); if (i === tickIntervals.length) { step = d3Array.tickStep(start / durationYear, stop / durationYear, interval); interval = year; } else if (i) { i = tickIntervals[target / tickIntervals[i - 1][2] < tickIntervals[i][2] / target ? i - 1 : i]; step = i[1]; interval = i[0]; } else { step = d3Array.tickStep(start, stop, interval); interval = millisecond; } } return step == null ? interval : interval.every(step); } scale.invert = function(y) { return new Date(invert(y)); }; scale.domain = function(_) { return arguments.length ? domain(map$1.call(_, number$1)) : domain().map(date); }; scale.ticks = function(interval, step) { var d = domain(), t0 = d[0], t1 = d[d.length - 1], r = t1 < t0, t; if (r) t = t0, t0 = t1, t1 = t; t = tickInterval(interval, t0, t1, step); t = t ? t.range(t0, t1 + 1) : []; // inclusive stop return r ? t.reverse() : t; }; scale.tickFormat = function(count, specifier) { return specifier == null ? tickFormat : format$$1(specifier); }; scale.nice = function(interval, step) { var d = domain(); return (interval = tickInterval(interval, d[0], d[d.length - 1], step)) ? domain(nice(d, interval)) : scale; }; scale.copy = function() { return copy(scale, calendar(year, month, week, day, hour, minute, second, millisecond, format$$1)); }; return scale; } var time = function() { return calendar(d3Time.timeYear, d3Time.timeMonth, d3Time.timeWeek, d3Time.timeDay, d3Time.timeHour, d3Time.timeMinute, d3Time.timeSecond, d3Time.timeMillisecond, d3TimeFormat.timeFormat).domain([new Date(2000, 0, 1), new Date(2000, 0, 2)]); }; var utcTime = function() { return calendar(d3Time.utcYear, d3Time.utcMonth, d3Time.utcWeek, d3Time.utcDay, d3Time.utcHour, d3Time.utcMinute, d3Time.utcSecond, d3Time.utcMillisecond, d3TimeFormat.utcFormat).domain([Date.UTC(2000, 0, 1), Date.UTC(2000, 0, 2)]); }; var colors = function(s) { return s.match(/.{6}/g).map(function(x) { return "#" + x; }); }; var category10 = colors("1f77b4ff7f0e2ca02cd627289467bd8c564be377c27f7f7fbcbd2217becf"); var category20b = colors("393b795254a36b6ecf9c9ede6379398ca252b5cf6bcedb9c8c6d31bd9e39e7ba52e7cb94843c39ad494ad6616be7969c7b4173a55194ce6dbdde9ed6"); var category20c = colors("3182bd6baed69ecae1c6dbefe6550dfd8d3cfdae6bfdd0a231a35474c476a1d99bc7e9c0756bb19e9ac8bcbddcdadaeb636363969696bdbdbdd9d9d9"); var category20 = colors("1f77b4aec7e8ff7f0effbb782ca02c98df8ad62728ff98969467bdc5b0d58c564bc49c94e377c2f7b6d27f7f7fc7c7c7bcbd22dbdb8d17becf9edae5"); var cubehelix$1 = d3Interpolate.interpolateCubehelixLong(d3Color.cubehelix(300, 0.5, 0.0), d3Color.cubehelix(-240, 0.5, 1.0)); var warm = d3Interpolate.interpolateCubehelixLong(d3Color.cubehelix(-100, 0.75, 0.35), d3Color.cubehelix(80, 1.50, 0.8)); var cool = d3Interpolate.interpolateCubehelixLong(d3Color.cubehelix(260, 0.75, 0.35), d3Color.cubehelix(80, 1.50, 0.8)); var rainbow = d3Color.cubehelix(); var rainbow$1 = function(t) { if (t < 0 || t > 1) t -= Math.floor(t); var ts = Math.abs(t - 0.5); rainbow.h = 360 * t - 100; rainbow.s = 1.5 - 1.5 * ts; rainbow.l = 0.8 - 0.9 * ts; return rainbow + ""; }; function ramp(range$$1) { var n = range$$1.length; return function(t) { return range$$1[Math.max(0, Math.min(n - 1, Math.floor(t * n)))]; }; } var viridis = ramp(colors("44015444025645045745055946075a46085c460a5d460b5e470d60470e6147106347116447136548146748166848176948186a481a6c481b6d481c6e481d6f481f70482071482173482374482475482576482677482878482979472a7a472c7a472d7b472e7c472f7d46307e46327e46337f463480453581453781453882443983443a83443b84433d84433e85423f854240864241864142874144874045884046883f47883f48893e49893e4a893e4c8a3d4d8a3d4e8a3c4f8a3c508b3b518b3b528b3a538b3a548c39558c39568c38588c38598c375a8c375b8d365c8d365d8d355e8d355f8d34608d34618d33628d33638d32648e32658e31668e31678e31688e30698e306a8e2f6b8e2f6c8e2e6d8e2e6e8e2e6f8e2d708e2d718e2c718e2c728e2c738e2b748e2b758e2a768e2a778e2a788e29798e297a8e297b8e287c8e287d8e277e8e277f8e27808e26818e26828e26828e25838e25848e25858e24868e24878e23888e23898e238a8d228b8d228c8d228d8d218e8d218f8d21908d21918c20928c20928c20938c1f948c1f958b1f968b1f978b1f988b1f998a1f9a8a1e9b8a1e9c891e9d891f9e891f9f881fa0881fa1881fa1871fa28720a38620a48621a58521a68522a78522a88423a98324aa8325ab8225ac8226ad8127ad8128ae8029af7f2ab07f2cb17e2db27d2eb37c2fb47c31b57b32b67a34b67935b77937b87838b9773aba763bbb753dbc743fbc7340bd7242be7144bf7046c06f48c16e4ac16d4cc26c4ec36b50c46a52c56954c56856c66758c7655ac8645cc8635ec96260ca6063cb5f65cb5e67cc5c69cd5b6ccd5a6ece5870cf5773d05675d05477d1537ad1517cd2507fd34e81d34d84d44b86d54989d5488bd6468ed64590d74393d74195d84098d83e9bd93c9dd93ba0da39a2da37a5db36a8db34aadc32addc30b0dd2fb2dd2db5de2bb8de29bade28bddf26c0df25c2df23c5e021c8e020cae11fcde11dd0e11cd2e21bd5e21ad8e219dae319dde318dfe318e2e418e5e419e7e419eae51aece51befe51cf1e51df4e61ef6e620f8e621fbe723fde725")); var magma = ramp(colors("00000401000501010601010802010902020b02020d03030f03031204041405041606051806051a07061c08071e0907200a08220b09240c09260d0a290e0b2b100b2d110c2f120d31130d34140e36150e38160f3b180f3d19103f1a10421c10441d11471e114920114b21114e22115024125325125527125829115a2a115c2c115f2d11612f116331116533106734106936106b38106c390f6e3b0f703d0f713f0f72400f74420f75440f764510774710784910784a10794c117a4e117b4f127b51127c52137c54137d56147d57157e59157e5a167e5c167f5d177f5f187f601880621980641a80651a80671b80681c816a1c816b1d816d1d816e1e81701f81721f817320817521817621817822817922827b23827c23827e24828025828125818326818426818627818827818928818b29818c29818e2a81902a81912b81932b80942c80962c80982d80992d809b2e7f9c2e7f9e2f7fa02f7fa1307ea3307ea5317ea6317da8327daa337dab337cad347cae347bb0357bb2357bb3367ab5367ab73779b83779ba3878bc3978bd3977bf3a77c03a76c23b75c43c75c53c74c73d73c83e73ca3e72cc3f71cd4071cf4070d0416fd2426fd3436ed5446dd6456cd8456cd9466bdb476adc4869de4968df4a68e04c67e24d66e34e65e44f64e55064e75263e85362e95462ea5661eb5760ec5860ed5a5fee5b5eef5d5ef05f5ef1605df2625df2645cf3655cf4675cf4695cf56b5cf66c5cf66e5cf7705cf7725cf8745cf8765cf9785df9795df97b5dfa7d5efa7f5efa815ffb835ffb8560fb8761fc8961fc8a62fc8c63fc8e64fc9065fd9266fd9467fd9668fd9869fd9a6afd9b6bfe9d6cfe9f6dfea16efea36ffea571fea772fea973feaa74feac76feae77feb078feb27afeb47bfeb67cfeb77efeb97ffebb81febd82febf84fec185fec287fec488fec68afec88cfeca8dfecc8ffecd90fecf92fed194fed395fed597fed799fed89afdda9cfddc9efddea0fde0a1fde2a3fde3a5fde5a7fde7a9fde9aafdebacfcecaefceeb0fcf0b2fcf2b4fcf4b6fcf6b8fcf7b9fcf9bbfcfbbdfcfdbf")); var inferno = ramp(colors("00000401000501010601010802010a02020c02020e03021004031204031405041706041907051b08051d09061f0a07220b07240c08260d08290e092b10092d110a30120a32140b34150b37160b39180c3c190c3e1b0c411c0c431e0c451f0c48210c4a230c4c240c4f260c51280b53290b552b0b572d0b592f0a5b310a5c320a5e340a5f3609613809623909633b09643d09653e0966400a67420a68440a68450a69470b6a490b6a4a0c6b4c0c6b4d0d6c4f0d6c510e6c520e6d540f6d550f6d57106e59106e5a116e5c126e5d126e5f136e61136e62146e64156e65156e67166e69166e6a176e6c186e6d186e6f196e71196e721a6e741a6e751b6e771c6d781c6d7a1d6d7c1d6d7d1e6d7f1e6c801f6c82206c84206b85216b87216b88226a8a226a8c23698d23698f24699025689225689326679526679727669827669a28659b29649d29649f2a63a02a63a22b62a32c61a52c60a62d60a82e5fa92e5eab2f5ead305dae305cb0315bb1325ab3325ab43359b63458b73557b93556ba3655bc3754bd3853bf3952c03a51c13a50c33b4fc43c4ec63d4dc73e4cc83f4bca404acb4149cc4248ce4347cf4446d04545d24644d34743d44842d54a41d74b3fd84c3ed94d3dda4e3cdb503bdd513ade5238df5337e05536e15635e25734e35933e45a31e55c30e65d2fe75e2ee8602de9612bea632aeb6429eb6628ec6726ed6925ee6a24ef6c23ef6e21f06f20f1711ff1731df2741cf3761bf37819f47918f57b17f57d15f67e14f68013f78212f78410f8850ff8870ef8890cf98b0bf98c0af98e09fa9008fa9207fa9407fb9606fb9706fb9906fb9b06fb9d07fc9f07fca108fca309fca50afca60cfca80dfcaa0ffcac11fcae12fcb014fcb216fcb418fbb61afbb81dfbba1ffbbc21fbbe23fac026fac228fac42afac62df9c72ff9c932f9cb35f8cd37f8cf3af7d13df7d340f6d543f6d746f5d949f5db4cf4dd4ff4df53f4e156f3e35af3e55df2e661f2e865f2ea69f1ec6df1ed71f1ef75f1f179f2f27df2f482f3f586f3f68af4f88ef5f992f6fa96f8fb9af9fc9dfafda1fcffa4")); var plasma = ramp(colors("0d088710078813078916078a19068c1b068d1d068e20068f2206902406912605912805922a05932c05942e05952f059631059733059735049837049938049a3a049a3c049b3e049c3f049c41049d43039e44039e46039f48039f4903a04b03a14c02a14e02a25002a25102a35302a35502a45601a45801a45901a55b01a55c01a65e01a66001a66100a76300a76400a76600a76700a86900a86a00a86c00a86e00a86f00a87100a87201a87401a87501a87701a87801a87a02a87b02a87d03a87e03a88004a88104a78305a78405a78606a68707a68808a68a09a58b0aa58d0ba58e0ca48f0da4910ea3920fa39410a29511a19613a19814a099159f9a169f9c179e9d189d9e199da01a9ca11b9ba21d9aa31e9aa51f99a62098a72197a82296aa2395ab2494ac2694ad2793ae2892b02991b12a90b22b8fb32c8eb42e8db52f8cb6308bb7318ab83289ba3388bb3488bc3587bd3786be3885bf3984c03a83c13b82c23c81c33d80c43e7fc5407ec6417dc7427cc8437bc9447aca457acb4679cc4778cc4977cd4a76ce4b75cf4c74d04d73d14e72d24f71d35171d45270d5536fd5546ed6556dd7566cd8576bd9586ada5a6ada5b69db5c68dc5d67dd5e66de5f65de6164df6263e06363e16462e26561e26660e3685fe4695ee56a5de56b5de66c5ce76e5be76f5ae87059e97158e97257ea7457eb7556eb7655ec7754ed7953ed7a52ee7b51ef7c51ef7e50f07f4ff0804ef1814df1834cf2844bf3854bf3874af48849f48948f58b47f58c46f68d45f68f44f79044f79143f79342f89441f89540f9973ff9983ef99a3efa9b3dfa9c3cfa9e3bfb9f3afba139fba238fca338fca537fca636fca835fca934fdab33fdac33fdae32fdaf31fdb130fdb22ffdb42ffdb52efeb72dfeb82cfeba2cfebb2bfebd2afebe2afec029fdc229fdc328fdc527fdc627fdc827fdca26fdcb26fccd25fcce25fcd025fcd225fbd324fbd524fbd724fad824fada24f9dc24f9dd25f8df25f8e125f7e225f7e425f6e626f6e826f5e926f5eb27f4ed27f3ee27f3f027f2f227f1f426f1f525f0f724f0f921")); function sequential(interpolator) { var x0 = 0, x1 = 1, clamp = false; function scale(x) { var t = (x - x0) / (x1 - x0); return interpolator(clamp ? Math.max(0, Math.min(1, t)) : t); } scale.domain = function(_) { return arguments.length ? (x0 = +_[0], x1 = +_[1], scale) : [x0, x1]; }; scale.clamp = function(_) { return arguments.length ? (clamp = !!_, scale) : clamp; }; scale.interpolator = function(_) { return arguments.length ? (interpolator = _, scale) : interpolator; }; scale.copy = function() { return sequential(interpolator).domain([x0, x1]).clamp(clamp); }; return linearish(scale); } exports.scaleBand = band; exports.scalePoint = point; exports.scaleIdentity = identity; exports.scaleLinear = linear; exports.scaleLog = log; exports.scaleOrdinal = ordinal; exports.scaleImplicit = implicit; exports.scalePow = pow; exports.scaleSqrt = sqrt; exports.scaleQuantile = quantile$1; exports.scaleQuantize = quantize; exports.scaleThreshold = threshold; exports.scaleTime = time; exports.scaleUtc = utcTime; exports.schemeCategory10 = category10; exports.schemeCategory20b = category20b; exports.schemeCategory20c = category20c; exports.schemeCategory20 = category20; exports.interpolateCubehelixDefault = cubehelix$1; exports.interpolateRainbow = rainbow$1; exports.interpolateWarm = warm; exports.interpolateCool = cool; exports.interpolateViridis = viridis; exports.interpolateMagma = magma; exports.interpolateInferno = inferno; exports.interpolatePlasma = plasma; exports.scaleSequential = sequential; Object.defineProperty(exports, '__esModule', { value: true }); }))); },{"d3-array":15,"d3-collection":19,"d3-color":20,"d3-format":26,"d3-interpolate":29,"d3-time":40,"d3-time-format":39}],37:[function(require,module,exports){ // https://d3js.org/d3-selection/ Version 1.1.0. Copyright 2017 Mike Bostock. (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (factory((global.d3 = global.d3 || {}))); }(this, (function (exports) { 'use strict'; var xhtml = "http://www.w3.org/1999/xhtml"; var namespaces = { svg: "http://www.w3.org/2000/svg", xhtml: xhtml, xlink: "http://www.w3.org/1999/xlink", xml: "http://www.w3.org/XML/1998/namespace", xmlns: "http://www.w3.org/2000/xmlns/" }; var namespace = function(name) { var prefix = name += "", i = prefix.indexOf(":"); if (i >= 0 && (prefix = name.slice(0, i)) !== "xmlns") name = name.slice(i + 1); return namespaces.hasOwnProperty(prefix) ? {space: namespaces[prefix], local: name} : name; }; function creatorInherit(name) { return function() { var document = this.ownerDocument, uri = this.namespaceURI; return uri === xhtml && document.documentElement.namespaceURI === xhtml ? document.createElement(name) : document.createElementNS(uri, name); }; } function creatorFixed(fullname) { return function() { return this.ownerDocument.createElementNS(fullname.space, fullname.local); }; } var creator = function(name) { var fullname = namespace(name); return (fullname.local ? creatorFixed : creatorInherit)(fullname); }; var nextId = 0; function local() { return new Local; } function Local() { this._ = "@" + (++nextId).toString(36); } Local.prototype = local.prototype = { constructor: Local, get: function(node) { var id = this._; while (!(id in node)) if (!(node = node.parentNode)) return; return node[id]; }, set: function(node, value) { return node[this._] = value; }, remove: function(node) { return this._ in node && delete node[this._]; }, toString: function() { return this._; } }; var matcher = function(selector) { return function() { return this.matches(selector); }; }; if (typeof document !== "undefined") { var element = document.documentElement; if (!element.matches) { var vendorMatches = element.webkitMatchesSelector || element.msMatchesSelector || element.mozMatchesSelector || element.oMatchesSelector; matcher = function(selector) { return function() { return vendorMatches.call(this, selector); }; }; } } var matcher$1 = matcher; var filterEvents = {}; exports.event = null; if (typeof document !== "undefined") { var element$1 = document.documentElement; if (!("onmouseenter" in element$1)) { filterEvents = {mouseenter: "mouseover", mouseleave: "mouseout"}; } } function filterContextListener(listener, index, group) { listener = contextListener(listener, index, group); return function(event) { var related = event.relatedTarget; if (!related || (related !== this && !(related.compareDocumentPosition(this) & 8))) { listener.call(this, event); } }; } function contextListener(listener, index, group) { return function(event1) { var event0 = exports.event; // Events can be reentrant (e.g., focus). exports.event = event1; try { listener.call(this, this.__data__, index, group); } finally { exports.event = event0; } }; } function parseTypenames(typenames) { return typenames.trim().split(/^|\s+/).map(function(t) { var name = "", i = t.indexOf("."); if (i >= 0) name = t.slice(i + 1), t = t.slice(0, i); return {type: t, name: name}; }); } function onRemove(typename) { return function() { var on = this.__on; if (!on) return; for (var j = 0, i = -1, m = on.length, o; j < m; ++j) { if (o = on[j], (!typename.type || o.type === typename.type) && o.name === typename.name) { this.removeEventListener(o.type, o.listener, o.capture); } else { on[++i] = o; } } if (++i) on.length = i; else delete this.__on; }; } function onAdd(typename, value, capture) { var wrap = filterEvents.hasOwnProperty(typename.type) ? filterContextListener : contextListener; return function(d, i, group) { var on = this.__on, o, listener = wrap(value, i, group); if (on) for (var j = 0, m = on.length; j < m; ++j) { if ((o = on[j]).type === typename.type && o.name === typename.name) { this.removeEventListener(o.type, o.listener, o.capture); this.addEventListener(o.type, o.listener = listener, o.capture = capture); o.value = value; return; } } this.addEventListener(typename.type, listener, capture); o = {type: typename.type, name: typename.name, value: value, listener: listener, capture: capture}; if (!on) this.__on = [o]; else on.push(o); }; } var selection_on = function(typename, value, capture) { var typenames = parseTypenames(typename + ""), i, n = typenames.length, t; if (arguments.length < 2) { var on = this.node().__on; if (on) for (var j = 0, m = on.length, o; j < m; ++j) { for (i = 0, o = on[j]; i < n; ++i) { if ((t = typenames[i]).type === o.type && t.name === o.name) { return o.value; } } } return; } on = value ? onAdd : onRemove; if (capture == null) capture = false; for (i = 0; i < n; ++i) this.each(on(typenames[i], value, capture)); return this; }; function customEvent(event1, listener, that, args) { var event0 = exports.event; event1.sourceEvent = exports.event; exports.event = event1; try { return listener.apply(that, args); } finally { exports.event = event0; } } var sourceEvent = function() { var current = exports.event, source; while (source = current.sourceEvent) current = source; return current; }; var point = function(node, event) { var svg = node.ownerSVGElement || node; if (svg.createSVGPoint) { var point = svg.createSVGPoint(); point.x = event.clientX, point.y = event.clientY; point = point.matrixTransform(node.getScreenCTM().inverse()); return [point.x, point.y]; } var rect = node.getBoundingClientRect(); return [event.clientX - rect.left - node.clientLeft, event.clientY - rect.top - node.clientTop]; }; var mouse = function(node) { var event = sourceEvent(); if (event.changedTouches) event = event.changedTouches[0]; return point(node, event); }; function none() {} var selector = function(selector) { return selector == null ? none : function() { return this.querySelector(selector); }; }; var selection_select = function(select) { if (typeof select !== "function") select = selector(select); for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) { for (var group = groups[j], n = group.length, subgroup = subgroups[j] = new Array(n), node, subnode, i = 0; i < n; ++i) { if ((node = group[i]) && (subnode = select.call(node, node.__data__, i, group))) { if ("__data__" in node) subnode.__data__ = node.__data__; subgroup[i] = subnode; } } } return new Selection(subgroups, this._parents); }; function empty() { return []; } var selectorAll = function(selector) { return selector == null ? empty : function() { return this.querySelectorAll(selector); }; }; var selection_selectAll = function(select) { if (typeof select !== "function") select = selectorAll(select); for (var groups = this._groups, m = groups.length, subgroups = [], parents = [], j = 0; j < m; ++j) { for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) { if (node = group[i]) { subgroups.push(select.call(node, node.__data__, i, group)); parents.push(node); } } } return new Selection(subgroups, parents); }; var selection_filter = function(match) { if (typeof match !== "function") match = matcher$1(match); for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) { for (var group = groups[j], n = group.length, subgroup = subgroups[j] = [], node, i = 0; i < n; ++i) { if ((node = group[i]) && match.call(node, node.__data__, i, group)) { subgroup.push(node); } } } return new Selection(subgroups, this._parents); }; var sparse = function(update) { return new Array(update.length); }; var selection_enter = function() { return new Selection(this._enter || this._groups.map(sparse), this._parents); }; function EnterNode(parent, datum) { this.ownerDocument = parent.ownerDocument; this.namespaceURI = parent.namespaceURI; this._next = null; this._parent = parent; this.__data__ = datum; } EnterNode.prototype = { constructor: EnterNode, appendChild: function(child) { return this._parent.insertBefore(child, this._next); }, insertBefore: function(child, next) { return this._parent.insertBefore(child, next); }, querySelector: function(selector) { return this._parent.querySelector(selector); }, querySelectorAll: function(selector) { return this._parent.querySelectorAll(selector); } }; var constant = function(x) { return function() { return x; }; }; var keyPrefix = "$"; // Protect against keys like “__proto__”. function bindIndex(parent, group, enter, update, exit, data) { var i = 0, node, groupLength = group.length, dataLength = data.length; // Put any non-null nodes that fit into update. // Put any null nodes into enter. // Put any remaining data into enter. for (; i < dataLength; ++i) { if (node = group[i]) { node.__data__ = data[i]; update[i] = node; } else { enter[i] = new EnterNode(parent, data[i]); } } // Put any non-null nodes that don’t fit into exit. for (; i < groupLength; ++i) { if (node = group[i]) { exit[i] = node; } } } function bindKey(parent, group, enter, update, exit, data, key) { var i, node, nodeByKeyValue = {}, groupLength = group.length, dataLength = data.length, keyValues = new Array(groupLength), keyValue; // Compute the key for each node. // If multiple nodes have the same key, the duplicates are added to exit. for (i = 0; i < groupLength; ++i) { if (node = group[i]) { keyValues[i] = keyValue = keyPrefix + key.call(node, node.__data__, i, group); if (keyValue in nodeByKeyValue) { exit[i] = node; } else { nodeByKeyValue[keyValue] = node; } } } // Compute the key for each datum. // If there a node associated with this key, join and add it to update. // If there is not (or the key is a duplicate), add it to enter. for (i = 0; i < dataLength; ++i) { keyValue = keyPrefix + key.call(parent, data[i], i, data); if (node = nodeByKeyValue[keyValue]) { update[i] = node; node.__data__ = data[i]; nodeByKeyValue[keyValue] = null; } else { enter[i] = new EnterNode(parent, data[i]); } } // Add any remaining nodes that were not bound to data to exit. for (i = 0; i < groupLength; ++i) { if ((node = group[i]) && (nodeByKeyValue[keyValues[i]] === node)) { exit[i] = node; } } } var selection_data = function(value, key) { if (!value) { data = new Array(this.size()), j = -1; this.each(function(d) { data[++j] = d; }); return data; } var bind = key ? bindKey : bindIndex, parents = this._parents, groups = this._groups; if (typeof value !== "function") value = constant(value); for (var m = groups.length, update = new Array(m), enter = new Array(m), exit = new Array(m), j = 0; j < m; ++j) { var parent = parents[j], group = groups[j], groupLength = group.length, data = value.call(parent, parent && parent.__data__, j, parents), dataLength = data.length, enterGroup = enter[j] = new Array(dataLength), updateGroup = update[j] = new Array(dataLength), exitGroup = exit[j] = new Array(groupLength); bind(parent, group, enterGroup, updateGroup, exitGroup, data, key); // Now connect the enter nodes to their following update node, such that // appendChild can insert the materialized enter node before this node, // rather than at the end of the parent node. for (var i0 = 0, i1 = 0, previous, next; i0 < dataLength; ++i0) { if (previous = enterGroup[i0]) { if (i0 >= i1) i1 = i0 + 1; while (!(next = updateGroup[i1]) && ++i1 < dataLength); previous._next = next || null; } } } update = new Selection(update, parents); update._enter = enter; update._exit = exit; return update; }; var selection_exit = function() { return new Selection(this._exit || this._groups.map(sparse), this._parents); }; var selection_merge = function(selection) { for (var groups0 = this._groups, groups1 = selection._groups, m0 = groups0.length, m1 = groups1.length, m = Math.min(m0, m1), merges = new Array(m0), j = 0; j < m; ++j) { for (var group0 = groups0[j], group1 = groups1[j], n = group0.length, merge = merges[j] = new Array(n), node, i = 0; i < n; ++i) { if (node = group0[i] || group1[i]) { merge[i] = node; } } } for (; j < m0; ++j) { merges[j] = groups0[j]; } return new Selection(merges, this._parents); }; var selection_order = function() { for (var groups = this._groups, j = -1, m = groups.length; ++j < m;) { for (var group = groups[j], i = group.length - 1, next = group[i], node; --i >= 0;) { if (node = group[i]) { if (next && next !== node.nextSibling) next.parentNode.insertBefore(node, next); next = node; } } } return this; }; var selection_sort = function(compare) { if (!compare) compare = ascending; function compareNode(a, b) { return a && b ? compare(a.__data__, b.__data__) : !a - !b; } for (var groups = this._groups, m = groups.length, sortgroups = new Array(m), j = 0; j < m; ++j) { for (var group = groups[j], n = group.length, sortgroup = sortgroups[j] = new Array(n), node, i = 0; i < n; ++i) { if (node = group[i]) { sortgroup[i] = node; } } sortgroup.sort(compareNode); } return new Selection(sortgroups, this._parents).order(); }; function ascending(a, b) { return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN; } var selection_call = function() { var callback = arguments[0]; arguments[0] = this; callback.apply(null, arguments); return this; }; var selection_nodes = function() { var nodes = new Array(this.size()), i = -1; this.each(function() { nodes[++i] = this; }); return nodes; }; var selection_node = function() { for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) { for (var group = groups[j], i = 0, n = group.length; i < n; ++i) { var node = group[i]; if (node) return node; } } return null; }; var selection_size = function() { var size = 0; this.each(function() { ++size; }); return size; }; var selection_empty = function() { return !this.node(); }; var selection_each = function(callback) { for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) { for (var group = groups[j], i = 0, n = group.length, node; i < n; ++i) { if (node = group[i]) callback.call(node, node.__data__, i, group); } } return this; }; function attrRemove(name) { return function() { this.removeAttribute(name); }; } function attrRemoveNS(fullname) { return function() { this.removeAttributeNS(fullname.space, fullname.local); }; } function attrConstant(name, value) { return function() { this.setAttribute(name, value); }; } function attrConstantNS(fullname, value) { return function() { this.setAttributeNS(fullname.space, fullname.local, value); }; } function attrFunction(name, value) { return function() { var v = value.apply(this, arguments); if (v == null) this.removeAttribute(name); else this.setAttribute(name, v); }; } function attrFunctionNS(fullname, value) { return function() { var v = value.apply(this, arguments); if (v == null) this.removeAttributeNS(fullname.space, fullname.local); else this.setAttributeNS(fullname.space, fullname.local, v); }; } var selection_attr = function(name, value) { var fullname = namespace(name); if (arguments.length < 2) { var node = this.node(); return fullname.local ? node.getAttributeNS(fullname.space, fullname.local) : node.getAttribute(fullname); } return this.each((value == null ? (fullname.local ? attrRemoveNS : attrRemove) : (typeof value === "function" ? (fullname.local ? attrFunctionNS : attrFunction) : (fullname.local ? attrConstantNS : attrConstant)))(fullname, value)); }; var defaultView = function(node) { return (node.ownerDocument && node.ownerDocument.defaultView) // node is a Node || (node.document && node) // node is a Window || node.defaultView; // node is a Document }; function styleRemove(name) { return function() { this.style.removeProperty(name); }; } function styleConstant(name, value, priority) { return function() { this.style.setProperty(name, value, priority); }; } function styleFunction(name, value, priority) { return function() { var v = value.apply(this, arguments); if (v == null) this.style.removeProperty(name); else this.style.setProperty(name, v, priority); }; } var selection_style = function(name, value, priority) { return arguments.length > 1 ? this.each((value == null ? styleRemove : typeof value === "function" ? styleFunction : styleConstant)(name, value, priority == null ? "" : priority)) : styleValue(this.node(), name); }; function styleValue(node, name) { return node.style.getPropertyValue(name) || defaultView(node).getComputedStyle(node, null).getPropertyValue(name); } function propertyRemove(name) { return function() { delete this[name]; }; } function propertyConstant(name, value) { return function() { this[name] = value; }; } function propertyFunction(name, value) { return function() { var v = value.apply(this, arguments); if (v == null) delete this[name]; else this[name] = v; }; } var selection_property = function(name, value) { return arguments.length > 1 ? this.each((value == null ? propertyRemove : typeof value === "function" ? propertyFunction : propertyConstant)(name, value)) : this.node()[name]; }; function classArray(string) { return string.trim().split(/^|\s+/); } function classList(node) { return node.classList || new ClassList(node); } function ClassList(node) { this._node = node; this._names = classArray(node.getAttribute("class") || ""); } ClassList.prototype = { add: function(name) { var i = this._names.indexOf(name); if (i < 0) { this._names.push(name); this._node.setAttribute("class", this._names.join(" ")); } }, remove: function(name) { var i = this._names.indexOf(name); if (i >= 0) { this._names.splice(i, 1); this._node.setAttribute("class", this._names.join(" ")); } }, contains: function(name) { return this._names.indexOf(name) >= 0; } }; function classedAdd(node, names) { var list = classList(node), i = -1, n = names.length; while (++i < n) list.add(names[i]); } function classedRemove(node, names) { var list = classList(node), i = -1, n = names.length; while (++i < n) list.remove(names[i]); } function classedTrue(names) { return function() { classedAdd(this, names); }; } function classedFalse(names) { return function() { classedRemove(this, names); }; } function classedFunction(names, value) { return function() { (value.apply(this, arguments) ? classedAdd : classedRemove)(this, names); }; } var selection_classed = function(name, value) { var names = classArray(name + ""); if (arguments.length < 2) { var list = classList(this.node()), i = -1, n = names.length; while (++i < n) if (!list.contains(names[i])) return false; return true; } return this.each((typeof value === "function" ? classedFunction : value ? classedTrue : classedFalse)(names, value)); }; function textRemove() { this.textContent = ""; } function textConstant(value) { return function() { this.textContent = value; }; } function textFunction(value) { return function() { var v = value.apply(this, arguments); this.textContent = v == null ? "" : v; }; } var selection_text = function(value) { return arguments.length ? this.each(value == null ? textRemove : (typeof value === "function" ? textFunction : textConstant)(value)) : this.node().textContent; }; function htmlRemove() { this.innerHTML = ""; } function htmlConstant(value) { return function() { this.innerHTML = value; }; } function htmlFunction(value) { return function() { var v = value.apply(this, arguments); this.innerHTML = v == null ? "" : v; }; } var selection_html = function(value) { return arguments.length ? this.each(value == null ? htmlRemove : (typeof value === "function" ? htmlFunction : htmlConstant)(value)) : this.node().innerHTML; }; function raise() { if (this.nextSibling) this.parentNode.appendChild(this); } var selection_raise = function() { return this.each(raise); }; function lower() { if (this.previousSibling) this.parentNode.insertBefore(this, this.parentNode.firstChild); } var selection_lower = function() { return this.each(lower); }; var selection_append = function(name) { var create = typeof name === "function" ? name : creator(name); return this.select(function() { return this.appendChild(create.apply(this, arguments)); }); }; function constantNull() { return null; } var selection_insert = function(name, before) { var create = typeof name === "function" ? name : creator(name), select = before == null ? constantNull : typeof before === "function" ? before : selector(before); return this.select(function() { return this.insertBefore(create.apply(this, arguments), select.apply(this, arguments) || null); }); }; function remove() { var parent = this.parentNode; if (parent) parent.removeChild(this); } var selection_remove = function() { return this.each(remove); }; var selection_datum = function(value) { return arguments.length ? this.property("__data__", value) : this.node().__data__; }; function dispatchEvent(node, type, params) { var window = defaultView(node), event = window.CustomEvent; if (typeof event === "function") { event = new event(type, params); } else { event = window.document.createEvent("Event"); if (params) event.initEvent(type, params.bubbles, params.cancelable), event.detail = params.detail; else event.initEvent(type, false, false); } node.dispatchEvent(event); } function dispatchConstant(type, params) { return function() { return dispatchEvent(this, type, params); }; } function dispatchFunction(type, params) { return function() { return dispatchEvent(this, type, params.apply(this, arguments)); }; } var selection_dispatch = function(type, params) { return this.each((typeof params === "function" ? dispatchFunction : dispatchConstant)(type, params)); }; var root = [null]; function Selection(groups, parents) { this._groups = groups; this._parents = parents; } function selection() { return new Selection([[document.documentElement]], root); } Selection.prototype = selection.prototype = { constructor: Selection, select: selection_select, selectAll: selection_selectAll, filter: selection_filter, data: selection_data, enter: selection_enter, exit: selection_exit, merge: selection_merge, order: selection_order, sort: selection_sort, call: selection_call, nodes: selection_nodes, node: selection_node, size: selection_size, empty: selection_empty, each: selection_each, attr: selection_attr, style: selection_style, property: selection_property, classed: selection_classed, text: selection_text, html: selection_html, raise: selection_raise, lower: selection_lower, append: selection_append, insert: selection_insert, remove: selection_remove, datum: selection_datum, on: selection_on, dispatch: selection_dispatch }; var select = function(selector) { return typeof selector === "string" ? new Selection([[document.querySelector(selector)]], [document.documentElement]) : new Selection([[selector]], root); }; var selectAll = function(selector) { return typeof selector === "string" ? new Selection([document.querySelectorAll(selector)], [document.documentElement]) : new Selection([selector == null ? [] : selector], root); }; var touch = function(node, touches, identifier) { if (arguments.length < 3) identifier = touches, touches = sourceEvent().changedTouches; for (var i = 0, n = touches ? touches.length : 0, touch; i < n; ++i) { if ((touch = touches[i]).identifier === identifier) { return point(node, touch); } } return null; }; var touches = function(node, touches) { if (touches == null) touches = sourceEvent().touches; for (var i = 0, n = touches ? touches.length : 0, points = new Array(n); i < n; ++i) { points[i] = point(node, touches[i]); } return points; }; exports.creator = creator; exports.local = local; exports.matcher = matcher$1; exports.mouse = mouse; exports.namespace = namespace; exports.namespaces = namespaces; exports.select = select; exports.selectAll = selectAll; exports.selection = selection; exports.selector = selector; exports.selectorAll = selectorAll; exports.style = styleValue; exports.touch = touch; exports.touches = touches; exports.window = defaultView; exports.customEvent = customEvent; Object.defineProperty(exports, '__esModule', { value: true }); }))); },{}],38:[function(require,module,exports){ // https://d3js.org/d3-shape/ Version 1.2.0. Copyright 2017 Mike Bostock. (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('d3-path')) : typeof define === 'function' && define.amd ? define(['exports', 'd3-path'], factory) : (factory((global.d3 = global.d3 || {}),global.d3)); }(this, (function (exports,d3Path) { 'use strict'; var constant = function(x) { return function constant() { return x; }; }; var abs = Math.abs; var atan2 = Math.atan2; var cos = Math.cos; var max = Math.max; var min = Math.min; var sin = Math.sin; var sqrt = Math.sqrt; var epsilon = 1e-12; var pi = Math.PI; var halfPi = pi / 2; var tau = 2 * pi; function acos(x) { return x > 1 ? 0 : x < -1 ? pi : Math.acos(x); } function asin(x) { return x >= 1 ? halfPi : x <= -1 ? -halfPi : Math.asin(x); } function arcInnerRadius(d) { return d.innerRadius; } function arcOuterRadius(d) { return d.outerRadius; } function arcStartAngle(d) { return d.startAngle; } function arcEndAngle(d) { return d.endAngle; } function arcPadAngle(d) { return d && d.padAngle; // Note: optional! } function intersect(x0, y0, x1, y1, x2, y2, x3, y3) { var x10 = x1 - x0, y10 = y1 - y0, x32 = x3 - x2, y32 = y3 - y2, t = (x32 * (y0 - y2) - y32 * (x0 - x2)) / (y32 * x10 - x32 * y10); return [x0 + t * x10, y0 + t * y10]; } // Compute perpendicular offset line of length rc. // http://mathworld.wolfram.com/Circle-LineIntersection.html function cornerTangents(x0, y0, x1, y1, r1, rc, cw) { var x01 = x0 - x1, y01 = y0 - y1, lo = (cw ? rc : -rc) / sqrt(x01 * x01 + y01 * y01), ox = lo * y01, oy = -lo * x01, x11 = x0 + ox, y11 = y0 + oy, x10 = x1 + ox, y10 = y1 + oy, x00 = (x11 + x10) / 2, y00 = (y11 + y10) / 2, dx = x10 - x11, dy = y10 - y11, d2 = dx * dx + dy * dy, r = r1 - rc, D = x11 * y10 - x10 * y11, d = (dy < 0 ? -1 : 1) * sqrt(max(0, r * r * d2 - D * D)), cx0 = (D * dy - dx * d) / d2, cy0 = (-D * dx - dy * d) / d2, cx1 = (D * dy + dx * d) / d2, cy1 = (-D * dx + dy * d) / d2, dx0 = cx0 - x00, dy0 = cy0 - y00, dx1 = cx1 - x00, dy1 = cy1 - y00; // Pick the closer of the two intersection points. // TODO Is there a faster way to determine which intersection to use? if (dx0 * dx0 + dy0 * dy0 > dx1 * dx1 + dy1 * dy1) cx0 = cx1, cy0 = cy1; return { cx: cx0, cy: cy0, x01: -ox, y01: -oy, x11: cx0 * (r1 / r - 1), y11: cy0 * (r1 / r - 1) }; } var arc = function() { var innerRadius = arcInnerRadius, outerRadius = arcOuterRadius, cornerRadius = constant(0), padRadius = null, startAngle = arcStartAngle, endAngle = arcEndAngle, padAngle = arcPadAngle, context = null; function arc() { var buffer, r, r0 = +innerRadius.apply(this, arguments), r1 = +outerRadius.apply(this, arguments), a0 = startAngle.apply(this, arguments) - halfPi, a1 = endAngle.apply(this, arguments) - halfPi, da = abs(a1 - a0), cw = a1 > a0; if (!context) context = buffer = d3Path.path(); // Ensure that the outer radius is always larger than the inner radius. if (r1 < r0) r = r1, r1 = r0, r0 = r; // Is it a point? if (!(r1 > epsilon)) context.moveTo(0, 0); // Or is it a circle or annulus? else if (da > tau - epsilon) { context.moveTo(r1 * cos(a0), r1 * sin(a0)); context.arc(0, 0, r1, a0, a1, !cw); if (r0 > epsilon) { context.moveTo(r0 * cos(a1), r0 * sin(a1)); context.arc(0, 0, r0, a1, a0, cw); } } // Or is it a circular or annular sector? else { var a01 = a0, a11 = a1, a00 = a0, a10 = a1, da0 = da, da1 = da, ap = padAngle.apply(this, arguments) / 2, rp = (ap > epsilon) && (padRadius ? +padRadius.apply(this, arguments) : sqrt(r0 * r0 + r1 * r1)), rc = min(abs(r1 - r0) / 2, +cornerRadius.apply(this, arguments)), rc0 = rc, rc1 = rc, t0, t1; // Apply padding? Note that since r1 ≥ r0, da1 ≥ da0. if (rp > epsilon) { var p0 = asin(rp / r0 * sin(ap)), p1 = asin(rp / r1 * sin(ap)); if ((da0 -= p0 * 2) > epsilon) p0 *= (cw ? 1 : -1), a00 += p0, a10 -= p0; else da0 = 0, a00 = a10 = (a0 + a1) / 2; if ((da1 -= p1 * 2) > epsilon) p1 *= (cw ? 1 : -1), a01 += p1, a11 -= p1; else da1 = 0, a01 = a11 = (a0 + a1) / 2; } var x01 = r1 * cos(a01), y01 = r1 * sin(a01), x10 = r0 * cos(a10), y10 = r0 * sin(a10); // Apply rounded corners? if (rc > epsilon) { var x11 = r1 * cos(a11), y11 = r1 * sin(a11), x00 = r0 * cos(a00), y00 = r0 * sin(a00); // Restrict the corner radius according to the sector angle. if (da < pi) { var oc = da0 > epsilon ? intersect(x01, y01, x00, y00, x11, y11, x10, y10) : [x10, y10], ax = x01 - oc[0], ay = y01 - oc[1], bx = x11 - oc[0], by = y11 - oc[1], kc = 1 / sin(acos((ax * bx + ay * by) / (sqrt(ax * ax + ay * ay) * sqrt(bx * bx + by * by))) / 2), lc = sqrt(oc[0] * oc[0] + oc[1] * oc[1]); rc0 = min(rc, (r0 - lc) / (kc - 1)); rc1 = min(rc, (r1 - lc) / (kc + 1)); } } // Is the sector collapsed to a line? if (!(da1 > epsilon)) context.moveTo(x01, y01); // Does the sector’s outer ring have rounded corners? else if (rc1 > epsilon) { t0 = cornerTangents(x00, y00, x01, y01, r1, rc1, cw); t1 = cornerTangents(x11, y11, x10, y10, r1, rc1, cw); context.moveTo(t0.cx + t0.x01, t0.cy + t0.y01); // Have the corners merged? if (rc1 < rc) context.arc(t0.cx, t0.cy, rc1, atan2(t0.y01, t0.x01), atan2(t1.y01, t1.x01), !cw); // Otherwise, draw the two corners and the ring. else { context.arc(t0.cx, t0.cy, rc1, atan2(t0.y01, t0.x01), atan2(t0.y11, t0.x11), !cw); context.arc(0, 0, r1, atan2(t0.cy + t0.y11, t0.cx + t0.x11), atan2(t1.cy + t1.y11, t1.cx + t1.x11), !cw); context.arc(t1.cx, t1.cy, rc1, atan2(t1.y11, t1.x11), atan2(t1.y01, t1.x01), !cw); } } // Or is the outer ring just a circular arc? else context.moveTo(x01, y01), context.arc(0, 0, r1, a01, a11, !cw); // Is there no inner ring, and it’s a circular sector? // Or perhaps it’s an annular sector collapsed due to padding? if (!(r0 > epsilon) || !(da0 > epsilon)) context.lineTo(x10, y10); // Does the sector’s inner ring (or point) have rounded corners? else if (rc0 > epsilon) { t0 = cornerTangents(x10, y10, x11, y11, r0, -rc0, cw); t1 = cornerTangents(x01, y01, x00, y00, r0, -rc0, cw); context.lineTo(t0.cx + t0.x01, t0.cy + t0.y01); // Have the corners merged? if (rc0 < rc) context.arc(t0.cx, t0.cy, rc0, atan2(t0.y01, t0.x01), atan2(t1.y01, t1.x01), !cw); // Otherwise, draw the two corners and the ring. else { context.arc(t0.cx, t0.cy, rc0, atan2(t0.y01, t0.x01), atan2(t0.y11, t0.x11), !cw); context.arc(0, 0, r0, atan2(t0.cy + t0.y11, t0.cx + t0.x11), atan2(t1.cy + t1.y11, t1.cx + t1.x11), cw); context.arc(t1.cx, t1.cy, rc0, atan2(t1.y11, t1.x11), atan2(t1.y01, t1.x01), !cw); } } // Or is the inner ring just a circular arc? else context.arc(0, 0, r0, a10, a00, cw); } context.closePath(); if (buffer) return context = null, buffer + "" || null; } arc.centroid = function() { var r = (+innerRadius.apply(this, arguments) + +outerRadius.apply(this, arguments)) / 2, a = (+startAngle.apply(this, arguments) + +endAngle.apply(this, arguments)) / 2 - pi / 2; return [cos(a) * r, sin(a) * r]; }; arc.innerRadius = function(_) { return arguments.length ? (innerRadius = typeof _ === "function" ? _ : constant(+_), arc) : innerRadius; }; arc.outerRadius = function(_) { return arguments.length ? (outerRadius = typeof _ === "function" ? _ : constant(+_), arc) : outerRadius; }; arc.cornerRadius = function(_) { return arguments.length ? (cornerRadius = typeof _ === "function" ? _ : constant(+_), arc) : cornerRadius; }; arc.padRadius = function(_) { return arguments.length ? (padRadius = _ == null ? null : typeof _ === "function" ? _ : constant(+_), arc) : padRadius; }; arc.startAngle = function(_) { return arguments.length ? (startAngle = typeof _ === "function" ? _ : constant(+_), arc) : startAngle; }; arc.endAngle = function(_) { return arguments.length ? (endAngle = typeof _ === "function" ? _ : constant(+_), arc) : endAngle; }; arc.padAngle = function(_) { return arguments.length ? (padAngle = typeof _ === "function" ? _ : constant(+_), arc) : padAngle; }; arc.context = function(_) { return arguments.length ? ((context = _ == null ? null : _), arc) : context; }; return arc; }; function Linear(context) { this._context = context; } Linear.prototype = { areaStart: function() { this._line = 0; }, areaEnd: function() { this._line = NaN; }, lineStart: function() { this._point = 0; }, lineEnd: function() { if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath(); this._line = 1 - this._line; }, point: function(x, y) { x = +x, y = +y; switch (this._point) { case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break; case 1: this._point = 2; // proceed default: this._context.lineTo(x, y); break; } } }; var curveLinear = function(context) { return new Linear(context); }; function x(p) { return p[0]; } function y(p) { return p[1]; } var line = function() { var x$$1 = x, y$$1 = y, defined = constant(true), context = null, curve = curveLinear, output = null; function line(data) { var i, n = data.length, d, defined0 = false, buffer; if (context == null) output = curve(buffer = d3Path.path()); for (i = 0; i <= n; ++i) { if (!(i < n && defined(d = data[i], i, data)) === defined0) { if (defined0 = !defined0) output.lineStart(); else output.lineEnd(); } if (defined0) output.point(+x$$1(d, i, data), +y$$1(d, i, data)); } if (buffer) return output = null, buffer + "" || null; } line.x = function(_) { return arguments.length ? (x$$1 = typeof _ === "function" ? _ : constant(+_), line) : x$$1; }; line.y = function(_) { return arguments.length ? (y$$1 = typeof _ === "function" ? _ : constant(+_), line) : y$$1; }; line.defined = function(_) { return arguments.length ? (defined = typeof _ === "function" ? _ : constant(!!_), line) : defined; }; line.curve = function(_) { return arguments.length ? (curve = _, context != null && (output = curve(context)), line) : curve; }; line.context = function(_) { return arguments.length ? (_ == null ? context = output = null : output = curve(context = _), line) : context; }; return line; }; var area = function() { var x0 = x, x1 = null, y0 = constant(0), y1 = y, defined = constant(true), context = null, curve = curveLinear, output = null; function area(data) { var i, j, k, n = data.length, d, defined0 = false, buffer, x0z = new Array(n), y0z = new Array(n); if (context == null) output = curve(buffer = d3Path.path()); for (i = 0; i <= n; ++i) { if (!(i < n && defined(d = data[i], i, data)) === defined0) { if (defined0 = !defined0) { j = i; output.areaStart(); output.lineStart(); } else { output.lineEnd(); output.lineStart(); for (k = i - 1; k >= j; --k) { output.point(x0z[k], y0z[k]); } output.lineEnd(); output.areaEnd(); } } if (defined0) { x0z[i] = +x0(d, i, data), y0z[i] = +y0(d, i, data); output.point(x1 ? +x1(d, i, data) : x0z[i], y1 ? +y1(d, i, data) : y0z[i]); } } if (buffer) return output = null, buffer + "" || null; } function arealine() { return line().defined(defined).curve(curve).context(context); } area.x = function(_) { return arguments.length ? (x0 = typeof _ === "function" ? _ : constant(+_), x1 = null, area) : x0; }; area.x0 = function(_) { return arguments.length ? (x0 = typeof _ === "function" ? _ : constant(+_), area) : x0; }; area.x1 = function(_) { return arguments.length ? (x1 = _ == null ? null : typeof _ === "function" ? _ : constant(+_), area) : x1; }; area.y = function(_) { return arguments.length ? (y0 = typeof _ === "function" ? _ : constant(+_), y1 = null, area) : y0; }; area.y0 = function(_) { return arguments.length ? (y0 = typeof _ === "function" ? _ : constant(+_), area) : y0; }; area.y1 = function(_) { return arguments.length ? (y1 = _ == null ? null : typeof _ === "function" ? _ : constant(+_), area) : y1; }; area.lineX0 = area.lineY0 = function() { return arealine().x(x0).y(y0); }; area.lineY1 = function() { return arealine().x(x0).y(y1); }; area.lineX1 = function() { return arealine().x(x1).y(y0); }; area.defined = function(_) { return arguments.length ? (defined = typeof _ === "function" ? _ : constant(!!_), area) : defined; }; area.curve = function(_) { return arguments.length ? (curve = _, context != null && (output = curve(context)), area) : curve; }; area.context = function(_) { return arguments.length ? (_ == null ? context = output = null : output = curve(context = _), area) : context; }; return area; }; var descending = function(a, b) { return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN; }; var identity = function(d) { return d; }; var pie = function() { var value = identity, sortValues = descending, sort = null, startAngle = constant(0), endAngle = constant(tau), padAngle = constant(0); function pie(data) { var i, n = data.length, j, k, sum = 0, index = new Array(n), arcs = new Array(n), a0 = +startAngle.apply(this, arguments), da = Math.min(tau, Math.max(-tau, endAngle.apply(this, arguments) - a0)), a1, p = Math.min(Math.abs(da) / n, padAngle.apply(this, arguments)), pa = p * (da < 0 ? -1 : 1), v; for (i = 0; i < n; ++i) { if ((v = arcs[index[i] = i] = +value(data[i], i, data)) > 0) { sum += v; } } // Optionally sort the arcs by previously-computed values or by data. if (sortValues != null) index.sort(function(i, j) { return sortValues(arcs[i], arcs[j]); }); else if (sort != null) index.sort(function(i, j) { return sort(data[i], data[j]); }); // Compute the arcs! They are stored in the original data's order. for (i = 0, k = sum ? (da - n * pa) / sum : 0; i < n; ++i, a0 = a1) { j = index[i], v = arcs[j], a1 = a0 + (v > 0 ? v * k : 0) + pa, arcs[j] = { data: data[j], index: i, value: v, startAngle: a0, endAngle: a1, padAngle: p }; } return arcs; } pie.value = function(_) { return arguments.length ? (value = typeof _ === "function" ? _ : constant(+_), pie) : value; }; pie.sortValues = function(_) { return arguments.length ? (sortValues = _, sort = null, pie) : sortValues; }; pie.sort = function(_) { return arguments.length ? (sort = _, sortValues = null, pie) : sort; }; pie.startAngle = function(_) { return arguments.length ? (startAngle = typeof _ === "function" ? _ : constant(+_), pie) : startAngle; }; pie.endAngle = function(_) { return arguments.length ? (endAngle = typeof _ === "function" ? _ : constant(+_), pie) : endAngle; }; pie.padAngle = function(_) { return arguments.length ? (padAngle = typeof _ === "function" ? _ : constant(+_), pie) : padAngle; }; return pie; }; var curveRadialLinear = curveRadial(curveLinear); function Radial(curve) { this._curve = curve; } Radial.prototype = { areaStart: function() { this._curve.areaStart(); }, areaEnd: function() { this._curve.areaEnd(); }, lineStart: function() { this._curve.lineStart(); }, lineEnd: function() { this._curve.lineEnd(); }, point: function(a, r) { this._curve.point(r * Math.sin(a), r * -Math.cos(a)); } }; function curveRadial(curve) { function radial(context) { return new Radial(curve(context)); } radial._curve = curve; return radial; } function lineRadial(l) { var c = l.curve; l.angle = l.x, delete l.x; l.radius = l.y, delete l.y; l.curve = function(_) { return arguments.length ? c(curveRadial(_)) : c()._curve; }; return l; } var lineRadial$1 = function() { return lineRadial(line().curve(curveRadialLinear)); }; var areaRadial = function() { var a = area().curve(curveRadialLinear), c = a.curve, x0 = a.lineX0, x1 = a.lineX1, y0 = a.lineY0, y1 = a.lineY1; a.angle = a.x, delete a.x; a.startAngle = a.x0, delete a.x0; a.endAngle = a.x1, delete a.x1; a.radius = a.y, delete a.y; a.innerRadius = a.y0, delete a.y0; a.outerRadius = a.y1, delete a.y1; a.lineStartAngle = function() { return lineRadial(x0()); }, delete a.lineX0; a.lineEndAngle = function() { return lineRadial(x1()); }, delete a.lineX1; a.lineInnerRadius = function() { return lineRadial(y0()); }, delete a.lineY0; a.lineOuterRadius = function() { return lineRadial(y1()); }, delete a.lineY1; a.curve = function(_) { return arguments.length ? c(curveRadial(_)) : c()._curve; }; return a; }; var pointRadial = function(x, y) { return [(y = +y) * Math.cos(x -= Math.PI / 2), y * Math.sin(x)]; }; var slice = Array.prototype.slice; function linkSource(d) { return d.source; } function linkTarget(d) { return d.target; } function link(curve) { var source = linkSource, target = linkTarget, x$$1 = x, y$$1 = y, context = null; function link() { var buffer, argv = slice.call(arguments), s = source.apply(this, argv), t = target.apply(this, argv); if (!context) context = buffer = d3Path.path(); curve(context, +x$$1.apply(this, (argv[0] = s, argv)), +y$$1.apply(this, argv), +x$$1.apply(this, (argv[0] = t, argv)), +y$$1.apply(this, argv)); if (buffer) return context = null, buffer + "" || null; } link.source = function(_) { return arguments.length ? (source = _, link) : source; }; link.target = function(_) { return arguments.length ? (target = _, link) : target; }; link.x = function(_) { return arguments.length ? (x$$1 = typeof _ === "function" ? _ : constant(+_), link) : x$$1; }; link.y = function(_) { return arguments.length ? (y$$1 = typeof _ === "function" ? _ : constant(+_), link) : y$$1; }; link.context = function(_) { return arguments.length ? ((context = _ == null ? null : _), link) : context; }; return link; } function curveHorizontal(context, x0, y0, x1, y1) { context.moveTo(x0, y0); context.bezierCurveTo(x0 = (x0 + x1) / 2, y0, x0, y1, x1, y1); } function curveVertical(context, x0, y0, x1, y1) { context.moveTo(x0, y0); context.bezierCurveTo(x0, y0 = (y0 + y1) / 2, x1, y0, x1, y1); } function curveRadial$1(context, x0, y0, x1, y1) { var p0 = pointRadial(x0, y0), p1 = pointRadial(x0, y0 = (y0 + y1) / 2), p2 = pointRadial(x1, y0), p3 = pointRadial(x1, y1); context.moveTo(p0[0], p0[1]); context.bezierCurveTo(p1[0], p1[1], p2[0], p2[1], p3[0], p3[1]); } function linkHorizontal() { return link(curveHorizontal); } function linkVertical() { return link(curveVertical); } function linkRadial() { var l = link(curveRadial$1); l.angle = l.x, delete l.x; l.radius = l.y, delete l.y; return l; } var circle = { draw: function(context, size) { var r = Math.sqrt(size / pi); context.moveTo(r, 0); context.arc(0, 0, r, 0, tau); } }; var cross = { draw: function(context, size) { var r = Math.sqrt(size / 5) / 2; context.moveTo(-3 * r, -r); context.lineTo(-r, -r); context.lineTo(-r, -3 * r); context.lineTo(r, -3 * r); context.lineTo(r, -r); context.lineTo(3 * r, -r); context.lineTo(3 * r, r); context.lineTo(r, r); context.lineTo(r, 3 * r); context.lineTo(-r, 3 * r); context.lineTo(-r, r); context.lineTo(-3 * r, r); context.closePath(); } }; var tan30 = Math.sqrt(1 / 3); var tan30_2 = tan30 * 2; var diamond = { draw: function(context, size) { var y = Math.sqrt(size / tan30_2), x = y * tan30; context.moveTo(0, -y); context.lineTo(x, 0); context.lineTo(0, y); context.lineTo(-x, 0); context.closePath(); } }; var ka = 0.89081309152928522810; var kr = Math.sin(pi / 10) / Math.sin(7 * pi / 10); var kx = Math.sin(tau / 10) * kr; var ky = -Math.cos(tau / 10) * kr; var star = { draw: function(context, size) { var r = Math.sqrt(size * ka), x = kx * r, y = ky * r; context.moveTo(0, -r); context.lineTo(x, y); for (var i = 1; i < 5; ++i) { var a = tau * i / 5, c = Math.cos(a), s = Math.sin(a); context.lineTo(s * r, -c * r); context.lineTo(c * x - s * y, s * x + c * y); } context.closePath(); } }; var square = { draw: function(context, size) { var w = Math.sqrt(size), x = -w / 2; context.rect(x, x, w, w); } }; var sqrt3 = Math.sqrt(3); var triangle = { draw: function(context, size) { var y = -Math.sqrt(size / (sqrt3 * 3)); context.moveTo(0, y * 2); context.lineTo(-sqrt3 * y, -y); context.lineTo(sqrt3 * y, -y); context.closePath(); } }; var c = -0.5; var s = Math.sqrt(3) / 2; var k = 1 / Math.sqrt(12); var a = (k / 2 + 1) * 3; var wye = { draw: function(context, size) { var r = Math.sqrt(size / a), x0 = r / 2, y0 = r * k, x1 = x0, y1 = r * k + r, x2 = -x1, y2 = y1; context.moveTo(x0, y0); context.lineTo(x1, y1); context.lineTo(x2, y2); context.lineTo(c * x0 - s * y0, s * x0 + c * y0); context.lineTo(c * x1 - s * y1, s * x1 + c * y1); context.lineTo(c * x2 - s * y2, s * x2 + c * y2); context.lineTo(c * x0 + s * y0, c * y0 - s * x0); context.lineTo(c * x1 + s * y1, c * y1 - s * x1); context.lineTo(c * x2 + s * y2, c * y2 - s * x2); context.closePath(); } }; var symbols = [ circle, cross, diamond, square, star, triangle, wye ]; var symbol = function() { var type = constant(circle), size = constant(64), context = null; function symbol() { var buffer; if (!context) context = buffer = d3Path.path(); type.apply(this, arguments).draw(context, +size.apply(this, arguments)); if (buffer) return context = null, buffer + "" || null; } symbol.type = function(_) { return arguments.length ? (type = typeof _ === "function" ? _ : constant(_), symbol) : type; }; symbol.size = function(_) { return arguments.length ? (size = typeof _ === "function" ? _ : constant(+_), symbol) : size; }; symbol.context = function(_) { return arguments.length ? (context = _ == null ? null : _, symbol) : context; }; return symbol; }; var noop = function() {}; function point(that, x, y) { that._context.bezierCurveTo( (2 * that._x0 + that._x1) / 3, (2 * that._y0 + that._y1) / 3, (that._x0 + 2 * that._x1) / 3, (that._y0 + 2 * that._y1) / 3, (that._x0 + 4 * that._x1 + x) / 6, (that._y0 + 4 * that._y1 + y) / 6 ); } function Basis(context) { this._context = context; } Basis.prototype = { areaStart: function() { this._line = 0; }, areaEnd: function() { this._line = NaN; }, lineStart: function() { this._x0 = this._x1 = this._y0 = this._y1 = NaN; this._point = 0; }, lineEnd: function() { switch (this._point) { case 3: point(this, this._x1, this._y1); // proceed case 2: this._context.lineTo(this._x1, this._y1); break; } if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath(); this._line = 1 - this._line; }, point: function(x, y) { x = +x, y = +y; switch (this._point) { case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break; case 1: this._point = 2; break; case 2: this._point = 3; this._context.lineTo((5 * this._x0 + this._x1) / 6, (5 * this._y0 + this._y1) / 6); // proceed default: point(this, x, y); break; } this._x0 = this._x1, this._x1 = x; this._y0 = this._y1, this._y1 = y; } }; var basis = function(context) { return new Basis(context); }; function BasisClosed(context) { this._context = context; } BasisClosed.prototype = { areaStart: noop, areaEnd: noop, lineStart: function() { this._x0 = this._x1 = this._x2 = this._x3 = this._x4 = this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = NaN; this._point = 0; }, lineEnd: function() { switch (this._point) { case 1: { this._context.moveTo(this._x2, this._y2); this._context.closePath(); break; } case 2: { this._context.moveTo((this._x2 + 2 * this._x3) / 3, (this._y2 + 2 * this._y3) / 3); this._context.lineTo((this._x3 + 2 * this._x2) / 3, (this._y3 + 2 * this._y2) / 3); this._context.closePath(); break; } case 3: { this.point(this._x2, this._y2); this.point(this._x3, this._y3); this.point(this._x4, this._y4); break; } } }, point: function(x, y) { x = +x, y = +y; switch (this._point) { case 0: this._point = 1; this._x2 = x, this._y2 = y; break; case 1: this._point = 2; this._x3 = x, this._y3 = y; break; case 2: this._point = 3; this._x4 = x, this._y4 = y; this._context.moveTo((this._x0 + 4 * this._x1 + x) / 6, (this._y0 + 4 * this._y1 + y) / 6); break; default: point(this, x, y); break; } this._x0 = this._x1, this._x1 = x; this._y0 = this._y1, this._y1 = y; } }; var basisClosed = function(context) { return new BasisClosed(context); }; function BasisOpen(context) { this._context = context; } BasisOpen.prototype = { areaStart: function() { this._line = 0; }, areaEnd: function() { this._line = NaN; }, lineStart: function() { this._x0 = this._x1 = this._y0 = this._y1 = NaN; this._point = 0; }, lineEnd: function() { if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath(); this._line = 1 - this._line; }, point: function(x, y) { x = +x, y = +y; switch (this._point) { case 0: this._point = 1; break; case 1: this._point = 2; break; case 2: this._point = 3; var x0 = (this._x0 + 4 * this._x1 + x) / 6, y0 = (this._y0 + 4 * this._y1 + y) / 6; this._line ? this._context.lineTo(x0, y0) : this._context.moveTo(x0, y0); break; case 3: this._point = 4; // proceed default: point(this, x, y); break; } this._x0 = this._x1, this._x1 = x; this._y0 = this._y1, this._y1 = y; } }; var basisOpen = function(context) { return new BasisOpen(context); }; function Bundle(context, beta) { this._basis = new Basis(context); this._beta = beta; } Bundle.prototype = { lineStart: function() { this._x = []; this._y = []; this._basis.lineStart(); }, lineEnd: function() { var x = this._x, y = this._y, j = x.length - 1; if (j > 0) { var x0 = x[0], y0 = y[0], dx = x[j] - x0, dy = y[j] - y0, i = -1, t; while (++i <= j) { t = i / j; this._basis.point( this._beta * x[i] + (1 - this._beta) * (x0 + t * dx), this._beta * y[i] + (1 - this._beta) * (y0 + t * dy) ); } } this._x = this._y = null; this._basis.lineEnd(); }, point: function(x, y) { this._x.push(+x); this._y.push(+y); } }; var bundle = ((function custom(beta) { function bundle(context) { return beta === 1 ? new Basis(context) : new Bundle(context, beta); } bundle.beta = function(beta) { return custom(+beta); }; return bundle; }))(0.85); function point$1(that, x, y) { that._context.bezierCurveTo( that._x1 + that._k * (that._x2 - that._x0), that._y1 + that._k * (that._y2 - that._y0), that._x2 + that._k * (that._x1 - x), that._y2 + that._k * (that._y1 - y), that._x2, that._y2 ); } function Cardinal(context, tension) { this._context = context; this._k = (1 - tension) / 6; } Cardinal.prototype = { areaStart: function() { this._line = 0; }, areaEnd: function() { this._line = NaN; }, lineStart: function() { this._x0 = this._x1 = this._x2 = this._y0 = this._y1 = this._y2 = NaN; this._point = 0; }, lineEnd: function() { switch (this._point) { case 2: this._context.lineTo(this._x2, this._y2); break; case 3: point$1(this, this._x1, this._y1); break; } if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath(); this._line = 1 - this._line; }, point: function(x, y) { x = +x, y = +y; switch (this._point) { case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break; case 1: this._point = 2; this._x1 = x, this._y1 = y; break; case 2: this._point = 3; // proceed default: point$1(this, x, y); break; } this._x0 = this._x1, this._x1 = this._x2, this._x2 = x; this._y0 = this._y1, this._y1 = this._y2, this._y2 = y; } }; var cardinal = ((function custom(tension) { function cardinal(context) { return new Cardinal(context, tension); } cardinal.tension = function(tension) { return custom(+tension); }; return cardinal; }))(0); function CardinalClosed(context, tension) { this._context = context; this._k = (1 - tension) / 6; } CardinalClosed.prototype = { areaStart: noop, areaEnd: noop, lineStart: function() { this._x0 = this._x1 = this._x2 = this._x3 = this._x4 = this._x5 = this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = this._y5 = NaN; this._point = 0; }, lineEnd: function() { switch (this._point) { case 1: { this._context.moveTo(this._x3, this._y3); this._context.closePath(); break; } case 2: { this._context.lineTo(this._x3, this._y3); this._context.closePath(); break; } case 3: { this.point(this._x3, this._y3); this.point(this._x4, this._y4); this.point(this._x5, this._y5); break; } } }, point: function(x, y) { x = +x, y = +y; switch (this._point) { case 0: this._point = 1; this._x3 = x, this._y3 = y; break; case 1: this._point = 2; this._context.moveTo(this._x4 = x, this._y4 = y); break; case 2: this._point = 3; this._x5 = x, this._y5 = y; break; default: point$1(this, x, y); break; } this._x0 = this._x1, this._x1 = this._x2, this._x2 = x; this._y0 = this._y1, this._y1 = this._y2, this._y2 = y; } }; var cardinalClosed = ((function custom(tension) { function cardinal(context) { return new CardinalClosed(context, tension); } cardinal.tension = function(tension) { return custom(+tension); }; return cardinal; }))(0); function CardinalOpen(context, tension) { this._context = context; this._k = (1 - tension) / 6; } CardinalOpen.prototype = { areaStart: function() { this._line = 0; }, areaEnd: function() { this._line = NaN; }, lineStart: function() { this._x0 = this._x1 = this._x2 = this._y0 = this._y1 = this._y2 = NaN; this._point = 0; }, lineEnd: function() { if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath(); this._line = 1 - this._line; }, point: function(x, y) { x = +x, y = +y; switch (this._point) { case 0: this._point = 1; break; case 1: this._point = 2; break; case 2: this._point = 3; this._line ? this._context.lineTo(this._x2, this._y2) : this._context.moveTo(this._x2, this._y2); break; case 3: this._point = 4; // proceed default: point$1(this, x, y); break; } this._x0 = this._x1, this._x1 = this._x2, this._x2 = x; this._y0 = this._y1, this._y1 = this._y2, this._y2 = y; } }; var cardinalOpen = ((function custom(tension) { function cardinal(context) { return new CardinalOpen(context, tension); } cardinal.tension = function(tension) { return custom(+tension); }; return cardinal; }))(0); function point$2(that, x, y) { var x1 = that._x1, y1 = that._y1, x2 = that._x2, y2 = that._y2; if (that._l01_a > epsilon) { var a = 2 * that._l01_2a + 3 * that._l01_a * that._l12_a + that._l12_2a, n = 3 * that._l01_a * (that._l01_a + that._l12_a); x1 = (x1 * a - that._x0 * that._l12_2a + that._x2 * that._l01_2a) / n; y1 = (y1 * a - that._y0 * that._l12_2a + that._y2 * that._l01_2a) / n; } if (that._l23_a > epsilon) { var b = 2 * that._l23_2a + 3 * that._l23_a * that._l12_a + that._l12_2a, m = 3 * that._l23_a * (that._l23_a + that._l12_a); x2 = (x2 * b + that._x1 * that._l23_2a - x * that._l12_2a) / m; y2 = (y2 * b + that._y1 * that._l23_2a - y * that._l12_2a) / m; } that._context.bezierCurveTo(x1, y1, x2, y2, that._x2, that._y2); } function CatmullRom(context, alpha) { this._context = context; this._alpha = alpha; } CatmullRom.prototype = { areaStart: function() { this._line = 0; }, areaEnd: function() { this._line = NaN; }, lineStart: function() { this._x0 = this._x1 = this._x2 = this._y0 = this._y1 = this._y2 = NaN; this._l01_a = this._l12_a = this._l23_a = this._l01_2a = this._l12_2a = this._l23_2a = this._point = 0; }, lineEnd: function() { switch (this._point) { case 2: this._context.lineTo(this._x2, this._y2); break; case 3: this.point(this._x2, this._y2); break; } if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath(); this._line = 1 - this._line; }, point: function(x, y) { x = +x, y = +y; if (this._point) { var x23 = this._x2 - x, y23 = this._y2 - y; this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha)); } switch (this._point) { case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break; case 1: this._point = 2; break; case 2: this._point = 3; // proceed default: point$2(this, x, y); break; } this._l01_a = this._l12_a, this._l12_a = this._l23_a; this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a; this._x0 = this._x1, this._x1 = this._x2, this._x2 = x; this._y0 = this._y1, this._y1 = this._y2, this._y2 = y; } }; var catmullRom = ((function custom(alpha) { function catmullRom(context) { return alpha ? new CatmullRom(context, alpha) : new Cardinal(context, 0); } catmullRom.alpha = function(alpha) { return custom(+alpha); }; return catmullRom; }))(0.5); function CatmullRomClosed(context, alpha) { this._context = context; this._alpha = alpha; } CatmullRomClosed.prototype = { areaStart: noop, areaEnd: noop, lineStart: function() { this._x0 = this._x1 = this._x2 = this._x3 = this._x4 = this._x5 = this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = this._y5 = NaN; this._l01_a = this._l12_a = this._l23_a = this._l01_2a = this._l12_2a = this._l23_2a = this._point = 0; }, lineEnd: function() { switch (this._point) { case 1: { this._context.moveTo(this._x3, this._y3); this._context.closePath(); break; } case 2: { this._context.lineTo(this._x3, this._y3); this._context.closePath(); break; } case 3: { this.point(this._x3, this._y3); this.point(this._x4, this._y4); this.point(this._x5, this._y5); break; } } }, point: function(x, y) { x = +x, y = +y; if (this._point) { var x23 = this._x2 - x, y23 = this._y2 - y; this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha)); } switch (this._point) { case 0: this._point = 1; this._x3 = x, this._y3 = y; break; case 1: this._point = 2; this._context.moveTo(this._x4 = x, this._y4 = y); break; case 2: this._point = 3; this._x5 = x, this._y5 = y; break; default: point$2(this, x, y); break; } this._l01_a = this._l12_a, this._l12_a = this._l23_a; this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a; this._x0 = this._x1, this._x1 = this._x2, this._x2 = x; this._y0 = this._y1, this._y1 = this._y2, this._y2 = y; } }; var catmullRomClosed = ((function custom(alpha) { function catmullRom(context) { return alpha ? new CatmullRomClosed(context, alpha) : new CardinalClosed(context, 0); } catmullRom.alpha = function(alpha) { return custom(+alpha); }; return catmullRom; }))(0.5); function CatmullRomOpen(context, alpha) { this._context = context; this._alpha = alpha; } CatmullRomOpen.prototype = { areaStart: function() { this._line = 0; }, areaEnd: function() { this._line = NaN; }, lineStart: function() { this._x0 = this._x1 = this._x2 = this._y0 = this._y1 = this._y2 = NaN; this._l01_a = this._l12_a = this._l23_a = this._l01_2a = this._l12_2a = this._l23_2a = this._point = 0; }, lineEnd: function() { if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath(); this._line = 1 - this._line; }, point: function(x, y) { x = +x, y = +y; if (this._point) { var x23 = this._x2 - x, y23 = this._y2 - y; this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha)); } switch (this._point) { case 0: this._point = 1; break; case 1: this._point = 2; break; case 2: this._point = 3; this._line ? this._context.lineTo(this._x2, this._y2) : this._context.moveTo(this._x2, this._y2); break; case 3: this._point = 4; // proceed default: point$2(this, x, y); break; } this._l01_a = this._l12_a, this._l12_a = this._l23_a; this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a; this._x0 = this._x1, this._x1 = this._x2, this._x2 = x; this._y0 = this._y1, this._y1 = this._y2, this._y2 = y; } }; var catmullRomOpen = ((function custom(alpha) { function catmullRom(context) { return alpha ? new CatmullRomOpen(context, alpha) : new CardinalOpen(context, 0); } catmullRom.alpha = function(alpha) { return custom(+alpha); }; return catmullRom; }))(0.5); function LinearClosed(context) { this._context = context; } LinearClosed.prototype = { areaStart: noop, areaEnd: noop, lineStart: function() { this._point = 0; }, lineEnd: function() { if (this._point) this._context.closePath(); }, point: function(x, y) { x = +x, y = +y; if (this._point) this._context.lineTo(x, y); else this._point = 1, this._context.moveTo(x, y); } }; var linearClosed = function(context) { return new LinearClosed(context); }; function sign(x) { return x < 0 ? -1 : 1; } // Calculate the slopes of the tangents (Hermite-type interpolation) based on // the following paper: Steffen, M. 1990. A Simple Method for Monotonic // Interpolation in One Dimension. Astronomy and Astrophysics, Vol. 239, NO. // NOV(II), P. 443, 1990. function slope3(that, x2, y2) { var h0 = that._x1 - that._x0, h1 = x2 - that._x1, s0 = (that._y1 - that._y0) / (h0 || h1 < 0 && -0), s1 = (y2 - that._y1) / (h1 || h0 < 0 && -0), p = (s0 * h1 + s1 * h0) / (h0 + h1); return (sign(s0) + sign(s1)) * Math.min(Math.abs(s0), Math.abs(s1), 0.5 * Math.abs(p)) || 0; } // Calculate a one-sided slope. function slope2(that, t) { var h = that._x1 - that._x0; return h ? (3 * (that._y1 - that._y0) / h - t) / 2 : t; } // According to https://en.wikipedia.org/wiki/Cubic_Hermite_spline#Representations // "you can express cubic Hermite interpolation in terms of cubic Bézier curves // with respect to the four values p0, p0 + m0 / 3, p1 - m1 / 3, p1". function point$3(that, t0, t1) { var x0 = that._x0, y0 = that._y0, x1 = that._x1, y1 = that._y1, dx = (x1 - x0) / 3; that._context.bezierCurveTo(x0 + dx, y0 + dx * t0, x1 - dx, y1 - dx * t1, x1, y1); } function MonotoneX(context) { this._context = context; } MonotoneX.prototype = { areaStart: function() { this._line = 0; }, areaEnd: function() { this._line = NaN; }, lineStart: function() { this._x0 = this._x1 = this._y0 = this._y1 = this._t0 = NaN; this._point = 0; }, lineEnd: function() { switch (this._point) { case 2: this._context.lineTo(this._x1, this._y1); break; case 3: point$3(this, this._t0, slope2(this, this._t0)); break; } if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath(); this._line = 1 - this._line; }, point: function(x, y) { var t1 = NaN; x = +x, y = +y; if (x === this._x1 && y === this._y1) return; // Ignore coincident points. switch (this._point) { case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break; case 1: this._point = 2; break; case 2: this._point = 3; point$3(this, slope2(this, t1 = slope3(this, x, y)), t1); break; default: point$3(this, this._t0, t1 = slope3(this, x, y)); break; } this._x0 = this._x1, this._x1 = x; this._y0 = this._y1, this._y1 = y; this._t0 = t1; } }; function MonotoneY(context) { this._context = new ReflectContext(context); } (MonotoneY.prototype = Object.create(MonotoneX.prototype)).point = function(x, y) { MonotoneX.prototype.point.call(this, y, x); }; function ReflectContext(context) { this._context = context; } ReflectContext.prototype = { moveTo: function(x, y) { this._context.moveTo(y, x); }, closePath: function() { this._context.closePath(); }, lineTo: function(x, y) { this._context.lineTo(y, x); }, bezierCurveTo: function(x1, y1, x2, y2, x, y) { this._context.bezierCurveTo(y1, x1, y2, x2, y, x); } }; function monotoneX(context) { return new MonotoneX(context); } function monotoneY(context) { return new MonotoneY(context); } function Natural(context) { this._context = context; } Natural.prototype = { areaStart: function() { this._line = 0; }, areaEnd: function() { this._line = NaN; }, lineStart: function() { this._x = []; this._y = []; }, lineEnd: function() { var x = this._x, y = this._y, n = x.length; if (n) { this._line ? this._context.lineTo(x[0], y[0]) : this._context.moveTo(x[0], y[0]); if (n === 2) { this._context.lineTo(x[1], y[1]); } else { var px = controlPoints(x), py = controlPoints(y); for (var i0 = 0, i1 = 1; i1 < n; ++i0, ++i1) { this._context.bezierCurveTo(px[0][i0], py[0][i0], px[1][i0], py[1][i0], x[i1], y[i1]); } } } if (this._line || (this._line !== 0 && n === 1)) this._context.closePath(); this._line = 1 - this._line; this._x = this._y = null; }, point: function(x, y) { this._x.push(+x); this._y.push(+y); } }; // See https://www.particleincell.com/2012/bezier-splines/ for derivation. function controlPoints(x) { var i, n = x.length - 1, m, a = new Array(n), b = new Array(n), r = new Array(n); a[0] = 0, b[0] = 2, r[0] = x[0] + 2 * x[1]; for (i = 1; i < n - 1; ++i) a[i] = 1, b[i] = 4, r[i] = 4 * x[i] + 2 * x[i + 1]; a[n - 1] = 2, b[n - 1] = 7, r[n - 1] = 8 * x[n - 1] + x[n]; for (i = 1; i < n; ++i) m = a[i] / b[i - 1], b[i] -= m, r[i] -= m * r[i - 1]; a[n - 1] = r[n - 1] / b[n - 1]; for (i = n - 2; i >= 0; --i) a[i] = (r[i] - a[i + 1]) / b[i]; b[n - 1] = (x[n] + a[n - 1]) / 2; for (i = 0; i < n - 1; ++i) b[i] = 2 * x[i + 1] - a[i + 1]; return [a, b]; } var natural = function(context) { return new Natural(context); }; function Step(context, t) { this._context = context; this._t = t; } Step.prototype = { areaStart: function() { this._line = 0; }, areaEnd: function() { this._line = NaN; }, lineStart: function() { this._x = this._y = NaN; this._point = 0; }, lineEnd: function() { if (0 < this._t && this._t < 1 && this._point === 2) this._context.lineTo(this._x, this._y); if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath(); if (this._line >= 0) this._t = 1 - this._t, this._line = 1 - this._line; }, point: function(x, y) { x = +x, y = +y; switch (this._point) { case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break; case 1: this._point = 2; // proceed default: { if (this._t <= 0) { this._context.lineTo(this._x, y); this._context.lineTo(x, y); } else { var x1 = this._x * (1 - this._t) + x * this._t; this._context.lineTo(x1, this._y); this._context.lineTo(x1, y); } break; } } this._x = x, this._y = y; } }; var step = function(context) { return new Step(context, 0.5); }; function stepBefore(context) { return new Step(context, 0); } function stepAfter(context) { return new Step(context, 1); } var none = function(series, order) { if (!((n = series.length) > 1)) return; for (var i = 1, j, s0, s1 = series[order[0]], n, m = s1.length; i < n; ++i) { s0 = s1, s1 = series[order[i]]; for (j = 0; j < m; ++j) { s1[j][1] += s1[j][0] = isNaN(s0[j][1]) ? s0[j][0] : s0[j][1]; } } }; var none$1 = function(series) { var n = series.length, o = new Array(n); while (--n >= 0) o[n] = n; return o; }; function stackValue(d, key) { return d[key]; } var stack = function() { var keys = constant([]), order = none$1, offset = none, value = stackValue; function stack(data) { var kz = keys.apply(this, arguments), i, m = data.length, n = kz.length, sz = new Array(n), oz; for (i = 0; i < n; ++i) { for (var ki = kz[i], si = sz[i] = new Array(m), j = 0, sij; j < m; ++j) { si[j] = sij = [0, +value(data[j], ki, j, data)]; sij.data = data[j]; } si.key = ki; } for (i = 0, oz = order(sz); i < n; ++i) { sz[oz[i]].index = i; } offset(sz, oz); return sz; } stack.keys = function(_) { return arguments.length ? (keys = typeof _ === "function" ? _ : constant(slice.call(_)), stack) : keys; }; stack.value = function(_) { return arguments.length ? (value = typeof _ === "function" ? _ : constant(+_), stack) : value; }; stack.order = function(_) { return arguments.length ? (order = _ == null ? none$1 : typeof _ === "function" ? _ : constant(slice.call(_)), stack) : order; }; stack.offset = function(_) { return arguments.length ? (offset = _ == null ? none : _, stack) : offset; }; return stack; }; var expand = function(series, order) { if (!((n = series.length) > 0)) return; for (var i, n, j = 0, m = series[0].length, y; j < m; ++j) { for (y = i = 0; i < n; ++i) y += series[i][j][1] || 0; if (y) for (i = 0; i < n; ++i) series[i][j][1] /= y; } none(series, order); }; var diverging = function(series, order) { if (!((n = series.length) > 1)) return; for (var i, j = 0, d, dy, yp, yn, n, m = series[order[0]].length; j < m; ++j) { for (yp = yn = 0, i = 0; i < n; ++i) { if ((dy = (d = series[order[i]][j])[1] - d[0]) >= 0) { d[0] = yp, d[1] = yp += dy; } else if (dy < 0) { d[1] = yn, d[0] = yn += dy; } else { d[0] = yp; } } } }; var silhouette = function(series, order) { if (!((n = series.length) > 0)) return; for (var j = 0, s0 = series[order[0]], n, m = s0.length; j < m; ++j) { for (var i = 0, y = 0; i < n; ++i) y += series[i][j][1] || 0; s0[j][1] += s0[j][0] = -y / 2; } none(series, order); }; var wiggle = function(series, order) { if (!((n = series.length) > 0) || !((m = (s0 = series[order[0]]).length) > 0)) return; for (var y = 0, j = 1, s0, m, n; j < m; ++j) { for (var i = 0, s1 = 0, s2 = 0; i < n; ++i) { var si = series[order[i]], sij0 = si[j][1] || 0, sij1 = si[j - 1][1] || 0, s3 = (sij0 - sij1) / 2; for (var k = 0; k < i; ++k) { var sk = series[order[k]], skj0 = sk[j][1] || 0, skj1 = sk[j - 1][1] || 0; s3 += skj0 - skj1; } s1 += sij0, s2 += s3 * sij0; } s0[j - 1][1] += s0[j - 1][0] = y; if (s1) y -= s2 / s1; } s0[j - 1][1] += s0[j - 1][0] = y; none(series, order); }; var ascending = function(series) { var sums = series.map(sum); return none$1(series).sort(function(a, b) { return sums[a] - sums[b]; }); }; function sum(series) { var s = 0, i = -1, n = series.length, v; while (++i < n) if (v = +series[i][1]) s += v; return s; } var descending$1 = function(series) { return ascending(series).reverse(); }; var insideOut = function(series) { var n = series.length, i, j, sums = series.map(sum), order = none$1(series).sort(function(a, b) { return sums[b] - sums[a]; }), top = 0, bottom = 0, tops = [], bottoms = []; for (i = 0; i < n; ++i) { j = order[i]; if (top < bottom) { top += sums[j]; tops.push(j); } else { bottom += sums[j]; bottoms.push(j); } } return bottoms.reverse().concat(tops); }; var reverse = function(series) { return none$1(series).reverse(); }; exports.arc = arc; exports.area = area; exports.line = line; exports.pie = pie; exports.areaRadial = areaRadial; exports.radialArea = areaRadial; exports.lineRadial = lineRadial$1; exports.radialLine = lineRadial$1; exports.pointRadial = pointRadial; exports.linkHorizontal = linkHorizontal; exports.linkVertical = linkVertical; exports.linkRadial = linkRadial; exports.symbol = symbol; exports.symbols = symbols; exports.symbolCircle = circle; exports.symbolCross = cross; exports.symbolDiamond = diamond; exports.symbolSquare = square; exports.symbolStar = star; exports.symbolTriangle = triangle; exports.symbolWye = wye; exports.curveBasisClosed = basisClosed; exports.curveBasisOpen = basisOpen; exports.curveBasis = basis; exports.curveBundle = bundle; exports.curveCardinalClosed = cardinalClosed; exports.curveCardinalOpen = cardinalOpen; exports.curveCardinal = cardinal; exports.curveCatmullRomClosed = catmullRomClosed; exports.curveCatmullRomOpen = catmullRomOpen; exports.curveCatmullRom = catmullRom; exports.curveLinearClosed = linearClosed; exports.curveLinear = curveLinear; exports.curveMonotoneX = monotoneX; exports.curveMonotoneY = monotoneY; exports.curveNatural = natural; exports.curveStep = step; exports.curveStepAfter = stepAfter; exports.curveStepBefore = stepBefore; exports.stack = stack; exports.stackOffsetExpand = expand; exports.stackOffsetDiverging = diverging; exports.stackOffsetNone = none; exports.stackOffsetSilhouette = silhouette; exports.stackOffsetWiggle = wiggle; exports.stackOrderAscending = ascending; exports.stackOrderDescending = descending$1; exports.stackOrderInsideOut = insideOut; exports.stackOrderNone = none$1; exports.stackOrderReverse = reverse; Object.defineProperty(exports, '__esModule', { value: true }); }))); },{"d3-path":30}],39:[function(require,module,exports){ // https://d3js.org/d3-time-format/ Version 2.0.5. Copyright 2017 Mike Bostock. (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('d3-time')) : typeof define === 'function' && define.amd ? define(['exports', 'd3-time'], factory) : (factory((global.d3 = global.d3 || {}),global.d3)); }(this, (function (exports,d3Time) { 'use strict'; function localDate(d) { if (0 <= d.y && d.y < 100) { var date = new Date(-1, d.m, d.d, d.H, d.M, d.S, d.L); date.setFullYear(d.y); return date; } return new Date(d.y, d.m, d.d, d.H, d.M, d.S, d.L); } function utcDate(d) { if (0 <= d.y && d.y < 100) { var date = new Date(Date.UTC(-1, d.m, d.d, d.H, d.M, d.S, d.L)); date.setUTCFullYear(d.y); return date; } return new Date(Date.UTC(d.y, d.m, d.d, d.H, d.M, d.S, d.L)); } function newYear(y) { return {y: y, m: 0, d: 1, H: 0, M: 0, S: 0, L: 0}; } function formatLocale(locale) { var locale_dateTime = locale.dateTime, locale_date = locale.date, locale_time = locale.time, locale_periods = locale.periods, locale_weekdays = locale.days, locale_shortWeekdays = locale.shortDays, locale_months = locale.months, locale_shortMonths = locale.shortMonths; var periodRe = formatRe(locale_periods), periodLookup = formatLookup(locale_periods), weekdayRe = formatRe(locale_weekdays), weekdayLookup = formatLookup(locale_weekdays), shortWeekdayRe = formatRe(locale_shortWeekdays), shortWeekdayLookup = formatLookup(locale_shortWeekdays), monthRe = formatRe(locale_months), monthLookup = formatLookup(locale_months), shortMonthRe = formatRe(locale_shortMonths), shortMonthLookup = formatLookup(locale_shortMonths); var formats = { "a": formatShortWeekday, "A": formatWeekday, "b": formatShortMonth, "B": formatMonth, "c": null, "d": formatDayOfMonth, "e": formatDayOfMonth, "H": formatHour24, "I": formatHour12, "j": formatDayOfYear, "L": formatMilliseconds, "m": formatMonthNumber, "M": formatMinutes, "p": formatPeriod, "S": formatSeconds, "U": formatWeekNumberSunday, "w": formatWeekdayNumber, "W": formatWeekNumberMonday, "x": null, "X": null, "y": formatYear, "Y": formatFullYear, "Z": formatZone, "%": formatLiteralPercent }; var utcFormats = { "a": formatUTCShortWeekday, "A": formatUTCWeekday, "b": formatUTCShortMonth, "B": formatUTCMonth, "c": null, "d": formatUTCDayOfMonth, "e": formatUTCDayOfMonth, "H": formatUTCHour24, "I": formatUTCHour12, "j": formatUTCDayOfYear, "L": formatUTCMilliseconds, "m": formatUTCMonthNumber, "M": formatUTCMinutes, "p": formatUTCPeriod, "S": formatUTCSeconds, "U": formatUTCWeekNumberSunday, "w": formatUTCWeekdayNumber, "W": formatUTCWeekNumberMonday, "x": null, "X": null, "y": formatUTCYear, "Y": formatUTCFullYear, "Z": formatUTCZone, "%": formatLiteralPercent }; var parses = { "a": parseShortWeekday, "A": parseWeekday, "b": parseShortMonth, "B": parseMonth, "c": parseLocaleDateTime, "d": parseDayOfMonth, "e": parseDayOfMonth, "H": parseHour24, "I": parseHour24, "j": parseDayOfYear, "L": parseMilliseconds, "m": parseMonthNumber, "M": parseMinutes, "p": parsePeriod, "S": parseSeconds, "U": parseWeekNumberSunday, "w": parseWeekdayNumber, "W": parseWeekNumberMonday, "x": parseLocaleDate, "X": parseLocaleTime, "y": parseYear, "Y": parseFullYear, "Z": parseZone, "%": parseLiteralPercent }; // These recursive directive definitions must be deferred. formats.x = newFormat(locale_date, formats); formats.X = newFormat(locale_time, formats); formats.c = newFormat(locale_dateTime, formats); utcFormats.x = newFormat(locale_date, utcFormats); utcFormats.X = newFormat(locale_time, utcFormats); utcFormats.c = newFormat(locale_dateTime, utcFormats); function newFormat(specifier, formats) { return function(date) { var string = [], i = -1, j = 0, n = specifier.length, c, pad, format; if (!(date instanceof Date)) date = new Date(+date); while (++i < n) { if (specifier.charCodeAt(i) === 37) { string.push(specifier.slice(j, i)); if ((pad = pads[c = specifier.charAt(++i)]) != null) c = specifier.charAt(++i); else pad = c === "e" ? " " : "0"; if (format = formats[c]) c = format(date, pad); string.push(c); j = i + 1; } } string.push(specifier.slice(j, i)); return string.join(""); }; } function newParse(specifier, newDate) { return function(string) { var d = newYear(1900), i = parseSpecifier(d, specifier, string += "", 0); if (i != string.length) return null; // The am-pm flag is 0 for AM, and 1 for PM. if ("p" in d) d.H = d.H % 12 + d.p * 12; // Convert day-of-week and week-of-year to day-of-year. if ("W" in d || "U" in d) { if (!("w" in d)) d.w = "W" in d ? 1 : 0; var day = "Z" in d ? utcDate(newYear(d.y)).getUTCDay() : newDate(newYear(d.y)).getDay(); d.m = 0; d.d = "W" in d ? (d.w + 6) % 7 + d.W * 7 - (day + 5) % 7 : d.w + d.U * 7 - (day + 6) % 7; } // If a time zone is specified, all fields are interpreted as UTC and then // offset according to the specified time zone. if ("Z" in d) { d.H += d.Z / 100 | 0; d.M += d.Z % 100; return utcDate(d); } // Otherwise, all fields are in local time. return newDate(d); }; } function parseSpecifier(d, specifier, string, j) { var i = 0, n = specifier.length, m = string.length, c, parse; while (i < n) { if (j >= m) return -1; c = specifier.charCodeAt(i++); if (c === 37) { c = specifier.charAt(i++); parse = parses[c in pads ? specifier.charAt(i++) : c]; if (!parse || ((j = parse(d, string, j)) < 0)) return -1; } else if (c != string.charCodeAt(j++)) { return -1; } } return j; } function parsePeriod(d, string, i) { var n = periodRe.exec(string.slice(i)); return n ? (d.p = periodLookup[n[0].toLowerCase()], i + n[0].length) : -1; } function parseShortWeekday(d, string, i) { var n = shortWeekdayRe.exec(string.slice(i)); return n ? (d.w = shortWeekdayLookup[n[0].toLowerCase()], i + n[0].length) : -1; } function parseWeekday(d, string, i) { var n = weekdayRe.exec(string.slice(i)); return n ? (d.w = weekdayLookup[n[0].toLowerCase()], i + n[0].length) : -1; } function parseShortMonth(d, string, i) { var n = shortMonthRe.exec(string.slice(i)); return n ? (d.m = shortMonthLookup[n[0].toLowerCase()], i + n[0].length) : -1; } function parseMonth(d, string, i) { var n = monthRe.exec(string.slice(i)); return n ? (d.m = monthLookup[n[0].toLowerCase()], i + n[0].length) : -1; } function parseLocaleDateTime(d, string, i) { return parseSpecifier(d, locale_dateTime, string, i); } function parseLocaleDate(d, string, i) { return parseSpecifier(d, locale_date, string, i); } function parseLocaleTime(d, string, i) { return parseSpecifier(d, locale_time, string, i); } function formatShortWeekday(d) { return locale_shortWeekdays[d.getDay()]; } function formatWeekday(d) { return locale_weekdays[d.getDay()]; } function formatShortMonth(d) { return locale_shortMonths[d.getMonth()]; } function formatMonth(d) { return locale_months[d.getMonth()]; } function formatPeriod(d) { return locale_periods[+(d.getHours() >= 12)]; } function formatUTCShortWeekday(d) { return locale_shortWeekdays[d.getUTCDay()]; } function formatUTCWeekday(d) { return locale_weekdays[d.getUTCDay()]; } function formatUTCShortMonth(d) { return locale_shortMonths[d.getUTCMonth()]; } function formatUTCMonth(d) { return locale_months[d.getUTCMonth()]; } function formatUTCPeriod(d) { return locale_periods[+(d.getUTCHours() >= 12)]; } return { format: function(specifier) { var f = newFormat(specifier += "", formats); f.toString = function() { return specifier; }; return f; }, parse: function(specifier) { var p = newParse(specifier += "", localDate); p.toString = function() { return specifier; }; return p; }, utcFormat: function(specifier) { var f = newFormat(specifier += "", utcFormats); f.toString = function() { return specifier; }; return f; }, utcParse: function(specifier) { var p = newParse(specifier, utcDate); p.toString = function() { return specifier; }; return p; } }; } var pads = {"-": "", "_": " ", "0": "0"}; var numberRe = /^\s*\d+/; var percentRe = /^%/; var requoteRe = /[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g; function pad(value, fill, width) { var sign = value < 0 ? "-" : "", string = (sign ? -value : value) + "", length = string.length; return sign + (length < width ? new Array(width - length + 1).join(fill) + string : string); } function requote(s) { return s.replace(requoteRe, "\\$&"); } function formatRe(names) { return new RegExp("^(?:" + names.map(requote).join("|") + ")", "i"); } function formatLookup(names) { var map = {}, i = -1, n = names.length; while (++i < n) map[names[i].toLowerCase()] = i; return map; } function parseWeekdayNumber(d, string, i) { var n = numberRe.exec(string.slice(i, i + 1)); return n ? (d.w = +n[0], i + n[0].length) : -1; } function parseWeekNumberSunday(d, string, i) { var n = numberRe.exec(string.slice(i)); return n ? (d.U = +n[0], i + n[0].length) : -1; } function parseWeekNumberMonday(d, string, i) { var n = numberRe.exec(string.slice(i)); return n ? (d.W = +n[0], i + n[0].length) : -1; } function parseFullYear(d, string, i) { var n = numberRe.exec(string.slice(i, i + 4)); return n ? (d.y = +n[0], i + n[0].length) : -1; } function parseYear(d, string, i) { var n = numberRe.exec(string.slice(i, i + 2)); return n ? (d.y = +n[0] + (+n[0] > 68 ? 1900 : 2000), i + n[0].length) : -1; } function parseZone(d, string, i) { var n = /^(Z)|([+-]\d\d)(?:\:?(\d\d))?/.exec(string.slice(i, i + 6)); return n ? (d.Z = n[1] ? 0 : -(n[2] + (n[3] || "00")), i + n[0].length) : -1; } function parseMonthNumber(d, string, i) { var n = numberRe.exec(string.slice(i, i + 2)); return n ? (d.m = n[0] - 1, i + n[0].length) : -1; } function parseDayOfMonth(d, string, i) { var n = numberRe.exec(string.slice(i, i + 2)); return n ? (d.d = +n[0], i + n[0].length) : -1; } function parseDayOfYear(d, string, i) { var n = numberRe.exec(string.slice(i, i + 3)); return n ? (d.m = 0, d.d = +n[0], i + n[0].length) : -1; } function parseHour24(d, string, i) { var n = numberRe.exec(string.slice(i, i + 2)); return n ? (d.H = +n[0], i + n[0].length) : -1; } function parseMinutes(d, string, i) { var n = numberRe.exec(string.slice(i, i + 2)); return n ? (d.M = +n[0], i + n[0].length) : -1; } function parseSeconds(d, string, i) { var n = numberRe.exec(string.slice(i, i + 2)); return n ? (d.S = +n[0], i + n[0].length) : -1; } function parseMilliseconds(d, string, i) { var n = numberRe.exec(string.slice(i, i + 3)); return n ? (d.L = +n[0], i + n[0].length) : -1; } function parseLiteralPercent(d, string, i) { var n = percentRe.exec(string.slice(i, i + 1)); return n ? i + n[0].length : -1; } function formatDayOfMonth(d, p) { return pad(d.getDate(), p, 2); } function formatHour24(d, p) { return pad(d.getHours(), p, 2); } function formatHour12(d, p) { return pad(d.getHours() % 12 || 12, p, 2); } function formatDayOfYear(d, p) { return pad(1 + d3Time.timeDay.count(d3Time.timeYear(d), d), p, 3); } function formatMilliseconds(d, p) { return pad(d.getMilliseconds(), p, 3); } function formatMonthNumber(d, p) { return pad(d.getMonth() + 1, p, 2); } function formatMinutes(d, p) { return pad(d.getMinutes(), p, 2); } function formatSeconds(d, p) { return pad(d.getSeconds(), p, 2); } function formatWeekNumberSunday(d, p) { return pad(d3Time.timeSunday.count(d3Time.timeYear(d), d), p, 2); } function formatWeekdayNumber(d) { return d.getDay(); } function formatWeekNumberMonday(d, p) { return pad(d3Time.timeMonday.count(d3Time.timeYear(d), d), p, 2); } function formatYear(d, p) { return pad(d.getFullYear() % 100, p, 2); } function formatFullYear(d, p) { return pad(d.getFullYear() % 10000, p, 4); } function formatZone(d) { var z = d.getTimezoneOffset(); return (z > 0 ? "-" : (z *= -1, "+")) + pad(z / 60 | 0, "0", 2) + pad(z % 60, "0", 2); } function formatUTCDayOfMonth(d, p) { return pad(d.getUTCDate(), p, 2); } function formatUTCHour24(d, p) { return pad(d.getUTCHours(), p, 2); } function formatUTCHour12(d, p) { return pad(d.getUTCHours() % 12 || 12, p, 2); } function formatUTCDayOfYear(d, p) { return pad(1 + d3Time.utcDay.count(d3Time.utcYear(d), d), p, 3); } function formatUTCMilliseconds(d, p) { return pad(d.getUTCMilliseconds(), p, 3); } function formatUTCMonthNumber(d, p) { return pad(d.getUTCMonth() + 1, p, 2); } function formatUTCMinutes(d, p) { return pad(d.getUTCMinutes(), p, 2); } function formatUTCSeconds(d, p) { return pad(d.getUTCSeconds(), p, 2); } function formatUTCWeekNumberSunday(d, p) { return pad(d3Time.utcSunday.count(d3Time.utcYear(d), d), p, 2); } function formatUTCWeekdayNumber(d) { return d.getUTCDay(); } function formatUTCWeekNumberMonday(d, p) { return pad(d3Time.utcMonday.count(d3Time.utcYear(d), d), p, 2); } function formatUTCYear(d, p) { return pad(d.getUTCFullYear() % 100, p, 2); } function formatUTCFullYear(d, p) { return pad(d.getUTCFullYear() % 10000, p, 4); } function formatUTCZone() { return "+0000"; } function formatLiteralPercent() { return "%"; } var locale$1; defaultLocale({ dateTime: "%x, %X", date: "%-m/%-d/%Y", time: "%-I:%M:%S %p", periods: ["AM", "PM"], days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], shortDays: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"], shortMonths: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"] }); function defaultLocale(definition) { locale$1 = formatLocale(definition); exports.timeFormat = locale$1.format; exports.timeParse = locale$1.parse; exports.utcFormat = locale$1.utcFormat; exports.utcParse = locale$1.utcParse; return locale$1; } var isoSpecifier = "%Y-%m-%dT%H:%M:%S.%LZ"; function formatIsoNative(date) { return date.toISOString(); } var formatIso = Date.prototype.toISOString ? formatIsoNative : exports.utcFormat(isoSpecifier); function parseIsoNative(string) { var date = new Date(string); return isNaN(date) ? null : date; } var parseIso = +new Date("2000-01-01T00:00:00.000Z") ? parseIsoNative : exports.utcParse(isoSpecifier); exports.timeFormatDefaultLocale = defaultLocale; exports.timeFormatLocale = formatLocale; exports.isoFormat = formatIso; exports.isoParse = parseIso; Object.defineProperty(exports, '__esModule', { value: true }); }))); },{"d3-time":40}],40:[function(require,module,exports){ // https://d3js.org/d3-time/ Version 1.0.7. Copyright 2017 Mike Bostock. (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (factory((global.d3 = global.d3 || {}))); }(this, (function (exports) { 'use strict'; var t0 = new Date; var t1 = new Date; function newInterval(floori, offseti, count, field) { function interval(date) { return floori(date = new Date(+date)), date; } interval.floor = interval; interval.ceil = function(date) { return floori(date = new Date(date - 1)), offseti(date, 1), floori(date), date; }; interval.round = function(date) { var d0 = interval(date), d1 = interval.ceil(date); return date - d0 < d1 - date ? d0 : d1; }; interval.offset = function(date, step) { return offseti(date = new Date(+date), step == null ? 1 : Math.floor(step)), date; }; interval.range = function(start, stop, step) { var range = []; start = interval.ceil(start); step = step == null ? 1 : Math.floor(step); if (!(start < stop) || !(step > 0)) return range; // also handles Invalid Date do range.push(new Date(+start)); while (offseti(start, step), floori(start), start < stop) return range; }; interval.filter = function(test) { return newInterval(function(date) { if (date >= date) while (floori(date), !test(date)) date.setTime(date - 1); }, function(date, step) { if (date >= date) { if (step < 0) while (++step <= 0) { while (offseti(date, -1), !test(date)) {} // eslint-disable-line no-empty } else while (--step >= 0) { while (offseti(date, +1), !test(date)) {} // eslint-disable-line no-empty } } }); }; if (count) { interval.count = function(start, end) { t0.setTime(+start), t1.setTime(+end); floori(t0), floori(t1); return Math.floor(count(t0, t1)); }; interval.every = function(step) { step = Math.floor(step); return !isFinite(step) || !(step > 0) ? null : !(step > 1) ? interval : interval.filter(field ? function(d) { return field(d) % step === 0; } : function(d) { return interval.count(0, d) % step === 0; }); }; } return interval; } var millisecond = newInterval(function() { // noop }, function(date, step) { date.setTime(+date + step); }, function(start, end) { return end - start; }); // An optimized implementation for this simple case. millisecond.every = function(k) { k = Math.floor(k); if (!isFinite(k) || !(k > 0)) return null; if (!(k > 1)) return millisecond; return newInterval(function(date) { date.setTime(Math.floor(date / k) * k); }, function(date, step) { date.setTime(+date + step * k); }, function(start, end) { return (end - start) / k; }); }; var milliseconds = millisecond.range; var durationSecond = 1e3; var durationMinute = 6e4; var durationHour = 36e5; var durationDay = 864e5; var durationWeek = 6048e5; var second = newInterval(function(date) { date.setTime(Math.floor(date / durationSecond) * durationSecond); }, function(date, step) { date.setTime(+date + step * durationSecond); }, function(start, end) { return (end - start) / durationSecond; }, function(date) { return date.getUTCSeconds(); }); var seconds = second.range; var minute = newInterval(function(date) { date.setTime(Math.floor(date / durationMinute) * durationMinute); }, function(date, step) { date.setTime(+date + step * durationMinute); }, function(start, end) { return (end - start) / durationMinute; }, function(date) { return date.getMinutes(); }); var minutes = minute.range; var hour = newInterval(function(date) { var offset = date.getTimezoneOffset() * durationMinute % durationHour; if (offset < 0) offset += durationHour; date.setTime(Math.floor((+date - offset) / durationHour) * durationHour + offset); }, function(date, step) { date.setTime(+date + step * durationHour); }, function(start, end) { return (end - start) / durationHour; }, function(date) { return date.getHours(); }); var hours = hour.range; var day = newInterval(function(date) { date.setHours(0, 0, 0, 0); }, function(date, step) { date.setDate(date.getDate() + step); }, function(start, end) { return (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * durationMinute) / durationDay; }, function(date) { return date.getDate() - 1; }); var days = day.range; function weekday(i) { return newInterval(function(date) { date.setDate(date.getDate() - (date.getDay() + 7 - i) % 7); date.setHours(0, 0, 0, 0); }, function(date, step) { date.setDate(date.getDate() + step * 7); }, function(start, end) { return (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * durationMinute) / durationWeek; }); } var sunday = weekday(0); var monday = weekday(1); var tuesday = weekday(2); var wednesday = weekday(3); var thursday = weekday(4); var friday = weekday(5); var saturday = weekday(6); var sundays = sunday.range; var mondays = monday.range; var tuesdays = tuesday.range; var wednesdays = wednesday.range; var thursdays = thursday.range; var fridays = friday.range; var saturdays = saturday.range; var month = newInterval(function(date) { date.setDate(1); date.setHours(0, 0, 0, 0); }, function(date, step) { date.setMonth(date.getMonth() + step); }, function(start, end) { return end.getMonth() - start.getMonth() + (end.getFullYear() - start.getFullYear()) * 12; }, function(date) { return date.getMonth(); }); var months = month.range; var year = newInterval(function(date) { date.setMonth(0, 1); date.setHours(0, 0, 0, 0); }, function(date, step) { date.setFullYear(date.getFullYear() + step); }, function(start, end) { return end.getFullYear() - start.getFullYear(); }, function(date) { return date.getFullYear(); }); // An optimized implementation for this simple case. year.every = function(k) { return !isFinite(k = Math.floor(k)) || !(k > 0) ? null : newInterval(function(date) { date.setFullYear(Math.floor(date.getFullYear() / k) * k); date.setMonth(0, 1); date.setHours(0, 0, 0, 0); }, function(date, step) { date.setFullYear(date.getFullYear() + step * k); }); }; var years = year.range; var utcMinute = newInterval(function(date) { date.setUTCSeconds(0, 0); }, function(date, step) { date.setTime(+date + step * durationMinute); }, function(start, end) { return (end - start) / durationMinute; }, function(date) { return date.getUTCMinutes(); }); var utcMinutes = utcMinute.range; var utcHour = newInterval(function(date) { date.setUTCMinutes(0, 0, 0); }, function(date, step) { date.setTime(+date + step * durationHour); }, function(start, end) { return (end - start) / durationHour; }, function(date) { return date.getUTCHours(); }); var utcHours = utcHour.range; var utcDay = newInterval(function(date) { date.setUTCHours(0, 0, 0, 0); }, function(date, step) { date.setUTCDate(date.getUTCDate() + step); }, function(start, end) { return (end - start) / durationDay; }, function(date) { return date.getUTCDate() - 1; }); var utcDays = utcDay.range; function utcWeekday(i) { return newInterval(function(date) { date.setUTCDate(date.getUTCDate() - (date.getUTCDay() + 7 - i) % 7); date.setUTCHours(0, 0, 0, 0); }, function(date, step) { date.setUTCDate(date.getUTCDate() + step * 7); }, function(start, end) { return (end - start) / durationWeek; }); } var utcSunday = utcWeekday(0); var utcMonday = utcWeekday(1); var utcTuesday = utcWeekday(2); var utcWednesday = utcWeekday(3); var utcThursday = utcWeekday(4); var utcFriday = utcWeekday(5); var utcSaturday = utcWeekday(6); var utcSundays = utcSunday.range; var utcMondays = utcMonday.range; var utcTuesdays = utcTuesday.range; var utcWednesdays = utcWednesday.range; var utcThursdays = utcThursday.range; var utcFridays = utcFriday.range; var utcSaturdays = utcSaturday.range; var utcMonth = newInterval(function(date) { date.setUTCDate(1); date.setUTCHours(0, 0, 0, 0); }, function(date, step) { date.setUTCMonth(date.getUTCMonth() + step); }, function(start, end) { return end.getUTCMonth() - start.getUTCMonth() + (end.getUTCFullYear() - start.getUTCFullYear()) * 12; }, function(date) { return date.getUTCMonth(); }); var utcMonths = utcMonth.range; var utcYear = newInterval(function(date) { date.setUTCMonth(0, 1); date.setUTCHours(0, 0, 0, 0); }, function(date, step) { date.setUTCFullYear(date.getUTCFullYear() + step); }, function(start, end) { return end.getUTCFullYear() - start.getUTCFullYear(); }, function(date) { return date.getUTCFullYear(); }); // An optimized implementation for this simple case. utcYear.every = function(k) { return !isFinite(k = Math.floor(k)) || !(k > 0) ? null : newInterval(function(date) { date.setUTCFullYear(Math.floor(date.getUTCFullYear() / k) * k); date.setUTCMonth(0, 1); date.setUTCHours(0, 0, 0, 0); }, function(date, step) { date.setUTCFullYear(date.getUTCFullYear() + step * k); }); }; var utcYears = utcYear.range; exports.timeInterval = newInterval; exports.timeMillisecond = millisecond; exports.timeMilliseconds = milliseconds; exports.utcMillisecond = millisecond; exports.utcMilliseconds = milliseconds; exports.timeSecond = second; exports.timeSeconds = seconds; exports.utcSecond = second; exports.utcSeconds = seconds; exports.timeMinute = minute; exports.timeMinutes = minutes; exports.timeHour = hour; exports.timeHours = hours; exports.timeDay = day; exports.timeDays = days; exports.timeWeek = sunday; exports.timeWeeks = sundays; exports.timeSunday = sunday; exports.timeSundays = sundays; exports.timeMonday = monday; exports.timeMondays = mondays; exports.timeTuesday = tuesday; exports.timeTuesdays = tuesdays; exports.timeWednesday = wednesday; exports.timeWednesdays = wednesdays; exports.timeThursday = thursday; exports.timeThursdays = thursdays; exports.timeFriday = friday; exports.timeFridays = fridays; exports.timeSaturday = saturday; exports.timeSaturdays = saturdays; exports.timeMonth = month; exports.timeMonths = months; exports.timeYear = year; exports.timeYears = years; exports.utcMinute = utcMinute; exports.utcMinutes = utcMinutes; exports.utcHour = utcHour; exports.utcHours = utcHours; exports.utcDay = utcDay; exports.utcDays = utcDays; exports.utcWeek = utcSunday; exports.utcWeeks = utcSundays; exports.utcSunday = utcSunday; exports.utcSundays = utcSundays; exports.utcMonday = utcMonday; exports.utcMondays = utcMondays; exports.utcTuesday = utcTuesday; exports.utcTuesdays = utcTuesdays; exports.utcWednesday = utcWednesday; exports.utcWednesdays = utcWednesdays; exports.utcThursday = utcThursday; exports.utcThursdays = utcThursdays; exports.utcFriday = utcFriday; exports.utcFridays = utcFridays; exports.utcSaturday = utcSaturday; exports.utcSaturdays = utcSaturdays; exports.utcMonth = utcMonth; exports.utcMonths = utcMonths; exports.utcYear = utcYear; exports.utcYears = utcYears; Object.defineProperty(exports, '__esModule', { value: true }); }))); },{}],41:[function(require,module,exports){ // https://d3js.org/d3-timer/ Version 1.0.7. Copyright 2017 Mike Bostock. (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (factory((global.d3 = global.d3 || {}))); }(this, (function (exports) { 'use strict'; var frame = 0; var timeout = 0; var interval = 0; var pokeDelay = 1000; var taskHead; var taskTail; var clockLast = 0; var clockNow = 0; var clockSkew = 0; var clock = typeof performance === "object" && performance.now ? performance : Date; var setFrame = typeof window === "object" && window.requestAnimationFrame ? window.requestAnimationFrame.bind(window) : function(f) { setTimeout(f, 17); }; function now() { return clockNow || (setFrame(clearNow), clockNow = clock.now() + clockSkew); } function clearNow() { clockNow = 0; } function Timer() { this._call = this._time = this._next = null; } Timer.prototype = timer.prototype = { constructor: Timer, restart: function(callback, delay, time) { if (typeof callback !== "function") throw new TypeError("callback is not a function"); time = (time == null ? now() : +time) + (delay == null ? 0 : +delay); if (!this._next && taskTail !== this) { if (taskTail) taskTail._next = this; else taskHead = this; taskTail = this; } this._call = callback; this._time = time; sleep(); }, stop: function() { if (this._call) { this._call = null; this._time = Infinity; sleep(); } } }; function timer(callback, delay, time) { var t = new Timer; t.restart(callback, delay, time); return t; } function timerFlush() { now(); // Get the current time, if not already set. ++frame; // Pretend we’ve set an alarm, if we haven’t already. var t = taskHead, e; while (t) { if ((e = clockNow - t._time) >= 0) t._call.call(null, e); t = t._next; } --frame; } function wake() { clockNow = (clockLast = clock.now()) + clockSkew; frame = timeout = 0; try { timerFlush(); } finally { frame = 0; nap(); clockNow = 0; } } function poke() { var now = clock.now(), delay = now - clockLast; if (delay > pokeDelay) clockSkew -= delay, clockLast = now; } function nap() { var t0, t1 = taskHead, t2, time = Infinity; while (t1) { if (t1._call) { if (time > t1._time) time = t1._time; t0 = t1, t1 = t1._next; } else { t2 = t1._next, t1._next = null; t1 = t0 ? t0._next = t2 : taskHead = t2; } } taskTail = t0; sleep(time); } function sleep(time) { if (frame) return; // Soonest alarm already set, or will be. if (timeout) timeout = clearTimeout(timeout); var delay = time - clockNow; // Strictly less than if we recomputed clockNow. if (delay > 24) { if (time < Infinity) timeout = setTimeout(wake, time - clock.now() - clockSkew); if (interval) interval = clearInterval(interval); } else { if (!interval) clockLast = clock.now(), interval = setInterval(poke, pokeDelay); frame = 1, setFrame(wake); } } var timeout$1 = function(callback, delay, time) { var t = new Timer; delay = delay == null ? 0 : +delay; t.restart(function(elapsed) { t.stop(); callback(elapsed + delay); }, delay, time); return t; }; var interval$1 = function(callback, delay, time) { var t = new Timer, total = delay; if (delay == null) return t.restart(callback, delay, time), t; delay = +delay, time = time == null ? now() : +time; t.restart(function tick(elapsed) { elapsed += total; t.restart(tick, total += delay, time); callback(elapsed); }, delay, time); return t; }; exports.now = now; exports.timer = timer; exports.timerFlush = timerFlush; exports.timeout = timeout$1; exports.interval = interval$1; Object.defineProperty(exports, '__esModule', { value: true }); }))); },{}],42:[function(require,module,exports){ // https://d3js.org/d3-transition/ Version 1.1.0. Copyright 2017 Mike Bostock. (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('d3-selection'), require('d3-dispatch'), require('d3-timer'), require('d3-interpolate'), require('d3-color'), require('d3-ease')) : typeof define === 'function' && define.amd ? define(['exports', 'd3-selection', 'd3-dispatch', 'd3-timer', 'd3-interpolate', 'd3-color', 'd3-ease'], factory) : (factory((global.d3 = global.d3 || {}),global.d3,global.d3,global.d3,global.d3,global.d3,global.d3)); }(this, (function (exports,d3Selection,d3Dispatch,d3Timer,d3Interpolate,d3Color,d3Ease) { 'use strict'; var emptyOn = d3Dispatch.dispatch("start", "end", "interrupt"); var emptyTween = []; var CREATED = 0; var SCHEDULED = 1; var STARTING = 2; var STARTED = 3; var RUNNING = 4; var ENDING = 5; var ENDED = 6; var schedule = function(node, name, id, index, group, timing) { var schedules = node.__transition; if (!schedules) node.__transition = {}; else if (id in schedules) return; create(node, id, { name: name, index: index, // For context during callback. group: group, // For context during callback. on: emptyOn, tween: emptyTween, time: timing.time, delay: timing.delay, duration: timing.duration, ease: timing.ease, timer: null, state: CREATED }); }; function init(node, id) { var schedule = node.__transition; if (!schedule || !(schedule = schedule[id]) || schedule.state > CREATED) throw new Error("too late"); return schedule; } function set(node, id) { var schedule = node.__transition; if (!schedule || !(schedule = schedule[id]) || schedule.state > STARTING) throw new Error("too late"); return schedule; } function get(node, id) { var schedule = node.__transition; if (!schedule || !(schedule = schedule[id])) throw new Error("too late"); return schedule; } function create(node, id, self) { var schedules = node.__transition, tween; // Initialize the self timer when the transition is created. // Note the actual delay is not known until the first callback! schedules[id] = self; self.timer = d3Timer.timer(schedule, 0, self.time); function schedule(elapsed) { self.state = SCHEDULED; self.timer.restart(start, self.delay, self.time); // If the elapsed delay is less than our first sleep, start immediately. if (self.delay <= elapsed) start(elapsed - self.delay); } function start(elapsed) { var i, j, n, o; // If the state is not SCHEDULED, then we previously errored on start. if (self.state !== SCHEDULED) return stop(); for (i in schedules) { o = schedules[i]; if (o.name !== self.name) continue; // While this element already has a starting transition during this frame, // defer starting an interrupting transition until that transition has a // chance to tick (and possibly end); see d3/d3-transition#54! if (o.state === STARTED) return d3Timer.timeout(start); // Interrupt the active transition, if any. // Dispatch the interrupt event. if (o.state === RUNNING) { o.state = ENDED; o.timer.stop(); o.on.call("interrupt", node, node.__data__, o.index, o.group); delete schedules[i]; } // Cancel any pre-empted transitions. No interrupt event is dispatched // because the cancelled transitions never started. Note that this also // removes this transition from the pending list! else if (+i < id) { o.state = ENDED; o.timer.stop(); delete schedules[i]; } } // Defer the first tick to end of the current frame; see d3/d3#1576. // Note the transition may be canceled after start and before the first tick! // Note this must be scheduled before the start event; see d3/d3-transition#16! // Assuming this is successful, subsequent callbacks go straight to tick. d3Timer.timeout(function() { if (self.state === STARTED) { self.state = RUNNING; self.timer.restart(tick, self.delay, self.time); tick(elapsed); } }); // Dispatch the start event. // Note this must be done before the tween are initialized. self.state = STARTING; self.on.call("start", node, node.__data__, self.index, self.group); if (self.state !== STARTING) return; // interrupted self.state = STARTED; // Initialize the tween, deleting null tween. tween = new Array(n = self.tween.length); for (i = 0, j = -1; i < n; ++i) { if (o = self.tween[i].value.call(node, node.__data__, self.index, self.group)) { tween[++j] = o; } } tween.length = j + 1; } function tick(elapsed) { var t = elapsed < self.duration ? self.ease.call(null, elapsed / self.duration) : (self.timer.restart(stop), self.state = ENDING, 1), i = -1, n = tween.length; while (++i < n) { tween[i].call(null, t); } // Dispatch the end event. if (self.state === ENDING) { self.on.call("end", node, node.__data__, self.index, self.group); stop(); } } function stop() { self.state = ENDED; self.timer.stop(); delete schedules[id]; for (var i in schedules) return; // eslint-disable-line no-unused-vars delete node.__transition; } } var interrupt = function(node, name) { var schedules = node.__transition, schedule, active, empty = true, i; if (!schedules) return; name = name == null ? null : name + ""; for (i in schedules) { if ((schedule = schedules[i]).name !== name) { empty = false; continue; } active = schedule.state > STARTING && schedule.state < ENDING; schedule.state = ENDED; schedule.timer.stop(); if (active) schedule.on.call("interrupt", node, node.__data__, schedule.index, schedule.group); delete schedules[i]; } if (empty) delete node.__transition; }; var selection_interrupt = function(name) { return this.each(function() { interrupt(this, name); }); }; function tweenRemove(id, name) { var tween0, tween1; return function() { var schedule = set(this, id), tween = schedule.tween; // If this node shared tween with the previous node, // just assign the updated shared tween and we’re done! // Otherwise, copy-on-write. if (tween !== tween0) { tween1 = tween0 = tween; for (var i = 0, n = tween1.length; i < n; ++i) { if (tween1[i].name === name) { tween1 = tween1.slice(); tween1.splice(i, 1); break; } } } schedule.tween = tween1; }; } function tweenFunction(id, name, value) { var tween0, tween1; if (typeof value !== "function") throw new Error; return function() { var schedule = set(this, id), tween = schedule.tween; // If this node shared tween with the previous node, // just assign the updated shared tween and we’re done! // Otherwise, copy-on-write. if (tween !== tween0) { tween1 = (tween0 = tween).slice(); for (var t = {name: name, value: value}, i = 0, n = tween1.length; i < n; ++i) { if (tween1[i].name === name) { tween1[i] = t; break; } } if (i === n) tween1.push(t); } schedule.tween = tween1; }; } var transition_tween = function(name, value) { var id = this._id; name += ""; if (arguments.length < 2) { var tween = get(this.node(), id).tween; for (var i = 0, n = tween.length, t; i < n; ++i) { if ((t = tween[i]).name === name) { return t.value; } } return null; } return this.each((value == null ? tweenRemove : tweenFunction)(id, name, value)); }; function tweenValue(transition, name, value) { var id = transition._id; transition.each(function() { var schedule = set(this, id); (schedule.value || (schedule.value = {}))[name] = value.apply(this, arguments); }); return function(node) { return get(node, id).value[name]; }; } var interpolate = function(a, b) { var c; return (typeof b === "number" ? d3Interpolate.interpolateNumber : b instanceof d3Color.color ? d3Interpolate.interpolateRgb : (c = d3Color.color(b)) ? (b = c, d3Interpolate.interpolateRgb) : d3Interpolate.interpolateString)(a, b); }; function attrRemove(name) { return function() { this.removeAttribute(name); }; } function attrRemoveNS(fullname) { return function() { this.removeAttributeNS(fullname.space, fullname.local); }; } function attrConstant(name, interpolate$$1, value1) { var value00, interpolate0; return function() { var value0 = this.getAttribute(name); return value0 === value1 ? null : value0 === value00 ? interpolate0 : interpolate0 = interpolate$$1(value00 = value0, value1); }; } function attrConstantNS(fullname, interpolate$$1, value1) { var value00, interpolate0; return function() { var value0 = this.getAttributeNS(fullname.space, fullname.local); return value0 === value1 ? null : value0 === value00 ? interpolate0 : interpolate0 = interpolate$$1(value00 = value0, value1); }; } function attrFunction(name, interpolate$$1, value) { var value00, value10, interpolate0; return function() { var value0, value1 = value(this); if (value1 == null) return void this.removeAttribute(name); value0 = this.getAttribute(name); return value0 === value1 ? null : value0 === value00 && value1 === value10 ? interpolate0 : interpolate0 = interpolate$$1(value00 = value0, value10 = value1); }; } function attrFunctionNS(fullname, interpolate$$1, value) { var value00, value10, interpolate0; return function() { var value0, value1 = value(this); if (value1 == null) return void this.removeAttributeNS(fullname.space, fullname.local); value0 = this.getAttributeNS(fullname.space, fullname.local); return value0 === value1 ? null : value0 === value00 && value1 === value10 ? interpolate0 : interpolate0 = interpolate$$1(value00 = value0, value10 = value1); }; } var transition_attr = function(name, value) { var fullname = d3Selection.namespace(name), i = fullname === "transform" ? d3Interpolate.interpolateTransformSvg : interpolate; return this.attrTween(name, typeof value === "function" ? (fullname.local ? attrFunctionNS : attrFunction)(fullname, i, tweenValue(this, "attr." + name, value)) : value == null ? (fullname.local ? attrRemoveNS : attrRemove)(fullname) : (fullname.local ? attrConstantNS : attrConstant)(fullname, i, value + "")); }; function attrTweenNS(fullname, value) { function tween() { var node = this, i = value.apply(node, arguments); return i && function(t) { node.setAttributeNS(fullname.space, fullname.local, i(t)); }; } tween._value = value; return tween; } function attrTween(name, value) { function tween() { var node = this, i = value.apply(node, arguments); return i && function(t) { node.setAttribute(name, i(t)); }; } tween._value = value; return tween; } var transition_attrTween = function(name, value) { var key = "attr." + name; if (arguments.length < 2) return (key = this.tween(key)) && key._value; if (value == null) return this.tween(key, null); if (typeof value !== "function") throw new Error; var fullname = d3Selection.namespace(name); return this.tween(key, (fullname.local ? attrTweenNS : attrTween)(fullname, value)); }; function delayFunction(id, value) { return function() { init(this, id).delay = +value.apply(this, arguments); }; } function delayConstant(id, value) { return value = +value, function() { init(this, id).delay = value; }; } var transition_delay = function(value) { var id = this._id; return arguments.length ? this.each((typeof value === "function" ? delayFunction : delayConstant)(id, value)) : get(this.node(), id).delay; }; function durationFunction(id, value) { return function() { set(this, id).duration = +value.apply(this, arguments); }; } function durationConstant(id, value) { return value = +value, function() { set(this, id).duration = value; }; } var transition_duration = function(value) { var id = this._id; return arguments.length ? this.each((typeof value === "function" ? durationFunction : durationConstant)(id, value)) : get(this.node(), id).duration; }; function easeConstant(id, value) { if (typeof value !== "function") throw new Error; return function() { set(this, id).ease = value; }; } var transition_ease = function(value) { var id = this._id; return arguments.length ? this.each(easeConstant(id, value)) : get(this.node(), id).ease; }; var transition_filter = function(match) { if (typeof match !== "function") match = d3Selection.matcher(match); for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) { for (var group = groups[j], n = group.length, subgroup = subgroups[j] = [], node, i = 0; i < n; ++i) { if ((node = group[i]) && match.call(node, node.__data__, i, group)) { subgroup.push(node); } } } return new Transition(subgroups, this._parents, this._name, this._id); }; var transition_merge = function(transition) { if (transition._id !== this._id) throw new Error; for (var groups0 = this._groups, groups1 = transition._groups, m0 = groups0.length, m1 = groups1.length, m = Math.min(m0, m1), merges = new Array(m0), j = 0; j < m; ++j) { for (var group0 = groups0[j], group1 = groups1[j], n = group0.length, merge = merges[j] = new Array(n), node, i = 0; i < n; ++i) { if (node = group0[i] || group1[i]) { merge[i] = node; } } } for (; j < m0; ++j) { merges[j] = groups0[j]; } return new Transition(merges, this._parents, this._name, this._id); }; function start(name) { return (name + "").trim().split(/^|\s+/).every(function(t) { var i = t.indexOf("."); if (i >= 0) t = t.slice(0, i); return !t || t === "start"; }); } function onFunction(id, name, listener) { var on0, on1, sit = start(name) ? init : set; return function() { var schedule = sit(this, id), on = schedule.on; // If this node shared a dispatch with the previous node, // just assign the updated shared dispatch and we’re done! // Otherwise, copy-on-write. if (on !== on0) (on1 = (on0 = on).copy()).on(name, listener); schedule.on = on1; }; } var transition_on = function(name, listener) { var id = this._id; return arguments.length < 2 ? get(this.node(), id).on.on(name) : this.each(onFunction(id, name, listener)); }; function removeFunction(id) { return function() { var parent = this.parentNode; for (var i in this.__transition) if (+i !== id) return; if (parent) parent.removeChild(this); }; } var transition_remove = function() { return this.on("end.remove", removeFunction(this._id)); }; var transition_select = function(select) { var name = this._name, id = this._id; if (typeof select !== "function") select = d3Selection.selector(select); for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) { for (var group = groups[j], n = group.length, subgroup = subgroups[j] = new Array(n), node, subnode, i = 0; i < n; ++i) { if ((node = group[i]) && (subnode = select.call(node, node.__data__, i, group))) { if ("__data__" in node) subnode.__data__ = node.__data__; subgroup[i] = subnode; schedule(subgroup[i], name, id, i, subgroup, get(node, id)); } } } return new Transition(subgroups, this._parents, name, id); }; var transition_selectAll = function(select) { var name = this._name, id = this._id; if (typeof select !== "function") select = d3Selection.selectorAll(select); for (var groups = this._groups, m = groups.length, subgroups = [], parents = [], j = 0; j < m; ++j) { for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) { if (node = group[i]) { for (var children = select.call(node, node.__data__, i, group), child, inherit = get(node, id), k = 0, l = children.length; k < l; ++k) { if (child = children[k]) { schedule(child, name, id, k, children, inherit); } } subgroups.push(children); parents.push(node); } } } return new Transition(subgroups, parents, name, id); }; var Selection = d3Selection.selection.prototype.constructor; var transition_selection = function() { return new Selection(this._groups, this._parents); }; function styleRemove(name, interpolate$$1) { var value00, value10, interpolate0; return function() { var value0 = d3Selection.style(this, name), value1 = (this.style.removeProperty(name), d3Selection.style(this, name)); return value0 === value1 ? null : value0 === value00 && value1 === value10 ? interpolate0 : interpolate0 = interpolate$$1(value00 = value0, value10 = value1); }; } function styleRemoveEnd(name) { return function() { this.style.removeProperty(name); }; } function styleConstant(name, interpolate$$1, value1) { var value00, interpolate0; return function() { var value0 = d3Selection.style(this, name); return value0 === value1 ? null : value0 === value00 ? interpolate0 : interpolate0 = interpolate$$1(value00 = value0, value1); }; } function styleFunction(name, interpolate$$1, value) { var value00, value10, interpolate0; return function() { var value0 = d3Selection.style(this, name), value1 = value(this); if (value1 == null) value1 = (this.style.removeProperty(name), d3Selection.style(this, name)); return value0 === value1 ? null : value0 === value00 && value1 === value10 ? interpolate0 : interpolate0 = interpolate$$1(value00 = value0, value10 = value1); }; } var transition_style = function(name, value, priority) { var i = (name += "") === "transform" ? d3Interpolate.interpolateTransformCss : interpolate; return value == null ? this .styleTween(name, styleRemove(name, i)) .on("end.style." + name, styleRemoveEnd(name)) : this.styleTween(name, typeof value === "function" ? styleFunction(name, i, tweenValue(this, "style." + name, value)) : styleConstant(name, i, value + ""), priority); }; function styleTween(name, value, priority) { function tween() { var node = this, i = value.apply(node, arguments); return i && function(t) { node.style.setProperty(name, i(t), priority); }; } tween._value = value; return tween; } var transition_styleTween = function(name, value, priority) { var key = "style." + (name += ""); if (arguments.length < 2) return (key = this.tween(key)) && key._value; if (value == null) return this.tween(key, null); if (typeof value !== "function") throw new Error; return this.tween(key, styleTween(name, value, priority == null ? "" : priority)); }; function textConstant(value) { return function() { this.textContent = value; }; } function textFunction(value) { return function() { var value1 = value(this); this.textContent = value1 == null ? "" : value1; }; } var transition_text = function(value) { return this.tween("text", typeof value === "function" ? textFunction(tweenValue(this, "text", value)) : textConstant(value == null ? "" : value + "")); }; var transition_transition = function() { var name = this._name, id0 = this._id, id1 = newId(); for (var groups = this._groups, m = groups.length, j = 0; j < m; ++j) { for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) { if (node = group[i]) { var inherit = get(node, id0); schedule(node, name, id1, i, group, { time: inherit.time + inherit.delay + inherit.duration, delay: 0, duration: inherit.duration, ease: inherit.ease }); } } } return new Transition(groups, this._parents, name, id1); }; var id = 0; function Transition(groups, parents, name, id) { this._groups = groups; this._parents = parents; this._name = name; this._id = id; } function transition(name) { return d3Selection.selection().transition(name); } function newId() { return ++id; } var selection_prototype = d3Selection.selection.prototype; Transition.prototype = transition.prototype = { constructor: Transition, select: transition_select, selectAll: transition_selectAll, filter: transition_filter, merge: transition_merge, selection: transition_selection, transition: transition_transition, call: selection_prototype.call, nodes: selection_prototype.nodes, node: selection_prototype.node, size: selection_prototype.size, empty: selection_prototype.empty, each: selection_prototype.each, on: transition_on, attr: transition_attr, attrTween: transition_attrTween, style: transition_style, styleTween: transition_styleTween, text: transition_text, remove: transition_remove, tween: transition_tween, delay: transition_delay, duration: transition_duration, ease: transition_ease }; var defaultTiming = { time: null, // Set on use. delay: 0, duration: 250, ease: d3Ease.easeCubicInOut }; function inherit(node, id) { var timing; while (!(timing = node.__transition) || !(timing = timing[id])) { if (!(node = node.parentNode)) { return defaultTiming.time = d3Timer.now(), defaultTiming; } } return timing; } var selection_transition = function(name) { var id, timing; if (name instanceof Transition) { id = name._id, name = name._name; } else { id = newId(), (timing = defaultTiming).time = d3Timer.now(), name = name == null ? null : name + ""; } for (var groups = this._groups, m = groups.length, j = 0; j < m; ++j) { for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) { if (node = group[i]) { schedule(node, name, id, i, group, timing || inherit(node, id)); } } } return new Transition(groups, this._parents, name, id); }; d3Selection.selection.prototype.interrupt = selection_interrupt; d3Selection.selection.prototype.transition = selection_transition; var root = [null]; var active = function(node, name) { var schedules = node.__transition, schedule, i; if (schedules) { name = name == null ? null : name + ""; for (i in schedules) { if ((schedule = schedules[i]).state > SCHEDULED && schedule.name === name) { return new Transition([[node]], root, name, +i); } } } return null; }; exports.transition = transition; exports.active = active; exports.interrupt = interrupt; Object.defineProperty(exports, '__esModule', { value: true }); }))); },{"d3-color":20,"d3-dispatch":21,"d3-ease":24,"d3-interpolate":29,"d3-selection":37,"d3-timer":41}],43:[function(require,module,exports){ // https://d3js.org/d3-voronoi/ Version 1.1.2. Copyright 2017 Mike Bostock. (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (factory((global.d3 = global.d3 || {}))); }(this, (function (exports) { 'use strict'; var constant = function(x) { return function() { return x; }; }; function x(d) { return d[0]; } function y(d) { return d[1]; } function RedBlackTree() { this._ = null; // root node } function RedBlackNode(node) { node.U = // parent node node.C = // color - true for red, false for black node.L = // left node node.R = // right node node.P = // previous node node.N = null; // next node } RedBlackTree.prototype = { constructor: RedBlackTree, insert: function(after, node) { var parent, grandpa, uncle; if (after) { node.P = after; node.N = after.N; if (after.N) after.N.P = node; after.N = node; if (after.R) { after = after.R; while (after.L) after = after.L; after.L = node; } else { after.R = node; } parent = after; } else if (this._) { after = RedBlackFirst(this._); node.P = null; node.N = after; after.P = after.L = node; parent = after; } else { node.P = node.N = null; this._ = node; parent = null; } node.L = node.R = null; node.U = parent; node.C = true; after = node; while (parent && parent.C) { grandpa = parent.U; if (parent === grandpa.L) { uncle = grandpa.R; if (uncle && uncle.C) { parent.C = uncle.C = false; grandpa.C = true; after = grandpa; } else { if (after === parent.R) { RedBlackRotateLeft(this, parent); after = parent; parent = after.U; } parent.C = false; grandpa.C = true; RedBlackRotateRight(this, grandpa); } } else { uncle = grandpa.L; if (uncle && uncle.C) { parent.C = uncle.C = false; grandpa.C = true; after = grandpa; } else { if (after === parent.L) { RedBlackRotateRight(this, parent); after = parent; parent = after.U; } parent.C = false; grandpa.C = true; RedBlackRotateLeft(this, grandpa); } } parent = after.U; } this._.C = false; }, remove: function(node) { if (node.N) node.N.P = node.P; if (node.P) node.P.N = node.N; node.N = node.P = null; var parent = node.U, sibling, left = node.L, right = node.R, next, red; if (!left) next = right; else if (!right) next = left; else next = RedBlackFirst(right); if (parent) { if (parent.L === node) parent.L = next; else parent.R = next; } else { this._ = next; } if (left && right) { red = next.C; next.C = node.C; next.L = left; left.U = next; if (next !== right) { parent = next.U; next.U = node.U; node = next.R; parent.L = node; next.R = right; right.U = next; } else { next.U = parent; parent = next; node = next.R; } } else { red = node.C; node = next; } if (node) node.U = parent; if (red) return; if (node && node.C) { node.C = false; return; } do { if (node === this._) break; if (node === parent.L) { sibling = parent.R; if (sibling.C) { sibling.C = false; parent.C = true; RedBlackRotateLeft(this, parent); sibling = parent.R; } if ((sibling.L && sibling.L.C) || (sibling.R && sibling.R.C)) { if (!sibling.R || !sibling.R.C) { sibling.L.C = false; sibling.C = true; RedBlackRotateRight(this, sibling); sibling = parent.R; } sibling.C = parent.C; parent.C = sibling.R.C = false; RedBlackRotateLeft(this, parent); node = this._; break; } } else { sibling = parent.L; if (sibling.C) { sibling.C = false; parent.C = true; RedBlackRotateRight(this, parent); sibling = parent.L; } if ((sibling.L && sibling.L.C) || (sibling.R && sibling.R.C)) { if (!sibling.L || !sibling.L.C) { sibling.R.C = false; sibling.C = true; RedBlackRotateLeft(this, sibling); sibling = parent.L; } sibling.C = parent.C; parent.C = sibling.L.C = false; RedBlackRotateRight(this, parent); node = this._; break; } } sibling.C = true; node = parent; parent = parent.U; } while (!node.C); if (node) node.C = false; } }; function RedBlackRotateLeft(tree, node) { var p = node, q = node.R, parent = p.U; if (parent) { if (parent.L === p) parent.L = q; else parent.R = q; } else { tree._ = q; } q.U = parent; p.U = q; p.R = q.L; if (p.R) p.R.U = p; q.L = p; } function RedBlackRotateRight(tree, node) { var p = node, q = node.L, parent = p.U; if (parent) { if (parent.L === p) parent.L = q; else parent.R = q; } else { tree._ = q; } q.U = parent; p.U = q; p.L = q.R; if (p.L) p.L.U = p; q.R = p; } function RedBlackFirst(node) { while (node.L) node = node.L; return node; } function createEdge(left, right, v0, v1) { var edge = [null, null], index = edges.push(edge) - 1; edge.left = left; edge.right = right; if (v0) setEdgeEnd(edge, left, right, v0); if (v1) setEdgeEnd(edge, right, left, v1); cells[left.index].halfedges.push(index); cells[right.index].halfedges.push(index); return edge; } function createBorderEdge(left, v0, v1) { var edge = [v0, v1]; edge.left = left; return edge; } function setEdgeEnd(edge, left, right, vertex) { if (!edge[0] && !edge[1]) { edge[0] = vertex; edge.left = left; edge.right = right; } else if (edge.left === right) { edge[1] = vertex; } else { edge[0] = vertex; } } // Liang–Barsky line clipping. function clipEdge(edge, x0, y0, x1, y1) { var a = edge[0], b = edge[1], ax = a[0], ay = a[1], bx = b[0], by = b[1], t0 = 0, t1 = 1, dx = bx - ax, dy = by - ay, r; r = x0 - ax; if (!dx && r > 0) return; r /= dx; if (dx < 0) { if (r < t0) return; if (r < t1) t1 = r; } else if (dx > 0) { if (r > t1) return; if (r > t0) t0 = r; } r = x1 - ax; if (!dx && r < 0) return; r /= dx; if (dx < 0) { if (r > t1) return; if (r > t0) t0 = r; } else if (dx > 0) { if (r < t0) return; if (r < t1) t1 = r; } r = y0 - ay; if (!dy && r > 0) return; r /= dy; if (dy < 0) { if (r < t0) return; if (r < t1) t1 = r; } else if (dy > 0) { if (r > t1) return; if (r > t0) t0 = r; } r = y1 - ay; if (!dy && r < 0) return; r /= dy; if (dy < 0) { if (r > t1) return; if (r > t0) t0 = r; } else if (dy > 0) { if (r < t0) return; if (r < t1) t1 = r; } if (!(t0 > 0) && !(t1 < 1)) return true; // TODO Better check? if (t0 > 0) edge[0] = [ax + t0 * dx, ay + t0 * dy]; if (t1 < 1) edge[1] = [ax + t1 * dx, ay + t1 * dy]; return true; } function connectEdge(edge, x0, y0, x1, y1) { var v1 = edge[1]; if (v1) return true; var v0 = edge[0], left = edge.left, right = edge.right, lx = left[0], ly = left[1], rx = right[0], ry = right[1], fx = (lx + rx) / 2, fy = (ly + ry) / 2, fm, fb; if (ry === ly) { if (fx < x0 || fx >= x1) return; if (lx > rx) { if (!v0) v0 = [fx, y0]; else if (v0[1] >= y1) return; v1 = [fx, y1]; } else { if (!v0) v0 = [fx, y1]; else if (v0[1] < y0) return; v1 = [fx, y0]; } } else { fm = (lx - rx) / (ry - ly); fb = fy - fm * fx; if (fm < -1 || fm > 1) { if (lx > rx) { if (!v0) v0 = [(y0 - fb) / fm, y0]; else if (v0[1] >= y1) return; v1 = [(y1 - fb) / fm, y1]; } else { if (!v0) v0 = [(y1 - fb) / fm, y1]; else if (v0[1] < y0) return; v1 = [(y0 - fb) / fm, y0]; } } else { if (ly < ry) { if (!v0) v0 = [x0, fm * x0 + fb]; else if (v0[0] >= x1) return; v1 = [x1, fm * x1 + fb]; } else { if (!v0) v0 = [x1, fm * x1 + fb]; else if (v0[0] < x0) return; v1 = [x0, fm * x0 + fb]; } } } edge[0] = v0; edge[1] = v1; return true; } function clipEdges(x0, y0, x1, y1) { var i = edges.length, edge; while (i--) { if (!connectEdge(edge = edges[i], x0, y0, x1, y1) || !clipEdge(edge, x0, y0, x1, y1) || !(Math.abs(edge[0][0] - edge[1][0]) > epsilon || Math.abs(edge[0][1] - edge[1][1]) > epsilon)) { delete edges[i]; } } } function createCell(site) { return cells[site.index] = { site: site, halfedges: [] }; } function cellHalfedgeAngle(cell, edge) { var site = cell.site, va = edge.left, vb = edge.right; if (site === vb) vb = va, va = site; if (vb) return Math.atan2(vb[1] - va[1], vb[0] - va[0]); if (site === va) va = edge[1], vb = edge[0]; else va = edge[0], vb = edge[1]; return Math.atan2(va[0] - vb[0], vb[1] - va[1]); } function cellHalfedgeStart(cell, edge) { return edge[+(edge.left !== cell.site)]; } function cellHalfedgeEnd(cell, edge) { return edge[+(edge.left === cell.site)]; } function sortCellHalfedges() { for (var i = 0, n = cells.length, cell, halfedges, j, m; i < n; ++i) { if ((cell = cells[i]) && (m = (halfedges = cell.halfedges).length)) { var index = new Array(m), array = new Array(m); for (j = 0; j < m; ++j) index[j] = j, array[j] = cellHalfedgeAngle(cell, edges[halfedges[j]]); index.sort(function(i, j) { return array[j] - array[i]; }); for (j = 0; j < m; ++j) array[j] = halfedges[index[j]]; for (j = 0; j < m; ++j) halfedges[j] = array[j]; } } } function clipCells(x0, y0, x1, y1) { var nCells = cells.length, iCell, cell, site, iHalfedge, halfedges, nHalfedges, start, startX, startY, end, endX, endY, cover = true; for (iCell = 0; iCell < nCells; ++iCell) { if (cell = cells[iCell]) { site = cell.site; halfedges = cell.halfedges; iHalfedge = halfedges.length; // Remove any dangling clipped edges. while (iHalfedge--) { if (!edges[halfedges[iHalfedge]]) { halfedges.splice(iHalfedge, 1); } } // Insert any border edges as necessary. iHalfedge = 0, nHalfedges = halfedges.length; while (iHalfedge < nHalfedges) { end = cellHalfedgeEnd(cell, edges[halfedges[iHalfedge]]), endX = end[0], endY = end[1]; start = cellHalfedgeStart(cell, edges[halfedges[++iHalfedge % nHalfedges]]), startX = start[0], startY = start[1]; if (Math.abs(endX - startX) > epsilon || Math.abs(endY - startY) > epsilon) { halfedges.splice(iHalfedge, 0, edges.push(createBorderEdge(site, end, Math.abs(endX - x0) < epsilon && y1 - endY > epsilon ? [x0, Math.abs(startX - x0) < epsilon ? startY : y1] : Math.abs(endY - y1) < epsilon && x1 - endX > epsilon ? [Math.abs(startY - y1) < epsilon ? startX : x1, y1] : Math.abs(endX - x1) < epsilon && endY - y0 > epsilon ? [x1, Math.abs(startX - x1) < epsilon ? startY : y0] : Math.abs(endY - y0) < epsilon && endX - x0 > epsilon ? [Math.abs(startY - y0) < epsilon ? startX : x0, y0] : null)) - 1); ++nHalfedges; } } if (nHalfedges) cover = false; } } // If there weren’t any edges, have the closest site cover the extent. // It doesn’t matter which corner of the extent we measure! if (cover) { var dx, dy, d2, dc = Infinity; for (iCell = 0, cover = null; iCell < nCells; ++iCell) { if (cell = cells[iCell]) { site = cell.site; dx = site[0] - x0; dy = site[1] - y0; d2 = dx * dx + dy * dy; if (d2 < dc) dc = d2, cover = cell; } } if (cover) { var v00 = [x0, y0], v01 = [x0, y1], v11 = [x1, y1], v10 = [x1, y0]; cover.halfedges.push( edges.push(createBorderEdge(site = cover.site, v00, v01)) - 1, edges.push(createBorderEdge(site, v01, v11)) - 1, edges.push(createBorderEdge(site, v11, v10)) - 1, edges.push(createBorderEdge(site, v10, v00)) - 1 ); } } // Lastly delete any cells with no edges; these were entirely clipped. for (iCell = 0; iCell < nCells; ++iCell) { if (cell = cells[iCell]) { if (!cell.halfedges.length) { delete cells[iCell]; } } } } var circlePool = []; var firstCircle; function Circle() { RedBlackNode(this); this.x = this.y = this.arc = this.site = this.cy = null; } function attachCircle(arc) { var lArc = arc.P, rArc = arc.N; if (!lArc || !rArc) return; var lSite = lArc.site, cSite = arc.site, rSite = rArc.site; if (lSite === rSite) return; var bx = cSite[0], by = cSite[1], ax = lSite[0] - bx, ay = lSite[1] - by, cx = rSite[0] - bx, cy = rSite[1] - by; var d = 2 * (ax * cy - ay * cx); if (d >= -epsilon2) return; var ha = ax * ax + ay * ay, hc = cx * cx + cy * cy, x = (cy * ha - ay * hc) / d, y = (ax * hc - cx * ha) / d; var circle = circlePool.pop() || new Circle; circle.arc = arc; circle.site = cSite; circle.x = x + bx; circle.y = (circle.cy = y + by) + Math.sqrt(x * x + y * y); // y bottom arc.circle = circle; var before = null, node = circles._; while (node) { if (circle.y < node.y || (circle.y === node.y && circle.x <= node.x)) { if (node.L) node = node.L; else { before = node.P; break; } } else { if (node.R) node = node.R; else { before = node; break; } } } circles.insert(before, circle); if (!before) firstCircle = circle; } function detachCircle(arc) { var circle = arc.circle; if (circle) { if (!circle.P) firstCircle = circle.N; circles.remove(circle); circlePool.push(circle); RedBlackNode(circle); arc.circle = null; } } var beachPool = []; function Beach() { RedBlackNode(this); this.edge = this.site = this.circle = null; } function createBeach(site) { var beach = beachPool.pop() || new Beach; beach.site = site; return beach; } function detachBeach(beach) { detachCircle(beach); beaches.remove(beach); beachPool.push(beach); RedBlackNode(beach); } function removeBeach(beach) { var circle = beach.circle, x = circle.x, y = circle.cy, vertex = [x, y], previous = beach.P, next = beach.N, disappearing = [beach]; detachBeach(beach); var lArc = previous; while (lArc.circle && Math.abs(x - lArc.circle.x) < epsilon && Math.abs(y - lArc.circle.cy) < epsilon) { previous = lArc.P; disappearing.unshift(lArc); detachBeach(lArc); lArc = previous; } disappearing.unshift(lArc); detachCircle(lArc); var rArc = next; while (rArc.circle && Math.abs(x - rArc.circle.x) < epsilon && Math.abs(y - rArc.circle.cy) < epsilon) { next = rArc.N; disappearing.push(rArc); detachBeach(rArc); rArc = next; } disappearing.push(rArc); detachCircle(rArc); var nArcs = disappearing.length, iArc; for (iArc = 1; iArc < nArcs; ++iArc) { rArc = disappearing[iArc]; lArc = disappearing[iArc - 1]; setEdgeEnd(rArc.edge, lArc.site, rArc.site, vertex); } lArc = disappearing[0]; rArc = disappearing[nArcs - 1]; rArc.edge = createEdge(lArc.site, rArc.site, null, vertex); attachCircle(lArc); attachCircle(rArc); } function addBeach(site) { var x = site[0], directrix = site[1], lArc, rArc, dxl, dxr, node = beaches._; while (node) { dxl = leftBreakPoint(node, directrix) - x; if (dxl > epsilon) node = node.L; else { dxr = x - rightBreakPoint(node, directrix); if (dxr > epsilon) { if (!node.R) { lArc = node; break; } node = node.R; } else { if (dxl > -epsilon) { lArc = node.P; rArc = node; } else if (dxr > -epsilon) { lArc = node; rArc = node.N; } else { lArc = rArc = node; } break; } } } createCell(site); var newArc = createBeach(site); beaches.insert(lArc, newArc); if (!lArc && !rArc) return; if (lArc === rArc) { detachCircle(lArc); rArc = createBeach(lArc.site); beaches.insert(newArc, rArc); newArc.edge = rArc.edge = createEdge(lArc.site, newArc.site); attachCircle(lArc); attachCircle(rArc); return; } if (!rArc) { // && lArc newArc.edge = createEdge(lArc.site, newArc.site); return; } // else lArc !== rArc detachCircle(lArc); detachCircle(rArc); var lSite = lArc.site, ax = lSite[0], ay = lSite[1], bx = site[0] - ax, by = site[1] - ay, rSite = rArc.site, cx = rSite[0] - ax, cy = rSite[1] - ay, d = 2 * (bx * cy - by * cx), hb = bx * bx + by * by, hc = cx * cx + cy * cy, vertex = [(cy * hb - by * hc) / d + ax, (bx * hc - cx * hb) / d + ay]; setEdgeEnd(rArc.edge, lSite, rSite, vertex); newArc.edge = createEdge(lSite, site, null, vertex); rArc.edge = createEdge(site, rSite, null, vertex); attachCircle(lArc); attachCircle(rArc); } function leftBreakPoint(arc, directrix) { var site = arc.site, rfocx = site[0], rfocy = site[1], pby2 = rfocy - directrix; if (!pby2) return rfocx; var lArc = arc.P; if (!lArc) return -Infinity; site = lArc.site; var lfocx = site[0], lfocy = site[1], plby2 = lfocy - directrix; if (!plby2) return lfocx; var hl = lfocx - rfocx, aby2 = 1 / pby2 - 1 / plby2, b = hl / plby2; if (aby2) return (-b + Math.sqrt(b * b - 2 * aby2 * (hl * hl / (-2 * plby2) - lfocy + plby2 / 2 + rfocy - pby2 / 2))) / aby2 + rfocx; return (rfocx + lfocx) / 2; } function rightBreakPoint(arc, directrix) { var rArc = arc.N; if (rArc) return leftBreakPoint(rArc, directrix); var site = arc.site; return site[1] === directrix ? site[0] : Infinity; } var epsilon = 1e-6; var epsilon2 = 1e-12; var beaches; var cells; var circles; var edges; function triangleArea(a, b, c) { return (a[0] - c[0]) * (b[1] - a[1]) - (a[0] - b[0]) * (c[1] - a[1]); } function lexicographic(a, b) { return b[1] - a[1] || b[0] - a[0]; } function Diagram(sites, extent) { var site = sites.sort(lexicographic).pop(), x, y, circle; edges = []; cells = new Array(sites.length); beaches = new RedBlackTree; circles = new RedBlackTree; while (true) { circle = firstCircle; if (site && (!circle || site[1] < circle.y || (site[1] === circle.y && site[0] < circle.x))) { if (site[0] !== x || site[1] !== y) { addBeach(site); x = site[0], y = site[1]; } site = sites.pop(); } else if (circle) { removeBeach(circle.arc); } else { break; } } sortCellHalfedges(); if (extent) { var x0 = +extent[0][0], y0 = +extent[0][1], x1 = +extent[1][0], y1 = +extent[1][1]; clipEdges(x0, y0, x1, y1); clipCells(x0, y0, x1, y1); } this.edges = edges; this.cells = cells; beaches = circles = edges = cells = null; } Diagram.prototype = { constructor: Diagram, polygons: function() { var edges = this.edges; return this.cells.map(function(cell) { var polygon = cell.halfedges.map(function(i) { return cellHalfedgeStart(cell, edges[i]); }); polygon.data = cell.site.data; return polygon; }); }, triangles: function() { var triangles = [], edges = this.edges; this.cells.forEach(function(cell, i) { if (!(m = (halfedges = cell.halfedges).length)) return; var site = cell.site, halfedges, j = -1, m, s0, e1 = edges[halfedges[m - 1]], s1 = e1.left === site ? e1.right : e1.left; while (++j < m) { s0 = s1; e1 = edges[halfedges[j]]; s1 = e1.left === site ? e1.right : e1.left; if (s0 && s1 && i < s0.index && i < s1.index && triangleArea(site, s0, s1) < 0) { triangles.push([site.data, s0.data, s1.data]); } } }); return triangles; }, links: function() { return this.edges.filter(function(edge) { return edge.right; }).map(function(edge) { return { source: edge.left.data, target: edge.right.data }; }); }, find: function(x, y, radius) { var that = this, i0, i1 = that._found || 0, n = that.cells.length, cell; // Use the previously-found cell, or start with an arbitrary one. while (!(cell = that.cells[i1])) if (++i1 >= n) return null; var dx = x - cell.site[0], dy = y - cell.site[1], d2 = dx * dx + dy * dy; // Traverse the half-edges to find a closer cell, if any. do { cell = that.cells[i0 = i1], i1 = null; cell.halfedges.forEach(function(e) { var edge = that.edges[e], v = edge.left; if ((v === cell.site || !v) && !(v = edge.right)) return; var vx = x - v[0], vy = y - v[1], v2 = vx * vx + vy * vy; if (v2 < d2) d2 = v2, i1 = v.index; }); } while (i1 !== null); that._found = i0; return radius == null || d2 <= radius * radius ? cell.site : null; } }; var voronoi = function() { var x$$1 = x, y$$1 = y, extent = null; function voronoi(data) { return new Diagram(data.map(function(d, i) { var s = [Math.round(x$$1(d, i, data) / epsilon) * epsilon, Math.round(y$$1(d, i, data) / epsilon) * epsilon]; s.index = i; s.data = d; return s; }), extent); } voronoi.polygons = function(data) { return voronoi(data).polygons(); }; voronoi.links = function(data) { return voronoi(data).links(); }; voronoi.triangles = function(data) { return voronoi(data).triangles(); }; voronoi.x = function(_) { return arguments.length ? (x$$1 = typeof _ === "function" ? _ : constant(+_), voronoi) : x$$1; }; voronoi.y = function(_) { return arguments.length ? (y$$1 = typeof _ === "function" ? _ : constant(+_), voronoi) : y$$1; }; voronoi.extent = function(_) { return arguments.length ? (extent = _ == null ? null : [[+_[0][0], +_[0][1]], [+_[1][0], +_[1][1]]], voronoi) : extent && [[extent[0][0], extent[0][1]], [extent[1][0], extent[1][1]]]; }; voronoi.size = function(_) { return arguments.length ? (extent = _ == null ? null : [[0, 0], [+_[0], +_[1]]], voronoi) : extent && [extent[1][0] - extent[0][0], extent[1][1] - extent[0][1]]; }; return voronoi; }; exports.voronoi = voronoi; Object.defineProperty(exports, '__esModule', { value: true }); }))); },{}],44:[function(require,module,exports){ // https://d3js.org/d3-zoom/ Version 1.5.0. Copyright 2017 Mike Bostock. (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('d3-dispatch'), require('d3-drag'), require('d3-interpolate'), require('d3-selection'), require('d3-transition')) : typeof define === 'function' && define.amd ? define(['exports', 'd3-dispatch', 'd3-drag', 'd3-interpolate', 'd3-selection', 'd3-transition'], factory) : (factory((global.d3 = global.d3 || {}),global.d3,global.d3,global.d3,global.d3,global.d3)); }(this, (function (exports,d3Dispatch,d3Drag,d3Interpolate,d3Selection,d3Transition) { 'use strict'; var constant = function(x) { return function() { return x; }; }; function ZoomEvent(target, type, transform) { this.target = target; this.type = type; this.transform = transform; } function Transform(k, x, y) { this.k = k; this.x = x; this.y = y; } Transform.prototype = { constructor: Transform, scale: function(k) { return k === 1 ? this : new Transform(this.k * k, this.x, this.y); }, translate: function(x, y) { return x === 0 & y === 0 ? this : new Transform(this.k, this.x + this.k * x, this.y + this.k * y); }, apply: function(point) { return [point[0] * this.k + this.x, point[1] * this.k + this.y]; }, applyX: function(x) { return x * this.k + this.x; }, applyY: function(y) { return y * this.k + this.y; }, invert: function(location) { return [(location[0] - this.x) / this.k, (location[1] - this.y) / this.k]; }, invertX: function(x) { return (x - this.x) / this.k; }, invertY: function(y) { return (y - this.y) / this.k; }, rescaleX: function(x) { return x.copy().domain(x.range().map(this.invertX, this).map(x.invert, x)); }, rescaleY: function(y) { return y.copy().domain(y.range().map(this.invertY, this).map(y.invert, y)); }, toString: function() { return "translate(" + this.x + "," + this.y + ") scale(" + this.k + ")"; } }; var identity = new Transform(1, 0, 0); transform.prototype = Transform.prototype; function transform(node) { return node.__zoom || identity; } function nopropagation() { d3Selection.event.stopImmediatePropagation(); } var noevent = function() { d3Selection.event.preventDefault(); d3Selection.event.stopImmediatePropagation(); }; // Ignore right-click, since that should open the context menu. function defaultFilter() { return !d3Selection.event.button; } function defaultExtent() { var e = this, w, h; if (e instanceof SVGElement) { e = e.ownerSVGElement || e; w = e.width.baseVal.value; h = e.height.baseVal.value; } else { w = e.clientWidth; h = e.clientHeight; } return [[0, 0], [w, h]]; } function defaultTransform() { return this.__zoom || identity; } function defaultWheelDelta() { return -d3Selection.event.deltaY * (d3Selection.event.deltaMode ? 120 : 1) / 500; } function touchable() { return "ontouchstart" in this; } var zoom = function() { var filter = defaultFilter, extent = defaultExtent, wheelDelta = defaultWheelDelta, k0 = 0, k1 = Infinity, x0 = -k1, x1 = k1, y0 = x0, y1 = x1, duration = 250, interpolate = d3Interpolate.interpolateZoom, gestures = [], listeners = d3Dispatch.dispatch("start", "zoom", "end"), touchstarting, touchending, touchDelay = 500, wheelDelay = 150, clickDistance2 = 0; function zoom(selection) { selection .property("__zoom", defaultTransform) .on("wheel.zoom", wheeled) .on("mousedown.zoom", mousedowned) .on("dblclick.zoom", dblclicked) .filter(touchable) .on("touchstart.zoom", touchstarted) .on("touchmove.zoom", touchmoved) .on("touchend.zoom touchcancel.zoom", touchended) .style("touch-action", "none") .style("-webkit-tap-highlight-color", "rgba(0,0,0,0)"); } zoom.transform = function(collection, transform$$1) { var selection = collection.selection ? collection.selection() : collection; selection.property("__zoom", defaultTransform); if (collection !== selection) { schedule(collection, transform$$1); } else { selection.interrupt().each(function() { gesture(this, arguments) .start() .zoom(null, typeof transform$$1 === "function" ? transform$$1.apply(this, arguments) : transform$$1) .end(); }); } }; zoom.scaleBy = function(selection, k) { zoom.scaleTo(selection, function() { var k0 = this.__zoom.k, k1 = typeof k === "function" ? k.apply(this, arguments) : k; return k0 * k1; }); }; zoom.scaleTo = function(selection, k) { zoom.transform(selection, function() { var e = extent.apply(this, arguments), t0 = this.__zoom, p0 = centroid(e), p1 = t0.invert(p0), k1 = typeof k === "function" ? k.apply(this, arguments) : k; return constrain(translate(scale(t0, k1), p0, p1), e); }); }; zoom.translateBy = function(selection, x, y) { zoom.transform(selection, function() { return constrain(this.__zoom.translate( typeof x === "function" ? x.apply(this, arguments) : x, typeof y === "function" ? y.apply(this, arguments) : y ), extent.apply(this, arguments)); }); }; zoom.translateTo = function(selection, x, y) { zoom.transform(selection, function() { var e = extent.apply(this, arguments), t = this.__zoom, p = centroid(e); return constrain(identity.translate(p[0], p[1]).scale(t.k).translate( typeof x === "function" ? -x.apply(this, arguments) : -x, typeof y === "function" ? -y.apply(this, arguments) : -y ), e); }); }; function scale(transform$$1, k) { k = Math.max(k0, Math.min(k1, k)); return k === transform$$1.k ? transform$$1 : new Transform(k, transform$$1.x, transform$$1.y); } function translate(transform$$1, p0, p1) { var x = p0[0] - p1[0] * transform$$1.k, y = p0[1] - p1[1] * transform$$1.k; return x === transform$$1.x && y === transform$$1.y ? transform$$1 : new Transform(transform$$1.k, x, y); } function constrain(transform$$1, extent) { var dx0 = transform$$1.invertX(extent[0][0]) - x0, dx1 = transform$$1.invertX(extent[1][0]) - x1, dy0 = transform$$1.invertY(extent[0][1]) - y0, dy1 = transform$$1.invertY(extent[1][1]) - y1; return transform$$1.translate( dx1 > dx0 ? (dx0 + dx1) / 2 : Math.min(0, dx0) || Math.max(0, dx1), dy1 > dy0 ? (dy0 + dy1) / 2 : Math.min(0, dy0) || Math.max(0, dy1) ); } function centroid(extent) { return [(+extent[0][0] + +extent[1][0]) / 2, (+extent[0][1] + +extent[1][1]) / 2]; } function schedule(transition, transform$$1, center) { transition .on("start.zoom", function() { gesture(this, arguments).start(); }) .on("interrupt.zoom end.zoom", function() { gesture(this, arguments).end(); }) .tween("zoom", function() { var that = this, args = arguments, g = gesture(that, args), e = extent.apply(that, args), p = center || centroid(e), w = Math.max(e[1][0] - e[0][0], e[1][1] - e[0][1]), a = that.__zoom, b = typeof transform$$1 === "function" ? transform$$1.apply(that, args) : transform$$1, i = interpolate(a.invert(p).concat(w / a.k), b.invert(p).concat(w / b.k)); return function(t) { if (t === 1) t = b; // Avoid rounding error on end. else { var l = i(t), k = w / l[2]; t = new Transform(k, p[0] - l[0] * k, p[1] - l[1] * k); } g.zoom(null, t); }; }); } function gesture(that, args) { for (var i = 0, n = gestures.length, g; i < n; ++i) { if ((g = gestures[i]).that === that) { return g; } } return new Gesture(that, args); } function Gesture(that, args) { this.that = that; this.args = args; this.index = -1; this.active = 0; this.extent = extent.apply(that, args); } Gesture.prototype = { start: function() { if (++this.active === 1) { this.index = gestures.push(this) - 1; this.emit("start"); } return this; }, zoom: function(key, transform$$1) { if (this.mouse && key !== "mouse") this.mouse[1] = transform$$1.invert(this.mouse[0]); if (this.touch0 && key !== "touch") this.touch0[1] = transform$$1.invert(this.touch0[0]); if (this.touch1 && key !== "touch") this.touch1[1] = transform$$1.invert(this.touch1[0]); this.that.__zoom = transform$$1; this.emit("zoom"); return this; }, end: function() { if (--this.active === 0) { gestures.splice(this.index, 1); this.index = -1; this.emit("end"); } return this; }, emit: function(type) { d3Selection.customEvent(new ZoomEvent(zoom, type, this.that.__zoom), listeners.apply, listeners, [type, this.that, this.args]); } }; function wheeled() { if (!filter.apply(this, arguments)) return; var g = gesture(this, arguments), t = this.__zoom, k = Math.max(k0, Math.min(k1, t.k * Math.pow(2, wheelDelta.apply(this, arguments)))), p = d3Selection.mouse(this); // If the mouse is in the same location as before, reuse it. // If there were recent wheel events, reset the wheel idle timeout. if (g.wheel) { if (g.mouse[0][0] !== p[0] || g.mouse[0][1] !== p[1]) { g.mouse[1] = t.invert(g.mouse[0] = p); } clearTimeout(g.wheel); } // If this wheel event won’t trigger a transform change, ignore it. else if (t.k === k) return; // Otherwise, capture the mouse point and location at the start. else { g.mouse = [p, t.invert(p)]; d3Transition.interrupt(this); g.start(); } noevent(); g.wheel = setTimeout(wheelidled, wheelDelay); g.zoom("mouse", constrain(translate(scale(t, k), g.mouse[0], g.mouse[1]), g.extent)); function wheelidled() { g.wheel = null; g.end(); } } function mousedowned() { if (touchending || !filter.apply(this, arguments)) return; var g = gesture(this, arguments), v = d3Selection.select(d3Selection.event.view).on("mousemove.zoom", mousemoved, true).on("mouseup.zoom", mouseupped, true), p = d3Selection.mouse(this), x0 = d3Selection.event.clientX, y0 = d3Selection.event.clientY; d3Drag.dragDisable(d3Selection.event.view); nopropagation(); g.mouse = [p, this.__zoom.invert(p)]; d3Transition.interrupt(this); g.start(); function mousemoved() { noevent(); if (!g.moved) { var dx = d3Selection.event.clientX - x0, dy = d3Selection.event.clientY - y0; g.moved = dx * dx + dy * dy > clickDistance2; } g.zoom("mouse", constrain(translate(g.that.__zoom, g.mouse[0] = d3Selection.mouse(g.that), g.mouse[1]), g.extent)); } function mouseupped() { v.on("mousemove.zoom mouseup.zoom", null); d3Drag.dragEnable(d3Selection.event.view, g.moved); noevent(); g.end(); } } function dblclicked() { if (!filter.apply(this, arguments)) return; var t0 = this.__zoom, p0 = d3Selection.mouse(this), p1 = t0.invert(p0), k1 = t0.k * (d3Selection.event.shiftKey ? 0.5 : 2), t1 = constrain(translate(scale(t0, k1), p0, p1), extent.apply(this, arguments)); noevent(); if (duration > 0) d3Selection.select(this).transition().duration(duration).call(schedule, t1, p0); else d3Selection.select(this).call(zoom.transform, t1); } function touchstarted() { if (!filter.apply(this, arguments)) return; var g = gesture(this, arguments), touches = d3Selection.event.changedTouches, started, n = touches.length, i, t, p; nopropagation(); for (i = 0; i < n; ++i) { t = touches[i], p = d3Selection.touch(this, touches, t.identifier); p = [p, this.__zoom.invert(p), t.identifier]; if (!g.touch0) g.touch0 = p, started = true; else if (!g.touch1) g.touch1 = p; } // If this is a dbltap, reroute to the (optional) dblclick.zoom handler. if (touchstarting) { touchstarting = clearTimeout(touchstarting); if (!g.touch1) { g.end(); p = d3Selection.select(this).on("dblclick.zoom"); if (p) p.apply(this, arguments); return; } } if (started) { touchstarting = setTimeout(function() { touchstarting = null; }, touchDelay); d3Transition.interrupt(this); g.start(); } } function touchmoved() { var g = gesture(this, arguments), touches = d3Selection.event.changedTouches, n = touches.length, i, t, p, l; noevent(); if (touchstarting) touchstarting = clearTimeout(touchstarting); for (i = 0; i < n; ++i) { t = touches[i], p = d3Selection.touch(this, touches, t.identifier); if (g.touch0 && g.touch0[2] === t.identifier) g.touch0[0] = p; else if (g.touch1 && g.touch1[2] === t.identifier) g.touch1[0] = p; } t = g.that.__zoom; if (g.touch1) { var p0 = g.touch0[0], l0 = g.touch0[1], p1 = g.touch1[0], l1 = g.touch1[1], dp = (dp = p1[0] - p0[0]) * dp + (dp = p1[1] - p0[1]) * dp, dl = (dl = l1[0] - l0[0]) * dl + (dl = l1[1] - l0[1]) * dl; t = scale(t, Math.sqrt(dp / dl)); p = [(p0[0] + p1[0]) / 2, (p0[1] + p1[1]) / 2]; l = [(l0[0] + l1[0]) / 2, (l0[1] + l1[1]) / 2]; } else if (g.touch0) p = g.touch0[0], l = g.touch0[1]; else return; g.zoom("touch", constrain(translate(t, p, l), g.extent)); } function touchended() { var g = gesture(this, arguments), touches = d3Selection.event.changedTouches, n = touches.length, i, t; nopropagation(); if (touchending) clearTimeout(touchending); touchending = setTimeout(function() { touchending = null; }, touchDelay); for (i = 0; i < n; ++i) { t = touches[i]; if (g.touch0 && g.touch0[2] === t.identifier) delete g.touch0; else if (g.touch1 && g.touch1[2] === t.identifier) delete g.touch1; } if (g.touch1 && !g.touch0) g.touch0 = g.touch1, delete g.touch1; if (g.touch0) g.touch0[1] = this.__zoom.invert(g.touch0[0]); else g.end(); } zoom.wheelDelta = function(_) { return arguments.length ? (wheelDelta = typeof _ === "function" ? _ : constant(+_), zoom) : wheelDelta; }; zoom.filter = function(_) { return arguments.length ? (filter = typeof _ === "function" ? _ : constant(!!_), zoom) : filter; }; zoom.extent = function(_) { return arguments.length ? (extent = typeof _ === "function" ? _ : constant([[+_[0][0], +_[0][1]], [+_[1][0], +_[1][1]]]), zoom) : extent; }; zoom.scaleExtent = function(_) { return arguments.length ? (k0 = +_[0], k1 = +_[1], zoom) : [k0, k1]; }; zoom.translateExtent = function(_) { return arguments.length ? (x0 = +_[0][0], x1 = +_[1][0], y0 = +_[0][1], y1 = +_[1][1], zoom) : [[x0, y0], [x1, y1]]; }; zoom.duration = function(_) { return arguments.length ? (duration = +_, zoom) : duration; }; zoom.interpolate = function(_) { return arguments.length ? (interpolate = _, zoom) : interpolate; }; zoom.on = function() { var value = listeners.on.apply(listeners, arguments); return value === listeners ? zoom : value; }; zoom.clickDistance = function(_) { return arguments.length ? (clickDistance2 = (_ = +_) * _, zoom) : Math.sqrt(clickDistance2); }; return zoom; }; exports.zoom = zoom; exports.zoomTransform = transform; exports.zoomIdentity = identity; Object.defineProperty(exports, '__esModule', { value: true }); }))); },{"d3-dispatch":21,"d3-drag":22,"d3-interpolate":29,"d3-selection":37,"d3-transition":42}],45:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var d3Array = require('d3-array'); var d3Axis = require('d3-axis'); var d3Brush = require('d3-brush'); var d3Chord = require('d3-chord'); var d3Collection = require('d3-collection'); var d3Color = require('d3-color'); var d3Dispatch = require('d3-dispatch'); var d3Drag = require('d3-drag'); var d3Dsv = require('d3-dsv'); var d3Ease = require('d3-ease'); var d3Force = require('d3-force'); var d3Format = require('d3-format'); var d3Geo = require('d3-geo'); var d3Hierarchy = require('d3-hierarchy'); var d3Interpolate = require('d3-interpolate'); var d3Path = require('d3-path'); var d3Polygon = require('d3-polygon'); var d3Quadtree = require('d3-quadtree'); var d3Queue = require('d3-queue'); var d3Random = require('d3-random'); var d3Request = require('d3-request'); var d3Scale = require('d3-scale'); var d3Selection = require('d3-selection'); var d3Shape = require('d3-shape'); var d3Time = require('d3-time'); var d3TimeFormat = require('d3-time-format'); var d3Timer = require('d3-timer'); var d3Transition = require('d3-transition'); var d3Voronoi = require('d3-voronoi'); var d3Zoom = require('d3-zoom'); var version = "4.10.2"; exports.version = version; Object.keys(d3Array).forEach(function (key) { exports[key] = d3Array[key]; }); Object.keys(d3Axis).forEach(function (key) { exports[key] = d3Axis[key]; }); Object.keys(d3Brush).forEach(function (key) { exports[key] = d3Brush[key]; }); Object.keys(d3Chord).forEach(function (key) { exports[key] = d3Chord[key]; }); Object.keys(d3Collection).forEach(function (key) { exports[key] = d3Collection[key]; }); Object.keys(d3Color).forEach(function (key) { exports[key] = d3Color[key]; }); Object.keys(d3Dispatch).forEach(function (key) { exports[key] = d3Dispatch[key]; }); Object.keys(d3Drag).forEach(function (key) { exports[key] = d3Drag[key]; }); Object.keys(d3Dsv).forEach(function (key) { exports[key] = d3Dsv[key]; }); Object.keys(d3Ease).forEach(function (key) { exports[key] = d3Ease[key]; }); Object.keys(d3Force).forEach(function (key) { exports[key] = d3Force[key]; }); Object.keys(d3Format).forEach(function (key) { exports[key] = d3Format[key]; }); Object.keys(d3Geo).forEach(function (key) { exports[key] = d3Geo[key]; }); Object.keys(d3Hierarchy).forEach(function (key) { exports[key] = d3Hierarchy[key]; }); Object.keys(d3Interpolate).forEach(function (key) { exports[key] = d3Interpolate[key]; }); Object.keys(d3Path).forEach(function (key) { exports[key] = d3Path[key]; }); Object.keys(d3Polygon).forEach(function (key) { exports[key] = d3Polygon[key]; }); Object.keys(d3Quadtree).forEach(function (key) { exports[key] = d3Quadtree[key]; }); Object.keys(d3Queue).forEach(function (key) { exports[key] = d3Queue[key]; }); Object.keys(d3Random).forEach(function (key) { exports[key] = d3Random[key]; }); Object.keys(d3Request).forEach(function (key) { exports[key] = d3Request[key]; }); Object.keys(d3Scale).forEach(function (key) { exports[key] = d3Scale[key]; }); Object.keys(d3Selection).forEach(function (key) { exports[key] = d3Selection[key]; }); Object.keys(d3Shape).forEach(function (key) { exports[key] = d3Shape[key]; }); Object.keys(d3Time).forEach(function (key) { exports[key] = d3Time[key]; }); Object.keys(d3TimeFormat).forEach(function (key) { exports[key] = d3TimeFormat[key]; }); Object.keys(d3Timer).forEach(function (key) { exports[key] = d3Timer[key]; }); Object.keys(d3Transition).forEach(function (key) { exports[key] = d3Transition[key]; }); Object.keys(d3Voronoi).forEach(function (key) { exports[key] = d3Voronoi[key]; }); Object.keys(d3Zoom).forEach(function (key) { exports[key] = d3Zoom[key]; }); Object.defineProperty(exports, "event", {get: function() { return d3Selection.event; }}); },{"d3-array":15,"d3-axis":16,"d3-brush":17,"d3-chord":18,"d3-collection":19,"d3-color":20,"d3-dispatch":21,"d3-drag":22,"d3-dsv":23,"d3-ease":24,"d3-force":25,"d3-format":26,"d3-geo":27,"d3-hierarchy":28,"d3-interpolate":29,"d3-path":30,"d3-polygon":31,"d3-quadtree":32,"d3-queue":33,"d3-random":34,"d3-request":35,"d3-scale":36,"d3-selection":37,"d3-shape":38,"d3-time":40,"d3-time-format":39,"d3-timer":41,"d3-transition":42,"d3-voronoi":43,"d3-zoom":44}],46:[function(require,module,exports){ function cubicInOut(t) { return t < 0.5 ? 4.0 * t * t * t : 0.5 * Math.pow(2.0 * t - 2.0, 3.0) + 1.0 } module.exports = cubicInOut },{}],47:[function(require,module,exports){ /* Copyright (C) 2013 Ariya Hidayat Copyright (C) 2013 Thaddee Tyl Copyright (C) 2013 Mathias Bynens Copyright (C) 2012 Ariya Hidayat Copyright (C) 2012 Mathias Bynens Copyright (C) 2012 Joost-Wim Boekesteijn Copyright (C) 2012 Kris Kowal Copyright (C) 2012 Yusuke Suzuki Copyright (C) 2012 Arpad Borsos Copyright (C) 2011 Ariya Hidayat Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*jslint bitwise:true plusplus:true */ /*global esprima:true, define:true, exports:true, window: true, createLocationMarker: true, throwError: true, generateStatement: true, peek: true, parseAssignmentExpression: true, parseBlock: true, parseExpression: true, parseFunctionDeclaration: true, parseFunctionExpression: true, parseFunctionSourceElements: true, parseVariableIdentifier: true, parseLeftHandSideExpression: true, parseUnaryExpression: true, parseStatement: true, parseSourceElement: true */ (function (root, factory) { 'use strict'; // Universal Module Definition (UMD) to support AMD, CommonJS/Node.js, // Rhino, and plain browser loading. if (typeof define === 'function' && define.amd) { define(['exports'], factory); } else if (typeof exports !== 'undefined') { factory(exports); } else { factory((root.esprima = {})); } }(this, function (exports) { 'use strict'; var Token, TokenName, FnExprTokens, Syntax, PropertyKind, Messages, Regex, SyntaxTreeDelegate, source, strict, index, lineNumber, lineStart, length, delegate, lookahead, state, extra; Token = { BooleanLiteral: 1, EOF: 2, Identifier: 3, Keyword: 4, NullLiteral: 5, NumericLiteral: 6, Punctuator: 7, StringLiteral: 8, RegularExpression: 9 }; TokenName = {}; TokenName[Token.BooleanLiteral] = 'Boolean'; TokenName[Token.EOF] = ''; TokenName[Token.Identifier] = 'Identifier'; TokenName[Token.Keyword] = 'Keyword'; TokenName[Token.NullLiteral] = 'Null'; TokenName[Token.NumericLiteral] = 'Numeric'; TokenName[Token.Punctuator] = 'Punctuator'; TokenName[Token.StringLiteral] = 'String'; TokenName[Token.RegularExpression] = 'RegularExpression'; // A function following one of those tokens is an expression. FnExprTokens = ['(', '{', '[', 'in', 'typeof', 'instanceof', 'new', 'return', 'case', 'delete', 'throw', 'void', // assignment operators '=', '+=', '-=', '*=', '/=', '%=', '<<=', '>>=', '>>>=', '&=', '|=', '^=', ',', // binary/unary operators '+', '-', '*', '/', '%', '++', '--', '<<', '>>', '>>>', '&', '|', '^', '!', '~', '&&', '||', '?', ':', '===', '==', '>=', '<=', '<', '>', '!=', '!==']; Syntax = { AssignmentExpression: 'AssignmentExpression', ArrayExpression: 'ArrayExpression', BlockStatement: 'BlockStatement', BinaryExpression: 'BinaryExpression', BreakStatement: 'BreakStatement', CallExpression: 'CallExpression', CatchClause: 'CatchClause', ConditionalExpression: 'ConditionalExpression', ContinueStatement: 'ContinueStatement', DoWhileStatement: 'DoWhileStatement', DebuggerStatement: 'DebuggerStatement', EmptyStatement: 'EmptyStatement', ExpressionStatement: 'ExpressionStatement', ForStatement: 'ForStatement', ForInStatement: 'ForInStatement', FunctionDeclaration: 'FunctionDeclaration', FunctionExpression: 'FunctionExpression', Identifier: 'Identifier', IfStatement: 'IfStatement', Literal: 'Literal', LabeledStatement: 'LabeledStatement', LogicalExpression: 'LogicalExpression', MemberExpression: 'MemberExpression', NewExpression: 'NewExpression', ObjectExpression: 'ObjectExpression', Program: 'Program', Property: 'Property', ReturnStatement: 'ReturnStatement', SequenceExpression: 'SequenceExpression', SwitchStatement: 'SwitchStatement', SwitchCase: 'SwitchCase', ThisExpression: 'ThisExpression', ThrowStatement: 'ThrowStatement', TryStatement: 'TryStatement', UnaryExpression: 'UnaryExpression', UpdateExpression: 'UpdateExpression', VariableDeclaration: 'VariableDeclaration', VariableDeclarator: 'VariableDeclarator', WhileStatement: 'WhileStatement', WithStatement: 'WithStatement' }; PropertyKind = { Data: 1, Get: 2, Set: 4 }; // Error messages should be identical to V8. Messages = { UnexpectedToken: 'Unexpected token %0', UnexpectedNumber: 'Unexpected number', UnexpectedString: 'Unexpected string', UnexpectedIdentifier: 'Unexpected identifier', UnexpectedReserved: 'Unexpected reserved word', UnexpectedEOS: 'Unexpected end of input', NewlineAfterThrow: 'Illegal newline after throw', InvalidRegExp: 'Invalid regular expression', UnterminatedRegExp: 'Invalid regular expression: missing /', InvalidLHSInAssignment: 'Invalid left-hand side in assignment', InvalidLHSInForIn: 'Invalid left-hand side in for-in', MultipleDefaultsInSwitch: 'More than one default clause in switch statement', NoCatchOrFinally: 'Missing catch or finally after try', UnknownLabel: 'Undefined label \'%0\'', Redeclaration: '%0 \'%1\' has already been declared', IllegalContinue: 'Illegal continue statement', IllegalBreak: 'Illegal break statement', IllegalReturn: 'Illegal return statement', StrictModeWith: 'Strict mode code may not include a with statement', StrictCatchVariable: 'Catch variable may not be eval or arguments in strict mode', StrictVarName: 'Variable name may not be eval or arguments in strict mode', StrictParamName: 'Parameter name eval or arguments is not allowed in strict mode', StrictParamDupe: 'Strict mode function may not have duplicate parameter names', StrictFunctionName: 'Function name may not be eval or arguments in strict mode', StrictOctalLiteral: 'Octal literals are not allowed in strict mode.', StrictDelete: 'Delete of an unqualified identifier in strict mode.', StrictDuplicateProperty: 'Duplicate data property in object literal not allowed in strict mode', AccessorDataProperty: 'Object literal may not have data and accessor property with the same name', AccessorGetSet: 'Object literal may not have multiple get/set accessors with the same name', StrictLHSAssignment: 'Assignment to eval or arguments is not allowed in strict mode', StrictLHSPostfix: 'Postfix increment/decrement may not have eval or arguments operand in strict mode', StrictLHSPrefix: 'Prefix increment/decrement may not have eval or arguments operand in strict mode', StrictReservedWord: 'Use of future reserved word in strict mode' }; // See also tools/generate-unicode-regex.py. Regex = { NonAsciiIdentifierStart: new RegExp('[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0977\u0979-\u097F\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F0\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA697\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]'), NonAsciiIdentifierPart: new RegExp('[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u08A0\u08A2-\u08AC\u08E4-\u08FE\u0900-\u0963\u0966-\u096F\u0971-\u0977\u0979-\u097F\u0981-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C01-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58\u0C59\u0C60-\u0C63\u0C66-\u0C6F\u0C82\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D02\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D57\u0D60-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F0\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191C\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19D9\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1CD0-\u1CD2\u1CD4-\u1CF6\u1D00-\u1DE6\u1DFC-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u200C\u200D\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u2E2F\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099\u309A\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA697\uA69F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA827\uA840-\uA873\uA880-\uA8C4\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A\uAA7B\uAA80-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uABC0-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE26\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]') }; // Ensure the condition is true, otherwise throw an error. // This is only to have a better contract semantic, i.e. another safety net // to catch a logic error. The condition shall be fulfilled in normal case. // Do NOT use this to enforce a certain condition on any user input. function assert(condition, message) { if (!condition) { throw new Error('ASSERT: ' + message); } } function isDecimalDigit(ch) { return (ch >= 48 && ch <= 57); // 0..9 } function isHexDigit(ch) { return '0123456789abcdefABCDEF'.indexOf(ch) >= 0; } function isOctalDigit(ch) { return '01234567'.indexOf(ch) >= 0; } // 7.2 White Space function isWhiteSpace(ch) { return (ch === 0x20) || (ch === 0x09) || (ch === 0x0B) || (ch === 0x0C) || (ch === 0xA0) || (ch >= 0x1680 && [0x1680, 0x180E, 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007, 0x2008, 0x2009, 0x200A, 0x202F, 0x205F, 0x3000, 0xFEFF].indexOf(ch) >= 0); } // 7.3 Line Terminators function isLineTerminator(ch) { return (ch === 0x0A) || (ch === 0x0D) || (ch === 0x2028) || (ch === 0x2029); } // 7.6 Identifier Names and Identifiers function isIdentifierStart(ch) { return (ch === 0x24) || (ch === 0x5F) || // $ (dollar) and _ (underscore) (ch >= 0x41 && ch <= 0x5A) || // A..Z (ch >= 0x61 && ch <= 0x7A) || // a..z (ch === 0x5C) || // \ (backslash) ((ch >= 0x80) && Regex.NonAsciiIdentifierStart.test(String.fromCharCode(ch))); } function isIdentifierPart(ch) { return (ch === 0x24) || (ch === 0x5F) || // $ (dollar) and _ (underscore) (ch >= 0x41 && ch <= 0x5A) || // A..Z (ch >= 0x61 && ch <= 0x7A) || // a..z (ch >= 0x30 && ch <= 0x39) || // 0..9 (ch === 0x5C) || // \ (backslash) ((ch >= 0x80) && Regex.NonAsciiIdentifierPart.test(String.fromCharCode(ch))); } // 7.6.1.2 Future Reserved Words function isFutureReservedWord(id) { switch (id) { case 'class': case 'enum': case 'export': case 'extends': case 'import': case 'super': return true; default: return false; } } function isStrictModeReservedWord(id) { switch (id) { case 'implements': case 'interface': case 'package': case 'private': case 'protected': case 'public': case 'static': case 'yield': case 'let': return true; default: return false; } } function isRestrictedWord(id) { return id === 'eval' || id === 'arguments'; } // 7.6.1.1 Keywords function isKeyword(id) { if (strict && isStrictModeReservedWord(id)) { return true; } // 'const' is specialized as Keyword in V8. // 'yield' and 'let' are for compatiblity with SpiderMonkey and ES.next. // Some others are from future reserved words. switch (id.length) { case 2: return (id === 'if') || (id === 'in') || (id === 'do'); case 3: return (id === 'var') || (id === 'for') || (id === 'new') || (id === 'try') || (id === 'let'); case 4: return (id === 'this') || (id === 'else') || (id === 'case') || (id === 'void') || (id === 'with') || (id === 'enum'); case 5: return (id === 'while') || (id === 'break') || (id === 'catch') || (id === 'throw') || (id === 'const') || (id === 'yield') || (id === 'class') || (id === 'super'); case 6: return (id === 'return') || (id === 'typeof') || (id === 'delete') || (id === 'switch') || (id === 'export') || (id === 'import'); case 7: return (id === 'default') || (id === 'finally') || (id === 'extends'); case 8: return (id === 'function') || (id === 'continue') || (id === 'debugger'); case 10: return (id === 'instanceof'); default: return false; } } // 7.4 Comments function addComment(type, value, start, end, loc) { var comment, attacher; assert(typeof start === 'number', 'Comment must have valid position'); // Because the way the actual token is scanned, often the comments // (if any) are skipped twice during the lexical analysis. // Thus, we need to skip adding a comment if the comment array already // handled it. if (state.lastCommentStart >= start) { return; } state.lastCommentStart = start; comment = { type: type, value: value }; if (extra.range) { comment.range = [start, end]; } if (extra.loc) { comment.loc = loc; } extra.comments.push(comment); if (extra.attachComment) { attacher = { comment: comment, leading: null, trailing: null, range: [start, end] }; extra.pendingComments.push(attacher); } } function skipSingleLineComment(offset) { var start, loc, ch, comment; start = index - offset; loc = { start: { line: lineNumber, column: index - lineStart - offset } }; while (index < length) { ch = source.charCodeAt(index); ++index; if (isLineTerminator(ch)) { if (extra.comments) { comment = source.slice(start + offset, index - 1); loc.end = { line: lineNumber, column: index - lineStart - 1 }; addComment('Line', comment, start, index - 1, loc); } if (ch === 13 && source.charCodeAt(index) === 10) { ++index; } ++lineNumber; lineStart = index; return; } } if (extra.comments) { comment = source.slice(start + offset, index); loc.end = { line: lineNumber, column: index - lineStart }; addComment('Line', comment, start, index, loc); } } function skipMultiLineComment() { var start, loc, ch, comment; if (extra.comments) { start = index - 2; loc = { start: { line: lineNumber, column: index - lineStart - 2 } }; } while (index < length) { ch = source.charCodeAt(index); if (isLineTerminator(ch)) { if (ch === 0x0D && source.charCodeAt(index + 1) === 0x0A) { ++index; } ++lineNumber; ++index; lineStart = index; if (index >= length) { throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); } } else if (ch === 0x2A) { // Block comment ends with '*/'. if (source.charCodeAt(index + 1) === 0x2F) { ++index; ++index; if (extra.comments) { comment = source.slice(start + 2, index - 2); loc.end = { line: lineNumber, column: index - lineStart }; addComment('Block', comment, start, index, loc); } return; } ++index; } else { ++index; } } throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); } function skipComment() { var ch, start; start = (index === 0); while (index < length) { ch = source.charCodeAt(index); if (isWhiteSpace(ch)) { ++index; } else if (isLineTerminator(ch)) { ++index; if (ch === 0x0D && source.charCodeAt(index) === 0x0A) { ++index; } ++lineNumber; lineStart = index; start = true; } else if (ch === 0x2F) { // U+002F is '/' ch = source.charCodeAt(index + 1); if (ch === 0x2F) { ++index; ++index; skipSingleLineComment(2); start = true; } else if (ch === 0x2A) { // U+002A is '*' ++index; ++index; skipMultiLineComment(); } else { break; } } else if (start && ch === 0x2D) { // U+002D is '-' // U+003E is '>' if ((source.charCodeAt(index + 1) === 0x2D) && (source.charCodeAt(index + 2) === 0x3E)) { // '-->' is a single-line comment index += 3; skipSingleLineComment(3); } else { break; } } else if (ch === 0x3C) { // U+003C is '<' if (source.slice(index + 1, index + 4) === '!--') { ++index; // `<` ++index; // `!` ++index; // `-` ++index; // `-` skipSingleLineComment(4); } else { break; } } else { break; } } } function scanHexEscape(prefix) { var i, len, ch, code = 0; len = (prefix === 'u') ? 4 : 2; for (i = 0; i < len; ++i) { if (index < length && isHexDigit(source[index])) { ch = source[index++]; code = code * 16 + '0123456789abcdef'.indexOf(ch.toLowerCase()); } else { return ''; } } return String.fromCharCode(code); } function getEscapedIdentifier() { var ch, id; ch = source.charCodeAt(index++); id = String.fromCharCode(ch); // '\u' (U+005C, U+0075) denotes an escaped character. if (ch === 0x5C) { if (source.charCodeAt(index) !== 0x75) { throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); } ++index; ch = scanHexEscape('u'); if (!ch || ch === '\\' || !isIdentifierStart(ch.charCodeAt(0))) { throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); } id = ch; } while (index < length) { ch = source.charCodeAt(index); if (!isIdentifierPart(ch)) { break; } ++index; id += String.fromCharCode(ch); // '\u' (U+005C, U+0075) denotes an escaped character. if (ch === 0x5C) { id = id.substr(0, id.length - 1); if (source.charCodeAt(index) !== 0x75) { throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); } ++index; ch = scanHexEscape('u'); if (!ch || ch === '\\' || !isIdentifierPart(ch.charCodeAt(0))) { throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); } id += ch; } } return id; } function getIdentifier() { var start, ch; start = index++; while (index < length) { ch = source.charCodeAt(index); if (ch === 0x5C) { // Blackslash (U+005C) marks Unicode escape sequence. index = start; return getEscapedIdentifier(); } if (isIdentifierPart(ch)) { ++index; } else { break; } } return source.slice(start, index); } function scanIdentifier() { var start, id, type; start = index; // Backslash (U+005C) starts an escaped character. id = (source.charCodeAt(index) === 0x5C) ? getEscapedIdentifier() : getIdentifier(); // There is no keyword or literal with only one character. // Thus, it must be an identifier. if (id.length === 1) { type = Token.Identifier; } else if (isKeyword(id)) { type = Token.Keyword; } else if (id === 'null') { type = Token.NullLiteral; } else if (id === 'true' || id === 'false') { type = Token.BooleanLiteral; } else { type = Token.Identifier; } return { type: type, value: id, lineNumber: lineNumber, lineStart: lineStart, range: [start, index] }; } // 7.7 Punctuators function scanPunctuator() { var start = index, code = source.charCodeAt(index), code2, ch1 = source[index], ch2, ch3, ch4; switch (code) { // Check for most common single-character punctuators. case 0x2E: // . dot case 0x28: // ( open bracket case 0x29: // ) close bracket case 0x3B: // ; semicolon case 0x2C: // , comma case 0x7B: // { open curly brace case 0x7D: // } close curly brace case 0x5B: // [ case 0x5D: // ] case 0x3A: // : case 0x3F: // ? case 0x7E: // ~ ++index; if (extra.tokenize) { if (code === 0x28) { extra.openParenToken = extra.tokens.length; } else if (code === 0x7B) { extra.openCurlyToken = extra.tokens.length; } } return { type: Token.Punctuator, value: String.fromCharCode(code), lineNumber: lineNumber, lineStart: lineStart, range: [start, index] }; default: code2 = source.charCodeAt(index + 1); // '=' (U+003D) marks an assignment or comparison operator. if (code2 === 0x3D) { switch (code) { case 0x25: // % case 0x26: // & case 0x2A: // *: case 0x2B: // + case 0x2D: // - case 0x2F: // / case 0x3C: // < case 0x3E: // > case 0x5E: // ^ case 0x7C: // | index += 2; return { type: Token.Punctuator, value: String.fromCharCode(code) + String.fromCharCode(code2), lineNumber: lineNumber, lineStart: lineStart, range: [start, index] }; case 0x21: // ! case 0x3D: // = index += 2; // !== and === if (source.charCodeAt(index) === 0x3D) { ++index; } return { type: Token.Punctuator, value: source.slice(start, index), lineNumber: lineNumber, lineStart: lineStart, range: [start, index] }; default: break; } } break; } // Peek more characters. ch2 = source[index + 1]; ch3 = source[index + 2]; ch4 = source[index + 3]; // 4-character punctuator: >>>= if (ch1 === '>' && ch2 === '>' && ch3 === '>') { if (ch4 === '=') { index += 4; return { type: Token.Punctuator, value: '>>>=', lineNumber: lineNumber, lineStart: lineStart, range: [start, index] }; } } // 3-character punctuators: === !== >>> <<= >>= if (ch1 === '>' && ch2 === '>' && ch3 === '>') { index += 3; return { type: Token.Punctuator, value: '>>>', lineNumber: lineNumber, lineStart: lineStart, range: [start, index] }; } if (ch1 === '<' && ch2 === '<' && ch3 === '=') { index += 3; return { type: Token.Punctuator, value: '<<=', lineNumber: lineNumber, lineStart: lineStart, range: [start, index] }; } if (ch1 === '>' && ch2 === '>' && ch3 === '=') { index += 3; return { type: Token.Punctuator, value: '>>=', lineNumber: lineNumber, lineStart: lineStart, range: [start, index] }; } // Other 2-character punctuators: ++ -- << >> && || if (ch1 === ch2 && ('+-<>&|'.indexOf(ch1) >= 0)) { index += 2; return { type: Token.Punctuator, value: ch1 + ch2, lineNumber: lineNumber, lineStart: lineStart, range: [start, index] }; } if ('<>=!+-*%&|^/'.indexOf(ch1) >= 0) { ++index; return { type: Token.Punctuator, value: ch1, lineNumber: lineNumber, lineStart: lineStart, range: [start, index] }; } throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); } // 7.8.3 Numeric Literals function scanHexLiteral(start) { var number = ''; while (index < length) { if (!isHexDigit(source[index])) { break; } number += source[index++]; } if (number.length === 0) { throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); } if (isIdentifierStart(source.charCodeAt(index))) { throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); } return { type: Token.NumericLiteral, value: parseInt('0x' + number, 16), lineNumber: lineNumber, lineStart: lineStart, range: [start, index] }; } function scanOctalLiteral(start) { var number = '0' + source[index++]; while (index < length) { if (!isOctalDigit(source[index])) { break; } number += source[index++]; } if (isIdentifierStart(source.charCodeAt(index)) || isDecimalDigit(source.charCodeAt(index))) { throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); } return { type: Token.NumericLiteral, value: parseInt(number, 8), octal: true, lineNumber: lineNumber, lineStart: lineStart, range: [start, index] }; } function scanNumericLiteral() { var number, start, ch; ch = source[index]; assert(isDecimalDigit(ch.charCodeAt(0)) || (ch === '.'), 'Numeric literal must start with a decimal digit or a decimal point'); start = index; number = ''; if (ch !== '.') { number = source[index++]; ch = source[index]; // Hex number starts with '0x'. // Octal number starts with '0'. if (number === '0') { if (ch === 'x' || ch === 'X') { ++index; return scanHexLiteral(start); } if (isOctalDigit(ch)) { return scanOctalLiteral(start); } // decimal number starts with '0' such as '09' is illegal. if (ch && isDecimalDigit(ch.charCodeAt(0))) { throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); } } while (isDecimalDigit(source.charCodeAt(index))) { number += source[index++]; } ch = source[index]; } if (ch === '.') { number += source[index++]; while (isDecimalDigit(source.charCodeAt(index))) { number += source[index++]; } ch = source[index]; } if (ch === 'e' || ch === 'E') { number += source[index++]; ch = source[index]; if (ch === '+' || ch === '-') { number += source[index++]; } if (isDecimalDigit(source.charCodeAt(index))) { while (isDecimalDigit(source.charCodeAt(index))) { number += source[index++]; } } else { throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); } } if (isIdentifierStart(source.charCodeAt(index))) { throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); } return { type: Token.NumericLiteral, value: parseFloat(number), lineNumber: lineNumber, lineStart: lineStart, range: [start, index] }; } // 7.8.4 String Literals function scanStringLiteral() { var str = '', quote, start, ch, code, unescaped, restore, octal = false; quote = source[index]; assert((quote === '\'' || quote === '"'), 'String literal must starts with a quote'); start = index; ++index; while (index < length) { ch = source[index++]; if (ch === quote) { quote = ''; break; } else if (ch === '\\') { ch = source[index++]; if (!ch || !isLineTerminator(ch.charCodeAt(0))) { switch (ch) { case 'n': str += '\n'; break; case 'r': str += '\r'; break; case 't': str += '\t'; break; case 'u': case 'x': restore = index; unescaped = scanHexEscape(ch); if (unescaped) { str += unescaped; } else { index = restore; str += ch; } break; case 'b': str += '\b'; break; case 'f': str += '\f'; break; case 'v': str += '\x0B'; break; default: if (isOctalDigit(ch)) { code = '01234567'.indexOf(ch); // \0 is not octal escape sequence if (code !== 0) { octal = true; } if (index < length && isOctalDigit(source[index])) { octal = true; code = code * 8 + '01234567'.indexOf(source[index++]); // 3 digits are only allowed when string starts // with 0, 1, 2, 3 if ('0123'.indexOf(ch) >= 0 && index < length && isOctalDigit(source[index])) { code = code * 8 + '01234567'.indexOf(source[index++]); } } str += String.fromCharCode(code); } else { str += ch; } break; } } else { ++lineNumber; if (ch === '\r' && source[index] === '\n') { ++index; } lineStart = index; } } else if (isLineTerminator(ch.charCodeAt(0))) { break; } else { str += ch; } } if (quote !== '') { throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); } return { type: Token.StringLiteral, value: str, octal: octal, lineNumber: lineNumber, lineStart: lineStart, range: [start, index] }; } function scanRegExp() { var str, ch, start, pattern, flags, value, classMarker = false, restore, terminated = false; lookahead = null; skipComment(); start = index; ch = source[index]; assert(ch === '/', 'Regular expression literal must start with a slash'); str = source[index++]; while (index < length) { ch = source[index++]; str += ch; if (ch === '\\') { ch = source[index++]; // ECMA-262 7.8.5 if (isLineTerminator(ch.charCodeAt(0))) { throwError({}, Messages.UnterminatedRegExp); } str += ch; } else if (isLineTerminator(ch.charCodeAt(0))) { throwError({}, Messages.UnterminatedRegExp); } else if (classMarker) { if (ch === ']') { classMarker = false; } } else { if (ch === '/') { terminated = true; break; } else if (ch === '[') { classMarker = true; } } } if (!terminated) { throwError({}, Messages.UnterminatedRegExp); } // Exclude leading and trailing slash. pattern = str.substr(1, str.length - 2); flags = ''; while (index < length) { ch = source[index]; if (!isIdentifierPart(ch.charCodeAt(0))) { break; } ++index; if (ch === '\\' && index < length) { ch = source[index]; if (ch === 'u') { ++index; restore = index; ch = scanHexEscape('u'); if (ch) { flags += ch; for (str += '\\u'; restore < index; ++restore) { str += source[restore]; } } else { index = restore; flags += 'u'; str += '\\u'; } } else { str += '\\'; } } else { flags += ch; str += ch; } } try { value = new RegExp(pattern, flags); } catch (e) { throwError({}, Messages.InvalidRegExp); } if (extra.tokenize) { return { type: Token.RegularExpression, value: value, lineNumber: lineNumber, lineStart: lineStart, range: [start, index] }; } return { literal: str, value: value, range: [start, index] }; } function collectRegex() { var pos, loc, regex, token; skipComment(); pos = index; loc = { start: { line: lineNumber, column: index - lineStart } }; regex = scanRegExp(); loc.end = { line: lineNumber, column: index - lineStart }; if (!extra.tokenize) { // Pop the previous token, which is likely '/' or '/=' if (extra.tokens.length > 0) { token = extra.tokens[extra.tokens.length - 1]; if (token.range[0] === pos && token.type === 'Punctuator') { if (token.value === '/' || token.value === '/=') { extra.tokens.pop(); } } } extra.tokens.push({ type: 'RegularExpression', value: regex.literal, range: [pos, index], loc: loc }); } return regex; } function isIdentifierName(token) { return token.type === Token.Identifier || token.type === Token.Keyword || token.type === Token.BooleanLiteral || token.type === Token.NullLiteral; } function advanceSlash() { var prevToken, checkToken; // Using the following algorithm: // https://github.com/mozilla/sweet.js/wiki/design prevToken = extra.tokens[extra.tokens.length - 1]; if (!prevToken) { // Nothing before that: it cannot be a division. return collectRegex(); } if (prevToken.type === 'Punctuator') { if (prevToken.value === ']') { return scanPunctuator(); } if (prevToken.value === ')') { checkToken = extra.tokens[extra.openParenToken - 1]; if (checkToken && checkToken.type === 'Keyword' && (checkToken.value === 'if' || checkToken.value === 'while' || checkToken.value === 'for' || checkToken.value === 'with')) { return collectRegex(); } return scanPunctuator(); } if (prevToken.value === '}') { // Dividing a function by anything makes little sense, // but we have to check for that. if (extra.tokens[extra.openCurlyToken - 3] && extra.tokens[extra.openCurlyToken - 3].type === 'Keyword') { // Anonymous function. checkToken = extra.tokens[extra.openCurlyToken - 4]; if (!checkToken) { return scanPunctuator(); } } else if (extra.tokens[extra.openCurlyToken - 4] && extra.tokens[extra.openCurlyToken - 4].type === 'Keyword') { // Named function. checkToken = extra.tokens[extra.openCurlyToken - 5]; if (!checkToken) { return collectRegex(); } } else { return scanPunctuator(); } // checkToken determines whether the function is // a declaration or an expression. if (FnExprTokens.indexOf(checkToken.value) >= 0) { // It is an expression. return scanPunctuator(); } // It is a declaration. return collectRegex(); } return collectRegex(); } if (prevToken.type === 'Keyword') { return collectRegex(); } return scanPunctuator(); } function advance() { var ch; skipComment(); if (index >= length) { return { type: Token.EOF, lineNumber: lineNumber, lineStart: lineStart, range: [index, index] }; } ch = source.charCodeAt(index); // Very common: ( and ) and ; if (ch === 0x28 || ch === 0x29 || ch === 0x3A) { return scanPunctuator(); } // String literal starts with single quote (U+0027) or double quote (U+0022). if (ch === 0x27 || ch === 0x22) { return scanStringLiteral(); } if (isIdentifierStart(ch)) { return scanIdentifier(); } // Dot (.) U+002E can also start a floating-point number, hence the need // to check the next character. if (ch === 0x2E) { if (isDecimalDigit(source.charCodeAt(index + 1))) { return scanNumericLiteral(); } return scanPunctuator(); } if (isDecimalDigit(ch)) { return scanNumericLiteral(); } // Slash (/) U+002F can also start a regex. if (extra.tokenize && ch === 0x2F) { return advanceSlash(); } return scanPunctuator(); } function collectToken() { var start, loc, token, range, value; skipComment(); start = index; loc = { start: { line: lineNumber, column: index - lineStart } }; token = advance(); loc.end = { line: lineNumber, column: index - lineStart }; if (token.type !== Token.EOF) { range = [token.range[0], token.range[1]]; value = source.slice(token.range[0], token.range[1]); extra.tokens.push({ type: TokenName[token.type], value: value, range: range, loc: loc }); } return token; } function lex() { var token; token = lookahead; index = token.range[1]; lineNumber = token.lineNumber; lineStart = token.lineStart; lookahead = (typeof extra.tokens !== 'undefined') ? collectToken() : advance(); index = token.range[1]; lineNumber = token.lineNumber; lineStart = token.lineStart; return token; } function peek() { var pos, line, start; pos = index; line = lineNumber; start = lineStart; lookahead = (typeof extra.tokens !== 'undefined') ? collectToken() : advance(); index = pos; lineNumber = line; lineStart = start; } SyntaxTreeDelegate = { name: 'SyntaxTree', markStart: function () { skipComment(); if (extra.loc) { state.markerStack.push(index - lineStart); state.markerStack.push(lineNumber); } if (extra.range) { state.markerStack.push(index); } }, processComment: function (node) { var i, attacher, pos, len, candidate; if (typeof node.type === 'undefined' || node.type === Syntax.Program) { return; } // Check for possible additional trailing comments. peek(); for (i = 0; i < extra.pendingComments.length; ++i) { attacher = extra.pendingComments[i]; if (node.range[0] >= attacher.comment.range[1]) { candidate = attacher.leading; if (candidate) { pos = candidate.range[0]; len = candidate.range[1] - pos; if (node.range[0] <= pos && (node.range[1] - node.range[0] >= len)) { attacher.leading = node; } } else { attacher.leading = node; } } if (node.range[1] <= attacher.comment.range[0]) { candidate = attacher.trailing; if (candidate) { pos = candidate.range[0]; len = candidate.range[1] - pos; if (node.range[0] <= pos && (node.range[1] - node.range[0] >= len)) { attacher.trailing = node; } } else { attacher.trailing = node; } } } }, markEnd: function (node) { if (extra.range) { node.range = [state.markerStack.pop(), index]; } if (extra.loc) { node.loc = { start: { line: state.markerStack.pop(), column: state.markerStack.pop() }, end: { line: lineNumber, column: index - lineStart } }; this.postProcess(node); } if (extra.attachComment) { this.processComment(node); } return node; }, markEndIf: function (node) { if (node.range || node.loc) { if (extra.loc) { state.markerStack.pop(); state.markerStack.pop(); } if (extra.range) { state.markerStack.pop(); } } else { this.markEnd(node); } return node; }, postProcess: function (node) { if (extra.source) { node.loc.source = extra.source; } return node; }, createArrayExpression: function (elements) { return { type: Syntax.ArrayExpression, elements: elements }; }, createAssignmentExpression: function (operator, left, right) { return { type: Syntax.AssignmentExpression, operator: operator, left: left, right: right }; }, createBinaryExpression: function (operator, left, right) { var type = (operator === '||' || operator === '&&') ? Syntax.LogicalExpression : Syntax.BinaryExpression; return { type: type, operator: operator, left: left, right: right }; }, createBlockStatement: function (body) { return { type: Syntax.BlockStatement, body: body }; }, createBreakStatement: function (label) { return { type: Syntax.BreakStatement, label: label }; }, createCallExpression: function (callee, args) { return { type: Syntax.CallExpression, callee: callee, 'arguments': args }; }, createCatchClause: function (param, body) { return { type: Syntax.CatchClause, param: param, body: body }; }, createConditionalExpression: function (test, consequent, alternate) { return { type: Syntax.ConditionalExpression, test: test, consequent: consequent, alternate: alternate }; }, createContinueStatement: function (label) { return { type: Syntax.ContinueStatement, label: label }; }, createDebuggerStatement: function () { return { type: Syntax.DebuggerStatement }; }, createDoWhileStatement: function (body, test) { return { type: Syntax.DoWhileStatement, body: body, test: test }; }, createEmptyStatement: function () { return { type: Syntax.EmptyStatement }; }, createExpressionStatement: function (expression) { return { type: Syntax.ExpressionStatement, expression: expression }; }, createForStatement: function (init, test, update, body) { return { type: Syntax.ForStatement, init: init, test: test, update: update, body: body }; }, createForInStatement: function (left, right, body) { return { type: Syntax.ForInStatement, left: left, right: right, body: body, each: false }; }, createFunctionDeclaration: function (id, params, defaults, body) { return { type: Syntax.FunctionDeclaration, id: id, params: params, defaults: defaults, body: body, rest: null, generator: false, expression: false }; }, createFunctionExpression: function (id, params, defaults, body) { return { type: Syntax.FunctionExpression, id: id, params: params, defaults: defaults, body: body, rest: null, generator: false, expression: false }; }, createIdentifier: function (name) { return { type: Syntax.Identifier, name: name }; }, createIfStatement: function (test, consequent, alternate) { return { type: Syntax.IfStatement, test: test, consequent: consequent, alternate: alternate }; }, createLabeledStatement: function (label, body) { return { type: Syntax.LabeledStatement, label: label, body: body }; }, createLiteral: function (token) { return { type: Syntax.Literal, value: token.value, raw: source.slice(token.range[0], token.range[1]) }; }, createMemberExpression: function (accessor, object, property) { return { type: Syntax.MemberExpression, computed: accessor === '[', object: object, property: property }; }, createNewExpression: function (callee, args) { return { type: Syntax.NewExpression, callee: callee, 'arguments': args }; }, createObjectExpression: function (properties) { return { type: Syntax.ObjectExpression, properties: properties }; }, createPostfixExpression: function (operator, argument) { return { type: Syntax.UpdateExpression, operator: operator, argument: argument, prefix: false }; }, createProgram: function (body) { return { type: Syntax.Program, body: body }; }, createProperty: function (kind, key, value) { return { type: Syntax.Property, key: key, value: value, kind: kind }; }, createReturnStatement: function (argument) { return { type: Syntax.ReturnStatement, argument: argument }; }, createSequenceExpression: function (expressions) { return { type: Syntax.SequenceExpression, expressions: expressions }; }, createSwitchCase: function (test, consequent) { return { type: Syntax.SwitchCase, test: test, consequent: consequent }; }, createSwitchStatement: function (discriminant, cases) { return { type: Syntax.SwitchStatement, discriminant: discriminant, cases: cases }; }, createThisExpression: function () { return { type: Syntax.ThisExpression }; }, createThrowStatement: function (argument) { return { type: Syntax.ThrowStatement, argument: argument }; }, createTryStatement: function (block, guardedHandlers, handlers, finalizer) { return { type: Syntax.TryStatement, block: block, guardedHandlers: guardedHandlers, handlers: handlers, finalizer: finalizer }; }, createUnaryExpression: function (operator, argument) { if (operator === '++' || operator === '--') { return { type: Syntax.UpdateExpression, operator: operator, argument: argument, prefix: true }; } return { type: Syntax.UnaryExpression, operator: operator, argument: argument, prefix: true }; }, createVariableDeclaration: function (declarations, kind) { return { type: Syntax.VariableDeclaration, declarations: declarations, kind: kind }; }, createVariableDeclarator: function (id, init) { return { type: Syntax.VariableDeclarator, id: id, init: init }; }, createWhileStatement: function (test, body) { return { type: Syntax.WhileStatement, test: test, body: body }; }, createWithStatement: function (object, body) { return { type: Syntax.WithStatement, object: object, body: body }; } }; // Return true if there is a line terminator before the next token. function peekLineTerminator() { var pos, line, start, found; pos = index; line = lineNumber; start = lineStart; skipComment(); found = lineNumber !== line; index = pos; lineNumber = line; lineStart = start; return found; } // Throw an exception function throwError(token, messageFormat) { var error, args = Array.prototype.slice.call(arguments, 2), msg = messageFormat.replace( /%(\d)/g, function (whole, index) { assert(index < args.length, 'Message reference must be in range'); return args[index]; } ); if (typeof token.lineNumber === 'number') { error = new Error('Line ' + token.lineNumber + ': ' + msg); error.index = token.range[0]; error.lineNumber = token.lineNumber; error.column = token.range[0] - lineStart + 1; } else { error = new Error('Line ' + lineNumber + ': ' + msg); error.index = index; error.lineNumber = lineNumber; error.column = index - lineStart + 1; } error.description = msg; throw error; } function throwErrorTolerant() { try { throwError.apply(null, arguments); } catch (e) { if (extra.errors) { extra.errors.push(e); } else { throw e; } } } // Throw an exception because of the token. function throwUnexpected(token) { if (token.type === Token.EOF) { throwError(token, Messages.UnexpectedEOS); } if (token.type === Token.NumericLiteral) { throwError(token, Messages.UnexpectedNumber); } if (token.type === Token.StringLiteral) { throwError(token, Messages.UnexpectedString); } if (token.type === Token.Identifier) { throwError(token, Messages.UnexpectedIdentifier); } if (token.type === Token.Keyword) { if (isFutureReservedWord(token.value)) { throwError(token, Messages.UnexpectedReserved); } else if (strict && isStrictModeReservedWord(token.value)) { throwErrorTolerant(token, Messages.StrictReservedWord); return; } throwError(token, Messages.UnexpectedToken, token.value); } // BooleanLiteral, NullLiteral, or Punctuator. throwError(token, Messages.UnexpectedToken, token.value); } // Expect the next token to match the specified punctuator. // If not, an exception will be thrown. function expect(value) { var token = lex(); if (token.type !== Token.Punctuator || token.value !== value) { throwUnexpected(token); } } // Expect the next token to match the specified keyword. // If not, an exception will be thrown. function expectKeyword(keyword) { var token = lex(); if (token.type !== Token.Keyword || token.value !== keyword) { throwUnexpected(token); } } // Return true if the next token matches the specified punctuator. function match(value) { return lookahead.type === Token.Punctuator && lookahead.value === value; } // Return true if the next token matches the specified keyword function matchKeyword(keyword) { return lookahead.type === Token.Keyword && lookahead.value === keyword; } // Return true if the next token is an assignment operator function matchAssign() { var op; if (lookahead.type !== Token.Punctuator) { return false; } op = lookahead.value; return op === '=' || op === '*=' || op === '/=' || op === '%=' || op === '+=' || op === '-=' || op === '<<=' || op === '>>=' || op === '>>>=' || op === '&=' || op === '^=' || op === '|='; } function consumeSemicolon() { var line; // Catch the very common case first: immediately a semicolon (U+003B). if (source.charCodeAt(index) === 0x3B) { lex(); return; } line = lineNumber; skipComment(); if (lineNumber !== line) { return; } if (match(';')) { lex(); return; } if (lookahead.type !== Token.EOF && !match('}')) { throwUnexpected(lookahead); } } // Return true if provided expression is LeftHandSideExpression function isLeftHandSide(expr) { return expr.type === Syntax.Identifier || expr.type === Syntax.MemberExpression; } // 11.1.4 Array Initialiser function parseArrayInitialiser() { var elements = []; expect('['); while (!match(']')) { if (match(',')) { lex(); elements.push(null); } else { elements.push(parseAssignmentExpression()); if (!match(']')) { expect(','); } } } expect(']'); return delegate.createArrayExpression(elements); } // 11.1.5 Object Initialiser function parsePropertyFunction(param, first) { var previousStrict, body; previousStrict = strict; delegate.markStart(); body = parseFunctionSourceElements(); if (first && strict && isRestrictedWord(param[0].name)) { throwErrorTolerant(first, Messages.StrictParamName); } strict = previousStrict; return delegate.markEnd(delegate.createFunctionExpression(null, param, [], body)); } function parseObjectPropertyKey() { var token; delegate.markStart(); token = lex(); // Note: This function is called only from parseObjectProperty(), where // EOF and Punctuator tokens are already filtered out. if (token.type === Token.StringLiteral || token.type === Token.NumericLiteral) { if (strict && token.octal) { throwErrorTolerant(token, Messages.StrictOctalLiteral); } return delegate.markEnd(delegate.createLiteral(token)); } return delegate.markEnd(delegate.createIdentifier(token.value)); } function parseObjectProperty() { var token, key, id, value, param; token = lookahead; delegate.markStart(); if (token.type === Token.Identifier) { id = parseObjectPropertyKey(); // Property Assignment: Getter and Setter. if (token.value === 'get' && !match(':')) { key = parseObjectPropertyKey(); expect('('); expect(')'); value = parsePropertyFunction([]); return delegate.markEnd(delegate.createProperty('get', key, value)); } if (token.value === 'set' && !match(':')) { key = parseObjectPropertyKey(); expect('('); token = lookahead; if (token.type !== Token.Identifier) { expect(')'); throwErrorTolerant(token, Messages.UnexpectedToken, token.value); value = parsePropertyFunction([]); } else { param = [ parseVariableIdentifier() ]; expect(')'); value = parsePropertyFunction(param, token); } return delegate.markEnd(delegate.createProperty('set', key, value)); } expect(':'); value = parseAssignmentExpression(); return delegate.markEnd(delegate.createProperty('init', id, value)); } if (token.type === Token.EOF || token.type === Token.Punctuator) { throwUnexpected(token); } else { key = parseObjectPropertyKey(); expect(':'); value = parseAssignmentExpression(); return delegate.markEnd(delegate.createProperty('init', key, value)); } } function parseObjectInitialiser() { var properties = [], property, name, key, kind, map = {}, toString = String; expect('{'); while (!match('}')) { property = parseObjectProperty(); if (property.key.type === Syntax.Identifier) { name = property.key.name; } else { name = toString(property.key.value); } kind = (property.kind === 'init') ? PropertyKind.Data : (property.kind === 'get') ? PropertyKind.Get : PropertyKind.Set; key = '$' + name; if (Object.prototype.hasOwnProperty.call(map, key)) { if (map[key] === PropertyKind.Data) { if (strict && kind === PropertyKind.Data) { throwErrorTolerant({}, Messages.StrictDuplicateProperty); } else if (kind !== PropertyKind.Data) { throwErrorTolerant({}, Messages.AccessorDataProperty); } } else { if (kind === PropertyKind.Data) { throwErrorTolerant({}, Messages.AccessorDataProperty); } else if (map[key] & kind) { throwErrorTolerant({}, Messages.AccessorGetSet); } } map[key] |= kind; } else { map[key] = kind; } properties.push(property); if (!match('}')) { expect(','); } } expect('}'); return delegate.createObjectExpression(properties); } // 11.1.6 The Grouping Operator function parseGroupExpression() { var expr; expect('('); expr = parseExpression(); expect(')'); return expr; } // 11.1 Primary Expressions function parsePrimaryExpression() { var type, token, expr; if (match('(')) { return parseGroupExpression(); } type = lookahead.type; delegate.markStart(); if (type === Token.Identifier) { expr = delegate.createIdentifier(lex().value); } else if (type === Token.StringLiteral || type === Token.NumericLiteral) { if (strict && lookahead.octal) { throwErrorTolerant(lookahead, Messages.StrictOctalLiteral); } expr = delegate.createLiteral(lex()); } else if (type === Token.Keyword) { if (matchKeyword('this')) { lex(); expr = delegate.createThisExpression(); } else if (matchKeyword('function')) { expr = parseFunctionExpression(); } } else if (type === Token.BooleanLiteral) { token = lex(); token.value = (token.value === 'true'); expr = delegate.createLiteral(token); } else if (type === Token.NullLiteral) { token = lex(); token.value = null; expr = delegate.createLiteral(token); } else if (match('[')) { expr = parseArrayInitialiser(); } else if (match('{')) { expr = parseObjectInitialiser(); } else if (match('/') || match('/=')) { if (typeof extra.tokens !== 'undefined') { expr = delegate.createLiteral(collectRegex()); } else { expr = delegate.createLiteral(scanRegExp()); } peek(); } if (expr) { return delegate.markEnd(expr); } throwUnexpected(lex()); } // 11.2 Left-Hand-Side Expressions function parseArguments() { var args = []; expect('('); if (!match(')')) { while (index < length) { args.push(parseAssignmentExpression()); if (match(')')) { break; } expect(','); } } expect(')'); return args; } function parseNonComputedProperty() { var token; delegate.markStart(); token = lex(); if (!isIdentifierName(token)) { throwUnexpected(token); } return delegate.markEnd(delegate.createIdentifier(token.value)); } function parseNonComputedMember() { expect('.'); return parseNonComputedProperty(); } function parseComputedMember() { var expr; expect('['); expr = parseExpression(); expect(']'); return expr; } function parseNewExpression() { var callee, args; delegate.markStart(); expectKeyword('new'); callee = parseLeftHandSideExpression(); args = match('(') ? parseArguments() : []; return delegate.markEnd(delegate.createNewExpression(callee, args)); } function parseLeftHandSideExpressionAllowCall() { var marker, previousAllowIn, expr, args, property; marker = createLocationMarker(); previousAllowIn = state.allowIn; state.allowIn = true; expr = matchKeyword('new') ? parseNewExpression() : parsePrimaryExpression(); state.allowIn = previousAllowIn; while (match('.') || match('[') || match('(')) { if (match('(')) { args = parseArguments(); expr = delegate.createCallExpression(expr, args); } else if (match('[')) { property = parseComputedMember(); expr = delegate.createMemberExpression('[', expr, property); } else { property = parseNonComputedMember(); expr = delegate.createMemberExpression('.', expr, property); } if (marker) { marker.apply(expr); } } return expr; } function parseLeftHandSideExpression() { var marker, previousAllowIn, expr, property; marker = createLocationMarker(); previousAllowIn = state.allowIn; expr = matchKeyword('new') ? parseNewExpression() : parsePrimaryExpression(); state.allowIn = previousAllowIn; while (match('.') || match('[')) { if (match('[')) { property = parseComputedMember(); expr = delegate.createMemberExpression('[', expr, property); } else { property = parseNonComputedMember(); expr = delegate.createMemberExpression('.', expr, property); } if (marker) { marker.apply(expr); } } return expr; } // 11.3 Postfix Expressions function parsePostfixExpression() { var expr, token; delegate.markStart(); expr = parseLeftHandSideExpressionAllowCall(); if (lookahead.type === Token.Punctuator) { if ((match('++') || match('--')) && !peekLineTerminator()) { // 11.3.1, 11.3.2 if (strict && expr.type === Syntax.Identifier && isRestrictedWord(expr.name)) { throwErrorTolerant({}, Messages.StrictLHSPostfix); } if (!isLeftHandSide(expr)) { throwErrorTolerant({}, Messages.InvalidLHSInAssignment); } token = lex(); expr = delegate.createPostfixExpression(token.value, expr); } } return delegate.markEndIf(expr); } // 11.4 Unary Operators function parseUnaryExpression() { var token, expr; delegate.markStart(); if (lookahead.type !== Token.Punctuator && lookahead.type !== Token.Keyword) { expr = parsePostfixExpression(); } else if (match('++') || match('--')) { token = lex(); expr = parseUnaryExpression(); // 11.4.4, 11.4.5 if (strict && expr.type === Syntax.Identifier && isRestrictedWord(expr.name)) { throwErrorTolerant({}, Messages.StrictLHSPrefix); } if (!isLeftHandSide(expr)) { throwErrorTolerant({}, Messages.InvalidLHSInAssignment); } expr = delegate.createUnaryExpression(token.value, expr); } else if (match('+') || match('-') || match('~') || match('!')) { token = lex(); expr = parseUnaryExpression(); expr = delegate.createUnaryExpression(token.value, expr); } else if (matchKeyword('delete') || matchKeyword('void') || matchKeyword('typeof')) { token = lex(); expr = parseUnaryExpression(); expr = delegate.createUnaryExpression(token.value, expr); if (strict && expr.operator === 'delete' && expr.argument.type === Syntax.Identifier) { throwErrorTolerant({}, Messages.StrictDelete); } } else { expr = parsePostfixExpression(); } return delegate.markEndIf(expr); } function binaryPrecedence(token, allowIn) { var prec = 0; if (token.type !== Token.Punctuator && token.type !== Token.Keyword) { return 0; } switch (token.value) { case '||': prec = 1; break; case '&&': prec = 2; break; case '|': prec = 3; break; case '^': prec = 4; break; case '&': prec = 5; break; case '==': case '!=': case '===': case '!==': prec = 6; break; case '<': case '>': case '<=': case '>=': case 'instanceof': prec = 7; break; case 'in': prec = allowIn ? 7 : 0; break; case '<<': case '>>': case '>>>': prec = 8; break; case '+': case '-': prec = 9; break; case '*': case '/': case '%': prec = 11; break; default: break; } return prec; } // 11.5 Multiplicative Operators // 11.6 Additive Operators // 11.7 Bitwise Shift Operators // 11.8 Relational Operators // 11.9 Equality Operators // 11.10 Binary Bitwise Operators // 11.11 Binary Logical Operators function parseBinaryExpression() { var marker, markers, expr, token, prec, stack, right, operator, left, i; marker = createLocationMarker(); left = parseUnaryExpression(); token = lookahead; prec = binaryPrecedence(token, state.allowIn); if (prec === 0) { return left; } token.prec = prec; lex(); markers = [marker, createLocationMarker()]; right = parseUnaryExpression(); stack = [left, token, right]; while ((prec = binaryPrecedence(lookahead, state.allowIn)) > 0) { // Reduce: make a binary expression from the three topmost entries. while ((stack.length > 2) && (prec <= stack[stack.length - 2].prec)) { right = stack.pop(); operator = stack.pop().value; left = stack.pop(); expr = delegate.createBinaryExpression(operator, left, right); markers.pop(); marker = markers.pop(); if (marker) { marker.apply(expr); } stack.push(expr); markers.push(marker); } // Shift. token = lex(); token.prec = prec; stack.push(token); markers.push(createLocationMarker()); expr = parseUnaryExpression(); stack.push(expr); } // Final reduce to clean-up the stack. i = stack.length - 1; expr = stack[i]; markers.pop(); while (i > 1) { expr = delegate.createBinaryExpression(stack[i - 1].value, stack[i - 2], expr); i -= 2; marker = markers.pop(); if (marker) { marker.apply(expr); } } return expr; } // 11.12 Conditional Operator function parseConditionalExpression() { var expr, previousAllowIn, consequent, alternate; delegate.markStart(); expr = parseBinaryExpression(); if (match('?')) { lex(); previousAllowIn = state.allowIn; state.allowIn = true; consequent = parseAssignmentExpression(); state.allowIn = previousAllowIn; expect(':'); alternate = parseAssignmentExpression(); expr = delegate.markEnd(delegate.createConditionalExpression(expr, consequent, alternate)); } else { delegate.markEnd({}); } return expr; } // 11.13 Assignment Operators function parseAssignmentExpression() { var token, left, right, node; token = lookahead; delegate.markStart(); node = left = parseConditionalExpression(); if (matchAssign()) { // LeftHandSideExpression if (!isLeftHandSide(left)) { throwErrorTolerant({}, Messages.InvalidLHSInAssignment); } // 11.13.1 if (strict && left.type === Syntax.Identifier && isRestrictedWord(left.name)) { throwErrorTolerant(token, Messages.StrictLHSAssignment); } token = lex(); right = parseAssignmentExpression(); node = delegate.createAssignmentExpression(token.value, left, right); } return delegate.markEndIf(node); } // 11.14 Comma Operator function parseExpression() { var expr; delegate.markStart(); expr = parseAssignmentExpression(); if (match(',')) { expr = delegate.createSequenceExpression([ expr ]); while (index < length) { if (!match(',')) { break; } lex(); expr.expressions.push(parseAssignmentExpression()); } } return delegate.markEndIf(expr); } // 12.1 Block function parseStatementList() { var list = [], statement; while (index < length) { if (match('}')) { break; } statement = parseSourceElement(); if (typeof statement === 'undefined') { break; } list.push(statement); } return list; } function parseBlock() { var block; delegate.markStart(); expect('{'); block = parseStatementList(); expect('}'); return delegate.markEnd(delegate.createBlockStatement(block)); } // 12.2 Variable Statement function parseVariableIdentifier() { var token; delegate.markStart(); token = lex(); if (token.type !== Token.Identifier) { throwUnexpected(token); } return delegate.markEnd(delegate.createIdentifier(token.value)); } function parseVariableDeclaration(kind) { var init = null, id; delegate.markStart(); id = parseVariableIdentifier(); // 12.2.1 if (strict && isRestrictedWord(id.name)) { throwErrorTolerant({}, Messages.StrictVarName); } if (kind === 'const') { expect('='); init = parseAssignmentExpression(); } else if (match('=')) { lex(); init = parseAssignmentExpression(); } return delegate.markEnd(delegate.createVariableDeclarator(id, init)); } function parseVariableDeclarationList(kind) { var list = []; do { list.push(parseVariableDeclaration(kind)); if (!match(',')) { break; } lex(); } while (index < length); return list; } function parseVariableStatement() { var declarations; expectKeyword('var'); declarations = parseVariableDeclarationList(); consumeSemicolon(); return delegate.createVariableDeclaration(declarations, 'var'); } // kind may be `const` or `let` // Both are experimental and not in the specification yet. // see http://wiki.ecmascript.org/doku.php?id=harmony:const // and http://wiki.ecmascript.org/doku.php?id=harmony:let function parseConstLetDeclaration(kind) { var declarations; delegate.markStart(); expectKeyword(kind); declarations = parseVariableDeclarationList(kind); consumeSemicolon(); return delegate.markEnd(delegate.createVariableDeclaration(declarations, kind)); } // 12.3 Empty Statement function parseEmptyStatement() { expect(';'); return delegate.createEmptyStatement(); } // 12.4 Expression Statement function parseExpressionStatement() { var expr = parseExpression(); consumeSemicolon(); return delegate.createExpressionStatement(expr); } // 12.5 If statement function parseIfStatement() { var test, consequent, alternate; expectKeyword('if'); expect('('); test = parseExpression(); expect(')'); consequent = parseStatement(); if (matchKeyword('else')) { lex(); alternate = parseStatement(); } else { alternate = null; } return delegate.createIfStatement(test, consequent, alternate); } // 12.6 Iteration Statements function parseDoWhileStatement() { var body, test, oldInIteration; expectKeyword('do'); oldInIteration = state.inIteration; state.inIteration = true; body = parseStatement(); state.inIteration = oldInIteration; expectKeyword('while'); expect('('); test = parseExpression(); expect(')'); if (match(';')) { lex(); } return delegate.createDoWhileStatement(body, test); } function parseWhileStatement() { var test, body, oldInIteration; expectKeyword('while'); expect('('); test = parseExpression(); expect(')'); oldInIteration = state.inIteration; state.inIteration = true; body = parseStatement(); state.inIteration = oldInIteration; return delegate.createWhileStatement(test, body); } function parseForVariableDeclaration() { var token, declarations; delegate.markStart(); token = lex(); declarations = parseVariableDeclarationList(); return delegate.markEnd(delegate.createVariableDeclaration(declarations, token.value)); } function parseForStatement() { var init, test, update, left, right, body, oldInIteration; init = test = update = null; expectKeyword('for'); expect('('); if (match(';')) { lex(); } else { if (matchKeyword('var') || matchKeyword('let')) { state.allowIn = false; init = parseForVariableDeclaration(); state.allowIn = true; if (init.declarations.length === 1 && matchKeyword('in')) { lex(); left = init; right = parseExpression(); init = null; } } else { state.allowIn = false; init = parseExpression(); state.allowIn = true; if (matchKeyword('in')) { // LeftHandSideExpression if (!isLeftHandSide(init)) { throwErrorTolerant({}, Messages.InvalidLHSInForIn); } lex(); left = init; right = parseExpression(); init = null; } } if (typeof left === 'undefined') { expect(';'); } } if (typeof left === 'undefined') { if (!match(';')) { test = parseExpression(); } expect(';'); if (!match(')')) { update = parseExpression(); } } expect(')'); oldInIteration = state.inIteration; state.inIteration = true; body = parseStatement(); state.inIteration = oldInIteration; return (typeof left === 'undefined') ? delegate.createForStatement(init, test, update, body) : delegate.createForInStatement(left, right, body); } // 12.7 The continue statement function parseContinueStatement() { var label = null, key; expectKeyword('continue'); // Optimize the most common form: 'continue;'. if (source.charCodeAt(index) === 0x3B) { lex(); if (!state.inIteration) { throwError({}, Messages.IllegalContinue); } return delegate.createContinueStatement(null); } if (peekLineTerminator()) { if (!state.inIteration) { throwError({}, Messages.IllegalContinue); } return delegate.createContinueStatement(null); } if (lookahead.type === Token.Identifier) { label = parseVariableIdentifier(); key = '$' + label.name; if (!Object.prototype.hasOwnProperty.call(state.labelSet, key)) { throwError({}, Messages.UnknownLabel, label.name); } } consumeSemicolon(); if (label === null && !state.inIteration) { throwError({}, Messages.IllegalContinue); } return delegate.createContinueStatement(label); } // 12.8 The break statement function parseBreakStatement() { var label = null, key; expectKeyword('break'); // Catch the very common case first: immediately a semicolon (U+003B). if (source.charCodeAt(index) === 0x3B) { lex(); if (!(state.inIteration || state.inSwitch)) { throwError({}, Messages.IllegalBreak); } return delegate.createBreakStatement(null); } if (peekLineTerminator()) { if (!(state.inIteration || state.inSwitch)) { throwError({}, Messages.IllegalBreak); } return delegate.createBreakStatement(null); } if (lookahead.type === Token.Identifier) { label = parseVariableIdentifier(); key = '$' + label.name; if (!Object.prototype.hasOwnProperty.call(state.labelSet, key)) { throwError({}, Messages.UnknownLabel, label.name); } } consumeSemicolon(); if (label === null && !(state.inIteration || state.inSwitch)) { throwError({}, Messages.IllegalBreak); } return delegate.createBreakStatement(label); } // 12.9 The return statement function parseReturnStatement() { var argument = null; expectKeyword('return'); if (!state.inFunctionBody) { throwErrorTolerant({}, Messages.IllegalReturn); } // 'return' followed by a space and an identifier is very common. if (source.charCodeAt(index) === 0x20) { if (isIdentifierStart(source.charCodeAt(index + 1))) { argument = parseExpression(); consumeSemicolon(); return delegate.createReturnStatement(argument); } } if (peekLineTerminator()) { return delegate.createReturnStatement(null); } if (!match(';')) { if (!match('}') && lookahead.type !== Token.EOF) { argument = parseExpression(); } } consumeSemicolon(); return delegate.createReturnStatement(argument); } // 12.10 The with statement function parseWithStatement() { var object, body; if (strict) { throwErrorTolerant({}, Messages.StrictModeWith); } expectKeyword('with'); expect('('); object = parseExpression(); expect(')'); body = parseStatement(); return delegate.createWithStatement(object, body); } // 12.10 The swith statement function parseSwitchCase() { var test, consequent = [], statement; delegate.markStart(); if (matchKeyword('default')) { lex(); test = null; } else { expectKeyword('case'); test = parseExpression(); } expect(':'); while (index < length) { if (match('}') || matchKeyword('default') || matchKeyword('case')) { break; } statement = parseStatement(); consequent.push(statement); } return delegate.markEnd(delegate.createSwitchCase(test, consequent)); } function parseSwitchStatement() { var discriminant, cases, clause, oldInSwitch, defaultFound; expectKeyword('switch'); expect('('); discriminant = parseExpression(); expect(')'); expect('{'); cases = []; if (match('}')) { lex(); return delegate.createSwitchStatement(discriminant, cases); } oldInSwitch = state.inSwitch; state.inSwitch = true; defaultFound = false; while (index < length) { if (match('}')) { break; } clause = parseSwitchCase(); if (clause.test === null) { if (defaultFound) { throwError({}, Messages.MultipleDefaultsInSwitch); } defaultFound = true; } cases.push(clause); } state.inSwitch = oldInSwitch; expect('}'); return delegate.createSwitchStatement(discriminant, cases); } // 12.13 The throw statement function parseThrowStatement() { var argument; expectKeyword('throw'); if (peekLineTerminator()) { throwError({}, Messages.NewlineAfterThrow); } argument = parseExpression(); consumeSemicolon(); return delegate.createThrowStatement(argument); } // 12.14 The try statement function parseCatchClause() { var param, body; delegate.markStart(); expectKeyword('catch'); expect('('); if (match(')')) { throwUnexpected(lookahead); } param = parseVariableIdentifier(); // 12.14.1 if (strict && isRestrictedWord(param.name)) { throwErrorTolerant({}, Messages.StrictCatchVariable); } expect(')'); body = parseBlock(); return delegate.markEnd(delegate.createCatchClause(param, body)); } function parseTryStatement() { var block, handlers = [], finalizer = null; expectKeyword('try'); block = parseBlock(); if (matchKeyword('catch')) { handlers.push(parseCatchClause()); } if (matchKeyword('finally')) { lex(); finalizer = parseBlock(); } if (handlers.length === 0 && !finalizer) { throwError({}, Messages.NoCatchOrFinally); } return delegate.createTryStatement(block, [], handlers, finalizer); } // 12.15 The debugger statement function parseDebuggerStatement() { expectKeyword('debugger'); consumeSemicolon(); return delegate.createDebuggerStatement(); } // 12 Statements function parseStatement() { var type = lookahead.type, expr, labeledBody, key; if (type === Token.EOF) { throwUnexpected(lookahead); } delegate.markStart(); if (type === Token.Punctuator) { switch (lookahead.value) { case ';': return delegate.markEnd(parseEmptyStatement()); case '{': return delegate.markEnd(parseBlock()); case '(': return delegate.markEnd(parseExpressionStatement()); default: break; } } if (type === Token.Keyword) { switch (lookahead.value) { case 'break': return delegate.markEnd(parseBreakStatement()); case 'continue': return delegate.markEnd(parseContinueStatement()); case 'debugger': return delegate.markEnd(parseDebuggerStatement()); case 'do': return delegate.markEnd(parseDoWhileStatement()); case 'for': return delegate.markEnd(parseForStatement()); case 'function': return delegate.markEnd(parseFunctionDeclaration()); case 'if': return delegate.markEnd(parseIfStatement()); case 'return': return delegate.markEnd(parseReturnStatement()); case 'switch': return delegate.markEnd(parseSwitchStatement()); case 'throw': return delegate.markEnd(parseThrowStatement()); case 'try': return delegate.markEnd(parseTryStatement()); case 'var': return delegate.markEnd(parseVariableStatement()); case 'while': return delegate.markEnd(parseWhileStatement()); case 'with': return delegate.markEnd(parseWithStatement()); default: break; } } expr = parseExpression(); // 12.12 Labelled Statements if ((expr.type === Syntax.Identifier) && match(':')) { lex(); key = '$' + expr.name; if (Object.prototype.hasOwnProperty.call(state.labelSet, key)) { throwError({}, Messages.Redeclaration, 'Label', expr.name); } state.labelSet[key] = true; labeledBody = parseStatement(); delete state.labelSet[key]; return delegate.markEnd(delegate.createLabeledStatement(expr, labeledBody)); } consumeSemicolon(); return delegate.markEnd(delegate.createExpressionStatement(expr)); } // 13 Function Definition function parseFunctionSourceElements() { var sourceElement, sourceElements = [], token, directive, firstRestricted, oldLabelSet, oldInIteration, oldInSwitch, oldInFunctionBody; delegate.markStart(); expect('{'); while (index < length) { if (lookahead.type !== Token.StringLiteral) { break; } token = lookahead; sourceElement = parseSourceElement(); sourceElements.push(sourceElement); if (sourceElement.expression.type !== Syntax.Literal) { // this is not directive break; } directive = source.slice(token.range[0] + 1, token.range[1] - 1); if (directive === 'use strict') { strict = true; if (firstRestricted) { throwErrorTolerant(firstRestricted, Messages.StrictOctalLiteral); } } else { if (!firstRestricted && token.octal) { firstRestricted = token; } } } oldLabelSet = state.labelSet; oldInIteration = state.inIteration; oldInSwitch = state.inSwitch; oldInFunctionBody = state.inFunctionBody; state.labelSet = {}; state.inIteration = false; state.inSwitch = false; state.inFunctionBody = true; while (index < length) { if (match('}')) { break; } sourceElement = parseSourceElement(); if (typeof sourceElement === 'undefined') { break; } sourceElements.push(sourceElement); } expect('}'); state.labelSet = oldLabelSet; state.inIteration = oldInIteration; state.inSwitch = oldInSwitch; state.inFunctionBody = oldInFunctionBody; return delegate.markEnd(delegate.createBlockStatement(sourceElements)); } function parseParams(firstRestricted) { var param, params = [], token, stricted, paramSet, key, message; expect('('); if (!match(')')) { paramSet = {}; while (index < length) { token = lookahead; param = parseVariableIdentifier(); key = '$' + token.value; if (strict) { if (isRestrictedWord(token.value)) { stricted = token; message = Messages.StrictParamName; } if (Object.prototype.hasOwnProperty.call(paramSet, key)) { stricted = token; message = Messages.StrictParamDupe; } } else if (!firstRestricted) { if (isRestrictedWord(token.value)) { firstRestricted = token; message = Messages.StrictParamName; } else if (isStrictModeReservedWord(token.value)) { firstRestricted = token; message = Messages.StrictReservedWord; } else if (Object.prototype.hasOwnProperty.call(paramSet, key)) { firstRestricted = token; message = Messages.StrictParamDupe; } } params.push(param); paramSet[key] = true; if (match(')')) { break; } expect(','); } } expect(')'); return { params: params, stricted: stricted, firstRestricted: firstRestricted, message: message }; } function parseFunctionDeclaration() { var id, params = [], body, token, stricted, tmp, firstRestricted, message, previousStrict; delegate.markStart(); expectKeyword('function'); token = lookahead; id = parseVariableIdentifier(); if (strict) { if (isRestrictedWord(token.value)) { throwErrorTolerant(token, Messages.StrictFunctionName); } } else { if (isRestrictedWord(token.value)) { firstRestricted = token; message = Messages.StrictFunctionName; } else if (isStrictModeReservedWord(token.value)) { firstRestricted = token; message = Messages.StrictReservedWord; } } tmp = parseParams(firstRestricted); params = tmp.params; stricted = tmp.stricted; firstRestricted = tmp.firstRestricted; if (tmp.message) { message = tmp.message; } previousStrict = strict; body = parseFunctionSourceElements(); if (strict && firstRestricted) { throwError(firstRestricted, message); } if (strict && stricted) { throwErrorTolerant(stricted, message); } strict = previousStrict; return delegate.markEnd(delegate.createFunctionDeclaration(id, params, [], body)); } function parseFunctionExpression() { var token, id = null, stricted, firstRestricted, message, tmp, params = [], body, previousStrict; delegate.markStart(); expectKeyword('function'); if (!match('(')) { token = lookahead; id = parseVariableIdentifier(); if (strict) { if (isRestrictedWord(token.value)) { throwErrorTolerant(token, Messages.StrictFunctionName); } } else { if (isRestrictedWord(token.value)) { firstRestricted = token; message = Messages.StrictFunctionName; } else if (isStrictModeReservedWord(token.value)) { firstRestricted = token; message = Messages.StrictReservedWord; } } } tmp = parseParams(firstRestricted); params = tmp.params; stricted = tmp.stricted; firstRestricted = tmp.firstRestricted; if (tmp.message) { message = tmp.message; } previousStrict = strict; body = parseFunctionSourceElements(); if (strict && firstRestricted) { throwError(firstRestricted, message); } if (strict && stricted) { throwErrorTolerant(stricted, message); } strict = previousStrict; return delegate.markEnd(delegate.createFunctionExpression(id, params, [], body)); } // 14 Program function parseSourceElement() { if (lookahead.type === Token.Keyword) { switch (lookahead.value) { case 'const': case 'let': return parseConstLetDeclaration(lookahead.value); case 'function': return parseFunctionDeclaration(); default: return parseStatement(); } } if (lookahead.type !== Token.EOF) { return parseStatement(); } } function parseSourceElements() { var sourceElement, sourceElements = [], token, directive, firstRestricted; while (index < length) { token = lookahead; if (token.type !== Token.StringLiteral) { break; } sourceElement = parseSourceElement(); sourceElements.push(sourceElement); if (sourceElement.expression.type !== Syntax.Literal) { // this is not directive break; } directive = source.slice(token.range[0] + 1, token.range[1] - 1); if (directive === 'use strict') { strict = true; if (firstRestricted) { throwErrorTolerant(firstRestricted, Messages.StrictOctalLiteral); } } else { if (!firstRestricted && token.octal) { firstRestricted = token; } } } while (index < length) { sourceElement = parseSourceElement(); if (typeof sourceElement === 'undefined') { break; } sourceElements.push(sourceElement); } return sourceElements; } function parseProgram() { var body; delegate.markStart(); strict = false; peek(); body = parseSourceElements(); return delegate.markEnd(delegate.createProgram(body)); } function attachComments() { var i, attacher, comment, leading, trailing; for (i = 0; i < extra.pendingComments.length; ++i) { attacher = extra.pendingComments[i]; comment = attacher.comment; leading = attacher.leading; if (leading) { if (typeof leading.leadingComments === 'undefined') { leading.leadingComments = []; } leading.leadingComments.push(attacher.comment); } trailing = attacher.trailing; if (trailing) { if (typeof trailing.trailingComments === 'undefined') { trailing.trailingComments = []; } trailing.trailingComments.push(attacher.comment); } } extra.pendingComments = []; } function filterTokenLocation() { var i, entry, token, tokens = []; for (i = 0; i < extra.tokens.length; ++i) { entry = extra.tokens[i]; token = { type: entry.type, value: entry.value }; if (extra.range) { token.range = entry.range; } if (extra.loc) { token.loc = entry.loc; } tokens.push(token); } extra.tokens = tokens; } function LocationMarker() { this.startIndex = index; this.startLine = lineNumber; this.startColumn = index - lineStart; } LocationMarker.prototype = { constructor: LocationMarker, apply: function (node) { if (extra.range) { node.range = [this.startIndex, index]; } if (extra.loc) { node.loc = { start: { line: this.startLine, column: this.startColumn }, end: { line: lineNumber, column: index - lineStart } }; node = delegate.postProcess(node); } if (extra.attachComment) { delegate.processComment(node); } } }; function createLocationMarker() { if (!extra.loc && !extra.range) { return null; } skipComment(); return new LocationMarker(); } function tokenize(code, options) { var toString, token, tokens; toString = String; if (typeof code !== 'string' && !(code instanceof String)) { code = toString(code); } delegate = SyntaxTreeDelegate; source = code; index = 0; lineNumber = (source.length > 0) ? 1 : 0; lineStart = 0; length = source.length; lookahead = null; state = { allowIn: true, labelSet: {}, inFunctionBody: false, inIteration: false, inSwitch: false, lastCommentStart: -1 }; extra = {}; // Options matching. options = options || {}; // Of course we collect tokens here. options.tokens = true; extra.tokens = []; extra.tokenize = true; // The following two fields are necessary to compute the Regex tokens. extra.openParenToken = -1; extra.openCurlyToken = -1; extra.range = (typeof options.range === 'boolean') && options.range; extra.loc = (typeof options.loc === 'boolean') && options.loc; if (typeof options.comment === 'boolean' && options.comment) { extra.comments = []; } if (typeof options.tolerant === 'boolean' && options.tolerant) { extra.errors = []; } if (length > 0) { if (typeof source[0] === 'undefined') { // Try first to convert to a string. This is good as fast path // for old IE which understands string indexing for string // literals only and not for string object. if (code instanceof String) { source = code.valueOf(); } } } try { peek(); if (lookahead.type === Token.EOF) { return extra.tokens; } token = lex(); while (lookahead.type !== Token.EOF) { try { token = lex(); } catch (lexError) { token = lookahead; if (extra.errors) { extra.errors.push(lexError); // We have to break on the first error // to avoid infinite loops. break; } else { throw lexError; } } } filterTokenLocation(); tokens = extra.tokens; if (typeof extra.comments !== 'undefined') { tokens.comments = extra.comments; } if (typeof extra.errors !== 'undefined') { tokens.errors = extra.errors; } } catch (e) { throw e; } finally { extra = {}; } return tokens; } function parse(code, options) { var program, toString; toString = String; if (typeof code !== 'string' && !(code instanceof String)) { code = toString(code); } delegate = SyntaxTreeDelegate; source = code; index = 0; lineNumber = (source.length > 0) ? 1 : 0; lineStart = 0; length = source.length; lookahead = null; state = { allowIn: true, labelSet: {}, inFunctionBody: false, inIteration: false, inSwitch: false, lastCommentStart: -1, markerStack: [] }; extra = {}; if (typeof options !== 'undefined') { extra.range = (typeof options.range === 'boolean') && options.range; extra.loc = (typeof options.loc === 'boolean') && options.loc; extra.attachComment = (typeof options.attachComment === 'boolean') && options.attachComment; if (extra.loc && options.source !== null && options.source !== undefined) { extra.source = toString(options.source); } if (typeof options.tokens === 'boolean' && options.tokens) { extra.tokens = []; } if (typeof options.comment === 'boolean' && options.comment) { extra.comments = []; } if (typeof options.tolerant === 'boolean' && options.tolerant) { extra.errors = []; } if (extra.attachComment) { extra.range = true; extra.pendingComments = []; extra.comments = []; } } if (length > 0) { if (typeof source[0] === 'undefined') { // Try first to convert to a string. This is good as fast path // for old IE which understands string indexing for string // literals only and not for string object. if (code instanceof String) { source = code.valueOf(); } } } try { program = parseProgram(); if (typeof extra.comments !== 'undefined') { program.comments = extra.comments; } if (typeof extra.tokens !== 'undefined') { filterTokenLocation(); program.tokens = extra.tokens; } if (typeof extra.errors !== 'undefined') { program.errors = extra.errors; } if (extra.attachComment) { attachComments(); } } catch (e) { throw e; } finally { extra = {}; } return program; } // Sync with *.json manifests. exports.version = '1.1.1'; exports.tokenize = tokenize; exports.parse = parse; // Deep copy. exports.Syntax = (function () { var name, types = {}; if (typeof Object.create === 'function') { types = Object.create(null); } for (name in Syntax) { if (Syntax.hasOwnProperty(name)) { types[name] = Syntax[name]; } } if (typeof Object.freeze === 'function') { Object.freeze(types); } return types; }()); })); /* vim: set sw=4 ts=4 et tw=80 : */ },{}],48:[function(require,module,exports){ // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to permit // persons to whom the Software is furnished to do so, subject to the // following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. function EventEmitter() { this._events = this._events || {}; this._maxListeners = this._maxListeners || undefined; } module.exports = EventEmitter; // Backwards-compat with node 0.10.x EventEmitter.EventEmitter = EventEmitter; EventEmitter.prototype._events = undefined; EventEmitter.prototype._maxListeners = undefined; // By default EventEmitters will print a warning if more than 10 listeners are // added to it. This is a useful default which helps finding memory leaks. EventEmitter.defaultMaxListeners = 10; // Obviously not all Emitters should be limited to 10. This function allows // that to be increased. Set to zero for unlimited. EventEmitter.prototype.setMaxListeners = function(n) { if (!isNumber(n) || n < 0 || isNaN(n)) throw TypeError('n must be a positive number'); this._maxListeners = n; return this; }; EventEmitter.prototype.emit = function(type) { var er, handler, len, args, i, listeners; if (!this._events) this._events = {}; // If there is no 'error' event listener then throw. if (type === 'error') { if (!this._events.error || (isObject(this._events.error) && !this._events.error.length)) { er = arguments[1]; if (er instanceof Error) { throw er; // Unhandled 'error' event } else { // At least give some kind of context to the user var err = new Error('Uncaught, unspecified "error" event. (' + er + ')'); err.context = er; throw err; } } } handler = this._events[type]; if (isUndefined(handler)) return false; if (isFunction(handler)) { switch (arguments.length) { // fast cases case 1: handler.call(this); break; case 2: handler.call(this, arguments[1]); break; case 3: handler.call(this, arguments[1], arguments[2]); break; // slower default: args = Array.prototype.slice.call(arguments, 1); handler.apply(this, args); } } else if (isObject(handler)) { args = Array.prototype.slice.call(arguments, 1); listeners = handler.slice(); len = listeners.length; for (i = 0; i < len; i++) listeners[i].apply(this, args); } return true; }; EventEmitter.prototype.addListener = function(type, listener) { var m; if (!isFunction(listener)) throw TypeError('listener must be a function'); if (!this._events) this._events = {}; // To avoid recursion in the case that type === "newListener"! Before // adding it to the listeners, first emit "newListener". if (this._events.newListener) this.emit('newListener', type, isFunction(listener.listener) ? listener.listener : listener); if (!this._events[type]) // Optimize the case of one listener. Don't need the extra array object. this._events[type] = listener; else if (isObject(this._events[type])) // If we've already got an array, just append. this._events[type].push(listener); else // Adding the second element, need to change to array. this._events[type] = [this._events[type], listener]; // Check for listener leak if (isObject(this._events[type]) && !this._events[type].warned) { if (!isUndefined(this._maxListeners)) { m = this._maxListeners; } else { m = EventEmitter.defaultMaxListeners; } if (m && m > 0 && this._events[type].length > m) { this._events[type].warned = true; console.error('(node) warning: possible EventEmitter memory ' + 'leak detected. %d listeners added. ' + 'Use emitter.setMaxListeners() to increase limit.', this._events[type].length); if (typeof console.trace === 'function') { // not supported in IE 10 console.trace(); } } } return this; }; EventEmitter.prototype.on = EventEmitter.prototype.addListener; EventEmitter.prototype.once = function(type, listener) { if (!isFunction(listener)) throw TypeError('listener must be a function'); var fired = false; function g() { this.removeListener(type, g); if (!fired) { fired = true; listener.apply(this, arguments); } } g.listener = listener; this.on(type, g); return this; }; // emits a 'removeListener' event iff the listener was removed EventEmitter.prototype.removeListener = function(type, listener) { var list, position, length, i; if (!isFunction(listener)) throw TypeError('listener must be a function'); if (!this._events || !this._events[type]) return this; list = this._events[type]; length = list.length; position = -1; if (list === listener || (isFunction(list.listener) && list.listener === listener)) { delete this._events[type]; if (this._events.removeListener) this.emit('removeListener', type, listener); } else if (isObject(list)) { for (i = length; i-- > 0;) { if (list[i] === listener || (list[i].listener && list[i].listener === listener)) { position = i; break; } } if (position < 0) return this; if (list.length === 1) { list.length = 0; delete this._events[type]; } else { list.splice(position, 1); } if (this._events.removeListener) this.emit('removeListener', type, listener); } return this; }; EventEmitter.prototype.removeAllListeners = function(type) { var key, listeners; if (!this._events) return this; // not listening for removeListener, no need to emit if (!this._events.removeListener) { if (arguments.length === 0) this._events = {}; else if (this._events[type]) delete this._events[type]; return this; } // emit removeListener for all listeners on all events if (arguments.length === 0) { for (key in this._events) { if (key === 'removeListener') continue; this.removeAllListeners(key); } this.removeAllListeners('removeListener'); this._events = {}; return this; } listeners = this._events[type]; if (isFunction(listeners)) { this.removeListener(type, listeners); } else if (listeners) { // LIFO order while (listeners.length) this.removeListener(type, listeners[listeners.length - 1]); } delete this._events[type]; return this; }; EventEmitter.prototype.listeners = function(type) { var ret; if (!this._events || !this._events[type]) ret = []; else if (isFunction(this._events[type])) ret = [this._events[type]]; else ret = this._events[type].slice(); return ret; }; EventEmitter.prototype.listenerCount = function(type) { if (this._events) { var evlistener = this._events[type]; if (isFunction(evlistener)) return 1; else if (evlistener) return evlistener.length; } return 0; }; EventEmitter.listenerCount = function(emitter, type) { return emitter.listenerCount(type); }; function isFunction(arg) { return typeof arg === 'function'; } function isNumber(arg) { return typeof arg === 'number'; } function isObject(arg) { return typeof arg === 'object' && arg !== null; } function isUndefined(arg) { return arg === void 0; } },{}],49:[function(require,module,exports){ module.exports = function(strings) { if (typeof strings === 'string') strings = [strings] var exprs = [].slice.call(arguments,1) var parts = [] for (var i = 0; i < strings.length-1; i++) { parts.push(strings[i], exprs[i] || '') } parts.push(strings[i]) return parts.join('') } },{}],50:[function(require,module,exports){ var http = require('http') var url = require('url') var https = module.exports for (var key in http) { if (http.hasOwnProperty(key)) https[key] = http[key] } https.request = function (params, cb) { params = validateParams(params) return http.request.call(this, params, cb) } https.get = function (params, cb) { params = validateParams(params) return http.get.call(this, params, cb) } function validateParams (params) { if (typeof params === 'string') { params = url.parse(params) } if (!params.protocol) { params.protocol = 'https:' } if (params.protocol !== 'https:') { throw new Error('Protocol "' + params.protocol + '" not supported. Expected "https:"') } return params } },{"http":77,"url":83}],51:[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 } },{}],52:[function(require,module,exports){ if (typeof Object.create === 'function') { // implementation from standard node.js 'util' module module.exports = function inherits(ctor, superCtor) { ctor.super_ = superCtor ctor.prototype = Object.create(superCtor.prototype, { constructor: { value: ctor, enumerable: false, writable: true, configurable: true } }); }; } else { // old school shim for old browsers module.exports = function inherits(ctor, superCtor) { ctor.super_ = superCtor var TempCtor = function () {} TempCtor.prototype = superCtor.prototype ctor.prototype = new TempCtor() ctor.prototype.constructor = ctor } } },{}],53:[function(require,module,exports){ "use strict" function iota(n) { var result = new Array(n) for(var i=0; i * @license MIT */ // The _isBuffer check is for Safari 5-7 support, because it's missing // Object.prototype.constructor. Remove this eventually module.exports = function (obj) { return obj != null && (isBuffer(obj) || isSlowBuffer(obj) || !!obj._isBuffer) } function isBuffer (obj) { return !!obj.constructor && typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj) } // For Node v0.10 support. Remove this eventually. function isSlowBuffer (obj) { return typeof obj.readFloatLE === 'function' && typeof obj.slice === 'function' && isBuffer(obj.slice(0, 0)) } },{}],55:[function(require,module,exports){ module.exports = function(arr) { if (!arr) return false if (!arr.dtype) return false var re = new RegExp('function View[0-9]+d(:?' + arr.dtype + ')+') return re.test(String(arr.constructor)) } },{}],56:[function(require,module,exports){ "use strict" var fill = require('cwise/lib/wrapper')({"args":["index","array","scalar"],"pre":{"body":"{}","args":[],"thisVars":[],"localVars":[]},"body":{"body":"{_inline_1_arg1_=_inline_1_arg2_.apply(void 0,_inline_1_arg0_)}","args":[{"name":"_inline_1_arg0_","lvalue":false,"rvalue":true,"count":1},{"name":"_inline_1_arg1_","lvalue":true,"rvalue":false,"count":1},{"name":"_inline_1_arg2_","lvalue":false,"rvalue":true,"count":1}],"thisVars":[],"localVars":[]},"post":{"body":"{}","args":[],"thisVars":[],"localVars":[]},"debug":false,"funcName":"cwise","blockSize":64}) module.exports = function(array, f) { fill(array, f) return array } },{"cwise/lib/wrapper":14}],57:[function(require,module,exports){ 'use strict'; var fill = require('ndarray-fill'); var isndarray = require('isndarray'); var isnonneg = require('validate.io-nonnegative-integer'); var isbool = require('validate.io-boolean'); module.exports = linspace; function linspace (output, start, end, options) { var n, endpoint, axis, d; if (!isndarray(output)) { throw new Error('ndarray-linspace: First argument must be a ndarray'); } n = output.shape[0]; options = options || {}; if (options.endpoint !== undefined && !isbool(options.endpoint)) { throw new Error('ndarray-linspace: Endpoint must be a boolean. Got ' + options.endpoint); } endpoint = !!(options.endpoint || true); if (options.axis !== undefined && !isnonneg(options.axis)) { throw new Error('ndarray-linspace: Axis must be a nonegative integer. Got ' + options.axis); } // Default axis, after we've checked the input axis = options.axis || 0; if (axis > output.dimension) { throw new Error('ndarray-linspace: Axis (' + axis + ') must be <= dimension (' + output.dimension + ')'); } // Precompute the spacing: d = (end - start) / Math.max(1, n - (endpoint ? 1 : 0)); // Fill it! fill(output, function () { return start + arguments[axis] * d; }); return output; } },{"isndarray":55,"ndarray-fill":56,"validate.io-boolean":86,"validate.io-nonnegative-integer":88}],58:[function(require,module,exports){ 'use strict'; module.exports = vectorFill; var cwise = require('cwise'); var fill = cwise({ args: [{blockIndices: -1}, 'scalar', 'index', 'shape'], body: function (A, func, idx, shape) { var i; var args = []; var n = shape[shape.length - 1]; for (i = 0; i < n; i++) { if (idx[i] === undefined) break; args[i] = idx[i]; } var f = func.apply(null, args); for (i = 0; i < f.length; i++) { A[i] = f[i]; } } }); function vectorFill (A, func) { fill(A, func); return A; } },{"cwise":13}],59:[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; iMath.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=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=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 1) { for (var i = 1; i < arguments.length; i++) { args[i - 1] = arguments[i]; } } queue.push(new Item(fun, args)); if (queue.length === 1 && !draining) { runTimeout(drainQueue); } }; // v8 likes predictible objects function Item(fun, array) { this.fun = fun; this.array = array; } Item.prototype.run = function () { this.fun.apply(null, this.array); }; process.title = 'browser'; process.browser = true; process.env = {}; process.argv = []; process.version = ''; // empty string to avoid regexp issues process.versions = {}; function noop() {} process.on = noop; process.addListener = noop; process.once = noop; process.off = noop; process.removeListener = noop; process.removeAllListeners = noop; process.emit = noop; process.prependListener = noop; process.prependOnceListener = noop; process.listeners = function (name) { return [] } process.binding = function (name) { throw new Error('process.binding is not supported'); }; process.cwd = function () { return '/' }; process.chdir = function (dir) { throw new Error('process.chdir is not supported'); }; process.umask = function() { return 0; }; },{}],62:[function(require,module,exports){ (function (global){ /*! https://mths.be/punycode v1.4.1 by @mathias */ ;(function(root) { /** Detect free variables */ var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports; var freeModule = typeof module == 'object' && module && !module.nodeType && module; var freeGlobal = typeof global == 'object' && global; if ( freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal || freeGlobal.self === freeGlobal ) { root = freeGlobal; } /** * The `punycode` object. * @name punycode * @type Object */ var punycode, /** Highest positive signed 32-bit float value */ maxInt = 2147483647, // aka. 0x7FFFFFFF or 2^31-1 /** Bootstring parameters */ base = 36, tMin = 1, tMax = 26, skew = 38, damp = 700, initialBias = 72, initialN = 128, // 0x80 delimiter = '-', // '\x2D' /** Regular expressions */ regexPunycode = /^xn--/, regexNonASCII = /[^\x20-\x7E]/, // unprintable ASCII chars + non-ASCII chars regexSeparators = /[\x2E\u3002\uFF0E\uFF61]/g, // RFC 3490 separators /** Error messages */ errors = { 'overflow': 'Overflow: input needs wider integers to process', 'not-basic': 'Illegal input >= 0x80 (not a basic code point)', 'invalid-input': 'Invalid input' }, /** Convenience shortcuts */ baseMinusTMin = base - tMin, floor = Math.floor, stringFromCharCode = String.fromCharCode, /** Temporary variable */ key; /*--------------------------------------------------------------------------*/ /** * A generic error utility function. * @private * @param {String} type The error type. * @returns {Error} Throws a `RangeError` with the applicable error message. */ function error(type) { throw new RangeError(errors[type]); } /** * A generic `Array#map` utility function. * @private * @param {Array} array The array to iterate over. * @param {Function} callback The function that gets called for every array * item. * @returns {Array} A new array of values returned by the callback function. */ function map(array, fn) { var length = array.length; var result = []; while (length--) { result[length] = fn(array[length]); } return result; } /** * A simple `Array#map`-like wrapper to work with domain name strings or email * addresses. * @private * @param {String} domain The domain name or email address. * @param {Function} callback The function that gets called for every * character. * @returns {Array} A new string of characters returned by the callback * function. */ function mapDomain(string, fn) { var parts = string.split('@'); var result = ''; if (parts.length > 1) { // In email addresses, only the domain name should be punycoded. Leave // the local part (i.e. everything up to `@`) intact. result = parts[0] + '@'; string = parts[1]; } // Avoid `split(regex)` for IE8 compatibility. See #17. string = string.replace(regexSeparators, '\x2E'); var labels = string.split('.'); var encoded = map(labels, fn).join('.'); return result + encoded; } /** * Creates an array containing the numeric code points of each Unicode * character in the string. While JavaScript uses UCS-2 internally, * this function will convert a pair of surrogate halves (each of which * UCS-2 exposes as separate characters) into a single code point, * matching UTF-16. * @see `punycode.ucs2.encode` * @see * @memberOf punycode.ucs2 * @name decode * @param {String} string The Unicode input string (UCS-2). * @returns {Array} The new array of code points. */ function ucs2decode(string) { var output = [], counter = 0, length = string.length, value, extra; while (counter < length) { value = string.charCodeAt(counter++); if (value >= 0xD800 && value <= 0xDBFF && counter < length) { // high surrogate, and there is a next character extra = string.charCodeAt(counter++); if ((extra & 0xFC00) == 0xDC00) { // low surrogate output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000); } else { // unmatched surrogate; only append this code unit, in case the next // code unit is the high surrogate of a surrogate pair output.push(value); counter--; } } else { output.push(value); } } return output; } /** * Creates a string based on an array of numeric code points. * @see `punycode.ucs2.decode` * @memberOf punycode.ucs2 * @name encode * @param {Array} codePoints The array of numeric code points. * @returns {String} The new Unicode string (UCS-2). */ function ucs2encode(array) { return map(array, function(value) { var output = ''; if (value > 0xFFFF) { value -= 0x10000; output += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800); value = 0xDC00 | value & 0x3FF; } output += stringFromCharCode(value); return output; }).join(''); } /** * Converts a basic code point into a digit/integer. * @see `digitToBasic()` * @private * @param {Number} codePoint The basic numeric code point value. * @returns {Number} The numeric value of a basic code point (for use in * representing integers) in the range `0` to `base - 1`, or `base` if * the code point does not represent a value. */ function basicToDigit(codePoint) { if (codePoint - 48 < 10) { return codePoint - 22; } if (codePoint - 65 < 26) { return codePoint - 65; } if (codePoint - 97 < 26) { return codePoint - 97; } return base; } /** * Converts a digit/integer into a basic code point. * @see `basicToDigit()` * @private * @param {Number} digit The numeric value of a basic code point. * @returns {Number} The basic code point whose value (when used for * representing integers) is `digit`, which needs to be in the range * `0` to `base - 1`. If `flag` is non-zero, the uppercase form is * used; else, the lowercase form is used. The behavior is undefined * if `flag` is non-zero and `digit` has no uppercase form. */ function digitToBasic(digit, flag) { // 0..25 map to ASCII a..z or A..Z // 26..35 map to ASCII 0..9 return digit + 22 + 75 * (digit < 26) - ((flag != 0) << 5); } /** * Bias adaptation function as per section 3.4 of RFC 3492. * https://tools.ietf.org/html/rfc3492#section-3.4 * @private */ function adapt(delta, numPoints, firstTime) { var k = 0; delta = firstTime ? floor(delta / damp) : delta >> 1; delta += floor(delta / numPoints); for (/* no initialization */; delta > baseMinusTMin * tMax >> 1; k += base) { delta = floor(delta / baseMinusTMin); } return floor(k + (baseMinusTMin + 1) * delta / (delta + skew)); } /** * Converts a Punycode string of ASCII-only symbols to a string of Unicode * symbols. * @memberOf punycode * @param {String} input The Punycode string of ASCII-only symbols. * @returns {String} The resulting string of Unicode symbols. */ function decode(input) { // Don't use UCS-2 var output = [], inputLength = input.length, out, i = 0, n = initialN, bias = initialBias, basic, j, index, oldi, w, k, digit, t, /** Cached calculation results */ baseMinusT; // Handle the basic code points: let `basic` be the number of input code // points before the last delimiter, or `0` if there is none, then copy // the first basic code points to the output. basic = input.lastIndexOf(delimiter); if (basic < 0) { basic = 0; } for (j = 0; j < basic; ++j) { // if it's not a basic code point if (input.charCodeAt(j) >= 0x80) { error('not-basic'); } output.push(input.charCodeAt(j)); } // Main decoding loop: start just after the last delimiter if any basic code // points were copied; start at the beginning otherwise. for (index = basic > 0 ? basic + 1 : 0; index < inputLength; /* no final expression */) { // `index` is the index of the next character to be consumed. // Decode a generalized variable-length integer into `delta`, // which gets added to `i`. The overflow checking is easier // if we increase `i` as we go, then subtract off its starting // value at the end to obtain `delta`. for (oldi = i, w = 1, k = base; /* no condition */; k += base) { if (index >= inputLength) { error('invalid-input'); } digit = basicToDigit(input.charCodeAt(index++)); if (digit >= base || digit > floor((maxInt - i) / w)) { error('overflow'); } i += digit * w; t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias); if (digit < t) { break; } baseMinusT = base - t; if (w > floor(maxInt / baseMinusT)) { error('overflow'); } w *= baseMinusT; } out = output.length + 1; bias = adapt(i - oldi, out, oldi == 0); // `i` was supposed to wrap around from `out` to `0`, // incrementing `n` each time, so we'll fix that now: if (floor(i / out) > maxInt - n) { error('overflow'); } n += floor(i / out); i %= out; // Insert `n` at position `i` of the output output.splice(i++, 0, n); } return ucs2encode(output); } /** * Converts a string of Unicode symbols (e.g. a domain name label) to a * Punycode string of ASCII-only symbols. * @memberOf punycode * @param {String} input The string of Unicode symbols. * @returns {String} The resulting Punycode string of ASCII-only symbols. */ function encode(input) { var n, delta, handledCPCount, basicLength, bias, j, m, q, k, t, currentValue, output = [], /** `inputLength` will hold the number of code points in `input`. */ inputLength, /** Cached calculation results */ handledCPCountPlusOne, baseMinusT, qMinusT; // Convert the input in UCS-2 to Unicode input = ucs2decode(input); // Cache the length inputLength = input.length; // Initialize the state n = initialN; delta = 0; bias = initialBias; // Handle the basic code points for (j = 0; j < inputLength; ++j) { currentValue = input[j]; if (currentValue < 0x80) { output.push(stringFromCharCode(currentValue)); } } handledCPCount = basicLength = output.length; // `handledCPCount` is the number of code points that have been handled; // `basicLength` is the number of basic code points. // Finish the basic string - if it is not empty - with a delimiter if (basicLength) { output.push(delimiter); } // Main encoding loop: while (handledCPCount < inputLength) { // All non-basic code points < n have been handled already. Find the next // larger one: for (m = maxInt, j = 0; j < inputLength; ++j) { currentValue = input[j]; if (currentValue >= n && currentValue < m) { m = currentValue; } } // Increase `delta` enough to advance the decoder's state to , // but guard against overflow handledCPCountPlusOne = handledCPCount + 1; if (m - n > floor((maxInt - delta) / handledCPCountPlusOne)) { error('overflow'); } delta += (m - n) * handledCPCountPlusOne; n = m; for (j = 0; j < inputLength; ++j) { currentValue = input[j]; if (currentValue < n && ++delta > maxInt) { error('overflow'); } if (currentValue == n) { // Represent delta as a generalized variable-length integer for (q = delta, k = base; /* no condition */; k += base) { t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias); if (q < t) { break; } qMinusT = q - t; baseMinusT = base - t; output.push( stringFromCharCode(digitToBasic(t + qMinusT % baseMinusT, 0)) ); q = floor(qMinusT / baseMinusT); } output.push(stringFromCharCode(digitToBasic(q, 0))); bias = adapt(delta, handledCPCountPlusOne, handledCPCount == basicLength); delta = 0; ++handledCPCount; } } ++delta; ++n; } return output.join(''); } /** * Converts a Punycode string representing a domain name or an email address * to Unicode. Only the Punycoded parts of the input will be converted, i.e. * it doesn't matter if you call it on a string that has already been * converted to Unicode. * @memberOf punycode * @param {String} input The Punycoded domain name or email address to * convert to Unicode. * @returns {String} The Unicode representation of the given Punycode * string. */ function toUnicode(input) { return mapDomain(input, function(string) { return regexPunycode.test(string) ? decode(string.slice(4).toLowerCase()) : string; }); } /** * Converts a Unicode string representing a domain name or an email address to * Punycode. Only the non-ASCII parts of the domain name will be converted, * i.e. it doesn't matter if you call it with a domain that's already in * ASCII. * @memberOf punycode * @param {String} input The domain name or email address to convert, as a * Unicode string. * @returns {String} The Punycode representation of the given domain name or * email address. */ function toASCII(input) { return mapDomain(input, function(string) { return regexNonASCII.test(string) ? 'xn--' + encode(string) : string; }); } /*--------------------------------------------------------------------------*/ /** Define the public API */ punycode = { /** * A string representing the current Punycode.js version number. * @memberOf punycode * @type String */ 'version': '1.4.1', /** * An object of methods to convert from JavaScript's internal character * representation (UCS-2) to Unicode code points, and back. * @see * @memberOf punycode * @type Object */ 'ucs2': { 'decode': ucs2decode, 'encode': ucs2encode }, 'decode': decode, 'encode': encode, 'toASCII': toASCII, 'toUnicode': toUnicode }; /** Expose `punycode` */ // Some AMD build optimizers, like r.js, check for specific condition patterns // like the following: if ( typeof define == 'function' && typeof define.amd == 'object' && define.amd ) { define('punycode', function() { return punycode; }); } else if (freeExports && freeModule) { if (module.exports == freeExports) { // in Node.js, io.js, or RingoJS v0.8.0+ freeModule.exports = punycode; } else { // in Narwhal or RingoJS v0.7.0- for (key in punycode) { punycode.hasOwnProperty(key) && (freeExports[key] = punycode[key]); } } } else { // in Rhino or a web browser root.punycode = punycode; } }(this)); }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{}],63:[function(require,module,exports){ // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to permit // persons to whom the Software is furnished to do so, subject to the // following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. 'use strict'; // If obj.hasOwnProperty has been overridden, then calling // obj.hasOwnProperty(prop) will break. // See: https://github.com/joyent/node/issues/1707 function hasOwnProperty(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); } module.exports = function(qs, sep, eq, options) { sep = sep || '&'; eq = eq || '='; var obj = {}; if (typeof qs !== 'string' || qs.length === 0) { return obj; } var regexp = /\+/g; qs = qs.split(sep); var maxKeys = 1000; if (options && typeof options.maxKeys === 'number') { maxKeys = options.maxKeys; } var len = qs.length; // maxKeys <= 0 means that we should not limit keys count if (maxKeys > 0 && len > maxKeys) { len = maxKeys; } for (var i = 0; i < len; ++i) { var x = qs[i].replace(regexp, '%20'), idx = x.indexOf(eq), kstr, vstr, k, v; if (idx >= 0) { kstr = x.substr(0, idx); vstr = x.substr(idx + 1); } else { kstr = x; vstr = ''; } k = decodeURIComponent(kstr); v = decodeURIComponent(vstr); if (!hasOwnProperty(obj, k)) { obj[k] = v; } else if (isArray(obj[k])) { obj[k].push(v); } else { obj[k] = [obj[k], v]; } } return obj; }; var isArray = Array.isArray || function (xs) { return Object.prototype.toString.call(xs) === '[object Array]'; }; },{}],64:[function(require,module,exports){ // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to permit // persons to whom the Software is furnished to do so, subject to the // following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. 'use strict'; var stringifyPrimitive = function(v) { switch (typeof v) { case 'string': return v; case 'boolean': return v ? 'true' : 'false'; case 'number': return isFinite(v) ? v : ''; default: return ''; } }; module.exports = function(obj, sep, eq, name) { sep = sep || '&'; eq = eq || '='; if (obj === null) { obj = undefined; } if (typeof obj === 'object') { return map(objectKeys(obj), function(k) { var ks = encodeURIComponent(stringifyPrimitive(k)) + eq; if (isArray(obj[k])) { return map(obj[k], function(v) { return ks + encodeURIComponent(stringifyPrimitive(v)); }).join(sep); } else { return ks + encodeURIComponent(stringifyPrimitive(obj[k])); } }).join(sep); } if (!name) return ''; return encodeURIComponent(stringifyPrimitive(name)) + eq + encodeURIComponent(stringifyPrimitive(obj)); }; var isArray = Array.isArray || function (xs) { return Object.prototype.toString.call(xs) === '[object Array]'; }; function map (xs, f) { if (xs.map) return xs.map(f); var res = []; for (var i = 0; i < xs.length; i++) { res.push(f(xs[i], i)); } return res; } var objectKeys = Object.keys || function (obj) { var res = []; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) res.push(key); } return res; }; },{}],65:[function(require,module,exports){ 'use strict'; exports.decode = exports.parse = require('./decode'); exports.encode = exports.stringify = require('./encode'); },{"./decode":63,"./encode":64}],66:[function(require,module,exports){ // a duplex stream is just a stream that is both readable and writable. // Since JS doesn't have multiple prototypal inheritance, this class // prototypally inherits from Readable, and then parasitically from // Writable. 'use strict'; /**/ var objectKeys = Object.keys || function (obj) { var keys = []; for (var key in obj) { keys.push(key); }return keys; }; /**/ module.exports = Duplex; /**/ var processNextTick = require('process-nextick-args'); /**/ /**/ var util = require('core-util-is'); util.inherits = require('inherits'); /**/ var Readable = require('./_stream_readable'); var Writable = require('./_stream_writable'); util.inherits(Duplex, Readable); var keys = objectKeys(Writable.prototype); for (var v = 0; v < keys.length; v++) { var method = keys[v]; if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable.prototype[method]; } function Duplex(options) { if (!(this instanceof Duplex)) return new Duplex(options); Readable.call(this, options); Writable.call(this, options); if (options && options.readable === false) this.readable = false; if (options && options.writable === false) this.writable = false; this.allowHalfOpen = true; if (options && options.allowHalfOpen === false) this.allowHalfOpen = false; this.once('end', onend); } // the no-half-open enforcer function onend() { // if we allow half-open state, or if the writable side ended, // then we're ok. if (this.allowHalfOpen || this._writableState.ended) return; // no more data can be written. // But allow more writes to happen in this tick. processNextTick(onEndNT, this); } function onEndNT(self) { self.end(); } function forEach(xs, f) { for (var i = 0, l = xs.length; i < l; i++) { f(xs[i], i); } } },{"./_stream_readable":68,"./_stream_writable":70,"core-util-is":8,"inherits":52,"process-nextick-args":60}],67:[function(require,module,exports){ // a passthrough stream. // basically just the most minimal sort of Transform stream. // Every written chunk gets output as-is. 'use strict'; module.exports = PassThrough; var Transform = require('./_stream_transform'); /**/ var util = require('core-util-is'); util.inherits = require('inherits'); /**/ util.inherits(PassThrough, Transform); function PassThrough(options) { if (!(this instanceof PassThrough)) return new PassThrough(options); Transform.call(this, options); } PassThrough.prototype._transform = function (chunk, encoding, cb) { cb(null, chunk); }; },{"./_stream_transform":69,"core-util-is":8,"inherits":52}],68:[function(require,module,exports){ (function (process){ 'use strict'; module.exports = Readable; /**/ var processNextTick = require('process-nextick-args'); /**/ /**/ var isArray = require('isarray'); /**/ /**/ var Duplex; /**/ Readable.ReadableState = ReadableState; /**/ var EE = require('events').EventEmitter; var EElistenerCount = function (emitter, type) { return emitter.listeners(type).length; }; /**/ /**/ var Stream = require('./internal/streams/stream'); /**/ var Buffer = require('buffer').Buffer; /**/ var bufferShim = require('buffer-shims'); /**/ /**/ var util = require('core-util-is'); util.inherits = require('inherits'); /**/ /**/ var debugUtil = require('util'); var debug = void 0; if (debugUtil && debugUtil.debuglog) { debug = debugUtil.debuglog('stream'); } else { debug = function () {}; } /**/ var BufferList = require('./internal/streams/BufferList'); var StringDecoder; util.inherits(Readable, Stream); var kProxyEvents = ['error', 'close', 'destroy', 'pause', 'resume']; function prependListener(emitter, event, fn) { // Sadly this is not cacheable as some libraries bundle their own // event emitter implementation with them. if (typeof emitter.prependListener === 'function') { return emitter.prependListener(event, fn); } else { // This is a hack to make sure that our error handler is attached before any // userland ones. NEVER DO THIS. This is here only because this code needs // to continue to work with older versions of Node.js that do not include // the prependListener() method. The goal is to eventually remove this hack. if (!emitter._events || !emitter._events[event]) emitter.on(event, fn);else if (isArray(emitter._events[event])) emitter._events[event].unshift(fn);else emitter._events[event] = [fn, emitter._events[event]]; } } function ReadableState(options, stream) { Duplex = Duplex || require('./_stream_duplex'); options = options || {}; // object stream flag. Used to make read(n) ignore n and to // make all the buffer merging and length checks go away this.objectMode = !!options.objectMode; if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.readableObjectMode; // the point at which it stops calling _read() to fill the buffer // Note: 0 is a valid value, means "don't call _read preemptively ever" var hwm = options.highWaterMark; var defaultHwm = this.objectMode ? 16 : 16 * 1024; this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm; // cast to ints. this.highWaterMark = ~~this.highWaterMark; // A linked list is used to store data chunks instead of an array because the // linked list can remove elements from the beginning faster than // array.shift() this.buffer = new BufferList(); this.length = 0; this.pipes = null; this.pipesCount = 0; this.flowing = null; this.ended = false; this.endEmitted = false; this.reading = false; // a flag to be able to tell if the onwrite cb is called immediately, // or on a later tick. We set this to true at first, because any // actions that shouldn't happen until "later" should generally also // not happen before the first write call. this.sync = true; // whenever we return null, then we set a flag to say // that we're awaiting a 'readable' event emission. this.needReadable = false; this.emittedReadable = false; this.readableListening = false; this.resumeScheduled = false; // Crypto is kind of old and crusty. Historically, its default string // encoding is 'binary' so we have to make this configurable. // Everything else in the universe uses 'utf8', though. this.defaultEncoding = options.defaultEncoding || 'utf8'; // when piping, we only care about 'readable' events that happen // after read()ing all the bytes and not getting any pushback. this.ranOut = false; // the number of writers that are awaiting a drain event in .pipe()s this.awaitDrain = 0; // if true, a maybeReadMore has been scheduled this.readingMore = false; this.decoder = null; this.encoding = null; if (options.encoding) { if (!StringDecoder) StringDecoder = require('string_decoder/').StringDecoder; this.decoder = new StringDecoder(options.encoding); this.encoding = options.encoding; } } function Readable(options) { Duplex = Duplex || require('./_stream_duplex'); if (!(this instanceof Readable)) return new Readable(options); this._readableState = new ReadableState(options, this); // legacy this.readable = true; if (options && typeof options.read === 'function') this._read = options.read; Stream.call(this); } // Manually shove something into the read() buffer. // This returns true if the highWaterMark has not been hit yet, // similar to how Writable.write() returns true if you should // write() some more. Readable.prototype.push = function (chunk, encoding) { var state = this._readableState; if (!state.objectMode && typeof chunk === 'string') { encoding = encoding || state.defaultEncoding; if (encoding !== state.encoding) { chunk = bufferShim.from(chunk, encoding); encoding = ''; } } return readableAddChunk(this, state, chunk, encoding, false); }; // Unshift should *always* be something directly out of read() Readable.prototype.unshift = function (chunk) { var state = this._readableState; return readableAddChunk(this, state, chunk, '', true); }; Readable.prototype.isPaused = function () { return this._readableState.flowing === false; }; function readableAddChunk(stream, state, chunk, encoding, addToFront) { var er = chunkInvalid(state, chunk); if (er) { stream.emit('error', er); } else if (chunk === null) { state.reading = false; onEofChunk(stream, state); } else if (state.objectMode || chunk && chunk.length > 0) { if (state.ended && !addToFront) { var e = new Error('stream.push() after EOF'); stream.emit('error', e); } else if (state.endEmitted && addToFront) { var _e = new Error('stream.unshift() after end event'); stream.emit('error', _e); } else { var skipAdd; if (state.decoder && !addToFront && !encoding) { chunk = state.decoder.write(chunk); skipAdd = !state.objectMode && chunk.length === 0; } if (!addToFront) state.reading = false; // Don't add to the buffer if we've decoded to an empty string chunk and // we're not in object mode if (!skipAdd) { // if we want the data now, just emit it. if (state.flowing && state.length === 0 && !state.sync) { stream.emit('data', chunk); stream.read(0); } else { // update the buffer info. state.length += state.objectMode ? 1 : chunk.length; if (addToFront) state.buffer.unshift(chunk);else state.buffer.push(chunk); if (state.needReadable) emitReadable(stream); } } maybeReadMore(stream, state); } } else if (!addToFront) { state.reading = false; } return needMoreData(state); } // if it's past the high water mark, we can push in some more. // Also, if we have no data yet, we can stand some // more bytes. This is to work around cases where hwm=0, // such as the repl. Also, if the push() triggered a // readable event, and the user called read(largeNumber) such that // needReadable was set, then we ought to push more, so that another // 'readable' event will be triggered. function needMoreData(state) { return !state.ended && (state.needReadable || state.length < state.highWaterMark || state.length === 0); } // backwards compatibility. Readable.prototype.setEncoding = function (enc) { if (!StringDecoder) StringDecoder = require('string_decoder/').StringDecoder; this._readableState.decoder = new StringDecoder(enc); this._readableState.encoding = enc; return this; }; // Don't raise the hwm > 8MB var MAX_HWM = 0x800000; function computeNewHighWaterMark(n) { if (n >= MAX_HWM) { n = MAX_HWM; } else { // Get the next highest power of 2 to prevent increasing hwm excessively in // tiny amounts n--; n |= n >>> 1; n |= n >>> 2; n |= n >>> 4; n |= n >>> 8; n |= n >>> 16; n++; } return n; } // This function is designed to be inlinable, so please take care when making // changes to the function body. function howMuchToRead(n, state) { if (n <= 0 || state.length === 0 && state.ended) return 0; if (state.objectMode) return 1; if (n !== n) { // Only flow one buffer at a time if (state.flowing && state.length) return state.buffer.head.data.length;else return state.length; } // If we're asking for more than the current hwm, then raise the hwm. if (n > state.highWaterMark) state.highWaterMark = computeNewHighWaterMark(n); if (n <= state.length) return n; // Don't have enough if (!state.ended) { state.needReadable = true; return 0; } return state.length; } // you can override either this method, or the async _read(n) below. Readable.prototype.read = function (n) { debug('read', n); n = parseInt(n, 10); var state = this._readableState; var nOrig = n; if (n !== 0) state.emittedReadable = false; // if we're doing read(0) to trigger a readable event, but we // already have a bunch of data in the buffer, then just trigger // the 'readable' event and move on. if (n === 0 && state.needReadable && (state.length >= state.highWaterMark || state.ended)) { debug('read: emitReadable', state.length, state.ended); if (state.length === 0 && state.ended) endReadable(this);else emitReadable(this); return null; } n = howMuchToRead(n, state); // if we've ended, and we're now clear, then finish it up. if (n === 0 && state.ended) { if (state.length === 0) endReadable(this); return null; } // All the actual chunk generation logic needs to be // *below* the call to _read. The reason is that in certain // synthetic stream cases, such as passthrough streams, _read // may be a completely synchronous operation which may change // the state of the read buffer, providing enough data when // before there was *not* enough. // // So, the steps are: // 1. Figure out what the state of things will be after we do // a read from the buffer. // // 2. If that resulting state will trigger a _read, then call _read. // Note that this may be asynchronous, or synchronous. Yes, it is // deeply ugly to write APIs this way, but that still doesn't mean // that the Readable class should behave improperly, as streams are // designed to be sync/async agnostic. // Take note if the _read call is sync or async (ie, if the read call // has returned yet), so that we know whether or not it's safe to emit // 'readable' etc. // // 3. Actually pull the requested chunks out of the buffer and return. // if we need a readable event, then we need to do some reading. var doRead = state.needReadable; debug('need readable', doRead); // if we currently have less than the highWaterMark, then also read some if (state.length === 0 || state.length - n < state.highWaterMark) { doRead = true; debug('length less than watermark', doRead); } // however, if we've ended, then there's no point, and if we're already // reading, then it's unnecessary. if (state.ended || state.reading) { doRead = false; debug('reading or ended', doRead); } else if (doRead) { debug('do read'); state.reading = true; state.sync = true; // if the length is currently zero, then we *need* a readable event. if (state.length === 0) state.needReadable = true; // call internal read method this._read(state.highWaterMark); state.sync = false; // If _read pushed data synchronously, then `reading` will be false, // and we need to re-evaluate how much data we can return to the user. if (!state.reading) n = howMuchToRead(nOrig, state); } var ret; if (n > 0) ret = fromList(n, state);else ret = null; if (ret === null) { state.needReadable = true; n = 0; } else { state.length -= n; } if (state.length === 0) { // If we have nothing in the buffer, then we want to know // as soon as we *do* get something into the buffer. if (!state.ended) state.needReadable = true; // If we tried to read() past the EOF, then emit end on the next tick. if (nOrig !== n && state.ended) endReadable(this); } if (ret !== null) this.emit('data', ret); return ret; }; function chunkInvalid(state, chunk) { var er = null; if (!Buffer.isBuffer(chunk) && typeof chunk !== 'string' && chunk !== null && chunk !== undefined && !state.objectMode) { er = new TypeError('Invalid non-string/buffer chunk'); } return er; } function onEofChunk(stream, state) { if (state.ended) return; if (state.decoder) { var chunk = state.decoder.end(); if (chunk && chunk.length) { state.buffer.push(chunk); state.length += state.objectMode ? 1 : chunk.length; } } state.ended = true; // emit 'readable' now to make sure it gets picked up. emitReadable(stream); } // Don't emit readable right away in sync mode, because this can trigger // another read() call => stack overflow. This way, it might trigger // a nextTick recursion warning, but that's not so bad. function emitReadable(stream) { var state = stream._readableState; state.needReadable = false; if (!state.emittedReadable) { debug('emitReadable', state.flowing); state.emittedReadable = true; if (state.sync) processNextTick(emitReadable_, stream);else emitReadable_(stream); } } function emitReadable_(stream) { debug('emit readable'); stream.emit('readable'); flow(stream); } // at this point, the user has presumably seen the 'readable' event, // and called read() to consume some data. that may have triggered // in turn another _read(n) call, in which case reading = true if // it's in progress. // However, if we're not ended, or reading, and the length < hwm, // then go ahead and try to read some more preemptively. function maybeReadMore(stream, state) { if (!state.readingMore) { state.readingMore = true; processNextTick(maybeReadMore_, stream, state); } } function maybeReadMore_(stream, state) { var len = state.length; while (!state.reading && !state.flowing && !state.ended && state.length < state.highWaterMark) { debug('maybeReadMore read 0'); stream.read(0); if (len === state.length) // didn't get any data, stop spinning. break;else len = state.length; } state.readingMore = false; } // abstract method. to be overridden in specific implementation classes. // call cb(er, data) where data is <= n in length. // for virtual (non-string, non-buffer) streams, "length" is somewhat // arbitrary, and perhaps not very meaningful. Readable.prototype._read = function (n) { this.emit('error', new Error('_read() is not implemented')); }; Readable.prototype.pipe = function (dest, pipeOpts) { var src = this; var state = this._readableState; switch (state.pipesCount) { case 0: state.pipes = dest; break; case 1: state.pipes = [state.pipes, dest]; break; default: state.pipes.push(dest); break; } state.pipesCount += 1; debug('pipe count=%d opts=%j', state.pipesCount, pipeOpts); var doEnd = (!pipeOpts || pipeOpts.end !== false) && dest !== process.stdout && dest !== process.stderr; var endFn = doEnd ? onend : cleanup; if (state.endEmitted) processNextTick(endFn);else src.once('end', endFn); dest.on('unpipe', onunpipe); function onunpipe(readable) { debug('onunpipe'); if (readable === src) { cleanup(); } } function onend() { debug('onend'); dest.end(); } // when the dest drains, it reduces the awaitDrain counter // on the source. This would be more elegant with a .once() // handler in flow(), but adding and removing repeatedly is // too slow. var ondrain = pipeOnDrain(src); dest.on('drain', ondrain); var cleanedUp = false; function cleanup() { debug('cleanup'); // cleanup event handlers once the pipe is broken dest.removeListener('close', onclose); dest.removeListener('finish', onfinish); dest.removeListener('drain', ondrain); dest.removeListener('error', onerror); dest.removeListener('unpipe', onunpipe); src.removeListener('end', onend); src.removeListener('end', cleanup); src.removeListener('data', ondata); cleanedUp = true; // if the reader is waiting for a drain event from this // specific writer, then it would cause it to never start // flowing again. // So, if this is awaiting a drain, then we just call it now. // If we don't know, then assume that we are waiting for one. if (state.awaitDrain && (!dest._writableState || dest._writableState.needDrain)) ondrain(); } // If the user pushes more data while we're writing to dest then we'll end up // in ondata again. However, we only want to increase awaitDrain once because // dest will only emit one 'drain' event for the multiple writes. // => Introduce a guard on increasing awaitDrain. var increasedAwaitDrain = false; src.on('data', ondata); function ondata(chunk) { debug('ondata'); increasedAwaitDrain = false; var ret = dest.write(chunk); if (false === ret && !increasedAwaitDrain) { // If the user unpiped during `dest.write()`, it is possible // to get stuck in a permanently paused state if that write // also returned false. // => Check whether `dest` is still a piping destination. if ((state.pipesCount === 1 && state.pipes === dest || state.pipesCount > 1 && indexOf(state.pipes, dest) !== -1) && !cleanedUp) { debug('false write response, pause', src._readableState.awaitDrain); src._readableState.awaitDrain++; increasedAwaitDrain = true; } src.pause(); } } // if the dest has an error, then stop piping into it. // however, don't suppress the throwing behavior for this. function onerror(er) { debug('onerror', er); unpipe(); dest.removeListener('error', onerror); if (EElistenerCount(dest, 'error') === 0) dest.emit('error', er); } // Make sure our error handler is attached before userland ones. prependListener(dest, 'error', onerror); // Both close and finish should trigger unpipe, but only once. function onclose() { dest.removeListener('finish', onfinish); unpipe(); } dest.once('close', onclose); function onfinish() { debug('onfinish'); dest.removeListener('close', onclose); unpipe(); } dest.once('finish', onfinish); function unpipe() { debug('unpipe'); src.unpipe(dest); } // tell the dest that it's being piped to dest.emit('pipe', src); // start the flow if it hasn't been started already. if (!state.flowing) { debug('pipe resume'); src.resume(); } return dest; }; function pipeOnDrain(src) { return function () { var state = src._readableState; debug('pipeOnDrain', state.awaitDrain); if (state.awaitDrain) state.awaitDrain--; if (state.awaitDrain === 0 && EElistenerCount(src, 'data')) { state.flowing = true; flow(src); } }; } Readable.prototype.unpipe = function (dest) { var state = this._readableState; // if we're not piping anywhere, then do nothing. if (state.pipesCount === 0) return this; // just one destination. most common case. if (state.pipesCount === 1) { // passed in one, but it's not the right one. if (dest && dest !== state.pipes) return this; if (!dest) dest = state.pipes; // got a match. state.pipes = null; state.pipesCount = 0; state.flowing = false; if (dest) dest.emit('unpipe', this); return this; } // slow case. multiple pipe destinations. if (!dest) { // remove all. var dests = state.pipes; var len = state.pipesCount; state.pipes = null; state.pipesCount = 0; state.flowing = false; for (var i = 0; i < len; i++) { dests[i].emit('unpipe', this); }return this; } // try to find the right one. var index = indexOf(state.pipes, dest); if (index === -1) return this; state.pipes.splice(index, 1); state.pipesCount -= 1; if (state.pipesCount === 1) state.pipes = state.pipes[0]; dest.emit('unpipe', this); return this; }; // set up data events if they are asked for // Ensure readable listeners eventually get something Readable.prototype.on = function (ev, fn) { var res = Stream.prototype.on.call(this, ev, fn); if (ev === 'data') { // Start flowing on next tick if stream isn't explicitly paused if (this._readableState.flowing !== false) this.resume(); } else if (ev === 'readable') { var state = this._readableState; if (!state.endEmitted && !state.readableListening) { state.readableListening = state.needReadable = true; state.emittedReadable = false; if (!state.reading) { processNextTick(nReadingNextTick, this); } else if (state.length) { emitReadable(this, state); } } } return res; }; Readable.prototype.addListener = Readable.prototype.on; function nReadingNextTick(self) { debug('readable nexttick read 0'); self.read(0); } // pause() and resume() are remnants of the legacy readable stream API // If the user uses them, then switch into old mode. Readable.prototype.resume = function () { var state = this._readableState; if (!state.flowing) { debug('resume'); state.flowing = true; resume(this, state); } return this; }; function resume(stream, state) { if (!state.resumeScheduled) { state.resumeScheduled = true; processNextTick(resume_, stream, state); } } function resume_(stream, state) { if (!state.reading) { debug('resume read 0'); stream.read(0); } state.resumeScheduled = false; state.awaitDrain = 0; stream.emit('resume'); flow(stream); if (state.flowing && !state.reading) stream.read(0); } Readable.prototype.pause = function () { debug('call pause flowing=%j', this._readableState.flowing); if (false !== this._readableState.flowing) { debug('pause'); this._readableState.flowing = false; this.emit('pause'); } return this; }; function flow(stream) { var state = stream._readableState; debug('flow', state.flowing); while (state.flowing && stream.read() !== null) {} } // wrap an old-style stream as the async data source. // This is *not* part of the readable stream interface. // It is an ugly unfortunate mess of history. Readable.prototype.wrap = function (stream) { var state = this._readableState; var paused = false; var self = this; stream.on('end', function () { debug('wrapped end'); if (state.decoder && !state.ended) { var chunk = state.decoder.end(); if (chunk && chunk.length) self.push(chunk); } self.push(null); }); stream.on('data', function (chunk) { debug('wrapped data'); if (state.decoder) chunk = state.decoder.write(chunk); // don't skip over falsy values in objectMode if (state.objectMode && (chunk === null || chunk === undefined)) return;else if (!state.objectMode && (!chunk || !chunk.length)) return; var ret = self.push(chunk); if (!ret) { paused = true; stream.pause(); } }); // proxy all the other methods. // important when wrapping filters and duplexes. for (var i in stream) { if (this[i] === undefined && typeof stream[i] === 'function') { this[i] = function (method) { return function () { return stream[method].apply(stream, arguments); }; }(i); } } // proxy certain important events. for (var n = 0; n < kProxyEvents.length; n++) { stream.on(kProxyEvents[n], self.emit.bind(self, kProxyEvents[n])); } // when we try to consume some more bytes, simply unpause the // underlying stream. self._read = function (n) { debug('wrapped _read', n); if (paused) { paused = false; stream.resume(); } }; return self; }; // exposed for testing purposes only. Readable._fromList = fromList; // Pluck off n bytes from an array of buffers. // Length is the combined lengths of all the buffers in the list. // This function is designed to be inlinable, so please take care when making // changes to the function body. function fromList(n, state) { // nothing buffered if (state.length === 0) return null; var ret; if (state.objectMode) ret = state.buffer.shift();else if (!n || n >= state.length) { // read it all, truncate the list if (state.decoder) ret = state.buffer.join('');else if (state.buffer.length === 1) ret = state.buffer.head.data;else ret = state.buffer.concat(state.length); state.buffer.clear(); } else { // read part of list ret = fromListPartial(n, state.buffer, state.decoder); } return ret; } // Extracts only enough buffered data to satisfy the amount requested. // This function is designed to be inlinable, so please take care when making // changes to the function body. function fromListPartial(n, list, hasStrings) { var ret; if (n < list.head.data.length) { // slice is the same for buffers and strings ret = list.head.data.slice(0, n); list.head.data = list.head.data.slice(n); } else if (n === list.head.data.length) { // first chunk is a perfect match ret = list.shift(); } else { // result spans more than one buffer ret = hasStrings ? copyFromBufferString(n, list) : copyFromBuffer(n, list); } return ret; } // Copies a specified amount of characters from the list of buffered data // chunks. // This function is designed to be inlinable, so please take care when making // changes to the function body. function copyFromBufferString(n, list) { var p = list.head; var c = 1; var ret = p.data; n -= ret.length; while (p = p.next) { var str = p.data; var nb = n > str.length ? str.length : n; if (nb === str.length) ret += str;else ret += str.slice(0, n); n -= nb; if (n === 0) { if (nb === str.length) { ++c; if (p.next) list.head = p.next;else list.head = list.tail = null; } else { list.head = p; p.data = str.slice(nb); } break; } ++c; } list.length -= c; return ret; } // Copies a specified amount of bytes from the list of buffered data chunks. // This function is designed to be inlinable, so please take care when making // changes to the function body. function copyFromBuffer(n, list) { var ret = bufferShim.allocUnsafe(n); var p = list.head; var c = 1; p.data.copy(ret); n -= p.data.length; while (p = p.next) { var buf = p.data; var nb = n > buf.length ? buf.length : n; buf.copy(ret, ret.length - n, 0, nb); n -= nb; if (n === 0) { if (nb === buf.length) { ++c; if (p.next) list.head = p.next;else list.head = list.tail = null; } else { list.head = p; p.data = buf.slice(nb); } break; } ++c; } list.length -= c; return ret; } function endReadable(stream) { var state = stream._readableState; // If we get here before consuming all the bytes, then that is a // bug in node. Should never happen. if (state.length > 0) throw new Error('"endReadable()" called on non-empty stream'); if (!state.endEmitted) { state.ended = true; processNextTick(endReadableNT, state, stream); } } function endReadableNT(state, stream) { // Check that we didn't get one last unshift. if (!state.endEmitted && state.length === 0) { state.endEmitted = true; stream.readable = false; stream.emit('end'); } } function forEach(xs, f) { for (var i = 0, l = xs.length; i < l; i++) { f(xs[i], i); } } function indexOf(xs, x) { for (var i = 0, l = xs.length; i < l; i++) { if (xs[i] === x) return i; } return -1; } }).call(this,require('_process')) },{"./_stream_duplex":66,"./internal/streams/BufferList":71,"./internal/streams/stream":72,"_process":61,"buffer":6,"buffer-shims":5,"core-util-is":8,"events":48,"inherits":52,"isarray":73,"process-nextick-args":60,"string_decoder/":74,"util":3}],69:[function(require,module,exports){ // a transform stream is a readable/writable stream where you do // something with the data. Sometimes it's called a "filter", // but that's not a great name for it, since that implies a thing where // some bits pass through, and others are simply ignored. (That would // be a valid example of a transform, of course.) // // While the output is causally related to the input, it's not a // necessarily symmetric or synchronous transformation. For example, // a zlib stream might take multiple plain-text writes(), and then // emit a single compressed chunk some time in the future. // // Here's how this works: // // The Transform stream has all the aspects of the readable and writable // stream classes. When you write(chunk), that calls _write(chunk,cb) // internally, and returns false if there's a lot of pending writes // buffered up. When you call read(), that calls _read(n) until // there's enough pending readable data buffered up. // // In a transform stream, the written data is placed in a buffer. When // _read(n) is called, it transforms the queued up data, calling the // buffered _write cb's as it consumes chunks. If consuming a single // written chunk would result in multiple output chunks, then the first // outputted bit calls the readcb, and subsequent chunks just go into // the read buffer, and will cause it to emit 'readable' if necessary. // // This way, back-pressure is actually determined by the reading side, // since _read has to be called to start processing a new chunk. However, // a pathological inflate type of transform can cause excessive buffering // here. For example, imagine a stream where every byte of input is // interpreted as an integer from 0-255, and then results in that many // bytes of output. Writing the 4 bytes {ff,ff,ff,ff} would result in // 1kb of data being output. In this case, you could write a very small // amount of input, and end up with a very large amount of output. In // such a pathological inflating mechanism, there'd be no way to tell // the system to stop doing the transform. A single 4MB write could // cause the system to run out of memory. // // However, even in such a pathological case, only a single written chunk // would be consumed, and then the rest would wait (un-transformed) until // the results of the previous transformed chunk were consumed. 'use strict'; module.exports = Transform; var Duplex = require('./_stream_duplex'); /**/ var util = require('core-util-is'); util.inherits = require('inherits'); /**/ util.inherits(Transform, Duplex); function TransformState(stream) { this.afterTransform = function (er, data) { return afterTransform(stream, er, data); }; this.needTransform = false; this.transforming = false; this.writecb = null; this.writechunk = null; this.writeencoding = null; } function afterTransform(stream, er, data) { var ts = stream._transformState; ts.transforming = false; var cb = ts.writecb; if (!cb) return stream.emit('error', new Error('no writecb in Transform class')); ts.writechunk = null; ts.writecb = null; if (data !== null && data !== undefined) stream.push(data); cb(er); var rs = stream._readableState; rs.reading = false; if (rs.needReadable || rs.length < rs.highWaterMark) { stream._read(rs.highWaterMark); } } function Transform(options) { if (!(this instanceof Transform)) return new Transform(options); Duplex.call(this, options); this._transformState = new TransformState(this); var stream = this; // start out asking for a readable event once data is transformed. this._readableState.needReadable = true; // we have implemented the _read method, and done the other things // that Readable wants before the first _read call, so unset the // sync guard flag. this._readableState.sync = false; if (options) { if (typeof options.transform === 'function') this._transform = options.transform; if (typeof options.flush === 'function') this._flush = options.flush; } // When the writable side finishes, then flush out anything remaining. this.once('prefinish', function () { if (typeof this._flush === 'function') this._flush(function (er, data) { done(stream, er, data); });else done(stream); }); } Transform.prototype.push = function (chunk, encoding) { this._transformState.needTransform = false; return Duplex.prototype.push.call(this, chunk, encoding); }; // This is the part where you do stuff! // override this function in implementation classes. // 'chunk' is an input chunk. // // Call `push(newChunk)` to pass along transformed output // to the readable side. You may call 'push' zero or more times. // // Call `cb(err)` when you are done with this chunk. If you pass // an error, then that'll put the hurt on the whole operation. If you // never call cb(), then you'll never get another chunk. Transform.prototype._transform = function (chunk, encoding, cb) { throw new Error('_transform() is not implemented'); }; Transform.prototype._write = function (chunk, encoding, cb) { var ts = this._transformState; ts.writecb = cb; ts.writechunk = chunk; ts.writeencoding = encoding; if (!ts.transforming) { var rs = this._readableState; if (ts.needTransform || rs.needReadable || rs.length < rs.highWaterMark) this._read(rs.highWaterMark); } }; // Doesn't matter what the args are here. // _transform does all the work. // That we got here means that the readable side wants more data. Transform.prototype._read = function (n) { var ts = this._transformState; if (ts.writechunk !== null && ts.writecb && !ts.transforming) { ts.transforming = true; this._transform(ts.writechunk, ts.writeencoding, ts.afterTransform); } else { // mark that we need a transform, so that any data that comes in // will get processed, now that we've asked for it. ts.needTransform = true; } }; function done(stream, er, data) { if (er) return stream.emit('error', er); if (data !== null && data !== undefined) stream.push(data); // if there's nothing in the write buffer, then that means // that nothing more will ever be provided var ws = stream._writableState; var ts = stream._transformState; if (ws.length) throw new Error('Calling transform done when ws.length != 0'); if (ts.transforming) throw new Error('Calling transform done when still transforming'); return stream.push(null); } },{"./_stream_duplex":66,"core-util-is":8,"inherits":52}],70:[function(require,module,exports){ (function (process){ // A bit simpler than readable streams. // Implement an async ._write(chunk, encoding, cb), and it'll handle all // the drain event emission and buffering. 'use strict'; module.exports = Writable; /**/ var processNextTick = require('process-nextick-args'); /**/ /**/ var asyncWrite = !process.browser && ['v0.10', 'v0.9.'].indexOf(process.version.slice(0, 5)) > -1 ? setImmediate : processNextTick; /**/ /**/ var Duplex; /**/ Writable.WritableState = WritableState; /**/ var util = require('core-util-is'); util.inherits = require('inherits'); /**/ /**/ var internalUtil = { deprecate: require('util-deprecate') }; /**/ /**/ var Stream = require('./internal/streams/stream'); /**/ var Buffer = require('buffer').Buffer; /**/ var bufferShim = require('buffer-shims'); /**/ util.inherits(Writable, Stream); function nop() {} function WriteReq(chunk, encoding, cb) { this.chunk = chunk; this.encoding = encoding; this.callback = cb; this.next = null; } function WritableState(options, stream) { Duplex = Duplex || require('./_stream_duplex'); options = options || {}; // object stream flag to indicate whether or not this stream // contains buffers or objects. this.objectMode = !!options.objectMode; if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.writableObjectMode; // the point at which write() starts returning false // Note: 0 is a valid value, means that we always return false if // the entire buffer is not flushed immediately on write() var hwm = options.highWaterMark; var defaultHwm = this.objectMode ? 16 : 16 * 1024; this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm; // cast to ints. this.highWaterMark = ~~this.highWaterMark; // drain event flag. this.needDrain = false; // at the start of calling end() this.ending = false; // when end() has been called, and returned this.ended = false; // when 'finish' is emitted this.finished = false; // should we decode strings into buffers before passing to _write? // this is here so that some node-core streams can optimize string // handling at a lower level. var noDecode = options.decodeStrings === false; this.decodeStrings = !noDecode; // Crypto is kind of old and crusty. Historically, its default string // encoding is 'binary' so we have to make this configurable. // Everything else in the universe uses 'utf8', though. this.defaultEncoding = options.defaultEncoding || 'utf8'; // not an actual buffer we keep track of, but a measurement // of how much we're waiting to get pushed to some underlying // socket or file. this.length = 0; // a flag to see when we're in the middle of a write. this.writing = false; // when true all writes will be buffered until .uncork() call this.corked = 0; // a flag to be able to tell if the onwrite cb is called immediately, // or on a later tick. We set this to true at first, because any // actions that shouldn't happen until "later" should generally also // not happen before the first write call. this.sync = true; // a flag to know if we're processing previously buffered items, which // may call the _write() callback in the same tick, so that we don't // end up in an overlapped onwrite situation. this.bufferProcessing = false; // the callback that's passed to _write(chunk,cb) this.onwrite = function (er) { onwrite(stream, er); }; // the callback that the user supplies to write(chunk,encoding,cb) this.writecb = null; // the amount that is being written when _write is called. this.writelen = 0; this.bufferedRequest = null; this.lastBufferedRequest = null; // number of pending user-supplied write callbacks // this must be 0 before 'finish' can be emitted this.pendingcb = 0; // emit prefinish if the only thing we're waiting for is _write cbs // This is relevant for synchronous Transform streams this.prefinished = false; // True if the error was already emitted and should not be thrown again this.errorEmitted = false; // count buffered requests this.bufferedRequestCount = 0; // allocate the first CorkedRequest, there is always // one allocated and free to use, and we maintain at most two this.corkedRequestsFree = new CorkedRequest(this); } WritableState.prototype.getBuffer = function getBuffer() { var current = this.bufferedRequest; var out = []; while (current) { out.push(current); current = current.next; } return out; }; (function () { try { Object.defineProperty(WritableState.prototype, 'buffer', { get: internalUtil.deprecate(function () { return this.getBuffer(); }, '_writableState.buffer is deprecated. Use _writableState.getBuffer ' + 'instead.') }); } catch (_) {} })(); // Test _writableState for inheritance to account for Duplex streams, // whose prototype chain only points to Readable. var realHasInstance; if (typeof Symbol === 'function' && Symbol.hasInstance && typeof Function.prototype[Symbol.hasInstance] === 'function') { realHasInstance = Function.prototype[Symbol.hasInstance]; Object.defineProperty(Writable, Symbol.hasInstance, { value: function (object) { if (realHasInstance.call(this, object)) return true; return object && object._writableState instanceof WritableState; } }); } else { realHasInstance = function (object) { return object instanceof this; }; } function Writable(options) { Duplex = Duplex || require('./_stream_duplex'); // Writable ctor is applied to Duplexes, too. // `realHasInstance` is necessary because using plain `instanceof` // would return false, as no `_writableState` property is attached. // Trying to use the custom `instanceof` for Writable here will also break the // Node.js LazyTransform implementation, which has a non-trivial getter for // `_writableState` that would lead to infinite recursion. if (!realHasInstance.call(Writable, this) && !(this instanceof Duplex)) { return new Writable(options); } this._writableState = new WritableState(options, this); // legacy. this.writable = true; if (options) { if (typeof options.write === 'function') this._write = options.write; if (typeof options.writev === 'function') this._writev = options.writev; } Stream.call(this); } // Otherwise people can pipe Writable streams, which is just wrong. Writable.prototype.pipe = function () { this.emit('error', new Error('Cannot pipe, not readable')); }; function writeAfterEnd(stream, cb) { var er = new Error('write after end'); // TODO: defer error events consistently everywhere, not just the cb stream.emit('error', er); processNextTick(cb, er); } // Checks that a user-supplied chunk is valid, especially for the particular // mode the stream is in. Currently this means that `null` is never accepted // and undefined/non-string values are only allowed in object mode. function validChunk(stream, state, chunk, cb) { var valid = true; var er = false; if (chunk === null) { er = new TypeError('May not write null values to stream'); } else if (typeof chunk !== 'string' && chunk !== undefined && !state.objectMode) { er = new TypeError('Invalid non-string/buffer chunk'); } if (er) { stream.emit('error', er); processNextTick(cb, er); valid = false; } return valid; } Writable.prototype.write = function (chunk, encoding, cb) { var state = this._writableState; var ret = false; var isBuf = Buffer.isBuffer(chunk); if (typeof encoding === 'function') { cb = encoding; encoding = null; } if (isBuf) encoding = 'buffer';else if (!encoding) encoding = state.defaultEncoding; if (typeof cb !== 'function') cb = nop; if (state.ended) writeAfterEnd(this, cb);else if (isBuf || validChunk(this, state, chunk, cb)) { state.pendingcb++; ret = writeOrBuffer(this, state, isBuf, chunk, encoding, cb); } return ret; }; Writable.prototype.cork = function () { var state = this._writableState; state.corked++; }; Writable.prototype.uncork = function () { var state = this._writableState; if (state.corked) { state.corked--; if (!state.writing && !state.corked && !state.finished && !state.bufferProcessing && state.bufferedRequest) clearBuffer(this, state); } }; Writable.prototype.setDefaultEncoding = function setDefaultEncoding(encoding) { // node::ParseEncoding() requires lower case. if (typeof encoding === 'string') encoding = encoding.toLowerCase(); if (!(['hex', 'utf8', 'utf-8', 'ascii', 'binary', 'base64', 'ucs2', 'ucs-2', 'utf16le', 'utf-16le', 'raw'].indexOf((encoding + '').toLowerCase()) > -1)) throw new TypeError('Unknown encoding: ' + encoding); this._writableState.defaultEncoding = encoding; return this; }; function decodeChunk(state, chunk, encoding) { if (!state.objectMode && state.decodeStrings !== false && typeof chunk === 'string') { chunk = bufferShim.from(chunk, encoding); } return chunk; } // if we're already writing something, then just put this // in the queue, and wait our turn. Otherwise, call _write // If we return false, then we need a drain event, so set that flag. function writeOrBuffer(stream, state, isBuf, chunk, encoding, cb) { if (!isBuf) { chunk = decodeChunk(state, chunk, encoding); if (Buffer.isBuffer(chunk)) encoding = 'buffer'; } var len = state.objectMode ? 1 : chunk.length; state.length += len; var ret = state.length < state.highWaterMark; // we must ensure that previous needDrain will not be reset to false. if (!ret) state.needDrain = true; if (state.writing || state.corked) { var last = state.lastBufferedRequest; state.lastBufferedRequest = new WriteReq(chunk, encoding, cb); if (last) { last.next = state.lastBufferedRequest; } else { state.bufferedRequest = state.lastBufferedRequest; } state.bufferedRequestCount += 1; } else { doWrite(stream, state, false, len, chunk, encoding, cb); } return ret; } function doWrite(stream, state, writev, len, chunk, encoding, cb) { state.writelen = len; state.writecb = cb; state.writing = true; state.sync = true; if (writev) stream._writev(chunk, state.onwrite);else stream._write(chunk, encoding, state.onwrite); state.sync = false; } function onwriteError(stream, state, sync, er, cb) { --state.pendingcb; if (sync) processNextTick(cb, er);else cb(er); stream._writableState.errorEmitted = true; stream.emit('error', er); } function onwriteStateUpdate(state) { state.writing = false; state.writecb = null; state.length -= state.writelen; state.writelen = 0; } function onwrite(stream, er) { var state = stream._writableState; var sync = state.sync; var cb = state.writecb; onwriteStateUpdate(state); if (er) onwriteError(stream, state, sync, er, cb);else { // Check if we're actually ready to finish, but don't emit yet var finished = needFinish(state); if (!finished && !state.corked && !state.bufferProcessing && state.bufferedRequest) { clearBuffer(stream, state); } if (sync) { /**/ asyncWrite(afterWrite, stream, state, finished, cb); /**/ } else { afterWrite(stream, state, finished, cb); } } } function afterWrite(stream, state, finished, cb) { if (!finished) onwriteDrain(stream, state); state.pendingcb--; cb(); finishMaybe(stream, state); } // Must force callback to be called on nextTick, so that we don't // emit 'drain' before the write() consumer gets the 'false' return // value, and has a chance to attach a 'drain' listener. function onwriteDrain(stream, state) { if (state.length === 0 && state.needDrain) { state.needDrain = false; stream.emit('drain'); } } // if there's something in the buffer waiting, then process it function clearBuffer(stream, state) { state.bufferProcessing = true; var entry = state.bufferedRequest; if (stream._writev && entry && entry.next) { // Fast case, write everything using _writev() var l = state.bufferedRequestCount; var buffer = new Array(l); var holder = state.corkedRequestsFree; holder.entry = entry; var count = 0; while (entry) { buffer[count] = entry; entry = entry.next; count += 1; } doWrite(stream, state, true, state.length, buffer, '', holder.finish); // doWrite is almost always async, defer these to save a bit of time // as the hot path ends with doWrite state.pendingcb++; state.lastBufferedRequest = null; if (holder.next) { state.corkedRequestsFree = holder.next; holder.next = null; } else { state.corkedRequestsFree = new CorkedRequest(state); } } else { // Slow case, write chunks one-by-one while (entry) { var chunk = entry.chunk; var encoding = entry.encoding; var cb = entry.callback; var len = state.objectMode ? 1 : chunk.length; doWrite(stream, state, false, len, chunk, encoding, cb); entry = entry.next; // if we didn't call the onwrite immediately, then // it means that we need to wait until it does. // also, that means that the chunk and cb are currently // being processed, so move the buffer counter past them. if (state.writing) { break; } } if (entry === null) state.lastBufferedRequest = null; } state.bufferedRequestCount = 0; state.bufferedRequest = entry; state.bufferProcessing = false; } Writable.prototype._write = function (chunk, encoding, cb) { cb(new Error('_write() is not implemented')); }; Writable.prototype._writev = null; Writable.prototype.end = function (chunk, encoding, cb) { var state = this._writableState; if (typeof chunk === 'function') { cb = chunk; chunk = null; encoding = null; } else if (typeof encoding === 'function') { cb = encoding; encoding = null; } if (chunk !== null && chunk !== undefined) this.write(chunk, encoding); // .end() fully uncorks if (state.corked) { state.corked = 1; this.uncork(); } // ignore unnecessary end() calls. if (!state.ending && !state.finished) endWritable(this, state, cb); }; function needFinish(state) { return state.ending && state.length === 0 && state.bufferedRequest === null && !state.finished && !state.writing; } function prefinish(stream, state) { if (!state.prefinished) { state.prefinished = true; stream.emit('prefinish'); } } function finishMaybe(stream, state) { var need = needFinish(state); if (need) { if (state.pendingcb === 0) { prefinish(stream, state); state.finished = true; stream.emit('finish'); } else { prefinish(stream, state); } } return need; } function endWritable(stream, state, cb) { state.ending = true; finishMaybe(stream, state); if (cb) { if (state.finished) processNextTick(cb);else stream.once('finish', cb); } state.ended = true; stream.writable = false; } // It seems a linked list but it is not // there will be only 2 of these for each stream function CorkedRequest(state) { var _this = this; this.next = null; this.entry = null; this.finish = function (err) { var entry = _this.entry; _this.entry = null; while (entry) { var cb = entry.callback; state.pendingcb--; cb(err); entry = entry.next; } if (state.corkedRequestsFree) { state.corkedRequestsFree.next = _this; } else { state.corkedRequestsFree = _this; } }; } }).call(this,require('_process')) },{"./_stream_duplex":66,"./internal/streams/stream":72,"_process":61,"buffer":6,"buffer-shims":5,"core-util-is":8,"inherits":52,"process-nextick-args":60,"util-deprecate":85}],71:[function(require,module,exports){ 'use strict'; var Buffer = require('buffer').Buffer; /**/ var bufferShim = require('buffer-shims'); /**/ module.exports = BufferList; function BufferList() { this.head = null; this.tail = null; this.length = 0; } BufferList.prototype.push = function (v) { var entry = { data: v, next: null }; if (this.length > 0) this.tail.next = entry;else this.head = entry; this.tail = entry; ++this.length; }; BufferList.prototype.unshift = function (v) { var entry = { data: v, next: this.head }; if (this.length === 0) this.tail = entry; this.head = entry; ++this.length; }; BufferList.prototype.shift = function () { if (this.length === 0) return; var ret = this.head.data; if (this.length === 1) this.head = this.tail = null;else this.head = this.head.next; --this.length; return ret; }; BufferList.prototype.clear = function () { this.head = this.tail = null; this.length = 0; }; BufferList.prototype.join = function (s) { if (this.length === 0) return ''; var p = this.head; var ret = '' + p.data; while (p = p.next) { ret += s + p.data; }return ret; }; BufferList.prototype.concat = function (n) { if (this.length === 0) return bufferShim.alloc(0); if (this.length === 1) return this.head.data; var ret = bufferShim.allocUnsafe(n >>> 0); var p = this.head; var i = 0; while (p) { p.data.copy(ret, i); i += p.data.length; p = p.next; } return ret; }; },{"buffer":6,"buffer-shims":5}],72:[function(require,module,exports){ module.exports = require('events').EventEmitter; },{"events":48}],73:[function(require,module,exports){ var toString = {}.toString; module.exports = Array.isArray || function (arr) { return toString.call(arr) == '[object Array]'; }; },{}],74:[function(require,module,exports){ 'use strict'; var Buffer = require('buffer').Buffer; var bufferShim = require('buffer-shims'); var isEncoding = Buffer.isEncoding || function (encoding) { encoding = '' + encoding; switch (encoding && encoding.toLowerCase()) { case 'hex':case 'utf8':case 'utf-8':case 'ascii':case 'binary':case 'base64':case 'ucs2':case 'ucs-2':case 'utf16le':case 'utf-16le':case 'raw': return true; default: return false; } }; function _normalizeEncoding(enc) { if (!enc) return 'utf8'; var retried; while (true) { switch (enc) { case 'utf8': case 'utf-8': return 'utf8'; case 'ucs2': case 'ucs-2': case 'utf16le': case 'utf-16le': return 'utf16le'; case 'latin1': case 'binary': return 'latin1'; case 'base64': case 'ascii': case 'hex': return enc; default: if (retried) return; // undefined enc = ('' + enc).toLowerCase(); retried = true; } } }; // Do not cache `Buffer.isEncoding` when checking encoding names as some // modules monkey-patch it to support additional encodings function normalizeEncoding(enc) { var nenc = _normalizeEncoding(enc); if (typeof nenc !== 'string' && (Buffer.isEncoding === isEncoding || !isEncoding(enc))) throw new Error('Unknown encoding: ' + enc); return nenc || enc; } // StringDecoder provides an interface for efficiently splitting a series of // buffers into a series of JS strings without breaking apart multi-byte // characters. exports.StringDecoder = StringDecoder; function StringDecoder(encoding) { this.encoding = normalizeEncoding(encoding); var nb; switch (this.encoding) { case 'utf16le': this.text = utf16Text; this.end = utf16End; nb = 4; break; case 'utf8': this.fillLast = utf8FillLast; nb = 4; break; case 'base64': this.text = base64Text; this.end = base64End; nb = 3; break; default: this.write = simpleWrite; this.end = simpleEnd; return; } this.lastNeed = 0; this.lastTotal = 0; this.lastChar = bufferShim.allocUnsafe(nb); } StringDecoder.prototype.write = function (buf) { if (buf.length === 0) return ''; var r; var i; if (this.lastNeed) { r = this.fillLast(buf); if (r === undefined) return ''; i = this.lastNeed; this.lastNeed = 0; } else { i = 0; } if (i < buf.length) return r ? r + this.text(buf, i) : this.text(buf, i); return r || ''; }; StringDecoder.prototype.end = utf8End; // Returns only complete characters in a Buffer StringDecoder.prototype.text = utf8Text; // Attempts to complete a partial non-UTF-8 character using bytes from a Buffer StringDecoder.prototype.fillLast = function (buf) { if (this.lastNeed <= buf.length) { buf.copy(this.lastChar, this.lastTotal - this.lastNeed, 0, this.lastNeed); return this.lastChar.toString(this.encoding, 0, this.lastTotal); } buf.copy(this.lastChar, this.lastTotal - this.lastNeed, 0, buf.length); this.lastNeed -= buf.length; }; // Checks the type of a UTF-8 byte, whether it's ASCII, a leading byte, or a // continuation byte. function utf8CheckByte(byte) { if (byte <= 0x7F) return 0;else if (byte >> 5 === 0x06) return 2;else if (byte >> 4 === 0x0E) return 3;else if (byte >> 3 === 0x1E) return 4; return -1; } // Checks at most 3 bytes at the end of a Buffer in order to detect an // incomplete multi-byte UTF-8 character. The total number of bytes (2, 3, or 4) // needed to complete the UTF-8 character (if applicable) are returned. function utf8CheckIncomplete(self, buf, i) { var j = buf.length - 1; if (j < i) return 0; var nb = utf8CheckByte(buf[j]); if (nb >= 0) { if (nb > 0) self.lastNeed = nb - 1; return nb; } if (--j < i) return 0; nb = utf8CheckByte(buf[j]); if (nb >= 0) { if (nb > 0) self.lastNeed = nb - 2; return nb; } if (--j < i) return 0; nb = utf8CheckByte(buf[j]); if (nb >= 0) { if (nb > 0) { if (nb === 2) nb = 0;else self.lastNeed = nb - 3; } return nb; } return 0; } // Validates as many continuation bytes for a multi-byte UTF-8 character as // needed or are available. If we see a non-continuation byte where we expect // one, we "replace" the validated continuation bytes we've seen so far with // UTF-8 replacement characters ('\ufffd'), to match v8's UTF-8 decoding // behavior. The continuation byte check is included three times in the case // where all of the continuation bytes for a character exist in the same buffer. // It is also done this way as a slight performance increase instead of using a // loop. function utf8CheckExtraBytes(self, buf, p) { if ((buf[0] & 0xC0) !== 0x80) { self.lastNeed = 0; return '\ufffd'.repeat(p); } if (self.lastNeed > 1 && buf.length > 1) { if ((buf[1] & 0xC0) !== 0x80) { self.lastNeed = 1; return '\ufffd'.repeat(p + 1); } if (self.lastNeed > 2 && buf.length > 2) { if ((buf[2] & 0xC0) !== 0x80) { self.lastNeed = 2; return '\ufffd'.repeat(p + 2); } } } } // Attempts to complete a multi-byte UTF-8 character using bytes from a Buffer. function utf8FillLast(buf) { var p = this.lastTotal - this.lastNeed; var r = utf8CheckExtraBytes(this, buf, p); if (r !== undefined) return r; if (this.lastNeed <= buf.length) { buf.copy(this.lastChar, p, 0, this.lastNeed); return this.lastChar.toString(this.encoding, 0, this.lastTotal); } buf.copy(this.lastChar, p, 0, buf.length); this.lastNeed -= buf.length; } // Returns all complete UTF-8 characters in a Buffer. If the Buffer ended on a // partial character, the character's bytes are buffered until the required // number of bytes are available. function utf8Text(buf, i) { var total = utf8CheckIncomplete(this, buf, i); if (!this.lastNeed) return buf.toString('utf8', i); this.lastTotal = total; var end = buf.length - (total - this.lastNeed); buf.copy(this.lastChar, 0, end); return buf.toString('utf8', i, end); } // For UTF-8, a replacement character for each buffered byte of a (partial) // character needs to be added to the output. function utf8End(buf) { var r = buf && buf.length ? this.write(buf) : ''; if (this.lastNeed) return r + '\ufffd'.repeat(this.lastTotal - this.lastNeed); return r; } // UTF-16LE typically needs two bytes per character, but even if we have an even // number of bytes available, we need to check if we end on a leading/high // surrogate. In that case, we need to wait for the next two bytes in order to // decode the last character properly. function utf16Text(buf, i) { if ((buf.length - i) % 2 === 0) { var r = buf.toString('utf16le', i); if (r) { var c = r.charCodeAt(r.length - 1); if (c >= 0xD800 && c <= 0xDBFF) { this.lastNeed = 2; this.lastTotal = 4; this.lastChar[0] = buf[buf.length - 2]; this.lastChar[1] = buf[buf.length - 1]; return r.slice(0, -1); } } return r; } this.lastNeed = 1; this.lastTotal = 2; this.lastChar[0] = buf[buf.length - 1]; return buf.toString('utf16le', i, buf.length - 1); } // For UTF-16LE we do not explicitly append special replacement characters if we // end on a partial character, we simply let v8 handle that. function utf16End(buf) { var r = buf && buf.length ? this.write(buf) : ''; if (this.lastNeed) { var end = this.lastTotal - this.lastNeed; return r + this.lastChar.toString('utf16le', 0, end); } return r; } function base64Text(buf, i) { var n = (buf.length - i) % 3; if (n === 0) return buf.toString('base64', i); this.lastNeed = 3 - n; this.lastTotal = 3; if (n === 1) { this.lastChar[0] = buf[buf.length - 1]; } else { this.lastChar[0] = buf[buf.length - 2]; this.lastChar[1] = buf[buf.length - 1]; } return buf.toString('base64', i, buf.length - n); } function base64End(buf) { var r = buf && buf.length ? this.write(buf) : ''; if (this.lastNeed) return r + this.lastChar.toString('base64', 0, 3 - this.lastNeed); return r; } // Pass bytes on through for single-byte encodings (e.g. ascii, latin1, hex) function simpleWrite(buf) { return buf.toString(this.encoding); } function simpleEnd(buf) { return buf && buf.length ? this.write(buf) : ''; } },{"buffer":6,"buffer-shims":5}],75:[function(require,module,exports){ exports = module.exports = require('./lib/_stream_readable.js'); exports.Stream = exports; exports.Readable = exports; exports.Writable = require('./lib/_stream_writable.js'); exports.Duplex = require('./lib/_stream_duplex.js'); exports.Transform = require('./lib/_stream_transform.js'); exports.PassThrough = require('./lib/_stream_passthrough.js'); },{"./lib/_stream_duplex.js":66,"./lib/_stream_passthrough.js":67,"./lib/_stream_readable.js":68,"./lib/_stream_transform.js":69,"./lib/_stream_writable.js":70}],76:[function(require,module,exports){ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : (global.createREGL = factory()); }(this, (function () { 'use strict'; var arrayTypes = { "[object Int8Array]": 5120, "[object Int16Array]": 5122, "[object Int32Array]": 5124, "[object Uint8Array]": 5121, "[object Uint8ClampedArray]": 5121, "[object Uint16Array]": 5123, "[object Uint32Array]": 5125, "[object Float32Array]": 5126, "[object Float64Array]": 5121, "[object ArrayBuffer]": 5121 }; var isTypedArray = function (x) { return Object.prototype.toString.call(x) in arrayTypes }; var extend = function (base, opts) { var keys = Object.keys(opts); for (var i = 0; i < keys.length; ++i) { base[keys[i]] = opts[keys[i]]; } return base }; // Error checking and parameter validation. // // Statements for the form `check.someProcedure(...)` get removed by // a browserify transform for optimized/minified bundles. // /* globals btoa */ // only used for extracting shader names. if btoa not present, then errors // will be slightly crappier function decodeB64 (str) { if (typeof btoa !== 'undefined') { return btoa(str) } return 'base64:' + str } function raise (message) { var error = new Error('(regl) ' + message); console.error(error); throw error } function check (pred, message) { if (!pred) { raise(message); } } function encolon (message) { if (message) { return ': ' + message } return '' } function checkParameter (param, possibilities, message) { if (!(param in possibilities)) { raise('unknown parameter (' + param + ')' + encolon(message) + '. possible values: ' + Object.keys(possibilities).join()); } } function checkIsTypedArray (data, message) { if (!isTypedArray(data)) { raise( 'invalid parameter type' + encolon(message) + '. must be a typed array'); } } function checkTypeOf (value, type, message) { if (typeof value !== type) { raise( 'invalid parameter type' + encolon(message) + '. expected ' + type + ', got ' + (typeof value)); } } function checkNonNegativeInt (value, message) { if (!((value >= 0) && ((value | 0) === value))) { raise('invalid parameter type, (' + value + ')' + encolon(message) + '. must be a nonnegative integer'); } } function checkOneOf (value, list, message) { if (list.indexOf(value) < 0) { raise('invalid value' + encolon(message) + '. must be one of: ' + list); } } var constructorKeys = [ 'gl', 'canvas', 'container', 'attributes', 'pixelRatio', 'extensions', 'optionalExtensions', 'profile', 'onDone' ]; function checkConstructor (obj) { Object.keys(obj).forEach(function (key) { if (constructorKeys.indexOf(key) < 0) { raise('invalid regl constructor argument "' + key + '". must be one of ' + constructorKeys); } }); } function leftPad (str, n) { str = str + ''; while (str.length < n) { str = ' ' + str; } return str } function ShaderFile () { this.name = 'unknown'; this.lines = []; this.index = {}; this.hasErrors = false; } function ShaderLine (number, line) { this.number = number; this.line = line; this.errors = []; } function ShaderError (fileNumber, lineNumber, message) { this.file = fileNumber; this.line = lineNumber; this.message = message; } function guessCommand () { var error = new Error(); var stack = (error.stack || error).toString(); var pat = /compileProcedure.*\n\s*at.*\((.*)\)/.exec(stack); if (pat) { return pat[1] } var pat2 = /compileProcedure.*\n\s*at\s+(.*)(\n|$)/.exec(stack); if (pat2) { return pat2[1] } return 'unknown' } function guessCallSite () { var error = new Error(); var stack = (error.stack || error).toString(); var pat = /at REGLCommand.*\n\s+at.*\((.*)\)/.exec(stack); if (pat) { return pat[1] } var pat2 = /at REGLCommand.*\n\s+at\s+(.*)\n/.exec(stack); if (pat2) { return pat2[1] } return 'unknown' } function parseSource (source, command) { var lines = source.split('\n'); var lineNumber = 1; var fileNumber = 0; var files = { unknown: new ShaderFile(), 0: new ShaderFile() }; files.unknown.name = files[0].name = command || guessCommand(); files.unknown.lines.push(new ShaderLine(0, '')); for (var i = 0; i < lines.length; ++i) { var line = lines[i]; var parts = /^\s*\#\s*(\w+)\s+(.+)\s*$/.exec(line); if (parts) { switch (parts[1]) { case 'line': var lineNumberInfo = /(\d+)(\s+\d+)?/.exec(parts[2]); if (lineNumberInfo) { lineNumber = lineNumberInfo[1] | 0; if (lineNumberInfo[2]) { fileNumber = lineNumberInfo[2] | 0; if (!(fileNumber in files)) { files[fileNumber] = new ShaderFile(); } } } break case 'define': var nameInfo = /SHADER_NAME(_B64)?\s+(.*)$/.exec(parts[2]); if (nameInfo) { files[fileNumber].name = (nameInfo[1] ? decodeB64(nameInfo[2]) : nameInfo[2]); } break } } files[fileNumber].lines.push(new ShaderLine(lineNumber++, line)); } Object.keys(files).forEach(function (fileNumber) { var file = files[fileNumber]; file.lines.forEach(function (line) { file.index[line.number] = line; }); }); return files } function parseErrorLog (errLog) { var result = []; errLog.split('\n').forEach(function (errMsg) { if (errMsg.length < 5) { return } var parts = /^ERROR\:\s+(\d+)\:(\d+)\:\s*(.*)$/.exec(errMsg); if (parts) { result.push(new ShaderError( parts[1] | 0, parts[2] | 0, parts[3].trim())); } else if (errMsg.length > 0) { result.push(new ShaderError('unknown', 0, errMsg)); } }); return result } function annotateFiles (files, errors) { errors.forEach(function (error) { var file = files[error.file]; if (file) { var line = file.index[error.line]; if (line) { line.errors.push(error); file.hasErrors = true; return } } files.unknown.hasErrors = true; files.unknown.lines[0].errors.push(error); }); } function checkShaderError (gl, shader, source, type, command) { if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { var errLog = gl.getShaderInfoLog(shader); var typeName = type === gl.FRAGMENT_SHADER ? 'fragment' : 'vertex'; checkCommandType(source, 'string', typeName + ' shader source must be a string', command); var files = parseSource(source, command); var errors = parseErrorLog(errLog); annotateFiles(files, errors); Object.keys(files).forEach(function (fileNumber) { var file = files[fileNumber]; if (!file.hasErrors) { return } var strings = ['']; var styles = ['']; function push (str, style) { strings.push(str); styles.push(style || ''); } push('file number ' + fileNumber + ': ' + file.name + '\n', 'color:red;text-decoration:underline;font-weight:bold'); file.lines.forEach(function (line) { if (line.errors.length > 0) { push(leftPad(line.number, 4) + '| ', 'background-color:yellow; font-weight:bold'); push(line.line + '\n', 'color:red; background-color:yellow; font-weight:bold'); // try to guess token var offset = 0; line.errors.forEach(function (error) { var message = error.message; var token = /^\s*\'(.*)\'\s*\:\s*(.*)$/.exec(message); if (token) { var tokenPat = token[1]; message = token[2]; switch (tokenPat) { case 'assign': tokenPat = '='; break } offset = Math.max(line.line.indexOf(tokenPat, offset), 0); } else { offset = 0; } push(leftPad('| ', 6)); push(leftPad('^^^', offset + 3) + '\n', 'font-weight:bold'); push(leftPad('| ', 6)); push(message + '\n', 'font-weight:bold'); }); push(leftPad('| ', 6) + '\n'); } else { push(leftPad(line.number, 4) + '| '); push(line.line + '\n', 'color:red'); } }); if (typeof document !== 'undefined') { styles[0] = strings.join('%c'); console.log.apply(console, styles); } else { console.log(strings.join('')); } }); check.raise('Error compiling ' + typeName + ' shader, ' + files[0].name); } } function checkLinkError (gl, program, fragShader, vertShader, command) { if (!gl.getProgramParameter(program, gl.LINK_STATUS)) { var errLog = gl.getProgramInfoLog(program); var fragParse = parseSource(fragShader, command); var vertParse = parseSource(vertShader, command); var header = 'Error linking program with vertex shader, "' + vertParse[0].name + '", and fragment shader "' + fragParse[0].name + '"'; if (typeof document !== 'undefined') { console.log('%c' + header + '\n%c' + errLog, 'color:red;text-decoration:underline;font-weight:bold', 'color:red'); } else { console.log(header + '\n' + errLog); } check.raise(header); } } function saveCommandRef (object) { object._commandRef = guessCommand(); } function saveDrawCommandInfo (opts, uniforms, attributes, stringStore) { saveCommandRef(opts); function id (str) { if (str) { return stringStore.id(str) } return 0 } opts._fragId = id(opts.static.frag); opts._vertId = id(opts.static.vert); function addProps (dict, set) { Object.keys(set).forEach(function (u) { dict[stringStore.id(u)] = true; }); } var uniformSet = opts._uniformSet = {}; addProps(uniformSet, uniforms.static); addProps(uniformSet, uniforms.dynamic); var attributeSet = opts._attributeSet = {}; addProps(attributeSet, attributes.static); addProps(attributeSet, attributes.dynamic); opts._hasCount = ( 'count' in opts.static || 'count' in opts.dynamic || 'elements' in opts.static || 'elements' in opts.dynamic); } function commandRaise (message, command) { var callSite = guessCallSite(); raise(message + ' in command ' + (command || guessCommand()) + (callSite === 'unknown' ? '' : ' called from ' + callSite)); } function checkCommand (pred, message, command) { if (!pred) { commandRaise(message, command || guessCommand()); } } function checkParameterCommand (param, possibilities, message, command) { if (!(param in possibilities)) { commandRaise( 'unknown parameter (' + param + ')' + encolon(message) + '. possible values: ' + Object.keys(possibilities).join(), command || guessCommand()); } } function checkCommandType (value, type, message, command) { if (typeof value !== type) { commandRaise( 'invalid parameter type' + encolon(message) + '. expected ' + type + ', got ' + (typeof value), command || guessCommand()); } } function checkOptional (block) { block(); } function checkFramebufferFormat (attachment, texFormats, rbFormats) { if (attachment.texture) { checkOneOf( attachment.texture._texture.internalformat, texFormats, 'unsupported texture format for attachment'); } else { checkOneOf( attachment.renderbuffer._renderbuffer.format, rbFormats, 'unsupported renderbuffer format for attachment'); } } var GL_CLAMP_TO_EDGE = 0x812F; var GL_NEAREST = 0x2600; var GL_NEAREST_MIPMAP_NEAREST = 0x2700; var GL_LINEAR_MIPMAP_NEAREST = 0x2701; var GL_NEAREST_MIPMAP_LINEAR = 0x2702; var GL_LINEAR_MIPMAP_LINEAR = 0x2703; var GL_BYTE = 5120; var GL_UNSIGNED_BYTE = 5121; var GL_SHORT = 5122; var GL_UNSIGNED_SHORT = 5123; var GL_INT = 5124; var GL_UNSIGNED_INT = 5125; var GL_FLOAT = 5126; var GL_UNSIGNED_SHORT_4_4_4_4 = 0x8033; var GL_UNSIGNED_SHORT_5_5_5_1 = 0x8034; var GL_UNSIGNED_SHORT_5_6_5 = 0x8363; var GL_UNSIGNED_INT_24_8_WEBGL = 0x84FA; var GL_HALF_FLOAT_OES = 0x8D61; var TYPE_SIZE = {}; TYPE_SIZE[GL_BYTE] = TYPE_SIZE[GL_UNSIGNED_BYTE] = 1; TYPE_SIZE[GL_SHORT] = TYPE_SIZE[GL_UNSIGNED_SHORT] = TYPE_SIZE[GL_HALF_FLOAT_OES] = TYPE_SIZE[GL_UNSIGNED_SHORT_5_6_5] = TYPE_SIZE[GL_UNSIGNED_SHORT_4_4_4_4] = TYPE_SIZE[GL_UNSIGNED_SHORT_5_5_5_1] = 2; TYPE_SIZE[GL_INT] = TYPE_SIZE[GL_UNSIGNED_INT] = TYPE_SIZE[GL_FLOAT] = TYPE_SIZE[GL_UNSIGNED_INT_24_8_WEBGL] = 4; function pixelSize (type, channels) { if (type === GL_UNSIGNED_SHORT_5_5_5_1 || type === GL_UNSIGNED_SHORT_4_4_4_4 || type === GL_UNSIGNED_SHORT_5_6_5) { return 2 } else if (type === GL_UNSIGNED_INT_24_8_WEBGL) { return 4 } else { return TYPE_SIZE[type] * channels } } function isPow2 (v) { return !(v & (v - 1)) && (!!v) } function checkTexture2D (info, mipData, limits) { var i; var w = mipData.width; var h = mipData.height; var c = mipData.channels; // Check texture shape check(w > 0 && w <= limits.maxTextureSize && h > 0 && h <= limits.maxTextureSize, 'invalid texture shape'); // check wrap mode if (info.wrapS !== GL_CLAMP_TO_EDGE || info.wrapT !== GL_CLAMP_TO_EDGE) { check(isPow2(w) && isPow2(h), 'incompatible wrap mode for texture, both width and height must be power of 2'); } if (mipData.mipmask === 1) { if (w !== 1 && h !== 1) { check( info.minFilter !== GL_NEAREST_MIPMAP_NEAREST && info.minFilter !== GL_NEAREST_MIPMAP_LINEAR && info.minFilter !== GL_LINEAR_MIPMAP_NEAREST && info.minFilter !== GL_LINEAR_MIPMAP_LINEAR, 'min filter requires mipmap'); } } else { // texture must be power of 2 check(isPow2(w) && isPow2(h), 'texture must be a square power of 2 to support mipmapping'); check(mipData.mipmask === (w << 1) - 1, 'missing or incomplete mipmap data'); } if (mipData.type === GL_FLOAT) { if (limits.extensions.indexOf('oes_texture_float_linear') < 0) { check(info.minFilter === GL_NEAREST && info.magFilter === GL_NEAREST, 'filter not supported, must enable oes_texture_float_linear'); } check(!info.genMipmaps, 'mipmap generation not supported with float textures'); } // check image complete var mipimages = mipData.images; for (i = 0; i < 16; ++i) { if (mipimages[i]) { var mw = w >> i; var mh = h >> i; check(mipData.mipmask & (1 << i), 'missing mipmap data'); var img = mipimages[i]; check( img.width === mw && img.height === mh, 'invalid shape for mip images'); check( img.format === mipData.format && img.internalformat === mipData.internalformat && img.type === mipData.type, 'incompatible type for mip image'); if (img.compressed) { // TODO: check size for compressed images } else if (img.data) { // check(img.data.byteLength === mw * mh * // Math.max(pixelSize(img.type, c), img.unpackAlignment), var rowSize = Math.ceil(pixelSize(img.type, c) * mw / img.unpackAlignment) * img.unpackAlignment; check(img.data.byteLength === rowSize * mh, 'invalid data for image, buffer size is inconsistent with image format'); } else if (img.element) { // TODO: check element can be loaded } else if (img.copy) { // TODO: check compatible format and type } } else if (!info.genMipmaps) { check((mipData.mipmask & (1 << i)) === 0, 'extra mipmap data'); } } if (mipData.compressed) { check(!info.genMipmaps, 'mipmap generation for compressed images not supported'); } } function checkTextureCube (texture, info, faces, limits) { var w = texture.width; var h = texture.height; var c = texture.channels; // Check texture shape check( w > 0 && w <= limits.maxTextureSize && h > 0 && h <= limits.maxTextureSize, 'invalid texture shape'); check( w === h, 'cube map must be square'); check( info.wrapS === GL_CLAMP_TO_EDGE && info.wrapT === GL_CLAMP_TO_EDGE, 'wrap mode not supported by cube map'); for (var i = 0; i < faces.length; ++i) { var face = faces[i]; check( face.width === w && face.height === h, 'inconsistent cube map face shape'); if (info.genMipmaps) { check(!face.compressed, 'can not generate mipmap for compressed textures'); check(face.mipmask === 1, 'can not specify mipmaps and generate mipmaps'); } else { // TODO: check mip and filter mode } var mipmaps = face.images; for (var j = 0; j < 16; ++j) { var img = mipmaps[j]; if (img) { var mw = w >> j; var mh = h >> j; check(face.mipmask & (1 << j), 'missing mipmap data'); check( img.width === mw && img.height === mh, 'invalid shape for mip images'); check( img.format === texture.format && img.internalformat === texture.internalformat && img.type === texture.type, 'incompatible type for mip image'); if (img.compressed) { // TODO: check size for compressed images } else if (img.data) { check(img.data.byteLength === mw * mh * Math.max(pixelSize(img.type, c), img.unpackAlignment), 'invalid data for image, buffer size is inconsistent with image format'); } else if (img.element) { // TODO: check element can be loaded } else if (img.copy) { // TODO: check compatible format and type } } } } } var check$1 = extend(check, { optional: checkOptional, raise: raise, commandRaise: commandRaise, command: checkCommand, parameter: checkParameter, commandParameter: checkParameterCommand, constructor: checkConstructor, type: checkTypeOf, commandType: checkCommandType, isTypedArray: checkIsTypedArray, nni: checkNonNegativeInt, oneOf: checkOneOf, shaderError: checkShaderError, linkError: checkLinkError, callSite: guessCallSite, saveCommandRef: saveCommandRef, saveDrawInfo: saveDrawCommandInfo, framebufferFormat: checkFramebufferFormat, guessCommand: guessCommand, texture2D: checkTexture2D, textureCube: checkTextureCube }); var VARIABLE_COUNTER = 0; var DYN_FUNC = 0; function DynamicVariable (type, data) { this.id = (VARIABLE_COUNTER++); this.type = type; this.data = data; } function escapeStr (str) { return str.replace(/\\/g, '\\\\').replace(/"/g, '\\"') } function splitParts (str) { if (str.length === 0) { return [] } var firstChar = str.charAt(0); var lastChar = str.charAt(str.length - 1); if (str.length > 1 && firstChar === lastChar && (firstChar === '"' || firstChar === "'")) { return ['"' + escapeStr(str.substr(1, str.length - 2)) + '"'] } var parts = /\[(false|true|null|\d+|'[^']*'|"[^"]*")\]/.exec(str); if (parts) { return ( splitParts(str.substr(0, parts.index)) .concat(splitParts(parts[1])) .concat(splitParts(str.substr(parts.index + parts[0].length))) ) } var subparts = str.split('.'); if (subparts.length === 1) { return ['"' + escapeStr(str) + '"'] } var result = []; for (var i = 0; i < subparts.length; ++i) { result = result.concat(splitParts(subparts[i])); } return result } function toAccessorString (str) { return '[' + splitParts(str).join('][') + ']' } function defineDynamic (type, data) { return new DynamicVariable(type, toAccessorString(data + '')) } function isDynamic (x) { return (typeof x === 'function' && !x._reglType) || x instanceof DynamicVariable } function unbox (x, path) { if (typeof x === 'function') { return new DynamicVariable(DYN_FUNC, x) } return x } var dynamic = { DynamicVariable: DynamicVariable, define: defineDynamic, isDynamic: isDynamic, unbox: unbox, accessor: toAccessorString }; /* globals requestAnimationFrame, cancelAnimationFrame */ var raf = { next: typeof requestAnimationFrame === 'function' ? function (cb) { return requestAnimationFrame(cb) } : function (cb) { return setTimeout(cb, 16) }, cancel: typeof cancelAnimationFrame === 'function' ? function (raf) { return cancelAnimationFrame(raf) } : clearTimeout }; /* globals performance */ var clock = (typeof performance !== 'undefined' && performance.now) ? function () { return performance.now() } : function () { return +(new Date()) }; function createStringStore () { var stringIds = {'': 0}; var stringValues = ['']; return { id: function (str) { var result = stringIds[str]; if (result) { return result } result = stringIds[str] = stringValues.length; stringValues.push(str); return result }, str: function (id) { return stringValues[id] } } } // Context and canvas creation helper functions function createCanvas (element, onDone, pixelRatio) { var canvas = document.createElement('canvas'); extend(canvas.style, { border: 0, margin: 0, padding: 0, top: 0, left: 0 }); element.appendChild(canvas); if (element === document.body) { canvas.style.position = 'absolute'; extend(element.style, { margin: 0, padding: 0 }); } function resize () { var w = window.innerWidth; var h = window.innerHeight; if (element !== document.body) { var bounds = element.getBoundingClientRect(); w = bounds.right - bounds.left; h = bounds.bottom - bounds.top; } canvas.width = pixelRatio * w; canvas.height = pixelRatio * h; extend(canvas.style, { width: w + 'px', height: h + 'px' }); } window.addEventListener('resize', resize, false); function onDestroy () { window.removeEventListener('resize', resize); element.removeChild(canvas); } resize(); return { canvas: canvas, onDestroy: onDestroy } } function createContext (canvas, contexAttributes) { function get (name) { try { return canvas.getContext(name, contexAttributes) } catch (e) { return null } } return ( get('webgl') || get('experimental-webgl') || get('webgl-experimental') ) } function isHTMLElement (obj) { return ( typeof obj.nodeName === 'string' && typeof obj.appendChild === 'function' && typeof obj.getBoundingClientRect === 'function' ) } function isWebGLContext (obj) { return ( typeof obj.drawArrays === 'function' || typeof obj.drawElements === 'function' ) } function parseExtensions (input) { if (typeof input === 'string') { return input.split() } check$1(Array.isArray(input), 'invalid extension array'); return input } function getElement (desc) { if (typeof desc === 'string') { check$1(typeof document !== 'undefined', 'not supported outside of DOM'); return document.querySelector(desc) } return desc } function parseArgs (args_) { var args = args_ || {}; var element, container, canvas, gl; var contextAttributes = {}; var extensions = []; var optionalExtensions = []; var pixelRatio = (typeof window === 'undefined' ? 1 : window.devicePixelRatio); var profile = false; var onDone = function (err) { if (err) { check$1.raise(err); } }; var onDestroy = function () {}; if (typeof args === 'string') { check$1( typeof document !== 'undefined', 'selector queries only supported in DOM enviroments'); element = document.querySelector(args); check$1(element, 'invalid query string for element'); } else if (typeof args === 'object') { if (isHTMLElement(args)) { element = args; } else if (isWebGLContext(args)) { gl = args; canvas = gl.canvas; } else { check$1.constructor(args); if ('gl' in args) { gl = args.gl; } else if ('canvas' in args) { canvas = getElement(args.canvas); } else if ('container' in args) { container = getElement(args.container); } if ('attributes' in args) { contextAttributes = args.attributes; check$1.type(contextAttributes, 'object', 'invalid context attributes'); } if ('extensions' in args) { extensions = parseExtensions(args.extensions); } if ('optionalExtensions' in args) { optionalExtensions = parseExtensions(args.optionalExtensions); } if ('onDone' in args) { check$1.type( args.onDone, 'function', 'invalid or missing onDone callback'); onDone = args.onDone; } if ('profile' in args) { profile = !!args.profile; } if ('pixelRatio' in args) { pixelRatio = +args.pixelRatio; check$1(pixelRatio > 0, 'invalid pixel ratio'); } } } else { check$1.raise('invalid arguments to regl'); } if (element) { if (element.nodeName.toLowerCase() === 'canvas') { canvas = element; } else { container = element; } } if (!gl) { if (!canvas) { check$1( typeof document !== 'undefined', 'must manually specify webgl context outside of DOM environments'); var result = createCanvas(container || document.body, onDone, pixelRatio); if (!result) { return null } canvas = result.canvas; onDestroy = result.onDestroy; } gl = createContext(canvas, contextAttributes); } if (!gl) { onDestroy(); onDone('webgl not supported, try upgrading your browser or graphics drivers http://get.webgl.org'); return null } return { gl: gl, canvas: canvas, container: container, extensions: extensions, optionalExtensions: optionalExtensions, pixelRatio: pixelRatio, profile: profile, onDone: onDone, onDestroy: onDestroy } } function createExtensionCache (gl, config) { var extensions = {}; function tryLoadExtension (name_) { check$1.type(name_, 'string', 'extension name must be string'); var name = name_.toLowerCase(); var ext; try { ext = extensions[name] = gl.getExtension(name); } catch (e) {} return !!ext } for (var i = 0; i < config.extensions.length; ++i) { var name = config.extensions[i]; if (!tryLoadExtension(name)) { config.onDestroy(); config.onDone('"' + name + '" extension is not supported by the current WebGL context, try upgrading your system or a different browser'); return null } } config.optionalExtensions.forEach(tryLoadExtension); return { extensions: extensions, restore: function () { Object.keys(extensions).forEach(function (name) { if (!tryLoadExtension(name)) { throw new Error('(regl): error restoring extension ' + name) } }); } } } var GL_SUBPIXEL_BITS = 0x0D50; var GL_RED_BITS = 0x0D52; var GL_GREEN_BITS = 0x0D53; var GL_BLUE_BITS = 0x0D54; var GL_ALPHA_BITS = 0x0D55; var GL_DEPTH_BITS = 0x0D56; var GL_STENCIL_BITS = 0x0D57; var GL_ALIASED_POINT_SIZE_RANGE = 0x846D; var GL_ALIASED_LINE_WIDTH_RANGE = 0x846E; var GL_MAX_TEXTURE_SIZE = 0x0D33; var GL_MAX_VIEWPORT_DIMS = 0x0D3A; var GL_MAX_VERTEX_ATTRIBS = 0x8869; var GL_MAX_VERTEX_UNIFORM_VECTORS = 0x8DFB; var GL_MAX_VARYING_VECTORS = 0x8DFC; var GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS = 0x8B4D; var GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS = 0x8B4C; var GL_MAX_TEXTURE_IMAGE_UNITS = 0x8872; var GL_MAX_FRAGMENT_UNIFORM_VECTORS = 0x8DFD; var GL_MAX_CUBE_MAP_TEXTURE_SIZE = 0x851C; var GL_MAX_RENDERBUFFER_SIZE = 0x84E8; var GL_VENDOR = 0x1F00; var GL_RENDERER = 0x1F01; var GL_VERSION = 0x1F02; var GL_SHADING_LANGUAGE_VERSION = 0x8B8C; var GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT = 0x84FF; var GL_MAX_COLOR_ATTACHMENTS_WEBGL = 0x8CDF; var GL_MAX_DRAW_BUFFERS_WEBGL = 0x8824; var wrapLimits = function (gl, extensions) { var maxAnisotropic = 1; if (extensions.ext_texture_filter_anisotropic) { maxAnisotropic = gl.getParameter(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT); } var maxDrawbuffers = 1; var maxColorAttachments = 1; if (extensions.webgl_draw_buffers) { maxDrawbuffers = gl.getParameter(GL_MAX_DRAW_BUFFERS_WEBGL); maxColorAttachments = gl.getParameter(GL_MAX_COLOR_ATTACHMENTS_WEBGL); } return { // drawing buffer bit depth colorBits: [ gl.getParameter(GL_RED_BITS), gl.getParameter(GL_GREEN_BITS), gl.getParameter(GL_BLUE_BITS), gl.getParameter(GL_ALPHA_BITS) ], depthBits: gl.getParameter(GL_DEPTH_BITS), stencilBits: gl.getParameter(GL_STENCIL_BITS), subpixelBits: gl.getParameter(GL_SUBPIXEL_BITS), // supported extensions extensions: Object.keys(extensions).filter(function (ext) { return !!extensions[ext] }), // max aniso samples maxAnisotropic: maxAnisotropic, // max draw buffers maxDrawbuffers: maxDrawbuffers, maxColorAttachments: maxColorAttachments, // point and line size ranges pointSizeDims: gl.getParameter(GL_ALIASED_POINT_SIZE_RANGE), lineWidthDims: gl.getParameter(GL_ALIASED_LINE_WIDTH_RANGE), maxViewportDims: gl.getParameter(GL_MAX_VIEWPORT_DIMS), maxCombinedTextureUnits: gl.getParameter(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS), maxCubeMapSize: gl.getParameter(GL_MAX_CUBE_MAP_TEXTURE_SIZE), maxRenderbufferSize: gl.getParameter(GL_MAX_RENDERBUFFER_SIZE), maxTextureUnits: gl.getParameter(GL_MAX_TEXTURE_IMAGE_UNITS), maxTextureSize: gl.getParameter(GL_MAX_TEXTURE_SIZE), maxAttributes: gl.getParameter(GL_MAX_VERTEX_ATTRIBS), maxVertexUniforms: gl.getParameter(GL_MAX_VERTEX_UNIFORM_VECTORS), maxVertexTextureUnits: gl.getParameter(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS), maxVaryingVectors: gl.getParameter(GL_MAX_VARYING_VECTORS), maxFragmentUniforms: gl.getParameter(GL_MAX_FRAGMENT_UNIFORM_VECTORS), // vendor info glsl: gl.getParameter(GL_SHADING_LANGUAGE_VERSION), renderer: gl.getParameter(GL_RENDERER), vendor: gl.getParameter(GL_VENDOR), version: gl.getParameter(GL_VERSION) } }; function isNDArrayLike (obj) { return ( !!obj && typeof obj === 'object' && Array.isArray(obj.shape) && Array.isArray(obj.stride) && typeof obj.offset === 'number' && obj.shape.length === obj.stride.length && (Array.isArray(obj.data) || isTypedArray(obj.data))) } var values = function (obj) { return Object.keys(obj).map(function (key) { return obj[key] }) }; function loop (n, f) { var result = Array(n); for (var i = 0; i < n; ++i) { result[i] = f(i); } return result } var GL_BYTE$1 = 5120; var GL_UNSIGNED_BYTE$2 = 5121; var GL_SHORT$1 = 5122; var GL_UNSIGNED_SHORT$1 = 5123; var GL_INT$1 = 5124; var GL_UNSIGNED_INT$1 = 5125; var GL_FLOAT$2 = 5126; var bufferPool = loop(8, function () { return [] }); function nextPow16 (v) { for (var i = 16; i <= (1 << 28); i *= 16) { if (v <= i) { return i } } return 0 } function log2 (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) } function alloc (n) { var sz = nextPow16(n); var bin = bufferPool[log2(sz) >> 2]; if (bin.length > 0) { return bin.pop() } return new ArrayBuffer(sz) } function free (buf) { bufferPool[log2(buf.byteLength) >> 2].push(buf); } function allocType (type, n) { var result = null; switch (type) { case GL_BYTE$1: result = new Int8Array(alloc(n), 0, n); break case GL_UNSIGNED_BYTE$2: result = new Uint8Array(alloc(n), 0, n); break case GL_SHORT$1: result = new Int16Array(alloc(2 * n), 0, n); break case GL_UNSIGNED_SHORT$1: result = new Uint16Array(alloc(2 * n), 0, n); break case GL_INT$1: result = new Int32Array(alloc(4 * n), 0, n); break case GL_UNSIGNED_INT$1: result = new Uint32Array(alloc(4 * n), 0, n); break case GL_FLOAT$2: result = new Float32Array(alloc(4 * n), 0, n); break default: return null } if (result.length !== n) { return result.subarray(0, n) } return result } function freeType (array) { free(array.buffer); } var pool = { alloc: alloc, free: free, allocType: allocType, freeType: freeType }; var flattenUtils = { shape: arrayShape$1, flatten: flattenArray }; function flatten1D (array, nx, out) { for (var i = 0; i < nx; ++i) { out[i] = array[i]; } } function flatten2D (array, nx, ny, out) { var ptr = 0; for (var i = 0; i < nx; ++i) { var row = array[i]; for (var j = 0; j < ny; ++j) { out[ptr++] = row[j]; } } } function flatten3D (array, nx, ny, nz, out, ptr_) { var ptr = ptr_; for (var i = 0; i < nx; ++i) { var row = array[i]; for (var j = 0; j < ny; ++j) { var col = row[j]; for (var k = 0; k < nz; ++k) { out[ptr++] = col[k]; } } } } function flattenRec (array, shape, level, out, ptr) { var stride = 1; for (var i = level + 1; i < shape.length; ++i) { stride *= shape[i]; } var n = shape[level]; if (shape.length - level === 4) { var nx = shape[level + 1]; var ny = shape[level + 2]; var nz = shape[level + 3]; for (i = 0; i < n; ++i) { flatten3D(array[i], nx, ny, nz, out, ptr); ptr += stride; } } else { for (i = 0; i < n; ++i) { flattenRec(array[i], shape, level + 1, out, ptr); ptr += stride; } } } function flattenArray (array, shape, type, out_) { var sz = 1; if (shape.length) { for (var i = 0; i < shape.length; ++i) { sz *= shape[i]; } } else { sz = 0; } var out = out_ || pool.allocType(type, sz); switch (shape.length) { case 0: break case 1: flatten1D(array, shape[0], out); break case 2: flatten2D(array, shape[0], shape[1], out); break case 3: flatten3D(array, shape[0], shape[1], shape[2], out, 0); break default: flattenRec(array, shape, 0, out, 0); } return out } function arrayShape$1 (array_) { var shape = []; for (var array = array_; array.length; array = array[0]) { shape.push(array.length); } return shape } var int8 = 5120; var int16 = 5122; var int32 = 5124; var uint8 = 5121; var uint16 = 5123; var uint32 = 5125; var float = 5126; var float32 = 5126; var glTypes = { int8: int8, int16: int16, int32: int32, uint8: uint8, uint16: uint16, uint32: uint32, float: float, float32: float32 }; var dynamic$1 = 35048; var stream = 35040; var usageTypes = { dynamic: dynamic$1, stream: stream, "static": 35044 }; var arrayFlatten = flattenUtils.flatten; var arrayShape = flattenUtils.shape; var GL_STATIC_DRAW = 0x88E4; var GL_STREAM_DRAW = 0x88E0; var GL_UNSIGNED_BYTE$1 = 5121; var GL_FLOAT$1 = 5126; var DTYPES_SIZES = []; DTYPES_SIZES[5120] = 1; // int8 DTYPES_SIZES[5122] = 2; // int16 DTYPES_SIZES[5124] = 4; // int32 DTYPES_SIZES[5121] = 1; // uint8 DTYPES_SIZES[5123] = 2; // uint16 DTYPES_SIZES[5125] = 4; // uint32 DTYPES_SIZES[5126] = 4; // float32 function typedArrayCode (data) { return arrayTypes[Object.prototype.toString.call(data)] | 0 } function copyArray (out, inp) { for (var i = 0; i < inp.length; ++i) { out[i] = inp[i]; } } function transpose ( result, data, shapeX, shapeY, strideX, strideY, offset) { var ptr = 0; for (var i = 0; i < shapeX; ++i) { for (var j = 0; j < shapeY; ++j) { result[ptr++] = data[strideX * i + strideY * j + offset]; } } } function wrapBufferState (gl, stats, config) { var bufferCount = 0; var bufferSet = {}; function REGLBuffer (type) { this.id = bufferCount++; this.buffer = gl.createBuffer(); this.type = type; this.usage = GL_STATIC_DRAW; this.byteLength = 0; this.dimension = 1; this.dtype = GL_UNSIGNED_BYTE$1; this.persistentData = null; if (config.profile) { this.stats = {size: 0}; } } REGLBuffer.prototype.bind = function () { gl.bindBuffer(this.type, this.buffer); }; REGLBuffer.prototype.destroy = function () { destroy(this); }; var streamPool = []; function createStream (type, data) { var buffer = streamPool.pop(); if (!buffer) { buffer = new REGLBuffer(type); } buffer.bind(); initBufferFromData(buffer, data, GL_STREAM_DRAW, 0, 1, false); return buffer } function destroyStream (stream$$1) { streamPool.push(stream$$1); } function initBufferFromTypedArray (buffer, data, usage) { buffer.byteLength = data.byteLength; gl.bufferData(buffer.type, data, usage); } function initBufferFromData (buffer, data, usage, dtype, dimension, persist) { var shape; buffer.usage = usage; if (Array.isArray(data)) { buffer.dtype = dtype || GL_FLOAT$1; if (data.length > 0) { var flatData; if (Array.isArray(data[0])) { shape = arrayShape(data); var dim = 1; for (var i = 1; i < shape.length; ++i) { dim *= shape[i]; } buffer.dimension = dim; flatData = arrayFlatten(data, shape, buffer.dtype); initBufferFromTypedArray(buffer, flatData, usage); if (persist) { buffer.persistentData = flatData; } else { pool.freeType(flatData); } } else if (typeof data[0] === 'number') { buffer.dimension = dimension; var typedData = pool.allocType(buffer.dtype, data.length); copyArray(typedData, data); initBufferFromTypedArray(buffer, typedData, usage); if (persist) { buffer.persistentData = typedData; } else { pool.freeType(typedData); } } else if (isTypedArray(data[0])) { buffer.dimension = data[0].length; buffer.dtype = dtype || typedArrayCode(data[0]) || GL_FLOAT$1; flatData = arrayFlatten( data, [data.length, data[0].length], buffer.dtype); initBufferFromTypedArray(buffer, flatData, usage); if (persist) { buffer.persistentData = flatData; } else { pool.freeType(flatData); } } else { check$1.raise('invalid buffer data'); } } } else if (isTypedArray(data)) { buffer.dtype = dtype || typedArrayCode(data); buffer.dimension = dimension; initBufferFromTypedArray(buffer, data, usage); if (persist) { buffer.persistentData = new Uint8Array(new Uint8Array(data.buffer)); } } else if (isNDArrayLike(data)) { shape = data.shape; var stride = data.stride; var offset = data.offset; var shapeX = 0; var shapeY = 0; var strideX = 0; var strideY = 0; if (shape.length === 1) { shapeX = shape[0]; shapeY = 1; strideX = stride[0]; strideY = 0; } else if (shape.length === 2) { shapeX = shape[0]; shapeY = shape[1]; strideX = stride[0]; strideY = stride[1]; } else { check$1.raise('invalid shape'); } buffer.dtype = dtype || typedArrayCode(data.data) || GL_FLOAT$1; buffer.dimension = shapeY; var transposeData = pool.allocType(buffer.dtype, shapeX * shapeY); transpose(transposeData, data.data, shapeX, shapeY, strideX, strideY, offset); initBufferFromTypedArray(buffer, transposeData, usage); if (persist) { buffer.persistentData = transposeData; } else { pool.freeType(transposeData); } } else { check$1.raise('invalid buffer data'); } } function destroy (buffer) { stats.bufferCount--; var handle = buffer.buffer; check$1(handle, 'buffer must not be deleted already'); gl.deleteBuffer(handle); buffer.buffer = null; delete bufferSet[buffer.id]; } function createBuffer (options, type, deferInit, persistent) { stats.bufferCount++; var buffer = new REGLBuffer(type); bufferSet[buffer.id] = buffer; function reglBuffer (options) { var usage = GL_STATIC_DRAW; var data = null; var byteLength = 0; var dtype = 0; var dimension = 1; if (Array.isArray(options) || isTypedArray(options) || isNDArrayLike(options)) { data = options; } else if (typeof options === 'number') { byteLength = options | 0; } else if (options) { check$1.type( options, 'object', 'buffer arguments must be an object, a number or an array'); if ('data' in options) { check$1( data === null || Array.isArray(data) || isTypedArray(data) || isNDArrayLike(data), 'invalid data for buffer'); data = options.data; } if ('usage' in options) { check$1.parameter(options.usage, usageTypes, 'invalid buffer usage'); usage = usageTypes[options.usage]; } if ('type' in options) { check$1.parameter(options.type, glTypes, 'invalid buffer type'); dtype = glTypes[options.type]; } if ('dimension' in options) { check$1.type(options.dimension, 'number', 'invalid dimension'); dimension = options.dimension | 0; } if ('length' in options) { check$1.nni(byteLength, 'buffer length must be a nonnegative integer'); byteLength = options.length | 0; } } buffer.bind(); if (!data) { gl.bufferData(buffer.type, byteLength, usage); buffer.dtype = dtype || GL_UNSIGNED_BYTE$1; buffer.usage = usage; buffer.dimension = dimension; buffer.byteLength = byteLength; } else { initBufferFromData(buffer, data, usage, dtype, dimension, persistent); } if (config.profile) { buffer.stats.size = buffer.byteLength * DTYPES_SIZES[buffer.dtype]; } return reglBuffer } function setSubData (data, offset) { check$1(offset + data.byteLength <= buffer.byteLength, 'invalid buffer subdata call, buffer is too small. ' + ' Can\'t write data of size ' + data.byteLength + ' starting from offset ' + offset + ' to a buffer of size ' + buffer.byteLength); gl.bufferSubData(buffer.type, offset, data); } function subdata (data, offset_) { var offset = (offset_ || 0) | 0; var shape; buffer.bind(); if (Array.isArray(data)) { if (data.length > 0) { if (typeof data[0] === 'number') { var converted = pool.allocType(buffer.dtype, data.length); copyArray(converted, data); setSubData(converted, offset); pool.freeType(converted); } else if (Array.isArray(data[0]) || isTypedArray(data[0])) { shape = arrayShape(data); var flatData = arrayFlatten(data, shape, buffer.dtype); setSubData(flatData, offset); pool.freeType(flatData); } else { check$1.raise('invalid buffer data'); } } } else if (isTypedArray(data)) { setSubData(data, offset); } else if (isNDArrayLike(data)) { shape = data.shape; var stride = data.stride; var shapeX = 0; var shapeY = 0; var strideX = 0; var strideY = 0; if (shape.length === 1) { shapeX = shape[0]; shapeY = 1; strideX = stride[0]; strideY = 0; } else if (shape.length === 2) { shapeX = shape[0]; shapeY = shape[1]; strideX = stride[0]; strideY = stride[1]; } else { check$1.raise('invalid shape'); } var dtype = Array.isArray(data.data) ? buffer.dtype : typedArrayCode(data.data); var transposeData = pool.allocType(dtype, shapeX * shapeY); transpose(transposeData, data.data, shapeX, shapeY, strideX, strideY, data.offset); setSubData(transposeData, offset); pool.freeType(transposeData); } else { check$1.raise('invalid data for buffer subdata'); } return reglBuffer } if (!deferInit) { reglBuffer(options); } reglBuffer._reglType = 'buffer'; reglBuffer._buffer = buffer; reglBuffer.subdata = subdata; if (config.profile) { reglBuffer.stats = buffer.stats; } reglBuffer.destroy = function () { destroy(buffer); }; return reglBuffer } function restoreBuffers () { values(bufferSet).forEach(function (buffer) { buffer.buffer = gl.createBuffer(); gl.bindBuffer(buffer.type, buffer.buffer); gl.bufferData( buffer.type, buffer.persistentData || buffer.byteLength, buffer.usage); }); } if (config.profile) { stats.getTotalBufferSize = function () { var total = 0; // TODO: Right now, the streams are not part of the total count. Object.keys(bufferSet).forEach(function (key) { total += bufferSet[key].stats.size; }); return total }; } return { create: createBuffer, createStream: createStream, destroyStream: destroyStream, clear: function () { values(bufferSet).forEach(destroy); streamPool.forEach(destroy); }, getBuffer: function (wrapper) { if (wrapper && wrapper._buffer instanceof REGLBuffer) { return wrapper._buffer } return null }, restore: restoreBuffers, _initBuffer: initBufferFromData } } var points = 0; var point = 0; var lines = 1; var line = 1; var triangles = 4; var triangle = 4; var primTypes = { points: points, point: point, lines: lines, line: line, triangles: triangles, triangle: triangle, "line loop": 2, "line strip": 3, "triangle strip": 5, "triangle fan": 6 }; var GL_POINTS = 0; var GL_LINES = 1; var GL_TRIANGLES = 4; var GL_BYTE$2 = 5120; var GL_UNSIGNED_BYTE$3 = 5121; var GL_SHORT$2 = 5122; var GL_UNSIGNED_SHORT$2 = 5123; var GL_INT$2 = 5124; var GL_UNSIGNED_INT$2 = 5125; var GL_ELEMENT_ARRAY_BUFFER = 34963; var GL_STREAM_DRAW$1 = 0x88E0; var GL_STATIC_DRAW$1 = 0x88E4; function wrapElementsState (gl, extensions, bufferState, stats) { var elementSet = {}; var elementCount = 0; var elementTypes = { 'uint8': GL_UNSIGNED_BYTE$3, 'uint16': GL_UNSIGNED_SHORT$2 }; if (extensions.oes_element_index_uint) { elementTypes.uint32 = GL_UNSIGNED_INT$2; } function REGLElementBuffer (buffer) { this.id = elementCount++; elementSet[this.id] = this; this.buffer = buffer; this.primType = GL_TRIANGLES; this.vertCount = 0; this.type = 0; } REGLElementBuffer.prototype.bind = function () { this.buffer.bind(); }; var bufferPool = []; function createElementStream (data) { var result = bufferPool.pop(); if (!result) { result = new REGLElementBuffer(bufferState.create( null, GL_ELEMENT_ARRAY_BUFFER, true, false)._buffer); } initElements(result, data, GL_STREAM_DRAW$1, -1, -1, 0, 0); return result } function destroyElementStream (elements) { bufferPool.push(elements); } function initElements ( elements, data, usage, prim, count, byteLength, type) { elements.buffer.bind(); if (data) { var predictedType = type; if (!type && ( !isTypedArray(data) || (isNDArrayLike(data) && !isTypedArray(data.data)))) { predictedType = extensions.oes_element_index_uint ? GL_UNSIGNED_INT$2 : GL_UNSIGNED_SHORT$2; } bufferState._initBuffer( elements.buffer, data, usage, predictedType, 3); } else { gl.bufferData(GL_ELEMENT_ARRAY_BUFFER, byteLength, usage); elements.buffer.dtype = dtype || GL_UNSIGNED_BYTE$3; elements.buffer.usage = usage; elements.buffer.dimension = 3; elements.buffer.byteLength = byteLength; } var dtype = type; if (!type) { switch (elements.buffer.dtype) { case GL_UNSIGNED_BYTE$3: case GL_BYTE$2: dtype = GL_UNSIGNED_BYTE$3; break case GL_UNSIGNED_SHORT$2: case GL_SHORT$2: dtype = GL_UNSIGNED_SHORT$2; break case GL_UNSIGNED_INT$2: case GL_INT$2: dtype = GL_UNSIGNED_INT$2; break default: check$1.raise('unsupported type for element array'); } elements.buffer.dtype = dtype; } elements.type = dtype; // Check oes_element_index_uint extension check$1( dtype !== GL_UNSIGNED_INT$2 || !!extensions.oes_element_index_uint, '32 bit element buffers not supported, enable oes_element_index_uint first'); // try to guess default primitive type and arguments var vertCount = count; if (vertCount < 0) { vertCount = elements.buffer.byteLength; if (dtype === GL_UNSIGNED_SHORT$2) { vertCount >>= 1; } else if (dtype === GL_UNSIGNED_INT$2) { vertCount >>= 2; } } elements.vertCount = vertCount; // try to guess primitive type from cell dimension var primType = prim; if (prim < 0) { primType = GL_TRIANGLES; var dimension = elements.buffer.dimension; if (dimension === 1) primType = GL_POINTS; if (dimension === 2) primType = GL_LINES; if (dimension === 3) primType = GL_TRIANGLES; } elements.primType = primType; } function destroyElements (elements) { stats.elementsCount--; check$1(elements.buffer !== null, 'must not double destroy elements'); delete elementSet[elements.id]; elements.buffer.destroy(); elements.buffer = null; } function createElements (options, persistent) { var buffer = bufferState.create(null, GL_ELEMENT_ARRAY_BUFFER, true); var elements = new REGLElementBuffer(buffer._buffer); stats.elementsCount++; function reglElements (options) { if (!options) { buffer(); elements.primType = GL_TRIANGLES; elements.vertCount = 0; elements.type = GL_UNSIGNED_BYTE$3; } else if (typeof options === 'number') { buffer(options); elements.primType = GL_TRIANGLES; elements.vertCount = options | 0; elements.type = GL_UNSIGNED_BYTE$3; } else { var data = null; var usage = GL_STATIC_DRAW$1; var primType = -1; var vertCount = -1; var byteLength = 0; var dtype = 0; if (Array.isArray(options) || isTypedArray(options) || isNDArrayLike(options)) { data = options; } else { check$1.type(options, 'object', 'invalid arguments for elements'); if ('data' in options) { data = options.data; check$1( Array.isArray(data) || isTypedArray(data) || isNDArrayLike(data), 'invalid data for element buffer'); } if ('usage' in options) { check$1.parameter( options.usage, usageTypes, 'invalid element buffer usage'); usage = usageTypes[options.usage]; } if ('primitive' in options) { check$1.parameter( options.primitive, primTypes, 'invalid element buffer primitive'); primType = primTypes[options.primitive]; } if ('count' in options) { check$1( typeof options.count === 'number' && options.count >= 0, 'invalid vertex count for elements'); vertCount = options.count | 0; } if ('type' in options) { check$1.parameter( options.type, elementTypes, 'invalid buffer type'); dtype = elementTypes[options.type]; } if ('length' in options) { byteLength = options.length | 0; } else { byteLength = vertCount; if (dtype === GL_UNSIGNED_SHORT$2 || dtype === GL_SHORT$2) { byteLength *= 2; } else if (dtype === GL_UNSIGNED_INT$2 || dtype === GL_INT$2) { byteLength *= 4; } } } initElements( elements, data, usage, primType, vertCount, byteLength, dtype); } return reglElements } reglElements(options); reglElements._reglType = 'elements'; reglElements._elements = elements; reglElements.subdata = function (data, offset) { buffer.subdata(data, offset); return reglElements }; reglElements.destroy = function () { destroyElements(elements); }; return reglElements } return { create: createElements, createStream: createElementStream, destroyStream: destroyElementStream, getElements: function (elements) { if (typeof elements === 'function' && elements._elements instanceof REGLElementBuffer) { return elements._elements } return null }, clear: function () { values(elementSet).forEach(destroyElements); } } } var FLOAT = new Float32Array(1); var INT = new Uint32Array(FLOAT.buffer); var GL_UNSIGNED_SHORT$4 = 5123; function convertToHalfFloat (array) { var ushorts = pool.allocType(GL_UNSIGNED_SHORT$4, array.length); for (var i = 0; i < array.length; ++i) { if (isNaN(array[i])) { ushorts[i] = 0xffff; } else if (array[i] === Infinity) { ushorts[i] = 0x7c00; } else if (array[i] === -Infinity) { ushorts[i] = 0xfc00; } else { FLOAT[0] = array[i]; var x = INT[0]; var sgn = (x >>> 31) << 15; var exp = ((x << 1) >>> 24) - 127; var frac = (x >> 13) & ((1 << 10) - 1); if (exp < -24) { // round non-representable denormals to 0 ushorts[i] = sgn; } else if (exp < -14) { // handle denormals var s = -14 - exp; ushorts[i] = sgn + ((frac + (1 << 10)) >> s); } else if (exp > 15) { // round overflow to +/- Infinity ushorts[i] = sgn + 0x7c00; } else { // otherwise convert directly ushorts[i] = sgn + ((exp + 15) << 10) + frac; } } } return ushorts } function isArrayLike (s) { return Array.isArray(s) || isTypedArray(s) } var GL_COMPRESSED_TEXTURE_FORMATS = 0x86A3; var GL_TEXTURE_2D = 0x0DE1; var GL_TEXTURE_CUBE_MAP = 0x8513; var GL_TEXTURE_CUBE_MAP_POSITIVE_X = 0x8515; var GL_RGBA = 0x1908; var GL_ALPHA = 0x1906; var GL_RGB = 0x1907; var GL_LUMINANCE = 0x1909; var GL_LUMINANCE_ALPHA = 0x190A; var GL_RGBA4 = 0x8056; var GL_RGB5_A1 = 0x8057; var GL_RGB565 = 0x8D62; var GL_UNSIGNED_SHORT_4_4_4_4$1 = 0x8033; var GL_UNSIGNED_SHORT_5_5_5_1$1 = 0x8034; var GL_UNSIGNED_SHORT_5_6_5$1 = 0x8363; var GL_UNSIGNED_INT_24_8_WEBGL$1 = 0x84FA; var GL_DEPTH_COMPONENT = 0x1902; var GL_DEPTH_STENCIL = 0x84F9; var GL_SRGB_EXT = 0x8C40; var GL_SRGB_ALPHA_EXT = 0x8C42; var GL_HALF_FLOAT_OES$1 = 0x8D61; var GL_COMPRESSED_RGB_S3TC_DXT1_EXT = 0x83F0; var GL_COMPRESSED_RGBA_S3TC_DXT1_EXT = 0x83F1; var GL_COMPRESSED_RGBA_S3TC_DXT3_EXT = 0x83F2; var GL_COMPRESSED_RGBA_S3TC_DXT5_EXT = 0x83F3; var GL_COMPRESSED_RGB_ATC_WEBGL = 0x8C92; var GL_COMPRESSED_RGBA_ATC_EXPLICIT_ALPHA_WEBGL = 0x8C93; var GL_COMPRESSED_RGBA_ATC_INTERPOLATED_ALPHA_WEBGL = 0x87EE; var GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG = 0x8C00; var GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG = 0x8C01; var GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG = 0x8C02; var GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG = 0x8C03; var GL_COMPRESSED_RGB_ETC1_WEBGL = 0x8D64; var GL_UNSIGNED_BYTE$4 = 0x1401; var GL_UNSIGNED_SHORT$3 = 0x1403; var GL_UNSIGNED_INT$3 = 0x1405; var GL_FLOAT$3 = 0x1406; var GL_TEXTURE_WRAP_S = 0x2802; var GL_TEXTURE_WRAP_T = 0x2803; var GL_REPEAT = 0x2901; var GL_CLAMP_TO_EDGE$1 = 0x812F; var GL_MIRRORED_REPEAT = 0x8370; var GL_TEXTURE_MAG_FILTER = 0x2800; var GL_TEXTURE_MIN_FILTER = 0x2801; var GL_NEAREST$1 = 0x2600; var GL_LINEAR = 0x2601; var GL_NEAREST_MIPMAP_NEAREST$1 = 0x2700; var GL_LINEAR_MIPMAP_NEAREST$1 = 0x2701; var GL_NEAREST_MIPMAP_LINEAR$1 = 0x2702; var GL_LINEAR_MIPMAP_LINEAR$1 = 0x2703; var GL_GENERATE_MIPMAP_HINT = 0x8192; var GL_DONT_CARE = 0x1100; var GL_FASTEST = 0x1101; var GL_NICEST = 0x1102; var GL_TEXTURE_MAX_ANISOTROPY_EXT = 0x84FE; var GL_UNPACK_ALIGNMENT = 0x0CF5; var GL_UNPACK_FLIP_Y_WEBGL = 0x9240; var GL_UNPACK_PREMULTIPLY_ALPHA_WEBGL = 0x9241; var GL_UNPACK_COLORSPACE_CONVERSION_WEBGL = 0x9243; var GL_BROWSER_DEFAULT_WEBGL = 0x9244; var GL_TEXTURE0 = 0x84C0; var MIPMAP_FILTERS = [ GL_NEAREST_MIPMAP_NEAREST$1, GL_NEAREST_MIPMAP_LINEAR$1, GL_LINEAR_MIPMAP_NEAREST$1, GL_LINEAR_MIPMAP_LINEAR$1 ]; var CHANNELS_FORMAT = [ 0, GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_RGB, GL_RGBA ]; var FORMAT_CHANNELS = {}; FORMAT_CHANNELS[GL_LUMINANCE] = FORMAT_CHANNELS[GL_ALPHA] = FORMAT_CHANNELS[GL_DEPTH_COMPONENT] = 1; FORMAT_CHANNELS[GL_DEPTH_STENCIL] = FORMAT_CHANNELS[GL_LUMINANCE_ALPHA] = 2; FORMAT_CHANNELS[GL_RGB] = FORMAT_CHANNELS[GL_SRGB_EXT] = 3; FORMAT_CHANNELS[GL_RGBA] = FORMAT_CHANNELS[GL_SRGB_ALPHA_EXT] = 4; function objectName (str) { return '[object ' + str + ']' } var CANVAS_CLASS = objectName('HTMLCanvasElement'); var CONTEXT2D_CLASS = objectName('CanvasRenderingContext2D'); var IMAGE_CLASS = objectName('HTMLImageElement'); var VIDEO_CLASS = objectName('HTMLVideoElement'); var PIXEL_CLASSES = Object.keys(arrayTypes).concat([ CANVAS_CLASS, CONTEXT2D_CLASS, IMAGE_CLASS, VIDEO_CLASS ]); // for every texture type, store // the size in bytes. var TYPE_SIZES = []; TYPE_SIZES[GL_UNSIGNED_BYTE$4] = 1; TYPE_SIZES[GL_FLOAT$3] = 4; TYPE_SIZES[GL_HALF_FLOAT_OES$1] = 2; TYPE_SIZES[GL_UNSIGNED_SHORT$3] = 2; TYPE_SIZES[GL_UNSIGNED_INT$3] = 4; var FORMAT_SIZES_SPECIAL = []; FORMAT_SIZES_SPECIAL[GL_RGBA4] = 2; FORMAT_SIZES_SPECIAL[GL_RGB5_A1] = 2; FORMAT_SIZES_SPECIAL[GL_RGB565] = 2; FORMAT_SIZES_SPECIAL[GL_DEPTH_STENCIL] = 4; FORMAT_SIZES_SPECIAL[GL_COMPRESSED_RGB_S3TC_DXT1_EXT] = 0.5; FORMAT_SIZES_SPECIAL[GL_COMPRESSED_RGBA_S3TC_DXT1_EXT] = 0.5; FORMAT_SIZES_SPECIAL[GL_COMPRESSED_RGBA_S3TC_DXT3_EXT] = 1; FORMAT_SIZES_SPECIAL[GL_COMPRESSED_RGBA_S3TC_DXT5_EXT] = 1; FORMAT_SIZES_SPECIAL[GL_COMPRESSED_RGB_ATC_WEBGL] = 0.5; FORMAT_SIZES_SPECIAL[GL_COMPRESSED_RGBA_ATC_EXPLICIT_ALPHA_WEBGL] = 1; FORMAT_SIZES_SPECIAL[GL_COMPRESSED_RGBA_ATC_INTERPOLATED_ALPHA_WEBGL] = 1; FORMAT_SIZES_SPECIAL[GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG] = 0.5; FORMAT_SIZES_SPECIAL[GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG] = 0.25; FORMAT_SIZES_SPECIAL[GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG] = 0.5; FORMAT_SIZES_SPECIAL[GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG] = 0.25; FORMAT_SIZES_SPECIAL[GL_COMPRESSED_RGB_ETC1_WEBGL] = 0.5; function isNumericArray (arr) { return ( Array.isArray(arr) && (arr.length === 0 || typeof arr[0] === 'number')) } function isRectArray (arr) { if (!Array.isArray(arr)) { return false } var width = arr.length; if (width === 0 || !isArrayLike(arr[0])) { return false } return true } function classString (x) { return Object.prototype.toString.call(x) } function isCanvasElement (object) { return classString(object) === CANVAS_CLASS } function isContext2D (object) { return classString(object) === CONTEXT2D_CLASS } function isImageElement (object) { return classString(object) === IMAGE_CLASS } function isVideoElement (object) { return classString(object) === VIDEO_CLASS } function isPixelData (object) { if (!object) { return false } var className = classString(object); if (PIXEL_CLASSES.indexOf(className) >= 0) { return true } return ( isNumericArray(object) || isRectArray(object) || isNDArrayLike(object)) } function typedArrayCode$1 (data) { return arrayTypes[Object.prototype.toString.call(data)] | 0 } function convertData (result, data) { var n = data.length; switch (result.type) { case GL_UNSIGNED_BYTE$4: case GL_UNSIGNED_SHORT$3: case GL_UNSIGNED_INT$3: case GL_FLOAT$3: var converted = pool.allocType(result.type, n); converted.set(data); result.data = converted; break case GL_HALF_FLOAT_OES$1: result.data = convertToHalfFloat(data); break default: check$1.raise('unsupported texture type, must specify a typed array'); } } function preConvert (image, n) { return pool.allocType( image.type === GL_HALF_FLOAT_OES$1 ? GL_FLOAT$3 : image.type, n) } function postConvert (image, data) { if (image.type === GL_HALF_FLOAT_OES$1) { image.data = convertToHalfFloat(data); pool.freeType(data); } else { image.data = data; } } function transposeData (image, array, strideX, strideY, strideC, offset) { var w = image.width; var h = image.height; var c = image.channels; var n = w * h * c; var data = preConvert(image, n); var p = 0; for (var i = 0; i < h; ++i) { for (var j = 0; j < w; ++j) { for (var k = 0; k < c; ++k) { data[p++] = array[strideX * j + strideY * i + strideC * k + offset]; } } } postConvert(image, data); } function getTextureSize (format, type, width, height, isMipmap, isCube) { var s; if (typeof FORMAT_SIZES_SPECIAL[format] !== 'undefined') { // we have a special array for dealing with weird color formats such as RGB5A1 s = FORMAT_SIZES_SPECIAL[format]; } else { s = FORMAT_CHANNELS[format] * TYPE_SIZES[type]; } if (isCube) { s *= 6; } if (isMipmap) { // compute the total size of all the mipmaps. var total = 0; var w = width; while (w >= 1) { // we can only use mipmaps on a square image, // so we can simply use the width and ignore the height: total += s * w * w; w /= 2; } return total } else { return s * width * height } } function createTextureSet ( gl, extensions, limits, reglPoll, contextState, stats, config) { // ------------------------------------------------------- // Initialize constants and parameter tables here // ------------------------------------------------------- var mipmapHint = { "don't care": GL_DONT_CARE, 'dont care': GL_DONT_CARE, 'nice': GL_NICEST, 'fast': GL_FASTEST }; var wrapModes = { 'repeat': GL_REPEAT, 'clamp': GL_CLAMP_TO_EDGE$1, 'mirror': GL_MIRRORED_REPEAT }; var magFilters = { 'nearest': GL_NEAREST$1, 'linear': GL_LINEAR }; var minFilters = extend({ 'mipmap': GL_LINEAR_MIPMAP_LINEAR$1, 'nearest mipmap nearest': GL_NEAREST_MIPMAP_NEAREST$1, 'linear mipmap nearest': GL_LINEAR_MIPMAP_NEAREST$1, 'nearest mipmap linear': GL_NEAREST_MIPMAP_LINEAR$1, 'linear mipmap linear': GL_LINEAR_MIPMAP_LINEAR$1 }, magFilters); var colorSpace = { 'none': 0, 'browser': GL_BROWSER_DEFAULT_WEBGL }; var textureTypes = { 'uint8': GL_UNSIGNED_BYTE$4, 'rgba4': GL_UNSIGNED_SHORT_4_4_4_4$1, 'rgb565': GL_UNSIGNED_SHORT_5_6_5$1, 'rgb5 a1': GL_UNSIGNED_SHORT_5_5_5_1$1 }; var textureFormats = { 'alpha': GL_ALPHA, 'luminance': GL_LUMINANCE, 'luminance alpha': GL_LUMINANCE_ALPHA, 'rgb': GL_RGB, 'rgba': GL_RGBA, 'rgba4': GL_RGBA4, 'rgb5 a1': GL_RGB5_A1, 'rgb565': GL_RGB565 }; var compressedTextureFormats = {}; if (extensions.ext_srgb) { textureFormats.srgb = GL_SRGB_EXT; textureFormats.srgba = GL_SRGB_ALPHA_EXT; } if (extensions.oes_texture_float) { textureTypes.float32 = textureTypes.float = GL_FLOAT$3; } if (extensions.oes_texture_half_float) { textureTypes['float16'] = textureTypes['half float'] = GL_HALF_FLOAT_OES$1; } if (extensions.webgl_depth_texture) { extend(textureFormats, { 'depth': GL_DEPTH_COMPONENT, 'depth stencil': GL_DEPTH_STENCIL }); extend(textureTypes, { 'uint16': GL_UNSIGNED_SHORT$3, 'uint32': GL_UNSIGNED_INT$3, 'depth stencil': GL_UNSIGNED_INT_24_8_WEBGL$1 }); } if (extensions.webgl_compressed_texture_s3tc) { extend(compressedTextureFormats, { 'rgb s3tc dxt1': GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 'rgba s3tc dxt1': GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 'rgba s3tc dxt3': GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, 'rgba s3tc dxt5': GL_COMPRESSED_RGBA_S3TC_DXT5_EXT }); } if (extensions.webgl_compressed_texture_atc) { extend(compressedTextureFormats, { 'rgb atc': GL_COMPRESSED_RGB_ATC_WEBGL, 'rgba atc explicit alpha': GL_COMPRESSED_RGBA_ATC_EXPLICIT_ALPHA_WEBGL, 'rgba atc interpolated alpha': GL_COMPRESSED_RGBA_ATC_INTERPOLATED_ALPHA_WEBGL }); } if (extensions.webgl_compressed_texture_pvrtc) { extend(compressedTextureFormats, { 'rgb pvrtc 4bppv1': GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG, 'rgb pvrtc 2bppv1': GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG, 'rgba pvrtc 4bppv1': GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG, 'rgba pvrtc 2bppv1': GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG }); } if (extensions.webgl_compressed_texture_etc1) { compressedTextureFormats['rgb etc1'] = GL_COMPRESSED_RGB_ETC1_WEBGL; } // Copy over all texture formats var supportedCompressedFormats = Array.prototype.slice.call( gl.getParameter(GL_COMPRESSED_TEXTURE_FORMATS)); Object.keys(compressedTextureFormats).forEach(function (name) { var format = compressedTextureFormats[name]; if (supportedCompressedFormats.indexOf(format) >= 0) { textureFormats[name] = format; } }); var supportedFormats = Object.keys(textureFormats); limits.textureFormats = supportedFormats; // associate with every format string its // corresponding GL-value. var textureFormatsInvert = []; Object.keys(textureFormats).forEach(function (key) { var val = textureFormats[key]; textureFormatsInvert[val] = key; }); // associate with every type string its // corresponding GL-value. var textureTypesInvert = []; Object.keys(textureTypes).forEach(function (key) { var val = textureTypes[key]; textureTypesInvert[val] = key; }); var magFiltersInvert = []; Object.keys(magFilters).forEach(function (key) { var val = magFilters[key]; magFiltersInvert[val] = key; }); var minFiltersInvert = []; Object.keys(minFilters).forEach(function (key) { var val = minFilters[key]; minFiltersInvert[val] = key; }); var wrapModesInvert = []; Object.keys(wrapModes).forEach(function (key) { var val = wrapModes[key]; wrapModesInvert[val] = key; }); // colorFormats[] gives the format (channels) associated to an // internalformat var colorFormats = supportedFormats.reduce(function (color, key) { var glenum = textureFormats[key]; if (glenum === GL_LUMINANCE || glenum === GL_ALPHA || glenum === GL_LUMINANCE || glenum === GL_LUMINANCE_ALPHA || glenum === GL_DEPTH_COMPONENT || glenum === GL_DEPTH_STENCIL) { color[glenum] = glenum; } else if (glenum === GL_RGB5_A1 || key.indexOf('rgba') >= 0) { color[glenum] = GL_RGBA; } else { color[glenum] = GL_RGB; } return color }, {}); function TexFlags () { // format info this.internalformat = GL_RGBA; this.format = GL_RGBA; this.type = GL_UNSIGNED_BYTE$4; this.compressed = false; // pixel storage this.premultiplyAlpha = false; this.flipY = false; this.unpackAlignment = 1; this.colorSpace = 0; // shape info this.width = 0; this.height = 0; this.channels = 0; } function copyFlags (result, other) { result.internalformat = other.internalformat; result.format = other.format; result.type = other.type; result.compressed = other.compressed; result.premultiplyAlpha = other.premultiplyAlpha; result.flipY = other.flipY; result.unpackAlignment = other.unpackAlignment; result.colorSpace = other.colorSpace; result.width = other.width; result.height = other.height; result.channels = other.channels; } function parseFlags (flags, options) { if (typeof options !== 'object' || !options) { return } if ('premultiplyAlpha' in options) { check$1.type(options.premultiplyAlpha, 'boolean', 'invalid premultiplyAlpha'); flags.premultiplyAlpha = options.premultiplyAlpha; } if ('flipY' in options) { check$1.type(options.flipY, 'boolean', 'invalid texture flip'); flags.flipY = options.flipY; } if ('alignment' in options) { check$1.oneOf(options.alignment, [1, 2, 4, 8], 'invalid texture unpack alignment'); flags.unpackAlignment = options.alignment; } if ('colorSpace' in options) { check$1.parameter(options.colorSpace, colorSpace, 'invalid colorSpace'); flags.colorSpace = colorSpace[options.colorSpace]; } if ('type' in options) { var type = options.type; check$1(extensions.oes_texture_float || !(type === 'float' || type === 'float32'), 'you must enable the OES_texture_float extension in order to use floating point textures.'); check$1(extensions.oes_texture_half_float || !(type === 'half float' || type === 'float16'), 'you must enable the OES_texture_half_float extension in order to use 16-bit floating point textures.'); check$1(extensions.webgl_depth_texture || !(type === 'uint16' || type === 'uint32' || type === 'depth stencil'), 'you must enable the WEBGL_depth_texture extension in order to use depth/stencil textures.'); check$1.parameter(type, textureTypes, 'invalid texture type'); flags.type = textureTypes[type]; } var w = flags.width; var h = flags.height; var c = flags.channels; var hasChannels = false; if ('shape' in options) { check$1(Array.isArray(options.shape) && options.shape.length >= 2, 'shape must be an array'); w = options.shape[0]; h = options.shape[1]; if (options.shape.length === 3) { c = options.shape[2]; check$1(c > 0 && c <= 4, 'invalid number of channels'); hasChannels = true; } check$1(w >= 0 && w <= limits.maxTextureSize, 'invalid width'); check$1(h >= 0 && h <= limits.maxTextureSize, 'invalid height'); } else { if ('radius' in options) { w = h = options.radius; check$1(w >= 0 && w <= limits.maxTextureSize, 'invalid radius'); } if ('width' in options) { w = options.width; check$1(w >= 0 && w <= limits.maxTextureSize, 'invalid width'); } if ('height' in options) { h = options.height; check$1(h >= 0 && h <= limits.maxTextureSize, 'invalid height'); } if ('channels' in options) { c = options.channels; check$1(c > 0 && c <= 4, 'invalid number of channels'); hasChannels = true; } } flags.width = w | 0; flags.height = h | 0; flags.channels = c | 0; var hasFormat = false; if ('format' in options) { var formatStr = options.format; check$1(extensions.webgl_depth_texture || !(formatStr === 'depth' || formatStr === 'depth stencil'), 'you must enable the WEBGL_depth_texture extension in order to use depth/stencil textures.'); check$1.parameter(formatStr, textureFormats, 'invalid texture format'); var internalformat = flags.internalformat = textureFormats[formatStr]; flags.format = colorFormats[internalformat]; if (formatStr in textureTypes) { if (!('type' in options)) { flags.type = textureTypes[formatStr]; } } if (formatStr in compressedTextureFormats) { flags.compressed = true; } hasFormat = true; } // Reconcile channels and format if (!hasChannels && hasFormat) { flags.channels = FORMAT_CHANNELS[flags.format]; } else if (hasChannels && !hasFormat) { if (flags.channels !== CHANNELS_FORMAT[flags.format]) { flags.format = flags.internalformat = CHANNELS_FORMAT[flags.channels]; } } else if (hasFormat && hasChannels) { check$1( flags.channels === FORMAT_CHANNELS[flags.format], 'number of channels inconsistent with specified format'); } } function setFlags (flags) { gl.pixelStorei(GL_UNPACK_FLIP_Y_WEBGL, flags.flipY); gl.pixelStorei(GL_UNPACK_PREMULTIPLY_ALPHA_WEBGL, flags.premultiplyAlpha); gl.pixelStorei(GL_UNPACK_COLORSPACE_CONVERSION_WEBGL, flags.colorSpace); gl.pixelStorei(GL_UNPACK_ALIGNMENT, flags.unpackAlignment); } // ------------------------------------------------------- // Tex image data // ------------------------------------------------------- function TexImage () { TexFlags.call(this); this.xOffset = 0; this.yOffset = 0; // data this.data = null; this.needsFree = false; // html element this.element = null; // copyTexImage info this.needsCopy = false; } function parseImage (image, options) { var data = null; if (isPixelData(options)) { data = options; } else if (options) { check$1.type(options, 'object', 'invalid pixel data type'); parseFlags(image, options); if ('x' in options) { image.xOffset = options.x | 0; } if ('y' in options) { image.yOffset = options.y | 0; } if (isPixelData(options.data)) { data = options.data; } } check$1( !image.compressed || data instanceof Uint8Array, 'compressed texture data must be stored in a uint8array'); if (options.copy) { check$1(!data, 'can not specify copy and data field for the same texture'); var viewW = contextState.viewportWidth; var viewH = contextState.viewportHeight; image.width = image.width || (viewW - image.xOffset); image.height = image.height || (viewH - image.yOffset); image.needsCopy = true; check$1(image.xOffset >= 0 && image.xOffset < viewW && image.yOffset >= 0 && image.yOffset < viewH && image.width > 0 && image.width <= viewW && image.height > 0 && image.height <= viewH, 'copy texture read out of bounds'); } else if (!data) { image.width = image.width || 1; image.height = image.height || 1; image.channels = image.channels || 4; } else if (isTypedArray(data)) { image.channels = image.channels || 4; image.data = data; if (!('type' in options) && image.type === GL_UNSIGNED_BYTE$4) { image.type = typedArrayCode$1(data); } } else if (isNumericArray(data)) { image.channels = image.channels || 4; convertData(image, data); image.alignment = 1; image.needsFree = true; } else if (isNDArrayLike(data)) { var array = data.data; if (!Array.isArray(array) && image.type === GL_UNSIGNED_BYTE$4) { image.type = typedArrayCode$1(array); } var shape = data.shape; var stride = data.stride; var shapeX, shapeY, shapeC, strideX, strideY, strideC; if (shape.length === 3) { shapeC = shape[2]; strideC = stride[2]; } else { check$1(shape.length === 2, 'invalid ndarray pixel data, must be 2 or 3D'); shapeC = 1; strideC = 1; } shapeX = shape[0]; shapeY = shape[1]; strideX = stride[0]; strideY = stride[1]; image.alignment = 1; image.width = shapeX; image.height = shapeY; image.channels = shapeC; image.format = image.internalformat = CHANNELS_FORMAT[shapeC]; image.needsFree = true; transposeData(image, array, strideX, strideY, strideC, data.offset); } else if (isCanvasElement(data) || isContext2D(data)) { if (isCanvasElement(data)) { image.element = data; } else { image.element = data.canvas; } image.width = image.element.width; image.height = image.element.height; image.channels = 4; } else if (isImageElement(data)) { image.element = data; image.width = data.naturalWidth; image.height = data.naturalHeight; image.channels = 4; } else if (isVideoElement(data)) { image.element = data; image.width = data.videoWidth; image.height = data.videoHeight; image.channels = 4; } else if (isRectArray(data)) { var w = image.width || data[0].length; var h = image.height || data.length; var c = image.channels; if (isArrayLike(data[0][0])) { c = c || data[0][0].length; } else { c = c || 1; } var arrayShape = flattenUtils.shape(data); var n = 1; for (var dd = 0; dd < arrayShape.length; ++dd) { n *= arrayShape[dd]; } var allocData = preConvert(image, n); flattenUtils.flatten(data, arrayShape, '', allocData); postConvert(image, allocData); image.alignment = 1; image.width = w; image.height = h; image.channels = c; image.format = image.internalformat = CHANNELS_FORMAT[c]; image.needsFree = true; } if (image.type === GL_FLOAT$3) { check$1(limits.extensions.indexOf('oes_texture_float') >= 0, 'oes_texture_float extension not enabled'); } else if (image.type === GL_HALF_FLOAT_OES$1) { check$1(limits.extensions.indexOf('oes_texture_half_float') >= 0, 'oes_texture_half_float extension not enabled'); } // do compressed texture validation here. } function setImage (info, target, miplevel) { var element = info.element; var data = info.data; var internalformat = info.internalformat; var format = info.format; var type = info.type; var width = info.width; var height = info.height; setFlags(info); if (element) { gl.texImage2D(target, miplevel, format, format, type, element); } else if (info.compressed) { gl.compressedTexImage2D(target, miplevel, internalformat, width, height, 0, data); } else if (info.needsCopy) { reglPoll(); gl.copyTexImage2D( target, miplevel, format, info.xOffset, info.yOffset, width, height, 0); } else { gl.texImage2D( target, miplevel, format, width, height, 0, format, type, data); } } function setSubImage (info, target, x, y, miplevel) { var element = info.element; var data = info.data; var internalformat = info.internalformat; var format = info.format; var type = info.type; var width = info.width; var height = info.height; setFlags(info); if (element) { gl.texSubImage2D( target, miplevel, x, y, format, type, element); } else if (info.compressed) { gl.compressedTexSubImage2D( target, miplevel, x, y, internalformat, width, height, data); } else if (info.needsCopy) { reglPoll(); gl.copyTexSubImage2D( target, miplevel, x, y, info.xOffset, info.yOffset, width, height); } else { gl.texSubImage2D( target, miplevel, x, y, width, height, format, type, data); } } // texImage pool var imagePool = []; function allocImage () { return imagePool.pop() || new TexImage() } function freeImage (image) { if (image.needsFree) { pool.freeType(image.data); } TexImage.call(image); imagePool.push(image); } // ------------------------------------------------------- // Mip map // ------------------------------------------------------- function MipMap () { TexFlags.call(this); this.genMipmaps = false; this.mipmapHint = GL_DONT_CARE; this.mipmask = 0; this.images = Array(16); } function parseMipMapFromShape (mipmap, width, height) { var img = mipmap.images[0] = allocImage(); mipmap.mipmask = 1; img.width = mipmap.width = width; img.height = mipmap.height = height; img.channels = mipmap.channels = 4; } function parseMipMapFromObject (mipmap, options) { var imgData = null; if (isPixelData(options)) { imgData = mipmap.images[0] = allocImage(); copyFlags(imgData, mipmap); parseImage(imgData, options); mipmap.mipmask = 1; } else { parseFlags(mipmap, options); if (Array.isArray(options.mipmap)) { var mipData = options.mipmap; for (var i = 0; i < mipData.length; ++i) { imgData = mipmap.images[i] = allocImage(); copyFlags(imgData, mipmap); imgData.width >>= i; imgData.height >>= i; parseImage(imgData, mipData[i]); mipmap.mipmask |= (1 << i); } } else { imgData = mipmap.images[0] = allocImage(); copyFlags(imgData, mipmap); parseImage(imgData, options); mipmap.mipmask = 1; } } copyFlags(mipmap, mipmap.images[0]); // For textures of the compressed format WEBGL_compressed_texture_s3tc // we must have that // // "When level equals zero width and height must be a multiple of 4. // When level is greater than 0 width and height must be 0, 1, 2 or a multiple of 4. " // // but we do not yet support having multiple mipmap levels for compressed textures, // so we only test for level zero. if (mipmap.compressed && (mipmap.internalformat === GL_COMPRESSED_RGB_S3TC_DXT1_EXT) || (mipmap.internalformat === GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) || (mipmap.internalformat === GL_COMPRESSED_RGBA_S3TC_DXT3_EXT) || (mipmap.internalformat === GL_COMPRESSED_RGBA_S3TC_DXT5_EXT)) { check$1(mipmap.width % 4 === 0 && mipmap.height % 4 === 0, 'for compressed texture formats, mipmap level 0 must have width and height that are a multiple of 4'); } } function setMipMap (mipmap, target) { var images = mipmap.images; for (var i = 0; i < images.length; ++i) { if (!images[i]) { return } setImage(images[i], target, i); } } var mipPool = []; function allocMipMap () { var result = mipPool.pop() || new MipMap(); TexFlags.call(result); result.mipmask = 0; for (var i = 0; i < 16; ++i) { result.images[i] = null; } return result } function freeMipMap (mipmap) { var images = mipmap.images; for (var i = 0; i < images.length; ++i) { if (images[i]) { freeImage(images[i]); } images[i] = null; } mipPool.push(mipmap); } // ------------------------------------------------------- // Tex info // ------------------------------------------------------- function TexInfo () { this.minFilter = GL_NEAREST$1; this.magFilter = GL_NEAREST$1; this.wrapS = GL_CLAMP_TO_EDGE$1; this.wrapT = GL_CLAMP_TO_EDGE$1; this.anisotropic = 1; this.genMipmaps = false; this.mipmapHint = GL_DONT_CARE; } function parseTexInfo (info, options) { if ('min' in options) { var minFilter = options.min; check$1.parameter(minFilter, minFilters); info.minFilter = minFilters[minFilter]; if (MIPMAP_FILTERS.indexOf(info.minFilter) >= 0) { info.genMipmaps = true; } } if ('mag' in options) { var magFilter = options.mag; check$1.parameter(magFilter, magFilters); info.magFilter = magFilters[magFilter]; } var wrapS = info.wrapS; var wrapT = info.wrapT; if ('wrap' in options) { var wrap = options.wrap; if (typeof wrap === 'string') { check$1.parameter(wrap, wrapModes); wrapS = wrapT = wrapModes[wrap]; } else if (Array.isArray(wrap)) { check$1.parameter(wrap[0], wrapModes); check$1.parameter(wrap[1], wrapModes); wrapS = wrapModes[wrap[0]]; wrapT = wrapModes[wrap[1]]; } } else { if ('wrapS' in options) { var optWrapS = options.wrapS; check$1.parameter(optWrapS, wrapModes); wrapS = wrapModes[optWrapS]; } if ('wrapT' in options) { var optWrapT = options.wrapT; check$1.parameter(optWrapT, wrapModes); wrapT = wrapModes[optWrapT]; } } info.wrapS = wrapS; info.wrapT = wrapT; if ('anisotropic' in options) { var anisotropic = options.anisotropic; check$1(typeof anisotropic === 'number' && anisotropic >= 1 && anisotropic <= limits.maxAnisotropic, 'aniso samples must be between 1 and '); info.anisotropic = options.anisotropic; } if ('mipmap' in options) { var hasMipMap = false; switch (typeof options.mipmap) { case 'string': check$1.parameter(options.mipmap, mipmapHint, 'invalid mipmap hint'); info.mipmapHint = mipmapHint[options.mipmap]; info.genMipmaps = true; hasMipMap = true; break case 'boolean': hasMipMap = info.genMipmaps = options.mipmap; break case 'object': check$1(Array.isArray(options.mipmap), 'invalid mipmap type'); info.genMipmaps = false; hasMipMap = true; break default: check$1.raise('invalid mipmap type'); } if (hasMipMap && !('min' in options)) { info.minFilter = GL_NEAREST_MIPMAP_NEAREST$1; } } } function setTexInfo (info, target) { gl.texParameteri(target, GL_TEXTURE_MIN_FILTER, info.minFilter); gl.texParameteri(target, GL_TEXTURE_MAG_FILTER, info.magFilter); gl.texParameteri(target, GL_TEXTURE_WRAP_S, info.wrapS); gl.texParameteri(target, GL_TEXTURE_WRAP_T, info.wrapT); if (extensions.ext_texture_filter_anisotropic) { gl.texParameteri(target, GL_TEXTURE_MAX_ANISOTROPY_EXT, info.anisotropic); } if (info.genMipmaps) { gl.hint(GL_GENERATE_MIPMAP_HINT, info.mipmapHint); gl.generateMipmap(target); } } // ------------------------------------------------------- // Full texture object // ------------------------------------------------------- var textureCount = 0; var textureSet = {}; var numTexUnits = limits.maxTextureUnits; var textureUnits = Array(numTexUnits).map(function () { return null }); function REGLTexture (target) { TexFlags.call(this); this.mipmask = 0; this.internalformat = GL_RGBA; this.id = textureCount++; this.refCount = 1; this.target = target; this.texture = gl.createTexture(); this.unit = -1; this.bindCount = 0; this.texInfo = new TexInfo(); if (config.profile) { this.stats = {size: 0}; } } function tempBind (texture) { gl.activeTexture(GL_TEXTURE0); gl.bindTexture(texture.target, texture.texture); } function tempRestore () { var prev = textureUnits[0]; if (prev) { gl.bindTexture(prev.target, prev.texture); } else { gl.bindTexture(GL_TEXTURE_2D, null); } } function destroy (texture) { var handle = texture.texture; check$1(handle, 'must not double destroy texture'); var unit = texture.unit; var target = texture.target; if (unit >= 0) { gl.activeTexture(GL_TEXTURE0 + unit); gl.bindTexture(target, null); textureUnits[unit] = null; } gl.deleteTexture(handle); texture.texture = null; texture.params = null; texture.pixels = null; texture.refCount = 0; delete textureSet[texture.id]; stats.textureCount--; } extend(REGLTexture.prototype, { bind: function () { var texture = this; texture.bindCount += 1; var unit = texture.unit; if (unit < 0) { for (var i = 0; i < numTexUnits; ++i) { var other = textureUnits[i]; if (other) { if (other.bindCount > 0) { continue } other.unit = -1; } textureUnits[i] = texture; unit = i; break } if (unit >= numTexUnits) { check$1.raise('insufficient number of texture units'); } if (config.profile && stats.maxTextureUnits < (unit + 1)) { stats.maxTextureUnits = unit + 1; // +1, since the units are zero-based } texture.unit = unit; gl.activeTexture(GL_TEXTURE0 + unit); gl.bindTexture(texture.target, texture.texture); } return unit }, unbind: function () { this.bindCount -= 1; }, decRef: function () { if (--this.refCount <= 0) { destroy(this); } } }); function createTexture2D (a, b) { var texture = new REGLTexture(GL_TEXTURE_2D); textureSet[texture.id] = texture; stats.textureCount++; function reglTexture2D (a, b) { var texInfo = texture.texInfo; TexInfo.call(texInfo); var mipData = allocMipMap(); if (typeof a === 'number') { if (typeof b === 'number') { parseMipMapFromShape(mipData, a | 0, b | 0); } else { parseMipMapFromShape(mipData, a | 0, a | 0); } } else if (a) { check$1.type(a, 'object', 'invalid arguments to regl.texture'); parseTexInfo(texInfo, a); parseMipMapFromObject(mipData, a); } else { // empty textures get assigned a default shape of 1x1 parseMipMapFromShape(mipData, 1, 1); } if (texInfo.genMipmaps) { mipData.mipmask = (mipData.width << 1) - 1; } texture.mipmask = mipData.mipmask; copyFlags(texture, mipData); check$1.texture2D(texInfo, mipData, limits); texture.internalformat = mipData.internalformat; reglTexture2D.width = mipData.width; reglTexture2D.height = mipData.height; tempBind(texture); setMipMap(mipData, GL_TEXTURE_2D); setTexInfo(texInfo, GL_TEXTURE_2D); tempRestore(); freeMipMap(mipData); if (config.profile) { texture.stats.size = getTextureSize( texture.internalformat, texture.type, mipData.width, mipData.height, texInfo.genMipmaps, false); } reglTexture2D.format = textureFormatsInvert[texture.internalformat]; reglTexture2D.type = textureTypesInvert[texture.type]; reglTexture2D.mag = magFiltersInvert[texInfo.magFilter]; reglTexture2D.min = minFiltersInvert[texInfo.minFilter]; reglTexture2D.wrapS = wrapModesInvert[texInfo.wrapS]; reglTexture2D.wrapT = wrapModesInvert[texInfo.wrapT]; return reglTexture2D } function subimage (image, x_, y_, level_) { check$1(!!image, 'must specify image data'); var x = x_ | 0; var y = y_ | 0; var level = level_ | 0; var imageData = allocImage(); copyFlags(imageData, texture); imageData.width = 0; imageData.height = 0; parseImage(imageData, image); imageData.width = imageData.width || ((texture.width >> level) - x); imageData.height = imageData.height || ((texture.height >> level) - y); check$1( texture.type === imageData.type && texture.format === imageData.format && texture.internalformat === imageData.internalformat, 'incompatible format for texture.subimage'); check$1( x >= 0 && y >= 0 && x + imageData.width <= texture.width && y + imageData.height <= texture.height, 'texture.subimage write out of bounds'); check$1( texture.mipmask & (1 << level), 'missing mipmap data'); check$1( imageData.data || imageData.element || imageData.needsCopy, 'missing image data'); tempBind(texture); setSubImage(imageData, GL_TEXTURE_2D, x, y, level); tempRestore(); freeImage(imageData); return reglTexture2D } function resize (w_, h_) { var w = w_ | 0; var h = (h_ | 0) || w; if (w === texture.width && h === texture.height) { return reglTexture2D } reglTexture2D.width = texture.width = w; reglTexture2D.height = texture.height = h; tempBind(texture); for (var i = 0; texture.mipmask >> i; ++i) { gl.texImage2D( GL_TEXTURE_2D, i, texture.format, w >> i, h >> i, 0, texture.format, texture.type, null); } tempRestore(); // also, recompute the texture size. if (config.profile) { texture.stats.size = getTextureSize( texture.internalformat, texture.type, w, h, false, false); } return reglTexture2D } reglTexture2D(a, b); reglTexture2D.subimage = subimage; reglTexture2D.resize = resize; reglTexture2D._reglType = 'texture2d'; reglTexture2D._texture = texture; if (config.profile) { reglTexture2D.stats = texture.stats; } reglTexture2D.destroy = function () { texture.decRef(); }; return reglTexture2D } function createTextureCube (a0, a1, a2, a3, a4, a5) { var texture = new REGLTexture(GL_TEXTURE_CUBE_MAP); textureSet[texture.id] = texture; stats.cubeCount++; var faces = new Array(6); function reglTextureCube (a0, a1, a2, a3, a4, a5) { var i; var texInfo = texture.texInfo; TexInfo.call(texInfo); for (i = 0; i < 6; ++i) { faces[i] = allocMipMap(); } if (typeof a0 === 'number' || !a0) { var s = (a0 | 0) || 1; for (i = 0; i < 6; ++i) { parseMipMapFromShape(faces[i], s, s); } } else if (typeof a0 === 'object') { if (a1) { parseMipMapFromObject(faces[0], a0); parseMipMapFromObject(faces[1], a1); parseMipMapFromObject(faces[2], a2); parseMipMapFromObject(faces[3], a3); parseMipMapFromObject(faces[4], a4); parseMipMapFromObject(faces[5], a5); } else { parseTexInfo(texInfo, a0); parseFlags(texture, a0); if ('faces' in a0) { var face_input = a0.faces; check$1(Array.isArray(face_input) && face_input.length === 6, 'cube faces must be a length 6 array'); for (i = 0; i < 6; ++i) { check$1(typeof face_input[i] === 'object' && !!face_input[i], 'invalid input for cube map face'); copyFlags(faces[i], texture); parseMipMapFromObject(faces[i], face_input[i]); } } else { for (i = 0; i < 6; ++i) { parseMipMapFromObject(faces[i], a0); } } } } else { check$1.raise('invalid arguments to cube map'); } copyFlags(texture, faces[0]); if (texInfo.genMipmaps) { texture.mipmask = (faces[0].width << 1) - 1; } else { texture.mipmask = faces[0].mipmask; } check$1.textureCube(texture, texInfo, faces, limits); texture.internalformat = faces[0].internalformat; reglTextureCube.width = faces[0].width; reglTextureCube.height = faces[0].height; tempBind(texture); for (i = 0; i < 6; ++i) { setMipMap(faces[i], GL_TEXTURE_CUBE_MAP_POSITIVE_X + i); } setTexInfo(texInfo, GL_TEXTURE_CUBE_MAP); tempRestore(); if (config.profile) { texture.stats.size = getTextureSize( texture.internalformat, texture.type, reglTextureCube.width, reglTextureCube.height, texInfo.genMipmaps, true); } reglTextureCube.format = textureFormatsInvert[texture.internalformat]; reglTextureCube.type = textureTypesInvert[texture.type]; reglTextureCube.mag = magFiltersInvert[texInfo.magFilter]; reglTextureCube.min = minFiltersInvert[texInfo.minFilter]; reglTextureCube.wrapS = wrapModesInvert[texInfo.wrapS]; reglTextureCube.wrapT = wrapModesInvert[texInfo.wrapT]; for (i = 0; i < 6; ++i) { freeMipMap(faces[i]); } return reglTextureCube } function subimage (face, image, x_, y_, level_) { check$1(!!image, 'must specify image data'); check$1(typeof face === 'number' && face === (face | 0) && face >= 0 && face < 6, 'invalid face'); var x = x_ | 0; var y = y_ | 0; var level = level_ | 0; var imageData = allocImage(); copyFlags(imageData, texture); imageData.width = 0; imageData.height = 0; parseImage(imageData, image); imageData.width = imageData.width || ((texture.width >> level) - x); imageData.height = imageData.height || ((texture.height >> level) - y); check$1( texture.type === imageData.type && texture.format === imageData.format && texture.internalformat === imageData.internalformat, 'incompatible format for texture.subimage'); check$1( x >= 0 && y >= 0 && x + imageData.width <= texture.width && y + imageData.height <= texture.height, 'texture.subimage write out of bounds'); check$1( texture.mipmask & (1 << level), 'missing mipmap data'); check$1( imageData.data || imageData.element || imageData.needsCopy, 'missing image data'); tempBind(texture); setSubImage(imageData, GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, x, y, level); tempRestore(); freeImage(imageData); return reglTextureCube } function resize (radius_) { var radius = radius_ | 0; if (radius === texture.width) { return } reglTextureCube.width = texture.width = radius; reglTextureCube.height = texture.height = radius; tempBind(texture); for (var i = 0; i < 6; ++i) { for (var j = 0; texture.mipmask >> j; ++j) { gl.texImage2D( GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, j, texture.format, radius >> j, radius >> j, 0, texture.format, texture.type, null); } } tempRestore(); if (config.profile) { texture.stats.size = getTextureSize( texture.internalformat, texture.type, reglTextureCube.width, reglTextureCube.height, false, true); } return reglTextureCube } reglTextureCube(a0, a1, a2, a3, a4, a5); reglTextureCube.subimage = subimage; reglTextureCube.resize = resize; reglTextureCube._reglType = 'textureCube'; reglTextureCube._texture = texture; if (config.profile) { reglTextureCube.stats = texture.stats; } reglTextureCube.destroy = function () { texture.decRef(); }; return reglTextureCube } // Called when regl is destroyed function destroyTextures () { for (var i = 0; i < numTexUnits; ++i) { gl.activeTexture(GL_TEXTURE0 + i); gl.bindTexture(GL_TEXTURE_2D, null); textureUnits[i] = null; } values(textureSet).forEach(destroy); stats.cubeCount = 0; stats.textureCount = 0; } if (config.profile) { stats.getTotalTextureSize = function () { var total = 0; Object.keys(textureSet).forEach(function (key) { total += textureSet[key].stats.size; }); return total }; } function restoreTextures () { values(textureSet).forEach(function (texture) { texture.texture = gl.createTexture(); gl.bindTexture(texture.target, texture.texture); for (var i = 0; i < 32; ++i) { if ((texture.mipmask & (1 << i)) === 0) { continue } if (texture.target === GL_TEXTURE_2D) { gl.texImage2D(GL_TEXTURE_2D, i, texture.internalformat, texture.width >> i, texture.height >> i, 0, texture.internalformat, texture.type, null); } else { for (var j = 0; j < 6; ++j) { gl.texImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + j, i, texture.internalformat, texture.width >> i, texture.height >> i, 0, texture.internalformat, texture.type, null); } } } setTexInfo(texture.texInfo, texture.target); }); } return { create2D: createTexture2D, createCube: createTextureCube, clear: destroyTextures, getTexture: function (wrapper) { return null }, restore: restoreTextures } } var GL_RENDERBUFFER = 0x8D41; var GL_RGBA4$1 = 0x8056; var GL_RGB5_A1$1 = 0x8057; var GL_RGB565$1 = 0x8D62; var GL_DEPTH_COMPONENT16 = 0x81A5; var GL_STENCIL_INDEX8 = 0x8D48; var GL_DEPTH_STENCIL$1 = 0x84F9; var GL_SRGB8_ALPHA8_EXT = 0x8C43; var GL_RGBA32F_EXT = 0x8814; var GL_RGBA16F_EXT = 0x881A; var GL_RGB16F_EXT = 0x881B; var FORMAT_SIZES = []; FORMAT_SIZES[GL_RGBA4$1] = 2; FORMAT_SIZES[GL_RGB5_A1$1] = 2; FORMAT_SIZES[GL_RGB565$1] = 2; FORMAT_SIZES[GL_DEPTH_COMPONENT16] = 2; FORMAT_SIZES[GL_STENCIL_INDEX8] = 1; FORMAT_SIZES[GL_DEPTH_STENCIL$1] = 4; FORMAT_SIZES[GL_SRGB8_ALPHA8_EXT] = 4; FORMAT_SIZES[GL_RGBA32F_EXT] = 16; FORMAT_SIZES[GL_RGBA16F_EXT] = 8; FORMAT_SIZES[GL_RGB16F_EXT] = 6; function getRenderbufferSize (format, width, height) { return FORMAT_SIZES[format] * width * height } var wrapRenderbuffers = function (gl, extensions, limits, stats, config) { var formatTypes = { 'rgba4': GL_RGBA4$1, 'rgb565': GL_RGB565$1, 'rgb5 a1': GL_RGB5_A1$1, 'depth': GL_DEPTH_COMPONENT16, 'stencil': GL_STENCIL_INDEX8, 'depth stencil': GL_DEPTH_STENCIL$1 }; if (extensions.ext_srgb) { formatTypes['srgba'] = GL_SRGB8_ALPHA8_EXT; } if (extensions.ext_color_buffer_half_float) { formatTypes['rgba16f'] = GL_RGBA16F_EXT; formatTypes['rgb16f'] = GL_RGB16F_EXT; } if (extensions.webgl_color_buffer_float) { formatTypes['rgba32f'] = GL_RGBA32F_EXT; } var formatTypesInvert = []; Object.keys(formatTypes).forEach(function (key) { var val = formatTypes[key]; formatTypesInvert[val] = key; }); var renderbufferCount = 0; var renderbufferSet = {}; function REGLRenderbuffer (renderbuffer) { this.id = renderbufferCount++; this.refCount = 1; this.renderbuffer = renderbuffer; this.format = GL_RGBA4$1; this.width = 0; this.height = 0; if (config.profile) { this.stats = {size: 0}; } } REGLRenderbuffer.prototype.decRef = function () { if (--this.refCount <= 0) { destroy(this); } }; function destroy (rb) { var handle = rb.renderbuffer; check$1(handle, 'must not double destroy renderbuffer'); gl.bindRenderbuffer(GL_RENDERBUFFER, null); gl.deleteRenderbuffer(handle); rb.renderbuffer = null; rb.refCount = 0; delete renderbufferSet[rb.id]; stats.renderbufferCount--; } function createRenderbuffer (a, b) { var renderbuffer = new REGLRenderbuffer(gl.createRenderbuffer()); renderbufferSet[renderbuffer.id] = renderbuffer; stats.renderbufferCount++; function reglRenderbuffer (a, b) { var w = 0; var h = 0; var format = GL_RGBA4$1; if (typeof a === 'object' && a) { var options = a; if ('shape' in options) { var shape = options.shape; check$1(Array.isArray(shape) && shape.length >= 2, 'invalid renderbuffer shape'); w = shape[0] | 0; h = shape[1] | 0; } else { if ('radius' in options) { w = h = options.radius | 0; } if ('width' in options) { w = options.width | 0; } if ('height' in options) { h = options.height | 0; } } if ('format' in options) { check$1.parameter(options.format, formatTypes, 'invalid renderbuffer format'); format = formatTypes[options.format]; } } else if (typeof a === 'number') { w = a | 0; if (typeof b === 'number') { h = b | 0; } else { h = w; } } else if (!a) { w = h = 1; } else { check$1.raise('invalid arguments to renderbuffer constructor'); } // check shape check$1( w > 0 && h > 0 && w <= limits.maxRenderbufferSize && h <= limits.maxRenderbufferSize, 'invalid renderbuffer size'); if (w === renderbuffer.width && h === renderbuffer.height && format === renderbuffer.format) { return } reglRenderbuffer.width = renderbuffer.width = w; reglRenderbuffer.height = renderbuffer.height = h; renderbuffer.format = format; gl.bindRenderbuffer(GL_RENDERBUFFER, renderbuffer.renderbuffer); gl.renderbufferStorage(GL_RENDERBUFFER, format, w, h); if (config.profile) { renderbuffer.stats.size = getRenderbufferSize(renderbuffer.format, renderbuffer.width, renderbuffer.height); } reglRenderbuffer.format = formatTypesInvert[renderbuffer.format]; return reglRenderbuffer } function resize (w_, h_) { var w = w_ | 0; var h = (h_ | 0) || w; if (w === renderbuffer.width && h === renderbuffer.height) { return reglRenderbuffer } // check shape check$1( w > 0 && h > 0 && w <= limits.maxRenderbufferSize && h <= limits.maxRenderbufferSize, 'invalid renderbuffer size'); reglRenderbuffer.width = renderbuffer.width = w; reglRenderbuffer.height = renderbuffer.height = h; gl.bindRenderbuffer(GL_RENDERBUFFER, renderbuffer.renderbuffer); gl.renderbufferStorage(GL_RENDERBUFFER, renderbuffer.format, w, h); // also, recompute size. if (config.profile) { renderbuffer.stats.size = getRenderbufferSize( renderbuffer.format, renderbuffer.width, renderbuffer.height); } return reglRenderbuffer } reglRenderbuffer(a, b); reglRenderbuffer.resize = resize; reglRenderbuffer._reglType = 'renderbuffer'; reglRenderbuffer._renderbuffer = renderbuffer; if (config.profile) { reglRenderbuffer.stats = renderbuffer.stats; } reglRenderbuffer.destroy = function () { renderbuffer.decRef(); }; return reglRenderbuffer } if (config.profile) { stats.getTotalRenderbufferSize = function () { var total = 0; Object.keys(renderbufferSet).forEach(function (key) { total += renderbufferSet[key].stats.size; }); return total }; } function restoreRenderbuffers () { values(renderbufferSet).forEach(function (rb) { rb.renderbuffer = gl.createRenderbuffer(); gl.bindRenderbuffer(GL_RENDERBUFFER, rb.renderbuffer); gl.renderbufferStorage(GL_RENDERBUFFER, rb.format, rb.width, rb.height); }); gl.bindRenderbuffer(GL_RENDERBUFFER, null); } return { create: createRenderbuffer, clear: function () { values(renderbufferSet).forEach(destroy); }, restore: restoreRenderbuffers } }; // We store these constants so that the minifier can inline them var GL_FRAMEBUFFER = 0x8D40; var GL_RENDERBUFFER$1 = 0x8D41; var GL_TEXTURE_2D$1 = 0x0DE1; var GL_TEXTURE_CUBE_MAP_POSITIVE_X$1 = 0x8515; var GL_COLOR_ATTACHMENT0 = 0x8CE0; var GL_DEPTH_ATTACHMENT = 0x8D00; var GL_STENCIL_ATTACHMENT = 0x8D20; var GL_DEPTH_STENCIL_ATTACHMENT = 0x821A; var GL_FRAMEBUFFER_COMPLETE = 0x8CD5; var GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT = 0x8CD6; var GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT = 0x8CD7; var GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS = 0x8CD9; var GL_FRAMEBUFFER_UNSUPPORTED = 0x8CDD; var GL_HALF_FLOAT_OES$2 = 0x8D61; var GL_UNSIGNED_BYTE$5 = 0x1401; var GL_FLOAT$4 = 0x1406; var GL_RGBA$1 = 0x1908; var GL_DEPTH_COMPONENT$1 = 0x1902; var colorTextureFormatEnums = [ GL_RGBA$1 ]; // for every texture format, store // the number of channels var textureFormatChannels = []; textureFormatChannels[GL_RGBA$1] = 4; // for every texture type, store // the size in bytes. var textureTypeSizes = []; textureTypeSizes[GL_UNSIGNED_BYTE$5] = 1; textureTypeSizes[GL_FLOAT$4] = 4; textureTypeSizes[GL_HALF_FLOAT_OES$2] = 2; var GL_RGBA4$2 = 0x8056; var GL_RGB5_A1$2 = 0x8057; var GL_RGB565$2 = 0x8D62; var GL_DEPTH_COMPONENT16$1 = 0x81A5; var GL_STENCIL_INDEX8$1 = 0x8D48; var GL_DEPTH_STENCIL$2 = 0x84F9; var GL_SRGB8_ALPHA8_EXT$1 = 0x8C43; var GL_RGBA32F_EXT$1 = 0x8814; var GL_RGBA16F_EXT$1 = 0x881A; var GL_RGB16F_EXT$1 = 0x881B; var colorRenderbufferFormatEnums = [ GL_RGBA4$2, GL_RGB5_A1$2, GL_RGB565$2, GL_SRGB8_ALPHA8_EXT$1, GL_RGBA16F_EXT$1, GL_RGB16F_EXT$1, GL_RGBA32F_EXT$1 ]; var statusCode = {}; statusCode[GL_FRAMEBUFFER_COMPLETE] = 'complete'; statusCode[GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT] = 'incomplete attachment'; statusCode[GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS] = 'incomplete dimensions'; statusCode[GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT] = 'incomplete, missing attachment'; statusCode[GL_FRAMEBUFFER_UNSUPPORTED] = 'unsupported'; function wrapFBOState ( gl, extensions, limits, textureState, renderbufferState, stats) { var framebufferState = { cur: null, next: null, dirty: false, setFBO: null }; var colorTextureFormats = ['rgba']; var colorRenderbufferFormats = ['rgba4', 'rgb565', 'rgb5 a1']; if (extensions.ext_srgb) { colorRenderbufferFormats.push('srgba'); } if (extensions.ext_color_buffer_half_float) { colorRenderbufferFormats.push('rgba16f', 'rgb16f'); } if (extensions.webgl_color_buffer_float) { colorRenderbufferFormats.push('rgba32f'); } var colorTypes = ['uint8']; if (extensions.oes_texture_half_float) { colorTypes.push('half float', 'float16'); } if (extensions.oes_texture_float) { colorTypes.push('float', 'float32'); } function FramebufferAttachment (target, texture, renderbuffer) { this.target = target; this.texture = texture; this.renderbuffer = renderbuffer; var w = 0; var h = 0; if (texture) { w = texture.width; h = texture.height; } else if (renderbuffer) { w = renderbuffer.width; h = renderbuffer.height; } this.width = w; this.height = h; } function decRef (attachment) { if (attachment) { if (attachment.texture) { attachment.texture._texture.decRef(); } if (attachment.renderbuffer) { attachment.renderbuffer._renderbuffer.decRef(); } } } function incRefAndCheckShape (attachment, width, height) { if (!attachment) { return } if (attachment.texture) { var texture = attachment.texture._texture; var tw = Math.max(1, texture.width); var th = Math.max(1, texture.height); check$1(tw === width && th === height, 'inconsistent width/height for supplied texture'); texture.refCount += 1; } else { var renderbuffer = attachment.renderbuffer._renderbuffer; check$1( renderbuffer.width === width && renderbuffer.height === height, 'inconsistent width/height for renderbuffer'); renderbuffer.refCount += 1; } } function attach (location, attachment) { if (attachment) { if (attachment.texture) { gl.framebufferTexture2D( GL_FRAMEBUFFER, location, attachment.target, attachment.texture._texture.texture, 0); } else { gl.framebufferRenderbuffer( GL_FRAMEBUFFER, location, GL_RENDERBUFFER$1, attachment.renderbuffer._renderbuffer.renderbuffer); } } } function parseAttachment (attachment) { var target = GL_TEXTURE_2D$1; var texture = null; var renderbuffer = null; var data = attachment; if (typeof attachment === 'object') { data = attachment.data; if ('target' in attachment) { target = attachment.target | 0; } } check$1.type(data, 'function', 'invalid attachment data'); var type = data._reglType; if (type === 'texture2d') { texture = data; check$1(target === GL_TEXTURE_2D$1); } else if (type === 'textureCube') { texture = data; check$1( target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X$1 && target < GL_TEXTURE_CUBE_MAP_POSITIVE_X$1 + 6, 'invalid cube map target'); } else if (type === 'renderbuffer') { renderbuffer = data; target = GL_RENDERBUFFER$1; } else { check$1.raise('invalid regl object for attachment'); } return new FramebufferAttachment(target, texture, renderbuffer) } function allocAttachment ( width, height, isTexture, format, type) { if (isTexture) { var texture = textureState.create2D({ width: width, height: height, format: format, type: type }); texture._texture.refCount = 0; return new FramebufferAttachment(GL_TEXTURE_2D$1, texture, null) } else { var rb = renderbufferState.create({ width: width, height: height, format: format }); rb._renderbuffer.refCount = 0; return new FramebufferAttachment(GL_RENDERBUFFER$1, null, rb) } } function unwrapAttachment (attachment) { return attachment && (attachment.texture || attachment.renderbuffer) } function resizeAttachment (attachment, w, h) { if (attachment) { if (attachment.texture) { attachment.texture.resize(w, h); } else if (attachment.renderbuffer) { attachment.renderbuffer.resize(w, h); } } } var framebufferCount = 0; var framebufferSet = {}; function REGLFramebuffer () { this.id = framebufferCount++; framebufferSet[this.id] = this; this.framebuffer = gl.createFramebuffer(); this.width = 0; this.height = 0; this.colorAttachments = []; this.depthAttachment = null; this.stencilAttachment = null; this.depthStencilAttachment = null; } function decFBORefs (framebuffer) { framebuffer.colorAttachments.forEach(decRef); decRef(framebuffer.depthAttachment); decRef(framebuffer.stencilAttachment); decRef(framebuffer.depthStencilAttachment); } function destroy (framebuffer) { var handle = framebuffer.framebuffer; check$1(handle, 'must not double destroy framebuffer'); gl.deleteFramebuffer(handle); framebuffer.framebuffer = null; stats.framebufferCount--; delete framebufferSet[framebuffer.id]; } function updateFramebuffer (framebuffer) { var i; gl.bindFramebuffer(GL_FRAMEBUFFER, framebuffer.framebuffer); var colorAttachments = framebuffer.colorAttachments; for (i = 0; i < colorAttachments.length; ++i) { attach(GL_COLOR_ATTACHMENT0 + i, colorAttachments[i]); } for (i = colorAttachments.length; i < limits.maxColorAttachments; ++i) { gl.framebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D$1, null, 0); } gl.framebufferTexture2D( GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D$1, null, 0); gl.framebufferTexture2D( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D$1, null, 0); gl.framebufferTexture2D( GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D$1, null, 0); attach(GL_DEPTH_ATTACHMENT, framebuffer.depthAttachment); attach(GL_STENCIL_ATTACHMENT, framebuffer.stencilAttachment); attach(GL_DEPTH_STENCIL_ATTACHMENT, framebuffer.depthStencilAttachment); // Check status code var status = gl.checkFramebufferStatus(GL_FRAMEBUFFER); if (status !== GL_FRAMEBUFFER_COMPLETE) { check$1.raise('framebuffer configuration not supported, status = ' + statusCode[status]); } gl.bindFramebuffer(GL_FRAMEBUFFER, framebufferState.next); framebufferState.cur = framebufferState.next; // FIXME: Clear error code here. This is a work around for a bug in // headless-gl gl.getError(); } function createFBO (a0, a1) { var framebuffer = new REGLFramebuffer(); stats.framebufferCount++; function reglFramebuffer (a, b) { var i; check$1(framebufferState.next !== framebuffer, 'can not update framebuffer which is currently in use'); var extDrawBuffers = extensions.webgl_draw_buffers; var width = 0; var height = 0; var needsDepth = true; var needsStencil = true; var colorBuffer = null; var colorTexture = true; var colorFormat = 'rgba'; var colorType = 'uint8'; var colorCount = 1; var depthBuffer = null; var stencilBuffer = null; var depthStencilBuffer = null; var depthStencilTexture = false; if (typeof a === 'number') { width = a | 0; height = (b | 0) || width; } else if (!a) { width = height = 1; } else { check$1.type(a, 'object', 'invalid arguments for framebuffer'); var options = a; if ('shape' in options) { var shape = options.shape; check$1(Array.isArray(shape) && shape.length >= 2, 'invalid shape for framebuffer'); width = shape[0]; height = shape[1]; } else { if ('radius' in options) { width = height = options.radius; } if ('width' in options) { width = options.width; } if ('height' in options) { height = options.height; } } if ('color' in options || 'colors' in options) { colorBuffer = options.color || options.colors; if (Array.isArray(colorBuffer)) { check$1( colorBuffer.length === 1 || extDrawBuffers, 'multiple render targets not supported'); } } if (!colorBuffer) { if ('colorCount' in options) { colorCount = options.colorCount | 0; check$1(colorCount > 0, 'invalid color buffer count'); } if ('colorTexture' in options) { colorTexture = !!options.colorTexture; colorFormat = 'rgba4'; } if ('colorType' in options) { colorType = options.colorType; if (!colorTexture) { if (colorType === 'half float' || colorType === 'float16') { check$1(extensions.ext_color_buffer_half_float, 'you must enable EXT_color_buffer_half_float to use 16-bit render buffers'); colorFormat = 'rgba16f'; } else if (colorType === 'float' || colorType === 'float32') { check$1(extensions.webgl_color_buffer_float, 'you must enable WEBGL_color_buffer_float in order to use 32-bit floating point renderbuffers'); colorFormat = 'rgba32f'; } } else { check$1(extensions.oes_texture_float || !(colorType === 'float' || colorType === 'float32'), 'you must enable OES_texture_float in order to use floating point framebuffer objects'); check$1(extensions.oes_texture_half_float || !(colorType === 'half float' || colorType === 'float16'), 'you must enable OES_texture_half_float in order to use 16-bit floating point framebuffer objects'); } check$1.oneOf(colorType, colorTypes, 'invalid color type'); } if ('colorFormat' in options) { colorFormat = options.colorFormat; if (colorTextureFormats.indexOf(colorFormat) >= 0) { colorTexture = true; } else if (colorRenderbufferFormats.indexOf(colorFormat) >= 0) { colorTexture = false; } else { if (colorTexture) { check$1.oneOf( options.colorFormat, colorTextureFormats, 'invalid color format for texture'); } else { check$1.oneOf( options.colorFormat, colorRenderbufferFormats, 'invalid color format for renderbuffer'); } } } } if ('depthTexture' in options || 'depthStencilTexture' in options) { depthStencilTexture = !!(options.depthTexture || options.depthStencilTexture); check$1(!depthStencilTexture || extensions.webgl_depth_texture, 'webgl_depth_texture extension not supported'); } if ('depth' in options) { if (typeof options.depth === 'boolean') { needsDepth = options.depth; } else { depthBuffer = options.depth; needsStencil = false; } } if ('stencil' in options) { if (typeof options.stencil === 'boolean') { needsStencil = options.stencil; } else { stencilBuffer = options.stencil; needsDepth = false; } } if ('depthStencil' in options) { if (typeof options.depthStencil === 'boolean') { needsDepth = needsStencil = options.depthStencil; } else { depthStencilBuffer = options.depthStencil; needsDepth = false; needsStencil = false; } } } // parse attachments var colorAttachments = null; var depthAttachment = null; var stencilAttachment = null; var depthStencilAttachment = null; // Set up color attachments if (Array.isArray(colorBuffer)) { colorAttachments = colorBuffer.map(parseAttachment); } else if (colorBuffer) { colorAttachments = [parseAttachment(colorBuffer)]; } else { colorAttachments = new Array(colorCount); for (i = 0; i < colorCount; ++i) { colorAttachments[i] = allocAttachment( width, height, colorTexture, colorFormat, colorType); } } check$1(extensions.webgl_draw_buffers || colorAttachments.length <= 1, 'you must enable the WEBGL_draw_buffers extension in order to use multiple color buffers.'); check$1(colorAttachments.length <= limits.maxColorAttachments, 'too many color attachments, not supported'); width = width || colorAttachments[0].width; height = height || colorAttachments[0].height; if (depthBuffer) { depthAttachment = parseAttachment(depthBuffer); } else if (needsDepth && !needsStencil) { depthAttachment = allocAttachment( width, height, depthStencilTexture, 'depth', 'uint32'); } if (stencilBuffer) { stencilAttachment = parseAttachment(stencilBuffer); } else if (needsStencil && !needsDepth) { stencilAttachment = allocAttachment( width, height, false, 'stencil', 'uint8'); } if (depthStencilBuffer) { depthStencilAttachment = parseAttachment(depthStencilBuffer); } else if (!depthBuffer && !stencilBuffer && needsStencil && needsDepth) { depthStencilAttachment = allocAttachment( width, height, depthStencilTexture, 'depth stencil', 'depth stencil'); } check$1( (!!depthBuffer) + (!!stencilBuffer) + (!!depthStencilBuffer) <= 1, 'invalid framebuffer configuration, can specify exactly one depth/stencil attachment'); var commonColorAttachmentSize = null; for (i = 0; i < colorAttachments.length; ++i) { incRefAndCheckShape(colorAttachments[i], width, height); check$1(!colorAttachments[i] || (colorAttachments[i].texture && colorTextureFormatEnums.indexOf(colorAttachments[i].texture._texture.format) >= 0) || (colorAttachments[i].renderbuffer && colorRenderbufferFormatEnums.indexOf(colorAttachments[i].renderbuffer._renderbuffer.format) >= 0), 'framebuffer color attachment ' + i + ' is invalid'); if (colorAttachments[i] && colorAttachments[i].texture) { var colorAttachmentSize = textureFormatChannels[colorAttachments[i].texture._texture.format] * textureTypeSizes[colorAttachments[i].texture._texture.type]; if (commonColorAttachmentSize === null) { commonColorAttachmentSize = colorAttachmentSize; } else { // We need to make sure that all color attachments have the same number of bitplanes // (that is, the same numer of bits per pixel) // This is required by the GLES2.0 standard. See the beginning of Chapter 4 in that document. check$1(commonColorAttachmentSize === colorAttachmentSize, 'all color attachments much have the same number of bits per pixel.'); } } } incRefAndCheckShape(depthAttachment, width, height); check$1(!depthAttachment || (depthAttachment.texture && depthAttachment.texture._texture.format === GL_DEPTH_COMPONENT$1) || (depthAttachment.renderbuffer && depthAttachment.renderbuffer._renderbuffer.format === GL_DEPTH_COMPONENT16$1), 'invalid depth attachment for framebuffer object'); incRefAndCheckShape(stencilAttachment, width, height); check$1(!stencilAttachment || (stencilAttachment.renderbuffer && stencilAttachment.renderbuffer._renderbuffer.format === GL_STENCIL_INDEX8$1), 'invalid stencil attachment for framebuffer object'); incRefAndCheckShape(depthStencilAttachment, width, height); check$1(!depthStencilAttachment || (depthStencilAttachment.texture && depthStencilAttachment.texture._texture.format === GL_DEPTH_STENCIL$2) || (depthStencilAttachment.renderbuffer && depthStencilAttachment.renderbuffer._renderbuffer.format === GL_DEPTH_STENCIL$2), 'invalid depth-stencil attachment for framebuffer object'); // decrement references decFBORefs(framebuffer); framebuffer.width = width; framebuffer.height = height; framebuffer.colorAttachments = colorAttachments; framebuffer.depthAttachment = depthAttachment; framebuffer.stencilAttachment = stencilAttachment; framebuffer.depthStencilAttachment = depthStencilAttachment; reglFramebuffer.color = colorAttachments.map(unwrapAttachment); reglFramebuffer.depth = unwrapAttachment(depthAttachment); reglFramebuffer.stencil = unwrapAttachment(stencilAttachment); reglFramebuffer.depthStencil = unwrapAttachment(depthStencilAttachment); reglFramebuffer.width = framebuffer.width; reglFramebuffer.height = framebuffer.height; updateFramebuffer(framebuffer); return reglFramebuffer } function resize (w_, h_) { check$1(framebufferState.next !== framebuffer, 'can not resize a framebuffer which is currently in use'); var w = w_ | 0; var h = (h_ | 0) || w; if (w === framebuffer.width && h === framebuffer.height) { return reglFramebuffer } // resize all buffers var colorAttachments = framebuffer.colorAttachments; for (var i = 0; i < colorAttachments.length; ++i) { resizeAttachment(colorAttachments[i], w, h); } resizeAttachment(framebuffer.depthAttachment, w, h); resizeAttachment(framebuffer.stencilAttachment, w, h); resizeAttachment(framebuffer.depthStencilAttachment, w, h); framebuffer.width = reglFramebuffer.width = w; framebuffer.height = reglFramebuffer.height = h; updateFramebuffer(framebuffer); return reglFramebuffer } reglFramebuffer(a0, a1); return extend(reglFramebuffer, { resize: resize, _reglType: 'framebuffer', _framebuffer: framebuffer, destroy: function () { destroy(framebuffer); decFBORefs(framebuffer); }, use: function (block) { framebufferState.setFBO({ framebuffer: reglFramebuffer }, block); } }) } function createCubeFBO (options) { var faces = Array(6); function reglFramebufferCube (a) { var i; check$1(faces.indexOf(framebufferState.next) < 0, 'can not update framebuffer which is currently in use'); var extDrawBuffers = extensions.webgl_draw_buffers; var params = { color: null }; var radius = 0; var colorBuffer = null; var colorFormat = 'rgba'; var colorType = 'uint8'; var colorCount = 1; if (typeof a === 'number') { radius = a | 0; } else if (!a) { radius = 1; } else { check$1.type(a, 'object', 'invalid arguments for framebuffer'); var options = a; if ('shape' in options) { var shape = options.shape; check$1( Array.isArray(shape) && shape.length >= 2, 'invalid shape for framebuffer'); check$1( shape[0] === shape[1], 'cube framebuffer must be square'); radius = shape[0]; } else { if ('radius' in options) { radius = options.radius | 0; } if ('width' in options) { radius = options.width | 0; if ('height' in options) { check$1(options.height === radius, 'must be square'); } } else if ('height' in options) { radius = options.height | 0; } } if ('color' in options || 'colors' in options) { colorBuffer = options.color || options.colors; if (Array.isArray(colorBuffer)) { check$1( colorBuffer.length === 1 || extDrawBuffers, 'multiple render targets not supported'); } } if (!colorBuffer) { if ('colorCount' in options) { colorCount = options.colorCount | 0; check$1(colorCount > 0, 'invalid color buffer count'); } if ('colorType' in options) { check$1.oneOf( options.colorType, colorTypes, 'invalid color type'); colorType = options.colorType; } if ('colorFormat' in options) { colorFormat = options.colorFormat; check$1.oneOf( options.colorFormat, colorTextureFormats, 'invalid color format for texture'); } } if ('depth' in options) { params.depth = options.depth; } if ('stencil' in options) { params.stencil = options.stencil; } if ('depthStencil' in options) { params.depthStencil = options.depthStencil; } } var colorCubes; if (colorBuffer) { if (Array.isArray(colorBuffer)) { colorCubes = []; for (i = 0; i < colorBuffer.length; ++i) { colorCubes[i] = colorBuffer[i]; } } else { colorCubes = [ colorBuffer ]; } } else { colorCubes = Array(colorCount); var cubeMapParams = { radius: radius, format: colorFormat, type: colorType }; for (i = 0; i < colorCount; ++i) { colorCubes[i] = textureState.createCube(cubeMapParams); } } // Check color cubes params.color = Array(colorCubes.length); for (i = 0; i < colorCubes.length; ++i) { var cube = colorCubes[i]; check$1( typeof cube === 'function' && cube._reglType === 'textureCube', 'invalid cube map'); radius = radius || cube.width; check$1( cube.width === radius && cube.height === radius, 'invalid cube map shape'); params.color[i] = { target: GL_TEXTURE_CUBE_MAP_POSITIVE_X$1, data: colorCubes[i] }; } for (i = 0; i < 6; ++i) { for (var j = 0; j < colorCubes.length; ++j) { params.color[j].target = GL_TEXTURE_CUBE_MAP_POSITIVE_X$1 + i; } // reuse depth-stencil attachments across all cube maps if (i > 0) { params.depth = faces[0].depth; params.stencil = faces[0].stencil; params.depthStencil = faces[0].depthStencil; } if (faces[i]) { (faces[i])(params); } else { faces[i] = createFBO(params); } } return extend(reglFramebufferCube, { width: radius, height: radius, color: colorCubes }) } function resize (radius_) { var i; var radius = radius_ | 0; check$1(radius > 0 && radius <= limits.maxCubeMapSize, 'invalid radius for cube fbo'); if (radius === reglFramebufferCube.width) { return reglFramebufferCube } var colors = reglFramebufferCube.color; for (i = 0; i < colors.length; ++i) { colors[i].resize(radius); } for (i = 0; i < 6; ++i) { faces[i].resize(radius); } reglFramebufferCube.width = reglFramebufferCube.height = radius; return reglFramebufferCube } reglFramebufferCube(options); return extend(reglFramebufferCube, { faces: faces, resize: resize, _reglType: 'framebufferCube', destroy: function () { faces.forEach(function (f) { f.destroy(); }); } }) } function restoreFramebuffers () { values(framebufferSet).forEach(function (fb) { fb.framebuffer = gl.createFramebuffer(); updateFramebuffer(fb); }); } return extend(framebufferState, { getFramebuffer: function (object) { if (typeof object === 'function' && object._reglType === 'framebuffer') { var fbo = object._framebuffer; if (fbo instanceof REGLFramebuffer) { return fbo } } return null }, create: createFBO, createCube: createCubeFBO, clear: function () { values(framebufferSet).forEach(destroy); }, restore: restoreFramebuffers }) } var GL_FLOAT$5 = 5126; function AttributeRecord () { this.state = 0; this.x = 0.0; this.y = 0.0; this.z = 0.0; this.w = 0.0; this.buffer = null; this.size = 0; this.normalized = false; this.type = GL_FLOAT$5; this.offset = 0; this.stride = 0; this.divisor = 0; } function wrapAttributeState ( gl, extensions, limits, bufferState, stringStore) { var NUM_ATTRIBUTES = limits.maxAttributes; var attributeBindings = new Array(NUM_ATTRIBUTES); for (var i = 0; i < NUM_ATTRIBUTES; ++i) { attributeBindings[i] = new AttributeRecord(); } return { Record: AttributeRecord, scope: {}, state: attributeBindings } } var GL_FRAGMENT_SHADER = 35632; var GL_VERTEX_SHADER = 35633; var GL_ACTIVE_UNIFORMS = 0x8B86; var GL_ACTIVE_ATTRIBUTES = 0x8B89; function wrapShaderState (gl, stringStore, stats, config) { // =================================================== // glsl compilation and linking // =================================================== var fragShaders = {}; var vertShaders = {}; function ActiveInfo (name, id, location, info) { this.name = name; this.id = id; this.location = location; this.info = info; } function insertActiveInfo (list, info) { for (var i = 0; i < list.length; ++i) { if (list[i].id === info.id) { list[i].location = info.location; return } } list.push(info); } function getShader (type, id, command) { var cache = type === GL_FRAGMENT_SHADER ? fragShaders : vertShaders; var shader = cache[id]; if (!shader) { var source = stringStore.str(id); shader = gl.createShader(type); gl.shaderSource(shader, source); gl.compileShader(shader); check$1.shaderError(gl, shader, source, type, command); cache[id] = shader; } return shader } // =================================================== // program linking // =================================================== var programCache = {}; var programList = []; var PROGRAM_COUNTER = 0; function REGLProgram (fragId, vertId) { this.id = PROGRAM_COUNTER++; this.fragId = fragId; this.vertId = vertId; this.program = null; this.uniforms = []; this.attributes = []; if (config.profile) { this.stats = { uniformsCount: 0, attributesCount: 0 }; } } function linkProgram (desc, command) { var i, info; // ------------------------------- // compile & link // ------------------------------- var fragShader = getShader(GL_FRAGMENT_SHADER, desc.fragId); var vertShader = getShader(GL_VERTEX_SHADER, desc.vertId); var program = desc.program = gl.createProgram(); gl.attachShader(program, fragShader); gl.attachShader(program, vertShader); gl.linkProgram(program); check$1.linkError( gl, program, stringStore.str(desc.fragId), stringStore.str(desc.vertId), command); // ------------------------------- // grab uniforms // ------------------------------- var numUniforms = gl.getProgramParameter(program, GL_ACTIVE_UNIFORMS); if (config.profile) { desc.stats.uniformsCount = numUniforms; } var uniforms = desc.uniforms; for (i = 0; i < numUniforms; ++i) { info = gl.getActiveUniform(program, i); if (info) { if (info.size > 1) { for (var j = 0; j < info.size; ++j) { var name = info.name.replace('[0]', '[' + j + ']'); insertActiveInfo(uniforms, new ActiveInfo( name, stringStore.id(name), gl.getUniformLocation(program, name), info)); } } else { insertActiveInfo(uniforms, new ActiveInfo( info.name, stringStore.id(info.name), gl.getUniformLocation(program, info.name), info)); } } } // ------------------------------- // grab attributes // ------------------------------- var numAttributes = gl.getProgramParameter(program, GL_ACTIVE_ATTRIBUTES); if (config.profile) { desc.stats.attributesCount = numAttributes; } var attributes = desc.attributes; for (i = 0; i < numAttributes; ++i) { info = gl.getActiveAttrib(program, i); if (info) { insertActiveInfo(attributes, new ActiveInfo( info.name, stringStore.id(info.name), gl.getAttribLocation(program, info.name), info)); } } } if (config.profile) { stats.getMaxUniformsCount = function () { var m = 0; programList.forEach(function (desc) { if (desc.stats.uniformsCount > m) { m = desc.stats.uniformsCount; } }); return m }; stats.getMaxAttributesCount = function () { var m = 0; programList.forEach(function (desc) { if (desc.stats.attributesCount > m) { m = desc.stats.attributesCount; } }); return m }; } function restoreShaders () { fragShaders = {}; vertShaders = {}; for (var i = 0; i < programList.length; ++i) { linkProgram(programList[i]); } } return { clear: function () { var deleteShader = gl.deleteShader.bind(gl); values(fragShaders).forEach(deleteShader); fragShaders = {}; values(vertShaders).forEach(deleteShader); vertShaders = {}; programList.forEach(function (desc) { gl.deleteProgram(desc.program); }); programList.length = 0; programCache = {}; stats.shaderCount = 0; }, program: function (vertId, fragId, command) { check$1.command(vertId >= 0, 'missing vertex shader', command); check$1.command(fragId >= 0, 'missing fragment shader', command); var cache = programCache[fragId]; if (!cache) { cache = programCache[fragId] = {}; } var program = cache[vertId]; if (!program) { program = new REGLProgram(fragId, vertId); stats.shaderCount++; linkProgram(program, command); cache[vertId] = program; programList.push(program); } return program }, restore: restoreShaders, shader: getShader, frag: -1, vert: -1 } } var GL_RGBA$2 = 6408; var GL_UNSIGNED_BYTE$6 = 5121; var GL_PACK_ALIGNMENT = 0x0D05; var GL_FLOAT$6 = 0x1406; // 5126 function wrapReadPixels ( gl, framebufferState, reglPoll, context, glAttributes, extensions) { function readPixelsImpl (input) { var type; if (framebufferState.next === null) { check$1( glAttributes.preserveDrawingBuffer, 'you must create a webgl context with "preserveDrawingBuffer":true in order to read pixels from the drawing buffer'); type = GL_UNSIGNED_BYTE$6; } else { check$1( framebufferState.next.colorAttachments[0].texture !== null, 'You cannot read from a renderbuffer'); type = framebufferState.next.colorAttachments[0].texture._texture.type; if (extensions.oes_texture_float) { check$1( type === GL_UNSIGNED_BYTE$6 || type === GL_FLOAT$6, 'Reading from a framebuffer is only allowed for the types \'uint8\' and \'float\''); } else { check$1( type === GL_UNSIGNED_BYTE$6, 'Reading from a framebuffer is only allowed for the type \'uint8\''); } } var x = 0; var y = 0; var width = context.framebufferWidth; var height = context.framebufferHeight; var data = null; if (isTypedArray(input)) { data = input; } else if (input) { check$1.type(input, 'object', 'invalid arguments to regl.read()'); x = input.x | 0; y = input.y | 0; check$1( x >= 0 && x < context.framebufferWidth, 'invalid x offset for regl.read'); check$1( y >= 0 && y < context.framebufferHeight, 'invalid y offset for regl.read'); width = (input.width || (context.framebufferWidth - x)) | 0; height = (input.height || (context.framebufferHeight - y)) | 0; data = input.data || null; } // sanity check input.data if (data) { if (type === GL_UNSIGNED_BYTE$6) { check$1( data instanceof Uint8Array, 'buffer must be \'Uint8Array\' when reading from a framebuffer of type \'uint8\''); } else if (type === GL_FLOAT$6) { check$1( data instanceof Float32Array, 'buffer must be \'Float32Array\' when reading from a framebuffer of type \'float\''); } } check$1( width > 0 && width + x <= context.framebufferWidth, 'invalid width for read pixels'); check$1( height > 0 && height + y <= context.framebufferHeight, 'invalid height for read pixels'); // Update WebGL state reglPoll(); // Compute size var size = width * height * 4; // Allocate data if (!data) { if (type === GL_UNSIGNED_BYTE$6) { data = new Uint8Array(size); } else if (type === GL_FLOAT$6) { data = data || new Float32Array(size); } } // Type check check$1.isTypedArray(data, 'data buffer for regl.read() must be a typedarray'); check$1(data.byteLength >= size, 'data buffer for regl.read() too small'); // Run read pixels gl.pixelStorei(GL_PACK_ALIGNMENT, 4); gl.readPixels(x, y, width, height, GL_RGBA$2, type, data); return data } function readPixelsFBO (options) { var result; framebufferState.setFBO({ framebuffer: options.framebuffer }, function () { result = readPixelsImpl(options); }); return result } function readPixels (options) { if (!options || !('framebuffer' in options)) { return readPixelsImpl(options) } else { return readPixelsFBO(options) } } return readPixels } function slice (x) { return Array.prototype.slice.call(x) } function join (x) { return slice(x).join('') } function createEnvironment () { // Unique variable id counter var varCounter = 0; // Linked values are passed from this scope into the generated code block // Calling link() passes a value into the generated scope and returns // the variable name which it is bound to var linkedNames = []; var linkedValues = []; function link (value) { for (var i = 0; i < linkedValues.length; ++i) { if (linkedValues[i] === value) { return linkedNames[i] } } var name = 'g' + (varCounter++); linkedNames.push(name); linkedValues.push(value); return name } // create a code block function block () { var code = []; function push () { code.push.apply(code, slice(arguments)); } var vars = []; function def () { var name = 'v' + (varCounter++); vars.push(name); if (arguments.length > 0) { code.push(name, '='); code.push.apply(code, slice(arguments)); code.push(';'); } return name } return extend(push, { def: def, toString: function () { return join([ (vars.length > 0 ? 'var ' + vars + ';' : ''), join(code) ]) } }) } function scope () { var entry = block(); var exit = block(); var entryToString = entry.toString; var exitToString = exit.toString; function save (object, prop) { exit(object, prop, '=', entry.def(object, prop), ';'); } return extend(function () { entry.apply(entry, slice(arguments)); }, { def: entry.def, entry: entry, exit: exit, save: save, set: function (object, prop, value) { save(object, prop); entry(object, prop, '=', value, ';'); }, toString: function () { return entryToString() + exitToString() } }) } function conditional () { var pred = join(arguments); var thenBlock = scope(); var elseBlock = scope(); var thenToString = thenBlock.toString; var elseToString = elseBlock.toString; return extend(thenBlock, { then: function () { thenBlock.apply(thenBlock, slice(arguments)); return this }, else: function () { elseBlock.apply(elseBlock, slice(arguments)); return this }, toString: function () { var elseClause = elseToString(); if (elseClause) { elseClause = 'else{' + elseClause + '}'; } return join([ 'if(', pred, '){', thenToString(), '}', elseClause ]) } }) } // procedure list var globalBlock = block(); var procedures = {}; function proc (name, count) { var args = []; function arg () { var name = 'a' + args.length; args.push(name); return name } count = count || 0; for (var i = 0; i < count; ++i) { arg(); } var body = scope(); var bodyToString = body.toString; var result = procedures[name] = extend(body, { arg: arg, toString: function () { return join([ 'function(', args.join(), '){', bodyToString(), '}' ]) } }); return result } function compile () { var code = ['"use strict";', globalBlock, 'return {']; Object.keys(procedures).forEach(function (name) { code.push('"', name, '":', procedures[name].toString(), ','); }); code.push('}'); var src = join(code) .replace(/;/g, ';\n') .replace(/}/g, '}\n') .replace(/{/g, '{\n'); var proc = Function.apply(null, linkedNames.concat(src)); return proc.apply(null, linkedValues) } return { global: globalBlock, link: link, block: block, proc: proc, scope: scope, cond: conditional, compile: compile } } // "cute" names for vector components var CUTE_COMPONENTS = 'xyzw'.split(''); var GL_UNSIGNED_BYTE$7 = 5121; var ATTRIB_STATE_POINTER = 1; var ATTRIB_STATE_CONSTANT = 2; var DYN_FUNC$1 = 0; var DYN_PROP$1 = 1; var DYN_CONTEXT$1 = 2; var DYN_STATE$1 = 3; var DYN_THUNK = 4; var S_DITHER = 'dither'; var S_BLEND_ENABLE = 'blend.enable'; var S_BLEND_COLOR = 'blend.color'; var S_BLEND_EQUATION = 'blend.equation'; var S_BLEND_FUNC = 'blend.func'; var S_DEPTH_ENABLE = 'depth.enable'; var S_DEPTH_FUNC = 'depth.func'; var S_DEPTH_RANGE = 'depth.range'; var S_DEPTH_MASK = 'depth.mask'; var S_COLOR_MASK = 'colorMask'; var S_CULL_ENABLE = 'cull.enable'; var S_CULL_FACE = 'cull.face'; var S_FRONT_FACE = 'frontFace'; var S_LINE_WIDTH = 'lineWidth'; var S_POLYGON_OFFSET_ENABLE = 'polygonOffset.enable'; var S_POLYGON_OFFSET_OFFSET = 'polygonOffset.offset'; var S_SAMPLE_ALPHA = 'sample.alpha'; var S_SAMPLE_ENABLE = 'sample.enable'; var S_SAMPLE_COVERAGE = 'sample.coverage'; var S_STENCIL_ENABLE = 'stencil.enable'; var S_STENCIL_MASK = 'stencil.mask'; var S_STENCIL_FUNC = 'stencil.func'; var S_STENCIL_OPFRONT = 'stencil.opFront'; var S_STENCIL_OPBACK = 'stencil.opBack'; var S_SCISSOR_ENABLE = 'scissor.enable'; var S_SCISSOR_BOX = 'scissor.box'; var S_VIEWPORT = 'viewport'; var S_PROFILE = 'profile'; var S_FRAMEBUFFER = 'framebuffer'; var S_VERT = 'vert'; var S_FRAG = 'frag'; var S_ELEMENTS = 'elements'; var S_PRIMITIVE = 'primitive'; var S_COUNT = 'count'; var S_OFFSET = 'offset'; var S_INSTANCES = 'instances'; var SUFFIX_WIDTH = 'Width'; var SUFFIX_HEIGHT = 'Height'; var S_FRAMEBUFFER_WIDTH = S_FRAMEBUFFER + SUFFIX_WIDTH; var S_FRAMEBUFFER_HEIGHT = S_FRAMEBUFFER + SUFFIX_HEIGHT; var S_VIEWPORT_WIDTH = S_VIEWPORT + SUFFIX_WIDTH; var S_VIEWPORT_HEIGHT = S_VIEWPORT + SUFFIX_HEIGHT; var S_DRAWINGBUFFER = 'drawingBuffer'; var S_DRAWINGBUFFER_WIDTH = S_DRAWINGBUFFER + SUFFIX_WIDTH; var S_DRAWINGBUFFER_HEIGHT = S_DRAWINGBUFFER + SUFFIX_HEIGHT; var NESTED_OPTIONS = [ S_BLEND_FUNC, S_BLEND_EQUATION, S_STENCIL_FUNC, S_STENCIL_OPFRONT, S_STENCIL_OPBACK, S_SAMPLE_COVERAGE, S_VIEWPORT, S_SCISSOR_BOX, S_POLYGON_OFFSET_OFFSET ]; var GL_ARRAY_BUFFER$1 = 34962; var GL_ELEMENT_ARRAY_BUFFER$1 = 34963; var GL_FRAGMENT_SHADER$1 = 35632; var GL_VERTEX_SHADER$1 = 35633; var GL_TEXTURE_2D$2 = 0x0DE1; var GL_TEXTURE_CUBE_MAP$1 = 0x8513; var GL_CULL_FACE = 0x0B44; var GL_BLEND = 0x0BE2; var GL_DITHER = 0x0BD0; var GL_STENCIL_TEST = 0x0B90; var GL_DEPTH_TEST = 0x0B71; var GL_SCISSOR_TEST = 0x0C11; var GL_POLYGON_OFFSET_FILL = 0x8037; var GL_SAMPLE_ALPHA_TO_COVERAGE = 0x809E; var GL_SAMPLE_COVERAGE = 0x80A0; var GL_FLOAT$7 = 5126; var GL_FLOAT_VEC2 = 35664; var GL_FLOAT_VEC3 = 35665; var GL_FLOAT_VEC4 = 35666; var GL_INT$3 = 5124; var GL_INT_VEC2 = 35667; var GL_INT_VEC3 = 35668; var GL_INT_VEC4 = 35669; var GL_BOOL = 35670; var GL_BOOL_VEC2 = 35671; var GL_BOOL_VEC3 = 35672; var GL_BOOL_VEC4 = 35673; var GL_FLOAT_MAT2 = 35674; var GL_FLOAT_MAT3 = 35675; var GL_FLOAT_MAT4 = 35676; var GL_SAMPLER_2D = 35678; var GL_SAMPLER_CUBE = 35680; var GL_TRIANGLES$1 = 4; var GL_FRONT = 1028; var GL_BACK = 1029; var GL_CW = 0x0900; var GL_CCW = 0x0901; var GL_MIN_EXT = 0x8007; var GL_MAX_EXT = 0x8008; var GL_ALWAYS = 519; var GL_KEEP = 7680; var GL_ZERO = 0; var GL_ONE = 1; var GL_FUNC_ADD = 0x8006; var GL_LESS = 513; var GL_FRAMEBUFFER$1 = 0x8D40; var GL_COLOR_ATTACHMENT0$1 = 0x8CE0; var blendFuncs = { '0': 0, '1': 1, 'zero': 0, 'one': 1, 'src color': 768, 'one minus src color': 769, 'src alpha': 770, 'one minus src alpha': 771, 'dst color': 774, 'one minus dst color': 775, 'dst alpha': 772, 'one minus dst alpha': 773, 'constant color': 32769, 'one minus constant color': 32770, 'constant alpha': 32771, 'one minus constant alpha': 32772, 'src alpha saturate': 776 }; // There are invalid values for srcRGB and dstRGB. See: // https://www.khronos.org/registry/webgl/specs/1.0/#6.13 // https://github.com/KhronosGroup/WebGL/blob/0d3201f5f7ec3c0060bc1f04077461541f1987b9/conformance-suites/1.0.3/conformance/misc/webgl-specific.html#L56 var invalidBlendCombinations = [ 'constant color, constant alpha', 'one minus constant color, constant alpha', 'constant color, one minus constant alpha', 'one minus constant color, one minus constant alpha', 'constant alpha, constant color', 'constant alpha, one minus constant color', 'one minus constant alpha, constant color', 'one minus constant alpha, one minus constant color' ]; var compareFuncs = { 'never': 512, 'less': 513, '<': 513, 'equal': 514, '=': 514, '==': 514, '===': 514, 'lequal': 515, '<=': 515, 'greater': 516, '>': 516, 'notequal': 517, '!=': 517, '!==': 517, 'gequal': 518, '>=': 518, 'always': 519 }; var stencilOps = { '0': 0, 'zero': 0, 'keep': 7680, 'replace': 7681, 'increment': 7682, 'decrement': 7683, 'increment wrap': 34055, 'decrement wrap': 34056, 'invert': 5386 }; var shaderType = { 'frag': GL_FRAGMENT_SHADER$1, 'vert': GL_VERTEX_SHADER$1 }; var orientationType = { 'cw': GL_CW, 'ccw': GL_CCW }; function isBufferArgs (x) { return Array.isArray(x) || isTypedArray(x) || isNDArrayLike(x) } // Make sure viewport is processed first function sortState (state) { return state.sort(function (a, b) { if (a === S_VIEWPORT) { return -1 } else if (b === S_VIEWPORT) { return 1 } return (a < b) ? -1 : 1 }) } function Declaration (thisDep, contextDep, propDep, append) { this.thisDep = thisDep; this.contextDep = contextDep; this.propDep = propDep; this.append = append; } function isStatic (decl) { return decl && !(decl.thisDep || decl.contextDep || decl.propDep) } function createStaticDecl (append) { return new Declaration(false, false, false, append) } function createDynamicDecl (dyn, append) { var type = dyn.type; if (type === DYN_FUNC$1) { var numArgs = dyn.data.length; return new Declaration( true, numArgs >= 1, numArgs >= 2, append) } else if (type === DYN_THUNK) { var data = dyn.data; return new Declaration( data.thisDep, data.contextDep, data.propDep, append) } else { return new Declaration( type === DYN_STATE$1, type === DYN_CONTEXT$1, type === DYN_PROP$1, append) } } var SCOPE_DECL = new Declaration(false, false, false, function () {}); function reglCore ( gl, stringStore, extensions, limits, bufferState, elementState, textureState, framebufferState, uniformState, attributeState, shaderState, drawState, contextState, timer, config) { var AttributeRecord = attributeState.Record; var blendEquations = { 'add': 32774, 'subtract': 32778, 'reverse subtract': 32779 }; if (extensions.ext_blend_minmax) { blendEquations.min = GL_MIN_EXT; blendEquations.max = GL_MAX_EXT; } var extInstancing = extensions.angle_instanced_arrays; var extDrawBuffers = extensions.webgl_draw_buffers; // =================================================== // =================================================== // WEBGL STATE // =================================================== // =================================================== var currentState = { dirty: true, profile: config.profile }; var nextState = {}; var GL_STATE_NAMES = []; var GL_FLAGS = {}; var GL_VARIABLES = {}; function propName (name) { return name.replace('.', '_') } function stateFlag (sname, cap, init) { var name = propName(sname); GL_STATE_NAMES.push(sname); nextState[name] = currentState[name] = !!init; GL_FLAGS[name] = cap; } function stateVariable (sname, func, init) { var name = propName(sname); GL_STATE_NAMES.push(sname); if (Array.isArray(init)) { currentState[name] = init.slice(); nextState[name] = init.slice(); } else { currentState[name] = nextState[name] = init; } GL_VARIABLES[name] = func; } // Dithering stateFlag(S_DITHER, GL_DITHER); // Blending stateFlag(S_BLEND_ENABLE, GL_BLEND); stateVariable(S_BLEND_COLOR, 'blendColor', [0, 0, 0, 0]); stateVariable(S_BLEND_EQUATION, 'blendEquationSeparate', [GL_FUNC_ADD, GL_FUNC_ADD]); stateVariable(S_BLEND_FUNC, 'blendFuncSeparate', [GL_ONE, GL_ZERO, GL_ONE, GL_ZERO]); // Depth stateFlag(S_DEPTH_ENABLE, GL_DEPTH_TEST, true); stateVariable(S_DEPTH_FUNC, 'depthFunc', GL_LESS); stateVariable(S_DEPTH_RANGE, 'depthRange', [0, 1]); stateVariable(S_DEPTH_MASK, 'depthMask', true); // Color mask stateVariable(S_COLOR_MASK, S_COLOR_MASK, [true, true, true, true]); // Face culling stateFlag(S_CULL_ENABLE, GL_CULL_FACE); stateVariable(S_CULL_FACE, 'cullFace', GL_BACK); // Front face orientation stateVariable(S_FRONT_FACE, S_FRONT_FACE, GL_CCW); // Line width stateVariable(S_LINE_WIDTH, S_LINE_WIDTH, 1); // Polygon offset stateFlag(S_POLYGON_OFFSET_ENABLE, GL_POLYGON_OFFSET_FILL); stateVariable(S_POLYGON_OFFSET_OFFSET, 'polygonOffset', [0, 0]); // Sample coverage stateFlag(S_SAMPLE_ALPHA, GL_SAMPLE_ALPHA_TO_COVERAGE); stateFlag(S_SAMPLE_ENABLE, GL_SAMPLE_COVERAGE); stateVariable(S_SAMPLE_COVERAGE, 'sampleCoverage', [1, false]); // Stencil stateFlag(S_STENCIL_ENABLE, GL_STENCIL_TEST); stateVariable(S_STENCIL_MASK, 'stencilMask', -1); stateVariable(S_STENCIL_FUNC, 'stencilFunc', [GL_ALWAYS, 0, -1]); stateVariable(S_STENCIL_OPFRONT, 'stencilOpSeparate', [GL_FRONT, GL_KEEP, GL_KEEP, GL_KEEP]); stateVariable(S_STENCIL_OPBACK, 'stencilOpSeparate', [GL_BACK, GL_KEEP, GL_KEEP, GL_KEEP]); // Scissor stateFlag(S_SCISSOR_ENABLE, GL_SCISSOR_TEST); stateVariable(S_SCISSOR_BOX, 'scissor', [0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight]); // Viewport stateVariable(S_VIEWPORT, S_VIEWPORT, [0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight]); // =================================================== // =================================================== // ENVIRONMENT // =================================================== // =================================================== var sharedState = { gl: gl, context: contextState, strings: stringStore, next: nextState, current: currentState, draw: drawState, elements: elementState, buffer: bufferState, shader: shaderState, attributes: attributeState.state, uniforms: uniformState, framebuffer: framebufferState, extensions: extensions, timer: timer, isBufferArgs: isBufferArgs }; var sharedConstants = { primTypes: primTypes, compareFuncs: compareFuncs, blendFuncs: blendFuncs, blendEquations: blendEquations, stencilOps: stencilOps, glTypes: glTypes, orientationType: orientationType }; check$1.optional(function () { sharedState.isArrayLike = isArrayLike; }); if (extDrawBuffers) { sharedConstants.backBuffer = [GL_BACK]; sharedConstants.drawBuffer = loop(limits.maxDrawbuffers, function (i) { if (i === 0) { return [0] } return loop(i, function (j) { return GL_COLOR_ATTACHMENT0$1 + j }) }); } var drawCallCounter = 0; function createREGLEnvironment () { var env = createEnvironment(); var link = env.link; var global = env.global; env.id = drawCallCounter++; env.batchId = '0'; // link shared state var SHARED = link(sharedState); var shared = env.shared = { props: 'a0' }; Object.keys(sharedState).forEach(function (prop) { shared[prop] = global.def(SHARED, '.', prop); }); // Inject runtime assertion stuff for debug builds check$1.optional(function () { env.CHECK = link(check$1); env.commandStr = check$1.guessCommand(); env.command = link(env.commandStr); env.assert = function (block, pred, message) { block( 'if(!(', pred, '))', this.CHECK, '.commandRaise(', link(message), ',', this.command, ');'); }; sharedConstants.invalidBlendCombinations = invalidBlendCombinations; }); // Copy GL state variables over var nextVars = env.next = {}; var currentVars = env.current = {}; Object.keys(GL_VARIABLES).forEach(function (variable) { if (Array.isArray(currentState[variable])) { nextVars[variable] = global.def(shared.next, '.', variable); currentVars[variable] = global.def(shared.current, '.', variable); } }); // Initialize shared constants var constants = env.constants = {}; Object.keys(sharedConstants).forEach(function (name) { constants[name] = global.def(JSON.stringify(sharedConstants[name])); }); // Helper function for calling a block env.invoke = function (block, x) { switch (x.type) { case DYN_FUNC$1: var argList = [ 'this', shared.context, shared.props, env.batchId ]; return block.def( link(x.data), '.call(', argList.slice(0, Math.max(x.data.length + 1, 4)), ')') case DYN_PROP$1: return block.def(shared.props, x.data) case DYN_CONTEXT$1: return block.def(shared.context, x.data) case DYN_STATE$1: return block.def('this', x.data) case DYN_THUNK: x.data.append(env, block); return x.data.ref } }; env.attribCache = {}; var scopeAttribs = {}; env.scopeAttrib = function (name) { var id = stringStore.id(name); if (id in scopeAttribs) { return scopeAttribs[id] } var binding = attributeState.scope[id]; if (!binding) { binding = attributeState.scope[id] = new AttributeRecord(); } var result = scopeAttribs[id] = link(binding); return result }; return env } // =================================================== // =================================================== // PARSING // =================================================== // =================================================== function parseProfile (options) { var staticOptions = options.static; var dynamicOptions = options.dynamic; var profileEnable; if (S_PROFILE in staticOptions) { var value = !!staticOptions[S_PROFILE]; profileEnable = createStaticDecl(function (env, scope) { return value }); profileEnable.enable = value; } else if (S_PROFILE in dynamicOptions) { var dyn = dynamicOptions[S_PROFILE]; profileEnable = createDynamicDecl(dyn, function (env, scope) { return env.invoke(scope, dyn) }); } return profileEnable } function parseFramebuffer (options, env) { var staticOptions = options.static; var dynamicOptions = options.dynamic; if (S_FRAMEBUFFER in staticOptions) { var framebuffer = staticOptions[S_FRAMEBUFFER]; if (framebuffer) { framebuffer = framebufferState.getFramebuffer(framebuffer); check$1.command(framebuffer, 'invalid framebuffer object'); return createStaticDecl(function (env, block) { var FRAMEBUFFER = env.link(framebuffer); var shared = env.shared; block.set( shared.framebuffer, '.next', FRAMEBUFFER); var CONTEXT = shared.context; block.set( CONTEXT, '.' + S_FRAMEBUFFER_WIDTH, FRAMEBUFFER + '.width'); block.set( CONTEXT, '.' + S_FRAMEBUFFER_HEIGHT, FRAMEBUFFER + '.height'); return FRAMEBUFFER }) } else { return createStaticDecl(function (env, scope) { var shared = env.shared; scope.set( shared.framebuffer, '.next', 'null'); var CONTEXT = shared.context; scope.set( CONTEXT, '.' + S_FRAMEBUFFER_WIDTH, CONTEXT + '.' + S_DRAWINGBUFFER_WIDTH); scope.set( CONTEXT, '.' + S_FRAMEBUFFER_HEIGHT, CONTEXT + '.' + S_DRAWINGBUFFER_HEIGHT); return 'null' }) } } else if (S_FRAMEBUFFER in dynamicOptions) { var dyn = dynamicOptions[S_FRAMEBUFFER]; return createDynamicDecl(dyn, function (env, scope) { var FRAMEBUFFER_FUNC = env.invoke(scope, dyn); var shared = env.shared; var FRAMEBUFFER_STATE = shared.framebuffer; var FRAMEBUFFER = scope.def( FRAMEBUFFER_STATE, '.getFramebuffer(', FRAMEBUFFER_FUNC, ')'); check$1.optional(function () { env.assert(scope, '!' + FRAMEBUFFER_FUNC + '||' + FRAMEBUFFER, 'invalid framebuffer object'); }); scope.set( FRAMEBUFFER_STATE, '.next', FRAMEBUFFER); var CONTEXT = shared.context; scope.set( CONTEXT, '.' + S_FRAMEBUFFER_WIDTH, FRAMEBUFFER + '?' + FRAMEBUFFER + '.width:' + CONTEXT + '.' + S_DRAWINGBUFFER_WIDTH); scope.set( CONTEXT, '.' + S_FRAMEBUFFER_HEIGHT, FRAMEBUFFER + '?' + FRAMEBUFFER + '.height:' + CONTEXT + '.' + S_DRAWINGBUFFER_HEIGHT); return FRAMEBUFFER }) } else { return null } } function parseViewportScissor (options, framebuffer, env) { var staticOptions = options.static; var dynamicOptions = options.dynamic; function parseBox (param) { if (param in staticOptions) { var box = staticOptions[param]; check$1.commandType(box, 'object', 'invalid ' + param, env.commandStr); var isStatic = true; var x = box.x | 0; var y = box.y | 0; var w, h; if ('width' in box) { w = box.width | 0; check$1.command(w >= 0, 'invalid ' + param, env.commandStr); } else { isStatic = false; } if ('height' in box) { h = box.height | 0; check$1.command(h >= 0, 'invalid ' + param, env.commandStr); } else { isStatic = false; } return new Declaration( !isStatic && framebuffer && framebuffer.thisDep, !isStatic && framebuffer && framebuffer.contextDep, !isStatic && framebuffer && framebuffer.propDep, function (env, scope) { var CONTEXT = env.shared.context; var BOX_W = w; if (!('width' in box)) { BOX_W = scope.def(CONTEXT, '.', S_FRAMEBUFFER_WIDTH, '-', x); } var BOX_H = h; if (!('height' in box)) { BOX_H = scope.def(CONTEXT, '.', S_FRAMEBUFFER_HEIGHT, '-', y); } return [x, y, BOX_W, BOX_H] }) } else if (param in dynamicOptions) { var dynBox = dynamicOptions[param]; var result = createDynamicDecl(dynBox, function (env, scope) { var BOX = env.invoke(scope, dynBox); check$1.optional(function () { env.assert(scope, BOX + '&&typeof ' + BOX + '==="object"', 'invalid ' + param); }); var CONTEXT = env.shared.context; var BOX_X = scope.def(BOX, '.x|0'); var BOX_Y = scope.def(BOX, '.y|0'); var BOX_W = scope.def( '"width" in ', BOX, '?', BOX, '.width|0:', '(', CONTEXT, '.', S_FRAMEBUFFER_WIDTH, '-', BOX_X, ')'); var BOX_H = scope.def( '"height" in ', BOX, '?', BOX, '.height|0:', '(', CONTEXT, '.', S_FRAMEBUFFER_HEIGHT, '-', BOX_Y, ')'); check$1.optional(function () { env.assert(scope, BOX_W + '>=0&&' + BOX_H + '>=0', 'invalid ' + param); }); return [BOX_X, BOX_Y, BOX_W, BOX_H] }); if (framebuffer) { result.thisDep = result.thisDep || framebuffer.thisDep; result.contextDep = result.contextDep || framebuffer.contextDep; result.propDep = result.propDep || framebuffer.propDep; } return result } else if (framebuffer) { return new Declaration( framebuffer.thisDep, framebuffer.contextDep, framebuffer.propDep, function (env, scope) { var CONTEXT = env.shared.context; return [ 0, 0, scope.def(CONTEXT, '.', S_FRAMEBUFFER_WIDTH), scope.def(CONTEXT, '.', S_FRAMEBUFFER_HEIGHT)] }) } else { return null } } var viewport = parseBox(S_VIEWPORT); if (viewport) { var prevViewport = viewport; viewport = new Declaration( viewport.thisDep, viewport.contextDep, viewport.propDep, function (env, scope) { var VIEWPORT = prevViewport.append(env, scope); var CONTEXT = env.shared.context; scope.set( CONTEXT, '.' + S_VIEWPORT_WIDTH, VIEWPORT[2]); scope.set( CONTEXT, '.' + S_VIEWPORT_HEIGHT, VIEWPORT[3]); return VIEWPORT }); } return { viewport: viewport, scissor_box: parseBox(S_SCISSOR_BOX) } } function parseProgram (options) { var staticOptions = options.static; var dynamicOptions = options.dynamic; function parseShader (name) { if (name in staticOptions) { var id = stringStore.id(staticOptions[name]); check$1.optional(function () { shaderState.shader(shaderType[name], id, check$1.guessCommand()); }); var result = createStaticDecl(function () { return id }); result.id = id; return result } else if (name in dynamicOptions) { var dyn = dynamicOptions[name]; return createDynamicDecl(dyn, function (env, scope) { var str = env.invoke(scope, dyn); var id = scope.def(env.shared.strings, '.id(', str, ')'); check$1.optional(function () { scope( env.shared.shader, '.shader(', shaderType[name], ',', id, ',', env.command, ');'); }); return id }) } return null } var frag = parseShader(S_FRAG); var vert = parseShader(S_VERT); var program = null; var progVar; if (isStatic(frag) && isStatic(vert)) { program = shaderState.program(vert.id, frag.id); progVar = createStaticDecl(function (env, scope) { return env.link(program) }); } else { progVar = new Declaration( (frag && frag.thisDep) || (vert && vert.thisDep), (frag && frag.contextDep) || (vert && vert.contextDep), (frag && frag.propDep) || (vert && vert.propDep), function (env, scope) { var SHADER_STATE = env.shared.shader; var fragId; if (frag) { fragId = frag.append(env, scope); } else { fragId = scope.def(SHADER_STATE, '.', S_FRAG); } var vertId; if (vert) { vertId = vert.append(env, scope); } else { vertId = scope.def(SHADER_STATE, '.', S_VERT); } var progDef = SHADER_STATE + '.program(' + vertId + ',' + fragId; check$1.optional(function () { progDef += ',' + env.command; }); return scope.def(progDef + ')') }); } return { frag: frag, vert: vert, progVar: progVar, program: program } } function parseDraw (options, env) { var staticOptions = options.static; var dynamicOptions = options.dynamic; function parseElements () { if (S_ELEMENTS in staticOptions) { var elements = staticOptions[S_ELEMENTS]; if (isBufferArgs(elements)) { elements = elementState.getElements(elementState.create(elements, true)); } else if (elements) { elements = elementState.getElements(elements); check$1.command(elements, 'invalid elements', env.commandStr); } var result = createStaticDecl(function (env, scope) { if (elements) { var result = env.link(elements); env.ELEMENTS = result; return result } env.ELEMENTS = null; return null }); result.value = elements; return result } else if (S_ELEMENTS in dynamicOptions) { var dyn = dynamicOptions[S_ELEMENTS]; return createDynamicDecl(dyn, function (env, scope) { var shared = env.shared; var IS_BUFFER_ARGS = shared.isBufferArgs; var ELEMENT_STATE = shared.elements; var elementDefn = env.invoke(scope, dyn); var elements = scope.def('null'); var elementStream = scope.def(IS_BUFFER_ARGS, '(', elementDefn, ')'); var ifte = env.cond(elementStream) .then(elements, '=', ELEMENT_STATE, '.createStream(', elementDefn, ');') .else(elements, '=', ELEMENT_STATE, '.getElements(', elementDefn, ');'); check$1.optional(function () { env.assert(ifte.else, '!' + elementDefn + '||' + elements, 'invalid elements'); }); scope.entry(ifte); scope.exit( env.cond(elementStream) .then(ELEMENT_STATE, '.destroyStream(', elements, ');')); env.ELEMENTS = elements; return elements }) } return null } var elements = parseElements(); function parsePrimitive () { if (S_PRIMITIVE in staticOptions) { var primitive = staticOptions[S_PRIMITIVE]; check$1.commandParameter(primitive, primTypes, 'invalid primitve', env.commandStr); return createStaticDecl(function (env, scope) { return primTypes[primitive] }) } else if (S_PRIMITIVE in dynamicOptions) { var dynPrimitive = dynamicOptions[S_PRIMITIVE]; return createDynamicDecl(dynPrimitive, function (env, scope) { var PRIM_TYPES = env.constants.primTypes; var prim = env.invoke(scope, dynPrimitive); check$1.optional(function () { env.assert(scope, prim + ' in ' + PRIM_TYPES, 'invalid primitive, must be one of ' + Object.keys(primTypes)); }); return scope.def(PRIM_TYPES, '[', prim, ']') }) } else if (elements) { if (isStatic(elements)) { if (elements.value) { return createStaticDecl(function (env, scope) { return scope.def(env.ELEMENTS, '.primType') }) } else { return createStaticDecl(function () { return GL_TRIANGLES$1 }) } } else { return new Declaration( elements.thisDep, elements.contextDep, elements.propDep, function (env, scope) { var elements = env.ELEMENTS; return scope.def(elements, '?', elements, '.primType:', GL_TRIANGLES$1) }) } } return null } function parseParam (param, isOffset) { if (param in staticOptions) { var value = staticOptions[param] | 0; check$1.command(!isOffset || value >= 0, 'invalid ' + param, env.commandStr); return createStaticDecl(function (env, scope) { if (isOffset) { env.OFFSET = value; } return value }) } else if (param in dynamicOptions) { var dynValue = dynamicOptions[param]; return createDynamicDecl(dynValue, function (env, scope) { var result = env.invoke(scope, dynValue); if (isOffset) { env.OFFSET = result; check$1.optional(function () { env.assert(scope, result + '>=0', 'invalid ' + param); }); } return result }) } else if (isOffset && elements) { return createStaticDecl(function (env, scope) { env.OFFSET = '0'; return 0 }) } return null } var OFFSET = parseParam(S_OFFSET, true); function parseVertCount () { if (S_COUNT in staticOptions) { var count = staticOptions[S_COUNT] | 0; check$1.command( typeof count === 'number' && count >= 0, 'invalid vertex count', env.commandStr); return createStaticDecl(function () { return count }) } else if (S_COUNT in dynamicOptions) { var dynCount = dynamicOptions[S_COUNT]; return createDynamicDecl(dynCount, function (env, scope) { var result = env.invoke(scope, dynCount); check$1.optional(function () { env.assert(scope, 'typeof ' + result + '==="number"&&' + result + '>=0&&' + result + '===(' + result + '|0)', 'invalid vertex count'); }); return result }) } else if (elements) { if (isStatic(elements)) { if (elements) { if (OFFSET) { return new Declaration( OFFSET.thisDep, OFFSET.contextDep, OFFSET.propDep, function (env, scope) { var result = scope.def( env.ELEMENTS, '.vertCount-', env.OFFSET); check$1.optional(function () { env.assert(scope, result + '>=0', 'invalid vertex offset/element buffer too small'); }); return result }) } else { return createStaticDecl(function (env, scope) { return scope.def(env.ELEMENTS, '.vertCount') }) } } else { var result = createStaticDecl(function () { return -1 }); check$1.optional(function () { result.MISSING = true; }); return result } } else { var variable = new Declaration( elements.thisDep || OFFSET.thisDep, elements.contextDep || OFFSET.contextDep, elements.propDep || OFFSET.propDep, function (env, scope) { var elements = env.ELEMENTS; if (env.OFFSET) { return scope.def(elements, '?', elements, '.vertCount-', env.OFFSET, ':-1') } return scope.def(elements, '?', elements, '.vertCount:-1') }); check$1.optional(function () { variable.DYNAMIC = true; }); return variable } } return null } return { elements: elements, primitive: parsePrimitive(), count: parseVertCount(), instances: parseParam(S_INSTANCES, false), offset: OFFSET } } function parseGLState (options, env) { var staticOptions = options.static; var dynamicOptions = options.dynamic; var STATE = {}; GL_STATE_NAMES.forEach(function (prop) { var param = propName(prop); function parseParam (parseStatic, parseDynamic) { if (prop in staticOptions) { var value = parseStatic(staticOptions[prop]); STATE[param] = createStaticDecl(function () { return value }); } else if (prop in dynamicOptions) { var dyn = dynamicOptions[prop]; STATE[param] = createDynamicDecl(dyn, function (env, scope) { return parseDynamic(env, scope, env.invoke(scope, dyn)) }); } } switch (prop) { case S_CULL_ENABLE: case S_BLEND_ENABLE: case S_DITHER: case S_STENCIL_ENABLE: case S_DEPTH_ENABLE: case S_SCISSOR_ENABLE: case S_POLYGON_OFFSET_ENABLE: case S_SAMPLE_ALPHA: case S_SAMPLE_ENABLE: case S_DEPTH_MASK: return parseParam( function (value) { check$1.commandType(value, 'boolean', prop, env.commandStr); return value }, function (env, scope, value) { check$1.optional(function () { env.assert(scope, 'typeof ' + value + '==="boolean"', 'invalid flag ' + prop, env.commandStr); }); return value }) case S_DEPTH_FUNC: return parseParam( function (value) { check$1.commandParameter(value, compareFuncs, 'invalid ' + prop, env.commandStr); return compareFuncs[value] }, function (env, scope, value) { var COMPARE_FUNCS = env.constants.compareFuncs; check$1.optional(function () { env.assert(scope, value + ' in ' + COMPARE_FUNCS, 'invalid ' + prop + ', must be one of ' + Object.keys(compareFuncs)); }); return scope.def(COMPARE_FUNCS, '[', value, ']') }) case S_DEPTH_RANGE: return parseParam( function (value) { check$1.command( isArrayLike(value) && value.length === 2 && typeof value[0] === 'number' && typeof value[1] === 'number' && value[0] <= value[1], 'depth range is 2d array', env.commandStr); return value }, function (env, scope, value) { check$1.optional(function () { env.assert(scope, env.shared.isArrayLike + '(' + value + ')&&' + value + '.length===2&&' + 'typeof ' + value + '[0]==="number"&&' + 'typeof ' + value + '[1]==="number"&&' + value + '[0]<=' + value + '[1]', 'depth range must be a 2d array'); }); var Z_NEAR = scope.def('+', value, '[0]'); var Z_FAR = scope.def('+', value, '[1]'); return [Z_NEAR, Z_FAR] }) case S_BLEND_FUNC: return parseParam( function (value) { check$1.commandType(value, 'object', 'blend.func', env.commandStr); var srcRGB = ('srcRGB' in value ? value.srcRGB : value.src); var srcAlpha = ('srcAlpha' in value ? value.srcAlpha : value.src); var dstRGB = ('dstRGB' in value ? value.dstRGB : value.dst); var dstAlpha = ('dstAlpha' in value ? value.dstAlpha : value.dst); check$1.commandParameter(srcRGB, blendFuncs, param + '.srcRGB', env.commandStr); check$1.commandParameter(srcAlpha, blendFuncs, param + '.srcAlpha', env.commandStr); check$1.commandParameter(dstRGB, blendFuncs, param + '.dstRGB', env.commandStr); check$1.commandParameter(dstAlpha, blendFuncs, param + '.dstAlpha', env.commandStr); check$1.command( (invalidBlendCombinations.indexOf(srcRGB + ', ' + dstRGB) === -1), 'unallowed blending combination (srcRGB, dstRGB) = (' + srcRGB + ', ' + dstRGB + ')', env.commandStr); return [ blendFuncs[srcRGB], blendFuncs[dstRGB], blendFuncs[srcAlpha], blendFuncs[dstAlpha] ] }, function (env, scope, value) { var BLEND_FUNCS = env.constants.blendFuncs; check$1.optional(function () { env.assert(scope, value + '&&typeof ' + value + '==="object"', 'invalid blend func, must be an object'); }); function read (prefix, suffix) { var func = scope.def( '"', prefix, suffix, '" in ', value, '?', value, '.', prefix, suffix, ':', value, '.', prefix); check$1.optional(function () { env.assert(scope, func + ' in ' + BLEND_FUNCS, 'invalid ' + prop + '.' + prefix + suffix + ', must be one of ' + Object.keys(blendFuncs)); }); return func } var srcRGB = read('src', 'RGB'); var dstRGB = read('dst', 'RGB'); check$1.optional(function () { var INVALID_BLEND_COMBINATIONS = env.constants.invalidBlendCombinations; env.assert(scope, INVALID_BLEND_COMBINATIONS + '.indexOf(' + srcRGB + '+", "+' + dstRGB + ') === -1 ', 'unallowed blending combination for (srcRGB, dstRGB)' ); }); var SRC_RGB = scope.def(BLEND_FUNCS, '[', srcRGB, ']'); var SRC_ALPHA = scope.def(BLEND_FUNCS, '[', read('src', 'Alpha'), ']'); var DST_RGB = scope.def(BLEND_FUNCS, '[', dstRGB, ']'); var DST_ALPHA = scope.def(BLEND_FUNCS, '[', read('dst', 'Alpha'), ']'); return [SRC_RGB, DST_RGB, SRC_ALPHA, DST_ALPHA] }) case S_BLEND_EQUATION: return parseParam( function (value) { if (typeof value === 'string') { check$1.commandParameter(value, blendEquations, 'invalid ' + prop, env.commandStr); return [ blendEquations[value], blendEquations[value] ] } else if (typeof value === 'object') { check$1.commandParameter( value.rgb, blendEquations, prop + '.rgb', env.commandStr); check$1.commandParameter( value.alpha, blendEquations, prop + '.alpha', env.commandStr); return [ blendEquations[value.rgb], blendEquations[value.alpha] ] } else { check$1.commandRaise('invalid blend.equation', env.commandStr); } }, function (env, scope, value) { var BLEND_EQUATIONS = env.constants.blendEquations; var RGB = scope.def(); var ALPHA = scope.def(); var ifte = env.cond('typeof ', value, '==="string"'); check$1.optional(function () { function checkProp (block, name, value) { env.assert(block, value + ' in ' + BLEND_EQUATIONS, 'invalid ' + name + ', must be one of ' + Object.keys(blendEquations)); } checkProp(ifte.then, prop, value); env.assert(ifte.else, value + '&&typeof ' + value + '==="object"', 'invalid ' + prop); checkProp(ifte.else, prop + '.rgb', value + '.rgb'); checkProp(ifte.else, prop + '.alpha', value + '.alpha'); }); ifte.then( RGB, '=', ALPHA, '=', BLEND_EQUATIONS, '[', value, '];'); ifte.else( RGB, '=', BLEND_EQUATIONS, '[', value, '.rgb];', ALPHA, '=', BLEND_EQUATIONS, '[', value, '.alpha];'); scope(ifte); return [RGB, ALPHA] }) case S_BLEND_COLOR: return parseParam( function (value) { check$1.command( isArrayLike(value) && value.length === 4, 'blend.color must be a 4d array', env.commandStr); return loop(4, function (i) { return +value[i] }) }, function (env, scope, value) { check$1.optional(function () { env.assert(scope, env.shared.isArrayLike + '(' + value + ')&&' + value + '.length===4', 'blend.color must be a 4d array'); }); return loop(4, function (i) { return scope.def('+', value, '[', i, ']') }) }) case S_STENCIL_MASK: return parseParam( function (value) { check$1.commandType(value, 'number', param, env.commandStr); return value | 0 }, function (env, scope, value) { check$1.optional(function () { env.assert(scope, 'typeof ' + value + '==="number"', 'invalid stencil.mask'); }); return scope.def(value, '|0') }) case S_STENCIL_FUNC: return parseParam( function (value) { check$1.commandType(value, 'object', param, env.commandStr); var cmp = value.cmp || 'keep'; var ref = value.ref || 0; var mask = 'mask' in value ? value.mask : -1; check$1.commandParameter(cmp, compareFuncs, prop + '.cmp', env.commandStr); check$1.commandType(ref, 'number', prop + '.ref', env.commandStr); check$1.commandType(mask, 'number', prop + '.mask', env.commandStr); return [ compareFuncs[cmp], ref, mask ] }, function (env, scope, value) { var COMPARE_FUNCS = env.constants.compareFuncs; check$1.optional(function () { function assert () { env.assert(scope, Array.prototype.join.call(arguments, ''), 'invalid stencil.func'); } assert(value + '&&typeof ', value, '==="object"'); assert('!("cmp" in ', value, ')||(', value, '.cmp in ', COMPARE_FUNCS, ')'); }); var cmp = scope.def( '"cmp" in ', value, '?', COMPARE_FUNCS, '[', value, '.cmp]', ':', GL_KEEP); var ref = scope.def(value, '.ref|0'); var mask = scope.def( '"mask" in ', value, '?', value, '.mask|0:-1'); return [cmp, ref, mask] }) case S_STENCIL_OPFRONT: case S_STENCIL_OPBACK: return parseParam( function (value) { check$1.commandType(value, 'object', param, env.commandStr); var fail = value.fail || 'keep'; var zfail = value.zfail || 'keep'; var zpass = value.zpass || 'keep'; check$1.commandParameter(fail, stencilOps, prop + '.fail', env.commandStr); check$1.commandParameter(zfail, stencilOps, prop + '.zfail', env.commandStr); check$1.commandParameter(zpass, stencilOps, prop + '.zpass', env.commandStr); return [ prop === S_STENCIL_OPBACK ? GL_BACK : GL_FRONT, stencilOps[fail], stencilOps[zfail], stencilOps[zpass] ] }, function (env, scope, value) { var STENCIL_OPS = env.constants.stencilOps; check$1.optional(function () { env.assert(scope, value + '&&typeof ' + value + '==="object"', 'invalid ' + prop); }); function read (name) { check$1.optional(function () { env.assert(scope, '!("' + name + '" in ' + value + ')||' + '(' + value + '.' + name + ' in ' + STENCIL_OPS + ')', 'invalid ' + prop + '.' + name + ', must be one of ' + Object.keys(stencilOps)); }); return scope.def( '"', name, '" in ', value, '?', STENCIL_OPS, '[', value, '.', name, ']:', GL_KEEP) } return [ prop === S_STENCIL_OPBACK ? GL_BACK : GL_FRONT, read('fail'), read('zfail'), read('zpass') ] }) case S_POLYGON_OFFSET_OFFSET: return parseParam( function (value) { check$1.commandType(value, 'object', param, env.commandStr); var factor = value.factor | 0; var units = value.units | 0; check$1.commandType(factor, 'number', param + '.factor', env.commandStr); check$1.commandType(units, 'number', param + '.units', env.commandStr); return [factor, units] }, function (env, scope, value) { check$1.optional(function () { env.assert(scope, value + '&&typeof ' + value + '==="object"', 'invalid ' + prop); }); var FACTOR = scope.def(value, '.factor|0'); var UNITS = scope.def(value, '.units|0'); return [FACTOR, UNITS] }) case S_CULL_FACE: return parseParam( function (value) { var face = 0; if (value === 'front') { face = GL_FRONT; } else if (value === 'back') { face = GL_BACK; } check$1.command(!!face, param, env.commandStr); return face }, function (env, scope, value) { check$1.optional(function () { env.assert(scope, value + '==="front"||' + value + '==="back"', 'invalid cull.face'); }); return scope.def(value, '==="front"?', GL_FRONT, ':', GL_BACK) }) case S_LINE_WIDTH: return parseParam( function (value) { check$1.command( typeof value === 'number' && value >= limits.lineWidthDims[0] && value <= limits.lineWidthDims[1], 'invalid line width, must positive number between ' + limits.lineWidthDims[0] + ' and ' + limits.lineWidthDims[1], env.commandStr); return value }, function (env, scope, value) { check$1.optional(function () { env.assert(scope, 'typeof ' + value + '==="number"&&' + value + '>=' + limits.lineWidthDims[0] + '&&' + value + '<=' + limits.lineWidthDims[1], 'invalid line width'); }); return value }) case S_FRONT_FACE: return parseParam( function (value) { check$1.commandParameter(value, orientationType, param, env.commandStr); return orientationType[value] }, function (env, scope, value) { check$1.optional(function () { env.assert(scope, value + '==="cw"||' + value + '==="ccw"', 'invalid frontFace, must be one of cw,ccw'); }); return scope.def(value + '==="cw"?' + GL_CW + ':' + GL_CCW) }) case S_COLOR_MASK: return parseParam( function (value) { check$1.command( isArrayLike(value) && value.length === 4, 'color.mask must be length 4 array', env.commandStr); return value.map(function (v) { return !!v }) }, function (env, scope, value) { check$1.optional(function () { env.assert(scope, env.shared.isArrayLike + '(' + value + ')&&' + value + '.length===4', 'invalid color.mask'); }); return loop(4, function (i) { return '!!' + value + '[' + i + ']' }) }) case S_SAMPLE_COVERAGE: return parseParam( function (value) { check$1.command(typeof value === 'object' && value, param, env.commandStr); var sampleValue = 'value' in value ? value.value : 1; var sampleInvert = !!value.invert; check$1.command( typeof sampleValue === 'number' && sampleValue >= 0 && sampleValue <= 1, 'sample.coverage.value must be a number between 0 and 1', env.commandStr); return [sampleValue, sampleInvert] }, function (env, scope, value) { check$1.optional(function () { env.assert(scope, value + '&&typeof ' + value + '==="object"', 'invalid sample.coverage'); }); var VALUE = scope.def( '"value" in ', value, '?+', value, '.value:1'); var INVERT = scope.def('!!', value, '.invert'); return [VALUE, INVERT] }) } }); return STATE } function parseUniforms (uniforms, env) { var staticUniforms = uniforms.static; var dynamicUniforms = uniforms.dynamic; var UNIFORMS = {}; Object.keys(staticUniforms).forEach(function (name) { var value = staticUniforms[name]; var result; if (typeof value === 'number' || typeof value === 'boolean') { result = createStaticDecl(function () { return value }); } else if (typeof value === 'function') { var reglType = value._reglType; if (reglType === 'texture2d' || reglType === 'textureCube') { result = createStaticDecl(function (env) { return env.link(value) }); } else if (reglType === 'framebuffer' || reglType === 'framebufferCube') { check$1.command(value.color.length > 0, 'missing color attachment for framebuffer sent to uniform "' + name + '"', env.commandStr); result = createStaticDecl(function (env) { return env.link(value.color[0]) }); } else { check$1.commandRaise('invalid data for uniform "' + name + '"', env.commandStr); } } else if (isArrayLike(value)) { result = createStaticDecl(function (env) { var ITEM = env.global.def('[', loop(value.length, function (i) { check$1.command( typeof value[i] === 'number' || typeof value[i] === 'boolean', 'invalid uniform ' + name, env.commandStr); return value[i] }), ']'); return ITEM }); } else { check$1.commandRaise('invalid or missing data for uniform "' + name + '"', env.commandStr); } result.value = value; UNIFORMS[name] = result; }); Object.keys(dynamicUniforms).forEach(function (key) { var dyn = dynamicUniforms[key]; UNIFORMS[key] = createDynamicDecl(dyn, function (env, scope) { return env.invoke(scope, dyn) }); }); return UNIFORMS } function parseAttributes (attributes, env) { var staticAttributes = attributes.static; var dynamicAttributes = attributes.dynamic; var attributeDefs = {}; Object.keys(staticAttributes).forEach(function (attribute) { var value = staticAttributes[attribute]; var id = stringStore.id(attribute); var record = new AttributeRecord(); if (isBufferArgs(value)) { record.state = ATTRIB_STATE_POINTER; record.buffer = bufferState.getBuffer( bufferState.create(value, GL_ARRAY_BUFFER$1, false, true)); record.type = 0; } else { var buffer = bufferState.getBuffer(value); if (buffer) { record.state = ATTRIB_STATE_POINTER; record.buffer = buffer; record.type = 0; } else { check$1.command(typeof value === 'object' && value, 'invalid data for attribute ' + attribute, env.commandStr); if (value.constant) { var constant = value.constant; record.buffer = 'null'; record.state = ATTRIB_STATE_CONSTANT; if (typeof constant === 'number') { record.x = constant; } else { check$1.command( isArrayLike(constant) && constant.length > 0 && constant.length <= 4, 'invalid constant for attribute ' + attribute, env.commandStr); CUTE_COMPONENTS.forEach(function (c, i) { if (i < constant.length) { record[c] = constant[i]; } }); } } else { if (isBufferArgs(value.buffer)) { buffer = bufferState.getBuffer( bufferState.create(value.buffer, GL_ARRAY_BUFFER$1, false, true)); } else { buffer = bufferState.getBuffer(value.buffer); } check$1.command(!!buffer, 'missing buffer for attribute "' + attribute + '"', env.commandStr); var offset = value.offset | 0; check$1.command(offset >= 0, 'invalid offset for attribute "' + attribute + '"', env.commandStr); var stride = value.stride | 0; check$1.command(stride >= 0 && stride < 256, 'invalid stride for attribute "' + attribute + '", must be integer betweeen [0, 255]', env.commandStr); var size = value.size | 0; check$1.command(!('size' in value) || (size > 0 && size <= 4), 'invalid size for attribute "' + attribute + '", must be 1,2,3,4', env.commandStr); var normalized = !!value.normalized; var type = 0; if ('type' in value) { check$1.commandParameter( value.type, glTypes, 'invalid type for attribute ' + attribute, env.commandStr); type = glTypes[value.type]; } var divisor = value.divisor | 0; if ('divisor' in value) { check$1.command(divisor === 0 || extInstancing, 'cannot specify divisor for attribute "' + attribute + '", instancing not supported', env.commandStr); check$1.command(divisor >= 0, 'invalid divisor for attribute "' + attribute + '"', env.commandStr); } check$1.optional(function () { var command = env.commandStr; var VALID_KEYS = [ 'buffer', 'offset', 'divisor', 'normalized', 'type', 'size', 'stride' ]; Object.keys(value).forEach(function (prop) { check$1.command( VALID_KEYS.indexOf(prop) >= 0, 'unknown parameter "' + prop + '" for attribute pointer "' + attribute + '" (valid parameters are ' + VALID_KEYS + ')', command); }); }); record.buffer = buffer; record.state = ATTRIB_STATE_POINTER; record.size = size; record.normalized = normalized; record.type = type || buffer.dtype; record.offset = offset; record.stride = stride; record.divisor = divisor; } } } attributeDefs[attribute] = createStaticDecl(function (env, scope) { var cache = env.attribCache; if (id in cache) { return cache[id] } var result = { isStream: false }; Object.keys(record).forEach(function (key) { result[key] = record[key]; }); if (record.buffer) { result.buffer = env.link(record.buffer); result.type = result.type || (result.buffer + '.dtype'); } cache[id] = result; return result }); }); Object.keys(dynamicAttributes).forEach(function (attribute) { var dyn = dynamicAttributes[attribute]; function appendAttributeCode (env, block) { var VALUE = env.invoke(block, dyn); var shared = env.shared; var IS_BUFFER_ARGS = shared.isBufferArgs; var BUFFER_STATE = shared.buffer; // Perform validation on attribute check$1.optional(function () { env.assert(block, VALUE + '&&(typeof ' + VALUE + '==="object"||typeof ' + VALUE + '==="function")&&(' + IS_BUFFER_ARGS + '(' + VALUE + ')||' + BUFFER_STATE + '.getBuffer(' + VALUE + ')||' + BUFFER_STATE + '.getBuffer(' + VALUE + '.buffer)||' + IS_BUFFER_ARGS + '(' + VALUE + '.buffer)||' + '("constant" in ' + VALUE + '&&(typeof ' + VALUE + '.constant==="number"||' + shared.isArrayLike + '(' + VALUE + '.constant))))', 'invalid dynamic attribute "' + attribute + '"'); }); // allocate names for result var result = { isStream: block.def(false) }; var defaultRecord = new AttributeRecord(); defaultRecord.state = ATTRIB_STATE_POINTER; Object.keys(defaultRecord).forEach(function (key) { result[key] = block.def('' + defaultRecord[key]); }); var BUFFER = result.buffer; var TYPE = result.type; block( 'if(', IS_BUFFER_ARGS, '(', VALUE, ')){', result.isStream, '=true;', BUFFER, '=', BUFFER_STATE, '.createStream(', GL_ARRAY_BUFFER$1, ',', VALUE, ');', TYPE, '=', BUFFER, '.dtype;', '}else{', BUFFER, '=', BUFFER_STATE, '.getBuffer(', VALUE, ');', 'if(', BUFFER, '){', TYPE, '=', BUFFER, '.dtype;', '}else if("constant" in ', VALUE, '){', result.state, '=', ATTRIB_STATE_CONSTANT, ';', 'if(typeof ' + VALUE + '.constant === "number"){', result[CUTE_COMPONENTS[0]], '=', VALUE, '.constant;', CUTE_COMPONENTS.slice(1).map(function (n) { return result[n] }).join('='), '=0;', '}else{', CUTE_COMPONENTS.map(function (name, i) { return ( result[name] + '=' + VALUE + '.constant.length>=' + i + '?' + VALUE + '.constant[' + i + ']:0;' ) }).join(''), '}}else{', 'if(', IS_BUFFER_ARGS, '(', VALUE, '.buffer)){', BUFFER, '=', BUFFER_STATE, '.createStream(', GL_ARRAY_BUFFER$1, ',', VALUE, '.buffer);', '}else{', BUFFER, '=', BUFFER_STATE, '.getBuffer(', VALUE, '.buffer);', '}', TYPE, '="type" in ', VALUE, '?', shared.glTypes, '[', VALUE, '.type]:', BUFFER, '.dtype;', result.normalized, '=!!', VALUE, '.normalized;'); function emitReadRecord (name) { block(result[name], '=', VALUE, '.', name, '|0;'); } emitReadRecord('size'); emitReadRecord('offset'); emitReadRecord('stride'); emitReadRecord('divisor'); block('}}'); block.exit( 'if(', result.isStream, '){', BUFFER_STATE, '.destroyStream(', BUFFER, ');', '}'); return result } attributeDefs[attribute] = createDynamicDecl(dyn, appendAttributeCode); }); return attributeDefs } function parseContext (context) { var staticContext = context.static; var dynamicContext = context.dynamic; var result = {}; Object.keys(staticContext).forEach(function (name) { var value = staticContext[name]; result[name] = createStaticDecl(function (env, scope) { if (typeof value === 'number' || typeof value === 'boolean') { return '' + value } else { return env.link(value) } }); }); Object.keys(dynamicContext).forEach(function (name) { var dyn = dynamicContext[name]; result[name] = createDynamicDecl(dyn, function (env, scope) { return env.invoke(scope, dyn) }); }); return result } function parseArguments (options, attributes, uniforms, context, env) { var staticOptions = options.static; var dynamicOptions = options.dynamic; check$1.optional(function () { var KEY_NAMES = [ S_FRAMEBUFFER, S_VERT, S_FRAG, S_ELEMENTS, S_PRIMITIVE, S_OFFSET, S_COUNT, S_INSTANCES, S_PROFILE ].concat(GL_STATE_NAMES); function checkKeys (dict) { Object.keys(dict).forEach(function (key) { check$1.command( KEY_NAMES.indexOf(key) >= 0, 'unknown parameter "' + key + '"', env.commandStr); }); } checkKeys(staticOptions); checkKeys(dynamicOptions); }); var framebuffer = parseFramebuffer(options, env); var viewportAndScissor = parseViewportScissor(options, framebuffer, env); var draw = parseDraw(options, env); var state = parseGLState(options, env); var shader = parseProgram(options, env); function copyBox (name) { var defn = viewportAndScissor[name]; if (defn) { state[name] = defn; } } copyBox(S_VIEWPORT); copyBox(propName(S_SCISSOR_BOX)); var dirty = Object.keys(state).length > 0; var result = { framebuffer: framebuffer, draw: draw, shader: shader, state: state, dirty: dirty }; result.profile = parseProfile(options, env); result.uniforms = parseUniforms(uniforms, env); result.attributes = parseAttributes(attributes, env); result.context = parseContext(context, env); return result } // =================================================== // =================================================== // COMMON UPDATE FUNCTIONS // =================================================== // =================================================== function emitContext (env, scope, context) { var shared = env.shared; var CONTEXT = shared.context; var contextEnter = env.scope(); Object.keys(context).forEach(function (name) { scope.save(CONTEXT, '.' + name); var defn = context[name]; contextEnter(CONTEXT, '.', name, '=', defn.append(env, scope), ';'); }); scope(contextEnter); } // =================================================== // =================================================== // COMMON DRAWING FUNCTIONS // =================================================== // =================================================== function emitPollFramebuffer (env, scope, framebuffer, skipCheck) { var shared = env.shared; var GL = shared.gl; var FRAMEBUFFER_STATE = shared.framebuffer; var EXT_DRAW_BUFFERS; if (extDrawBuffers) { EXT_DRAW_BUFFERS = scope.def(shared.extensions, '.webgl_draw_buffers'); } var constants = env.constants; var DRAW_BUFFERS = constants.drawBuffer; var BACK_BUFFER = constants.backBuffer; var NEXT; if (framebuffer) { NEXT = framebuffer.append(env, scope); } else { NEXT = scope.def(FRAMEBUFFER_STATE, '.next'); } if (!skipCheck) { scope('if(', NEXT, '!==', FRAMEBUFFER_STATE, '.cur){'); } scope( 'if(', NEXT, '){', GL, '.bindFramebuffer(', GL_FRAMEBUFFER$1, ',', NEXT, '.framebuffer);'); if (extDrawBuffers) { scope(EXT_DRAW_BUFFERS, '.drawBuffersWEBGL(', DRAW_BUFFERS, '[', NEXT, '.colorAttachments.length]);'); } scope('}else{', GL, '.bindFramebuffer(', GL_FRAMEBUFFER$1, ',null);'); if (extDrawBuffers) { scope(EXT_DRAW_BUFFERS, '.drawBuffersWEBGL(', BACK_BUFFER, ');'); } scope( '}', FRAMEBUFFER_STATE, '.cur=', NEXT, ';'); if (!skipCheck) { scope('}'); } } function emitPollState (env, scope, args) { var shared = env.shared; var GL = shared.gl; var CURRENT_VARS = env.current; var NEXT_VARS = env.next; var CURRENT_STATE = shared.current; var NEXT_STATE = shared.next; var block = env.cond(CURRENT_STATE, '.dirty'); GL_STATE_NAMES.forEach(function (prop) { var param = propName(prop); if (param in args.state) { return } var NEXT, CURRENT; if (param in NEXT_VARS) { NEXT = NEXT_VARS[param]; CURRENT = CURRENT_VARS[param]; var parts = loop(currentState[param].length, function (i) { return block.def(NEXT, '[', i, ']') }); block(env.cond(parts.map(function (p, i) { return p + '!==' + CURRENT + '[' + i + ']' }).join('||')) .then( GL, '.', GL_VARIABLES[param], '(', parts, ');', parts.map(function (p, i) { return CURRENT + '[' + i + ']=' + p }).join(';'), ';')); } else { NEXT = block.def(NEXT_STATE, '.', param); var ifte = env.cond(NEXT, '!==', CURRENT_STATE, '.', param); block(ifte); if (param in GL_FLAGS) { ifte( env.cond(NEXT) .then(GL, '.enable(', GL_FLAGS[param], ');') .else(GL, '.disable(', GL_FLAGS[param], ');'), CURRENT_STATE, '.', param, '=', NEXT, ';'); } else { ifte( GL, '.', GL_VARIABLES[param], '(', NEXT, ');', CURRENT_STATE, '.', param, '=', NEXT, ';'); } } }); if (Object.keys(args.state).length === 0) { block(CURRENT_STATE, '.dirty=false;'); } scope(block); } function emitSetOptions (env, scope, options, filter) { var shared = env.shared; var CURRENT_VARS = env.current; var CURRENT_STATE = shared.current; var GL = shared.gl; sortState(Object.keys(options)).forEach(function (param) { var defn = options[param]; if (filter && !filter(defn)) { return } var variable = defn.append(env, scope); if (GL_FLAGS[param]) { var flag = GL_FLAGS[param]; if (isStatic(defn)) { if (variable) { scope(GL, '.enable(', flag, ');'); } else { scope(GL, '.disable(', flag, ');'); } } else { scope(env.cond(variable) .then(GL, '.enable(', flag, ');') .else(GL, '.disable(', flag, ');')); } scope(CURRENT_STATE, '.', param, '=', variable, ';'); } else if (isArrayLike(variable)) { var CURRENT = CURRENT_VARS[param]; scope( GL, '.', GL_VARIABLES[param], '(', variable, ');', variable.map(function (v, i) { return CURRENT + '[' + i + ']=' + v }).join(';'), ';'); } else { scope( GL, '.', GL_VARIABLES[param], '(', variable, ');', CURRENT_STATE, '.', param, '=', variable, ';'); } }); } function injectExtensions (env, scope) { if (extInstancing) { env.instancing = scope.def( env.shared.extensions, '.angle_instanced_arrays'); } } function emitProfile (env, scope, args, useScope, incrementCounter) { var shared = env.shared; var STATS = env.stats; var CURRENT_STATE = shared.current; var TIMER = shared.timer; var profileArg = args.profile; function perfCounter () { if (typeof performance === 'undefined') { return 'Date.now()' } else { return 'performance.now()' } } var CPU_START, QUERY_COUNTER; function emitProfileStart (block) { CPU_START = scope.def(); block(CPU_START, '=', perfCounter(), ';'); if (typeof incrementCounter === 'string') { block(STATS, '.count+=', incrementCounter, ';'); } else { block(STATS, '.count++;'); } if (timer) { if (useScope) { QUERY_COUNTER = scope.def(); block(QUERY_COUNTER, '=', TIMER, '.getNumPendingQueries();'); } else { block(TIMER, '.beginQuery(', STATS, ');'); } } } function emitProfileEnd (block) { block(STATS, '.cpuTime+=', perfCounter(), '-', CPU_START, ';'); if (timer) { if (useScope) { block(TIMER, '.pushScopeStats(', QUERY_COUNTER, ',', TIMER, '.getNumPendingQueries(),', STATS, ');'); } else { block(TIMER, '.endQuery();'); } } } function scopeProfile (value) { var prev = scope.def(CURRENT_STATE, '.profile'); scope(CURRENT_STATE, '.profile=', value, ';'); scope.exit(CURRENT_STATE, '.profile=', prev, ';'); } var USE_PROFILE; if (profileArg) { if (isStatic(profileArg)) { if (profileArg.enable) { emitProfileStart(scope); emitProfileEnd(scope.exit); scopeProfile('true'); } else { scopeProfile('false'); } return } USE_PROFILE = profileArg.append(env, scope); scopeProfile(USE_PROFILE); } else { USE_PROFILE = scope.def(CURRENT_STATE, '.profile'); } var start = env.block(); emitProfileStart(start); scope('if(', USE_PROFILE, '){', start, '}'); var end = env.block(); emitProfileEnd(end); scope.exit('if(', USE_PROFILE, '){', end, '}'); } function emitAttributes (env, scope, args, attributes, filter) { var shared = env.shared; function typeLength (x) { switch (x) { case GL_FLOAT_VEC2: case GL_INT_VEC2: case GL_BOOL_VEC2: return 2 case GL_FLOAT_VEC3: case GL_INT_VEC3: case GL_BOOL_VEC3: return 3 case GL_FLOAT_VEC4: case GL_INT_VEC4: case GL_BOOL_VEC4: return 4 default: return 1 } } function emitBindAttribute (ATTRIBUTE, size, record) { var GL = shared.gl; var LOCATION = scope.def(ATTRIBUTE, '.location'); var BINDING = scope.def(shared.attributes, '[', LOCATION, ']'); var STATE = record.state; var BUFFER = record.buffer; var CONST_COMPONENTS = [ record.x, record.y, record.z, record.w ]; var COMMON_KEYS = [ 'buffer', 'normalized', 'offset', 'stride' ]; function emitBuffer () { scope( 'if(!', BINDING, '.buffer){', GL, '.enableVertexAttribArray(', LOCATION, ');}'); var TYPE = record.type; var SIZE; if (!record.size) { SIZE = size; } else { SIZE = scope.def(record.size, '||', size); } scope('if(', BINDING, '.type!==', TYPE, '||', BINDING, '.size!==', SIZE, '||', COMMON_KEYS.map(function (key) { return BINDING + '.' + key + '!==' + record[key] }).join('||'), '){', GL, '.bindBuffer(', GL_ARRAY_BUFFER$1, ',', BUFFER, '.buffer);', GL, '.vertexAttribPointer(', [ LOCATION, SIZE, TYPE, record.normalized, record.stride, record.offset ], ');', BINDING, '.type=', TYPE, ';', BINDING, '.size=', SIZE, ';', COMMON_KEYS.map(function (key) { return BINDING + '.' + key + '=' + record[key] + ';' }).join(''), '}'); if (extInstancing) { var DIVISOR = record.divisor; scope( 'if(', BINDING, '.divisor!==', DIVISOR, '){', env.instancing, '.vertexAttribDivisorANGLE(', [LOCATION, DIVISOR], ');', BINDING, '.divisor=', DIVISOR, ';}'); } } function emitConstant () { scope( 'if(', BINDING, '.buffer){', GL, '.disableVertexAttribArray(', LOCATION, ');', '}if(', CUTE_COMPONENTS.map(function (c, i) { return BINDING + '.' + c + '!==' + CONST_COMPONENTS[i] }).join('||'), '){', GL, '.vertexAttrib4f(', LOCATION, ',', CONST_COMPONENTS, ');', CUTE_COMPONENTS.map(function (c, i) { return BINDING + '.' + c + '=' + CONST_COMPONENTS[i] + ';' }).join(''), '}'); } if (STATE === ATTRIB_STATE_POINTER) { emitBuffer(); } else if (STATE === ATTRIB_STATE_CONSTANT) { emitConstant(); } else { scope('if(', STATE, '===', ATTRIB_STATE_POINTER, '){'); emitBuffer(); scope('}else{'); emitConstant(); scope('}'); } } attributes.forEach(function (attribute) { var name = attribute.name; var arg = args.attributes[name]; var record; if (arg) { if (!filter(arg)) { return } record = arg.append(env, scope); } else { if (!filter(SCOPE_DECL)) { return } var scopeAttrib = env.scopeAttrib(name); check$1.optional(function () { env.assert(scope, scopeAttrib + '.state', 'missing attribute ' + name); }); record = {}; Object.keys(new AttributeRecord()).forEach(function (key) { record[key] = scope.def(scopeAttrib, '.', key); }); } emitBindAttribute( env.link(attribute), typeLength(attribute.info.type), record); }); } function emitUniforms (env, scope, args, uniforms, filter) { var shared = env.shared; var GL = shared.gl; var infix; for (var i = 0; i < uniforms.length; ++i) { var uniform = uniforms[i]; var name = uniform.name; var type = uniform.info.type; var arg = args.uniforms[name]; var UNIFORM = env.link(uniform); var LOCATION = UNIFORM + '.location'; var VALUE; if (arg) { if (!filter(arg)) { continue } if (isStatic(arg)) { var value = arg.value; check$1.command( value !== null && typeof value !== 'undefined', 'missing uniform "' + name + '"', env.commandStr); if (type === GL_SAMPLER_2D || type === GL_SAMPLER_CUBE) { check$1.command( typeof value === 'function' && ((type === GL_SAMPLER_2D && (value._reglType === 'texture2d' || value._reglType === 'framebuffer')) || (type === GL_SAMPLER_CUBE && (value._reglType === 'textureCube' || value._reglType === 'framebufferCube'))), 'invalid texture for uniform ' + name, env.commandStr); var TEX_VALUE = env.link(value._texture || value.color[0]._texture); scope(GL, '.uniform1i(', LOCATION, ',', TEX_VALUE + '.bind());'); scope.exit(TEX_VALUE, '.unbind();'); } else if ( type === GL_FLOAT_MAT2 || type === GL_FLOAT_MAT3 || type === GL_FLOAT_MAT4) { check$1.optional(function () { check$1.command(isArrayLike(value), 'invalid matrix for uniform ' + name, env.commandStr); check$1.command( (type === GL_FLOAT_MAT2 && value.length === 4) || (type === GL_FLOAT_MAT3 && value.length === 9) || (type === GL_FLOAT_MAT4 && value.length === 16), 'invalid length for matrix uniform ' + name, env.commandStr); }); var MAT_VALUE = env.global.def('new Float32Array([' + Array.prototype.slice.call(value) + '])'); var dim = 2; if (type === GL_FLOAT_MAT3) { dim = 3; } else if (type === GL_FLOAT_MAT4) { dim = 4; } scope( GL, '.uniformMatrix', dim, 'fv(', LOCATION, ',false,', MAT_VALUE, ');'); } else { switch (type) { case GL_FLOAT$7: check$1.commandType(value, 'number', 'uniform ' + name, env.commandStr); infix = '1f'; break case GL_FLOAT_VEC2: check$1.command( isArrayLike(value) && value.length === 2, 'uniform ' + name, env.commandStr); infix = '2f'; break case GL_FLOAT_VEC3: check$1.command( isArrayLike(value) && value.length === 3, 'uniform ' + name, env.commandStr); infix = '3f'; break case GL_FLOAT_VEC4: check$1.command( isArrayLike(value) && value.length === 4, 'uniform ' + name, env.commandStr); infix = '4f'; break case GL_BOOL: check$1.commandType(value, 'boolean', 'uniform ' + name, env.commandStr); infix = '1i'; break case GL_INT$3: check$1.commandType(value, 'number', 'uniform ' + name, env.commandStr); infix = '1i'; break case GL_BOOL_VEC2: check$1.command( isArrayLike(value) && value.length === 2, 'uniform ' + name, env.commandStr); infix = '2i'; break case GL_INT_VEC2: check$1.command( isArrayLike(value) && value.length === 2, 'uniform ' + name, env.commandStr); infix = '2i'; break case GL_BOOL_VEC3: check$1.command( isArrayLike(value) && value.length === 3, 'uniform ' + name, env.commandStr); infix = '3i'; break case GL_INT_VEC3: check$1.command( isArrayLike(value) && value.length === 3, 'uniform ' + name, env.commandStr); infix = '3i'; break case GL_BOOL_VEC4: check$1.command( isArrayLike(value) && value.length === 4, 'uniform ' + name, env.commandStr); infix = '4i'; break case GL_INT_VEC4: check$1.command( isArrayLike(value) && value.length === 4, 'uniform ' + name, env.commandStr); infix = '4i'; break } scope(GL, '.uniform', infix, '(', LOCATION, ',', isArrayLike(value) ? Array.prototype.slice.call(value) : value, ');'); } continue } else { VALUE = arg.append(env, scope); } } else { if (!filter(SCOPE_DECL)) { continue } VALUE = scope.def(shared.uniforms, '[', stringStore.id(name), ']'); } if (type === GL_SAMPLER_2D) { scope( 'if(', VALUE, '&&', VALUE, '._reglType==="framebuffer"){', VALUE, '=', VALUE, '.color[0];', '}'); } else if (type === GL_SAMPLER_CUBE) { scope( 'if(', VALUE, '&&', VALUE, '._reglType==="framebufferCube"){', VALUE, '=', VALUE, '.color[0];', '}'); } // perform type validation check$1.optional(function () { function check (pred, message) { env.assert(scope, pred, 'bad data or missing for uniform "' + name + '". ' + message); } function checkType (type) { check( 'typeof ' + VALUE + '==="' + type + '"', 'invalid type, expected ' + type); } function checkVector (n, type) { check( shared.isArrayLike + '(' + VALUE + ')&&' + VALUE + '.length===' + n, 'invalid vector, should have length ' + n, env.commandStr); } function checkTexture (target) { check( 'typeof ' + VALUE + '==="function"&&' + VALUE + '._reglType==="texture' + (target === GL_TEXTURE_2D$2 ? '2d' : 'Cube') + '"', 'invalid texture type', env.commandStr); } switch (type) { case GL_INT$3: checkType('number'); break case GL_INT_VEC2: checkVector(2, 'number'); break case GL_INT_VEC3: checkVector(3, 'number'); break case GL_INT_VEC4: checkVector(4, 'number'); break case GL_FLOAT$7: checkType('number'); break case GL_FLOAT_VEC2: checkVector(2, 'number'); break case GL_FLOAT_VEC3: checkVector(3, 'number'); break case GL_FLOAT_VEC4: checkVector(4, 'number'); break case GL_BOOL: checkType('boolean'); break case GL_BOOL_VEC2: checkVector(2, 'boolean'); break case GL_BOOL_VEC3: checkVector(3, 'boolean'); break case GL_BOOL_VEC4: checkVector(4, 'boolean'); break case GL_FLOAT_MAT2: checkVector(4, 'number'); break case GL_FLOAT_MAT3: checkVector(9, 'number'); break case GL_FLOAT_MAT4: checkVector(16, 'number'); break case GL_SAMPLER_2D: checkTexture(GL_TEXTURE_2D$2); break case GL_SAMPLER_CUBE: checkTexture(GL_TEXTURE_CUBE_MAP$1); break } }); var unroll = 1; switch (type) { case GL_SAMPLER_2D: case GL_SAMPLER_CUBE: var TEX = scope.def(VALUE, '._texture'); scope(GL, '.uniform1i(', LOCATION, ',', TEX, '.bind());'); scope.exit(TEX, '.unbind();'); continue case GL_INT$3: case GL_BOOL: infix = '1i'; break case GL_INT_VEC2: case GL_BOOL_VEC2: infix = '2i'; unroll = 2; break case GL_INT_VEC3: case GL_BOOL_VEC3: infix = '3i'; unroll = 3; break case GL_INT_VEC4: case GL_BOOL_VEC4: infix = '4i'; unroll = 4; break case GL_FLOAT$7: infix = '1f'; break case GL_FLOAT_VEC2: infix = '2f'; unroll = 2; break case GL_FLOAT_VEC3: infix = '3f'; unroll = 3; break case GL_FLOAT_VEC4: infix = '4f'; unroll = 4; break case GL_FLOAT_MAT2: infix = 'Matrix2fv'; break case GL_FLOAT_MAT3: infix = 'Matrix3fv'; break case GL_FLOAT_MAT4: infix = 'Matrix4fv'; break } scope(GL, '.uniform', infix, '(', LOCATION, ','); if (infix.charAt(0) === 'M') { var matSize = Math.pow(type - GL_FLOAT_MAT2 + 2, 2); var STORAGE = env.global.def('new Float32Array(', matSize, ')'); scope( 'false,(Array.isArray(', VALUE, ')||', VALUE, ' instanceof Float32Array)?', VALUE, ':(', loop(matSize, function (i) { return STORAGE + '[' + i + ']=' + VALUE + '[' + i + ']' }), ',', STORAGE, ')'); } else if (unroll > 1) { scope(loop(unroll, function (i) { return VALUE + '[' + i + ']' })); } else { scope(VALUE); } scope(');'); } } function emitDraw (env, outer, inner, args) { var shared = env.shared; var GL = shared.gl; var DRAW_STATE = shared.draw; var drawOptions = args.draw; function emitElements () { var defn = drawOptions.elements; var ELEMENTS; var scope = outer; if (defn) { if ((defn.contextDep && args.contextDynamic) || defn.propDep) { scope = inner; } ELEMENTS = defn.append(env, scope); } else { ELEMENTS = scope.def(DRAW_STATE, '.', S_ELEMENTS); } if (ELEMENTS) { scope( 'if(' + ELEMENTS + ')' + GL + '.bindBuffer(' + GL_ELEMENT_ARRAY_BUFFER$1 + ',' + ELEMENTS + '.buffer.buffer);'); } return ELEMENTS } function emitCount () { var defn = drawOptions.count; var COUNT; var scope = outer; if (defn) { if ((defn.contextDep && args.contextDynamic) || defn.propDep) { scope = inner; } COUNT = defn.append(env, scope); check$1.optional(function () { if (defn.MISSING) { env.assert(outer, 'false', 'missing vertex count'); } if (defn.DYNAMIC) { env.assert(scope, COUNT + '>=0', 'missing vertex count'); } }); } else { COUNT = scope.def(DRAW_STATE, '.', S_COUNT); check$1.optional(function () { env.assert(scope, COUNT + '>=0', 'missing vertex count'); }); } return COUNT } var ELEMENTS = emitElements(); function emitValue (name) { var defn = drawOptions[name]; if (defn) { if ((defn.contextDep && args.contextDynamic) || defn.propDep) { return defn.append(env, inner) } else { return defn.append(env, outer) } } else { return outer.def(DRAW_STATE, '.', name) } } var PRIMITIVE = emitValue(S_PRIMITIVE); var OFFSET = emitValue(S_OFFSET); var COUNT = emitCount(); if (typeof COUNT === 'number') { if (COUNT === 0) { return } } else { inner('if(', COUNT, '){'); inner.exit('}'); } var INSTANCES, EXT_INSTANCING; if (extInstancing) { INSTANCES = emitValue(S_INSTANCES); EXT_INSTANCING = env.instancing; } var ELEMENT_TYPE = ELEMENTS + '.type'; var elementsStatic = drawOptions.elements && isStatic(drawOptions.elements); function emitInstancing () { function drawElements () { inner(EXT_INSTANCING, '.drawElementsInstancedANGLE(', [ PRIMITIVE, COUNT, ELEMENT_TYPE, OFFSET + '<<((' + ELEMENT_TYPE + '-' + GL_UNSIGNED_BYTE$7 + ')>>1)', INSTANCES ], ');'); } function drawArrays () { inner(EXT_INSTANCING, '.drawArraysInstancedANGLE(', [PRIMITIVE, OFFSET, COUNT, INSTANCES], ');'); } if (ELEMENTS) { if (!elementsStatic) { inner('if(', ELEMENTS, '){'); drawElements(); inner('}else{'); drawArrays(); inner('}'); } else { drawElements(); } } else { drawArrays(); } } function emitRegular () { function drawElements () { inner(GL + '.drawElements(' + [ PRIMITIVE, COUNT, ELEMENT_TYPE, OFFSET + '<<((' + ELEMENT_TYPE + '-' + GL_UNSIGNED_BYTE$7 + ')>>1)' ] + ');'); } function drawArrays () { inner(GL + '.drawArrays(' + [PRIMITIVE, OFFSET, COUNT] + ');'); } if (ELEMENTS) { if (!elementsStatic) { inner('if(', ELEMENTS, '){'); drawElements(); inner('}else{'); drawArrays(); inner('}'); } else { drawElements(); } } else { drawArrays(); } } if (extInstancing && (typeof INSTANCES !== 'number' || INSTANCES >= 0)) { if (typeof INSTANCES === 'string') { inner('if(', INSTANCES, '>0){'); emitInstancing(); inner('}else if(', INSTANCES, '<0){'); emitRegular(); inner('}'); } else { emitInstancing(); } } else { emitRegular(); } } function createBody (emitBody, parentEnv, args, program, count) { var env = createREGLEnvironment(); var scope = env.proc('body', count); check$1.optional(function () { env.commandStr = parentEnv.commandStr; env.command = env.link(parentEnv.commandStr); }); if (extInstancing) { env.instancing = scope.def( env.shared.extensions, '.angle_instanced_arrays'); } emitBody(env, scope, args, program); return env.compile().body } // =================================================== // =================================================== // DRAW PROC // =================================================== // =================================================== function emitDrawBody (env, draw, args, program) { injectExtensions(env, draw); emitAttributes(env, draw, args, program.attributes, function () { return true }); emitUniforms(env, draw, args, program.uniforms, function () { return true }); emitDraw(env, draw, draw, args); } function emitDrawProc (env, args) { var draw = env.proc('draw', 1); injectExtensions(env, draw); emitContext(env, draw, args.context); emitPollFramebuffer(env, draw, args.framebuffer); emitPollState(env, draw, args); emitSetOptions(env, draw, args.state); emitProfile(env, draw, args, false, true); var program = args.shader.progVar.append(env, draw); draw(env.shared.gl, '.useProgram(', program, '.program);'); if (args.shader.program) { emitDrawBody(env, draw, args, args.shader.program); } else { var drawCache = env.global.def('{}'); var PROG_ID = draw.def(program, '.id'); var CACHED_PROC = draw.def(drawCache, '[', PROG_ID, ']'); draw( env.cond(CACHED_PROC) .then(CACHED_PROC, '.call(this,a0);') .else( CACHED_PROC, '=', drawCache, '[', PROG_ID, ']=', env.link(function (program) { return createBody(emitDrawBody, env, args, program, 1) }), '(', program, ');', CACHED_PROC, '.call(this,a0);')); } if (Object.keys(args.state).length > 0) { draw(env.shared.current, '.dirty=true;'); } } // =================================================== // =================================================== // BATCH PROC // =================================================== // =================================================== function emitBatchDynamicShaderBody (env, scope, args, program) { env.batchId = 'a1'; injectExtensions(env, scope); function all () { return true } emitAttributes(env, scope, args, program.attributes, all); emitUniforms(env, scope, args, program.uniforms, all); emitDraw(env, scope, scope, args); } function emitBatchBody (env, scope, args, program) { injectExtensions(env, scope); var contextDynamic = args.contextDep; var BATCH_ID = scope.def(); var PROP_LIST = 'a0'; var NUM_PROPS = 'a1'; var PROPS = scope.def(); env.shared.props = PROPS; env.batchId = BATCH_ID; var outer = env.scope(); var inner = env.scope(); scope( outer.entry, 'for(', BATCH_ID, '=0;', BATCH_ID, '<', NUM_PROPS, ';++', BATCH_ID, '){', PROPS, '=', PROP_LIST, '[', BATCH_ID, '];', inner, '}', outer.exit); function isInnerDefn (defn) { return ((defn.contextDep && contextDynamic) || defn.propDep) } function isOuterDefn (defn) { return !isInnerDefn(defn) } if (args.needsContext) { emitContext(env, inner, args.context); } if (args.needsFramebuffer) { emitPollFramebuffer(env, inner, args.framebuffer); } emitSetOptions(env, inner, args.state, isInnerDefn); if (args.profile && isInnerDefn(args.profile)) { emitProfile(env, inner, args, false, true); } if (!program) { var progCache = env.global.def('{}'); var PROGRAM = args.shader.progVar.append(env, inner); var PROG_ID = inner.def(PROGRAM, '.id'); var CACHED_PROC = inner.def(progCache, '[', PROG_ID, ']'); inner( env.shared.gl, '.useProgram(', PROGRAM, '.program);', 'if(!', CACHED_PROC, '){', CACHED_PROC, '=', progCache, '[', PROG_ID, ']=', env.link(function (program) { return createBody( emitBatchDynamicShaderBody, env, args, program, 2) }), '(', PROGRAM, ');}', CACHED_PROC, '.call(this,a0[', BATCH_ID, '],', BATCH_ID, ');'); } else { emitAttributes(env, outer, args, program.attributes, isOuterDefn); emitAttributes(env, inner, args, program.attributes, isInnerDefn); emitUniforms(env, outer, args, program.uniforms, isOuterDefn); emitUniforms(env, inner, args, program.uniforms, isInnerDefn); emitDraw(env, outer, inner, args); } } function emitBatchProc (env, args) { var batch = env.proc('batch', 2); env.batchId = '0'; injectExtensions(env, batch); // Check if any context variables depend on props var contextDynamic = false; var needsContext = true; Object.keys(args.context).forEach(function (name) { contextDynamic = contextDynamic || args.context[name].propDep; }); if (!contextDynamic) { emitContext(env, batch, args.context); needsContext = false; } // framebuffer state affects framebufferWidth/height context vars var framebuffer = args.framebuffer; var needsFramebuffer = false; if (framebuffer) { if (framebuffer.propDep) { contextDynamic = needsFramebuffer = true; } else if (framebuffer.contextDep && contextDynamic) { needsFramebuffer = true; } if (!needsFramebuffer) { emitPollFramebuffer(env, batch, framebuffer); } } else { emitPollFramebuffer(env, batch, null); } // viewport is weird because it can affect context vars if (args.state.viewport && args.state.viewport.propDep) { contextDynamic = true; } function isInnerDefn (defn) { return (defn.contextDep && contextDynamic) || defn.propDep } // set webgl options emitPollState(env, batch, args); emitSetOptions(env, batch, args.state, function (defn) { return !isInnerDefn(defn) }); if (!args.profile || !isInnerDefn(args.profile)) { emitProfile(env, batch, args, false, 'a1'); } // Save these values to args so that the batch body routine can use them args.contextDep = contextDynamic; args.needsContext = needsContext; args.needsFramebuffer = needsFramebuffer; // determine if shader is dynamic var progDefn = args.shader.progVar; if ((progDefn.contextDep && contextDynamic) || progDefn.propDep) { emitBatchBody( env, batch, args, null); } else { var PROGRAM = progDefn.append(env, batch); batch(env.shared.gl, '.useProgram(', PROGRAM, '.program);'); if (args.shader.program) { emitBatchBody( env, batch, args, args.shader.program); } else { var batchCache = env.global.def('{}'); var PROG_ID = batch.def(PROGRAM, '.id'); var CACHED_PROC = batch.def(batchCache, '[', PROG_ID, ']'); batch( env.cond(CACHED_PROC) .then(CACHED_PROC, '.call(this,a0,a1);') .else( CACHED_PROC, '=', batchCache, '[', PROG_ID, ']=', env.link(function (program) { return createBody(emitBatchBody, env, args, program, 2) }), '(', PROGRAM, ');', CACHED_PROC, '.call(this,a0,a1);')); } } if (Object.keys(args.state).length > 0) { batch(env.shared.current, '.dirty=true;'); } } // =================================================== // =================================================== // SCOPE COMMAND // =================================================== // =================================================== function emitScopeProc (env, args) { var scope = env.proc('scope', 3); env.batchId = 'a2'; var shared = env.shared; var CURRENT_STATE = shared.current; emitContext(env, scope, args.context); if (args.framebuffer) { args.framebuffer.append(env, scope); } sortState(Object.keys(args.state)).forEach(function (name) { var defn = args.state[name]; var value = defn.append(env, scope); if (isArrayLike(value)) { value.forEach(function (v, i) { scope.set(env.next[name], '[' + i + ']', v); }); } else { scope.set(shared.next, '.' + name, value); } }); emitProfile(env, scope, args, true, true) ;[S_ELEMENTS, S_OFFSET, S_COUNT, S_INSTANCES, S_PRIMITIVE].forEach( function (opt) { var variable = args.draw[opt]; if (!variable) { return } scope.set(shared.draw, '.' + opt, '' + variable.append(env, scope)); }); Object.keys(args.uniforms).forEach(function (opt) { scope.set( shared.uniforms, '[' + stringStore.id(opt) + ']', args.uniforms[opt].append(env, scope)); }); Object.keys(args.attributes).forEach(function (name) { var record = args.attributes[name].append(env, scope); var scopeAttrib = env.scopeAttrib(name); Object.keys(new AttributeRecord()).forEach(function (prop) { scope.set(scopeAttrib, '.' + prop, record[prop]); }); }); function saveShader (name) { var shader = args.shader[name]; if (shader) { scope.set(shared.shader, '.' + name, shader.append(env, scope)); } } saveShader(S_VERT); saveShader(S_FRAG); if (Object.keys(args.state).length > 0) { scope(CURRENT_STATE, '.dirty=true;'); scope.exit(CURRENT_STATE, '.dirty=true;'); } scope('a1(', env.shared.context, ',a0,', env.batchId, ');'); } function isDynamicObject (object) { if (typeof object !== 'object' || isArrayLike(object)) { return } var props = Object.keys(object); for (var i = 0; i < props.length; ++i) { if (dynamic.isDynamic(object[props[i]])) { return true } } return false } function splatObject (env, options, name) { var object = options.static[name]; if (!object || !isDynamicObject(object)) { return } var globals = env.global; var keys = Object.keys(object); var thisDep = false; var contextDep = false; var propDep = false; var objectRef = env.global.def('{}'); keys.forEach(function (key) { var value = object[key]; if (dynamic.isDynamic(value)) { if (typeof value === 'function') { value = object[key] = dynamic.unbox(value); } var deps = createDynamicDecl(value, null); thisDep = thisDep || deps.thisDep; propDep = propDep || deps.propDep; contextDep = contextDep || deps.contextDep; } else { globals(objectRef, '.', key, '='); switch (typeof value) { case 'number': globals(value); break case 'string': globals('"', value, '"'); break case 'object': if (Array.isArray(value)) { globals('[', value.join(), ']'); } break default: globals(env.link(value)); break } globals(';'); } }); function appendBlock (env, block) { keys.forEach(function (key) { var value = object[key]; if (!dynamic.isDynamic(value)) { return } var ref = env.invoke(block, value); block(objectRef, '.', key, '=', ref, ';'); }); } options.dynamic[name] = new dynamic.DynamicVariable(DYN_THUNK, { thisDep: thisDep, contextDep: contextDep, propDep: propDep, ref: objectRef, append: appendBlock }); delete options.static[name]; } // =========================================================================== // =========================================================================== // MAIN DRAW COMMAND // =========================================================================== // =========================================================================== function compileCommand (options, attributes, uniforms, context, stats) { var env = createREGLEnvironment(); // link stats, so that we can easily access it in the program. env.stats = env.link(stats); // splat options and attributes to allow for dynamic nested properties Object.keys(attributes.static).forEach(function (key) { splatObject(env, attributes, key); }); NESTED_OPTIONS.forEach(function (name) { splatObject(env, options, name); }); var args = parseArguments(options, attributes, uniforms, context, env); emitDrawProc(env, args); emitScopeProc(env, args); emitBatchProc(env, args); return env.compile() } // =========================================================================== // =========================================================================== // POLL / REFRESH // =========================================================================== // =========================================================================== return { next: nextState, current: currentState, procs: (function () { var env = createREGLEnvironment(); var poll = env.proc('poll'); var refresh = env.proc('refresh'); var common = env.block(); poll(common); refresh(common); var shared = env.shared; var GL = shared.gl; var NEXT_STATE = shared.next; var CURRENT_STATE = shared.current; common(CURRENT_STATE, '.dirty=false;'); emitPollFramebuffer(env, poll); emitPollFramebuffer(env, refresh, null, true); // Refresh updates all attribute state changes var extInstancing = gl.getExtension('angle_instanced_arrays'); var INSTANCING; if (extInstancing) { INSTANCING = env.link(extInstancing); } for (var i = 0; i < limits.maxAttributes; ++i) { var BINDING = refresh.def(shared.attributes, '[', i, ']'); var ifte = env.cond(BINDING, '.buffer'); ifte.then( GL, '.enableVertexAttribArray(', i, ');', GL, '.bindBuffer(', GL_ARRAY_BUFFER$1, ',', BINDING, '.buffer.buffer);', GL, '.vertexAttribPointer(', i, ',', BINDING, '.size,', BINDING, '.type,', BINDING, '.normalized,', BINDING, '.stride,', BINDING, '.offset);' ).else( GL, '.disableVertexAttribArray(', i, ');', GL, '.vertexAttrib4f(', i, ',', BINDING, '.x,', BINDING, '.y,', BINDING, '.z,', BINDING, '.w);', BINDING, '.buffer=null;'); refresh(ifte); if (extInstancing) { refresh( INSTANCING, '.vertexAttribDivisorANGLE(', i, ',', BINDING, '.divisor);'); } } Object.keys(GL_FLAGS).forEach(function (flag) { var cap = GL_FLAGS[flag]; var NEXT = common.def(NEXT_STATE, '.', flag); var block = env.block(); block('if(', NEXT, '){', GL, '.enable(', cap, ')}else{', GL, '.disable(', cap, ')}', CURRENT_STATE, '.', flag, '=', NEXT, ';'); refresh(block); poll( 'if(', NEXT, '!==', CURRENT_STATE, '.', flag, '){', block, '}'); }); Object.keys(GL_VARIABLES).forEach(function (name) { var func = GL_VARIABLES[name]; var init = currentState[name]; var NEXT, CURRENT; var block = env.block(); block(GL, '.', func, '('); if (isArrayLike(init)) { var n = init.length; NEXT = env.global.def(NEXT_STATE, '.', name); CURRENT = env.global.def(CURRENT_STATE, '.', name); block( loop(n, function (i) { return NEXT + '[' + i + ']' }), ');', loop(n, function (i) { return CURRENT + '[' + i + ']=' + NEXT + '[' + i + '];' }).join('')); poll( 'if(', loop(n, function (i) { return NEXT + '[' + i + ']!==' + CURRENT + '[' + i + ']' }).join('||'), '){', block, '}'); } else { NEXT = common.def(NEXT_STATE, '.', name); CURRENT = common.def(CURRENT_STATE, '.', name); block( NEXT, ');', CURRENT_STATE, '.', name, '=', NEXT, ';'); poll( 'if(', NEXT, '!==', CURRENT, '){', block, '}'); } refresh(block); }); return env.compile() })(), compile: compileCommand } } function stats () { return { bufferCount: 0, elementsCount: 0, framebufferCount: 0, shaderCount: 0, textureCount: 0, cubeCount: 0, renderbufferCount: 0, maxTextureUnits: 0 } } var GL_QUERY_RESULT_EXT = 0x8866; var GL_QUERY_RESULT_AVAILABLE_EXT = 0x8867; var GL_TIME_ELAPSED_EXT = 0x88BF; var createTimer = function (gl, extensions) { var extTimer = extensions.ext_disjoint_timer_query; if (!extTimer) { return null } // QUERY POOL BEGIN var queryPool = []; function allocQuery () { return queryPool.pop() || extTimer.createQueryEXT() } function freeQuery (query) { queryPool.push(query); } // QUERY POOL END var pendingQueries = []; function beginQuery (stats) { var query = allocQuery(); extTimer.beginQueryEXT(GL_TIME_ELAPSED_EXT, query); pendingQueries.push(query); pushScopeStats(pendingQueries.length - 1, pendingQueries.length, stats); } function endQuery () { extTimer.endQueryEXT(GL_TIME_ELAPSED_EXT); } // // Pending stats pool. // function PendingStats () { this.startQueryIndex = -1; this.endQueryIndex = -1; this.sum = 0; this.stats = null; } var pendingStatsPool = []; function allocPendingStats () { return pendingStatsPool.pop() || new PendingStats() } function freePendingStats (pendingStats) { pendingStatsPool.push(pendingStats); } // Pending stats pool end var pendingStats = []; function pushScopeStats (start, end, stats) { var ps = allocPendingStats(); ps.startQueryIndex = start; ps.endQueryIndex = end; ps.sum = 0; ps.stats = stats; pendingStats.push(ps); } // we should call this at the beginning of the frame, // in order to update gpuTime var timeSum = []; var queryPtr = []; function update () { var ptr, i; var n = pendingQueries.length; if (n === 0) { return } // Reserve space queryPtr.length = Math.max(queryPtr.length, n + 1); timeSum.length = Math.max(timeSum.length, n + 1); timeSum[0] = 0; queryPtr[0] = 0; // Update all pending timer queries var queryTime = 0; ptr = 0; for (i = 0; i < pendingQueries.length; ++i) { var query = pendingQueries[i]; if (extTimer.getQueryObjectEXT(query, GL_QUERY_RESULT_AVAILABLE_EXT)) { queryTime += extTimer.getQueryObjectEXT(query, GL_QUERY_RESULT_EXT); freeQuery(query); } else { pendingQueries[ptr++] = query; } timeSum[i + 1] = queryTime; queryPtr[i + 1] = ptr; } pendingQueries.length = ptr; // Update all pending stat queries ptr = 0; for (i = 0; i < pendingStats.length; ++i) { var stats = pendingStats[i]; var start = stats.startQueryIndex; var end = stats.endQueryIndex; stats.sum += timeSum[end] - timeSum[start]; var startPtr = queryPtr[start]; var endPtr = queryPtr[end]; if (endPtr === startPtr) { stats.stats.gpuTime += stats.sum / 1e6; freePendingStats(stats); } else { stats.startQueryIndex = startPtr; stats.endQueryIndex = endPtr; pendingStats[ptr++] = stats; } } pendingStats.length = ptr; } return { beginQuery: beginQuery, endQuery: endQuery, pushScopeStats: pushScopeStats, update: update, getNumPendingQueries: function () { return pendingQueries.length }, clear: function () { queryPool.push.apply(queryPool, pendingQueries); for (var i = 0; i < queryPool.length; i++) { extTimer.deleteQueryEXT(queryPool[i]); } pendingQueries.length = 0; queryPool.length = 0; }, restore: function () { pendingQueries.length = 0; queryPool.length = 0; } } }; var GL_COLOR_BUFFER_BIT = 16384; var GL_DEPTH_BUFFER_BIT = 256; var GL_STENCIL_BUFFER_BIT = 1024; var GL_ARRAY_BUFFER = 34962; var CONTEXT_LOST_EVENT = 'webglcontextlost'; var CONTEXT_RESTORED_EVENT = 'webglcontextrestored'; var DYN_PROP = 1; var DYN_CONTEXT = 2; var DYN_STATE = 3; function find (haystack, needle) { for (var i = 0; i < haystack.length; ++i) { if (haystack[i] === needle) { return i } } return -1 } function wrapREGL (args) { var config = parseArgs(args); if (!config) { return null } var gl = config.gl; var glAttributes = gl.getContextAttributes(); var contextLost = gl.isContextLost(); var extensionState = createExtensionCache(gl, config); if (!extensionState) { return null } var stringStore = createStringStore(); var stats$$1 = stats(); var extensions = extensionState.extensions; var timer = createTimer(gl, extensions); var START_TIME = clock(); var WIDTH = gl.drawingBufferWidth; var HEIGHT = gl.drawingBufferHeight; var contextState = { tick: 0, time: 0, viewportWidth: WIDTH, viewportHeight: HEIGHT, framebufferWidth: WIDTH, framebufferHeight: HEIGHT, drawingBufferWidth: WIDTH, drawingBufferHeight: HEIGHT, pixelRatio: config.pixelRatio }; var uniformState = {}; var drawState = { elements: null, primitive: 4, // GL_TRIANGLES count: -1, offset: 0, instances: -1 }; var limits = wrapLimits(gl, extensions); var bufferState = wrapBufferState(gl, stats$$1, config); var elementState = wrapElementsState(gl, extensions, bufferState, stats$$1); var attributeState = wrapAttributeState( gl, extensions, limits, bufferState, stringStore); var shaderState = wrapShaderState(gl, stringStore, stats$$1, config); var textureState = createTextureSet( gl, extensions, limits, function () { core.procs.poll(); }, contextState, stats$$1, config); var renderbufferState = wrapRenderbuffers(gl, extensions, limits, stats$$1, config); var framebufferState = wrapFBOState( gl, extensions, limits, textureState, renderbufferState, stats$$1); var core = reglCore( gl, stringStore, extensions, limits, bufferState, elementState, textureState, framebufferState, uniformState, attributeState, shaderState, drawState, contextState, timer, config); var readPixels = wrapReadPixels( gl, framebufferState, core.procs.poll, contextState, glAttributes, extensions); var nextState = core.next; var canvas = gl.canvas; var rafCallbacks = []; var lossCallbacks = []; var restoreCallbacks = []; var destroyCallbacks = [config.onDestroy]; var activeRAF = null; function handleRAF () { if (rafCallbacks.length === 0) { if (timer) { timer.update(); } activeRAF = null; return } // schedule next animation frame activeRAF = raf.next(handleRAF); // poll for changes poll(); // fire a callback for all pending rafs for (var i = rafCallbacks.length - 1; i >= 0; --i) { var cb = rafCallbacks[i]; if (cb) { cb(contextState, null, 0); } } // flush all pending webgl calls gl.flush(); // poll GPU timers *after* gl.flush so we don't delay command dispatch if (timer) { timer.update(); } } function startRAF () { if (!activeRAF && rafCallbacks.length > 0) { activeRAF = raf.next(handleRAF); } } function stopRAF () { if (activeRAF) { raf.cancel(handleRAF); activeRAF = null; } } function handleContextLoss (event) { event.preventDefault(); // set context lost flag contextLost = true; // pause request animation frame stopRAF(); // lose context lossCallbacks.forEach(function (cb) { cb(); }); } function handleContextRestored (event) { // clear error code gl.getError(); // clear context lost flag contextLost = false; // refresh state extensionState.restore(); shaderState.restore(); bufferState.restore(); textureState.restore(); renderbufferState.restore(); framebufferState.restore(); if (timer) { timer.restore(); } // refresh state core.procs.refresh(); // restart RAF startRAF(); // restore context restoreCallbacks.forEach(function (cb) { cb(); }); } if (canvas) { canvas.addEventListener(CONTEXT_LOST_EVENT, handleContextLoss, false); canvas.addEventListener(CONTEXT_RESTORED_EVENT, handleContextRestored, false); } function destroy () { rafCallbacks.length = 0; stopRAF(); if (canvas) { canvas.removeEventListener(CONTEXT_LOST_EVENT, handleContextLoss); canvas.removeEventListener(CONTEXT_RESTORED_EVENT, handleContextRestored); } shaderState.clear(); framebufferState.clear(); renderbufferState.clear(); textureState.clear(); elementState.clear(); bufferState.clear(); if (timer) { timer.clear(); } destroyCallbacks.forEach(function (cb) { cb(); }); } function compileProcedure (options) { check$1(!!options, 'invalid args to regl({...})'); check$1.type(options, 'object', 'invalid args to regl({...})'); function flattenNestedOptions (options) { var result = extend({}, options); delete result.uniforms; delete result.attributes; delete result.context; if ('stencil' in result && result.stencil.op) { result.stencil.opBack = result.stencil.opFront = result.stencil.op; delete result.stencil.op; } function merge (name) { if (name in result) { var child = result[name]; delete result[name]; Object.keys(child).forEach(function (prop) { result[name + '.' + prop] = child[prop]; }); } } merge('blend'); merge('depth'); merge('cull'); merge('stencil'); merge('polygonOffset'); merge('scissor'); merge('sample'); return result } function separateDynamic (object) { var staticItems = {}; var dynamicItems = {}; Object.keys(object).forEach(function (option) { var value = object[option]; if (dynamic.isDynamic(value)) { dynamicItems[option] = dynamic.unbox(value, option); } else { staticItems[option] = value; } }); return { dynamic: dynamicItems, static: staticItems } } // Treat context variables separate from other dynamic variables var context = separateDynamic(options.context || {}); var uniforms = separateDynamic(options.uniforms || {}); var attributes = separateDynamic(options.attributes || {}); var opts = separateDynamic(flattenNestedOptions(options)); var stats$$1 = { gpuTime: 0.0, cpuTime: 0.0, count: 0 }; var compiled = core.compile(opts, attributes, uniforms, context, stats$$1); var draw = compiled.draw; var batch = compiled.batch; var scope = compiled.scope; // FIXME: we should modify code generation for batch commands so this // isn't necessary var EMPTY_ARRAY = []; function reserve (count) { while (EMPTY_ARRAY.length < count) { EMPTY_ARRAY.push(null); } return EMPTY_ARRAY } function REGLCommand (args, body) { var i; if (contextLost) { check$1.raise('context lost'); } if (typeof args === 'function') { return scope.call(this, null, args, 0) } else if (typeof body === 'function') { if (typeof args === 'number') { for (i = 0; i < args; ++i) { scope.call(this, null, body, i); } return } else if (Array.isArray(args)) { for (i = 0; i < args.length; ++i) { scope.call(this, args[i], body, i); } return } else { return scope.call(this, args, body, 0) } } else if (typeof args === 'number') { if (args > 0) { return batch.call(this, reserve(args | 0), args | 0) } } else if (Array.isArray(args)) { if (args.length) { return batch.call(this, args, args.length) } } else { return draw.call(this, args) } } return extend(REGLCommand, { stats: stats$$1 }) } var setFBO = framebufferState.setFBO = compileProcedure({ framebuffer: dynamic.define.call(null, DYN_PROP, 'framebuffer') }); function clearImpl (_, options) { var clearFlags = 0; core.procs.poll(); var c = options.color; if (c) { gl.clearColor(+c[0] || 0, +c[1] || 0, +c[2] || 0, +c[3] || 0); clearFlags |= GL_COLOR_BUFFER_BIT; } if ('depth' in options) { gl.clearDepth(+options.depth); clearFlags |= GL_DEPTH_BUFFER_BIT; } if ('stencil' in options) { gl.clearStencil(options.stencil | 0); clearFlags |= GL_STENCIL_BUFFER_BIT; } check$1(!!clearFlags, 'called regl.clear with no buffer specified'); gl.clear(clearFlags); } function clear (options) { check$1( typeof options === 'object' && options, 'regl.clear() takes an object as input'); if ('framebuffer' in options) { if (options.framebuffer && options.framebuffer_reglType === 'framebufferCube') { for (var i = 0; i < 6; ++i) { setFBO(extend({ framebuffer: options.framebuffer.faces[i] }, options), clearImpl); } } else { setFBO(options, clearImpl); } } else { clearImpl(null, options); } } function frame (cb) { check$1.type(cb, 'function', 'regl.frame() callback must be a function'); rafCallbacks.push(cb); function cancel () { // FIXME: should we check something other than equals cb here? // what if a user calls frame twice with the same callback... // var i = find(rafCallbacks, cb); check$1(i >= 0, 'cannot cancel a frame twice'); function pendingCancel () { var index = find(rafCallbacks, pendingCancel); rafCallbacks[index] = rafCallbacks[rafCallbacks.length - 1]; rafCallbacks.length -= 1; if (rafCallbacks.length <= 0) { stopRAF(); } } rafCallbacks[i] = pendingCancel; } startRAF(); return { cancel: cancel } } // poll viewport function pollViewport () { var viewport = nextState.viewport; var scissorBox = nextState.scissor_box; viewport[0] = viewport[1] = scissorBox[0] = scissorBox[1] = 0; contextState.viewportWidth = contextState.framebufferWidth = contextState.drawingBufferWidth = viewport[2] = scissorBox[2] = gl.drawingBufferWidth; contextState.viewportHeight = contextState.framebufferHeight = contextState.drawingBufferHeight = viewport[3] = scissorBox[3] = gl.drawingBufferHeight; } function poll () { contextState.tick += 1; contextState.time = now(); pollViewport(); core.procs.poll(); } function refresh () { pollViewport(); core.procs.refresh(); if (timer) { timer.update(); } } function now () { return (clock() - START_TIME) / 1000.0 } refresh(); function addListener (event, callback) { check$1.type(callback, 'function', 'listener callback must be a function'); var callbacks; switch (event) { case 'frame': return frame(callback) case 'lost': callbacks = lossCallbacks; break case 'restore': callbacks = restoreCallbacks; break case 'destroy': callbacks = destroyCallbacks; break default: check$1.raise('invalid event, must be one of frame,lost,restore,destroy'); } callbacks.push(callback); return { cancel: function () { for (var i = 0; i < callbacks.length; ++i) { if (callbacks[i] === callback) { callbacks[i] = callbacks[callbacks.length - 1]; callbacks.pop(); return } } } } } var regl = extend(compileProcedure, { // Clear current FBO clear: clear, // Short cuts for dynamic variables prop: dynamic.define.bind(null, DYN_PROP), context: dynamic.define.bind(null, DYN_CONTEXT), this: dynamic.define.bind(null, DYN_STATE), // executes an empty draw command draw: compileProcedure({}), // Resources buffer: function (options) { return bufferState.create(options, GL_ARRAY_BUFFER, false, false) }, elements: function (options) { return elementState.create(options, false) }, texture: textureState.create2D, cube: textureState.createCube, renderbuffer: renderbufferState.create, framebuffer: framebufferState.create, framebufferCube: framebufferState.createCube, // Expose context attributes attributes: glAttributes, // Frame rendering frame: frame, on: addListener, // System limits limits: limits, hasExtension: function (name) { return limits.extensions.indexOf(name.toLowerCase()) >= 0 }, // Read pixels read: readPixels, // Destroy regl and all associated resources destroy: destroy, // Direct GL state manipulation _gl: gl, _refresh: refresh, poll: function () { poll(); if (timer) { timer.update(); } }, // Current time now: now, // regl Statistics Information stats: stats$$1 }); config.onDone(null, regl); return regl } return wrapREGL; }))); },{}],77:[function(require,module,exports){ (function (global){ var ClientRequest = require('./lib/request') var extend = require('xtend') var statusCodes = require('builtin-status-codes') var url = require('url') var http = exports http.request = function (opts, cb) { if (typeof opts === 'string') opts = url.parse(opts) else opts = extend(opts) // Normally, the page is loaded from http or https, so not specifying a protocol // will result in a (valid) protocol-relative url. However, this won't work if // the protocol is something else, like 'file:' var defaultProtocol = global.location.protocol.search(/^https?:$/) === -1 ? 'http:' : '' var protocol = opts.protocol || defaultProtocol var host = opts.hostname || opts.host var port = opts.port var path = opts.path || '/' // Necessary for IPv6 addresses if (host && host.indexOf(':') !== -1) host = '[' + host + ']' // This may be a relative url. The browser should always be able to interpret it correctly. opts.url = (host ? (protocol + '//' + host) : '') + (port ? ':' + port : '') + path opts.method = (opts.method || 'GET').toUpperCase() opts.headers = opts.headers || {} // Also valid opts.auth, opts.mode var req = new ClientRequest(opts) if (cb) req.on('response', cb) return req } http.get = function get (opts, cb) { var req = http.request(opts, cb) req.end() return req } http.Agent = function () {} http.Agent.defaultMaxSockets = 4 http.STATUS_CODES = statusCodes http.METHODS = [ 'CHECKOUT', 'CONNECT', 'COPY', 'DELETE', 'GET', 'HEAD', 'LOCK', 'M-SEARCH', 'MERGE', 'MKACTIVITY', 'MKCOL', 'MOVE', 'NOTIFY', 'OPTIONS', 'PATCH', 'POST', 'PROPFIND', 'PROPPATCH', 'PURGE', 'PUT', 'REPORT', 'SEARCH', 'SUBSCRIBE', 'TRACE', 'UNLOCK', 'UNSUBSCRIBE' ] }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{"./lib/request":79,"builtin-status-codes":7,"url":83,"xtend":91}],78:[function(require,module,exports){ (function (global){ exports.fetch = isFunction(global.fetch) && isFunction(global.ReadableStream) exports.blobConstructor = false try { new Blob([new ArrayBuffer(1)]) exports.blobConstructor = true } catch (e) {} // The xhr request to example.com may violate some restrictive CSP configurations, // so if we're running in a browser that supports `fetch`, avoid calling getXHR() // and assume support for certain features below. var xhr function getXHR () { // Cache the xhr value if (xhr !== undefined) return xhr if (global.XMLHttpRequest) { xhr = new global.XMLHttpRequest() // If XDomainRequest is available (ie only, where xhr might not work // cross domain), use the page location. Otherwise use example.com // Note: this doesn't actually make an http request. try { xhr.open('GET', global.XDomainRequest ? '/' : 'https://example.com') } catch(e) { xhr = null } } else { // Service workers don't have XHR xhr = null } return xhr } function checkTypeSupport (type) { var xhr = getXHR() if (!xhr) return false try { xhr.responseType = type return xhr.responseType === type } catch (e) {} return false } // For some strange reason, Safari 7.0 reports typeof global.ArrayBuffer === 'object'. // Safari 7.1 appears to have fixed this bug. var haveArrayBuffer = typeof global.ArrayBuffer !== 'undefined' var haveSlice = haveArrayBuffer && isFunction(global.ArrayBuffer.prototype.slice) // If fetch is supported, then arraybuffer will be supported too. Skip calling // checkTypeSupport(), since that calls getXHR(). exports.arraybuffer = exports.fetch || (haveArrayBuffer && checkTypeSupport('arraybuffer')) // These next two tests unavoidably show warnings in Chrome. Since fetch will always // be used if it's available, just return false for these to avoid the warnings. exports.msstream = !exports.fetch && haveSlice && checkTypeSupport('ms-stream') exports.mozchunkedarraybuffer = !exports.fetch && haveArrayBuffer && checkTypeSupport('moz-chunked-arraybuffer') // If fetch is supported, then overrideMimeType will be supported too. Skip calling // getXHR(). exports.overrideMimeType = exports.fetch || (getXHR() ? isFunction(getXHR().overrideMimeType) : false) exports.vbArray = isFunction(global.VBArray) function isFunction (value) { return typeof value === 'function' } xhr = null // Help gc }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{}],79:[function(require,module,exports){ (function (process,global,Buffer){ var capability = require('./capability') var inherits = require('inherits') var response = require('./response') var stream = require('readable-stream') var toArrayBuffer = require('to-arraybuffer') var IncomingMessage = response.IncomingMessage var rStates = response.readyStates function decideMode (preferBinary, useFetch) { if (capability.fetch && useFetch) { return 'fetch' } else if (capability.mozchunkedarraybuffer) { return 'moz-chunked-arraybuffer' } else if (capability.msstream) { return 'ms-stream' } else if (capability.arraybuffer && preferBinary) { return 'arraybuffer' } else if (capability.vbArray && preferBinary) { return 'text:vbarray' } else { return 'text' } } var ClientRequest = module.exports = function (opts) { var self = this stream.Writable.call(self) self._opts = opts self._body = [] self._headers = {} if (opts.auth) self.setHeader('Authorization', 'Basic ' + new Buffer(opts.auth).toString('base64')) Object.keys(opts.headers).forEach(function (name) { self.setHeader(name, opts.headers[name]) }) var preferBinary var useFetch = true if (opts.mode === 'disable-fetch' || 'timeout' in opts) { // If the use of XHR should be preferred and includes preserving the 'content-type' header. // Force XHR to be used since the Fetch API does not yet support timeouts. useFetch = false preferBinary = true } else if (opts.mode === 'prefer-streaming') { // If streaming is a high priority but binary compatibility and // the accuracy of the 'content-type' header aren't preferBinary = false } else if (opts.mode === 'allow-wrong-content-type') { // If streaming is more important than preserving the 'content-type' header preferBinary = !capability.overrideMimeType } else if (!opts.mode || opts.mode === 'default' || opts.mode === 'prefer-fast') { // Use binary if text streaming may corrupt data or the content-type header, or for speed preferBinary = true } else { throw new Error('Invalid value for opts.mode') } self._mode = decideMode(preferBinary, useFetch) self.on('finish', function () { self._onFinish() }) } inherits(ClientRequest, stream.Writable) ClientRequest.prototype.setHeader = function (name, value) { var self = this var lowerName = name.toLowerCase() // This check is not necessary, but it prevents warnings from browsers about setting unsafe // headers. To be honest I'm not entirely sure hiding these warnings is a good thing, but // http-browserify did it, so I will too. if (unsafeHeaders.indexOf(lowerName) !== -1) return self._headers[lowerName] = { name: name, value: value } } ClientRequest.prototype.getHeader = function (name) { var self = this return self._headers[name.toLowerCase()].value } ClientRequest.prototype.removeHeader = function (name) { var self = this delete self._headers[name.toLowerCase()] } ClientRequest.prototype._onFinish = function () { var self = this if (self._destroyed) return var opts = self._opts var headersObj = self._headers var body = null if (opts.method !== 'GET' && opts.method !== 'HEAD') { if (capability.blobConstructor) { body = new global.Blob(self._body.map(function (buffer) { return toArrayBuffer(buffer) }), { type: (headersObj['content-type'] || {}).value || '' }) } else { // get utf8 string body = Buffer.concat(self._body).toString() } } // create flattened list of headers var headersList = [] Object.keys(headersObj).forEach(function (keyName) { var name = headersObj[keyName].name var value = headersObj[keyName].value if (Array.isArray(value)) { value.forEach(function (v) { headersList.push([name, v]) }) } else { headersList.push([name, value]) } }) if (self._mode === 'fetch') { global.fetch(self._opts.url, { method: self._opts.method, headers: headersList, body: body || undefined, mode: 'cors', credentials: opts.withCredentials ? 'include' : 'same-origin' }).then(function (response) { self._fetchResponse = response self._connect() }, function (reason) { self.emit('error', reason) }) } else { var xhr = self._xhr = new global.XMLHttpRequest() try { xhr.open(self._opts.method, self._opts.url, true) } catch (err) { process.nextTick(function () { self.emit('error', err) }) return } // Can't set responseType on really old browsers if ('responseType' in xhr) xhr.responseType = self._mode.split(':')[0] if ('withCredentials' in xhr) xhr.withCredentials = !!opts.withCredentials if (self._mode === 'text' && 'overrideMimeType' in xhr) xhr.overrideMimeType('text/plain; charset=x-user-defined') if ('timeout' in opts) { xhr.timeout = opts.timeout xhr.ontimeout = function () { self.emit('timeout') } } headersList.forEach(function (header) { xhr.setRequestHeader(header[0], header[1]) }) self._response = null xhr.onreadystatechange = function () { switch (xhr.readyState) { case rStates.LOADING: case rStates.DONE: self._onXHRProgress() break } } // Necessary for streaming in Firefox, since xhr.response is ONLY defined // in onprogress, not in onreadystatechange with xhr.readyState = 3 if (self._mode === 'moz-chunked-arraybuffer') { xhr.onprogress = function () { self._onXHRProgress() } } xhr.onerror = function () { if (self._destroyed) return self.emit('error', new Error('XHR error')) } try { xhr.send(body) } catch (err) { process.nextTick(function () { self.emit('error', err) }) return } } } /** * Checks if xhr.status is readable and non-zero, indicating no error. * Even though the spec says it should be available in readyState 3, * accessing it throws an exception in IE8 */ function statusValid (xhr) { try { var status = xhr.status return (status !== null && status !== 0) } catch (e) { return false } } ClientRequest.prototype._onXHRProgress = function () { var self = this if (!statusValid(self._xhr) || self._destroyed) return if (!self._response) self._connect() self._response._onXHRProgress() } ClientRequest.prototype._connect = function () { var self = this if (self._destroyed) return self._response = new IncomingMessage(self._xhr, self._fetchResponse, self._mode) self._response.on('error', function(err) { self.emit('error', err) }) self.emit('response', self._response) } ClientRequest.prototype._write = function (chunk, encoding, cb) { var self = this self._body.push(chunk) cb() } ClientRequest.prototype.abort = ClientRequest.prototype.destroy = function () { var self = this self._destroyed = true if (self._response) self._response._destroyed = true if (self._xhr) self._xhr.abort() // Currently, there isn't a way to truly abort a fetch. // If you like bikeshedding, see https://github.com/whatwg/fetch/issues/27 } ClientRequest.prototype.end = function (data, encoding, cb) { var self = this if (typeof data === 'function') { cb = data data = undefined } stream.Writable.prototype.end.call(self, data, encoding, cb) } ClientRequest.prototype.flushHeaders = function () {} ClientRequest.prototype.setTimeout = function () {} ClientRequest.prototype.setNoDelay = function () {} ClientRequest.prototype.setSocketKeepAlive = function () {} // Taken from http://www.w3.org/TR/XMLHttpRequest/#the-setrequestheader%28%29-method var unsafeHeaders = [ 'accept-charset', 'accept-encoding', 'access-control-request-headers', 'access-control-request-method', 'connection', 'content-length', 'cookie', 'cookie2', 'date', 'dnt', 'expect', 'host', 'keep-alive', 'origin', 'referer', 'te', 'trailer', 'transfer-encoding', 'upgrade', 'user-agent', 'via' ] }).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer) },{"./capability":78,"./response":80,"_process":61,"buffer":6,"inherits":52,"readable-stream":75,"to-arraybuffer":81}],80:[function(require,module,exports){ (function (process,global,Buffer){ var capability = require('./capability') var inherits = require('inherits') var stream = require('readable-stream') var rStates = exports.readyStates = { UNSENT: 0, OPENED: 1, HEADERS_RECEIVED: 2, LOADING: 3, DONE: 4 } var IncomingMessage = exports.IncomingMessage = function (xhr, response, mode) { var self = this stream.Readable.call(self) self._mode = mode self.headers = {} self.rawHeaders = [] self.trailers = {} self.rawTrailers = [] // Fake the 'close' event, but only once 'end' fires self.on('end', function () { // The nextTick is necessary to prevent the 'request' module from causing an infinite loop process.nextTick(function () { self.emit('close') }) }) if (mode === 'fetch') { self._fetchResponse = response self.url = response.url self.statusCode = response.status self.statusMessage = response.statusText response.headers.forEach(function(header, key){ self.headers[key.toLowerCase()] = header self.rawHeaders.push(key, header) }) // TODO: this doesn't respect backpressure. Once WritableStream is available, this can be fixed var reader = response.body.getReader() function read () { reader.read().then(function (result) { if (self._destroyed) return if (result.done) { self.push(null) return } self.push(new Buffer(result.value)) read() }).catch(function(err) { self.emit('error', err) }) } read() } else { self._xhr = xhr self._pos = 0 self.url = xhr.responseURL self.statusCode = xhr.status self.statusMessage = xhr.statusText var headers = xhr.getAllResponseHeaders().split(/\r?\n/) headers.forEach(function (header) { var matches = header.match(/^([^:]+):\s*(.*)/) if (matches) { var key = matches[1].toLowerCase() if (key === 'set-cookie') { if (self.headers[key] === undefined) { self.headers[key] = [] } self.headers[key].push(matches[2]) } else if (self.headers[key] !== undefined) { self.headers[key] += ', ' + matches[2] } else { self.headers[key] = matches[2] } self.rawHeaders.push(matches[1], matches[2]) } }) self._charset = 'x-user-defined' if (!capability.overrideMimeType) { var mimeType = self.rawHeaders['mime-type'] if (mimeType) { var charsetMatch = mimeType.match(/;\s*charset=([^;])(;|$)/) if (charsetMatch) { self._charset = charsetMatch[1].toLowerCase() } } if (!self._charset) self._charset = 'utf-8' // best guess } } } inherits(IncomingMessage, stream.Readable) IncomingMessage.prototype._read = function () {} IncomingMessage.prototype._onXHRProgress = function () { var self = this var xhr = self._xhr var response = null switch (self._mode) { case 'text:vbarray': // For IE9 if (xhr.readyState !== rStates.DONE) break try { // This fails in IE8 response = new global.VBArray(xhr.responseBody).toArray() } catch (e) {} if (response !== null) { self.push(new Buffer(response)) break } // Falls through in IE8 case 'text': try { // This will fail when readyState = 3 in IE9. Switch mode and wait for readyState = 4 response = xhr.responseText } catch (e) { self._mode = 'text:vbarray' break } if (response.length > self._pos) { var newData = response.substr(self._pos) if (self._charset === 'x-user-defined') { var buffer = new Buffer(newData.length) for (var i = 0; i < newData.length; i++) buffer[i] = newData.charCodeAt(i) & 0xff self.push(buffer) } else { self.push(newData, self._charset) } self._pos = response.length } break case 'arraybuffer': if (xhr.readyState !== rStates.DONE || !xhr.response) break response = xhr.response self.push(new Buffer(new Uint8Array(response))) break case 'moz-chunked-arraybuffer': // take whole response = xhr.response if (xhr.readyState !== rStates.LOADING || !response) break self.push(new Buffer(new Uint8Array(response))) break case 'ms-stream': response = xhr.response if (xhr.readyState !== rStates.LOADING) break var reader = new global.MSStreamReader() reader.onprogress = function () { if (reader.result.byteLength > self._pos) { self.push(new Buffer(new Uint8Array(reader.result.slice(self._pos)))) self._pos = reader.result.byteLength } } reader.onload = function () { self.push(null) } // reader.onerror = ??? // TODO: this reader.readAsArrayBuffer(response) break } // The ms-stream case handles end separately in reader.onload() if (self._xhr.readyState === rStates.DONE && self._mode !== 'ms-stream') { self.push(null) } } }).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer) },{"./capability":78,"_process":61,"buffer":6,"inherits":52,"readable-stream":75}],81:[function(require,module,exports){ var Buffer = require('buffer').Buffer module.exports = function (buf) { // If the buffer is backed by a Uint8Array, a faster version will work if (buf instanceof Uint8Array) { // If the buffer isn't a subarray, return the underlying ArrayBuffer if (buf.byteOffset === 0 && buf.byteLength === buf.buffer.byteLength) { return buf.buffer } else if (typeof buf.buffer.slice === 'function') { // Otherwise we need to get a proper copy return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength) } } if (Buffer.isBuffer(buf)) { // This is the slow version that will work with any Buffer // implementation (even in old browsers) var arrayCopy = new Uint8Array(buf.length) var len = buf.length for (var i = 0; i < len; i++) { arrayCopy[i] = buf[i] } return arrayCopy.buffer } else { throw new Error('Argument must be a Buffer') } } },{"buffer":6}],82:[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', '"', '`', ' ', '\r', '\n', '\t'], // RFC 2396: characters not allowed for various reasons. unwise = ['{', '}', '|', '\\', '^', '`'].concat(delims), // Allowed by RFCs, but cause of XSS attacks. Always escape these. autoEscape = ['\''].concat(unwise), // Characters that are never ever allowed in a hostname. // Note that any invalid chars are also handled, but these // are the ones that are *expected* to be seen, so we fast-path // them. nonHostChars = ['%', '/', '?', ';', '#'].concat(autoEscape), hostEndingChars = ['/', '?', '#'], hostnameMaxLen = 255, hostnamePartPattern = /^[+a-z0-9A-Z_-]{0,63}$/, hostnamePartStart = /^([+a-z0-9A-Z_-]{0,63})(.*)$/, // protocols that can allow "unsafe" and "unwise" chars. unsafeProtocol = { 'javascript': true, 'javascript:': true }, // protocols that never have a hostname. hostlessProtocol = { 'javascript': true, 'javascript:': true }, // protocols that always contain a // bit. slashedProtocol = { 'http': true, 'https': true, 'ftp': true, 'gopher': true, 'file': true, 'http:': true, 'https:': true, 'ftp:': true, 'gopher:': true, 'file:': true }, querystring = require('querystring'); function urlParse(url, parseQueryString, slashesDenoteHost) { if (url && util.isObject(url) && url instanceof Url) return url; var u = new Url; u.parse(url, parseQueryString, slashesDenoteHost); return u; } Url.prototype.parse = function(url, parseQueryString, slashesDenoteHost) { if (!util.isString(url)) { throw new TypeError("Parameter 'url' must be a string, not " + typeof url); } // Copy chrome, IE, opera backslash-handling behavior. // Back slashes before the query string get converted to forward slashes // See: https://code.google.com/p/chromium/issues/detail?id=25916 var queryIndex = url.indexOf('?'), splitter = (queryIndex !== -1 && queryIndex < url.indexOf('#')) ? '?' : '#', uSplit = url.split(splitter), slashRegex = /\\/g; uSplit[0] = uSplit[0].replace(slashRegex, '/'); url = uSplit.join(splitter); var rest = url; // trim before proceeding. // This is to support parse stuff like " http://foo.com \n" rest = rest.trim(); if (!slashesDenoteHost && url.split('#').length === 1) { // Try fast path regexp var simplePath = simplePathPattern.exec(rest); if (simplePath) { this.path = rest; this.href = rest; this.pathname = simplePath[1]; if (simplePath[2]) { this.search = simplePath[2]; if (parseQueryString) { this.query = querystring.parse(this.search.substr(1)); } else { this.query = this.search.substr(1); } } else if (parseQueryString) { this.search = ''; this.query = {}; } return this; } } var proto = protocolPattern.exec(rest); if (proto) { proto = proto[0]; var lowerProto = proto.toLowerCase(); this.protocol = lowerProto; rest = rest.substr(proto.length); } // figure out if it's got a host // user@server is *always* interpreted as a hostname, and url // resolution will treat //foo/bar as host=foo,path=bar because that's // how the browser resolves relative URLs. if (slashesDenoteHost || proto || rest.match(/^\/\/[^@\/]+@[^@\/]+/)) { var slashes = rest.substr(0, 2) === '//'; if (slashes && !(proto && hostlessProtocol[proto])) { rest = rest.substr(2); this.slashes = true; } } if (!hostlessProtocol[proto] && (slashes || (proto && !slashedProtocol[proto]))) { // there's a hostname. // the first instance of /, ?, ;, or # ends the host. // // If there is an @ in the hostname, then non-host chars *are* allowed // to the left of the last @ sign, unless some host-ending character // comes *before* the @-sign. // URLs are obnoxious. // // ex: // http://a@b@c/ => user:a@b host:c // http://a@b?@c => user:a host:c path:/?@c // v0.12 TODO(isaacs): This is not quite how Chrome does things. // Review our test case against browsers more comprehensively. // find the first instance of any hostEndingChars var hostEnd = -1; for (var i = 0; i < hostEndingChars.length; i++) { var hec = rest.indexOf(hostEndingChars[i]); if (hec !== -1 && (hostEnd === -1 || hec < hostEnd)) hostEnd = hec; } // at this point, either we have an explicit point where the // auth portion cannot go past, or the last @ char is the decider. var auth, atSign; if (hostEnd === -1) { // atSign can be anywhere. atSign = rest.lastIndexOf('@'); } else { // atSign must be in auth portion. // http://a@b/c@d => host:b auth:a path:/c@d atSign = rest.lastIndexOf('@', hostEnd); } // Now we have a portion which is definitely the auth. // Pull that off. if (atSign !== -1) { auth = rest.slice(0, atSign); rest = rest.slice(atSign + 1); this.auth = decodeURIComponent(auth); } // the host is the remaining to the left of the first non-host char hostEnd = -1; for (var i = 0; i < nonHostChars.length; i++) { var hec = rest.indexOf(nonHostChars[i]); if (hec !== -1 && (hostEnd === -1 || hec < hostEnd)) hostEnd = hec; } // if we still have not hit it, then the entire thing is a host. if (hostEnd === -1) hostEnd = rest.length; this.host = rest.slice(0, hostEnd); rest = rest.slice(hostEnd); // pull out port. this.parseHost(); // we've indicated that there is a hostname, // so even if it's empty, it has to be present. this.hostname = this.hostname || ''; // if hostname begins with [ and ends with ] // assume that it's an IPv6 address. var ipv6Hostname = this.hostname[0] === '[' && this.hostname[this.hostname.length - 1] === ']'; // validate a little. if (!ipv6Hostname) { var hostparts = this.hostname.split(/\./); for (var i = 0, l = hostparts.length; i < l; i++) { var part = hostparts[i]; if (!part) continue; if (!part.match(hostnamePartPattern)) { var newpart = ''; for (var j = 0, k = part.length; j < k; j++) { if (part.charCodeAt(j) > 127) { // we replace non-ASCII char with a temporary placeholder // we need this to make sure size of hostname is not // broken by replacing non-ASCII by nothing newpart += 'x'; } else { newpart += part[j]; } } // we test again with ASCII char only if (!newpart.match(hostnamePartPattern)) { var validParts = hostparts.slice(0, i); var notHost = hostparts.slice(i + 1); var bit = part.match(hostnamePartStart); if (bit) { validParts.push(bit[1]); notHost.unshift(bit[2]); } if (notHost.length) { rest = '/' + notHost.join('.') + rest; } this.hostname = validParts.join('.'); break; } } } } if (this.hostname.length > hostnameMaxLen) { this.hostname = ''; } else { // hostnames are always lower case. this.hostname = this.hostname.toLowerCase(); } if (!ipv6Hostname) { // IDNA Support: Returns a punycoded representation of "domain". // It only converts parts of the domain name that // have non-ASCII characters, i.e. it doesn't matter if // you call it with a domain that already is ASCII-only. this.hostname = punycode.toASCII(this.hostname); } var p = this.port ? ':' + this.port : ''; var h = this.hostname || ''; this.host = h + p; this.href += this.host; // strip [ and ] from the hostname // the host field still retains them, though if (ipv6Hostname) { this.hostname = this.hostname.substr(1, this.hostname.length - 2); if (rest[0] !== '/') { rest = '/' + rest; } } } // now rest is set to the post-host stuff. // chop off any delim chars. if (!unsafeProtocol[lowerProto]) { // First, make 100% sure that any "autoEscape" chars get // escaped, even if encodeURIComponent doesn't think they // need to be. for (var i = 0, l = autoEscape.length; i < l; i++) { var ae = autoEscape[i]; if (rest.indexOf(ae) === -1) continue; var esc = encodeURIComponent(ae); if (esc === ae) { esc = escape(ae); } rest = rest.split(ae).join(esc); } } // chop off from the tail first. var hash = rest.indexOf('#'); if (hash !== -1) { // got a fragment string. this.hash = rest.substr(hash); rest = rest.slice(0, hash); } var qm = rest.indexOf('?'); if (qm !== -1) { this.search = rest.substr(qm); this.query = rest.substr(qm + 1); if (parseQueryString) { this.query = querystring.parse(this.query); } rest = rest.slice(0, qm); } else if (parseQueryString) { // no query string, but parseQueryString still requested this.search = ''; this.query = {}; } if (rest) this.pathname = rest; if (slashedProtocol[lowerProto] && this.hostname && !this.pathname) { this.pathname = '/'; } //to support http.request if (this.pathname || this.search) { var p = this.pathname || ''; var s = this.search || ''; this.path = p + s; } // finally, reconstruct the href based on what has been validated. this.href = this.format(); return this; }; // format a parsed object into a url string function urlFormat(obj) { // ensure it's an object, and not a string url. // If it's an obj, this is a no-op. // this way, you can call url_format() on strings // to clean up potentially wonky urls. if (util.isString(obj)) obj = urlParse(obj); if (!(obj instanceof Url)) return Url.prototype.format.call(obj); return obj.format(); } Url.prototype.format = function() { var auth = this.auth || ''; if (auth) { auth = encodeURIComponent(auth); auth = auth.replace(/%3A/i, ':'); auth += '@'; } var protocol = this.protocol || '', pathname = this.pathname || '', hash = this.hash || '', host = false, query = ''; if (this.host) { host = auth + this.host; } else if (this.hostname) { host = auth + (this.hostname.indexOf(':') === -1 ? this.hostname : '[' + this.hostname + ']'); if (this.port) { host += ':' + this.port; } } if (this.query && util.isObject(this.query) && Object.keys(this.query).length) { query = querystring.stringify(this.query); } var search = this.search || (query && ('?' + query)) || ''; if (protocol && protocol.substr(-1) !== ':') protocol += ':'; // only the slashedProtocols get the //. Not mailto:, xmpp:, etc. // unless they had them to begin with. if (this.slashes || (!protocol || slashedProtocol[protocol]) && host !== false) { host = '//' + (host || ''); if (pathname && pathname.charAt(0) !== '/') pathname = '/' + pathname; } else if (!host) { host = ''; } if (hash && hash.charAt(0) !== '#') hash = '#' + hash; if (search && search.charAt(0) !== '?') search = '?' + search; pathname = pathname.replace(/[?#]/g, function(match) { return encodeURIComponent(match); }); search = search.replace('#', '%23'); return protocol + host + pathname + search + hash; }; function urlResolve(source, relative) { return urlParse(source, false, true).resolve(relative); } Url.prototype.resolve = function(relative) { return this.resolveObject(urlParse(relative, false, true)).format(); }; function urlResolveObject(source, relative) { if (!source) return relative; return urlParse(source, false, true).resolveObject(relative); } Url.prototype.resolveObject = function(relative) { if (util.isString(relative)) { var rel = new Url(); rel.parse(relative, false, true); relative = rel; } var result = new Url(); var tkeys = Object.keys(this); for (var tk = 0; tk < tkeys.length; tk++) { var tkey = tkeys[tk]; result[tkey] = this[tkey]; } // hash is always overridden, no matter what. // even href="" will remove it. result.hash = relative.hash; // if the relative url is empty, then there's nothing left to do here. if (relative.href === '') { result.href = result.format(); return result; } // hrefs like //foo/bar always cut to the protocol. if (relative.slashes && !relative.protocol) { // take everything except the protocol from relative var rkeys = Object.keys(relative); for (var rk = 0; rk < rkeys.length; rk++) { var rkey = rkeys[rk]; if (rkey !== 'protocol') result[rkey] = relative[rkey]; } //urlParse appends trailing / to urls like http://www.example.com if (slashedProtocol[result.protocol] && result.hostname && !result.pathname) { result.path = result.pathname = '/'; } result.href = result.format(); return result; } if (relative.protocol && relative.protocol !== result.protocol) { // if it's a known url protocol, then changing // the protocol does weird things // first, if it's not file:, then we MUST have a host, // and if there was a path // to begin with, then we MUST have a path. // if it is file:, then the host is dropped, // because that's known to be hostless. // anything else is assumed to be absolute. if (!slashedProtocol[relative.protocol]) { var keys = Object.keys(relative); for (var v = 0; v < keys.length; v++) { var k = keys[v]; result[k] = relative[k]; } result.href = result.format(); return result; } result.protocol = relative.protocol; if (!relative.host && !hostlessProtocol[relative.protocol]) { var relPath = (relative.pathname || '').split('/'); while (relPath.length && !(relative.host = relPath.shift())); if (!relative.host) relative.host = ''; if (!relative.hostname) relative.hostname = ''; if (relPath[0] !== '') relPath.unshift(''); if (relPath.length < 2) relPath.unshift(''); result.pathname = relPath.join('/'); } else { result.pathname = relative.pathname; } result.search = relative.search; result.query = relative.query; result.host = relative.host || ''; result.auth = relative.auth; result.hostname = relative.hostname || relative.host; result.port = relative.port; // to support http.request if (result.pathname || result.search) { var p = result.pathname || ''; var s = result.search || ''; result.path = p + s; } result.slashes = result.slashes || relative.slashes; result.href = result.format(); return result; } var isSourceAbs = (result.pathname && result.pathname.charAt(0) === '/'), isRelAbs = ( relative.host || relative.pathname && relative.pathname.charAt(0) === '/' ), mustEndAbs = (isRelAbs || isSourceAbs || (result.host && relative.pathname)), removeAllDots = mustEndAbs, srcPath = result.pathname && result.pathname.split('/') || [], relPath = relative.pathname && relative.pathname.split('/') || [], psychotic = result.protocol && !slashedProtocol[result.protocol]; // if the url is a non-slashed url, then relative // links like ../.. should be able // to crawl up to the hostname, as well. This is strange. // result.protocol has already been set by now. // Later on, put the first path part into the host field. if (psychotic) { result.hostname = ''; result.port = null; if (result.host) { if (srcPath[0] === '') srcPath[0] = result.host; else srcPath.unshift(result.host); } result.host = ''; if (relative.protocol) { relative.hostname = null; relative.port = null; if (relative.host) { if (relPath[0] === '') relPath[0] = relative.host; else relPath.unshift(relative.host); } relative.host = null; } mustEndAbs = mustEndAbs && (relPath[0] === '' || srcPath[0] === ''); } if (isRelAbs) { // it's absolute. result.host = (relative.host || relative.host === '') ? relative.host : result.host; result.hostname = (relative.hostname || relative.hostname === '') ? relative.hostname : result.hostname; result.search = relative.search; result.query = relative.query; srcPath = relPath; // fall through to the dot-handling below. } else if (relPath.length) { // it's relative // throw away the existing file, and take the new path instead. if (!srcPath) srcPath = []; srcPath.pop(); srcPath = srcPath.concat(relPath); result.search = relative.search; result.query = relative.query; } else if (!util.isNullOrUndefined(relative.search)) { // just pull out the search. // like href='?foo'. // Put this after the other two cases because it simplifies the booleans if (psychotic) { result.hostname = result.host = srcPath.shift(); //occationaly the auth can get stuck only in host //this especially happens in cases like //url.resolveObject('mailto:local1@domain1', 'local2@domain2') var authInHost = result.host && result.host.indexOf('@') > 0 ? result.host.split('@') : false; if (authInHost) { result.auth = authInHost.shift(); result.host = result.hostname = authInHost.shift(); } } result.search = relative.search; result.query = relative.query; //to support http.request if (!util.isNull(result.pathname) || !util.isNull(result.search)) { result.path = (result.pathname ? result.pathname : '') + (result.search ? result.search : ''); } result.href = result.format(); return result; } if (!srcPath.length) { // no path at all. easy. // we've already handled the other stuff above. result.pathname = null; //to support http.request if (result.search) { result.path = '/' + result.search; } else { result.path = null; } result.href = result.format(); return result; } // if a url ENDs in . or .., then it must get a trailing slash. // however, if it ends in anything else non-slashy, // then it must NOT get a trailing slash. var last = srcPath.slice(-1)[0]; var hasTrailingSlash = ( (result.host || relative.host || srcPath.length > 1) && (last === '.' || last === '..') || last === ''); // strip single dots, resolve double dots to parent dir // if the path tries to go above the root, `up` ends up > 0 var up = 0; for (var i = srcPath.length; i >= 0; i--) { last = srcPath[i]; if (last === '.') { srcPath.splice(i, 1); } else if (last === '..') { srcPath.splice(i, 1); up++; } else if (up) { srcPath.splice(i, 1); up--; } } // if the path is allowed to go above the root, restore leading ..s if (!mustEndAbs && !removeAllDots) { for (; up--; up) { srcPath.unshift('..'); } } if (mustEndAbs && srcPath[0] !== '' && (!srcPath[0] || srcPath[0].charAt(0) !== '/')) { srcPath.unshift(''); } if (hasTrailingSlash && (srcPath.join('/').substr(-1) !== '/')) { srcPath.push(''); } var isAbsolute = srcPath[0] === '' || (srcPath[0] && srcPath[0].charAt(0) === '/'); // put the host back if (psychotic) { result.hostname = result.host = isAbsolute ? '' : srcPath.length ? srcPath.shift() : ''; //occationaly the auth can get stuck only in host //this especially happens in cases like //url.resolveObject('mailto:local1@domain1', 'local2@domain2') var authInHost = result.host && result.host.indexOf('@') > 0 ? result.host.split('@') : false; if (authInHost) { result.auth = authInHost.shift(); result.host = result.hostname = authInHost.shift(); } } mustEndAbs = mustEndAbs || (result.host && srcPath.length); if (mustEndAbs && !isAbsolute) { srcPath.unshift(''); } if (!srcPath.length) { result.pathname = null; result.path = null; } else { result.pathname = srcPath.join('/'); } //to support request.http if (!util.isNull(result.pathname) || !util.isNull(result.search)) { result.path = (result.pathname ? result.pathname : '') + (result.search ? result.search : ''); } result.auth = relative.auth || result.auth; result.slashes = result.slashes || relative.slashes; result.href = result.format(); return result; }; Url.prototype.parseHost = function() { var host = this.host; var port = portPattern.exec(host); if (port) { port = port[0]; if (port !== ':') { this.port = port.substr(1); } host = host.substr(0, host.length - port.length); } if (host) this.hostname = host; }; },{"./util":84,"punycode":62,"querystring":65}],84:[function(require,module,exports){ 'use strict'; module.exports = { isString: function(arg) { return typeof(arg) === 'string'; }, isObject: function(arg) { return typeof(arg) === 'object' && arg !== null; }, isNull: function(arg) { return arg === null; }, isNullOrUndefined: function(arg) { return arg == null; } }; },{}],85:[function(require,module,exports){ (function (global){ /** * Module exports. */ module.exports = deprecate; /** * Mark that a method should not be used. * Returns a modified function which warns once by default. * * If `localStorage.noDeprecation = true` is set, then it is a no-op. * * If `localStorage.throwDeprecation = true` is set, then deprecated functions * will throw an Error when invoked. * * If `localStorage.traceDeprecation = true` is set, then deprecated functions * will invoke `console.trace()` instead of `console.error()`. * * @param {Function} fn - the function to deprecate * @param {String} msg - the string to print to the console when `fn` is invoked * @returns {Function} a new "deprecated" version of `fn` * @api public */ function deprecate (fn, msg) { if (config('noDeprecation')) { return fn; } var warned = false; function deprecated() { if (!warned) { if (config('throwDeprecation')) { throw new Error(msg); } else if (config('traceDeprecation')) { console.trace(msg); } else { console.warn(msg); } warned = true; } return fn.apply(this, arguments); } return deprecated; } /** * Checks `localStorage` for boolean values for the given `name`. * * @param {String} name * @returns {Boolean} * @api private */ function config (name) { // accessing global.localStorage can trigger a DOMException in sandboxed iframes try { if (!global.localStorage) return false; } catch (_) { return false; } var val = global.localStorage[name]; if (null == val) return false; return String(val).toLowerCase() === 'true'; } }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{}],86:[function(require,module,exports){ /** * * VALIDATE: boolean * * * DESCRIPTION: * - Validates if a value is a boolean. * * * NOTES: * [1] * * * TODO: * [1] * * * LICENSE: * MIT * * Copyright (c) 2014. Athan Reines. * * * AUTHOR: * Athan Reines. kgryte@gmail.com. 2014. * */ 'use strict'; /** * FUNCTION: isBoolean( value ) * Validates if a value is a boolean. * * @param {*} value - value to be validated * @returns {Boolean} boolean indicating whether value is a boolean */ function isBoolean( value ) { return ( typeof value === 'boolean' || Object.prototype.toString.call( value ) === '[object Boolean]' ); } // end FUNCTION isBoolean() // EXPORTS // module.exports = isBoolean; },{}],87:[function(require,module,exports){ /** * * VALIDATE: integer * * * DESCRIPTION: * - Validates if a value is an integer. * * * NOTES: * [1] * * * TODO: * [1] * * * LICENSE: * MIT * * Copyright (c) 2014. Athan Reines. * * * AUTHOR: * Athan Reines. kgryte@gmail.com. 2014. * */ 'use strict'; // MODULES // var isNumber = require( 'validate.io-number' ); // ISINTEGER // /** * FUNCTION: isInteger( value ) * Validates if a value is an integer. * * @param {Number} value - value to be validated * @returns {Boolean} boolean indicating whether value is an integer */ function isInteger( value ) { return isNumber( value ) && value%1 === 0; } // end FUNCTION isInteger() // EXPORTS // module.exports = isInteger; },{"validate.io-number":89}],88:[function(require,module,exports){ /** * * VALIDATE: nonnegative-integer * * * DESCRIPTION: * - Validates if a value is a nonnegative integer. * * * NOTES: * [1] * * * TODO: * [1] * * * LICENSE: * MIT * * Copyright (c) 2015. Athan Reines. * * * AUTHOR: * Athan Reines. kgryte@gmail.com. 2015. * */ 'use strict'; // MODULES // var isInteger = require( 'validate.io-integer' ); // IS NONNEGATIVE INTEGER // /** * FUNCTION: isNonNegativeInteger( value ) * Validates if a value is a nonnegative integer. * * @param {*} value - value to be validated * @returns {Boolean} boolean indicating if a value is a nonnegative integer */ function isNonNegativeInteger( value ) { return isInteger( value ) && value >= 0; } // end FUNCTION isNonNegativeInteger() // EXPORTS // module.exports = isNonNegativeInteger; },{"validate.io-integer":87}],89:[function(require,module,exports){ /** * * VALIDATE: number * * * DESCRIPTION: * - Validates if a value is a number. * * * NOTES: * [1] * * * TODO: * [1] * * * LICENSE: * MIT * * Copyright (c) 2014. Athan Reines. * * * AUTHOR: * Athan Reines. kgryte@gmail.com. 2014. * */ 'use strict'; /** * FUNCTION: isNumber( value ) * Validates if a value is a number. * * @param {*} value - value to be validated * @returns {Boolean} boolean indicating whether value is a number */ function isNumber( value ) { return ( typeof value === 'number' || Object.prototype.toString.call( value ) === '[object Number]' ) && value.valueOf() === value.valueOf(); } // end FUNCTION isNumber() // EXPORTS // module.exports = isNumber; },{}],90:[function(require,module,exports){ (function (process,Buffer){ /** * Wrapper for built-in http.js to emulate the browser XMLHttpRequest object. * * This can be used with JS designed for browsers to improve reuse of code and * allow the use of existing libraries. * * Usage: include("XMLHttpRequest.js") and use XMLHttpRequest per W3C specs. * * @author Dan DeFelippi * @contributor David Ellis * @license MIT */ var Url = require("url"); var spawn = require("child_process").spawn; var fs = require("fs"); exports.XMLHttpRequest = function() { "use strict"; /** * Private variables */ var self = this; var http = require("http"); var https = require("https"); // Holds http.js objects var request; var response; // Request settings var settings = {}; // Disable header blacklist. // Not part of XHR specs. var disableHeaderCheck = false; // Set some default headers var defaultHeaders = { "User-Agent": "node-XMLHttpRequest", "Accept": "*/*", }; var headers = {}; var headersCase = {}; // These headers are not user setable. // The following are allowed but banned in the spec: // * user-agent var forbiddenRequestHeaders = [ "accept-charset", "accept-encoding", "access-control-request-headers", "access-control-request-method", "connection", "content-length", "content-transfer-encoding", "cookie", "cookie2", "date", "expect", "host", "keep-alive", "origin", "referer", "te", "trailer", "transfer-encoding", "upgrade", "via" ]; // These request methods are not allowed var forbiddenRequestMethods = [ "TRACE", "TRACK", "CONNECT" ]; // Send flag var sendFlag = false; // Error flag, used when errors occur or abort is called var errorFlag = false; // Event listeners var listeners = {}; /** * Constants */ this.UNSENT = 0; this.OPENED = 1; this.HEADERS_RECEIVED = 2; this.LOADING = 3; this.DONE = 4; /** * Public vars */ // Current state this.readyState = this.UNSENT; // default ready state change handler in case one is not set or is set late this.onreadystatechange = null; // Result & response this.responseText = ""; this.responseXML = ""; this.status = null; this.statusText = null; // Whether cross-site Access-Control requests should be made using // credentials such as cookies or authorization headers this.withCredentials = false; /** * Private methods */ /** * Check if the specified header is allowed. * * @param string header Header to validate * @return boolean False if not allowed, otherwise true */ var isAllowedHttpHeader = function(header) { return disableHeaderCheck || (header && forbiddenRequestHeaders.indexOf(header.toLowerCase()) === -1); }; /** * Check if the specified method is allowed. * * @param string method Request method to validate * @return boolean False if not allowed, otherwise true */ var isAllowedHttpMethod = function(method) { return (method && forbiddenRequestMethods.indexOf(method) === -1); }; /** * Public methods */ /** * Open the connection. Currently supports local server requests. * * @param string method Connection method (eg GET, POST) * @param string url URL for the connection. * @param boolean async Asynchronous connection. Default is true. * @param string user Username for basic authentication (optional) * @param string password Password for basic authentication (optional) */ this.open = function(method, url, async, user, password) { this.abort(); errorFlag = false; // Check for valid request method if (!isAllowedHttpMethod(method)) { throw new Error("SecurityError: Request method not allowed"); } settings = { "method": method, "url": url.toString(), "async": (typeof async !== "boolean" ? true : async), "user": user || null, "password": password || null }; setState(this.OPENED); }; /** * Disables or enables isAllowedHttpHeader() check the request. Enabled by default. * This does not conform to the W3C spec. * * @param boolean state Enable or disable header checking. */ this.setDisableHeaderCheck = function(state) { disableHeaderCheck = state; }; /** * Sets a header for the request or appends the value if one is already set. * * @param string header Header name * @param string value Header value */ this.setRequestHeader = function(header, value) { if (this.readyState !== this.OPENED) { throw new Error("INVALID_STATE_ERR: setRequestHeader can only be called when state is OPEN"); } if (!isAllowedHttpHeader(header)) { console.warn("Refused to set unsafe header \"" + header + "\""); return; } if (sendFlag) { throw new Error("INVALID_STATE_ERR: send flag is true"); } header = headersCase[header.toLowerCase()] || header; headersCase[header.toLowerCase()] = header; headers[header] = headers[header] ? headers[header] + ', ' + value : value; }; /** * Gets a header from the server response. * * @param string header Name of header to get. * @return string Text of the header or null if it doesn't exist. */ this.getResponseHeader = function(header) { if (typeof header === "string" && this.readyState > this.OPENED && response && response.headers && response.headers[header.toLowerCase()] && !errorFlag ) { return response.headers[header.toLowerCase()]; } return null; }; /** * Gets all the response headers. * * @return string A string with all response headers separated by CR+LF */ this.getAllResponseHeaders = function() { if (this.readyState < this.HEADERS_RECEIVED || errorFlag) { return ""; } var result = ""; for (var i in response.headers) { // Cookie headers are excluded if (i !== "set-cookie" && i !== "set-cookie2") { result += i + ": " + response.headers[i] + "\r\n"; } } return result.substr(0, result.length - 2); }; /** * Gets a request header * * @param string name Name of header to get * @return string Returns the request header or empty string if not set */ this.getRequestHeader = function(name) { if (typeof name === "string" && headersCase[name.toLowerCase()]) { return headers[headersCase[name.toLowerCase()]]; } return ""; }; /** * Sends the request to the server. * * @param string data Optional data to send as request body. */ this.send = function(data) { if (this.readyState !== this.OPENED) { throw new Error("INVALID_STATE_ERR: connection must be opened before send() is called"); } if (sendFlag) { throw new Error("INVALID_STATE_ERR: send has already been called"); } var ssl = false, local = false; var url = Url.parse(settings.url); var host; // Determine the server switch (url.protocol) { case "https:": ssl = true; // SSL & non-SSL both need host, no break here. case "http:": host = url.hostname; break; case "file:": local = true; break; case undefined: case null: case "": host = "localhost"; break; default: throw new Error("Protocol not supported."); } // Load files off the local filesystem (file://) if (local) { if (settings.method !== "GET") { throw new Error("XMLHttpRequest: Only GET method is supported"); } if (settings.async) { fs.readFile(url.pathname, "utf8", function(error, data) { if (error) { self.handleError(error); } else { self.status = 200; self.responseText = data; setState(self.DONE); } }); } else { try { this.responseText = fs.readFileSync(url.pathname, "utf8"); this.status = 200; setState(self.DONE); } catch(e) { this.handleError(e); } } return; } // Default to port 80. If accessing localhost on another port be sure // to use http://localhost:port/path var port = url.port || (ssl ? 443 : 80); // Add query string if one is used var uri = url.pathname + (url.search ? url.search : ""); // Set the defaults if they haven't been set for (var name in defaultHeaders) { if (!headersCase[name.toLowerCase()]) { headers[name] = defaultHeaders[name]; } } // Set the Host header or the server may reject the request headers.Host = host; if (!((ssl && port === 443) || port === 80)) { headers.Host += ":" + url.port; } // Set Basic Auth if necessary if (settings.user) { if (typeof settings.password === "undefined") { settings.password = ""; } var authBuf = new Buffer(settings.user + ":" + settings.password); headers.Authorization = "Basic " + authBuf.toString("base64"); } // Set content length header if (settings.method === "GET" || settings.method === "HEAD") { data = null; } else if (data) { headers["Content-Length"] = Buffer.isBuffer(data) ? data.length : Buffer.byteLength(data); if (!headers["Content-Type"]) { headers["Content-Type"] = "text/plain;charset=UTF-8"; } } else if (settings.method === "POST") { // For a post with no data set Content-Length: 0. // This is required by buggy servers that don't meet the specs. headers["Content-Length"] = 0; } var options = { host: host, port: port, path: uri, method: settings.method, headers: headers, agent: false, withCredentials: self.withCredentials }; // Reset error flag errorFlag = false; // Handle async requests if (settings.async) { // Use the proper protocol var doRequest = ssl ? https.request : http.request; // Request is being sent, set send flag sendFlag = true; // As per spec, this is called here for historical reasons. self.dispatchEvent("readystatechange"); // Handler for the response var responseHandler = function responseHandler(resp) { // Set response var to the response we got back // This is so it remains accessable outside this scope response = resp; // Check for redirect // @TODO Prevent looped redirects if (response.statusCode === 301 || response.statusCode === 302 || response.statusCode === 303 || response.statusCode === 307) { // Change URL to the redirect location settings.url = response.headers.location; var url = Url.parse(settings.url); // Set host var in case it's used later host = url.hostname; // Options for the new request var newOptions = { hostname: url.hostname, port: url.port, path: url.path, method: response.statusCode === 303 ? "GET" : settings.method, headers: headers, withCredentials: self.withCredentials }; // Issue the new request request = doRequest(newOptions, responseHandler).on("error", errorHandler); request.end(); // @TODO Check if an XHR event needs to be fired here return; } response.setEncoding("utf8"); setState(self.HEADERS_RECEIVED); self.status = response.statusCode; response.on("data", function(chunk) { // Make sure there's some data if (chunk) { self.responseText += chunk; } // Don't emit state changes if the connection has been aborted. if (sendFlag) { setState(self.LOADING); } }); response.on("end", function() { if (sendFlag) { // Discard the end event if the connection has been aborted setState(self.DONE); sendFlag = false; } }); response.on("error", function(error) { self.handleError(error); }); }; // Error handler for the request var errorHandler = function errorHandler(error) { self.handleError(error); }; // Create the request request = doRequest(options, responseHandler).on("error", errorHandler); // Node 0.4 and later won't accept empty data. Make sure it's needed. if (data) { request.write(data); } request.end(); self.dispatchEvent("loadstart"); } else { // Synchronous // Create a temporary file for communication with the other Node process var contentFile = ".node-xmlhttprequest-content-" + process.pid; var syncFile = ".node-xmlhttprequest-sync-" + process.pid; fs.writeFileSync(syncFile, "", "utf8"); // The async request the other Node process executes var execString = "var http = require('http'), https = require('https'), fs = require('fs');" + "var doRequest = http" + (ssl ? "s" : "") + ".request;" + "var options = " + JSON.stringify(options) + ";" + "var responseText = '';" + "var req = doRequest(options, function(response) {" + "response.setEncoding('utf8');" + "response.on('data', function(chunk) {" + " responseText += chunk;" + "});" + "response.on('end', function() {" + "fs.writeFileSync('" + contentFile + "', JSON.stringify({err: null, data: {statusCode: response.statusCode, headers: response.headers, text: responseText}}), 'utf8');" + "fs.unlinkSync('" + syncFile + "');" + "});" + "response.on('error', function(error) {" + "fs.writeFileSync('" + contentFile + "', JSON.stringify({err: error}), 'utf8');" + "fs.unlinkSync('" + syncFile + "');" + "});" + "}).on('error', function(error) {" + "fs.writeFileSync('" + contentFile + "', JSON.stringify({err: error}), 'utf8');" + "fs.unlinkSync('" + syncFile + "');" + "});" + (data ? "req.write('" + JSON.stringify(data).slice(1,-1).replace(/'/g, "\\'") + "');":"") + "req.end();"; // Start the other Node Process, executing this string var syncProc = spawn(process.argv[0], ["-e", execString]); while(fs.existsSync(syncFile)) { // Wait while the sync file is empty } var resp = JSON.parse(fs.readFileSync(contentFile, 'utf8')); // Kill the child process once the file has data syncProc.stdin.end(); // Remove the temporary file fs.unlinkSync(contentFile); if (resp.err) { self.handleError(resp.err); } else { response = resp.data; self.status = resp.data.statusCode; self.responseText = resp.data.text; setState(self.DONE); } } }; /** * Called when an error is encountered to deal with it. */ this.handleError = function(error) { this.status = 0; this.statusText = error; this.responseText = error.stack; errorFlag = true; setState(this.DONE); this.dispatchEvent('error'); }; /** * Aborts a request. */ this.abort = function() { if (request) { request.abort(); request = null; } headers = defaultHeaders; this.status = 0; this.responseText = ""; this.responseXML = ""; errorFlag = true; if (this.readyState !== this.UNSENT && (this.readyState !== this.OPENED || sendFlag) && this.readyState !== this.DONE) { sendFlag = false; setState(this.DONE); } this.readyState = this.UNSENT; this.dispatchEvent('abort'); }; /** * Adds an event listener. Preferred method of binding to events. */ this.addEventListener = function(event, callback) { if (!(event in listeners)) { listeners[event] = []; } // Currently allows duplicate callbacks. Should it? listeners[event].push(callback); }; /** * Remove an event callback that has already been bound. * Only works on the matching funciton, cannot be a copy. */ this.removeEventListener = function(event, callback) { if (event in listeners) { // Filter will return a new array with the callback removed listeners[event] = listeners[event].filter(function(ev) { return ev !== callback; }); } }; /** * Dispatch any events, including both "on" methods and events attached using addEventListener. */ this.dispatchEvent = function(event) { if (typeof self["on" + event] === "function") { self["on" + event](); } if (event in listeners) { for (var i = 0, len = listeners[event].length; i < len; i++) { listeners[event][i].call(self); } } }; /** * Changes readyState and calls onreadystatechange. * * @param int state New state */ var setState = function(state) { if (state == self.LOADING || self.readyState !== state) { self.readyState = state; if (settings.async || self.readyState < self.OPENED || self.readyState === self.DONE) { self.dispatchEvent("readystatechange"); } if (self.readyState === self.DONE && !errorFlag) { self.dispatchEvent("load"); // @TODO figure out InspectorInstrumentation::didLoadXHR(cookie) self.dispatchEvent("loadend"); } } }; }; }).call(this,require('_process'),require("buffer").Buffer) },{"_process":61,"buffer":6,"child_process":4,"fs":4,"http":77,"https":50,"url":83}],91:[function(require,module,exports){ module.exports = extend var hasOwnProperty = Object.prototype.hasOwnProperty; function extend() { var target = {} for (var i = 0; i < arguments.length; i++) { var source = arguments[i] for (var key in source) { if (hasOwnProperty.call(source, key)) { target[key] = source[key] } } } return target } },{}]},{},[1]);