var RAWCHANNEL = "";(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Leenkx = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i pk, ek, timestamp this.seen = {}; // messages we've seen recently: hash -> timestamp this.lastwirecount = null; // rpc api functions and pending callback functions this.api = {}; this.callbacks = {}; this.serveraddress = null; this.heartbeattimer = null; debug("address", this.address()); debug("identifier", this.identifier); debug("public key", this.pk); debug("encryption key", this.ek); if (typeof(File) == "object") { var blob = new File([this.identifier], this.identifier); } else { var blob = new Buffer.from(this.identifier); blob.name = this.identifier; } var torrent = this.wt.seed(blob, Object.assign({"name": this.identifier, "announce": this.announce}, opts["torrentOpts"] || {}), partial(function(leenkx, torrent) { debug("torrent", leenkx.identifier, torrent); leenkx.emit("torrent", leenkx.identifier, torrent); if (torrent.discovery.tracker) { torrent.discovery.tracker.on("update", function(update) { leenkx.emit("tracker", leenkx.identifier, update); }); } torrent.discovery.on("trackerAnnounce", function() { leenkx.emit("announce", leenkx.identifier); leenkx.connections(); }); }, this)); torrent.on("wire", partial(attach, this, this.identifier)); this.torrent = torrent; if (opts.heartbeat) { this.heartbeat(opts.heartbeat); } } Leenkx.prototype.WebTorrent = WebTorrent; Leenkx.encodeseed = Leenkx.prototype.encodeseed = function(material) { return bs58check.encode(Buffer.concat([Buffer.from(SEEDPREFIX, "hex"), Buffer.from(material)])); } Leenkx.encodeaddress = Leenkx.prototype.encodeaddress = function(material) { return bs58check.encode(Buffer.concat([Buffer.from(ADDRESSPREFIX, "hex"), new ripemd160().update(Buffer.from(nacl.hash(material))).digest()])); } // start a heartbeat and expire old "seen" peers who don't send us a heartbeat Leenkx.prototype.heartbeat = function(interval) { var interval = interval || 30000; this.heartbeattimer = setInterval(partial(function (leenkx) { // broadcast a 'ping' message leenkx.ping(); var t = now(); // remove any 'peers' entries with timestamps older than timeout for (var p in leenkx.peers) { var pk = leenkx.peers[p].pk; var address = leenkx.address(pk); var last = leenkx.peers[p].last; if (last + leenkx.timeout < t) { delete leenkx.peers[p]; leenkx.emit("timeout", address); leenkx.emit("left", address); } } }, this), interval); } // clean up this leenkx instance Leenkx.prototype.destroy = function(cb) { clearInterval(this.heartbeattimer); var packet = makePacket(this, {"y": "x"}); sendRaw(this, packet); this.wt.remove(this.torrent, cb); } Leenkx.prototype.close = Leenkx.prototype.destroy; Leenkx.prototype.connections = function() { if (this.torrent.wires.length != this.lastwirecount) { this.lastwirecount = this.torrent.wires.length; this.emit("connections", this.torrent.wires.length); } return this.lastwirecount; } Leenkx.prototype.sintel = function() { var sintelT = new WebTorrent(); var torrentId = 'magnet:?xt=urn:btih:08ada5a7a6183aae1e09d831df6748d566095a10&dn=Sintel&tr=udp%3A%2F%2Fexplodie.org%3A6969&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Ftracker.empire-js.us%3A1337&tr=udp%3A%2F%2Ftracker.leechers-paradise.org%3A6969&tr=udp%3A%2F%2Ftracker.opentrackr.org%3A1337&tr=wss%3A%2F%2Fpaid2stream.com:3000&tr=wss%3A%2F%2Ftracker.fastcast.nz&tr=wss%3A%2F%2Ftracker.openwebtorrent.com&ws=https%3A%2F%2Fwebtorrent.io%2Ftorrents%2F&xs=https%3A%2F%2Fwebtorrent.io%2Ftorrents%2Fsintel.torrent'; sintelT.add(torrentId, function (torrent) { var file = torrent.files.find(function (file) { return file.name.endsWith('.mp4') }) file.appendTo('body') }); } Leenkx.prototype.address = function(pk) { if (pk && typeof(pk) == "string") { pk = bs58.decode(pk); } else if (pk && pk.length == 32) { pk = pk; } else { pk = this.keyPair.publicKey; } return this.encodeaddress(pk); } Leenkx.address = Leenkx.prototype.address; Leenkx.prototype.ping = function() { // send a ping out so they know about us too var packet = makePacket(this, {"y": "p"}); sendRaw(this, packet); } Leenkx.prototype.send = function(address, message) { if (!message) { var message = address; var address = null; } var packet = makePacket(this, {"y": "m", "v": JSON.stringify(message)}); if (address) { if (this.peers[address]) { packet = encryptPacket(this, this.peers[address].pk, packet); } else { throw address + " not seen - no public key."; } } sendRaw(this, packet); } function sendRaw(leenkx, message) { var wires = leenkx.torrent.wires; for (var w=0; w t; debug("packet", packet); if (checksig && checkid && checktime) { // message is authenticated var ek = packet.ek.toString(); sawPeer(leenkx, pk, ek, identifier); // check packet types if (packet.y == "m") { debug("message", identifier, packet); var messagestring = packet.v.toString(); var messagejson = null; try { var messagejson = JSON.parse(messagestring); } catch(e) { debug("Malformed message JSON: " + messagestring); } if (messagejson) { leenkx.emit("message", leenkx.address(pk), messagejson, packet); } } else if (packet.y == "r") { // rpc call debug("rpc", identifier, packet); var call = packet.c.toString(); var argsstring = packet.a.toString(); try { var args = JSON.parse(argsstring); } catch(e) { var args = null; debug("Malformed args JSON: " + argsstring); } var nonce = packet.rn; leenkx.emit("rpc", leenkx.address(pk), call, args, toHex(nonce)); // make the API call and send back response rpcCall(leenkx, pk, call, args, nonce); } else if (packet.y == "rr") { // rpc response var nonce = toHex(packet.rn); if (leenkx.callbacks[nonce]) { if (typeof(packet["rr"]) != "undefined") { var responsestring = packet.rr.toString(); } else { debug("Empty rr in rpc response."); } try { var responsestringstruct = JSON.parse(responsestring); } catch(e) { debug("Malformed response JSON: " + responsestring); var responsestringstruct = null; } if (leenkx.callbacks[nonce] && responsestringstruct) { debug("rpc-response", leenkx.address(pk), nonce, responsestringstruct); leenkx.emit("rpc-response", leenkx.address(pk), nonce, responsestringstruct); leenkx.callbacks[nonce](responsestringstruct); delete leenkx.callbacks[nonce]; } else { debug("RPC response nonce not known:", nonce); } } else { debug("dropped response with no callback.", nonce); } } else if (packet.y == "p") { var address = leenkx.address(pk); debug("ping from", address); leenkx.emit("ping", address); } else if (packet.y == "x") { var address = leenkx.address(pk); debug("got left from", address); delete leenkx.peers[address]; leenkx.emit("left", address); } else { // TODO: handle ping/keep-alive message debug("unknown packet type"); } } else { debug("dropping bad packet", hash, checksig, checkid, checktime); } } else { debug("skipping packet with no payload", hash, unpacked); } // forward first-seen message to all connected wires // TODO: block flooders sendRaw(leenkx, message); } else { debug("already seen", hash); } // refresh last-seen timestamp on this message leenkx.seen[hash] = now(); } // network functions function rpcCall(leenkx, pk, call, args, nonce, callback) { var packet = {"y": "rr", "rn": nonce}; if (leenkx.api[call]) { leenkx.api[call](leenkx.address(pk), args, function(result) { packet["rr"] = JSON.stringify(result); makeEncryptSendPacket(leenkx, pk, packet); }); } else { packet["rr"] = JSON.stringify({"error": "No such API call."}); makeEncryptSendPacket(leenkx, pk, packet); } } function sawPeer(leenkx, pk, ek, identifier) { debug("sawPeer", leenkx.address(pk), ek); var t = now(); var address = leenkx.address(pk); // ignore ourself if (address != leenkx.address()) { // if we haven't seen this peer for a while if (!leenkx.peers[address] || leenkx.peers[address].last + leenkx.timeout < t) { leenkx.peers[address] = { "ek": ek, "pk": pk, "last": t, }; debug("seen", leenkx.address(pk)); leenkx.emit("seen", leenkx.address(pk)); if (leenkx.address(pk) == leenkx.identifier) { leenkx.serveraddress = address; debug("seen server", leenkx.address(pk)); leenkx.emit("server", leenkx.address(pk)); } // send a ping out so they know about us too var packet = makePacket(leenkx, {"y": "p"}); sendRaw(leenkx, packet); } else { leenkx.peers[address].ek = ek; leenkx.peers[address].last = t; } } } // extension protocol plumbing function attach(leenkx, identifier, wire, addr) { debug("saw wire", wire.peerId, identifier); wire.use(extension(leenkx, identifier, wire)); wire.on("close", partial(detach, leenkx, identifier, wire)); } function detach(leenkx, identifier, wire) { debug("wire left", wire.peerId, identifier); leenkx.emit("wireleft", leenkx.torrent.wires.length, wire); leenkx.connections(); } function extension(leenkx, identifier, wire) { var ext = partial(wirefn, leenkx, identifier); ext.prototype.name = EXT; ext.prototype.onExtendedHandshake = partial(onExtendedHandshake, leenkx, identifier, wire); ext.prototype.onMessage = partial(onMessage, leenkx, identifier, wire); return ext; } function wirefn(leenkx, identifier, wire) { // TODO: sign handshake to prove key custody wire.extendedHandshake.id = identifier; wire.extendedHandshake.pk = leenkx.pk; wire.extendedHandshake.ek = leenkx.ek; } function onExtendedHandshake(leenkx, identifier, wire, handshake) { debug("wire extended handshake", leenkx.address(handshake.pk.toString()), wire.peerId, handshake); leenkx.emit("wireseen", leenkx.torrent.wires.length, wire); leenkx.connections(); // TODO: check sig and drop on failure - wire.peerExtendedHandshake sawPeer(leenkx, handshake.pk.toString(), handshake.ek.toString(), identifier); } // utility fns function now() { return (new Date()).getTime(); } // https://stackoverflow.com/a/39225475/2131094 function toHex(x) { return x.reduce(function(memo, i) { return memo + ('0' + i.toString(16)).slice(-2); }, ''); } // javascript why function partial(fn) { var slice = Array.prototype.slice; var stored_args = slice.call(arguments, 1); return function () { var new_args = slice.call(arguments); var args = stored_args.concat(new_args); return fn.apply(null, args); }; } }).call(this)}).call(this,require("buffer").Buffer) },{"bencode":6,"bs58":53,"bs58check":55,"buffer":331,"debug":93,"events":333,"inherits":131,"ripemd160":222,"tweetnacl":290,"webtorrent":301}],2:[function(require,module,exports){ const ADDR_RE = /^\[?([^\]]+)\]?:(\d+)$/ // ipv4/ipv6/hostname + port let cache = {} // reset cache when it gets to 100,000 elements (~ 600KB of ipv4 addresses) // so it will not grow to consume all memory in long-running processes let size = 0 module.exports = function addrToIPPort (addr) { if (size === 100000) module.exports.reset() if (!cache[addr]) { const m = ADDR_RE.exec(addr) if (!m) throw new Error(`invalid addr: ${addr}`) cache[addr] = [ m[1], Number(m[2]) ] size += 1 } return cache[addr] } module.exports.reset = function reset () { cache = {} size = 0 } },{}],3:[function(require,module,exports){ 'use strict' // base-x encoding / decoding // Copyright (c) 2018 base-x contributors // Copyright (c) 2014-2018 The Bitcoin Core developers (base58.cpp) // Distributed under the MIT software license, see the accompanying // file LICENSE or http://www.opensource.org/licenses/mit-license.php. // @ts-ignore var _Buffer = require('safe-buffer').Buffer function base (ALPHABET) { if (ALPHABET.length >= 255) { throw new TypeError('Alphabet too long') } var BASE_MAP = new Uint8Array(256) for (var j = 0; j < BASE_MAP.length; j++) { BASE_MAP[j] = 255 } for (var i = 0; i < ALPHABET.length; i++) { var x = ALPHABET.charAt(i) var xc = x.charCodeAt(0) if (BASE_MAP[xc] !== 255) { throw new TypeError(x + ' is ambiguous') } BASE_MAP[xc] = i } var BASE = ALPHABET.length var LEADER = ALPHABET.charAt(0) var FACTOR = Math.log(BASE) / Math.log(256) // log(BASE) / log(256), rounded up var iFACTOR = Math.log(256) / Math.log(BASE) // log(256) / log(BASE), rounded up function encode (source) { if (Array.isArray(source) || source instanceof Uint8Array) { source = _Buffer.from(source) } if (!_Buffer.isBuffer(source)) { throw new TypeError('Expected Buffer') } if (source.length === 0) { return '' } // Skip & count leading zeroes. var zeroes = 0 var length = 0 var pbegin = 0 var pend = source.length while (pbegin !== pend && source[pbegin] === 0) { pbegin++ zeroes++ } // Allocate enough space in big-endian base58 representation. var size = ((pend - pbegin) * iFACTOR + 1) >>> 0 var b58 = new Uint8Array(size) // Process the bytes. while (pbegin !== pend) { var carry = source[pbegin] // Apply "b58 = b58 * 256 + ch". var i = 0 for (var it1 = size - 1; (carry !== 0 || i < length) && (it1 !== -1); it1--, i++) { carry += (256 * b58[it1]) >>> 0 b58[it1] = (carry % BASE) >>> 0 carry = (carry / BASE) >>> 0 } if (carry !== 0) { throw new Error('Non-zero carry') } length = i pbegin++ } // Skip leading zeroes in base58 result. var it2 = size - length while (it2 !== size && b58[it2] === 0) { it2++ } // Translate the result into a string. var str = LEADER.repeat(zeroes) for (; it2 < size; ++it2) { str += ALPHABET.charAt(b58[it2]) } return str } function decodeUnsafe (source) { if (typeof source !== 'string') { throw new TypeError('Expected String') } if (source.length === 0) { return _Buffer.alloc(0) } var psz = 0 // Skip leading spaces. if (source[psz] === ' ') { return } // Skip and count leading '1's. var zeroes = 0 var length = 0 while (source[psz] === LEADER) { zeroes++ psz++ } // Allocate enough space in big-endian base256 representation. var size = (((source.length - psz) * FACTOR) + 1) >>> 0 // log(58) / log(256), rounded up. var b256 = new Uint8Array(size) // Process the characters. while (source[psz]) { // Decode character var carry = BASE_MAP[source.charCodeAt(psz)] // Invalid character if (carry === 255) { return } var i = 0 for (var it3 = size - 1; (carry !== 0 || i < length) && (it3 !== -1); it3--, i++) { carry += (BASE * b256[it3]) >>> 0 b256[it3] = (carry % 256) >>> 0 carry = (carry / 256) >>> 0 } if (carry !== 0) { throw new Error('Non-zero carry') } length = i psz++ } // Skip trailing spaces. if (source[psz] === ' ') { return } // Skip leading zeroes in b256. var it4 = size - length while (it4 !== size && b256[it4] === 0) { it4++ } var vch = _Buffer.allocUnsafe(zeroes + (size - it4)) vch.fill(0x00, 0, zeroes) var j = zeroes while (it4 !== size) { vch[j++] = b256[it4++] } return vch } function decode (string) { var buffer = decodeUnsafe(string) if (buffer) { return buffer } throw new Error('Non-base' + BASE + ' character') } return { encode: encode, decodeUnsafe: decodeUnsafe, decode: decode } } module.exports = base },{"safe-buffer":226}],4:[function(require,module,exports){ var Buffer = require('safe-buffer').Buffer const INTEGER_START = 0x69 // 'i' const STRING_DELIM = 0x3A // ':' const DICTIONARY_START = 0x64 // 'd' const LIST_START = 0x6C // 'l' const END_OF_TYPE = 0x65 // 'e' /** * replaces parseInt(buffer.toString('ascii', start, end)). * For strings with less then ~30 charachters, this is actually a lot faster. * * @param {Buffer} data * @param {Number} start * @param {Number} end * @return {Number} calculated number */ function getIntFromBuffer (buffer, start, end) { var sum = 0 var sign = 1 for (var i = start; i < end; i++) { var num = buffer[i] if (num < 58 && num >= 48) { sum = sum * 10 + (num - 48) continue } if (i === start && num === 43) { // + continue } if (i === start && num === 45) { // - sign = -1 continue } if (num === 46) { // . // its a float. break here. break } throw new Error('not a number: buffer[' + i + '] = ' + num) } return sum * sign } /** * Decodes bencoded data. * * @param {Buffer} data * @param {Number} start (optional) * @param {Number} end (optional) * @param {String} encoding (optional) * @return {Object|Array|Buffer|String|Number} */ function decode (data, start, end, encoding) { if (data == null || data.length === 0) { return null } if (typeof start !== 'number' && encoding == null) { encoding = start start = undefined } if (typeof end !== 'number' && encoding == null) { encoding = end end = undefined } decode.position = 0 decode.encoding = encoding || null decode.data = !(Buffer.isBuffer(data)) ? Buffer.from(data) : data.slice(start, end) decode.bytes = decode.data.length return decode.next() } decode.bytes = 0 decode.position = 0 decode.data = null decode.encoding = null decode.next = function () { switch (decode.data[decode.position]) { case DICTIONARY_START: return decode.dictionary() case LIST_START: return decode.list() case INTEGER_START: return decode.integer() default: return decode.buffer() } } decode.find = function (chr) { var i = decode.position var c = decode.data.length var d = decode.data while (i < c) { if (d[i] === chr) return i i++ } throw new Error( 'Invalid data: Missing delimiter "' + String.fromCharCode(chr) + '" [0x' + chr.toString(16) + ']' ) } decode.dictionary = function () { decode.position++ var dict = {} while (decode.data[decode.position] !== END_OF_TYPE) { dict[decode.buffer()] = decode.next() } decode.position++ return dict } decode.list = function () { decode.position++ var lst = [] while (decode.data[decode.position] !== END_OF_TYPE) { lst.push(decode.next()) } decode.position++ return lst } decode.integer = function () { var end = decode.find(END_OF_TYPE) var number = getIntFromBuffer(decode.data, decode.position + 1, end) decode.position += end + 1 - decode.position return number } decode.buffer = function () { var sep = decode.find(STRING_DELIM) var length = getIntFromBuffer(decode.data, decode.position, sep) var end = ++sep + length decode.position = end return decode.encoding ? decode.data.toString(decode.encoding, sep, end) : decode.data.slice(sep, end) } module.exports = decode },{"safe-buffer":226}],5:[function(require,module,exports){ var Buffer = require('safe-buffer').Buffer /** * Encodes data in bencode. * * @param {Buffer|Array|String|Object|Number|Boolean} data * @return {Buffer} */ function encode (data, buffer, offset) { var buffers = [] var result = null encode._encode(buffers, data) result = Buffer.concat(buffers) encode.bytes = result.length if (Buffer.isBuffer(buffer)) { result.copy(buffer, offset) return buffer } return result } encode.bytes = -1 encode._floatConversionDetected = false encode.getType = function (value) { if (Buffer.isBuffer(value)) return 'buffer' if (Array.isArray(value)) return 'array' if (ArrayBuffer.isView(value)) return 'arraybufferview' if (value instanceof Number) return 'number' if (value instanceof Boolean) return 'boolean' if (value instanceof ArrayBuffer) return 'arraybuffer' return typeof value } encode._encode = function (buffers, data) { if (data == null) { return } switch (encode.getType(data)) { case 'buffer': encode.buffer(buffers, data); break case 'object': encode.dict(buffers, data); break case 'array': encode.list(buffers, data); break case 'string': encode.string(buffers, data); break case 'number': encode.number(buffers, data); break case 'boolean': encode.number(buffers, data); break case 'arraybufferview': encode.buffer(buffers, Buffer.from(data.buffer, data.byteOffset, data.byteLength)); break case 'arraybuffer': encode.buffer(buffers, Buffer.from(data)); break } } var buffE = Buffer.from('e') var buffD = Buffer.from('d') var buffL = Buffer.from('l') encode.buffer = function (buffers, data) { buffers.push(Buffer.from(data.length + ':'), data) } encode.string = function (buffers, data) { buffers.push(Buffer.from(Buffer.byteLength(data) + ':' + data)) } encode.number = function (buffers, data) { var maxLo = 0x80000000 var hi = (data / maxLo) << 0 var lo = (data % maxLo) << 0 var val = hi * maxLo + lo buffers.push(Buffer.from('i' + val + 'e')) if (val !== data && !encode._floatConversionDetected) { encode._floatConversionDetected = true console.warn( 'WARNING: Possible data corruption detected with value "' + data + '":', 'Bencoding only defines support for integers, value was converted to "' + val + '"' ) console.trace() } } encode.dict = function (buffers, data) { buffers.push(buffD) var j = 0 var k // fix for issue #13 - sorted dicts var keys = Object.keys(data).sort() var kl = keys.length for (; j < kl; j++) { k = keys[j] if (data[k] == null) continue encode.string(buffers, k) encode._encode(buffers, data[k]) } buffers.push(buffE) } encode.list = function (buffers, data) { var i = 0 var c = data.length buffers.push(buffL) for (; i < c; i++) { if (data[i] == null) continue encode._encode(buffers, data[i]) } buffers.push(buffE) } module.exports = encode },{"safe-buffer":226}],6:[function(require,module,exports){ var bencode = module.exports bencode.encode = require('./encode') bencode.decode = require('./decode') /** * Determines the amount of bytes * needed to encode the given value * @param {Object|Array|Buffer|String|Number|Boolean} value * @return {Number} byteCount */ bencode.byteLength = bencode.encodingLength = function (value) { return bencode.encode(value).length } },{"./decode":4,"./encode":5}],7:[function(require,module,exports){ module.exports = parseRange module.exports.parse = parseRange module.exports.compose = composeRange function composeRange (range) { return range .reduce((acc, cur, idx, arr) => { if (idx === 0 || cur !== arr[idx - 1] + 1) acc.push([]) acc[acc.length - 1].push(cur) return acc }, []) .map((cur) => { return cur.length > 1 ? `${cur[0]}-${cur[cur.length - 1]}` : `${cur[0]}` }) } function parseRange (range) { const generateRange = (start, end = start) => Array.from({ length: end - start + 1 }, (cur, idx) => idx + start) return range .reduce((acc, cur, idx, arr) => { const r = cur.split('-').map(cur => parseInt(cur)) return acc.concat(generateRange(...r)) }, []) } },{}],8:[function(require,module,exports){ module.exports = function(haystack, needle, comparator, low, high) { var mid, cmp; if(low === undefined) low = 0; else { low = low|0; if(low < 0 || low >= haystack.length) throw new RangeError("invalid lower bound"); } if(high === undefined) high = haystack.length - 1; else { high = high|0; if(high < low || high >= haystack.length) throw new RangeError("invalid upper bound"); } while(low <= high) { // The naive `low + high >>> 1` could fail for array lengths > 2**31 // because `>>>` converts its operands to int32. `low + (high - low >>> 1)` // works for array lengths <= 2**32-1 which is also Javascript's max array // length. mid = low + ((high - low) >>> 1); cmp = +comparator(haystack[mid], needle, mid, haystack); // Too low. if(cmp < 0.0) low = mid + 1; // Too high. else if(cmp > 0.0) high = mid - 1; // Key found. else return mid; } // Key not found. return ~low; } },{}],9:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); function getByteSize(num) { var out = num >> 3; if (num % 8 !== 0) out++; return out; } var BitField = /** @class */ (function () { /** * * * @param data Either a number representing the maximum number of supported bytes, or a Uint8Array. * @param opts Options for the bitfield. */ function BitField(data, opts) { if (data === void 0) { data = 0; } var grow = opts === null || opts === void 0 ? void 0 : opts.grow; this.grow = (grow && isFinite(grow) && getByteSize(grow)) || grow || 0; this.buffer = typeof data === "number" ? new Uint8Array(getByteSize(data)) : data; } /** * Get a particular bit. * * @param i Bit index to retrieve. * @returns A boolean indicating whether the `i`th bit is set. */ BitField.prototype.get = function (i) { var j = i >> 3; return j < this.buffer.length && !!(this.buffer[j] & (128 >> i % 8)); }; /** * Set a particular bit. * * Will grow the underlying array if the bit is out of bounds and the `grow` option is set. * * @param i Bit index to set. * @param value Value to set the bit to. Defaults to `true`. */ BitField.prototype.set = function (i, value) { if (value === void 0) { value = true; } var j = i >> 3; if (value) { if (this.buffer.length < j + 1) { var length_1 = Math.max(j + 1, Math.min(2 * this.buffer.length, this.grow)); if (length_1 <= this.grow) { var newBuffer = new Uint8Array(length_1); newBuffer.set(this.buffer); this.buffer = newBuffer; } } // Set this.buffer[j] |= 128 >> i % 8; } else if (j < this.buffer.length) { // Clear this.buffer[j] &= ~(128 >> i % 8); } }; /** * Loop through the bits in the bitfield. * * @param fn Function to be called with the bit value and index. * @param start Index of the first bit to look at. * @param end Index of the first bit that should no longer be considered. */ BitField.prototype.forEach = function (fn, start, end) { if (start === void 0) { start = 0; } if (end === void 0) { end = this.buffer.length * 8; } for (var i = start, j = i >> 3, y = 128 >> i % 8, byte = this.buffer[j]; i < end; i++) { fn(!!(byte & y), i); y = y === 1 ? ((byte = this.buffer[++j]), 128) : y >> 1; } }; return BitField; }()); exports.default = BitField; },{}],10:[function(require,module,exports){ (function (Buffer){(function (){ /*! bittorrent-protocol. MIT License. WebTorrent LLC */ const arrayRemove = require('unordered-array-remove') const bencode = require('bencode') const BitField = require('bitfield').default const debug = require('debug')('bittorrent-protocol') const randombytes = require('randombytes') const speedometer = require('speedometer') const stream = require('readable-stream') const BITFIELD_GROW = 400000 const KEEP_ALIVE_TIMEOUT = 55000 const MESSAGE_PROTOCOL = Buffer.from('\u0013BitTorrent protocol') const MESSAGE_KEEP_ALIVE = Buffer.from([0x00, 0x00, 0x00, 0x00]) const MESSAGE_CHOKE = Buffer.from([0x00, 0x00, 0x00, 0x01, 0x00]) const MESSAGE_UNCHOKE = Buffer.from([0x00, 0x00, 0x00, 0x01, 0x01]) const MESSAGE_INTERESTED = Buffer.from([0x00, 0x00, 0x00, 0x01, 0x02]) const MESSAGE_UNINTERESTED = Buffer.from([0x00, 0x00, 0x00, 0x01, 0x03]) const MESSAGE_RESERVED = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] const MESSAGE_PORT = [0x00, 0x00, 0x00, 0x03, 0x09, 0x00, 0x00] class Request { constructor (piece, offset, length, callback) { this.piece = piece this.offset = offset this.length = length this.callback = callback } } class Wire extends stream.Duplex { constructor () { super() this._debugId = randombytes(4).toString('hex') this._debug('new wire') this.peerId = null // remote peer id (hex string) this.peerIdBuffer = null // remote peer id (buffer) this.type = null // connection type ('webrtc', 'tcpIncoming', 'tcpOutgoing', 'webSeed') this.amChoking = true // are we choking the peer? this.amInterested = false // are we interested in the peer? this.peerChoking = true // is the peer choking us? this.peerInterested = false // is the peer interested in us? // The largest torrent that I know of (the Geocities archive) is ~641 GB and has // ~41,000 pieces. Therefore, cap bitfield to 10x larger (400,000 bits) to support all // possible torrents but prevent malicious peers from growing bitfield to fill memory. this.peerPieces = new BitField(0, { grow: BITFIELD_GROW }) this.peerExtensions = {} this.requests = [] // outgoing this.peerRequests = [] // incoming this.extendedMapping = {} // number -> string, ex: 1 -> 'ut_metadata' this.peerExtendedMapping = {} // string -> number, ex: 9 -> 'ut_metadata' // The extended handshake to send, minus the "m" field, which gets automatically // filled from `this.extendedMapping` this.extendedHandshake = {} this.peerExtendedHandshake = {} // remote peer's extended handshake this._ext = {} // string -> function, ex 'ut_metadata' -> ut_metadata() this._nextExt = 1 this.uploaded = 0 this.downloaded = 0 this.uploadSpeed = speedometer() this.downloadSpeed = speedometer() this._keepAliveInterval = null this._timeout = null this._timeoutMs = 0 this.destroyed = false // was the wire ended by calling `destroy`? this._finished = false this._parserSize = 0 // number of needed bytes to parse next message from remote peer this._parser = null // function to call once `this._parserSize` bytes are available this._buffer = [] // incomplete message data this._bufferSize = 0 // cached total length of buffers in `this._buffer` this.once('finish', () => this._onFinish()) this._parseHandshake() } /** * Set whether to send a "keep-alive" ping (sent every 55s) * @param {boolean} enable */ setKeepAlive (enable) { this._debug('setKeepAlive %s', enable) clearInterval(this._keepAliveInterval) if (enable === false) return this._keepAliveInterval = setInterval(() => { this.keepAlive() }, KEEP_ALIVE_TIMEOUT) } /** * Set the amount of time to wait before considering a request to be "timed out" * @param {number} ms * @param {boolean=} unref (should the timer be unref'd? default: false) */ setTimeout (ms, unref) { this._debug('setTimeout ms=%d unref=%s', ms, unref) this._clearTimeout() this._timeoutMs = ms this._timeoutUnref = !!unref this._updateTimeout() } destroy () { if (this.destroyed) return this.destroyed = true this._debug('destroy') this.emit('close') this.end() } end (...args) { this._debug('end') this._onUninterested() this._onChoke() super.end(...args) } /** * Use the specified protocol extension. * @param {function} Extension */ use (Extension) { const name = Extension.prototype.name if (!name) { throw new Error('Extension class requires a "name" property on the prototype') } this._debug('use extension.name=%s', name) const ext = this._nextExt const handler = new Extension(this) function noop () {} if (typeof handler.onHandshake !== 'function') { handler.onHandshake = noop } if (typeof handler.onExtendedHandshake !== 'function') { handler.onExtendedHandshake = noop } if (typeof handler.onMessage !== 'function') { handler.onMessage = noop } this.extendedMapping[ext] = name this._ext[name] = handler this[name] = handler this._nextExt += 1 } // // OUTGOING MESSAGES // /** * Message "keep-alive": */ keepAlive () { this._debug('keep-alive') this._push(MESSAGE_KEEP_ALIVE) } /** * Message: "handshake" * @param {Buffer|string} infoHash (as Buffer or *hex* string) * @param {Buffer|string} peerId * @param {Object} extensions */ handshake (infoHash, peerId, extensions) { let infoHashBuffer let peerIdBuffer if (typeof infoHash === 'string') { infoHash = infoHash.toLowerCase() infoHashBuffer = Buffer.from(infoHash, 'hex') } else { infoHashBuffer = infoHash infoHash = infoHashBuffer.toString('hex') } if (typeof peerId === 'string') { peerIdBuffer = Buffer.from(peerId, 'hex') } else { peerIdBuffer = peerId peerId = peerIdBuffer.toString('hex') } if (infoHashBuffer.length !== 20 || peerIdBuffer.length !== 20) { throw new Error('infoHash and peerId MUST have length 20') } this._debug('handshake i=%s p=%s exts=%o', infoHash, peerId, extensions) const reserved = Buffer.from(MESSAGE_RESERVED) // enable extended message reserved[5] |= 0x10 if (extensions && extensions.dht) reserved[7] |= 1 this._push(Buffer.concat([MESSAGE_PROTOCOL, reserved, infoHashBuffer, peerIdBuffer])) this._handshakeSent = true if (this.peerExtensions.extended && !this._extendedHandshakeSent) { // Peer's handshake indicated support already // (incoming connection) this._sendExtendedHandshake() } } /* Peer supports BEP-0010, send extended handshake. * * This comes after the 'handshake' event to give the user a chance to populate * `this.extendedHandshake` and `this.extendedMapping` before the extended handshake * is sent to the remote peer. */ _sendExtendedHandshake () { // Create extended message object from registered extensions const msg = Object.assign({}, this.extendedHandshake) msg.m = {} for (const ext in this.extendedMapping) { const name = this.extendedMapping[ext] msg.m[name] = Number(ext) } // Send extended handshake this.extended(0, bencode.encode(msg)) this._extendedHandshakeSent = true } /** * Message "choke": */ choke () { if (this.amChoking) return this.amChoking = true this._debug('choke') while (this.peerRequests.length) { this.peerRequests.pop() } this._push(MESSAGE_CHOKE) } /** * Message "unchoke": */ unchoke () { if (!this.amChoking) return this.amChoking = false this._debug('unchoke') this._push(MESSAGE_UNCHOKE) } /** * Message "interested": */ interested () { if (this.amInterested) return this.amInterested = true this._debug('interested') this._push(MESSAGE_INTERESTED) } /** * Message "uninterested": */ uninterested () { if (!this.amInterested) return this.amInterested = false this._debug('uninterested') this._push(MESSAGE_UNINTERESTED) } /** * Message "have": * @param {number} index */ have (index) { this._debug('have %d', index) this._message(4, [index], null) } /** * Message "bitfield": * @param {BitField|Buffer} bitfield */ bitfield (bitfield) { this._debug('bitfield') if (!Buffer.isBuffer(bitfield)) bitfield = bitfield.buffer this._message(5, [], bitfield) } /** * Message "request": * @param {number} index * @param {number} offset * @param {number} length * @param {function} cb */ request (index, offset, length, cb) { if (!cb) cb = () => {} if (this._finished) return cb(new Error('wire is closed')) if (this.peerChoking) return cb(new Error('peer is choking')) this._debug('request index=%d offset=%d length=%d', index, offset, length) this.requests.push(new Request(index, offset, length, cb)) this._updateTimeout() this._message(6, [index, offset, length], null) } /** * Message "piece": * @param {number} index * @param {number} offset * @param {Buffer} buffer */ piece (index, offset, buffer) { this._debug('piece index=%d offset=%d', index, offset) this.uploaded += buffer.length this.uploadSpeed(buffer.length) this.emit('upload', buffer.length) this._message(7, [index, offset], buffer) } /** * Message "cancel": * @param {number} index * @param {number} offset * @param {number} length */ cancel (index, offset, length) { this._debug('cancel index=%d offset=%d length=%d', index, offset, length) this._callback( this._pull(this.requests, index, offset, length), new Error('request was cancelled'), null ) this._message(8, [index, offset, length], null) } /** * Message: "port" * @param {Number} port */ port (port) { this._debug('port %d', port) const message = Buffer.from(MESSAGE_PORT) message.writeUInt16BE(port, 5) this._push(message) } /** * Message: "extended" * @param {number|string} ext * @param {Object} obj */ extended (ext, obj) { this._debug('extended ext=%s', ext) if (typeof ext === 'string' && this.peerExtendedMapping[ext]) { ext = this.peerExtendedMapping[ext] } if (typeof ext === 'number') { const extId = Buffer.from([ext]) const buf = Buffer.isBuffer(obj) ? obj : bencode.encode(obj) this._message(20, [], Buffer.concat([extId, buf])) } else { throw new Error(`Unrecognized extension: ${ext}`) } } /** * Duplex stream method. Called whenever the remote peer stream wants data. No-op * since we'll just push data whenever we get it. */ _read () {} /** * Send a message to the remote peer. */ _message (id, numbers, data) { const dataLength = data ? data.length : 0 const buffer = Buffer.allocUnsafe(5 + (4 * numbers.length)) buffer.writeUInt32BE(buffer.length + dataLength - 4, 0) buffer[4] = id for (let i = 0; i < numbers.length; i++) { buffer.writeUInt32BE(numbers[i], 5 + (4 * i)) } this._push(buffer) if (data) this._push(data) } _push (data) { if (this._finished) return return this.push(data) } // // INCOMING MESSAGES // _onKeepAlive () { this._debug('got keep-alive') this.emit('keep-alive') } _onHandshake (infoHashBuffer, peerIdBuffer, extensions) { const infoHash = infoHashBuffer.toString('hex') const peerId = peerIdBuffer.toString('hex') this._debug('got handshake i=%s p=%s exts=%o', infoHash, peerId, extensions) this.peerId = peerId this.peerIdBuffer = peerIdBuffer this.peerExtensions = extensions this.emit('handshake', infoHash, peerId, extensions) let name for (name in this._ext) { this._ext[name].onHandshake(infoHash, peerId, extensions) } if (extensions.extended && this._handshakeSent && !this._extendedHandshakeSent) { // outgoing connection this._sendExtendedHandshake() } } _onChoke () { this.peerChoking = true this._debug('got choke') this.emit('choke') while (this.requests.length) { this._callback(this.requests.pop(), new Error('peer is choking'), null) } } _onUnchoke () { this.peerChoking = false this._debug('got unchoke') this.emit('unchoke') } _onInterested () { this.peerInterested = true this._debug('got interested') this.emit('interested') } _onUninterested () { this.peerInterested = false this._debug('got uninterested') this.emit('uninterested') } _onHave (index) { if (this.peerPieces.get(index)) return this._debug('got have %d', index) this.peerPieces.set(index, true) this.emit('have', index) } _onBitField (buffer) { this.peerPieces = new BitField(buffer) this._debug('got bitfield') this.emit('bitfield', this.peerPieces) } _onRequest (index, offset, length) { if (this.amChoking) return this._debug('got request index=%d offset=%d length=%d', index, offset, length) const respond = (err, buffer) => { if (request !== this._pull(this.peerRequests, index, offset, length)) return if (err) return this._debug('error satisfying request index=%d offset=%d length=%d (%s)', index, offset, length, err.message) this.piece(index, offset, buffer) } const request = new Request(index, offset, length, respond) this.peerRequests.push(request) this.emit('request', index, offset, length, respond) } _onPiece (index, offset, buffer) { this._debug('got piece index=%d offset=%d', index, offset) this._callback(this._pull(this.requests, index, offset, buffer.length), null, buffer) this.downloaded += buffer.length this.downloadSpeed(buffer.length) this.emit('download', buffer.length) this.emit('piece', index, offset, buffer) } _onCancel (index, offset, length) { this._debug('got cancel index=%d offset=%d length=%d', index, offset, length) this._pull(this.peerRequests, index, offset, length) this.emit('cancel', index, offset, length) } _onPort (port) { this._debug('got port %d', port) this.emit('port', port) } _onExtended (ext, buf) { if (ext === 0) { let info try { info = bencode.decode(buf) } catch (err) { this._debug('ignoring invalid extended handshake: %s', err.message || err) } if (!info) return this.peerExtendedHandshake = info let name if (typeof info.m === 'object') { for (name in info.m) { this.peerExtendedMapping[name] = Number(info.m[name].toString()) } } for (name in this._ext) { if (this.peerExtendedMapping[name]) { this._ext[name].onExtendedHandshake(this.peerExtendedHandshake) } } this._debug('got extended handshake') this.emit('extended', 'handshake', this.peerExtendedHandshake) } else { if (this.extendedMapping[ext]) { ext = this.extendedMapping[ext] // friendly name for extension if (this._ext[ext]) { // there is an registered extension handler, so call it this._ext[ext].onMessage(buf) } } this._debug('got extended message ext=%s', ext) this.emit('extended', ext, buf) } } _onTimeout () { this._debug('request timed out') this._callback(this.requests.shift(), new Error('request has timed out'), null) this.emit('timeout') } /** * Duplex stream method. Called whenever the remote peer has data for us. Data that the * remote peer sends gets buffered (i.e. not actually processed) until the right number * of bytes have arrived, determined by the last call to `this._parse(number, callback)`. * Once enough bytes have arrived to process the message, the callback function * (i.e. `this._parser`) gets called with the full buffer of data. * @param {Buffer} data * @param {string} encoding * @param {function} cb */ _write (data, encoding, cb) { this._bufferSize += data.length this._buffer.push(data) while (this._bufferSize >= this._parserSize) { const buffer = (this._buffer.length === 1) ? this._buffer[0] : Buffer.concat(this._buffer) this._bufferSize -= this._parserSize this._buffer = this._bufferSize ? [buffer.slice(this._parserSize)] : [] this._parser(buffer.slice(0, this._parserSize)) } cb(null) // Signal that we're ready for more data } _callback (request, err, buffer) { if (!request) return this._clearTimeout() if (!this.peerChoking && !this._finished) this._updateTimeout() request.callback(err, buffer) } _clearTimeout () { if (!this._timeout) return clearTimeout(this._timeout) this._timeout = null } _updateTimeout () { if (!this._timeoutMs || !this.requests.length || this._timeout) return this._timeout = setTimeout(() => this._onTimeout(), this._timeoutMs) if (this._timeoutUnref && this._timeout.unref) this._timeout.unref() } /** * Takes a number of bytes that the local peer is waiting to receive from the remote peer * in order to parse a complete message, and a callback function to be called once enough * bytes have arrived. * @param {number} size * @param {function} parser */ _parse (size, parser) { this._parserSize = size this._parser = parser } /** * Handle the first 4 bytes of a message, to determine the length of bytes that must be * waited for in order to have the whole message. * @param {Buffer} buffer */ _onMessageLength (buffer) { const length = buffer.readUInt32BE(0) if (length > 0) { this._parse(length, this._onMessage) } else { this._onKeepAlive() this._parse(4, this._onMessageLength) } } /** * Handle a message from the remote peer. * @param {Buffer} buffer */ _onMessage (buffer) { this._parse(4, this._onMessageLength) switch (buffer[0]) { case 0: return this._onChoke() case 1: return this._onUnchoke() case 2: return this._onInterested() case 3: return this._onUninterested() case 4: return this._onHave(buffer.readUInt32BE(1)) case 5: return this._onBitField(buffer.slice(1)) case 6: return this._onRequest( buffer.readUInt32BE(1), buffer.readUInt32BE(5), buffer.readUInt32BE(9) ) case 7: return this._onPiece( buffer.readUInt32BE(1), buffer.readUInt32BE(5), buffer.slice(9) ) case 8: return this._onCancel( buffer.readUInt32BE(1), buffer.readUInt32BE(5), buffer.readUInt32BE(9) ) case 9: return this._onPort(buffer.readUInt16BE(1)) case 20: return this._onExtended(buffer.readUInt8(1), buffer.slice(2)) default: this._debug('got unknown message') return this.emit('unknownmessage', buffer) } } _parseHandshake () { this._parse(1, buffer => { const pstrlen = buffer.readUInt8(0) this._parse(pstrlen + 48, handshake => { const protocol = handshake.slice(0, pstrlen) if (protocol.toString() !== 'BitTorrent protocol') { this._debug('Error: wire not speaking BitTorrent protocol (%s)', protocol.toString()) this.end() return } handshake = handshake.slice(pstrlen) this._onHandshake(handshake.slice(8, 28), handshake.slice(28, 48), { dht: !!(handshake[7] & 0x01), // see bep_0005 extended: !!(handshake[5] & 0x10) // see bep_0010 }) this._parse(4, this._onMessageLength) }) }) } _onFinish () { this._finished = true this.push(null) // stream cannot be half open, so signal the end of it while (this.read()) { // body intentionally empty // consume and discard the rest of the stream data } clearInterval(this._keepAliveInterval) this._parse(Number.MAX_VALUE, () => {}) while (this.peerRequests.length) { this.peerRequests.pop() } while (this.requests.length) { this._callback(this.requests.pop(), new Error('wire was closed'), null) } } _debug (...args) { args[0] = `[${this._debugId}] ${args[0]}` debug(...args) } _pull (requests, piece, offset, length) { for (let i = 0; i < requests.length; i++) { const req = requests[i] if (req.piece === piece && req.offset === offset && req.length === length) { arrayRemove(requests, i) return req } } return null } } module.exports = Wire }).call(this)}).call(this,require("buffer").Buffer) },{"bencode":6,"bitfield":9,"buffer":331,"debug":11,"randombytes":200,"readable-stream":28,"speedometer":277,"unordered-array-remove":293}],11:[function(require,module,exports){ (function (process){(function (){ /* eslint-env browser */ /** * This is the web browser implementation of `debug()`. */ exports.formatArgs = formatArgs; exports.save = save; exports.load = load; exports.useColors = useColors; exports.storage = localstorage(); exports.destroy = (() => { let warned = false; return () => { if (!warned) { warned = true; console.warn('Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.'); } }; })(); /** * Colors. */ exports.colors = [ '#0000CC', '#0000FF', '#0033CC', '#0033FF', '#0066CC', '#0066FF', '#0099CC', '#0099FF', '#00CC00', '#00CC33', '#00CC66', '#00CC99', '#00CCCC', '#00CCFF', '#3300CC', '#3300FF', '#3333CC', '#3333FF', '#3366CC', '#3366FF', '#3399CC', '#3399FF', '#33CC00', '#33CC33', '#33CC66', '#33CC99', '#33CCCC', '#33CCFF', '#6600CC', '#6600FF', '#6633CC', '#6633FF', '#66CC00', '#66CC33', '#9900CC', '#9900FF', '#9933CC', '#9933FF', '#99CC00', '#99CC33', '#CC0000', '#CC0033', '#CC0066', '#CC0099', '#CC00CC', '#CC00FF', '#CC3300', '#CC3333', '#CC3366', '#CC3399', '#CC33CC', '#CC33FF', '#CC6600', '#CC6633', '#CC9900', '#CC9933', '#CCCC00', '#CCCC33', '#FF0000', '#FF0033', '#FF0066', '#FF0099', '#FF00CC', '#FF00FF', '#FF3300', '#FF3333', '#FF3366', '#FF3399', '#FF33CC', '#FF33FF', '#FF6600', '#FF6633', '#FF9900', '#FF9933', '#FFCC00', '#FFCC33' ]; /** * Currently only WebKit-based Web Inspectors, Firefox >= v31, * and the Firebug extension (any Firefox version) are known * to support "%c" CSS customizations. * * TODO: add a `localStorage` variable to explicitly enable/disable colors */ // eslint-disable-next-line complexity function useColors() { // NB: In an Electron preload script, document will be defined but not fully // initialized. Since we know we're in Chrome, we'll just detect this case // explicitly if (typeof window !== 'undefined' && window.process && (window.process.type === 'renderer' || window.process.__nwjs)) { return true; } // Internet Explorer and Edge do not support colors. if (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) { return false; } // Is webkit? http://stackoverflow.com/a/16459606/376773 // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632 return (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) || // Is firebug? http://stackoverflow.com/a/398120/376773 (typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) || // Is firefox >= v31? // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31) || // Double check webkit in userAgent just in case we are in a worker (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/)); } /** * Colorize log arguments if enabled. * * @api public */ function formatArgs(args) { args[0] = (this.useColors ? '%c' : '') + this.namespace + (this.useColors ? ' %c' : ' ') + args[0] + (this.useColors ? '%c ' : ' ') + '+' + module.exports.humanize(this.diff); if (!this.useColors) { return; } const c = 'color: ' + this.color; args.splice(1, 0, c, 'color: inherit'); // The final "%c" is somewhat tricky, because there could be other // arguments passed either before or after the %c, so we need to // figure out the correct index to insert the CSS into let index = 0; let lastC = 0; args[0].replace(/%[a-zA-Z%]/g, match => { if (match === '%%') { return; } index++; if (match === '%c') { // We only are interested in the *last* %c // (the user may have provided their own) lastC = index; } }); args.splice(lastC, 0, c); } /** * Invokes `console.debug()` when available. * No-op when `console.debug` is not a "function". * If `console.debug` is not available, falls back * to `console.log`. * * @api public */ exports.log = console.debug || console.log || (() => {}); /** * Save `namespaces`. * * @param {String} namespaces * @api private */ function save(namespaces) { try { if (namespaces) { exports.storage.setItem('debug', namespaces); } else { exports.storage.removeItem('debug'); } } catch (error) { // Swallow // XXX (@Qix-) should we be logging these? } } /** * Load `namespaces`. * * @return {String} returns the previously persisted debug modes * @api private */ function load() { let r; try { r = exports.storage.getItem('debug'); } catch (error) { // Swallow // XXX (@Qix-) should we be logging these? } // If debug isn't set in LS, and we're in Electron, try to load $DEBUG if (!r && typeof process !== 'undefined' && 'env' in process) { r = process.env.DEBUG; } return r; } /** * Localstorage attempts to return the localstorage. * * This is necessary because safari throws * when a user disables cookies/localstorage * and you attempt to access it. * * @return {LocalStorage} * @api private */ function localstorage() { try { // TVMLKit (Apple TV JS Runtime) does not have a window object, just localStorage in the global context // The Browser also has localStorage in the global context. return localStorage; } catch (error) { // Swallow // XXX (@Qix-) should we be logging these? } } module.exports = require('./common')(exports); const {formatters} = module.exports; /** * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default. */ formatters.j = function (v) { try { return JSON.stringify(v); } catch (error) { return '[UnexpectedJSONParseError]: ' + error.message; } }; }).call(this)}).call(this,require('_process')) },{"./common":12,"_process":338}],12:[function(require,module,exports){ /** * This is the common logic for both the Node.js and web browser * implementations of `debug()`. */ function setup(env) { createDebug.debug = createDebug; createDebug.default = createDebug; createDebug.coerce = coerce; createDebug.disable = disable; createDebug.enable = enable; createDebug.enabled = enabled; createDebug.humanize = require('ms'); createDebug.destroy = destroy; Object.keys(env).forEach(key => { createDebug[key] = env[key]; }); /** * The currently active debug mode names, and names to skip. */ createDebug.names = []; createDebug.skips = []; /** * Map of special "%n" handling functions, for the debug "format" argument. * * Valid key names are a single, lower or upper-case letter, i.e. "n" and "N". */ createDebug.formatters = {}; /** * Selects a color for a debug namespace * @param {String} namespace The namespace string for the for the debug instance to be colored * @return {Number|String} An ANSI color code for the given namespace * @api private */ function selectColor(namespace) { let hash = 0; for (let i = 0; i < namespace.length; i++) { hash = ((hash << 5) - hash) + namespace.charCodeAt(i); hash |= 0; // Convert to 32bit integer } return createDebug.colors[Math.abs(hash) % createDebug.colors.length]; } createDebug.selectColor = selectColor; /** * Create a debugger with the given `namespace`. * * @param {String} namespace * @return {Function} * @api public */ function createDebug(namespace) { let prevTime; let enableOverride = null; function debug(...args) { // Disabled? if (!debug.enabled) { return; } const self = debug; // Set `diff` timestamp const curr = Number(new Date()); const ms = curr - (prevTime || curr); self.diff = ms; self.prev = prevTime; self.curr = curr; prevTime = curr; args[0] = createDebug.coerce(args[0]); if (typeof args[0] !== 'string') { // Anything else let's inspect with %O args.unshift('%O'); } // Apply any `formatters` transformations let index = 0; args[0] = args[0].replace(/%([a-zA-Z%])/g, (match, format) => { // If we encounter an escaped % then don't increase the array index if (match === '%%') { return '%'; } index++; const formatter = createDebug.formatters[format]; if (typeof formatter === 'function') { const val = args[index]; match = formatter.call(self, val); // Now we need to remove `args[index]` since it's inlined in the `format` args.splice(index, 1); index--; } return match; }); // Apply env-specific formatting (colors, etc.) createDebug.formatArgs.call(self, args); const logFn = self.log || createDebug.log; logFn.apply(self, args); } debug.namespace = namespace; debug.useColors = createDebug.useColors(); debug.color = createDebug.selectColor(namespace); debug.extend = extend; debug.destroy = createDebug.destroy; // XXX Temporary. Will be removed in the next major release. Object.defineProperty(debug, 'enabled', { enumerable: true, configurable: false, get: () => enableOverride === null ? createDebug.enabled(namespace) : enableOverride, set: v => { enableOverride = v; } }); // Env-specific initialization logic for debug instances if (typeof createDebug.init === 'function') { createDebug.init(debug); } return debug; } function extend(namespace, delimiter) { const newDebug = createDebug(this.namespace + (typeof delimiter === 'undefined' ? ':' : delimiter) + namespace); newDebug.log = this.log; return newDebug; } /** * Enables a debug mode by namespaces. This can include modes * separated by a colon and wildcards. * * @param {String} namespaces * @api public */ function enable(namespaces) { createDebug.save(namespaces); createDebug.names = []; createDebug.skips = []; let i; const split = (typeof namespaces === 'string' ? namespaces : '').split(/[\s,]+/); const len = split.length; for (i = 0; i < len; i++) { if (!split[i]) { // ignore empty strings continue; } namespaces = split[i].replace(/\*/g, '.*?'); if (namespaces[0] === '-') { createDebug.skips.push(new RegExp('^' + namespaces.substr(1) + '$')); } else { createDebug.names.push(new RegExp('^' + namespaces + '$')); } } } /** * Disable debug output. * * @return {String} namespaces * @api public */ function disable() { const namespaces = [ ...createDebug.names.map(toNamespace), ...createDebug.skips.map(toNamespace).map(namespace => '-' + namespace) ].join(','); createDebug.enable(''); return namespaces; } /** * Returns true if the given mode name is enabled, false otherwise. * * @param {String} name * @return {Boolean} * @api public */ function enabled(name) { if (name[name.length - 1] === '*') { return true; } let i; let len; for (i = 0, len = createDebug.skips.length; i < len; i++) { if (createDebug.skips[i].test(name)) { return false; } } for (i = 0, len = createDebug.names.length; i < len; i++) { if (createDebug.names[i].test(name)) { return true; } } return false; } /** * Convert regexp to namespace * * @param {RegExp} regxep * @return {String} namespace * @api private */ function toNamespace(regexp) { return regexp.toString() .substring(2, regexp.toString().length - 2) .replace(/\.\*\?$/, '*'); } /** * Coerce `val`. * * @param {Mixed} val * @return {Mixed} * @api private */ function coerce(val) { if (val instanceof Error) { return val.stack || val.message; } return val; } /** * XXX DO NOT USE. This is a temporary stub function. * XXX It WILL be removed in the next major release. */ function destroy() { console.warn('Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.'); } createDebug.enable(createDebug.load()); return createDebug; } module.exports = setup; },{"ms":13}],13:[function(require,module,exports){ /** * Helpers. */ var s = 1000; var m = s * 60; var h = m * 60; var d = h * 24; var w = d * 7; var y = d * 365.25; /** * Parse or format the given `val`. * * Options: * * - `long` verbose formatting [false] * * @param {String|Number} val * @param {Object} [options] * @throws {Error} throw an error if val is not a non-empty string or a number * @return {String|Number} * @api public */ module.exports = function(val, options) { options = options || {}; var type = typeof val; if (type === 'string' && val.length > 0) { return parse(val); } else if (type === 'number' && isFinite(val)) { return options.long ? fmtLong(val) : fmtShort(val); } throw new Error( 'val is not a non-empty string or a valid number. val=' + JSON.stringify(val) ); }; /** * Parse the given `str` and return milliseconds. * * @param {String} str * @return {Number} * @api private */ function parse(str) { str = String(str); if (str.length > 100) { return; } var match = /^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec( str ); if (!match) { return; } var n = parseFloat(match[1]); var type = (match[2] || 'ms').toLowerCase(); switch (type) { case 'years': case 'year': case 'yrs': case 'yr': case 'y': return n * y; case 'weeks': case 'week': case 'w': return n * w; case 'days': case 'day': case 'd': return n * d; case 'hours': case 'hour': case 'hrs': case 'hr': case 'h': return n * h; case 'minutes': case 'minute': case 'mins': case 'min': case 'm': return n * m; case 'seconds': case 'second': case 'secs': case 'sec': case 's': return n * s; case 'milliseconds': case 'millisecond': case 'msecs': case 'msec': case 'ms': return n; default: return undefined; } } /** * Short format for `ms`. * * @param {Number} ms * @return {String} * @api private */ function fmtShort(ms) { var msAbs = Math.abs(ms); if (msAbs >= d) { return Math.round(ms / d) + 'd'; } if (msAbs >= h) { return Math.round(ms / h) + 'h'; } if (msAbs >= m) { return Math.round(ms / m) + 'm'; } if (msAbs >= s) { return Math.round(ms / s) + 's'; } return ms + 'ms'; } /** * Long format for `ms`. * * @param {Number} ms * @return {String} * @api private */ function fmtLong(ms) { var msAbs = Math.abs(ms); if (msAbs >= d) { return plural(ms, msAbs, d, 'day'); } if (msAbs >= h) { return plural(ms, msAbs, h, 'hour'); } if (msAbs >= m) { return plural(ms, msAbs, m, 'minute'); } if (msAbs >= s) { return plural(ms, msAbs, s, 'second'); } return ms + ' ms'; } /** * Pluralization helper. */ function plural(ms, msAbs, n, name) { var isPlural = msAbs >= n * 1.5; return Math.round(ms / n) + ' ' + name + (isPlural ? 's' : ''); } },{}],14:[function(require,module,exports){ 'use strict'; function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; } var codes = {}; function createErrorType(code, message, Base) { if (!Base) { Base = Error; } function getMessage(arg1, arg2, arg3) { if (typeof message === 'string') { return message; } else { return message(arg1, arg2, arg3); } } var NodeError = /*#__PURE__*/ function (_Base) { _inheritsLoose(NodeError, _Base); function NodeError(arg1, arg2, arg3) { return _Base.call(this, getMessage(arg1, arg2, arg3)) || this; } return NodeError; }(Base); NodeError.prototype.name = Base.name; NodeError.prototype.code = code; codes[code] = NodeError; } // https://github.com/nodejs/node/blob/v10.8.0/lib/internal/errors.js function oneOf(expected, thing) { if (Array.isArray(expected)) { var len = expected.length; expected = expected.map(function (i) { return String(i); }); if (len > 2) { return "one of ".concat(thing, " ").concat(expected.slice(0, len - 1).join(', '), ", or ") + expected[len - 1]; } else if (len === 2) { return "one of ".concat(thing, " ").concat(expected[0], " or ").concat(expected[1]); } else { return "of ".concat(thing, " ").concat(expected[0]); } } else { return "of ".concat(thing, " ").concat(String(expected)); } } // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith function startsWith(str, search, pos) { return str.substr(!pos || pos < 0 ? 0 : +pos, search.length) === search; } // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/endsWith function endsWith(str, search, this_len) { if (this_len === undefined || this_len > str.length) { this_len = str.length; } return str.substring(this_len - search.length, this_len) === search; } // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/includes function includes(str, search, start) { if (typeof start !== 'number') { start = 0; } if (start + search.length > str.length) { return false; } else { return str.indexOf(search, start) !== -1; } } createErrorType('ERR_INVALID_OPT_VALUE', function (name, value) { return 'The value "' + value + '" is invalid for option "' + name + '"'; }, TypeError); createErrorType('ERR_INVALID_ARG_TYPE', function (name, expected, actual) { // determiner: 'must be' or 'must not be' var determiner; if (typeof expected === 'string' && startsWith(expected, 'not ')) { determiner = 'must not be'; expected = expected.replace(/^not /, ''); } else { determiner = 'must be'; } var msg; if (endsWith(name, ' argument')) { // For cases like 'first argument' msg = "The ".concat(name, " ").concat(determiner, " ").concat(oneOf(expected, 'type')); } else { var type = includes(name, '.') ? 'property' : 'argument'; msg = "The \"".concat(name, "\" ").concat(type, " ").concat(determiner, " ").concat(oneOf(expected, 'type')); } msg += ". Received type ".concat(typeof actual); return msg; }, TypeError); createErrorType('ERR_STREAM_PUSH_AFTER_EOF', 'stream.push() after EOF'); createErrorType('ERR_METHOD_NOT_IMPLEMENTED', function (name) { return 'The ' + name + ' method is not implemented'; }); createErrorType('ERR_STREAM_PREMATURE_CLOSE', 'Premature close'); createErrorType('ERR_STREAM_DESTROYED', function (name) { return 'Cannot call ' + name + ' after a stream was destroyed'; }); createErrorType('ERR_MULTIPLE_CALLBACK', 'Callback called multiple times'); createErrorType('ERR_STREAM_CANNOT_PIPE', 'Cannot pipe, not readable'); createErrorType('ERR_STREAM_WRITE_AFTER_END', 'write after end'); createErrorType('ERR_STREAM_NULL_VALUES', 'May not write null values to stream', TypeError); createErrorType('ERR_UNKNOWN_ENCODING', function (arg) { return 'Unknown encoding: ' + arg; }, TypeError); createErrorType('ERR_STREAM_UNSHIFT_AFTER_END_EVENT', 'stream.unshift() after end event'); module.exports.codes = codes; },{}],15:[function(require,module,exports){ (function (process){(function (){ // 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. // 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 Readable = require('./_stream_readable'); var Writable = require('./_stream_writable'); require('inherits')(Duplex, Readable); { // Allow the keys array to be GC'ed. 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); this.allowHalfOpen = true; if (options) { if (options.readable === false) this.readable = false; if (options.writable === false) this.writable = false; if (options.allowHalfOpen === false) { this.allowHalfOpen = false; this.once('end', onend); } } } Object.defineProperty(Duplex.prototype, 'writableHighWaterMark', { // making it explicit this property is not enumerable // because otherwise some prototype manipulation in // userland will fail enumerable: false, get: function get() { return this._writableState.highWaterMark; } }); Object.defineProperty(Duplex.prototype, 'writableBuffer', { // making it explicit this property is not enumerable // because otherwise some prototype manipulation in // userland will fail enumerable: false, get: function get() { return this._writableState && this._writableState.getBuffer(); } }); Object.defineProperty(Duplex.prototype, 'writableLength', { // making it explicit this property is not enumerable // because otherwise some prototype manipulation in // userland will fail enumerable: false, get: function get() { return this._writableState.length; } }); // the no-half-open enforcer function onend() { // If the writable side ended, then we're ok. if (this._writableState.ended) return; // no more data can be written. // But allow more writes to happen in this tick. process.nextTick(onEndNT, this); } function onEndNT(self) { self.end(); } Object.defineProperty(Duplex.prototype, 'destroyed', { // making it explicit this property is not enumerable // because otherwise some prototype manipulation in // userland will fail enumerable: false, get: function get() { if (this._readableState === undefined || this._writableState === undefined) { return false; } return this._readableState.destroyed && this._writableState.destroyed; }, set: function set(value) { // we ignore the value if the stream // has not been initialized yet if (this._readableState === undefined || this._writableState === undefined) { return; } // backward compatibility, the user is explicitly // managing destroyed this._readableState.destroyed = value; this._writableState.destroyed = value; } }); }).call(this)}).call(this,require('_process')) },{"./_stream_readable":17,"./_stream_writable":19,"_process":338,"inherits":131}],16:[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. // 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'); require('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":18,"inherits":131}],17:[function(require,module,exports){ (function (process,global){(function (){ // 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'; module.exports = Readable; /**/ var Duplex; /**/ Readable.ReadableState = ReadableState; /**/ var EE = require('events').EventEmitter; var EElistenerCount = function EElistenerCount(emitter, type) { return emitter.listeners(type).length; }; /**/ /**/ var Stream = require('./internal/streams/stream'); /**/ var Buffer = require('buffer').Buffer; var OurUint8Array = global.Uint8Array || function () {}; function _uint8ArrayToBuffer(chunk) { return Buffer.from(chunk); } function _isUint8Array(obj) { return Buffer.isBuffer(obj) || obj instanceof OurUint8Array; } /**/ var debugUtil = require('util'); var debug; if (debugUtil && debugUtil.debuglog) { debug = debugUtil.debuglog('stream'); } else { debug = function debug() {}; } /**/ var BufferList = require('./internal/streams/buffer_list'); var destroyImpl = require('./internal/streams/destroy'); var _require = require('./internal/streams/state'), getHighWaterMark = _require.getHighWaterMark; var _require$codes = require('../errors').codes, ERR_INVALID_ARG_TYPE = _require$codes.ERR_INVALID_ARG_TYPE, ERR_STREAM_PUSH_AFTER_EOF = _require$codes.ERR_STREAM_PUSH_AFTER_EOF, ERR_METHOD_NOT_IMPLEMENTED = _require$codes.ERR_METHOD_NOT_IMPLEMENTED, ERR_STREAM_UNSHIFT_AFTER_END_EVENT = _require$codes.ERR_STREAM_UNSHIFT_AFTER_END_EVENT; // Lazy loaded to improve the startup performance. var StringDecoder; var createReadableStreamAsyncIterator; var from; require('inherits')(Readable, Stream); var errorOrDestroy = destroyImpl.errorOrDestroy; 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); // 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 (Array.isArray(emitter._events[event])) emitter._events[event].unshift(fn);else emitter._events[event] = [fn, emitter._events[event]]; } function ReadableState(options, stream, isDuplex) { Duplex = Duplex || require('./_stream_duplex'); options = options || {}; // Duplex streams are both readable and writable, but share // the same options object. // However, some cases require setting options to different // values for the readable and the writable sides of the duplex stream. // These options can be provided separately as readableXXX and writableXXX. if (typeof isDuplex !== 'boolean') isDuplex = stream instanceof Duplex; // 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 (isDuplex) 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" this.highWaterMark = getHighWaterMark(this, options, 'readableHighWaterMark', isDuplex); // 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 event 'readable'/'data' is emitted // 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 read 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; this.paused = true; // Should close be emitted on destroy. Defaults to true. this.emitClose = options.emitClose !== false; // Should .destroy() be called after 'end' (and potentially 'finish') this.autoDestroy = !!options.autoDestroy; // has it been destroyed this.destroyed = 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'; // 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); // Checking for a Stream.Duplex instance is faster here instead of inside // the ReadableState constructor, at least with V8 6.5 var isDuplex = this instanceof Duplex; this._readableState = new ReadableState(options, this, isDuplex); // legacy this.readable = true; if (options) { if (typeof options.read === 'function') this._read = options.read; if (typeof options.destroy === 'function') this._destroy = options.destroy; } Stream.call(this); } Object.defineProperty(Readable.prototype, 'destroyed', { // making it explicit this property is not enumerable // because otherwise some prototype manipulation in // userland will fail enumerable: false, get: function get() { if (this._readableState === undefined) { return false; } return this._readableState.destroyed; }, set: function set(value) { // we ignore the value if the stream // has not been initialized yet if (!this._readableState) { return; } // backward compatibility, the user is explicitly // managing destroyed this._readableState.destroyed = value; } }); Readable.prototype.destroy = destroyImpl.destroy; Readable.prototype._undestroy = destroyImpl.undestroy; Readable.prototype._destroy = function (err, cb) { cb(err); }; // 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; var skipChunkCheck; if (!state.objectMode) { if (typeof chunk === 'string') { encoding = encoding || state.defaultEncoding; if (encoding !== state.encoding) { chunk = Buffer.from(chunk, encoding); encoding = ''; } skipChunkCheck = true; } } else { skipChunkCheck = true; } return readableAddChunk(this, chunk, encoding, false, skipChunkCheck); }; // Unshift should *always* be something directly out of read() Readable.prototype.unshift = function (chunk) { return readableAddChunk(this, chunk, null, true, false); }; function readableAddChunk(stream, chunk, encoding, addToFront, skipChunkCheck) { debug('readableAddChunk', chunk); var state = stream._readableState; if (chunk === null) { state.reading = false; onEofChunk(stream, state); } else { var er; if (!skipChunkCheck) er = chunkInvalid(state, chunk); if (er) { errorOrDestroy(stream, er); } else if (state.objectMode || chunk && chunk.length > 0) { if (typeof chunk !== 'string' && !state.objectMode && Object.getPrototypeOf(chunk) !== Buffer.prototype) { chunk = _uint8ArrayToBuffer(chunk); } if (addToFront) { if (state.endEmitted) errorOrDestroy(stream, new ERR_STREAM_UNSHIFT_AFTER_END_EVENT());else addChunk(stream, state, chunk, true); } else if (state.ended) { errorOrDestroy(stream, new ERR_STREAM_PUSH_AFTER_EOF()); } else if (state.destroyed) { return false; } else { state.reading = false; if (state.decoder && !encoding) { chunk = state.decoder.write(chunk); if (state.objectMode || chunk.length !== 0) addChunk(stream, state, chunk, false);else maybeReadMore(stream, state); } else { addChunk(stream, state, chunk, false); } } } else if (!addToFront) { state.reading = false; maybeReadMore(stream, state); } } // We can push more data if we are below the highWaterMark. // 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. return !state.ended && (state.length < state.highWaterMark || state.length === 0); } function addChunk(stream, state, chunk, addToFront) { if (state.flowing && state.length === 0 && !state.sync) { state.awaitDrain = 0; stream.emit('data', chunk); } 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); } function chunkInvalid(state, chunk) { var er; if (!_isUint8Array(chunk) && typeof chunk !== 'string' && chunk !== undefined && !state.objectMode) { er = new ERR_INVALID_ARG_TYPE('chunk', ['string', 'Buffer', 'Uint8Array'], chunk); } return er; } Readable.prototype.isPaused = function () { return this._readableState.flowing === false; }; // backwards compatibility. Readable.prototype.setEncoding = function (enc) { if (!StringDecoder) StringDecoder = require('string_decoder/').StringDecoder; var decoder = new StringDecoder(enc); this._readableState.decoder = decoder; // If setEncoding(null), decoder.encoding equals utf8 this._readableState.encoding = this._readableState.decoder.encoding; // Iterate over current buffer to convert already stored Buffers: var p = this._readableState.buffer.head; var content = ''; while (p !== null) { content += decoder.write(p.data); p = p.next; } this._readableState.buffer.clear(); if (content !== '') this._readableState.buffer.push(content); this._readableState.length = content.length; return this; }; // Don't raise the hwm > 1GB var MAX_HWM = 0x40000000; function computeNewHighWaterMark(n) { if (n >= MAX_HWM) { // TODO(ronag): Throw ERR_VALUE_OUT_OF_RANGE. 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.highWaterMark !== 0 ? state.length >= state.highWaterMark : state.length > 0) || 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 = state.length <= state.highWaterMark; n = 0; } else { state.length -= n; state.awaitDrain = 0; } 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 onEofChunk(stream, state) { debug('onEofChunk'); 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; if (state.sync) { // if we are sync, wait until next tick to emit the data. // Otherwise we risk emitting data in the flow() // the readable code triggers during a read() call emitReadable(stream); } else { // emit 'readable' now to make sure it gets picked up. state.needReadable = false; if (!state.emittedReadable) { state.emittedReadable = true; 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; debug('emitReadable', state.needReadable, state.emittedReadable); state.needReadable = false; if (!state.emittedReadable) { debug('emitReadable', state.flowing); state.emittedReadable = true; process.nextTick(emitReadable_, stream); } } function emitReadable_(stream) { var state = stream._readableState; debug('emitReadable_', state.destroyed, state.length, state.ended); if (!state.destroyed && (state.length || state.ended)) { stream.emit('readable'); state.emittedReadable = false; } // The stream needs another readable event if // 1. It is not flowing, as the flow mechanism will take // care of it. // 2. It is not ended. // 3. It is below the highWaterMark, so we can schedule // another readable later. state.needReadable = !state.flowing && !state.ended && state.length <= state.highWaterMark; 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; process.nextTick(maybeReadMore_, stream, state); } } function maybeReadMore_(stream, state) { // Attempt to read more data if we should. // // The conditions for reading more data are (one of): // - Not enough data buffered (state.length < state.highWaterMark). The loop // is responsible for filling the buffer with enough data if such data // is available. If highWaterMark is 0 and we are not in the flowing mode // we should _not_ attempt to buffer any extra data. We'll get more data // when the stream consumer calls read() instead. // - No data in the buffer, and the stream is in flowing mode. In this mode // the loop below is responsible for ensuring read() is called. Failing to // call read here would abort the flow and there's no other mechanism for // continuing the flow if the stream consumer has just subscribed to the // 'data' event. // // In addition to the above conditions to keep reading data, the following // conditions prevent the data from being read: // - The stream has ended (state.ended). // - There is already a pending 'read' operation (state.reading). This is a // case where the the stream has called the implementation defined _read() // method, but they are processing the call asynchronously and have _not_ // called push() with new data. In this case we skip performing more // read()s. The execution ends in this method again after the _read() ends // up calling push() with more data. while (!state.reading && !state.ended && (state.length < state.highWaterMark || state.flowing && state.length === 0)) { var len = state.length; debug('maybeReadMore read 0'); stream.read(0); if (len === state.length) // didn't get any data, stop spinning. break; } 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) { errorOrDestroy(this, new ERR_METHOD_NOT_IMPLEMENTED('_read()')); }; 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 : unpipe; if (state.endEmitted) process.nextTick(endFn);else src.once('end', endFn); dest.on('unpipe', onunpipe); function onunpipe(readable, unpipeInfo) { debug('onunpipe'); if (readable === src) { if (unpipeInfo && unpipeInfo.hasUnpiped === false) { unpipeInfo.hasUnpiped = true; 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', unpipe); 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(); } src.on('data', ondata); function ondata(chunk) { debug('ondata'); var ret = dest.write(chunk); debug('dest.write', ret); if (ret === false) { // 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', state.awaitDrain); state.awaitDrain++; } 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) errorOrDestroy(dest, 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 pipeOnDrainFunctionResult() { 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; var unpipeInfo = { hasUnpiped: false }; // 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, unpipeInfo); 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, { hasUnpiped: false }); } 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, unpipeInfo); 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); var state = this._readableState; if (ev === 'data') { // update readableListening so that resume() may be a no-op // a few lines down. This is needed to support once('readable'). state.readableListening = this.listenerCount('readable') > 0; // Try start flowing on next tick if stream isn't explicitly paused if (state.flowing !== false) this.resume(); } else if (ev === 'readable') { if (!state.endEmitted && !state.readableListening) { state.readableListening = state.needReadable = true; state.flowing = false; state.emittedReadable = false; debug('on readable', state.length, state.reading); if (state.length) { emitReadable(this); } else if (!state.reading) { process.nextTick(nReadingNextTick, this); } } } return res; }; Readable.prototype.addListener = Readable.prototype.on; Readable.prototype.removeListener = function (ev, fn) { var res = Stream.prototype.removeListener.call(this, ev, fn); if (ev === 'readable') { // We need to check if there is someone still listening to // readable and reset the state. However this needs to happen // after readable has been emitted but before I/O (nextTick) to // support once('readable', fn) cycles. This means that calling // resume within the same tick will have no // effect. process.nextTick(updateReadableListening, this); } return res; }; Readable.prototype.removeAllListeners = function (ev) { var res = Stream.prototype.removeAllListeners.apply(this, arguments); if (ev === 'readable' || ev === undefined) { // We need to check if there is someone still listening to // readable and reset the state. However this needs to happen // after readable has been emitted but before I/O (nextTick) to // support once('readable', fn) cycles. This means that calling // resume within the same tick will have no // effect. process.nextTick(updateReadableListening, this); } return res; }; function updateReadableListening(self) { var state = self._readableState; state.readableListening = self.listenerCount('readable') > 0; if (state.resumeScheduled && !state.paused) { // flowing needs to be set to true now, otherwise // the upcoming resume will not flow. state.flowing = true; // crude way to check if we should resume } else if (self.listenerCount('data') > 0) { self.resume(); } } 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'); // we flow only if there is no one listening // for readable, but we still have to call // resume() state.flowing = !state.readableListening; resume(this, state); } state.paused = false; return this; }; function resume(stream, state) { if (!state.resumeScheduled) { state.resumeScheduled = true; process.nextTick(resume_, stream, state); } } function resume_(stream, state) { debug('resume', state.reading); if (!state.reading) { stream.read(0); } state.resumeScheduled = false; 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 (this._readableState.flowing !== false) { debug('pause'); this._readableState.flowing = false; this.emit('pause'); } this._readableState.paused = true; 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 _this = this; var state = this._readableState; var paused = false; stream.on('end', function () { debug('wrapped end'); if (state.decoder && !state.ended) { var chunk = state.decoder.end(); if (chunk && chunk.length) _this.push(chunk); } _this.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 = _this.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 methodWrap(method) { return function methodWrapReturnFunction() { return stream[method].apply(stream, arguments); }; }(i); } } // proxy certain important events. for (var n = 0; n < kProxyEvents.length; n++) { stream.on(kProxyEvents[n], this.emit.bind(this, kProxyEvents[n])); } // when we try to consume some more bytes, simply unpause the // underlying stream. this._read = function (n) { debug('wrapped _read', n); if (paused) { paused = false; stream.resume(); } }; return this; }; if (typeof Symbol === 'function') { Readable.prototype[Symbol.asyncIterator] = function () { if (createReadableStreamAsyncIterator === undefined) { createReadableStreamAsyncIterator = require('./internal/streams/async_iterator'); } return createReadableStreamAsyncIterator(this); }; } Object.defineProperty(Readable.prototype, 'readableHighWaterMark', { // making it explicit this property is not enumerable // because otherwise some prototype manipulation in // userland will fail enumerable: false, get: function get() { return this._readableState.highWaterMark; } }); Object.defineProperty(Readable.prototype, 'readableBuffer', { // making it explicit this property is not enumerable // because otherwise some prototype manipulation in // userland will fail enumerable: false, get: function get() { return this._readableState && this._readableState.buffer; } }); Object.defineProperty(Readable.prototype, 'readableFlowing', { // making it explicit this property is not enumerable // because otherwise some prototype manipulation in // userland will fail enumerable: false, get: function get() { return this._readableState.flowing; }, set: function set(state) { if (this._readableState) { this._readableState.flowing = state; } } }); // exposed for testing purposes only. Readable._fromList = fromList; Object.defineProperty(Readable.prototype, 'readableLength', { // making it explicit this property is not enumerable // because otherwise some prototype manipulation in // userland will fail enumerable: false, get: function get() { return this._readableState.length; } }); // 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.first();else ret = state.buffer.concat(state.length); state.buffer.clear(); } else { // read part of list ret = state.buffer.consume(n, state.decoder); } return ret; } function endReadable(stream) { var state = stream._readableState; debug('endReadable', state.endEmitted); if (!state.endEmitted) { state.ended = true; process.nextTick(endReadableNT, state, stream); } } function endReadableNT(state, stream) { debug('endReadableNT', state.endEmitted, state.length); // Check that we didn't get one last unshift. if (!state.endEmitted && state.length === 0) { state.endEmitted = true; stream.readable = false; stream.emit('end'); if (state.autoDestroy) { // In case of duplex streams we need a way to detect // if the writable side is ready for autoDestroy as well var wState = stream._writableState; if (!wState || wState.autoDestroy && wState.finished) { stream.destroy(); } } } } if (typeof Symbol === 'function') { Readable.from = function (iterable, opts) { if (from === undefined) { from = require('./internal/streams/from'); } return from(Readable, iterable, opts); }; } function indexOf(xs, x) { for (var i = 0, l = xs.length; i < l; i++) { if (xs[i] === x) return i; } return -1; } }).call(this)}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{"../errors":14,"./_stream_duplex":15,"./internal/streams/async_iterator":20,"./internal/streams/buffer_list":21,"./internal/streams/destroy":22,"./internal/streams/from":24,"./internal/streams/state":26,"./internal/streams/stream":27,"_process":338,"buffer":331,"events":333,"inherits":131,"string_decoder/":281,"util":330}],18:[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. // 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 _require$codes = require('../errors').codes, ERR_METHOD_NOT_IMPLEMENTED = _require$codes.ERR_METHOD_NOT_IMPLEMENTED, ERR_MULTIPLE_CALLBACK = _require$codes.ERR_MULTIPLE_CALLBACK, ERR_TRANSFORM_ALREADY_TRANSFORMING = _require$codes.ERR_TRANSFORM_ALREADY_TRANSFORMING, ERR_TRANSFORM_WITH_LENGTH_0 = _require$codes.ERR_TRANSFORM_WITH_LENGTH_0; var Duplex = require('./_stream_duplex'); require('inherits')(Transform, Duplex); function afterTransform(er, data) { var ts = this._transformState; ts.transforming = false; var cb = ts.writecb; if (cb === null) { return this.emit('error', new ERR_MULTIPLE_CALLBACK()); } ts.writechunk = null; ts.writecb = null; if (data != null) // single equals check for both `null` and `undefined` this.push(data); cb(er); var rs = this._readableState; rs.reading = false; if (rs.needReadable || rs.length < rs.highWaterMark) { this._read(rs.highWaterMark); } } function Transform(options) { if (!(this instanceof Transform)) return new Transform(options); Duplex.call(this, options); this._transformState = { afterTransform: afterTransform.bind(this), needTransform: false, transforming: false, writecb: null, writechunk: null, writeencoding: null }; // 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.on('prefinish', prefinish); } function prefinish() { var _this = this; if (typeof this._flush === 'function' && !this._readableState.destroyed) { this._flush(function (er, data) { done(_this, er, data); }); } else { done(this, null, null); } } 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) { cb(new ERR_METHOD_NOT_IMPLEMENTED('_transform()')); }; 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.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; } }; Transform.prototype._destroy = function (err, cb) { Duplex.prototype._destroy.call(this, err, function (err2) { cb(err2); }); }; function done(stream, er, data) { if (er) return stream.emit('error', er); if (data != null) // single equals check for both `null` and `undefined` stream.push(data); // TODO(BridgeAR): Write a test for these two error cases // if there's nothing in the write buffer, then that means // that nothing more will ever be provided if (stream._writableState.length) throw new ERR_TRANSFORM_WITH_LENGTH_0(); if (stream._transformState.transforming) throw new ERR_TRANSFORM_ALREADY_TRANSFORMING(); return stream.push(null); } },{"../errors":14,"./_stream_duplex":15,"inherits":131}],19:[function(require,module,exports){ (function (process,global){(function (){ // 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. // 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; /* */ function WriteReq(chunk, encoding, cb) { this.chunk = chunk; this.encoding = encoding; this.callback = cb; this.next = null; } // 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 () { onCorkedFinish(_this, state); }; } /* */ /**/ var Duplex; /**/ Writable.WritableState = WritableState; /**/ var internalUtil = { deprecate: require('util-deprecate') }; /**/ /**/ var Stream = require('./internal/streams/stream'); /**/ var Buffer = require('buffer').Buffer; var OurUint8Array = global.Uint8Array || function () {}; function _uint8ArrayToBuffer(chunk) { return Buffer.from(chunk); } function _isUint8Array(obj) { return Buffer.isBuffer(obj) || obj instanceof OurUint8Array; } var destroyImpl = require('./internal/streams/destroy'); var _require = require('./internal/streams/state'), getHighWaterMark = _require.getHighWaterMark; var _require$codes = require('../errors').codes, ERR_INVALID_ARG_TYPE = _require$codes.ERR_INVALID_ARG_TYPE, ERR_METHOD_NOT_IMPLEMENTED = _require$codes.ERR_METHOD_NOT_IMPLEMENTED, ERR_MULTIPLE_CALLBACK = _require$codes.ERR_MULTIPLE_CALLBACK, ERR_STREAM_CANNOT_PIPE = _require$codes.ERR_STREAM_CANNOT_PIPE, ERR_STREAM_DESTROYED = _require$codes.ERR_STREAM_DESTROYED, ERR_STREAM_NULL_VALUES = _require$codes.ERR_STREAM_NULL_VALUES, ERR_STREAM_WRITE_AFTER_END = _require$codes.ERR_STREAM_WRITE_AFTER_END, ERR_UNKNOWN_ENCODING = _require$codes.ERR_UNKNOWN_ENCODING; var errorOrDestroy = destroyImpl.errorOrDestroy; require('inherits')(Writable, Stream); function nop() {} function WritableState(options, stream, isDuplex) { Duplex = Duplex || require('./_stream_duplex'); options = options || {}; // Duplex streams are both readable and writable, but share // the same options object. // However, some cases require setting options to different // values for the readable and the writable sides of the duplex stream, // e.g. options.readableObjectMode vs. options.writableObjectMode, etc. if (typeof isDuplex !== 'boolean') isDuplex = stream instanceof Duplex; // object stream flag to indicate whether or not this stream // contains buffers or objects. this.objectMode = !!options.objectMode; if (isDuplex) 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() this.highWaterMark = getHighWaterMark(this, options, 'writableHighWaterMark', isDuplex); // if _final has been called this.finalCalled = false; // 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; // has it been destroyed this.destroyed = 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; // Should close be emitted on destroy. Defaults to true. this.emitClose = options.emitClose !== false; // Should .destroy() be called after 'finish' (and potentially 'end') this.autoDestroy = !!options.autoDestroy; // 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 writableStateBufferGetter() { return this.getBuffer(); }, '_writableState.buffer is deprecated. Use _writableState.getBuffer ' + 'instead.', 'DEP0003') }); } 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 value(object) { if (realHasInstance.call(this, object)) return true; if (this !== Writable) return false; return object && object._writableState instanceof WritableState; } }); } else { realHasInstance = function realHasInstance(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. // Checking for a Stream.Duplex instance is faster here instead of inside // the WritableState constructor, at least with V8 6.5 var isDuplex = this instanceof Duplex; if (!isDuplex && !realHasInstance.call(Writable, this)) return new Writable(options); this._writableState = new WritableState(options, this, isDuplex); // legacy. this.writable = true; if (options) { if (typeof options.write === 'function') this._write = options.write; if (typeof options.writev === 'function') this._writev = options.writev; if (typeof options.destroy === 'function') this._destroy = options.destroy; if (typeof options.final === 'function') this._final = options.final; } Stream.call(this); } // Otherwise people can pipe Writable streams, which is just wrong. Writable.prototype.pipe = function () { errorOrDestroy(this, new ERR_STREAM_CANNOT_PIPE()); }; function writeAfterEnd(stream, cb) { var er = new ERR_STREAM_WRITE_AFTER_END(); // TODO: defer error events consistently everywhere, not just the cb errorOrDestroy(stream, er); process.nextTick(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 er; if (chunk === null) { er = new ERR_STREAM_NULL_VALUES(); } else if (typeof chunk !== 'string' && !state.objectMode) { er = new ERR_INVALID_ARG_TYPE('chunk', ['string', 'Buffer'], chunk); } if (er) { errorOrDestroy(stream, er); process.nextTick(cb, er); return false; } return true; } Writable.prototype.write = function (chunk, encoding, cb) { var state = this._writableState; var ret = false; var isBuf = !state.objectMode && _isUint8Array(chunk); if (isBuf && !Buffer.isBuffer(chunk)) { chunk = _uint8ArrayToBuffer(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.ending) 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 () { this._writableState.corked++; }; Writable.prototype.uncork = function () { var state = this._writableState; if (state.corked) { state.corked--; if (!state.writing && !state.corked && !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 ERR_UNKNOWN_ENCODING(encoding); this._writableState.defaultEncoding = encoding; return this; }; Object.defineProperty(Writable.prototype, 'writableBuffer', { // making it explicit this property is not enumerable // because otherwise some prototype manipulation in // userland will fail enumerable: false, get: function get() { return this._writableState && this._writableState.getBuffer(); } }); function decodeChunk(state, chunk, encoding) { if (!state.objectMode && state.decodeStrings !== false && typeof chunk === 'string') { chunk = Buffer.from(chunk, encoding); } return chunk; } Object.defineProperty(Writable.prototype, 'writableHighWaterMark', { // making it explicit this property is not enumerable // because otherwise some prototype manipulation in // userland will fail enumerable: false, get: function get() { return this._writableState.highWaterMark; } }); // 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) { var newChunk = decodeChunk(state, chunk, encoding); if (chunk !== newChunk) { isBuf = true; encoding = 'buffer'; chunk = newChunk; } } 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 = { chunk: chunk, encoding: encoding, isBuf: isBuf, callback: cb, next: null }; 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 (state.destroyed) state.onwrite(new ERR_STREAM_DESTROYED('write'));else 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) { // defer the callback if we are being called synchronously // to avoid piling up things on the stack process.nextTick(cb, er); // this can emit finish, and it will always happen // after error process.nextTick(finishMaybe, stream, state); stream._writableState.errorEmitted = true; errorOrDestroy(stream, er); } else { // the caller expect this to happen before if // it is async cb(er); stream._writableState.errorEmitted = true; errorOrDestroy(stream, er); // this can emit finish, but finish must // always follow error finishMaybe(stream, state); } } 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; if (typeof cb !== 'function') throw new ERR_MULTIPLE_CALLBACK(); 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) || stream.destroyed; if (!finished && !state.corked && !state.bufferProcessing && state.bufferedRequest) { clearBuffer(stream, state); } if (sync) { process.nextTick(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; var allBuffers = true; while (entry) { buffer[count] = entry; if (!entry.isBuf) allBuffers = false; entry = entry.next; count += 1; } buffer.allBuffers = allBuffers; 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); } state.bufferedRequestCount = 0; } 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; state.bufferedRequestCount--; // 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.bufferedRequest = entry; state.bufferProcessing = false; } Writable.prototype._write = function (chunk, encoding, cb) { cb(new ERR_METHOD_NOT_IMPLEMENTED('_write()')); }; 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) endWritable(this, state, cb); return this; }; Object.defineProperty(Writable.prototype, 'writableLength', { // making it explicit this property is not enumerable // because otherwise some prototype manipulation in // userland will fail enumerable: false, get: function get() { return this._writableState.length; } }); function needFinish(state) { return state.ending && state.length === 0 && state.bufferedRequest === null && !state.finished && !state.writing; } function callFinal(stream, state) { stream._final(function (err) { state.pendingcb--; if (err) { errorOrDestroy(stream, err); } state.prefinished = true; stream.emit('prefinish'); finishMaybe(stream, state); }); } function prefinish(stream, state) { if (!state.prefinished && !state.finalCalled) { if (typeof stream._final === 'function' && !state.destroyed) { state.pendingcb++; state.finalCalled = true; process.nextTick(callFinal, stream, state); } else { state.prefinished = true; stream.emit('prefinish'); } } } function finishMaybe(stream, state) { var need = needFinish(state); if (need) { prefinish(stream, state); if (state.pendingcb === 0) { state.finished = true; stream.emit('finish'); if (state.autoDestroy) { // In case of duplex streams we need a way to detect // if the readable side is ready for autoDestroy as well var rState = stream._readableState; if (!rState || rState.autoDestroy && rState.endEmitted) { stream.destroy(); } } } } return need; } function endWritable(stream, state, cb) { state.ending = true; finishMaybe(stream, state); if (cb) { if (state.finished) process.nextTick(cb);else stream.once('finish', cb); } state.ended = true; stream.writable = false; } function onCorkedFinish(corkReq, state, err) { var entry = corkReq.entry; corkReq.entry = null; while (entry) { var cb = entry.callback; state.pendingcb--; cb(err); entry = entry.next; } // reuse the free corkReq. state.corkedRequestsFree.next = corkReq; } Object.defineProperty(Writable.prototype, 'destroyed', { // making it explicit this property is not enumerable // because otherwise some prototype manipulation in // userland will fail enumerable: false, get: function get() { if (this._writableState === undefined) { return false; } return this._writableState.destroyed; }, set: function set(value) { // we ignore the value if the stream // has not been initialized yet if (!this._writableState) { return; } // backward compatibility, the user is explicitly // managing destroyed this._writableState.destroyed = value; } }); Writable.prototype.destroy = destroyImpl.destroy; Writable.prototype._undestroy = destroyImpl.undestroy; Writable.prototype._destroy = function (err, cb) { cb(err); }; }).call(this)}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{"../errors":14,"./_stream_duplex":15,"./internal/streams/destroy":22,"./internal/streams/state":26,"./internal/streams/stream":27,"_process":338,"buffer":331,"inherits":131,"util-deprecate":298}],20:[function(require,module,exports){ (function (process){(function (){ 'use strict'; var _Object$setPrototypeO; function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } var finished = require('./end-of-stream'); var kLastResolve = Symbol('lastResolve'); var kLastReject = Symbol('lastReject'); var kError = Symbol('error'); var kEnded = Symbol('ended'); var kLastPromise = Symbol('lastPromise'); var kHandlePromise = Symbol('handlePromise'); var kStream = Symbol('stream'); function createIterResult(value, done) { return { value: value, done: done }; } function readAndResolve(iter) { var resolve = iter[kLastResolve]; if (resolve !== null) { var data = iter[kStream].read(); // we defer if data is null // we can be expecting either 'end' or // 'error' if (data !== null) { iter[kLastPromise] = null; iter[kLastResolve] = null; iter[kLastReject] = null; resolve(createIterResult(data, false)); } } } function onReadable(iter) { // we wait for the next tick, because it might // emit an error with process.nextTick process.nextTick(readAndResolve, iter); } function wrapForNext(lastPromise, iter) { return function (resolve, reject) { lastPromise.then(function () { if (iter[kEnded]) { resolve(createIterResult(undefined, true)); return; } iter[kHandlePromise](resolve, reject); }, reject); }; } var AsyncIteratorPrototype = Object.getPrototypeOf(function () {}); var ReadableStreamAsyncIteratorPrototype = Object.setPrototypeOf((_Object$setPrototypeO = { get stream() { return this[kStream]; }, next: function next() { var _this = this; // if we have detected an error in the meanwhile // reject straight away var error = this[kError]; if (error !== null) { return Promise.reject(error); } if (this[kEnded]) { return Promise.resolve(createIterResult(undefined, true)); } if (this[kStream].destroyed) { // We need to defer via nextTick because if .destroy(err) is // called, the error will be emitted via nextTick, and // we cannot guarantee that there is no error lingering around // waiting to be emitted. return new Promise(function (resolve, reject) { process.nextTick(function () { if (_this[kError]) { reject(_this[kError]); } else { resolve(createIterResult(undefined, true)); } }); }); } // if we have multiple next() calls // we will wait for the previous Promise to finish // this logic is optimized to support for await loops, // where next() is only called once at a time var lastPromise = this[kLastPromise]; var promise; if (lastPromise) { promise = new Promise(wrapForNext(lastPromise, this)); } else { // fast path needed to support multiple this.push() // without triggering the next() queue var data = this[kStream].read(); if (data !== null) { return Promise.resolve(createIterResult(data, false)); } promise = new Promise(this[kHandlePromise]); } this[kLastPromise] = promise; return promise; } }, _defineProperty(_Object$setPrototypeO, Symbol.asyncIterator, function () { return this; }), _defineProperty(_Object$setPrototypeO, "return", function _return() { var _this2 = this; // destroy(err, cb) is a private API // we can guarantee we have that here, because we control the // Readable class this is attached to return new Promise(function (resolve, reject) { _this2[kStream].destroy(null, function (err) { if (err) { reject(err); return; } resolve(createIterResult(undefined, true)); }); }); }), _Object$setPrototypeO), AsyncIteratorPrototype); var createReadableStreamAsyncIterator = function createReadableStreamAsyncIterator(stream) { var _Object$create; var iterator = Object.create(ReadableStreamAsyncIteratorPrototype, (_Object$create = {}, _defineProperty(_Object$create, kStream, { value: stream, writable: true }), _defineProperty(_Object$create, kLastResolve, { value: null, writable: true }), _defineProperty(_Object$create, kLastReject, { value: null, writable: true }), _defineProperty(_Object$create, kError, { value: null, writable: true }), _defineProperty(_Object$create, kEnded, { value: stream._readableState.endEmitted, writable: true }), _defineProperty(_Object$create, kHandlePromise, { value: function value(resolve, reject) { var data = iterator[kStream].read(); if (data) { iterator[kLastPromise] = null; iterator[kLastResolve] = null; iterator[kLastReject] = null; resolve(createIterResult(data, false)); } else { iterator[kLastResolve] = resolve; iterator[kLastReject] = reject; } }, writable: true }), _Object$create)); iterator[kLastPromise] = null; finished(stream, function (err) { if (err && err.code !== 'ERR_STREAM_PREMATURE_CLOSE') { var reject = iterator[kLastReject]; // reject if we are waiting for data in the Promise // returned by next() and store the error if (reject !== null) { iterator[kLastPromise] = null; iterator[kLastResolve] = null; iterator[kLastReject] = null; reject(err); } iterator[kError] = err; return; } var resolve = iterator[kLastResolve]; if (resolve !== null) { iterator[kLastPromise] = null; iterator[kLastResolve] = null; iterator[kLastReject] = null; resolve(createIterResult(undefined, true)); } iterator[kEnded] = true; }); stream.on('readable', onReadable.bind(null, iterator)); return iterator; }; module.exports = createReadableStreamAsyncIterator; }).call(this)}).call(this,require('_process')) },{"./end-of-stream":23,"_process":338}],21:[function(require,module,exports){ 'use strict'; function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } var _require = require('buffer'), Buffer = _require.Buffer; var _require2 = require('util'), inspect = _require2.inspect; var custom = inspect && inspect.custom || 'inspect'; function copyBuffer(src, target, offset) { Buffer.prototype.copy.call(src, target, offset); } module.exports = /*#__PURE__*/ function () { function BufferList() { _classCallCheck(this, BufferList); this.head = null; this.tail = null; this.length = 0; } _createClass(BufferList, [{ key: "push", value: function push(v) { var entry = { data: v, next: null }; if (this.length > 0) this.tail.next = entry;else this.head = entry; this.tail = entry; ++this.length; } }, { key: "unshift", value: function unshift(v) { var entry = { data: v, next: this.head }; if (this.length === 0) this.tail = entry; this.head = entry; ++this.length; } }, { key: "shift", value: function shift() { 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; } }, { key: "clear", value: function clear() { this.head = this.tail = null; this.length = 0; } }, { key: "join", value: function join(s) { if (this.length === 0) return ''; var p = this.head; var ret = '' + p.data; while (p = p.next) { ret += s + p.data; } return ret; } }, { key: "concat", value: function concat(n) { if (this.length === 0) return Buffer.alloc(0); var ret = Buffer.allocUnsafe(n >>> 0); var p = this.head; var i = 0; while (p) { copyBuffer(p.data, ret, i); i += p.data.length; p = p.next; } return ret; } // Consumes a specified amount of bytes or characters from the buffered data. }, { key: "consume", value: function consume(n, hasStrings) { var ret; if (n < this.head.data.length) { // `slice` is the same for buffers and strings. ret = this.head.data.slice(0, n); this.head.data = this.head.data.slice(n); } else if (n === this.head.data.length) { // First chunk is a perfect match. ret = this.shift(); } else { // Result spans more than one buffer. ret = hasStrings ? this._getString(n) : this._getBuffer(n); } return ret; } }, { key: "first", value: function first() { return this.head.data; } // Consumes a specified amount of characters from the buffered data. }, { key: "_getString", value: function _getString(n) { var p = this.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) this.head = p.next;else this.head = this.tail = null; } else { this.head = p; p.data = str.slice(nb); } break; } ++c; } this.length -= c; return ret; } // Consumes a specified amount of bytes from the buffered data. }, { key: "_getBuffer", value: function _getBuffer(n) { var ret = Buffer.allocUnsafe(n); var p = this.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) this.head = p.next;else this.head = this.tail = null; } else { this.head = p; p.data = buf.slice(nb); } break; } ++c; } this.length -= c; return ret; } // Make sure the linked list only shows the minimal necessary information. }, { key: custom, value: function value(_, options) { return inspect(this, _objectSpread({}, options, { // Only inspect one level. depth: 0, // It should not recurse. customInspect: false })); } }]); return BufferList; }(); },{"buffer":331,"util":330}],22:[function(require,module,exports){ (function (process){(function (){ 'use strict'; // undocumented cb() API, needed for core, not for public API function destroy(err, cb) { var _this = this; var readableDestroyed = this._readableState && this._readableState.destroyed; var writableDestroyed = this._writableState && this._writableState.destroyed; if (readableDestroyed || writableDestroyed) { if (cb) { cb(err); } else if (err) { if (!this._writableState) { process.nextTick(emitErrorNT, this, err); } else if (!this._writableState.errorEmitted) { this._writableState.errorEmitted = true; process.nextTick(emitErrorNT, this, err); } } return this; } // we set destroyed to true before firing error callbacks in order // to make it re-entrance safe in case destroy() is called within callbacks if (this._readableState) { this._readableState.destroyed = true; } // if this is a duplex stream mark the writable part as destroyed as well if (this._writableState) { this._writableState.destroyed = true; } this._destroy(err || null, function (err) { if (!cb && err) { if (!_this._writableState) { process.nextTick(emitErrorAndCloseNT, _this, err); } else if (!_this._writableState.errorEmitted) { _this._writableState.errorEmitted = true; process.nextTick(emitErrorAndCloseNT, _this, err); } else { process.nextTick(emitCloseNT, _this); } } else if (cb) { process.nextTick(emitCloseNT, _this); cb(err); } else { process.nextTick(emitCloseNT, _this); } }); return this; } function emitErrorAndCloseNT(self, err) { emitErrorNT(self, err); emitCloseNT(self); } function emitCloseNT(self) { if (self._writableState && !self._writableState.emitClose) return; if (self._readableState && !self._readableState.emitClose) return; self.emit('close'); } function undestroy() { if (this._readableState) { this._readableState.destroyed = false; this._readableState.reading = false; this._readableState.ended = false; this._readableState.endEmitted = false; } if (this._writableState) { this._writableState.destroyed = false; this._writableState.ended = false; this._writableState.ending = false; this._writableState.finalCalled = false; this._writableState.prefinished = false; this._writableState.finished = false; this._writableState.errorEmitted = false; } } function emitErrorNT(self, err) { self.emit('error', err); } function errorOrDestroy(stream, err) { // We have tests that rely on errors being emitted // in the same tick, so changing this is semver major. // For now when you opt-in to autoDestroy we allow // the error to be emitted nextTick. In a future // semver major update we should change the default to this. var rState = stream._readableState; var wState = stream._writableState; if (rState && rState.autoDestroy || wState && wState.autoDestroy) stream.destroy(err);else stream.emit('error', err); } module.exports = { destroy: destroy, undestroy: undestroy, errorOrDestroy: errorOrDestroy }; }).call(this)}).call(this,require('_process')) },{"_process":338}],23:[function(require,module,exports){ // Ported from https://github.com/mafintosh/end-of-stream with // permission from the author, Mathias Buus (@mafintosh). 'use strict'; var ERR_STREAM_PREMATURE_CLOSE = require('../../../errors').codes.ERR_STREAM_PREMATURE_CLOSE; function once(callback) { var called = false; return function () { if (called) return; called = true; for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } callback.apply(this, args); }; } function noop() {} function isRequest(stream) { return stream.setHeader && typeof stream.abort === 'function'; } function eos(stream, opts, callback) { if (typeof opts === 'function') return eos(stream, null, opts); if (!opts) opts = {}; callback = once(callback || noop); var readable = opts.readable || opts.readable !== false && stream.readable; var writable = opts.writable || opts.writable !== false && stream.writable; var onlegacyfinish = function onlegacyfinish() { if (!stream.writable) onfinish(); }; var writableEnded = stream._writableState && stream._writableState.finished; var onfinish = function onfinish() { writable = false; writableEnded = true; if (!readable) callback.call(stream); }; var readableEnded = stream._readableState && stream._readableState.endEmitted; var onend = function onend() { readable = false; readableEnded = true; if (!writable) callback.call(stream); }; var onerror = function onerror(err) { callback.call(stream, err); }; var onclose = function onclose() { var err; if (readable && !readableEnded) { if (!stream._readableState || !stream._readableState.ended) err = new ERR_STREAM_PREMATURE_CLOSE(); return callback.call(stream, err); } if (writable && !writableEnded) { if (!stream._writableState || !stream._writableState.ended) err = new ERR_STREAM_PREMATURE_CLOSE(); return callback.call(stream, err); } }; var onrequest = function onrequest() { stream.req.on('finish', onfinish); }; if (isRequest(stream)) { stream.on('complete', onfinish); stream.on('abort', onclose); if (stream.req) onrequest();else stream.on('request', onrequest); } else if (writable && !stream._writableState) { // legacy streams stream.on('end', onlegacyfinish); stream.on('close', onlegacyfinish); } stream.on('end', onend); stream.on('finish', onfinish); if (opts.error !== false) stream.on('error', onerror); stream.on('close', onclose); return function () { stream.removeListener('complete', onfinish); stream.removeListener('abort', onclose); stream.removeListener('request', onrequest); if (stream.req) stream.req.removeListener('finish', onfinish); stream.removeListener('end', onlegacyfinish); stream.removeListener('close', onlegacyfinish); stream.removeListener('finish', onfinish); stream.removeListener('end', onend); stream.removeListener('error', onerror); stream.removeListener('close', onclose); }; } module.exports = eos; },{"../../../errors":14}],24:[function(require,module,exports){ module.exports = function () { throw new Error('Readable.from is not available in the browser') }; },{}],25:[function(require,module,exports){ // Ported from https://github.com/mafintosh/pump with // permission from the author, Mathias Buus (@mafintosh). 'use strict'; var eos; function once(callback) { var called = false; return function () { if (called) return; called = true; callback.apply(void 0, arguments); }; } var _require$codes = require('../../../errors').codes, ERR_MISSING_ARGS = _require$codes.ERR_MISSING_ARGS, ERR_STREAM_DESTROYED = _require$codes.ERR_STREAM_DESTROYED; function noop(err) { // Rethrow the error if it exists to avoid swallowing it if (err) throw err; } function isRequest(stream) { return stream.setHeader && typeof stream.abort === 'function'; } function destroyer(stream, reading, writing, callback) { callback = once(callback); var closed = false; stream.on('close', function () { closed = true; }); if (eos === undefined) eos = require('./end-of-stream'); eos(stream, { readable: reading, writable: writing }, function (err) { if (err) return callback(err); closed = true; callback(); }); var destroyed = false; return function (err) { if (closed) return; if (destroyed) return; destroyed = true; // request.destroy just do .end - .abort is what we want if (isRequest(stream)) return stream.abort(); if (typeof stream.destroy === 'function') return stream.destroy(); callback(err || new ERR_STREAM_DESTROYED('pipe')); }; } function call(fn) { fn(); } function pipe(from, to) { return from.pipe(to); } function popCallback(streams) { if (!streams.length) return noop; if (typeof streams[streams.length - 1] !== 'function') return noop; return streams.pop(); } function pipeline() { for (var _len = arguments.length, streams = new Array(_len), _key = 0; _key < _len; _key++) { streams[_key] = arguments[_key]; } var callback = popCallback(streams); if (Array.isArray(streams[0])) streams = streams[0]; if (streams.length < 2) { throw new ERR_MISSING_ARGS('streams'); } var error; var destroys = streams.map(function (stream, i) { var reading = i < streams.length - 1; var writing = i > 0; return destroyer(stream, reading, writing, function (err) { if (!error) error = err; if (err) destroys.forEach(call); if (reading) return; destroys.forEach(call); callback(error); }); }); return streams.reduce(pipe); } module.exports = pipeline; },{"../../../errors":14,"./end-of-stream":23}],26:[function(require,module,exports){ 'use strict'; var ERR_INVALID_OPT_VALUE = require('../../../errors').codes.ERR_INVALID_OPT_VALUE; function highWaterMarkFrom(options, isDuplex, duplexKey) { return options.highWaterMark != null ? options.highWaterMark : isDuplex ? options[duplexKey] : null; } function getHighWaterMark(state, options, duplexKey, isDuplex) { var hwm = highWaterMarkFrom(options, isDuplex, duplexKey); if (hwm != null) { if (!(isFinite(hwm) && Math.floor(hwm) === hwm) || hwm < 0) { var name = isDuplex ? duplexKey : 'highWaterMark'; throw new ERR_INVALID_OPT_VALUE(name, hwm); } return Math.floor(hwm); } // Default value return state.objectMode ? 16 : 16 * 1024; } module.exports = { getHighWaterMark: getHighWaterMark }; },{"../../../errors":14}],27:[function(require,module,exports){ module.exports = require('events').EventEmitter; },{"events":333}],28:[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'); exports.finished = require('./lib/internal/streams/end-of-stream.js'); exports.pipeline = require('./lib/internal/streams/pipeline.js'); },{"./lib/_stream_duplex.js":15,"./lib/_stream_passthrough.js":16,"./lib/_stream_readable.js":17,"./lib/_stream_transform.js":18,"./lib/_stream_writable.js":19,"./lib/internal/streams/end-of-stream.js":23,"./lib/internal/streams/pipeline.js":25}],29:[function(require,module,exports){ (function (process,Buffer){(function (){ const debug = require('debug')('bittorrent-tracker:client') const EventEmitter = require('events') const once = require('once') const parallel = require('run-parallel') const Peer = require('simple-peer') const common = require('./lib/common') const HTTPTracker = require('./lib/client/http-tracker') // empty object in browser const UDPTracker = require('./lib/client/udp-tracker') // empty object in browser const WebSocketTracker = require('./lib/client/websocket-tracker') /** * BitTorrent tracker client. * * Find torrent peers, to help a torrent client participate in a torrent swarm. * * @param {Object} opts options object * @param {string|Buffer} opts.infoHash torrent info hash * @param {string|Buffer} opts.peerId peer id * @param {string|Array.} opts.announce announce * @param {number} opts.port torrent client listening port * @param {function} opts.getAnnounceOpts callback to provide data to tracker * @param {number} opts.rtcConfig RTCPeerConnection configuration object * @param {number} opts.userAgent User-Agent header for http requests * @param {number} opts.wrtc custom webrtc impl (useful in node.js) */ class Client extends EventEmitter { constructor (opts = {}) { super() if (!opts.peerId) throw new Error('Option `peerId` is required') if (!opts.infoHash) throw new Error('Option `infoHash` is required') if (!opts.announce) throw new Error('Option `announce` is required') if (!process.browser && !opts.port) throw new Error('Option `port` is required') this.peerId = typeof opts.peerId === 'string' ? opts.peerId : opts.peerId.toString('hex') this._peerIdBuffer = Buffer.from(this.peerId, 'hex') this._peerIdBinary = this._peerIdBuffer.toString('binary') this.infoHash = typeof opts.infoHash === 'string' ? opts.infoHash.toLowerCase() : opts.infoHash.toString('hex') this._infoHashBuffer = Buffer.from(this.infoHash, 'hex') this._infoHashBinary = this._infoHashBuffer.toString('binary') debug('new client %s', this.infoHash) this.destroyed = false this._port = opts.port this._getAnnounceOpts = opts.getAnnounceOpts this._rtcConfig = opts.rtcConfig this._userAgent = opts.userAgent // Support lazy 'wrtc' module initialization // See: https://github.com/webtorrent/webtorrent-hybrid/issues/46 this._wrtc = typeof opts.wrtc === 'function' ? opts.wrtc() : opts.wrtc let announce = typeof opts.announce === 'string' ? [opts.announce] : opts.announce == null ? [] : opts.announce // Remove trailing slash from trackers to catch duplicates announce = announce.map(announceUrl => { announceUrl = announceUrl.toString() if (announceUrl[announceUrl.length - 1] === '/') { announceUrl = announceUrl.substring(0, announceUrl.length - 1) } return announceUrl }) // remove duplicates by converting to Set and back announce = Array.from(new Set(announce)) const webrtcSupport = this._wrtc !== false && (!!this._wrtc || Peer.WEBRTC_SUPPORT) const nextTickWarn = err => { process.nextTick(() => { this.emit('warning', err) }) } this._trackers = announce .map(announceUrl => { let parsedUrl try { parsedUrl = new URL(announceUrl) } catch (err) { nextTickWarn(new Error(`Invalid tracker URL: ${announceUrl}`)) return null } const port = parsedUrl.port if (port < 0 || port > 65535) { nextTickWarn(new Error(`Invalid tracker port: ${announceUrl}`)) return null } const protocol = parsedUrl.protocol if ((protocol === 'http:' || protocol === 'https:') && typeof HTTPTracker === 'function') { return new HTTPTracker(this, announceUrl) } else if (protocol === 'udp:' && typeof UDPTracker === 'function') { return new UDPTracker(this, announceUrl) } else if ((protocol === 'ws:' || protocol === 'wss:') && webrtcSupport) { // Skip ws:// trackers on https:// sites because they throw SecurityError if (protocol === 'ws:' && typeof window !== 'undefined' && window.location.protocol === 'https:') { nextTickWarn(new Error(`Unsupported tracker protocol: ${announceUrl}`)) return null } return new WebSocketTracker(this, announceUrl) } else { nextTickWarn(new Error(`Unsupported tracker protocol: ${announceUrl}`)) return null } }) .filter(Boolean) } /** * Send a `start` announce to the trackers. * @param {Object} opts * @param {number=} opts.uploaded * @param {number=} opts.downloaded * @param {number=} opts.left (if not set, calculated automatically) */ start (opts) { opts = this._defaultAnnounceOpts(opts) opts.event = 'started' debug('send `start` %o', opts) this._announce(opts) // start announcing on intervals this._trackers.forEach(tracker => { tracker.setInterval() }) } /** * Send a `stop` announce to the trackers. * @param {Object} opts * @param {number=} opts.uploaded * @param {number=} opts.downloaded * @param {number=} opts.numwant * @param {number=} opts.left (if not set, calculated automatically) */ stop (opts) { opts = this._defaultAnnounceOpts(opts) opts.event = 'stopped' debug('send `stop` %o', opts) this._announce(opts) } /** * Send a `complete` announce to the trackers. * @param {Object} opts * @param {number=} opts.uploaded * @param {number=} opts.downloaded * @param {number=} opts.numwant * @param {number=} opts.left (if not set, calculated automatically) */ complete (opts) { if (!opts) opts = {} opts = this._defaultAnnounceOpts(opts) opts.event = 'completed' debug('send `complete` %o', opts) this._announce(opts) } /** * Send a `update` announce to the trackers. * @param {Object} opts * @param {number=} opts.uploaded * @param {number=} opts.downloaded * @param {number=} opts.numwant * @param {number=} opts.left (if not set, calculated automatically) */ update (opts) { opts = this._defaultAnnounceOpts(opts) if (opts.event) delete opts.event debug('send `update` %o', opts) this._announce(opts) } _announce (opts) { this._trackers.forEach(tracker => { // tracker should not modify `opts` object, it's passed to all trackers tracker.announce(opts) }) } /** * Send a scrape request to the trackers. * @param {Object} opts */ scrape (opts) { debug('send `scrape`') if (!opts) opts = {} this._trackers.forEach(tracker => { // tracker should not modify `opts` object, it's passed to all trackers tracker.scrape(opts) }) } setInterval (intervalMs) { debug('setInterval %d', intervalMs) this._trackers.forEach(tracker => { tracker.setInterval(intervalMs) }) } destroy (cb) { if (this.destroyed) return this.destroyed = true debug('destroy') const tasks = this._trackers.map(tracker => cb => { tracker.destroy(cb) }) parallel(tasks, cb) this._trackers = [] this._getAnnounceOpts = null } _defaultAnnounceOpts (opts = {}) { if (opts.numwant == null) opts.numwant = common.DEFAULT_ANNOUNCE_PEERS if (opts.uploaded == null) opts.uploaded = 0 if (opts.downloaded == null) opts.downloaded = 0 if (this._getAnnounceOpts) opts = Object.assign({}, opts, this._getAnnounceOpts()) return opts } } /** * Simple convenience function to scrape a tracker for an info hash without needing to * create a Client, pass it a parsed torrent, etc. Support scraping a tracker for multiple * torrents at the same time. * @params {Object} opts * @param {string|Array.} opts.infoHash * @param {string} opts.announce * @param {function} cb */ Client.scrape = (opts, cb) => { cb = once(cb) if (!opts.infoHash) throw new Error('Option `infoHash` is required') if (!opts.announce) throw new Error('Option `announce` is required') const clientOpts = Object.assign({}, opts, { infoHash: Array.isArray(opts.infoHash) ? opts.infoHash[0] : opts.infoHash, peerId: Buffer.from('01234567890123456789'), // dummy value port: 6881 // dummy value }) const client = new Client(clientOpts) client.once('error', cb) client.once('warning', cb) let len = Array.isArray(opts.infoHash) ? opts.infoHash.length : 1 const results = {} client.on('scrape', data => { len -= 1 results[data.infoHash] = data if (len === 0) { client.destroy() const keys = Object.keys(results) if (keys.length === 1) { cb(null, results[keys[0]]) } else { cb(null, results) } } }) opts.infoHash = Array.isArray(opts.infoHash) ? opts.infoHash.map(infoHash => { return Buffer.from(infoHash, 'hex') }) : Buffer.from(opts.infoHash, 'hex') client.scrape({ infoHash: opts.infoHash }) return client } module.exports = Client }).call(this)}).call(this,require('_process'),require("buffer").Buffer) },{"./lib/client/http-tracker":330,"./lib/client/udp-tracker":330,"./lib/client/websocket-tracker":31,"./lib/common":32,"_process":338,"buffer":331,"debug":33,"events":333,"once":194,"run-parallel":224,"simple-peer":237}],30:[function(require,module,exports){ const EventEmitter = require('events') class Tracker extends EventEmitter { constructor (client, announceUrl) { super() this.client = client this.announceUrl = announceUrl this.interval = null this.destroyed = false } setInterval (intervalMs) { if (intervalMs == null) intervalMs = this.DEFAULT_ANNOUNCE_INTERVAL clearInterval(this.interval) if (intervalMs) { this.interval = setInterval(() => { this.announce(this.client._defaultAnnounceOpts()) }, intervalMs) if (this.interval.unref) this.interval.unref() } } } module.exports = Tracker },{"events":333}],31:[function(require,module,exports){ const debug = require('debug')('bittorrent-tracker:websocket-tracker') const Peer = require('simple-peer') const randombytes = require('randombytes') const Socket = require('simple-websocket') const common = require('../common') const Tracker = require('./tracker') // Use a socket pool, so tracker clients share WebSocket objects for the same server. // In practice, WebSockets are pretty slow to establish, so this gives a nice performance // boost, and saves browser resources. const socketPool = {} const RECONNECT_MINIMUM = 10 * 1000 const RECONNECT_MAXIMUM = 60 * 60 * 1000 const RECONNECT_VARIANCE = 5 * 60 * 1000 const OFFER_TIMEOUT = 50 * 1000 class WebSocketTracker extends Tracker { constructor (client, announceUrl, opts) { super(client, announceUrl) debug('new websocket tracker %s', announceUrl) this.peers = {} // peers (offer id -> peer) this.socket = null this.reconnecting = false this.retries = 0 this.reconnectTimer = null // Simple boolean flag to track whether the socket has received data from // the websocket server since the last time socket.send() was called. this.expectingResponse = false this._openSocket() } announce (opts) { if (this.destroyed || this.reconnecting) return if (!this.socket.connected) { this.socket.once('connect', () => { this.announce(opts) }) return } const params = Object.assign({}, opts, { action: 'announce', info_hash: this.client._infoHashBinary, peer_id: this.client._peerIdBinary }) if (this._trackerId) params.trackerid = this._trackerId if (opts.event === 'stopped' || opts.event === 'completed') { // Don't include offers with 'stopped' or 'completed' event this._send(params) } else { // Limit the number of offers that are generated, since it can be slow const numwant = Math.min(opts.numwant, 10) this._generateOffers(numwant, offers => { params.numwant = numwant params.offers = offers this._send(params) }) } } scrape (opts) { if (this.destroyed || this.reconnecting) return if (!this.socket.connected) { this.socket.once('connect', () => { this.scrape(opts) }) return } const infoHashes = (Array.isArray(opts.infoHash) && opts.infoHash.length > 0) ? opts.infoHash.map(infoHash => { return infoHash.toString('binary') }) : (opts.infoHash && opts.infoHash.toString('binary')) || this.client._infoHashBinary const params = { action: 'scrape', info_hash: infoHashes } this._send(params) } destroy (cb = noop) { if (this.destroyed) return cb(null) this.destroyed = true clearInterval(this.interval) clearTimeout(this.reconnectTimer) // Destroy peers for (const peerId in this.peers) { const peer = this.peers[peerId] clearTimeout(peer.trackerTimeout) peer.destroy() } this.peers = null if (this.socket) { this.socket.removeListener('connect', this._onSocketConnectBound) this.socket.removeListener('data', this._onSocketDataBound) this.socket.removeListener('close', this._onSocketCloseBound) this.socket.removeListener('error', this._onSocketErrorBound) this.socket = null } this._onSocketConnectBound = null this._onSocketErrorBound = null this._onSocketDataBound = null this._onSocketCloseBound = null if (socketPool[this.announceUrl]) { socketPool[this.announceUrl].consumers -= 1 } // Other instances are using the socket, so there's nothing left to do here if (socketPool[this.announceUrl].consumers > 0) return cb() let socket = socketPool[this.announceUrl] delete socketPool[this.announceUrl] socket.on('error', noop) // ignore all future errors socket.once('close', cb) // If there is no data response expected, destroy immediately. if (!this.expectingResponse) return destroyCleanup() // Otherwise, wait a short time for potential responses to come in from the // server, then force close the socket. var timeout = setTimeout(destroyCleanup, common.DESTROY_TIMEOUT) // But, if a response comes from the server before the timeout fires, do cleanup // right away. socket.once('data', destroyCleanup) function destroyCleanup () { if (timeout) { clearTimeout(timeout) timeout = null } socket.removeListener('data', destroyCleanup) socket.destroy() socket = null } } _openSocket () { this.destroyed = false if (!this.peers) this.peers = {} this._onSocketConnectBound = () => { this._onSocketConnect() } this._onSocketErrorBound = err => { this._onSocketError(err) } this._onSocketDataBound = data => { this._onSocketData(data) } this._onSocketCloseBound = () => { this._onSocketClose() } this.socket = socketPool[this.announceUrl] if (this.socket) { socketPool[this.announceUrl].consumers += 1 if (this.socket.connected) { this._onSocketConnectBound() } } else { this.socket = socketPool[this.announceUrl] = new Socket(this.announceUrl) this.socket.consumers = 1 this.socket.once('connect', this._onSocketConnectBound) } this.socket.on('data', this._onSocketDataBound) this.socket.once('close', this._onSocketCloseBound) this.socket.once('error', this._onSocketErrorBound) } _onSocketConnect () { if (this.destroyed) return if (this.reconnecting) { this.reconnecting = false this.retries = 0 this.announce(this.client._defaultAnnounceOpts()) } } _onSocketData (data) { if (this.destroyed) return this.expectingResponse = false try { data = JSON.parse(data) } catch (err) { this.client.emit('warning', new Error('Invalid tracker response')) return } if (data.action === 'announce') { this._onAnnounceResponse(data) } else if (data.action === 'scrape') { this._onScrapeResponse(data) } else { this._onSocketError(new Error(`invalid action in WS response: ${data.action}`)) } } _onAnnounceResponse (data) { if (data.info_hash !== this.client._infoHashBinary) { debug( 'ignoring websocket data from %s for %s (looking for %s: reused socket)', this.announceUrl, common.binaryToHex(data.info_hash), this.client.infoHash ) return } if (data.peer_id && data.peer_id === this.client._peerIdBinary) { // ignore offers/answers from this client return } debug( 'received %s from %s for %s', JSON.stringify(data), this.announceUrl, this.client.infoHash ) const failure = data['failure reason'] if (failure) return this.client.emit('warning', new Error(failure)) const warning = data['warning message'] if (warning) this.client.emit('warning', new Error(warning)) const interval = data.interval || data['min interval'] if (interval) this.setInterval(interval * 1000) const trackerId = data['tracker id'] if (trackerId) { // If absent, do not discard previous trackerId value this._trackerId = trackerId } if (data.complete != null) { const response = Object.assign({}, data, { announce: this.announceUrl, infoHash: common.binaryToHex(data.info_hash) }) this.client.emit('update', response) } let peer if (data.offer && data.peer_id) { debug('creating peer (from remote offer)') peer = this._createPeer() peer.id = common.binaryToHex(data.peer_id) peer.once('signal', answer => { const params = { action: 'announce', info_hash: this.client._infoHashBinary, peer_id: this.client._peerIdBinary, to_peer_id: data.peer_id, answer, offer_id: data.offer_id } if (this._trackerId) params.trackerid = this._trackerId this._send(params) }) peer.signal(data.offer) this.client.emit('peer', peer) } if (data.answer && data.peer_id) { const offerId = common.binaryToHex(data.offer_id) peer = this.peers[offerId] if (peer) { peer.id = common.binaryToHex(data.peer_id) peer.signal(data.answer) this.client.emit('peer', peer) clearTimeout(peer.trackerTimeout) peer.trackerTimeout = null delete this.peers[offerId] } else { debug(`got unexpected answer: ${JSON.stringify(data.answer)}`) } } } _onScrapeResponse (data) { data = data.files || {} const keys = Object.keys(data) if (keys.length === 0) { this.client.emit('warning', new Error('invalid scrape response')) return } keys.forEach(infoHash => { // TODO: optionally handle data.flags.min_request_interval // (separate from announce interval) const response = Object.assign(data[infoHash], { announce: this.announceUrl, infoHash: common.binaryToHex(infoHash) }) this.client.emit('scrape', response) }) } _onSocketClose () { if (this.destroyed) return this.destroy() this._startReconnectTimer() } _onSocketError (err) { if (this.destroyed) return this.destroy() // errors will often happen if a tracker is offline, so don't treat it as fatal this.client.emit('warning', err) this._startReconnectTimer() } _startReconnectTimer () { const ms = Math.floor(Math.random() * RECONNECT_VARIANCE) + Math.min(Math.pow(2, this.retries) * RECONNECT_MINIMUM, RECONNECT_MAXIMUM) this.reconnecting = true clearTimeout(this.reconnectTimer) this.reconnectTimer = setTimeout(() => { this.retries++ this._openSocket() }, ms) if (this.reconnectTimer.unref) this.reconnectTimer.unref() debug('reconnecting socket in %s ms', ms) } _send (params) { if (this.destroyed) return this.expectingResponse = true const message = JSON.stringify(params) debug('send %s', message) this.socket.send(message) } _generateOffers (numwant, cb) { const self = this const offers = [] debug('generating %s offers', numwant) for (let i = 0; i < numwant; ++i) { generateOffer() } checkDone() function generateOffer () { const offerId = randombytes(20).toString('hex') debug('creating peer (from _generateOffers)') const peer = self.peers[offerId] = self._createPeer({ initiator: true }) peer.once('signal', offer => { offers.push({ offer, offer_id: common.hexToBinary(offerId) }) checkDone() }) peer.trackerTimeout = setTimeout(() => { debug('tracker timeout: destroying peer') peer.trackerTimeout = null delete self.peers[offerId] peer.destroy() }, OFFER_TIMEOUT) if (peer.trackerTimeout.unref) peer.trackerTimeout.unref() } function checkDone () { if (offers.length === numwant) { debug('generated %s offers', numwant) cb(offers) } } } _createPeer (opts) { const self = this opts = Object.assign({ trickle: false, ordered: false, config: self.client._rtcConfig, wrtc: self.client._wrtc }, opts) const peer = new Peer(opts) peer.once('error', onError) peer.once('connect', onConnect) return peer // Handle peer 'error' events that are fired *before* the peer is emitted in // a 'peer' event. function onError (err) { self.client.emit('warning', new Error(`Connection error: ${err.message}`)) peer.destroy() } // Once the peer is emitted in a 'peer' event, then it's the consumer's // responsibility to listen for errors, so the listeners are removed here. function onConnect () { peer.removeListener('error', onError) peer.removeListener('connect', onConnect) } } } WebSocketTracker.prototype.DEFAULT_ANNOUNCE_INTERVAL = 30 * 1000 // 30 seconds // Normally this shouldn't be accessed but is occasionally useful WebSocketTracker._socketPool = socketPool function noop () {} module.exports = WebSocketTracker },{"../common":32,"./tracker":30,"debug":33,"randombytes":200,"simple-peer":237,"simple-websocket":258}],32:[function(require,module,exports){ (function (Buffer){(function (){ /** * Functions/constants needed by both the client and server. */ exports.DEFAULT_ANNOUNCE_PEERS = 50 exports.MAX_ANNOUNCE_PEERS = 82 exports.binaryToHex = function (str) { if (typeof str !== 'string') { str = String(str) } return Buffer.from(str, 'binary').toString('hex') } exports.hexToBinary = function (str) { if (typeof str !== 'string') { str = String(str) } return Buffer.from(str, 'hex').toString('binary') } var config = require('./common-node') Object.assign(exports, config) }).call(this)}).call(this,require("buffer").Buffer) },{"./common-node":330,"buffer":331}],33:[function(require,module,exports){ arguments[4][11][0].apply(exports,arguments) },{"./common":34,"_process":338,"dup":11}],34:[function(require,module,exports){ arguments[4][12][0].apply(exports,arguments) },{"dup":12,"ms":35}],35:[function(require,module,exports){ arguments[4][13][0].apply(exports,arguments) },{"dup":13}],36:[function(require,module,exports){ (function (Buffer){(function (){ /*! blob-to-buffer. MIT License. Feross Aboukhadijeh */ /* global Blob, FileReader */ module.exports = function blobToBuffer (blob, cb) { if (typeof Blob === 'undefined' || !(blob instanceof Blob)) { throw new Error('first argument must be a Blob') } if (typeof cb !== 'function') { throw new Error('second argument must be a function') } const reader = new FileReader() function onLoadEnd (e) { reader.removeEventListener('loadend', onLoadEnd, false) if (e.error) cb(e.error) else cb(null, Buffer.from(reader.result)) } reader.addEventListener('loadend', onLoadEnd, false) reader.readAsArrayBuffer(blob) } }).call(this)}).call(this,require("buffer").Buffer) },{"buffer":331}],37:[function(require,module,exports){ (function (Buffer){(function (){ const { Transform } = require('readable-stream') class Block extends Transform { constructor (size, opts = {}) { super(opts) if (typeof size === 'object') { opts = size size = opts.size } this.size = size || 512 const { nopad, zeroPadding = true } = opts if (nopad) this._zeroPadding = false else this._zeroPadding = !!zeroPadding this._buffered = [] this._bufferedBytes = 0 } _transform (buf, enc, next) { this._bufferedBytes += buf.length this._buffered.push(buf) while (this._bufferedBytes >= this.size) { const b = Buffer.concat(this._buffered) this._bufferedBytes -= this.size this.push(b.slice(0, this.size)) this._buffered = [ b.slice(this.size, b.length) ] } next() } _flush () { if (this._bufferedBytes && this._zeroPadding) { const zeroes = Buffer.alloc(this.size - this._bufferedBytes) this._buffered.push(zeroes) this.push(Buffer.concat(this._buffered)) this._buffered = null } else if (this._bufferedBytes) { this.push(Buffer.concat(this._buffered)) this._buffered = null } this.push(null) } } module.exports = Block }).call(this)}).call(this,require("buffer").Buffer) },{"buffer":331,"readable-stream":52}],38:[function(require,module,exports){ arguments[4][14][0].apply(exports,arguments) },{"dup":14}],39:[function(require,module,exports){ arguments[4][15][0].apply(exports,arguments) },{"./_stream_readable":41,"./_stream_writable":43,"_process":338,"dup":15,"inherits":131}],40:[function(require,module,exports){ arguments[4][16][0].apply(exports,arguments) },{"./_stream_transform":42,"dup":16,"inherits":131}],41:[function(require,module,exports){ arguments[4][17][0].apply(exports,arguments) },{"../errors":38,"./_stream_duplex":39,"./internal/streams/async_iterator":44,"./internal/streams/buffer_list":45,"./internal/streams/destroy":46,"./internal/streams/from":48,"./internal/streams/state":50,"./internal/streams/stream":51,"_process":338,"buffer":331,"dup":17,"events":333,"inherits":131,"string_decoder/":281,"util":330}],42:[function(require,module,exports){ arguments[4][18][0].apply(exports,arguments) },{"../errors":38,"./_stream_duplex":39,"dup":18,"inherits":131}],43:[function(require,module,exports){ arguments[4][19][0].apply(exports,arguments) },{"../errors":38,"./_stream_duplex":39,"./internal/streams/destroy":46,"./internal/streams/state":50,"./internal/streams/stream":51,"_process":338,"buffer":331,"dup":19,"inherits":131,"util-deprecate":298}],44:[function(require,module,exports){ arguments[4][20][0].apply(exports,arguments) },{"./end-of-stream":47,"_process":338,"dup":20}],45:[function(require,module,exports){ arguments[4][21][0].apply(exports,arguments) },{"buffer":331,"dup":21,"util":330}],46:[function(require,module,exports){ arguments[4][22][0].apply(exports,arguments) },{"_process":338,"dup":22}],47:[function(require,module,exports){ arguments[4][23][0].apply(exports,arguments) },{"../../../errors":38,"dup":23}],48:[function(require,module,exports){ arguments[4][24][0].apply(exports,arguments) },{"dup":24}],49:[function(require,module,exports){ arguments[4][25][0].apply(exports,arguments) },{"../../../errors":38,"./end-of-stream":47,"dup":25}],50:[function(require,module,exports){ arguments[4][26][0].apply(exports,arguments) },{"../../../errors":38,"dup":26}],51:[function(require,module,exports){ arguments[4][27][0].apply(exports,arguments) },{"dup":27,"events":333}],52:[function(require,module,exports){ arguments[4][28][0].apply(exports,arguments) },{"./lib/_stream_duplex.js":39,"./lib/_stream_passthrough.js":40,"./lib/_stream_readable.js":41,"./lib/_stream_transform.js":42,"./lib/_stream_writable.js":43,"./lib/internal/streams/end-of-stream.js":47,"./lib/internal/streams/pipeline.js":49,"dup":28}],53:[function(require,module,exports){ var basex = require('base-x') var ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz' module.exports = basex(ALPHABET) },{"base-x":3}],54:[function(require,module,exports){ 'use strict' var base58 = require('bs58') var Buffer = require('safe-buffer').Buffer module.exports = function (checksumFn) { // Encode a buffer as a base58-check encoded string function encode (payload) { var checksum = checksumFn(payload) return base58.encode(Buffer.concat([ payload, checksum ], payload.length + 4)) } function decodeRaw (buffer) { var payload = buffer.slice(0, -4) var checksum = buffer.slice(-4) var newChecksum = checksumFn(payload) if (checksum[0] ^ newChecksum[0] | checksum[1] ^ newChecksum[1] | checksum[2] ^ newChecksum[2] | checksum[3] ^ newChecksum[3]) return return payload } // Decode a base58-check encoded string to a buffer, no result if checksum is wrong function decodeUnsafe (string) { var buffer = base58.decodeUnsafe(string) if (!buffer) return return decodeRaw(buffer) } function decode (string) { var buffer = base58.decode(string) var payload = decodeRaw(buffer, checksumFn) if (!payload) throw new Error('Invalid checksum') return payload } return { encode: encode, decode: decode, decodeUnsafe: decodeUnsafe } } },{"bs58":53,"safe-buffer":226}],55:[function(require,module,exports){ 'use strict' var createHash = require('create-hash') var bs58checkBase = require('./base') // SHA256(SHA256(buffer)) function sha256x2 (buffer) { var tmp = createHash('sha256').update(buffer).digest() return createHash('sha256').update(tmp).digest() } module.exports = bs58checkBase(sha256x2) },{"./base":54,"create-hash":76}],56:[function(require,module,exports){ (function (Buffer){(function (){ function allocUnsafe (size) { if (typeof size !== 'number') { throw new TypeError('"size" argument must be a number') } if (size < 0) { throw new RangeError('"size" argument must not be negative') } if (Buffer.allocUnsafe) { return Buffer.allocUnsafe(size) } else { return new Buffer(size) } } module.exports = allocUnsafe }).call(this)}).call(this,require("buffer").Buffer) },{"buffer":331}],57:[function(require,module,exports){ (function (Buffer){(function (){ var bufferFill = require('buffer-fill') var allocUnsafe = require('buffer-alloc-unsafe') module.exports = function alloc (size, fill, encoding) { if (typeof size !== 'number') { throw new TypeError('"size" argument must be a number') } if (size < 0) { throw new RangeError('"size" argument must not be negative') } if (Buffer.alloc) { return Buffer.alloc(size, fill, encoding) } var buffer = allocUnsafe(size) if (size === 0) { return buffer } if (fill === undefined) { return bufferFill(buffer, 0) } if (typeof encoding !== 'string') { encoding = undefined } return bufferFill(buffer, fill, encoding) } }).call(this)}).call(this,require("buffer").Buffer) },{"buffer":331,"buffer-alloc-unsafe":56,"buffer-fill":58}],58:[function(require,module,exports){ (function (Buffer){(function (){ /* Node.js 6.4.0 and up has full support */ var hasFullSupport = (function () { try { if (!Buffer.isEncoding('latin1')) { return false } var buf = Buffer.alloc ? Buffer.alloc(4) : new Buffer(4) buf.fill('ab', 'ucs2') return (buf.toString('hex') === '61006200') } catch (_) { return false } }()) function isSingleByte (val) { return (val.length === 1 && val.charCodeAt(0) < 256) } function fillWithNumber (buffer, val, start, end) { if (start < 0 || end > buffer.length) { throw new RangeError('Out of range index') } start = start >>> 0 end = end === undefined ? buffer.length : end >>> 0 if (end > start) { buffer.fill(val, start, end) } return buffer } function fillWithBuffer (buffer, val, start, end) { if (start < 0 || end > buffer.length) { throw new RangeError('Out of range index') } if (end <= start) { return buffer } start = start >>> 0 end = end === undefined ? buffer.length : end >>> 0 var pos = start var len = val.length while (pos <= (end - len)) { val.copy(buffer, pos) pos += len } if (pos !== end) { val.copy(buffer, pos, 0, end - pos) } return buffer } function fill (buffer, val, start, end, encoding) { if (hasFullSupport) { return buffer.fill(val, start, end, encoding) } if (typeof val === 'number') { return fillWithNumber(buffer, val, start, end) } if (typeof val === 'string') { if (typeof start === 'string') { encoding = start start = 0 end = buffer.length } else if (typeof end === 'string') { encoding = end end = buffer.length } if (encoding !== undefined && typeof encoding !== 'string') { throw new TypeError('encoding must be a string') } if (encoding === 'latin1') { encoding = 'binary' } if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) { throw new TypeError('Unknown encoding: ' + encoding) } if (val === '') { return fillWithNumber(buffer, 0, start, end) } if (isSingleByte(val)) { return fillWithNumber(buffer, val.charCodeAt(0), start, end) } val = new Buffer(val, encoding) } if (Buffer.isBuffer(val)) { return fillWithBuffer(buffer, val, start, end) } // Other values (e.g. undefined, boolean, object) results in zero-fill return fillWithNumber(buffer, 0, start, end) } module.exports = fill }).call(this)}).call(this,require("buffer").Buffer) },{"buffer":331}],59:[function(require,module,exports){ arguments[4][14][0].apply(exports,arguments) },{"dup":14}],60:[function(require,module,exports){ arguments[4][15][0].apply(exports,arguments) },{"./_stream_readable":62,"./_stream_writable":64,"_process":338,"dup":15,"inherits":131}],61:[function(require,module,exports){ arguments[4][16][0].apply(exports,arguments) },{"./_stream_transform":63,"dup":16,"inherits":131}],62:[function(require,module,exports){ arguments[4][17][0].apply(exports,arguments) },{"../errors":59,"./_stream_duplex":60,"./internal/streams/async_iterator":65,"./internal/streams/buffer_list":66,"./internal/streams/destroy":67,"./internal/streams/from":69,"./internal/streams/state":71,"./internal/streams/stream":72,"_process":338,"buffer":331,"dup":17,"events":333,"inherits":131,"string_decoder/":281,"util":330}],63:[function(require,module,exports){ arguments[4][18][0].apply(exports,arguments) },{"../errors":59,"./_stream_duplex":60,"dup":18,"inherits":131}],64:[function(require,module,exports){ arguments[4][19][0].apply(exports,arguments) },{"../errors":59,"./_stream_duplex":60,"./internal/streams/destroy":67,"./internal/streams/state":71,"./internal/streams/stream":72,"_process":338,"buffer":331,"dup":19,"inherits":131,"util-deprecate":298}],65:[function(require,module,exports){ arguments[4][20][0].apply(exports,arguments) },{"./end-of-stream":68,"_process":338,"dup":20}],66:[function(require,module,exports){ arguments[4][21][0].apply(exports,arguments) },{"buffer":331,"dup":21,"util":330}],67:[function(require,module,exports){ arguments[4][22][0].apply(exports,arguments) },{"_process":338,"dup":22}],68:[function(require,module,exports){ arguments[4][23][0].apply(exports,arguments) },{"../../../errors":59,"dup":23}],69:[function(require,module,exports){ arguments[4][24][0].apply(exports,arguments) },{"dup":24}],70:[function(require,module,exports){ arguments[4][25][0].apply(exports,arguments) },{"../../../errors":59,"./end-of-stream":68,"dup":25}],71:[function(require,module,exports){ arguments[4][26][0].apply(exports,arguments) },{"../../../errors":59,"dup":26}],72:[function(require,module,exports){ arguments[4][27][0].apply(exports,arguments) },{"dup":27,"events":333}],73:[function(require,module,exports){ arguments[4][28][0].apply(exports,arguments) },{"./lib/_stream_duplex.js":60,"./lib/_stream_passthrough.js":61,"./lib/_stream_readable.js":62,"./lib/_stream_transform.js":63,"./lib/_stream_writable.js":64,"./lib/internal/streams/end-of-stream.js":68,"./lib/internal/streams/pipeline.js":70,"dup":28}],74:[function(require,module,exports){ const BlockStream = require('block-stream2') const stream = require('readable-stream') class ChunkStoreWriteStream extends stream.Writable { constructor (store, chunkLength, opts = {}) { super(opts) if (!store || !store.put || !store.get) { throw new Error('First argument must be an abstract-chunk-store compliant store') } chunkLength = Number(chunkLength) if (!chunkLength) throw new Error('Second argument must be a chunk length') this._blockstream = new BlockStream(chunkLength, { zeroPadding: false }) this._outstandingPuts = 0 let index = 0 const onData = chunk => { if (this.destroyed) return this._outstandingPuts += 1 store.put(index, chunk, () => { this._outstandingPuts -= 1 if (this._outstandingPuts === 0 && typeof this._finalCb === 'function') { this._finalCb(null) this._finalCb = null } }) index += 1 } this._blockstream .on('data', onData) .on('error', err => { this.destroy(err) }) } _write (chunk, encoding, callback) { this._blockstream.write(chunk, encoding, callback) } _final (cb) { this._blockstream.end() this._blockstream.once('end', () => { if (this._outstandingPuts === 0) cb(null) else this._finalCb = cb }) } destroy (err) { if (this.destroyed) return this.destroyed = true if (err) this.emit('error', err) this.emit('close') } } module.exports = ChunkStoreWriteStream },{"block-stream2":37,"readable-stream":73}],75:[function(require,module,exports){ var Buffer = require('safe-buffer').Buffer var Transform = require('stream').Transform var StringDecoder = require('string_decoder').StringDecoder var inherits = require('inherits') function CipherBase (hashMode) { Transform.call(this) this.hashMode = typeof hashMode === 'string' if (this.hashMode) { this[hashMode] = this._finalOrDigest } else { this.final = this._finalOrDigest } if (this._final) { this.__final = this._final this._final = null } this._decoder = null this._encoding = null } inherits(CipherBase, Transform) CipherBase.prototype.update = function (data, inputEnc, outputEnc) { if (typeof data === 'string') { data = Buffer.from(data, inputEnc) } var outData = this._update(data) if (this.hashMode) return this if (outputEnc) { outData = this._toString(outData, outputEnc) } return outData } CipherBase.prototype.setAutoPadding = function () {} CipherBase.prototype.getAuthTag = function () { throw new Error('trying to get auth tag in unsupported state') } CipherBase.prototype.setAuthTag = function () { throw new Error('trying to set auth tag in unsupported state') } CipherBase.prototype.setAAD = function () { throw new Error('trying to set aad in unsupported state') } CipherBase.prototype._transform = function (data, _, next) { var err try { if (this.hashMode) { this._update(data) } else { this.push(this._update(data)) } } catch (e) { err = e } finally { next(err) } } CipherBase.prototype._flush = function (done) { var err try { this.push(this.__final()) } catch (e) { err = e } done(err) } CipherBase.prototype._finalOrDigest = function (outputEnc) { var outData = this.__final() || Buffer.alloc(0) if (outputEnc) { outData = this._toString(outData, outputEnc, true) } return outData } CipherBase.prototype._toString = function (value, enc, fin) { if (!this._decoder) { this._decoder = new StringDecoder(enc) this._encoding = enc } if (this._encoding !== enc) throw new Error('can\'t switch encodings') var out = this._decoder.write(value) if (fin) { out += this._decoder.end() } return out } module.exports = CipherBase },{"inherits":131,"safe-buffer":226,"stream":344,"string_decoder":378}],76:[function(require,module,exports){ 'use strict' var inherits = require('inherits') var MD5 = require('md5.js') var RIPEMD160 = require('ripemd160') var sha = require('sha.js') var Base = require('cipher-base') function Hash (hash) { Base.call(this, 'digest') this._hash = hash } inherits(Hash, Base) Hash.prototype._update = function (data) { this._hash.update(data) } Hash.prototype._final = function () { return this._hash.digest() } module.exports = function createHash (alg) { alg = alg.toLowerCase() if (alg === 'md5') return new MD5() if (alg === 'rmd160' || alg === 'ripemd160') return new RIPEMD160() return new Hash(sha(alg)) } },{"cipher-base":75,"inherits":131,"md5.js":137,"ripemd160":222,"sha.js":228}],77:[function(require,module,exports){ (function (process,global,Buffer){(function (){ /*! create-torrent. MIT License. WebTorrent LLC */ const bencode = require('bencode') const BlockStream = require('block-stream2') const calcPieceLength = require('piece-length') const corePath = require('path') const FileReadStream = require('filestream/read') const isFile = require('is-file') const junk = require('junk') const MultiStream = require('multistream') const once = require('once') const parallel = require('run-parallel') const sha1 = require('simple-sha1') const stream = require('readable-stream') const getFiles = require('./get-files') // browser exclude // TODO: When Node 10 support is dropped, replace this with Array.prototype.flat function flat (arr1) { return arr1.reduce( (acc, val) => Array.isArray(val) ? acc.concat(flat(val)) : acc.concat(val), [] ) } const announceList = [ ['udp://tracker.leechers-paradise.org:6969'], ['udp://tracker.coppersurfer.tk:6969'], ['udp://tracker.opentrackr.org:1337'], ['udp://explodie.org:6969'], ['udp://tracker.empire-js.us:1337'], ['wss://tracker.btorrent.xyz'], ['wss://tracker.openwebtorrent.com'] ] /** * Create a torrent. * @param {string|File|FileList|Buffer|Stream|Array.} input * @param {Object} opts * @param {string=} opts.name * @param {Date=} opts.creationDate * @param {string=} opts.comment * @param {string=} opts.createdBy * @param {boolean|number=} opts.private * @param {number=} opts.pieceLength * @param {Array.>=} opts.announceList * @param {Array.=} opts.urlList * @param {Object=} opts.info * @param {function} cb * @return {Buffer} buffer of .torrent file data */ function createTorrent (input, opts, cb) { if (typeof opts === 'function') [opts, cb] = [cb, opts] opts = opts ? Object.assign({}, opts) : {} _parseInput(input, opts, (err, files, singleFileTorrent) => { if (err) return cb(err) opts.singleFileTorrent = singleFileTorrent onFiles(files, opts, cb) }) } function parseInput (input, opts, cb) { if (typeof opts === 'function') [opts, cb] = [cb, opts] opts = opts ? Object.assign({}, opts) : {} _parseInput(input, opts, cb) } /** * Parse input file and return file information. */ function _parseInput (input, opts, cb) { if (isFileList(input)) input = Array.from(input) if (!Array.isArray(input)) input = [input] if (input.length === 0) throw new Error('invalid input type') input.forEach(item => { if (item == null) throw new Error(`invalid input type: ${item}`) }) // In Electron, use the true file path input = input.map(item => { if (isBlob(item) && typeof item.path === 'string' && typeof getFiles === 'function') return item.path return item }) // If there's just one file, allow the name to be set by `opts.name` if (input.length === 1 && typeof input[0] !== 'string' && !input[0].name) input[0].name = opts.name let commonPrefix = null input.forEach((item, i) => { if (typeof item === 'string') { return } let path = item.fullPath || item.name if (!path) { path = `Unknown File ${i + 1}` item.unknownName = true } item.path = path.split('/') // Remove initial slash if (!item.path[0]) { item.path.shift() } if (item.path.length < 2) { // No real prefix commonPrefix = null } else if (i === 0 && input.length > 1) { // The first file has a prefix commonPrefix = item.path[0] } else if (item.path[0] !== commonPrefix) { // The prefix doesn't match commonPrefix = null } }) // remove junk files input = input.filter(item => { if (typeof item === 'string') { return true } const filename = item.path[item.path.length - 1] return notHidden(filename) && junk.not(filename) }) if (commonPrefix) { input.forEach(item => { const pathless = (Buffer.isBuffer(item) || isReadable(item)) && !item.path if (typeof item === 'string' || pathless) return item.path.shift() }) } if (!opts.name && commonPrefix) { opts.name = commonPrefix } if (!opts.name) { // use first user-set file name input.some(item => { if (typeof item === 'string') { opts.name = corePath.basename(item) return true } else if (!item.unknownName) { opts.name = item.path[item.path.length - 1] return true } }) } if (!opts.name) { opts.name = `Unnamed Torrent ${Date.now()}` } const numPaths = input.reduce((sum, item) => sum + Number(typeof item === 'string'), 0) let isSingleFileTorrent = (input.length === 1) if (input.length === 1 && typeof input[0] === 'string') { if (typeof getFiles !== 'function') { throw new Error('filesystem paths do not work in the browser') } // If there's a single path, verify it's a file before deciding this is a single // file torrent isFile(input[0], (err, pathIsFile) => { if (err) return cb(err) isSingleFileTorrent = pathIsFile processInput() }) } else { process.nextTick(() => { processInput() }) } function processInput () { parallel(input.map(item => cb => { const file = {} if (isBlob(item)) { file.getStream = getBlobStream(item) file.length = item.size } else if (Buffer.isBuffer(item)) { file.getStream = getBufferStream(item) file.length = item.length } else if (isReadable(item)) { file.getStream = getStreamStream(item, file) file.length = 0 } else if (typeof item === 'string') { if (typeof getFiles !== 'function') { throw new Error('filesystem paths do not work in the browser') } const keepRoot = numPaths > 1 || isSingleFileTorrent getFiles(item, keepRoot, cb) return // early return! } else { throw new Error('invalid input type') } file.path = item.path cb(null, file) }), (err, files) => { if (err) return cb(err) files = flat(files) cb(null, files, isSingleFileTorrent) }) } } function notHidden (file) { return file[0] !== '.' } function getPieceList (files, pieceLength, cb) { cb = once(cb) const pieces = [] let length = 0 const streams = files.map(file => file.getStream) let remainingHashes = 0 let pieceNum = 0 let ended = false const multistream = new MultiStream(streams) const blockstream = new BlockStream(pieceLength, { zeroPadding: false }) multistream.on('error', onError) multistream .pipe(blockstream) .on('data', onData) .on('end', onEnd) .on('error', onError) function onData (chunk) { length += chunk.length const i = pieceNum sha1(chunk, hash => { pieces[i] = hash remainingHashes -= 1 maybeDone() }) remainingHashes += 1 pieceNum += 1 } function onEnd () { ended = true maybeDone() } function onError (err) { cleanup() cb(err) } function cleanup () { multistream.removeListener('error', onError) blockstream.removeListener('data', onData) blockstream.removeListener('end', onEnd) blockstream.removeListener('error', onError) } function maybeDone () { if (ended && remainingHashes === 0) { cleanup() cb(null, Buffer.from(pieces.join(''), 'hex'), length) } } } function onFiles (files, opts, cb) { let announceList = opts.announceList if (!announceList) { if (typeof opts.announce === 'string') announceList = [[opts.announce]] else if (Array.isArray(opts.announce)) { announceList = opts.announce.map(u => [u]) } } if (!announceList) announceList = [] if (global.WEBTORRENT_ANNOUNCE) { if (typeof global.WEBTORRENT_ANNOUNCE === 'string') { announceList.push([[global.WEBTORRENT_ANNOUNCE]]) } else if (Array.isArray(global.WEBTORRENT_ANNOUNCE)) { announceList = announceList.concat(global.WEBTORRENT_ANNOUNCE.map(u => [u])) } } // When no trackers specified, use some reasonable defaults if (opts.announce === undefined && opts.announceList === undefined) { announceList = announceList.concat(module.exports.announceList) } if (typeof opts.urlList === 'string') opts.urlList = [opts.urlList] const torrent = { info: { name: opts.name }, 'creation date': Math.ceil((Number(opts.creationDate) || Date.now()) / 1000), encoding: 'UTF-8' } if (announceList.length !== 0) { torrent.announce = announceList[0][0] torrent['announce-list'] = announceList } if (opts.comment !== undefined) torrent.comment = opts.comment if (opts.createdBy !== undefined) torrent['created by'] = opts.createdBy if (opts.private !== undefined) torrent.info.private = Number(opts.private) if (opts.info !== undefined) Object.assign(torrent.info, opts.info) // "ssl-cert" key is for SSL torrents, see: // - http://blog.libtorrent.org/2012/01/bittorrent-over-ssl/ // - http://www.libtorrent.org/manual-ref.html#ssl-torrents // - http://www.libtorrent.org/reference-Create_Torrents.html if (opts.sslCert !== undefined) torrent.info['ssl-cert'] = opts.sslCert if (opts.urlList !== undefined) torrent['url-list'] = opts.urlList const pieceLength = opts.pieceLength || calcPieceLength(files.reduce(sumLength, 0)) torrent.info['piece length'] = pieceLength getPieceList(files, pieceLength, (err, pieces, torrentLength) => { if (err) return cb(err) torrent.info.pieces = pieces files.forEach(file => { delete file.getStream }) if (opts.singleFileTorrent) { torrent.info.length = torrentLength } else { torrent.info.files = files } cb(null, bencode.encode(torrent)) }) } /** * Accumulator to sum file lengths * @param {number} sum * @param {Object} file * @return {number} */ function sumLength (sum, file) { return sum + file.length } /** * Check if `obj` is a W3C `Blob` object (which `File` inherits from) * @param {*} obj * @return {boolean} */ function isBlob (obj) { return typeof Blob !== 'undefined' && obj instanceof Blob } /** * Check if `obj` is a W3C `FileList` object * @param {*} obj * @return {boolean} */ function isFileList (obj) { return typeof FileList !== 'undefined' && obj instanceof FileList } /** * Check if `obj` is a node Readable stream * @param {*} obj * @return {boolean} */ function isReadable (obj) { return typeof obj === 'object' && obj != null && typeof obj.pipe === 'function' } /** * Convert a `File` to a lazy readable stream. * @param {File|Blob} file * @return {function} */ function getBlobStream (file) { return () => new FileReadStream(file) } /** * Convert a `Buffer` to a lazy readable stream. * @param {Buffer} buffer * @return {function} */ function getBufferStream (buffer) { return () => { const s = new stream.PassThrough() s.end(buffer) return s } } /** * Convert a readable stream to a lazy readable stream. Adds instrumentation to track * the number of bytes in the stream and set `file.length`. * * @param {Stream} readable * @param {Object} file * @return {function} */ function getStreamStream (readable, file) { return () => { const counter = new stream.Transform() counter._transform = function (buf, enc, done) { file.length += buf.length this.push(buf) done() } readable.pipe(counter) return counter } } module.exports = createTorrent module.exports.parseInput = parseInput module.exports.announceList = announceList }).call(this)}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer) },{"./get-files":330,"_process":338,"bencode":6,"block-stream2":37,"buffer":331,"filestream/read":112,"is-file":133,"junk":135,"multistream":177,"once":194,"path":337,"piece-length":196,"readable-stream":92,"run-parallel":224,"simple-sha1":256}],78:[function(require,module,exports){ arguments[4][14][0].apply(exports,arguments) },{"dup":14}],79:[function(require,module,exports){ arguments[4][15][0].apply(exports,arguments) },{"./_stream_readable":81,"./_stream_writable":83,"_process":338,"dup":15,"inherits":131}],80:[function(require,module,exports){ arguments[4][16][0].apply(exports,arguments) },{"./_stream_transform":82,"dup":16,"inherits":131}],81:[function(require,module,exports){ arguments[4][17][0].apply(exports,arguments) },{"../errors":78,"./_stream_duplex":79,"./internal/streams/async_iterator":84,"./internal/streams/buffer_list":85,"./internal/streams/destroy":86,"./internal/streams/from":88,"./internal/streams/state":90,"./internal/streams/stream":91,"_process":338,"buffer":331,"dup":17,"events":333,"inherits":131,"string_decoder/":281,"util":330}],82:[function(require,module,exports){ arguments[4][18][0].apply(exports,arguments) },{"../errors":78,"./_stream_duplex":79,"dup":18,"inherits":131}],83:[function(require,module,exports){ arguments[4][19][0].apply(exports,arguments) },{"../errors":78,"./_stream_duplex":79,"./internal/streams/destroy":86,"./internal/streams/state":90,"./internal/streams/stream":91,"_process":338,"buffer":331,"dup":19,"inherits":131,"util-deprecate":298}],84:[function(require,module,exports){ arguments[4][20][0].apply(exports,arguments) },{"./end-of-stream":87,"_process":338,"dup":20}],85:[function(require,module,exports){ arguments[4][21][0].apply(exports,arguments) },{"buffer":331,"dup":21,"util":330}],86:[function(require,module,exports){ arguments[4][22][0].apply(exports,arguments) },{"_process":338,"dup":22}],87:[function(require,module,exports){ arguments[4][23][0].apply(exports,arguments) },{"../../../errors":78,"dup":23}],88:[function(require,module,exports){ arguments[4][24][0].apply(exports,arguments) },{"dup":24}],89:[function(require,module,exports){ arguments[4][25][0].apply(exports,arguments) },{"../../../errors":78,"./end-of-stream":87,"dup":25}],90:[function(require,module,exports){ arguments[4][26][0].apply(exports,arguments) },{"../../../errors":78,"dup":26}],91:[function(require,module,exports){ arguments[4][27][0].apply(exports,arguments) },{"dup":27,"events":333}],92:[function(require,module,exports){ arguments[4][28][0].apply(exports,arguments) },{"./lib/_stream_duplex.js":79,"./lib/_stream_passthrough.js":80,"./lib/_stream_readable.js":81,"./lib/_stream_transform.js":82,"./lib/_stream_writable.js":83,"./lib/internal/streams/end-of-stream.js":87,"./lib/internal/streams/pipeline.js":89,"dup":28}],93:[function(require,module,exports){ (function (process){(function (){ "use strict"; function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } /* eslint-env browser */ /** * This is the web browser implementation of `debug()`. */ exports.log = log; exports.formatArgs = formatArgs; exports.save = save; exports.load = load; exports.useColors = useColors; exports.storage = localstorage(); /** * Colors. */ exports.colors = ['#0000CC', '#0000FF', '#0033CC', '#0033FF', '#0066CC', '#0066FF', '#0099CC', '#0099FF', '#00CC00', '#00CC33', '#00CC66', '#00CC99', '#00CCCC', '#00CCFF', '#3300CC', '#3300FF', '#3333CC', '#3333FF', '#3366CC', '#3366FF', '#3399CC', '#3399FF', '#33CC00', '#33CC33', '#33CC66', '#33CC99', '#33CCCC', '#33CCFF', '#6600CC', '#6600FF', '#6633CC', '#6633FF', '#66CC00', '#66CC33', '#9900CC', '#9900FF', '#9933CC', '#9933FF', '#99CC00', '#99CC33', '#CC0000', '#CC0033', '#CC0066', '#CC0099', '#CC00CC', '#CC00FF', '#CC3300', '#CC3333', '#CC3366', '#CC3399', '#CC33CC', '#CC33FF', '#CC6600', '#CC6633', '#CC9900', '#CC9933', '#CCCC00', '#CCCC33', '#FF0000', '#FF0033', '#FF0066', '#FF0099', '#FF00CC', '#FF00FF', '#FF3300', '#FF3333', '#FF3366', '#FF3399', '#FF33CC', '#FF33FF', '#FF6600', '#FF6633', '#FF9900', '#FF9933', '#FFCC00', '#FFCC33']; /** * Currently only WebKit-based Web Inspectors, Firefox >= v31, * and the Firebug extension (any Firefox version) are known * to support "%c" CSS customizations. * * TODO: add a `localStorage` variable to explicitly enable/disable colors */ // eslint-disable-next-line complexity function useColors() { // NB: In an Electron preload script, document will be defined but not fully // initialized. Since we know we're in Chrome, we'll just detect this case // explicitly if (typeof window !== 'undefined' && window.process && (window.process.type === 'renderer' || window.process.__nwjs)) { return true; } // Internet Explorer and Edge do not support colors. if (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) { return false; } // Is webkit? http://stackoverflow.com/a/16459606/376773 // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632 return typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance || // Is firebug? http://stackoverflow.com/a/398120/376773 typeof window !== 'undefined' && window.console && (window.console.firebug || window.console.exception && window.console.table) || // Is firefox >= v31? // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31 || // Double check webkit in userAgent just in case we are in a worker typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/); } /** * Colorize log arguments if enabled. * * @api public */ function formatArgs(args) { args[0] = (this.useColors ? '%c' : '') + this.namespace + (this.useColors ? ' %c' : ' ') + args[0] + (this.useColors ? '%c ' : ' ') + '+' + module.exports.humanize(this.diff); if (!this.useColors) { return; } var c = 'color: ' + this.color; args.splice(1, 0, c, 'color: inherit'); // The final "%c" is somewhat tricky, because there could be other // arguments passed either before or after the %c, so we need to // figure out the correct index to insert the CSS into var index = 0; var lastC = 0; args[0].replace(/%[a-zA-Z%]/g, function (match) { if (match === '%%') { return; } index++; if (match === '%c') { // We only are interested in the *last* %c // (the user may have provided their own) lastC = index; } }); args.splice(lastC, 0, c); } /** * Invokes `console.log()` when available. * No-op when `console.log` is not a "function". * * @api public */ function log() { var _console; // This hackery is required for IE8/9, where // the `console.log` function doesn't have 'apply' return (typeof console === "undefined" ? "undefined" : _typeof(console)) === 'object' && console.log && (_console = console).log.apply(_console, arguments); } /** * Save `namespaces`. * * @param {String} namespaces * @api private */ function save(namespaces) { try { if (namespaces) { exports.storage.setItem('debug', namespaces); } else { exports.storage.removeItem('debug'); } } catch (error) {// Swallow // XXX (@Qix-) should we be logging these? } } /** * Load `namespaces`. * * @return {String} returns the previously persisted debug modes * @api private */ function load() { var r; try { r = exports.storage.getItem('debug'); } catch (error) {} // Swallow // XXX (@Qix-) should we be logging these? // If debug isn't set in LS, and we're in Electron, try to load $DEBUG if (!r && typeof process !== 'undefined' && 'env' in process) { r = process.env.DEBUG; } return r; } /** * Localstorage attempts to return the localstorage. * * This is necessary because safari throws * when a user disables cookies/localstorage * and you attempt to access it. * * @return {LocalStorage} * @api private */ function localstorage() { try { // TVMLKit (Apple TV JS Runtime) does not have a window object, just localStorage in the global context // The Browser also has localStorage in the global context. return localStorage; } catch (error) {// Swallow // XXX (@Qix-) should we be logging these? } } module.exports = require('./common')(exports); var formatters = module.exports.formatters; /** * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default. */ formatters.j = function (v) { try { return JSON.stringify(v); } catch (error) { return '[UnexpectedJSONParseError]: ' + error.message; } }; }).call(this)}).call(this,require('_process')) },{"./common":94,"_process":338}],94:[function(require,module,exports){ "use strict"; /** * This is the common logic for both the Node.js and web browser * implementations of `debug()`. */ function setup(env) { createDebug.debug = createDebug; createDebug.default = createDebug; createDebug.coerce = coerce; createDebug.disable = disable; createDebug.enable = enable; createDebug.enabled = enabled; createDebug.humanize = require('ms'); Object.keys(env).forEach(function (key) { createDebug[key] = env[key]; }); /** * Active `debug` instances. */ createDebug.instances = []; /** * The currently active debug mode names, and names to skip. */ createDebug.names = []; createDebug.skips = []; /** * Map of special "%n" handling functions, for the debug "format" argument. * * Valid key names are a single, lower or upper-case letter, i.e. "n" and "N". */ createDebug.formatters = {}; /** * Selects a color for a debug namespace * @param {String} namespace The namespace string for the for the debug instance to be colored * @return {Number|String} An ANSI color code for the given namespace * @api private */ function selectColor(namespace) { var hash = 0; for (var i = 0; i < namespace.length; i++) { hash = (hash << 5) - hash + namespace.charCodeAt(i); hash |= 0; // Convert to 32bit integer } return createDebug.colors[Math.abs(hash) % createDebug.colors.length]; } createDebug.selectColor = selectColor; /** * Create a debugger with the given `namespace`. * * @param {String} namespace * @return {Function} * @api public */ function createDebug(namespace) { var prevTime; function debug() { // Disabled? if (!debug.enabled) { return; } for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } var self = debug; // Set `diff` timestamp var curr = Number(new Date()); var ms = curr - (prevTime || curr); self.diff = ms; self.prev = prevTime; self.curr = curr; prevTime = curr; args[0] = createDebug.coerce(args[0]); if (typeof args[0] !== 'string') { // Anything else let's inspect with %O args.unshift('%O'); } // Apply any `formatters` transformations var index = 0; args[0] = args[0].replace(/%([a-zA-Z%])/g, function (match, format) { // If we encounter an escaped % then don't increase the array index if (match === '%%') { return match; } index++; var formatter = createDebug.formatters[format]; if (typeof formatter === 'function') { var val = args[index]; match = formatter.call(self, val); // Now we need to remove `args[index]` since it's inlined in the `format` args.splice(index, 1); index--; } return match; }); // Apply env-specific formatting (colors, etc.) createDebug.formatArgs.call(self, args); var logFn = self.log || createDebug.log; logFn.apply(self, args); } debug.namespace = namespace; debug.enabled = createDebug.enabled(namespace); debug.useColors = createDebug.useColors(); debug.color = selectColor(namespace); debug.destroy = destroy; debug.extend = extend; // Debug.formatArgs = formatArgs; // debug.rawLog = rawLog; // env-specific initialization logic for debug instances if (typeof createDebug.init === 'function') { createDebug.init(debug); } createDebug.instances.push(debug); return debug; } function destroy() { var index = createDebug.instances.indexOf(this); if (index !== -1) { createDebug.instances.splice(index, 1); return true; } return false; } function extend(namespace, delimiter) { return createDebug(this.namespace + (typeof delimiter === 'undefined' ? ':' : delimiter) + namespace); } /** * Enables a debug mode by namespaces. This can include modes * separated by a colon and wildcards. * * @param {String} namespaces * @api public */ function enable(namespaces) { createDebug.save(namespaces); createDebug.names = []; createDebug.skips = []; var i; var split = (typeof namespaces === 'string' ? namespaces : '').split(/[\s,]+/); var len = split.length; for (i = 0; i < len; i++) { if (!split[i]) { // ignore empty strings continue; } namespaces = split[i].replace(/\*/g, '.*?'); if (namespaces[0] === '-') { createDebug.skips.push(new RegExp('^' + namespaces.substr(1) + '$')); } else { createDebug.names.push(new RegExp('^' + namespaces + '$')); } } for (i = 0; i < createDebug.instances.length; i++) { var instance = createDebug.instances[i]; instance.enabled = createDebug.enabled(instance.namespace); } } /** * Disable debug output. * * @api public */ function disable() { createDebug.enable(''); } /** * Returns true if the given mode name is enabled, false otherwise. * * @param {String} name * @return {Boolean} * @api public */ function enabled(name) { if (name[name.length - 1] === '*') { return true; } var i; var len; for (i = 0, len = createDebug.skips.length; i < len; i++) { if (createDebug.skips[i].test(name)) { return false; } } for (i = 0, len = createDebug.names.length; i < len; i++) { if (createDebug.names[i].test(name)) { return true; } } return false; } /** * Coerce `val`. * * @param {Mixed} val * @return {Mixed} * @api private */ function coerce(val) { if (val instanceof Error) { return val.stack || val.message; } return val; } createDebug.enable(createDebug.load()); return createDebug; } module.exports = setup; },{"ms":176}],95:[function(require,module,exports){ var once = require('once'); var noop = function() {}; var isRequest = function(stream) { return stream.setHeader && typeof stream.abort === 'function'; }; var isChildProcess = function(stream) { return stream.stdio && Array.isArray(stream.stdio) && stream.stdio.length === 3 }; var eos = function(stream, opts, callback) { if (typeof opts === 'function') return eos(stream, null, opts); if (!opts) opts = {}; callback = once(callback || noop); var ws = stream._writableState; var rs = stream._readableState; var readable = opts.readable || (opts.readable !== false && stream.readable); var writable = opts.writable || (opts.writable !== false && stream.writable); var onlegacyfinish = function() { if (!stream.writable) onfinish(); }; var onfinish = function() { writable = false; if (!readable) callback.call(stream); }; var onend = function() { readable = false; if (!writable) callback.call(stream); }; var onexit = function(exitCode) { callback.call(stream, exitCode ? new Error('exited with error code: ' + exitCode) : null); }; var onerror = function(err) { callback.call(stream, err); }; var onclose = function() { if (readable && !(rs && rs.ended)) return callback.call(stream, new Error('premature close')); if (writable && !(ws && ws.ended)) return callback.call(stream, new Error('premature close')); }; var onrequest = function() { stream.req.on('finish', onfinish); }; if (isRequest(stream)) { stream.on('complete', onfinish); stream.on('abort', onclose); if (stream.req) onrequest(); else stream.on('request', onrequest); } else if (writable && !ws) { // legacy streams stream.on('end', onlegacyfinish); stream.on('close', onlegacyfinish); } if (isChildProcess(stream)) stream.on('exit', onexit); stream.on('end', onend); stream.on('finish', onfinish); if (opts.error !== false) stream.on('error', onerror); stream.on('close', onclose); return function() { stream.removeListener('complete', onfinish); stream.removeListener('abort', onclose); stream.removeListener('request', onrequest); if (stream.req) stream.req.removeListener('finish', onfinish); stream.removeListener('end', onlegacyfinish); stream.removeListener('close', onlegacyfinish); stream.removeListener('finish', onfinish); stream.removeListener('exit', onexit); stream.removeListener('end', onend); stream.removeListener('error', onerror); stream.removeListener('close', onclose); }; }; module.exports = eos; },{"once":194}],96:[function(require,module,exports){ 'use strict'; function assign(obj, props) { for (const key in props) { Object.defineProperty(obj, key, { value: props[key], enumerable: true, configurable: true, }); } return obj; } function createError(err, code, props) { if (!err || typeof err === 'string') { throw new TypeError('Please pass an Error to err-code'); } if (!props) { props = {}; } if (typeof code === 'object') { props = code; code = undefined; } if (code != null) { props.code = code; } try { return assign(err, props); } catch (_) { props.message = err.message; props.stack = err.stack; const ErrClass = function () {}; ErrClass.prototype = Object.create(Object.getPrototypeOf(err)); return assign(new ErrClass(), props); } } module.exports = createError; },{}],97:[function(require,module,exports){ arguments[4][14][0].apply(exports,arguments) },{"dup":14}],98:[function(require,module,exports){ arguments[4][15][0].apply(exports,arguments) },{"./_stream_readable":100,"./_stream_writable":102,"_process":338,"dup":15,"inherits":131}],99:[function(require,module,exports){ arguments[4][16][0].apply(exports,arguments) },{"./_stream_transform":101,"dup":16,"inherits":131}],100:[function(require,module,exports){ arguments[4][17][0].apply(exports,arguments) },{"../errors":97,"./_stream_duplex":98,"./internal/streams/async_iterator":103,"./internal/streams/buffer_list":104,"./internal/streams/destroy":105,"./internal/streams/from":107,"./internal/streams/state":109,"./internal/streams/stream":110,"_process":338,"buffer":331,"dup":17,"events":333,"inherits":131,"string_decoder/":281,"util":330}],101:[function(require,module,exports){ arguments[4][18][0].apply(exports,arguments) },{"../errors":97,"./_stream_duplex":98,"dup":18,"inherits":131}],102:[function(require,module,exports){ arguments[4][19][0].apply(exports,arguments) },{"../errors":97,"./_stream_duplex":98,"./internal/streams/destroy":105,"./internal/streams/state":109,"./internal/streams/stream":110,"_process":338,"buffer":331,"dup":19,"inherits":131,"util-deprecate":298}],103:[function(require,module,exports){ arguments[4][20][0].apply(exports,arguments) },{"./end-of-stream":106,"_process":338,"dup":20}],104:[function(require,module,exports){ arguments[4][21][0].apply(exports,arguments) },{"buffer":331,"dup":21,"util":330}],105:[function(require,module,exports){ arguments[4][22][0].apply(exports,arguments) },{"_process":338,"dup":22}],106:[function(require,module,exports){ arguments[4][23][0].apply(exports,arguments) },{"../../../errors":97,"dup":23}],107:[function(require,module,exports){ arguments[4][24][0].apply(exports,arguments) },{"dup":24}],108:[function(require,module,exports){ arguments[4][25][0].apply(exports,arguments) },{"../../../errors":97,"./end-of-stream":106,"dup":25}],109:[function(require,module,exports){ arguments[4][26][0].apply(exports,arguments) },{"../../../errors":97,"dup":26}],110:[function(require,module,exports){ arguments[4][27][0].apply(exports,arguments) },{"dup":27,"events":333}],111:[function(require,module,exports){ arguments[4][28][0].apply(exports,arguments) },{"./lib/_stream_duplex.js":98,"./lib/_stream_passthrough.js":99,"./lib/_stream_readable.js":100,"./lib/_stream_transform.js":101,"./lib/_stream_writable.js":102,"./lib/internal/streams/end-of-stream.js":106,"./lib/internal/streams/pipeline.js":108,"dup":28}],112:[function(require,module,exports){ /* global FileReader */ const { Readable } = require('readable-stream') const toBuffer = require('typedarray-to-buffer') class FileReadStream extends Readable { constructor (file, opts = {}) { super(opts) // save the read offset this._offset = 0 this._ready = false this._file = file this._size = file.size this._chunkSize = opts.chunkSize || Math.max(this._size / 1000, 200 * 1024) // create the reader const reader = new FileReader() reader.onload = () => { // get the data chunk this.push(toBuffer(reader.result)) } reader.onerror = () => { this.emit('error', reader.error) } this.reader = reader // generate the header blocks that we will send as part of the initial payload this._generateHeaderBlocks(file, opts, (err, blocks) => { // if we encountered an error, emit it if (err) { return this.emit('error', err) } // push the header blocks out to the stream if (Array.isArray(blocks)) { blocks.forEach(block => this.push(block)) } this._ready = true this.emit('_ready') }) } _generateHeaderBlocks (file, opts, callback) { callback(null, []) } _read () { if (!this._ready) { this.once('_ready', this._read.bind(this)) return } const startOffset = this._offset let endOffset = this._offset + this._chunkSize if (endOffset > this._size) endOffset = this._size if (startOffset === this._size) { this.destroy() this.push(null) return } this.reader.readAsArrayBuffer(this._file.slice(startOffset, endOffset)) // update the stream offset this._offset = endOffset } destroy () { this._file = null if (this.reader) { this.reader.onload = null this.reader.onerror = null try { this.reader.abort() } catch (e) {}; } this.reader = null } } module.exports = FileReadStream },{"readable-stream":111,"typedarray-to-buffer":291}],113:[function(require,module,exports){ // originally pulled out of simple-peer module.exports = function getBrowserRTC () { if (typeof globalThis === 'undefined') return null var wrtc = { RTCPeerConnection: globalThis.RTCPeerConnection || globalThis.mozRTCPeerConnection || globalThis.webkitRTCPeerConnection, RTCSessionDescription: globalThis.RTCSessionDescription || globalThis.mozRTCSessionDescription || globalThis.webkitRTCSessionDescription, RTCIceCandidate: globalThis.RTCIceCandidate || globalThis.mozRTCIceCandidate || globalThis.webkitRTCIceCandidate } if (!wrtc.RTCPeerConnection) return null return wrtc } },{}],114:[function(require,module,exports){ 'use strict' var Buffer = require('safe-buffer').Buffer var Transform = require('readable-stream').Transform var inherits = require('inherits') function throwIfNotStringOrBuffer (val, prefix) { if (!Buffer.isBuffer(val) && typeof val !== 'string') { throw new TypeError(prefix + ' must be a string or a buffer') } } function HashBase (blockSize) { Transform.call(this) this._block = Buffer.allocUnsafe(blockSize) this._blockSize = blockSize this._blockOffset = 0 this._length = [0, 0, 0, 0] this._finalized = false } inherits(HashBase, Transform) HashBase.prototype._transform = function (chunk, encoding, callback) { var error = null try { this.update(chunk, encoding) } catch (err) { error = err } callback(error) } HashBase.prototype._flush = function (callback) { var error = null try { this.push(this.digest()) } catch (err) { error = err } callback(error) } HashBase.prototype.update = function (data, encoding) { throwIfNotStringOrBuffer(data, 'Data') if (this._finalized) throw new Error('Digest already called') if (!Buffer.isBuffer(data)) data = Buffer.from(data, encoding) // consume data var block = this._block var offset = 0 while (this._blockOffset + data.length - offset >= this._blockSize) { for (var i = this._blockOffset; i < this._blockSize;) block[i++] = data[offset++] this._update() this._blockOffset = 0 } while (offset < data.length) block[this._blockOffset++] = data[offset++] // update length for (var j = 0, carry = data.length * 8; carry > 0; ++j) { this._length[j] += carry carry = (this._length[j] / 0x0100000000) | 0 if (carry > 0) this._length[j] -= 0x0100000000 * carry } return this } HashBase.prototype._update = function () { throw new Error('_update is not implemented') } HashBase.prototype.digest = function (encoding) { if (this._finalized) throw new Error('Digest already called') this._finalized = true var digest = this._digest() if (encoding !== undefined) digest = digest.toString(encoding) // reset state this._block.fill(0) this._blockOffset = 0 for (var i = 0; i < 4; ++i) this._length[i] = 0 return digest } HashBase.prototype._digest = function () { throw new Error('_digest is not implemented') } module.exports = HashBase },{"inherits":131,"readable-stream":129,"safe-buffer":226}],115:[function(require,module,exports){ arguments[4][14][0].apply(exports,arguments) },{"dup":14}],116:[function(require,module,exports){ arguments[4][15][0].apply(exports,arguments) },{"./_stream_readable":118,"./_stream_writable":120,"_process":338,"dup":15,"inherits":131}],117:[function(require,module,exports){ arguments[4][16][0].apply(exports,arguments) },{"./_stream_transform":119,"dup":16,"inherits":131}],118:[function(require,module,exports){ arguments[4][17][0].apply(exports,arguments) },{"../errors":115,"./_stream_duplex":116,"./internal/streams/async_iterator":121,"./internal/streams/buffer_list":122,"./internal/streams/destroy":123,"./internal/streams/from":125,"./internal/streams/state":127,"./internal/streams/stream":128,"_process":338,"buffer":331,"dup":17,"events":333,"inherits":131,"string_decoder/":281,"util":330}],119:[function(require,module,exports){ arguments[4][18][0].apply(exports,arguments) },{"../errors":115,"./_stream_duplex":116,"dup":18,"inherits":131}],120:[function(require,module,exports){ arguments[4][19][0].apply(exports,arguments) },{"../errors":115,"./_stream_duplex":116,"./internal/streams/destroy":123,"./internal/streams/state":127,"./internal/streams/stream":128,"_process":338,"buffer":331,"dup":19,"inherits":131,"util-deprecate":298}],121:[function(require,module,exports){ arguments[4][20][0].apply(exports,arguments) },{"./end-of-stream":124,"_process":338,"dup":20}],122:[function(require,module,exports){ arguments[4][21][0].apply(exports,arguments) },{"buffer":331,"dup":21,"util":330}],123:[function(require,module,exports){ arguments[4][22][0].apply(exports,arguments) },{"_process":338,"dup":22}],124:[function(require,module,exports){ arguments[4][23][0].apply(exports,arguments) },{"../../../errors":115,"dup":23}],125:[function(require,module,exports){ arguments[4][24][0].apply(exports,arguments) },{"dup":24}],126:[function(require,module,exports){ arguments[4][25][0].apply(exports,arguments) },{"../../../errors":115,"./end-of-stream":124,"dup":25}],127:[function(require,module,exports){ arguments[4][26][0].apply(exports,arguments) },{"../../../errors":115,"dup":26}],128:[function(require,module,exports){ arguments[4][27][0].apply(exports,arguments) },{"dup":27,"events":333}],129:[function(require,module,exports){ arguments[4][28][0].apply(exports,arguments) },{"./lib/_stream_duplex.js":116,"./lib/_stream_passthrough.js":117,"./lib/_stream_readable.js":118,"./lib/_stream_transform.js":119,"./lib/_stream_writable.js":120,"./lib/internal/streams/end-of-stream.js":124,"./lib/internal/streams/pipeline.js":126,"dup":28}],130:[function(require,module,exports){ /*! immediate-chunk-store. MIT License. Feross Aboukhadijeh */ // TODO: remove when window.queueMicrotask() is well supported const queueMicrotask = require('queue-microtask') class ImmediateStore { constructor (store) { this.store = store this.chunkLength = store.chunkLength if (!this.store || !this.store.get || !this.store.put) { throw new Error('First argument must be abstract-chunk-store compliant') } this.mem = [] } put (index, buf, cb) { this.mem[index] = buf this.store.put(index, buf, err => { this.mem[index] = null if (cb) cb(err) }) } get (index, opts, cb) { if (typeof opts === 'function') return this.get(index, null, opts) let memoryBuffer = this.mem[index] // if the chunk isn't in the immediate memory cache if (!memoryBuffer) { return this.store.get(index, opts, cb) } if (opts) { const start = opts.offset || 0 const end = opts.length ? (start + opts.length) : memoryBuffer.length memoryBuffer = memoryBuffer.slice(start, end) } // queueMicrotask to ensure the function is async queueMicrotask(() => { if (cb) cb(null, memoryBuffer) }) } close (cb) { this.store.close(cb) } destroy (cb) { this.store.destroy(cb) } } module.exports = ImmediateStore },{"queue-microtask":198}],131:[function(require,module,exports){ if (typeof Object.create === 'function') { // implementation from standard node.js 'util' module module.exports = function inherits(ctor, superCtor) { if (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) { if (superCtor) { ctor.super_ = superCtor var TempCtor = function () {} TempCtor.prototype = superCtor.prototype ctor.prototype = new TempCtor() ctor.prototype.constructor = ctor } } } },{}],132:[function(require,module,exports){ /* (c) 2016 Ari Porad (@ariporad) . License: ariporad.mit-license.org */ // Partially from http://stackoverflow.com/a/94049/1928484, and from another SO answer, which told me that the highest // char code that's ascii is 127, but I can't find the link for. Sorry. var MAX_ASCII_CHAR_CODE = 127; module.exports = function isAscii(str) { for (var i = 0, strLen = str.length; i < strLen; ++i) { if (str.charCodeAt(i) > MAX_ASCII_CHAR_CODE) return false; } return true; }; },{}],133:[function(require,module,exports){ 'use strict'; var fs = require('fs'); module.exports = function isFile(path, cb){ if(!cb)return isFileSync(path); fs.stat(path, function(err, stats){ if(err)return cb(err); return cb(null, stats.isFile()); }); }; module.exports.sync = isFileSync; function isFileSync(path){ return fs.existsSync(path) && fs.statSync(path).isFile(); } },{"fs":328}],134:[function(require,module,exports){ module.exports = isTypedArray isTypedArray.strict = isStrictTypedArray isTypedArray.loose = isLooseTypedArray var toString = Object.prototype.toString var names = { '[object Int8Array]': true , '[object Int16Array]': true , '[object Int32Array]': true , '[object Uint8Array]': true , '[object Uint8ClampedArray]': true , '[object Uint16Array]': true , '[object Uint32Array]': true , '[object Float32Array]': true , '[object Float64Array]': true } function isTypedArray(arr) { return ( isStrictTypedArray(arr) || isLooseTypedArray(arr) ) } function isStrictTypedArray(arr) { return ( arr instanceof Int8Array || arr instanceof Int16Array || arr instanceof Int32Array || arr instanceof Uint8Array || arr instanceof Uint8ClampedArray || arr instanceof Uint16Array || arr instanceof Uint32Array || arr instanceof Float32Array || arr instanceof Float64Array ) } function isLooseTypedArray(arr) { return names[toString.call(arr)] } },{}],135:[function(require,module,exports){ 'use strict'; const blacklist = [ // # All '^npm-debug\\.log$', // Error log for npm '^\\..*\\.swp$', // Swap file for vim state // # macOS '^\\.DS_Store$', // Stores custom folder attributes '^\\.AppleDouble$', // Stores additional file resources '^\\.LSOverride$', // Contains the absolute path to the app to be used '^Icon\\r$', // Custom Finder icon: http://superuser.com/questions/298785/icon-file-on-os-x-desktop '^\\._.*', // Thumbnail '^\\.Spotlight-V100(?:$|\\/)', // Directory that might appear on external disk '\\.Trashes', // File that might appear on external disk '^__MACOSX$', // Resource fork // # Linux '~$', // Backup file // # Windows '^Thumbs\\.db$', // Image file cache '^ehthumbs\\.db$', // Folder config file '^Desktop\\.ini$', // Stores custom folder attributes '@eaDir$' // Synology Diskstation "hidden" folder where the server stores thumbnails ]; exports.re = () => { throw new Error('`junk.re` was renamed to `junk.regex`'); }; exports.regex = new RegExp(blacklist.join('|')); exports.is = filename => exports.regex.test(filename); exports.not = filename => !exports.is(filename); // TODO: Remove this for the next major release exports.default = module.exports; },{}],136:[function(require,module,exports){ (function (Buffer){(function (){ /*! magnet-uri. MIT License. WebTorrent LLC */ module.exports = magnetURIDecode module.exports.decode = magnetURIDecode module.exports.encode = magnetURIEncode const base32 = require('thirty-two') const bep53Range = require('bep53-range') /** * Parse a magnet URI and return an object of keys/values * * @param {string} uri * @return {Object} parsed uri */ function magnetURIDecode (uri) { const result = {} // Support 'magnet:' and 'stream-magnet:' uris const data = uri.split('magnet:?')[1] const params = (data && data.length >= 0) ? data.split('&') : [] params.forEach(param => { const keyval = param.split('=') // This keyval is invalid, skip it if (keyval.length !== 2) return const key = keyval[0] let val = keyval[1] // Clean up torrent name if (key === 'dn') val = decodeURIComponent(val).replace(/\+/g, ' ') // Address tracker (tr), exact source (xs), and acceptable source (as) are encoded // URIs, so decode them if (key === 'tr' || key === 'xs' || key === 'as' || key === 'ws') { val = decodeURIComponent(val) } // Return keywords as an array if (key === 'kt') val = decodeURIComponent(val).split('+') // Cast file index (ix) to a number if (key === 'ix') val = Number(val) // bep53 if (key === 'so') val = bep53Range.parse(decodeURIComponent(val).split(',')) // If there are repeated parameters, return an array of values if (result[key]) { if (!Array.isArray(result[key])) { result[key] = [result[key]] } result[key].push(val) } else { result[key] = val } }) // Convenience properties for parity with `parse-torrent-file` module let m if (result.xt) { const xts = Array.isArray(result.xt) ? result.xt : [result.xt] xts.forEach(xt => { if ((m = xt.match(/^urn:btih:(.{40})/))) { result.infoHash = m[1].toLowerCase() } else if ((m = xt.match(/^urn:btih:(.{32})/))) { const decodedStr = base32.decode(m[1]) result.infoHash = Buffer.from(decodedStr, 'binary').toString('hex') } }) } if (result.xs) { const xss = Array.isArray(result.xs) ? result.xs : [result.xs] xss.forEach(xs => { if ((m = xs.match(/^urn:btpk:(.{64})/))) { result.publicKey = m[1].toLowerCase() } }) } if (result.infoHash) result.infoHashBuffer = Buffer.from(result.infoHash, 'hex') if (result.publicKey) result.publicKeyBuffer = Buffer.from(result.publicKey, 'hex') if (result.dn) result.name = result.dn if (result.kt) result.keywords = result.kt result.announce = [] if (typeof result.tr === 'string' || Array.isArray(result.tr)) { result.announce = result.announce.concat(result.tr) } result.urlList = [] if (typeof result.as === 'string' || Array.isArray(result.as)) { result.urlList = result.urlList.concat(result.as) } if (typeof result.ws === 'string' || Array.isArray(result.ws)) { result.urlList = result.urlList.concat(result.ws) } result.peerAddresses = [] if (typeof result['x.pe'] === 'string' || Array.isArray(result['x.pe'])) { result.peerAddresses = result.peerAddresses.concat(result['x.pe']) } // remove duplicates by converting to Set and back result.announce = Array.from(new Set(result.announce)) result.urlList = Array.from(new Set(result.urlList)) result.peerAddresses = Array.from(new Set(result.peerAddresses)) return result } function magnetURIEncode (obj) { obj = Object.assign({}, obj) // clone obj, so we can mutate it // support using convenience names, in addition to spec names // (example: `infoHash` for `xt`, `name` for `dn`) if (obj.infoHashBuffer) obj.xt = `urn:btih:${obj.infoHashBuffer.toString('hex')}` if (obj.infoHash) obj.xt = `urn:btih:${obj.infoHash}` if (obj.publicKeyBuffer) obj.xs = `urn:btpk:${obj.publicKeyBuffer.toString('hex')}` if (obj.publicKey) obj.xs = `urn:btpk:${obj.publicKey}` if (obj.name) obj.dn = obj.name if (obj.keywords) obj.kt = obj.keywords if (obj.announce) obj.tr = obj.announce if (obj.urlList) { obj.ws = obj.urlList delete obj.as } if (obj.peerAddresses) obj['x.pe'] = obj.peerAddresses let result = 'magnet:?' Object.keys(obj) .filter(key => key.length === 2 || key === 'x.pe') .forEach((key, i) => { const values = Array.isArray(obj[key]) ? obj[key] : [obj[key]] values.forEach((val, j) => { if ((i > 0 || j > 0) && ((key !== 'kt' && key !== 'so') || j === 0)) result += '&' if (key === 'dn') val = encodeURIComponent(val).replace(/%20/g, '+') if (key === 'tr' || key === 'as' || key === 'ws') { val = encodeURIComponent(val) } // Don't URI encode BEP46 keys if (key === 'xs' && !val.startsWith('urn:btpk:')) { val = encodeURIComponent(val) } if (key === 'kt') val = encodeURIComponent(val) if (key === 'so') return if (key === 'kt' && j > 0) result += `+${val}` else result += `${key}=${val}` }) if (key === 'so') result += `${key}=${bep53Range.compose(values)}` }) return result } }).call(this)}).call(this,require("buffer").Buffer) },{"bep53-range":7,"buffer":331,"thirty-two":282}],137:[function(require,module,exports){ 'use strict' var inherits = require('inherits') var HashBase = require('hash-base') var Buffer = require('safe-buffer').Buffer var ARRAY16 = new Array(16) function MD5 () { HashBase.call(this, 64) // state this._a = 0x67452301 this._b = 0xefcdab89 this._c = 0x98badcfe this._d = 0x10325476 } inherits(MD5, HashBase) MD5.prototype._update = function () { var M = ARRAY16 for (var i = 0; i < 16; ++i) M[i] = this._block.readInt32LE(i * 4) var a = this._a var b = this._b var c = this._c var d = this._d a = fnF(a, b, c, d, M[0], 0xd76aa478, 7) d = fnF(d, a, b, c, M[1], 0xe8c7b756, 12) c = fnF(c, d, a, b, M[2], 0x242070db, 17) b = fnF(b, c, d, a, M[3], 0xc1bdceee, 22) a = fnF(a, b, c, d, M[4], 0xf57c0faf, 7) d = fnF(d, a, b, c, M[5], 0x4787c62a, 12) c = fnF(c, d, a, b, M[6], 0xa8304613, 17) b = fnF(b, c, d, a, M[7], 0xfd469501, 22) a = fnF(a, b, c, d, M[8], 0x698098d8, 7) d = fnF(d, a, b, c, M[9], 0x8b44f7af, 12) c = fnF(c, d, a, b, M[10], 0xffff5bb1, 17) b = fnF(b, c, d, a, M[11], 0x895cd7be, 22) a = fnF(a, b, c, d, M[12], 0x6b901122, 7) d = fnF(d, a, b, c, M[13], 0xfd987193, 12) c = fnF(c, d, a, b, M[14], 0xa679438e, 17) b = fnF(b, c, d, a, M[15], 0x49b40821, 22) a = fnG(a, b, c, d, M[1], 0xf61e2562, 5) d = fnG(d, a, b, c, M[6], 0xc040b340, 9) c = fnG(c, d, a, b, M[11], 0x265e5a51, 14) b = fnG(b, c, d, a, M[0], 0xe9b6c7aa, 20) a = fnG(a, b, c, d, M[5], 0xd62f105d, 5) d = fnG(d, a, b, c, M[10], 0x02441453, 9) c = fnG(c, d, a, b, M[15], 0xd8a1e681, 14) b = fnG(b, c, d, a, M[4], 0xe7d3fbc8, 20) a = fnG(a, b, c, d, M[9], 0x21e1cde6, 5) d = fnG(d, a, b, c, M[14], 0xc33707d6, 9) c = fnG(c, d, a, b, M[3], 0xf4d50d87, 14) b = fnG(b, c, d, a, M[8], 0x455a14ed, 20) a = fnG(a, b, c, d, M[13], 0xa9e3e905, 5) d = fnG(d, a, b, c, M[2], 0xfcefa3f8, 9) c = fnG(c, d, a, b, M[7], 0x676f02d9, 14) b = fnG(b, c, d, a, M[12], 0x8d2a4c8a, 20) a = fnH(a, b, c, d, M[5], 0xfffa3942, 4) d = fnH(d, a, b, c, M[8], 0x8771f681, 11) c = fnH(c, d, a, b, M[11], 0x6d9d6122, 16) b = fnH(b, c, d, a, M[14], 0xfde5380c, 23) a = fnH(a, b, c, d, M[1], 0xa4beea44, 4) d = fnH(d, a, b, c, M[4], 0x4bdecfa9, 11) c = fnH(c, d, a, b, M[7], 0xf6bb4b60, 16) b = fnH(b, c, d, a, M[10], 0xbebfbc70, 23) a = fnH(a, b, c, d, M[13], 0x289b7ec6, 4) d = fnH(d, a, b, c, M[0], 0xeaa127fa, 11) c = fnH(c, d, a, b, M[3], 0xd4ef3085, 16) b = fnH(b, c, d, a, M[6], 0x04881d05, 23) a = fnH(a, b, c, d, M[9], 0xd9d4d039, 4) d = fnH(d, a, b, c, M[12], 0xe6db99e5, 11) c = fnH(c, d, a, b, M[15], 0x1fa27cf8, 16) b = fnH(b, c, d, a, M[2], 0xc4ac5665, 23) a = fnI(a, b, c, d, M[0], 0xf4292244, 6) d = fnI(d, a, b, c, M[7], 0x432aff97, 10) c = fnI(c, d, a, b, M[14], 0xab9423a7, 15) b = fnI(b, c, d, a, M[5], 0xfc93a039, 21) a = fnI(a, b, c, d, M[12], 0x655b59c3, 6) d = fnI(d, a, b, c, M[3], 0x8f0ccc92, 10) c = fnI(c, d, a, b, M[10], 0xffeff47d, 15) b = fnI(b, c, d, a, M[1], 0x85845dd1, 21) a = fnI(a, b, c, d, M[8], 0x6fa87e4f, 6) d = fnI(d, a, b, c, M[15], 0xfe2ce6e0, 10) c = fnI(c, d, a, b, M[6], 0xa3014314, 15) b = fnI(b, c, d, a, M[13], 0x4e0811a1, 21) a = fnI(a, b, c, d, M[4], 0xf7537e82, 6) d = fnI(d, a, b, c, M[11], 0xbd3af235, 10) c = fnI(c, d, a, b, M[2], 0x2ad7d2bb, 15) b = fnI(b, c, d, a, M[9], 0xeb86d391, 21) this._a = (this._a + a) | 0 this._b = (this._b + b) | 0 this._c = (this._c + c) | 0 this._d = (this._d + d) | 0 } MD5.prototype._digest = function () { // create padding and handle blocks this._block[this._blockOffset++] = 0x80 if (this._blockOffset > 56) { this._block.fill(0, this._blockOffset, 64) this._update() this._blockOffset = 0 } this._block.fill(0, this._blockOffset, 56) this._block.writeUInt32LE(this._length[0], 56) this._block.writeUInt32LE(this._length[1], 60) this._update() // produce result var buffer = Buffer.allocUnsafe(16) buffer.writeInt32LE(this._a, 0) buffer.writeInt32LE(this._b, 4) buffer.writeInt32LE(this._c, 8) buffer.writeInt32LE(this._d, 12) return buffer } function rotl (x, n) { return (x << n) | (x >>> (32 - n)) } function fnF (a, b, c, d, m, k, s) { return (rotl((a + ((b & c) | ((~b) & d)) + m + k) | 0, s) + b) | 0 } function fnG (a, b, c, d, m, k, s) { return (rotl((a + ((b & d) | (c & (~d))) + m + k) | 0, s) + b) | 0 } function fnH (a, b, c, d, m, k, s) { return (rotl((a + (b ^ c ^ d) + m + k) | 0, s) + b) | 0 } function fnI (a, b, c, d, m, k, s) { return (rotl((a + ((c ^ (b | (~d)))) + m + k) | 0, s) + b) | 0 } module.exports = MD5 },{"hash-base":114,"inherits":131,"safe-buffer":226}],138:[function(require,module,exports){ /*! mediasource. MIT License. Feross Aboukhadijeh */ module.exports = MediaElementWrapper var inherits = require('inherits') var stream = require('readable-stream') var toArrayBuffer = require('to-arraybuffer') var MediaSource = typeof window !== 'undefined' && window.MediaSource var DEFAULT_BUFFER_DURATION = 60 // seconds function MediaElementWrapper (elem, opts) { var self = this if (!(self instanceof MediaElementWrapper)) return new MediaElementWrapper(elem, opts) if (!MediaSource) throw new Error('web browser lacks MediaSource support') if (!opts) opts = {} self._debug = opts.debug self._bufferDuration = opts.bufferDuration || DEFAULT_BUFFER_DURATION self._elem = elem self._mediaSource = new MediaSource() self._streams = [] self.detailedError = null self._errorHandler = function () { self._elem.removeEventListener('error', self._errorHandler) var streams = self._streams.slice() streams.forEach(function (stream) { stream.destroy(self._elem.error) }) } self._elem.addEventListener('error', self._errorHandler) self._elem.src = window.URL.createObjectURL(self._mediaSource) } /* * `obj` can be a previous value returned by this function * or a string */ MediaElementWrapper.prototype.createWriteStream = function (obj) { var self = this return new MediaSourceStream(self, obj) } /* * Use to trigger an error on the underlying media element */ MediaElementWrapper.prototype.error = function (err) { var self = this // be careful not to overwrite any existing detailedError values if (!self.detailedError) { self.detailedError = err } self._dumpDebugData() try { self._mediaSource.endOfStream('decode') } catch (err) {} try { // Attempt to clean up object URL window.URL.revokeObjectURL(self._elem.src) } catch (err) {} } /* * When self._debug is set, dump all data to files */ MediaElementWrapper.prototype._dumpDebugData = function () { var self = this if (self._debug) { self._debug = false // prevent multiple dumps on multiple errors self._streams.forEach(function (stream, i) { downloadBuffers(stream._debugBuffers, 'mediasource-stream-' + i) }) } } inherits(MediaSourceStream, stream.Writable) function MediaSourceStream (wrapper, obj) { var self = this stream.Writable.call(self) self._wrapper = wrapper self._elem = wrapper._elem self._mediaSource = wrapper._mediaSource self._allStreams = wrapper._streams self._allStreams.push(self) self._bufferDuration = wrapper._bufferDuration self._sourceBuffer = null self._debugBuffers = [] self._openHandler = function () { self._onSourceOpen() } self._flowHandler = function () { self._flow() } self._errorHandler = function (err) { if (!self.destroyed) { self.emit('error', err) } } if (typeof obj === 'string') { self._type = obj // Need to create a new sourceBuffer if (self._mediaSource.readyState === 'open') { self._createSourceBuffer() } else { self._mediaSource.addEventListener('sourceopen', self._openHandler) } } else if (obj._sourceBuffer === null) { obj.destroy() self._type = obj._type // The old stream was created but hasn't finished initializing self._mediaSource.addEventListener('sourceopen', self._openHandler) } else if (obj._sourceBuffer) { obj.destroy() self._type = obj._type self._sourceBuffer = obj._sourceBuffer // Copy over the old sourceBuffer self._debugBuffers = obj._debugBuffers // Copy over previous debug data self._sourceBuffer.addEventListener('updateend', self._flowHandler) self._sourceBuffer.addEventListener('error', self._errorHandler) } else { throw new Error('The argument to MediaElementWrapper.createWriteStream must be a string or a previous stream returned from that function') } self._elem.addEventListener('timeupdate', self._flowHandler) self.on('error', function (err) { self._wrapper.error(err) }) self.on('finish', function () { if (self.destroyed) return self._finished = true if (self._allStreams.every(function (other) { return other._finished })) { self._wrapper._dumpDebugData() try { self._mediaSource.endOfStream() } catch (err) {} } }) } MediaSourceStream.prototype._onSourceOpen = function () { var self = this if (self.destroyed) return self._mediaSource.removeEventListener('sourceopen', self._openHandler) self._createSourceBuffer() } MediaSourceStream.prototype.destroy = function (err) { var self = this if (self.destroyed) return self.destroyed = true // Remove from allStreams self._allStreams.splice(self._allStreams.indexOf(self), 1) self._mediaSource.removeEventListener('sourceopen', self._openHandler) self._elem.removeEventListener('timeupdate', self._flowHandler) if (self._sourceBuffer) { self._sourceBuffer.removeEventListener('updateend', self._flowHandler) self._sourceBuffer.removeEventListener('error', self._errorHandler) if (self._mediaSource.readyState === 'open') { self._sourceBuffer.abort() } } if (err) self.emit('error', err) self.emit('close') } MediaSourceStream.prototype._createSourceBuffer = function () { var self = this if (self.destroyed) return if (MediaSource.isTypeSupported(self._type)) { self._sourceBuffer = self._mediaSource.addSourceBuffer(self._type) self._sourceBuffer.addEventListener('updateend', self._flowHandler) self._sourceBuffer.addEventListener('error', self._errorHandler) if (self._cb) { var cb = self._cb self._cb = null cb() } } else { self.destroy(new Error('The provided type is not supported')) } } MediaSourceStream.prototype._write = function (chunk, encoding, cb) { var self = this if (self.destroyed) return if (!self._sourceBuffer) { self._cb = function (err) { if (err) return cb(err) self._write(chunk, encoding, cb) } return } if (self._sourceBuffer.updating) { return cb(new Error('Cannot append buffer while source buffer updating')) } var arr = toArrayBuffer(chunk) if (self._wrapper._debug) { self._debugBuffers.push(arr) } try { self._sourceBuffer.appendBuffer(arr) } catch (err) { // appendBuffer can throw for a number of reasons, most notably when the data // being appended is invalid or if appendBuffer is called after another error // already occurred on the media element. In Chrome, there may be useful debugging // info in chrome://media-internals self.destroy(err) return } self._cb = cb } MediaSourceStream.prototype._flow = function () { var self = this if (self.destroyed || !self._sourceBuffer || self._sourceBuffer.updating) { return } if (self._mediaSource.readyState === 'open') { // check buffer size if (self._getBufferDuration() > self._bufferDuration) { return } } if (self._cb) { var cb = self._cb self._cb = null cb() } } // TODO: if zero actually works in all browsers, remove the logic associated with this below var EPSILON = 0 MediaSourceStream.prototype._getBufferDuration = function () { var self = this var buffered = self._sourceBuffer.buffered var currentTime = self._elem.currentTime var bufferEnd = -1 // end of the buffer // This is a little over complex because some browsers seem to separate the // buffered region into multiple sections with slight gaps. for (var i = 0; i < buffered.length; i++) { var start = buffered.start(i) var end = buffered.end(i) + EPSILON if (start > currentTime) { // Reached past the joined buffer break } else if (bufferEnd >= 0 || currentTime <= end) { // Found the start/continuation of the joined buffer bufferEnd = end } } var bufferedTime = bufferEnd - currentTime if (bufferedTime < 0) { bufferedTime = 0 } return bufferedTime } function downloadBuffers (bufs, name) { var a = document.createElement('a') a.href = window.URL.createObjectURL(new window.Blob(bufs)) a.download = name a.click() } },{"inherits":131,"readable-stream":153,"to-arraybuffer":284}],139:[function(require,module,exports){ arguments[4][14][0].apply(exports,arguments) },{"dup":14}],140:[function(require,module,exports){ arguments[4][15][0].apply(exports,arguments) },{"./_stream_readable":142,"./_stream_writable":144,"_process":338,"dup":15,"inherits":131}],141:[function(require,module,exports){ arguments[4][16][0].apply(exports,arguments) },{"./_stream_transform":143,"dup":16,"inherits":131}],142:[function(require,module,exports){ arguments[4][17][0].apply(exports,arguments) },{"../errors":139,"./_stream_duplex":140,"./internal/streams/async_iterator":145,"./internal/streams/buffer_list":146,"./internal/streams/destroy":147,"./internal/streams/from":149,"./internal/streams/state":151,"./internal/streams/stream":152,"_process":338,"buffer":331,"dup":17,"events":333,"inherits":131,"string_decoder/":281,"util":330}],143:[function(require,module,exports){ arguments[4][18][0].apply(exports,arguments) },{"../errors":139,"./_stream_duplex":140,"dup":18,"inherits":131}],144:[function(require,module,exports){ arguments[4][19][0].apply(exports,arguments) },{"../errors":139,"./_stream_duplex":140,"./internal/streams/destroy":147,"./internal/streams/state":151,"./internal/streams/stream":152,"_process":338,"buffer":331,"dup":19,"inherits":131,"util-deprecate":298}],145:[function(require,module,exports){ arguments[4][20][0].apply(exports,arguments) },{"./end-of-stream":148,"_process":338,"dup":20}],146:[function(require,module,exports){ arguments[4][21][0].apply(exports,arguments) },{"buffer":331,"dup":21,"util":330}],147:[function(require,module,exports){ arguments[4][22][0].apply(exports,arguments) },{"_process":338,"dup":22}],148:[function(require,module,exports){ arguments[4][23][0].apply(exports,arguments) },{"../../../errors":139,"dup":23}],149:[function(require,module,exports){ arguments[4][24][0].apply(exports,arguments) },{"dup":24}],150:[function(require,module,exports){ arguments[4][25][0].apply(exports,arguments) },{"../../../errors":139,"./end-of-stream":148,"dup":25}],151:[function(require,module,exports){ arguments[4][26][0].apply(exports,arguments) },{"../../../errors":139,"dup":26}],152:[function(require,module,exports){ arguments[4][27][0].apply(exports,arguments) },{"dup":27,"events":333}],153:[function(require,module,exports){ arguments[4][28][0].apply(exports,arguments) },{"./lib/_stream_duplex.js":140,"./lib/_stream_passthrough.js":141,"./lib/_stream_readable.js":142,"./lib/_stream_transform.js":143,"./lib/_stream_writable.js":144,"./lib/internal/streams/end-of-stream.js":148,"./lib/internal/streams/pipeline.js":150,"dup":28}],154:[function(require,module,exports){ (function (process){(function (){ module.exports = Storage function Storage (chunkLength, opts) { if (!(this instanceof Storage)) return new Storage(chunkLength, opts) if (!opts) opts = {} this.chunkLength = Number(chunkLength) if (!this.chunkLength) throw new Error('First argument must be a chunk length') this.chunks = [] this.closed = false this.length = Number(opts.length) || Infinity if (this.length !== Infinity) { this.lastChunkLength = (this.length % this.chunkLength) || this.chunkLength this.lastChunkIndex = Math.ceil(this.length / this.chunkLength) - 1 } } Storage.prototype.put = function (index, buf, cb) { if (this.closed) return nextTick(cb, new Error('Storage is closed')) var isLastChunk = (index === this.lastChunkIndex) if (isLastChunk && buf.length !== this.lastChunkLength) { return nextTick(cb, new Error('Last chunk length must be ' + this.lastChunkLength)) } if (!isLastChunk && buf.length !== this.chunkLength) { return nextTick(cb, new Error('Chunk length must be ' + this.chunkLength)) } this.chunks[index] = buf nextTick(cb, null) } Storage.prototype.get = function (index, opts, cb) { if (typeof opts === 'function') return this.get(index, null, opts) if (this.closed) return nextTick(cb, new Error('Storage is closed')) var buf = this.chunks[index] if (!buf) { var err = new Error('Chunk not found') err.notFound = true return nextTick(cb, err) } if (!opts) return nextTick(cb, null, buf) var offset = opts.offset || 0 var len = opts.length || (buf.length - offset) nextTick(cb, null, buf.slice(offset, len + offset)) } Storage.prototype.close = Storage.prototype.destroy = function (cb) { if (this.closed) return nextTick(cb, new Error('Storage is closed')) this.closed = true this.chunks = null nextTick(cb, null) } function nextTick (cb, err, val) { process.nextTick(function () { if (cb) cb(err, val) }) } }).call(this)}).call(this,require('_process')) },{"_process":338}],155:[function(require,module,exports){ (function (Buffer){(function (){ // This is an intentionally recursive require. I don't like it either. var Box = require('./index') var Descriptor = require('./descriptor') var uint64be = require('uint64be') var TIME_OFFSET = 2082844800000 /* TODO: test these add new box versions */ // These have 'version' and 'flags' fields in the headers exports.fullBoxes = {} var fullBoxes = [ 'mvhd', 'tkhd', 'mdhd', 'vmhd', 'smhd', 'stsd', 'esds', 'stsz', 'stco', 'co64', 'stss', 'stts', 'ctts', 'stsc', 'dref', 'elst', 'hdlr', 'mehd', 'trex', 'mfhd', 'tfhd', 'tfdt', 'trun' ] fullBoxes.forEach(function (type) { exports.fullBoxes[type] = true }) exports.ftyp = {} exports.ftyp.encode = function (box, buf, offset) { buf = buf ? buf.slice(offset) : Buffer.alloc(exports.ftyp.encodingLength(box)) var brands = box.compatibleBrands || [] buf.write(box.brand, 0, 4, 'ascii') buf.writeUInt32BE(box.brandVersion, 4) for (var i = 0; i < brands.length; i++) buf.write(brands[i], 8 + (i * 4), 4, 'ascii') exports.ftyp.encode.bytes = 8 + brands.length * 4 return buf } exports.ftyp.decode = function (buf, offset) { buf = buf.slice(offset) var brand = buf.toString('ascii', 0, 4) var version = buf.readUInt32BE(4) var compatibleBrands = [] for (var i = 8; i < buf.length; i += 4) compatibleBrands.push(buf.toString('ascii', i, i + 4)) return { brand: brand, brandVersion: version, compatibleBrands: compatibleBrands } } exports.ftyp.encodingLength = function (box) { return 8 + (box.compatibleBrands || []).length * 4 } exports.mvhd = {} exports.mvhd.encode = function (box, buf, offset) { buf = buf ? buf.slice(offset) : Buffer.alloc(96) writeDate(box.ctime || new Date(), buf, 0) writeDate(box.mtime || new Date(), buf, 4) buf.writeUInt32BE(box.timeScale || 0, 8) buf.writeUInt32BE(box.duration || 0, 12) writeFixed32(box.preferredRate || 0, buf, 16) writeFixed16(box.preferredVolume || 0, buf, 20) writeReserved(buf, 22, 32) writeMatrix(box.matrix, buf, 32) buf.writeUInt32BE(box.previewTime || 0, 68) buf.writeUInt32BE(box.previewDuration || 0, 72) buf.writeUInt32BE(box.posterTime || 0, 76) buf.writeUInt32BE(box.selectionTime || 0, 80) buf.writeUInt32BE(box.selectionDuration || 0, 84) buf.writeUInt32BE(box.currentTime || 0, 88) buf.writeUInt32BE(box.nextTrackId || 0, 92) exports.mvhd.encode.bytes = 96 return buf } exports.mvhd.decode = function (buf, offset) { buf = buf.slice(offset) return { ctime: readDate(buf, 0), mtime: readDate(buf, 4), timeScale: buf.readUInt32BE(8), duration: buf.readUInt32BE(12), preferredRate: readFixed32(buf, 16), preferredVolume: readFixed16(buf, 20), matrix: readMatrix(buf.slice(32, 68)), previewTime: buf.readUInt32BE(68), previewDuration: buf.readUInt32BE(72), posterTime: buf.readUInt32BE(76), selectionTime: buf.readUInt32BE(80), selectionDuration: buf.readUInt32BE(84), currentTime: buf.readUInt32BE(88), nextTrackId: buf.readUInt32BE(92) } } exports.mvhd.encodingLength = function (box) { return 96 } exports.tkhd = {} exports.tkhd.encode = function (box, buf, offset) { buf = buf ? buf.slice(offset) : Buffer.alloc(80) writeDate(box.ctime || new Date(), buf, 0) writeDate(box.mtime || new Date(), buf, 4) buf.writeUInt32BE(box.trackId || 0, 8) writeReserved(buf, 12, 16) buf.writeUInt32BE(box.duration || 0, 16) writeReserved(buf, 20, 28) buf.writeUInt16BE(box.layer || 0, 28) buf.writeUInt16BE(box.alternateGroup || 0, 30) buf.writeUInt16BE(box.volume || 0, 32) writeMatrix(box.matrix, buf, 36) buf.writeUInt32BE(box.trackWidth || 0, 72) buf.writeUInt32BE(box.trackHeight || 0, 76) exports.tkhd.encode.bytes = 80 return buf } exports.tkhd.decode = function (buf, offset) { buf = buf.slice(offset) return { ctime: readDate(buf, 0), mtime: readDate(buf, 4), trackId: buf.readUInt32BE(8), duration: buf.readUInt32BE(16), layer: buf.readUInt16BE(28), alternateGroup: buf.readUInt16BE(30), volume: buf.readUInt16BE(32), matrix: readMatrix(buf.slice(36, 72)), trackWidth: buf.readUInt32BE(72), trackHeight: buf.readUInt32BE(76) } } exports.tkhd.encodingLength = function (box) { return 80 } exports.mdhd = {} exports.mdhd.encode = function (box, buf, offset) { if (box.version === 1) { buf = buf ? buf.slice(offset) : Buffer.alloc(32) writeDate64(box.ctime || new Date(), buf, 0) writeDate64(box.mtime || new Date(), buf, 8) buf.writeUInt32BE(box.timeScale || 0, 16) // Node only supports integer <= 48bit. Waiting for BigInt! buf.writeUIntBE(box.duration || 0, 20, 6) buf.writeUInt16BE(box.language || 0, 28) buf.writeUInt16BE(box.quality || 0, 30) exports.mdhd.encode.bytes = 32 return buf } buf = buf ? buf.slice(offset) : Buffer.alloc(20) writeDate(box.ctime || new Date(), buf, 0) writeDate(box.mtime || new Date(), buf, 4) buf.writeUInt32BE(box.timeScale || 0, 8) buf.writeUInt32BE(box.duration || 0, 12) buf.writeUInt16BE(box.language || 0, 16) buf.writeUInt16BE(box.quality || 0, 18) exports.mdhd.encode.bytes = 20 return buf } exports.mdhd.decode = function (buf, offset, end) { buf = buf.slice(offset) var version1 = (end - offset) !== 20 // In version 1 creation time and modification time are unsigned long if (version1) { return { ctime: readDate64(buf, 0), mtime: readDate64(buf, 8), timeScale: buf.readUInt32BE(16), // Node only supports integer <= 48bit. Waiting for BigInt! duration: buf.readUIntBE(20, 6), language: buf.readUInt16BE(28), quality: buf.readUInt16BE(30) } } return { ctime: readDate(buf, 0), mtime: readDate(buf, 4), timeScale: buf.readUInt32BE(8), duration: buf.readUInt32BE(12), language: buf.readUInt16BE(16), quality: buf.readUInt16BE(18) } } exports.mdhd.encodingLength = function (box) { if (box.version === 1) return 32 return 20 } exports.vmhd = {} exports.vmhd.encode = function (box, buf, offset) { buf = buf ? buf.slice(offset) : Buffer.alloc(8) buf.writeUInt16BE(box.graphicsMode || 0, 0) var opcolor = box.opcolor || [0, 0, 0] buf.writeUInt16BE(opcolor[0], 2) buf.writeUInt16BE(opcolor[1], 4) buf.writeUInt16BE(opcolor[2], 6) exports.vmhd.encode.bytes = 8 return buf } exports.vmhd.decode = function (buf, offset) { buf = buf.slice(offset) return { graphicsMode: buf.readUInt16BE(0), opcolor: [buf.readUInt16BE(2), buf.readUInt16BE(4), buf.readUInt16BE(6)] } } exports.vmhd.encodingLength = function (box) { return 8 } exports.smhd = {} exports.smhd.encode = function (box, buf, offset) { buf = buf ? buf.slice(offset) : Buffer.alloc(4) buf.writeUInt16BE(box.balance || 0, 0) writeReserved(buf, 2, 4) exports.smhd.encode.bytes = 4 return buf } exports.smhd.decode = function (buf, offset) { buf = buf.slice(offset) return { balance: buf.readUInt16BE(0) } } exports.smhd.encodingLength = function (box) { return 4 } exports.stsd = {} exports.stsd.encode = function (box, buf, offset) { buf = buf ? buf.slice(offset) : Buffer.alloc(exports.stsd.encodingLength(box)) var entries = box.entries || [] buf.writeUInt32BE(entries.length, 0) var ptr = 4 for (var i = 0; i < entries.length; i++) { var entry = entries[i] Box.encode(entry, buf, ptr) ptr += Box.encode.bytes } exports.stsd.encode.bytes = ptr return buf } exports.stsd.decode = function (buf, offset, end) { buf = buf.slice(offset) var num = buf.readUInt32BE(0) var entries = new Array(num) var ptr = 4 for (var i = 0; i < num; i++) { var entry = Box.decode(buf, ptr, end) entries[i] = entry ptr += entry.length } return { entries: entries } } exports.stsd.encodingLength = function (box) { var totalSize = 4 if (!box.entries) return totalSize for (var i = 0; i < box.entries.length; i++) { totalSize += Box.encodingLength(box.entries[i]) } return totalSize } exports.avc1 = exports.VisualSampleEntry = {} exports.VisualSampleEntry.encode = function (box, buf, offset) { buf = buf ? buf.slice(offset) : Buffer.alloc(exports.VisualSampleEntry.encodingLength(box)) writeReserved(buf, 0, 6) buf.writeUInt16BE(box.dataReferenceIndex || 0, 6) writeReserved(buf, 8, 24) buf.writeUInt16BE(box.width || 0, 24) buf.writeUInt16BE(box.height || 0, 26) buf.writeUInt32BE(box.hResolution || 0x480000, 28) buf.writeUInt32BE(box.vResolution || 0x480000, 32) writeReserved(buf, 36, 40) buf.writeUInt16BE(box.frameCount || 1, 40) var compressorName = box.compressorName || '' var nameLen = Math.min(compressorName.length, 31) buf.writeUInt8(nameLen, 42) buf.write(compressorName, 43, nameLen, 'utf8') buf.writeUInt16BE(box.depth || 0x18, 74) buf.writeInt16BE(-1, 76) var ptr = 78 var children = box.children || [] children.forEach(function (child) { Box.encode(child, buf, ptr) ptr += Box.encode.bytes }) exports.VisualSampleEntry.encode.bytes = ptr } exports.VisualSampleEntry.decode = function (buf, offset, end) { buf = buf.slice(offset) var length = end - offset var nameLen = Math.min(buf.readUInt8(42), 31) var box = { dataReferenceIndex: buf.readUInt16BE(6), width: buf.readUInt16BE(24), height: buf.readUInt16BE(26), hResolution: buf.readUInt32BE(28), vResolution: buf.readUInt32BE(32), frameCount: buf.readUInt16BE(40), compressorName: buf.toString('utf8', 43, 43 + nameLen), depth: buf.readUInt16BE(74), children: [] } var ptr = 78 while (length - ptr >= 8) { var child = Box.decode(buf, ptr, length) box.children.push(child) box[child.type] = child ptr += child.length } return box } exports.VisualSampleEntry.encodingLength = function (box) { var len = 78 var children = box.children || [] children.forEach(function (child) { len += Box.encodingLength(child) }) return len } exports.avcC = {} exports.avcC.encode = function (box, buf, offset) { buf = buf ? buf.slice(offset) : Buffer.alloc(box.buffer.length) box.buffer.copy(buf) exports.avcC.encode.bytes = box.buffer.length } exports.avcC.decode = function (buf, offset, end) { buf = buf.slice(offset, end) return { mimeCodec: buf.toString('hex', 1, 4), buffer: Buffer.from(buf) } } exports.avcC.encodingLength = function (box) { return box.buffer.length } exports.mp4a = exports.AudioSampleEntry = {} exports.AudioSampleEntry.encode = function (box, buf, offset) { buf = buf ? buf.slice(offset) : Buffer.alloc(exports.AudioSampleEntry.encodingLength(box)) writeReserved(buf, 0, 6) buf.writeUInt16BE(box.dataReferenceIndex || 0, 6) writeReserved(buf, 8, 16) buf.writeUInt16BE(box.channelCount || 2, 16) buf.writeUInt16BE(box.sampleSize || 16, 18) writeReserved(buf, 20, 24) buf.writeUInt32BE(box.sampleRate || 0, 24) var ptr = 28 var children = box.children || [] children.forEach(function (child) { Box.encode(child, buf, ptr) ptr += Box.encode.bytes }) exports.AudioSampleEntry.encode.bytes = ptr } exports.AudioSampleEntry.decode = function (buf, offset, end) { buf = buf.slice(offset, end) var length = end - offset var box = { dataReferenceIndex: buf.readUInt16BE(6), channelCount: buf.readUInt16BE(16), sampleSize: buf.readUInt16BE(18), sampleRate: buf.readUInt32BE(24), children: [] } var ptr = 28 while (length - ptr >= 8) { var child = Box.decode(buf, ptr, length) box.children.push(child) box[child.type] = child ptr += child.length } return box } exports.AudioSampleEntry.encodingLength = function (box) { var len = 28 var children = box.children || [] children.forEach(function (child) { len += Box.encodingLength(child) }) return len } exports.esds = {} exports.esds.encode = function (box, buf, offset) { buf = buf ? buf.slice(offset) : Buffer.alloc(box.buffer.length) box.buffer.copy(buf, 0) exports.esds.encode.bytes = box.buffer.length } exports.esds.decode = function (buf, offset, end) { buf = buf.slice(offset, end) var desc = Descriptor.Descriptor.decode(buf, 0, buf.length) var esd = (desc.tagName === 'ESDescriptor') ? desc : {} var dcd = esd.DecoderConfigDescriptor || {} var oti = dcd.oti || 0 var dsi = dcd.DecoderSpecificInfo var audioConfig = dsi ? (dsi.buffer.readUInt8(0) & 0xf8) >> 3 : 0 var mimeCodec = null if (oti) { mimeCodec = oti.toString(16) if (audioConfig) { mimeCodec += '.' + audioConfig } } return { mimeCodec: mimeCodec, buffer: Buffer.from(buf.slice(0)) } } exports.esds.encodingLength = function (box) { return box.buffer.length } // TODO: integrate the two versions in a saner way exports.stsz = {} exports.stsz.encode = function (box, buf, offset) { var entries = box.entries || [] buf = buf ? buf.slice(offset) : Buffer.alloc(exports.stsz.encodingLength(box)) buf.writeUInt32BE(0, 0) buf.writeUInt32BE(entries.length, 4) for (var i = 0; i < entries.length; i++) { buf.writeUInt32BE(entries[i], i * 4 + 8) } exports.stsz.encode.bytes = 8 + entries.length * 4 return buf } exports.stsz.decode = function (buf, offset) { buf = buf.slice(offset) var size = buf.readUInt32BE(0) var num = buf.readUInt32BE(4) var entries = new Array(num) for (var i = 0; i < num; i++) { if (size === 0) { entries[i] = buf.readUInt32BE(i * 4 + 8) } else { entries[i] = size } } return { entries: entries } } exports.stsz.encodingLength = function (box) { return 8 + box.entries.length * 4 } exports.stss = exports.stco = {} exports.stco.encode = function (box, buf, offset) { var entries = box.entries || [] buf = buf ? buf.slice(offset) : Buffer.alloc(exports.stco.encodingLength(box)) buf.writeUInt32BE(entries.length, 0) for (var i = 0; i < entries.length; i++) { buf.writeUInt32BE(entries[i], i * 4 + 4) } exports.stco.encode.bytes = 4 + entries.length * 4 return buf } exports.stco.decode = function (buf, offset) { buf = buf.slice(offset) var num = buf.readUInt32BE(0) var entries = new Array(num) for (var i = 0; i < num; i++) { entries[i] = buf.readUInt32BE(i * 4 + 4) } return { entries: entries } } exports.stco.encodingLength = function (box) { return 4 + box.entries.length * 4 } exports.co64 = {} exports.co64.encode = function (box, buf, offset) { var entries = box.entries || [] buf = buf ? buf.slice(offset) : Buffer.alloc(exports.co64.encodingLength(box)) buf.writeUInt32BE(entries.length, 0) for (var i = 0; i < entries.length; i++) { uint64be.encode(entries[i], buf, i * 8 + 4) } exports.co64.encode.bytes = 4 + entries.length * 8 return buf } exports.co64.decode = function (buf, offset) { buf = buf.slice(offset) var num = buf.readUInt32BE(0) var entries = new Array(num) for (var i = 0; i < num; i++) { entries[i] = uint64be.decode(buf, i * 8 + 4) } return { entries: entries } } exports.co64.encodingLength = function (box) { return 4 + box.entries.length * 8 } exports.stts = {} exports.stts.encode = function (box, buf, offset) { var entries = box.entries || [] buf = buf ? buf.slice(offset) : Buffer.alloc(exports.stts.encodingLength(box)) buf.writeUInt32BE(entries.length, 0) for (var i = 0; i < entries.length; i++) { var ptr = i * 8 + 4 buf.writeUInt32BE(entries[i].count || 0, ptr) buf.writeUInt32BE(entries[i].duration || 0, ptr + 4) } exports.stts.encode.bytes = 4 + box.entries.length * 8 return buf } exports.stts.decode = function (buf, offset) { buf = buf.slice(offset) var num = buf.readUInt32BE(0) var entries = new Array(num) for (var i = 0; i < num; i++) { var ptr = i * 8 + 4 entries[i] = { count: buf.readUInt32BE(ptr), duration: buf.readUInt32BE(ptr + 4) } } return { entries: entries } } exports.stts.encodingLength = function (box) { return 4 + box.entries.length * 8 } exports.ctts = {} exports.ctts.encode = function (box, buf, offset) { var entries = box.entries || [] buf = buf ? buf.slice(offset) : Buffer.alloc(exports.ctts.encodingLength(box)) buf.writeUInt32BE(entries.length, 0) for (var i = 0; i < entries.length; i++) { var ptr = i * 8 + 4 buf.writeUInt32BE(entries[i].count || 0, ptr) buf.writeUInt32BE(entries[i].compositionOffset || 0, ptr + 4) } exports.ctts.encode.bytes = 4 + entries.length * 8 return buf } exports.ctts.decode = function (buf, offset) { buf = buf.slice(offset) var num = buf.readUInt32BE(0) var entries = new Array(num) for (var i = 0; i < num; i++) { var ptr = i * 8 + 4 entries[i] = { count: buf.readUInt32BE(ptr), compositionOffset: buf.readInt32BE(ptr + 4) } } return { entries: entries } } exports.ctts.encodingLength = function (box) { return 4 + box.entries.length * 8 } exports.stsc = {} exports.stsc.encode = function (box, buf, offset) { var entries = box.entries || [] buf = buf ? buf.slice(offset) : Buffer.alloc(exports.stsc.encodingLength(box)) buf.writeUInt32BE(entries.length, 0) for (var i = 0; i < entries.length; i++) { var ptr = i * 12 + 4 buf.writeUInt32BE(entries[i].firstChunk || 0, ptr) buf.writeUInt32BE(entries[i].samplesPerChunk || 0, ptr + 4) buf.writeUInt32BE(entries[i].sampleDescriptionId || 0, ptr + 8) } exports.stsc.encode.bytes = 4 + entries.length * 12 return buf } exports.stsc.decode = function (buf, offset) { buf = buf.slice(offset) var num = buf.readUInt32BE(0) var entries = new Array(num) for (var i = 0; i < num; i++) { var ptr = i * 12 + 4 entries[i] = { firstChunk: buf.readUInt32BE(ptr), samplesPerChunk: buf.readUInt32BE(ptr + 4), sampleDescriptionId: buf.readUInt32BE(ptr + 8) } } return { entries: entries } } exports.stsc.encodingLength = function (box) { return 4 + box.entries.length * 12 } exports.dref = {} exports.dref.encode = function (box, buf, offset) { buf = buf ? buf.slice(offset) : Buffer.alloc(exports.dref.encodingLength(box)) var entries = box.entries || [] buf.writeUInt32BE(entries.length, 0) var ptr = 4 for (var i = 0; i < entries.length; i++) { var entry = entries[i] var size = (entry.buf ? entry.buf.length : 0) + 4 + 4 buf.writeUInt32BE(size, ptr) ptr += 4 buf.write(entry.type, ptr, 4, 'ascii') ptr += 4 if (entry.buf) { entry.buf.copy(buf, ptr) ptr += entry.buf.length } } exports.dref.encode.bytes = ptr return buf } exports.dref.decode = function (buf, offset) { buf = buf.slice(offset) var num = buf.readUInt32BE(0) var entries = new Array(num) var ptr = 4 for (var i = 0; i < num; i++) { var size = buf.readUInt32BE(ptr) var type = buf.toString('ascii', ptr + 4, ptr + 8) var tmp = buf.slice(ptr + 8, ptr + size) ptr += size entries[i] = { type: type, buf: tmp } } return { entries: entries } } exports.dref.encodingLength = function (box) { var totalSize = 4 if (!box.entries) return totalSize for (var i = 0; i < box.entries.length; i++) { var buf = box.entries[i].buf totalSize += (buf ? buf.length : 0) + 4 + 4 } return totalSize } exports.elst = {} exports.elst.encode = function (box, buf, offset) { var entries = box.entries || [] buf = buf ? buf.slice(offset) : Buffer.alloc(exports.elst.encodingLength(box)) buf.writeUInt32BE(entries.length, 0) for (var i = 0; i < entries.length; i++) { var ptr = i * 12 + 4 buf.writeUInt32BE(entries[i].trackDuration || 0, ptr) buf.writeUInt32BE(entries[i].mediaTime || 0, ptr + 4) writeFixed32(entries[i].mediaRate || 0, buf, ptr + 8) } exports.elst.encode.bytes = 4 + entries.length * 12 return buf } exports.elst.decode = function (buf, offset) { buf = buf.slice(offset) var num = buf.readUInt32BE(0) var entries = new Array(num) for (var i = 0; i < num; i++) { var ptr = i * 12 + 4 entries[i] = { trackDuration: buf.readUInt32BE(ptr), mediaTime: buf.readInt32BE(ptr + 4), mediaRate: readFixed32(buf, ptr + 8) } } return { entries: entries } } exports.elst.encodingLength = function (box) { return 4 + box.entries.length * 12 } exports.hdlr = {} exports.hdlr.encode = function (box, buf, offset) { buf = buf ? buf.slice(offset) : Buffer.alloc(exports.hdlr.encodingLength(box)) var len = 21 + (box.name || '').length buf.fill(0, 0, len) buf.write(box.handlerType || '', 4, 4, 'ascii') writeString(box.name || '', buf, 20) exports.hdlr.encode.bytes = len return buf } exports.hdlr.decode = function (buf, offset, end) { buf = buf.slice(offset) return { handlerType: buf.toString('ascii', 4, 8), name: readString(buf, 20, end) } } exports.hdlr.encodingLength = function (box) { return 21 + (box.name || '').length } exports.mehd = {} exports.mehd.encode = function (box, buf, offset) { buf = buf ? buf.slice(offset) : Buffer.alloc(4) buf.writeUInt32BE(box.fragmentDuration || 0, 0) exports.mehd.encode.bytes = 4 return buf } exports.mehd.decode = function (buf, offset) { buf = buf.slice(offset) return { fragmentDuration: buf.readUInt32BE(0) } } exports.mehd.encodingLength = function (box) { return 4 } exports.trex = {} exports.trex.encode = function (box, buf, offset) { buf = buf ? buf.slice(offset) : Buffer.alloc(20) buf.writeUInt32BE(box.trackId || 0, 0) buf.writeUInt32BE(box.defaultSampleDescriptionIndex || 0, 4) buf.writeUInt32BE(box.defaultSampleDuration || 0, 8) buf.writeUInt32BE(box.defaultSampleSize || 0, 12) buf.writeUInt32BE(box.defaultSampleFlags || 0, 16) exports.trex.encode.bytes = 20 return buf } exports.trex.decode = function (buf, offset) { buf = buf.slice(offset) return { trackId: buf.readUInt32BE(0), defaultSampleDescriptionIndex: buf.readUInt32BE(4), defaultSampleDuration: buf.readUInt32BE(8), defaultSampleSize: buf.readUInt32BE(12), defaultSampleFlags: buf.readUInt32BE(16) } } exports.trex.encodingLength = function (box) { return 20 } exports.mfhd = {} exports.mfhd.encode = function (box, buf, offset) { buf = buf ? buf.slice(offset) : Buffer.alloc(4) buf.writeUInt32BE(box.sequenceNumber || 0, 0) exports.mfhd.encode.bytes = 4 return buf } exports.mfhd.decode = function (buf, offset) { return { sequenceNumber: buf.readUInt32BE(0) } } exports.mfhd.encodingLength = function (box) { return 4 } exports.tfhd = {} exports.tfhd.encode = function (box, buf, offset) { buf = buf ? buf.slice(offset) : Buffer.alloc(4) buf.writeUInt32BE(box.trackId, 0) exports.tfhd.encode.bytes = 4 return buf } exports.tfhd.decode = function (buf, offset) { // TODO: this } exports.tfhd.encodingLength = function (box) { // TODO: this is wrong! return 4 } exports.tfdt = {} exports.tfdt.encode = function (box, buf, offset) { buf = buf ? buf.slice(offset) : Buffer.alloc(4) buf.writeUInt32BE(box.baseMediaDecodeTime || 0, 0) exports.tfdt.encode.bytes = 4 return buf } exports.tfdt.decode = function (buf, offset) { // TODO: this } exports.tfdt.encodingLength = function (box) { return 4 } exports.trun = {} exports.trun.encode = function (box, buf, offset) { buf = buf ? buf.slice(offset) : Buffer.alloc(8 + box.entries.length * 16) // TODO: this is wrong buf.writeUInt32BE(box.entries.length, 0) buf.writeInt32BE(box.dataOffset, 4) var ptr = 8 for (var i = 0; i < box.entries.length; i++) { var entry = box.entries[i] buf.writeUInt32BE(entry.sampleDuration, ptr) ptr += 4 buf.writeUInt32BE(entry.sampleSize, ptr) ptr += 4 buf.writeUInt32BE(entry.sampleFlags, ptr) ptr += 4 if ((box.version || 0) === 0) { buf.writeUInt32BE(entry.sampleCompositionTimeOffset, ptr) } else { buf.writeInt32BE(entry.sampleCompositionTimeOffset, ptr) } ptr += 4 } exports.trun.encode.bytes = ptr } exports.trun.decode = function (buf, offset) { // TODO: this } exports.trun.encodingLength = function (box) { // TODO: this is wrong return 8 + box.entries.length * 16 } exports.mdat = {} exports.mdat.encode = function (box, buf, offset) { if (box.buffer) { box.buffer.copy(buf, offset) exports.mdat.encode.bytes = box.buffer.length } else { exports.mdat.encode.bytes = exports.mdat.encodingLength(box) } } exports.mdat.decode = function (buf, start, end) { return { buffer: Buffer.from(buf.slice(start, end)) } } exports.mdat.encodingLength = function (box) { return box.buffer ? box.buffer.length : box.contentLength } function writeReserved (buf, offset, end) { for (var i = offset; i < end; i++) buf[i] = 0 } function writeDate (date, buf, offset) { buf.writeUInt32BE(Math.floor((date.getTime() + TIME_OFFSET) / 1000), offset) } function writeDate64 (date, buf, offset) { // Node only supports integer <= 48bit. Waiting for BigInt! buf.writeUIntBE(Math.floor((date.getTime() + TIME_OFFSET) / 1000), offset, 6) } // TODO: think something is wrong here function writeFixed32 (num, buf, offset) { buf.writeUInt16BE(Math.floor(num) % (256 * 256), offset) buf.writeUInt16BE(Math.floor(num * 256 * 256) % (256 * 256), offset + 2) } function writeFixed16 (num, buf, offset) { buf[offset] = Math.floor(num) % 256 buf[offset + 1] = Math.floor(num * 256) % 256 } function writeMatrix (list, buf, offset) { if (!list) list = [0, 0, 0, 0, 0, 0, 0, 0, 0] for (var i = 0; i < list.length; i++) { writeFixed32(list[i], buf, offset + i * 4) } } function writeString (str, buf, offset) { var strBuffer = Buffer.from(str, 'utf8') strBuffer.copy(buf, offset) buf[offset + strBuffer.length] = 0 } function readMatrix (buf) { var list = new Array(buf.length / 4) for (var i = 0; i < list.length; i++) list[i] = readFixed32(buf, i * 4) return list } function readDate64 (buf, offset) { // Node only supports integer <= 48bit. Waiting for BigInt! return new Date(buf.readUIntBE(offset, 6) * 1000 - TIME_OFFSET) } function readDate (buf, offset) { return new Date(buf.readUInt32BE(offset) * 1000 - TIME_OFFSET) } function readFixed32 (buf, offset) { return buf.readUInt16BE(offset) + buf.readUInt16BE(offset + 2) / (256 * 256) } function readFixed16 (buf, offset) { return buf[offset] + buf[offset + 1] / 256 } function readString (buf, offset, length) { var i for (i = 0; i < length; i++) { if (buf[offset + i] === 0) { break } } return buf.toString('utf8', offset, offset + i) } }).call(this)}).call(this,require("buffer").Buffer) },{"./descriptor":156,"./index":157,"buffer":331,"uint64be":292}],156:[function(require,module,exports){ (function (Buffer){(function (){ var tagToName = { 0x03: 'ESDescriptor', 0x04: 'DecoderConfigDescriptor', 0x05: 'DecoderSpecificInfo', 0x06: 'SLConfigDescriptor' } exports.Descriptor = {} exports.Descriptor.decode = function (buf, start, end) { var tag = buf.readUInt8(start) var ptr = start + 1 var lenByte var len = 0 do { lenByte = buf.readUInt8(ptr++) len = (len << 7) | (lenByte & 0x7f) } while (lenByte & 0x80) var obj var tagName = tagToName[tag] // May be undefined; that's ok if (exports[tagName]) { obj = exports[tagName].decode(buf, ptr, end) } else { obj = { buffer: Buffer.from(buf.slice(ptr, ptr + len)) } } obj.tag = tag obj.tagName = tagName obj.length = (ptr - start) + len obj.contentsLen = len return obj } exports.DescriptorArray = {} exports.DescriptorArray.decode = function (buf, start, end) { var ptr = start var obj = {} while (ptr + 2 <= end) { var descriptor = exports.Descriptor.decode(buf, ptr, end) ptr += descriptor.length var tagName = tagToName[descriptor.tag] || ('Descriptor' + descriptor.tag) obj[tagName] = descriptor } return obj } exports.ESDescriptor = {} exports.ESDescriptor.decode = function (buf, start, end) { var flags = buf.readUInt8(start + 2) var ptr = start + 3 if (flags & 0x80) { ptr += 2 } if (flags & 0x40) { var len = buf.readUInt8(ptr) ptr += len + 1 } if (flags & 0x20) { ptr += 2 } return exports.DescriptorArray.decode(buf, ptr, end) } exports.DecoderConfigDescriptor = {} exports.DecoderConfigDescriptor.decode = function (buf, start, end) { var oti = buf.readUInt8(start) var obj = exports.DescriptorArray.decode(buf, start + 13, end) obj.oti = oti return obj } }).call(this)}).call(this,require("buffer").Buffer) },{"buffer":331}],157:[function(require,module,exports){ (function (Buffer){(function (){ // var assert = require('assert') var uint64be = require('uint64be') var boxes = require('./boxes') var UINT32_MAX = 4294967295 var Box = exports /* * Lists the proper order for boxes inside containers. * Five-character names ending in 's' indicate arrays instead of single elements. */ var containers = exports.containers = { 'moov': ['mvhd', 'meta', 'traks', 'mvex'], 'trak': ['tkhd', 'tref', 'trgr', 'edts', 'meta', 'mdia', 'udta'], 'edts': ['elst'], 'mdia': ['mdhd', 'hdlr', 'elng', 'minf'], 'minf': ['vmhd', 'smhd', 'hmhd', 'sthd', 'nmhd', 'dinf', 'stbl'], 'dinf': ['dref'], 'stbl': ['stsd', 'stts', 'ctts', 'cslg', 'stsc', 'stsz', 'stz2', 'stco', 'co64', 'stss', 'stsh', 'padb', 'stdp', 'sdtp', 'sbgps', 'sgpds', 'subss', 'saizs', 'saios'], 'mvex': ['mehd', 'trexs', 'leva'], 'moof': ['mfhd', 'meta', 'trafs'], 'traf': ['tfhd', 'tfdt', 'trun', 'sbgps', 'sgpds', 'subss', 'saizs', 'saios', 'meta'] } Box.encode = function (obj, buffer, offset) { Box.encodingLength(obj) // sets every level appropriately offset = offset || 0 buffer = buffer || Buffer.alloc(obj.length) return Box._encode(obj, buffer, offset) } Box._encode = function (obj, buffer, offset) { var type = obj.type var len = obj.length if (len > UINT32_MAX) { len = 1 } buffer.writeUInt32BE(len, offset) buffer.write(obj.type, offset + 4, 4, 'ascii') var ptr = offset + 8 if (len === 1) { uint64be.encode(obj.length, buffer, ptr) ptr += 8 } if (boxes.fullBoxes[type]) { buffer.writeUInt32BE(obj.flags || 0, ptr) buffer.writeUInt8(obj.version || 0, ptr) ptr += 4 } if (containers[type]) { var contents = containers[type] contents.forEach(function (childType) { if (childType.length === 5) { var entry = obj[childType] || [] childType = childType.substr(0, 4) entry.forEach(function (child) { Box._encode(child, buffer, ptr) ptr += Box.encode.bytes }) } else if (obj[childType]) { Box._encode(obj[childType], buffer, ptr) ptr += Box.encode.bytes } }) if (obj.otherBoxes) { obj.otherBoxes.forEach(function (child) { Box._encode(child, buffer, ptr) ptr += Box.encode.bytes }) } } else if (boxes[type]) { var encode = boxes[type].encode encode(obj, buffer, ptr) ptr += encode.bytes } else if (obj.buffer) { var buf = obj.buffer buf.copy(buffer, ptr) ptr += obj.buffer.length } else { throw new Error('Either `type` must be set to a known type (not\'' + type + '\') or `buffer` must be set') } Box.encode.bytes = ptr - offset // assert.equal(ptr - offset, obj.length, 'Error encoding \'' + type + '\': wrote ' + ptr - offset + ' bytes, expecting ' + obj.length) return buffer } /* * Returns an object with `type` and `size` fields, * or if there isn't enough data, returns the total * number of bytes needed to read the headers */ Box.readHeaders = function (buffer, start, end) { start = start || 0 end = end || buffer.length if (end - start < 8) { return 8 } var len = buffer.readUInt32BE(start) var type = buffer.toString('ascii', start + 4, start + 8) var ptr = start + 8 if (len === 1) { if (end - start < 16) { return 16 } len = uint64be.decode(buffer, ptr) ptr += 8 } var version var flags if (boxes.fullBoxes[type]) { version = buffer.readUInt8(ptr) flags = buffer.readUInt32BE(ptr) & 0xffffff ptr += 4 } return { length: len, headersLen: ptr - start, contentLen: len - (ptr - start), type: type, version: version, flags: flags } } Box.decode = function (buffer, start, end) { start = start || 0 end = end || buffer.length var headers = Box.readHeaders(buffer, start, end) if (!headers || headers.length > end - start) { throw new Error('Data too short') } return Box.decodeWithoutHeaders(headers, buffer, start + headers.headersLen, start + headers.length) } Box.decodeWithoutHeaders = function (headers, buffer, start, end) { start = start || 0 end = end || buffer.length var type = headers.type var obj = {} if (containers[type]) { obj.otherBoxes = [] var contents = containers[type] var ptr = start while (end - ptr >= 8) { var child = Box.decode(buffer, ptr, end) ptr += child.length if (contents.indexOf(child.type) >= 0) { obj[child.type] = child } else if (contents.indexOf(child.type + 's') >= 0) { var childType = child.type + 's' var entry = obj[childType] = obj[childType] || [] entry.push(child) } else { obj.otherBoxes.push(child) } } } else if (boxes[type]) { var decode = boxes[type].decode obj = decode(buffer, start, end) } else { obj.buffer = Buffer.from(buffer.slice(start, end)) } obj.length = headers.length obj.contentLen = headers.contentLen obj.type = headers.type obj.version = headers.version obj.flags = headers.flags return obj } Box.encodingLength = function (obj) { var type = obj.type var len = 8 if (boxes.fullBoxes[type]) { len += 4 } if (containers[type]) { var contents = containers[type] contents.forEach(function (childType) { if (childType.length === 5) { var entry = obj[childType] || [] childType = childType.substr(0, 4) entry.forEach(function (child) { child.type = childType len += Box.encodingLength(child) }) } else if (obj[childType]) { var child = obj[childType] child.type = childType len += Box.encodingLength(child) } }) if (obj.otherBoxes) { obj.otherBoxes.forEach(function (child) { len += Box.encodingLength(child) }) } } else if (boxes[type]) { len += boxes[type].encodingLength(obj) } else if (obj.buffer) { len += obj.buffer.length } else { throw new Error('Either `type` must be set to a known type (not\'' + type + '\') or `buffer` must be set') } if (len > UINT32_MAX) { len += 8 } obj.length = len return len } }).call(this)}).call(this,require("buffer").Buffer) },{"./boxes":155,"buffer":331,"uint64be":292}],158:[function(require,module,exports){ (function (Buffer){(function (){ var stream = require('readable-stream') var nextEvent = require('next-event') var Box = require('mp4-box-encoding') var EMPTY = Buffer.alloc(0) class Decoder extends stream.Writable { constructor (opts) { super(opts) this.destroyed = false this._pending = 0 this._missing = 0 this._ignoreEmpty = false this._buf = null this._str = null this._cb = null this._ondrain = null this._writeBuffer = null this._writeCb = null this._ondrain = null this._kick() } destroy (err) { if (this.destroyed) return this.destroyed = true if (err) this.emit('error', err) this.emit('close') } _write (data, enc, next) { if (this.destroyed) return var drained = !this._str || !this._str._writableState.needDrain while (data.length && !this.destroyed) { if (!this._missing && !this._ignoreEmpty) { this._writeBuffer = data this._writeCb = next return } var consumed = data.length < this._missing ? data.length : this._missing if (this._buf) data.copy(this._buf, this._buf.length - this._missing) else if (this._str) drained = this._str.write(consumed === data.length ? data : data.slice(0, consumed)) this._missing -= consumed if (!this._missing) { var buf = this._buf var cb = this._cb var stream = this._str this._buf = this._cb = this._str = this._ondrain = null drained = true this._ignoreEmpty = false if (stream) stream.end() if (cb) cb(buf) } data = consumed === data.length ? EMPTY : data.slice(consumed) } if (this._pending && !this._missing) { this._writeBuffer = data this._writeCb = next return } if (drained) next() else this._ondrain(next) } _buffer (size, cb) { this._missing = size this._buf = Buffer.alloc(size) this._cb = cb } _stream (size, cb) { this._missing = size this._str = new MediaData(this) this._ondrain = nextEvent(this._str, 'drain') this._pending++ this._str.on('end', () => { this._pending-- this._kick() }) this._cb = cb return this._str } _readBox () { const bufferHeaders = (len, buf) => { this._buffer(len, additionalBuf => { if (buf) { buf = Buffer.concat([buf, additionalBuf]) } else { buf = additionalBuf } var headers = Box.readHeaders(buf) if (typeof headers === 'number') { bufferHeaders(headers - buf.length, buf) } else { this._pending++ this._headers = headers this.emit('box', headers) } }) } bufferHeaders(8) } stream () { if (!this._headers) throw new Error('this function can only be called once after \'box\' is emitted') var headers = this._headers this._headers = null return this._stream(headers.contentLen, null) } decode (cb) { if (!this._headers) throw new Error('this function can only be called once after \'box\' is emitted') var headers = this._headers this._headers = null this._buffer(headers.contentLen, buf => { var box = Box.decodeWithoutHeaders(headers, buf) cb(box) this._pending-- this._kick() }) } ignore () { if (!this._headers) throw new Error('this function can only be called once after \'box\' is emitted') var headers = this._headers this._headers = null this._missing = headers.contentLen if (this._missing === 0) { this._ignoreEmpty = true } this._cb = () => { this._pending-- this._kick() } } _kick () { if (this._pending) return if (!this._buf && !this._str) this._readBox() if (this._writeBuffer) { var next = this._writeCb var buffer = this._writeBuffer this._writeBuffer = null this._writeCb = null this._write(buffer, null, next) } } } class MediaData extends stream.PassThrough { constructor (parent) { super() this._parent = parent this.destroyed = false } destroy (err) { if (this.destroyed) return this.destroyed = true this._parent.destroy(err) if (err) this.emit('error', err) this.emit('close') } } module.exports = Decoder }).call(this)}).call(this,require("buffer").Buffer) },{"buffer":331,"mp4-box-encoding":157,"next-event":193,"readable-stream":175}],159:[function(require,module,exports){ (function (process,Buffer){(function (){ var stream = require('readable-stream') var Box = require('mp4-box-encoding') function noop () {} class Encoder extends stream.Readable { constructor (opts) { super(opts) this.destroyed = false this._finalized = false this._reading = false this._stream = null this._drain = null this._want = false this._onreadable = () => { if (!this._want) return this._want = false this._read() } this._onend = () => { this._stream = null } } mdat (size, cb) { this.mediaData(size, cb) } mediaData (size, cb) { var stream = new MediaData(this) this.box({ type: 'mdat', contentLength: size, encodeBufferLen: 8, stream: stream }, cb) return stream } box (box, cb) { if (!cb) cb = noop if (this.destroyed) return cb(new Error('Encoder is destroyed')) var buf if (box.encodeBufferLen) { buf = Buffer.alloc(box.encodeBufferLen) } if (box.stream) { box.buffer = null buf = Box.encode(box, buf) this.push(buf) this._stream = box.stream this._stream.on('readable', this._onreadable) this._stream.on('end', this._onend) this._stream.on('end', cb) this._forward() } else { buf = Box.encode(box, buf) var drained = this.push(buf) if (drained) return process.nextTick(cb) this._drain = cb } } destroy (err) { if (this.destroyed) return this.destroyed = true if (this._stream && this._stream.destroy) this._stream.destroy() this._stream = null if (this._drain) { var cb = this._drain this._drain = null cb(err) } if (err) this.emit('error', err) this.emit('close') } finalize () { this._finalized = true if (!this._stream && !this._drain) { this.push(null) } } _forward () { if (!this._stream) return while (!this.destroyed) { var buf = this._stream.read() if (!buf) { this._want = !!this._stream return } if (!this.push(buf)) return } } _read () { if (this._reading || this.destroyed) return this._reading = true if (this._stream) this._forward() if (this._drain) { var drain = this._drain this._drain = null drain() } this._reading = false if (this._finalized) { this.push(null) } } } class MediaData extends stream.PassThrough { constructor (parent) { super() this._parent = parent this.destroyed = false } destroy (err) { if (this.destroyed) return this.destroyed = true this._parent.destroy(err) if (err) this.emit('error', err) this.emit('close') } } module.exports = Encoder }).call(this)}).call(this,require('_process'),require("buffer").Buffer) },{"_process":338,"buffer":331,"mp4-box-encoding":157,"readable-stream":175}],160:[function(require,module,exports){ const Decoder = require('./decode') const Encoder = require('./encode') exports.decode = opts => new Decoder(opts) exports.encode = opts => new Encoder(opts) },{"./decode":158,"./encode":159}],161:[function(require,module,exports){ arguments[4][14][0].apply(exports,arguments) },{"dup":14}],162:[function(require,module,exports){ arguments[4][15][0].apply(exports,arguments) },{"./_stream_readable":164,"./_stream_writable":166,"_process":338,"dup":15,"inherits":131}],163:[function(require,module,exports){ arguments[4][16][0].apply(exports,arguments) },{"./_stream_transform":165,"dup":16,"inherits":131}],164:[function(require,module,exports){ arguments[4][17][0].apply(exports,arguments) },{"../errors":161,"./_stream_duplex":162,"./internal/streams/async_iterator":167,"./internal/streams/buffer_list":168,"./internal/streams/destroy":169,"./internal/streams/from":171,"./internal/streams/state":173,"./internal/streams/stream":174,"_process":338,"buffer":331,"dup":17,"events":333,"inherits":131,"string_decoder/":281,"util":330}],165:[function(require,module,exports){ arguments[4][18][0].apply(exports,arguments) },{"../errors":161,"./_stream_duplex":162,"dup":18,"inherits":131}],166:[function(require,module,exports){ arguments[4][19][0].apply(exports,arguments) },{"../errors":161,"./_stream_duplex":162,"./internal/streams/destroy":169,"./internal/streams/state":173,"./internal/streams/stream":174,"_process":338,"buffer":331,"dup":19,"inherits":131,"util-deprecate":298}],167:[function(require,module,exports){ arguments[4][20][0].apply(exports,arguments) },{"./end-of-stream":170,"_process":338,"dup":20}],168:[function(require,module,exports){ arguments[4][21][0].apply(exports,arguments) },{"buffer":331,"dup":21,"util":330}],169:[function(require,module,exports){ arguments[4][22][0].apply(exports,arguments) },{"_process":338,"dup":22}],170:[function(require,module,exports){ arguments[4][23][0].apply(exports,arguments) },{"../../../errors":161,"dup":23}],171:[function(require,module,exports){ arguments[4][24][0].apply(exports,arguments) },{"dup":24}],172:[function(require,module,exports){ arguments[4][25][0].apply(exports,arguments) },{"../../../errors":161,"./end-of-stream":170,"dup":25}],173:[function(require,module,exports){ arguments[4][26][0].apply(exports,arguments) },{"../../../errors":161,"dup":26}],174:[function(require,module,exports){ arguments[4][27][0].apply(exports,arguments) },{"dup":27,"events":333}],175:[function(require,module,exports){ arguments[4][28][0].apply(exports,arguments) },{"./lib/_stream_duplex.js":162,"./lib/_stream_passthrough.js":163,"./lib/_stream_readable.js":164,"./lib/_stream_transform.js":165,"./lib/_stream_writable.js":166,"./lib/internal/streams/end-of-stream.js":170,"./lib/internal/streams/pipeline.js":172,"dup":28}],176:[function(require,module,exports){ /** * Helpers. */ var s = 1000; var m = s * 60; var h = m * 60; var d = h * 24; var w = d * 7; var y = d * 365.25; /** * Parse or format the given `val`. * * Options: * * - `long` verbose formatting [false] * * @param {String|Number} val * @param {Object} [options] * @throws {Error} throw an error if val is not a non-empty string or a number * @return {String|Number} * @api public */ module.exports = function (val, options) { options = options || {}; var type = typeof val; if (type === 'string' && val.length > 0) { return parse(val); } else if (type === 'number' && isFinite(val)) { return options.long ? fmtLong(val) : fmtShort(val); } throw new Error( 'val is not a non-empty string or a valid number. val=' + JSON.stringify(val) ); }; /** * Parse the given `str` and return milliseconds. * * @param {String} str * @return {Number} * @api private */ function parse(str) { str = String(str); if (str.length > 100) { return; } var match = /^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec( str ); if (!match) { return; } var n = parseFloat(match[1]); var type = (match[2] || 'ms').toLowerCase(); switch (type) { case 'years': case 'year': case 'yrs': case 'yr': case 'y': return n * y; case 'weeks': case 'week': case 'w': return n * w; case 'days': case 'day': case 'd': return n * d; case 'hours': case 'hour': case 'hrs': case 'hr': case 'h': return n * h; case 'minutes': case 'minute': case 'mins': case 'min': case 'm': return n * m; case 'seconds': case 'second': case 'secs': case 'sec': case 's': return n * s; case 'milliseconds': case 'millisecond': case 'msecs': case 'msec': case 'ms': return n; default: return undefined; } } /** * Short format for `ms`. * * @param {Number} ms * @return {String} * @api private */ function fmtShort(ms) { var msAbs = Math.abs(ms); if (msAbs >= d) { return Math.round(ms / d) + 'd'; } if (msAbs >= h) { return Math.round(ms / h) + 'h'; } if (msAbs >= m) { return Math.round(ms / m) + 'm'; } if (msAbs >= s) { return Math.round(ms / s) + 's'; } return ms + 'ms'; } /** * Long format for `ms`. * * @param {Number} ms * @return {String} * @api private */ function fmtLong(ms) { var msAbs = Math.abs(ms); if (msAbs >= d) { return plural(ms, msAbs, d, 'day'); } if (msAbs >= h) { return plural(ms, msAbs, h, 'hour'); } if (msAbs >= m) { return plural(ms, msAbs, m, 'minute'); } if (msAbs >= s) { return plural(ms, msAbs, s, 'second'); } return ms + ' ms'; } /** * Pluralization helper. */ function plural(ms, msAbs, n, name) { var isPlural = msAbs >= n * 1.5; return Math.round(ms / n) + ' ' + name + (isPlural ? 's' : ''); } },{}],177:[function(require,module,exports){ /*! multistream. MIT License. Feross Aboukhadijeh */ var stream = require('readable-stream') function toStreams2Obj (s) { return toStreams2(s, { objectMode: true, highWaterMark: 16 }) } function toStreams2Buf (s) { return toStreams2(s) } function toStreams2 (s, opts) { if (!s || typeof s === 'function' || s._readableState) return s var wrap = new stream.Readable(opts).wrap(s) if (s.destroy) { wrap.destroy = s.destroy.bind(s) } return wrap } class MultiStream extends stream.Readable { constructor (streams, opts) { super(opts) this.destroyed = false this._drained = false this._forwarding = false this._current = null this._toStreams2 = (opts && opts.objectMode) ? toStreams2Obj : toStreams2Buf if (typeof streams === 'function') { this._queue = streams } else { this._queue = streams.map(this._toStreams2) this._queue.forEach(stream => { if (typeof stream !== 'function') this._attachErrorListener(stream) }) } this._next() } _read () { this._drained = true this._forward() } _forward () { if (this._forwarding || !this._drained || !this._current) return this._forwarding = true var chunk while (this._drained && (chunk = this._current.read()) !== null) { this._drained = this.push(chunk) } this._forwarding = false } destroy (err) { if (this.destroyed) return this.destroyed = true if (this._current && this._current.destroy) this._current.destroy() if (typeof this._queue !== 'function') { this._queue.forEach(stream => { if (stream.destroy) stream.destroy() }) } if (err) this.emit('error', err) this.emit('close') } _next () { this._current = null if (typeof this._queue === 'function') { this._queue((err, stream) => { if (err) return this.destroy(err) stream = this._toStreams2(stream) this._attachErrorListener(stream) this._gotNextStream(stream) }) } else { var stream = this._queue.shift() if (typeof stream === 'function') { stream = this._toStreams2(stream()) this._attachErrorListener(stream) } this._gotNextStream(stream) } } _gotNextStream (stream) { if (!stream) { this.push(null) this.destroy() return } this._current = stream this._forward() const onReadable = () => { this._forward() } const onClose = () => { if (!stream._readableState.ended) { this.destroy() } } const onEnd = () => { this._current = null stream.removeListener('readable', onReadable) stream.removeListener('end', onEnd) stream.removeListener('close', onClose) this._next() } stream.on('readable', onReadable) stream.once('end', onEnd) stream.once('close', onClose) } _attachErrorListener (stream) { if (!stream) return const onError = (err) => { stream.removeListener('error', onError) this.destroy(err) } stream.once('error', onError) } } MultiStream.obj = streams => ( new MultiStream(streams, { objectMode: true, highWaterMark: 16 }) ) module.exports = MultiStream },{"readable-stream":192}],178:[function(require,module,exports){ arguments[4][14][0].apply(exports,arguments) },{"dup":14}],179:[function(require,module,exports){ arguments[4][15][0].apply(exports,arguments) },{"./_stream_readable":181,"./_stream_writable":183,"_process":338,"dup":15,"inherits":131}],180:[function(require,module,exports){ arguments[4][16][0].apply(exports,arguments) },{"./_stream_transform":182,"dup":16,"inherits":131}],181:[function(require,module,exports){ arguments[4][17][0].apply(exports,arguments) },{"../errors":178,"./_stream_duplex":179,"./internal/streams/async_iterator":184,"./internal/streams/buffer_list":185,"./internal/streams/destroy":186,"./internal/streams/from":188,"./internal/streams/state":190,"./internal/streams/stream":191,"_process":338,"buffer":331,"dup":17,"events":333,"inherits":131,"string_decoder/":281,"util":330}],182:[function(require,module,exports){ arguments[4][18][0].apply(exports,arguments) },{"../errors":178,"./_stream_duplex":179,"dup":18,"inherits":131}],183:[function(require,module,exports){ arguments[4][19][0].apply(exports,arguments) },{"../errors":178,"./_stream_duplex":179,"./internal/streams/destroy":186,"./internal/streams/state":190,"./internal/streams/stream":191,"_process":338,"buffer":331,"dup":19,"inherits":131,"util-deprecate":298}],184:[function(require,module,exports){ arguments[4][20][0].apply(exports,arguments) },{"./end-of-stream":187,"_process":338,"dup":20}],185:[function(require,module,exports){ arguments[4][21][0].apply(exports,arguments) },{"buffer":331,"dup":21,"util":330}],186:[function(require,module,exports){ arguments[4][22][0].apply(exports,arguments) },{"_process":338,"dup":22}],187:[function(require,module,exports){ arguments[4][23][0].apply(exports,arguments) },{"../../../errors":178,"dup":23}],188:[function(require,module,exports){ arguments[4][24][0].apply(exports,arguments) },{"dup":24}],189:[function(require,module,exports){ arguments[4][25][0].apply(exports,arguments) },{"../../../errors":178,"./end-of-stream":187,"dup":25}],190:[function(require,module,exports){ arguments[4][26][0].apply(exports,arguments) },{"../../../errors":178,"dup":26}],191:[function(require,module,exports){ arguments[4][27][0].apply(exports,arguments) },{"dup":27,"events":333}],192:[function(require,module,exports){ arguments[4][28][0].apply(exports,arguments) },{"./lib/_stream_duplex.js":179,"./lib/_stream_passthrough.js":180,"./lib/_stream_readable.js":181,"./lib/_stream_transform.js":182,"./lib/_stream_writable.js":183,"./lib/internal/streams/end-of-stream.js":187,"./lib/internal/streams/pipeline.js":189,"dup":28}],193:[function(require,module,exports){ module.exports = nextEvent function nextEvent (emitter, name) { var next = null emitter.on(name, function (data) { if (!next) return var fn = next next = null fn(data) }) return function (once) { next = once } } },{}],194:[function(require,module,exports){ var wrappy = require('wrappy') module.exports = wrappy(once) module.exports.strict = wrappy(onceStrict) once.proto = once(function () { Object.defineProperty(Function.prototype, 'once', { value: function () { return once(this) }, configurable: true }) Object.defineProperty(Function.prototype, 'onceStrict', { value: function () { return onceStrict(this) }, configurable: true }) }) function once (fn) { var f = function () { if (f.called) return f.value f.called = true return f.value = fn.apply(this, arguments) } f.called = false return f } function onceStrict (fn) { var f = function () { if (f.called) throw new Error(f.onceError) f.called = true return f.value = fn.apply(this, arguments) } var name = fn.name || 'Function wrapped with `once`' f.onceError = name + " shouldn't be called more than once" f.called = false return f } },{"wrappy":327}],195:[function(require,module,exports){ (function (process,Buffer){(function (){ /*! parse-torrent. MIT License. WebTorrent LLC */ /* global Blob */ const bencode = require('bencode') const blobToBuffer = require('blob-to-buffer') const fs = require('fs') // browser exclude const get = require('simple-get') const magnet = require('magnet-uri') const path = require('path') const sha1 = require('simple-sha1') module.exports = parseTorrent module.exports.remote = parseTorrentRemote module.exports.toMagnetURI = magnet.encode module.exports.toTorrentFile = encodeTorrentFile /** * Parse a torrent identifier (magnet uri, .torrent file, info hash) * @param {string|Buffer|Object} torrentId * @return {Object} */ function parseTorrent (torrentId) { if (typeof torrentId === 'string' && /^(stream-)?magnet:/.test(torrentId)) { // if magnet uri (string) const torrentObj = magnet(torrentId) // infoHash won't be defined if a non-bittorrent magnet is passed if (!torrentObj.infoHash) { throw new Error('Invalid torrent identifier') } return torrentObj } else if (typeof torrentId === 'string' && (/^[a-f0-9]{40}$/i.test(torrentId) || /^[a-z2-7]{32}$/i.test(torrentId))) { // if info hash (hex/base-32 string) return magnet(`magnet:?xt=urn:btih:${torrentId}`) } else if (Buffer.isBuffer(torrentId) && torrentId.length === 20) { // if info hash (buffer) return magnet(`magnet:?xt=urn:btih:${torrentId.toString('hex')}`) } else if (Buffer.isBuffer(torrentId)) { // if .torrent file (buffer) return decodeTorrentFile(torrentId) // might throw } else if (torrentId && torrentId.infoHash) { // if parsed torrent (from `parse-torrent` or `magnet-uri`) torrentId.infoHash = torrentId.infoHash.toLowerCase() if (!torrentId.announce) torrentId.announce = [] if (typeof torrentId.announce === 'string') { torrentId.announce = [torrentId.announce] } if (!torrentId.urlList) torrentId.urlList = [] return torrentId } else { throw new Error('Invalid torrent identifier') } } function parseTorrentRemote (torrentId, opts, cb) { if (typeof opts === 'function') return parseTorrentRemote(torrentId, {}, opts) if (typeof cb !== 'function') throw new Error('second argument must be a Function') let parsedTorrent try { parsedTorrent = parseTorrent(torrentId) } catch (err) { // If torrent fails to parse, it could be a Blob, http/https URL or // filesystem path, so don't consider it an error yet. } if (parsedTorrent && parsedTorrent.infoHash) { process.nextTick(() => { cb(null, parsedTorrent) }) } else if (isBlob(torrentId)) { blobToBuffer(torrentId, (err, torrentBuf) => { if (err) return cb(new Error(`Error converting Blob: ${err.message}`)) parseOrThrow(torrentBuf) }) } else if (typeof get === 'function' && /^https?:/.test(torrentId)) { // http, or https url to torrent file opts = Object.assign({ url: torrentId, timeout: 30 * 1000, headers: { 'user-agent': 'WebTorrent (https://webtorrent.io)' } }, opts) get.concat(opts, (err, res, torrentBuf) => { if (err) return cb(new Error(`Error downloading torrent: ${err.message}`)) parseOrThrow(torrentBuf) }) } else if (typeof fs.readFile === 'function' && typeof torrentId === 'string') { // assume it's a filesystem path fs.readFile(torrentId, (err, torrentBuf) => { if (err) return cb(new Error('Invalid torrent identifier')) parseOrThrow(torrentBuf) }) } else { process.nextTick(() => { cb(new Error('Invalid torrent identifier')) }) } function parseOrThrow (torrentBuf) { try { parsedTorrent = parseTorrent(torrentBuf) } catch (err) { return cb(err) } if (parsedTorrent && parsedTorrent.infoHash) cb(null, parsedTorrent) else cb(new Error('Invalid torrent identifier')) } } /** * Parse a torrent. Throws an exception if the torrent is missing required fields. * @param {Buffer|Object} torrent * @return {Object} parsed torrent */ function decodeTorrentFile (torrent) { if (Buffer.isBuffer(torrent)) { torrent = bencode.decode(torrent) } // sanity check ensure(torrent.info, 'info') ensure(torrent.info['name.utf-8'] || torrent.info.name, 'info.name') ensure(torrent.info['piece length'], 'info[\'piece length\']') ensure(torrent.info.pieces, 'info.pieces') if (torrent.info.files) { torrent.info.files.forEach(file => { ensure(typeof file.length === 'number', 'info.files[0].length') ensure(file['path.utf-8'] || file.path, 'info.files[0].path') }) } else { ensure(typeof torrent.info.length === 'number', 'info.length') } const result = { info: torrent.info, infoBuffer: bencode.encode(torrent.info), name: (torrent.info['name.utf-8'] || torrent.info.name).toString(), announce: [] } result.infoHash = sha1.sync(result.infoBuffer) result.infoHashBuffer = Buffer.from(result.infoHash, 'hex') if (torrent.info.private !== undefined) result.private = !!torrent.info.private if (torrent['creation date']) result.created = new Date(torrent['creation date'] * 1000) if (torrent['created by']) result.createdBy = torrent['created by'].toString() if (Buffer.isBuffer(torrent.comment)) result.comment = torrent.comment.toString() // announce and announce-list will be missing if metadata fetched via ut_metadata if (Array.isArray(torrent['announce-list']) && torrent['announce-list'].length > 0) { torrent['announce-list'].forEach(urls => { urls.forEach(url => { result.announce.push(url.toString()) }) }) } else if (torrent.announce) { result.announce.push(torrent.announce.toString()) } // handle url-list (BEP19 / web seeding) if (Buffer.isBuffer(torrent['url-list'])) { // some clients set url-list to empty string torrent['url-list'] = torrent['url-list'].length > 0 ? [torrent['url-list']] : [] } result.urlList = (torrent['url-list'] || []).map(url => url.toString()) // remove duplicates by converting to Set and back result.announce = Array.from(new Set(result.announce)) result.urlList = Array.from(new Set(result.urlList)) const files = torrent.info.files || [torrent.info] result.files = files.map((file, i) => { const parts = [].concat(result.name, file['path.utf-8'] || file.path || []).map(p => p.toString()) return { path: path.join.apply(null, [path.sep].concat(parts)).slice(1), name: parts[parts.length - 1], length: file.length, offset: files.slice(0, i).reduce(sumLength, 0) } }) result.length = files.reduce(sumLength, 0) const lastFile = result.files[result.files.length - 1] result.pieceLength = torrent.info['piece length'] result.lastPieceLength = ((lastFile.offset + lastFile.length) % result.pieceLength) || result.pieceLength result.pieces = splitPieces(torrent.info.pieces) return result } /** * Convert a parsed torrent object back into a .torrent file buffer. * @param {Object} parsed parsed torrent * @return {Buffer} */ function encodeTorrentFile (parsed) { const torrent = { info: parsed.info } torrent['announce-list'] = (parsed.announce || []).map(url => { if (!torrent.announce) torrent.announce = url url = Buffer.from(url, 'utf8') return [url] }) torrent['url-list'] = parsed.urlList || [] if (parsed.private !== undefined) { torrent.private = Number(parsed.private) } if (parsed.created) { torrent['creation date'] = (parsed.created.getTime() / 1000) | 0 } if (parsed.createdBy) { torrent['created by'] = parsed.createdBy } if (parsed.comment) { torrent.comment = parsed.comment } return bencode.encode(torrent) } /** * Check if `obj` is a W3C `Blob` or `File` object * @param {*} obj * @return {boolean} */ function isBlob (obj) { return typeof Blob !== 'undefined' && obj instanceof Blob } function sumLength (sum, file) { return sum + file.length } function splitPieces (buf) { const pieces = [] for (let i = 0; i < buf.length; i += 20) { pieces.push(buf.slice(i, i + 20).toString('hex')) } return pieces } function ensure (bool, fieldName) { if (!bool) throw new Error(`Torrent is missing required field: ${fieldName}`) } // Workaround Browserify v13 bug // https://github.com/substack/node-browserify/issues/1483 ;(() => { Buffer.alloc(0) })() }).call(this)}).call(this,require('_process'),require("buffer").Buffer) },{"_process":338,"bencode":6,"blob-to-buffer":36,"buffer":331,"fs":328,"magnet-uri":136,"path":337,"simple-get":236,"simple-sha1":256}],196:[function(require,module,exports){ module.exports = length function length (bytes) { return Math.max(16384, 1 << Math.log2(bytes < 1024 ? 1 : bytes / 1024) + 0.5 | 0) } },{}],197:[function(require,module,exports){ (function (process){(function (){ var once = require('once') var eos = require('end-of-stream') var fs = require('fs') // we only need fs to get the ReadStream and WriteStream prototypes var noop = function () {} var ancient = /^v?\.0/.test(process.version) var isFn = function (fn) { return typeof fn === 'function' } var isFS = function (stream) { if (!ancient) return false // newer node version do not need to care about fs is a special way if (!fs) return false // browser return (stream instanceof (fs.ReadStream || noop) || stream instanceof (fs.WriteStream || noop)) && isFn(stream.close) } var isRequest = function (stream) { return stream.setHeader && isFn(stream.abort) } var destroyer = function (stream, reading, writing, callback) { callback = once(callback) var closed = false stream.on('close', function () { closed = true }) eos(stream, {readable: reading, writable: writing}, function (err) { if (err) return callback(err) closed = true callback() }) var destroyed = false return function (err) { if (closed) return if (destroyed) return destroyed = true if (isFS(stream)) return stream.close(noop) // use close for fs streams to avoid fd leaks if (isRequest(stream)) return stream.abort() // request.destroy just do .end - .abort is what we want if (isFn(stream.destroy)) return stream.destroy() callback(err || new Error('stream was destroyed')) } } var call = function (fn) { fn() } var pipe = function (from, to) { return from.pipe(to) } var pump = function () { var streams = Array.prototype.slice.call(arguments) var callback = isFn(streams[streams.length - 1] || noop) && streams.pop() || noop if (Array.isArray(streams[0])) streams = streams[0] if (streams.length < 2) throw new Error('pump requires two streams per minimum') var error var destroys = streams.map(function (stream, i) { var reading = i < streams.length - 1 var writing = i > 0 return destroyer(stream, reading, writing, function (err) { if (!error) error = err if (err) destroys.forEach(call) if (reading) return destroys.forEach(call) callback(error) }) }) return streams.reduce(pipe) } module.exports = pump }).call(this)}).call(this,require('_process')) },{"_process":338,"end-of-stream":95,"fs":330,"once":194}],198:[function(require,module,exports){ /*! queue-microtask. MIT License. Feross Aboukhadijeh */ let promise module.exports = typeof queueMicrotask === 'function' ? queueMicrotask.bind(globalThis) // reuse resolved promise, and allocate it lazily : cb => (promise || (promise = Promise.resolve())) .then(cb) .catch(err => setTimeout(() => { throw err }, 0)) },{}],199:[function(require,module,exports){ var iterate = function (list) { var offset = 0 return function () { if (offset === list.length) return null var len = list.length - offset var i = (Math.random() * len) | 0 var el = list[offset + i] var tmp = list[offset] list[offset] = el list[offset + i] = tmp offset++ return el } } module.exports = iterate },{}],200:[function(require,module,exports){ (function (process,global){(function (){ 'use strict' // limit of Crypto.getRandomValues() // https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues var MAX_BYTES = 65536 // Node supports requesting up to this number of bytes // https://github.com/nodejs/node/blob/master/lib/internal/crypto/random.js#L48 var MAX_UINT32 = 4294967295 function oldBrowser () { throw new Error('Secure random number generation is not supported by this browser.\nUse Chrome, Firefox or Internet Explorer 11') } var Buffer = require('safe-buffer').Buffer var crypto = global.crypto || global.msCrypto if (crypto && crypto.getRandomValues) { module.exports = randomBytes } else { module.exports = oldBrowser } function randomBytes (size, cb) { // phantomjs needs to throw if (size > MAX_UINT32) throw new RangeError('requested too many random bytes') var bytes = Buffer.allocUnsafe(size) if (size > 0) { // getRandomValues fails on IE if size == 0 if (size > MAX_BYTES) { // this is the max bytes crypto.getRandomValues // can do at once see https://developer.mozilla.org/en-US/docs/Web/API/window.crypto.getRandomValues for (var generated = 0; generated < size; generated += MAX_BYTES) { // buffer.slice automatically checks if the end is past the end of // the buffer so we don't have to here crypto.getRandomValues(bytes.slice(generated, generated + MAX_BYTES)) } } else { crypto.getRandomValues(bytes) } } if (typeof cb === 'function') { return process.nextTick(function () { cb(null, bytes) }) } return bytes } }).call(this)}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{"_process":338,"safe-buffer":226}],201:[function(require,module,exports){ /* Instance of writable stream. call .get(length) or .discard(length) to get a stream (relative to the last end) emits 'stalled' once everything is written */ const { Writable, PassThrough } = require('readable-stream') class RangeSliceStream extends Writable { constructor (offset, opts = {}) { super(opts) this.destroyed = false this._queue = [] this._position = offset || 0 this._cb = null this._buffer = null this._out = null } _write (chunk, encoding, cb) { let drained = true while (true) { if (this.destroyed) { return } // Wait for more queue entries if (this._queue.length === 0) { this._buffer = chunk this._cb = cb return } this._buffer = null var currRange = this._queue[0] // Relative to the start of chunk, what data do we need? const writeStart = Math.max(currRange.start - this._position, 0) const writeEnd = currRange.end - this._position // Check if we need to throw it all away if (writeStart >= chunk.length) { this._position += chunk.length return cb(null) } // Check if we need to use it all let toWrite if (writeEnd > chunk.length) { this._position += chunk.length if (writeStart === 0) { toWrite = chunk } else { toWrite = chunk.slice(writeStart) } drained = currRange.stream.write(toWrite) && drained break } this._position += writeEnd toWrite = (writeStart === 0 && writeEnd === chunk.length) ? chunk : chunk.slice(writeStart, writeEnd) drained = currRange.stream.write(toWrite) && drained if (currRange.last) { currRange.stream.end() } chunk = chunk.slice(writeEnd) this._queue.shift() } if (drained) { cb(null) } else { currRange.stream.once('drain', cb.bind(null, null)) } } slice (ranges) { if (this.destroyed) return null if (!Array.isArray(ranges)) ranges = [ranges] const str = new PassThrough() ranges.forEach((range, i) => { this._queue.push({ start: range.start, end: range.end, stream: str, last: i === ranges.length - 1 }) }) if (this._buffer) { this._write(this._buffer, null, this._cb) } return str } destroy (err) { if (this.destroyed) return this.destroyed = true if (err) this.emit('error', err) } } module.exports = RangeSliceStream },{"readable-stream":216}],202:[function(require,module,exports){ arguments[4][14][0].apply(exports,arguments) },{"dup":14}],203:[function(require,module,exports){ arguments[4][15][0].apply(exports,arguments) },{"./_stream_readable":205,"./_stream_writable":207,"_process":338,"dup":15,"inherits":131}],204:[function(require,module,exports){ arguments[4][16][0].apply(exports,arguments) },{"./_stream_transform":206,"dup":16,"inherits":131}],205:[function(require,module,exports){ arguments[4][17][0].apply(exports,arguments) },{"../errors":202,"./_stream_duplex":203,"./internal/streams/async_iterator":208,"./internal/streams/buffer_list":209,"./internal/streams/destroy":210,"./internal/streams/from":212,"./internal/streams/state":214,"./internal/streams/stream":215,"_process":338,"buffer":331,"dup":17,"events":333,"inherits":131,"string_decoder/":281,"util":330}],206:[function(require,module,exports){ arguments[4][18][0].apply(exports,arguments) },{"../errors":202,"./_stream_duplex":203,"dup":18,"inherits":131}],207:[function(require,module,exports){ arguments[4][19][0].apply(exports,arguments) },{"../errors":202,"./_stream_duplex":203,"./internal/streams/destroy":210,"./internal/streams/state":214,"./internal/streams/stream":215,"_process":338,"buffer":331,"dup":19,"inherits":131,"util-deprecate":298}],208:[function(require,module,exports){ arguments[4][20][0].apply(exports,arguments) },{"./end-of-stream":211,"_process":338,"dup":20}],209:[function(require,module,exports){ arguments[4][21][0].apply(exports,arguments) },{"buffer":331,"dup":21,"util":330}],210:[function(require,module,exports){ arguments[4][22][0].apply(exports,arguments) },{"_process":338,"dup":22}],211:[function(require,module,exports){ arguments[4][23][0].apply(exports,arguments) },{"../../../errors":202,"dup":23}],212:[function(require,module,exports){ arguments[4][24][0].apply(exports,arguments) },{"dup":24}],213:[function(require,module,exports){ arguments[4][25][0].apply(exports,arguments) },{"../../../errors":202,"./end-of-stream":211,"dup":25}],214:[function(require,module,exports){ arguments[4][26][0].apply(exports,arguments) },{"../../../errors":202,"dup":26}],215:[function(require,module,exports){ arguments[4][27][0].apply(exports,arguments) },{"dup":27,"events":333}],216:[function(require,module,exports){ arguments[4][28][0].apply(exports,arguments) },{"./lib/_stream_duplex.js":203,"./lib/_stream_passthrough.js":204,"./lib/_stream_readable.js":205,"./lib/_stream_transform.js":206,"./lib/_stream_writable.js":207,"./lib/internal/streams/end-of-stream.js":211,"./lib/internal/streams/pipeline.js":213,"dup":28}],217:[function(require,module,exports){ /*! render-media. MIT License. Feross Aboukhadijeh */ exports.render = render exports.append = append exports.mime = require('./lib/mime.json') const debug = require('debug')('render-media') const isAscii = require('is-ascii') const MediaElementWrapper = require('mediasource') const path = require('path') const streamToBlobURL = require('stream-to-blob-url') const VideoStream = require('videostream') // Note: Everything listed in VIDEOSTREAM_EXTS should also appear in either // MEDIASOURCE_VIDEO_EXTS or MEDIASOURCE_AUDIO_EXTS. const VIDEOSTREAM_EXTS = [ '.m4a', '.m4b', '.m4p', '.m4v', '.mp4' ] const MEDIASOURCE_VIDEO_EXTS = [ '.m4v', '.mkv', '.mp4', '.webm' ] const MEDIASOURCE_AUDIO_EXTS = [ '.m4a', '.m4b', '.m4p', '.mp3' ] const MEDIASOURCE_EXTS = [].concat( MEDIASOURCE_VIDEO_EXTS, MEDIASOURCE_AUDIO_EXTS ) const VIDEO_EXTS = [ '.mov', '.ogv' ] const AUDIO_EXTS = [ '.aac', '.oga', '.ogg', '.wav', '.flac' ] const IMAGE_EXTS = [ '.bmp', '.gif', '.jpeg', '.jpg', '.png', '.svg' ] const IFRAME_EXTS = [ '.css', '.html', '.js', '.md', '.pdf', '.srt', '.txt' ] // Maximum file length for which the Blob URL strategy will be attempted // See: https://github.com/feross/render-media/issues/18 const MAX_BLOB_LENGTH = 200 * 1000 * 1000 // 200 MB const MediaSource = typeof window !== 'undefined' && window.MediaSource function render (file, elem, opts, cb) { if (typeof opts === 'function') { cb = opts opts = {} } if (!opts) opts = {} if (!cb) cb = () => {} validateFile(file) parseOpts(opts) if (typeof elem === 'string') elem = document.querySelector(elem) renderMedia(file, tagName => { if (elem.nodeName !== tagName.toUpperCase()) { const extname = path.extname(file.name).toLowerCase() throw new Error( `Cannot render "${extname}" inside a "${elem.nodeName.toLowerCase()}" element, expected "${tagName}"` ) } if (tagName === 'video' || tagName === 'audio') setMediaOpts(elem, opts) return elem }, opts, cb) } function append (file, rootElem, opts, cb) { if (typeof opts === 'function') { cb = opts opts = {} } if (!opts) opts = {} if (!cb) cb = () => {} validateFile(file) parseOpts(opts) if (typeof rootElem === 'string') rootElem = document.querySelector(rootElem) if (rootElem && (rootElem.nodeName === 'VIDEO' || rootElem.nodeName === 'AUDIO')) { throw new Error( 'Invalid video/audio node argument. Argument must be root element that ' + 'video/audio tag will be appended to.' ) } renderMedia(file, getElem, opts, done) function getElem (tagName) { if (tagName === 'video' || tagName === 'audio') return createMedia(tagName) else return createElem(tagName) } function createMedia (tagName) { const elem = createElem(tagName) setMediaOpts(elem, opts) rootElem.appendChild(elem) return elem } function createElem (tagName) { const elem = document.createElement(tagName) rootElem.appendChild(elem) return elem } function done (err, elem) { if (err && elem) elem.remove() cb(err, elem) } } function renderMedia (file, getElem, opts, cb) { const extname = path.extname(file.name).toLowerCase() let currentTime = 0 let elem if (MEDIASOURCE_EXTS.includes(extname)) { renderMediaSource() } else if (VIDEO_EXTS.includes(extname)) { renderMediaElement('video') } else if (AUDIO_EXTS.includes(extname)) { renderMediaElement('audio') } else if (IMAGE_EXTS.includes(extname)) { renderImage() } else if (IFRAME_EXTS.includes(extname)) { renderIframe() } else { tryRenderIframe() } function renderMediaSource () { const tagName = MEDIASOURCE_VIDEO_EXTS.includes(extname) ? 'video' : 'audio' if (MediaSource) { if (VIDEOSTREAM_EXTS.includes(extname)) { useVideostream() } else { useMediaSource() } } else { useBlobURL() } function useVideostream () { debug(`Use \`videostream\` package for ${file.name}`) prepareElem() elem.addEventListener('error', fallbackToMediaSource) elem.addEventListener('loadstart', onLoadStart) elem.addEventListener('loadedmetadata', onLoadedMetadata) new VideoStream(file, elem) /* eslint-disable-line no-new */ } function useMediaSource () { debug(`Use MediaSource API for ${file.name}`) prepareElem() elem.addEventListener('error', fallbackToBlobURL) elem.addEventListener('loadstart', onLoadStart) elem.addEventListener('loadedmetadata', onLoadedMetadata) const wrapper = new MediaElementWrapper(elem) const writable = wrapper.createWriteStream(getCodec(file.name)) file.createReadStream().pipe(writable) if (currentTime) elem.currentTime = currentTime } function useBlobURL () { debug(`Use Blob URL for ${file.name}`) prepareElem() elem.addEventListener('error', fatalError) elem.addEventListener('loadstart', onLoadStart) elem.addEventListener('loadedmetadata', onLoadedMetadata) getBlobURL(file, (err, url) => { if (err) return fatalError(err) elem.src = url if (currentTime) elem.currentTime = currentTime }) } function fallbackToMediaSource (err) { debug('videostream error: fallback to MediaSource API: %o', err.message || err) elem.removeEventListener('error', fallbackToMediaSource) elem.removeEventListener('loadedmetadata', onLoadedMetadata) useMediaSource() } function fallbackToBlobURL (err) { debug('MediaSource API error: fallback to Blob URL: %o', err.message || err) if (!checkBlobLength()) return elem.removeEventListener('error', fallbackToBlobURL) elem.removeEventListener('loadedmetadata', onLoadedMetadata) useBlobURL() } function prepareElem () { if (!elem) { elem = getElem(tagName) elem.addEventListener('progress', () => { currentTime = elem.currentTime }) } } } function checkBlobLength () { if (typeof file.length === 'number' && file.length > opts.maxBlobLength) { debug( 'File length too large for Blob URL approach: %d (max: %d)', file.length, opts.maxBlobLength ) fatalError(new Error( `File length too large for Blob URL approach: ${file.length} (max: ${opts.maxBlobLength})` )) return false } return true } function renderMediaElement (type) { if (!checkBlobLength()) return elem = getElem(type) getBlobURL(file, (err, url) => { if (err) return fatalError(err) elem.addEventListener('error', fatalError) elem.addEventListener('loadstart', onLoadStart) elem.addEventListener('loadedmetadata', onLoadedMetadata) elem.src = url }) } function onLoadStart () { elem.removeEventListener('loadstart', onLoadStart) if (opts.autoplay) { const playPromise = elem.play() if (typeof playPromise !== 'undefined') playPromise.catch(fatalError) } } function onLoadedMetadata () { elem.removeEventListener('loadedmetadata', onLoadedMetadata) cb(null, elem) } function renderImage () { elem = getElem('img') getBlobURL(file, (err, url) => { if (err) return fatalError(err) elem.src = url elem.alt = file.name cb(null, elem) }) } function renderIframe () { getBlobURL(file, (err, url) => { if (err) return fatalError(err) if (extname !== '.pdf') { // Render iframe elem = getElem('iframe') elem.sandbox = 'allow-forms allow-scripts' elem.src = url } else { // Render .pdf elem = getElem('object') // Firefox-only: `typemustmatch` keeps the embedded file from running unless // its content type matches the specified `type` attribute elem.setAttribute('typemustmatch', true) elem.setAttribute('type', 'application/pdf') elem.setAttribute('data', url) } cb(null, elem) }) } function tryRenderIframe () { debug('Unknown file extension "%s" - will attempt to render into iframe', extname) let str = '' file.createReadStream({ start: 0, end: 1000 }) .setEncoding('utf8') .on('data', chunk => { str += chunk }) .on('end', done) .on('error', cb) function done () { if (isAscii(str)) { debug('File extension "%s" appears ascii, so will render.', extname) renderIframe() } else { debug('File extension "%s" appears non-ascii, will not render.', extname) cb(new Error(`Unsupported file type "${extname}": Cannot append to DOM`)) } } } function fatalError (err) { err.message = `Error rendering file "${file.name}": ${err.message}` debug(err.message) cb(err) } } function getBlobURL (file, cb) { const extname = path.extname(file.name).toLowerCase() streamToBlobURL(file.createReadStream(), exports.mime[extname]) .then( blobUrl => cb(null, blobUrl), err => cb(err) ) } function validateFile (file) { if (file == null) { throw new Error('file cannot be null or undefined') } if (typeof file.name !== 'string') { throw new Error('missing or invalid file.name property') } if (typeof file.createReadStream !== 'function') { throw new Error('missing or invalid file.createReadStream property') } } function getCodec (name) { const extname = path.extname(name).toLowerCase() return { '.m4a': 'audio/mp4; codecs="mp4a.40.5"', '.m4b': 'audio/mp4; codecs="mp4a.40.5"', '.m4p': 'audio/mp4; codecs="mp4a.40.5"', '.m4v': 'video/mp4; codecs="avc1.640029, mp4a.40.5"', '.mkv': 'video/webm; codecs="avc1.640029, mp4a.40.5"', '.mp3': 'audio/mpeg', '.mp4': 'video/mp4; codecs="avc1.640029, mp4a.40.5"', '.webm': 'video/webm; codecs="vorbis, vp8"' }[extname] } function parseOpts (opts) { if (opts.autoplay == null) opts.autoplay = false if (opts.muted == null) opts.muted = false if (opts.controls == null) opts.controls = true if (opts.maxBlobLength == null) opts.maxBlobLength = MAX_BLOB_LENGTH } function setMediaOpts (elem, opts) { elem.autoplay = !!opts.autoplay elem.muted = !!opts.muted elem.controls = !!opts.controls } },{"./lib/mime.json":218,"debug":219,"is-ascii":132,"mediasource":138,"path":337,"stream-to-blob-url":278,"videostream":300}],218:[function(require,module,exports){ module.exports={ ".3gp": "video/3gpp", ".aac": "audio/aac", ".aif": "audio/x-aiff", ".aiff": "audio/x-aiff", ".atom": "application/atom+xml", ".avi": "video/x-msvideo", ".bmp": "image/bmp", ".bz2": "application/x-bzip2", ".conf": "text/plain", ".css": "text/css", ".csv": "text/plain", ".diff": "text/x-diff", ".doc": "application/msword", ".flv": "video/x-flv", ".gif": "image/gif", ".gz": "application/x-gzip", ".htm": "text/html", ".html": "text/html", ".ico": "image/vnd.microsoft.icon", ".ics": "text/calendar", ".iso": "application/octet-stream", ".jar": "application/java-archive", ".jpeg": "image/jpeg", ".jpg": "image/jpeg", ".js": "application/javascript", ".json": "application/json", ".less": "text/css", ".log": "text/plain", ".m3u": "audio/x-mpegurl", ".m4a": "audio/x-m4a", ".m4b": "audio/mp4", ".m4p": "audio/mp4", ".m4v": "video/x-m4v", ".manifest": "text/cache-manifest", ".markdown": "text/x-markdown", ".mathml": "application/mathml+xml", ".md": "text/x-markdown", ".mid": "audio/midi", ".midi": "audio/midi", ".mov": "video/quicktime", ".mp3": "audio/mpeg", ".mp4": "video/mp4", ".mp4v": "video/mp4", ".mpeg": "video/mpeg", ".mpg": "video/mpeg", ".odp": "application/vnd.oasis.opendocument.presentation", ".ods": "application/vnd.oasis.opendocument.spreadsheet", ".odt": "application/vnd.oasis.opendocument.text", ".oga": "audio/ogg", ".ogg": "application/ogg", ".pdf": "application/pdf", ".png": "image/png", ".pps": "application/vnd.ms-powerpoint", ".ppt": "application/vnd.ms-powerpoint", ".ps": "application/postscript", ".psd": "image/vnd.adobe.photoshop", ".qt": "video/quicktime", ".rar": "application/x-rar-compressed", ".rdf": "application/rdf+xml", ".rss": "application/rss+xml", ".rtf": "application/rtf", ".svg": "image/svg+xml", ".svgz": "image/svg+xml", ".swf": "application/x-shockwave-flash", ".tar": "application/x-tar", ".tbz": "application/x-bzip-compressed-tar", ".text": "text/plain", ".tif": "image/tiff", ".tiff": "image/tiff", ".torrent": "application/x-bittorrent", ".ttf": "application/x-font-ttf", ".txt": "text/plain", ".wav": "audio/wav", ".webm": "video/webm", ".wma": "audio/x-ms-wma", ".wmv": "video/x-ms-wmv", ".xls": "application/vnd.ms-excel", ".xml": "application/xml", ".yaml": "text/yaml", ".yml": "text/yaml", ".zip": "application/zip" } },{}],219:[function(require,module,exports){ arguments[4][11][0].apply(exports,arguments) },{"./common":220,"_process":338,"dup":11}],220:[function(require,module,exports){ arguments[4][12][0].apply(exports,arguments) },{"dup":12,"ms":221}],221:[function(require,module,exports){ arguments[4][13][0].apply(exports,arguments) },{"dup":13}],222:[function(require,module,exports){ 'use strict' var Buffer = require('buffer').Buffer var inherits = require('inherits') var HashBase = require('hash-base') var ARRAY16 = new Array(16) var zl = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8, 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12, 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2, 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13 ] var zr = [ 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12, 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2, 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13, 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14, 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11 ] var sl = [ 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8, 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12, 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5, 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12, 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6 ] var sr = [ 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6, 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11, 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5, 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8, 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11 ] var hl = [0x00000000, 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xa953fd4e] var hr = [0x50a28be6, 0x5c4dd124, 0x6d703ef3, 0x7a6d76e9, 0x00000000] function RIPEMD160 () { HashBase.call(this, 64) // state this._a = 0x67452301 this._b = 0xefcdab89 this._c = 0x98badcfe this._d = 0x10325476 this._e = 0xc3d2e1f0 } inherits(RIPEMD160, HashBase) RIPEMD160.prototype._update = function () { var words = ARRAY16 for (var j = 0; j < 16; ++j) words[j] = this._block.readInt32LE(j * 4) var al = this._a | 0 var bl = this._b | 0 var cl = this._c | 0 var dl = this._d | 0 var el = this._e | 0 var ar = this._a | 0 var br = this._b | 0 var cr = this._c | 0 var dr = this._d | 0 var er = this._e | 0 // computation for (var i = 0; i < 80; i += 1) { var tl var tr if (i < 16) { tl = fn1(al, bl, cl, dl, el, words[zl[i]], hl[0], sl[i]) tr = fn5(ar, br, cr, dr, er, words[zr[i]], hr[0], sr[i]) } else if (i < 32) { tl = fn2(al, bl, cl, dl, el, words[zl[i]], hl[1], sl[i]) tr = fn4(ar, br, cr, dr, er, words[zr[i]], hr[1], sr[i]) } else if (i < 48) { tl = fn3(al, bl, cl, dl, el, words[zl[i]], hl[2], sl[i]) tr = fn3(ar, br, cr, dr, er, words[zr[i]], hr[2], sr[i]) } else if (i < 64) { tl = fn4(al, bl, cl, dl, el, words[zl[i]], hl[3], sl[i]) tr = fn2(ar, br, cr, dr, er, words[zr[i]], hr[3], sr[i]) } else { // if (i<80) { tl = fn5(al, bl, cl, dl, el, words[zl[i]], hl[4], sl[i]) tr = fn1(ar, br, cr, dr, er, words[zr[i]], hr[4], sr[i]) } al = el el = dl dl = rotl(cl, 10) cl = bl bl = tl ar = er er = dr dr = rotl(cr, 10) cr = br br = tr } // update state var t = (this._b + cl + dr) | 0 this._b = (this._c + dl + er) | 0 this._c = (this._d + el + ar) | 0 this._d = (this._e + al + br) | 0 this._e = (this._a + bl + cr) | 0 this._a = t } RIPEMD160.prototype._digest = function () { // create padding and handle blocks this._block[this._blockOffset++] = 0x80 if (this._blockOffset > 56) { this._block.fill(0, this._blockOffset, 64) this._update() this._blockOffset = 0 } this._block.fill(0, this._blockOffset, 56) this._block.writeUInt32LE(this._length[0], 56) this._block.writeUInt32LE(this._length[1], 60) this._update() // produce result var buffer = Buffer.alloc ? Buffer.alloc(20) : new Buffer(20) buffer.writeInt32LE(this._a, 0) buffer.writeInt32LE(this._b, 4) buffer.writeInt32LE(this._c, 8) buffer.writeInt32LE(this._d, 12) buffer.writeInt32LE(this._e, 16) return buffer } function rotl (x, n) { return (x << n) | (x >>> (32 - n)) } function fn1 (a, b, c, d, e, m, k, s) { return (rotl((a + (b ^ c ^ d) + m + k) | 0, s) + e) | 0 } function fn2 (a, b, c, d, e, m, k, s) { return (rotl((a + ((b & c) | ((~b) & d)) + m + k) | 0, s) + e) | 0 } function fn3 (a, b, c, d, e, m, k, s) { return (rotl((a + ((b | (~c)) ^ d) + m + k) | 0, s) + e) | 0 } function fn4 (a, b, c, d, e, m, k, s) { return (rotl((a + ((b & d) | (c & (~d))) + m + k) | 0, s) + e) | 0 } function fn5 (a, b, c, d, e, m, k, s) { return (rotl((a + (b ^ (c | (~d))) + m + k) | 0, s) + e) | 0 } module.exports = RIPEMD160 },{"buffer":331,"hash-base":114,"inherits":131}],223:[function(require,module,exports){ (function (process){(function (){ /*! run-parallel-limit. MIT License. Feross Aboukhadijeh */ module.exports = runParallelLimit function runParallelLimit (tasks, limit, cb) { if (typeof limit !== 'number') throw new Error('second argument must be a Number') var results, len, pending, keys, isErrored var isSync = true if (Array.isArray(tasks)) { results = [] pending = len = tasks.length } else { keys = Object.keys(tasks) results = {} pending = len = keys.length } function done (err) { function end () { if (cb) cb(err, results) cb = null } if (isSync) process.nextTick(end) else end() } function each (i, err, result) { results[i] = result if (err) isErrored = true if (--pending === 0 || err) { done(err) } else if (!isErrored && next < len) { var key if (keys) { key = keys[next] next += 1 tasks[key](function (err, result) { each(key, err, result) }) } else { key = next next += 1 tasks[key](function (err, result) { each(key, err, result) }) } } } var next = limit if (!pending) { // empty done(null) } else if (keys) { // object keys.some(function (key, i) { tasks[key](function (err, result) { each(key, err, result) }) if (i === limit - 1) return true // early return }) } else { // array tasks.some(function (task, i) { task(function (err, result) { each(i, err, result) }) if (i === limit - 1) return true // early return }) } isSync = false } }).call(this)}).call(this,require('_process')) },{"_process":338}],224:[function(require,module,exports){ (function (process){(function (){ /*! run-parallel. MIT License. Feross Aboukhadijeh */ module.exports = runParallel function runParallel (tasks, cb) { var results, pending, keys var isSync = true if (Array.isArray(tasks)) { results = [] pending = tasks.length } else { keys = Object.keys(tasks) results = {} pending = keys.length } function done (err) { function end () { if (cb) cb(err, results) cb = null } if (isSync) process.nextTick(end) else end() } function each (i, err, result) { results[i] = result if (--pending === 0 || err) { done(err) } } if (!pending) { // empty done(null) } else if (keys) { // object keys.forEach(function (key) { tasks[key](function (err, result) { each(key, err, result) }) }) } else { // array tasks.forEach(function (task, i) { task(function (err, result) { each(i, err, result) }) }) } isSync = false } }).call(this)}).call(this,require('_process')) },{"_process":338}],225:[function(require,module,exports){ (function webpackUniversalModuleDefinition(root, factory) { if(typeof exports === 'object' && typeof module === 'object') module.exports = factory(); else if(typeof define === 'function' && define.amd) define([], factory); else if(typeof exports === 'object') exports["Rusha"] = factory(); else root["Rusha"] = factory(); })(typeof self !== 'undefined' ? self : this, function() { return /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) { /******/ return installedModules[moduleId].exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ i: moduleId, /******/ l: false, /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ /******/ // Flag the module as loaded /******/ module.l = true; /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /******/ /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ /******/ // define getter function for harmony exports /******/ __webpack_require__.d = function(exports, name, getter) { /******/ if(!__webpack_require__.o(exports, name)) { /******/ Object.defineProperty(exports, name, { /******/ configurable: false, /******/ enumerable: true, /******/ get: getter /******/ }); /******/ } /******/ }; /******/ /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = function(module) { /******/ var getter = module && module.__esModule ? /******/ function getDefault() { return module['default']; } : /******/ function getModuleExports() { return module; }; /******/ __webpack_require__.d(getter, 'a', getter); /******/ return getter; /******/ }; /******/ /******/ // Object.prototype.hasOwnProperty.call /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; /******/ /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; /******/ /******/ // Load entry module and return exports /******/ return __webpack_require__(__webpack_require__.s = 3); /******/ }) /************************************************************************/ /******/ ([ /* 0 */ /***/ (function(module, exports, __webpack_require__) { function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /* eslint-env commonjs, browser */ var RushaCore = __webpack_require__(5); var _require = __webpack_require__(1), toHex = _require.toHex, ceilHeapSize = _require.ceilHeapSize; var conv = __webpack_require__(6); // Calculate the length of buffer that the sha1 routine uses // including the padding. var padlen = function (len) { for (len += 9; len % 64 > 0; len += 1) {} return len; }; var padZeroes = function (bin, len) { var h8 = new Uint8Array(bin.buffer); var om = len % 4, align = len - om; switch (om) { case 0: h8[align + 3] = 0; case 1: h8[align + 2] = 0; case 2: h8[align + 1] = 0; case 3: h8[align + 0] = 0; } for (var i = (len >> 2) + 1; i < bin.length; i++) { bin[i] = 0; } }; var padData = function (bin, chunkLen, msgLen) { bin[chunkLen >> 2] |= 0x80 << 24 - (chunkLen % 4 << 3); // To support msgLen >= 2 GiB, use a float division when computing the // high 32-bits of the big-endian message length in bits. bin[((chunkLen >> 2) + 2 & ~0x0f) + 14] = msgLen / (1 << 29) | 0; bin[((chunkLen >> 2) + 2 & ~0x0f) + 15] = msgLen << 3; }; var getRawDigest = function (heap, padMaxChunkLen) { var io = new Int32Array(heap, padMaxChunkLen + 320, 5); var out = new Int32Array(5); var arr = new DataView(out.buffer); arr.setInt32(0, io[0], false); arr.setInt32(4, io[1], false); arr.setInt32(8, io[2], false); arr.setInt32(12, io[3], false); arr.setInt32(16, io[4], false); return out; }; var Rusha = function () { function Rusha(chunkSize) { _classCallCheck(this, Rusha); chunkSize = chunkSize || 64 * 1024; if (chunkSize % 64 > 0) { throw new Error('Chunk size must be a multiple of 128 bit'); } this._offset = 0; this._maxChunkLen = chunkSize; this._padMaxChunkLen = padlen(chunkSize); // The size of the heap is the sum of: // 1. The padded input message size // 2. The extended space the algorithm needs (320 byte) // 3. The 160 bit state the algoritm uses this._heap = new ArrayBuffer(ceilHeapSize(this._padMaxChunkLen + 320 + 20)); this._h32 = new Int32Array(this._heap); this._h8 = new Int8Array(this._heap); this._core = new RushaCore({ Int32Array: Int32Array }, {}, this._heap); } Rusha.prototype._initState = function _initState(heap, padMsgLen) { this._offset = 0; var io = new Int32Array(heap, padMsgLen + 320, 5); io[0] = 1732584193; io[1] = -271733879; io[2] = -1732584194; io[3] = 271733878; io[4] = -1009589776; }; Rusha.prototype._padChunk = function _padChunk(chunkLen, msgLen) { var padChunkLen = padlen(chunkLen); var view = new Int32Array(this._heap, 0, padChunkLen >> 2); padZeroes(view, chunkLen); padData(view, chunkLen, msgLen); return padChunkLen; }; Rusha.prototype._write = function _write(data, chunkOffset, chunkLen, off) { conv(data, this._h8, this._h32, chunkOffset, chunkLen, off || 0); }; Rusha.prototype._coreCall = function _coreCall(data, chunkOffset, chunkLen, msgLen, finalize) { var padChunkLen = chunkLen; this._write(data, chunkOffset, chunkLen); if (finalize) { padChunkLen = this._padChunk(chunkLen, msgLen); } this._core.hash(padChunkLen, this._padMaxChunkLen); }; Rusha.prototype.rawDigest = function rawDigest(str) { var msgLen = str.byteLength || str.length || str.size || 0; this._initState(this._heap, this._padMaxChunkLen); var chunkOffset = 0, chunkLen = this._maxChunkLen; for (chunkOffset = 0; msgLen > chunkOffset + chunkLen; chunkOffset += chunkLen) { this._coreCall(str, chunkOffset, chunkLen, msgLen, false); } this._coreCall(str, chunkOffset, msgLen - chunkOffset, msgLen, true); return getRawDigest(this._heap, this._padMaxChunkLen); }; Rusha.prototype.digest = function digest(str) { return toHex(this.rawDigest(str).buffer); }; Rusha.prototype.digestFromString = function digestFromString(str) { return this.digest(str); }; Rusha.prototype.digestFromBuffer = function digestFromBuffer(str) { return this.digest(str); }; Rusha.prototype.digestFromArrayBuffer = function digestFromArrayBuffer(str) { return this.digest(str); }; Rusha.prototype.resetState = function resetState() { this._initState(this._heap, this._padMaxChunkLen); return this; }; Rusha.prototype.append = function append(chunk) { var chunkOffset = 0; var chunkLen = chunk.byteLength || chunk.length || chunk.size || 0; var turnOffset = this._offset % this._maxChunkLen; var inputLen = void 0; this._offset += chunkLen; while (chunkOffset < chunkLen) { inputLen = Math.min(chunkLen - chunkOffset, this._maxChunkLen - turnOffset); this._write(chunk, chunkOffset, inputLen, turnOffset); turnOffset += inputLen; chunkOffset += inputLen; if (turnOffset === this._maxChunkLen) { this._core.hash(this._maxChunkLen, this._padMaxChunkLen); turnOffset = 0; } } return this; }; Rusha.prototype.getState = function getState() { var turnOffset = this._offset % this._maxChunkLen; var heap = void 0; if (!turnOffset) { var io = new Int32Array(this._heap, this._padMaxChunkLen + 320, 5); heap = io.buffer.slice(io.byteOffset, io.byteOffset + io.byteLength); } else { heap = this._heap.slice(0); } return { offset: this._offset, heap: heap }; }; Rusha.prototype.setState = function setState(state) { this._offset = state.offset; if (state.heap.byteLength === 20) { var io = new Int32Array(this._heap, this._padMaxChunkLen + 320, 5); io.set(new Int32Array(state.heap)); } else { this._h32.set(new Int32Array(state.heap)); } return this; }; Rusha.prototype.rawEnd = function rawEnd() { var msgLen = this._offset; var chunkLen = msgLen % this._maxChunkLen; var padChunkLen = this._padChunk(chunkLen, msgLen); this._core.hash(padChunkLen, this._padMaxChunkLen); var result = getRawDigest(this._heap, this._padMaxChunkLen); this._initState(this._heap, this._padMaxChunkLen); return result; }; Rusha.prototype.end = function end() { return toHex(this.rawEnd().buffer); }; return Rusha; }(); module.exports = Rusha; module.exports._core = RushaCore; /***/ }), /* 1 */ /***/ (function(module, exports) { /* eslint-env commonjs, browser */ // // toHex // var precomputedHex = new Array(256); for (var i = 0; i < 256; i++) { precomputedHex[i] = (i < 0x10 ? '0' : '') + i.toString(16); } module.exports.toHex = function (arrayBuffer) { var binarray = new Uint8Array(arrayBuffer); var res = new Array(arrayBuffer.byteLength); for (var _i = 0; _i < res.length; _i++) { res[_i] = precomputedHex[binarray[_i]]; } return res.join(''); }; // // ceilHeapSize // module.exports.ceilHeapSize = function (v) { // The asm.js spec says: // The heap object's byteLength must be either // 2^n for n in [12, 24) or 2^24 * n for n ≥ 1. // Also, byteLengths smaller than 2^16 are deprecated. var p = 0; // If v is smaller than 2^16, the smallest possible solution // is 2^16. if (v <= 65536) return 65536; // If v < 2^24, we round up to 2^n, // otherwise we round up to 2^24 * n. if (v < 16777216) { for (p = 1; p < v; p = p << 1) {} } else { for (p = 16777216; p < v; p += 16777216) {} } return p; }; // // isDedicatedWorkerScope // module.exports.isDedicatedWorkerScope = function (self) { var isRunningInWorker = 'WorkerGlobalScope' in self && self instanceof self.WorkerGlobalScope; var isRunningInSharedWorker = 'SharedWorkerGlobalScope' in self && self instanceof self.SharedWorkerGlobalScope; var isRunningInServiceWorker = 'ServiceWorkerGlobalScope' in self && self instanceof self.ServiceWorkerGlobalScope; // Detects whether we run inside a dedicated worker or not. // // We can't just check for `DedicatedWorkerGlobalScope`, since IE11 // has a bug where it only supports `WorkerGlobalScope`. // // Therefore, we consider us as running inside a dedicated worker // when we are running inside a worker, but not in a shared or service worker. // // When new types of workers are introduced, we will need to adjust this code. return isRunningInWorker && !isRunningInSharedWorker && !isRunningInServiceWorker; }; /***/ }), /* 2 */ /***/ (function(module, exports, __webpack_require__) { /* eslint-env commonjs, worker */ module.exports = function () { var Rusha = __webpack_require__(0); var hashData = function (hasher, data, cb) { try { return cb(null, hasher.digest(data)); } catch (e) { return cb(e); } }; var hashFile = function (hasher, readTotal, blockSize, file, cb) { var reader = new self.FileReader(); reader.onloadend = function onloadend() { if (reader.error) { return cb(reader.error); } var buffer = reader.result; readTotal += reader.result.byteLength; try { hasher.append(buffer); } catch (e) { cb(e); return; } if (readTotal < file.size) { hashFile(hasher, readTotal, blockSize, file, cb); } else { cb(null, hasher.end()); } }; reader.readAsArrayBuffer(file.slice(readTotal, readTotal + blockSize)); }; var workerBehaviourEnabled = true; self.onmessage = function (event) { if (!workerBehaviourEnabled) { return; } var data = event.data.data, file = event.data.file, id = event.data.id; if (typeof id === 'undefined') return; if (!file && !data) return; var blockSize = event.data.blockSize || 4 * 1024 * 1024; var hasher = new Rusha(blockSize); hasher.resetState(); var done = function (err, hash) { if (!err) { self.postMessage({ id: id, hash: hash }); } else { self.postMessage({ id: id, error: err.name }); } }; if (data) hashData(hasher, data, done); if (file) hashFile(hasher, 0, blockSize, file, done); }; return function () { workerBehaviourEnabled = false; }; }; /***/ }), /* 3 */ /***/ (function(module, exports, __webpack_require__) { /* eslint-env commonjs, browser */ var work = __webpack_require__(4); var Rusha = __webpack_require__(0); var createHash = __webpack_require__(7); var runWorker = __webpack_require__(2); var _require = __webpack_require__(1), isDedicatedWorkerScope = _require.isDedicatedWorkerScope; var isRunningInDedicatedWorker = typeof self !== 'undefined' && isDedicatedWorkerScope(self); Rusha.disableWorkerBehaviour = isRunningInDedicatedWorker ? runWorker() : function () {}; Rusha.createWorker = function () { var worker = work(/*require.resolve*/(2)); var terminate = worker.terminate; worker.terminate = function () { URL.revokeObjectURL(worker.objectURL); terminate.call(worker); }; return worker; }; Rusha.createHash = createHash; module.exports = Rusha; /***/ }), /* 4 */ /***/ (function(module, exports, __webpack_require__) { function webpackBootstrapFunc (modules) { /******/ // The module cache /******/ var installedModules = {}; /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) /******/ return installedModules[moduleId].exports; /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ i: moduleId, /******/ l: false, /******/ exports: {} /******/ }; /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ // Flag the module as loaded /******/ module.l = true; /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ // identity function for calling harmony imports with the correct context /******/ __webpack_require__.i = function(value) { return value; }; /******/ // define getter function for harmony exports /******/ __webpack_require__.d = function(exports, name, getter) { /******/ if(!__webpack_require__.o(exports, name)) { /******/ Object.defineProperty(exports, name, { /******/ configurable: false, /******/ enumerable: true, /******/ get: getter /******/ }); /******/ } /******/ }; /******/ // define __esModule on exports /******/ __webpack_require__.r = function(exports) { /******/ Object.defineProperty(exports, '__esModule', { value: true }); /******/ }; /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = function(module) { /******/ var getter = module && module.__esModule ? /******/ function getDefault() { return module['default']; } : /******/ function getModuleExports() { return module; }; /******/ __webpack_require__.d(getter, 'a', getter); /******/ return getter; /******/ }; /******/ // Object.prototype.hasOwnProperty.call /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; /******/ // __webpack_public_path__ /******/ __webpack_require__.p = "/"; /******/ // on error function for async loading /******/ __webpack_require__.oe = function(err) { console.error(err); throw err; }; var f = __webpack_require__(__webpack_require__.s = ENTRY_MODULE) return f.default || f // try to call default if defined to also support babel esmodule exports } var moduleNameReqExp = '[\\.|\\-|\\+|\\w|\/|@]+' var dependencyRegExp = '\\((\/\\*.*?\\*\/)?\s?.*?(' + moduleNameReqExp + ').*?\\)' // additional chars when output.pathinfo is true // http://stackoverflow.com/a/2593661/130442 function quoteRegExp (str) { return (str + '').replace(/[.?*+^$[\]\\(){}|-]/g, '\\$&') } function getModuleDependencies (sources, module, queueName) { var retval = {} retval[queueName] = [] var fnString = module.toString() var wrapperSignature = fnString.match(/^function\s?\(\w+,\s*\w+,\s*(\w+)\)/) if (!wrapperSignature) return retval var webpackRequireName = wrapperSignature[1] // main bundle deps var re = new RegExp('(\\\\n|\\W)' + quoteRegExp(webpackRequireName) + dependencyRegExp, 'g') var match while ((match = re.exec(fnString))) { if (match[3] === 'dll-reference') continue retval[queueName].push(match[3]) } // dll deps re = new RegExp('\\(' + quoteRegExp(webpackRequireName) + '\\("(dll-reference\\s(' + moduleNameReqExp + '))"\\)\\)' + dependencyRegExp, 'g') while ((match = re.exec(fnString))) { if (!sources[match[2]]) { retval[queueName].push(match[1]) sources[match[2]] = __webpack_require__(match[1]).m } retval[match[2]] = retval[match[2]] || [] retval[match[2]].push(match[4]) } return retval } function hasValuesInQueues (queues) { var keys = Object.keys(queues) return keys.reduce(function (hasValues, key) { return hasValues || queues[key].length > 0 }, false) } function getRequiredModules (sources, moduleId) { var modulesQueue = { main: [moduleId] } var requiredModules = { main: [] } var seenModules = { main: {} } while (hasValuesInQueues(modulesQueue)) { var queues = Object.keys(modulesQueue) for (var i = 0; i < queues.length; i++) { var queueName = queues[i] var queue = modulesQueue[queueName] var moduleToCheck = queue.pop() seenModules[queueName] = seenModules[queueName] || {} if (seenModules[queueName][moduleToCheck] || !sources[queueName][moduleToCheck]) continue seenModules[queueName][moduleToCheck] = true requiredModules[queueName] = requiredModules[queueName] || [] requiredModules[queueName].push(moduleToCheck) var newModules = getModuleDependencies(sources, sources[queueName][moduleToCheck], queueName) var newModulesKeys = Object.keys(newModules) for (var j = 0; j < newModulesKeys.length; j++) { modulesQueue[newModulesKeys[j]] = modulesQueue[newModulesKeys[j]] || [] modulesQueue[newModulesKeys[j]] = modulesQueue[newModulesKeys[j]].concat(newModules[newModulesKeys[j]]) } } } return requiredModules } module.exports = function (moduleId, options) { options = options || {} var sources = { main: __webpack_require__.m } var requiredModules = options.all ? { main: Object.keys(sources) } : getRequiredModules(sources, moduleId) var src = '' Object.keys(requiredModules).filter(function (m) { return m !== 'main' }).forEach(function (module) { var entryModule = 0 while (requiredModules[module][entryModule]) { entryModule++ } requiredModules[module].push(entryModule) sources[module][entryModule] = '(function(module, exports, __webpack_require__) { module.exports = __webpack_require__; })' src = src + 'var ' + module + ' = (' + webpackBootstrapFunc.toString().replace('ENTRY_MODULE', JSON.stringify(entryModule)) + ')({' + requiredModules[module].map(function (id) { return '' + JSON.stringify(id) + ': ' + sources[module][id].toString() }).join(',') + '});\n' }) src = src + '(' + webpackBootstrapFunc.toString().replace('ENTRY_MODULE', JSON.stringify(moduleId)) + ')({' + requiredModules.main.map(function (id) { return '' + JSON.stringify(id) + ': ' + sources.main[id].toString() }).join(',') + '})(self);' var blob = new window.Blob([src], { type: 'text/javascript' }) if (options.bare) { return blob } var URL = window.URL || window.webkitURL || window.mozURL || window.msURL var workerUrl = URL.createObjectURL(blob) var worker = new window.Worker(workerUrl) worker.objectURL = workerUrl return worker } /***/ }), /* 5 */ /***/ (function(module, exports) { // The low-level RushCore module provides the heart of Rusha, // a high-speed sha1 implementation working on an Int32Array heap. // At first glance, the implementation seems complicated, however // with the SHA1 spec at hand, it is obvious this almost a textbook // implementation that has a few functions hand-inlined and a few loops // hand-unrolled. module.exports = function RushaCore(stdlib$846, foreign$847, heap$848) { 'use asm'; var H$849 = new stdlib$846.Int32Array(heap$848); function hash$850(k$851, x$852) { // k in bytes k$851 = k$851 | 0; x$852 = x$852 | 0; var i$853 = 0, j$854 = 0, y0$855 = 0, z0$856 = 0, y1$857 = 0, z1$858 = 0, y2$859 = 0, z2$860 = 0, y3$861 = 0, z3$862 = 0, y4$863 = 0, z4$864 = 0, t0$865 = 0, t1$866 = 0; y0$855 = H$849[x$852 + 320 >> 2] | 0; y1$857 = H$849[x$852 + 324 >> 2] | 0; y2$859 = H$849[x$852 + 328 >> 2] | 0; y3$861 = H$849[x$852 + 332 >> 2] | 0; y4$863 = H$849[x$852 + 336 >> 2] | 0; for (i$853 = 0; (i$853 | 0) < (k$851 | 0); i$853 = i$853 + 64 | 0) { z0$856 = y0$855; z1$858 = y1$857; z2$860 = y2$859; z3$862 = y3$861; z4$864 = y4$863; for (j$854 = 0; (j$854 | 0) < 64; j$854 = j$854 + 4 | 0) { t1$866 = H$849[i$853 + j$854 >> 2] | 0; t0$865 = ((y0$855 << 5 | y0$855 >>> 27) + (y1$857 & y2$859 | ~y1$857 & y3$861) | 0) + ((t1$866 + y4$863 | 0) + 1518500249 | 0) | 0; y4$863 = y3$861; y3$861 = y2$859; y2$859 = y1$857 << 30 | y1$857 >>> 2; y1$857 = y0$855; y0$855 = t0$865; H$849[k$851 + j$854 >> 2] = t1$866; } for (j$854 = k$851 + 64 | 0; (j$854 | 0) < (k$851 + 80 | 0); j$854 = j$854 + 4 | 0) { t1$866 = (H$849[j$854 - 12 >> 2] ^ H$849[j$854 - 32 >> 2] ^ H$849[j$854 - 56 >> 2] ^ H$849[j$854 - 64 >> 2]) << 1 | (H$849[j$854 - 12 >> 2] ^ H$849[j$854 - 32 >> 2] ^ H$849[j$854 - 56 >> 2] ^ H$849[j$854 - 64 >> 2]) >>> 31; t0$865 = ((y0$855 << 5 | y0$855 >>> 27) + (y1$857 & y2$859 | ~y1$857 & y3$861) | 0) + ((t1$866 + y4$863 | 0) + 1518500249 | 0) | 0; y4$863 = y3$861; y3$861 = y2$859; y2$859 = y1$857 << 30 | y1$857 >>> 2; y1$857 = y0$855; y0$855 = t0$865; H$849[j$854 >> 2] = t1$866; } for (j$854 = k$851 + 80 | 0; (j$854 | 0) < (k$851 + 160 | 0); j$854 = j$854 + 4 | 0) { t1$866 = (H$849[j$854 - 12 >> 2] ^ H$849[j$854 - 32 >> 2] ^ H$849[j$854 - 56 >> 2] ^ H$849[j$854 - 64 >> 2]) << 1 | (H$849[j$854 - 12 >> 2] ^ H$849[j$854 - 32 >> 2] ^ H$849[j$854 - 56 >> 2] ^ H$849[j$854 - 64 >> 2]) >>> 31; t0$865 = ((y0$855 << 5 | y0$855 >>> 27) + (y1$857 ^ y2$859 ^ y3$861) | 0) + ((t1$866 + y4$863 | 0) + 1859775393 | 0) | 0; y4$863 = y3$861; y3$861 = y2$859; y2$859 = y1$857 << 30 | y1$857 >>> 2; y1$857 = y0$855; y0$855 = t0$865; H$849[j$854 >> 2] = t1$866; } for (j$854 = k$851 + 160 | 0; (j$854 | 0) < (k$851 + 240 | 0); j$854 = j$854 + 4 | 0) { t1$866 = (H$849[j$854 - 12 >> 2] ^ H$849[j$854 - 32 >> 2] ^ H$849[j$854 - 56 >> 2] ^ H$849[j$854 - 64 >> 2]) << 1 | (H$849[j$854 - 12 >> 2] ^ H$849[j$854 - 32 >> 2] ^ H$849[j$854 - 56 >> 2] ^ H$849[j$854 - 64 >> 2]) >>> 31; t0$865 = ((y0$855 << 5 | y0$855 >>> 27) + (y1$857 & y2$859 | y1$857 & y3$861 | y2$859 & y3$861) | 0) + ((t1$866 + y4$863 | 0) - 1894007588 | 0) | 0; y4$863 = y3$861; y3$861 = y2$859; y2$859 = y1$857 << 30 | y1$857 >>> 2; y1$857 = y0$855; y0$855 = t0$865; H$849[j$854 >> 2] = t1$866; } for (j$854 = k$851 + 240 | 0; (j$854 | 0) < (k$851 + 320 | 0); j$854 = j$854 + 4 | 0) { t1$866 = (H$849[j$854 - 12 >> 2] ^ H$849[j$854 - 32 >> 2] ^ H$849[j$854 - 56 >> 2] ^ H$849[j$854 - 64 >> 2]) << 1 | (H$849[j$854 - 12 >> 2] ^ H$849[j$854 - 32 >> 2] ^ H$849[j$854 - 56 >> 2] ^ H$849[j$854 - 64 >> 2]) >>> 31; t0$865 = ((y0$855 << 5 | y0$855 >>> 27) + (y1$857 ^ y2$859 ^ y3$861) | 0) + ((t1$866 + y4$863 | 0) - 899497514 | 0) | 0; y4$863 = y3$861; y3$861 = y2$859; y2$859 = y1$857 << 30 | y1$857 >>> 2; y1$857 = y0$855; y0$855 = t0$865; H$849[j$854 >> 2] = t1$866; } y0$855 = y0$855 + z0$856 | 0; y1$857 = y1$857 + z1$858 | 0; y2$859 = y2$859 + z2$860 | 0; y3$861 = y3$861 + z3$862 | 0; y4$863 = y4$863 + z4$864 | 0; } H$849[x$852 + 320 >> 2] = y0$855; H$849[x$852 + 324 >> 2] = y1$857; H$849[x$852 + 328 >> 2] = y2$859; H$849[x$852 + 332 >> 2] = y3$861; H$849[x$852 + 336 >> 2] = y4$863; } return { hash: hash$850 }; }; /***/ }), /* 6 */ /***/ (function(module, exports) { var _this = this; /* eslint-env commonjs, browser */ var reader = void 0; if (typeof self !== 'undefined' && typeof self.FileReaderSync !== 'undefined') { reader = new self.FileReaderSync(); } // Convert a binary string and write it to the heap. // A binary string is expected to only contain char codes < 256. var convStr = function (str, H8, H32, start, len, off) { var i = void 0, om = off % 4, lm = (len + om) % 4, j = len - lm; switch (om) { case 0: H8[off] = str.charCodeAt(start + 3); case 1: H8[off + 1 - (om << 1) | 0] = str.charCodeAt(start + 2); case 2: H8[off + 2 - (om << 1) | 0] = str.charCodeAt(start + 1); case 3: H8[off + 3 - (om << 1) | 0] = str.charCodeAt(start); } if (len < lm + (4 - om)) { return; } for (i = 4 - om; i < j; i = i + 4 | 0) { H32[off + i >> 2] = str.charCodeAt(start + i) << 24 | str.charCodeAt(start + i + 1) << 16 | str.charCodeAt(start + i + 2) << 8 | str.charCodeAt(start + i + 3); } switch (lm) { case 3: H8[off + j + 1 | 0] = str.charCodeAt(start + j + 2); case 2: H8[off + j + 2 | 0] = str.charCodeAt(start + j + 1); case 1: H8[off + j + 3 | 0] = str.charCodeAt(start + j); } }; // Convert a buffer or array and write it to the heap. // The buffer or array is expected to only contain elements < 256. var convBuf = function (buf, H8, H32, start, len, off) { var i = void 0, om = off % 4, lm = (len + om) % 4, j = len - lm; switch (om) { case 0: H8[off] = buf[start + 3]; case 1: H8[off + 1 - (om << 1) | 0] = buf[start + 2]; case 2: H8[off + 2 - (om << 1) | 0] = buf[start + 1]; case 3: H8[off + 3 - (om << 1) | 0] = buf[start]; } if (len < lm + (4 - om)) { return; } for (i = 4 - om; i < j; i = i + 4 | 0) { H32[off + i >> 2 | 0] = buf[start + i] << 24 | buf[start + i + 1] << 16 | buf[start + i + 2] << 8 | buf[start + i + 3]; } switch (lm) { case 3: H8[off + j + 1 | 0] = buf[start + j + 2]; case 2: H8[off + j + 2 | 0] = buf[start + j + 1]; case 1: H8[off + j + 3 | 0] = buf[start + j]; } }; var convBlob = function (blob, H8, H32, start, len, off) { var i = void 0, om = off % 4, lm = (len + om) % 4, j = len - lm; var buf = new Uint8Array(reader.readAsArrayBuffer(blob.slice(start, start + len))); switch (om) { case 0: H8[off] = buf[3]; case 1: H8[off + 1 - (om << 1) | 0] = buf[2]; case 2: H8[off + 2 - (om << 1) | 0] = buf[1]; case 3: H8[off + 3 - (om << 1) | 0] = buf[0]; } if (len < lm + (4 - om)) { return; } for (i = 4 - om; i < j; i = i + 4 | 0) { H32[off + i >> 2 | 0] = buf[i] << 24 | buf[i + 1] << 16 | buf[i + 2] << 8 | buf[i + 3]; } switch (lm) { case 3: H8[off + j + 1 | 0] = buf[j + 2]; case 2: H8[off + j + 2 | 0] = buf[j + 1]; case 1: H8[off + j + 3 | 0] = buf[j]; } }; module.exports = function (data, H8, H32, start, len, off) { if (typeof data === 'string') { return convStr(data, H8, H32, start, len, off); } if (data instanceof Array) { return convBuf(data, H8, H32, start, len, off); } // Safely doing a Buffer check using "this" to avoid Buffer polyfill to be included in the dist if (_this && _this.Buffer && _this.Buffer.isBuffer(data)) { return convBuf(data, H8, H32, start, len, off); } if (data instanceof ArrayBuffer) { return convBuf(new Uint8Array(data), H8, H32, start, len, off); } if (data.buffer instanceof ArrayBuffer) { return convBuf(new Uint8Array(data.buffer, data.byteOffset, data.byteLength), H8, H32, start, len, off); } if (data instanceof Blob) { return convBlob(data, H8, H32, start, len, off); } throw new Error('Unsupported data type.'); }; /***/ }), /* 7 */ /***/ (function(module, exports, __webpack_require__) { function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /* eslint-env commonjs, browser */ var Rusha = __webpack_require__(0); var _require = __webpack_require__(1), toHex = _require.toHex; var Hash = function () { function Hash() { _classCallCheck(this, Hash); this._rusha = new Rusha(); this._rusha.resetState(); } Hash.prototype.update = function update(data) { this._rusha.append(data); return this; }; Hash.prototype.digest = function digest(encoding) { var digest = this._rusha.rawEnd().buffer; if (!encoding) { return digest; } if (encoding === 'hex') { return toHex(digest); } throw new Error('unsupported digest encoding'); }; return Hash; }(); module.exports = function () { return new Hash(); }; /***/ }) /******/ ]); }); },{}],226:[function(require,module,exports){ /*! safe-buffer. MIT License. Feross Aboukhadijeh */ /* eslint-disable node/no-deprecated-api */ var buffer = require('buffer') var Buffer = buffer.Buffer // alternative to using Object.keys for old browsers function copyProps (src, dst) { for (var key in src) { dst[key] = src[key] } } if (Buffer.from && Buffer.alloc && Buffer.allocUnsafe && Buffer.allocUnsafeSlow) { module.exports = buffer } else { // Copy properties from require('buffer') copyProps(buffer, exports) exports.Buffer = SafeBuffer } function SafeBuffer (arg, encodingOrOffset, length) { return Buffer(arg, encodingOrOffset, length) } SafeBuffer.prototype = Object.create(Buffer.prototype) // Copy static methods from Buffer copyProps(Buffer, SafeBuffer) SafeBuffer.from = function (arg, encodingOrOffset, length) { if (typeof arg === 'number') { throw new TypeError('Argument must not be a number') } return Buffer(arg, encodingOrOffset, length) } SafeBuffer.alloc = function (size, fill, encoding) { if (typeof size !== 'number') { throw new TypeError('Argument must be a number') } var buf = Buffer(size) if (fill !== undefined) { if (typeof encoding === 'string') { buf.fill(fill, encoding) } else { buf.fill(fill) } } else { buf.fill(0) } return buf } SafeBuffer.allocUnsafe = function (size) { if (typeof size !== 'number') { throw new TypeError('Argument must be a number') } return Buffer(size) } SafeBuffer.allocUnsafeSlow = function (size) { if (typeof size !== 'number') { throw new TypeError('Argument must be a number') } return buffer.SlowBuffer(size) } },{"buffer":331}],227:[function(require,module,exports){ var Buffer = require('safe-buffer').Buffer // prototype class for hash functions function Hash (blockSize, finalSize) { this._block = Buffer.alloc(blockSize) this._finalSize = finalSize this._blockSize = blockSize this._len = 0 } Hash.prototype.update = function (data, enc) { if (typeof data === 'string') { enc = enc || 'utf8' data = Buffer.from(data, enc) } var block = this._block var blockSize = this._blockSize var length = data.length var accum = this._len for (var offset = 0; offset < length;) { var assigned = accum % blockSize var remainder = Math.min(length - offset, blockSize - assigned) for (var i = 0; i < remainder; i++) { block[assigned + i] = data[offset + i] } accum += remainder offset += remainder if ((accum % blockSize) === 0) { this._update(block) } } this._len += length return this } Hash.prototype.digest = function (enc) { var rem = this._len % this._blockSize this._block[rem] = 0x80 // zero (rem + 1) trailing bits, where (rem + 1) is the smallest // non-negative solution to the equation (length + 1 + (rem + 1)) === finalSize mod blockSize this._block.fill(0, rem + 1) if (rem >= this._finalSize) { this._update(this._block) this._block.fill(0) } var bits = this._len * 8 // uint32 if (bits <= 0xffffffff) { this._block.writeUInt32BE(bits, this._blockSize - 4) // uint64 } else { var lowBits = (bits & 0xffffffff) >>> 0 var highBits = (bits - lowBits) / 0x100000000 this._block.writeUInt32BE(highBits, this._blockSize - 8) this._block.writeUInt32BE(lowBits, this._blockSize - 4) } this._update(this._block) var hash = this._hash() return enc ? hash.toString(enc) : hash } Hash.prototype._update = function () { throw new Error('_update must be implemented by subclass') } module.exports = Hash },{"safe-buffer":226}],228:[function(require,module,exports){ var exports = module.exports = function SHA (algorithm) { algorithm = algorithm.toLowerCase() var Algorithm = exports[algorithm] if (!Algorithm) throw new Error(algorithm + ' is not supported (we accept pull requests)') return new Algorithm() } exports.sha = require('./sha') exports.sha1 = require('./sha1') exports.sha224 = require('./sha224') exports.sha256 = require('./sha256') exports.sha384 = require('./sha384') exports.sha512 = require('./sha512') },{"./sha":229,"./sha1":230,"./sha224":231,"./sha256":232,"./sha384":233,"./sha512":234}],229:[function(require,module,exports){ /* * A JavaScript implementation of the Secure Hash Algorithm, SHA-0, as defined * in FIPS PUB 180-1 * This source code is derived from sha1.js of the same repository. * The difference between SHA-0 and SHA-1 is just a bitwise rotate left * operation was added. */ var inherits = require('inherits') var Hash = require('./hash') var Buffer = require('safe-buffer').Buffer var K = [ 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc | 0, 0xca62c1d6 | 0 ] var W = new Array(80) function Sha () { this.init() this._w = W Hash.call(this, 64, 56) } inherits(Sha, Hash) Sha.prototype.init = function () { this._a = 0x67452301 this._b = 0xefcdab89 this._c = 0x98badcfe this._d = 0x10325476 this._e = 0xc3d2e1f0 return this } function rotl5 (num) { return (num << 5) | (num >>> 27) } function rotl30 (num) { return (num << 30) | (num >>> 2) } function ft (s, b, c, d) { if (s === 0) return (b & c) | ((~b) & d) if (s === 2) return (b & c) | (b & d) | (c & d) return b ^ c ^ d } Sha.prototype._update = function (M) { var W = this._w var a = this._a | 0 var b = this._b | 0 var c = this._c | 0 var d = this._d | 0 var e = this._e | 0 for (var i = 0; i < 16; ++i) W[i] = M.readInt32BE(i * 4) for (; i < 80; ++i) W[i] = W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16] for (var j = 0; j < 80; ++j) { var s = ~~(j / 20) var t = (rotl5(a) + ft(s, b, c, d) + e + W[j] + K[s]) | 0 e = d d = c c = rotl30(b) b = a a = t } this._a = (a + this._a) | 0 this._b = (b + this._b) | 0 this._c = (c + this._c) | 0 this._d = (d + this._d) | 0 this._e = (e + this._e) | 0 } Sha.prototype._hash = function () { var H = Buffer.allocUnsafe(20) H.writeInt32BE(this._a | 0, 0) H.writeInt32BE(this._b | 0, 4) H.writeInt32BE(this._c | 0, 8) H.writeInt32BE(this._d | 0, 12) H.writeInt32BE(this._e | 0, 16) return H } module.exports = Sha },{"./hash":227,"inherits":131,"safe-buffer":226}],230:[function(require,module,exports){ /* * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined * in FIPS PUB 180-1 * Version 2.1a Copyright Paul Johnston 2000 - 2002. * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet * Distributed under the BSD License * See http://pajhome.org.uk/crypt/md5 for details. */ var inherits = require('inherits') var Hash = require('./hash') var Buffer = require('safe-buffer').Buffer var K = [ 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc | 0, 0xca62c1d6 | 0 ] var W = new Array(80) function Sha1 () { this.init() this._w = W Hash.call(this, 64, 56) } inherits(Sha1, Hash) Sha1.prototype.init = function () { this._a = 0x67452301 this._b = 0xefcdab89 this._c = 0x98badcfe this._d = 0x10325476 this._e = 0xc3d2e1f0 return this } function rotl1 (num) { return (num << 1) | (num >>> 31) } function rotl5 (num) { return (num << 5) | (num >>> 27) } function rotl30 (num) { return (num << 30) | (num >>> 2) } function ft (s, b, c, d) { if (s === 0) return (b & c) | ((~b) & d) if (s === 2) return (b & c) | (b & d) | (c & d) return b ^ c ^ d } Sha1.prototype._update = function (M) { var W = this._w var a = this._a | 0 var b = this._b | 0 var c = this._c | 0 var d = this._d | 0 var e = this._e | 0 for (var i = 0; i < 16; ++i) W[i] = M.readInt32BE(i * 4) for (; i < 80; ++i) W[i] = rotl1(W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16]) for (var j = 0; j < 80; ++j) { var s = ~~(j / 20) var t = (rotl5(a) + ft(s, b, c, d) + e + W[j] + K[s]) | 0 e = d d = c c = rotl30(b) b = a a = t } this._a = (a + this._a) | 0 this._b = (b + this._b) | 0 this._c = (c + this._c) | 0 this._d = (d + this._d) | 0 this._e = (e + this._e) | 0 } Sha1.prototype._hash = function () { var H = Buffer.allocUnsafe(20) H.writeInt32BE(this._a | 0, 0) H.writeInt32BE(this._b | 0, 4) H.writeInt32BE(this._c | 0, 8) H.writeInt32BE(this._d | 0, 12) H.writeInt32BE(this._e | 0, 16) return H } module.exports = Sha1 },{"./hash":227,"inherits":131,"safe-buffer":226}],231:[function(require,module,exports){ /** * A JavaScript implementation of the Secure Hash Algorithm, SHA-256, as defined * in FIPS 180-2 * Version 2.2-beta Copyright Angel Marin, Paul Johnston 2000 - 2009. * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet * */ var inherits = require('inherits') var Sha256 = require('./sha256') var Hash = require('./hash') var Buffer = require('safe-buffer').Buffer var W = new Array(64) function Sha224 () { this.init() this._w = W // new Array(64) Hash.call(this, 64, 56) } inherits(Sha224, Sha256) Sha224.prototype.init = function () { this._a = 0xc1059ed8 this._b = 0x367cd507 this._c = 0x3070dd17 this._d = 0xf70e5939 this._e = 0xffc00b31 this._f = 0x68581511 this._g = 0x64f98fa7 this._h = 0xbefa4fa4 return this } Sha224.prototype._hash = function () { var H = Buffer.allocUnsafe(28) H.writeInt32BE(this._a, 0) H.writeInt32BE(this._b, 4) H.writeInt32BE(this._c, 8) H.writeInt32BE(this._d, 12) H.writeInt32BE(this._e, 16) H.writeInt32BE(this._f, 20) H.writeInt32BE(this._g, 24) return H } module.exports = Sha224 },{"./hash":227,"./sha256":232,"inherits":131,"safe-buffer":226}],232:[function(require,module,exports){ /** * A JavaScript implementation of the Secure Hash Algorithm, SHA-256, as defined * in FIPS 180-2 * Version 2.2-beta Copyright Angel Marin, Paul Johnston 2000 - 2009. * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet * */ var inherits = require('inherits') var Hash = require('./hash') var Buffer = require('safe-buffer').Buffer var K = [ 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5, 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3, 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174, 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC, 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA, 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7, 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967, 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13, 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85, 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3, 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070, 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5, 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3, 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208, 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2 ] var W = new Array(64) function Sha256 () { this.init() this._w = W // new Array(64) Hash.call(this, 64, 56) } inherits(Sha256, Hash) Sha256.prototype.init = function () { this._a = 0x6a09e667 this._b = 0xbb67ae85 this._c = 0x3c6ef372 this._d = 0xa54ff53a this._e = 0x510e527f this._f = 0x9b05688c this._g = 0x1f83d9ab this._h = 0x5be0cd19 return this } function ch (x, y, z) { return z ^ (x & (y ^ z)) } function maj (x, y, z) { return (x & y) | (z & (x | y)) } function sigma0 (x) { return (x >>> 2 | x << 30) ^ (x >>> 13 | x << 19) ^ (x >>> 22 | x << 10) } function sigma1 (x) { return (x >>> 6 | x << 26) ^ (x >>> 11 | x << 21) ^ (x >>> 25 | x << 7) } function gamma0 (x) { return (x >>> 7 | x << 25) ^ (x >>> 18 | x << 14) ^ (x >>> 3) } function gamma1 (x) { return (x >>> 17 | x << 15) ^ (x >>> 19 | x << 13) ^ (x >>> 10) } Sha256.prototype._update = function (M) { var W = this._w var a = this._a | 0 var b = this._b | 0 var c = this._c | 0 var d = this._d | 0 var e = this._e | 0 var f = this._f | 0 var g = this._g | 0 var h = this._h | 0 for (var i = 0; i < 16; ++i) W[i] = M.readInt32BE(i * 4) for (; i < 64; ++i) W[i] = (gamma1(W[i - 2]) + W[i - 7] + gamma0(W[i - 15]) + W[i - 16]) | 0 for (var j = 0; j < 64; ++j) { var T1 = (h + sigma1(e) + ch(e, f, g) + K[j] + W[j]) | 0 var T2 = (sigma0(a) + maj(a, b, c)) | 0 h = g g = f f = e e = (d + T1) | 0 d = c c = b b = a a = (T1 + T2) | 0 } this._a = (a + this._a) | 0 this._b = (b + this._b) | 0 this._c = (c + this._c) | 0 this._d = (d + this._d) | 0 this._e = (e + this._e) | 0 this._f = (f + this._f) | 0 this._g = (g + this._g) | 0 this._h = (h + this._h) | 0 } Sha256.prototype._hash = function () { var H = Buffer.allocUnsafe(32) H.writeInt32BE(this._a, 0) H.writeInt32BE(this._b, 4) H.writeInt32BE(this._c, 8) H.writeInt32BE(this._d, 12) H.writeInt32BE(this._e, 16) H.writeInt32BE(this._f, 20) H.writeInt32BE(this._g, 24) H.writeInt32BE(this._h, 28) return H } module.exports = Sha256 },{"./hash":227,"inherits":131,"safe-buffer":226}],233:[function(require,module,exports){ var inherits = require('inherits') var SHA512 = require('./sha512') var Hash = require('./hash') var Buffer = require('safe-buffer').Buffer var W = new Array(160) function Sha384 () { this.init() this._w = W Hash.call(this, 128, 112) } inherits(Sha384, SHA512) Sha384.prototype.init = function () { this._ah = 0xcbbb9d5d this._bh = 0x629a292a this._ch = 0x9159015a this._dh = 0x152fecd8 this._eh = 0x67332667 this._fh = 0x8eb44a87 this._gh = 0xdb0c2e0d this._hh = 0x47b5481d this._al = 0xc1059ed8 this._bl = 0x367cd507 this._cl = 0x3070dd17 this._dl = 0xf70e5939 this._el = 0xffc00b31 this._fl = 0x68581511 this._gl = 0x64f98fa7 this._hl = 0xbefa4fa4 return this } Sha384.prototype._hash = function () { var H = Buffer.allocUnsafe(48) function writeInt64BE (h, l, offset) { H.writeInt32BE(h, offset) H.writeInt32BE(l, offset + 4) } writeInt64BE(this._ah, this._al, 0) writeInt64BE(this._bh, this._bl, 8) writeInt64BE(this._ch, this._cl, 16) writeInt64BE(this._dh, this._dl, 24) writeInt64BE(this._eh, this._el, 32) writeInt64BE(this._fh, this._fl, 40) return H } module.exports = Sha384 },{"./hash":227,"./sha512":234,"inherits":131,"safe-buffer":226}],234:[function(require,module,exports){ var inherits = require('inherits') var Hash = require('./hash') var Buffer = require('safe-buffer').Buffer var K = [ 0x428a2f98, 0xd728ae22, 0x71374491, 0x23ef65cd, 0xb5c0fbcf, 0xec4d3b2f, 0xe9b5dba5, 0x8189dbbc, 0x3956c25b, 0xf348b538, 0x59f111f1, 0xb605d019, 0x923f82a4, 0xaf194f9b, 0xab1c5ed5, 0xda6d8118, 0xd807aa98, 0xa3030242, 0x12835b01, 0x45706fbe, 0x243185be, 0x4ee4b28c, 0x550c7dc3, 0xd5ffb4e2, 0x72be5d74, 0xf27b896f, 0x80deb1fe, 0x3b1696b1, 0x9bdc06a7, 0x25c71235, 0xc19bf174, 0xcf692694, 0xe49b69c1, 0x9ef14ad2, 0xefbe4786, 0x384f25e3, 0x0fc19dc6, 0x8b8cd5b5, 0x240ca1cc, 0x77ac9c65, 0x2de92c6f, 0x592b0275, 0x4a7484aa, 0x6ea6e483, 0x5cb0a9dc, 0xbd41fbd4, 0x76f988da, 0x831153b5, 0x983e5152, 0xee66dfab, 0xa831c66d, 0x2db43210, 0xb00327c8, 0x98fb213f, 0xbf597fc7, 0xbeef0ee4, 0xc6e00bf3, 0x3da88fc2, 0xd5a79147, 0x930aa725, 0x06ca6351, 0xe003826f, 0x14292967, 0x0a0e6e70, 0x27b70a85, 0x46d22ffc, 0x2e1b2138, 0x5c26c926, 0x4d2c6dfc, 0x5ac42aed, 0x53380d13, 0x9d95b3df, 0x650a7354, 0x8baf63de, 0x766a0abb, 0x3c77b2a8, 0x81c2c92e, 0x47edaee6, 0x92722c85, 0x1482353b, 0xa2bfe8a1, 0x4cf10364, 0xa81a664b, 0xbc423001, 0xc24b8b70, 0xd0f89791, 0xc76c51a3, 0x0654be30, 0xd192e819, 0xd6ef5218, 0xd6990624, 0x5565a910, 0xf40e3585, 0x5771202a, 0x106aa070, 0x32bbd1b8, 0x19a4c116, 0xb8d2d0c8, 0x1e376c08, 0x5141ab53, 0x2748774c, 0xdf8eeb99, 0x34b0bcb5, 0xe19b48a8, 0x391c0cb3, 0xc5c95a63, 0x4ed8aa4a, 0xe3418acb, 0x5b9cca4f, 0x7763e373, 0x682e6ff3, 0xd6b2b8a3, 0x748f82ee, 0x5defb2fc, 0x78a5636f, 0x43172f60, 0x84c87814, 0xa1f0ab72, 0x8cc70208, 0x1a6439ec, 0x90befffa, 0x23631e28, 0xa4506ceb, 0xde82bde9, 0xbef9a3f7, 0xb2c67915, 0xc67178f2, 0xe372532b, 0xca273ece, 0xea26619c, 0xd186b8c7, 0x21c0c207, 0xeada7dd6, 0xcde0eb1e, 0xf57d4f7f, 0xee6ed178, 0x06f067aa, 0x72176fba, 0x0a637dc5, 0xa2c898a6, 0x113f9804, 0xbef90dae, 0x1b710b35, 0x131c471b, 0x28db77f5, 0x23047d84, 0x32caab7b, 0x40c72493, 0x3c9ebe0a, 0x15c9bebc, 0x431d67c4, 0x9c100d4c, 0x4cc5d4be, 0xcb3e42b6, 0x597f299c, 0xfc657e2a, 0x5fcb6fab, 0x3ad6faec, 0x6c44198c, 0x4a475817 ] var W = new Array(160) function Sha512 () { this.init() this._w = W Hash.call(this, 128, 112) } inherits(Sha512, Hash) Sha512.prototype.init = function () { this._ah = 0x6a09e667 this._bh = 0xbb67ae85 this._ch = 0x3c6ef372 this._dh = 0xa54ff53a this._eh = 0x510e527f this._fh = 0x9b05688c this._gh = 0x1f83d9ab this._hh = 0x5be0cd19 this._al = 0xf3bcc908 this._bl = 0x84caa73b this._cl = 0xfe94f82b this._dl = 0x5f1d36f1 this._el = 0xade682d1 this._fl = 0x2b3e6c1f this._gl = 0xfb41bd6b this._hl = 0x137e2179 return this } function Ch (x, y, z) { return z ^ (x & (y ^ z)) } function maj (x, y, z) { return (x & y) | (z & (x | y)) } function sigma0 (x, xl) { return (x >>> 28 | xl << 4) ^ (xl >>> 2 | x << 30) ^ (xl >>> 7 | x << 25) } function sigma1 (x, xl) { return (x >>> 14 | xl << 18) ^ (x >>> 18 | xl << 14) ^ (xl >>> 9 | x << 23) } function Gamma0 (x, xl) { return (x >>> 1 | xl << 31) ^ (x >>> 8 | xl << 24) ^ (x >>> 7) } function Gamma0l (x, xl) { return (x >>> 1 | xl << 31) ^ (x >>> 8 | xl << 24) ^ (x >>> 7 | xl << 25) } function Gamma1 (x, xl) { return (x >>> 19 | xl << 13) ^ (xl >>> 29 | x << 3) ^ (x >>> 6) } function Gamma1l (x, xl) { return (x >>> 19 | xl << 13) ^ (xl >>> 29 | x << 3) ^ (x >>> 6 | xl << 26) } function getCarry (a, b) { return (a >>> 0) < (b >>> 0) ? 1 : 0 } Sha512.prototype._update = function (M) { var W = this._w var ah = this._ah | 0 var bh = this._bh | 0 var ch = this._ch | 0 var dh = this._dh | 0 var eh = this._eh | 0 var fh = this._fh | 0 var gh = this._gh | 0 var hh = this._hh | 0 var al = this._al | 0 var bl = this._bl | 0 var cl = this._cl | 0 var dl = this._dl | 0 var el = this._el | 0 var fl = this._fl | 0 var gl = this._gl | 0 var hl = this._hl | 0 for (var i = 0; i < 32; i += 2) { W[i] = M.readInt32BE(i * 4) W[i + 1] = M.readInt32BE(i * 4 + 4) } for (; i < 160; i += 2) { var xh = W[i - 15 * 2] var xl = W[i - 15 * 2 + 1] var gamma0 = Gamma0(xh, xl) var gamma0l = Gamma0l(xl, xh) xh = W[i - 2 * 2] xl = W[i - 2 * 2 + 1] var gamma1 = Gamma1(xh, xl) var gamma1l = Gamma1l(xl, xh) // W[i] = gamma0 + W[i - 7] + gamma1 + W[i - 16] var Wi7h = W[i - 7 * 2] var Wi7l = W[i - 7 * 2 + 1] var Wi16h = W[i - 16 * 2] var Wi16l = W[i - 16 * 2 + 1] var Wil = (gamma0l + Wi7l) | 0 var Wih = (gamma0 + Wi7h + getCarry(Wil, gamma0l)) | 0 Wil = (Wil + gamma1l) | 0 Wih = (Wih + gamma1 + getCarry(Wil, gamma1l)) | 0 Wil = (Wil + Wi16l) | 0 Wih = (Wih + Wi16h + getCarry(Wil, Wi16l)) | 0 W[i] = Wih W[i + 1] = Wil } for (var j = 0; j < 160; j += 2) { Wih = W[j] Wil = W[j + 1] var majh = maj(ah, bh, ch) var majl = maj(al, bl, cl) var sigma0h = sigma0(ah, al) var sigma0l = sigma0(al, ah) var sigma1h = sigma1(eh, el) var sigma1l = sigma1(el, eh) // t1 = h + sigma1 + ch + K[j] + W[j] var Kih = K[j] var Kil = K[j + 1] var chh = Ch(eh, fh, gh) var chl = Ch(el, fl, gl) var t1l = (hl + sigma1l) | 0 var t1h = (hh + sigma1h + getCarry(t1l, hl)) | 0 t1l = (t1l + chl) | 0 t1h = (t1h + chh + getCarry(t1l, chl)) | 0 t1l = (t1l + Kil) | 0 t1h = (t1h + Kih + getCarry(t1l, Kil)) | 0 t1l = (t1l + Wil) | 0 t1h = (t1h + Wih + getCarry(t1l, Wil)) | 0 // t2 = sigma0 + maj var t2l = (sigma0l + majl) | 0 var t2h = (sigma0h + majh + getCarry(t2l, sigma0l)) | 0 hh = gh hl = gl gh = fh gl = fl fh = eh fl = el el = (dl + t1l) | 0 eh = (dh + t1h + getCarry(el, dl)) | 0 dh = ch dl = cl ch = bh cl = bl bh = ah bl = al al = (t1l + t2l) | 0 ah = (t1h + t2h + getCarry(al, t1l)) | 0 } this._al = (this._al + al) | 0 this._bl = (this._bl + bl) | 0 this._cl = (this._cl + cl) | 0 this._dl = (this._dl + dl) | 0 this._el = (this._el + el) | 0 this._fl = (this._fl + fl) | 0 this._gl = (this._gl + gl) | 0 this._hl = (this._hl + hl) | 0 this._ah = (this._ah + ah + getCarry(this._al, al)) | 0 this._bh = (this._bh + bh + getCarry(this._bl, bl)) | 0 this._ch = (this._ch + ch + getCarry(this._cl, cl)) | 0 this._dh = (this._dh + dh + getCarry(this._dl, dl)) | 0 this._eh = (this._eh + eh + getCarry(this._el, el)) | 0 this._fh = (this._fh + fh + getCarry(this._fl, fl)) | 0 this._gh = (this._gh + gh + getCarry(this._gl, gl)) | 0 this._hh = (this._hh + hh + getCarry(this._hl, hl)) | 0 } Sha512.prototype._hash = function () { var H = Buffer.allocUnsafe(64) function writeInt64BE (h, l, offset) { H.writeInt32BE(h, offset) H.writeInt32BE(l, offset + 4) } writeInt64BE(this._ah, this._al, 0) writeInt64BE(this._bh, this._bl, 8) writeInt64BE(this._ch, this._cl, 16) writeInt64BE(this._dh, this._dl, 24) writeInt64BE(this._eh, this._el, 32) writeInt64BE(this._fh, this._fl, 40) writeInt64BE(this._gh, this._gl, 48) writeInt64BE(this._hh, this._hl, 56) return H } module.exports = Sha512 },{"./hash":227,"inherits":131,"safe-buffer":226}],235:[function(require,module,exports){ (function (Buffer){(function (){ /*! simple-concat. MIT License. Feross Aboukhadijeh */ module.exports = function (stream, cb) { var chunks = [] stream.on('data', function (chunk) { chunks.push(chunk) }) stream.once('end', function () { if (cb) cb(null, Buffer.concat(chunks)) cb = null }) stream.once('error', function (err) { if (cb) cb(err) cb = null }) } }).call(this)}).call(this,require("buffer").Buffer) },{"buffer":331}],236:[function(require,module,exports){ (function (Buffer){(function (){ /*! simple-get. MIT License. Feross Aboukhadijeh */ module.exports = simpleGet const concat = require('simple-concat') const decompressResponse = require('decompress-response') // excluded from browser build const http = require('http') const https = require('https') const once = require('once') const querystring = require('querystring') const url = require('url') const isStream = o => o !== null && typeof o === 'object' && typeof o.pipe === 'function' function simpleGet (opts, cb) { opts = Object.assign({ maxRedirects: 10 }, typeof opts === 'string' ? { url: opts } : opts) cb = once(cb) if (opts.url) { const { hostname, port, protocol, auth, path } = url.parse(opts.url) // eslint-disable-line node/no-deprecated-api delete opts.url if (!hostname && !port && !protocol && !auth) opts.path = path // Relative redirect else Object.assign(opts, { hostname, port, protocol, auth, path }) // Absolute redirect } const headers = { 'accept-encoding': 'gzip, deflate' } if (opts.headers) Object.keys(opts.headers).forEach(k => (headers[k.toLowerCase()] = opts.headers[k])) opts.headers = headers let body if (opts.body) { body = opts.json && !isStream(opts.body) ? JSON.stringify(opts.body) : opts.body } else if (opts.form) { body = typeof opts.form === 'string' ? opts.form : querystring.stringify(opts.form) opts.headers['content-type'] = 'application/x-www-form-urlencoded' } if (body) { if (!opts.method) opts.method = 'POST' if (!isStream(body)) opts.headers['content-length'] = Buffer.byteLength(body) if (opts.json && !opts.form) opts.headers['content-type'] = 'application/json' } delete opts.body; delete opts.form if (opts.json) opts.headers.accept = 'application/json' if (opts.method) opts.method = opts.method.toUpperCase() const protocol = opts.protocol === 'https:' ? https : http // Support http/https urls const req = protocol.request(opts, res => { if (opts.followRedirects !== false && res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) { opts.url = res.headers.location // Follow 3xx redirects delete opts.headers.host // Discard `host` header on redirect (see #32) res.resume() // Discard response if (opts.method === 'POST' && [301, 302].includes(res.statusCode)) { opts.method = 'GET' // On 301/302 redirect, change POST to GET (see #35) delete opts.headers['content-length']; delete opts.headers['content-type'] } if (opts.maxRedirects-- === 0) return cb(new Error('too many redirects')) else return simpleGet(opts, cb) } const tryUnzip = typeof decompressResponse === 'function' && opts.method !== 'HEAD' cb(null, tryUnzip ? decompressResponse(res) : res) }) req.on('timeout', () => { req.abort() cb(new Error('Request timed out')) }) req.on('error', cb) if (isStream(body)) body.on('error', cb).pipe(req) else req.end(body) return req } simpleGet.concat = (opts, cb) => { return simpleGet(opts, (err, res) => { if (err) return cb(err) concat(res, (err, data) => { if (err) return cb(err) if (opts.json) { try { data = JSON.parse(data.toString()) } catch (err) { return cb(err, res, data) } } cb(null, res, data) }) }) } ;['get', 'post', 'put', 'patch', 'head', 'delete'].forEach(method => { simpleGet[method] = (opts, cb) => { if (typeof opts === 'string') opts = { url: opts } return simpleGet(Object.assign({ method: method.toUpperCase() }, opts), cb) } }) }).call(this)}).call(this,require("buffer").Buffer) },{"buffer":331,"decompress-response":330,"http":359,"https":334,"once":194,"querystring":342,"simple-concat":235,"url":379}],237:[function(require,module,exports){ /*! simple-peer. MIT License. Feross Aboukhadijeh */ const debug = require('debug')('simple-peer') const getBrowserRTC = require('get-browser-rtc') const randombytes = require('randombytes') const stream = require('readable-stream') const queueMicrotask = require('queue-microtask') // TODO: remove when Node 10 is not supported const errCode = require('err-code') const { Buffer } = require('buffer') const MAX_BUFFERED_AMOUNT = 64 * 1024 const ICECOMPLETE_TIMEOUT = 5 * 1000 const CHANNEL_CLOSING_TIMEOUT = 5 * 1000 // HACK: Filter trickle lines when trickle is disabled #354 function filterTrickle (sdp) { return sdp.replace(/a=ice-options:trickle\s\n/g, '') } function warn (message) { console.warn(message) } /** * WebRTC peer connection. Same API as node core `net.Socket`, plus a few extra methods. * Duplex stream. * @param {Object} opts */ class Peer extends stream.Duplex { constructor (opts) { opts = Object.assign({ allowHalfOpen: false, ordered: false, maxRetransmits: 0 }, opts) super(opts) this._id = randombytes(4).toString('hex').slice(0, 7) this._debug('new peer %o', opts) this.channelName = opts.initiator ? opts.channelName || randombytes(20).toString('hex') : null this.initiator = opts.initiator || false this.channelConfig = opts.channelConfig || Peer.channelConfig this.channelNegotiated = this.channelConfig.negotiated this.config = Object.assign({}, Peer.config, opts.config) this.offerOptions = opts.offerOptions || {} this.answerOptions = opts.answerOptions || {} this.sdpTransform = opts.sdpTransform || (sdp => sdp) this.streams = opts.streams || (opts.stream ? [opts.stream] : []) // support old "stream" option this.trickle = opts.trickle !== undefined ? opts.trickle : true this.allowHalfTrickle = opts.allowHalfTrickle !== undefined ? opts.allowHalfTrickle : false this.iceCompleteTimeout = opts.iceCompleteTimeout || ICECOMPLETE_TIMEOUT this.destroyed = false this.destroying = false this._connected = false this.remoteAddress = undefined this.remoteFamily = undefined this.remotePort = undefined this.localAddress = undefined this.localFamily = undefined this.localPort = undefined this._wrtc = (opts.wrtc && typeof opts.wrtc === 'object') ? opts.wrtc : getBrowserRTC() if (!this._wrtc) { if (typeof window === 'undefined') { throw errCode(new Error('No WebRTC support: Specify `opts.wrtc` option in this environment'), 'ERR_WEBRTC_SUPPORT') } else { throw errCode(new Error('No WebRTC support: Not a supported browser'), 'ERR_WEBRTC_SUPPORT') } } this._pcReady = false this._channelReady = false this._iceComplete = false // ice candidate trickle done (got null candidate) this._iceCompleteTimer = null // send an offer/answer anyway after some timeout this._channel = null this._pendingCandidates = [] this._isNegotiating = false // is this peer waiting for negotiation to complete? this._firstNegotiation = true this._batchedNegotiation = false // batch synchronous negotiations this._queuedNegotiation = false // is there a queued negotiation request? this._sendersAwaitingStable = [] this._senderMap = new Map() this._closingInterval = null this._remoteTracks = [] this._remoteStreams = [] this._chunk = null this._cb = null this._interval = null try { this._pc = new (this._wrtc.RTCPeerConnection)(this.config) } catch (err) { queueMicrotask(() => this.destroy(errCode(err, 'ERR_PC_CONSTRUCTOR'))) return } // We prefer feature detection whenever possible, but sometimes that's not // possible for certain implementations. this._isReactNativeWebrtc = typeof this._pc._peerConnectionId === 'number' this._pc.oniceconnectionstatechange = () => { this._onIceStateChange() } this._pc.onicegatheringstatechange = () => { this._onIceStateChange() } this._pc.onconnectionstatechange = () => { this._onConnectionStateChange() } this._pc.onsignalingstatechange = () => { this._onSignalingStateChange() } this._pc.onicecandidate = event => { this._onIceCandidate(event) } // Other spec events, unused by this implementation: // - onconnectionstatechange // - onicecandidateerror // - onfingerprintfailure // - onnegotiationneeded if (this.initiator || this.channelNegotiated) { this._setupData({ channel: this._pc.createDataChannel(this.channelName, this.channelConfig) }) } else { this._pc.ondatachannel = event => { this._setupData(event) } } if (this.streams) { this.streams.forEach(stream => { this.addStream(stream) }) } this._pc.ontrack = event => { this._onTrack(event) } this._debug('initial negotiation') this._needsNegotiation() this._onFinishBound = () => { this._onFinish() } this.once('finish', this._onFinishBound) } get bufferSize () { return (this._channel && this._channel.bufferedAmount) || 0 } // HACK: it's possible channel.readyState is "closing" before peer.destroy() fires // https://bugs.chromium.org/p/chromium/issues/detail?id=882743 get connected () { return (this._connected && this._channel.readyState === 'open') } address () { return { port: this.localPort, family: this.localFamily, address: this.localAddress } } signal (data) { if (this.destroyed) throw errCode(new Error('cannot signal after peer is destroyed'), 'ERR_SIGNALING') if (typeof data === 'string') { try { data = JSON.parse(data) } catch (err) { data = {} } } this._debug('signal()') if (data.renegotiate && this.initiator) { this._debug('got request to renegotiate') this._needsNegotiation() } if (data.transceiverRequest && this.initiator) { this._debug('got request for transceiver') this.addTransceiver(data.transceiverRequest.kind, data.transceiverRequest.init) } if (data.candidate) { if (this._pc.remoteDescription && this._pc.remoteDescription.type) { this._addIceCandidate(data.candidate) } else { this._pendingCandidates.push(data.candidate) } } if (data.sdp) { this._pc.setRemoteDescription(new (this._wrtc.RTCSessionDescription)(data)) .then(() => { if (this.destroyed) return this._pendingCandidates.forEach(candidate => { this._addIceCandidate(candidate) }) this._pendingCandidates = [] if (this._pc.remoteDescription.type === 'offer') this._createAnswer() }) .catch(err => { this.destroy(errCode(err, 'ERR_SET_REMOTE_DESCRIPTION')) }) } if (!data.sdp && !data.candidate && !data.renegotiate && !data.transceiverRequest) { this.destroy(errCode(new Error('signal() called with invalid signal data'), 'ERR_SIGNALING')) } } _addIceCandidate (candidate) { const iceCandidateObj = new this._wrtc.RTCIceCandidate(candidate) this._pc.addIceCandidate(iceCandidateObj) .catch(err => { if (!iceCandidateObj.address || iceCandidateObj.address.endsWith('.local')) { warn('Ignoring unsupported ICE candidate.') } else { this.destroy(errCode(err, 'ERR_ADD_ICE_CANDIDATE')) } }) } /** * Send text/binary data to the remote peer. * @param {ArrayBufferView|ArrayBuffer|Buffer|string|Blob} chunk */ send (chunk) { this._channel.send(chunk) } /** * Add a Transceiver to the connection. * @param {String} kind * @param {Object} init */ addTransceiver (kind, init) { this._debug('addTransceiver()') if (this.initiator) { try { this._pc.addTransceiver(kind, init) this._needsNegotiation() } catch (err) { this.destroy(errCode(err, 'ERR_ADD_TRANSCEIVER')) } } else { this.emit('signal', { // request initiator to renegotiate type: 'transceiverRequest', transceiverRequest: { kind, init } }) } } /** * Add a MediaStream to the connection. * @param {MediaStream} stream */ addStream (stream) { this._debug('addStream()') stream.getTracks().forEach(track => { this.addTrack(track, stream) }) } /** * Add a MediaStreamTrack to the connection. * @param {MediaStreamTrack} track * @param {MediaStream} stream */ addTrack (track, stream) { this._debug('addTrack()') const submap = this._senderMap.get(track) || new Map() // nested Maps map [track, stream] to sender let sender = submap.get(stream) if (!sender) { sender = this._pc.addTrack(track, stream) submap.set(stream, sender) this._senderMap.set(track, submap) this._needsNegotiation() } else if (sender.removed) { throw errCode(new Error('Track has been removed. You should enable/disable tracks that you want to re-add.'), 'ERR_SENDER_REMOVED') } else { throw errCode(new Error('Track has already been added to that stream.'), 'ERR_SENDER_ALREADY_ADDED') } } /** * Replace a MediaStreamTrack by another in the connection. * @param {MediaStreamTrack} oldTrack * @param {MediaStreamTrack} newTrack * @param {MediaStream} stream */ replaceTrack (oldTrack, newTrack, stream) { this._debug('replaceTrack()') const submap = this._senderMap.get(oldTrack) const sender = submap ? submap.get(stream) : null if (!sender) { throw errCode(new Error('Cannot replace track that was never added.'), 'ERR_TRACK_NOT_ADDED') } if (newTrack) this._senderMap.set(newTrack, submap) if (sender.replaceTrack != null) { sender.replaceTrack(newTrack) } else { this.destroy(errCode(new Error('replaceTrack is not supported in this browser'), 'ERR_UNSUPPORTED_REPLACETRACK')) } } /** * Remove a MediaStreamTrack from the connection. * @param {MediaStreamTrack} track * @param {MediaStream} stream */ removeTrack (track, stream) { this._debug('removeSender()') const submap = this._senderMap.get(track) const sender = submap ? submap.get(stream) : null if (!sender) { throw errCode(new Error('Cannot remove track that was never added.'), 'ERR_TRACK_NOT_ADDED') } try { sender.removed = true this._pc.removeTrack(sender) } catch (err) { if (err.name === 'NS_ERROR_UNEXPECTED') { this._sendersAwaitingStable.push(sender) // HACK: Firefox must wait until (signalingState === stable) https://bugzilla.mozilla.org/show_bug.cgi?id=1133874 } else { this.destroy(errCode(err, 'ERR_REMOVE_TRACK')) } } this._needsNegotiation() } /** * Remove a MediaStream from the connection. * @param {MediaStream} stream */ removeStream (stream) { this._debug('removeSenders()') stream.getTracks().forEach(track => { this.removeTrack(track, stream) }) } _needsNegotiation () { this._debug('_needsNegotiation') if (this._batchedNegotiation) return // batch synchronous renegotiations this._batchedNegotiation = true queueMicrotask(() => { this._batchedNegotiation = false if (this.initiator || !this._firstNegotiation) { this._debug('starting batched negotiation') this.negotiate() } else { this._debug('non-initiator initial negotiation request discarded') } this._firstNegotiation = false }) } negotiate () { if (this.initiator) { if (this._isNegotiating) { this._queuedNegotiation = true this._debug('already negotiating, queueing') } else { this._debug('start negotiation') setTimeout(() => { // HACK: Chrome crashes if we immediately call createOffer this._createOffer() }, 0) } } else { if (this._isNegotiating) { this._queuedNegotiation = true this._debug('already negotiating, queueing') } else { this._debug('requesting negotiation from initiator') this.emit('signal', { // request initiator to renegotiate type: 'renegotiate', renegotiate: true }) } } this._isNegotiating = true } // TODO: Delete this method once readable-stream is updated to contain a default // implementation of destroy() that automatically calls _destroy() // See: https://github.com/nodejs/readable-stream/issues/283 destroy (err) { this._destroy(err, () => {}) } _destroy (err, cb) { if (this.destroyed || this.destroying) return this.destroying = true this._debug('destroying (error: %s)', err && (err.message || err)) queueMicrotask(() => { // allow events concurrent with the call to _destroy() to fire (see #692) this.destroyed = true this.destroying = false this._debug('destroy (error: %s)', err && (err.message || err)) this.readable = this.writable = false if (!this._readableState.ended) this.push(null) if (!this._writableState.finished) this.end() this._connected = false this._pcReady = false this._channelReady = false this._remoteTracks = null this._remoteStreams = null this._senderMap = null clearInterval(this._closingInterval) this._closingInterval = null clearInterval(this._interval) this._interval = null this._chunk = null this._cb = null if (this._onFinishBound) this.removeListener('finish', this._onFinishBound) this._onFinishBound = null if (this._channel) { try { this._channel.close() } catch (err) {} // allow events concurrent with destruction to be handled this._channel.onmessage = null this._channel.onopen = null this._channel.onclose = null this._channel.onerror = null } if (this._pc) { try { this._pc.close() } catch (err) {} // allow events concurrent with destruction to be handled this._pc.oniceconnectionstatechange = null this._pc.onicegatheringstatechange = null this._pc.onsignalingstatechange = null this._pc.onicecandidate = null this._pc.ontrack = null this._pc.ondatachannel = null } this._pc = null this._channel = null if (err) this.emit('error', err) this.emit('close') cb() }) } _setupData (event) { if (!event.channel) { // In some situations `pc.createDataChannel()` returns `undefined` (in wrtc), // which is invalid behavior. Handle it gracefully. // See: https://github.com/feross/simple-peer/issues/163 return this.destroy(errCode(new Error('Data channel event is missing `channel` property'), 'ERR_DATA_CHANNEL')) } this._channel = event.channel this._channel.binaryType = 'arraybuffer' if (typeof this._channel.bufferedAmountLowThreshold === 'number') { this._channel.bufferedAmountLowThreshold = MAX_BUFFERED_AMOUNT } this.channelName = this._channel.label this._channel.onmessage = event => { this._onChannelMessage(event) } this._channel.onbufferedamountlow = () => { this._onChannelBufferedAmountLow() } this._channel.onopen = () => { this._onChannelOpen() } this._channel.onclose = () => { this._onChannelClose() } this._channel.onerror = err => { this.destroy(errCode(err, 'ERR_DATA_CHANNEL')) } // HACK: Chrome will sometimes get stuck in readyState "closing", let's check for this condition // https://bugs.chromium.org/p/chromium/issues/detail?id=882743 let isClosing = false this._closingInterval = setInterval(() => { // No "onclosing" event if (this._channel && this._channel.readyState === 'closing') { if (isClosing) this._onChannelClose() // closing timed out: equivalent to onclose firing isClosing = true } else { isClosing = false } }, CHANNEL_CLOSING_TIMEOUT) } _read () {} _write (chunk, encoding, cb) { if (this.destroyed) return cb(errCode(new Error('cannot write after peer is destroyed'), 'ERR_DATA_CHANNEL')) if (this._connected) { try { this.send(chunk) } catch (err) { return this.destroy(errCode(err, 'ERR_DATA_CHANNEL')) } if (this._channel.bufferedAmount > MAX_BUFFERED_AMOUNT) { this._debug('start backpressure: bufferedAmount %d', this._channel.bufferedAmount) this._cb = cb } else { cb(null) } } else { this._debug('write before connect') this._chunk = chunk this._cb = cb } } // When stream finishes writing, close socket. Half open connections are not // supported. _onFinish () { if (this.destroyed) return // Wait a bit before destroying so the socket flushes. // TODO: is there a more reliable way to accomplish this? const destroySoon = () => { setTimeout(() => this.destroy(), 1000) } if (this._connected) { destroySoon() } else { this.once('connect', destroySoon) } } _startIceCompleteTimeout () { if (this.destroyed) return if (this._iceCompleteTimer) return this._debug('started iceComplete timeout') this._iceCompleteTimer = setTimeout(() => { if (!this._iceComplete) { this._iceComplete = true this._debug('iceComplete timeout completed') this.emit('iceTimeout') this.emit('_iceComplete') } }, this.iceCompleteTimeout) } _createOffer () { if (this.destroyed) return this._pc.createOffer(this.offerOptions) .then(offer => { if (this.destroyed) return if (!this.trickle && !this.allowHalfTrickle) offer.sdp = filterTrickle(offer.sdp) offer.sdp = this.sdpTransform(offer.sdp) const sendOffer = () => { if (this.destroyed) return const signal = this._pc.localDescription || offer this._debug('signal') this.emit('signal', { type: signal.type, sdp: signal.sdp }) } const onSuccess = () => { this._debug('createOffer success') if (this.destroyed) return if (this.trickle || this._iceComplete) sendOffer() else this.once('_iceComplete', sendOffer) // wait for candidates } const onError = err => { this.destroy(errCode(err, 'ERR_SET_LOCAL_DESCRIPTION')) } this._pc.setLocalDescription(offer) .then(onSuccess) .catch(onError) }) .catch(err => { this.destroy(errCode(err, 'ERR_CREATE_OFFER')) }) } _requestMissingTransceivers () { if (this._pc.getTransceivers) { this._pc.getTransceivers().forEach(transceiver => { if (!transceiver.mid && transceiver.sender.track && !transceiver.requested) { transceiver.requested = true // HACK: Safari returns negotiated transceivers with a null mid this.addTransceiver(transceiver.sender.track.kind) } }) } } _createAnswer () { if (this.destroyed) return this._pc.createAnswer(this.answerOptions) .then(answer => { if (this.destroyed) return if (!this.trickle && !this.allowHalfTrickle) answer.sdp = filterTrickle(answer.sdp) answer.sdp = this.sdpTransform(answer.sdp) const sendAnswer = () => { if (this.destroyed) return const signal = this._pc.localDescription || answer this._debug('signal') this.emit('signal', { type: signal.type, sdp: signal.sdp }) if (!this.initiator) this._requestMissingTransceivers() } const onSuccess = () => { if (this.destroyed) return if (this.trickle || this._iceComplete) sendAnswer() else this.once('_iceComplete', sendAnswer) } const onError = err => { this.destroy(errCode(err, 'ERR_SET_LOCAL_DESCRIPTION')) } this._pc.setLocalDescription(answer) .then(onSuccess) .catch(onError) }) .catch(err => { this.destroy(errCode(err, 'ERR_CREATE_ANSWER')) }) } _onConnectionStateChange () { if (this.destroyed) return if (this._pc.connectionState === 'failed') { this.destroy(errCode(new Error('Connection failed.'), 'ERR_CONNECTION_FAILURE')) } } _onIceStateChange () { if (this.destroyed) return const iceConnectionState = this._pc.iceConnectionState const iceGatheringState = this._pc.iceGatheringState this._debug( 'iceStateChange (connection: %s) (gathering: %s)', iceConnectionState, iceGatheringState ) this.emit('iceStateChange', iceConnectionState, iceGatheringState) if (iceConnectionState === 'connected' || iceConnectionState === 'completed') { this._pcReady = true this._maybeReady() } if (iceConnectionState === 'failed') { this.destroy(errCode(new Error('Ice connection failed.'), 'ERR_ICE_CONNECTION_FAILURE')) } if (iceConnectionState === 'closed') { this.destroy(errCode(new Error('Ice connection closed.'), 'ERR_ICE_CONNECTION_CLOSED')) } } getStats (cb) { // statreports can come with a value array instead of properties const flattenValues = report => { if (Object.prototype.toString.call(report.values) === '[object Array]') { report.values.forEach(value => { Object.assign(report, value) }) } return report } // Promise-based getStats() (standard) if (this._pc.getStats.length === 0 || this._isReactNativeWebrtc) { this._pc.getStats() .then(res => { const reports = [] res.forEach(report => { reports.push(flattenValues(report)) }) cb(null, reports) }, err => cb(err)) // Single-parameter callback-based getStats() (non-standard) } else if (this._pc.getStats.length > 0) { this._pc.getStats(res => { // If we destroy connection in `connect` callback this code might happen to run when actual connection is already closed if (this.destroyed) return const reports = [] res.result().forEach(result => { const report = {} result.names().forEach(name => { report[name] = result.stat(name) }) report.id = result.id report.type = result.type report.timestamp = result.timestamp reports.push(flattenValues(report)) }) cb(null, reports) }, err => cb(err)) // Unknown browser, skip getStats() since it's anyone's guess which style of // getStats() they implement. } else { cb(null, []) } } _maybeReady () { this._debug('maybeReady pc %s channel %s', this._pcReady, this._channelReady) if (this._connected || this._connecting || !this._pcReady || !this._channelReady) return this._connecting = true // HACK: We can't rely on order here, for details see https://github.com/js-platform/node-webrtc/issues/339 const findCandidatePair = () => { if (this.destroyed) return this.getStats((err, items) => { if (this.destroyed) return // Treat getStats error as non-fatal. It's not essential. if (err) items = [] const remoteCandidates = {} const localCandidates = {} const candidatePairs = {} let foundSelectedCandidatePair = false items.forEach(item => { // TODO: Once all browsers support the hyphenated stats report types, remove // the non-hypenated ones if (item.type === 'remotecandidate' || item.type === 'remote-candidate') { remoteCandidates[item.id] = item } if (item.type === 'localcandidate' || item.type === 'local-candidate') { localCandidates[item.id] = item } if (item.type === 'candidatepair' || item.type === 'candidate-pair') { candidatePairs[item.id] = item } }) const setSelectedCandidatePair = selectedCandidatePair => { foundSelectedCandidatePair = true let local = localCandidates[selectedCandidatePair.localCandidateId] if (local && (local.ip || local.address)) { // Spec this.localAddress = local.ip || local.address this.localPort = Number(local.port) } else if (local && local.ipAddress) { // Firefox this.localAddress = local.ipAddress this.localPort = Number(local.portNumber) } else if (typeof selectedCandidatePair.googLocalAddress === 'string') { // TODO: remove this once Chrome 58 is released local = selectedCandidatePair.googLocalAddress.split(':') this.localAddress = local[0] this.localPort = Number(local[1]) } if (this.localAddress) { this.localFamily = this.localAddress.includes(':') ? 'IPv6' : 'IPv4' } let remote = remoteCandidates[selectedCandidatePair.remoteCandidateId] if (remote && (remote.ip || remote.address)) { // Spec this.remoteAddress = remote.ip || remote.address this.remotePort = Number(remote.port) } else if (remote && remote.ipAddress) { // Firefox this.remoteAddress = remote.ipAddress this.remotePort = Number(remote.portNumber) } else if (typeof selectedCandidatePair.googRemoteAddress === 'string') { // TODO: remove this once Chrome 58 is released remote = selectedCandidatePair.googRemoteAddress.split(':') this.remoteAddress = remote[0] this.remotePort = Number(remote[1]) } if (this.remoteAddress) { this.remoteFamily = this.remoteAddress.includes(':') ? 'IPv6' : 'IPv4' } this._debug( 'connect local: %s:%s remote: %s:%s', this.localAddress, this.localPort, this.remoteAddress, this.remotePort ) } items.forEach(item => { // Spec-compliant if (item.type === 'transport' && item.selectedCandidatePairId) { setSelectedCandidatePair(candidatePairs[item.selectedCandidatePairId]) } // Old implementations if ( (item.type === 'googCandidatePair' && item.googActiveConnection === 'true') || ((item.type === 'candidatepair' || item.type === 'candidate-pair') && item.selected) ) { setSelectedCandidatePair(item) } }) // Ignore candidate pair selection in browsers like Safari 11 that do not have any local or remote candidates // But wait until at least 1 candidate pair is available if (!foundSelectedCandidatePair && (!Object.keys(candidatePairs).length || Object.keys(localCandidates).length)) { setTimeout(findCandidatePair, 100) return } else { this._connecting = false this._connected = true } if (this._chunk) { try { this.send(this._chunk) } catch (err) { return this.destroy(errCode(err, 'ERR_DATA_CHANNEL')) } this._chunk = null this._debug('sent chunk from "write before connect"') const cb = this._cb this._cb = null cb(null) } // If `bufferedAmountLowThreshold` and 'onbufferedamountlow' are unsupported, // fallback to using setInterval to implement backpressure. if (typeof this._channel.bufferedAmountLowThreshold !== 'number') { this._interval = setInterval(() => this._onInterval(), 150) if (this._interval.unref) this._interval.unref() } this._debug('connect') this.emit('connect') }) } findCandidatePair() } _onInterval () { if (!this._cb || !this._channel || this._channel.bufferedAmount > MAX_BUFFERED_AMOUNT) { return } this._onChannelBufferedAmountLow() } _onSignalingStateChange () { if (this.destroyed) return if (this._pc.signalingState === 'stable') { this._isNegotiating = false // HACK: Firefox doesn't yet support removing tracks when signalingState !== 'stable' this._debug('flushing sender queue', this._sendersAwaitingStable) this._sendersAwaitingStable.forEach(sender => { this._pc.removeTrack(sender) this._queuedNegotiation = true }) this._sendersAwaitingStable = [] if (this._queuedNegotiation) { this._debug('flushing negotiation queue') this._queuedNegotiation = false this._needsNegotiation() // negotiate again } else { this._debug('negotiated') this.emit('negotiated') } } this._debug('signalingStateChange %s', this._pc.signalingState) this.emit('signalingStateChange', this._pc.signalingState) } _onIceCandidate (event) { if (this.destroyed) return if (event.candidate && this.trickle) { this.emit('signal', { type: 'candidate', candidate: { candidate: event.candidate.candidate, sdpMLineIndex: event.candidate.sdpMLineIndex, sdpMid: event.candidate.sdpMid } }) } else if (!event.candidate && !this._iceComplete) { this._iceComplete = true this.emit('_iceComplete') } // as soon as we've received one valid candidate start timeout if (event.candidate) { this._startIceCompleteTimeout() } } _onChannelMessage (event) { if (this.destroyed) return; if(event.data.constructor.name == "String"){ leenkx.network.Leenkx.data.set(RAWCHANNEL, event.data); leenkx.network.Leenkx.id.set(RAWCHANNEL, event.srcElement.label); leenkx.network.Leenkx.connections.h[RAWCHANNEL].onmessage(); return; } let data = event.data; if (data instanceof ArrayBuffer){ //console.log("Arrayy Buffer"); data = Buffer.from(data); } if (data instanceof Object){ //console.log("Objection!@"); this.push(data); return; } } _onChannelBufferedAmountLow () { if (this.destroyed || !this._cb) return this._debug('ending backpressure: bufferedAmount %d', this._channel.bufferedAmount) const cb = this._cb this._cb = null cb(null) } _onChannelOpen () { if (this._connected || this.destroyed) return this._debug('on channel open') this._channelReady = true this._maybeReady() leenkx.network.Leenkx.data.set(RAWCHANNEL, leenkx.network.Leenkx.connections.h[RAWCHANNEL].client.torrent._peersLength); leenkx.network.Leenkx.id.set(RAWCHANNEL, this.channelName); leenkx.network.Leenkx.connections.h[RAWCHANNEL].onopen(); } _onChannelClose () { if (this.destroyed) return this._debug('on channel close') leenkx.network.Leenkx.data.set(RAWCHANNEL, leenkx.network.Leenkx.connections.h[RAWCHANNEL].client.torrent._peersLength); leenkx.network.Leenkx.id.set(RAWCHANNEL, this.channelName); leenkx.network.Leenkx.connections.h[RAWCHANNEL].onclose(); this.destroy() } _onTrack (event) { if (this.destroyed) return event.streams.forEach(eventStream => { this._debug('on track') this.emit('track', event.track, eventStream) this._remoteTracks.push({ track: event.track, stream: eventStream }) if (this._remoteStreams.some(remoteStream => { return remoteStream.id === eventStream.id })) return // Only fire one 'stream' event, even though there may be multiple tracks per stream this._remoteStreams.push(eventStream) queueMicrotask(() => { this._debug('on stream') this.emit('stream', eventStream) // ensure all tracks have been added }) }) } _debug () { const args = [].slice.call(arguments) args[0] = '[' + this._id + '] ' + args[0] debug.apply(null, args) } } Peer.WEBRTC_SUPPORT = !!getBrowserRTC() /** * Expose peer and data channel config for overriding all Peer * instances. Otherwise, just set opts.config or opts.channelConfig * when constructing a Peer. */ Peer.config = { iceServers: [ { urls: [ 'stun:stun.l.google.com:19302', 'stun:global.stun.twilio.com:3478' ] } ], sdpSemantics: 'unified-plan' } Peer.channelConfig = { ordered: false, maxRetransmits: 0 } module.exports = Peer },{"buffer":331,"debug":238,"err-code":96,"get-browser-rtc":113,"queue-microtask":198,"randombytes":200,"readable-stream":255}],238:[function(require,module,exports){ arguments[4][11][0].apply(exports,arguments) },{"./common":239,"_process":338,"dup":11}],239:[function(require,module,exports){ arguments[4][12][0].apply(exports,arguments) },{"dup":12,"ms":240}],240:[function(require,module,exports){ arguments[4][13][0].apply(exports,arguments) },{"dup":13}],241:[function(require,module,exports){ arguments[4][14][0].apply(exports,arguments) },{"dup":14}],242:[function(require,module,exports){ arguments[4][15][0].apply(exports,arguments) },{"./_stream_readable":244,"./_stream_writable":246,"_process":338,"dup":15,"inherits":131}],243:[function(require,module,exports){ arguments[4][16][0].apply(exports,arguments) },{"./_stream_transform":245,"dup":16,"inherits":131}],244:[function(require,module,exports){ arguments[4][17][0].apply(exports,arguments) },{"../errors":241,"./_stream_duplex":242,"./internal/streams/async_iterator":247,"./internal/streams/buffer_list":248,"./internal/streams/destroy":249,"./internal/streams/from":251,"./internal/streams/state":253,"./internal/streams/stream":254,"_process":338,"buffer":331,"dup":17,"events":333,"inherits":131,"string_decoder/":281,"util":330}],245:[function(require,module,exports){ arguments[4][18][0].apply(exports,arguments) },{"../errors":241,"./_stream_duplex":242,"dup":18,"inherits":131}],246:[function(require,module,exports){ arguments[4][19][0].apply(exports,arguments) },{"../errors":241,"./_stream_duplex":242,"./internal/streams/destroy":249,"./internal/streams/state":253,"./internal/streams/stream":254,"_process":338,"buffer":331,"dup":19,"inherits":131,"util-deprecate":298}],247:[function(require,module,exports){ arguments[4][20][0].apply(exports,arguments) },{"./end-of-stream":250,"_process":338,"dup":20}],248:[function(require,module,exports){ arguments[4][21][0].apply(exports,arguments) },{"buffer":331,"dup":21,"util":330}],249:[function(require,module,exports){ arguments[4][22][0].apply(exports,arguments) },{"_process":338,"dup":22}],250:[function(require,module,exports){ arguments[4][23][0].apply(exports,arguments) },{"../../../errors":241,"dup":23}],251:[function(require,module,exports){ arguments[4][24][0].apply(exports,arguments) },{"dup":24}],252:[function(require,module,exports){ arguments[4][25][0].apply(exports,arguments) },{"../../../errors":241,"./end-of-stream":250,"dup":25}],253:[function(require,module,exports){ arguments[4][26][0].apply(exports,arguments) },{"../../../errors":241,"dup":26}],254:[function(require,module,exports){ arguments[4][27][0].apply(exports,arguments) },{"dup":27,"events":333}],255:[function(require,module,exports){ arguments[4][28][0].apply(exports,arguments) },{"./lib/_stream_duplex.js":242,"./lib/_stream_passthrough.js":243,"./lib/_stream_readable.js":244,"./lib/_stream_transform.js":245,"./lib/_stream_writable.js":246,"./lib/internal/streams/end-of-stream.js":250,"./lib/internal/streams/pipeline.js":252,"dup":28}],256:[function(require,module,exports){ /* global self */ var Rusha = require('rusha') var rushaWorkerSha1 = require('./rusha-worker-sha1') var rusha = new Rusha() var scope = typeof window !== 'undefined' ? window : self var crypto = scope.crypto || scope.msCrypto || {} var subtle = crypto.subtle || crypto.webkitSubtle function sha1sync (buf) { return rusha.digest(buf) } // Browsers throw if they lack support for an algorithm. // Promise will be rejected on non-secure origins. (http://goo.gl/lq4gCo) try { subtle.digest({ name: 'sha-1' }, new Uint8Array()).catch(function () { subtle = false }) } catch (err) { subtle = false } function sha1 (buf, cb) { if (!subtle) { if (typeof window !== 'undefined') { rushaWorkerSha1(buf, function onRushaWorkerSha1 (err, hash) { if (err) { // On error, fallback to synchronous method which cannot fail cb(sha1sync(buf)) return } cb(hash) }) } else { queueMicrotask(() => cb(sha1sync(buf))) } return } if (typeof buf === 'string') { buf = uint8array(buf) } subtle.digest({ name: 'sha-1' }, buf) .then(function succeed (result) { cb(hex(new Uint8Array(result))) }, function fail () { // On error, fallback to synchronous method which cannot fail cb(sha1sync(buf)) }) } function uint8array (s) { var l = s.length var array = new Uint8Array(l) for (var i = 0; i < l; i++) { array[i] = s.charCodeAt(i) } return array } function hex (buf) { var l = buf.length var chars = [] for (var i = 0; i < l; i++) { var bite = buf[i] chars.push((bite >>> 4).toString(16)) chars.push((bite & 0x0f).toString(16)) } return chars.join('') } module.exports = sha1 module.exports.sync = sha1sync },{"./rusha-worker-sha1":257,"rusha":225}],257:[function(require,module,exports){ var Rusha = require('rusha') var worker var nextTaskId var cbs function init () { worker = Rusha.createWorker() nextTaskId = 1 cbs = {} // taskId -> cb worker.onmessage = function onRushaMessage (e) { var taskId = e.data.id var cb = cbs[taskId] delete cbs[taskId] if (e.data.error != null) { cb(new Error('Rusha worker error: ' + e.data.error)) } else { cb(null, e.data.hash) } } } function sha1 (buf, cb) { if (!worker) init() cbs[nextTaskId] = cb worker.postMessage({ id: nextTaskId, data: buf }) nextTaskId += 1 } module.exports = sha1 },{"rusha":225}],258:[function(require,module,exports){ (function (Buffer){(function (){ /* global WebSocket, DOMException */ const debug = require('debug')('simple-websocket') const randombytes = require('randombytes') const stream = require('readable-stream') const queueMicrotask = require('queue-microtask') // TODO: remove when Node 10 is not supported const ws = require('ws') // websockets in node - will be empty object in browser const _WebSocket = typeof ws !== 'function' ? WebSocket : ws const MAX_BUFFERED_AMOUNT = 64 * 1024 /** * WebSocket. Same API as node core `net.Socket`. Duplex stream. * @param {Object} opts * @param {string=} opts.url websocket server url * @param {string=} opts.socket raw websocket instance to wrap */ class Socket extends stream.Duplex { constructor (opts = {}) { // Support simple usage: `new Socket(url)` if (typeof opts === 'string') { opts = { url: opts } } opts = Object.assign({ allowHalfOpen: false }, opts) super(opts) if (opts.url == null && opts.socket == null) { throw new Error('Missing required `url` or `socket` option') } if (opts.url != null && opts.socket != null) { throw new Error('Must specify either `url` or `socket` option, not both') } this._id = randombytes(4).toString('hex').slice(0, 7) this._debug('new websocket: %o', opts) this.connected = false this.destroyed = false this._chunk = null this._cb = null this._interval = null if (opts.socket) { this.url = opts.socket.url this._ws = opts.socket this.connected = opts.socket.readyState === _WebSocket.OPEN } else { this.url = opts.url try { if (typeof ws === 'function') { // `ws` package accepts options this._ws = new _WebSocket(opts.url, opts) } else { this._ws = new _WebSocket(opts.url) } } catch (err) { queueMicrotask(() => this.destroy(err)) return } } this._ws.binaryType = 'arraybuffer' this._ws.onopen = () => { this._onOpen() } this._ws.onmessage = event => { this._onMessage(event) } this._ws.onclose = () => { this._onClose() } this._ws.onerror = () => { this.destroy(new Error('connection error to ' + this.url)) } this._onFinishBound = () => { this._onFinish() } this.once('finish', this._onFinishBound) } /** * Send text/binary data to the WebSocket server. * @param {TypedArrayView|ArrayBuffer|Buffer|string|Blob|Object} chunk */ send (chunk) { this._ws.send(chunk) } // TODO: Delete this method once readable-stream is updated to contain a default // implementation of destroy() that automatically calls _destroy() // See: https://github.com/nodejs/readable-stream/issues/283 destroy (err) { this._destroy(err, () => {}) } _destroy (err, cb) { if (this.destroyed) return this._debug('destroy (error: %s)', err && (err.message || err)) this.readable = this.writable = false if (!this._readableState.ended) this.push(null) if (!this._writableState.finished) this.end() this.connected = false this.destroyed = true clearInterval(this._interval) this._interval = null this._chunk = null this._cb = null if (this._onFinishBound) this.removeListener('finish', this._onFinishBound) this._onFinishBound = null if (this._ws) { const ws = this._ws const onClose = () => { ws.onclose = null } if (ws.readyState === _WebSocket.CLOSED) { onClose() } else { try { ws.onclose = onClose ws.close() } catch (err) { onClose() } } ws.onopen = null ws.onmessage = null ws.onerror = () => {} } this._ws = null if (err) { if (typeof DOMException !== 'undefined' && err instanceof DOMException) { // Convert Edge DOMException object to Error object const code = err.code err = new Error(err.message) err.code = code } this.emit('error', err) } this.emit('close') cb() } _read () {} _write (chunk, encoding, cb) { if (this.destroyed) return cb(new Error('cannot write after socket is destroyed')) if (this.connected) { try { this.send(chunk) } catch (err) { return this.destroy(err) } if (typeof ws !== 'function' && this._ws.bufferedAmount > MAX_BUFFERED_AMOUNT) { this._debug('start backpressure: bufferedAmount %d', this._ws.bufferedAmount) this._cb = cb } else { cb(null) } } else { this._debug('write before connect') this._chunk = chunk this._cb = cb } } // When stream finishes writing, close socket. Half open connections are not // supported. _onFinish () { if (this.destroyed) return // Wait a bit before destroying so the socket flushes. // TODO: is there a more reliable way to accomplish this? const destroySoon = () => { setTimeout(() => this.destroy(), 1000) } if (this.connected) { destroySoon() } else { this.once('connect', destroySoon) } } _onMessage (event) { if (this.destroyed) return let data = event.data if (data instanceof ArrayBuffer) data = Buffer.from(data) this.push(data) } _onOpen () { if (this.connected || this.destroyed) return this.connected = true if (this._chunk) { try { this.send(this._chunk) } catch (err) { return this.destroy(err) } this._chunk = null this._debug('sent chunk from "write before connect"') const cb = this._cb this._cb = null cb(null) } // Backpressure is not implemented in Node.js. The `ws` module has a buggy // `bufferedAmount` property. See: https://github.com/websockets/ws/issues/492 if (typeof ws !== 'function') { this._interval = setInterval(() => this._onInterval(), 150) if (this._interval.unref) this._interval.unref() } this._debug('connect') this.emit('connect') } _onInterval () { if (!this._cb || !this._ws || this._ws.bufferedAmount > MAX_BUFFERED_AMOUNT) { return } this._debug('ending backpressure: bufferedAmount %d', this._ws.bufferedAmount) const cb = this._cb this._cb = null cb(null) } _onClose () { if (this.destroyed) return this._debug('on close') this.destroy() } _debug () { const args = [].slice.call(arguments) args[0] = '[' + this._id + '] ' + args[0] debug.apply(null, args) } } Socket.WEBSOCKET_SUPPORT = !!_WebSocket module.exports = Socket }).call(this)}).call(this,require("buffer").Buffer) },{"buffer":331,"debug":259,"queue-microtask":198,"randombytes":200,"readable-stream":276,"ws":330}],259:[function(require,module,exports){ arguments[4][11][0].apply(exports,arguments) },{"./common":260,"_process":338,"dup":11}],260:[function(require,module,exports){ arguments[4][12][0].apply(exports,arguments) },{"dup":12,"ms":261}],261:[function(require,module,exports){ arguments[4][13][0].apply(exports,arguments) },{"dup":13}],262:[function(require,module,exports){ arguments[4][14][0].apply(exports,arguments) },{"dup":14}],263:[function(require,module,exports){ arguments[4][15][0].apply(exports,arguments) },{"./_stream_readable":265,"./_stream_writable":267,"_process":338,"dup":15,"inherits":131}],264:[function(require,module,exports){ arguments[4][16][0].apply(exports,arguments) },{"./_stream_transform":266,"dup":16,"inherits":131}],265:[function(require,module,exports){ arguments[4][17][0].apply(exports,arguments) },{"../errors":262,"./_stream_duplex":263,"./internal/streams/async_iterator":268,"./internal/streams/buffer_list":269,"./internal/streams/destroy":270,"./internal/streams/from":272,"./internal/streams/state":274,"./internal/streams/stream":275,"_process":338,"buffer":331,"dup":17,"events":333,"inherits":131,"string_decoder/":281,"util":330}],266:[function(require,module,exports){ arguments[4][18][0].apply(exports,arguments) },{"../errors":262,"./_stream_duplex":263,"dup":18,"inherits":131}],267:[function(require,module,exports){ arguments[4][19][0].apply(exports,arguments) },{"../errors":262,"./_stream_duplex":263,"./internal/streams/destroy":270,"./internal/streams/state":274,"./internal/streams/stream":275,"_process":338,"buffer":331,"dup":19,"inherits":131,"util-deprecate":298}],268:[function(require,module,exports){ arguments[4][20][0].apply(exports,arguments) },{"./end-of-stream":271,"_process":338,"dup":20}],269:[function(require,module,exports){ arguments[4][21][0].apply(exports,arguments) },{"buffer":331,"dup":21,"util":330}],270:[function(require,module,exports){ arguments[4][22][0].apply(exports,arguments) },{"_process":338,"dup":22}],271:[function(require,module,exports){ arguments[4][23][0].apply(exports,arguments) },{"../../../errors":262,"dup":23}],272:[function(require,module,exports){ arguments[4][24][0].apply(exports,arguments) },{"dup":24}],273:[function(require,module,exports){ arguments[4][25][0].apply(exports,arguments) },{"../../../errors":262,"./end-of-stream":271,"dup":25}],274:[function(require,module,exports){ arguments[4][26][0].apply(exports,arguments) },{"../../../errors":262,"dup":26}],275:[function(require,module,exports){ arguments[4][27][0].apply(exports,arguments) },{"dup":27,"events":333}],276:[function(require,module,exports){ arguments[4][28][0].apply(exports,arguments) },{"./lib/_stream_duplex.js":263,"./lib/_stream_passthrough.js":264,"./lib/_stream_readable.js":265,"./lib/_stream_transform.js":266,"./lib/_stream_writable.js":267,"./lib/internal/streams/end-of-stream.js":271,"./lib/internal/streams/pipeline.js":273,"dup":28}],277:[function(require,module,exports){ var tick = 1 var maxTick = 65535 var resolution = 4 var timer var inc = function () { tick = (tick + 1) & maxTick } module.exports = function (seconds) { if (!timer) { timer = setInterval(inc, (1000 / resolution) | 0) if (timer.unref) timer.unref() } var size = resolution * (seconds || 5) var buffer = [0] var pointer = 1 var last = (tick - 1) & maxTick return function (delta) { var dist = (tick - last) & maxTick if (dist > size) dist = size last = tick while (dist--) { if (pointer === size) pointer = 0 buffer[pointer] = buffer[pointer === 0 ? size - 1 : pointer - 1] pointer++ } if (delta) buffer[pointer - 1] += delta var top = buffer[pointer - 1] var btm = buffer.length < size ? 0 : buffer[pointer === size ? 0 : pointer] return buffer.length < resolution ? top : (top - btm) * resolution / buffer.length } } },{}],278:[function(require,module,exports){ /*! stream-to-blob-url. MIT License. Feross Aboukhadijeh */ module.exports = getBlobURL const getBlob = require('stream-to-blob') async function getBlobURL (stream, mimeType) { const blob = await getBlob(stream, mimeType) const url = URL.createObjectURL(blob) return url } },{"stream-to-blob":279}],279:[function(require,module,exports){ /*! stream-to-blob. MIT License. Feross Aboukhadijeh */ /* global Blob */ module.exports = streamToBlob function streamToBlob (stream, mimeType) { if (mimeType != null && typeof mimeType !== 'string') { throw new Error('Invalid mimetype, expected string.') } return new Promise((resolve, reject) => { const chunks = [] stream .on('data', chunk => chunks.push(chunk)) .once('end', () => { const blob = mimeType != null ? new Blob(chunks, { type: mimeType }) : new Blob(chunks) resolve(blob) }) .once('error', reject) }) } },{}],280:[function(require,module,exports){ (function (Buffer){(function (){ /*! stream-with-known-length-to-buffer. MIT License. Feross Aboukhadijeh */ var once = require('once') module.exports = function getBuffer (stream, length, cb) { cb = once(cb) var buf = Buffer.alloc(length) var offset = 0 stream .on('data', function (chunk) { chunk.copy(buf, offset) offset += chunk.length }) .on('end', function () { cb(null, buf) }) .on('error', cb) } }).call(this)}).call(this,require("buffer").Buffer) },{"buffer":331,"once":194}],281:[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 Buffer = require('safe-buffer').Buffer; /**/ 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 = Buffer.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. If an invalid byte is detected, -2 is returned. 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 byte >> 6 === 0x02 ? -1 : -2; } // 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 || nb === -2) return 0; nb = utf8CheckByte(buf[j]); if (nb >= 0) { if (nb > 0) self.lastNeed = nb - 2; return nb; } if (--j < i || nb === -2) 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 // a single UTF-8 replacement character ('\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'; } if (self.lastNeed > 1 && buf.length > 1) { if ((buf[1] & 0xC0) !== 0x80) { self.lastNeed = 1; return '\ufffd'; } if (self.lastNeed > 2 && buf.length > 2) { if ((buf[2] & 0xC0) !== 0x80) { self.lastNeed = 2; return '\ufffd'; } } } } // 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 is added when ending on a partial // character. function utf8End(buf) { var r = buf && buf.length ? this.write(buf) : ''; if (this.lastNeed) return r + '\ufffd'; 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) : ''; } },{"safe-buffer":226}],282:[function(require,module,exports){ /* Copyright (c) 2011, Chris Umbel 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. */ var base32 = require('./thirty-two'); exports.encode = base32.encode; exports.decode = base32.decode; },{"./thirty-two":283}],283:[function(require,module,exports){ (function (Buffer){(function (){ /* Copyright (c) 2011, Chris Umbel 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 charTable = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"; var byteTable = [ 0xff, 0xff, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0xff, 0xff, 0xff, 0xff, 0xff ]; function quintetCount(buff) { var quintets = Math.floor(buff.length / 5); return buff.length % 5 === 0 ? quintets: quintets + 1; } exports.encode = function(plain) { if(!Buffer.isBuffer(plain)){ plain = new Buffer(plain); } var i = 0; var j = 0; var shiftIndex = 0; var digit = 0; var encoded = new Buffer(quintetCount(plain) * 8); /* byte by byte isn't as pretty as quintet by quintet but tests a bit faster. will have to revisit. */ while(i < plain.length) { var current = plain[i]; if(shiftIndex > 3) { digit = current & (0xff >> shiftIndex); shiftIndex = (shiftIndex + 5) % 8; digit = (digit << shiftIndex) | ((i + 1 < plain.length) ? plain[i + 1] : 0) >> (8 - shiftIndex); i++; } else { digit = (current >> (8 - (shiftIndex + 5))) & 0x1f; shiftIndex = (shiftIndex + 5) % 8; if(shiftIndex === 0) i++; } encoded[j] = charTable.charCodeAt(digit); j++; } for(i = j; i < encoded.length; i++) { encoded[i] = 0x3d; //'='.charCodeAt(0) } return encoded; }; exports.decode = function(encoded) { var shiftIndex = 0; var plainDigit = 0; var plainChar; var plainPos = 0; if(!Buffer.isBuffer(encoded)){ encoded = new Buffer(encoded); } var decoded = new Buffer(Math.ceil(encoded.length * 5 / 8)); /* byte by byte isn't as pretty as octet by octet but tests a bit faster. will have to revisit. */ for(var i = 0; i < encoded.length; i++) { if(encoded[i] === 0x3d){ //'=' break; } var encodedByte = encoded[i] - 0x30; if(encodedByte < byteTable.length) { plainDigit = byteTable[encodedByte]; if(shiftIndex <= 3) { shiftIndex = (shiftIndex + 5) % 8; if(shiftIndex === 0) { plainChar |= plainDigit; decoded[plainPos] = plainChar; plainPos++; plainChar = 0; } else { plainChar |= 0xff & (plainDigit << (8 - shiftIndex)); } } else { shiftIndex = (shiftIndex + 5) % 8; plainChar |= 0xff & (plainDigit >>> shiftIndex); decoded[plainPos] = plainChar; plainPos++; plainChar = 0xff & (plainDigit << (8 - shiftIndex)); } } else { throw new Error('Invalid input - it is not base32 encoded string'); } } return decoded.slice(0, plainPos); }; }).call(this)}).call(this,require("buffer").Buffer) },{"buffer":331}],284:[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":331}],285:[function(require,module,exports){ (function (process){(function (){ /*! torrent-discovery. MIT License. WebTorrent LLC */ const debug = require('debug')('torrent-discovery') const DHT = require('bittorrent-dht/client') // empty object in browser const EventEmitter = require('events').EventEmitter const parallel = require('run-parallel') const Tracker = require('bittorrent-tracker/client') const LSD = require('bittorrent-lsd') class Discovery extends EventEmitter { constructor (opts) { super() if (!opts.peerId) throw new Error('Option `peerId` is required') if (!opts.infoHash) throw new Error('Option `infoHash` is required') if (!process.browser && !opts.port) throw new Error('Option `port` is required') this.peerId = typeof opts.peerId === 'string' ? opts.peerId : opts.peerId.toString('hex') this.infoHash = typeof opts.infoHash === 'string' ? opts.infoHash.toLowerCase() : opts.infoHash.toString('hex') this._port = opts.port // torrent port this._userAgent = opts.userAgent // User-Agent header for http requests this.destroyed = false this._announce = opts.announce || [] this._intervalMs = opts.intervalMs || (15 * 60 * 1000) this._trackerOpts = null this._dhtAnnouncing = false this._dhtTimeout = false this._internalDHT = false // is the DHT created internally? this._onWarning = err => { this.emit('warning', err) } this._onError = err => { this.emit('error', err) } this._onDHTPeer = (peer, infoHash) => { if (infoHash.toString('hex') !== this.infoHash) return this.emit('peer', `${peer.host}:${peer.port}`, 'dht') } this._onTrackerPeer = peer => { this.emit('peer', peer, 'tracker') } this._onTrackerAnnounce = () => { this.emit('trackerAnnounce') } this._onLSDPeer = (peer, infoHash) => { this.emit('peer', peer, 'lsd') } const createDHT = (port, opts) => { const dht = new DHT(opts) dht.on('warning', this._onWarning) dht.on('error', this._onError) dht.listen(port) this._internalDHT = true return dht } if (opts.tracker === false) { this.tracker = null } else if (opts.tracker && typeof opts.tracker === 'object') { this._trackerOpts = Object.assign({}, opts.tracker) this.tracker = this._createTracker() } else { this.tracker = this._createTracker() } if (opts.dht === false || typeof DHT !== 'function') { this.dht = null } else if (opts.dht && typeof opts.dht.addNode === 'function') { this.dht = opts.dht } else if (opts.dht && typeof opts.dht === 'object') { this.dht = createDHT(opts.dhtPort, opts.dht) } else { this.dht = createDHT(opts.dhtPort) } if (this.dht) { this.dht.on('peer', this._onDHTPeer) this._dhtAnnounce() } if (opts.lsd === false || typeof LSD !== 'function') { this.lsd = null } else { this.lsd = this._createLSD() } } updatePort (port) { if (port === this._port) return this._port = port if (this.dht) this._dhtAnnounce() if (this.tracker) { this.tracker.stop() this.tracker.destroy(() => { this.tracker = this._createTracker() }) } } complete (opts) { if (this.tracker) { this.tracker.complete(opts) } } destroy (cb) { if (this.destroyed) return this.destroyed = true clearTimeout(this._dhtTimeout) const tasks = [] if (this.tracker) { this.tracker.stop() this.tracker.removeListener('warning', this._onWarning) this.tracker.removeListener('error', this._onError) this.tracker.removeListener('peer', this._onTrackerPeer) this.tracker.removeListener('update', this._onTrackerAnnounce) tasks.push(cb => { this.tracker.destroy(cb) }) } if (this.dht) { this.dht.removeListener('peer', this._onDHTPeer) } if (this._internalDHT) { this.dht.removeListener('warning', this._onWarning) this.dht.removeListener('error', this._onError) tasks.push(cb => { this.dht.destroy(cb) }) } if (this.lsd) { this.lsd.removeListener('warning', this._onWarning) this.lsd.removeListener('error', this._onError) this.lsd.removeListener('peer', this._onLSDPeer) tasks.push(cb => { this.lsd.destroy(cb) }) } parallel(tasks, cb) // cleanup this.dht = null this.tracker = null this.lsd = null this._announce = null } _createTracker () { const opts = Object.assign({}, this._trackerOpts, { infoHash: this.infoHash, announce: this._announce, peerId: this.peerId, port: this._port, userAgent: this._userAgent }) const tracker = new Tracker(opts) tracker.on('warning', this._onWarning) tracker.on('error', this._onError) tracker.on('peer', this._onTrackerPeer) tracker.on('update', this._onTrackerAnnounce) tracker.setInterval(this._intervalMs) tracker.start() return tracker } _dhtAnnounce () { if (this._dhtAnnouncing) return debug('dht announce') this._dhtAnnouncing = true clearTimeout(this._dhtTimeout) this.dht.announce(this.infoHash, this._port, err => { this._dhtAnnouncing = false debug('dht announce complete') if (err) this.emit('warning', err) this.emit('dhtAnnounce') if (!this.destroyed) { this._dhtTimeout = setTimeout(() => { this._dhtAnnounce() }, this._intervalMs + Math.floor(Math.random() * this._intervalMs / 5)) if (this._dhtTimeout.unref) this._dhtTimeout.unref() } }) } _createLSD () { const opts = Object.assign({}, { infoHash: this.infoHash, peerId: this.peerId, port: this._port }) const lsd = new LSD(opts) lsd.on('warning', this._onWarning) lsd.on('error', this._onError) lsd.on('peer', this._onLSDPeer) lsd.start() return lsd } } module.exports = Discovery }).call(this)}).call(this,require('_process')) },{"_process":338,"bittorrent-dht/client":330,"bittorrent-lsd":330,"bittorrent-tracker/client":29,"debug":286,"events":333,"run-parallel":224}],286:[function(require,module,exports){ arguments[4][11][0].apply(exports,arguments) },{"./common":287,"_process":338,"dup":11}],287:[function(require,module,exports){ arguments[4][12][0].apply(exports,arguments) },{"dup":12,"ms":288}],288:[function(require,module,exports){ arguments[4][13][0].apply(exports,arguments) },{"dup":13}],289:[function(require,module,exports){ (function (Buffer){(function (){ const BLOCK_LENGTH = 1 << 14 class Piece { constructor (length) { this.length = length this.missing = length this.sources = null this._chunks = Math.ceil(length / BLOCK_LENGTH) this._remainder = (length % BLOCK_LENGTH) || BLOCK_LENGTH this._buffered = 0 this._buffer = null this._cancellations = null this._reservations = 0 this._flushed = false } chunkLength (i) { return i === this._chunks - 1 ? this._remainder : BLOCK_LENGTH } chunkLengthRemaining (i) { return this.length - (i * BLOCK_LENGTH) } chunkOffset (i) { return i * BLOCK_LENGTH } reserve () { if (!this.init()) return -1 if (this._cancellations.length) return this._cancellations.pop() if (this._reservations < this._chunks) return this._reservations++ return -1 } reserveRemaining () { if (!this.init()) return -1 if (this._reservations < this._chunks) { const min = this._reservations this._reservations = this._chunks return min } return -1 } cancel (i) { if (!this.init()) return this._cancellations.push(i) } cancelRemaining (i) { if (!this.init()) return this._reservations = i } get (i) { if (!this.init()) return null return this._buffer[i] } set (i, data, source) { if (!this.init()) return false const len = data.length const blocks = Math.ceil(len / BLOCK_LENGTH) for (let j = 0; j < blocks; j++) { if (!this._buffer[i + j]) { const offset = j * BLOCK_LENGTH const splitData = data.slice(offset, offset + BLOCK_LENGTH) this._buffered++ this._buffer[i + j] = splitData this.missing -= splitData.length if (!this.sources.includes(source)) { this.sources.push(source) } } } return this._buffered === this._chunks } flush () { if (!this._buffer || this._chunks !== this._buffered) return null const buffer = Buffer.concat(this._buffer, this.length) this._buffer = null this._cancellations = null this.sources = null this._flushed = true return buffer } init () { if (this._flushed) return false if (this._buffer) return true this._buffer = new Array(this._chunks) this._cancellations = [] this.sources = [] return true } } Object.defineProperty(Piece, 'BLOCK_LENGTH', { value: BLOCK_LENGTH }) module.exports = Piece }).call(this)}).call(this,require("buffer").Buffer) },{"buffer":331}],290:[function(require,module,exports){ (function(nacl) { 'use strict'; // Ported in 2014 by Dmitry Chestnykh and Devi Mandiri. // Public domain. // // Implementation derived from TweetNaCl version 20140427. // See for details: http://tweetnacl.cr.yp.to/ var gf = function(init) { var i, r = new Float64Array(16); if (init) for (i = 0; i < init.length; i++) r[i] = init[i]; return r; }; // Pluggable, initialized in high-level API below. var randombytes = function(/* x, n */) { throw new Error('no PRNG'); }; var _0 = new Uint8Array(16); var _9 = new Uint8Array(32); _9[0] = 9; var gf0 = gf(), gf1 = gf([1]), _121665 = gf([0xdb41, 1]), D = gf([0x78a3, 0x1359, 0x4dca, 0x75eb, 0xd8ab, 0x4141, 0x0a4d, 0x0070, 0xe898, 0x7779, 0x4079, 0x8cc7, 0xfe73, 0x2b6f, 0x6cee, 0x5203]), D2 = gf([0xf159, 0x26b2, 0x9b94, 0xebd6, 0xb156, 0x8283, 0x149a, 0x00e0, 0xd130, 0xeef3, 0x80f2, 0x198e, 0xfce7, 0x56df, 0xd9dc, 0x2406]), X = gf([0xd51a, 0x8f25, 0x2d60, 0xc956, 0xa7b2, 0x9525, 0xc760, 0x692c, 0xdc5c, 0xfdd6, 0xe231, 0xc0a4, 0x53fe, 0xcd6e, 0x36d3, 0x2169]), Y = gf([0x6658, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666]), I = gf([0xa0b0, 0x4a0e, 0x1b27, 0xc4ee, 0xe478, 0xad2f, 0x1806, 0x2f43, 0xd7a7, 0x3dfb, 0x0099, 0x2b4d, 0xdf0b, 0x4fc1, 0x2480, 0x2b83]); function ts64(x, i, h, l) { x[i] = (h >> 24) & 0xff; x[i+1] = (h >> 16) & 0xff; x[i+2] = (h >> 8) & 0xff; x[i+3] = h & 0xff; x[i+4] = (l >> 24) & 0xff; x[i+5] = (l >> 16) & 0xff; x[i+6] = (l >> 8) & 0xff; x[i+7] = l & 0xff; } function vn(x, xi, y, yi, n) { var i,d = 0; for (i = 0; i < n; i++) d |= x[xi+i]^y[yi+i]; return (1 & ((d - 1) >>> 8)) - 1; } function crypto_verify_16(x, xi, y, yi) { return vn(x,xi,y,yi,16); } function crypto_verify_32(x, xi, y, yi) { return vn(x,xi,y,yi,32); } function core_salsa20(o, p, k, c) { var j0 = c[ 0] & 0xff | (c[ 1] & 0xff)<<8 | (c[ 2] & 0xff)<<16 | (c[ 3] & 0xff)<<24, j1 = k[ 0] & 0xff | (k[ 1] & 0xff)<<8 | (k[ 2] & 0xff)<<16 | (k[ 3] & 0xff)<<24, j2 = k[ 4] & 0xff | (k[ 5] & 0xff)<<8 | (k[ 6] & 0xff)<<16 | (k[ 7] & 0xff)<<24, j3 = k[ 8] & 0xff | (k[ 9] & 0xff)<<8 | (k[10] & 0xff)<<16 | (k[11] & 0xff)<<24, j4 = k[12] & 0xff | (k[13] & 0xff)<<8 | (k[14] & 0xff)<<16 | (k[15] & 0xff)<<24, j5 = c[ 4] & 0xff | (c[ 5] & 0xff)<<8 | (c[ 6] & 0xff)<<16 | (c[ 7] & 0xff)<<24, j6 = p[ 0] & 0xff | (p[ 1] & 0xff)<<8 | (p[ 2] & 0xff)<<16 | (p[ 3] & 0xff)<<24, j7 = p[ 4] & 0xff | (p[ 5] & 0xff)<<8 | (p[ 6] & 0xff)<<16 | (p[ 7] & 0xff)<<24, j8 = p[ 8] & 0xff | (p[ 9] & 0xff)<<8 | (p[10] & 0xff)<<16 | (p[11] & 0xff)<<24, j9 = p[12] & 0xff | (p[13] & 0xff)<<8 | (p[14] & 0xff)<<16 | (p[15] & 0xff)<<24, j10 = c[ 8] & 0xff | (c[ 9] & 0xff)<<8 | (c[10] & 0xff)<<16 | (c[11] & 0xff)<<24, j11 = k[16] & 0xff | (k[17] & 0xff)<<8 | (k[18] & 0xff)<<16 | (k[19] & 0xff)<<24, j12 = k[20] & 0xff | (k[21] & 0xff)<<8 | (k[22] & 0xff)<<16 | (k[23] & 0xff)<<24, j13 = k[24] & 0xff | (k[25] & 0xff)<<8 | (k[26] & 0xff)<<16 | (k[27] & 0xff)<<24, j14 = k[28] & 0xff | (k[29] & 0xff)<<8 | (k[30] & 0xff)<<16 | (k[31] & 0xff)<<24, j15 = c[12] & 0xff | (c[13] & 0xff)<<8 | (c[14] & 0xff)<<16 | (c[15] & 0xff)<<24; var x0 = j0, x1 = j1, x2 = j2, x3 = j3, x4 = j4, x5 = j5, x6 = j6, x7 = j7, x8 = j8, x9 = j9, x10 = j10, x11 = j11, x12 = j12, x13 = j13, x14 = j14, x15 = j15, u; for (var i = 0; i < 20; i += 2) { u = x0 + x12 | 0; x4 ^= u<<7 | u>>>(32-7); u = x4 + x0 | 0; x8 ^= u<<9 | u>>>(32-9); u = x8 + x4 | 0; x12 ^= u<<13 | u>>>(32-13); u = x12 + x8 | 0; x0 ^= u<<18 | u>>>(32-18); u = x5 + x1 | 0; x9 ^= u<<7 | u>>>(32-7); u = x9 + x5 | 0; x13 ^= u<<9 | u>>>(32-9); u = x13 + x9 | 0; x1 ^= u<<13 | u>>>(32-13); u = x1 + x13 | 0; x5 ^= u<<18 | u>>>(32-18); u = x10 + x6 | 0; x14 ^= u<<7 | u>>>(32-7); u = x14 + x10 | 0; x2 ^= u<<9 | u>>>(32-9); u = x2 + x14 | 0; x6 ^= u<<13 | u>>>(32-13); u = x6 + x2 | 0; x10 ^= u<<18 | u>>>(32-18); u = x15 + x11 | 0; x3 ^= u<<7 | u>>>(32-7); u = x3 + x15 | 0; x7 ^= u<<9 | u>>>(32-9); u = x7 + x3 | 0; x11 ^= u<<13 | u>>>(32-13); u = x11 + x7 | 0; x15 ^= u<<18 | u>>>(32-18); u = x0 + x3 | 0; x1 ^= u<<7 | u>>>(32-7); u = x1 + x0 | 0; x2 ^= u<<9 | u>>>(32-9); u = x2 + x1 | 0; x3 ^= u<<13 | u>>>(32-13); u = x3 + x2 | 0; x0 ^= u<<18 | u>>>(32-18); u = x5 + x4 | 0; x6 ^= u<<7 | u>>>(32-7); u = x6 + x5 | 0; x7 ^= u<<9 | u>>>(32-9); u = x7 + x6 | 0; x4 ^= u<<13 | u>>>(32-13); u = x4 + x7 | 0; x5 ^= u<<18 | u>>>(32-18); u = x10 + x9 | 0; x11 ^= u<<7 | u>>>(32-7); u = x11 + x10 | 0; x8 ^= u<<9 | u>>>(32-9); u = x8 + x11 | 0; x9 ^= u<<13 | u>>>(32-13); u = x9 + x8 | 0; x10 ^= u<<18 | u>>>(32-18); u = x15 + x14 | 0; x12 ^= u<<7 | u>>>(32-7); u = x12 + x15 | 0; x13 ^= u<<9 | u>>>(32-9); u = x13 + x12 | 0; x14 ^= u<<13 | u>>>(32-13); u = x14 + x13 | 0; x15 ^= u<<18 | u>>>(32-18); } x0 = x0 + j0 | 0; x1 = x1 + j1 | 0; x2 = x2 + j2 | 0; x3 = x3 + j3 | 0; x4 = x4 + j4 | 0; x5 = x5 + j5 | 0; x6 = x6 + j6 | 0; x7 = x7 + j7 | 0; x8 = x8 + j8 | 0; x9 = x9 + j9 | 0; x10 = x10 + j10 | 0; x11 = x11 + j11 | 0; x12 = x12 + j12 | 0; x13 = x13 + j13 | 0; x14 = x14 + j14 | 0; x15 = x15 + j15 | 0; o[ 0] = x0 >>> 0 & 0xff; o[ 1] = x0 >>> 8 & 0xff; o[ 2] = x0 >>> 16 & 0xff; o[ 3] = x0 >>> 24 & 0xff; o[ 4] = x1 >>> 0 & 0xff; o[ 5] = x1 >>> 8 & 0xff; o[ 6] = x1 >>> 16 & 0xff; o[ 7] = x1 >>> 24 & 0xff; o[ 8] = x2 >>> 0 & 0xff; o[ 9] = x2 >>> 8 & 0xff; o[10] = x2 >>> 16 & 0xff; o[11] = x2 >>> 24 & 0xff; o[12] = x3 >>> 0 & 0xff; o[13] = x3 >>> 8 & 0xff; o[14] = x3 >>> 16 & 0xff; o[15] = x3 >>> 24 & 0xff; o[16] = x4 >>> 0 & 0xff; o[17] = x4 >>> 8 & 0xff; o[18] = x4 >>> 16 & 0xff; o[19] = x4 >>> 24 & 0xff; o[20] = x5 >>> 0 & 0xff; o[21] = x5 >>> 8 & 0xff; o[22] = x5 >>> 16 & 0xff; o[23] = x5 >>> 24 & 0xff; o[24] = x6 >>> 0 & 0xff; o[25] = x6 >>> 8 & 0xff; o[26] = x6 >>> 16 & 0xff; o[27] = x6 >>> 24 & 0xff; o[28] = x7 >>> 0 & 0xff; o[29] = x7 >>> 8 & 0xff; o[30] = x7 >>> 16 & 0xff; o[31] = x7 >>> 24 & 0xff; o[32] = x8 >>> 0 & 0xff; o[33] = x8 >>> 8 & 0xff; o[34] = x8 >>> 16 & 0xff; o[35] = x8 >>> 24 & 0xff; o[36] = x9 >>> 0 & 0xff; o[37] = x9 >>> 8 & 0xff; o[38] = x9 >>> 16 & 0xff; o[39] = x9 >>> 24 & 0xff; o[40] = x10 >>> 0 & 0xff; o[41] = x10 >>> 8 & 0xff; o[42] = x10 >>> 16 & 0xff; o[43] = x10 >>> 24 & 0xff; o[44] = x11 >>> 0 & 0xff; o[45] = x11 >>> 8 & 0xff; o[46] = x11 >>> 16 & 0xff; o[47] = x11 >>> 24 & 0xff; o[48] = x12 >>> 0 & 0xff; o[49] = x12 >>> 8 & 0xff; o[50] = x12 >>> 16 & 0xff; o[51] = x12 >>> 24 & 0xff; o[52] = x13 >>> 0 & 0xff; o[53] = x13 >>> 8 & 0xff; o[54] = x13 >>> 16 & 0xff; o[55] = x13 >>> 24 & 0xff; o[56] = x14 >>> 0 & 0xff; o[57] = x14 >>> 8 & 0xff; o[58] = x14 >>> 16 & 0xff; o[59] = x14 >>> 24 & 0xff; o[60] = x15 >>> 0 & 0xff; o[61] = x15 >>> 8 & 0xff; o[62] = x15 >>> 16 & 0xff; o[63] = x15 >>> 24 & 0xff; } function core_hsalsa20(o,p,k,c) { var j0 = c[ 0] & 0xff | (c[ 1] & 0xff)<<8 | (c[ 2] & 0xff)<<16 | (c[ 3] & 0xff)<<24, j1 = k[ 0] & 0xff | (k[ 1] & 0xff)<<8 | (k[ 2] & 0xff)<<16 | (k[ 3] & 0xff)<<24, j2 = k[ 4] & 0xff | (k[ 5] & 0xff)<<8 | (k[ 6] & 0xff)<<16 | (k[ 7] & 0xff)<<24, j3 = k[ 8] & 0xff | (k[ 9] & 0xff)<<8 | (k[10] & 0xff)<<16 | (k[11] & 0xff)<<24, j4 = k[12] & 0xff | (k[13] & 0xff)<<8 | (k[14] & 0xff)<<16 | (k[15] & 0xff)<<24, j5 = c[ 4] & 0xff | (c[ 5] & 0xff)<<8 | (c[ 6] & 0xff)<<16 | (c[ 7] & 0xff)<<24, j6 = p[ 0] & 0xff | (p[ 1] & 0xff)<<8 | (p[ 2] & 0xff)<<16 | (p[ 3] & 0xff)<<24, j7 = p[ 4] & 0xff | (p[ 5] & 0xff)<<8 | (p[ 6] & 0xff)<<16 | (p[ 7] & 0xff)<<24, j8 = p[ 8] & 0xff | (p[ 9] & 0xff)<<8 | (p[10] & 0xff)<<16 | (p[11] & 0xff)<<24, j9 = p[12] & 0xff | (p[13] & 0xff)<<8 | (p[14] & 0xff)<<16 | (p[15] & 0xff)<<24, j10 = c[ 8] & 0xff | (c[ 9] & 0xff)<<8 | (c[10] & 0xff)<<16 | (c[11] & 0xff)<<24, j11 = k[16] & 0xff | (k[17] & 0xff)<<8 | (k[18] & 0xff)<<16 | (k[19] & 0xff)<<24, j12 = k[20] & 0xff | (k[21] & 0xff)<<8 | (k[22] & 0xff)<<16 | (k[23] & 0xff)<<24, j13 = k[24] & 0xff | (k[25] & 0xff)<<8 | (k[26] & 0xff)<<16 | (k[27] & 0xff)<<24, j14 = k[28] & 0xff | (k[29] & 0xff)<<8 | (k[30] & 0xff)<<16 | (k[31] & 0xff)<<24, j15 = c[12] & 0xff | (c[13] & 0xff)<<8 | (c[14] & 0xff)<<16 | (c[15] & 0xff)<<24; var x0 = j0, x1 = j1, x2 = j2, x3 = j3, x4 = j4, x5 = j5, x6 = j6, x7 = j7, x8 = j8, x9 = j9, x10 = j10, x11 = j11, x12 = j12, x13 = j13, x14 = j14, x15 = j15, u; for (var i = 0; i < 20; i += 2) { u = x0 + x12 | 0; x4 ^= u<<7 | u>>>(32-7); u = x4 + x0 | 0; x8 ^= u<<9 | u>>>(32-9); u = x8 + x4 | 0; x12 ^= u<<13 | u>>>(32-13); u = x12 + x8 | 0; x0 ^= u<<18 | u>>>(32-18); u = x5 + x1 | 0; x9 ^= u<<7 | u>>>(32-7); u = x9 + x5 | 0; x13 ^= u<<9 | u>>>(32-9); u = x13 + x9 | 0; x1 ^= u<<13 | u>>>(32-13); u = x1 + x13 | 0; x5 ^= u<<18 | u>>>(32-18); u = x10 + x6 | 0; x14 ^= u<<7 | u>>>(32-7); u = x14 + x10 | 0; x2 ^= u<<9 | u>>>(32-9); u = x2 + x14 | 0; x6 ^= u<<13 | u>>>(32-13); u = x6 + x2 | 0; x10 ^= u<<18 | u>>>(32-18); u = x15 + x11 | 0; x3 ^= u<<7 | u>>>(32-7); u = x3 + x15 | 0; x7 ^= u<<9 | u>>>(32-9); u = x7 + x3 | 0; x11 ^= u<<13 | u>>>(32-13); u = x11 + x7 | 0; x15 ^= u<<18 | u>>>(32-18); u = x0 + x3 | 0; x1 ^= u<<7 | u>>>(32-7); u = x1 + x0 | 0; x2 ^= u<<9 | u>>>(32-9); u = x2 + x1 | 0; x3 ^= u<<13 | u>>>(32-13); u = x3 + x2 | 0; x0 ^= u<<18 | u>>>(32-18); u = x5 + x4 | 0; x6 ^= u<<7 | u>>>(32-7); u = x6 + x5 | 0; x7 ^= u<<9 | u>>>(32-9); u = x7 + x6 | 0; x4 ^= u<<13 | u>>>(32-13); u = x4 + x7 | 0; x5 ^= u<<18 | u>>>(32-18); u = x10 + x9 | 0; x11 ^= u<<7 | u>>>(32-7); u = x11 + x10 | 0; x8 ^= u<<9 | u>>>(32-9); u = x8 + x11 | 0; x9 ^= u<<13 | u>>>(32-13); u = x9 + x8 | 0; x10 ^= u<<18 | u>>>(32-18); u = x15 + x14 | 0; x12 ^= u<<7 | u>>>(32-7); u = x12 + x15 | 0; x13 ^= u<<9 | u>>>(32-9); u = x13 + x12 | 0; x14 ^= u<<13 | u>>>(32-13); u = x14 + x13 | 0; x15 ^= u<<18 | u>>>(32-18); } o[ 0] = x0 >>> 0 & 0xff; o[ 1] = x0 >>> 8 & 0xff; o[ 2] = x0 >>> 16 & 0xff; o[ 3] = x0 >>> 24 & 0xff; o[ 4] = x5 >>> 0 & 0xff; o[ 5] = x5 >>> 8 & 0xff; o[ 6] = x5 >>> 16 & 0xff; o[ 7] = x5 >>> 24 & 0xff; o[ 8] = x10 >>> 0 & 0xff; o[ 9] = x10 >>> 8 & 0xff; o[10] = x10 >>> 16 & 0xff; o[11] = x10 >>> 24 & 0xff; o[12] = x15 >>> 0 & 0xff; o[13] = x15 >>> 8 & 0xff; o[14] = x15 >>> 16 & 0xff; o[15] = x15 >>> 24 & 0xff; o[16] = x6 >>> 0 & 0xff; o[17] = x6 >>> 8 & 0xff; o[18] = x6 >>> 16 & 0xff; o[19] = x6 >>> 24 & 0xff; o[20] = x7 >>> 0 & 0xff; o[21] = x7 >>> 8 & 0xff; o[22] = x7 >>> 16 & 0xff; o[23] = x7 >>> 24 & 0xff; o[24] = x8 >>> 0 & 0xff; o[25] = x8 >>> 8 & 0xff; o[26] = x8 >>> 16 & 0xff; o[27] = x8 >>> 24 & 0xff; o[28] = x9 >>> 0 & 0xff; o[29] = x9 >>> 8 & 0xff; o[30] = x9 >>> 16 & 0xff; o[31] = x9 >>> 24 & 0xff; } function crypto_core_salsa20(out,inp,k,c) { core_salsa20(out,inp,k,c); } function crypto_core_hsalsa20(out,inp,k,c) { core_hsalsa20(out,inp,k,c); } var sigma = new Uint8Array([101, 120, 112, 97, 110, 100, 32, 51, 50, 45, 98, 121, 116, 101, 32, 107]); // "expand 32-byte k" function crypto_stream_salsa20_xor(c,cpos,m,mpos,b,n,k) { var z = new Uint8Array(16), x = new Uint8Array(64); var u, i; for (i = 0; i < 16; i++) z[i] = 0; for (i = 0; i < 8; i++) z[i] = n[i]; while (b >= 64) { crypto_core_salsa20(x,z,k,sigma); for (i = 0; i < 64; i++) c[cpos+i] = m[mpos+i] ^ x[i]; u = 1; for (i = 8; i < 16; i++) { u = u + (z[i] & 0xff) | 0; z[i] = u & 0xff; u >>>= 8; } b -= 64; cpos += 64; mpos += 64; } if (b > 0) { crypto_core_salsa20(x,z,k,sigma); for (i = 0; i < b; i++) c[cpos+i] = m[mpos+i] ^ x[i]; } return 0; } function crypto_stream_salsa20(c,cpos,b,n,k) { var z = new Uint8Array(16), x = new Uint8Array(64); var u, i; for (i = 0; i < 16; i++) z[i] = 0; for (i = 0; i < 8; i++) z[i] = n[i]; while (b >= 64) { crypto_core_salsa20(x,z,k,sigma); for (i = 0; i < 64; i++) c[cpos+i] = x[i]; u = 1; for (i = 8; i < 16; i++) { u = u + (z[i] & 0xff) | 0; z[i] = u & 0xff; u >>>= 8; } b -= 64; cpos += 64; } if (b > 0) { crypto_core_salsa20(x,z,k,sigma); for (i = 0; i < b; i++) c[cpos+i] = x[i]; } return 0; } function crypto_stream(c,cpos,d,n,k) { var s = new Uint8Array(32); crypto_core_hsalsa20(s,n,k,sigma); var sn = new Uint8Array(8); for (var i = 0; i < 8; i++) sn[i] = n[i+16]; return crypto_stream_salsa20(c,cpos,d,sn,s); } function crypto_stream_xor(c,cpos,m,mpos,d,n,k) { var s = new Uint8Array(32); crypto_core_hsalsa20(s,n,k,sigma); var sn = new Uint8Array(8); for (var i = 0; i < 8; i++) sn[i] = n[i+16]; return crypto_stream_salsa20_xor(c,cpos,m,mpos,d,sn,s); } /* * Port of Andrew Moon's Poly1305-donna-16. Public domain. * https://github.com/floodyberry/poly1305-donna */ var poly1305 = function(key) { this.buffer = new Uint8Array(16); this.r = new Uint16Array(10); this.h = new Uint16Array(10); this.pad = new Uint16Array(8); this.leftover = 0; this.fin = 0; var t0, t1, t2, t3, t4, t5, t6, t7; t0 = key[ 0] & 0xff | (key[ 1] & 0xff) << 8; this.r[0] = ( t0 ) & 0x1fff; t1 = key[ 2] & 0xff | (key[ 3] & 0xff) << 8; this.r[1] = ((t0 >>> 13) | (t1 << 3)) & 0x1fff; t2 = key[ 4] & 0xff | (key[ 5] & 0xff) << 8; this.r[2] = ((t1 >>> 10) | (t2 << 6)) & 0x1f03; t3 = key[ 6] & 0xff | (key[ 7] & 0xff) << 8; this.r[3] = ((t2 >>> 7) | (t3 << 9)) & 0x1fff; t4 = key[ 8] & 0xff | (key[ 9] & 0xff) << 8; this.r[4] = ((t3 >>> 4) | (t4 << 12)) & 0x00ff; this.r[5] = ((t4 >>> 1)) & 0x1ffe; t5 = key[10] & 0xff | (key[11] & 0xff) << 8; this.r[6] = ((t4 >>> 14) | (t5 << 2)) & 0x1fff; t6 = key[12] & 0xff | (key[13] & 0xff) << 8; this.r[7] = ((t5 >>> 11) | (t6 << 5)) & 0x1f81; t7 = key[14] & 0xff | (key[15] & 0xff) << 8; this.r[8] = ((t6 >>> 8) | (t7 << 8)) & 0x1fff; this.r[9] = ((t7 >>> 5)) & 0x007f; this.pad[0] = key[16] & 0xff | (key[17] & 0xff) << 8; this.pad[1] = key[18] & 0xff | (key[19] & 0xff) << 8; this.pad[2] = key[20] & 0xff | (key[21] & 0xff) << 8; this.pad[3] = key[22] & 0xff | (key[23] & 0xff) << 8; this.pad[4] = key[24] & 0xff | (key[25] & 0xff) << 8; this.pad[5] = key[26] & 0xff | (key[27] & 0xff) << 8; this.pad[6] = key[28] & 0xff | (key[29] & 0xff) << 8; this.pad[7] = key[30] & 0xff | (key[31] & 0xff) << 8; }; poly1305.prototype.blocks = function(m, mpos, bytes) { var hibit = this.fin ? 0 : (1 << 11); var t0, t1, t2, t3, t4, t5, t6, t7, c; var d0, d1, d2, d3, d4, d5, d6, d7, d8, d9; var h0 = this.h[0], h1 = this.h[1], h2 = this.h[2], h3 = this.h[3], h4 = this.h[4], h5 = this.h[5], h6 = this.h[6], h7 = this.h[7], h8 = this.h[8], h9 = this.h[9]; var r0 = this.r[0], r1 = this.r[1], r2 = this.r[2], r3 = this.r[3], r4 = this.r[4], r5 = this.r[5], r6 = this.r[6], r7 = this.r[7], r8 = this.r[8], r9 = this.r[9]; while (bytes >= 16) { t0 = m[mpos+ 0] & 0xff | (m[mpos+ 1] & 0xff) << 8; h0 += ( t0 ) & 0x1fff; t1 = m[mpos+ 2] & 0xff | (m[mpos+ 3] & 0xff) << 8; h1 += ((t0 >>> 13) | (t1 << 3)) & 0x1fff; t2 = m[mpos+ 4] & 0xff | (m[mpos+ 5] & 0xff) << 8; h2 += ((t1 >>> 10) | (t2 << 6)) & 0x1fff; t3 = m[mpos+ 6] & 0xff | (m[mpos+ 7] & 0xff) << 8; h3 += ((t2 >>> 7) | (t3 << 9)) & 0x1fff; t4 = m[mpos+ 8] & 0xff | (m[mpos+ 9] & 0xff) << 8; h4 += ((t3 >>> 4) | (t4 << 12)) & 0x1fff; h5 += ((t4 >>> 1)) & 0x1fff; t5 = m[mpos+10] & 0xff | (m[mpos+11] & 0xff) << 8; h6 += ((t4 >>> 14) | (t5 << 2)) & 0x1fff; t6 = m[mpos+12] & 0xff | (m[mpos+13] & 0xff) << 8; h7 += ((t5 >>> 11) | (t6 << 5)) & 0x1fff; t7 = m[mpos+14] & 0xff | (m[mpos+15] & 0xff) << 8; h8 += ((t6 >>> 8) | (t7 << 8)) & 0x1fff; h9 += ((t7 >>> 5)) | hibit; c = 0; d0 = c; d0 += h0 * r0; d0 += h1 * (5 * r9); d0 += h2 * (5 * r8); d0 += h3 * (5 * r7); d0 += h4 * (5 * r6); c = (d0 >>> 13); d0 &= 0x1fff; d0 += h5 * (5 * r5); d0 += h6 * (5 * r4); d0 += h7 * (5 * r3); d0 += h8 * (5 * r2); d0 += h9 * (5 * r1); c += (d0 >>> 13); d0 &= 0x1fff; d1 = c; d1 += h0 * r1; d1 += h1 * r0; d1 += h2 * (5 * r9); d1 += h3 * (5 * r8); d1 += h4 * (5 * r7); c = (d1 >>> 13); d1 &= 0x1fff; d1 += h5 * (5 * r6); d1 += h6 * (5 * r5); d1 += h7 * (5 * r4); d1 += h8 * (5 * r3); d1 += h9 * (5 * r2); c += (d1 >>> 13); d1 &= 0x1fff; d2 = c; d2 += h0 * r2; d2 += h1 * r1; d2 += h2 * r0; d2 += h3 * (5 * r9); d2 += h4 * (5 * r8); c = (d2 >>> 13); d2 &= 0x1fff; d2 += h5 * (5 * r7); d2 += h6 * (5 * r6); d2 += h7 * (5 * r5); d2 += h8 * (5 * r4); d2 += h9 * (5 * r3); c += (d2 >>> 13); d2 &= 0x1fff; d3 = c; d3 += h0 * r3; d3 += h1 * r2; d3 += h2 * r1; d3 += h3 * r0; d3 += h4 * (5 * r9); c = (d3 >>> 13); d3 &= 0x1fff; d3 += h5 * (5 * r8); d3 += h6 * (5 * r7); d3 += h7 * (5 * r6); d3 += h8 * (5 * r5); d3 += h9 * (5 * r4); c += (d3 >>> 13); d3 &= 0x1fff; d4 = c; d4 += h0 * r4; d4 += h1 * r3; d4 += h2 * r2; d4 += h3 * r1; d4 += h4 * r0; c = (d4 >>> 13); d4 &= 0x1fff; d4 += h5 * (5 * r9); d4 += h6 * (5 * r8); d4 += h7 * (5 * r7); d4 += h8 * (5 * r6); d4 += h9 * (5 * r5); c += (d4 >>> 13); d4 &= 0x1fff; d5 = c; d5 += h0 * r5; d5 += h1 * r4; d5 += h2 * r3; d5 += h3 * r2; d5 += h4 * r1; c = (d5 >>> 13); d5 &= 0x1fff; d5 += h5 * r0; d5 += h6 * (5 * r9); d5 += h7 * (5 * r8); d5 += h8 * (5 * r7); d5 += h9 * (5 * r6); c += (d5 >>> 13); d5 &= 0x1fff; d6 = c; d6 += h0 * r6; d6 += h1 * r5; d6 += h2 * r4; d6 += h3 * r3; d6 += h4 * r2; c = (d6 >>> 13); d6 &= 0x1fff; d6 += h5 * r1; d6 += h6 * r0; d6 += h7 * (5 * r9); d6 += h8 * (5 * r8); d6 += h9 * (5 * r7); c += (d6 >>> 13); d6 &= 0x1fff; d7 = c; d7 += h0 * r7; d7 += h1 * r6; d7 += h2 * r5; d7 += h3 * r4; d7 += h4 * r3; c = (d7 >>> 13); d7 &= 0x1fff; d7 += h5 * r2; d7 += h6 * r1; d7 += h7 * r0; d7 += h8 * (5 * r9); d7 += h9 * (5 * r8); c += (d7 >>> 13); d7 &= 0x1fff; d8 = c; d8 += h0 * r8; d8 += h1 * r7; d8 += h2 * r6; d8 += h3 * r5; d8 += h4 * r4; c = (d8 >>> 13); d8 &= 0x1fff; d8 += h5 * r3; d8 += h6 * r2; d8 += h7 * r1; d8 += h8 * r0; d8 += h9 * (5 * r9); c += (d8 >>> 13); d8 &= 0x1fff; d9 = c; d9 += h0 * r9; d9 += h1 * r8; d9 += h2 * r7; d9 += h3 * r6; d9 += h4 * r5; c = (d9 >>> 13); d9 &= 0x1fff; d9 += h5 * r4; d9 += h6 * r3; d9 += h7 * r2; d9 += h8 * r1; d9 += h9 * r0; c += (d9 >>> 13); d9 &= 0x1fff; c = (((c << 2) + c)) | 0; c = (c + d0) | 0; d0 = c & 0x1fff; c = (c >>> 13); d1 += c; h0 = d0; h1 = d1; h2 = d2; h3 = d3; h4 = d4; h5 = d5; h6 = d6; h7 = d7; h8 = d8; h9 = d9; mpos += 16; bytes -= 16; } this.h[0] = h0; this.h[1] = h1; this.h[2] = h2; this.h[3] = h3; this.h[4] = h4; this.h[5] = h5; this.h[6] = h6; this.h[7] = h7; this.h[8] = h8; this.h[9] = h9; }; poly1305.prototype.finish = function(mac, macpos) { var g = new Uint16Array(10); var c, mask, f, i; if (this.leftover) { i = this.leftover; this.buffer[i++] = 1; for (; i < 16; i++) this.buffer[i] = 0; this.fin = 1; this.blocks(this.buffer, 0, 16); } c = this.h[1] >>> 13; this.h[1] &= 0x1fff; for (i = 2; i < 10; i++) { this.h[i] += c; c = this.h[i] >>> 13; this.h[i] &= 0x1fff; } this.h[0] += (c * 5); c = this.h[0] >>> 13; this.h[0] &= 0x1fff; this.h[1] += c; c = this.h[1] >>> 13; this.h[1] &= 0x1fff; this.h[2] += c; g[0] = this.h[0] + 5; c = g[0] >>> 13; g[0] &= 0x1fff; for (i = 1; i < 10; i++) { g[i] = this.h[i] + c; c = g[i] >>> 13; g[i] &= 0x1fff; } g[9] -= (1 << 13); mask = (c ^ 1) - 1; for (i = 0; i < 10; i++) g[i] &= mask; mask = ~mask; for (i = 0; i < 10; i++) this.h[i] = (this.h[i] & mask) | g[i]; this.h[0] = ((this.h[0] ) | (this.h[1] << 13) ) & 0xffff; this.h[1] = ((this.h[1] >>> 3) | (this.h[2] << 10) ) & 0xffff; this.h[2] = ((this.h[2] >>> 6) | (this.h[3] << 7) ) & 0xffff; this.h[3] = ((this.h[3] >>> 9) | (this.h[4] << 4) ) & 0xffff; this.h[4] = ((this.h[4] >>> 12) | (this.h[5] << 1) | (this.h[6] << 14)) & 0xffff; this.h[5] = ((this.h[6] >>> 2) | (this.h[7] << 11) ) & 0xffff; this.h[6] = ((this.h[7] >>> 5) | (this.h[8] << 8) ) & 0xffff; this.h[7] = ((this.h[8] >>> 8) | (this.h[9] << 5) ) & 0xffff; f = this.h[0] + this.pad[0]; this.h[0] = f & 0xffff; for (i = 1; i < 8; i++) { f = (((this.h[i] + this.pad[i]) | 0) + (f >>> 16)) | 0; this.h[i] = f & 0xffff; } mac[macpos+ 0] = (this.h[0] >>> 0) & 0xff; mac[macpos+ 1] = (this.h[0] >>> 8) & 0xff; mac[macpos+ 2] = (this.h[1] >>> 0) & 0xff; mac[macpos+ 3] = (this.h[1] >>> 8) & 0xff; mac[macpos+ 4] = (this.h[2] >>> 0) & 0xff; mac[macpos+ 5] = (this.h[2] >>> 8) & 0xff; mac[macpos+ 6] = (this.h[3] >>> 0) & 0xff; mac[macpos+ 7] = (this.h[3] >>> 8) & 0xff; mac[macpos+ 8] = (this.h[4] >>> 0) & 0xff; mac[macpos+ 9] = (this.h[4] >>> 8) & 0xff; mac[macpos+10] = (this.h[5] >>> 0) & 0xff; mac[macpos+11] = (this.h[5] >>> 8) & 0xff; mac[macpos+12] = (this.h[6] >>> 0) & 0xff; mac[macpos+13] = (this.h[6] >>> 8) & 0xff; mac[macpos+14] = (this.h[7] >>> 0) & 0xff; mac[macpos+15] = (this.h[7] >>> 8) & 0xff; }; poly1305.prototype.update = function(m, mpos, bytes) { var i, want; if (this.leftover) { want = (16 - this.leftover); if (want > bytes) want = bytes; for (i = 0; i < want; i++) this.buffer[this.leftover + i] = m[mpos+i]; bytes -= want; mpos += want; this.leftover += want; if (this.leftover < 16) return; this.blocks(this.buffer, 0, 16); this.leftover = 0; } if (bytes >= 16) { want = bytes - (bytes % 16); this.blocks(m, mpos, want); mpos += want; bytes -= want; } if (bytes) { for (i = 0; i < bytes; i++) this.buffer[this.leftover + i] = m[mpos+i]; this.leftover += bytes; } }; function crypto_onetimeauth(out, outpos, m, mpos, n, k) { var s = new poly1305(k); s.update(m, mpos, n); s.finish(out, outpos); return 0; } function crypto_onetimeauth_verify(h, hpos, m, mpos, n, k) { var x = new Uint8Array(16); crypto_onetimeauth(x,0,m,mpos,n,k); return crypto_verify_16(h,hpos,x,0); } function crypto_secretbox(c,m,d,n,k) { var i; if (d < 32) return -1; crypto_stream_xor(c,0,m,0,d,n,k); crypto_onetimeauth(c, 16, c, 32, d - 32, c); for (i = 0; i < 16; i++) c[i] = 0; return 0; } function crypto_secretbox_open(m,c,d,n,k) { var i; var x = new Uint8Array(32); if (d < 32) return -1; crypto_stream(x,0,32,n,k); if (crypto_onetimeauth_verify(c, 16,c, 32,d - 32,x) !== 0) return -1; crypto_stream_xor(m,0,c,0,d,n,k); for (i = 0; i < 32; i++) m[i] = 0; return 0; } function set25519(r, a) { var i; for (i = 0; i < 16; i++) r[i] = a[i]|0; } function car25519(o) { var i, v, c = 1; for (i = 0; i < 16; i++) { v = o[i] + c + 65535; c = Math.floor(v / 65536); o[i] = v - c * 65536; } o[0] += c-1 + 37 * (c-1); } function sel25519(p, q, b) { var t, c = ~(b-1); for (var i = 0; i < 16; i++) { t = c & (p[i] ^ q[i]); p[i] ^= t; q[i] ^= t; } } function pack25519(o, n) { var i, j, b; var m = gf(), t = gf(); for (i = 0; i < 16; i++) t[i] = n[i]; car25519(t); car25519(t); car25519(t); for (j = 0; j < 2; j++) { m[0] = t[0] - 0xffed; for (i = 1; i < 15; i++) { m[i] = t[i] - 0xffff - ((m[i-1]>>16) & 1); m[i-1] &= 0xffff; } m[15] = t[15] - 0x7fff - ((m[14]>>16) & 1); b = (m[15]>>16) & 1; m[14] &= 0xffff; sel25519(t, m, 1-b); } for (i = 0; i < 16; i++) { o[2*i] = t[i] & 0xff; o[2*i+1] = t[i]>>8; } } function neq25519(a, b) { var c = new Uint8Array(32), d = new Uint8Array(32); pack25519(c, a); pack25519(d, b); return crypto_verify_32(c, 0, d, 0); } function par25519(a) { var d = new Uint8Array(32); pack25519(d, a); return d[0] & 1; } function unpack25519(o, n) { var i; for (i = 0; i < 16; i++) o[i] = n[2*i] + (n[2*i+1] << 8); o[15] &= 0x7fff; } function A(o, a, b) { for (var i = 0; i < 16; i++) o[i] = a[i] + b[i]; } function Z(o, a, b) { for (var i = 0; i < 16; i++) o[i] = a[i] - b[i]; } function M(o, a, b) { var v, c, t0 = 0, t1 = 0, t2 = 0, t3 = 0, t4 = 0, t5 = 0, t6 = 0, t7 = 0, t8 = 0, t9 = 0, t10 = 0, t11 = 0, t12 = 0, t13 = 0, t14 = 0, t15 = 0, t16 = 0, t17 = 0, t18 = 0, t19 = 0, t20 = 0, t21 = 0, t22 = 0, t23 = 0, t24 = 0, t25 = 0, t26 = 0, t27 = 0, t28 = 0, t29 = 0, t30 = 0, b0 = b[0], b1 = b[1], b2 = b[2], b3 = b[3], b4 = b[4], b5 = b[5], b6 = b[6], b7 = b[7], b8 = b[8], b9 = b[9], b10 = b[10], b11 = b[11], b12 = b[12], b13 = b[13], b14 = b[14], b15 = b[15]; v = a[0]; t0 += v * b0; t1 += v * b1; t2 += v * b2; t3 += v * b3; t4 += v * b4; t5 += v * b5; t6 += v * b6; t7 += v * b7; t8 += v * b8; t9 += v * b9; t10 += v * b10; t11 += v * b11; t12 += v * b12; t13 += v * b13; t14 += v * b14; t15 += v * b15; v = a[1]; t1 += v * b0; t2 += v * b1; t3 += v * b2; t4 += v * b3; t5 += v * b4; t6 += v * b5; t7 += v * b6; t8 += v * b7; t9 += v * b8; t10 += v * b9; t11 += v * b10; t12 += v * b11; t13 += v * b12; t14 += v * b13; t15 += v * b14; t16 += v * b15; v = a[2]; t2 += v * b0; t3 += v * b1; t4 += v * b2; t5 += v * b3; t6 += v * b4; t7 += v * b5; t8 += v * b6; t9 += v * b7; t10 += v * b8; t11 += v * b9; t12 += v * b10; t13 += v * b11; t14 += v * b12; t15 += v * b13; t16 += v * b14; t17 += v * b15; v = a[3]; t3 += v * b0; t4 += v * b1; t5 += v * b2; t6 += v * b3; t7 += v * b4; t8 += v * b5; t9 += v * b6; t10 += v * b7; t11 += v * b8; t12 += v * b9; t13 += v * b10; t14 += v * b11; t15 += v * b12; t16 += v * b13; t17 += v * b14; t18 += v * b15; v = a[4]; t4 += v * b0; t5 += v * b1; t6 += v * b2; t7 += v * b3; t8 += v * b4; t9 += v * b5; t10 += v * b6; t11 += v * b7; t12 += v * b8; t13 += v * b9; t14 += v * b10; t15 += v * b11; t16 += v * b12; t17 += v * b13; t18 += v * b14; t19 += v * b15; v = a[5]; t5 += v * b0; t6 += v * b1; t7 += v * b2; t8 += v * b3; t9 += v * b4; t10 += v * b5; t11 += v * b6; t12 += v * b7; t13 += v * b8; t14 += v * b9; t15 += v * b10; t16 += v * b11; t17 += v * b12; t18 += v * b13; t19 += v * b14; t20 += v * b15; v = a[6]; t6 += v * b0; t7 += v * b1; t8 += v * b2; t9 += v * b3; t10 += v * b4; t11 += v * b5; t12 += v * b6; t13 += v * b7; t14 += v * b8; t15 += v * b9; t16 += v * b10; t17 += v * b11; t18 += v * b12; t19 += v * b13; t20 += v * b14; t21 += v * b15; v = a[7]; t7 += v * b0; t8 += v * b1; t9 += v * b2; t10 += v * b3; t11 += v * b4; t12 += v * b5; t13 += v * b6; t14 += v * b7; t15 += v * b8; t16 += v * b9; t17 += v * b10; t18 += v * b11; t19 += v * b12; t20 += v * b13; t21 += v * b14; t22 += v * b15; v = a[8]; t8 += v * b0; t9 += v * b1; t10 += v * b2; t11 += v * b3; t12 += v * b4; t13 += v * b5; t14 += v * b6; t15 += v * b7; t16 += v * b8; t17 += v * b9; t18 += v * b10; t19 += v * b11; t20 += v * b12; t21 += v * b13; t22 += v * b14; t23 += v * b15; v = a[9]; t9 += v * b0; t10 += v * b1; t11 += v * b2; t12 += v * b3; t13 += v * b4; t14 += v * b5; t15 += v * b6; t16 += v * b7; t17 += v * b8; t18 += v * b9; t19 += v * b10; t20 += v * b11; t21 += v * b12; t22 += v * b13; t23 += v * b14; t24 += v * b15; v = a[10]; t10 += v * b0; t11 += v * b1; t12 += v * b2; t13 += v * b3; t14 += v * b4; t15 += v * b5; t16 += v * b6; t17 += v * b7; t18 += v * b8; t19 += v * b9; t20 += v * b10; t21 += v * b11; t22 += v * b12; t23 += v * b13; t24 += v * b14; t25 += v * b15; v = a[11]; t11 += v * b0; t12 += v * b1; t13 += v * b2; t14 += v * b3; t15 += v * b4; t16 += v * b5; t17 += v * b6; t18 += v * b7; t19 += v * b8; t20 += v * b9; t21 += v * b10; t22 += v * b11; t23 += v * b12; t24 += v * b13; t25 += v * b14; t26 += v * b15; v = a[12]; t12 += v * b0; t13 += v * b1; t14 += v * b2; t15 += v * b3; t16 += v * b4; t17 += v * b5; t18 += v * b6; t19 += v * b7; t20 += v * b8; t21 += v * b9; t22 += v * b10; t23 += v * b11; t24 += v * b12; t25 += v * b13; t26 += v * b14; t27 += v * b15; v = a[13]; t13 += v * b0; t14 += v * b1; t15 += v * b2; t16 += v * b3; t17 += v * b4; t18 += v * b5; t19 += v * b6; t20 += v * b7; t21 += v * b8; t22 += v * b9; t23 += v * b10; t24 += v * b11; t25 += v * b12; t26 += v * b13; t27 += v * b14; t28 += v * b15; v = a[14]; t14 += v * b0; t15 += v * b1; t16 += v * b2; t17 += v * b3; t18 += v * b4; t19 += v * b5; t20 += v * b6; t21 += v * b7; t22 += v * b8; t23 += v * b9; t24 += v * b10; t25 += v * b11; t26 += v * b12; t27 += v * b13; t28 += v * b14; t29 += v * b15; v = a[15]; t15 += v * b0; t16 += v * b1; t17 += v * b2; t18 += v * b3; t19 += v * b4; t20 += v * b5; t21 += v * b6; t22 += v * b7; t23 += v * b8; t24 += v * b9; t25 += v * b10; t26 += v * b11; t27 += v * b12; t28 += v * b13; t29 += v * b14; t30 += v * b15; t0 += 38 * t16; t1 += 38 * t17; t2 += 38 * t18; t3 += 38 * t19; t4 += 38 * t20; t5 += 38 * t21; t6 += 38 * t22; t7 += 38 * t23; t8 += 38 * t24; t9 += 38 * t25; t10 += 38 * t26; t11 += 38 * t27; t12 += 38 * t28; t13 += 38 * t29; t14 += 38 * t30; // t15 left as is // first car c = 1; v = t0 + c + 65535; c = Math.floor(v / 65536); t0 = v - c * 65536; v = t1 + c + 65535; c = Math.floor(v / 65536); t1 = v - c * 65536; v = t2 + c + 65535; c = Math.floor(v / 65536); t2 = v - c * 65536; v = t3 + c + 65535; c = Math.floor(v / 65536); t3 = v - c * 65536; v = t4 + c + 65535; c = Math.floor(v / 65536); t4 = v - c * 65536; v = t5 + c + 65535; c = Math.floor(v / 65536); t5 = v - c * 65536; v = t6 + c + 65535; c = Math.floor(v / 65536); t6 = v - c * 65536; v = t7 + c + 65535; c = Math.floor(v / 65536); t7 = v - c * 65536; v = t8 + c + 65535; c = Math.floor(v / 65536); t8 = v - c * 65536; v = t9 + c + 65535; c = Math.floor(v / 65536); t9 = v - c * 65536; v = t10 + c + 65535; c = Math.floor(v / 65536); t10 = v - c * 65536; v = t11 + c + 65535; c = Math.floor(v / 65536); t11 = v - c * 65536; v = t12 + c + 65535; c = Math.floor(v / 65536); t12 = v - c * 65536; v = t13 + c + 65535; c = Math.floor(v / 65536); t13 = v - c * 65536; v = t14 + c + 65535; c = Math.floor(v / 65536); t14 = v - c * 65536; v = t15 + c + 65535; c = Math.floor(v / 65536); t15 = v - c * 65536; t0 += c-1 + 37 * (c-1); // second car c = 1; v = t0 + c + 65535; c = Math.floor(v / 65536); t0 = v - c * 65536; v = t1 + c + 65535; c = Math.floor(v / 65536); t1 = v - c * 65536; v = t2 + c + 65535; c = Math.floor(v / 65536); t2 = v - c * 65536; v = t3 + c + 65535; c = Math.floor(v / 65536); t3 = v - c * 65536; v = t4 + c + 65535; c = Math.floor(v / 65536); t4 = v - c * 65536; v = t5 + c + 65535; c = Math.floor(v / 65536); t5 = v - c * 65536; v = t6 + c + 65535; c = Math.floor(v / 65536); t6 = v - c * 65536; v = t7 + c + 65535; c = Math.floor(v / 65536); t7 = v - c * 65536; v = t8 + c + 65535; c = Math.floor(v / 65536); t8 = v - c * 65536; v = t9 + c + 65535; c = Math.floor(v / 65536); t9 = v - c * 65536; v = t10 + c + 65535; c = Math.floor(v / 65536); t10 = v - c * 65536; v = t11 + c + 65535; c = Math.floor(v / 65536); t11 = v - c * 65536; v = t12 + c + 65535; c = Math.floor(v / 65536); t12 = v - c * 65536; v = t13 + c + 65535; c = Math.floor(v / 65536); t13 = v - c * 65536; v = t14 + c + 65535; c = Math.floor(v / 65536); t14 = v - c * 65536; v = t15 + c + 65535; c = Math.floor(v / 65536); t15 = v - c * 65536; t0 += c-1 + 37 * (c-1); o[ 0] = t0; o[ 1] = t1; o[ 2] = t2; o[ 3] = t3; o[ 4] = t4; o[ 5] = t5; o[ 6] = t6; o[ 7] = t7; o[ 8] = t8; o[ 9] = t9; o[10] = t10; o[11] = t11; o[12] = t12; o[13] = t13; o[14] = t14; o[15] = t15; } function S(o, a) { M(o, a, a); } function inv25519(o, i) { var c = gf(); var a; for (a = 0; a < 16; a++) c[a] = i[a]; for (a = 253; a >= 0; a--) { S(c, c); if(a !== 2 && a !== 4) M(c, c, i); } for (a = 0; a < 16; a++) o[a] = c[a]; } function pow2523(o, i) { var c = gf(); var a; for (a = 0; a < 16; a++) c[a] = i[a]; for (a = 250; a >= 0; a--) { S(c, c); if(a !== 1) M(c, c, i); } for (a = 0; a < 16; a++) o[a] = c[a]; } function crypto_scalarmult(q, n, p) { var z = new Uint8Array(32); var x = new Float64Array(80), r, i; var a = gf(), b = gf(), c = gf(), d = gf(), e = gf(), f = gf(); for (i = 0; i < 31; i++) z[i] = n[i]; z[31]=(n[31]&127)|64; z[0]&=248; unpack25519(x,p); for (i = 0; i < 16; i++) { b[i]=x[i]; d[i]=a[i]=c[i]=0; } a[0]=d[0]=1; for (i=254; i>=0; --i) { r=(z[i>>>3]>>>(i&7))&1; sel25519(a,b,r); sel25519(c,d,r); A(e,a,c); Z(a,a,c); A(c,b,d); Z(b,b,d); S(d,e); S(f,a); M(a,c,a); M(c,b,e); A(e,a,c); Z(a,a,c); S(b,a); Z(c,d,f); M(a,c,_121665); A(a,a,d); M(c,c,a); M(a,d,f); M(d,b,x); S(b,e); sel25519(a,b,r); sel25519(c,d,r); } for (i = 0; i < 16; i++) { x[i+16]=a[i]; x[i+32]=c[i]; x[i+48]=b[i]; x[i+64]=d[i]; } var x32 = x.subarray(32); var x16 = x.subarray(16); inv25519(x32,x32); M(x16,x16,x32); pack25519(q,x16); return 0; } function crypto_scalarmult_base(q, n) { return crypto_scalarmult(q, n, _9); } function crypto_box_keypair(y, x) { randombytes(x, 32); return crypto_scalarmult_base(y, x); } function crypto_box_beforenm(k, y, x) { var s = new Uint8Array(32); crypto_scalarmult(s, x, y); return crypto_core_hsalsa20(k, _0, s, sigma); } var crypto_box_afternm = crypto_secretbox; var crypto_box_open_afternm = crypto_secretbox_open; function crypto_box(c, m, d, n, y, x) { var k = new Uint8Array(32); crypto_box_beforenm(k, y, x); return crypto_box_afternm(c, m, d, n, k); } function crypto_box_open(m, c, d, n, y, x) { var k = new Uint8Array(32); crypto_box_beforenm(k, y, x); return crypto_box_open_afternm(m, c, d, n, k); } var K = [ 0x428a2f98, 0xd728ae22, 0x71374491, 0x23ef65cd, 0xb5c0fbcf, 0xec4d3b2f, 0xe9b5dba5, 0x8189dbbc, 0x3956c25b, 0xf348b538, 0x59f111f1, 0xb605d019, 0x923f82a4, 0xaf194f9b, 0xab1c5ed5, 0xda6d8118, 0xd807aa98, 0xa3030242, 0x12835b01, 0x45706fbe, 0x243185be, 0x4ee4b28c, 0x550c7dc3, 0xd5ffb4e2, 0x72be5d74, 0xf27b896f, 0x80deb1fe, 0x3b1696b1, 0x9bdc06a7, 0x25c71235, 0xc19bf174, 0xcf692694, 0xe49b69c1, 0x9ef14ad2, 0xefbe4786, 0x384f25e3, 0x0fc19dc6, 0x8b8cd5b5, 0x240ca1cc, 0x77ac9c65, 0x2de92c6f, 0x592b0275, 0x4a7484aa, 0x6ea6e483, 0x5cb0a9dc, 0xbd41fbd4, 0x76f988da, 0x831153b5, 0x983e5152, 0xee66dfab, 0xa831c66d, 0x2db43210, 0xb00327c8, 0x98fb213f, 0xbf597fc7, 0xbeef0ee4, 0xc6e00bf3, 0x3da88fc2, 0xd5a79147, 0x930aa725, 0x06ca6351, 0xe003826f, 0x14292967, 0x0a0e6e70, 0x27b70a85, 0x46d22ffc, 0x2e1b2138, 0x5c26c926, 0x4d2c6dfc, 0x5ac42aed, 0x53380d13, 0x9d95b3df, 0x650a7354, 0x8baf63de, 0x766a0abb, 0x3c77b2a8, 0x81c2c92e, 0x47edaee6, 0x92722c85, 0x1482353b, 0xa2bfe8a1, 0x4cf10364, 0xa81a664b, 0xbc423001, 0xc24b8b70, 0xd0f89791, 0xc76c51a3, 0x0654be30, 0xd192e819, 0xd6ef5218, 0xd6990624, 0x5565a910, 0xf40e3585, 0x5771202a, 0x106aa070, 0x32bbd1b8, 0x19a4c116, 0xb8d2d0c8, 0x1e376c08, 0x5141ab53, 0x2748774c, 0xdf8eeb99, 0x34b0bcb5, 0xe19b48a8, 0x391c0cb3, 0xc5c95a63, 0x4ed8aa4a, 0xe3418acb, 0x5b9cca4f, 0x7763e373, 0x682e6ff3, 0xd6b2b8a3, 0x748f82ee, 0x5defb2fc, 0x78a5636f, 0x43172f60, 0x84c87814, 0xa1f0ab72, 0x8cc70208, 0x1a6439ec, 0x90befffa, 0x23631e28, 0xa4506ceb, 0xde82bde9, 0xbef9a3f7, 0xb2c67915, 0xc67178f2, 0xe372532b, 0xca273ece, 0xea26619c, 0xd186b8c7, 0x21c0c207, 0xeada7dd6, 0xcde0eb1e, 0xf57d4f7f, 0xee6ed178, 0x06f067aa, 0x72176fba, 0x0a637dc5, 0xa2c898a6, 0x113f9804, 0xbef90dae, 0x1b710b35, 0x131c471b, 0x28db77f5, 0x23047d84, 0x32caab7b, 0x40c72493, 0x3c9ebe0a, 0x15c9bebc, 0x431d67c4, 0x9c100d4c, 0x4cc5d4be, 0xcb3e42b6, 0x597f299c, 0xfc657e2a, 0x5fcb6fab, 0x3ad6faec, 0x6c44198c, 0x4a475817 ]; function crypto_hashblocks_hl(hh, hl, m, n) { var wh = new Int32Array(16), wl = new Int32Array(16), bh0, bh1, bh2, bh3, bh4, bh5, bh6, bh7, bl0, bl1, bl2, bl3, bl4, bl5, bl6, bl7, th, tl, i, j, h, l, a, b, c, d; var ah0 = hh[0], ah1 = hh[1], ah2 = hh[2], ah3 = hh[3], ah4 = hh[4], ah5 = hh[5], ah6 = hh[6], ah7 = hh[7], al0 = hl[0], al1 = hl[1], al2 = hl[2], al3 = hl[3], al4 = hl[4], al5 = hl[5], al6 = hl[6], al7 = hl[7]; var pos = 0; while (n >= 128) { for (i = 0; i < 16; i++) { j = 8 * i + pos; wh[i] = (m[j+0] << 24) | (m[j+1] << 16) | (m[j+2] << 8) | m[j+3]; wl[i] = (m[j+4] << 24) | (m[j+5] << 16) | (m[j+6] << 8) | m[j+7]; } for (i = 0; i < 80; i++) { bh0 = ah0; bh1 = ah1; bh2 = ah2; bh3 = ah3; bh4 = ah4; bh5 = ah5; bh6 = ah6; bh7 = ah7; bl0 = al0; bl1 = al1; bl2 = al2; bl3 = al3; bl4 = al4; bl5 = al5; bl6 = al6; bl7 = al7; // add h = ah7; l = al7; a = l & 0xffff; b = l >>> 16; c = h & 0xffff; d = h >>> 16; // Sigma1 h = ((ah4 >>> 14) | (al4 << (32-14))) ^ ((ah4 >>> 18) | (al4 << (32-18))) ^ ((al4 >>> (41-32)) | (ah4 << (32-(41-32)))); l = ((al4 >>> 14) | (ah4 << (32-14))) ^ ((al4 >>> 18) | (ah4 << (32-18))) ^ ((ah4 >>> (41-32)) | (al4 << (32-(41-32)))); a += l & 0xffff; b += l >>> 16; c += h & 0xffff; d += h >>> 16; // Ch h = (ah4 & ah5) ^ (~ah4 & ah6); l = (al4 & al5) ^ (~al4 & al6); a += l & 0xffff; b += l >>> 16; c += h & 0xffff; d += h >>> 16; // K h = K[i*2]; l = K[i*2+1]; a += l & 0xffff; b += l >>> 16; c += h & 0xffff; d += h >>> 16; // w h = wh[i%16]; l = wl[i%16]; a += l & 0xffff; b += l >>> 16; c += h & 0xffff; d += h >>> 16; b += a >>> 16; c += b >>> 16; d += c >>> 16; th = c & 0xffff | d << 16; tl = a & 0xffff | b << 16; // add h = th; l = tl; a = l & 0xffff; b = l >>> 16; c = h & 0xffff; d = h >>> 16; // Sigma0 h = ((ah0 >>> 28) | (al0 << (32-28))) ^ ((al0 >>> (34-32)) | (ah0 << (32-(34-32)))) ^ ((al0 >>> (39-32)) | (ah0 << (32-(39-32)))); l = ((al0 >>> 28) | (ah0 << (32-28))) ^ ((ah0 >>> (34-32)) | (al0 << (32-(34-32)))) ^ ((ah0 >>> (39-32)) | (al0 << (32-(39-32)))); a += l & 0xffff; b += l >>> 16; c += h & 0xffff; d += h >>> 16; // Maj h = (ah0 & ah1) ^ (ah0 & ah2) ^ (ah1 & ah2); l = (al0 & al1) ^ (al0 & al2) ^ (al1 & al2); a += l & 0xffff; b += l >>> 16; c += h & 0xffff; d += h >>> 16; b += a >>> 16; c += b >>> 16; d += c >>> 16; bh7 = (c & 0xffff) | (d << 16); bl7 = (a & 0xffff) | (b << 16); // add h = bh3; l = bl3; a = l & 0xffff; b = l >>> 16; c = h & 0xffff; d = h >>> 16; h = th; l = tl; a += l & 0xffff; b += l >>> 16; c += h & 0xffff; d += h >>> 16; b += a >>> 16; c += b >>> 16; d += c >>> 16; bh3 = (c & 0xffff) | (d << 16); bl3 = (a & 0xffff) | (b << 16); ah1 = bh0; ah2 = bh1; ah3 = bh2; ah4 = bh3; ah5 = bh4; ah6 = bh5; ah7 = bh6; ah0 = bh7; al1 = bl0; al2 = bl1; al3 = bl2; al4 = bl3; al5 = bl4; al6 = bl5; al7 = bl6; al0 = bl7; if (i%16 === 15) { for (j = 0; j < 16; j++) { // add h = wh[j]; l = wl[j]; a = l & 0xffff; b = l >>> 16; c = h & 0xffff; d = h >>> 16; h = wh[(j+9)%16]; l = wl[(j+9)%16]; a += l & 0xffff; b += l >>> 16; c += h & 0xffff; d += h >>> 16; // sigma0 th = wh[(j+1)%16]; tl = wl[(j+1)%16]; h = ((th >>> 1) | (tl << (32-1))) ^ ((th >>> 8) | (tl << (32-8))) ^ (th >>> 7); l = ((tl >>> 1) | (th << (32-1))) ^ ((tl >>> 8) | (th << (32-8))) ^ ((tl >>> 7) | (th << (32-7))); a += l & 0xffff; b += l >>> 16; c += h & 0xffff; d += h >>> 16; // sigma1 th = wh[(j+14)%16]; tl = wl[(j+14)%16]; h = ((th >>> 19) | (tl << (32-19))) ^ ((tl >>> (61-32)) | (th << (32-(61-32)))) ^ (th >>> 6); l = ((tl >>> 19) | (th << (32-19))) ^ ((th >>> (61-32)) | (tl << (32-(61-32)))) ^ ((tl >>> 6) | (th << (32-6))); a += l & 0xffff; b += l >>> 16; c += h & 0xffff; d += h >>> 16; b += a >>> 16; c += b >>> 16; d += c >>> 16; wh[j] = (c & 0xffff) | (d << 16); wl[j] = (a & 0xffff) | (b << 16); } } } // add h = ah0; l = al0; a = l & 0xffff; b = l >>> 16; c = h & 0xffff; d = h >>> 16; h = hh[0]; l = hl[0]; a += l & 0xffff; b += l >>> 16; c += h & 0xffff; d += h >>> 16; b += a >>> 16; c += b >>> 16; d += c >>> 16; hh[0] = ah0 = (c & 0xffff) | (d << 16); hl[0] = al0 = (a & 0xffff) | (b << 16); h = ah1; l = al1; a = l & 0xffff; b = l >>> 16; c = h & 0xffff; d = h >>> 16; h = hh[1]; l = hl[1]; a += l & 0xffff; b += l >>> 16; c += h & 0xffff; d += h >>> 16; b += a >>> 16; c += b >>> 16; d += c >>> 16; hh[1] = ah1 = (c & 0xffff) | (d << 16); hl[1] = al1 = (a & 0xffff) | (b << 16); h = ah2; l = al2; a = l & 0xffff; b = l >>> 16; c = h & 0xffff; d = h >>> 16; h = hh[2]; l = hl[2]; a += l & 0xffff; b += l >>> 16; c += h & 0xffff; d += h >>> 16; b += a >>> 16; c += b >>> 16; d += c >>> 16; hh[2] = ah2 = (c & 0xffff) | (d << 16); hl[2] = al2 = (a & 0xffff) | (b << 16); h = ah3; l = al3; a = l & 0xffff; b = l >>> 16; c = h & 0xffff; d = h >>> 16; h = hh[3]; l = hl[3]; a += l & 0xffff; b += l >>> 16; c += h & 0xffff; d += h >>> 16; b += a >>> 16; c += b >>> 16; d += c >>> 16; hh[3] = ah3 = (c & 0xffff) | (d << 16); hl[3] = al3 = (a & 0xffff) | (b << 16); h = ah4; l = al4; a = l & 0xffff; b = l >>> 16; c = h & 0xffff; d = h >>> 16; h = hh[4]; l = hl[4]; a += l & 0xffff; b += l >>> 16; c += h & 0xffff; d += h >>> 16; b += a >>> 16; c += b >>> 16; d += c >>> 16; hh[4] = ah4 = (c & 0xffff) | (d << 16); hl[4] = al4 = (a & 0xffff) | (b << 16); h = ah5; l = al5; a = l & 0xffff; b = l >>> 16; c = h & 0xffff; d = h >>> 16; h = hh[5]; l = hl[5]; a += l & 0xffff; b += l >>> 16; c += h & 0xffff; d += h >>> 16; b += a >>> 16; c += b >>> 16; d += c >>> 16; hh[5] = ah5 = (c & 0xffff) | (d << 16); hl[5] = al5 = (a & 0xffff) | (b << 16); h = ah6; l = al6; a = l & 0xffff; b = l >>> 16; c = h & 0xffff; d = h >>> 16; h = hh[6]; l = hl[6]; a += l & 0xffff; b += l >>> 16; c += h & 0xffff; d += h >>> 16; b += a >>> 16; c += b >>> 16; d += c >>> 16; hh[6] = ah6 = (c & 0xffff) | (d << 16); hl[6] = al6 = (a & 0xffff) | (b << 16); h = ah7; l = al7; a = l & 0xffff; b = l >>> 16; c = h & 0xffff; d = h >>> 16; h = hh[7]; l = hl[7]; a += l & 0xffff; b += l >>> 16; c += h & 0xffff; d += h >>> 16; b += a >>> 16; c += b >>> 16; d += c >>> 16; hh[7] = ah7 = (c & 0xffff) | (d << 16); hl[7] = al7 = (a & 0xffff) | (b << 16); pos += 128; n -= 128; } return n; } function crypto_hash(out, m, n) { var hh = new Int32Array(8), hl = new Int32Array(8), x = new Uint8Array(256), i, b = n; hh[0] = 0x6a09e667; hh[1] = 0xbb67ae85; hh[2] = 0x3c6ef372; hh[3] = 0xa54ff53a; hh[4] = 0x510e527f; hh[5] = 0x9b05688c; hh[6] = 0x1f83d9ab; hh[7] = 0x5be0cd19; hl[0] = 0xf3bcc908; hl[1] = 0x84caa73b; hl[2] = 0xfe94f82b; hl[3] = 0x5f1d36f1; hl[4] = 0xade682d1; hl[5] = 0x2b3e6c1f; hl[6] = 0xfb41bd6b; hl[7] = 0x137e2179; crypto_hashblocks_hl(hh, hl, m, n); n %= 128; for (i = 0; i < n; i++) x[i] = m[b-n+i]; x[n] = 128; n = 256-128*(n<112?1:0); x[n-9] = 0; ts64(x, n-8, (b / 0x20000000) | 0, b << 3); crypto_hashblocks_hl(hh, hl, x, n); for (i = 0; i < 8; i++) ts64(out, 8*i, hh[i], hl[i]); return 0; } function add(p, q) { var a = gf(), b = gf(), c = gf(), d = gf(), e = gf(), f = gf(), g = gf(), h = gf(), t = gf(); Z(a, p[1], p[0]); Z(t, q[1], q[0]); M(a, a, t); A(b, p[0], p[1]); A(t, q[0], q[1]); M(b, b, t); M(c, p[3], q[3]); M(c, c, D2); M(d, p[2], q[2]); A(d, d, d); Z(e, b, a); Z(f, d, c); A(g, d, c); A(h, b, a); M(p[0], e, f); M(p[1], h, g); M(p[2], g, f); M(p[3], e, h); } function cswap(p, q, b) { var i; for (i = 0; i < 4; i++) { sel25519(p[i], q[i], b); } } function pack(r, p) { var tx = gf(), ty = gf(), zi = gf(); inv25519(zi, p[2]); M(tx, p[0], zi); M(ty, p[1], zi); pack25519(r, ty); r[31] ^= par25519(tx) << 7; } function scalarmult(p, q, s) { var b, i; set25519(p[0], gf0); set25519(p[1], gf1); set25519(p[2], gf1); set25519(p[3], gf0); for (i = 255; i >= 0; --i) { b = (s[(i/8)|0] >> (i&7)) & 1; cswap(p, q, b); add(q, p); add(p, p); cswap(p, q, b); } } function scalarbase(p, s) { var q = [gf(), gf(), gf(), gf()]; set25519(q[0], X); set25519(q[1], Y); set25519(q[2], gf1); M(q[3], X, Y); scalarmult(p, q, s); } function crypto_sign_keypair(pk, sk, seeded) { var d = new Uint8Array(64); var p = [gf(), gf(), gf(), gf()]; var i; if (!seeded) randombytes(sk, 32); crypto_hash(d, sk, 32); d[0] &= 248; d[31] &= 127; d[31] |= 64; scalarbase(p, d); pack(pk, p); for (i = 0; i < 32; i++) sk[i+32] = pk[i]; return 0; } var L = new Float64Array([0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x10]); function modL(r, x) { var carry, i, j, k; for (i = 63; i >= 32; --i) { carry = 0; for (j = i - 32, k = i - 12; j < k; ++j) { x[j] += carry - 16 * x[i] * L[j - (i - 32)]; carry = Math.floor((x[j] + 128) / 256); x[j] -= carry * 256; } x[j] += carry; x[i] = 0; } carry = 0; for (j = 0; j < 32; j++) { x[j] += carry - (x[31] >> 4) * L[j]; carry = x[j] >> 8; x[j] &= 255; } for (j = 0; j < 32; j++) x[j] -= carry * L[j]; for (i = 0; i < 32; i++) { x[i+1] += x[i] >> 8; r[i] = x[i] & 255; } } function reduce(r) { var x = new Float64Array(64), i; for (i = 0; i < 64; i++) x[i] = r[i]; for (i = 0; i < 64; i++) r[i] = 0; modL(r, x); } // Note: difference from C - smlen returned, not passed as argument. function crypto_sign(sm, m, n, sk) { var d = new Uint8Array(64), h = new Uint8Array(64), r = new Uint8Array(64); var i, j, x = new Float64Array(64); var p = [gf(), gf(), gf(), gf()]; crypto_hash(d, sk, 32); d[0] &= 248; d[31] &= 127; d[31] |= 64; var smlen = n + 64; for (i = 0; i < n; i++) sm[64 + i] = m[i]; for (i = 0; i < 32; i++) sm[32 + i] = d[32 + i]; crypto_hash(r, sm.subarray(32), n+32); reduce(r); scalarbase(p, r); pack(sm, p); for (i = 32; i < 64; i++) sm[i] = sk[i]; crypto_hash(h, sm, n + 64); reduce(h); for (i = 0; i < 64; i++) x[i] = 0; for (i = 0; i < 32; i++) x[i] = r[i]; for (i = 0; i < 32; i++) { for (j = 0; j < 32; j++) { x[i+j] += h[i] * d[j]; } } modL(sm.subarray(32), x); return smlen; } function unpackneg(r, p) { var t = gf(), chk = gf(), num = gf(), den = gf(), den2 = gf(), den4 = gf(), den6 = gf(); set25519(r[2], gf1); unpack25519(r[1], p); S(num, r[1]); M(den, num, D); Z(num, num, r[2]); A(den, r[2], den); S(den2, den); S(den4, den2); M(den6, den4, den2); M(t, den6, num); M(t, t, den); pow2523(t, t); M(t, t, num); M(t, t, den); M(t, t, den); M(r[0], t, den); S(chk, r[0]); M(chk, chk, den); if (neq25519(chk, num)) M(r[0], r[0], I); S(chk, r[0]); M(chk, chk, den); if (neq25519(chk, num)) return -1; if (par25519(r[0]) === (p[31]>>7)) Z(r[0], gf0, r[0]); M(r[3], r[0], r[1]); return 0; } function crypto_sign_open(m, sm, n, pk) { var i; var t = new Uint8Array(32), h = new Uint8Array(64); var p = [gf(), gf(), gf(), gf()], q = [gf(), gf(), gf(), gf()]; if (n < 64) return -1; if (unpackneg(q, pk)) return -1; for (i = 0; i < n; i++) m[i] = sm[i]; for (i = 0; i < 32; i++) m[i+32] = pk[i]; crypto_hash(h, m, n); reduce(h); scalarmult(p, q, h); scalarbase(q, sm.subarray(32)); add(p, q); pack(t, p); n -= 64; if (crypto_verify_32(sm, 0, t, 0)) { for (i = 0; i < n; i++) m[i] = 0; return -1; } for (i = 0; i < n; i++) m[i] = sm[i + 64]; return n; } var crypto_secretbox_KEYBYTES = 32, crypto_secretbox_NONCEBYTES = 24, crypto_secretbox_ZEROBYTES = 32, crypto_secretbox_BOXZEROBYTES = 16, crypto_scalarmult_BYTES = 32, crypto_scalarmult_SCALARBYTES = 32, crypto_box_PUBLICKEYBYTES = 32, crypto_box_SECRETKEYBYTES = 32, crypto_box_BEFORENMBYTES = 32, crypto_box_NONCEBYTES = crypto_secretbox_NONCEBYTES, crypto_box_ZEROBYTES = crypto_secretbox_ZEROBYTES, crypto_box_BOXZEROBYTES = crypto_secretbox_BOXZEROBYTES, crypto_sign_BYTES = 64, crypto_sign_PUBLICKEYBYTES = 32, crypto_sign_SECRETKEYBYTES = 64, crypto_sign_SEEDBYTES = 32, crypto_hash_BYTES = 64; nacl.lowlevel = { crypto_core_hsalsa20: crypto_core_hsalsa20, crypto_stream_xor: crypto_stream_xor, crypto_stream: crypto_stream, crypto_stream_salsa20_xor: crypto_stream_salsa20_xor, crypto_stream_salsa20: crypto_stream_salsa20, crypto_onetimeauth: crypto_onetimeauth, crypto_onetimeauth_verify: crypto_onetimeauth_verify, crypto_verify_16: crypto_verify_16, crypto_verify_32: crypto_verify_32, crypto_secretbox: crypto_secretbox, crypto_secretbox_open: crypto_secretbox_open, crypto_scalarmult: crypto_scalarmult, crypto_scalarmult_base: crypto_scalarmult_base, crypto_box_beforenm: crypto_box_beforenm, crypto_box_afternm: crypto_box_afternm, crypto_box: crypto_box, crypto_box_open: crypto_box_open, crypto_box_keypair: crypto_box_keypair, crypto_hash: crypto_hash, crypto_sign: crypto_sign, crypto_sign_keypair: crypto_sign_keypair, crypto_sign_open: crypto_sign_open, crypto_secretbox_KEYBYTES: crypto_secretbox_KEYBYTES, crypto_secretbox_NONCEBYTES: crypto_secretbox_NONCEBYTES, crypto_secretbox_ZEROBYTES: crypto_secretbox_ZEROBYTES, crypto_secretbox_BOXZEROBYTES: crypto_secretbox_BOXZEROBYTES, crypto_scalarmult_BYTES: crypto_scalarmult_BYTES, crypto_scalarmult_SCALARBYTES: crypto_scalarmult_SCALARBYTES, crypto_box_PUBLICKEYBYTES: crypto_box_PUBLICKEYBYTES, crypto_box_SECRETKEYBYTES: crypto_box_SECRETKEYBYTES, crypto_box_BEFORENMBYTES: crypto_box_BEFORENMBYTES, crypto_box_NONCEBYTES: crypto_box_NONCEBYTES, crypto_box_ZEROBYTES: crypto_box_ZEROBYTES, crypto_box_BOXZEROBYTES: crypto_box_BOXZEROBYTES, crypto_sign_BYTES: crypto_sign_BYTES, crypto_sign_PUBLICKEYBYTES: crypto_sign_PUBLICKEYBYTES, crypto_sign_SECRETKEYBYTES: crypto_sign_SECRETKEYBYTES, crypto_sign_SEEDBYTES: crypto_sign_SEEDBYTES, crypto_hash_BYTES: crypto_hash_BYTES, gf: gf, D: D, L: L, pack25519: pack25519, unpack25519: unpack25519, M: M, A: A, S: S, Z: Z, pow2523: pow2523, add: add, set25519: set25519, modL: modL, scalarmult: scalarmult, scalarbase: scalarbase, }; /* High-level API */ function checkLengths(k, n) { if (k.length !== crypto_secretbox_KEYBYTES) throw new Error('bad key size'); if (n.length !== crypto_secretbox_NONCEBYTES) throw new Error('bad nonce size'); } function checkBoxLengths(pk, sk) { if (pk.length !== crypto_box_PUBLICKEYBYTES) throw new Error('bad public key size'); if (sk.length !== crypto_box_SECRETKEYBYTES) throw new Error('bad secret key size'); } function checkArrayTypes() { for (var i = 0; i < arguments.length; i++) { if (!(arguments[i] instanceof Uint8Array)) throw new TypeError('unexpected type, use Uint8Array'); } } function cleanup(arr) { for (var i = 0; i < arr.length; i++) arr[i] = 0; } nacl.randomBytes = function(n) { var b = new Uint8Array(n); randombytes(b, n); return b; }; nacl.secretbox = function(msg, nonce, key) { checkArrayTypes(msg, nonce, key); checkLengths(key, nonce); var m = new Uint8Array(crypto_secretbox_ZEROBYTES + msg.length); var c = new Uint8Array(m.length); for (var i = 0; i < msg.length; i++) m[i+crypto_secretbox_ZEROBYTES] = msg[i]; crypto_secretbox(c, m, m.length, nonce, key); return c.subarray(crypto_secretbox_BOXZEROBYTES); }; nacl.secretbox.open = function(box, nonce, key) { checkArrayTypes(box, nonce, key); checkLengths(key, nonce); var c = new Uint8Array(crypto_secretbox_BOXZEROBYTES + box.length); var m = new Uint8Array(c.length); for (var i = 0; i < box.length; i++) c[i+crypto_secretbox_BOXZEROBYTES] = box[i]; if (c.length < 32) return null; if (crypto_secretbox_open(m, c, c.length, nonce, key) !== 0) return null; return m.subarray(crypto_secretbox_ZEROBYTES); }; nacl.secretbox.keyLength = crypto_secretbox_KEYBYTES; nacl.secretbox.nonceLength = crypto_secretbox_NONCEBYTES; nacl.secretbox.overheadLength = crypto_secretbox_BOXZEROBYTES; nacl.scalarMult = function(n, p) { checkArrayTypes(n, p); if (n.length !== crypto_scalarmult_SCALARBYTES) throw new Error('bad n size'); if (p.length !== crypto_scalarmult_BYTES) throw new Error('bad p size'); var q = new Uint8Array(crypto_scalarmult_BYTES); crypto_scalarmult(q, n, p); return q; }; nacl.scalarMult.base = function(n) { checkArrayTypes(n); if (n.length !== crypto_scalarmult_SCALARBYTES) throw new Error('bad n size'); var q = new Uint8Array(crypto_scalarmult_BYTES); crypto_scalarmult_base(q, n); return q; }; nacl.scalarMult.scalarLength = crypto_scalarmult_SCALARBYTES; nacl.scalarMult.groupElementLength = crypto_scalarmult_BYTES; nacl.box = function(msg, nonce, publicKey, secretKey) { var k = nacl.box.before(publicKey, secretKey); return nacl.secretbox(msg, nonce, k); }; nacl.box.before = function(publicKey, secretKey) { checkArrayTypes(publicKey, secretKey); checkBoxLengths(publicKey, secretKey); var k = new Uint8Array(crypto_box_BEFORENMBYTES); crypto_box_beforenm(k, publicKey, secretKey); return k; }; nacl.box.after = nacl.secretbox; nacl.box.open = function(msg, nonce, publicKey, secretKey) { var k = nacl.box.before(publicKey, secretKey); return nacl.secretbox.open(msg, nonce, k); }; nacl.box.open.after = nacl.secretbox.open; nacl.box.keyPair = function() { var pk = new Uint8Array(crypto_box_PUBLICKEYBYTES); var sk = new Uint8Array(crypto_box_SECRETKEYBYTES); crypto_box_keypair(pk, sk); return {publicKey: pk, secretKey: sk}; }; nacl.box.keyPair.fromSecretKey = function(secretKey) { checkArrayTypes(secretKey); if (secretKey.length !== crypto_box_SECRETKEYBYTES) throw new Error('bad secret key size'); var pk = new Uint8Array(crypto_box_PUBLICKEYBYTES); crypto_scalarmult_base(pk, secretKey); return {publicKey: pk, secretKey: new Uint8Array(secretKey)}; }; nacl.box.publicKeyLength = crypto_box_PUBLICKEYBYTES; nacl.box.secretKeyLength = crypto_box_SECRETKEYBYTES; nacl.box.sharedKeyLength = crypto_box_BEFORENMBYTES; nacl.box.nonceLength = crypto_box_NONCEBYTES; nacl.box.overheadLength = nacl.secretbox.overheadLength; nacl.sign = function(msg, secretKey) { checkArrayTypes(msg, secretKey); if (secretKey.length !== crypto_sign_SECRETKEYBYTES) throw new Error('bad secret key size'); var signedMsg = new Uint8Array(crypto_sign_BYTES+msg.length); crypto_sign(signedMsg, msg, msg.length, secretKey); return signedMsg; }; nacl.sign.open = function(signedMsg, publicKey) { checkArrayTypes(signedMsg, publicKey); if (publicKey.length !== crypto_sign_PUBLICKEYBYTES) throw new Error('bad public key size'); var tmp = new Uint8Array(signedMsg.length); var mlen = crypto_sign_open(tmp, signedMsg, signedMsg.length, publicKey); if (mlen < 0) return null; var m = new Uint8Array(mlen); for (var i = 0; i < m.length; i++) m[i] = tmp[i]; return m; }; nacl.sign.detached = function(msg, secretKey) { var signedMsg = nacl.sign(msg, secretKey); var sig = new Uint8Array(crypto_sign_BYTES); for (var i = 0; i < sig.length; i++) sig[i] = signedMsg[i]; return sig; }; nacl.sign.detached.verify = function(msg, sig, publicKey) { checkArrayTypes(msg, sig, publicKey); if (sig.length !== crypto_sign_BYTES) throw new Error('bad signature size'); if (publicKey.length !== crypto_sign_PUBLICKEYBYTES) throw new Error('bad public key size'); var sm = new Uint8Array(crypto_sign_BYTES + msg.length); var m = new Uint8Array(crypto_sign_BYTES + msg.length); var i; for (i = 0; i < crypto_sign_BYTES; i++) sm[i] = sig[i]; for (i = 0; i < msg.length; i++) sm[i+crypto_sign_BYTES] = msg[i]; return (crypto_sign_open(m, sm, sm.length, publicKey) >= 0); }; nacl.sign.keyPair = function() { var pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES); var sk = new Uint8Array(crypto_sign_SECRETKEYBYTES); crypto_sign_keypair(pk, sk); return {publicKey: pk, secretKey: sk}; }; nacl.sign.keyPair.fromSecretKey = function(secretKey) { checkArrayTypes(secretKey); if (secretKey.length !== crypto_sign_SECRETKEYBYTES) throw new Error('bad secret key size'); var pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES); for (var i = 0; i < pk.length; i++) pk[i] = secretKey[32+i]; return {publicKey: pk, secretKey: new Uint8Array(secretKey)}; }; nacl.sign.keyPair.fromSeed = function(seed) { checkArrayTypes(seed); if (seed.length !== crypto_sign_SEEDBYTES) throw new Error('bad seed size'); var pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES); var sk = new Uint8Array(crypto_sign_SECRETKEYBYTES); for (var i = 0; i < 32; i++) sk[i] = seed[i]; crypto_sign_keypair(pk, sk, true); return {publicKey: pk, secretKey: sk}; }; nacl.sign.publicKeyLength = crypto_sign_PUBLICKEYBYTES; nacl.sign.secretKeyLength = crypto_sign_SECRETKEYBYTES; nacl.sign.seedLength = crypto_sign_SEEDBYTES; nacl.sign.signatureLength = crypto_sign_BYTES; nacl.hash = function(msg) { checkArrayTypes(msg); var h = new Uint8Array(crypto_hash_BYTES); crypto_hash(h, msg, msg.length); return h; }; nacl.hash.hashLength = crypto_hash_BYTES; nacl.verify = function(x, y) { checkArrayTypes(x, y); // Zero length arguments are considered not equal. if (x.length === 0 || y.length === 0) return false; if (x.length !== y.length) return false; return (vn(x, 0, y, 0, x.length) === 0) ? true : false; }; nacl.setPRNG = function(fn) { randombytes = fn; }; (function() { // Initialize PRNG if environment provides CSPRNG. // If not, methods calling randombytes will throw. var crypto = typeof self !== 'undefined' ? (self.crypto || self.msCrypto) : null; if (crypto && crypto.getRandomValues) { // Browsers. var QUOTA = 65536; nacl.setPRNG(function(x, n) { var i, v = new Uint8Array(n); for (i = 0; i < n; i += QUOTA) { crypto.getRandomValues(v.subarray(i, i + Math.min(n - i, QUOTA))); } for (i = 0; i < n; i++) x[i] = v[i]; cleanup(v); }); } else if (typeof require !== 'undefined') { // Node.js. crypto = require('crypto'); if (crypto && crypto.randomBytes) { nacl.setPRNG(function(x, n) { var i, v = crypto.randomBytes(n); for (i = 0; i < n; i++) x[i] = v[i]; cleanup(v); }); } } })(); })(typeof module !== 'undefined' && module.exports ? module.exports : (self.nacl = self.nacl || {})); },{"crypto":330}],291:[function(require,module,exports){ (function (Buffer){(function (){ /** * Convert a typed array to a Buffer without a copy * * Author: Feross Aboukhadijeh * License: MIT * * `npm install typedarray-to-buffer` */ var isTypedArray = require('is-typedarray').strict module.exports = function typedarrayToBuffer (arr) { if (isTypedArray(arr)) { // To avoid a copy, use the typed array's underlying ArrayBuffer to back new Buffer var buf = Buffer.from(arr.buffer) if (arr.byteLength !== arr.buffer.byteLength) { // Respect the "view", i.e. byteOffset and byteLength, without doing a copy buf = buf.slice(arr.byteOffset, arr.byteOffset + arr.byteLength) } return buf } else { // Pass through all other types to `Buffer.from` return Buffer.from(arr) } } }).call(this)}).call(this,require("buffer").Buffer) },{"buffer":331,"is-typedarray":134}],292:[function(require,module,exports){ var bufferAlloc = require('buffer-alloc') var UINT_32_MAX = Math.pow(2, 32) exports.encodingLength = function () { return 8 } exports.encode = function (num, buf, offset) { if (!buf) buf = bufferAlloc(8) if (!offset) offset = 0 var top = Math.floor(num / UINT_32_MAX) var rem = num - top * UINT_32_MAX buf.writeUInt32BE(top, offset) buf.writeUInt32BE(rem, offset + 4) return buf } exports.decode = function (buf, offset) { if (!offset) offset = 0 var top = buf.readUInt32BE(offset) var rem = buf.readUInt32BE(offset + 4) return top * UINT_32_MAX + rem } exports.encode.bytes = 8 exports.decode.bytes = 8 },{"buffer-alloc":57}],293:[function(require,module,exports){ module.exports = remove function remove (arr, i) { if (i >= arr.length || i < 0) return var last = arr.pop() if (i < arr.length) { var tmp = arr[i] arr[i] = last return tmp } return last } },{}],294:[function(require,module,exports){ (function (Buffer){(function (){ /*! ut_metadata. MIT License. WebTorrent LLC */ const { EventEmitter } = require('events') const bencode = require('bencode') const BitField = require('bitfield').default const debug = require('debug')('ut_metadata') const sha1 = require('simple-sha1') const MAX_METADATA_SIZE = 1E7 // 10 MB const BITFIELD_GROW = 1E3 const PIECE_LENGTH = 1 << 14 // 16 KiB module.exports = metadata => { class utMetadata extends EventEmitter { constructor (wire) { super() this._wire = wire this._fetching = false this._metadataComplete = false this._metadataSize = null // how many reject messages to tolerate before quitting this._remainingRejects = null // The largest torrent file that I know of is ~1-2MB, which is ~100 // pieces. Therefore, cap the bitfield to 10x that (1000 pieces) so a // malicious peer can't make it grow to fill all memory. this._bitfield = new BitField(0, { grow: BITFIELD_GROW }) if (Buffer.isBuffer(metadata)) { this.setMetadata(metadata) } } onHandshake (infoHash, peerId, extensions) { this._infoHash = infoHash } onExtendedHandshake (handshake) { if (!handshake.m || !handshake.m.ut_metadata) { return this.emit('warning', new Error('Peer does not support ut_metadata')) } if (!handshake.metadata_size) { return this.emit('warning', new Error('Peer does not have metadata')) } if (typeof handshake.metadata_size !== 'number' || MAX_METADATA_SIZE < handshake.metadata_size || handshake.metadata_size <= 0) { return this.emit('warning', new Error('Peer gave invalid metadata size')) } this._metadataSize = handshake.metadata_size this._numPieces = Math.ceil(this._metadataSize / PIECE_LENGTH) this._remainingRejects = this._numPieces * 2 this._requestPieces() } onMessage (buf) { let dict let trailer try { const str = buf.toString() const trailerIndex = str.indexOf('ee') + 2 dict = bencode.decode(str.substring(0, trailerIndex)) trailer = buf.slice(trailerIndex) } catch (err) { // drop invalid messages return } switch (dict.msg_type) { case 0: // ut_metadata request (from peer) // example: { 'msg_type': 0, 'piece': 0 } this._onRequest(dict.piece) break case 1: // ut_metadata data (in response to our request) // example: { 'msg_type': 1, 'piece': 0, 'total_size': 3425 } this._onData(dict.piece, trailer, dict.total_size) break case 2: // ut_metadata reject (peer doesn't have piece we requested) // { 'msg_type': 2, 'piece': 0 } this._onReject(dict.piece) break } } /** * Ask the peer to send metadata. * @public */ fetch () { if (this._metadataComplete) { return } this._fetching = true if (this._metadataSize) { this._requestPieces() } } /** * Stop asking the peer to send metadata. * @public */ cancel () { this._fetching = false } setMetadata (metadata) { if (this._metadataComplete) return true debug('set metadata') // if full torrent dictionary was passed in, pull out just `info` key try { const info = bencode.decode(metadata).info if (info) { metadata = bencode.encode(info) } } catch (err) {} // check hash if (this._infoHash && this._infoHash !== sha1.sync(metadata)) { return false } this.cancel() this.metadata = metadata this._metadataComplete = true this._metadataSize = this.metadata.length this._wire.extendedHandshake.metadata_size = this._metadataSize this.emit('metadata', bencode.encode({ info: bencode.decode(this.metadata) })) return true } _send (dict, trailer) { let buf = bencode.encode(dict) if (Buffer.isBuffer(trailer)) { buf = Buffer.concat([buf, trailer]) } this._wire.extended('ut_metadata', buf) } _request (piece) { this._send({ msg_type: 0, piece }) } _data (piece, buf, totalSize) { const msg = { msg_type: 1, piece } if (typeof totalSize === 'number') { msg.total_size = totalSize } this._send(msg, buf) } _reject (piece) { this._send({ msg_type: 2, piece }) } _onRequest (piece) { if (!this._metadataComplete) { this._reject(piece) return } const start = piece * PIECE_LENGTH let end = start + PIECE_LENGTH if (end > this._metadataSize) { end = this._metadataSize } const buf = this.metadata.slice(start, end) this._data(piece, buf, this._metadataSize) } _onData (piece, buf, totalSize) { if (buf.length > PIECE_LENGTH || !this._fetching) { return } buf.copy(this.metadata, piece * PIECE_LENGTH) this._bitfield.set(piece) this._checkDone() } _onReject (piece) { if (this._remainingRejects > 0 && this._fetching) { // If we haven't been rejected too much, // then try to request the piece again this._request(piece) this._remainingRejects -= 1 } else { this.emit('warning', new Error('Peer sent "reject" too much')) } } _requestPieces () { if (!this._fetching) return this.metadata = Buffer.alloc(this._metadataSize) for (let piece = 0; piece < this._numPieces; piece++) { this._request(piece) } } _checkDone () { let done = true for (let piece = 0; piece < this._numPieces; piece++) { if (!this._bitfield.get(piece)) { done = false break } } if (!done) return // attempt to set metadata -- may fail sha1 check const success = this.setMetadata(this.metadata) if (!success) { this._failedMetadata() } } _failedMetadata () { // reset bitfield & try again this._bitfield = new BitField(0, { grow: BITFIELD_GROW }) this._remainingRejects -= this._numPieces if (this._remainingRejects > 0) { this._requestPieces() } else { this.emit('warning', new Error('Peer sent invalid metadata')) } } } // Name of the bittorrent-protocol extension utMetadata.prototype.name = 'ut_metadata' return utMetadata } }).call(this)}).call(this,require("buffer").Buffer) },{"bencode":6,"bitfield":9,"buffer":331,"debug":295,"events":333,"simple-sha1":256}],295:[function(require,module,exports){ arguments[4][11][0].apply(exports,arguments) },{"./common":296,"_process":338,"dup":11}],296:[function(require,module,exports){ arguments[4][12][0].apply(exports,arguments) },{"dup":12,"ms":297}],297:[function(require,module,exports){ arguments[4][13][0].apply(exports,arguments) },{"dup":13}],298:[function(require,module,exports){ (function (global){(function (){ /** * 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)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{}],299:[function(require,module,exports){ (function (Buffer){(function (){ const bs = require('binary-search') const EventEmitter = require('events') const mp4 = require('mp4-stream') const Box = require('mp4-box-encoding') const RangeSliceStream = require('range-slice-stream') // if we want to ignore more than this many bytes, request a new stream. // if we want to ignore fewer, just skip them. const FIND_MOOV_SEEK_SIZE = 4096 class MP4Remuxer extends EventEmitter { constructor (file) { super() this._tracks = [] this._file = file this._decoder = null this._findMoov(0) } _findMoov (offset) { if (this._decoder) { this._decoder.destroy() } let toSkip = 0 this._decoder = mp4.decode() const fileStream = this._file.createReadStream({ start: offset }) fileStream.pipe(this._decoder) const boxHandler = headers => { if (headers.type === 'moov') { this._decoder.removeListener('box', boxHandler) this._decoder.decode(moov => { fileStream.destroy() try { this._processMoov(moov) } catch (err) { err.message = `Cannot parse mp4 file: ${err.message}` this.emit('error', err) } }) } else if (headers.length < FIND_MOOV_SEEK_SIZE) { toSkip += headers.length this._decoder.ignore() } else { this._decoder.removeListener('box', boxHandler) toSkip += headers.length fileStream.destroy() this._decoder.destroy() this._findMoov(offset + toSkip) } } this._decoder.on('box', boxHandler) } _processMoov (moov) { const traks = moov.traks this._tracks = [] this._hasVideo = false this._hasAudio = false for (let i = 0; i < traks.length; i++) { const trak = traks[i] const stbl = trak.mdia.minf.stbl const stsdEntry = stbl.stsd.entries[0] const handlerType = trak.mdia.hdlr.handlerType let codec let mime if (handlerType === 'vide' && stsdEntry.type === 'avc1') { if (this._hasVideo) { continue } this._hasVideo = true codec = 'avc1' if (stsdEntry.avcC) { codec += `.${stsdEntry.avcC.mimeCodec}` } mime = `video/mp4; codecs="${codec}"` } else if (handlerType === 'soun' && stsdEntry.type === 'mp4a') { if (this._hasAudio) { continue } this._hasAudio = true codec = 'mp4a' if (stsdEntry.esds && stsdEntry.esds.mimeCodec) { codec += `.${stsdEntry.esds.mimeCodec}` } mime = `audio/mp4; codecs="${codec}"` } else { continue } const samples = [] let sample = 0 // Chunk/position data let sampleInChunk = 0 let chunk = 0 let offsetInChunk = 0 let sampleToChunkIndex = 0 // Time data let dts = 0 const decodingTimeEntry = new RunLengthIndex(stbl.stts.entries) let presentationOffsetEntry = null if (stbl.ctts) { presentationOffsetEntry = new RunLengthIndex(stbl.ctts.entries) } // Sync table index let syncSampleIndex = 0 while (true) { var currChunkEntry = stbl.stsc.entries[sampleToChunkIndex] // Compute size const size = stbl.stsz.entries[sample] // Compute time data const duration = decodingTimeEntry.value.duration const presentationOffset = presentationOffsetEntry ? presentationOffsetEntry.value.compositionOffset : 0 // Compute sync let sync = true if (stbl.stss) { sync = stbl.stss.entries[syncSampleIndex] === sample + 1 } // Create new sample entry const chunkOffsetTable = stbl.stco || stbl.co64 samples.push({ size, duration, dts, presentationOffset, sync, offset: offsetInChunk + chunkOffsetTable.entries[chunk] }) // Go to next sample sample++ if (sample >= stbl.stsz.entries.length) { break } // Move position/chunk sampleInChunk++ offsetInChunk += size if (sampleInChunk >= currChunkEntry.samplesPerChunk) { // Move to new chunk sampleInChunk = 0 offsetInChunk = 0 chunk++ // Move sample to chunk box index const nextChunkEntry = stbl.stsc.entries[sampleToChunkIndex + 1] if (nextChunkEntry && chunk + 1 >= nextChunkEntry.firstChunk) { sampleToChunkIndex++ } } // Move time forward dts += duration decodingTimeEntry.inc() presentationOffsetEntry && presentationOffsetEntry.inc() // Move sync table index if (sync) { syncSampleIndex++ } } trak.mdia.mdhd.duration = 0 trak.tkhd.duration = 0 const defaultSampleDescriptionIndex = currChunkEntry.sampleDescriptionId const trackMoov = { type: 'moov', mvhd: moov.mvhd, traks: [{ tkhd: trak.tkhd, mdia: { mdhd: trak.mdia.mdhd, hdlr: trak.mdia.hdlr, elng: trak.mdia.elng, minf: { vmhd: trak.mdia.minf.vmhd, smhd: trak.mdia.minf.smhd, dinf: trak.mdia.minf.dinf, stbl: { stsd: stbl.stsd, stts: empty(), ctts: empty(), stsc: empty(), stsz: empty(), stco: empty(), stss: empty() } } } }], mvex: { mehd: { fragmentDuration: moov.mvhd.duration }, trexs: [{ trackId: trak.tkhd.trackId, defaultSampleDescriptionIndex, defaultSampleDuration: 0, defaultSampleSize: 0, defaultSampleFlags: 0 }] } } this._tracks.push({ fragmentSequence: 1, trackId: trak.tkhd.trackId, timeScale: trak.mdia.mdhd.timeScale, samples, currSample: null, currTime: null, moov: trackMoov, mime }) } if (this._tracks.length === 0) { this.emit('error', new Error('no playable tracks')) return } // Must be set last since this is used above moov.mvhd.duration = 0 this._ftyp = { type: 'ftyp', brand: 'iso5', brandVersion: 0, compatibleBrands: [ 'iso5' ] } const ftypBuf = Box.encode(this._ftyp) const data = this._tracks.map(track => { const moovBuf = Box.encode(track.moov) return { mime: track.mime, init: Buffer.concat([ftypBuf, moovBuf]) } }) this.emit('ready', data) } seek (time) { if (!this._tracks) { throw new Error('Not ready yet; wait for \'ready\' event') } if (this._fileStream) { this._fileStream.destroy() this._fileStream = null } let startOffset = -1 this._tracks.map((track, i) => { // find the keyframe before the time // stream from there if (track.outStream) { track.outStream.destroy() } if (track.inStream) { track.inStream.destroy() track.inStream = null } const outStream = track.outStream = mp4.encode() const fragment = this._generateFragment(i, time) if (!fragment) { return outStream.finalize() } if (startOffset === -1 || fragment.ranges[0].start < startOffset) { startOffset = fragment.ranges[0].start } const writeFragment = (frag) => { if (outStream.destroyed) return outStream.box(frag.moof, err => { if (err) return this.emit('error', err) if (outStream.destroyed) return const slicedStream = track.inStream.slice(frag.ranges) slicedStream.pipe(outStream.mediaData(frag.length, err => { if (err) return this.emit('error', err) if (outStream.destroyed) return const nextFrag = this._generateFragment(i) if (!nextFrag) { return outStream.finalize() } writeFragment(nextFrag) })) }) } writeFragment(fragment) }) if (startOffset >= 0) { const fileStream = this._fileStream = this._file.createReadStream({ start: startOffset }) this._tracks.forEach(track => { track.inStream = new RangeSliceStream(startOffset, { // Allow up to a 10MB offset between audio and video, // which should be fine for any reasonable interleaving // interval and bitrate highWaterMark: 10000000 }) fileStream.pipe(track.inStream) }) } return this._tracks.map(track => { return track.outStream }) } _findSampleBefore (trackInd, time) { const track = this._tracks[trackInd] const scaledTime = Math.floor(track.timeScale * time) let sample = bs(track.samples, scaledTime, (sample, t) => { const pts = sample.dts + sample.presentationOffset// - track.editShift return pts - t }) if (sample === -1) { sample = 0 } else if (sample < 0) { sample = -sample - 2 } // sample is now the last sample with dts <= time // Find the preceeding sync sample while (!track.samples[sample].sync) { sample-- } return sample } _generateFragment (track, time) { /* 1. Find correct sample 2. Process backward until sync sample found 3. Process forward until next sync sample after MIN_FRAGMENT_DURATION found */ const currTrack = this._tracks[track] let firstSample if (time !== undefined) { firstSample = this._findSampleBefore(track, time) } else { firstSample = currTrack.currSample } if (firstSample >= currTrack.samples.length) { return null } const startDts = currTrack.samples[firstSample].dts let totalLen = 0 const ranges = [] for (var currSample = firstSample; currSample < currTrack.samples.length; currSample++) { const sample = currTrack.samples[currSample] if (sample.sync && sample.dts - startDts >= currTrack.timeScale * MIN_FRAGMENT_DURATION) { break // This is a reasonable place to end the fragment } totalLen += sample.size const currRange = ranges.length - 1 if (currRange < 0 || ranges[currRange].end !== sample.offset) { // Push a new range ranges.push({ start: sample.offset, end: sample.offset + sample.size }) } else { ranges[currRange].end += sample.size } } currTrack.currSample = currSample return { moof: this._generateMoof(track, firstSample, currSample), ranges, length: totalLen } } _generateMoof (track, firstSample, lastSample) { const currTrack = this._tracks[track] const entries = [] let trunVersion = 0 for (let j = firstSample; j < lastSample; j++) { const currSample = currTrack.samples[j] if (currSample.presentationOffset < 0) { trunVersion = 1 } entries.push({ sampleDuration: currSample.duration, sampleSize: currSample.size, sampleFlags: currSample.sync ? 0x2000000 : 0x1010000, sampleCompositionTimeOffset: currSample.presentationOffset }) } const moof = { type: 'moof', mfhd: { sequenceNumber: currTrack.fragmentSequence++ }, trafs: [{ tfhd: { flags: 0x20000, // default-base-is-moof trackId: currTrack.trackId }, tfdt: { baseMediaDecodeTime: currTrack.samples[firstSample].dts }, trun: { flags: 0xf01, dataOffset: 8, // The moof size has to be added to this later as well entries, version: trunVersion } }] } // Update the offset moof.trafs[0].trun.dataOffset += Box.encodingLength(moof) return moof } } class RunLengthIndex { constructor (entries, countName) { this._entries = entries this._countName = countName || 'count' this._index = 0 this._offset = 0 this.value = this._entries[0] } inc () { this._offset++ if (this._offset >= this._entries[this._index][this._countName]) { this._index++ this._offset = 0 } this.value = this._entries[this._index] } } function empty () { return { version: 0, flags: 0, entries: [] } } const MIN_FRAGMENT_DURATION = 1 // second module.exports = MP4Remuxer }).call(this)}).call(this,require("buffer").Buffer) },{"binary-search":8,"buffer":331,"events":333,"mp4-box-encoding":157,"mp4-stream":160,"range-slice-stream":201}],300:[function(require,module,exports){ const MediaElementWrapper = require('mediasource') const pump = require('pump') const MP4Remuxer = require('./mp4-remuxer') function VideoStream (file, mediaElem, opts = {}) { if (!(this instanceof VideoStream)) { console.warn("Don't invoke VideoStream without the 'new' keyword.") return new VideoStream(file, mediaElem, opts) } this.detailedError = null this._elem = mediaElem this._elemWrapper = new MediaElementWrapper(mediaElem) this._waitingFired = false this._trackMeta = null this._file = file this._tracks = null if (this._elem.preload !== 'none') { this._createMuxer() } this._onError = () => { this.detailedError = this._elemWrapper.detailedError this.destroy() // don't pass err though so the user doesn't need to listen for errors } this._onWaiting = () => { this._waitingFired = true if (!this._muxer) { this._createMuxer() } else if (this._tracks) { this._pump() } } if (mediaElem.autoplay) { mediaElem.preload = 'auto' } mediaElem.addEventListener('waiting', this._onWaiting) mediaElem.addEventListener('error', this._onError) } VideoStream.prototype = { _createMuxer () { this._muxer = new MP4Remuxer(this._file) this._muxer.on('ready', data => { this._tracks = data.map(trackData => { const mediaSource = this._elemWrapper.createWriteStream(trackData.mime) mediaSource.on('error', err => { this._elemWrapper.error(err) }) const track = { muxed: null, mediaSource, initFlushed: false, onInitFlushed: null } mediaSource.write(trackData.init, err => { track.initFlushed = true if (track.onInitFlushed) { track.onInitFlushed(err) } }) return track }) if (this._waitingFired || this._elem.preload === 'auto') { this._pump() } }) this._muxer.on('error', err => { this._elemWrapper.error(err) }) }, _pump () { const muxed = this._muxer.seek(this._elem.currentTime, !this._tracks) this._tracks.forEach((track, i) => { const pumpTrack = () => { if (track.muxed) { track.muxed.destroy() track.mediaSource = this._elemWrapper.createWriteStream(track.mediaSource) track.mediaSource.on('error', err => { this._elemWrapper.error(err) }) } track.muxed = muxed[i] pump(track.muxed, track.mediaSource) } if (!track.initFlushed) { track.onInitFlushed = err => { if (err) { this._elemWrapper.error(err) return } pumpTrack() } } else { pumpTrack() } }) }, destroy () { if (this.destroyed) { return } this.destroyed = true this._elem.removeEventListener('waiting', this._onWaiting) this._elem.removeEventListener('error', this._onError) if (this._tracks) { this._tracks.forEach(track => { if (track.muxed) { track.muxed.destroy() } }) } this._elem.src = '' } } module.exports = VideoStream },{"./mp4-remuxer":299,"mediasource":138,"pump":197}],301:[function(require,module,exports){ (function (process,global,Buffer){(function (){ /*! webtorrent. MIT License. WebTorrent LLC */ /* global FileList */ const { EventEmitter } = require('events') const concat = require('simple-concat') const createTorrent = require('create-torrent') const debug = require('debug')('webtorrent') const DHT = require('bittorrent-dht/client') // browser exclude const loadIPSet = require('load-ip-set') // browser exclude const parallel = require('run-parallel') const parseTorrent = require('parse-torrent') const path = require('path') const Peer = require('simple-peer') const randombytes = require('randombytes') const speedometer = require('speedometer') const ConnPool = require('./lib/conn-pool') // browser exclude const Torrent = require('./lib/torrent') const VERSION = require('./package.json').version /** * Version number in Azureus-style. Generated from major and minor semver version. * For example: * '0.16.1' -> '0016' * '1.2.5' -> '0102' */ const VERSION_STR = VERSION .replace(/\d*./g, v => `0${v % 100}`.slice(-2)) .slice(0, 4) /** * Version prefix string (used in peer ID). WebTorrent uses the Azureus-style * encoding: '-', two characters for client id ('WW'), four ascii digits for version * number, '-', followed by random numbers. * For example: * '-WW0102-'... */ const VERSION_PREFIX = `-WW${VERSION_STR}-` /** * WebTorrent Client * @param {Object=} opts */ class WebTorrent extends EventEmitter { constructor (opts = {}) { super() if (typeof opts.peerId === 'string') { this.peerId = opts.peerId } else if (Buffer.isBuffer(opts.peerId)) { this.peerId = opts.peerId.toString('hex') } else { this.peerId = Buffer.from(VERSION_PREFIX + randombytes(9).toString('base64')).toString('hex') } this.peerIdBuffer = Buffer.from(this.peerId, 'hex') if (typeof opts.nodeId === 'string') { this.nodeId = opts.nodeId } else if (Buffer.isBuffer(opts.nodeId)) { this.nodeId = opts.nodeId.toString('hex') } else { this.nodeId = randombytes(20).toString('hex') } this.nodeIdBuffer = Buffer.from(this.nodeId, 'hex') this._debugId = this.peerId.toString('hex').substring(0, 7) this.destroyed = false this.listening = false this.torrentPort = opts.torrentPort || 0 this.dhtPort = opts.dhtPort || 0 this.tracker = opts.tracker !== undefined ? opts.tracker : {} this.lsd = opts.lsd !== false this.torrents = [] this.maxConns = Number(opts.maxConns) || 55 this.utp = opts.utp === true this._debug( 'new webtorrent (peerId %s, nodeId %s, port %s)', this.peerId, this.nodeId, this.torrentPort ) if (this.tracker) { if (typeof this.tracker !== 'object') this.tracker = {} if (opts.rtcConfig) { // TODO: remove in v1 console.warn('WebTorrent: opts.rtcConfig is deprecated. Use opts.tracker.rtcConfig instead') this.tracker.rtcConfig = opts.rtcConfig } if (opts.wrtc) { // TODO: remove in v1 console.warn('WebTorrent: opts.wrtc is deprecated. Use opts.tracker.wrtc instead') this.tracker.wrtc = opts.wrtc } if (global.WRTC && !this.tracker.wrtc) { this.tracker.wrtc = global.WRTC } } if (typeof ConnPool === 'function') { this._connPool = new ConnPool(this) } else { process.nextTick(() => { this._onListening() }) } // stats this._downloadSpeed = speedometer() this._uploadSpeed = speedometer() if (opts.dht !== false && typeof DHT === 'function' /* browser exclude */) { // use a single DHT instance for all torrents, so the routing table can be reused this.dht = new DHT(Object.assign({}, { nodeId: this.nodeId }, opts.dht)) this.dht.once('error', err => { this._destroy(err) }) this.dht.once('listening', () => { const address = this.dht.address() if (address) this.dhtPort = address.port }) // Ignore warning when there are > 10 torrents in the client this.dht.setMaxListeners(0) this.dht.listen(this.dhtPort) } else { this.dht = false } // Enable or disable BEP19 (Web Seeds). Enabled by default: this.enableWebSeeds = opts.webSeeds !== false const ready = () => { if (this.destroyed) return this.ready = true this.emit('ready') } if (typeof loadIPSet === 'function' && opts.blocklist != null) { loadIPSet(opts.blocklist, { headers: { 'user-agent': `WebTorrent/${VERSION} (https://webtorrent.io)` } }, (err, ipSet) => { if (err) return this.error(`Failed to load blocklist: ${err.message}`) this.blocked = ipSet ready() }) } else { process.nextTick(ready) } } get downloadSpeed () { return this._downloadSpeed() } get uploadSpeed () { return this._uploadSpeed() } get progress () { const torrents = this.torrents.filter(torrent => torrent.progress !== 1) const downloaded = torrents.reduce((total, torrent) => total + torrent.downloaded, 0) const length = torrents.reduce((total, torrent) => total + (torrent.length || 0), 0) || 1 return downloaded / length } get ratio () { const uploaded = this.torrents.reduce((total, torrent) => total + torrent.uploaded, 0) const received = this.torrents.reduce((total, torrent) => total + torrent.received, 0) || 1 return uploaded / received } /** * Returns the torrent with the given `torrentId`. Convenience method. Easier than * searching through the `client.torrents` array. Returns `null` if no matching torrent * found. * * @param {string|Buffer|Object|Torrent} torrentId * @return {Torrent|null} */ get (torrentId) { if (torrentId instanceof Torrent) { if (this.torrents.includes(torrentId)) return torrentId } else { let parsed try { parsed = parseTorrent(torrentId) } catch (err) {} if (!parsed) return null if (!parsed.infoHash) throw new Error('Invalid torrent identifier') for (const torrent of this.torrents) { if (torrent.infoHash === parsed.infoHash) return torrent } } return null } // TODO: remove in v1 download (torrentId, opts, ontorrent) { console.warn('WebTorrent: client.download() is deprecated. Use client.add() instead') return this.add(torrentId, opts, ontorrent) } /** * Start downloading a new torrent. Aliased as `client.download`. * @param {string|Buffer|Object} torrentId * @param {Object} opts torrent-specific options * @param {function=} ontorrent called when the torrent is ready (has metadata) */ add (torrentId, opts = {}, ontorrent = () => {}) { if (this.destroyed) throw new Error('client is destroyed') if (typeof opts === 'function') [opts, ontorrent] = [{}, opts] const onInfoHash = () => { if (this.destroyed) return for (const t of this.torrents) { if (t.infoHash === torrent.infoHash && t !== torrent) { torrent._destroy(new Error(`Cannot add duplicate torrent ${torrent.infoHash}`)) return } } } const onReady = () => { if (this.destroyed) return ontorrent(torrent) this.emit('torrent', torrent) } function onClose () { torrent.removeListener('_infoHash', onInfoHash) torrent.removeListener('ready', onReady) torrent.removeListener('close', onClose) } this._debug('add') opts = opts ? Object.assign({}, opts) : {} const torrent = new Torrent(torrentId, this, opts) this.torrents.push(torrent) torrent.once('_infoHash', onInfoHash) torrent.once('ready', onReady) torrent.once('close', onClose) return torrent } /** * Start seeding a new file/folder. * @param {string|File|FileList|Buffer|Array.} input * @param {Object=} opts * @param {function=} onseed called when torrent is seeding */ seed (input, opts, onseed) { if (this.destroyed) throw new Error('client is destroyed') if (typeof opts === 'function') [opts, onseed] = [{}, opts] this._debug('seed') opts = opts ? Object.assign({}, opts) : {} // no need to verify the hashes we create opts.skipVerify = true const isFilePath = typeof input === 'string' // When seeding from fs path, initialize store from that path to avoid a copy if (isFilePath) opts.path = path.dirname(input) if (!opts.createdBy) opts.createdBy = `WebTorrent/${VERSION_STR}` const onTorrent = torrent => { const tasks = [ cb => { // when a filesystem path is specified, files are already in the FS store if (isFilePath) return cb() torrent.load(streams, cb) } ] if (this.dht) { tasks.push(cb => { torrent.once('dhtAnnounce', cb) }) } parallel(tasks, err => { if (this.destroyed) return if (err) return torrent._destroy(err) _onseed(torrent) }) } const _onseed = torrent => { this._debug('on seed') if (typeof onseed === 'function') onseed(torrent) torrent.emit('seed') this.emit('seed', torrent) } const torrent = this.add(null, opts, onTorrent) let streams if (isFileList(input)) input = Array.from(input) else if (!Array.isArray(input)) input = [input] parallel(input.map(item => cb => { if (isReadable(item)) concat(item, cb) else cb(null, item) }), (err, input) => { if (this.destroyed) return if (err) return torrent._destroy(err) createTorrent.parseInput(input, opts, (err, files) => { if (this.destroyed) return if (err) return torrent._destroy(err) streams = files.map(file => file.getStream) createTorrent(input, opts, (err, torrentBuf) => { if (this.destroyed) return if (err) return torrent._destroy(err) const existingTorrent = this.get(torrentBuf) if (existingTorrent) { torrent._destroy(new Error(`Cannot add duplicate torrent ${existingTorrent.infoHash}`)) } else { torrent._onTorrentId(torrentBuf) } }) }) }) return torrent } /** * Remove a torrent from the client. * @param {string|Buffer|Torrent} torrentId * @param {function} cb */ remove (torrentId, opts, cb) { if (typeof opts === 'function') return this.remove(torrentId, null, opts) this._debug('remove') const torrent = this.get(torrentId) if (!torrent) throw new Error(`No torrent with id ${torrentId}`) this._remove(torrentId, opts, cb) } _remove (torrentId, opts, cb) { if (typeof opts === 'function') return this._remove(torrentId, null, opts) const torrent = this.get(torrentId) if (!torrent) return this.torrents.splice(this.torrents.indexOf(torrent), 1) torrent.destroy(opts, cb) } address () { if (!this.listening) return null return this._connPool ? this._connPool.tcpServer.address() : { address: '0.0.0.0', family: 'IPv4', port: 0 } } /** * Destroy the client, including all torrents and connections to peers. * @param {function} cb */ destroy (cb) { if (this.destroyed) throw new Error('client already destroyed') this._destroy(null, cb) } _destroy (err, cb) { this._debug('client destroy') this.destroyed = true const tasks = this.torrents.map(torrent => cb => { torrent.destroy(cb) }) if (this._connPool) { tasks.push(cb => { this._connPool.destroy(cb) }) } if (this.dht) { tasks.push(cb => { this.dht.destroy(cb) }) } parallel(tasks, cb) if (err) this.emit('error', err) this.torrents = [] this._connPool = null this.dht = null } _onListening () { this._debug('listening') this.listening = true if (this._connPool) { // Sometimes server.address() returns `null` in Docker. const address = this._connPool.tcpServer.address() if (address) this.torrentPort = address.port } this.emit('listening') } _debug () { const args = [].slice.call(arguments) args[0] = `[${this._debugId}] ${args[0]}` debug(...args) } } WebTorrent.WEBRTC_SUPPORT = Peer.WEBRTC_SUPPORT WebTorrent.VERSION = VERSION /** * Check if `obj` is a node Readable stream * @param {*} obj * @return {boolean} */ function isReadable (obj) { return typeof obj === 'object' && obj != null && typeof obj.pipe === 'function' } /** * Check if `obj` is a W3C `FileList` object * @param {*} obj * @return {boolean} */ function isFileList (obj) { return typeof FileList !== 'undefined' && obj instanceof FileList } module.exports = WebTorrent }).call(this)}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer) },{"./lib/conn-pool":330,"./lib/torrent":306,"./package.json":326,"_process":338,"bittorrent-dht/client":330,"buffer":331,"create-torrent":77,"debug":308,"events":333,"load-ip-set":330,"parse-torrent":195,"path":337,"randombytes":200,"run-parallel":224,"simple-concat":235,"simple-peer":237,"speedometer":277}],302:[function(require,module,exports){ const debug = require('debug')('webtorrent:file-stream') const stream = require('readable-stream') /** * Readable stream of a torrent file * * @param {File} file * @param {Object} opts * @param {number} opts.start stream slice of file, starting from this byte (inclusive) * @param {number} opts.end stream slice of file, ending with this byte (inclusive) */ class FileStream extends stream.Readable { constructor (file, opts) { super(opts) this.destroyed = false this._torrent = file._torrent const start = (opts && opts.start) || 0 const end = (opts && opts.end && opts.end < file.length) ? opts.end : file.length - 1 const pieceLength = file._torrent.pieceLength this._startPiece = (start + file.offset) / pieceLength | 0 this._endPiece = (end + file.offset) / pieceLength | 0 this._piece = this._startPiece this._offset = (start + file.offset) - (this._startPiece * pieceLength) this._missing = end - start + 1 this._reading = false this._notifying = false this._criticalLength = Math.min((1024 * 1024 / pieceLength) | 0, 2) } _read () { if (this._reading) return this._reading = true this._notify() } _notify () { if (!this._reading || this._missing === 0) return if (!this._torrent.bitfield.get(this._piece)) { return this._torrent.critical(this._piece, this._piece + this._criticalLength) } if (this._notifying) return this._notifying = true if (this._torrent.destroyed) return this._destroy(new Error('Torrent removed')) const p = this._piece this._torrent.store.get(p, (err, buffer) => { this._notifying = false if (this.destroyed) return debug('read %s (length %s) (err %s)', p, buffer.length, err && err.message) if (err) return this._destroy(err) if (this._offset) { buffer = buffer.slice(this._offset) this._offset = 0 } if (this._missing < buffer.length) { buffer = buffer.slice(0, this._missing) } this._missing -= buffer.length debug('pushing buffer of length %s', buffer.length) this._reading = false this.push(buffer) if (this._missing === 0) this.push(null) }) this._piece += 1 } destroy (onclose) { this._destroy(null, onclose) } _destroy (err, onclose) { if (this.destroyed) return this.destroyed = true if (!this._torrent.destroyed) { this._torrent.deselect(this._startPiece, this._endPiece, true) } if (err) this.emit('error', err) this.emit('close') if (onclose) onclose() } } module.exports = FileStream },{"debug":308,"readable-stream":325}],303:[function(require,module,exports){ (function (process){(function (){ const { EventEmitter } = require('events') const { PassThrough } = require('readable-stream') const eos = require('end-of-stream') const path = require('path') const render = require('render-media') const streamToBlob = require('stream-to-blob') const streamToBlobURL = require('stream-to-blob-url') const streamToBuffer = require('stream-with-known-length-to-buffer') const FileStream = require('./file-stream') class File extends EventEmitter { constructor (torrent, file) { super() this._torrent = torrent this._destroyed = false this.name = file.name this.path = file.path this.length = file.length this.offset = file.offset this.done = false const start = file.offset const end = start + file.length - 1 this._startPiece = start / this._torrent.pieceLength | 0 this._endPiece = end / this._torrent.pieceLength | 0 if (this.length === 0) { this.done = true this.emit('done') } } get downloaded () { if (!this._torrent.bitfield) return 0 const { pieces, bitfield, pieceLength } = this._torrent const { _startPiece: start, _endPiece: end } = this const piece = pieces[start] // First piece may have an offset, e.g. irrelevant bytes from the end of // the previous file const irrelevantFirstPieceBytes = this.offset % pieceLength let downloaded = bitfield.get(start) ? pieceLength - irrelevantFirstPieceBytes : Math.max(pieceLength - irrelevantFirstPieceBytes - piece.missing, 0) for (let index = start + 1; index <= end; ++index) { if (bitfield.get(index)) { // verified data downloaded += pieceLength } else { // "in progress" data const piece = pieces[index] downloaded += pieceLength - piece.missing } } // We don't know the end offset, so return this.length if it's oversized. // e.g. One small file can fit in the middle of a piece. return Math.min(downloaded, this.length) } get progress () { return this.length ? this.downloaded / this.length : 0 } select (priority) { if (this.length === 0) return this._torrent.select(this._startPiece, this._endPiece, priority) } deselect () { if (this.length === 0) return this._torrent.deselect(this._startPiece, this._endPiece, false) } createReadStream (opts) { if (this.length === 0) { const empty = new PassThrough() process.nextTick(() => { empty.end() }) return empty } const fileStream = new FileStream(this, opts) this._torrent.select(fileStream._startPiece, fileStream._endPiece, true, () => { fileStream._notify() }) eos(fileStream, () => { if (this._destroyed) return if (!this._torrent.destroyed) { this._torrent.deselect(fileStream._startPiece, fileStream._endPiece, true) } }) return fileStream } getBuffer (cb) { streamToBuffer(this.createReadStream(), this.length, cb) } getBlob (cb) { if (typeof window === 'undefined') throw new Error('browser-only method') streamToBlob(this.createReadStream(), this._getMimeType()) .then( blob => cb(null, blob), err => cb(err) ) } getBlobURL (cb) { if (typeof window === 'undefined') throw new Error('browser-only method') streamToBlobURL(this.createReadStream(), this._getMimeType()) .then( blobUrl => cb(null, blobUrl), err => cb(err) ) } appendTo (elem, opts, cb) { if (typeof window === 'undefined') throw new Error('browser-only method') render.append(this, elem, opts, cb) } renderTo (elem, opts, cb) { if (typeof window === 'undefined') throw new Error('browser-only method') render.render(this, elem, opts, cb) } _getMimeType () { return render.mime[path.extname(this.name).toLowerCase()] } _destroy () { this._destroyed = true this._torrent = null } } module.exports = File }).call(this)}).call(this,require('_process')) },{"./file-stream":302,"_process":338,"end-of-stream":95,"events":333,"path":337,"readable-stream":325,"render-media":217,"stream-to-blob":279,"stream-to-blob-url":278,"stream-with-known-length-to-buffer":280}],304:[function(require,module,exports){ const arrayRemove = require('unordered-array-remove') const debug = require('debug')('webtorrent:peer') const Wire = require('bittorrent-protocol') const WebConn = require('./webconn') const CONNECT_TIMEOUT_TCP = 5000 const CONNECT_TIMEOUT_UTP = 5000 const CONNECT_TIMEOUT_WEBRTC = 25000 const HANDSHAKE_TIMEOUT = 25000 /** * WebRTC peer connections start out connected, because WebRTC peers require an * "introduction" (i.e. WebRTC signaling), and there's no equivalent to an IP address * that lets you refer to a WebRTC endpoint. */ exports.createWebRTCPeer = (conn, swarm) => { const peer = new Peer(conn.id, 'webrtc') peer.conn = conn peer.swarm = swarm if (peer.conn.connected) { peer.onConnect() } else { peer.conn.once('connect', () => { peer.onConnect() }) peer.conn.once('error', err => { peer.destroy(err) }) peer.startConnectTimeout() } return peer } /** * Incoming TCP peers start out connected, because the remote peer connected to the * listening port of the TCP server. Until the remote peer sends a handshake, we don't * know what swarm the connection is intended for. */ exports.createTCPIncomingPeer = conn => { return _createIncomingPeer(conn, 'tcpIncoming') } /** * Incoming uTP peers start out connected, because the remote peer connected to the * listening port of the uTP server. Until the remote peer sends a handshake, we don't * know what swarm the connection is intended for. */ exports.createUTPIncomingPeer = conn => { return _createIncomingPeer(conn, 'utpIncoming') } /** * Outgoing TCP peers start out with just an IP address. At some point (when there is an * available connection), the client can attempt to connect to the address. */ exports.createTCPOutgoingPeer = (addr, swarm) => { return _createOutgoingPeer(addr, swarm, 'tcpOutgoing') } /** * Outgoing uTP peers start out with just an IP address. At some point (when there is an * available connection), the client can attempt to connect to the address. */ exports.createUTPOutgoingPeer = (addr, swarm) => { return _createOutgoingPeer(addr, swarm, 'utpOutgoing') } const _createIncomingPeer = (conn, type) => { const addr = `${conn.remoteAddress}:${conn.remotePort}` const peer = new Peer(addr, type) peer.conn = conn peer.addr = addr peer.onConnect() return peer } const _createOutgoingPeer = (addr, swarm, type) => { const peer = new Peer(addr, type) peer.addr = addr peer.swarm = swarm return peer } /** * Peer that represents a Web Seed (BEP17 / BEP19). */ exports.createWebSeedPeer = (url, swarm) => { const peer = new Peer(url, 'webSeed') peer.swarm = swarm peer.conn = new WebConn(url, swarm) peer.onConnect() return peer } /** * Peer. Represents a peer in the torrent swarm. * * @param {string} id "ip:port" string, peer id (for WebRTC peers), or url (for Web Seeds) * @param {string} type the type of the peer */ class Peer { constructor (id, type) { this.id = id this.type = type debug('new %s Peer %s', type, id) this.addr = null this.conn = null this.swarm = null this.wire = null this.connected = false this.destroyed = false this.timeout = null // handshake timeout this.retries = 0 // outgoing TCP connection retry count this.sentHandshake = false } /** * Called once the peer is connected (i.e. fired 'connect' event) * @param {Socket} conn */ onConnect () { if (this.destroyed) return this.connected = true debug('Peer %s connected', this.id) clearTimeout(this.connectTimeout) const conn = this.conn conn.once('end', () => { this.destroy() }) conn.once('close', () => { this.destroy() }) conn.once('finish', () => { this.destroy() }) conn.once('error', err => { this.destroy(err) }) const wire = this.wire = new Wire() wire.type = this.type wire.once('end', () => { this.destroy() }) wire.once('close', () => { this.destroy() }) wire.once('finish', () => { this.destroy() }) wire.once('error', err => { this.destroy(err) }) wire.once('handshake', (infoHash, peerId) => { this.onHandshake(infoHash, peerId) }) this.startHandshakeTimeout() conn.pipe(wire).pipe(conn) if (this.swarm && !this.sentHandshake) this.handshake() } /** * Called when handshake is received from remote peer. * @param {string} infoHash * @param {string} peerId */ onHandshake (infoHash, peerId) { if (!this.swarm) return // `this.swarm` not set yet, so do nothing if (this.destroyed) return if (this.swarm.destroyed) { return this.destroy(new Error('swarm already destroyed')) } if (infoHash !== this.swarm.infoHash) { return this.destroy(new Error('unexpected handshake info hash for this swarm')) } if (peerId === this.swarm.peerId) { return this.destroy(new Error('refusing to connect to ourselves')) } debug('Peer %s got handshake %s', this.id, infoHash) clearTimeout(this.handshakeTimeout) this.retries = 0 let addr = this.addr if (!addr && this.conn.remoteAddress && this.conn.remotePort) { addr = `${this.conn.remoteAddress}:${this.conn.remotePort}` } this.swarm._onWire(this.wire, addr) // swarm could be destroyed in user's 'wire' event handler if (!this.swarm || this.swarm.destroyed) return if (!this.sentHandshake) this.handshake() } handshake () { const opts = { dht: this.swarm.private ? false : !!this.swarm.client.dht } this.wire.handshake(this.swarm.infoHash, this.swarm.client.peerId, opts) this.sentHandshake = true } startConnectTimeout () { clearTimeout(this.connectTimeout) const connectTimeoutValues = { webrtc: CONNECT_TIMEOUT_WEBRTC, tcpOutgoing: CONNECT_TIMEOUT_TCP, utpOutgoing: CONNECT_TIMEOUT_UTP } this.connectTimeout = setTimeout(() => { this.destroy(new Error('connect timeout')) }, connectTimeoutValues[this.type]) if (this.connectTimeout.unref) this.connectTimeout.unref() } startHandshakeTimeout () { clearTimeout(this.handshakeTimeout) this.handshakeTimeout = setTimeout(() => { this.destroy(new Error('handshake timeout')) }, HANDSHAKE_TIMEOUT) if (this.handshakeTimeout.unref) this.handshakeTimeout.unref() } destroy (err) { if (this.destroyed) return this.destroyed = true this.connected = false debug('destroy %s %s (error: %s)', this.type, this.id, err && (err.message || err)) clearTimeout(this.connectTimeout) clearTimeout(this.handshakeTimeout) const swarm = this.swarm const conn = this.conn const wire = this.wire this.swarm = null this.conn = null this.wire = null if (swarm && wire) { arrayRemove(swarm.wires, swarm.wires.indexOf(wire)) } if (conn) { conn.on('error', () => {}) conn.destroy() } if (wire) wire.destroy() if (swarm) swarm.removePeer(this.id) } } },{"./webconn":307,"bittorrent-protocol":10,"debug":308,"unordered-array-remove":293}],305:[function(require,module,exports){ /** * Mapping of torrent pieces to their respective availability in the torrent swarm. Used * by the torrent manager for implementing the rarest piece first selection strategy. */ class RarityMap { constructor (torrent) { this._torrent = torrent this._numPieces = torrent.pieces.length this._pieces = new Array(this._numPieces) this._onWire = wire => { this.recalculate() this._initWire(wire) } this._onWireHave = index => { this._pieces[index] += 1 } this._onWireBitfield = () => { this.recalculate() } this._torrent.wires.forEach(wire => { this._initWire(wire) }) this._torrent.on('wire', this._onWire) this.recalculate() } /** * Get the index of the rarest piece. Optionally, pass a filter function to exclude * certain pieces (for instance, those that we already have). * * @param {function} pieceFilterFunc * @return {number} index of rarest piece, or -1 */ getRarestPiece (pieceFilterFunc) { let candidates = [] let min = Infinity for (let i = 0; i < this._numPieces; ++i) { if (pieceFilterFunc && !pieceFilterFunc(i)) continue const availability = this._pieces[i] if (availability === min) { candidates.push(i) } else if (availability < min) { candidates = [i] min = availability } } if (candidates.length) { // if there are multiple pieces with the same availability, choose one randomly return candidates[Math.random() * candidates.length | 0] } else { return -1 } } destroy () { this._torrent.removeListener('wire', this._onWire) this._torrent.wires.forEach(wire => { this._cleanupWireEvents(wire) }) this._torrent = null this._pieces = null this._onWire = null this._onWireHave = null this._onWireBitfield = null } _initWire (wire) { wire._onClose = () => { this._cleanupWireEvents(wire) for (let i = 0; i < this._numPieces; ++i) { this._pieces[i] -= wire.peerPieces.get(i) } } wire.on('have', this._onWireHave) wire.on('bitfield', this._onWireBitfield) wire.once('close', wire._onClose) } /** * Recalculates piece availability across all peers in the torrent. */ recalculate () { this._pieces.fill(0) for (const wire of this._torrent.wires) { for (let i = 0; i < this._numPieces; ++i) { this._pieces[i] += wire.peerPieces.get(i) } } } _cleanupWireEvents (wire) { wire.removeListener('have', this._onWireHave) wire.removeListener('bitfield', this._onWireBitfield) if (wire._onClose) wire.removeListener('close', wire._onClose) wire._onClose = null } } module.exports = RarityMap },{}],306:[function(require,module,exports){ (function (process,global){(function (){ /* global Blob */ const addrToIPPort = require('addr-to-ip-port') const BitField = require('bitfield').default const ChunkStoreWriteStream = require('chunk-store-stream/write') const debug = require('debug')('webtorrent:torrent') const Discovery = require('torrent-discovery') const EventEmitter = require('events').EventEmitter const fs = require('fs') const FSChunkStore = require('fs-chunk-store') // browser: `memory-chunk-store` const get = require('simple-get') const ImmediateChunkStore = require('immediate-chunk-store') const MultiStream = require('multistream') const net = require('net') // browser exclude const os = require('os') // browser exclude const parallel = require('run-parallel') const parallelLimit = require('run-parallel-limit') const parseTorrent = require('parse-torrent') const path = require('path') const Piece = require('torrent-piece') const pump = require('pump') const randomIterate = require('random-iterate') const sha1 = require('simple-sha1') const speedometer = require('speedometer') const utMetadata = require('ut_metadata') const utPex = require('ut_pex') // browser exclude const utp = require('utp-native') // browser exclude const File = require('./file') const Peer = require('./peer') const RarityMap = require('./rarity-map') const Server = require('./server') // browser exclude const MAX_BLOCK_LENGTH = 128 * 1024 const PIECE_TIMEOUT = 30000 const CHOKE_TIMEOUT = 5000 const SPEED_THRESHOLD = 3 * Piece.BLOCK_LENGTH const PIPELINE_MIN_DURATION = 0.5 const PIPELINE_MAX_DURATION = 1 const RECHOKE_INTERVAL = 10000 // 10 seconds const RECHOKE_OPTIMISTIC_DURATION = 2 // 30 seconds // IndexedDB chunk stores used in the browser benefit from maximum concurrency const FILESYSTEM_CONCURRENCY = process.browser ? Infinity : 2 const RECONNECT_WAIT = [1000, 5000, 15000] const VERSION = require('../package.json').version const USER_AGENT = `WebTorrent/${VERSION} (https://webtorrent.io)` let TMP try { TMP = path.join(fs.statSync('/tmp') && '/tmp', 'webtorrent') } catch (err) { TMP = path.join(typeof os.tmpdir === 'function' ? os.tmpdir() : '/', 'webtorrent') } class Torrent extends EventEmitter { constructor (torrentId, client, opts) { super() this._debugId = 'unknown infohash' this.client = client this.announce = opts.announce this.urlList = opts.urlList this.path = opts.path this.skipVerify = !!opts.skipVerify this._store = opts.store || FSChunkStore this._getAnnounceOpts = opts.getAnnounceOpts // if defined, `opts.private` overrides default privacy of torrent if (typeof opts.private === 'boolean') this.private = opts.private this.strategy = opts.strategy || 'sequential' this.maxWebConns = opts.maxWebConns || 4 this._rechokeNumSlots = (opts.uploads === false || opts.uploads === 0) ? 0 : (+opts.uploads || 10) this._rechokeOptimisticWire = null this._rechokeOptimisticTime = 0 this._rechokeIntervalId = null this.ready = false this.destroyed = false this.paused = false this.done = false this.metadata = null this.store = null this.files = [] this.pieces = [] this._amInterested = false this._selections = [] this._critical = [] this.wires = [] // open wires (added *after* handshake) this._queue = [] // queue of outgoing tcp peers to connect to this._peers = {} // connected peers (addr/peerId -> Peer) this._peersLength = 0 // number of elements in `this._peers` (cache, for perf) // stats this.received = 0 this.uploaded = 0 this._downloadSpeed = speedometer() this._uploadSpeed = speedometer() // for cleanup this._servers = [] this._xsRequests = [] // TODO: remove this and expose a hook instead // optimization: don't recheck every file if it hasn't changed this._fileModtimes = opts.fileModtimes if (torrentId !== null) this._onTorrentId(torrentId) this._debug('new torrent') } get timeRemaining () { if (this.done) return 0 if (this.downloadSpeed === 0) return Infinity return ((this.length - this.downloaded) / this.downloadSpeed) * 1000 } get downloaded () { if (!this.bitfield) return 0 let downloaded = 0 for (let index = 0, len = this.pieces.length; index < len; ++index) { if (this.bitfield.get(index)) { // verified data downloaded += (index === len - 1) ? this.lastPieceLength : this.pieceLength } else { // "in progress" data const piece = this.pieces[index] downloaded += (piece.length - piece.missing) } } return downloaded } // TODO: re-enable this. The number of missing pieces. Used to implement 'end game' mode. // Object.defineProperty(Storage.prototype, 'numMissing', { // get: function () { // var self = this // var numMissing = self.pieces.length // for (var index = 0, len = self.pieces.length; index < len; index++) { // numMissing -= self.bitfield.get(index) // } // return numMissing // } // }) get downloadSpeed () { return this._downloadSpeed() } get uploadSpeed () { return this._uploadSpeed() } get progress () { return this.length ? this.downloaded / this.length : 0 } get ratio () { return this.uploaded / (this.received || this.length) } get numPeers () { return this.wires.length } get torrentFileBlobURL () { if (typeof window === 'undefined') throw new Error('browser-only property') if (!this.torrentFile) return null return URL.createObjectURL( new Blob([this.torrentFile], { type: 'application/x-bittorrent' }) ) } get _numQueued () { return this._queue.length + (this._peersLength - this._numConns) } get _numConns () { let numConns = 0 for (const id in this._peers) { if (this._peers[id].connected) numConns += 1 } return numConns } // TODO: remove in v1 get swarm () { console.warn('WebTorrent: `torrent.swarm` is deprecated. Use `torrent` directly instead.') return this } _onTorrentId (torrentId) { if (this.destroyed) return let parsedTorrent try { parsedTorrent = parseTorrent(torrentId) } catch (err) {} if (parsedTorrent) { // Attempt to set infoHash property synchronously this.infoHash = parsedTorrent.infoHash this._debugId = parsedTorrent.infoHash.toString('hex').substring(0, 7) process.nextTick(() => { if (this.destroyed) return this._onParsedTorrent(parsedTorrent) }) } else { // If torrentId failed to parse, it could be in a form that requires an async // operation, i.e. http/https link, filesystem path, or Blob. parseTorrent.remote(torrentId, (err, parsedTorrent) => { if (this.destroyed) return if (err) return this._destroy(err) this._onParsedTorrent(parsedTorrent) }) } } _onParsedTorrent (parsedTorrent) { if (this.destroyed) return this._processParsedTorrent(parsedTorrent) if (!this.infoHash) { return this._destroy(new Error('Malformed torrent data: No info hash')) } if (!this.path) this.path = path.join(TMP, this.infoHash) this._rechokeIntervalId = setInterval(() => { this._rechoke() }, RECHOKE_INTERVAL) if (this._rechokeIntervalId.unref) this._rechokeIntervalId.unref() // Private 'infoHash' event allows client.add to check for duplicate torrents and // destroy them before the normal 'infoHash' event is emitted. Prevents user // applications from needing to deal with duplicate 'infoHash' events. this.emit('_infoHash', this.infoHash) if (this.destroyed) return this.emit('infoHash', this.infoHash) if (this.destroyed) return // user might destroy torrent in event handler if (this.client.listening) { this._onListening() } else { this.client.once('listening', () => { this._onListening() }) } } _processParsedTorrent (parsedTorrent) { this._debugId = parsedTorrent.infoHash.toString('hex').substring(0, 7) if (typeof this.private !== 'undefined') { // `private` option overrides default, only if it's defined parsedTorrent.private = this.private } if (this.announce) { // Allow specifying trackers via `opts` parameter parsedTorrent.announce = parsedTorrent.announce.concat(this.announce) } if (this.client.tracker && global.WEBTORRENT_ANNOUNCE && !parsedTorrent.private) { // So `webtorrent-hybrid` can force specific trackers to be used parsedTorrent.announce = parsedTorrent.announce.concat(global.WEBTORRENT_ANNOUNCE) } if (this.urlList) { // Allow specifying web seeds via `opts` parameter parsedTorrent.urlList = parsedTorrent.urlList.concat(this.urlList) } // remove duplicates by converting to Set and back parsedTorrent.announce = Array.from(new Set(parsedTorrent.announce)) parsedTorrent.urlList = Array.from(new Set(parsedTorrent.urlList)) Object.assign(this, parsedTorrent) this.magnetURI = parseTorrent.toMagnetURI(parsedTorrent) this.torrentFile = parseTorrent.toTorrentFile(parsedTorrent) } _onListening () { if (this.destroyed) return if (this.info) { // if full metadata was included in initial torrent id, use it immediately. Otherwise, // wait for torrent-discovery to find peers and ut_metadata to get the metadata. this._onMetadata(this) } else { if (this.xs) this._getMetadataFromServer() this._startDiscovery() } } _startDiscovery () { if (this.discovery || this.destroyed) return let trackerOpts = this.client.tracker if (trackerOpts) { trackerOpts = Object.assign({}, this.client.tracker, { getAnnounceOpts: () => { const opts = { uploaded: this.uploaded, downloaded: this.downloaded, left: Math.max(this.length - this.downloaded, 0) } if (this.client.tracker.getAnnounceOpts) { Object.assign(opts, this.client.tracker.getAnnounceOpts()) } if (this._getAnnounceOpts) { // TODO: consider deprecating this, as it's redundant with the former case Object.assign(opts, this._getAnnounceOpts()) } return opts } }) } // add BEP09 peer-address if (this.peerAddresses) { this.peerAddresses.forEach(peer => this.addPeer(peer)) } // begin discovering peers via DHT and trackers this.discovery = new Discovery({ infoHash: this.infoHash, announce: this.announce, peerId: this.client.peerId, dht: !this.private && this.client.dht, tracker: trackerOpts, port: this.client.torrentPort, userAgent: USER_AGENT, lsd: this.client.lsd }) this.discovery.on('error', (err) => { this._destroy(err) }) this.discovery.on('peer', (peer, source) => { this._debug('peer %s discovered via %s', peer, source) // Don't create new outgoing TCP connections when torrent is done if (typeof peer === 'string' && this.done) return this.addPeer(peer) }) this.discovery.on('trackerAnnounce', () => { this.emit('trackerAnnounce') if (this.numPeers === 0) this.emit('noPeers', 'tracker') }) this.discovery.on('dhtAnnounce', () => { this.emit('dhtAnnounce') if (this.numPeers === 0) this.emit('noPeers', 'dht') }) this.discovery.on('warning', (err) => { this.emit('warning', err) }) } _getMetadataFromServer () { // to allow function hoisting const self = this const urls = Array.isArray(this.xs) ? this.xs : [this.xs] const tasks = urls.map(url => cb => { getMetadataFromURL(url, cb) }) parallel(tasks) function getMetadataFromURL (url, cb) { if (url.indexOf('http://') !== 0 && url.indexOf('https://') !== 0) { self.emit('warning', new Error(`skipping non-http xs param: ${url}`)) return cb(null) } const opts = { url, method: 'GET', headers: { 'user-agent': USER_AGENT } } let req try { req = get.concat(opts, onResponse) } catch (err) { self.emit('warning', new Error(`skipping invalid url xs param: ${url}`)) return cb(null) } self._xsRequests.push(req) function onResponse (err, res, torrent) { if (self.destroyed) return cb(null) if (self.metadata) return cb(null) if (err) { self.emit('warning', new Error(`http error from xs param: ${url}`)) return cb(null) } if (res.statusCode !== 200) { self.emit('warning', new Error(`non-200 status code ${res.statusCode} from xs param: ${url}`)) return cb(null) } let parsedTorrent try { parsedTorrent = parseTorrent(torrent) } catch (err) {} if (!parsedTorrent) { self.emit('warning', new Error(`got invalid torrent file from xs param: ${url}`)) return cb(null) } if (parsedTorrent.infoHash !== self.infoHash) { self.emit('warning', new Error(`got torrent file with incorrect info hash from xs param: ${url}`)) return cb(null) } self._onMetadata(parsedTorrent) cb(null) } } } /** * Called when the full torrent metadata is received. */ _onMetadata (metadata) { if (this.metadata || this.destroyed) return this._debug('got metadata') this._xsRequests.forEach(req => { req.abort() }) this._xsRequests = [] let parsedTorrent if (metadata && metadata.infoHash) { // `metadata` is a parsed torrent (from parse-torrent module) parsedTorrent = metadata } else { try { parsedTorrent = parseTorrent(metadata) } catch (err) { return this._destroy(err) } } this._processParsedTorrent(parsedTorrent) this.metadata = this.torrentFile // add web seed urls (BEP19) if (this.client.enableWebSeeds) { this.urlList.forEach(url => { this.addWebSeed(url) }) } this._rarityMap = new RarityMap(this) this.store = new ImmediateChunkStore( new this._store(this.pieceLength, { torrent: { infoHash: this.infoHash }, files: this.files.map(file => ({ path: path.join(this.path, file.path), length: file.length, offset: file.offset })), length: this.length, name: this.infoHash }) ) this.files = this.files.map(file => new File(this, file)) // Select only specified files (BEP53) http://www.bittorrent.org/beps/bep_0053.html if (this.so) { this.files.forEach((v, i) => { if (this.so.includes(i)) { this.files[i].select() } else { this.files[i].deselect() } }) } else { // start off selecting the entire torrent with low priority if (this.pieces.length !== 0) { this.select(0, this.pieces.length - 1, false) } } this._hashes = this.pieces this.pieces = this.pieces.map((hash, i) => { const pieceLength = (i === this.pieces.length - 1) ? this.lastPieceLength : this.pieceLength return new Piece(pieceLength) }) this._reservations = this.pieces.map(() => []) this.bitfield = new BitField(this.pieces.length) this.wires.forEach(wire => { // If we didn't have the metadata at the time ut_metadata was initialized for this // wire, we still want to make it available to the peer in case they request it. if (wire.ut_metadata) wire.ut_metadata.setMetadata(this.metadata) this._onWireWithMetadata(wire) }) // Emit 'metadata' before 'ready' and 'done' this.emit('metadata') // User might destroy torrent in response to 'metadata' event if (this.destroyed) return if (this.skipVerify) { // Skip verifying exisitng data and just assume it's correct this._markAllVerified() this._onStore() } else { const onPiecesVerified = (err) => { if (err) return this._destroy(err) this._debug('done verifying') this._onStore() } this._debug('verifying existing torrent data') if (this._fileModtimes && this._store === FSChunkStore) { // don't verify if the files haven't been modified since we last checked this.getFileModtimes((err, fileModtimes) => { if (err) return this._destroy(err) const unchanged = this.files.map((_, index) => fileModtimes[index] === this._fileModtimes[index]).every(x => x) if (unchanged) { this._markAllVerified() this._onStore() } else { this._verifyPieces(onPiecesVerified) } }) } else { this._verifyPieces(onPiecesVerified) } } } /* * TODO: remove this * Gets the last modified time of every file on disk for this torrent. * Only valid in Node, not in the browser. */ getFileModtimes (cb) { const ret = [] parallelLimit(this.files.map((file, index) => cb => { fs.stat(path.join(this.path, file.path), (err, stat) => { if (err && err.code !== 'ENOENT') return cb(err) ret[index] = stat && stat.mtime.getTime() cb(null) }) }), FILESYSTEM_CONCURRENCY, err => { this._debug('done getting file modtimes') cb(err, ret) }) } _verifyPieces (cb) { parallelLimit(this.pieces.map((piece, index) => cb => { if (this.destroyed) return cb(new Error('torrent is destroyed')) this.store.get(index, (err, buf) => { if (this.destroyed) return cb(new Error('torrent is destroyed')) if (err) return process.nextTick(cb, null) // ignore error sha1(buf, hash => { if (this.destroyed) return cb(new Error('torrent is destroyed')) if (hash === this._hashes[index]) { if (!this.pieces[index]) return cb(null) this._debug('piece verified %s', index) this._markVerified(index) } else { this._debug('piece invalid %s', index) } cb(null) }) }) }), FILESYSTEM_CONCURRENCY, cb) } rescanFiles (cb) { if (this.destroyed) throw new Error('torrent is destroyed') if (!cb) cb = noop this._verifyPieces((err) => { if (err) { this._destroy(err) return cb(err) } this._checkDone() cb(null) }) } _markAllVerified () { for (let index = 0; index < this.pieces.length; index++) { this._markVerified(index) } } _markVerified (index) { this.pieces[index] = null this._reservations[index] = null this.bitfield.set(index, true) } /** * Called when the metadata, listening server, and underlying chunk store is initialized. */ _onStore () { if (this.destroyed) return this._debug('on store') // Start discovery before emitting 'ready' this._startDiscovery() this.ready = true this.emit('ready') // Files may start out done if the file was already in the store this._checkDone() // In case any selections were made before torrent was ready this._updateSelections() } destroy (opts, cb) { if (typeof opts === 'function') return this.destroy(null, opts) this._destroy(null, opts, cb) } _destroy (err, opts, cb) { if (typeof opts === 'function') return this._destroy(err, null, opts) if (this.destroyed) return this.destroyed = true this._debug('destroy') this.client._remove(this) clearInterval(this._rechokeIntervalId) this._xsRequests.forEach(req => { req.abort() }) if (this._rarityMap) { this._rarityMap.destroy() } for (const id in this._peers) { this.removePeer(id) } this.files.forEach(file => { if (file instanceof File) file._destroy() }) const tasks = this._servers.map(server => cb => { server.destroy(cb) }) if (this.discovery) { tasks.push(cb => { this.discovery.destroy(cb) }) } if (this.store) { tasks.push(cb => { if (opts && opts.destroyStore) { this.store.destroy(cb) } else { this.store.close(cb) } }) } parallel(tasks, cb) if (err) { // Torrent errors are emitted at `torrent.on('error')`. If there are no 'error' // event handlers on the torrent instance, then the error will be emitted at // `client.on('error')`. This prevents throwing an uncaught exception // (unhandled 'error' event), but it makes it impossible to distinguish client // errors versus torrent errors. Torrent errors are not fatal, and the client // is still usable afterwards. Therefore, always listen for errors in both // places (`client.on('error')` and `torrent.on('error')`). if (this.listenerCount('error') === 0) { this.client.emit('error', err) } else { this.emit('error', err) } } this.emit('close') this.client = null this.files = [] this.discovery = null this.store = null this._rarityMap = null this._peers = null this._servers = null this._xsRequests = null } addPeer (peer) { if (this.destroyed) throw new Error('torrent is destroyed') if (!this.infoHash) throw new Error('addPeer() must not be called before the `infoHash` event') if (this.client.blocked) { let host if (typeof peer === 'string') { let parts try { parts = addrToIPPort(peer) } catch (e) { this._debug('ignoring peer: invalid %s', peer) this.emit('invalidPeer', peer) return false } host = parts[0] } else if (typeof peer.remoteAddress === 'string') { host = peer.remoteAddress } if (host && this.client.blocked.contains(host)) { this._debug('ignoring peer: blocked %s', peer) if (typeof peer !== 'string') peer.destroy() this.emit('blockedPeer', peer) return false } } // if the utp connection fails to connect, then it is replaced with a tcp connection to the same ip:port const wasAdded = !!this._addPeer(peer, this.client.utp ? 'utp' : 'tcp') if (wasAdded) { this.emit('peer', peer) } else { this.emit('invalidPeer', peer) } return wasAdded } _addPeer (peer, type) { if (this.destroyed) { if (typeof peer !== 'string') peer.destroy() return null } if (typeof peer === 'string' && !this._validAddr(peer)) { this._debug('ignoring peer: invalid %s', peer) return null } const id = (peer && peer.id) || peer if (this._peers[id]) { this._debug('ignoring peer: duplicate (%s)', id) if (typeof peer !== 'string') peer.destroy() return null } if (this.paused) { this._debug('ignoring peer: torrent is paused') if (typeof peer !== 'string') peer.destroy() return null } this._debug('add peer %s', id) let newPeer if (typeof peer === 'string') { // `peer` is an addr ("ip:port" string) newPeer = type === 'utp' ? Peer.createUTPOutgoingPeer(peer, this) : Peer.createTCPOutgoingPeer(peer, this) } else { // `peer` is a WebRTC connection (simple-peer) newPeer = Peer.createWebRTCPeer(peer, this) } this._peers[newPeer.id] = newPeer this._peersLength += 1 if (typeof peer === 'string') { // `peer` is an addr ("ip:port" string) this._queue.push(newPeer) this._drain() } return newPeer } addWebSeed (url) { if (this.destroyed) throw new Error('torrent is destroyed') if (!/^https?:\/\/.+/.test(url)) { this.emit('warning', new Error(`ignoring invalid web seed: ${url}`)) this.emit('invalidPeer', url) return } if (this._peers[url]) { this.emit('warning', new Error(`ignoring duplicate web seed: ${url}`)) this.emit('invalidPeer', url) return } this._debug('add web seed %s', url) const newPeer = Peer.createWebSeedPeer(url, this) this._peers[newPeer.id] = newPeer this._peersLength += 1 this.emit('peer', url) } /** * Called whenever a new incoming TCP peer connects to this torrent swarm. Called with a * peer that has already sent a handshake. */ _addIncomingPeer (peer) { if (this.destroyed) return peer.destroy(new Error('torrent is destroyed')) if (this.paused) return peer.destroy(new Error('torrent is paused')) this._debug('add incoming peer %s', peer.id) this._peers[peer.id] = peer this._peersLength += 1 } removePeer (peer) { const id = (peer && peer.id) || peer peer = this._peers[id] if (!peer) return this._debug('removePeer %s', id) delete this._peers[id] this._peersLength -= 1 peer.destroy() // If torrent swarm was at capacity before, try to open a new connection now this._drain() } select (start, end, priority, notify) { if (this.destroyed) throw new Error('torrent is destroyed') if (start < 0 || end < start || this.pieces.length <= end) { throw new Error(`invalid selection ${start} : ${end}`) } priority = Number(priority) || 0 this._debug('select %s-%s (priority %s)', start, end, priority) this._selections.push({ from: start, to: end, offset: 0, priority, notify: notify || noop }) this._selections.sort((a, b) => b.priority - a.priority) this._updateSelections() } deselect (start, end, priority) { if (this.destroyed) throw new Error('torrent is destroyed') priority = Number(priority) || 0 this._debug('deselect %s-%s (priority %s)', start, end, priority) for (let i = 0; i < this._selections.length; ++i) { const s = this._selections[i] if (s.from === start && s.to === end && s.priority === priority) { this._selections.splice(i, 1) break } } this._updateSelections() } critical (start, end) { if (this.destroyed) throw new Error('torrent is destroyed') this._debug('critical %s-%s', start, end) for (let i = start; i <= end; ++i) { this._critical[i] = true } this._updateSelections() } _onWire (wire, addr) { this._debug('got wire %s (%s)', wire._debugId, addr || 'Unknown') wire.on('download', downloaded => { if (this.destroyed) return this.received += downloaded this._downloadSpeed(downloaded) this.client._downloadSpeed(downloaded) this.emit('download', downloaded) if (this.destroyed) return this.client.emit('download', downloaded) }) wire.on('upload', uploaded => { if (this.destroyed) return this.uploaded += uploaded this._uploadSpeed(uploaded) this.client._uploadSpeed(uploaded) this.emit('upload', uploaded) if (this.destroyed) return this.client.emit('upload', uploaded) }) this.wires.push(wire) if (addr) { // Sometimes RTCPeerConnection.getStats() doesn't return an ip:port for peers const parts = addrToIPPort(addr) wire.remoteAddress = parts[0] wire.remotePort = parts[1] } // When peer sends PORT message, add that DHT node to routing table if (this.client.dht && this.client.dht.listening) { wire.on('port', port => { if (this.destroyed || this.client.dht.destroyed) { return } if (!wire.remoteAddress) { return this._debug('ignoring PORT from peer with no address') } if (port === 0 || port > 65536) { return this._debug('ignoring invalid PORT from peer') } this._debug('port: %s (from %s)', port, addr) this.client.dht.addNode({ host: wire.remoteAddress, port }) }) } wire.on('timeout', () => { this._debug('wire timeout (%s)', addr) // TODO: this might be destroying wires too eagerly wire.destroy() }) // Timeout for piece requests to this peer wire.setTimeout(PIECE_TIMEOUT, true) // Send KEEP-ALIVE (every 60s) so peers will not disconnect the wire wire.setKeepAlive(true) // use ut_metadata extension wire.use(utMetadata(this.metadata)) wire.ut_metadata.on('warning', err => { this._debug('ut_metadata warning: %s', err.message) }) if (!this.metadata) { wire.ut_metadata.on('metadata', metadata => { this._debug('got metadata via ut_metadata') this._onMetadata(metadata) }) wire.ut_metadata.fetch() } // use ut_pex extension if the torrent is not flagged as private if (typeof utPex === 'function' && !this.private) { wire.use(utPex()) wire.ut_pex.on('peer', peer => { // Only add potential new peers when we're not seeding if (this.done) return this._debug('ut_pex: got peer: %s (from %s)', peer, addr) this.addPeer(peer) }) wire.ut_pex.on('dropped', peer => { // the remote peer believes a given peer has been dropped from the torrent swarm. // if we're not currently connected to it, then remove it from the queue. const peerObj = this._peers[peer] if (peerObj && !peerObj.connected) { this._debug('ut_pex: dropped peer: %s (from %s)', peer, addr) this.removePeer(peer) } }) wire.once('close', () => { // Stop sending updates to remote peer wire.ut_pex.reset() }) } // Hook to allow user-defined `bittorrent-protocol` extensions // More info: https://github.com/webtorrent/bittorrent-protocol#extension-api this.emit('wire', wire, addr) if (this.metadata) { process.nextTick(() => { // This allows wire.handshake() to be called (by Peer.onHandshake) before any // messages get sent on the wire this._onWireWithMetadata(wire) }) } } _onWireWithMetadata (wire) { let timeoutId = null const onChokeTimeout = () => { if (this.destroyed || wire.destroyed) return if (this._numQueued > 2 * (this._numConns - this.numPeers) && wire.amInterested) { wire.destroy() } else { timeoutId = setTimeout(onChokeTimeout, CHOKE_TIMEOUT) if (timeoutId.unref) timeoutId.unref() } } let i const updateSeedStatus = () => { if (wire.peerPieces.buffer.length !== this.bitfield.buffer.length) return for (i = 0; i < this.pieces.length; ++i) { if (!wire.peerPieces.get(i)) return } wire.isSeeder = true wire.choke() // always choke seeders } wire.on('bitfield', () => { updateSeedStatus() this._update() this._updateWireInterest(wire) }) wire.on('have', () => { updateSeedStatus() this._update() this._updateWireInterest(wire) }) wire.once('interested', () => { wire.unchoke() }) wire.once('close', () => { clearTimeout(timeoutId) }) wire.on('choke', () => { clearTimeout(timeoutId) timeoutId = setTimeout(onChokeTimeout, CHOKE_TIMEOUT) if (timeoutId.unref) timeoutId.unref() }) wire.on('unchoke', () => { clearTimeout(timeoutId) this._update() }) wire.on('request', (index, offset, length, cb) => { if (length > MAX_BLOCK_LENGTH) { // Per spec, disconnect from peers that request >128KB return wire.destroy() } if (this.pieces[index]) return this.store.get(index, { offset, length }, cb) }) wire.bitfield(this.bitfield) // always send bitfield (required) // initialize interest in case bitfield message was already received before above handler was registered this._updateWireInterest(wire) // Send PORT message to peers that support DHT if (wire.peerExtensions.dht && this.client.dht && this.client.dht.listening) { wire.port(this.client.dht.address().port) } if (wire.type !== 'webSeed') { // do not choke on webseeds timeoutId = setTimeout(onChokeTimeout, CHOKE_TIMEOUT) if (timeoutId.unref) timeoutId.unref() } wire.isSeeder = false updateSeedStatus() } /** * Called on selection changes. */ _updateSelections () { if (!this.ready || this.destroyed) return process.nextTick(() => { this._gcSelections() }) this._updateInterest() this._update() } /** * Garbage collect selections with respect to the store's current state. */ _gcSelections () { for (let i = 0; i < this._selections.length; ++i) { const s = this._selections[i] const oldOffset = s.offset // check for newly downloaded pieces in selection while (this.bitfield.get(s.from + s.offset) && s.from + s.offset < s.to) { s.offset += 1 } if (oldOffset !== s.offset) s.notify() if (s.to !== s.from + s.offset) continue if (!this.bitfield.get(s.from + s.offset)) continue this._selections.splice(i, 1) // remove fully downloaded selection i -= 1 // decrement i to offset splice s.notify() this._updateInterest() } if (!this._selections.length) this.emit('idle') } /** * Update interested status for all peers. */ _updateInterest () { const prev = this._amInterested this._amInterested = !!this._selections.length this.wires.forEach(wire => this._updateWireInterest(wire)) if (prev === this._amInterested) return if (this._amInterested) this.emit('interested') else this.emit('uninterested') } _updateWireInterest (wire) { let interested = false for (let index = 0; index < this.pieces.length; ++index) { if (this.pieces[index] && wire.peerPieces.get(index)) { interested = true break } } if (interested) wire.interested() else wire.uninterested() } /** * Heartbeat to update all peers and their requests. */ _update () { if (this.destroyed) return // update wires in random order for better request distribution const ite = randomIterate(this.wires) let wire while ((wire = ite())) { this._updateWireWrapper(wire) } } _updateWireWrapper (wire) { const self = this if (typeof window !== 'undefined' && typeof window.requestIdleCallback === 'function') { window.requestIdleCallback(function () { self._updateWire(wire) }, { timeout: 250 }) } else { self._updateWire(wire) } } /** * Attempts to update a peer's requests */ _updateWire (wire) { // to allow function hoisting const self = this if (wire.peerChoking) return if (!wire.downloaded) return validateWire() const minOutstandingRequests = getBlockPipelineLength(wire, PIPELINE_MIN_DURATION) if (wire.requests.length >= minOutstandingRequests) return const maxOutstandingRequests = getBlockPipelineLength(wire, PIPELINE_MAX_DURATION) trySelectWire(false) || trySelectWire(true) function genPieceFilterFunc (start, end, tried, rank) { return i => i >= start && i <= end && !(i in tried) && wire.peerPieces.get(i) && (!rank || rank(i)) } // TODO: Do we need both validateWire and trySelectWire? function validateWire () { if (wire.requests.length) return let i = self._selections.length while (i--) { const next = self._selections[i] let piece if (self.strategy === 'rarest') { const start = next.from + next.offset const end = next.to const len = end - start + 1 const tried = {} let tries = 0 const filter = genPieceFilterFunc(start, end, tried) while (tries < len) { piece = self._rarityMap.getRarestPiece(filter) if (piece < 0) break if (self._request(wire, piece, false)) return tried[piece] = true tries += 1 } } else { for (piece = next.to; piece >= next.from + next.offset; --piece) { if (!wire.peerPieces.get(piece)) continue if (self._request(wire, piece, false)) return } } } // TODO: wire failed to validate as useful; should we close it? // probably not, since 'have' and 'bitfield' messages might be coming } function speedRanker () { const speed = wire.downloadSpeed() || 1 if (speed > SPEED_THRESHOLD) return () => true const secs = Math.max(1, wire.requests.length) * Piece.BLOCK_LENGTH / speed let tries = 10 let ptr = 0 return index => { if (!tries || self.bitfield.get(index)) return true let missing = self.pieces[index].missing for (; ptr < self.wires.length; ptr++) { const otherWire = self.wires[ptr] const otherSpeed = otherWire.downloadSpeed() if (otherSpeed < SPEED_THRESHOLD) continue if (otherSpeed <= speed) continue if (!otherWire.peerPieces.get(index)) continue if ((missing -= otherSpeed * secs) > 0) continue tries-- return false } return true } } function shufflePriority (i) { let last = i for (let j = i; j < self._selections.length && self._selections[j].priority; j++) { last = j } const tmp = self._selections[i] self._selections[i] = self._selections[last] self._selections[last] = tmp } function trySelectWire (hotswap) { if (wire.requests.length >= maxOutstandingRequests) return true const rank = speedRanker() for (let i = 0; i < self._selections.length; i++) { const next = self._selections[i] let piece if (self.strategy === 'rarest') { const start = next.from + next.offset const end = next.to const len = end - start + 1 const tried = {} let tries = 0 const filter = genPieceFilterFunc(start, end, tried, rank) while (tries < len) { piece = self._rarityMap.getRarestPiece(filter) if (piece < 0) break while (self._request(wire, piece, self._critical[piece] || hotswap)) { // body intentionally empty // request all non-reserved blocks in this piece } if (wire.requests.length < maxOutstandingRequests) { tried[piece] = true tries++ continue } if (next.priority) shufflePriority(i) return true } } else { for (piece = next.from + next.offset; piece <= next.to; piece++) { if (!wire.peerPieces.get(piece) || !rank(piece)) continue while (self._request(wire, piece, self._critical[piece] || hotswap)) { // body intentionally empty // request all non-reserved blocks in piece } if (wire.requests.length < maxOutstandingRequests) continue if (next.priority) shufflePriority(i) return true } } } return false } } /** * Called periodically to update the choked status of all peers, handling optimistic * unchoking as described in BEP3. */ _rechoke () { if (!this.ready) return // wires in increasing order of quality (pop() gives next best peer) const wireStack = this.wires .map(wire => ({ wire, random: Math.random() })) // insert a random seed for randomizing the sort .sort((objA, objB) => { const wireA = objA.wire const wireB = objB.wire // prefer peers that send us data faster if (wireA.downloadSpeed() !== wireB.downloadSpeed()) { return wireA.downloadSpeed() - wireB.downloadSpeed() } // then prefer peers that can download data from us faster if (wireA.uploadSpeed() !== wireB.uploadSpeed()) { return wireA.uploadSpeed() - wireB.uploadSpeed() } // then prefer already unchoked peers (to minimize fibrillation) if (wireA.amChoking !== wireB.amChoking) { return wireA.amChoking ? -1 : 1 // choking < unchoked } // otherwise random order return objA.random - objB.random }) .map(obj => obj.wire) // return array of wires (remove random seed) if (this._rechokeOptimisticTime <= 0) { // clear old optimistic peer, so it can be rechoked normally and then replaced this._rechokeOptimisticWire = null } else { this._rechokeOptimisticTime -= 1 } let numInterestedUnchoked = 0 // leave one rechoke slot open for optimistic unchoking while (wireStack.length > 0 && numInterestedUnchoked < this._rechokeNumSlots - 1) { const wire = wireStack.pop() // next best quality peer if (wire.isSeeder || wire === this._rechokeOptimisticWire) { continue } wire.unchoke() // only stop unchoking once we fill the slots with interested peers that will actually download if (wire.peerInterested) { numInterestedUnchoked++ } } // fill optimistic unchoke slot if empty if (this._rechokeOptimisticWire === null && this._rechokeNumSlots > 0) { // don't optimistically unchoke uninterested peers const remaining = wireStack.filter(wire => wire.peerInterested) if (remaining.length > 0) { // select random remaining (not yet unchoked) peer const newOptimisticPeer = remaining[randomInt(remaining.length)] newOptimisticPeer.unchoke() this._rechokeOptimisticWire = newOptimisticPeer this._rechokeOptimisticTime = RECHOKE_OPTIMISTIC_DURATION } } // choke the rest wireStack .filter(wire => wire !== this._rechokeOptimisticWire) // except the optimistically unchoked peer .forEach(wire => wire.choke()) } /** * Attempts to cancel a slow block request from another wire such that the * given wire may effectively swap out the request for one of its own. */ _hotswap (wire, index) { const speed = wire.downloadSpeed() if (speed < Piece.BLOCK_LENGTH) return false if (!this._reservations[index]) return false const r = this._reservations[index] if (!r) { return false } let minSpeed = Infinity let minWire let i for (i = 0; i < r.length; i++) { const otherWire = r[i] if (!otherWire || otherWire === wire) continue const otherSpeed = otherWire.downloadSpeed() if (otherSpeed >= SPEED_THRESHOLD) continue if (2 * otherSpeed > speed || otherSpeed > minSpeed) continue minWire = otherWire minSpeed = otherSpeed } if (!minWire) return false for (i = 0; i < r.length; i++) { if (r[i] === minWire) r[i] = null } for (i = 0; i < minWire.requests.length; i++) { const req = minWire.requests[i] if (req.piece !== index) continue this.pieces[index].cancel((req.offset / Piece.BLOCK_LENGTH) | 0) } this.emit('hotswap', minWire, wire, index) return true } /** * Attempts to request a block from the given wire. */ _request (wire, index, hotswap) { const self = this const numRequests = wire.requests.length const isWebSeed = wire.type === 'webSeed' if (self.bitfield.get(index)) return false const maxOutstandingRequests = isWebSeed ? Math.min( getPiecePipelineLength(wire, PIPELINE_MAX_DURATION, self.pieceLength), self.maxWebConns ) : getBlockPipelineLength(wire, PIPELINE_MAX_DURATION) if (numRequests >= maxOutstandingRequests) return false // var endGame = (wire.requests.length === 0 && self.store.numMissing < 30) const piece = self.pieces[index] let reservation = isWebSeed ? piece.reserveRemaining() : piece.reserve() if (reservation === -1 && hotswap && self._hotswap(wire, index)) { reservation = isWebSeed ? piece.reserveRemaining() : piece.reserve() } if (reservation === -1) return false let r = self._reservations[index] if (!r) r = self._reservations[index] = [] let i = r.indexOf(null) if (i === -1) i = r.length r[i] = wire const chunkOffset = piece.chunkOffset(reservation) const chunkLength = isWebSeed ? piece.chunkLengthRemaining(reservation) : piece.chunkLength(reservation) wire.request(index, chunkOffset, chunkLength, function onChunk (err, chunk) { if (self.destroyed) return // TODO: what is this for? if (!self.ready) return self.once('ready', () => { onChunk(err, chunk) }) if (r[i] === wire) r[i] = null if (piece !== self.pieces[index]) return onUpdateTick() if (err) { self._debug( 'error getting piece %s (offset: %s length: %s) from %s: %s', index, chunkOffset, chunkLength, `${wire.remoteAddress}:${wire.remotePort}`, err.message ) isWebSeed ? piece.cancelRemaining(reservation) : piece.cancel(reservation) onUpdateTick() return } self._debug( 'got piece %s (offset: %s length: %s) from %s', index, chunkOffset, chunkLength, `${wire.remoteAddress}:${wire.remotePort}` ) if (!piece.set(reservation, chunk, wire)) return onUpdateTick() const buf = piece.flush() // TODO: might need to set self.pieces[index] = null here since sha1 is async sha1(buf, hash => { if (self.destroyed) return if (hash === self._hashes[index]) { if (!self.pieces[index]) return self._debug('piece verified %s', index) self.pieces[index] = null self._reservations[index] = null self.bitfield.set(index, true) self.store.put(index, buf) self.wires.forEach(wire => { wire.have(index) }) // We also check `self.destroyed` since `torrent.destroy()` could have been // called in the `torrent.on('done')` handler, triggered by `_checkDone()`. if (self._checkDone() && !self.destroyed) self.discovery.complete() } else { self.pieces[index] = new Piece(piece.length) self.emit('warning', new Error(`Piece ${index} failed verification`)) } onUpdateTick() }) }) function onUpdateTick () { process.nextTick(() => { self._update() }) } return true } _checkDone () { if (this.destroyed) return // are any new files done? this.files.forEach(file => { if (file.done) return for (let i = file._startPiece; i <= file._endPiece; ++i) { if (!this.bitfield.get(i)) return } file.done = true file.emit('done') this._debug(`file done: ${file.name}`) }) // is the torrent done? (if all current selections are satisfied, or there are // no selections, then torrent is done) let done = true for (let i = 0; i < this._selections.length; i++) { const selection = this._selections[i] for (let piece = selection.from; piece <= selection.to; piece++) { if (!this.bitfield.get(piece)) { done = false break } } if (!done) break } if (!this.done && done) { this.done = true this._debug(`torrent done: ${this.infoHash}`) this.emit('done') } this._gcSelections() return done } load (streams, cb) { if (this.destroyed) throw new Error('torrent is destroyed') if (!this.ready) return this.once('ready', () => { this.load(streams, cb) }) if (!Array.isArray(streams)) streams = [streams] if (!cb) cb = noop const readable = new MultiStream(streams) const writable = new ChunkStoreWriteStream(this.store, this.pieceLength) pump(readable, writable, err => { if (err) return cb(err) this._markAllVerified() this._checkDone() cb(null) }) } createServer (requestListener) { if (typeof Server !== 'function') throw new Error('node.js-only method') if (this.destroyed) throw new Error('torrent is destroyed') const server = new Server(this, requestListener) this._servers.push(server) return server } pause () { if (this.destroyed) return this._debug('pause') this.paused = true } resume () { if (this.destroyed) return this._debug('resume') this.paused = false this._drain() } _debug () { const args = [].slice.call(arguments) args[0] = `[${this.client ? this.client._debugId : 'No Client'}] [${this._debugId}] ${args[0]}` debug(...args) } /** * Pop a peer off the FIFO queue and connect to it. When _drain() gets called, * the queue will usually have only one peer in it, except when there are too * many peers (over `this.maxConns`) in which case they will just sit in the * queue until another connection closes. */ _drain () { this._debug('_drain numConns %s maxConns %s', this._numConns, this.client.maxConns) if (typeof net.connect !== 'function' || this.destroyed || this.paused || this._numConns >= this.client.maxConns) { return } this._debug('drain (%s queued, %s/%s peers)', this._numQueued, this.numPeers, this.client.maxConns) const peer = this._queue.shift() if (!peer) return // queue could be empty this._debug('%s connect attempt to %s', peer.type, peer.addr) const parts = addrToIPPort(peer.addr) const opts = { host: parts[0], port: parts[1] } if (peer.type === 'utpOutgoing') { peer.conn = utp.connect(opts.port, opts.host) } else { peer.conn = net.connect(opts) } const conn = peer.conn conn.once('connect', () => { peer.onConnect() }) conn.once('error', err => { peer.destroy(err) }) peer.startConnectTimeout() // When connection closes, attempt reconnect after timeout (with exponential backoff) conn.on('close', () => { if (this.destroyed) return if (peer.retries >= RECONNECT_WAIT.length) { if (this.client.utp) { const newPeer = this._addPeer(peer.addr, 'tcp') if (newPeer) newPeer.retries = 0 } else { this._debug( 'conn %s closed: will not re-add (max %s attempts)', peer.addr, RECONNECT_WAIT.length ) } return } const ms = RECONNECT_WAIT[peer.retries] this._debug( 'conn %s closed: will re-add to queue in %sms (attempt %s)', peer.addr, ms, peer.retries + 1 ) const reconnectTimeout = setTimeout(() => { if (this.destroyed) return const newPeer = this._addPeer(peer.addr, this.client.utp ? 'utp' : 'tcp') if (newPeer) newPeer.retries = peer.retries + 1 }, ms) if (reconnectTimeout.unref) reconnectTimeout.unref() }) } /** * Returns `true` if string is valid IPv4/6 address. * @param {string} addr * @return {boolean} */ _validAddr (addr) { let parts try { parts = addrToIPPort(addr) } catch (e) { return false } const host = parts[0] const port = parts[1] return port > 0 && port < 65535 && !(host === '127.0.0.1' && port === this.client.torrentPort) } } function getBlockPipelineLength (wire, duration) { return 2 + Math.ceil(duration * wire.downloadSpeed() / Piece.BLOCK_LENGTH) } function getPiecePipelineLength (wire, duration, pieceLength) { return 1 + Math.ceil(duration * wire.downloadSpeed() / pieceLength) } /** * Returns a random integer in [0,high) */ function randomInt (high) { return Math.random() * high | 0 } function noop () {} module.exports = Torrent }).call(this)}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{"../package.json":326,"./file":303,"./peer":304,"./rarity-map":305,"./server":330,"_process":338,"addr-to-ip-port":2,"bitfield":9,"chunk-store-stream/write":74,"debug":308,"events":333,"fs":328,"fs-chunk-store":154,"immediate-chunk-store":130,"multistream":177,"net":330,"os":330,"parse-torrent":195,"path":337,"pump":197,"random-iterate":199,"run-parallel":224,"run-parallel-limit":223,"simple-get":236,"simple-sha1":256,"speedometer":277,"torrent-discovery":285,"torrent-piece":289,"ut_metadata":294,"ut_pex":330,"utp-native":330}],307:[function(require,module,exports){ (function (Buffer){(function (){ const BitField = require('bitfield').default const debug = require('debug')('webtorrent:webconn') const get = require('simple-get') const sha1 = require('simple-sha1') const Wire = require('bittorrent-protocol') const VERSION = require('../package.json').version /** * Converts requests for torrent blocks into http range requests. * @param {string} url web seed url * @param {Object} torrent */ class WebConn extends Wire { constructor (url, torrent) { super() this.url = url this.webPeerId = sha1.sync(url) this._torrent = torrent this._init() } _init () { this.setKeepAlive(true) this.once('handshake', (infoHash, peerId) => { if (this.destroyed) return this.handshake(infoHash, this.webPeerId) const numPieces = this._torrent.pieces.length const bitfield = new BitField(numPieces) for (let i = 0; i <= numPieces; i++) { bitfield.set(i, true) } this.bitfield(bitfield) }) this.once('interested', () => { debug('interested') this.unchoke() }) this.on('uninterested', () => { debug('uninterested') }) this.on('choke', () => { debug('choke') }) this.on('unchoke', () => { debug('unchoke') }) this.on('bitfield', () => { debug('bitfield') }) this.on('request', (pieceIndex, offset, length, callback) => { debug('request pieceIndex=%d offset=%d length=%d', pieceIndex, offset, length) this.httpRequest(pieceIndex, offset, length, callback) }) } httpRequest (pieceIndex, offset, length, cb) { const pieceOffset = pieceIndex * this._torrent.pieceLength const rangeStart = pieceOffset + offset /* offset within whole torrent */ const rangeEnd = rangeStart + length - 1 // Web seed URL format: // For single-file torrents, make HTTP range requests directly to the web seed URL // For multi-file torrents, add the torrent folder and file name to the URL const files = this._torrent.files let requests if (files.length <= 1) { requests = [{ url: this.url, start: rangeStart, end: rangeEnd }] } else { const requestedFiles = files.filter(file => { return file.offset <= rangeEnd && (file.offset + file.length) > rangeStart }) if (requestedFiles.length < 1) { return cb(new Error('Could not find file corresponnding to web seed range request')) } requests = requestedFiles.map(requestedFile => { const fileEnd = requestedFile.offset + requestedFile.length - 1 const url = this.url + (this.url[this.url.length - 1] === '/' ? '' : '/') + requestedFile.path return { url, fileOffsetInRange: Math.max(requestedFile.offset - rangeStart, 0), start: Math.max(rangeStart - requestedFile.offset, 0), end: Math.min(fileEnd, rangeEnd - requestedFile.offset) } }) } // Now make all the HTTP requests we need in order to load this piece // Usually that's one requests, but sometimes it will be multiple // Send requests in parallel and wait for them all to come back let numRequestsSucceeded = 0 let hasError = false let ret if (requests.length > 1) { ret = Buffer.alloc(length) } requests.forEach(request => { const url = request.url const start = request.start const end = request.end debug( 'Requesting url=%s pieceIndex=%d offset=%d length=%d start=%d end=%d', url, pieceIndex, offset, length, start, end ) const opts = { url, method: 'GET', headers: { 'user-agent': `WebTorrent/${VERSION} (https://webtorrent.io)`, range: `bytes=${start}-${end}` } } function onResponse (res, data) { if (res.statusCode < 200 || res.statusCode >= 300) { hasError = true return cb(new Error(`Unexpected HTTP status code ${res.statusCode}`)) } debug('Got data of length %d', data.length) if (requests.length === 1) { // Common case: fetch piece in a single HTTP request, return directly cb(null, data) } else { // Rare case: reconstruct multiple HTTP requests across 2+ files into one // piece buffer data.copy(ret, request.fileOffsetInRange) if (++numRequestsSucceeded === requests.length) { cb(null, ret) } } } get.concat(opts, (err, res, data) => { if (hasError) return if (err) { // Browsers allow HTTP redirects for simple cross-origin // requests but not for requests that require preflight. // Use a simple request to unravel any redirects and get the // final URL. Retry the original request with the new URL if // it's different. // // This test is imperfect but it's simple and good for common // cases. It catches all cross-origin cases but matches a few // same-origin cases too. if (typeof window === 'undefined' || url.startsWith(`${window.location.origin}/`)) { hasError = true return cb(err) } return get.head(url, (errHead, res) => { if (hasError) return if (errHead) { hasError = true return cb(errHead) } if (res.statusCode < 200 || res.statusCode >= 300) { hasError = true return cb(new Error(`Unexpected HTTP status code ${res.statusCode}`)) } if (res.url === url) { hasError = true return cb(err) } opts.url = res.url get.concat(opts, (err, res, data) => { if (hasError) return if (err) { hasError = true return cb(err) } onResponse(res, data) }) }) } onResponse(res, data) }) }) } destroy () { super.destroy() this._torrent = null } } module.exports = WebConn }).call(this)}).call(this,require("buffer").Buffer) },{"../package.json":326,"bitfield":9,"bittorrent-protocol":10,"buffer":331,"debug":308,"simple-get":236,"simple-sha1":256}],308:[function(require,module,exports){ arguments[4][11][0].apply(exports,arguments) },{"./common":309,"_process":338,"dup":11}],309:[function(require,module,exports){ arguments[4][12][0].apply(exports,arguments) },{"dup":12,"ms":310}],310:[function(require,module,exports){ arguments[4][13][0].apply(exports,arguments) },{"dup":13}],311:[function(require,module,exports){ arguments[4][14][0].apply(exports,arguments) },{"dup":14}],312:[function(require,module,exports){ arguments[4][15][0].apply(exports,arguments) },{"./_stream_readable":314,"./_stream_writable":316,"_process":338,"dup":15,"inherits":131}],313:[function(require,module,exports){ arguments[4][16][0].apply(exports,arguments) },{"./_stream_transform":315,"dup":16,"inherits":131}],314:[function(require,module,exports){ arguments[4][17][0].apply(exports,arguments) },{"../errors":311,"./_stream_duplex":312,"./internal/streams/async_iterator":317,"./internal/streams/buffer_list":318,"./internal/streams/destroy":319,"./internal/streams/from":321,"./internal/streams/state":323,"./internal/streams/stream":324,"_process":338,"buffer":331,"dup":17,"events":333,"inherits":131,"string_decoder/":281,"util":330}],315:[function(require,module,exports){ arguments[4][18][0].apply(exports,arguments) },{"../errors":311,"./_stream_duplex":312,"dup":18,"inherits":131}],316:[function(require,module,exports){ arguments[4][19][0].apply(exports,arguments) },{"../errors":311,"./_stream_duplex":312,"./internal/streams/destroy":319,"./internal/streams/state":323,"./internal/streams/stream":324,"_process":338,"buffer":331,"dup":19,"inherits":131,"util-deprecate":298}],317:[function(require,module,exports){ arguments[4][20][0].apply(exports,arguments) },{"./end-of-stream":320,"_process":338,"dup":20}],318:[function(require,module,exports){ arguments[4][21][0].apply(exports,arguments) },{"buffer":331,"dup":21,"util":330}],319:[function(require,module,exports){ arguments[4][22][0].apply(exports,arguments) },{"_process":338,"dup":22}],320:[function(require,module,exports){ arguments[4][23][0].apply(exports,arguments) },{"../../../errors":311,"dup":23}],321:[function(require,module,exports){ arguments[4][24][0].apply(exports,arguments) },{"dup":24}],322:[function(require,module,exports){ arguments[4][25][0].apply(exports,arguments) },{"../../../errors":311,"./end-of-stream":320,"dup":25}],323:[function(require,module,exports){ arguments[4][26][0].apply(exports,arguments) },{"../../../errors":311,"dup":26}],324:[function(require,module,exports){ arguments[4][27][0].apply(exports,arguments) },{"dup":27,"events":333}],325:[function(require,module,exports){ arguments[4][28][0].apply(exports,arguments) },{"./lib/_stream_duplex.js":312,"./lib/_stream_passthrough.js":313,"./lib/_stream_readable.js":314,"./lib/_stream_transform.js":315,"./lib/_stream_writable.js":316,"./lib/internal/streams/end-of-stream.js":320,"./lib/internal/streams/pipeline.js":322,"dup":28}],326:[function(require,module,exports){ module.exports={ "version": "0.112.0" } },{}],327:[function(require,module,exports){ // Returns a wrapper function that returns a wrapped callback // The wrapper function should do some stuff, and return a // presumably different callback function. // This makes sure that own properties are retained, so that // decorations and such are not lost along the way. module.exports = wrappy function wrappy (fn, cb) { if (fn && cb) return wrappy(fn)(cb) if (typeof fn !== 'function') throw new TypeError('need wrapper function') Object.keys(fn).forEach(function (k) { wrapper[k] = fn[k] }) return wrapper function wrapper() { var args = new Array(arguments.length) for (var i = 0; i < args.length; i++) { args[i] = arguments[i] } var ret = fn.apply(this, args) var cb = args[args.length-1] if (typeof ret === 'function' && ret !== cb) { Object.keys(cb).forEach(function (k) { ret[k] = cb[k] }) } return ret } } },{}],328:[function(require,module,exports){ },{}],329:[function(require,module,exports){ 'use strict' exports.byteLength = byteLength exports.toByteArray = toByteArray exports.fromByteArray = fromByteArray var lookup = [] var revLookup = [] var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' for (var i = 0, len = code.length; i < len; ++i) { lookup[i] = code[i] revLookup[code.charCodeAt(i)] = i } // Support decoding URL-safe base64 strings, as Node.js does. // See: https://en.wikipedia.org/wiki/Base64#URL_applications revLookup['-'.charCodeAt(0)] = 62 revLookup['_'.charCodeAt(0)] = 63 function getLens (b64) { var len = b64.length if (len % 4 > 0) { throw new Error('Invalid string. Length must be a multiple of 4') } // Trim off extra bytes after placeholder bytes are found // See: https://github.com/beatgammit/base64-js/issues/42 var validLen = b64.indexOf('=') if (validLen === -1) validLen = len var placeHoldersLen = validLen === len ? 0 : 4 - (validLen % 4) return [validLen, placeHoldersLen] } // base64 is 4/3 + up to two characters of the original data function byteLength (b64) { var lens = getLens(b64) var validLen = lens[0] var placeHoldersLen = lens[1] return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen } function _byteLength (b64, validLen, placeHoldersLen) { return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen } function toByteArray (b64) { var tmp var lens = getLens(b64) var validLen = lens[0] var placeHoldersLen = lens[1] var arr = new Arr(_byteLength(b64, validLen, placeHoldersLen)) var curByte = 0 // if there are placeholders, only get up to the last complete 4 chars var len = placeHoldersLen > 0 ? validLen - 4 : validLen var i for (i = 0; i < len; i += 4) { tmp = (revLookup[b64.charCodeAt(i)] << 18) | (revLookup[b64.charCodeAt(i + 1)] << 12) | (revLookup[b64.charCodeAt(i + 2)] << 6) | revLookup[b64.charCodeAt(i + 3)] arr[curByte++] = (tmp >> 16) & 0xFF arr[curByte++] = (tmp >> 8) & 0xFF arr[curByte++] = tmp & 0xFF } if (placeHoldersLen === 2) { tmp = (revLookup[b64.charCodeAt(i)] << 2) | (revLookup[b64.charCodeAt(i + 1)] >> 4) arr[curByte++] = tmp & 0xFF } if (placeHoldersLen === 1) { tmp = (revLookup[b64.charCodeAt(i)] << 10) | (revLookup[b64.charCodeAt(i + 1)] << 4) | (revLookup[b64.charCodeAt(i + 2)] >> 2) arr[curByte++] = (tmp >> 8) & 0xFF arr[curByte++] = tmp & 0xFF } return arr } function tripletToBase64 (num) { return lookup[num >> 18 & 0x3F] + lookup[num >> 12 & 0x3F] + lookup[num >> 6 & 0x3F] + lookup[num & 0x3F] } function encodeChunk (uint8, start, end) { var tmp var output = [] for (var i = start; i < end; i += 3) { tmp = ((uint8[i] << 16) & 0xFF0000) + ((uint8[i + 1] << 8) & 0xFF00) + (uint8[i + 2] & 0xFF) output.push(tripletToBase64(tmp)) } return output.join('') } function fromByteArray (uint8) { var tmp var len = uint8.length var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes var parts = [] var maxChunkLength = 16383 // must be multiple of 3 // go through the array every three bytes, we'll deal with trailing stuff later for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) { parts.push(encodeChunk(uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength))) } // pad the end with zeros, but make sure to not forget the extra bytes if (extraBytes === 1) { tmp = uint8[len - 1] parts.push( lookup[tmp >> 2] + lookup[(tmp << 4) & 0x3F] + '==' ) } else if (extraBytes === 2) { tmp = (uint8[len - 2] << 8) + uint8[len - 1] parts.push( lookup[tmp >> 10] + lookup[(tmp >> 4) & 0x3F] + lookup[(tmp << 2) & 0x3F] + '=' ) } return parts.join('') } },{}],330:[function(require,module,exports){ arguments[4][328][0].apply(exports,arguments) },{"dup":328}],331:[function(require,module,exports){ (function (Buffer){(function (){ /*! * 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 } } Object.defineProperty(Buffer.prototype, 'parent', { enumerable: true, get: function () { if (!Buffer.isBuffer(this)) return undefined return this.buffer } }) Object.defineProperty(Buffer.prototype, 'offset', { enumerable: true, get: function () { if (!Buffer.isBuffer(this)) return undefined return this.byteOffset } }) function createBuffer (length) { if (length > K_MAX_LENGTH) { throw new RangeError('The value "' + length + '" is invalid for option "size"') } // Return an augmented `Uint8Array` instance var buf = new Uint8Array(length) 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 TypeError( 'The "string" argument must be of type string. Received type number' ) } 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 != null && 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 === 'string') { return fromString(value, encodingOrOffset) } if (ArrayBuffer.isView(value)) { return fromArrayLike(value) } if (value == null) { throw TypeError( 'The first argument must be one of type string, Buffer, ArrayBuffer, Array, ' + 'or Array-like Object. Received type ' + (typeof value) ) } if (isInstance(value, ArrayBuffer) || (value && isInstance(value.buffer, ArrayBuffer))) { return fromArrayBuffer(value, encodingOrOffset, length) } if (typeof value === 'number') { throw new TypeError( 'The "value" argument must not be of type number. Received type number' ) } var valueOf = value.valueOf && value.valueOf() if (valueOf != null && valueOf !== value) { return Buffer.from(valueOf, encodingOrOffset, length) } var b = fromObject(value) if (b) return b if (typeof Symbol !== 'undefined' && Symbol.toPrimitive != null && typeof value[Symbol.toPrimitive] === 'function') { return Buffer.from( value[Symbol.toPrimitive]('string'), encodingOrOffset, length ) } throw new TypeError( 'The first argument must be one of type string, Buffer, ArrayBuffer, Array, ' + 'or Array-like Object. Received type ' + (typeof value) ) } /** * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError * if value is a number. * Buffer.from(str[, encoding]) * Buffer.from(array) * Buffer.from(buffer) * Buffer.from(arrayBuffer[, byteOffset[, length]]) **/ Buffer.from = function (value, encodingOrOffset, length) { return from(value, encodingOrOffset, length) } // Note: Change prototype *after* Buffer.from is defined to workaround Chrome bug: // https://github.com/feross/buffer/pull/148 Buffer.prototype.__proto__ = Uint8Array.prototype Buffer.__proto__ = Uint8Array function assertSize (size) { if (typeof size !== 'number') { throw new TypeError('"size" argument must be of type number') } else if (size < 0) { throw new RangeError('The value "' + size + '" is invalid for option "size"') } } function alloc (size, fill, encoding) { assertSize(size) if (size <= 0) { return createBuffer(size) } if (fill !== undefined) { // Only pay attention to encoding if it's a string. This // prevents accidentally sending in a number that would // be 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('Unknown encoding: ' + encoding) } var length = byteLength(string, encoding) | 0 var buf = createBuffer(length) var actual = buf.write(string, encoding) if (actual !== length) { // Writing a hex string, for example, that contains invalid characters will // cause everything after the first invalid character to be ignored. (e.g. // 'abxxcd' will be treated as 'ab') buf = buf.slice(0, actual) } return buf } function fromArrayLike (array) { var length = array.length < 0 ? 0 : checked(array.length) | 0 var buf = createBuffer(length) for (var i = 0; i < length; i += 1) { buf[i] = array[i] & 255 } return buf } function fromArrayBuffer (array, byteOffset, length) { if (byteOffset < 0 || array.byteLength < byteOffset) { throw new RangeError('"offset" is outside of buffer bounds') } if (array.byteLength < byteOffset + (length || 0)) { throw new RangeError('"length" is outside of buffer bounds') } var buf if (byteOffset === undefined && length === undefined) { buf = new Uint8Array(array) } else if (length === undefined) { buf = new Uint8Array(array, byteOffset) } else { buf = new Uint8Array(array, byteOffset, length) } // Return an augmented `Uint8Array` instance 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.length !== undefined) { if (typeof obj.length !== 'number' || numberIsNaN(obj.length)) { return createBuffer(0) } return fromArrayLike(obj) } if (obj.type === 'Buffer' && Array.isArray(obj.data)) { return fromArrayLike(obj.data) } } function checked (length) { // Note: cannot use `length < K_MAX_LENGTH` here because that fails when // length is NaN (which is otherwise coerced to zero.) if (length >= K_MAX_LENGTH) { throw new RangeError('Attempt to allocate Buffer larger than maximum ' + 'size: 0x' + K_MAX_LENGTH.toString(16) + ' bytes') } return length | 0 } function SlowBuffer (length) { if (+length != length) { // eslint-disable-line eqeqeq length = 0 } return Buffer.alloc(+length) } Buffer.isBuffer = function isBuffer (b) { return b != null && b._isBuffer === true && b !== Buffer.prototype // so Buffer.isBuffer(Buffer.prototype) will be false } Buffer.compare = function compare (a, b) { if (isInstance(a, Uint8Array)) a = Buffer.from(a, a.offset, a.byteLength) if (isInstance(b, Uint8Array)) b = Buffer.from(b, b.offset, b.byteLength) if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) { throw new TypeError( 'The "buf1", "buf2" arguments must be one of type Buffer or Uint8Array' ) } if (a === b) return 0 var x = a.length var y = b.length for (var i = 0, len = Math.min(x, y); i < len; ++i) { if (a[i] !== b[i]) { x = a[i] y = b[i] break } } if (x < y) return -1 if (y < x) return 1 return 0 } Buffer.isEncoding = function isEncoding (encoding) { switch (String(encoding).toLowerCase()) { case 'hex': case 'utf8': case 'utf-8': case 'ascii': case 'latin1': case 'binary': case 'base64': case 'ucs2': case 'ucs-2': case 'utf16le': case 'utf-16le': return true default: return false } } Buffer.concat = function concat (list, length) { if (!Array.isArray(list)) { throw new TypeError('"list" argument must be an Array of Buffers') } if (list.length === 0) { return Buffer.alloc(0) } var i if (length === undefined) { length = 0 for (i = 0; i < list.length; ++i) { length += list[i].length } } var buffer = Buffer.allocUnsafe(length) var pos = 0 for (i = 0; i < list.length; ++i) { var buf = list[i] if (isInstance(buf, Uint8Array)) { buf = Buffer.from(buf) } 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 (ArrayBuffer.isView(string) || isInstance(string, ArrayBuffer)) { return string.byteLength } if (typeof string !== 'string') { throw new TypeError( 'The "string" argument must be one of type string, Buffer, or ArrayBuffer. ' + 'Received type ' + typeof string ) } var len = string.length var mustMatch = (arguments.length > 2 && arguments[2] === true) if (!mustMatch && len === 0) return 0 // Use a for loop to avoid recursion var loweredCase = false for (;;) { switch (encoding) { case 'ascii': case 'latin1': case 'binary': return len case 'utf8': case 'utf-8': return utf8ToBytes(string).length case 'ucs2': case 'ucs-2': case 'utf16le': case 'utf-16le': return len * 2 case 'hex': return len >>> 1 case 'base64': return base64ToBytes(string).length default: if (loweredCase) { return mustMatch ? -1 : utf8ToBytes(string).length // assume utf8 } encoding = ('' + encoding).toLowerCase() loweredCase = true } } } Buffer.byteLength = byteLength function slowToString (encoding, start, end) { var loweredCase = false // No need to verify that "this.length <= MAX_UINT32" since it's a read-only // property of a typed array. // This behaves neither like String nor Uint8Array in that we set start/end // to their upper/lower bounds if the value passed is out of range. // undefined is handled specially as per ECMA-262 6th Edition, // Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization. if (start === undefined || start < 0) { start = 0 } // Return early if start > this.length. Done here to prevent potential uint32 // coercion fail below. if (start > this.length) { return '' } if (end === undefined || end > this.length) { end = this.length } if (end <= 0) { return '' } // Force 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.toLocaleString = Buffer.prototype.toString Buffer.prototype.equals = function equals (b) { if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer') if (this === b) return true return Buffer.compare(this, b) === 0 } Buffer.prototype.inspect = function inspect () { var str = '' var max = exports.INSPECT_MAX_BYTES str = this.toString('hex', 0, max).replace(/(.{2})/g, '$1 ').trim() if (this.length > max) str += ' ... ' return '' } Buffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) { if (isInstance(target, Uint8Array)) { target = Buffer.from(target, target.offset, target.byteLength) } if (!Buffer.isBuffer(target)) { throw new TypeError( 'The "target" argument must be one of type Buffer or Uint8Array. ' + 'Received type ' + (typeof target) ) } if (start === undefined) { start = 0 } if (end === undefined) { end = target ? target.length : 0 } if (thisStart === undefined) { thisStart = 0 } if (thisEnd === undefined) { thisEnd = this.length } if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) { throw new RangeError('out of range index') } if (thisStart >= thisEnd && start >= end) { return 0 } if (thisStart >= thisEnd) { return -1 } if (start >= end) { return 1 } start >>>= 0 end >>>= 0 thisStart >>>= 0 thisEnd >>>= 0 if (this === target) return 0 var x = thisEnd - thisStart var y = end - start var len = Math.min(x, y) var thisCopy = this.slice(thisStart, thisEnd) var targetCopy = target.slice(start, end) for (var i = 0; i < len; ++i) { if (thisCopy[i] !== targetCopy[i]) { x = thisCopy[i] y = targetCopy[i] break } } if (x < y) return -1 if (y < x) return 1 return 0 } // Finds either the first index of `val` in `buffer` at offset >= `byteOffset`, // OR the last index of `val` in `buffer` at offset <= `byteOffset`. // // Arguments: // - buffer - a Buffer to search // - val - a string, Buffer, or number // - byteOffset - an index into `buffer`; will be clamped to an int32 // - encoding - an optional encoding, relevant is val is a string // - dir - true for indexOf, false for lastIndexOf function bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) { // Empty buffer means no match if (buffer.length === 0) return -1 // Normalize byteOffset if (typeof byteOffset === 'string') { encoding = byteOffset byteOffset = 0 } else if (byteOffset > 0x7fffffff) { byteOffset = 0x7fffffff } else if (byteOffset < -0x80000000) { byteOffset = -0x80000000 } byteOffset = +byteOffset // Coerce to Number. if (numberIsNaN(byteOffset)) { // byteOffset: it it's undefined, null, NaN, "foo", etc, search whole buffer byteOffset = dir ? 0 : (buffer.length - 1) } // Normalize byteOffset: negative offsets start from the end of the buffer if (byteOffset < 0) byteOffset = buffer.length + byteOffset if (byteOffset >= buffer.length) { if (dir) return -1 else byteOffset = buffer.length - 1 } else if (byteOffset < 0) { if (dir) byteOffset = 0 else return -1 } // Normalize val if (typeof val === 'string') { val = Buffer.from(val, encoding) } // Finally, search either indexOf (if dir is true) or lastIndexOf if (Buffer.isBuffer(val)) { // Special case: looking for empty string/buffer always fails if (val.length === 0) { return -1 } return arrayIndexOf(buffer, val, byteOffset, encoding, dir) } else if (typeof val === 'number') { val = val & 0xFF // Search for a byte value [0-255] if (typeof Uint8Array.prototype.indexOf === 'function') { if (dir) { return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset) } else { return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset) } } return arrayIndexOf(buffer, [ val ], byteOffset, encoding, dir) } throw new TypeError('val must be string, number or Buffer') } function arrayIndexOf (arr, val, byteOffset, encoding, dir) { var indexSize = 1 var arrLength = arr.length var valLength = val.length if (encoding !== undefined) { encoding = String(encoding).toLowerCase() if (encoding === 'ucs2' || encoding === 'ucs-2' || encoding === 'utf16le' || encoding === 'utf-16le') { if (arr.length < 2 || val.length < 2) { return -1 } indexSize = 2 arrLength /= 2 valLength /= 2 byteOffset /= 2 } } function read (buf, i) { if (indexSize === 1) { return buf[i] } else { return buf.readUInt16BE(i * indexSize) } } var i if (dir) { var foundIndex = -1 for (i = byteOffset; i < arrLength; i++) { if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) { if (foundIndex === -1) foundIndex = i if (i - foundIndex + 1 === valLength) return foundIndex * indexSize } else { if (foundIndex !== -1) i -= i - foundIndex foundIndex = -1 } } } else { if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength for (i = byteOffset; i >= 0; i--) { var found = true for (var j = 0; j < valLength; j++) { if (read(arr, i + j) !== read(val, j)) { found = false break } } if (found) return i } } return -1 } Buffer.prototype.includes = function includes (val, byteOffset, encoding) { return this.indexOf(val, byteOffset, encoding) !== -1 } Buffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) { return bidirectionalIndexOf(this, val, byteOffset, encoding, true) } Buffer.prototype.lastIndexOf = function lastIndexOf (val, byteOffset, encoding) { return bidirectionalIndexOf(this, val, byteOffset, encoding, false) } function hexWrite (buf, string, offset, length) { offset = Number(offset) || 0 var remaining = buf.length - offset if (!length) { length = remaining } else { length = Number(length) if (length > remaining) { length = remaining } } var strLen = string.length if (length > strLen / 2) { length = strLen / 2 } 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 (!Buffer.isBuffer(target)) throw new TypeError('argument should be a Buffer') if (!start) start = 0 if (!end && end !== 0) end = this.length if (targetStart >= target.length) targetStart = target.length if (!targetStart) targetStart = 0 if (end > 0 && end < start) end = start // Copy 0 bytes; we're done if (end === start) return 0 if (target.length === 0 || this.length === 0) return 0 // Fatal error conditions if (targetStart < 0) { throw new RangeError('targetStart out of bounds') } if (start < 0 || start >= this.length) throw new RangeError('Index out of range') if (end < 0) throw new RangeError('sourceEnd out of bounds') // Are we oob? if (end > this.length) end = this.length if (target.length - targetStart < end - start) { end = target.length - targetStart + start } var len = end - start if (this === target && typeof Uint8Array.prototype.copyWithin === 'function') { // Use built-in when available, missing from IE11 this.copyWithin(targetStart, start, end) } else if (this === target && start < targetStart && targetStart < end) { // descending copy from end for (var i = len - 1; i >= 0; --i) { target[i + targetStart] = this[i + start] } } else { Uint8Array.prototype.set.call( target, this.subarray(start, end), targetStart ) } return len } // Usage: // buffer.fill(number[, offset[, end]]) // buffer.fill(buffer[, offset[, end]]) // buffer.fill(string[, offset[, end]][, encoding]) Buffer.prototype.fill = function fill (val, start, end, encoding) { // Handle string cases: if (typeof val === 'string') { if (typeof start === 'string') { encoding = start start = 0 end = this.length } else if (typeof end === 'string') { encoding = end end = this.length } if (encoding !== undefined && typeof encoding !== 'string') { throw new TypeError('encoding must be a string') } if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) { throw new TypeError('Unknown encoding: ' + encoding) } if (val.length === 1) { var code = val.charCodeAt(0) if ((encoding === 'utf8' && code < 128) || encoding === 'latin1') { // Fast path: If `val` fits into a single byte, use that numeric value. val = code } } } else if (typeof val === 'number') { val = val & 255 } // Invalid ranges are not set to a default, so can range check early. if (start < 0 || this.length < start || this.length < end) { throw new RangeError('Out of range index') } if (end <= start) { return this } start = start >>> 0 end = end === undefined ? this.length : end >>> 0 if (!val) val = 0 var i if (typeof val === 'number') { for (i = start; i < end; ++i) { this[i] = val } } else { var bytes = Buffer.isBuffer(val) ? val : Buffer.from(val, encoding) var len = bytes.length if (len === 0) { throw new TypeError('The value "' + val + '" is invalid for argument "value"') } for (i = 0; i < end - start; ++i) { this[i + start] = bytes[i % len] } } return this } // HELPER FUNCTIONS // ================ var INVALID_BASE64_RE = /[^+/0-9A-Za-z-_]/g function base64clean (str) { // Node takes equal signs as end of the Base64 encoding str = str.split('=')[0] // Node strips out invalid characters like \n and \t from the string, base64-js does not str = str.trim().replace(INVALID_BASE64_RE, '') // Node converts strings with length < 2 to '' if (str.length < 2) return '' // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not while (str.length % 4 !== 0) { str = str + '=' } return str } function 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 } // ArrayBuffer or Uint8Array objects from other contexts (i.e. iframes) do not pass // the `instanceof` check but they should be treated as of that type. // See: https://github.com/feross/buffer/issues/166 function isInstance (obj, type) { return obj instanceof type || (obj != null && obj.constructor != null && obj.constructor.name != null && obj.constructor.name === type.name) } function numberIsNaN (obj) { // For IE11 support return obj !== obj // eslint-disable-line no-self-compare } }).call(this)}).call(this,require("buffer").Buffer) },{"base64-js":329,"buffer":331,"ieee754":335}],332:[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" } },{}],333:[function(require,module,exports){ // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to permit // persons to whom the Software is furnished to do so, subject to the // following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. 'use strict'; var R = typeof Reflect === 'object' ? Reflect : null var ReflectApply = R && typeof R.apply === 'function' ? R.apply : function ReflectApply(target, receiver, args) { return Function.prototype.apply.call(target, receiver, args); } var ReflectOwnKeys if (R && typeof R.ownKeys === 'function') { ReflectOwnKeys = R.ownKeys } else if (Object.getOwnPropertySymbols) { ReflectOwnKeys = function ReflectOwnKeys(target) { return Object.getOwnPropertyNames(target) .concat(Object.getOwnPropertySymbols(target)); }; } else { ReflectOwnKeys = function ReflectOwnKeys(target) { return Object.getOwnPropertyNames(target); }; } function ProcessEmitWarning(warning) { if (console && console.warn) console.warn(warning); } var NumberIsNaN = Number.isNaN || function NumberIsNaN(value) { return value !== value; } function EventEmitter() { EventEmitter.init.call(this); } module.exports = EventEmitter; module.exports.once = once; // Backwards-compat with node 0.10.x EventEmitter.EventEmitter = EventEmitter; EventEmitter.prototype._events = undefined; EventEmitter.prototype._eventsCount = 0; EventEmitter.prototype._maxListeners = undefined; // By default EventEmitters will print a warning if more than 10 listeners are // added to it. This is a useful default which helps finding memory leaks. var defaultMaxListeners = 10; function checkListener(listener) { if (typeof listener !== "function") { throw new TypeError("The listener argument must be of type Function. Received type " + typeof listener); } } Object.defineProperty(EventEmitter, 'defaultMaxListeners', { enumerable: true, get: function() { return defaultMaxListeners; }, set: function(arg) { if (typeof arg !== 'number' || arg < 0 || NumberIsNaN(arg)) { throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received ' + arg + '.'); } defaultMaxListeners = arg; } }); EventEmitter.init = function() { if (this._events === undefined || this._events === Object.getPrototypeOf(this)._events) { this._events = Object.create(null); this._eventsCount = 0; } this._maxListeners = this._maxListeners || undefined; }; // Obviously not all Emitters should be limited to 10. This function allows // that to be increased. Set to zero for unlimited. EventEmitter.prototype.setMaxListeners = function setMaxListeners(n) { if (typeof n !== 'number' || n < 0 || NumberIsNaN(n)) { throw new RangeError('The value of "n" is out of range. It must be a non-negative number. Received ' + n + '.'); } this._maxListeners = n; return this; }; function _getMaxListeners(that) { if (that._maxListeners === undefined) return EventEmitter.defaultMaxListeners; return that._maxListeners; } EventEmitter.prototype.getMaxListeners = function getMaxListeners() { return _getMaxListeners(this); }; EventEmitter.prototype.emit = function emit(type) { var args = []; for (var i = 1; i < arguments.length; i++) args.push(arguments[i]); var doError = (type === 'error'); var events = this._events; if (events !== undefined) doError = (doError && events.error === undefined); else if (!doError) return false; // If there is no 'error' event listener then throw. if (doError) { var er; if (args.length > 0) er = args[0]; if (er instanceof Error) { // Note: The comments on the `throw` lines are intentional, they show // up in Node's output if this results in an unhandled exception. throw er; // Unhandled 'error' event } // At least give some kind of context to the user var err = new Error('Unhandled error.' + (er ? ' (' + er.message + ')' : '')); err.context = er; throw err; // Unhandled 'error' event } var handler = events[type]; if (handler === undefined) return false; if (typeof handler === 'function') { ReflectApply(handler, this, args); } else { var len = handler.length; var listeners = arrayClone(handler, len); for (var i = 0; i < len; ++i) ReflectApply(listeners[i], this, args); } return true; }; function _addListener(target, type, listener, prepend) { var m; var events; var existing; checkListener(listener); events = target._events; if (events === undefined) { events = target._events = Object.create(null); target._eventsCount = 0; } else { // To avoid recursion in the case that type === "newListener"! Before // adding it to the listeners, first emit "newListener". if (events.newListener !== undefined) { target.emit('newListener', type, listener.listener ? listener.listener : listener); // Re-assign `events` because a newListener handler could have caused the // this._events to be assigned to a new object events = target._events; } existing = events[type]; } if (existing === undefined) { // Optimize the case of one listener. Don't need the extra array object. existing = events[type] = listener; ++target._eventsCount; } else { if (typeof existing === 'function') { // Adding the second element, need to change to array. existing = events[type] = prepend ? [listener, existing] : [existing, listener]; // If we've already got an array, just append. } else if (prepend) { existing.unshift(listener); } else { existing.push(listener); } // Check for listener leak m = _getMaxListeners(target); if (m > 0 && existing.length > m && !existing.warned) { existing.warned = true; // No error code for this since it is a Warning // eslint-disable-next-line no-restricted-syntax var w = new Error('Possible EventEmitter memory leak detected. ' + existing.length + ' ' + String(type) + ' listeners ' + 'added. Use emitter.setMaxListeners() to ' + 'increase limit'); w.name = 'MaxListenersExceededWarning'; w.emitter = target; w.type = type; w.count = existing.length; ProcessEmitWarning(w); } } return target; } EventEmitter.prototype.addListener = function addListener(type, listener) { return _addListener(this, type, listener, false); }; EventEmitter.prototype.on = EventEmitter.prototype.addListener; EventEmitter.prototype.prependListener = function prependListener(type, listener) { return _addListener(this, type, listener, true); }; function onceWrapper() { if (!this.fired) { this.target.removeListener(this.type, this.wrapFn); this.fired = true; if (arguments.length === 0) return this.listener.call(this.target); return this.listener.apply(this.target, arguments); } } function _onceWrap(target, type, listener) { var state = { fired: false, wrapFn: undefined, target: target, type: type, listener: listener }; var wrapped = onceWrapper.bind(state); wrapped.listener = listener; state.wrapFn = wrapped; return wrapped; } EventEmitter.prototype.once = function once(type, listener) { checkListener(listener); this.on(type, _onceWrap(this, type, listener)); return this; }; EventEmitter.prototype.prependOnceListener = function prependOnceListener(type, listener) { checkListener(listener); this.prependListener(type, _onceWrap(this, type, listener)); return this; }; // Emits a 'removeListener' event if and only if the listener was removed. EventEmitter.prototype.removeListener = function removeListener(type, listener) { var list, events, position, i, originalListener; checkListener(listener); events = this._events; if (events === undefined) return this; list = events[type]; if (list === undefined) return this; if (list === listener || list.listener === listener) { if (--this._eventsCount === 0) this._events = Object.create(null); else { delete events[type]; if (events.removeListener) this.emit('removeListener', type, list.listener || listener); } } else if (typeof list !== 'function') { position = -1; for (i = list.length - 1; i >= 0; i--) { if (list[i] === listener || list[i].listener === listener) { originalListener = list[i].listener; position = i; break; } } if (position < 0) return this; if (position === 0) list.shift(); else { spliceOne(list, position); } if (list.length === 1) events[type] = list[0]; if (events.removeListener !== undefined) this.emit('removeListener', type, originalListener || listener); } return this; }; EventEmitter.prototype.off = EventEmitter.prototype.removeListener; EventEmitter.prototype.removeAllListeners = function removeAllListeners(type) { var listeners, events, i; events = this._events; if (events === undefined) return this; // not listening for removeListener, no need to emit if (events.removeListener === undefined) { if (arguments.length === 0) { this._events = Object.create(null); this._eventsCount = 0; } else if (events[type] !== undefined) { if (--this._eventsCount === 0) this._events = Object.create(null); else delete events[type]; } return this; } // emit removeListener for all listeners on all events if (arguments.length === 0) { var keys = Object.keys(events); var key; for (i = 0; i < keys.length; ++i) { key = keys[i]; if (key === 'removeListener') continue; this.removeAllListeners(key); } this.removeAllListeners('removeListener'); this._events = Object.create(null); this._eventsCount = 0; return this; } listeners = events[type]; if (typeof listeners === 'function') { this.removeListener(type, listeners); } else if (listeners !== undefined) { // LIFO order for (i = listeners.length - 1; i >= 0; i--) { this.removeListener(type, listeners[i]); } } return this; }; function _listeners(target, type, unwrap) { var events = target._events; if (events === undefined) return []; var evlistener = events[type]; if (evlistener === undefined) return []; if (typeof evlistener === 'function') return unwrap ? [evlistener.listener || evlistener] : [evlistener]; return unwrap ? unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length); } EventEmitter.prototype.listeners = function listeners(type) { return _listeners(this, type, true); }; EventEmitter.prototype.rawListeners = function rawListeners(type) { return _listeners(this, type, false); }; EventEmitter.listenerCount = function(emitter, type) { if (typeof emitter.listenerCount === 'function') { return emitter.listenerCount(type); } else { return listenerCount.call(emitter, type); } }; EventEmitter.prototype.listenerCount = listenerCount; function listenerCount(type) { var events = this._events; if (events !== undefined) { var evlistener = events[type]; if (typeof evlistener === 'function') { return 1; } else if (evlistener !== undefined) { return evlistener.length; } } return 0; } EventEmitter.prototype.eventNames = function eventNames() { return this._eventsCount > 0 ? ReflectOwnKeys(this._events) : []; }; function arrayClone(arr, n) { var copy = new Array(n); for (var i = 0; i < n; ++i) copy[i] = arr[i]; return copy; } function spliceOne(list, index) { for (; index + 1 < list.length; index++) list[index] = list[index + 1]; list.pop(); } function unwrapListeners(arr) { var ret = new Array(arr.length); for (var i = 0; i < ret.length; ++i) { ret[i] = arr[i].listener || arr[i]; } return ret; } function once(emitter, name) { return new Promise(function (resolve, reject) { function eventListener() { if (errorListener !== undefined) { emitter.removeListener('error', errorListener); } resolve([].slice.call(arguments)); }; var errorListener; // Adding an error listener is not optional because // if an error is thrown on an event emitter we cannot // guarantee that the actual event we are waiting will // be fired. The result could be a silent way to create // memory or file descriptor leaks, which is something // we should avoid. if (name !== 'error') { errorListener = function errorListener(err) { emitter.removeListener(name, eventListener); reject(err); }; emitter.once('error', errorListener); } emitter.once(name, eventListener); }); } },{}],334:[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":359,"url":379}],335:[function(require,module,exports){ /*! ieee754. BSD-3-Clause License. Feross Aboukhadijeh */ exports.read = function (buffer, offset, isLE, mLen, nBytes) { var e, m var eLen = (nBytes * 8) - mLen - 1 var eMax = (1 << eLen) - 1 var eBias = eMax >> 1 var nBits = -7 var i = isLE ? (nBytes - 1) : 0 var d = isLE ? -1 : 1 var s = buffer[offset + i] i += d e = s & ((1 << (-nBits)) - 1) s >>= (-nBits) nBits += eLen for (; nBits > 0; e = (e * 256) + buffer[offset + i], i += d, nBits -= 8) {} m = e & ((1 << (-nBits)) - 1) e >>= (-nBits) nBits += mLen for (; nBits > 0; m = (m * 256) + buffer[offset + i], i += d, nBits -= 8) {} if (e === 0) { e = 1 - eBias } else if (e === eMax) { return m ? NaN : ((s ? -1 : 1) * Infinity) } else { m = m + Math.pow(2, mLen) e = e - eBias } return (s ? -1 : 1) * m * Math.pow(2, e - mLen) } exports.write = function (buffer, value, offset, isLE, mLen, nBytes) { var e, m, c var eLen = (nBytes * 8) - mLen - 1 var eMax = (1 << eLen) - 1 var eBias = eMax >> 1 var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0) var i = isLE ? 0 : (nBytes - 1) var d = isLE ? 1 : -1 var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0 value = Math.abs(value) if (isNaN(value) || value === Infinity) { m = isNaN(value) ? 1 : 0 e = eMax } else { e = Math.floor(Math.log(value) / Math.LN2) if (value * (c = Math.pow(2, -e)) < 1) { e-- c *= 2 } if (e + eBias >= 1) { value += rt / c } else { value += rt * Math.pow(2, 1 - eBias) } if (value * c >= 2) { e++ c /= 2 } if (e + eBias >= eMax) { m = 0 e = eMax } else if (e + eBias >= 1) { m = ((value * c) - 1) * Math.pow(2, mLen) e = e + eBias } else { m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen) e = 0 } } for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {} e = (e << mLen) | m eLen += mLen for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {} buffer[offset + i - d] |= s * 128 } },{}],336:[function(require,module,exports){ arguments[4][131][0].apply(exports,arguments) },{"dup":131}],337:[function(require,module,exports){ (function (process){(function (){ // 'path' module extracted from Node.js v8.11.1 (only the posix part) // transplited with Babel // 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'; function assertPath(path) { if (typeof path !== 'string') { throw new TypeError('Path must be a string. Received ' + JSON.stringify(path)); } } // Resolves . and .. elements in a path with directory names function normalizeStringPosix(path, allowAboveRoot) { var res = ''; var lastSegmentLength = 0; var lastSlash = -1; var dots = 0; var code; for (var i = 0; i <= path.length; ++i) { if (i < path.length) code = path.charCodeAt(i); else if (code === 47 /*/*/) break; else code = 47 /*/*/; if (code === 47 /*/*/) { if (lastSlash === i - 1 || dots === 1) { // NOOP } else if (lastSlash !== i - 1 && dots === 2) { if (res.length < 2 || lastSegmentLength !== 2 || res.charCodeAt(res.length - 1) !== 46 /*.*/ || res.charCodeAt(res.length - 2) !== 46 /*.*/) { if (res.length > 2) { var lastSlashIndex = res.lastIndexOf('/'); if (lastSlashIndex !== res.length - 1) { if (lastSlashIndex === -1) { res = ''; lastSegmentLength = 0; } else { res = res.slice(0, lastSlashIndex); lastSegmentLength = res.length - 1 - res.lastIndexOf('/'); } lastSlash = i; dots = 0; continue; } } else if (res.length === 2 || res.length === 1) { res = ''; lastSegmentLength = 0; lastSlash = i; dots = 0; continue; } } if (allowAboveRoot) { if (res.length > 0) res += '/..'; else res = '..'; lastSegmentLength = 2; } } else { if (res.length > 0) res += '/' + path.slice(lastSlash + 1, i); else res = path.slice(lastSlash + 1, i); lastSegmentLength = i - lastSlash - 1; } lastSlash = i; dots = 0; } else if (code === 46 /*.*/ && dots !== -1) { ++dots; } else { dots = -1; } } return res; } function _format(sep, pathObject) { var dir = pathObject.dir || pathObject.root; var base = pathObject.base || (pathObject.name || '') + (pathObject.ext || ''); if (!dir) { return base; } if (dir === pathObject.root) { return dir + base; } return dir + sep + base; } var posix = { // path.resolve([from ...], to) resolve: function resolve() { var resolvedPath = ''; var resolvedAbsolute = false; var cwd; for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) { var path; if (i >= 0) path = arguments[i]; else { if (cwd === undefined) cwd = process.cwd(); path = cwd; } assertPath(path); // Skip empty entries if (path.length === 0) { continue; } resolvedPath = path + '/' + resolvedPath; resolvedAbsolute = path.charCodeAt(0) === 47 /*/*/; } // At this point the path should be resolved to a full absolute path, but // handle relative paths to be safe (might happen when process.cwd() fails) // Normalize the path resolvedPath = normalizeStringPosix(resolvedPath, !resolvedAbsolute); if (resolvedAbsolute) { if (resolvedPath.length > 0) return '/' + resolvedPath; else return '/'; } else if (resolvedPath.length > 0) { return resolvedPath; } else { return '.'; } }, normalize: function normalize(path) { assertPath(path); if (path.length === 0) return '.'; var isAbsolute = path.charCodeAt(0) === 47 /*/*/; var trailingSeparator = path.charCodeAt(path.length - 1) === 47 /*/*/; // Normalize the path path = normalizeStringPosix(path, !isAbsolute); if (path.length === 0 && !isAbsolute) path = '.'; if (path.length > 0 && trailingSeparator) path += '/'; if (isAbsolute) return '/' + path; return path; }, isAbsolute: function isAbsolute(path) { assertPath(path); return path.length > 0 && path.charCodeAt(0) === 47 /*/*/; }, join: function join() { if (arguments.length === 0) return '.'; var joined; for (var i = 0; i < arguments.length; ++i) { var arg = arguments[i]; assertPath(arg); if (arg.length > 0) { if (joined === undefined) joined = arg; else joined += '/' + arg; } } if (joined === undefined) return '.'; return posix.normalize(joined); }, relative: function relative(from, to) { assertPath(from); assertPath(to); if (from === to) return ''; from = posix.resolve(from); to = posix.resolve(to); if (from === to) return ''; // Trim any leading backslashes var fromStart = 1; for (; fromStart < from.length; ++fromStart) { if (from.charCodeAt(fromStart) !== 47 /*/*/) break; } var fromEnd = from.length; var fromLen = fromEnd - fromStart; // Trim any leading backslashes var toStart = 1; for (; toStart < to.length; ++toStart) { if (to.charCodeAt(toStart) !== 47 /*/*/) break; } var toEnd = to.length; var toLen = toEnd - toStart; // Compare paths to find the longest common path from root var length = fromLen < toLen ? fromLen : toLen; var lastCommonSep = -1; var i = 0; for (; i <= length; ++i) { if (i === length) { if (toLen > length) { if (to.charCodeAt(toStart + i) === 47 /*/*/) { // We get here if `from` is the exact base path for `to`. // For example: from='/foo/bar'; to='/foo/bar/baz' return to.slice(toStart + i + 1); } else if (i === 0) { // We get here if `from` is the root // For example: from='/'; to='/foo' return to.slice(toStart + i); } } else if (fromLen > length) { if (from.charCodeAt(fromStart + i) === 47 /*/*/) { // We get here if `to` is the exact base path for `from`. // For example: from='/foo/bar/baz'; to='/foo/bar' lastCommonSep = i; } else if (i === 0) { // We get here if `to` is the root. // For example: from='/foo'; to='/' lastCommonSep = 0; } } break; } var fromCode = from.charCodeAt(fromStart + i); var toCode = to.charCodeAt(toStart + i); if (fromCode !== toCode) break; else if (fromCode === 47 /*/*/) lastCommonSep = i; } var out = ''; // Generate the relative path based on the path difference between `to` // and `from` for (i = fromStart + lastCommonSep + 1; i <= fromEnd; ++i) { if (i === fromEnd || from.charCodeAt(i) === 47 /*/*/) { if (out.length === 0) out += '..'; else out += '/..'; } } // Lastly, append the rest of the destination (`to`) path that comes after // the common path parts if (out.length > 0) return out + to.slice(toStart + lastCommonSep); else { toStart += lastCommonSep; if (to.charCodeAt(toStart) === 47 /*/*/) ++toStart; return to.slice(toStart); } }, _makeLong: function _makeLong(path) { return path; }, dirname: function dirname(path) { assertPath(path); if (path.length === 0) return '.'; var code = path.charCodeAt(0); var hasRoot = code === 47 /*/*/; var end = -1; var matchedSlash = true; for (var i = path.length - 1; i >= 1; --i) { code = path.charCodeAt(i); if (code === 47 /*/*/) { if (!matchedSlash) { end = i; break; } } else { // We saw the first non-path separator matchedSlash = false; } } if (end === -1) return hasRoot ? '/' : '.'; if (hasRoot && end === 1) return '//'; return path.slice(0, end); }, basename: function basename(path, ext) { if (ext !== undefined && typeof ext !== 'string') throw new TypeError('"ext" argument must be a string'); assertPath(path); var start = 0; var end = -1; var matchedSlash = true; var i; if (ext !== undefined && ext.length > 0 && ext.length <= path.length) { if (ext.length === path.length && ext === path) return ''; var extIdx = ext.length - 1; var firstNonSlashEnd = -1; for (i = path.length - 1; i >= 0; --i) { var code = path.charCodeAt(i); if (code === 47 /*/*/) { // If we reached a path separator that was not part of a set of path // separators at the end of the string, stop now if (!matchedSlash) { start = i + 1; break; } } else { if (firstNonSlashEnd === -1) { // We saw the first non-path separator, remember this index in case // we need it if the extension ends up not matching matchedSlash = false; firstNonSlashEnd = i + 1; } if (extIdx >= 0) { // Try to match the explicit extension if (code === ext.charCodeAt(extIdx)) { if (--extIdx === -1) { // We matched the extension, so mark this as the end of our path // component end = i; } } else { // Extension does not match, so our result is the entire path // component extIdx = -1; end = firstNonSlashEnd; } } } } if (start === end) end = firstNonSlashEnd;else if (end === -1) end = path.length; return path.slice(start, end); } else { for (i = path.length - 1; i >= 0; --i) { if (path.charCodeAt(i) === 47 /*/*/) { // If we reached a path separator that was not part of a set of path // separators at the end of the string, stop now if (!matchedSlash) { start = i + 1; break; } } else if (end === -1) { // We saw the first non-path separator, mark this as the end of our // path component matchedSlash = false; end = i + 1; } } if (end === -1) return ''; return path.slice(start, end); } }, extname: function extname(path) { assertPath(path); var startDot = -1; var startPart = 0; var end = -1; var matchedSlash = true; // Track the state of characters (if any) we see before our first dot and // after any path separator we find var preDotState = 0; for (var i = path.length - 1; i >= 0; --i) { var code = path.charCodeAt(i); if (code === 47 /*/*/) { // If we reached a path separator that was not part of a set of path // separators at the end of the string, stop now if (!matchedSlash) { startPart = i + 1; break; } continue; } if (end === -1) { // We saw the first non-path separator, mark this as the end of our // extension matchedSlash = false; end = i + 1; } if (code === 46 /*.*/) { // If this is our first dot, mark it as the start of our extension if (startDot === -1) startDot = i; else if (preDotState !== 1) preDotState = 1; } else if (startDot !== -1) { // We saw a non-dot and non-path separator before our dot, so we should // have a good chance at having a non-empty extension preDotState = -1; } } if (startDot === -1 || end === -1 || // We saw a non-dot character immediately before the dot preDotState === 0 || // The (right-most) trimmed path component is exactly '..' preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) { return ''; } return path.slice(startDot, end); }, format: function format(pathObject) { if (pathObject === null || typeof pathObject !== 'object') { throw new TypeError('The "pathObject" argument must be of type Object. Received type ' + typeof pathObject); } return _format('/', pathObject); }, parse: function parse(path) { assertPath(path); var ret = { root: '', dir: '', base: '', ext: '', name: '' }; if (path.length === 0) return ret; var code = path.charCodeAt(0); var isAbsolute = code === 47 /*/*/; var start; if (isAbsolute) { ret.root = '/'; start = 1; } else { start = 0; } var startDot = -1; var startPart = 0; var end = -1; var matchedSlash = true; var i = path.length - 1; // Track the state of characters (if any) we see before our first dot and // after any path separator we find var preDotState = 0; // Get non-dir info for (; i >= start; --i) { code = path.charCodeAt(i); if (code === 47 /*/*/) { // If we reached a path separator that was not part of a set of path // separators at the end of the string, stop now if (!matchedSlash) { startPart = i + 1; break; } continue; } if (end === -1) { // We saw the first non-path separator, mark this as the end of our // extension matchedSlash = false; end = i + 1; } if (code === 46 /*.*/) { // If this is our first dot, mark it as the start of our extension if (startDot === -1) startDot = i;else if (preDotState !== 1) preDotState = 1; } else if (startDot !== -1) { // We saw a non-dot and non-path separator before our dot, so we should // have a good chance at having a non-empty extension preDotState = -1; } } if (startDot === -1 || end === -1 || // We saw a non-dot character immediately before the dot preDotState === 0 || // The (right-most) trimmed path component is exactly '..' preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) { if (end !== -1) { if (startPart === 0 && isAbsolute) ret.base = ret.name = path.slice(1, end);else ret.base = ret.name = path.slice(startPart, end); } } else { if (startPart === 0 && isAbsolute) { ret.name = path.slice(1, startDot); ret.base = path.slice(1, end); } else { ret.name = path.slice(startPart, startDot); ret.base = path.slice(startPart, end); } ret.ext = path.slice(startDot, end); } if (startPart > 0) ret.dir = path.slice(0, startPart - 1);else if (isAbsolute) ret.dir = '/'; return ret; }, sep: '/', delimiter: ':', win32: null, posix: null }; posix.posix = posix; module.exports = posix; }).call(this)}).call(this,require('_process')) },{"_process":338}],338:[function(require,module,exports){ // shim for using process in browser var process = module.exports = {}; // cached from whatever global is present so that test runners that stub it // don't break things. But we need to wrap it in a try catch in case it is // wrapped in strict mode code which doesn't define any globals. It's inside a // function because try/catches deoptimize in certain engines. var cachedSetTimeout; var cachedClearTimeout; function defaultSetTimout() { throw new Error('setTimeout has not been defined'); } function defaultClearTimeout () { throw new Error('clearTimeout has not been defined'); } (function () { try { if (typeof setTimeout === 'function') { cachedSetTimeout = setTimeout; } else { cachedSetTimeout = defaultSetTimout; } } catch (e) { cachedSetTimeout = defaultSetTimout; } try { if (typeof clearTimeout === 'function') { cachedClearTimeout = clearTimeout; } else { cachedClearTimeout = defaultClearTimeout; } } catch (e) { cachedClearTimeout = defaultClearTimeout; } } ()) function runTimeout(fun) { if (cachedSetTimeout === setTimeout) { //normal enviroments in sane situations return setTimeout(fun, 0); } // if setTimeout wasn't available but was latter defined if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) { cachedSetTimeout = setTimeout; return setTimeout(fun, 0); } try { // when when somebody has screwed with setTimeout but no I.E. maddness return cachedSetTimeout(fun, 0); } catch(e){ try { // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally return cachedSetTimeout.call(null, fun, 0); } catch(e){ // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error return cachedSetTimeout.call(this, fun, 0); } } } function runClearTimeout(marker) { if (cachedClearTimeout === clearTimeout) { //normal enviroments in sane situations return clearTimeout(marker); } // if clearTimeout wasn't available but was latter defined if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) { cachedClearTimeout = clearTimeout; return clearTimeout(marker); } try { // when when somebody has screwed with setTimeout but no I.E. maddness return cachedClearTimeout(marker); } catch (e){ try { // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally return cachedClearTimeout.call(null, marker); } catch (e){ // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error. // Some versions of I.E. have different rules for clearTimeout vs setTimeout return cachedClearTimeout.call(this, marker); } } } var queue = []; var draining = false; var currentQueue; var queueIndex = -1; function cleanUpNextTick() { if (!draining || !currentQueue) { return; } draining = false; if (currentQueue.length) { queue = currentQueue.concat(queue); } else { queueIndex = -1; } if (queue.length) { drainQueue(); } } function drainQueue() { if (draining) { return; } var timeout = runTimeout(cleanUpNextTick); draining = true; var len = queue.length; while(len) { currentQueue = queue; queue = []; while (++queueIndex < len) { if (currentQueue) { currentQueue[queueIndex].run(); } } queueIndex = -1; len = queue.length; } currentQueue = null; draining = false; runClearTimeout(timeout); } process.nextTick = function (fun) { var args = new Array(arguments.length - 1); if (arguments.length > 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; }; },{}],339:[function(require,module,exports){ (function (global){(function (){ /*! 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)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{}],340:[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]'; }; },{}],341:[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; }; },{}],342:[function(require,module,exports){ 'use strict'; exports.decode = exports.parse = require('./decode'); exports.encode = exports.stringify = require('./encode'); },{"./decode":340,"./encode":341}],343:[function(require,module,exports){ arguments[4][226][0].apply(exports,arguments) },{"buffer":331,"dup":226}],344:[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. module.exports = Stream; var EE = require('events').EventEmitter; var inherits = require('inherits'); inherits(Stream, EE); Stream.Readable = require('readable-stream/lib/_stream_readable.js'); Stream.Writable = require('readable-stream/lib/_stream_writable.js'); Stream.Duplex = require('readable-stream/lib/_stream_duplex.js'); Stream.Transform = require('readable-stream/lib/_stream_transform.js'); Stream.PassThrough = require('readable-stream/lib/_stream_passthrough.js'); Stream.finished = require('readable-stream/lib/internal/streams/end-of-stream.js') Stream.pipeline = require('readable-stream/lib/internal/streams/pipeline.js') // Backwards-compat with node 0.4.x Stream.Stream = Stream; // old-style streams. Note that the pipe method (the only relevant // part of this class) is overridden in the Readable class. function Stream() { EE.call(this); } Stream.prototype.pipe = function(dest, options) { var source = this; function ondata(chunk) { if (dest.writable) { if (false === dest.write(chunk) && source.pause) { source.pause(); } } } source.on('data', ondata); function ondrain() { if (source.readable && source.resume) { source.resume(); } } dest.on('drain', ondrain); // If the 'end' option is not supplied, dest.end() will be called when // source gets the 'end' or 'close' events. Only dest.end() once. if (!dest._isStdio && (!options || options.end !== false)) { source.on('end', onend); source.on('close', onclose); } var didOnEnd = false; function onend() { if (didOnEnd) return; didOnEnd = true; dest.end(); } function onclose() { if (didOnEnd) return; didOnEnd = true; if (typeof dest.destroy === 'function') dest.destroy(); } // don't leave dangling pipes when there are errors. function onerror(er) { cleanup(); if (EE.listenerCount(this, 'error') === 0) { throw er; // Unhandled stream error in pipe. } } source.on('error', onerror); dest.on('error', onerror); // remove all the event listeners that were added. function cleanup() { source.removeListener('data', ondata); dest.removeListener('drain', ondrain); source.removeListener('end', onend); source.removeListener('close', onclose); source.removeListener('error', onerror); dest.removeListener('error', onerror); source.removeListener('end', cleanup); source.removeListener('close', cleanup); dest.removeListener('close', cleanup); } source.on('end', cleanup); source.on('close', cleanup); dest.on('close', cleanup); dest.emit('pipe', source); // Allow for unix-like usage: A.pipe(B).pipe(C) return dest; }; },{"events":333,"inherits":336,"readable-stream/lib/_stream_duplex.js":346,"readable-stream/lib/_stream_passthrough.js":347,"readable-stream/lib/_stream_readable.js":348,"readable-stream/lib/_stream_transform.js":349,"readable-stream/lib/_stream_writable.js":350,"readable-stream/lib/internal/streams/end-of-stream.js":354,"readable-stream/lib/internal/streams/pipeline.js":356}],345:[function(require,module,exports){ arguments[4][14][0].apply(exports,arguments) },{"dup":14}],346:[function(require,module,exports){ arguments[4][15][0].apply(exports,arguments) },{"./_stream_readable":348,"./_stream_writable":350,"_process":338,"dup":15,"inherits":336}],347:[function(require,module,exports){ arguments[4][16][0].apply(exports,arguments) },{"./_stream_transform":349,"dup":16,"inherits":336}],348:[function(require,module,exports){ arguments[4][17][0].apply(exports,arguments) },{"../errors":345,"./_stream_duplex":346,"./internal/streams/async_iterator":351,"./internal/streams/buffer_list":352,"./internal/streams/destroy":353,"./internal/streams/from":355,"./internal/streams/state":357,"./internal/streams/stream":358,"_process":338,"buffer":331,"dup":17,"events":333,"inherits":336,"string_decoder/":378,"util":330}],349:[function(require,module,exports){ arguments[4][18][0].apply(exports,arguments) },{"../errors":345,"./_stream_duplex":346,"dup":18,"inherits":336}],350:[function(require,module,exports){ arguments[4][19][0].apply(exports,arguments) },{"../errors":345,"./_stream_duplex":346,"./internal/streams/destroy":353,"./internal/streams/state":357,"./internal/streams/stream":358,"_process":338,"buffer":331,"dup":19,"inherits":336,"util-deprecate":381}],351:[function(require,module,exports){ arguments[4][20][0].apply(exports,arguments) },{"./end-of-stream":354,"_process":338,"dup":20}],352:[function(require,module,exports){ arguments[4][21][0].apply(exports,arguments) },{"buffer":331,"dup":21,"util":330}],353:[function(require,module,exports){ arguments[4][22][0].apply(exports,arguments) },{"_process":338,"dup":22}],354:[function(require,module,exports){ arguments[4][23][0].apply(exports,arguments) },{"../../../errors":345,"dup":23}],355:[function(require,module,exports){ arguments[4][24][0].apply(exports,arguments) },{"dup":24}],356:[function(require,module,exports){ arguments[4][25][0].apply(exports,arguments) },{"../../../errors":345,"./end-of-stream":354,"dup":25}],357:[function(require,module,exports){ arguments[4][26][0].apply(exports,arguments) },{"../../../errors":345,"dup":26}],358:[function(require,module,exports){ arguments[4][27][0].apply(exports,arguments) },{"dup":27,"events":333}],359:[function(require,module,exports){ (function (global){(function (){ var ClientRequest = require('./lib/request') var response = require('./lib/response') 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.ClientRequest = ClientRequest http.IncomingMessage = response.IncomingMessage http.Agent = function () {} http.Agent.defaultMaxSockets = 4 http.globalAgent = new http.Agent() 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)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{"./lib/request":361,"./lib/response":362,"builtin-status-codes":332,"url":379,"xtend":382}],360:[function(require,module,exports){ (function (global){(function (){ exports.fetch = isFunction(global.fetch) && isFunction(global.ReadableStream) exports.writableStream = isFunction(global.WritableStream) exports.abortController = isFunction(global.AbortController) // 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 } // If fetch is supported, then arraybuffer will be supported too. Skip calling // checkTypeSupport(), since that calls getXHR(). exports.arraybuffer = exports.fetch || 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 && checkTypeSupport('ms-stream') exports.mozchunkedarraybuffer = !exports.fetch && 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) function isFunction (value) { return typeof value === 'function' } xhr = null // Help gc }).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{}],361:[function(require,module,exports){ (function (process,global,Buffer){(function (){ var capability = require('./capability') var inherits = require('inherits') var response = require('./response') var stream = require('readable-stream') 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 { 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 ' + Buffer.from(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' || ('requestTimeout' in opts && !capability.abortController)) { // If the use of XHR should be preferred. Not typically needed. 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._fetchTimer = null 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 header = this._headers[name.toLowerCase()] if (header) return header.value return null } 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') { body = new Blob(self._body, { type: (headersObj['content-type'] || {}).value || '' }); } // 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') { var signal = null if (capability.abortController) { var controller = new AbortController() signal = controller.signal self._fetchAbortController = controller if ('requestTimeout' in opts && opts.requestTimeout !== 0) { self._fetchTimer = global.setTimeout(function () { self.emit('requestTimeout') if (self._fetchAbortController) self._fetchAbortController.abort() }, opts.requestTimeout) } } global.fetch(self._opts.url, { method: self._opts.method, headers: headersList, body: body || undefined, mode: 'cors', credentials: opts.withCredentials ? 'include' : 'same-origin', signal: signal }).then(function (response) { self._fetchResponse = response self._connect() }, function (reason) { global.clearTimeout(self._fetchTimer) if (!self._destroyed) 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 if ('withCredentials' in xhr) xhr.withCredentials = !!opts.withCredentials if (self._mode === 'text' && 'overrideMimeType' in xhr) xhr.overrideMimeType('text/plain; charset=x-user-defined') if ('requestTimeout' in opts) { xhr.timeout = opts.requestTimeout xhr.ontimeout = function () { self.emit('requestTimeout') } } 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._fetchTimer) 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 global.clearTimeout(self._fetchTimer) if (self._response) self._response._destroyed = true if (self._xhr) self._xhr.abort() else if (self._fetchAbortController) self._fetchAbortController.abort() } 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', 'via' ] }).call(this)}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer) },{"./capability":360,"./response":362,"_process":338,"buffer":331,"inherits":336,"readable-stream":377}],362:[function(require,module,exports){ (function (process,global,Buffer){(function (){ 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, fetchTimer) { 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) }) if (capability.writableStream) { var writable = new WritableStream({ write: function (chunk) { return new Promise(function (resolve, reject) { if (self._destroyed) { reject() } else if(self.push(Buffer.from(chunk))) { resolve() } else { self._resumeFetch = resolve } }) }, close: function () { global.clearTimeout(fetchTimer) if (!self._destroyed) self.push(null) }, abort: function (err) { if (!self._destroyed) self.emit('error', err) } }) try { response.body.pipeTo(writable).catch(function (err) { global.clearTimeout(fetchTimer) if (!self._destroyed) self.emit('error', err) }) return } catch (e) {} // pipeTo method isn't defined. Can't find a better way to feature test this } // fallback for when writableStream or pipeTo aren't available var reader = response.body.getReader() function read () { reader.read().then(function (result) { if (self._destroyed) return if (result.done) { global.clearTimeout(fetchTimer) self.push(null) return } self.push(Buffer.from(result.value)) read() }).catch(function (err) { global.clearTimeout(fetchTimer) if (!self._destroyed) 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 () { var self = this var resolve = self._resumeFetch if (resolve) { self._resumeFetch = null resolve() } } IncomingMessage.prototype._onXHRProgress = function () { var self = this var xhr = self._xhr var response = null switch (self._mode) { case 'text': response = xhr.responseText if (response.length > self._pos) { var newData = response.substr(self._pos) if (self._charset === 'x-user-defined') { var buffer = Buffer.alloc(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(Buffer.from(new Uint8Array(response))) break case 'moz-chunked-arraybuffer': // take whole response = xhr.response if (xhr.readyState !== rStates.LOADING || !response) break self.push(Buffer.from(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(Buffer.from(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)}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer) },{"./capability":360,"_process":338,"buffer":331,"inherits":336,"readable-stream":377}],363:[function(require,module,exports){ arguments[4][14][0].apply(exports,arguments) },{"dup":14}],364:[function(require,module,exports){ arguments[4][15][0].apply(exports,arguments) },{"./_stream_readable":366,"./_stream_writable":368,"_process":338,"dup":15,"inherits":336}],365:[function(require,module,exports){ arguments[4][16][0].apply(exports,arguments) },{"./_stream_transform":367,"dup":16,"inherits":336}],366:[function(require,module,exports){ arguments[4][17][0].apply(exports,arguments) },{"../errors":363,"./_stream_duplex":364,"./internal/streams/async_iterator":369,"./internal/streams/buffer_list":370,"./internal/streams/destroy":371,"./internal/streams/from":373,"./internal/streams/state":375,"./internal/streams/stream":376,"_process":338,"buffer":331,"dup":17,"events":333,"inherits":336,"string_decoder/":378,"util":330}],367:[function(require,module,exports){ arguments[4][18][0].apply(exports,arguments) },{"../errors":363,"./_stream_duplex":364,"dup":18,"inherits":336}],368:[function(require,module,exports){ arguments[4][19][0].apply(exports,arguments) },{"../errors":363,"./_stream_duplex":364,"./internal/streams/destroy":371,"./internal/streams/state":375,"./internal/streams/stream":376,"_process":338,"buffer":331,"dup":19,"inherits":336,"util-deprecate":381}],369:[function(require,module,exports){ arguments[4][20][0].apply(exports,arguments) },{"./end-of-stream":372,"_process":338,"dup":20}],370:[function(require,module,exports){ arguments[4][21][0].apply(exports,arguments) },{"buffer":331,"dup":21,"util":330}],371:[function(require,module,exports){ arguments[4][22][0].apply(exports,arguments) },{"_process":338,"dup":22}],372:[function(require,module,exports){ arguments[4][23][0].apply(exports,arguments) },{"../../../errors":363,"dup":23}],373:[function(require,module,exports){ arguments[4][24][0].apply(exports,arguments) },{"dup":24}],374:[function(require,module,exports){ arguments[4][25][0].apply(exports,arguments) },{"../../../errors":363,"./end-of-stream":372,"dup":25}],375:[function(require,module,exports){ arguments[4][26][0].apply(exports,arguments) },{"../../../errors":363,"dup":26}],376:[function(require,module,exports){ arguments[4][27][0].apply(exports,arguments) },{"dup":27,"events":333}],377:[function(require,module,exports){ arguments[4][28][0].apply(exports,arguments) },{"./lib/_stream_duplex.js":364,"./lib/_stream_passthrough.js":365,"./lib/_stream_readable.js":366,"./lib/_stream_transform.js":367,"./lib/_stream_writable.js":368,"./lib/internal/streams/end-of-stream.js":372,"./lib/internal/streams/pipeline.js":374,"dup":28}],378:[function(require,module,exports){ arguments[4][281][0].apply(exports,arguments) },{"dup":281,"safe-buffer":343}],379:[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 punycode = require('punycode'); var util = require('./util'); exports.parse = urlParse; exports.resolve = urlResolve; exports.resolveObject = urlResolveObject; exports.format = urlFormat; exports.Url = Url; function Url() { this.protocol = null; this.slashes = null; this.auth = null; this.host = null; this.port = null; this.hostname = null; this.hash = null; this.search = null; this.query = null; this.pathname = null; this.path = null; this.href = null; } // Reference: RFC 3986, RFC 1808, RFC 2396 // define these here so at least they only have to be // compiled once on the first module load. var protocolPattern = /^([a-z0-9.+-]+:)/i, portPattern = /:[0-9]*$/, // Special case for a simple path URL simplePathPattern = /^(\/\/?(?!\/)[^\?\s]*)(\?[^\s]*)?$/, // RFC 2396: characters reserved for delimiting URLs. // We actually just auto-escape these. delims = ['<', '>', '"', '`', ' ', '\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":380,"punycode":339,"querystring":342}],380:[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; } }; },{}],381:[function(require,module,exports){ arguments[4][298][0].apply(exports,arguments) },{"dup":298}],382:[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])(1) });