From 6f51d4e17f4ad1e9c660095ed360dfeda4016c16 Mon Sep 17 00:00:00 2001 From: Carlos Date: Tue, 18 Oct 2016 01:12:08 +0300 Subject: [PATCH] Published 0.1.1 to npm and minimized version --- cachep2p.min.js | 20541 +--------------------------------------------- package.json | 4 +- 2 files changed, 11 insertions(+), 20534 deletions(-) diff --git a/cachep2p.min.js b/cachep2p.min.js index 62fb6d4..90d4e79 100644 --- a/cachep2p.min.js +++ b/cachep2p.min.js @@ -1,20534 +1,11 @@ -(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.CacheP2P = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o0)throw new Error("Invalid string. Length must be a multiple of 4");return"="===e[t-2]?2:"="===e[t-1]?1:0}function o(e){return 3*e.length/4-r(e)}function i(e){var t,n,o,i,s,a,u=e.length;s=r(e),a=new d(3*u/4-s),o=s>0?u-4:u;var c=0;for(t=0,n=0;o>t;t+=4,n+=3)i=f[e.charCodeAt(t)]<<18|f[e.charCodeAt(t+1)]<<12|f[e.charCodeAt(t+2)]<<6|f[e.charCodeAt(t+3)],a[c++]=i>>16&255,a[c++]=i>>8&255,a[c++]=255&i;return 2===s?(i=f[e.charCodeAt(t)]<<2|f[e.charCodeAt(t+1)]>>4,a[c++]=255&i):1===s&&(i=f[e.charCodeAt(t)]<<10|f[e.charCodeAt(t+1)]<<4|f[e.charCodeAt(t+2)]>>2,a[c++]=i>>8&255,a[c++]=255&i),a}function s(e){return c[e>>18&63]+c[e>>12&63]+c[e>>6&63]+c[63&e]}function a(e,t,n){for(var r,o=[],i=t;n>i;i+=3)r=(e[i]<<16)+(e[i+1]<<8)+e[i+2],o.push(s(r));return o.join("")}function u(e){for(var t,n=e.length,r=n%3,o="",i=[],s=16383,u=0,f=n-r;f>u;u+=s)i.push(a(e,u,u+s>f?f:u+s));return 1===r?(t=e[n-1],o+=c[t>>2],o+=c[t<<4&63],o+="=="):2===r&&(t=(e[n-2]<<8)+e[n-1],o+=c[t>>10],o+=c[t>>4&63],o+=c[t<<2&63],o+="="),i.push(o),i.join("")}n.byteLength=o,n.toByteArray=i,n.fromByteArray=u;for(var c=[],f=[],d="undefined"!=typeof Uint8Array?Uint8Array:Array,h="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",l=0,p=h.length;p>l;++l)c[l]=h[l],f[h.charCodeAt(l)]=l;f["-".charCodeAt(0)]=62,f["_".charCodeAt(0)]=63},{}],3:[function(e,t,n){arguments[4][1][0].apply(n,arguments)},{dup:1}],4:[function(e,t,n){(function(t){"use strict";var r=e("buffer"),o=r.Buffer,i=r.SlowBuffer,s=r.kMaxLength||2147483647;n.alloc=function(e,t,n){if("function"==typeof o.alloc)return o.alloc(e,t,n);if("number"==typeof n)throw new TypeError("encoding must not be number");if("number"!=typeof e)throw new TypeError("size must be a number");if(e>s)throw new RangeError("size is too large");var r=n,i=t;void 0===i&&(r=void 0,i=0);var a=new o(e);if("string"==typeof i)for(var u=new o(i,r),c=u.length,f=-1;++fs)throw new RangeError("size is too large");return new o(e)},n.from=function(e,n,r){if("function"==typeof o.from&&(!t.Uint8Array||Uint8Array.from!==o.from))return o.from(e,n,r);if("number"==typeof e)throw new TypeError('"value" argument must not be a number');if("string"==typeof e)return new o(e,n);if("undefined"!=typeof ArrayBuffer&&e instanceof ArrayBuffer){var i=n;if(1===arguments.length)return new o(e);"undefined"==typeof i&&(i=0);var s=r;if("undefined"==typeof s&&(s=e.byteLength-i),i>=e.byteLength)throw new RangeError("'offset' is out of bounds");if(s>e.byteLength-i)throw new RangeError("'length' is out of bounds");return new o(e.slice(i,i+s))}if(o.isBuffer(e)){var a=new o(e.length);return e.copy(a,0,0,e.length),a}if(e){if(Array.isArray(e)||"undefined"!=typeof ArrayBuffer&&e.buffer instanceof ArrayBuffer||"length"in e)return new o(e);if("Buffer"===e.type&&Array.isArray(e.data))return new o(e.data)}throw new TypeError("First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.")},n.allocUnsafeSlow=function(e){if("function"==typeof o.allocUnsafeSlow)return o.allocUnsafeSlow(e);if("number"!=typeof e)throw new TypeError("size must be a number");if(e>=s)throw new RangeError("size is too large");return new i(e)}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{buffer:5}],5:[function(e,t,n){(function(t){"use strict";function r(){try{var e=new Uint8Array(1);return e.__proto__={__proto__:Uint8Array.prototype,foo:function(){return 42}},42===e.foo()&&"function"==typeof e.subarray&&0===e.subarray(1,1).byteLength}catch(t){return!1}}function o(){return s.TYPED_ARRAY_SUPPORT?2147483647:1073741823}function i(e,t){if(o()e)throw new RangeError('"size" argument must not be negative')}function c(e,t,n,r){return u(t),0>=t?i(e,t):void 0!==n?"string"==typeof r?i(e,t).fill(n,r):i(e,t).fill(n):i(e,t)}function f(e,t){if(u(t),e=i(e,0>t?0:0|m(t)),!s.TYPED_ARRAY_SUPPORT)for(var n=0;t>n;++n)e[n]=0;return e}function d(e,t,n){if(("string"!=typeof n||""===n)&&(n="utf8"),!s.isEncoding(n))throw new TypeError('"encoding" must be a valid string encoding');var r=0|y(t,n);e=i(e,r);var o=e.write(t,n);return o!==r&&(e=e.slice(0,o)),e}function h(e,t){var n=t.length<0?0:0|m(t.length);e=i(e,n);for(var r=0;n>r;r+=1)e[r]=255&t[r];return e}function l(e,t,n,r){if(t.byteLength,0>n||t.byteLength=o())throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+o().toString(16)+" bytes");return 0|e}function g(e){return+e!=e&&(e=0),s.alloc(+e)}function y(e,t){if(s.isBuffer(e))return e.length;if("undefined"!=typeof ArrayBuffer&&"function"==typeof ArrayBuffer.isView&&(ArrayBuffer.isView(e)||e instanceof ArrayBuffer))return e.byteLength;"string"!=typeof e&&(e=""+e);var n=e.length;if(0===n)return 0;for(var r=!1;;)switch(t){case"ascii":case"latin1":case"binary":return n;case"utf8":case"utf-8":case void 0:return Y(e).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*n;case"hex":return n>>>1;case"base64":return $(e).length;default:if(r)return Y(e).length;t=(""+t).toLowerCase(),r=!0}}function _(e,t,n){var r=!1;if((void 0===t||0>t)&&(t=0),t>this.length)return"";if((void 0===n||n>this.length)&&(n=this.length),0>=n)return"";if(n>>>=0,t>>>=0,t>=n)return"";for(e||(e="utf8");;)switch(e){case"hex":return U(this,t,n);case"utf8":case"utf-8":return T(this,t,n);case"ascii":return L(this,t,n);case"latin1":case"binary":return R(this,t,n);case"base64":return I(this,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return P(this,t,n);default:if(r)throw new TypeError("Unknown encoding: "+e);e=(e+"").toLowerCase(),r=!0}}function v(e,t,n){var r=e[t];e[t]=e[n],e[n]=r}function b(e,t,n,r,o){if(0===e.length)return-1;if("string"==typeof n?(r=n,n=0):n>2147483647?n=2147483647:-2147483648>n&&(n=-2147483648),n=+n,isNaN(n)&&(n=o?0:e.length-1),0>n&&(n=e.length+n),n>=e.length){if(o)return-1;n=e.length-1}else if(0>n){if(!o)return-1;n=0}if("string"==typeof t&&(t=s.from(t,r)),s.isBuffer(t))return 0===t.length?-1:w(e,t,n,r,o);if("number"==typeof t)return t=255&t,s.TYPED_ARRAY_SUPPORT&&"function"==typeof Uint8Array.prototype.indexOf?o?Uint8Array.prototype.indexOf.call(e,t,n):Uint8Array.prototype.lastIndexOf.call(e,t,n):w(e,[t],n,r,o);throw new TypeError("val must be string, number or Buffer")}function w(e,t,n,r,o){function i(e,t){return 1===s?e[t]:e.readUInt16BE(t*s)}var s=1,a=e.length,u=t.length;if(void 0!==r&&(r=String(r).toLowerCase(),"ucs2"===r||"ucs-2"===r||"utf16le"===r||"utf-16le"===r)){if(e.length<2||t.length<2)return-1;s=2,a/=2,u/=2,n/=2}var c;if(o){var f=-1;for(c=n;a>c;c++)if(i(e,c)===i(t,-1===f?0:c-f)){if(-1===f&&(f=c),c-f+1===u)return f*s}else-1!==f&&(c-=c-f),f=-1}else for(n+u>a&&(n=a-u),c=n;c>=0;c--){for(var d=!0,h=0;u>h;h++)if(i(e,c+h)!==i(t,h)){d=!1;break}if(d)return c}return-1}function E(e,t,n,r){n=Number(n)||0;var o=e.length-n;r?(r=Number(r),r>o&&(r=o)):r=o;var i=t.length;if(i%2!==0)throw new TypeError("Invalid hex string");r>i/2&&(r=i/2);for(var s=0;r>s;++s){var a=parseInt(t.substr(2*s,2),16);if(isNaN(a))return s;e[n+s]=a}return s}function k(e,t,n,r){return K(Y(t,e.length-n),e,n,r)}function x(e,t,n,r){return K(V(t),e,n,r)}function S(e,t,n,r){return x(e,t,n,r)}function B(e,t,n,r){return K($(t),e,n,r)}function A(e,t,n,r){return K(G(t,e.length-n),e,n,r)}function I(e,t,n){return J.fromByteArray(0===t&&n===e.length?e:e.slice(t,n))}function T(e,t,n){n=Math.min(e.length,n);for(var r=[],o=t;n>o;){var i=e[o],s=null,a=i>239?4:i>223?3:i>191?2:1;if(n>=o+a){var u,c,f,d;switch(a){case 1:128>i&&(s=i);break;case 2:u=e[o+1],128===(192&u)&&(d=(31&i)<<6|63&u,d>127&&(s=d));break;case 3:u=e[o+1],c=e[o+2],128===(192&u)&&128===(192&c)&&(d=(15&i)<<12|(63&u)<<6|63&c,d>2047&&(55296>d||d>57343)&&(s=d));break;case 4:u=e[o+1],c=e[o+2],f=e[o+3],128===(192&u)&&128===(192&c)&&128===(192&f)&&(d=(15&i)<<18|(63&u)<<12|(63&c)<<6|63&f,d>65535&&1114112>d&&(s=d))}}null===s?(s=65533,a=1):s>65535&&(s-=65536,r.push(s>>>10&1023|55296),s=56320|1023&s),r.push(s),o+=a}return C(r)}function C(e){var t=e.length;if(ee>=t)return String.fromCharCode.apply(String,e);for(var n="",r=0;t>r;)n+=String.fromCharCode.apply(String,e.slice(r,r+=ee));return n}function L(e,t,n){var r="";n=Math.min(e.length,n);for(var o=t;n>o;++o)r+=String.fromCharCode(127&e[o]);return r}function R(e,t,n){var r="";n=Math.min(e.length,n);for(var o=t;n>o;++o)r+=String.fromCharCode(e[o]);return r}function U(e,t,n){var r=e.length;(!t||0>t)&&(t=0),(!n||0>n||n>r)&&(n=r);for(var o="",i=t;n>i;++i)o+=F(e[i]);return o}function P(e,t,n){for(var r=e.slice(t,n),o="",i=0;ie)throw new RangeError("offset is not uint");if(e+t>n)throw new RangeError("Trying to access beyond buffer length")}function M(e,t,n,r,o,i){if(!s.isBuffer(e))throw new TypeError('"buffer" argument must be a Buffer instance');if(t>o||i>t)throw new RangeError('"value" argument is out of bounds');if(n+r>e.length)throw new RangeError("Index out of range")}function j(e,t,n,r){0>t&&(t=65535+t+1);for(var o=0,i=Math.min(e.length-n,2);i>o;++o)e[n+o]=(t&255<<8*(r?o:1-o))>>>8*(r?o:1-o)}function H(e,t,n,r){0>t&&(t=4294967295+t+1);for(var o=0,i=Math.min(e.length-n,4);i>o;++o)e[n+o]=t>>>8*(r?o:3-o)&255}function D(e,t,n,r){if(n+r>e.length)throw new RangeError("Index out of range");if(0>n)throw new RangeError("Index out of range")}function q(e,t,n,r,o){return o||D(e,t,n,4,3.4028234663852886e38,-3.4028234663852886e38),Q.write(e,t,n,r,23,4),n+4}function N(e,t,n,r,o){return o||D(e,t,n,8,1.7976931348623157e308,-1.7976931348623157e308),Q.write(e,t,n,r,52,8),n+8}function z(e){if(e=W(e).replace(te,""),e.length<2)return"";for(;e.length%4!==0;)e+="=";return e}function W(e){return e.trim?e.trim():e.replace(/^\s+|\s+$/g,"")}function F(e){return 16>e?"0"+e.toString(16):e.toString(16)}function Y(e,t){t=t||1/0;for(var n,r=e.length,o=null,i=[],s=0;r>s;++s){if(n=e.charCodeAt(s),n>55295&&57344>n){if(!o){if(n>56319){(t-=3)>-1&&i.push(239,191,189);continue}if(s+1===r){(t-=3)>-1&&i.push(239,191,189);continue}o=n;continue}if(56320>n){(t-=3)>-1&&i.push(239,191,189),o=n;continue}n=(o-55296<<10|n-56320)+65536}else o&&(t-=3)>-1&&i.push(239,191,189);if(o=null,128>n){if((t-=1)<0)break;i.push(n)}else if(2048>n){if((t-=2)<0)break;i.push(n>>6|192,63&n|128)}else if(65536>n){if((t-=3)<0)break;i.push(n>>12|224,n>>6&63|128,63&n|128)}else{if(!(1114112>n))throw new Error("Invalid code point");if((t-=4)<0)break;i.push(n>>18|240,n>>12&63|128,n>>6&63|128,63&n|128)}}return i}function V(e){for(var t=[],n=0;n>8,o=n%256,i.push(o),i.push(r);return i}function $(e){return J.toByteArray(z(e))}function K(e,t,n,r){for(var o=0;r>o&&!(o+n>=t.length||o>=e.length);++o)t[o+n]=e[o];return o}function X(e){return e!==e}var J=e("base64-js"),Q=e("ieee754"),Z=e("isarray");n.Buffer=s,n.SlowBuffer=g,n.INSPECT_MAX_BYTES=50,s.TYPED_ARRAY_SUPPORT=void 0!==t.TYPED_ARRAY_SUPPORT?t.TYPED_ARRAY_SUPPORT:r(),n.kMaxLength=o(),s.poolSize=8192,s._augment=function(e){return e.__proto__=s.prototype,e},s.from=function(e,t,n){return a(null,e,t,n)},s.TYPED_ARRAY_SUPPORT&&(s.prototype.__proto__=Uint8Array.prototype,s.__proto__=Uint8Array,"undefined"!=typeof Symbol&&Symbol.species&&s[Symbol.species]===s&&Object.defineProperty(s,Symbol.species,{value:null,configurable:!0})),s.alloc=function(e,t,n){return c(null,e,t,n)},s.allocUnsafe=function(e){return f(null,e)},s.allocUnsafeSlow=function(e){return f(null,e)},s.isBuffer=function(e){return!(null==e||!e._isBuffer)},s.compare=function(e,t){if(!s.isBuffer(e)||!s.isBuffer(t))throw new TypeError("Arguments must be Buffers");if(e===t)return 0;for(var n=e.length,r=t.length,o=0,i=Math.min(n,r);i>o;++o)if(e[o]!==t[o]){n=e[o],r=t[o];break}return r>n?-1:n>r?1:0},s.isEncoding=function(e){switch(String(e).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!0;default:return!1}},s.concat=function(e,t){if(!Z(e))throw new TypeError('"list" argument must be an Array of Buffers');if(0===e.length)return s.alloc(0);var n;if(void 0===t)for(t=0,n=0;nt;t+=2)v(this,t,t+1);return this},s.prototype.swap32=function(){var e=this.length;if(e%4!==0)throw new RangeError("Buffer size must be a multiple of 32-bits");for(var t=0;e>t;t+=4)v(this,t,t+3),v(this,t+1,t+2);return this},s.prototype.swap64=function(){var e=this.length;if(e%8!==0)throw new RangeError("Buffer size must be a multiple of 64-bits");for(var t=0;e>t;t+=8)v(this,t,t+7),v(this,t+1,t+6),v(this,t+2,t+5),v(this,t+3,t+4);return this},s.prototype.toString=function(){var e=0|this.length;return 0===e?"":0===arguments.length?T(this,0,e):_.apply(this,arguments)},s.prototype.equals=function(e){if(!s.isBuffer(e))throw new TypeError("Argument must be a Buffer");return this===e?!0:0===s.compare(this,e)},s.prototype.inspect=function(){var e="",t=n.INSPECT_MAX_BYTES;return this.length>0&&(e=this.toString("hex",0,t).match(/.{2}/g).join(" "),this.length>t&&(e+=" ... ")),""},s.prototype.compare=function(e,t,n,r,o){if(!s.isBuffer(e))throw new TypeError("Argument must be a Buffer");if(void 0===t&&(t=0),void 0===n&&(n=e?e.length:0),void 0===r&&(r=0),void 0===o&&(o=this.length),0>t||n>e.length||0>r||o>this.length)throw new RangeError("out of range index");if(r>=o&&t>=n)return 0;if(r>=o)return-1;if(t>=n)return 1;if(t>>>=0,n>>>=0,r>>>=0,o>>>=0,this===e)return 0;for(var i=o-r,a=n-t,u=Math.min(i,a),c=this.slice(r,o),f=e.slice(t,n),d=0;u>d;++d)if(c[d]!==f[d]){i=c[d],a=f[d];break}return a>i?-1:i>a?1:0},s.prototype.includes=function(e,t,n){return-1!==this.indexOf(e,t,n)},s.prototype.indexOf=function(e,t,n){return b(this,e,t,n,!0)},s.prototype.lastIndexOf=function(e,t,n){return b(this,e,t,n,!1)},s.prototype.write=function(e,t,n,r){if(void 0===t)r="utf8",n=this.length,t=0;else if(void 0===n&&"string"==typeof t)r=t,n=this.length,t=0;else{if(!isFinite(t))throw new Error("Buffer.write(string, encoding, offset[, length]) is no longer supported");t=0|t,isFinite(n)?(n=0|n,void 0===r&&(r="utf8")):(r=n,n=void 0)}var o=this.length-t;if((void 0===n||n>o)&&(n=o),e.length>0&&(0>n||0>t)||t>this.length)throw new RangeError("Attempt to write outside buffer bounds");r||(r="utf8");for(var i=!1;;)switch(r){case"hex":return E(this,e,t,n);case"utf8":case"utf-8":return k(this,e,t,n);case"ascii":return x(this,e,t,n);case"latin1":case"binary":return S(this,e,t,n);case"base64":return B(this,e,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return A(this,e,t,n);default:if(i)throw new TypeError("Unknown encoding: "+r);r=(""+r).toLowerCase(),i=!0}},s.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};var ee=4096;s.prototype.slice=function(e,t){var n=this.length;e=~~e,t=void 0===t?n:~~t,0>e?(e+=n,0>e&&(e=0)):e>n&&(e=n),0>t?(t+=n,0>t&&(t=0)):t>n&&(t=n),e>t&&(t=e);var r;if(s.TYPED_ARRAY_SUPPORT)r=this.subarray(e,t),r.__proto__=s.prototype;else{var o=t-e;r=new s(o,void 0);for(var i=0;o>i;++i)r[i]=this[i+e]}return r},s.prototype.readUIntLE=function(e,t,n){e=0|e,t=0|t,n||O(e,t,this.length);for(var r=this[e],o=1,i=0;++i0&&(o*=256);)r+=this[e+--t]*o;return r},s.prototype.readUInt8=function(e,t){return t||O(e,1,this.length),this[e]},s.prototype.readUInt16LE=function(e,t){return t||O(e,2,this.length),this[e]|this[e+1]<<8},s.prototype.readUInt16BE=function(e,t){return t||O(e,2,this.length),this[e]<<8|this[e+1]},s.prototype.readUInt32LE=function(e,t){return t||O(e,4,this.length),(this[e]|this[e+1]<<8|this[e+2]<<16)+16777216*this[e+3]},s.prototype.readUInt32BE=function(e,t){return t||O(e,4,this.length),16777216*this[e]+(this[e+1]<<16|this[e+2]<<8|this[e+3])},s.prototype.readIntLE=function(e,t,n){e=0|e,t=0|t,n||O(e,t,this.length);for(var r=this[e],o=1,i=0;++i=o&&(r-=Math.pow(2,8*t)),r},s.prototype.readIntBE=function(e,t,n){e=0|e,t=0|t,n||O(e,t,this.length);for(var r=t,o=1,i=this[e+--r];r>0&&(o*=256);)i+=this[e+--r]*o;return o*=128,i>=o&&(i-=Math.pow(2,8*t)),i},s.prototype.readInt8=function(e,t){return t||O(e,1,this.length),128&this[e]?-1*(255-this[e]+1):this[e]},s.prototype.readInt16LE=function(e,t){t||O(e,2,this.length);var n=this[e]|this[e+1]<<8;return 32768&n?4294901760|n:n},s.prototype.readInt16BE=function(e,t){t||O(e,2,this.length);var n=this[e+1]|this[e]<<8;return 32768&n?4294901760|n:n},s.prototype.readInt32LE=function(e,t){return t||O(e,4,this.length),this[e]|this[e+1]<<8|this[e+2]<<16|this[e+3]<<24},s.prototype.readInt32BE=function(e,t){return t||O(e,4,this.length),this[e]<<24|this[e+1]<<16|this[e+2]<<8|this[e+3]},s.prototype.readFloatLE=function(e,t){return t||O(e,4,this.length),Q.read(this,e,!0,23,4)},s.prototype.readFloatBE=function(e,t){return t||O(e,4,this.length),Q.read(this,e,!1,23,4)},s.prototype.readDoubleLE=function(e,t){return t||O(e,8,this.length),Q.read(this,e,!0,52,8)},s.prototype.readDoubleBE=function(e,t){return t||O(e,8,this.length),Q.read(this,e,!1,52,8)},s.prototype.writeUIntLE=function(e,t,n,r){if(e=+e,t=0|t,n=0|n,!r){var o=Math.pow(2,8*n)-1;M(this,e,t,n,o,0)}var i=1,s=0;for(this[t]=255&e;++s=0&&(s*=256);)this[t+i]=e/s&255;return t+n},s.prototype.writeUInt8=function(e,t,n){return e=+e,t=0|t,n||M(this,e,t,1,255,0),s.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),this[t]=255&e,t+1},s.prototype.writeUInt16LE=function(e,t,n){return e=+e,t=0|t,n||M(this,e,t,2,65535,0),s.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8):j(this,e,t,!0),t+2},s.prototype.writeUInt16BE=function(e,t,n){return e=+e,t=0|t,n||M(this,e,t,2,65535,0),s.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):j(this,e,t,!1),t+2},s.prototype.writeUInt32LE=function(e,t,n){return e=+e,t=0|t,n||M(this,e,t,4,4294967295,0),s.TYPED_ARRAY_SUPPORT?(this[t+3]=e>>>24,this[t+2]=e>>>16,this[t+1]=e>>>8,this[t]=255&e):H(this,e,t,!0),t+4},s.prototype.writeUInt32BE=function(e,t,n){return e=+e,t=0|t,n||M(this,e,t,4,4294967295,0),s.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):H(this,e,t,!1),t+4},s.prototype.writeIntLE=function(e,t,n,r){if(e=+e,t=0|t,!r){var o=Math.pow(2,8*n-1);M(this,e,t,n,o-1,-o)}var i=0,s=1,a=0;for(this[t]=255&e;++ie&&0===a&&0!==this[t+i-1]&&(a=1),this[t+i]=(e/s>>0)-a&255;return t+n},s.prototype.writeIntBE=function(e,t,n,r){if(e=+e,t=0|t,!r){var o=Math.pow(2,8*n-1);M(this,e,t,n,o-1,-o)}var i=n-1,s=1,a=0;for(this[t+i]=255&e;--i>=0&&(s*=256);)0>e&&0===a&&0!==this[t+i+1]&&(a=1),this[t+i]=(e/s>>0)-a&255;return t+n},s.prototype.writeInt8=function(e,t,n){return e=+e,t=0|t,n||M(this,e,t,1,127,-128),s.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),0>e&&(e=255+e+1),this[t]=255&e,t+1},s.prototype.writeInt16LE=function(e,t,n){return e=+e,t=0|t,n||M(this,e,t,2,32767,-32768),s.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8):j(this,e,t,!0),t+2},s.prototype.writeInt16BE=function(e,t,n){return e=+e,t=0|t,n||M(this,e,t,2,32767,-32768),s.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):j(this,e,t,!1),t+2},s.prototype.writeInt32LE=function(e,t,n){return e=+e,t=0|t,n||M(this,e,t,4,2147483647,-2147483648),s.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8,this[t+2]=e>>>16,this[t+3]=e>>>24):H(this,e,t,!0),t+4},s.prototype.writeInt32BE=function(e,t,n){return e=+e,t=0|t,n||M(this,e,t,4,2147483647,-2147483648),0>e&&(e=4294967295+e+1),s.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):H(this,e,t,!1),t+4},s.prototype.writeFloatLE=function(e,t,n){return q(this,e,t,!0,n)},s.prototype.writeFloatBE=function(e,t,n){return q(this,e,t,!1,n)},s.prototype.writeDoubleLE=function(e,t,n){return N(this,e,t,!0,n)},s.prototype.writeDoubleBE=function(e,t,n){return N(this,e,t,!1,n)},s.prototype.copy=function(e,t,n,r){if(n||(n=0),r||0===r||(r=this.length),t>=e.length&&(t=e.length),t||(t=0),r>0&&n>r&&(r=n),r===n)return 0;if(0===e.length||0===this.length)return 0;if(0>t)throw new RangeError("targetStart out of bounds");if(0>n||n>=this.length)throw new RangeError("sourceStart out of bounds");if(0>r)throw new RangeError("sourceEnd out of bounds");r>this.length&&(r=this.length),e.length-tn&&r>t)for(o=i-1;o>=0;--o)e[o+t]=this[o+n];else if(1e3>i||!s.TYPED_ARRAY_SUPPORT)for(o=0;i>o;++o)e[o+t]=this[o+n];else Uint8Array.prototype.set.call(e,this.subarray(n,n+i),t);return i},s.prototype.fill=function(e,t,n,r){if("string"==typeof e){if("string"==typeof t?(r=t,t=0,n=this.length):"string"==typeof n&&(r=n,n=this.length),1===e.length){var o=e.charCodeAt(0);256>o&&(e=o)}if(void 0!==r&&"string"!=typeof r)throw new TypeError("encoding must be a string");if("string"==typeof r&&!s.isEncoding(r))throw new TypeError("Unknown encoding: "+r)}else"number"==typeof e&&(e=255&e);if(0>t||this.length=n)return this;t>>>=0,n=void 0===n?this.length:n>>>0,e||(e=0);var i;if("number"==typeof e)for(i=t;n>i;++i)this[i]=e;else{var a=s.isBuffer(e)?e:Y(new s(e,r).toString()),u=a.length;for(i=0;n-t>i;++i)this[i+t]=a[i%u]}return this};var te=/[^+\/0-9A-Za-z-_]/g}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"base64-js":2,ieee754:10,isarray:13}],6:[function(e,t){t.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",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"}},{}],7:[function(e,t,n){(function(e){function t(e){return Array.isArray?Array.isArray(e):"[object Array]"===g(e)}function r(e){return"boolean"==typeof e}function o(e){return null===e}function i(e){return null==e}function s(e){return"number"==typeof e}function a(e){return"string"==typeof e}function u(e){return"symbol"==typeof e}function c(e){return void 0===e}function f(e){return"[object RegExp]"===g(e)}function d(e){return"object"==typeof e&&null!==e}function h(e){return"[object Date]"===g(e)}function l(e){return"[object Error]"===g(e)||e instanceof Error}function p(e){return"function"==typeof e}function m(e){return null===e||"boolean"==typeof e||"number"==typeof e||"string"==typeof e||"symbol"==typeof e||"undefined"==typeof e}function g(e){return Object.prototype.toString.call(e)}n.isArray=t,n.isBoolean=r,n.isNull=o,n.isNullOrUndefined=i,n.isNumber=s,n.isString=a,n.isSymbol=u,n.isUndefined=c,n.isRegExp=f,n.isObject=d,n.isDate=h,n.isError=l,n.isFunction=p,n.isPrimitive=m,n.isBuffer=e.isBuffer}).call(this,{isBuffer:e("../../is-buffer/index.js")})},{"../../is-buffer/index.js":12}],8:[function(e,t){function n(){this._events=this._events||{},this._maxListeners=this._maxListeners||void 0}function r(e){return"function"==typeof e}function o(e){return"number"==typeof e}function i(e){return"object"==typeof e&&null!==e}function s(e){return void 0===e}t.exports=n,n.EventEmitter=n,n.prototype._events=void 0,n.prototype._maxListeners=void 0,n.defaultMaxListeners=10,n.prototype.setMaxListeners=function(e){if(!o(e)||0>e||isNaN(e))throw TypeError("n must be a positive number");return this._maxListeners=e,this},n.prototype.emit=function(e){var t,n,o,a,u,c;if(this._events||(this._events={}),"error"===e&&(!this._events.error||i(this._events.error)&&!this._events.error.length)){if(t=arguments[1],t instanceof Error)throw t;var f=new Error('Uncaught, unspecified "error" event. ('+t+")");throw f.context=t,f}if(n=this._events[e],s(n))return!1;if(r(n))switch(arguments.length){case 1:n.call(this);break;case 2:n.call(this,arguments[1]);break;case 3:n.call(this,arguments[1],arguments[2]);break;default:a=Array.prototype.slice.call(arguments,1),n.apply(this,a)}else if(i(n))for(a=Array.prototype.slice.call(arguments,1),c=n.slice(),o=c.length,u=0;o>u;u++)c[u].apply(this,a);return!0},n.prototype.addListener=function(e,t){var o;if(!r(t))throw TypeError("listener must be a function");return this._events||(this._events={}),this._events.newListener&&this.emit("newListener",e,r(t.listener)?t.listener:t),this._events[e]?i(this._events[e])?this._events[e].push(t):this._events[e]=[this._events[e],t]:this._events[e]=t,i(this._events[e])&&!this._events[e].warned&&(o=s(this._maxListeners)?n.defaultMaxListeners:this._maxListeners,o&&o>0&&this._events[e].length>o&&(this._events[e].warned=!0,console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[e].length),"function"==typeof console.trace&&console.trace())),this},n.prototype.on=n.prototype.addListener,n.prototype.once=function(e,t){function n(){this.removeListener(e,n),o||(o=!0,t.apply(this,arguments))}if(!r(t))throw TypeError("listener must be a function");var o=!1;return n.listener=t,this.on(e,n),this},n.prototype.removeListener=function(e,t){var n,o,s,a;if(!r(t))throw TypeError("listener must be a function");if(!this._events||!this._events[e])return this;if(n=this._events[e],s=n.length,o=-1,n===t||r(n.listener)&&n.listener===t)delete this._events[e],this._events.removeListener&&this.emit("removeListener",e,t);else if(i(n)){for(a=s;a-->0;)if(n[a]===t||n[a].listener&&n[a].listener===t){o=a;break}if(0>o)return this;1===n.length?(n.length=0,delete this._events[e]):n.splice(o,1),this._events.removeListener&&this.emit("removeListener",e,t)}return this},n.prototype.removeAllListeners=function(e){var t,n;if(!this._events)return this;if(!this._events.removeListener)return 0===arguments.length?this._events={}:this._events[e]&&delete this._events[e],this;if(0===arguments.length){for(t in this._events)"removeListener"!==t&&this.removeAllListeners(t);return this.removeAllListeners("removeListener"),this._events={},this}if(n=this._events[e],r(n))this.removeListener(e,n);else if(n)for(;n.length;)this.removeListener(e,n[n.length-1]);return delete this._events[e],this},n.prototype.listeners=function(e){var t;return t=this._events&&this._events[e]?r(this._events[e])?[this._events[e]]:this._events[e].slice():[]},n.prototype.listenerCount=function(e){if(this._events){var t=this._events[e];if(r(t))return 1;if(t)return t.length}return 0},n.listenerCount=function(e,t){return e.listenerCount(t)}},{}],9:[function(e,t){var n=e("http"),r=t.exports;for(var o in n)n.hasOwnProperty(o)&&(r[o]=n[o]);r.request=function(e,t){return e||(e={}),e.scheme="https",e.protocol="https:",n.request.call(this,e,t)}},{http:28}],10:[function(e,t,n){n.read=function(e,t,n,r,o){var i,s,a=8*o-r-1,u=(1<>1,f=-7,d=n?o-1:0,h=n?-1:1,l=e[t+d];for(d+=h,i=l&(1<<-f)-1,l>>=-f,f+=a;f>0;i=256*i+e[t+d],d+=h,f-=8);for(s=i&(1<<-f)-1,i>>=-f,f+=r;f>0;s=256*s+e[t+d],d+=h,f-=8);if(0===i)i=1-c;else{if(i===u)return s?0/0:(l?-1:1)*(1/0);s+=Math.pow(2,r),i-=c}return(l?-1:1)*s*Math.pow(2,i-r)},n.write=function(e,t,n,r,o,i){var s,a,u,c=8*i-o-1,f=(1<>1,h=23===o?Math.pow(2,-24)-Math.pow(2,-77):0,l=r?0:i-1,p=r?1:-1,m=0>t||0===t&&0>1/t?1:0;for(t=Math.abs(t),isNaN(t)||t===1/0?(a=isNaN(t)?1:0,s=f):(s=Math.floor(Math.log(t)/Math.LN2),t*(u=Math.pow(2,-s))<1&&(s--,u*=2),t+=s+d>=1?h/u:h*Math.pow(2,1-d),t*u>=2&&(s++,u/=2),s+d>=f?(a=0,s=f):s+d>=1?(a=(t*u-1)*Math.pow(2,o),s+=d):(a=t*Math.pow(2,d-1)*Math.pow(2,o),s=0));o>=8;e[n+l]=255&a,l+=p,a/=256,o-=8);for(s=s<0;e[n+l]=255&s,l+=p,s/=256,c-=8);e[n+l-p]|=128*m}},{}],11:[function(e,t){t.exports="function"==typeof Object.create?function(e,t){e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}})}:function(e,t){e.super_=t;var n=function(){};n.prototype=t.prototype,e.prototype=new n,e.prototype.constructor=e}},{}],12:[function(e,t){function n(e){return!!e.constructor&&"function"==typeof e.constructor.isBuffer&&e.constructor.isBuffer(e)}function r(e){return"function"==typeof e.readFloatLE&&"function"==typeof e.slice&&n(e.slice(0,0)); -exports.byteLength = byteLength -exports.toByteArray = toByteArray -exports.fromByteArray = fromByteArray +}t.exports=function(e){return null!=e&&(n(e)||r(e)||!!e._isBuffer)}},{}],13:[function(e,t){var n={}.toString;t.exports=Array.isArray||function(e){return"[object Array]"==n.call(e)}},{}],14:[function(e,t,n){(function(e){function t(e,t){for(var n=0,r=e.length-1;r>=0;r--){var o=e[r];"."===o?e.splice(r,1):".."===o?(e.splice(r,1),n++):n&&(e.splice(r,1),n--)}if(t)for(;n--;n)e.unshift("..");return e}function r(e,t){if(e.filter)return e.filter(t);for(var n=[],r=0;r=-1&&!o;i--){var s=i>=0?arguments[i]:e.cwd();if("string"!=typeof s)throw new TypeError("Arguments to path.resolve must be strings");s&&(n=s+"/"+n,o="/"===s.charAt(0))}return n=t(r(n.split("/"),function(e){return!!e}),!o).join("/"),(o?"/":"")+n||"."},n.normalize=function(e){var o=n.isAbsolute(e),i="/"===s(e,-1);return e=t(r(e.split("/"),function(e){return!!e}),!o).join("/"),e||o||(e="."),e&&i&&(e+="/"),(o?"/":"")+e},n.isAbsolute=function(e){return"/"===e.charAt(0)},n.join=function(){var e=Array.prototype.slice.call(arguments,0);return n.normalize(r(e,function(e){if("string"!=typeof e)throw new TypeError("Arguments to path.join must be strings");return e}).join("/"))},n.relative=function(e,t){function r(e){for(var t=0;t=0&&""===e[n];n--);return t>n?[]:e.slice(t,n-t+1)}e=n.resolve(e).substr(1),t=n.resolve(t).substr(1);for(var o=r(e.split("/")),i=r(t.split("/")),s=Math.min(o.length,i.length),a=s,u=0;s>u;u++)if(o[u]!==i[u]){a=u;break}for(var c=[],u=a;ut&&(t=e.length+t),e.substr(t,n)}}).call(this,e("_process"))},{_process:16}],15:[function(e,t){(function(e){"use strict";function n(t,n,r,o){if("function"!=typeof t)throw new TypeError('"callback" argument must be a function');var i,s,a=arguments.length;switch(a){case 0:case 1:return e.nextTick(t);case 2:return e.nextTick(function(){t.call(null,n)});case 3:return e.nextTick(function(){t.call(null,n,r)});case 4:return e.nextTick(function(){t.call(null,n,r,o)});default:for(i=new Array(a-1),s=0;s1)for(var n=1;n1&&(r=n[0]+"@",e=n[1]),e=e.replace(U,".");var o=e.split("."),i=s(o,t).join(".");return r+i}function u(e){for(var t,n,r=[],o=0,i=e.length;i>o;)t=e.charCodeAt(o++),t>=55296&&56319>=t&&i>o?(n=e.charCodeAt(o++),56320==(64512&n)?r.push(((1023&t)<<10)+(1023&n)+65536):(r.push(t),o--)):r.push(t);return r}function c(e){return s(e,function(e){var t="";return e>65535&&(e-=65536,t+=j(e>>>10&1023|55296),e=56320|1023&e),t+=j(e)}).join("")}function f(e){return 10>e-48?e-22:26>e-65?e-65:26>e-97?e-97:k}function d(e,t){return e+22+75*(26>e)-((0!=t)<<5)}function h(e,t,n){var r=0;for(e=n?M(e/A):e>>1,e+=M(e/t);e>O*S>>1;r+=k)e=M(e/O);return M(r+(O+1)*e/(e+B))}function l(e){var t,n,r,o,s,a,u,d,l,p,m=[],g=e.length,y=0,_=T,v=I;for(n=e.lastIndexOf(C),0>n&&(n=0),r=0;n>r;++r)e.charCodeAt(r)>=128&&i("not-basic"),m.push(e.charCodeAt(r));for(o=n>0?n+1:0;g>o;){for(s=y,a=1,u=k;o>=g&&i("invalid-input"),d=f(e.charCodeAt(o++)),(d>=k||d>M((E-y)/a))&&i("overflow"),y+=d*a,l=v>=u?x:u>=v+S?S:u-v,!(l>d);u+=k)p=k-l,a>M(E/p)&&i("overflow"),a*=p;t=m.length+1,v=h(y-s,t,0==s),M(y/t)>E-_&&i("overflow"),_+=M(y/t),y%=t,m.splice(y++,0,_)}return c(m)}function p(e){var t,n,r,o,s,a,c,f,l,p,m,g,y,_,v,b=[];for(e=u(e),g=e.length,t=T,n=0,s=I,a=0;g>a;++a)m=e[a],128>m&&b.push(j(m));for(r=o=b.length,o&&b.push(C);g>r;){for(c=E,a=0;g>a;++a)m=e[a],m>=t&&c>m&&(c=m);for(y=r+1,c-t>M((E-n)/y)&&i("overflow"),n+=(c-t)*y,t=c,a=0;g>a;++a)if(m=e[a],t>m&&++n>E&&i("overflow"),m==t){for(f=n,l=k;p=s>=l?x:l>=s+S?S:l-s,!(p>f);l+=k)v=f-p,_=k-p,b.push(j(d(p+v%_,0))),f=M(v/_);b.push(j(d(f,0))),s=h(n,y,r==o),n=0,++r}++n,++t}return b.join("")}function m(e){return a(e,function(e){return L.test(e)?l(e.slice(4).toLowerCase()):e})}function g(e){return a(e,function(e){return R.test(e)?"xn--"+p(e):e})}var y="object"==typeof r&&r&&!r.nodeType&&r,_="object"==typeof n&&n&&!n.nodeType&&n,v="object"==typeof t&&t;(v.global===v||v.window===v||v.self===v)&&(o=v);var b,w,E=2147483647,k=36,x=1,S=26,B=38,A=700,I=72,T=128,C="-",L=/^xn--/,R=/[^\x20-\x7E]/,U=/[\x2E\u3002\uFF0E\uFF61]/g,P={overflow:"Overflow: input needs wider integers to process","not-basic":"Illegal input >= 0x80 (not a basic code point)","invalid-input":"Invalid input"},O=k-x,M=Math.floor,j=String.fromCharCode;if(b={version:"1.4.1",ucs2:{decode:u,encode:c},decode:l,encode:p,toASCII:g,toUnicode:m},"function"==typeof e&&"object"==typeof e.amd&&e.amd)e("punycode",function(){return b});else if(y&&_)if(n.exports==y)_.exports=b;else for(w in b)b.hasOwnProperty(w)&&(y[w]=b[w]);else o.punycode=b}(this)}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],18:[function(e,t){"use strict";function n(e,t){return Object.prototype.hasOwnProperty.call(e,t)}t.exports=function(e,t,o,i){t=t||"&",o=o||"=";var s={};if("string"!=typeof e||0===e.length)return s;var a=/\+/g;e=e.split(t);var u=1e3;i&&"number"==typeof i.maxKeys&&(u=i.maxKeys);var c=e.length;u>0&&c>u&&(c=u);for(var f=0;c>f;++f){var d,h,l,p,m=e[f].replace(a,"%20"),g=m.indexOf(o);g>=0?(d=m.substr(0,g),h=m.substr(g+1)):(d=m,h=""),l=decodeURIComponent(d),p=decodeURIComponent(h),n(s,l)?r(s[l])?s[l].push(p):s[l]=[s[l],p]:s[l]=p}return s};var r=Array.isArray||function(e){return"[object Array]"===Object.prototype.toString.call(e)}},{}],19:[function(e,t){"use strict";function n(e,t){if(e.map)return e.map(t);for(var n=[],r=0;r0)if(t.ended&&!o){var s=new Error("stream.push() after EOF");e.emit("error",s)}else if(t.endEmitted&&o){var u=new Error("stream.unshift() after end event");e.emit("error",u)}else{var c;!t.decoder||o||r||(n=t.decoder.write(n),c=!t.objectMode&&0===n.length),o||(t.reading=!1),c||(t.flowing&&0===t.length&&!t.sync?(e.emit("data",n),e.read(0)):(t.length+=t.objectMode?1:n.length,o?t.buffer.unshift(n):t.buffer.push(n),t.needReadable&&h(e))),p(e,t)}else o||(t.reading=!1);return a(t)}function a(e){return!e.ended&&(e.needReadable||e.length=N?e=N:(e--,e|=e>>>1,e|=e>>>2,e|=e>>>4,e|=e>>>8,e|=e>>>16,e++),e}function c(e,t){return 0>=e||0===t.length&&t.ended?0:t.objectMode?1:e!==e?t.flowing&&t.length?t.buffer.head.data.length:t.length:(e>t.highWaterMark&&(t.highWaterMark=u(e)),e<=t.length?e:t.ended?t.length:(t.needReadable=!0,0))}function f(e,t){var n=null;return U.isBuffer(t)||"string"==typeof t||null===t||void 0===t||e.objectMode||(n=new TypeError("Invalid non-string/buffer chunk")),n}function d(e,t){if(!t.ended){if(t.decoder){var n=t.decoder.end();n&&n.length&&(t.buffer.push(n),t.length+=t.objectMode?1:n.length)}t.ended=!0,h(e)}}function h(e){var t=e._readableState;t.needReadable=!1,t.emittedReadable||(j("emitReadable",t.flowing),t.emittedReadable=!0,t.sync?T(l,e):l(e))}function l(e){j("emit readable"),e.emit("readable"),b(e)}function p(e,t){t.readingMore||(t.readingMore=!0,T(m,e,t))}function m(e,t){for(var n=t.length;!t.reading&&!t.flowing&&!t.ended&&t.length=t.length?(n=t.decoder?t.buffer.join(""):1===t.buffer.length?t.buffer.head.data:t.buffer.concat(t.length),t.buffer.clear()):n=E(e,t.buffer,t.decoder),n}function E(e,t,n){var r;return ei.length?i.length:e;if(o+=s===i.length?i:i.slice(0,e),e-=s,0===e){s===i.length?(++r,t.head=n.next?n.next:t.tail=null):(t.head=n,n.data=i.slice(s));break}++r}return t.length-=r,o}function x(e,t){var n=P.allocUnsafe(e),r=t.head,o=1;for(r.data.copy(n),e-=r.data.length;r=r.next;){var i=r.data,s=e>i.length?i.length:e;if(i.copy(n,n.length-e,0,s),e-=s,0===e){s===i.length?(++o,t.head=r.next?r.next:t.tail=null):(t.head=r,r.data=i.slice(s));break}++o}return t.length-=o,n}function S(e){var t=e._readableState;if(t.length>0)throw new Error('"endReadable()" called on non-empty stream');t.endEmitted||(t.ended=!0,T(B,t,e))}function B(e,t){e.endEmitted||0!==e.length||(e.endEmitted=!0,t.readable=!1,t.emit("end"))}function A(e,t){for(var n=0,r=e.length;r>n;n++)t(e[n],n)}function I(e,t){for(var n=0,r=e.length;r>n;n++)if(e[n]===t)return n;return-1}t.exports=i;var T=e("process-nextick-args"),C=e("isarray");i.ReadableState=o;var L,R=(e("events").EventEmitter,function(e,t){return e.listeners(t).length});!function(){try{L=e("stream")}catch(t){}finally{L||(L=e("events").EventEmitter)}}();var U=e("buffer").Buffer,P=e("buffer-shims"),O=e("core-util-is");O.inherits=e("inherits");var M=e("util"),j=void 0;j=M&&M.debuglog?M.debuglog("stream"):function(){};var H,D=e("./internal/streams/BufferList");O.inherits(i,L);var q,q;i.prototype.push=function(e,t){var n=this._readableState;return n.objectMode||"string"!=typeof e||(t=t||n.defaultEncoding,t!==n.encoding&&(e=P.from(e,t),t="")),s(this,n,e,t,!1)},i.prototype.unshift=function(e){var t=this._readableState;return s(this,t,e,"",!0)},i.prototype.isPaused=function(){return this._readableState.flowing===!1},i.prototype.setEncoding=function(t){return H||(H=e("string_decoder/").StringDecoder),this._readableState.decoder=new H(t),this._readableState.encoding=t,this};var N=8388608;i.prototype.read=function(e){j("read",e),e=parseInt(e,10);var t=this._readableState,n=e;if(0!==e&&(t.emittedReadable=!1),0===e&&t.needReadable&&(t.length>=t.highWaterMark||t.ended))return j("read: emitReadable",t.length,t.ended),0===t.length&&t.ended?S(this):h(this),null;if(e=c(e,t),0===e&&t.ended)return 0===t.length&&S(this),null;var r=t.needReadable;j("need readable",r),(0===t.length||t.length-e0?w(e,t):null,null===o?(t.needReadable=!0,e=0):t.length-=e,0===t.length&&(t.ended||(t.needReadable=!0),n!==e&&t.ended&&S(this)),null!==o&&this.emit("data",o),o},i.prototype._read=function(){this.emit("error",new Error("not implemented"))},i.prototype.pipe=function(e,t){function o(e){j("onunpipe"),e===h&&s()}function i(){j("onend"),e.end()}function s(){j("cleanup"),e.removeListener("close",c),e.removeListener("finish",f),e.removeListener("drain",y),e.removeListener("error",u),e.removeListener("unpipe",o),h.removeListener("end",i),h.removeListener("end",s),h.removeListener("data",a),_=!0,!l.awaitDrain||e._writableState&&!e._writableState.needDrain||y()}function a(t){j("ondata"),v=!1;var n=e.write(t);!1!==n||v||((1===l.pipesCount&&l.pipes===e||l.pipesCount>1&&-1!==I(l.pipes,e))&&!_&&(j("false write response, pause",h._readableState.awaitDrain),h._readableState.awaitDrain++,v=!0),h.pause())}function u(t){j("onerror",t),d(),e.removeListener("error",u),0===R(e,"error")&&e.emit("error",t)}function c(){e.removeListener("finish",f),d()}function f(){j("onfinish"),e.removeListener("close",c),d()}function d(){j("unpipe"),h.unpipe(e)}var h=this,l=this._readableState;switch(l.pipesCount){case 0:l.pipes=e;break;case 1:l.pipes=[l.pipes,e];break;default:l.pipes.push(e)}l.pipesCount+=1,j("pipe count=%d opts=%j",l.pipesCount,t);var p=(!t||t.end!==!1)&&e!==n.stdout&&e!==n.stderr,m=p?i:s;l.endEmitted?T(m):h.once("end",m),e.on("unpipe",o);var y=g(h);e.on("drain",y);var _=!1,v=!1;return h.on("data",a),r(e,"error",u),e.once("close",c),e.once("finish",f),e.emit("pipe",h),l.flowing||(j("pipe resume"),h.resume()),e},i.prototype.unpipe=function(e){var t=this._readableState;if(0===t.pipesCount)return this;if(1===t.pipesCount)return e&&e!==t.pipes?this:(e||(e=t.pipes),t.pipes=null,t.pipesCount=0,t.flowing=!1,e&&e.emit("unpipe",this),this);if(!e){var n=t.pipes,r=t.pipesCount;t.pipes=null,t.pipesCount=0,t.flowing=!1;for(var o=0;r>o;o++)n[o].emit("unpipe",this);return this}var i=I(t.pipes,e);return-1===i?this:(t.pipes.splice(i,1),t.pipesCount-=1,1===t.pipesCount&&(t.pipes=t.pipes[0]),e.emit("unpipe",this),this)},i.prototype.on=function(e,t){var n=L.prototype.on.call(this,e,t);if("data"===e)this._readableState.flowing!==!1&&this.resume();else if("readable"===e){var r=this._readableState;r.endEmitted||r.readableListening||(r.readableListening=r.needReadable=!0,r.emittedReadable=!1,r.reading?r.length&&h(this,r):T(y,this))}return n},i.prototype.addListener=i.prototype.on,i.prototype.resume=function(){var e=this._readableState;return e.flowing||(j("resume"),e.flowing=!0,_(this,e)),this},i.prototype.pause=function(){return j("call pause flowing=%j",this._readableState.flowing),!1!==this._readableState.flowing&&(j("pause"),this._readableState.flowing=!1,this.emit("pause")),this},i.prototype.wrap=function(e){var t=this._readableState,n=!1,r=this;e.on("end",function(){if(j("wrapped end"),t.decoder&&!t.ended){var e=t.decoder.end();e&&e.length&&r.push(e)}r.push(null)}),e.on("data",function(o){if(j("wrapped data"),t.decoder&&(o=t.decoder.write(o)),(!t.objectMode||null!==o&&void 0!==o)&&(t.objectMode||o&&o.length)){var i=r.push(o);i||(n=!0,e.pause())}});for(var o in e)void 0===this[o]&&"function"==typeof e[o]&&(this[o]=function(t){return function(){return e[t].apply(e,arguments)}}(o));var i=["error","close","destroy","pause","resume"];return A(i,function(t){e.on(t,r.emit.bind(r,t))}),r._read=function(t){j("wrapped _read",t),n&&(n=!1,e.resume())},r},i._fromList=w}).call(this,e("_process"))},{"./_stream_duplex":21,"./internal/streams/BufferList":26,_process:16,buffer:5,"buffer-shims":4,"core-util-is":7,events:8,inherits:11,isarray:13,"process-nextick-args":15,"string_decoder/":32,util:3}],24:[function(e,t){"use strict";function n(e){this.afterTransform=function(t,n){return r(e,t,n)},this.needTransform=!1,this.transforming=!1,this.writecb=null,this.writechunk=null,this.writeencoding=null}function r(e,t,n){var r=e._transformState;r.transforming=!1;var o=r.writecb;if(!o)return e.emit("error",new Error("no writecb in Transform class"));r.writechunk=null,r.writecb=null,null!==n&&void 0!==n&&e.push(n),o(t);var i=e._readableState;i.reading=!1,(i.needReadable||i.length-1?setImmediate:k;s.WritableState=i;var S=e("core-util-is");S.inherits=e("inherits");var B,A={deprecate:e("util-deprecate")};!function(){try{B=e("stream")}catch(t){}finally{B||(B=e("events").EventEmitter)}}();var I=e("buffer").Buffer,T=e("buffer-shims");S.inherits(s,B);var C;i.prototype.getBuffer=function(){for(var e=this.bufferedRequest,t=[];e;)t.push(e),e=e.next;return t},function(){try{Object.defineProperty(i.prototype,"buffer",{get:A.deprecate(function(){return this.getBuffer()},"_writableState.buffer is deprecated. Use _writableState.getBuffer instead.")})}catch(e){}}();var C;s.prototype.pipe=function(){this.emit("error",new Error("Cannot pipe, not readable"))},s.prototype.write=function(e,t,n){var o=this._writableState,i=!1;return"function"==typeof t&&(n=t,t=null),I.isBuffer(e)?t="buffer":t||(t=o.defaultEncoding),"function"!=typeof n&&(n=r),o.ended?a(this,n):u(this,o,e,n)&&(o.pendingcb++,i=f(this,o,e,t,n)),i},s.prototype.cork=function(){var e=this._writableState;e.corked++},s.prototype.uncork=function(){var e=this._writableState;e.corked&&(e.corked--,e.writing||e.corked||e.finished||e.bufferProcessing||!e.bufferedRequest||y(this,e))},s.prototype.setDefaultEncoding=function(e){if("string"==typeof e&&(e=e.toLowerCase()),!(["hex","utf8","utf-8","ascii","binary","base64","ucs2","ucs-2","utf16le","utf-16le","raw"].indexOf((e+"").toLowerCase())>-1))throw new TypeError("Unknown encoding: "+e);return this._writableState.defaultEncoding=e,this},s.prototype._write=function(e,t,n){n(new Error("not implemented"))},s.prototype._writev=null,s.prototype.end=function(e,t,n){var r=this._writableState;"function"==typeof e?(n=e,e=null,t=null):"function"==typeof t&&(n=t,t=null),null!==e&&void 0!==e&&this.write(e,t),r.corked&&(r.corked=1,this.uncork()),r.ending||r.finished||w(this,r,n)}}).call(this,e("_process"))},{"./_stream_duplex":21,_process:16,buffer:5,"buffer-shims":4,"core-util-is":7,events:8,inherits:11,"process-nextick-args":15,"util-deprecate":36}],26:[function(e,t){"use strict";function n(){this.head=null,this.tail=null,this.length=0}var r=(e("buffer").Buffer,e("buffer-shims"));t.exports=n,n.prototype.push=function(e){var t={data:e,next:null};this.length>0?this.tail.next=t:this.head=t,this.tail=t,++this.length},n.prototype.unshift=function(e){var t={data:e,next:this.head};0===this.length&&(this.tail=t),this.head=t,++this.length},n.prototype.shift=function(){if(0!==this.length){var e=this.head.data;return this.head=1===this.length?this.tail=null:this.head.next,--this.length,e}},n.prototype.clear=function(){this.head=this.tail=null,this.length=0},n.prototype.join=function(e){if(0===this.length)return"";for(var t=this.head,n=""+t.data;t=t.next;)n+=e+t.data;return n},n.prototype.concat=function(e){if(0===this.length)return r.alloc(0);if(1===this.length)return this.head.data;for(var t=r.allocUnsafe(e>>>0),n=this.head,o=0;n;)n.data.copy(t,o),o+=n.data.length,n=n.next;return t}},{buffer:5,"buffer-shims":4}],27:[function(e,t,n){(function(r){var o=function(){try{return e("stream")}catch(t){}}();n=t.exports=e("./lib/_stream_readable.js"),n.Stream=o||n,n.Readable=n,n.Writable=e("./lib/_stream_writable.js"),n.Duplex=e("./lib/_stream_duplex.js"),n.Transform=e("./lib/_stream_transform.js"),n.PassThrough=e("./lib/_stream_passthrough.js"),!r.browser&&"disable"===r.env.READABLE_STREAM&&o&&(t.exports=o)}).call(this,e("_process"))},{"./lib/_stream_duplex.js":21,"./lib/_stream_passthrough.js":22,"./lib/_stream_readable.js":23,"./lib/_stream_transform.js":24,"./lib/_stream_writable.js":25,_process:16}],28:[function(e,t,n){(function(t){var r=e("./lib/request"),o=e("xtend"),i=e("builtin-status-codes"),s=e("url"),a=n;a.request=function(e,n){e="string"==typeof e?s.parse(e):o(e);var i=-1===t.location.protocol.search(/^https?:$/)?"http:":"",a=e.protocol||i,u=e.hostname||e.host,c=e.port,f=e.path||"/";u&&-1!==u.indexOf(":")&&(u="["+u+"]"),e.url=(u?a+"//"+u:"")+(c?":"+c:"")+f,e.method=(e.method||"GET").toUpperCase(),e.headers=e.headers||{};var d=new r(e);return n&&d.on("response",n),d},a.get=function(e,t){var n=a.request(e,t);return n.end(),n},a.Agent=function(){},a.Agent.defaultMaxSockets=4,a.STATUS_CODES=i,a.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,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./lib/request":30,"builtin-status-codes":6,url:34,xtend:37}],29:[function(e,t,n){(function(e){function t(e){try{return i.responseType=e,i.responseType===e}catch(t){}return!1}function r(e){return"function"==typeof e}n.fetch=r(e.fetch)&&r(e.ReadableStream),n.blobConstructor=!1;try{new Blob([new ArrayBuffer(1)]),n.blobConstructor=!0}catch(o){}var i=new e.XMLHttpRequest;i.open("GET",e.location.host?"/":"https://example.com");var s="undefined"!=typeof e.ArrayBuffer,a=s&&r(e.ArrayBuffer.prototype.slice);n.arraybuffer=s&&t("arraybuffer"),n.msstream=!n.fetch&&a&&t("ms-stream"),n.mozchunkedarraybuffer=!n.fetch&&s&&t("moz-chunked-arraybuffer"),n.overrideMimeType=r(i.overrideMimeType),n.vbArray=r(e.VBArray),i=null}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],30:[function(e,t){(function(n,r,o){function i(e,t){return a.fetch&&t?"fetch":a.mozchunkedarraybuffer?"moz-chunked-arraybuffer":a.msstream?"ms-stream":a.arraybuffer&&e?"arraybuffer":a.vbArray&&e?"text:vbarray":"text"}function s(e){try{var t=e.status;return null!==t&&0!==t}catch(n){return!1}}var a=e("./capability"),u=e("inherits"),c=e("./response"),f=e("readable-stream"),d=e("to-arraybuffer"),h=c.IncomingMessage,l=c.readyStates,p=t.exports=function(e){var t=this;f.Writable.call(t),t._opts=e,t._body=[],t._headers={},e.auth&&t.setHeader("Authorization","Basic "+new o(e.auth).toString("base64")), +Object.keys(e.headers).forEach(function(n){t.setHeader(n,e.headers[n])});var n,r=!0;if("disable-fetch"===e.mode)r=!1,n=!0;else if("prefer-streaming"===e.mode)n=!1;else if("allow-wrong-content-type"===e.mode)n=!a.overrideMimeType;else{if(e.mode&&"default"!==e.mode&&"prefer-fast"!==e.mode)throw new Error("Invalid value for opts.mode");n=!0}t._mode=i(n,r),t.on("finish",function(){t._onFinish()})};u(p,f.Writable),p.prototype.setHeader=function(e,t){var n=this,r=e.toLowerCase();-1===m.indexOf(r)&&(n._headers[r]={name:e,value:t})},p.prototype.getHeader=function(e){var t=this;return t._headers[e.toLowerCase()].value},p.prototype.removeHeader=function(e){var t=this;delete t._headers[e.toLowerCase()]},p.prototype._onFinish=function(){var e=this;if(!e._destroyed){var t,i=e._opts,s=e._headers;if(("POST"===i.method||"PUT"===i.method||"PATCH"===i.method)&&(t=a.blobConstructor?new r.Blob(e._body.map(function(e){return d(e)}),{type:(s["content-type"]||{}).value||""}):o.concat(e._body).toString()),"fetch"===e._mode){var u=Object.keys(s).map(function(e){return[s[e].name,s[e].value]});r.fetch(e._opts.url,{method:e._opts.method,headers:u,body:t,mode:"cors",credentials:i.withCredentials?"include":"same-origin"}).then(function(t){e._fetchResponse=t,e._connect()},function(t){e.emit("error",t)})}else{var c=e._xhr=new r.XMLHttpRequest;try{c.open(e._opts.method,e._opts.url,!0)}catch(f){return void n.nextTick(function(){e.emit("error",f)})}"responseType"in c&&(c.responseType=e._mode.split(":")[0]),"withCredentials"in c&&(c.withCredentials=!!i.withCredentials),"text"===e._mode&&"overrideMimeType"in c&&c.overrideMimeType("text/plain; charset=x-user-defined"),Object.keys(s).forEach(function(e){c.setRequestHeader(s[e].name,s[e].value)}),e._response=null,c.onreadystatechange=function(){switch(c.readyState){case l.LOADING:case l.DONE:e._onXHRProgress()}},"moz-chunked-arraybuffer"===e._mode&&(c.onprogress=function(){e._onXHRProgress()}),c.onerror=function(){e._destroyed||e.emit("error",new Error("XHR error"))};try{c.send(t)}catch(f){return void n.nextTick(function(){e.emit("error",f)})}}}},p.prototype._onXHRProgress=function(){var e=this;s(e._xhr)&&!e._destroyed&&(e._response||e._connect(),e._response._onXHRProgress())},p.prototype._connect=function(){var e=this;e._destroyed||(e._response=new h(e._xhr,e._fetchResponse,e._mode),e.emit("response",e._response))},p.prototype._write=function(e,t,n){var r=this;r._body.push(e),n()},p.prototype.abort=p.prototype.destroy=function(){var e=this;e._destroyed=!0,e._response&&(e._response._destroyed=!0),e._xhr&&e._xhr.abort()},p.prototype.end=function(e,t,n){var r=this;"function"==typeof e&&(n=e,e=void 0),f.Writable.prototype.end.call(r,e,t,n)},p.prototype.flushHeaders=function(){},p.prototype.setTimeout=function(){},p.prototype.setNoDelay=function(){},p.prototype.setSocketKeepAlive=function(){};var m=["accept-charset","accept-encoding","access-control-request-headers","access-control-request-method","connection","content-length","cookie","cookie2","date","dnt","expect","host","keep-alive","origin","referer","te","trailer","transfer-encoding","upgrade","user-agent","via"]}).call(this,e("_process"),"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{},e("buffer").Buffer)},{"./capability":29,"./response":31,_process:16,buffer:5,inherits:11,"readable-stream":27,"to-arraybuffer":33}],31:[function(e,t,n){(function(t,r,o){var i=e("./capability"),s=e("inherits"),a=e("readable-stream"),u=n.readyStates={UNSENT:0,OPENED:1,HEADERS_RECEIVED:2,LOADING:3,DONE:4},c=n.IncomingMessage=function(e,n,r){function s(){h.read().then(function(e){if(!u._destroyed){if(e.done)return void u.push(null);u.push(new o(e.value)),s()}})}var u=this;if(a.Readable.call(u),u._mode=r,u.headers={},u.rawHeaders=[],u.trailers={},u.rawTrailers=[],u.on("end",function(){t.nextTick(function(){u.emit("close")})}),"fetch"===r){u._fetchResponse=n,u.url=n.url,u.statusCode=n.status,u.statusMessage=n.statusText;for(var c,f,d=n.headers[Symbol.iterator]();c=(f=d.next()).value,!f.done;)u.headers[c[0].toLowerCase()]=c[1],u.rawHeaders.push(c[0],c[1]);var h=n.body.getReader();s()}else{u._xhr=e,u._pos=0,u.url=e.responseURL,u.statusCode=e.status,u.statusMessage=e.statusText;var l=e.getAllResponseHeaders().split(/\r?\n/);if(l.forEach(function(e){var t=e.match(/^([^:]+):\s*(.*)/);if(t){var n=t[1].toLowerCase();"set-cookie"===n?(void 0===u.headers[n]&&(u.headers[n]=[]),u.headers[n].push(t[2])):void 0!==u.headers[n]?u.headers[n]+=", "+t[2]:u.headers[n]=t[2],u.rawHeaders.push(t[1],t[2])}}),u._charset="x-user-defined",!i.overrideMimeType){var p=u.rawHeaders["mime-type"];if(p){var m=p.match(/;\s*charset=([^;])(;|$)/);m&&(u._charset=m[1].toLowerCase())}u._charset||(u._charset="utf-8")}}};s(c,a.Readable),c.prototype._read=function(){},c.prototype._onXHRProgress=function(){var e=this,t=e._xhr,n=null;switch(e._mode){case"text:vbarray":if(t.readyState!==u.DONE)break;try{n=new r.VBArray(t.responseBody).toArray()}catch(i){}if(null!==n){e.push(new o(n));break}case"text":try{n=t.responseText}catch(i){e._mode="text:vbarray";break}if(n.length>e._pos){var s=n.substr(e._pos);if("x-user-defined"===e._charset){for(var a=new o(s.length),c=0;ce._pos&&(e.push(new o(new Uint8Array(f.result.slice(e._pos)))),e._pos=f.result.byteLength)},f.onload=function(){e.push(null)},f.readAsArrayBuffer(n)}e._xhr.readyState===u.DONE&&"ms-stream"!==e._mode&&e.push(null)}}).call(this,e("_process"),"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{},e("buffer").Buffer)},{"./capability":29,_process:16,buffer:5,inherits:11,"readable-stream":27}],32:[function(e,t,n){function r(e){if(e&&!u(e))throw new Error("Unknown encoding: "+e)}function o(e){return e.toString(this.encoding)}function i(e){this.charReceived=e.length%2,this.charLength=this.charReceived?2:0}function s(e){this.charReceived=e.length%3,this.charLength=this.charReceived?3:0}var a=e("buffer").Buffer,u=a.isEncoding||function(e){switch(e&&e.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!0;default:return!1}},c=n.StringDecoder=function(e){switch(this.encoding=(e||"utf8").toLowerCase().replace(/[-_]/,""),r(e),this.encoding){case"utf8":this.surrogateSize=3;break;case"ucs2":case"utf16le":this.surrogateSize=2,this.detectIncompleteChar=i;break;case"base64":this.surrogateSize=3,this.detectIncompleteChar=s;break;default:return void(this.write=o)}this.charBuffer=new a(6),this.charReceived=0,this.charLength=0};c.prototype.write=function(e){for(var t="";this.charLength;){var n=e.length>=this.charLength-this.charReceived?this.charLength-this.charReceived:e.length;if(e.copy(this.charBuffer,this.charReceived,0,n),this.charReceived+=n,this.charReceived=55296&&56319>=r)){if(this.charReceived=this.charLength=0,0===e.length)return t;break}this.charLength+=this.surrogateSize,t=""}this.detectIncompleteChar(e);var o=e.length;this.charLength&&(e.copy(this.charBuffer,0,e.length-this.charReceived,o),o-=this.charReceived),t+=e.toString(this.encoding,0,o);var o=t.length-1,r=t.charCodeAt(o);if(r>=55296&&56319>=r){var i=this.surrogateSize;return this.charLength+=i,this.charReceived+=i,this.charBuffer.copy(this.charBuffer,i,0,i),e.copy(this.charBuffer,0,0,i),t.substring(0,o)}return t},c.prototype.detectIncompleteChar=function(e){for(var t=e.length>=3?3:e.length;t>0;t--){var n=e[e.length-t];if(1==t&&n>>5==6){this.charLength=2;break}if(2>=t&&n>>4==14){this.charLength=3;break}if(3>=t&&n>>3==30){this.charLength=4;break}}this.charReceived=t},c.prototype.end=function(e){var t="";if(e&&e.length&&(t=this.write(e)),this.charReceived){var n=this.charReceived,r=this.charBuffer,o=this.encoding;t+=r.slice(0,n).toString(o)}return t}},{buffer:5}],33:[function(e,t){var n=e("buffer").Buffer;t.exports=function(e){if(e instanceof Uint8Array){if(0===e.byteOffset&&e.byteLength===e.buffer.byteLength)return e.buffer;if("function"==typeof e.buffer.slice)return e.buffer.slice(e.byteOffset,e.byteOffset+e.byteLength)}if(n.isBuffer(e)){for(var t=new Uint8Array(e.length),r=e.length,o=0;r>o;o++)t[o]=e[o];return t.buffer}throw new Error("Argument must be a Buffer")}},{buffer:5}],34:[function(e,t,n){"use strict";function r(){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}function o(e,t,n){if(e&&c.isObject(e)&&e instanceof r)return e;var o=new r;return o.parse(e,t,n),o}function i(e){return c.isString(e)&&(e=o(e)),e instanceof r?e.format():r.prototype.format.call(e)}function s(e,t){return o(e,!1,!0).resolve(t)}function a(e,t){return e?o(e,!1,!0).resolveObject(t):t}var u=e("punycode"),c=e("./util");n.parse=o,n.resolve=s,n.resolveObject=a,n.format=i,n.Url=r;var f=/^([a-z0-9.+-]+:)/i,d=/:[0-9]*$/,h=/^(\/\/?(?!\/)[^\?\s]*)(\?[^\s]*)?$/,l=["<",">",'"',"`"," ","\r","\n"," "],p=["{","}","|","\\","^","`"].concat(l),m=["'"].concat(p),g=["%","/","?",";","#"].concat(m),y=["/","?","#"],_=255,v=/^[+a-z0-9A-Z_-]{0,63}$/,b=/^([+a-z0-9A-Z_-]{0,63})(.*)$/,w={javascript:!0,"javascript:":!0},E={javascript:!0,"javascript:":!0},k={http:!0,https:!0,ftp:!0,gopher:!0,file:!0,"http:":!0,"https:":!0,"ftp:":!0,"gopher:":!0,"file:":!0},x=e("querystring");r.prototype.parse=function(e,t,n){if(!c.isString(e))throw new TypeError("Parameter 'url' must be a string, not "+typeof e);var r=e.indexOf("?"),o=-1!==r&&rI)&&(B=I)}var T,C;C=-1===B?a.lastIndexOf("@"):a.lastIndexOf("@",B),-1!==C&&(T=a.slice(0,C),a=a.slice(C+1),this.auth=decodeURIComponent(T)),B=-1;for(var A=0;AI)&&(B=I)}-1===B&&(B=a.length),this.host=a.slice(0,B),a=a.slice(B),this.parseHost(),this.hostname=this.hostname||"";var L="["===this.hostname[0]&&"]"===this.hostname[this.hostname.length-1];if(!L)for(var R=this.hostname.split(/\./),A=0,U=R.length;U>A;A++){var P=R[A];if(P&&!P.match(v)){for(var O="",M=0,j=P.length;j>M;M++)O+=P.charCodeAt(M)>127?"x":P[M];if(!O.match(v)){var H=R.slice(0,A),D=R.slice(A+1),q=P.match(b);q&&(H.push(q[1]),D.unshift(q[2])),D.length&&(a="/"+D.join(".")+a),this.hostname=H.join(".");break}}}this.hostname=this.hostname.length>_?"":this.hostname.toLowerCase(),L||(this.hostname=u.toASCII(this.hostname));var N=this.port?":"+this.port:"",z=this.hostname||"";this.host=z+N,this.href+=this.host,L&&(this.hostname=this.hostname.substr(1,this.hostname.length-2),"/"!==a[0]&&(a="/"+a))}if(!w[p])for(var A=0,U=m.length;U>A;A++){var W=m[A];if(-1!==a.indexOf(W)){var F=encodeURIComponent(W);F===W&&(F=escape(W)),a=a.split(W).join(F)}}var Y=a.indexOf("#");-1!==Y&&(this.hash=a.substr(Y),a=a.slice(0,Y));var V=a.indexOf("?");if(-1!==V?(this.search=a.substr(V),this.query=a.substr(V+1),t&&(this.query=x.parse(this.query)),a=a.slice(0,V)):t&&(this.search="",this.query={}),a&&(this.pathname=a),k[p]&&this.hostname&&!this.pathname&&(this.pathname="/"),this.pathname||this.search){var N=this.pathname||"",G=this.search||"";this.path=N+G}return this.href=this.format(),this},r.prototype.format=function(){var e=this.auth||"";e&&(e=encodeURIComponent(e),e=e.replace(/%3A/i,":"),e+="@");var t=this.protocol||"",n=this.pathname||"",r=this.hash||"",o=!1,i="";this.host?o=e+this.host:this.hostname&&(o=e+(-1===this.hostname.indexOf(":")?this.hostname:"["+this.hostname+"]"),this.port&&(o+=":"+this.port)),this.query&&c.isObject(this.query)&&Object.keys(this.query).length&&(i=x.stringify(this.query));var s=this.search||i&&"?"+i||"";return t&&":"!==t.substr(-1)&&(t+=":"),this.slashes||(!t||k[t])&&o!==!1?(o="//"+(o||""),n&&"/"!==n.charAt(0)&&(n="/"+n)):o||(o=""),r&&"#"!==r.charAt(0)&&(r="#"+r),s&&"?"!==s.charAt(0)&&(s="?"+s),n=n.replace(/[?#]/g,function(e){return encodeURIComponent(e)}),s=s.replace("#","%23"),t+o+n+s+r},r.prototype.resolve=function(e){return this.resolveObject(o(e,!1,!0)).format()},r.prototype.resolveObject=function(e){if(c.isString(e)){var t=new r;t.parse(e,!1,!0),e=t}for(var n=new r,o=Object.keys(this),i=0;i0?n.host.split("@"):!1;S&&(n.auth=S.shift(),n.host=n.hostname=S.shift())}return n.search=e.search,n.query=e.query,c.isNull(n.pathname)&&c.isNull(n.search)||(n.path=(n.pathname?n.pathname:"")+(n.search?n.search:"")),n.href=n.format(),n}if(!w.length)return n.pathname=null,n.path=n.search?"/"+n.search:null,n.href=n.format(),n;for(var B=w.slice(-1)[0],A=(n.host||e.host||w.length>1)&&("."===B||".."===B)||""===B,I=0,T=w.length;T>=0;T--)B=w[T],"."===B?w.splice(T,1):".."===B?(w.splice(T,1),I++):I&&(w.splice(T,1),I--);if(!v&&!b)for(;I--;I)w.unshift("..");!v||""===w[0]||w[0]&&"/"===w[0].charAt(0)||w.unshift(""),A&&"/"!==w.join("/").substr(-1)&&w.push("");var C=""===w[0]||w[0]&&"/"===w[0].charAt(0);if(x){n.hostname=n.host=C?"":w.length?w.shift():"";var S=n.host&&n.host.indexOf("@")>0?n.host.split("@"):!1;S&&(n.auth=S.shift(),n.host=n.hostname=S.shift())}return v=v||n.host&&w.length,v&&!C&&w.unshift(""),w.length?n.pathname=w.join("/"):(n.pathname=null,n.path=null),c.isNull(n.pathname)&&c.isNull(n.search)||(n.path=(n.pathname?n.pathname:"")+(n.search?n.search:"")),n.auth=e.auth||n.auth,n.slashes=n.slashes||e.slashes,n.href=n.format(),n},r.prototype.parseHost=function(){var e=this.host,t=d.exec(e);t&&(t=t[0],":"!==t&&(this.port=t.substr(1)),e=e.substr(0,e.length-t.length)),e&&(this.hostname=e)}},{"./util":35,punycode:17,querystring:20}],35:[function(e,t){"use strict";t.exports={isString:function(e){return"string"==typeof e},isObject:function(e){return"object"==typeof e&&null!==e},isNull:function(e){return null===e},isNullOrUndefined:function(e){return null==e}}},{}],36:[function(e,t){(function(e){function n(e,t){function n(){if(!o){if(r("throwDeprecation"))throw new Error(t);r("traceDeprecation")?console.trace(t):console.warn(t),o=!0}return e.apply(this,arguments)}if(r("noDeprecation"))return e;var o=!1;return n}function r(t){try{if(!e.localStorage)return!1}catch(n){return!1}var r=e.localStorage[t];return null==r?!1:"true"===String(r).toLowerCase()}t.exports=n}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],37:[function(e,t){function n(){for(var e={},t=0;tt;){if(o[t]===e)return t;t++}throw new Error('Invalid data: Missing delimiter "'+String.fromCharCode(e)+'" [0x'+e.toString(16)+"]")},n.dictionary=function(){n.position++;for(var e={};101!==n.data[n.position];)e[n.buffer()]=n.next();return n.position++,e},n.list=function(){n.position++;for(var e=[];101!==n.data[n.position];)e.push(n.next());return n.position++,e},n.integer=function(){var e=n.find(101),t=n.data.toString("ascii",n.position+1,e);return n.position+=e+1-n.position,parseInt(t,10)},n.buffer=function(){var e=n.find(58),t=parseInt(n.data.toString("ascii",n.position,e),10),r=++e+t;return n.position=r,n.encoding?n.data.toString(n.encoding,e,r):n.data.slice(e,r)},t.exports=n}).call(this,e("buffer").Buffer)},{buffer:5}],40:[function(e,t){(function(e){function n(t,r,o){var i=[],s=null;return n._encode(i,t),s=e.concat(i),n.bytes=s.length,e.isBuffer(r)?(s.copy(r,o),r):s}n.bytes=-1,n._floatConversionDetected=!1,n._encode=function(t,r){if(e.isBuffer(r))return t.push(new e(r.length+":")),void t.push(r);switch(typeof r){case"string":n.buffer(t,r);break;case"number":n.number(t,r);break;case"object":r.constructor===Array?n.list(t,r):n.dict(t,r);break;case"boolean":n.number(t,r?1:0)}};var r=new e("e"),o=new e("d"),i=new e("l");n.buffer=function(t,n){t.push(new e(e.byteLength(n)+":"+n))},n.number=function(t,r){var o=2147483648,i=r/o<<0,s=r%o<<0,a=i*o+s;t.push(new e("i"+a+"e")),a===r||n._floatConversionDetected||(n._floatConversionDetected=!0,console.warn('WARNING: Possible data corruption detected with value "'+r+'":','Bencoding only defines support for integers, value was converted to "'+a+'"'),console.trace())},n.dict=function(e,t){e.push(o);for(var i,s=0,a=Object.keys(t).sort(),u=a.length;u>s;s++)i=a[s],n.buffer(e,i),n._encode(e,t[i]);e.push(r)},n.list=function(e,t){var o=0,s=t.length;for(e.push(i);s>o;o++)n._encode(e,t[o]);e.push(r)},t.exports=n}).call(this,e("buffer").Buffer)},{buffer:5}],41:[function(e,t){var n=t.exports;n.encode=e("./encode"),n.decode=e("./decode"),n.byteLength=n.encodingLength=function(e){return n.encode(e).length}},{"./decode":39,"./encode":40}],42:[function(e,t){t.exports=function(e,t,n,r,o){var i,s;if(void 0===r)r=0;else if(r=0|r,0>r||r>=e.length)throw new RangeError("invalid lower bound");if(void 0===o)o=e.length-1;else if(o=0|o,r>o||o>=e.length)throw new RangeError("invalid upper bound");for(;o>=r;)if(i=r+(o-r>>1),s=+n(e[i],t,i,e),0>s)r=i+1;else{if(!(s>0))return i;o=i-1}return~r}},{}],43:[function(e,t){(function(e){function n(e,t){return this instanceof n?(0===arguments.length&&(e=0),this.grow=t&&(isFinite(t.grow)&&r(t.grow)||t.grow)||0,("number"==typeof e||void 0===e)&&(e=new o(r(e)),e.fill&&!e._isBuffer&&e.fill(0)),void(this.buffer=e)):new n(e,t)}function r(e){var t=e>>3;return e%8!==0&&t++,t}var o="undefined"!=typeof e?e:"undefined"!=typeof Int8Array?Int8Array:function(e){for(var t=new Array(e),n=0;e>n;n++)t[n]=0};n.prototype.get=function(e){var t=e>>3;return t>e%8)},n.prototype.set=function(e,t){var n=e>>3;t||1===arguments.length?(this.buffer.length>e%8):n>e%8))},n.prototype._grow=function(e){if(this.buffer.length=this._parserSize;){var r=1===this._buffer.length?this._buffer[0]:a.concat(this._buffer);this._bufferSize-=this._parserSize,this._buffer=this._bufferSize?[r.slice(this._parserSize)]:[],this._parser(r.slice(0,this._parserSize))}n(null)},r.prototype._callback=function(e,t,n){e&&(this._clearTimeout(),this.peerChoking||this._finished||this._updateTimeout(),e.callback(t,n))},r.prototype._clearTimeout=function(){this._timeout&&(clearTimeout(this._timeout),this._timeout=null)},r.prototype._updateTimeout=function(){var e=this;e._timeoutMs&&e.requests.length&&!e._timeout&&(e._timeout=setTimeout(function(){e._onTimeout()},e._timeoutMs),e._timeoutUnref&&e._timeout.unref&&e._timeout.unref())},r.prototype._parse=function(e,t){this._parserSize=e,this._parser=t},r.prototype._onMessageLength=function(e){var t=e.readUInt32BE(0);t>0?this._parse(t,this._onMessage):(this._onKeepAlive(),this._parse(4,this._onMessageLength))},r.prototype._onMessage=function(e){switch(this._parse(4,this._onMessageLength),e[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(e.readUInt32BE(1));case 5:return this._onBitField(e.slice(1));case 6:return this._onRequest(e.readUInt32BE(1),e.readUInt32BE(5),e.readUInt32BE(9));case 7:return this._onPiece(e.readUInt32BE(1),e.readUInt32BE(5),e.slice(9));case 8:return this._onCancel(e.readUInt32BE(1),e.readUInt32BE(5),e.readUInt32BE(9));case 9:return this._onPort(e.readUInt16BE(1));case 20:return this._onExtended(e.readUInt8(1),e.slice(2));default:return this._debug("got unknown message"),this.emit("unknownmessage",e)}},r.prototype._parseHandshake=function(){var e=this;e._parse(1,function(t){var n=t.readUInt8(0);e._parse(n+48,function(t){var r=t.slice(0,n);return"BitTorrent protocol"!==r.toString()?(e._debug("Error: wire not speaking BitTorrent protocol (%s)",r.toString()), +void e.end()):(t=t.slice(n),e._onHandshake(t.slice(8,28),t.slice(28,48),{dht:!!(1&t[7]),extended:!!(16&t[5])}),void e._parse(4,e._onMessageLength))})})},r.prototype._onFinish=function(){for(this._finished=!0,this.push(null);this.read(););for(clearInterval(this._keepAliveInterval),this._parse(Number.MAX_VALUE,function(){}),this.peerRequests=[];this.requests.length;)this._callback(this.requests.shift(),new Error("wire was closed"),null)},r.prototype._debug=function(){var e=[].slice.call(arguments);e[0]="["+this._debugId+"] "+e[0],u.apply(null,e)}},{bencode:41,bitfield:43,debug:56,inherits:65,randombytes:90,"readable-stream":98,"safe-buffer":104,speedometer:110,xtend:137}],45:[function(e,t){(function(n){function r(e){function t(e){n.nextTick(function(){a.emit("warning",e)})}var a=this;if(!(a instanceof r))return new r(e);if(s.call(a),e||(e={}),!e.peerId)throw new Error("Option `peerId` is required");if(!e.infoHash)throw new Error("Option `infoHash` is required");if(!e.announce)throw new Error("Option `announce` is required");if(!n.browser&&!e.port)throw new Error("Option `port` is required");a.peerId="string"==typeof e.peerId?e.peerId:e.peerId.toString("hex"),a._peerIdBuffer=o.from(a.peerId,"hex"),a._peerIdBinary=a._peerIdBuffer.toString("binary"),a.infoHash="string"==typeof e.infoHash?e.infoHash:e.infoHash.toString("hex"),a._infoHashBuffer=o.from(a.infoHash,"hex"),a._infoHashBinary=a._infoHashBuffer.toString("binary"),a._port=e.port,a.destroyed=!1,a._rtcConfig=e.rtcConfig,a._getAnnounceOpts=e.getAnnounceOpts,a._wrtc=e.wrtc,"function"==typeof a._wrtc&&(a._wrtc=a._wrtc()),i("new client %s",a.infoHash);var u=a._wrtc!==!1&&(!!a._wrtc||d.WEBRTC_SUPPORT),c="string"==typeof e.announce?[e.announce]:null==e.announce?[]:e.announce;c=c.map(function(e){return e=e.toString(),"/"===e[e.length-1]&&(e=e.substring(0,e.length-1)),e}),c=h(c),a._trackers=c.map(function(e){var n=l.parse(e).protocol;return"http:"!==n&&"https:"!==n||"function"!=typeof m?"udp:"===n&&"function"==typeof g?new g(a,e):"ws:"!==n&&"wss:"!==n||!u?(t(new Error("Unsupported tracker protocol: "+e)),null):"ws:"===n&&"undefined"!=typeof window&&"https:"===window.location.protocol?(t(new Error("Unsupported tracker protocol: "+e)),null):new y(a,e):new m(a,e)}).filter(Boolean)}t.exports=r;var o=e("safe-buffer").Buffer,i=e("debug")("bittorrent-tracker"),s=e("events").EventEmitter,a=e("xtend"),u=e("inherits"),c=e("once"),f=e("run-parallel"),d=e("simple-peer"),h=e("uniq"),l=e("url"),p=e("./lib/common"),m=e("./lib/client/http-tracker"),g=e("./lib/client/udp-tracker"),y=e("./lib/client/websocket-tracker");u(r,s),r.scrape=function(e,t){if(t=c(t),!e.infoHash)throw new Error("Option `infoHash` is required");if(!e.announce)throw new Error("Option `announce` is required");var n=a(e,{infoHash:Array.isArray(e.infoHash)?e.infoHash[0]:e.infoHash,peerId:o.from("01234567890123456789"),port:6881}),i=new r(n);i.once("error",t),i.once("warning",t);var s=Array.isArray(e.infoHash)?e.infoHash.length:1,u={};return i.on("scrape",function(e){if(s-=1,u[e.infoHash]=e,0===s){i.destroy();var n=Object.keys(u);1===n.length?t(null,u[n[0]]):t(null,u)}}),e.infoHash=Array.isArray(e.infoHash)?e.infoHash.map(function(e){return o.from(e,"hex")}):o.from(e.infoHash,"hex"),i.scrape({infoHash:e.infoHash}),i},r.prototype.start=function(e){var t=this;i("send `start`"),e=t._defaultAnnounceOpts(e),e.event="started",t._announce(e),t._trackers.forEach(function(e){e.setInterval()})},r.prototype.stop=function(e){var t=this;i("send `stop`"),e=t._defaultAnnounceOpts(e),e.event="stopped",t._announce(e)},r.prototype.complete=function(e){var t=this;i("send `complete`"),e||(e={}),e=t._defaultAnnounceOpts(e),e.event="completed",t._announce(e)},r.prototype.update=function(e){var t=this;i("send `update`"),e=t._defaultAnnounceOpts(e),e.event&&delete e.event,t._announce(e)},r.prototype._announce=function(e){var t=this;t._trackers.forEach(function(t){t.announce(e)})},r.prototype.scrape=function(e){var t=this;i("send `scrape`"),e||(e={}),t._trackers.forEach(function(t){t.scrape(e)})},r.prototype.setInterval=function(e){var t=this;i("setInterval %d",e),t._trackers.forEach(function(t){t.setInterval(e)})},r.prototype.destroy=function(e){var t=this;if(!t.destroyed){t.destroyed=!0,i("destroy");var n=t._trackers.map(function(e){return function(t){e.destroy(t)}});f(n,e),t._trackers=[],t._getAnnounceOpts=null}},r.prototype._defaultAnnounceOpts=function(e){var t=this;return e||(e={}),null==e.numwant&&(e.numwant=p.DEFAULT_ANNOUNCE_PEERS),null==e.uploaded&&(e.uploaded=0),null==e.downloaded&&(e.downloaded=0),t._getAnnounceOpts&&(e=a(e,t._getAnnounceOpts())),e}}).call(this,e("_process"))},{"./lib/client/http-tracker":3,"./lib/client/udp-tracker":3,"./lib/client/websocket-tracker":47,"./lib/common":48,_process:16,debug:56,events:8,inherits:65,once:83,"run-parallel":102,"safe-buffer":104,"simple-peer":107,uniq:122,url:34,xtend:137}],46:[function(e,t){function n(e,t){var n=this;r.call(n),n.client=e,n.announceUrl=t,n.interval=null,n.destroyed=!1}t.exports=n;var r=e("events").EventEmitter,o=e("inherits");o(n,r),n.prototype.setInterval=function(e){var t=this;null==e&&(e=t.DEFAULT_ANNOUNCE_INTERVAL),clearInterval(t.interval),e&&(t.interval=setInterval(function(){t.announce(t.client._defaultAnnounceOpts())},e),t.interval.unref&&t.interval.unref())}},{events:8,inherits:65}],47:[function(e,t){function n(e,t){var n=this;d.call(n,e,t),o("new websocket tracker %s",t),n.peers={},n.socket=null,n.reconnecting=!1,n.retries=0,n.reconnectTimer=null,n._openSocket()}function r(){}t.exports=n;var o=e("debug")("bittorrent-tracker:websocket-tracker"),i=e("xtend"),s=e("inherits"),a=e("simple-peer"),u=e("randombytes"),c=e("simple-websocket"),f=e("../common"),d=e("./tracker"),h={},l=15e3,p=18e5,m=3e4,g=5e4;s(n,d),n.prototype.DEFAULT_ANNOUNCE_INTERVAL=3e4,n.prototype.announce=function(e){var t=this;if(!t.destroyed&&!t.reconnecting){if(!t.socket.connected)return void t.socket.once("connect",function(){t.announce(e)});var n=i(e,{action:"announce",info_hash:t.client._infoHashBinary,peer_id:t.client._peerIdBinary});if(t._trackerId&&(n.trackerid=t._trackerId),"stopped"===e.event)t._send(n);else{var r=Math.min(e.numwant,10);t._generateOffers(r,function(e){n.numwant=r,n.offers=e,t._send(n)})}}},n.prototype.scrape=function(e){var t=this;if(!t.destroyed&&!t.reconnecting){if(!t.socket.connected)return void t.socket.once("connect",function(){t.scrape(e)});var n=Array.isArray(e.infoHash)&&e.infoHash.length>0?e.infoHash.map(function(e){return e.toString("binary")}):e.infoHash&&e.infoHash.toString("binary")||t.client._infoHashBinary,r={action:"scrape",info_hash:n};t._send(r)}},n.prototype.destroy=function(e){var t=this;if(e||(e=r),t.destroyed)return e(null);t.destroyed=!0,clearInterval(t.interval),clearTimeout(t.reconnectTimer),t.socket&&(t.socket.removeListener("connect",t._onSocketConnectBound),t.socket.removeListener("data",t._onSocketDataBound),t.socket.removeListener("close",t._onSocketCloseBound),t.socket.removeListener("error",t._onSocketErrorBound)),t._onSocketConnectBound=null,t._onSocketErrorBound=null,t._onSocketDataBound=null,t._onSocketCloseBound=null;for(var n in t.peers){var o=t.peers[n];clearTimeout(o.trackerTimeout),o.destroy()}if(t.peers=null,h[t.announceUrl]&&(h[t.announceUrl].consumers-=1),0===h[t.announceUrl].consumers){delete h[t.announceUrl];try{t.socket.on("error",r),t.socket.destroy(e)}catch(i){e(null)}}else e(null);t.socket=null},n.prototype._openSocket=function(){var e=this;e.destroyed=!1,e.peers||(e.peers={}),e._onSocketConnectBound=function(){e._onSocketConnect()},e._onSocketErrorBound=function(t){e._onSocketError(t)},e._onSocketDataBound=function(t){e._onSocketData(t)},e._onSocketCloseBound=function(){e._onSocketClose()},e.socket=h[e.announceUrl],e.socket?h[e.announceUrl].consumers+=1:(e.socket=h[e.announceUrl]=new c(e.announceUrl),e.socket.consumers=1,e.socket.once("connect",e._onSocketConnectBound)),e.socket.on("data",e._onSocketDataBound),e.socket.once("close",e._onSocketCloseBound),e.socket.once("error",e._onSocketErrorBound)},n.prototype._onSocketConnect=function(){var e=this;e.destroyed||e.reconnecting&&(e.reconnecting=!1,e.retries=0,e.announce(e.client._defaultAnnounceOpts()))},n.prototype._onSocketData=function(e){var t=this;if(!t.destroyed){try{e=JSON.parse(e)}catch(n){return void t.client.emit("warning",new Error("Invalid tracker response"))}"announce"===e.action?t._onAnnounceResponse(e):"scrape"===e.action?t._onScrapeResponse(e):t._onSocketError(new Error("invalid action in WS response: "+e.action))}},n.prototype._onAnnounceResponse=function(e){var t=this;if(e.info_hash!==t.client._infoHashBinary)return void o("ignoring websocket data from %s for %s (looking for %s: reused socket)",t.announceUrl,f.binaryToHex(e.info_hash),t.client.infoHash);if(!e.peer_id||e.peer_id!==t.client._peerIdBinary){o("received %s from %s for %s",JSON.stringify(e),t.announceUrl,t.client.infoHash);var n=e["failure reason"];if(n)return t.client.emit("warning",new Error(n));var r=e["warning message"];r&&t.client.emit("warning",new Error(r));var i=e.interval||e["min interval"];i&&t.setInterval(1e3*i);var s=e["tracker id"];s&&(t._trackerId=s),null!=e.complete&&t.client.emit("update",{announce:t.announceUrl,complete:e.complete,incomplete:e.incomplete});var u;if(e.offer&&e.peer_id&&(o("creating peer (from remote offer)"),u=new a({trickle:!1,config:t.client._rtcConfig,wrtc:t.client._wrtc}),u.id=f.binaryToHex(e.peer_id),u.once("signal",function(n){var r={action:"announce",info_hash:t.client._infoHashBinary,peer_id:t.client._peerIdBinary,to_peer_id:e.peer_id,answer:n,offer_id:e.offer_id};t._trackerId&&(r.trackerid=t._trackerId),t._send(r)}),u.signal(e.offer),t.client.emit("peer",u)),e.answer&&e.peer_id){var c=f.binaryToHex(e.offer_id);u=t.peers[c],u?(u.id=f.binaryToHex(e.peer_id),u.signal(e.answer),t.client.emit("peer",u),clearTimeout(u.trackerTimeout),u.trackerTimeout=null,delete t.peers[c]):o("got unexpected answer: "+JSON.stringify(e.answer))}}},n.prototype._onScrapeResponse=function(e){var t=this;e=e.files||{};var n=Object.keys(e);return 0===n.length?void t.client.emit("warning",new Error("invalid scrape response")):void n.forEach(function(n){var r=e[n];t.client.emit("scrape",{announce:t.announceUrl,infoHash:f.binaryToHex(n),complete:r.complete,incomplete:r.incomplete,downloaded:r.downloaded})})},n.prototype._onSocketClose=function(){var e=this;e.destroyed||(e.destroy(),e._startReconnectTimer())},n.prototype._onSocketError=function(e){var t=this;t.destroyed||(t.destroy(),t.client.emit("warning",e),t._startReconnectTimer())},n.prototype._startReconnectTimer=function(){var e=this,t=Math.floor(Math.random()*m)+Math.min(Math.pow(2,e.retries)*l,p);e.reconnecting=!0,clearTimeout(e.reconnectTimer),e.reconnectTimer=setTimeout(function(){e.retries++,e._openSocket()},t),e.reconnectTimer.unref&&e.reconnectTimer.unref(),o("reconnecting socket in %s ms",t)},n.prototype._send=function(e){var t=this;if(!t.destroyed){var n=JSON.stringify(e);o("send %s",n),t.socket.send(n)}},n.prototype._generateOffers=function(e,t){function n(){var e=u(20).toString("hex");o("creating peer (from _generateOffers)");var t=i.peers[e]=new a({initiator:!0,trickle:!1,config:i.client._rtcConfig,wrtc:i.client._wrtc});t.once("signal",function(t){s.push({offer:t,offer_id:f.hexToBinary(e)}),r()}),t.trackerTimeout=setTimeout(function(){o("tracker timeout: destroying peer"),t.trackerTimeout=null,delete i.peers[e],t.destroy()},g),t.trackerTimeout.unref&&t.trackerTimeout.unref()}function r(){s.length===e&&(o("generated %s offers",e),t(s))}var i=this,s=[];o("generating %s offers",e);for(var c=0;e>c;++c)n();r()}},{"../common":48,"./tracker":46,debug:56,inherits:65,randombytes:90,"simple-peer":107,"simple-websocket":109,xtend:137}],48:[function(e,t,n){var r=e("safe-buffer").Buffer,o=e("xtend/mutable");n.DEFAULT_ANNOUNCE_PEERS=50,n.MAX_ANNOUNCE_PEERS=82,n.binaryToHex=function(e){return"string"!=typeof e&&(e=String(e)),r.from(e,"binary").toString("hex")},n.hexToBinary=function(e){return"string"!=typeof e&&(e=String(e)),r.from(e,"hex").toString("binary")};var i=e("./common-node");o(n,i)},{"./common-node":3,"safe-buffer":104,"xtend/mutable":138}],49:[function(e,t){(function(e){t.exports=function(t,n){function r(t){o.removeEventListener("loadend",r,!1),t.error?n(t.error):n(null,new e(o.result))}if("undefined"==typeof Blob||!(t instanceof Blob))throw new Error("first argument must be a Blob");if("function"!=typeof n)throw new Error("second argument must be a function");var o=new FileReader;o.addEventListener("loadend",r,!1),o.readAsArrayBuffer(t)}}).call(this,e("buffer").Buffer)},{buffer:5}],50:[function(e,t){(function(n){function r(e,t){return this instanceof r?(i.call(this),t||(t={}),"object"==typeof e&&(t=e,e=t.size),this.size=e||512,this._zeroPadding=t.nopad?!1:s(t.zeroPadding,!0),this._buffered=[],void(this._bufferedBytes=0)):new r(e,t)}var o=e("inherits"),i=e("readable-stream").Transform,s=e("defined");t.exports=r,o(r,i),r.prototype._transform=function(e,t,r){for(this._bufferedBytes+=e.length,this._buffered.push(e);this._bufferedBytes>=this.size;){var o=n.concat(this._buffered);this._bufferedBytes-=this.size,this.push(o.slice(0,this.size)),this._buffered=[o.slice(this.size,o.length)]}r()},r.prototype._flush=function(){if(this._bufferedBytes&&this._zeroPadding){var e=new n(this.size-this._bufferedBytes);e.fill(0),this._buffered.push(e),this.push(n.concat(this._buffered)),this._buffered=null}else this._bufferedBytes&&(this.push(n.concat(this._buffered)),this._buffered=null);this.push(null)}}).call(this,e("buffer").Buffer)},{buffer:5,defined:58,inherits:65,"readable-stream":98}],51:[function(e,t,n){arguments[4][4][0].apply(n,arguments)},{buffer:5,dup:4}],52:[function(e,t){function n(e,t,o){function s(t){a.destroyed||(e.put(u,t),u+=1)}var a=this;if(!(a instanceof n))return new n(e,t,o);if(i.Writable.call(a,o),o||(o={}),!e||!e.put||!e.get)throw new Error("First argument must be an abstract-chunk-store compliant store");if(t=Number(t),!t)throw new Error("Second argument must be a chunk length");a._blockstream=new r(t,{zeroPadding:!1}),a._blockstream.on("data",s).on("error",function(e){a.destroy(e)});var u=0;a.on("finish",function(){this._blockstream.end()})}t.exports=n;var r=e("block-stream2"),o=e("inherits"),i=e("readable-stream");o(n,i.Writable),n.prototype._write=function(e,t,n){this._blockstream.write(e,t,n)},n.prototype.destroy=function(e){this.destroyed||(this.destroyed=!0,e&&this.emit("error",e),this.emit("close"))}},{"block-stream2":50,inherits:65,"readable-stream":98}],53:[function(e,t){t.exports=function(e,t){var n=1/0,r=0,o=null;t.sort(function(e,t){return e-t});for(var i=0,s=t.length;s>i&&(r=Math.abs(e-t[i]),!(r>=n));i++)n=r,o=t[i];return o}},{}],54:[function(e,t,n){(function(e){function t(e){return Array.isArray?Array.isArray(e):"[object Array]"===g(e)}function r(e){return"boolean"==typeof e}function o(e){return null===e}function i(e){return null==e}function s(e){return"number"==typeof e}function a(e){return"string"==typeof e}function u(e){return"symbol"==typeof e}function c(e){return void 0===e}function f(e){return"[object RegExp]"===g(e)}function d(e){return"object"==typeof e&&null!==e}function h(e){return"[object Date]"===g(e)}function l(e){return"[object Error]"===g(e)||e instanceof Error}function p(e){return"function"==typeof e}function m(e){return null===e||"boolean"==typeof e||"number"==typeof e||"string"==typeof e||"symbol"==typeof e||"undefined"==typeof e}function g(e){return Object.prototype.toString.call(e)}n.isArray=t,n.isBoolean=r,n.isNull=o,n.isNullOrUndefined=i,n.isNumber=s,n.isString=a,n.isSymbol=u,n.isUndefined=c,n.isRegExp=f,n.isObject=d,n.isDate=h,n.isError=l,n.isFunction=p,n.isPrimitive=m,n.isBuffer=e.isBuffer}).call(this,{isBuffer:e("../../../../../.nvm/versions/node/v5.5.0/lib/node_modules/browserify/node_modules/is-buffer/index.js")})},{"../../../../../.nvm/versions/node/v5.5.0/lib/node_modules/browserify/node_modules/is-buffer/index.js":12}],55:[function(e,t){(function(n,r,o){function i(e,t,n){return"function"==typeof t?i(e,null,t):(t=t?B(t):{},void a(e,t,function(e,r,o){return e?n(e):(t.singleFileTorrent=o,void l(r,t,n))}))}function s(e,t,n){return"function"==typeof t?s(e,null,t):(t=t?B(t):{},void a(e,t,n))}function a(e,t,r){function i(){P(e.map(function(e){return function(t){var n={};if(m(e))n.getStream=_(e),n.length=e.size;else if(o.isBuffer(e))n.getStream=v(e),n.length=e.length;else{if(!y(e)){if("string"==typeof e){if("function"!=typeof T.stat)throw new Error("filesystem paths do not work in the browser");var r=a>1||c;return void u(e,r,t)}throw new Error("invalid input type")}n.getStream=w(e,n),n.length=0}n.path=e.path,t(null,n)}}),function(e,t){return e?r(e):(t=I(t),void r(null,t,c))})}if(Array.isArray(e)&&0===e.length)throw new Error("invalid input type");g(e)&&(e=Array.prototype.slice.call(e)),Array.isArray(e)||(e=[e]),e=e.map(function(e){return m(e)&&"string"==typeof e.path&&"function"==typeof T.stat?e.path:e}),1!==e.length||"string"==typeof e[0]||e[0].name||(e[0].name=t.name);var s=null;e.forEach(function(t,n){if("string"!=typeof t){var r=t.fullPath||t.name;r||(r="Unknown File "+(n+1),t.unknownName=!0),t.path=r.split("/"),t.path[0]||t.path.shift(),t.path.length<2?s=null:0===n&&e.length>1?s=t.path[0]:t.path[0]!==s&&(s=null)}}),e=e.filter(function(e){if("string"==typeof e)return!0;var t=e.path[e.path.length-1];return d(t)&&L.not(t)}),s&&e.forEach(function(e){var t=(o.isBuffer(e)||y(e))&&!e.path;"string"==typeof e||t||e.path.shift()}),!t.name&&s&&(t.name=s),t.name||e.some(function(e){return"string"==typeof e?(t.name=S.basename(e),!0):e.unknownName?void 0:(t.name=e.path[e.path.length-1],!0)}),t.name||(t.name="Unnamed Torrent "+Date.now());var a=e.reduce(function(e,t){return e+Number("string"==typeof t)},0),c=1===e.length;if(1===e.length&&"string"==typeof e[0]){if("function"!=typeof T.stat)throw new Error("filesystem paths do not work in the browser");C(e[0],function(e,t){return e?r(e):(c=t,void i())})}else n.nextTick(function(){i()})}function u(e,t,n){f(e,c,function(r,o){return r?n(r):(o=Array.isArray(o)?I(o):[o],e=S.normalize(e),t&&(e=e.slice(0,e.lastIndexOf(S.sep)+1)),e[e.length-1]!==S.sep&&(e+=S.sep),o.forEach(function(t){t.getStream=b(t.path),t.path=t.path.replace(e,"").split(S.sep)}),void n(null,o))})}function c(e,t){t=U(t),T.stat(e,function(n,r){if(n)return t(n);var o={length:r.size,path:e};t(null,o)})}function f(e,t,n){T.readdir(e,function(r,o){r&&"ENOTDIR"===r.code?t(e,n):r?n(r):P(o.filter(d).filter(L.not).map(function(n){return function(r){f(S.join(e,n),t,r)}}),n)})}function d(e){return"."!==e[0]}function h(e,t,n){function r(e){f+=e.length;var t=l;O(e,function(e){c[t]=e,h-=1,u()}),h+=1,l+=1}function i(){p=!0,u()}function s(e){a(),n(e)}function a(){m.removeListener("error",s),g.removeListener("data",r),g.removeListener("end",i),g.removeListener("error",s)}function u(){p&&0===h&&(a(),n(null,new o(c.join(""),"hex"),f))}n=U(n);var c=[],f=0,d=e.map(function(e){return e.getStream}),h=0,l=0,p=!1,m=new R(d),g=new k(t,{zeroPadding:!1});m.on("error",s),m.pipe(g).on("data",r).on("end",i).on("error",s)}function l(e,n,o){var i=n.announceList;i||("string"==typeof n.announce?i=[[n.announce]]:Array.isArray(n.announce)&&(i=n.announce.map(function(e){return[e]}))),i||(i=[]),r.WEBTORRENT_ANNOUNCE&&("string"==typeof r.WEBTORRENT_ANNOUNCE?i.push([[r.WEBTORRENT_ANNOUNCE]]):Array.isArray(r.WEBTORRENT_ANNOUNCE)&&(i=i.concat(r.WEBTORRENT_ANNOUNCE.map(function(e){return[e]})))),void 0===n.announce&&void 0===n.announceList&&(i=i.concat(t.exports.announceList)),"string"==typeof n.urlList&&(n.urlList=[n.urlList]);var s={info:{name:n.name},"creation date":Math.ceil((Number(n.creationDate)||Date.now())/1e3),encoding:"UTF-8"};0!==i.length&&(s.announce=i[0][0],s["announce-list"]=i),void 0!==n.comment&&(s.comment=n.comment),void 0!==n.createdBy&&(s["created by"]=n.createdBy),void 0!==n["private"]&&(s.info["private"]=Number(n["private"])),void 0!==n.sslCert&&(s.info["ssl-cert"]=n.sslCert),void 0!==n.urlList&&(s["url-list"]=n.urlList);var a=n.pieceLength||x(e.reduce(p,0));s.info["piece length"]=a,h(e,a,function(t,r,i){return t?o(t):(s.info.pieces=r,e.forEach(function(e){delete e.getStream}),n.singleFileTorrent?s.info.length=i:s.info.files=e,void o(null,E.encode(s)))})}function p(e,t){return e+t.length}function m(e){return"undefined"!=typeof Blob&&e instanceof Blob}function g(e){return"undefined"!=typeof FileList&&e instanceof FileList}function y(e){return"object"==typeof e&&null!=e&&"function"==typeof e.pipe}function _(e){return function(){return new A(e)}}function v(e){return function(){var t=new M.PassThrough;return t.end(e),t}}function b(e){return function(){return T.createReadStream(e)}}function w(e,t){return function(){var n=new M.Transform;return n._transform=function(e,n,r){t.length+=e.length,this.push(e),r()},e.pipe(n),n}}t.exports=i,t.exports.parseInput=s,t.exports.announceList=[["udp://tracker.openbittorrent.com:80"],["udp://tracker.internetwarriors.net:1337"],["udp://tracker.leechers-paradise.org:6969"],["udp://tracker.coppersurfer.tk:6969"],["udp://exodus.desync.com:6969"],["wss://tracker.btorrent.xyz"],["wss://tracker.openwebtorrent.com"],["wss://tracker.fastcast.nz"]];var E=e("bencode"),k=e("block-stream2"),x=e("piece-length"),S=e("path"),B=e("xtend"),A=e("filestream/read"),I=e("flatten"),T=e("fs"),C=e("is-file"),L=e("junk"),R=e("multistream"),U=e("once"),P=e("run-parallel"),O=e("simple-sha1"),M=e("readable-stream")}).call(this,e("_process"),"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{},e("buffer").Buffer)},{_process:16,bencode:41,"block-stream2":50,buffer:5,"filestream/read":61,flatten:62,fs:1,"is-file":67,junk:70,multistream:81,once:83,path:14,"piece-length":86,"readable-stream":98,"run-parallel":102,"simple-sha1":108,xtend:137}],56:[function(e,t,n){function r(){return"WebkitAppearance"in document.documentElement.style||window.console&&(console.firebug||console.exception&&console.table)||navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)&&parseInt(RegExp.$1,10)>=31}function o(){var e=arguments,t=this.useColors;if(e[0]=(t?"%c":"")+this.namespace+(t?" %c":" ")+e[0]+(t?"%c ":" ")+"+"+n.humanize(this.diff),!t)return e;var r="color: "+this.color;e=[e[0],r,"color: inherit"].concat(Array.prototype.slice.call(e,1));var o=0,i=0;return e[0].replace(/%[a-z%]/g,function(e){"%%"!==e&&(o++,"%c"===e&&(i=o))}),e.splice(i,0,r),e}function i(){return"object"==typeof console&&console.log&&Function.prototype.apply.call(console.log,console,arguments)}function s(e){try{null==e?n.storage.removeItem("debug"):n.storage.debug=e}catch(t){}}function a(){var e;try{e=n.storage.debug}catch(t){}return e}function u(){try{return window.localStorage}catch(e){}}n=t.exports=e("./debug"),n.log=i,n.formatArgs=o,n.save=s,n.load=a,n.useColors=r,n.storage="undefined"!=typeof chrome&&"undefined"!=typeof chrome.storage?chrome.storage.local:u(),n.colors=["lightseagreen","forestgreen","goldenrod","dodgerblue","darkorchid","crimson"],n.formatters.j=function(e){return JSON.stringify(e)},n.enable(a())},{"./debug":57}],57:[function(e,t,n){function r(){return n.colors[f++%n.colors.length]}function o(e){function t(){}function o(){var e=o,t=+new Date,i=t-(c||t);e.diff=i,e.prev=c,e.curr=t,c=t,null==e.useColors&&(e.useColors=n.useColors()),null==e.color&&e.useColors&&(e.color=r());var s=Array.prototype.slice.call(arguments);s[0]=n.coerce(s[0]),"string"!=typeof s[0]&&(s=["%o"].concat(s));var a=0;s[0]=s[0].replace(/%([a-z%])/g,function(t,r){if("%%"===t)return t;a++;var o=n.formatters[r];if("function"==typeof o){var i=s[a];t=o.call(e,i),s.splice(a,1),a--}return t}),"function"==typeof n.formatArgs&&(s=n.formatArgs.apply(e,s));var u=o.log||n.log||console.log.bind(console);u.apply(e,s)}t.enabled=!1,o.enabled=!0;var i=n.enabled(e)?o:t;return i.namespace=e,i}function i(e){n.save(e);for(var t=(e||"").split(/[\s,]+/),r=t.length,o=0;r>o;o++)t[o]&&(e=t[o].replace(/\*/g,".*?"),"-"===e[0]?n.skips.push(new RegExp("^"+e.substr(1)+"$")):n.names.push(new RegExp("^"+e+"$")))}function s(){n.enable("")}function a(e){var t,r;for(t=0,r=n.skips.length;r>t;t++)if(n.skips[t].test(e))return!1;for(t=0,r=n.names.length;r>t;t++)if(n.names[t].test(e))return!0;return!1}function u(e){return e instanceof Error?e.stack||e.message:e}n=t.exports=o,n.coerce=u,n.disable=s,n.enable=i,n.enabled=a,n.humanize=e("ms"),n.names=[],n.skips=[],n.formatters={};var c,f=0},{ms:80}],58:[function(e,t){t.exports=function(){for(var e=0;ethis._size&&(r=this._size),n===this._size?(this.destroy(),void this.push(null)):(t.onload=function(){e._offset=r,e.push(i(t.result))},t.onerror=function(){e.emit("error",t.error)},void t.readAsArrayBuffer(this._file.slice(n,r)))},n.prototype.destroy=function(){if(this._file=null,this.reader){this.reader.onload=null,this.reader.onerror=null;try{this.reader.abort()}catch(e){}}this.reader=null}},{inherits:65,"readable-stream":98,"typedarray-to-buffer":120}],62:[function(e,t){t.exports=function(e,t){function n(e,r){return e.reduce(function(e,o){return e.concat(Array.isArray(o)&&t>r?n(o,r+1):o)},[])}return t="number"==typeof t?t:1/0,t?n(e,1):Array.isArray(e)?e.map(function(e){return e}):e}},{}],63:[function(e,t){t.exports=function(){if("undefined"==typeof window)return null;var e={RTCPeerConnection:window.RTCPeerConnection||window.mozRTCPeerConnection||window.webkitRTCPeerConnection,RTCSessionDescription:window.RTCSessionDescription||window.mozRTCSessionDescription||window.webkitRTCSessionDescription,RTCIceCandidate:window.RTCIceCandidate||window.mozRTCIceCandidate||window.webkitRTCIceCandidate};return e.RTCPeerConnection?e:null}},{}],64:[function(e,t){(function(e){function n(e){if(!(this instanceof n))return new n(e);if(this.store=e,this.chunkLength=e.chunkLength,!this.store||!this.store.get||!this.store.put)throw new Error("First argument must be abstract-chunk-store compliant");this.mem=[]}function r(t,n,r){e.nextTick(function(){t&&t(n,r)})}t.exports=n,n.prototype.put=function(e,t,n){var r=this;r.mem[e]=t,r.store.put(e,t,function(t){r.mem[e]=null,n&&n(t)})},n.prototype.get=function(e,t,n){if("function"==typeof t)return this.get(e,null,t);var o=t&&t.offset||0,i=t&&t.length&&o+t.length,s=this.mem[e];return s?r(n,null,t?s.slice(o,i):s):void this.store.get(e,t,n)},n.prototype.close=function(e){this.store.close(e)},n.prototype.destroy=function(e){this.store.destroy(e)}}).call(this,e("_process"))},{_process:16}],65:[function(e,t,n){arguments[4][11][0].apply(n,arguments)},{dup:11}],66:[function(e,t){var n=127;t.exports=function(e){for(var t=0,r=e.length;r>t;++t)if(e.charCodeAt(t)>n)return!1;return!0}},{}],67:[function(e,t){"use strict";function n(e){return r.existsSync(e)&&r.statSync(e).isFile()}var r=e("fs");t.exports=function(e,t){return t?void r.stat(e,function(e,n){return e?t(e):t(null,n.isFile())}):n(e)},t.exports.sync=n},{fs:1}],68:[function(e,t){function n(e){return r(e)||o(e)}function r(e){return e instanceof Int8Array||e instanceof Int16Array||e instanceof Int32Array||e instanceof Uint8Array||e instanceof Uint8ClampedArray||e instanceof Uint16Array||e instanceof Uint32Array||e instanceof Float32Array||e instanceof Float64Array}function o(e){return s[i.call(e)]}t.exports=n,n.strict=r,n.loose=o;var i=Object.prototype.toString,s={"[object Int8Array]":!0,"[object Int16Array]":!0,"[object Int32Array]":!0,"[object Uint8Array]":!0,"[object Uint8ClampedArray]":!0,"[object Uint16Array]":!0,"[object Uint32Array]":!0,"[object Float32Array]":!0,"[object Float64Array]":!0}},{}],69:[function(e,t,n){arguments[4][13][0].apply(n,arguments)},{dup:13}],70:[function(e,t,n){"use strict";n.re=/^npm-debug\.log$|^\..*\.swp$|^\.DS_Store$|^\.AppleDouble$|^\.LSOverride$|^Icon\r$|^\._.*|^\.Spotlight-V100$|\.Trashes|^__MACOSX$|~$|^Thumbs\.db$|^ehthumbs\.db$|^Desktop\.ini$/,n.is=function(e){return n.re.test(e)},n.not=n.isnt=function(e){return!n.is(e)}},{}],71:[function(e,t){(function(n){function r(e){var t={},r=e.split("magnet:?")[1],o=r&&r.length>=0?r.split("&"):[];o.forEach(function(e){var n=e.split("=");if(2===n.length){var r=n[0],o=n[1];if("dn"===r&&(o=decodeURIComponent(o).replace(/\+/g," ")),("tr"===r||"xs"===r||"as"===r||"ws"===r)&&(o=decodeURIComponent(o)),"kt"===r&&(o=decodeURIComponent(o).split("+")),t[r])if(Array.isArray(t[r]))t[r].push(o);else{var i=t[r];t[r]=[i,o]}else t[r]=o}});var s;if(t.xt){var u=Array.isArray(t.xt)?t.xt:[t.xt];u.forEach(function(e){if(s=e.match(/^urn:btih:(.{40})/))t.infoHash=s[1].toLowerCase();else if(s=e.match(/^urn:btih:(.{32})/)){var r=i.decode(s[1]);t.infoHash=new n(r,"binary").toString("hex")}})}return t.infoHash&&(t.infoHashBuffer=new n(t.infoHash,"hex")),t.dn&&(t.name=t.dn),t.kt&&(t.keywords=t.kt),t.announce="string"==typeof t.tr?[t.tr]:Array.isArray(t.tr)?t.tr:[],t.urlList=[],("string"==typeof t.as||Array.isArray(t.as))&&(t.urlList=t.urlList.concat(t.as)),("string"==typeof t.ws||Array.isArray(t.ws))&&(t.urlList=t.urlList.concat(t.ws)),a(t.announce),a(t.urlList),t}function o(e){e=s(e),e.infoHashBuffer&&(e.xt="urn:btih:"+e.infoHashBuffer.toString("hex")),e.infoHash&&(e.xt="urn:btih:"+e.infoHash),e.name&&(e.dn=e.name),e.keywords&&(e.kt=e.keywords),e.announce&&(e.tr=e.announce),e.urlList&&(e.ws=e.urlList,delete e.as);var t="magnet:?";return Object.keys(e).filter(function(e){return 2===e.length}).forEach(function(n,r){var o=Array.isArray(e[n])?e[n]:[e[n]];o.forEach(function(e,o){!(r>0||o>0)||"kt"===n&&0!==o||(t+="&"),"dn"===n&&(e=encodeURIComponent(e).replace(/%20/g,"+")),("tr"===n||"xs"===n||"as"===n||"ws"===n)&&(e=encodeURIComponent(e)),"kt"===n&&(e=encodeURIComponent(e)),t+="kt"===n&&o>0?"+"+e:n+"="+e})}),t}t.exports=r,t.exports.decode=r, +t.exports.encode=o;var i=e("thirty-two"),s=e("xtend"),a=e("uniq")}).call(this,e("buffer").Buffer)},{buffer:5,"thirty-two":115,uniq:122,xtend:137}],72:[function(e,t){function n(e,t){var r=this;if(!(r instanceof n))return new n(e,t);if(!a)throw new Error("web browser lacks MediaSource support");t||(t={}),r._bufferDuration=t.bufferDuration||u,r._elem=e,r._mediaSource=new a,r._streams=[],r.detailedError=null,r._errorHandler=function(){r._elem.removeEventListener("error",r._errorHandler);var e=r._streams.slice();e.forEach(function(e){e.destroy(r._elem.error)})},r._elem.addEventListener("error",r._errorHandler),r._elem.src=window.URL.createObjectURL(r._mediaSource)}function r(e,t){var n=this;if(i.Writable.call(n),n._wrapper=e,n._elem=e._elem,n._mediaSource=e._mediaSource,n._allStreams=e._streams,n._allStreams.push(n),n._bufferDuration=e._bufferDuration,n._sourceBuffer=null,n._openHandler=function(){n._onSourceOpen()},n._flowHandler=function(){n._flow()},"string"==typeof t)n._type=t,"open"===n._mediaSource.readyState?n._createSourceBuffer():n._mediaSource.addEventListener("sourceopen",n._openHandler);else if(null===t._sourceBuffer)t.destroy(),n._type=t._type,n._mediaSource.addEventListener("sourceopen",n._openHandler);else{if(!t._sourceBuffer)throw new Error("The argument to MediaElementWrapper.createWriteStream must be a string or a previous stream returned from that function");t.destroy(),n._type=t._type,n._sourceBuffer=t._sourceBuffer,n._sourceBuffer.addEventListener("updateend",n._flowHandler)}n._elem.addEventListener("timeupdate",n._flowHandler),n.on("error",function(e){n._wrapper.error(e)}),n.on("finish",function(){if(!n.destroyed&&(n._finished=!0,n._allStreams.every(function(e){return e._finished})))try{n._mediaSource.endOfStream()}catch(e){}})}t.exports=n;var o=e("inherits"),i=e("readable-stream"),s=e("to-arraybuffer"),a="undefined"!=typeof window&&window.MediaSource,u=60;n.prototype.createWriteStream=function(e){var t=this;return new r(t,e)},n.prototype.error=function(e){var t=this;t.detailedError||(t.detailedError=e);try{t._mediaSource.endOfStream("decode")}catch(e){}},o(r,i.Writable),r.prototype._onSourceOpen=function(){var e=this;e.destroyed||(e._mediaSource.removeEventListener("sourceopen",e._openHandler),e._createSourceBuffer())},r.prototype.destroy=function(e){var t=this;t.destroyed||(t.destroyed=!0,t._allStreams.splice(t._allStreams.indexOf(t),1),t._mediaSource.removeEventListener("sourceopen",t._openHandler),t._elem.removeEventListener("timeupdate",t._flowHandler),t._sourceBuffer&&(t._sourceBuffer.removeEventListener("updateend",t._flowHandler),"open"===t._mediaSource.readyState&&t._sourceBuffer.abort()),e&&t.emit("error",e),t.emit("close"))},r.prototype._createSourceBuffer=function(){var e=this;if(!e.destroyed)if(a.isTypeSupported(e._type)){if(e._sourceBuffer=e._mediaSource.addSourceBuffer(e._type),e._sourceBuffer.addEventListener("updateend",e._flowHandler),e._cb){var t=e._cb;e._cb=null,t()}}else e.destroy(new Error("The provided type is not supported"))},r.prototype._write=function(e,t,n){var r=this;if(!r.destroyed){if(!r._sourceBuffer)return void(r._cb=function(o){return o?n(o):void r._write(e,t,n)});if(r._sourceBuffer.updating)return n(new Error("Cannot append buffer while source buffer updating"));try{r._sourceBuffer.appendBuffer(s(e))}catch(o){return void r.destroy(o)}r._cb=n}},r.prototype._flow=function(){var e=this;if(!e.destroyed&&e._sourceBuffer&&!e._sourceBuffer.updating&&!("open"===e._mediaSource.readyState&&e._getBufferDuration()>e._bufferDuration)&&e._cb){var t=e._cb;e._cb=null,t()}};var c=0;r.prototype._getBufferDuration=function(){for(var e=this,t=e._sourceBuffer.buffered,n=e._elem.currentTime,r=-1,o=0;on)break;(r>=0||s>=n)&&(r=s)}var a=r-n;return 0>a&&(a=0),a}},{inherits:65,"readable-stream":98,"to-arraybuffer":117}],73:[function(e,t){(function(e){function n(e,t){if(!(this instanceof n))return new n(e,t);if(t||(t={}),this.chunkLength=Number(e),!this.chunkLength)throw new Error("First argument must be a chunk length");this.chunks=[],this.closed=!1,this.length=Number(t.length)||1/0,this.length!==1/0&&(this.lastChunkLength=this.length%this.chunkLength||this.chunkLength,this.lastChunkIndex=Math.ceil(this.length/this.chunkLength)-1)}function r(t,n,r){e.nextTick(function(){t&&t(n,r)})}t.exports=n,n.prototype.put=function(e,t,n){if(this.closed)return r(n,new Error("Storage is closed"));var o=e===this.lastChunkIndex;return o&&t.length!==this.lastChunkLength?r(n,new Error("Last chunk length must be "+this.lastChunkLength)):o||t.length===this.chunkLength?(this.chunks[e]=t,void r(n,null)):r(n,new Error("Chunk length must be "+this.chunkLength))},n.prototype.get=function(e,t,n){if("function"==typeof t)return this.get(e,null,t);if(this.closed)return r(n,new Error("Storage is closed"));var o=this.chunks[e];if(!o)return r(n,new Error("Chunk not found"));if(!t)return r(n,null,o);var i=t.offset||0,s=t.length||o.length-i;r(n,null,o.slice(i,s+i))},n.prototype.close=n.prototype.destroy=function(e){return this.closed?r(e,new Error("Storage is closed")):(this.closed=!0,this.chunks=null,void r(e,null))}}).call(this,e("_process"))},{_process:16}],74:[function(e,t,n){(function(t){function r(e,t,n){for(var r=t;n>r;r++)e[r]=0}function o(e,t,n){t.writeUInt32BE(Math.floor((e.getTime()+g)/1e3),n)}function i(e,t,n){t.writeUInt16BE(Math.floor(e)%65536,n),t.writeUInt16BE(Math.floor(256*e*256)%65536,n+2)}function s(e,t,n){t[n]=Math.floor(e)%256,t[n+1]=Math.floor(256*e)%256}function a(e,t,n){e||(e=[0,0,0,0,0,0,0,0,0]);for(var r=0;rr&&0!==e[t+r];r++);return e.toString("utf8",t,t+r)}var p=e("./index"),m=e("./descriptor"),g=20828448e5;n.fullBoxes={};var y=["mvhd","tkhd","mdhd","vmhd","smhd","stsd","esds","stsz","stco","stss","stts","ctts","stsc","dref","elst","hdlr","mehd","trex","mfhd","tfhd","tfdt","trun"];y.forEach(function(e){n.fullBoxes[e]=!0}),n.ftyp={},n.ftyp.encode=function(e,r,o){r=r?r.slice(o):new t(n.ftyp.encodingLength(e));var i=e.compatibleBrands||[];r.write(e.brand,0,4,"ascii"),r.writeUInt32BE(e.brandVersion,4);for(var s=0;ss;s++){var a=p.decode(e,i,n);o[s]=a,i+=a.length}return{entries:o}},n.stsd.encodingLength=function(e){var t=4;if(!e.entries)return t;for(var n=0;n=8;){var a=p.decode(e,s,r);i.children.push(a),i[a.type]=a,s+=a.length}return i},n.VisualSampleEntry.encodingLength=function(e){var t=78,n=e.children||[];return n.forEach(function(e){t+=p.encodingLength(e)}),t},n.avcC={},n.avcC.encode=function(e,r,o){r=r?r.slice(o):t(e.buffer.length),e.buffer.copy(r),n.avcC.encode.bytes=e.buffer.length},n.avcC.decode=function(e,n,r){return e=e.slice(n,r),{mimeCodec:e.toString("hex",1,4),buffer:new t(e)}},n.avcC.encodingLength=function(e){return e.buffer.length},n.mp4a=n.AudioSampleEntry={},n.AudioSampleEntry.encode=function(e,o,i){o=o?o.slice(i):new t(n.AudioSampleEntry.encodingLength(e)),r(o,0,6),o.writeUInt16BE(e.dataReferenceIndex||0,6),r(o,8,16),o.writeUInt16BE(e.channelCount||2,16),o.writeUInt16BE(e.sampleSize||16,18),r(o,20,24),o.writeUInt32BE(e.sampleRate||0,24);var s=28,a=e.children||[];a.forEach(function(e){p.encode(e,o,s),s+=p.encode.bytes}),n.AudioSampleEntry.encode.bytes=s},n.AudioSampleEntry.decode=function(e,t,n){e=e.slice(t,n);for(var r=n-t,o={dataReferenceIndex:e.readUInt16BE(6),channelCount:e.readUInt16BE(16),sampleSize:e.readUInt16BE(18),sampleRate:e.readUInt32BE(24),children:[]},i=28;r-i>=8;){var s=p.decode(e,i,r);o.children.push(s),o[s.type]=s,i+=s.length}return o},n.AudioSampleEntry.encodingLength=function(e){var t=28,n=e.children||[];return n.forEach(function(e){t+=p.encodingLength(e)}),t},n.esds={},n.esds.encode=function(e,r,o){r=r?r.slice(o):t(e.buffer.length),e.buffer.copy(r,0),n.esds.encode.bytes=e.buffer.length},n.esds.decode=function(e,n,r){e=e.slice(n,r);var o=m.Descriptor.decode(e,0,e.length),i="ESDescriptor"===o.tagName?o:{},s=i.DecoderConfigDescriptor||{},a=s.oti||0,u=s.DecoderSpecificInfo,c=u?(248&u.buffer.readUInt8(0))>>3:0,f=null;return a&&(f=a.toString(16),c&&(f+="."+c)),{mimeCodec:f,buffer:new t(e.slice(0))}},n.esds.encodingLength=function(e){return e.buffer.length},n.stsz={},n.stsz.encode=function(e,r,o){var i=e.entries||[];r=r?r.slice(o):t(n.stsz.encodingLength(e)),r.writeUInt32BE(0,0),r.writeUInt32BE(i.length,4);for(var s=0;si;i++)o[i]=0===n?e.readUInt32BE(4*i+8):n;return{entries:o}},n.stsz.encodingLength=function(e){return 8+4*e.entries.length},n.stss=n.stco={},n.stco.encode=function(e,r,o){var i=e.entries||[];r=r?r.slice(o):new t(n.stco.encodingLength(e)),r.writeUInt32BE(i.length,0);for(var s=0;so;o++)r[o]=e.readUInt32BE(4*o+4);return{entries:r}},n.stco.encodingLength=function(e){return 4+4*e.entries.length},n.stts={},n.stts.encode=function(e,r,o){var i=e.entries||[];r=r?r.slice(o):new t(n.stts.encodingLength(e)),r.writeUInt32BE(i.length,0);for(var s=0;so;o++){var i=8*o+4;r[o]={count:e.readUInt32BE(i),duration:e.readUInt32BE(i+4)}}return{entries:r}},n.stts.encodingLength=function(e){return 4+8*e.entries.length},n.ctts={},n.ctts.encode=function(e,r,o){var i=e.entries||[];r=r?r.slice(o):new t(n.ctts.encodingLength(e)),r.writeUInt32BE(i.length,0);for(var s=0;so;o++){var i=8*o+4;r[o]={count:e.readUInt32BE(i),compositionOffset:e.readInt32BE(i+4)}}return{entries:r}},n.ctts.encodingLength=function(e){return 4+8*e.entries.length},n.stsc={},n.stsc.encode=function(e,r,o){var i=e.entries||[];r=r?r.slice(o):new t(n.stsc.encodingLength(e)),r.writeUInt32BE(i.length,0);for(var s=0;so;o++){var i=12*o+4;r[o]={firstChunk:e.readUInt32BE(i),samplesPerChunk:e.readUInt32BE(i+4),sampleDescriptionId:e.readUInt32BE(i+8)}}return{entries:r}},n.stsc.encodingLength=function(e){return 4+12*e.entries.length},n.dref={},n.dref.encode=function(e,r,o){r=r?r.slice(o):new t(n.dref.encodingLength(e));var i=e.entries||[];r.writeUInt32BE(i.length,0);for(var s=4,a=0;ai;i++){var s=e.readUInt32BE(o),a=e.toString("ascii",o+4,o+8),u=e.slice(o+8,o+s);o+=s,r[i]={type:a,buf:u}}return{entries:r}},n.dref.encodingLength=function(e){var t=4;if(!e.entries)return t;for(var n=0;no;o++){var i=12*o+4;r[o]={trackDuration:e.readUInt32BE(i),mediaTime:e.readInt32BE(i+4),mediaRate:d(e,i+8)}}return{entries:r}},n.elst.encodingLength=function(e){return 4+12*e.entries.length},n.hdlr={},n.hdlr.encode=function(e,r,o){r=r?r.slice(o):new t(n.hdlr.encodingLength(e));var i=21+(e.name||"").length;return r.fill(0,0,i),r.write(e.handlerType||"",4,4,"ascii"),u(e.name||"",r,20),n.hdlr.encode.bytes=i,r},n.hdlr.decode=function(e,t,n){return e=e.slice(t),{handlerType:e.toString("ascii",4,8),name:l(e,20,n)}},n.hdlr.encodingLength=function(e){return 21+(e.name||"").length},n.mehd={},n.mehd.encode=function(e,r,o){return r=r?r.slice(o):new t(4),r.writeUInt32BE(e.fragmentDuration||0,0),n.mehd.encode.bytes=4,r},n.mehd.decode=function(e,t){return e=e.slice(t),{fragmentDuration:e.readUInt32BE(0)}},n.mehd.encodingLength=function(){return 4},n.trex={},n.trex.encode=function(e,r,o){return r=r?r.slice(o):new t(20),r.writeUInt32BE(e.trackId||0,0),r.writeUInt32BE(e.defaultSampleDescriptionIndex||0,4),r.writeUInt32BE(e.defaultSampleDuration||0,8),r.writeUInt32BE(e.defaultSampleSize||0,12),r.writeUInt32BE(e.defaultSampleFlags||0,16),n.trex.encode.bytes=20,r},n.trex.decode=function(e,t){return e=e.slice(t),{trackId:e.readUInt32BE(0),defaultSampleDescriptionIndex:e.readUInt32BE(4),defaultSampleDuration:e.readUInt32BE(8),defaultSampleSize:e.readUInt32BE(12),defaultSampleFlags:e.readUInt32BE(16)}},n.trex.encodingLength=function(){return 20},n.mfhd={},n.mfhd.encode=function(e,r,o){return r=r?r.slice(o):new t(4),r.writeUInt32BE(e.sequenceNumber||0,0),n.mfhd.encode.bytes=4,r},n.mfhd.decode=function(e){return{sequenceNumber:e.readUint32BE(0)}},n.mfhd.encodingLength=function(){return 4},n.tfhd={},n.tfhd.encode=function(e,r,o){return r=r?r.slice(o):new t(4),r.writeUInt32BE(e.trackId,0),n.tfhd.encode.bytes=4,r},n.tfhd.decode=function(){},n.tfhd.encodingLength=function(){return 4},n.tfdt={},n.tfdt.encode=function(e,r,o){return r=r?r.slice(o):new t(4),r.writeUInt32BE(e.baseMediaDecodeTime||0,0),n.tfdt.encode.bytes=4,r},n.tfdt.decode=function(){},n.tfdt.encodingLength=function(){return 4},n.trun={},n.trun.encode=function(e,r,o){r=r?r.slice(o):new t(8+16*e.entries.length),r.writeUInt32BE(e.entries.length,0),r.writeInt32BE(e.dataOffset,4);for(var i=8,s=0;s=i+2;){var a=n.Descriptor.decode(e,i,o);i+=a.length;var u=t[a.tag]||"Descriptor"+a.tag;s[u]=a}return s},n.ESDescriptor={},n.ESDescriptor.decode=function(e,t,r){var o=e.readUInt8(t+2),i=t+3;if(128&o&&(i+=2),64&o){var s=e.readUInt8(i);i+=s+1}return 32&o&&(i+=2),n.DescriptorArray.decode(e,i,r)},n.DecoderConfigDescriptor={},n.DecoderConfigDescriptor.decode=function(e,t,r){var o=e.readUInt8(t),i=n.DescriptorArray.decode(e,t+13,r);return i.oti=o,i}}).call(this,e("buffer").Buffer)},{buffer:5}],76:[function(e,t,n){(function(t){var r=e("uint64be"),o=e("./boxes"),i=4294967295,s=n,a=n.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","trun","sbgps","sgpds","subss","saizs","saios","tfdt","meta"]};s.encode=function(e,n,r){return s.encodingLength(e),r=r||0,n=n||new t(e.length),s._encode(e,n,r)},s._encode=function(e,t,n){var u=e.type,c=e.length;c>i&&(c=1),t.writeUInt32BE(c,n),t.write(e.type,n+4,4,"ascii");var f=n+8;if(1===c&&(r.encode(e.length,t,f),f+=8),o.fullBoxes[u]&&(t.writeUInt32BE(e.flags||0,f),t.writeUInt8(e.version||0,f),f+=4),a[u]){var d=a[u];d.forEach(function(n){if(5===n.length){var r=e[n]||[];n=n.substr(0,4),r.forEach(function(e){s._encode(e,t,f),f+=s.encode.bytes})}else e[n]&&(s._encode(e[n],t,f),f+=s.encode.bytes)}),e.otherBoxes&&e.otherBoxes.forEach(function(e){s._encode(e,t,f),f+=s.encode.bytes})}else if(o[u]){var h=o[u].encode;h(e,t,f),f+=h.bytes}else{if(!e.buffer)throw new Error("Either `type` must be set to a known type (not'"+u+"') or `buffer` must be set");var l=e.buffer;l.copy(t,f),f+=e.buffer.length}return s.encode.bytes=f-n,t},s.readHeaders=function(e,t,n){if(t=t||0,n=n||e.length,8>n-t)return 8;var i=e.readUInt32BE(t),s=e.toString("ascii",t+4,t+8),a=t+8;if(1===i){if(16>n-t)return 16;i=r.decode(e,a),a+=8}var u,c;return o.fullBoxes[s]&&(u=e.readUInt8(a),c=16777215&e.readUInt32BE(a),a+=4),{length:i,headersLen:a-t,contentLen:i-(a-t),type:s,version:u,flags:c}},s.decode=function(e,t,n){t=t||0,n=n||e.length;var r=s.readHeaders(e,t,n);if(!r||r.length>n-t)throw new Error("Data too short");return s.decodeWithoutHeaders(r,e,t+r.headersLen,t+r.length)},s.decodeWithoutHeaders=function(e,n,r,i){r=r||0,i=i||n.length;var u=e.type,c={};if(a[u]){c.otherBoxes=[];for(var f=a[u],d=r;i-d>=8;){var h=s.decode(n,d,i);if(d+=h.length,f.indexOf(h.type)>=0)c[h.type]=h;else if(f.indexOf(h.type+"s")>=0){var l=h.type+"s",p=c[l]=c[l]||[];p.push(h)}else c.otherBoxes.push(h)}}else if(o[u]){var m=o[u].decode;c=m(n,r,i)}else c.buffer=new t(n.slice(r,i));return c.length=e.length,c.contentLen=e.contentLen,c.type=e.type,c.version=e.version,c.flags=e.flags,c},s.encodingLength=function(e){var t=e.type,n=8;if(o.fullBoxes[t]&&(n+=4),a[t]){var r=a[t];r.forEach(function(t){if(5===t.length){var r=e[t]||[];t=t.substr(0,4),r.forEach(function(e){e.type=t,n+=s.encodingLength(e)})}else if(e[t]){var o=e[t];o.type=t,n+=s.encodingLength(o)}}),e.otherBoxes&&e.otherBoxes.forEach(function(e){n+=s.encodingLength(e)})}else if(o[t])n+=o[t].encodingLength(e);else{if(!e.buffer)throw new Error("Either `type` must be set to a known type (not'"+t+"') or `buffer` must be set");n+=e.buffer.length}return n>i&&(n+=8),e.length=n,n}}).call(this,e("buffer").Buffer)},{"./boxes":74,buffer:5,uint64be:121}],77:[function(e,t){(function(n){function r(){return this instanceof r?(i.Writable.call(this),this.destroyed=!1,this._pending=0,this._missing=0,this._buf=null,this._str=null,this._cb=null,this._ondrain=null,this._writeBuffer=null,this._writeCb=null,this._ondrain=null,void this._kick()):new r}function o(e){this._parent=e,this.destroyed=!1,i.PassThrough.call(this)}var i=e("readable-stream"),s=e("inherits"),a=e("next-event"),u=e("mp4-box-encoding"),c=new n(0);t.exports=r,s(r,i.Writable),r.prototype.destroy=function(e){this.destroyed||(this.destroyed=!0,e&&this.emit("error",e),this.emit("close"))},r.prototype._write=function(e,t,n){if(!this.destroyed){for(var r=!this._str||!this._str._writableState.needDrain;e.length&&!this.destroyed;){if(!this._missing)return this._writeBuffer=e,void(this._writeCb=n);var o=e.length1e4)){var t=/^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(e);if(t){var n=parseFloat(t[1]),r=(t[2]||"ms").toLowerCase();switch(r){case"years":case"year":case"yrs":case"yr":case"y":return n*f;case"days":case"day":case"d":return n*c;case"hours":case"hour":case"hrs":case"hr":case"h":return n*u;case"minutes":case"minute":case"mins":case"min":case"m":return n*a;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}}}}function r(e){return e>=c?Math.round(e/c)+"d":e>=u?Math.round(e/u)+"h":e>=a?Math.round(e/a)+"m":e>=s?Math.round(e/s)+"s":e+"ms"}function o(e){return i(e,c,"day")||i(e,u,"hour")||i(e,a,"minute")||i(e,s,"second")||e+" ms"}function i(e,t,n){return t>e?void 0:1.5*t>e?Math.floor(e/t)+" "+n:Math.ceil(e/t)+" "+n+"s"}var s=1e3,a=60*s,u=60*a,c=24*u,f=365.25*c;t.exports=function(e,t){return t=t||{},"string"==typeof e?n(e):t["long"]?o(e):r(e)}},{}],81:[function(e,t){function n(e,t){var o=this;return o instanceof n?(i.Readable.call(o,t),o.destroyed=!1,o._drained=!1,o._forwarding=!1,o._current=null,"function"==typeof e?o._queue=e:(o._queue=e.map(r),o._queue.forEach(function(e){"function"!=typeof e&&o._attachErrorListener(e)})),void o._next()):new n(e,t)}function r(e){if(!e||"function"==typeof e||e._readableState)return e;var t=(new i.Readable).wrap(e);return e.destroy&&(t.destroy=e.destroy.bind(e)),t}t.exports=n;var o=e("inherits"),i=e("readable-stream");o(n,i.Readable),n.obj=function(e){return new n(e,{objectMode:!0,highWaterMark:16})},n.prototype._read=function(){this._drained=!0,this._forward()},n.prototype._forward=function(){if(!this._forwarding&&this._drained&&this._current){this._forwarding=!0;for(var e;null!==(e=this._current.read());)this._drained=this.push(e);this._forwarding=!1}},n.prototype.destroy=function(e){this.destroyed||(this.destroyed=!0,this._current&&this._current.destroy&&this._current.destroy(),"function"!=typeof this._queue&&this._queue.forEach(function(e){e.destroy&&e.destroy()}),e&&this.emit("error",e),this.emit("close"))},n.prototype._next=function(){var e=this;if(e._current=null,"function"==typeof e._queue)e._queue(function(t,n){return t?e.destroy(t):(n=r(n),e._attachErrorListener(n),void e._gotNextStream(n))});else{var t=e._queue.shift();"function"==typeof t&&(t=r(t()),e._attachErrorListener(t)),e._gotNextStream(t)}},n.prototype._gotNextStream=function(e){function t(){o._forward()}function n(){e._readableState.ended||o.destroy()}function r(){o._current=null,e.removeListener("readable",t),e.removeListener("end",r),e.removeListener("close",n),o._next()}var o=this;return e?(o._current=e, +o._forward(),e.on("readable",t),e.once("end",r),void e.once("close",n)):(o.push(null),void o.destroy())},n.prototype._attachErrorListener=function(e){function t(r){e.removeListener("error",t),n.destroy(r)}var n=this;e&&e.once("error",t)}},{inherits:65,"readable-stream":98}],82:[function(e,t){function n(e,t){var n=null;return e.on(t,function(e){if(n){var t=n;n=null,t(e)}}),function(e){n=e}}t.exports=n},{}],83:[function(e,t){function n(e){var t=function(){return t.called?t.value:(t.called=!0,t.value=e.apply(this,arguments))};return t.called=!1,t}function r(e){var t=function(){if(t.called)throw new Error(t.onceError);return t.called=!0,t.value=e.apply(this,arguments)},n=e.name||"Function wrapped with `once`";return t.onceError=n+" shouldn't be called more than once",t.called=!1,t}var o=e("wrappy");t.exports=o(n),t.exports.strict=o(r),n.proto=n(function(){Object.defineProperty(Function.prototype,"once",{value:function(){return n(this)},configurable:!0}),Object.defineProperty(Function.prototype,"onceStrict",{value:function(){return r(this)},configurable:!0})})},{wrappy:136}],84:[function(e,t){(function(n){function r(e){n.isBuffer(e)&&(e=u.decode(e)),a(e.info,"info"),a(e.info["name.utf-8"]||e.info.name,"info.name"),a(e.info["piece length"],"info['piece length']"),a(e.info.pieces,"info.pieces"),e.info.files?e.info.files.forEach(function(e){a("number"==typeof e.length,"info.files[0].length"),a(e["path.utf-8"]||e.path,"info.files[0].path")}):a("number"==typeof e.info.length,"info.length");var t={};t.info=e.info,t.infoBuffer=u.encode(e.info),t.infoHash=f.sync(t.infoBuffer),t.infoHashBuffer=new n(t.infoHash,"hex"),t.name=(e.info["name.utf-8"]||e.info.name).toString(),void 0!==e.info["private"]&&(t["private"]=!!e.info["private"]),e["creation date"]&&(t.created=new Date(1e3*e["creation date"])),e["created by"]&&(t.createdBy=e["created by"].toString()),n.isBuffer(e.comment)&&(t.comment=e.comment.toString()),t.announce=[],e["announce-list"]&&e["announce-list"].length?e["announce-list"].forEach(function(e){e.forEach(function(e){t.announce.push(e.toString())})}):e.announce&&t.announce.push(e.announce.toString()),n.isBuffer(e["url-list"])&&(e["url-list"]=e["url-list"].length>0?[e["url-list"]]:[]),t.urlList=(e["url-list"]||[]).map(function(e){return e.toString()}),d(t.announce),d(t.urlList);var r=e.info.files||[e.info];t.files=r.map(function(e,n){var o=[].concat(t.name,e["path.utf-8"]||e.path||[]).map(function(e){return e.toString()});return{path:c.join.apply(null,[c.sep].concat(o)).slice(1),name:o[o.length-1],length:e.length,offset:r.slice(0,n).reduce(i,0)}}),t.length=r.reduce(i,0);var o=t.files[t.files.length-1];return t.pieceLength=e.info["piece length"],t.lastPieceLength=(o.offset+o.length)%t.pieceLength||t.pieceLength,t.pieces=s(e.info.pieces),t}function o(e){var t={info:e.info};return t["announce-list"]=(e.announce||[]).map(function(e){return t.announce||(t.announce=e),e=new n(e,"utf8"),[e]}),t["url-list"]=e.urlList||[],e.created&&(t["creation date"]=e.created.getTime()/1e3|0),e.createdBy&&(t["created by"]=e.createdBy),e.comment&&(t.comment=e.comment),u.encode(t)}function i(e,t){return e+t.length}function s(e){for(var t=[],n=0;n=o;o++)r.push(Math.pow(2,o));t.exports=function(e){return n(e/Math.pow(2,10),r)}},{"closest-to":53}],87:[function(e,t,n){arguments[4][15][0].apply(n,arguments)},{_process:16,dup:15}],88:[function(e,t){var n=e("once"),r=e("end-of-stream"),o=e("fs"),i=function(){},s=function(e){return"function"==typeof e},a=function(e){return(e instanceof(o.ReadStream||i)||e instanceof(o.WriteStream||i))&&s(e.close)},u=function(e){return e.setHeader&&s(e.abort)},c=function(e,t,o,i){i=n(i);var c=!1;e.on("close",function(){c=!0}),r(e,{readable:t,writable:o},function(e){return e?i(e):(c=!0,void i())});var f=!1;return function(t){return c||f?void 0:(f=!0,a(e)?e.close():u(e)?e.abort():s(e.destroy)?e.destroy():void i(t||new Error("stream was destroyed")))}},f=function(e){e()},d=function(e,t){return e.pipe(t)},h=function(){var e=Array.prototype.slice.call(arguments),t=s(e[e.length-1]||i)&&e.pop()||i;if(Array.isArray(e[0])&&(e=e[0]),e.length<2)throw new Error("pump requires two streams per minimum");var n,r=e.map(function(o,i){var s=i0;return c(o,s,a,function(e){n||(n=e),e&&r.forEach(f),s||(r.forEach(f),t(n))})});return e.reduce(d)};t.exports=h},{"end-of-stream":59,fs:1,once:83}],89:[function(e,t){var n=function(e){var t=0;return function(){if(t===e.length)return null;var n=e.length-t,r=Math.random()*n|0,o=e[t+r],i=e[t];return e[t]=o,e[t+r]=i,t++,o}};t.exports=n},{}],90:[function(e,t){(function(e,n,r){"use strict";function o(){throw new Error("secure random number generation not supported by this browser\nuse chrome, FireFox or Internet Explorer 11")}function i(t,o){if(t>65536)throw new Error("requested too many random bytes");var i=new n.Uint8Array(t);t>0&&s.getRandomValues(i);var a=new r(i.buffer);return"function"==typeof o?e.nextTick(function(){o(null,a)}):a}var s=n.crypto||n.msCrypto;t.exports=s&&s.getRandomValues?i:o}).call(this,e("_process"),"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{},e("buffer").Buffer)},{_process:16,buffer:5}],91:[function(e,t){function n(e){var t=this;return t instanceof n?(o.Writable.call(t),t.destroyed=!1,t._queue=[],t._position=e||0,t._cb=null,t._buffer=null,void(t._out=null)):new n(e)}var r=e("inherits"),o=e("readable-stream");t.exports=n,r(n,o.Writable),n.prototype._write=function(e,t,n){for(var r=this,o=!0;;){if(r.destroyed)return;if(0===r._queue.length)return r._buffer=e,void(r._cb=n);r._buffer=null;var i=r._queue[0],s=Math.max(i.start-r._position,0),a=i.end-r._position;if(s>=e.length)return r._position+=e.length,n(null);var u;if(a>e.length){r._position+=e.length,u=0===s?e:e.slice(s),o=i.stream.write(u)&&o;break}r._position+=a,u=0===s&&a===e.length?e:e.slice(s,a),o=i.stream.write(u)&&o,i.last&&i.stream.end(),e=e.slice(a),r._queue.shift()}o?n(null):i.stream.once("drain",n.bind(null,null))},n.prototype.slice=function(e){var t=this;if(t.destroyed)return null;e instanceof Array||(e=[e]);var n=new o.PassThrough;return e.forEach(function(r,o){t._queue.push({start:r.start,end:r.end,stream:n,last:o===e.length-1})}),t._buffer&&t._write(t._buffer,null,t._cb),n},n.prototype.destroy=function(e){var t=this;t.destroyed||(t.destroyed=!0,e&&t.emit("error",e))}},{inherits:65,"readable-stream":98}],92:[function(e,t,n){arguments[4][21][0].apply(n,arguments)},{"./_stream_readable":94,"./_stream_writable":96,"core-util-is":54,dup:21,inherits:65,"process-nextick-args":87}],93:[function(e,t,n){arguments[4][22][0].apply(n,arguments)},{"./_stream_transform":95,"core-util-is":54,dup:22,inherits:65}],94:[function(e,t,n){arguments[4][23][0].apply(n,arguments)},{"./_stream_duplex":92,"./internal/streams/BufferList":97,_process:16,buffer:5,"buffer-shims":51,"core-util-is":54,dup:23,events:8,inherits:65,isarray:69,"process-nextick-args":87,"string_decoder/":114,util:3}],95:[function(e,t,n){arguments[4][24][0].apply(n,arguments)},{"./_stream_duplex":92,"core-util-is":54,dup:24,inherits:65}],96:[function(e,t,n){arguments[4][25][0].apply(n,arguments)},{"./_stream_duplex":92,_process:16,buffer:5,"buffer-shims":51,"core-util-is":54,dup:25,events:8,inherits:65,"process-nextick-args":87,"util-deprecate":125}],97:[function(e,t,n){arguments[4][26][0].apply(n,arguments)},{buffer:5,"buffer-shims":51,dup:26}],98:[function(e,t,n){arguments[4][27][0].apply(n,arguments)},{"./lib/_stream_duplex.js":92,"./lib/_stream_passthrough.js":93,"./lib/_stream_readable.js":94,"./lib/_stream_transform.js":95,"./lib/_stream_writable.js":96,_process:16,dup:27}],99:[function(e,t,n){function r(e,t,n,r){"function"==typeof n&&(r=n,n={}),n||(n={}),r||(r=function(){}),a(e),c(n),"string"==typeof t&&(t=document.querySelector(t)),i(e,function(n){if(t.nodeName!==n.toUpperCase()){var r=l.extname(e.name).toLowerCase();throw new Error('Cannot render "'+r+'" inside a "'+t.nodeName.toLowerCase()+'" element, expected "'+n+'"')}return t},n,r)}function o(e,t,n,r){function o(e){return"video"===e||"audio"===e?s(e):u(e)}function s(e){var r=u(e);return n.controls&&(r.controls=!0),n.autoplay&&(r.autoplay=!0),t.appendChild(r),r}function u(e){var n=document.createElement(e);return t.appendChild(n),n}function f(e,t){e&&t&&t.remove(),r(e,t)}if("function"==typeof n&&(r=n,n={}),n||(n={}),r||(r=function(){}),a(e),c(n),"string"==typeof t&&(t=document.querySelector(t)),t&&("VIDEO"===t.nodeName||"AUDIO"===t.nodeName))throw new Error("Invalid video/audio node argument. Argument must be root element that video/audio tag will be appended to.");i(e,o,n,f)}function i(e,t,n,r){function o(){function r(){f("Use `videostream` package for "+e.name),p(),B.addEventListener("error",d),B.addEventListener("loadstart",a),B.addEventListener("canplay",c),m(e,B)}function o(){f("Use MediaSource API for "+e.name),p(),B.addEventListener("error",l),B.addEventListener("loadstart",a),B.addEventListener("canplay",c);var t=new h(B),n=t.createWriteStream(u(e.name));e.createReadStream().pipe(n),I&&(B.currentTime=I)}function i(){f("Use Blob URL for "+e.name),p(),B.addEventListener("error",S),B.addEventListener("loadstart",a),B.addEventListener("canplay",c),s(e,function(e,t){return e?S(e):(B.src=t,void(I&&(B.currentTime=I)))})}function d(e){f("videostream error: fallback to MediaSource API: %o",e.message||e),B.removeEventListener("error",d),B.removeEventListener("canplay",c),o()}function l(t){return f("MediaSource API error: fallback to Blob URL: %o",t.message||t),"number"==typeof e.length&&e.length>n.maxBlobLength?(f("File length too large for Blob URL approach: %d (max: %d)",e.length,n.maxBlobLength),S(new Error("File length too large for Blob URL approach: "+e.length+" (max: "+n.maxBlobLength+")"))):(B.removeEventListener("error",l),B.removeEventListener("canplay",c),void i())}function p(){B||(B=t(_),B.addEventListener("progress",function(){I=B.currentTime}))}var _=y.indexOf(A)>=0?"video":"audio";x?g.indexOf(A)>=0?r():o():i()}function i(){B=t("audio"),s(e,function(e,t){return e?S(e):(B.addEventListener("error",S),B.addEventListener("loadstart",a),B.addEventListener("canplay",c),void(B.src=t))})}function a(){B.removeEventListener("loadstart",a),n.autoplay&&B.play()}function c(){B.removeEventListener("canplay",c),r(null,B)}function p(){B=t("img"),s(e,function(t,n){return t?S(t):(B.src=n,B.alt=e.name,void r(null,B))})}function _(){B=t("iframe"),s(e,function(e,t){return e?S(e):(B.src=t,".pdf"!==A&&(B.sandbox="allow-forms allow-scripts"),void r(null,B))})}function k(){function t(){d(n)?(f('File extension "%s" appears ascii, so will render.',A),_()):(f('File extension "%s" appears non-ascii, will not render.',A),r(new Error('Unsupported file type "'+A+'": Cannot append to DOM')))}f('Unknown file extension "%s" - will attempt to render into iframe',A);var n="";e.createReadStream({start:0,end:1e3}).setEncoding("utf8").on("data",function(e){n+=e}).on("end",t).on("error",r)}function S(t){t.message='Error rendering file "'+e.name+'": '+t.message,f(t.message),r(t)}var B,A=l.extname(e.name).toLowerCase(),I=0;v.indexOf(A)>=0?o():b.indexOf(A)>=0?i():w.indexOf(A)>=0?p():E.indexOf(A)>=0?_():k()}function s(e,t){var r=l.extname(e.name).toLowerCase();p(e.createReadStream(),n.mime[r],t)}function a(e){if(null==e)throw new Error("file cannot be null or undefined");if("string"!=typeof e.name)throw new Error("missing or invalid file.name property");if("function"!=typeof e.createReadStream)throw new Error("missing or invalid file.createReadStream property")}function u(e){var t=l.extname(e).toLowerCase();return{".m4a":'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"'}[t]}function c(e){null==e.autoplay&&(e.autoplay=!0),null==e.controls&&(e.controls=!0),null==e.maxBlobLength&&(e.maxBlobLength=k)}n.render=r,n.append=o,n.mime=e("./lib/mime.json");var f=e("debug")("render-media"),d=e("is-ascii"),h=e("mediasource"),l=e("path"),p=e("stream-to-blob-url"),m=e("videostream"),g=[".m4a",".m4v",".mp4"],y=[".m4v",".mkv",".mp4",".webm"],_=[".m4a",".mp3"],v=[].concat(y,_),b=[".aac",".oga",".ogg",".wav"],w=[".bmp",".gif",".jpeg",".jpg",".png"],E=[".css",".html",".js",".md",".pdf",".txt"],k=2e8,x="undefined"!=typeof window&&window.MediaSource},{"./lib/mime.json":100,debug:56,"is-ascii":66,mediasource:72,path:14,"stream-to-blob-url":111,videostream:127}],100:[function(e,t){t.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/csv",".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/mp4",".m4v":"video/mp4",".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"}},{}],101:[function(e,t){(function(e){t.exports=function(t,n,r){function o(t){function n(){r&&r(t,s),r=null}d?e.nextTick(n):n()}function i(e,n,r){if(s[e]=r,n&&(f=!0),0===--u||n)o(n);else if(!f&&a>h){var d;c?(d=c[h],h+=1,t[d](function(e,t){i(d,e,t)})):(d=h,h+=1,t[d](function(e,t){i(d,e,t)}))}}if("number"!=typeof n)throw new Error("second argument must be a Number");var s,a,u,c,f,d=!0;Array.isArray(t)?(s=[],u=a=t.length):(c=Object.keys(t),s={},u=a=c.length);var h=n;u?c?c.some(function(e,r){return t[e](function(t,n){i(e,t,n)}),r===n-1?!0:void 0}):t.some(function(e,t){return e(function(e,n){i(t,e,n)}),t===n-1?!0:void 0}):o(null),d=!1}}).call(this,e("_process"))},{_process:16}],102:[function(e,t){(function(e){t.exports=function(t,n){function r(t){function r(){n&&n(t,i),n=null}u?e.nextTick(r):r()}function o(e,t,n){i[e]=n,(0===--s||t)&&r(t)}var i,s,a,u=!0;Array.isArray(t)?(i=[],s=t.length):(a=Object.keys(t),i={},s=a.length),s?a?a.forEach(function(e){t[e](function(t,n){o(e,t,n)})}):t.forEach(function(e,t){e(function(e,n){o(t,e,n)})}):r(null),u=!1}}).call(this,e("_process"))},{_process:16}],103:[function(e,t){(function(e){!function(){function n(e){"use strict";for(var t={fill:0},i=function(e){for(e+=9;e%64>0;e+=1);return e},s=function(e,t){for(var n=t>>2;n>2]|=128<<24-(t%4<<3),e[((t>>2)+2&-16)+14]=n/(1<<29)|0,e[((t>>2)+2&-16)+15]=n<<3},u=function(e,t,n,r,o){var i,s=this,a=o%4,u=r%4,c=r-u;if(c>0)switch(a){case 0:e[o+3|0]=s.charCodeAt(n);case 1:e[o+2|0]=s.charCodeAt(n+1);case 2:e[o+1|0]=s.charCodeAt(n+2);case 3:e[0|o]=s.charCodeAt(n+3)}for(i=a;c>i;i=i+4|0)t[o+i>>2]=s.charCodeAt(n+i)<<24|s.charCodeAt(n+i+1)<<16|s.charCodeAt(n+i+2)<<8|s.charCodeAt(n+i+3);switch(u){case 3:e[o+c+1|0]=s.charCodeAt(n+c+2);case 2:e[o+c+2|0]=s.charCodeAt(n+c+1);case 1:e[o+c+3|0]=s.charCodeAt(n+c)}},c=function(e,t,n,r,o){var i,s=this,a=o%4,u=r%4,c=r-u;if(c>0)switch(a){case 0:e[o+3|0]=s[n];case 1:e[o+2|0]=s[n+1];case 2:e[o+1|0]=s[n+2];case 3:e[0|o]=s[n+3]}for(i=4-a;c>i;i=i+=4)t[o+i>>2]=s[n+i]<<24|s[n+i+1]<<16|s[n+i+2]<<8|s[n+i+3];switch(u){case 3:e[o+c+1|0]=s[n+c+2];case 2:e[o+c+2|0]=s[n+c+1];case 1:e[o+c+3|0]=s[n+c]}},f=function(e,t,n,r,i){var s,a=this,u=i%4,c=r%4,f=r-c,d=new Uint8Array(o.readAsArrayBuffer(a.slice(n,n+r)));if(f>0)switch(u){case 0:e[i+3|0]=d[0];case 1:e[i+2|0]=d[1];case 2:e[i+1|0]=d[2];case 3:e[0|i]=d[3]}for(s=4-u;f>s;s=s+=4)t[i+s>>2]=d[s]<<24|d[s+1]<<16|d[s+2]<<8|d[s+3];switch(c){case 3:e[i+f+1|0]=d[f+2];case 2:e[i+f+2|0]=d[f+1];case 1:e[i+f+3|0]=d[f]}},d=function(e){switch(r.getDataType(e)){case"string":return u.bind(e);case"array":return c.bind(e);case"buffer":return c.bind(e);case"arraybuffer":return c.bind(new Uint8Array(e));case"view":return c.bind(new Uint8Array(e.buffer,e.byteOffset,e.byteLength));case"blob":return f.bind(e)}},h=new Array(256),l=0;256>l;l++)h[l]=(16>l?"0":"")+l.toString(16);var p=function(e){for(var t=new Uint8Array(e),n=new Array(e.byteLength),r=0;r=e)return 65536;if(16777216>e)for(t=1;e>t;t<<=1);else for(t=16777216;e>t;t+=16777216);return t},g=function(e){if(e%64>0)throw new Error("Chunk size must be a multiple of 128 bit");t.maxChunkLen=e,t.padMaxChunkLen=i(e),t.heap=new ArrayBuffer(m(t.padMaxChunkLen+320+20)),t.h32=new Int32Array(t.heap),t.h8=new Int8Array(t.heap),t.core=new n._core({Int32Array:Int32Array,DataView:DataView},{},t.heap),t.buffer=null};g(e||65536);var y=function(e,t){var n=new Int32Array(e,t+320,5);n[0]=1732584193,n[1]=-271733879,n[2]=-1732584194,n[3]=271733878,n[4]=-1009589776},_=function(e,n){var r=i(e),o=new Int32Array(t.heap,0,r>>2);return s(o,e),a(o,e,n),r},v=function(e,n,r){d(e)(t.h8,t.h32,n,r,0)},b=function(e,n,r,o,i){var s=r;i&&(s=_(r,o)),v(e,n,r),t.core.hash(s,t.padMaxChunkLen)},w=function(e,t){var n=new Int32Array(e,t+320,5),r=new Int32Array(5),o=new DataView(r.buffer);return o.setInt32(0,n[0],!1),o.setInt32(4,n[1],!1),o.setInt32(8,n[2],!1),o.setInt32(12,n[3],!1),o.setInt32(16,n[4],!1),r},E=this.rawDigest=function(e){var n=e.byteLength||e.length||e.size||0;y(t.heap,t.padMaxChunkLen);var r=0,o=t.maxChunkLen;for(r=0;n>r+o;r+=o)b(e,r,o,n,!1);return b(e,r,n-r,n,!0),w(t.heap,t.padMaxChunkLen)};this.digest=this.digestFromString=this.digestFromBuffer=this.digestFromArrayBuffer=function(e){return p(E(e).buffer)}}var r={getDataType:function(t){if("string"==typeof t)return"string";if(t instanceof Array)return"array";if("undefined"!=typeof e&&e.Buffer&&e.Buffer.isBuffer(t))return"buffer";if(t instanceof ArrayBuffer)return"arraybuffer";if(t.buffer instanceof ArrayBuffer)return"view";if(t instanceof Blob)return"blob";throw new Error("Unsupported data type.")}};if(n._core=function(e,t,n){"use asm";function r(e,t){e|=0,t|=0;var n=0,r=0,i=0,s=0,a=0,u=0,c=0,f=0,d=0,h=0,l=0,p=0,m=0,g=0;for(i=o[t+320>>2]|0,a=o[t+324>>2]|0,c=o[t+328>>2]|0,d=o[t+332>>2]|0,l=o[t+336>>2]|0,n=0;(n|0)<(e|0);n=n+64|0){for(s=i,u=a,f=c,h=d,p=l,r=0;(r|0)<64;r=r+4|0)g=o[n+r>>2]|0,m=((i<<5|i>>>27)+(a&c|~a&d)|0)+((g+l|0)+1518500249|0)|0,l=d,d=c,c=a<<30|a>>>2,a=i,i=m,o[e+r>>2]=g;for(r=e+64|0;(r|0)<(e+80|0);r=r+4|0)g=(o[r-12>>2]^o[r-32>>2]^o[r-56>>2]^o[r-64>>2])<<1|(o[r-12>>2]^o[r-32>>2]^o[r-56>>2]^o[r-64>>2])>>>31,m=((i<<5|i>>>27)+(a&c|~a&d)|0)+((g+l|0)+1518500249|0)|0,l=d,d=c,c=a<<30|a>>>2,a=i,i=m,o[r>>2]=g;for(r=e+80|0;(r|0)<(e+160|0);r=r+4|0)g=(o[r-12>>2]^o[r-32>>2]^o[r-56>>2]^o[r-64>>2])<<1|(o[r-12>>2]^o[r-32>>2]^o[r-56>>2]^o[r-64>>2])>>>31,m=((i<<5|i>>>27)+(a^c^d)|0)+((g+l|0)+1859775393|0)|0,l=d,d=c,c=a<<30|a>>>2,a=i,i=m,o[r>>2]=g;for(r=e+160|0;(r|0)<(e+240|0);r=r+4|0)g=(o[r-12>>2]^o[r-32>>2]^o[r-56>>2]^o[r-64>>2])<<1|(o[r-12>>2]^o[r-32>>2]^o[r-56>>2]^o[r-64>>2])>>>31,m=((i<<5|i>>>27)+(a&c|a&d|c&d)|0)+((g+l|0)-1894007588|0)|0,l=d,d=c,c=a<<30|a>>>2,a=i,i=m,o[r>>2]=g;for(r=e+240|0;(r|0)<(e+320|0);r=r+4|0)g=(o[r-12>>2]^o[r-32>>2]^o[r-56>>2]^o[r-64>>2])<<1|(o[r-12>>2]^o[r-32>>2]^o[r-56>>2]^o[r-64>>2])>>>31,m=((i<<5|i>>>27)+(a^c^d)|0)+((g+l|0)-899497514|0)|0,l=d,d=c,c=a<<30|a>>>2,a=i,i=m,o[r>>2]=g;i=i+s|0,a=a+u|0,c=c+f|0,d=d+h|0,l=l+p|0}o[t+320>>2]=i,o[t+324>>2]=a,o[t+328>>2]=c,o[t+332>>2]=d,o[t+336>>2]=l}var o=new e.Int32Array(n);return{hash:r}},"undefined"!=typeof t?t.exports=n:"undefined"!=typeof window&&(window.Rusha=n),"undefined"!=typeof FileReaderSync){var o=new FileReaderSync,i=new n(4194304);self.onmessage=function(e){var t,n=e.data.data;try{t=i.digest(n),self.postMessage({id:e.data.id,hash:t})}catch(r){self.postMessage({id:e.data.id,error:r.name})}}}}()}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],104:[function(e,t){t.exports=e("buffer")},{buffer:5}],105:[function(e,t){(function(e){t.exports=function(t,n){var r=[];t.on("data",function(e){r.push(e)}),t.once("end",function(){n&&n(null,e.concat(r)),n=null}),t.once("error",function(e){n&&n(e),n=null})}}).call(this,e("buffer").Buffer)},{buffer:5}],106:[function(e,t){(function(n){function r(e,t){e="string"==typeof e?{url:e}:Object.assign({},e),t=u(t),e.url&&o(e),null==e.headers&&(e.headers={}),null==e.maxRedirects&&(e.maxRedirects=10);var i;e.form&&(i="string"==typeof e.form?e.form:c.stringify(e.form)),e.body&&(i=e.json?JSON.stringify(e.body):e.body),e.json&&(e.headers.accept="application/json"),e.json&&i&&(e.headers["content-type"]="application/json"),e.form&&(e.headers["content-type"]="application/x-www-form-urlencoded"),i&&(e.headers["content-length"]=n.byteLength(i)),delete e.body,delete e.form,i&&!e.method&&(e.method="POST"),e.method&&(e.method=e.method.toUpperCase());var d=Object.keys(e.headers).some(function(e){return"accept-encoding"===e.toLowerCase()});d||(e.headers["accept-encoding"]="gzip, deflate");var h="https:"===e.protocol?a:s,l=h.request(e,function(n){if(n.statusCode>=300&&n.statusCode<400&&"location"in n.headers)return e.url=n.headers.location,o(e),n.resume(),e.maxRedirects-=1,void(e.maxRedirects>0?r(e,t):t(new Error("too many redirects")));var i="function"==typeof f&&"HEAD"!==e.method;t(null,i?f(n):n)});return l.on("error",t),l.end(i),l}function o(e){var t=d.parse(e.url);t.hostname&&(e.hostname=t.hostname),t.port&&(e.port=t.port),t.protocol&&(e.protocol=t.protocol),t.auth&&(e.auth=t.auth),e.path=t.path,delete e.url}t.exports=r;var i=e("simple-concat"),s=e("http"),a=e("https"),u=e("once"),c=e("querystring"),f=e("unzip-response"),d=e("url");r.concat=function(e,t){return r(e,function(n,r){return n?t(n):void i(r,function(n,o){if(n)return t(n);if(e.json)try{o=JSON.parse(o.toString())}catch(n){return t(n,r,o)}t(null,r,o)})})},["get","post","put","patch","head","delete"].forEach(function(e){r[e]=function(t,n){return"string"==typeof t&&(t={url:t}),t.method=e.toUpperCase(),r(t,n)}})}).call(this,e("buffer").Buffer)},{buffer:5,http:28,https:9,once:83,querystring:20,"simple-concat":105,"unzip-response":3,url:34}],107:[function(e,t){(function(n){function r(e){var t=this;if(!(t instanceof r))return new r(e);if(t.channelName=e.initiator?e.channelName||u(20).toString("hex"):null,t._debug("new peer %o",e),e||(e={}),e.allowHalfOpen=!1,null==e.highWaterMark&&(e.highWaterMark=1048576),c.Duplex.call(t,e),t.initiator=e.initiator||!1,t.channelConfig=e.channelConfig||r.channelConfig,t.config=e.config||r.config,t.constraints=e.constraints||r.constraints,t.offerConstraints=e.offerConstraints||{},t.answerConstraints=e.answerConstraints||{},t.reconnectTimer=e.reconnectTimer||!1,t.sdpTransform=e.sdpTransform||function(e){return e},t.stream=e.stream||!1,t.trickle=void 0!==e.trickle?e.trickle:!0,t.destroyed=!1,t.connected=!1,t.remoteAddress=void 0,t.remoteFamily=void 0,t.remotePort=void 0,t.localAddress=void 0,t.localPort=void 0,t._isWrtc=!!e.wrtc,t._wrtc=e.wrtc&&"object"==typeof e.wrtc?e.wrtc:s(),!t._wrtc)throw new Error("undefined"==typeof window?"No WebRTC support: Specify `opts.wrtc` option in this environment":"No WebRTC support: Not a supported browser");if(t._maxBufferedAmount=e.highWaterMark,t._pcReady=!1,t._channelReady=!1,t._iceComplete=!1,t._channel=null,t._pendingCandidates=[],t._chunk=null,t._cb=null,t._interval=null,t._reconnectTimeout=null,t._pc=new t._wrtc.RTCPeerConnection(t.config,t.constraints),t._pc.oniceconnectionstatechange=function(){t._onIceConnectionStateChange()},t._pc.onsignalingstatechange=function(){t._onSignalingStateChange()},t._pc.onicecandidate=function(e){t._onIceCandidate(e)},t.stream&&t._pc.addStream(t.stream),"ontrack"in t._pc?t._pc.ontrack=function(e){t._onTrack(e)}:t._pc.onaddstream=function(e){t._onAddStream(e)},t.initiator){t._setupData({channel:t._pc.createDataChannel(t.channelName,t.channelConfig)});var n=!1;t._pc.onnegotiationneeded=function(){n||t._createOffer(),n=!0},"undefined"!=typeof window&&window.webkitRTCPeerConnection||t._pc.onnegotiationneeded()}else t._pc.ondatachannel=function(e){t._setupData(e)};t.on("finish",function(){t.connected?setTimeout(function(){t._destroy()},100):t.once("connect",function(){setTimeout(function(){t._destroy()},100)})})}function o(){}t.exports=r;var i=e("debug")("simple-peer"),s=e("get-browser-rtc"),a=e("inherits"),u=e("randombytes"),c=e("readable-stream");a(r,c.Duplex),r.WEBRTC_SUPPORT=!!s(),r.config={iceServers:[{url:"stun:23.21.150.121",urls:"stun:23.21.150.121"}]},r.constraints={},r.channelConfig={},Object.defineProperty(r.prototype,"bufferSize",{get:function(){var e=this;return e._channel&&e._channel.bufferedAmount||0}}),r.prototype.address=function(){var e=this;return{port:e.localPort,family:"IPv4",address:e.localAddress}},r.prototype.signal=function(e){function t(e){try{n._pc.addIceCandidate(new n._wrtc.RTCIceCandidate(e),o,function(e){n._onError(e)})}catch(t){n._destroy(new Error("error adding candidate: "+t.message))}}var n=this;if(n.destroyed)throw new Error("cannot signal after peer is destroyed");if("string"==typeof e)try{e=JSON.parse(e)}catch(r){e={}}n._debug("signal()"),e.sdp&&n._pc.setRemoteDescription(new n._wrtc.RTCSessionDescription(e),function(){n.destroyed||("offer"===n._pc.remoteDescription.type&&n._createAnswer(),n._pendingCandidates.forEach(t),n._pendingCandidates=[])},function(e){n._onError(e)}),e.candidate&&(n._pc.remoteDescription?t(e.candidate):n._pendingCandidates.push(e.candidate)),e.sdp||e.candidate||n._destroy(new Error("signal() called with invalid signal data"))},r.prototype.send=function(e){var t=this;n.isBuffer(e)&&t._isWrtc&&(e=new Uint8Array(e));var r=e.length||e.byteLength||e.size;t._channel.send(e),t._debug("write: %d bytes",r)},r.prototype.destroy=function(e){var t=this;t._destroy(null,e)},r.prototype._destroy=function(e,t){var n=this;if(!n.destroyed){if(t&&n.once("close",t),n._debug("destroy (error: %s)",e&&e.message),n.readable=n.writable=!1,n._readableState.ended||n.push(null),n._writableState.finished||n.end(),n.destroyed=!0,n.connected=!1,n._pcReady=!1,n._channelReady=!1,n._chunk=null,n._cb=null,clearInterval(n._interval),clearTimeout(n._reconnectTimeout),n._pc){try{n._pc.close()}catch(e){}n._pc.oniceconnectionstatechange=null,n._pc.onsignalingstatechange=null,n._pc.onicecandidate=null,"ontrack"in n._pc?n._pc.ontrack=null:n._pc.onaddstream=null,n._pc.onnegotiationneeded=null,n._pc.ondatachannel=null}if(n._channel){try{n._channel.close()}catch(e){}n._channel.onmessage=null,n._channel.onopen=null,n._channel.onclose=null}n._pc=null,n._channel=null,e&&n.emit("error",e),n.emit("close")}},r.prototype._setupData=function(e){var t=this;t._channel=e.channel,t.channelName=t._channel.label,t._channel.binaryType="arraybuffer",t._channel.onmessage=function(e){t._onChannelMessage(e)},t._channel.onopen=function(){t._onChannelOpen()},t._channel.onclose=function(){t._onChannelClose()}},r.prototype._read=function(){},r.prototype._write=function(e,t,n){var r=this;if(r.destroyed)return n(new Error("cannot write after peer is destroyed"));if(r.connected){try{r.send(e)}catch(o){return r._onError(o)}r._channel.bufferedAmount>r._maxBufferedAmount?(r._debug("start backpressure: bufferedAmount %d",r._channel.bufferedAmount),r._cb=n):n(null)}else r._debug("write before connect"),r._chunk=e,r._cb=n},r.prototype._createOffer=function(){var e=this;e.destroyed||e._pc.createOffer(function(t){if(!e.destroyed){t.sdp=e.sdpTransform(t.sdp),e._pc.setLocalDescription(t,o,function(t){e._onError(t)});var n=function(){var n=e._pc.localDescription||t;e._debug("signal"),e.emit("signal",{type:n.type,sdp:n.sdp})};e.trickle||e._iceComplete?n():e.once("_iceComplete",n)}},function(t){e._onError(t)},e.offerConstraints)},r.prototype._createAnswer=function(){var e=this;e.destroyed||e._pc.createAnswer(function(t){if(!e.destroyed){t.sdp=e.sdpTransform(t.sdp),e._pc.setLocalDescription(t,o,function(t){e._onError(t)});var n=function(){var n=e._pc.localDescription||t;e._debug("signal"),e.emit("signal",{type:n.type,sdp:n.sdp})};e.trickle||e._iceComplete?n():e.once("_iceComplete",n)}},function(t){e._onError(t)},e.answerConstraints)},r.prototype._onIceConnectionStateChange=function(){var e=this;if(!e.destroyed){var t=e._pc.iceGatheringState,n=e._pc.iceConnectionState;e._debug("iceConnectionStateChange %s %s",t,n),e.emit("iceConnectionStateChange",t,n),("connected"===n||"completed"===n)&&(clearTimeout(e._reconnectTimeout),e._pcReady=!0,e._maybeReady()),"disconnected"===n&&(e.reconnectTimer?(clearTimeout(e._reconnectTimeout),e._reconnectTimeout=setTimeout(function(){e._destroy(); -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 -} - -revLookup['-'.charCodeAt(0)] = 62 -revLookup['_'.charCodeAt(0)] = 63 - -function placeHoldersCount (b64) { - var len = b64.length - if (len % 4 > 0) { - throw new Error('Invalid string. Length must be a multiple of 4') - } - - // the number of equal signs (place holders) - // if there are two placeholders, than the two characters before it - // represent one byte - // if there is only one, then the three characters before it represent 2 bytes - // this is just a cheap hack to not do indexOf twice - return b64[len - 2] === '=' ? 2 : b64[len - 1] === '=' ? 1 : 0 -} - -function byteLength (b64) { - // base64 is 4/3 + up to two characters of the original data - return b64.length * 3 / 4 - placeHoldersCount(b64) -} - -function toByteArray (b64) { - var i, j, l, tmp, placeHolders, arr - var len = b64.length - placeHolders = placeHoldersCount(b64) - - arr = new Arr(len * 3 / 4 - placeHolders) - - // if there are placeholders, only get up to the last complete 4 chars - l = placeHolders > 0 ? len - 4 : len - - var L = 0 - - for (i = 0, j = 0; i < l; i += 4, j += 3) { - tmp = (revLookup[b64.charCodeAt(i)] << 18) | (revLookup[b64.charCodeAt(i + 1)] << 12) | (revLookup[b64.charCodeAt(i + 2)] << 6) | revLookup[b64.charCodeAt(i + 3)] - arr[L++] = (tmp >> 16) & 0xFF - arr[L++] = (tmp >> 8) & 0xFF - arr[L++] = tmp & 0xFF - } - - if (placeHolders === 2) { - tmp = (revLookup[b64.charCodeAt(i)] << 2) | (revLookup[b64.charCodeAt(i + 1)] >> 4) - arr[L++] = tmp & 0xFF - } else if (placeHolders === 1) { - tmp = (revLookup[b64.charCodeAt(i)] << 10) | (revLookup[b64.charCodeAt(i + 1)] << 4) | (revLookup[b64.charCodeAt(i + 2)] >> 2) - arr[L++] = (tmp >> 8) & 0xFF - arr[L++] = tmp & 0xFF - } - - return arr -} - -function tripletToBase64 (num) { - return lookup[num >> 18 & 0x3F] + lookup[num >> 12 & 0x3F] + lookup[num >> 6 & 0x3F] + lookup[num & 0x3F] -} - -function encodeChunk (uint8, start, end) { - var tmp - var output = [] - for (var i = start; i < end; i += 3) { - tmp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2]) - output.push(tripletToBase64(tmp)) - } - return output.join('') -} - -function fromByteArray (uint8) { - var tmp - var len = uint8.length - var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes - var output = '' - var parts = [] - var maxChunkLength = 16383 // must be multiple of 3 - - // go through the array every three bytes, we'll deal with trailing stuff later - for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) { - parts.push(encodeChunk(uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength))) - } - - // pad the end with zeros, but make sure to not forget the extra bytes - if (extraBytes === 1) { - tmp = uint8[len - 1] - output += lookup[tmp >> 2] - output += lookup[(tmp << 4) & 0x3F] - output += '==' - } else if (extraBytes === 2) { - tmp = (uint8[len - 2] << 8) + (uint8[len - 1]) - output += lookup[tmp >> 10] - output += lookup[(tmp >> 4) & 0x3F] - output += lookup[(tmp << 2) & 0x3F] - output += '=' - } - - parts.push(output) - - return parts.join('') -} - -},{}],2:[function(require,module,exports){ - -},{}],3:[function(require,module,exports){ -arguments[4][2][0].apply(exports,arguments) -},{"dup":2}],4:[function(require,module,exports){ -(function (global){ -'use strict'; - -var buffer = require('buffer'); -var Buffer = buffer.Buffer; -var SlowBuffer = buffer.SlowBuffer; -var MAX_LEN = buffer.kMaxLength || 2147483647; -exports.alloc = function alloc(size, fill, encoding) { - if (typeof Buffer.alloc === 'function') { - return Buffer.alloc(size, fill, encoding); - } - if (typeof encoding === 'number') { - throw new TypeError('encoding must not be number'); - } - if (typeof size !== 'number') { - throw new TypeError('size must be a number'); - } - if (size > MAX_LEN) { - throw new RangeError('size is too large'); - } - var enc = encoding; - var _fill = fill; - if (_fill === undefined) { - enc = undefined; - _fill = 0; - } - var buf = new Buffer(size); - if (typeof _fill === 'string') { - var fillBuf = new Buffer(_fill, enc); - var flen = fillBuf.length; - var i = -1; - while (++i < size) { - buf[i] = fillBuf[i % flen]; - } - } else { - buf.fill(_fill); - } - return buf; -} -exports.allocUnsafe = function allocUnsafe(size) { - if (typeof Buffer.allocUnsafe === 'function') { - return Buffer.allocUnsafe(size); - } - if (typeof size !== 'number') { - throw new TypeError('size must be a number'); - } - if (size > MAX_LEN) { - throw new RangeError('size is too large'); - } - return new Buffer(size); -} -exports.from = function from(value, encodingOrOffset, length) { - if (typeof Buffer.from === 'function' && (!global.Uint8Array || Uint8Array.from !== Buffer.from)) { - return Buffer.from(value, encodingOrOffset, length); - } - if (typeof value === 'number') { - throw new TypeError('"value" argument must not be a number'); - } - if (typeof value === 'string') { - return new Buffer(value, encodingOrOffset); - } - if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) { - var offset = encodingOrOffset; - if (arguments.length === 1) { - return new Buffer(value); - } - if (typeof offset === 'undefined') { - offset = 0; - } - var len = length; - if (typeof len === 'undefined') { - len = value.byteLength - offset; - } - if (offset >= value.byteLength) { - throw new RangeError('\'offset\' is out of bounds'); - } - if (len > value.byteLength - offset) { - throw new RangeError('\'length\' is out of bounds'); - } - return new Buffer(value.slice(offset, offset + len)); - } - if (Buffer.isBuffer(value)) { - var out = new Buffer(value.length); - value.copy(out, 0, 0, value.length); - return out; - } - if (value) { - if (Array.isArray(value) || (typeof ArrayBuffer !== 'undefined' && value.buffer instanceof ArrayBuffer) || 'length' in value) { - return new Buffer(value); - } - if (value.type === 'Buffer' && Array.isArray(value.data)) { - return new Buffer(value.data); - } - } - - throw new TypeError('First argument must be a string, Buffer, ' + 'ArrayBuffer, Array, or array-like object.'); -} -exports.allocUnsafeSlow = function allocUnsafeSlow(size) { - if (typeof Buffer.allocUnsafeSlow === 'function') { - return Buffer.allocUnsafeSlow(size); - } - if (typeof size !== 'number') { - throw new TypeError('size must be a number'); - } - if (size >= MAX_LEN) { - throw new RangeError('size is too large'); - } - return new SlowBuffer(size); -} - -}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"buffer":5}],5:[function(require,module,exports){ -(function (global){ -/*! - * 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') -var isArray = require('isarray') - -exports.Buffer = Buffer -exports.SlowBuffer = SlowBuffer -exports.INSPECT_MAX_BYTES = 50 - -/** - * If `Buffer.TYPED_ARRAY_SUPPORT`: - * === true Use Uint8Array implementation (fastest) - * === false Use Object implementation (most compatible, even IE6) - * - * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+, - * Opera 11.6+, iOS 4.2+. - * - * Due to various browser bugs, sometimes the Object implementation will be used even - * when the browser supports typed arrays. - * - * Note: - * - * - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances, - * See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438. - * - * - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function. - * - * - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of - * incorrect length in some situations. - - * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they - * get the Object implementation, which is slower but behaves correctly. - */ -Buffer.TYPED_ARRAY_SUPPORT = global.TYPED_ARRAY_SUPPORT !== undefined - ? global.TYPED_ARRAY_SUPPORT - : typedArraySupport() - -/* - * Export kMaxLength after typed array support is determined. - */ -exports.kMaxLength = kMaxLength() - -function typedArraySupport () { - try { - var arr = new Uint8Array(1) - arr.__proto__ = {__proto__: Uint8Array.prototype, foo: function () { return 42 }} - return arr.foo() === 42 && // typed array instances can be augmented - typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray` - arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray` - } catch (e) { - return false - } -} - -function kMaxLength () { - return Buffer.TYPED_ARRAY_SUPPORT - ? 0x7fffffff - : 0x3fffffff -} - -function createBuffer (that, length) { - if (kMaxLength() < length) { - throw new RangeError('Invalid typed array length') - } - if (Buffer.TYPED_ARRAY_SUPPORT) { - // Return an augmented `Uint8Array` instance, for best performance - that = new Uint8Array(length) - that.__proto__ = Buffer.prototype - } else { - // Fallback: Return an object instance of the Buffer class - if (that === null) { - that = new Buffer(length) - } - that.length = length - } - - return that -} - -/** - * 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) { - if (!Buffer.TYPED_ARRAY_SUPPORT && !(this instanceof Buffer)) { - return new Buffer(arg, encodingOrOffset, length) - } - - // Common case. - if (typeof arg === 'number') { - if (typeof encodingOrOffset === 'string') { - throw new Error( - 'If encoding is specified then the first argument must be a string' - ) - } - return allocUnsafe(this, arg) - } - return from(this, arg, encodingOrOffset, length) -} - -Buffer.poolSize = 8192 // not used by this implementation - -// TODO: Legacy, not needed anymore. Remove in next major version. -Buffer._augment = function (arr) { - arr.__proto__ = Buffer.prototype - return arr -} - -function from (that, value, encodingOrOffset, length) { - if (typeof value === 'number') { - throw new TypeError('"value" argument must not be a number') - } - - if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) { - return fromArrayBuffer(that, value, encodingOrOffset, length) - } - - if (typeof value === 'string') { - return fromString(that, value, encodingOrOffset) - } - - return fromObject(that, 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(null, value, encodingOrOffset, length) -} - -if (Buffer.TYPED_ARRAY_SUPPORT) { - Buffer.prototype.__proto__ = Uint8Array.prototype - Buffer.__proto__ = Uint8Array - if (typeof Symbol !== 'undefined' && Symbol.species && - Buffer[Symbol.species] === Buffer) { - // Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97 - Object.defineProperty(Buffer, Symbol.species, { - value: null, - configurable: true - }) - } -} - -function assertSize (size) { - if (typeof size !== 'number') { - throw new TypeError('"size" argument must be a number') - } else if (size < 0) { - throw new RangeError('"size" argument must not be negative') - } -} - -function alloc (that, size, fill, encoding) { - assertSize(size) - if (size <= 0) { - return createBuffer(that, 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(that, size).fill(fill, encoding) - : createBuffer(that, size).fill(fill) - } - return createBuffer(that, size) -} - -/** - * Creates a new filled Buffer instance. - * alloc(size[, fill[, encoding]]) - **/ -Buffer.alloc = function (size, fill, encoding) { - return alloc(null, size, fill, encoding) -} - -function allocUnsafe (that, size) { - assertSize(size) - that = createBuffer(that, size < 0 ? 0 : checked(size) | 0) - if (!Buffer.TYPED_ARRAY_SUPPORT) { - for (var i = 0; i < size; ++i) { - that[i] = 0 - } - } - return that -} - -/** - * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance. - * */ -Buffer.allocUnsafe = function (size) { - return allocUnsafe(null, size) -} -/** - * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance. - */ -Buffer.allocUnsafeSlow = function (size) { - return allocUnsafe(null, size) -} - -function fromString (that, string, encoding) { - if (typeof encoding !== 'string' || encoding === '') { - encoding = 'utf8' - } - - if (!Buffer.isEncoding(encoding)) { - throw new TypeError('"encoding" must be a valid string encoding') - } - - var length = byteLength(string, encoding) | 0 - that = createBuffer(that, length) - - var actual = that.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') - that = that.slice(0, actual) - } - - return that -} - -function fromArrayLike (that, array) { - var length = array.length < 0 ? 0 : checked(array.length) | 0 - that = createBuffer(that, length) - for (var i = 0; i < length; i += 1) { - that[i] = array[i] & 255 - } - return that -} - -function fromArrayBuffer (that, array, byteOffset, length) { - array.byteLength // this throws if `array` is not a valid ArrayBuffer - - if (byteOffset < 0 || array.byteLength < byteOffset) { - throw new RangeError('\'offset\' is out of bounds') - } - - if (array.byteLength < byteOffset + (length || 0)) { - throw new RangeError('\'length\' is out of bounds') - } - - if (byteOffset === undefined && length === undefined) { - array = new Uint8Array(array) - } else if (length === undefined) { - array = new Uint8Array(array, byteOffset) - } else { - array = new Uint8Array(array, byteOffset, length) - } - - if (Buffer.TYPED_ARRAY_SUPPORT) { - // Return an augmented `Uint8Array` instance, for best performance - that = array - that.__proto__ = Buffer.prototype - } else { - // Fallback: Return an object instance of the Buffer class - that = fromArrayLike(that, array) - } - return that -} - -function fromObject (that, obj) { - if (Buffer.isBuffer(obj)) { - var len = checked(obj.length) | 0 - that = createBuffer(that, len) - - if (that.length === 0) { - return that - } - - obj.copy(that, 0, 0, len) - return that - } - - if (obj) { - if ((typeof ArrayBuffer !== 'undefined' && - obj.buffer instanceof ArrayBuffer) || 'length' in obj) { - if (typeof obj.length !== 'number' || isnan(obj.length)) { - return createBuffer(that, 0) - } - return fromArrayLike(that, obj) - } - - if (obj.type === 'Buffer' && isArray(obj.data)) { - return fromArrayLike(that, obj.data) - } - } - - throw new TypeError('First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.') -} - -function checked (length) { - // Note: cannot use `length < kMaxLength()` here because that fails when - // length is NaN (which is otherwise coerced to zero.) - if (length >= kMaxLength()) { - throw new RangeError('Attempt to allocate Buffer larger than maximum ' + - 'size: 0x' + kMaxLength().toString(16) + ' bytes') - } - return length | 0 -} - -function SlowBuffer (length) { - if (+length != length) { // eslint-disable-line eqeqeq - length = 0 - } - return Buffer.alloc(+length) -} - -Buffer.isBuffer = function isBuffer (b) { - return !!(b != null && b._isBuffer) -} - -Buffer.compare = function compare (a, b) { - if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) { - throw new TypeError('Arguments must be Buffers') - } - - if (a === b) return 0 - - var x = a.length - var y = b.length - - 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 (!isArray(list)) { - throw new TypeError('"list" argument must be an Array of Buffers') - } - - if (list.length === 0) { - return Buffer.alloc(0) - } - - var i - if (length === undefined) { - length = 0 - for (i = 0; i < list.length; ++i) { - length += list[i].length - } - } - - var buffer = Buffer.allocUnsafe(length) - var pos = 0 - for (i = 0; i < list.length; ++i) { - var buf = list[i] - if (!Buffer.isBuffer(buf)) { - throw new TypeError('"list" argument must be an Array of Buffers') - } - buf.copy(buffer, pos) - pos += buf.length - } - return buffer -} - -function byteLength (string, encoding) { - if (Buffer.isBuffer(string)) { - return string.length - } - if (typeof ArrayBuffer !== 'undefined' && typeof ArrayBuffer.isView === 'function' && - (ArrayBuffer.isView(string) || string instanceof ArrayBuffer)) { - return string.byteLength - } - if (typeof string !== 'string') { - string = '' + string - } - - var len = string.length - if (len === 0) return 0 - - // Use a for loop to avoid recursion - var loweredCase = false - for (;;) { - switch (encoding) { - case 'ascii': - case 'latin1': - case 'binary': - return len - case 'utf8': - case 'utf-8': - case undefined: - return utf8ToBytes(string).length - case 'ucs2': - case 'ucs-2': - case 'utf16le': - case 'utf-16le': - return len * 2 - case 'hex': - return len >>> 1 - case 'base64': - return base64ToBytes(string).length - default: - if (loweredCase) return utf8ToBytes(string).length // assume utf8 - encoding = ('' + encoding).toLowerCase() - loweredCase = true - } - } -} -Buffer.byteLength = byteLength - -function slowToString (encoding, start, end) { - var loweredCase = false - - // No need to verify that "this.length <= MAX_UINT32" since it's a read-only - // property of a typed array. - - // This behaves neither like String nor Uint8Array in that we set start/end - // to their upper/lower bounds if the value passed is out of range. - // undefined is handled specially as per ECMA-262 6th Edition, - // Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization. - if (start === undefined || start < 0) { - start = 0 - } - // Return early if start > this.length. Done here to prevent potential uint32 - // coercion fail below. - if (start > this.length) { - return '' - } - - if (end === undefined || end > this.length) { - end = this.length - } - - if (end <= 0) { - return '' - } - - // Force coersion to uint32. This will also coerce falsey/NaN values to 0. - end >>>= 0 - start >>>= 0 - - if (end <= start) { - return '' - } - - if (!encoding) encoding = 'utf8' - - while (true) { - switch (encoding) { - case 'hex': - return hexSlice(this, start, end) - - case 'utf8': - case 'utf-8': - return utf8Slice(this, start, end) - - case 'ascii': - return asciiSlice(this, start, end) - - case 'latin1': - case 'binary': - return latin1Slice(this, start, end) - - case 'base64': - return base64Slice(this, start, end) - - case 'ucs2': - case 'ucs-2': - case 'utf16le': - case 'utf-16le': - return utf16leSlice(this, start, end) - - default: - if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding) - encoding = (encoding + '').toLowerCase() - loweredCase = true - } - } -} - -// The property is used by `Buffer.isBuffer` and `is-buffer` (in Safari 5-7) to detect -// Buffer instances. -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 | 0 - if (length === 0) return '' - if (arguments.length === 0) return utf8Slice(this, 0, length) - return slowToString.apply(this, arguments) -} - -Buffer.prototype.equals = function equals (b) { - if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer') - if (this === b) return true - return Buffer.compare(this, b) === 0 -} - -Buffer.prototype.inspect = function inspect () { - var str = '' - var max = exports.INSPECT_MAX_BYTES - if (this.length > 0) { - str = this.toString('hex', 0, max).match(/.{2}/g).join(' ') - if (this.length > max) str += ' ... ' - } - return '' -} - -Buffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) { - if (!Buffer.isBuffer(target)) { - throw new TypeError('Argument must be a Buffer') - } - - if (start === undefined) { - start = 0 - } - if (end === undefined) { - end = target ? target.length : 0 - } - if (thisStart === undefined) { - thisStart = 0 - } - if (thisEnd === undefined) { - thisEnd = this.length - } - - if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) { - throw new RangeError('out of range index') - } - - if (thisStart >= thisEnd && start >= end) { - return 0 - } - if (thisStart >= thisEnd) { - return -1 - } - if (start >= end) { - return 1 - } - - start >>>= 0 - end >>>= 0 - thisStart >>>= 0 - thisEnd >>>= 0 - - if (this === target) return 0 - - var x = thisEnd - thisStart - var y = end - start - var len = Math.min(x, y) - - var thisCopy = this.slice(thisStart, thisEnd) - var targetCopy = target.slice(start, end) - - for (var i = 0; i < len; ++i) { - if (thisCopy[i] !== targetCopy[i]) { - x = thisCopy[i] - y = targetCopy[i] - break - } - } - - if (x < y) return -1 - if (y < x) return 1 - return 0 -} - -// Finds either the first index of `val` in `buffer` at offset >= `byteOffset`, -// OR the last index of `val` in `buffer` at offset <= `byteOffset`. -// -// Arguments: -// - buffer - a Buffer to search -// - val - a string, Buffer, or number -// - byteOffset - an index into `buffer`; will be clamped to an int32 -// - encoding - an optional encoding, relevant is val is a string -// - dir - true for indexOf, false for lastIndexOf -function bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) { - // Empty buffer means no match - if (buffer.length === 0) return -1 - - // Normalize byteOffset - if (typeof byteOffset === 'string') { - encoding = byteOffset - byteOffset = 0 - } else if (byteOffset > 0x7fffffff) { - byteOffset = 0x7fffffff - } else if (byteOffset < -0x80000000) { - byteOffset = -0x80000000 - } - byteOffset = +byteOffset // Coerce to Number. - if (isNaN(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 (Buffer.TYPED_ARRAY_SUPPORT && - typeof Uint8Array.prototype.indexOf === 'function') { - if (dir) { - return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset) - } else { - return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset) - } - } - return arrayIndexOf(buffer, [ val ], byteOffset, encoding, dir) - } - - throw new TypeError('val must be string, number or Buffer') -} - -function arrayIndexOf (arr, val, byteOffset, encoding, dir) { - var indexSize = 1 - var arrLength = arr.length - var valLength = val.length - - if (encoding !== undefined) { - encoding = String(encoding).toLowerCase() - if (encoding === 'ucs2' || encoding === 'ucs-2' || - encoding === 'utf16le' || encoding === 'utf-16le') { - if (arr.length < 2 || val.length < 2) { - return -1 - } - indexSize = 2 - arrLength /= 2 - valLength /= 2 - byteOffset /= 2 - } - } - - function read (buf, i) { - if (indexSize === 1) { - return buf[i] - } else { - return buf.readUInt16BE(i * indexSize) - } - } - - var i - if (dir) { - var foundIndex = -1 - for (i = byteOffset; i < arrLength; i++) { - if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) { - if (foundIndex === -1) foundIndex = i - if (i - foundIndex + 1 === valLength) return foundIndex * indexSize - } else { - if (foundIndex !== -1) i -= i - foundIndex - foundIndex = -1 - } - } - } else { - if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength - for (i = byteOffset; i >= 0; i--) { - var found = true - for (var j = 0; j < valLength; j++) { - if (read(arr, i + j) !== read(val, j)) { - found = false - break - } - } - if (found) return i - } - } - - return -1 -} - -Buffer.prototype.includes = function includes (val, byteOffset, encoding) { - return this.indexOf(val, byteOffset, encoding) !== -1 -} - -Buffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) { - return bidirectionalIndexOf(this, val, byteOffset, encoding, true) -} - -Buffer.prototype.lastIndexOf = function lastIndexOf (val, byteOffset, encoding) { - return bidirectionalIndexOf(this, val, byteOffset, encoding, false) -} - -function hexWrite (buf, string, offset, length) { - offset = Number(offset) || 0 - var remaining = buf.length - offset - if (!length) { - length = remaining - } else { - length = Number(length) - if (length > remaining) { - length = remaining - } - } - - // must be an even number of digits - var strLen = string.length - if (strLen % 2 !== 0) throw new TypeError('Invalid hex string') - - if (length > strLen / 2) { - length = strLen / 2 - } - for (var i = 0; i < length; ++i) { - var parsed = parseInt(string.substr(i * 2, 2), 16) - if (isNaN(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 - } - // legacy write(string, encoding, offset, length) - remove in v0.13 - } 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 - if (Buffer.TYPED_ARRAY_SUPPORT) { - newBuf = this.subarray(start, end) - newBuf.__proto__ = Buffer.prototype - } else { - var sliceLen = end - start - newBuf = new Buffer(sliceLen, undefined) - for (var i = 0; i < sliceLen; ++i) { - newBuf[i] = this[i + start] - } - } - - return newBuf -} - -/* - * Need to make sure that buffer isn't trying to write out of bounds. - */ -function checkOffset (offset, ext, length) { - if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint') - if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length') -} - -Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) { - offset = offset | 0 - byteLength = byteLength | 0 - if (!noAssert) checkOffset(offset, byteLength, this.length) - - var val = this[offset] - var mul = 1 - var i = 0 - while (++i < byteLength && (mul *= 0x100)) { - val += this[offset + i] * mul - } - - return val -} - -Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) { - offset = offset | 0 - byteLength = byteLength | 0 - if (!noAssert) { - checkOffset(offset, byteLength, this.length) - } - - var val = this[offset + --byteLength] - var mul = 1 - while (byteLength > 0 && (mul *= 0x100)) { - val += this[offset + --byteLength] * mul - } - - return val -} - -Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) { - if (!noAssert) checkOffset(offset, 1, this.length) - return this[offset] -} - -Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 2, this.length) - return this[offset] | (this[offset + 1] << 8) -} - -Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 2, this.length) - return (this[offset] << 8) | this[offset + 1] -} - -Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 4, this.length) - - return ((this[offset]) | - (this[offset + 1] << 8) | - (this[offset + 2] << 16)) + - (this[offset + 3] * 0x1000000) -} - -Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 4, this.length) - - return (this[offset] * 0x1000000) + - ((this[offset + 1] << 16) | - (this[offset + 2] << 8) | - this[offset + 3]) -} - -Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) { - offset = offset | 0 - byteLength = byteLength | 0 - if (!noAssert) checkOffset(offset, byteLength, this.length) - - var val = this[offset] - var mul = 1 - var i = 0 - while (++i < byteLength && (mul *= 0x100)) { - val += this[offset + i] * mul - } - mul *= 0x80 - - if (val >= mul) val -= Math.pow(2, 8 * byteLength) - - return val -} - -Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) { - offset = offset | 0 - byteLength = byteLength | 0 - if (!noAssert) checkOffset(offset, byteLength, this.length) - - var i = byteLength - var mul = 1 - var val = this[offset + --i] - while (i > 0 && (mul *= 0x100)) { - val += this[offset + --i] * mul - } - mul *= 0x80 - - if (val >= mul) val -= Math.pow(2, 8 * byteLength) - - return val -} - -Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) { - if (!noAssert) checkOffset(offset, 1, this.length) - if (!(this[offset] & 0x80)) return (this[offset]) - return ((0xff - this[offset] + 1) * -1) -} - -Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 2, this.length) - var val = this[offset] | (this[offset + 1] << 8) - return (val & 0x8000) ? val | 0xFFFF0000 : val -} - -Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 2, this.length) - var val = this[offset + 1] | (this[offset] << 8) - return (val & 0x8000) ? val | 0xFFFF0000 : val -} - -Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 4, this.length) - - return (this[offset]) | - (this[offset + 1] << 8) | - (this[offset + 2] << 16) | - (this[offset + 3] << 24) -} - -Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 4, this.length) - - return (this[offset] << 24) | - (this[offset + 1] << 16) | - (this[offset + 2] << 8) | - (this[offset + 3]) -} - -Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 4, this.length) - return ieee754.read(this, offset, true, 23, 4) -} - -Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 4, this.length) - return ieee754.read(this, offset, false, 23, 4) -} - -Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 8, this.length) - return ieee754.read(this, offset, true, 52, 8) -} - -Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 8, this.length) - return ieee754.read(this, offset, false, 52, 8) -} - -function checkInt (buf, value, offset, ext, max, min) { - if (!Buffer.isBuffer(buf)) throw new TypeError('"buffer" 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) - if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value) - this[offset] = (value & 0xff) - return offset + 1 -} - -function objectWriteUInt16 (buf, value, offset, littleEndian) { - if (value < 0) value = 0xffff + value + 1 - for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; ++i) { - buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>> - (littleEndian ? i : 1 - i) * 8 - } -} - -Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) - if (Buffer.TYPED_ARRAY_SUPPORT) { - this[offset] = (value & 0xff) - this[offset + 1] = (value >>> 8) - } else { - objectWriteUInt16(this, value, offset, true) - } - return offset + 2 -} - -Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) - if (Buffer.TYPED_ARRAY_SUPPORT) { - this[offset] = (value >>> 8) - this[offset + 1] = (value & 0xff) - } else { - objectWriteUInt16(this, value, offset, false) - } - return offset + 2 -} - -function objectWriteUInt32 (buf, value, offset, littleEndian) { - if (value < 0) value = 0xffffffff + value + 1 - for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; ++i) { - buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff - } -} - -Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0) - if (Buffer.TYPED_ARRAY_SUPPORT) { - this[offset + 3] = (value >>> 24) - this[offset + 2] = (value >>> 16) - this[offset + 1] = (value >>> 8) - this[offset] = (value & 0xff) - } else { - objectWriteUInt32(this, value, offset, true) - } - return offset + 4 -} - -Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0) - if (Buffer.TYPED_ARRAY_SUPPORT) { - this[offset] = (value >>> 24) - this[offset + 1] = (value >>> 16) - this[offset + 2] = (value >>> 8) - this[offset + 3] = (value & 0xff) - } else { - objectWriteUInt32(this, value, offset, false) - } - return offset + 4 -} - -Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) { - var limit = Math.pow(2, 8 * byteLength - 1) - - checkInt(this, value, offset, byteLength, limit - 1, -limit) - } - - var i = 0 - var mul = 1 - var sub = 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 (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value) - if (value < 0) value = 0xff + value + 1 - this[offset] = (value & 0xff) - return offset + 1 -} - -Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000) - if (Buffer.TYPED_ARRAY_SUPPORT) { - this[offset] = (value & 0xff) - this[offset + 1] = (value >>> 8) - } else { - objectWriteUInt16(this, value, offset, true) - } - return offset + 2 -} - -Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000) - if (Buffer.TYPED_ARRAY_SUPPORT) { - this[offset] = (value >>> 8) - this[offset + 1] = (value & 0xff) - } else { - objectWriteUInt16(this, value, offset, false) - } - return offset + 2 -} - -Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) - if (Buffer.TYPED_ARRAY_SUPPORT) { - this[offset] = (value & 0xff) - this[offset + 1] = (value >>> 8) - this[offset + 2] = (value >>> 16) - this[offset + 3] = (value >>> 24) - } else { - objectWriteUInt32(this, value, offset, true) - } - return offset + 4 -} - -Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) - if (value < 0) value = 0xffffffff + value + 1 - if (Buffer.TYPED_ARRAY_SUPPORT) { - this[offset] = (value >>> 24) - this[offset + 1] = (value >>> 16) - this[offset + 2] = (value >>> 8) - this[offset + 3] = (value & 0xff) - } else { - objectWriteUInt32(this, value, offset, false) - } - return offset + 4 -} - -function checkIEEE754 (buf, value, offset, ext, max, min) { - if (offset + ext > buf.length) throw new RangeError('Index out of range') - if (offset < 0) throw new RangeError('Index out of range') -} - -function writeFloat (buf, value, offset, littleEndian, noAssert) { - if (!noAssert) { - checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38) - } - ieee754.write(buf, value, offset, littleEndian, 23, 4) - return offset + 4 -} - -Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) { - return writeFloat(this, value, offset, true, noAssert) -} - -Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) { - return writeFloat(this, value, offset, false, noAssert) -} - -function writeDouble (buf, value, offset, littleEndian, noAssert) { - if (!noAssert) { - checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308) - } - ieee754.write(buf, value, offset, littleEndian, 52, 8) - return offset + 8 -} - -Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) { - return writeDouble(this, value, offset, true, noAssert) -} - -Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) { - return writeDouble(this, value, offset, false, noAssert) -} - -// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length) -Buffer.prototype.copy = function copy (target, targetStart, start, end) { - if (!start) start = 0 - if (!end && end !== 0) end = this.length - if (targetStart >= target.length) targetStart = target.length - if (!targetStart) targetStart = 0 - if (end > 0 && end < start) end = start - - // Copy 0 bytes; we're done - if (end === start) return 0 - if (target.length === 0 || this.length === 0) return 0 - - // Fatal error conditions - if (targetStart < 0) { - throw new RangeError('targetStart out of bounds') - } - if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds') - if (end < 0) throw new RangeError('sourceEnd out of bounds') - - // Are we oob? - if (end > this.length) end = this.length - if (target.length - targetStart < end - start) { - end = target.length - targetStart + start - } - - var len = end - start - var i - - if (this === target && start < targetStart && targetStart < end) { - // descending copy from end - for (i = len - 1; i >= 0; --i) { - target[i + targetStart] = this[i + start] - } - } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) { - // ascending copy from start - for (i = 0; i < len; ++i) { - target[i + targetStart] = this[i + start] - } - } else { - Uint8Array.prototype.set.call( - target, - this.subarray(start, start + len), - targetStart - ) - } - - return len -} - -// Usage: -// buffer.fill(number[, offset[, end]]) -// buffer.fill(buffer[, offset[, end]]) -// buffer.fill(string[, offset[, end]][, encoding]) -Buffer.prototype.fill = function fill (val, start, end, encoding) { - // Handle string cases: - if (typeof val === 'string') { - if (typeof start === 'string') { - encoding = start - start = 0 - end = this.length - } else if (typeof end === 'string') { - encoding = end - end = this.length - } - if (val.length === 1) { - var code = val.charCodeAt(0) - if (code < 256) { - val = code - } - } - if (encoding !== undefined && typeof encoding !== 'string') { - throw new TypeError('encoding must be a string') - } - if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) { - throw new TypeError('Unknown encoding: ' + encoding) - } - } else if (typeof val === 'number') { - val = val & 255 - } - - // Invalid ranges are not set to a default, so can range check early. - if (start < 0 || this.length < start || this.length < end) { - throw new RangeError('Out of range index') - } - - if (end <= start) { - return this - } - - start = start >>> 0 - end = end === undefined ? this.length : end >>> 0 - - if (!val) val = 0 - - var i - if (typeof val === 'number') { - for (i = start; i < end; ++i) { - this[i] = val - } - } else { - var bytes = Buffer.isBuffer(val) - ? val - : utf8ToBytes(new Buffer(val, encoding).toString()) - var len = bytes.length - for (i = 0; i < end - start; ++i) { - this[i + start] = bytes[i % len] - } - } - - return this -} - -// HELPER FUNCTIONS -// ================ - -var INVALID_BASE64_RE = /[^+\/0-9A-Za-z-_]/g - -function base64clean (str) { - // Node strips out invalid characters like \n and \t from the string, base64-js does not - str = stringtrim(str).replace(INVALID_BASE64_RE, '') - // Node converts strings with length < 2 to '' - if (str.length < 2) return '' - // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not - while (str.length % 4 !== 0) { - str = str + '=' - } - return str -} - -function stringtrim (str) { - if (str.trim) return str.trim() - return str.replace(/^\s+|\s+$/g, '') -} - -function toHex (n) { - if (n < 16) return '0' + n.toString(16) - return n.toString(16) -} - -function utf8ToBytes (string, units) { - units = units || Infinity - var codePoint - var length = string.length - var leadSurrogate = null - var bytes = [] - - for (var i = 0; i < length; ++i) { - codePoint = string.charCodeAt(i) - - // is surrogate component - if (codePoint > 0xD7FF && codePoint < 0xE000) { - // last char was a lead - if (!leadSurrogate) { - // no lead yet - if (codePoint > 0xDBFF) { - // unexpected trail - if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) - continue - } else if (i + 1 === length) { - // unpaired lead - if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) - continue - } - - // valid lead - leadSurrogate = codePoint - - continue - } - - // 2 leads in a row - if (codePoint < 0xDC00) { - if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) - leadSurrogate = codePoint - continue - } - - // valid surrogate pair - codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000 - } else if (leadSurrogate) { - // valid bmp char, but last char was a lead - if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) - } - - leadSurrogate = null - - // encode utf8 - if (codePoint < 0x80) { - if ((units -= 1) < 0) break - bytes.push(codePoint) - } else if (codePoint < 0x800) { - if ((units -= 2) < 0) break - bytes.push( - codePoint >> 0x6 | 0xC0, - codePoint & 0x3F | 0x80 - ) - } else if (codePoint < 0x10000) { - if ((units -= 3) < 0) break - bytes.push( - codePoint >> 0xC | 0xE0, - codePoint >> 0x6 & 0x3F | 0x80, - codePoint & 0x3F | 0x80 - ) - } else if (codePoint < 0x110000) { - if ((units -= 4) < 0) break - bytes.push( - codePoint >> 0x12 | 0xF0, - codePoint >> 0xC & 0x3F | 0x80, - codePoint >> 0x6 & 0x3F | 0x80, - codePoint & 0x3F | 0x80 - ) - } else { - throw new Error('Invalid code point') - } - } - - return bytes -} - -function asciiToBytes (str) { - var byteArray = [] - for (var i = 0; i < str.length; ++i) { - // Node's code seems to be doing this and not & 0x7F.. - byteArray.push(str.charCodeAt(i) & 0xFF) - } - return byteArray -} - -function utf16leToBytes (str, units) { - var c, hi, lo - var byteArray = [] - for (var i = 0; i < str.length; ++i) { - if ((units -= 2) < 0) break - - c = str.charCodeAt(i) - hi = c >> 8 - lo = c % 256 - byteArray.push(lo) - byteArray.push(hi) - } - - return byteArray -} - -function base64ToBytes (str) { - return base64.toByteArray(base64clean(str)) -} - -function blitBuffer (src, dst, offset, length) { - for (var i = 0; i < length; ++i) { - if ((i + offset >= dst.length) || (i >= src.length)) break - dst[i + offset] = src[i] - } - return i -} - -function isnan (val) { - return val !== val // eslint-disable-line no-self-compare -} - -}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"base64-js":1,"ieee754":10,"isarray":13}],6:[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", - "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" -} - -},{}],7:[function(require,module,exports){ -(function (Buffer){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -// NOTE: These type checking functions intentionally don't use `instanceof` -// because it is fragile and can be easily faked with `Object.create()`. - -function isArray(arg) { - if (Array.isArray) { - return Array.isArray(arg); - } - return objectToString(arg) === '[object Array]'; -} -exports.isArray = isArray; - -function isBoolean(arg) { - return typeof arg === 'boolean'; -} -exports.isBoolean = isBoolean; - -function isNull(arg) { - return arg === null; -} -exports.isNull = isNull; - -function isNullOrUndefined(arg) { - return arg == null; -} -exports.isNullOrUndefined = isNullOrUndefined; - -function isNumber(arg) { - return typeof arg === 'number'; -} -exports.isNumber = isNumber; - -function isString(arg) { - return typeof arg === 'string'; -} -exports.isString = isString; - -function isSymbol(arg) { - return typeof arg === 'symbol'; -} -exports.isSymbol = isSymbol; - -function isUndefined(arg) { - return arg === void 0; -} -exports.isUndefined = isUndefined; - -function isRegExp(re) { - return objectToString(re) === '[object RegExp]'; -} -exports.isRegExp = isRegExp; - -function isObject(arg) { - return typeof arg === 'object' && arg !== null; -} -exports.isObject = isObject; - -function isDate(d) { - return objectToString(d) === '[object Date]'; -} -exports.isDate = isDate; - -function isError(e) { - return (objectToString(e) === '[object Error]' || e instanceof Error); -} -exports.isError = isError; - -function isFunction(arg) { - return typeof arg === 'function'; -} -exports.isFunction = isFunction; - -function isPrimitive(arg) { - return arg === null || - typeof arg === 'boolean' || - typeof arg === 'number' || - typeof arg === 'string' || - typeof arg === 'symbol' || // ES6 symbol - typeof arg === 'undefined'; -} -exports.isPrimitive = isPrimitive; - -exports.isBuffer = Buffer.isBuffer; - -function objectToString(o) { - return Object.prototype.toString.call(o); -} - -}).call(this,{"isBuffer":require("../../is-buffer/index.js")}) -},{"../../is-buffer/index.js":12}],8:[function(require,module,exports){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -function EventEmitter() { - this._events = this._events || {}; - this._maxListeners = this._maxListeners || undefined; -} -module.exports = EventEmitter; - -// Backwards-compat with node 0.10.x -EventEmitter.EventEmitter = EventEmitter; - -EventEmitter.prototype._events = undefined; -EventEmitter.prototype._maxListeners = undefined; - -// By default EventEmitters will print a warning if more than 10 listeners are -// added to it. This is a useful default which helps finding memory leaks. -EventEmitter.defaultMaxListeners = 10; - -// Obviously not all Emitters should be limited to 10. This function allows -// that to be increased. Set to zero for unlimited. -EventEmitter.prototype.setMaxListeners = function(n) { - if (!isNumber(n) || n < 0 || isNaN(n)) - throw TypeError('n must be a positive number'); - this._maxListeners = n; - return this; -}; - -EventEmitter.prototype.emit = function(type) { - var er, handler, len, args, i, listeners; - - if (!this._events) - this._events = {}; - - // If there is no 'error' event listener then throw. - if (type === 'error') { - if (!this._events.error || - (isObject(this._events.error) && !this._events.error.length)) { - er = arguments[1]; - if (er instanceof Error) { - throw er; // Unhandled 'error' event - } else { - // At least give some kind of context to the user - var err = new Error('Uncaught, unspecified "error" event. (' + er + ')'); - err.context = er; - throw err; - } - } - } - - handler = this._events[type]; - - if (isUndefined(handler)) - return false; - - if (isFunction(handler)) { - switch (arguments.length) { - // fast cases - case 1: - handler.call(this); - break; - case 2: - handler.call(this, arguments[1]); - break; - case 3: - handler.call(this, arguments[1], arguments[2]); - break; - // slower - default: - args = Array.prototype.slice.call(arguments, 1); - handler.apply(this, args); - } - } else if (isObject(handler)) { - args = Array.prototype.slice.call(arguments, 1); - listeners = handler.slice(); - len = listeners.length; - for (i = 0; i < len; i++) - listeners[i].apply(this, args); - } - - return true; -}; - -EventEmitter.prototype.addListener = function(type, listener) { - var m; - - if (!isFunction(listener)) - throw TypeError('listener must be a function'); - - if (!this._events) - this._events = {}; - - // To avoid recursion in the case that type === "newListener"! Before - // adding it to the listeners, first emit "newListener". - if (this._events.newListener) - this.emit('newListener', type, - isFunction(listener.listener) ? - listener.listener : listener); - - if (!this._events[type]) - // Optimize the case of one listener. Don't need the extra array object. - this._events[type] = listener; - else if (isObject(this._events[type])) - // If we've already got an array, just append. - this._events[type].push(listener); - else - // Adding the second element, need to change to array. - this._events[type] = [this._events[type], listener]; - - // Check for listener leak - if (isObject(this._events[type]) && !this._events[type].warned) { - if (!isUndefined(this._maxListeners)) { - m = this._maxListeners; - } else { - m = EventEmitter.defaultMaxListeners; - } - - if (m && m > 0 && this._events[type].length > m) { - this._events[type].warned = true; - console.error('(node) warning: possible EventEmitter memory ' + - 'leak detected. %d listeners added. ' + - 'Use emitter.setMaxListeners() to increase limit.', - this._events[type].length); - if (typeof console.trace === 'function') { - // not supported in IE 10 - console.trace(); - } - } - } - - return this; -}; - -EventEmitter.prototype.on = EventEmitter.prototype.addListener; - -EventEmitter.prototype.once = function(type, listener) { - if (!isFunction(listener)) - throw TypeError('listener must be a function'); - - var fired = false; - - function g() { - this.removeListener(type, g); - - if (!fired) { - fired = true; - listener.apply(this, arguments); - } - } - - g.listener = listener; - this.on(type, g); - - return this; -}; - -// emits a 'removeListener' event iff the listener was removed -EventEmitter.prototype.removeListener = function(type, listener) { - var list, position, length, i; - - if (!isFunction(listener)) - throw TypeError('listener must be a function'); - - if (!this._events || !this._events[type]) - return this; - - list = this._events[type]; - length = list.length; - position = -1; - - if (list === listener || - (isFunction(list.listener) && list.listener === listener)) { - delete this._events[type]; - if (this._events.removeListener) - this.emit('removeListener', type, listener); - - } else if (isObject(list)) { - for (i = length; i-- > 0;) { - if (list[i] === listener || - (list[i].listener && list[i].listener === listener)) { - position = i; - break; - } - } - - if (position < 0) - return this; - - if (list.length === 1) { - list.length = 0; - delete this._events[type]; - } else { - list.splice(position, 1); - } - - if (this._events.removeListener) - this.emit('removeListener', type, listener); - } - - return this; -}; - -EventEmitter.prototype.removeAllListeners = function(type) { - var key, listeners; - - if (!this._events) - return this; - - // not listening for removeListener, no need to emit - if (!this._events.removeListener) { - if (arguments.length === 0) - this._events = {}; - else if (this._events[type]) - delete this._events[type]; - return this; - } - - // emit removeListener for all listeners on all events - if (arguments.length === 0) { - for (key in this._events) { - if (key === 'removeListener') continue; - this.removeAllListeners(key); - } - this.removeAllListeners('removeListener'); - this._events = {}; - return this; - } - - listeners = this._events[type]; - - if (isFunction(listeners)) { - this.removeListener(type, listeners); - } else if (listeners) { - // LIFO order - while (listeners.length) - this.removeListener(type, listeners[listeners.length - 1]); - } - delete this._events[type]; - - return this; -}; - -EventEmitter.prototype.listeners = function(type) { - var ret; - if (!this._events || !this._events[type]) - ret = []; - else if (isFunction(this._events[type])) - ret = [this._events[type]]; - else - ret = this._events[type].slice(); - return ret; -}; - -EventEmitter.prototype.listenerCount = function(type) { - if (this._events) { - var evlistener = this._events[type]; - - if (isFunction(evlistener)) - return 1; - else if (evlistener) - return evlistener.length; - } - return 0; -}; - -EventEmitter.listenerCount = function(emitter, type) { - return emitter.listenerCount(type); -}; - -function isFunction(arg) { - return typeof arg === 'function'; -} - -function isNumber(arg) { - return typeof arg === 'number'; -} - -function isObject(arg) { - return typeof arg === 'object' && arg !== null; -} - -function isUndefined(arg) { - return arg === void 0; -} - -},{}],9:[function(require,module,exports){ -var http = require('http'); - -var https = module.exports; - -for (var key in http) { - if (http.hasOwnProperty(key)) https[key] = http[key]; -}; - -https.request = function (params, cb) { - if (!params) params = {}; - params.scheme = 'https'; - params.protocol = 'https:'; - return http.request.call(this, params, cb); -} - -},{"http":28}],10:[function(require,module,exports){ -exports.read = function (buffer, offset, isLE, mLen, nBytes) { - var e, m - var eLen = nBytes * 8 - mLen - 1 - var eMax = (1 << eLen) - 1 - var eBias = eMax >> 1 - var nBits = -7 - var i = isLE ? (nBytes - 1) : 0 - var d = isLE ? -1 : 1 - var s = buffer[offset + i] - - i += d - - e = s & ((1 << (-nBits)) - 1) - s >>= (-nBits) - nBits += eLen - for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {} - - m = e & ((1 << (-nBits)) - 1) - e >>= (-nBits) - nBits += mLen - for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {} - - if (e === 0) { - e = 1 - eBias - } else if (e === eMax) { - return m ? NaN : ((s ? -1 : 1) * Infinity) - } else { - m = m + Math.pow(2, mLen) - e = e - eBias - } - return (s ? -1 : 1) * m * Math.pow(2, e - mLen) -} - -exports.write = function (buffer, value, offset, isLE, mLen, nBytes) { - var e, m, c - var eLen = nBytes * 8 - mLen - 1 - var eMax = (1 << eLen) - 1 - var eBias = eMax >> 1 - var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0) - var i = isLE ? 0 : (nBytes - 1) - var d = isLE ? 1 : -1 - var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0 - - value = Math.abs(value) - - if (isNaN(value) || value === Infinity) { - m = isNaN(value) ? 1 : 0 - e = eMax - } else { - e = Math.floor(Math.log(value) / Math.LN2) - if (value * (c = Math.pow(2, -e)) < 1) { - e-- - c *= 2 - } - if (e + eBias >= 1) { - value += rt / c - } else { - value += rt * Math.pow(2, 1 - eBias) - } - if (value * c >= 2) { - e++ - c /= 2 - } - - if (e + eBias >= eMax) { - m = 0 - e = eMax - } else if (e + eBias >= 1) { - m = (value * c - 1) * Math.pow(2, mLen) - e = e + eBias - } else { - m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen) - e = 0 - } - } - - for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {} - - e = (e << mLen) | m - eLen += mLen - for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {} - - buffer[offset + i - d] |= s * 128 -} - -},{}],11:[function(require,module,exports){ -if (typeof Object.create === 'function') { - // implementation from standard node.js 'util' module - module.exports = function inherits(ctor, superCtor) { - ctor.super_ = superCtor - ctor.prototype = Object.create(superCtor.prototype, { - constructor: { - value: ctor, - enumerable: false, - writable: true, - configurable: true - } - }); - }; -} else { - // old school shim for old browsers - module.exports = function inherits(ctor, superCtor) { - ctor.super_ = superCtor - var TempCtor = function () {} - TempCtor.prototype = superCtor.prototype - ctor.prototype = new TempCtor() - ctor.prototype.constructor = ctor - } -} - -},{}],12:[function(require,module,exports){ -/*! - * Determine if an object is a Buffer - * - * @author Feross Aboukhadijeh - * @license MIT - */ - -// The _isBuffer check is for Safari 5-7 support, because it's missing -// Object.prototype.constructor. Remove this eventually -module.exports = function (obj) { - return obj != null && (isBuffer(obj) || isSlowBuffer(obj) || !!obj._isBuffer) -} - -function isBuffer (obj) { - return !!obj.constructor && typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj) -} - -// For Node v0.10 support. Remove this eventually. -function isSlowBuffer (obj) { - return typeof obj.readFloatLE === 'function' && typeof obj.slice === 'function' && isBuffer(obj.slice(0, 0)) -} - -},{}],13:[function(require,module,exports){ -var toString = {}.toString; - -module.exports = Array.isArray || function (arr) { - return toString.call(arr) == '[object Array]'; -}; - -},{}],14:[function(require,module,exports){ -(function (process){ -// 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. - -// resolves . and .. elements in a path array with directory names there -// must be no slashes, empty elements, or device names (c:\) in the array -// (so also no leading and trailing slashes - it does not distinguish -// relative and absolute paths) -function normalizeArray(parts, allowAboveRoot) { - // if the path tries to go above the root, `up` ends up > 0 - var up = 0; - for (var i = parts.length - 1; i >= 0; i--) { - var last = parts[i]; - if (last === '.') { - parts.splice(i, 1); - } else if (last === '..') { - parts.splice(i, 1); - up++; - } else if (up) { - parts.splice(i, 1); - up--; - } - } - - // if the path is allowed to go above the root, restore leading ..s - if (allowAboveRoot) { - for (; up--; up) { - parts.unshift('..'); - } - } - - return parts; -} - -// Split a filename into [root, dir, basename, ext], unix version -// 'root' is just a slash, or nothing. -var splitPathRe = - /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/; -var splitPath = function(filename) { - return splitPathRe.exec(filename).slice(1); -}; - -// path.resolve([from ...], to) -// posix version -exports.resolve = function() { - var resolvedPath = '', - resolvedAbsolute = false; - - for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) { - var path = (i >= 0) ? arguments[i] : process.cwd(); - - // Skip empty and invalid entries - if (typeof path !== 'string') { - throw new TypeError('Arguments to path.resolve must be strings'); - } else if (!path) { - continue; - } - - resolvedPath = path + '/' + resolvedPath; - resolvedAbsolute = path.charAt(0) === '/'; - } - - // 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 = normalizeArray(filter(resolvedPath.split('/'), function(p) { - return !!p; - }), !resolvedAbsolute).join('/'); - - return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.'; -}; - -// path.normalize(path) -// posix version -exports.normalize = function(path) { - var isAbsolute = exports.isAbsolute(path), - trailingSlash = substr(path, -1) === '/'; - - // Normalize the path - path = normalizeArray(filter(path.split('/'), function(p) { - return !!p; - }), !isAbsolute).join('/'); - - if (!path && !isAbsolute) { - path = '.'; - } - if (path && trailingSlash) { - path += '/'; - } - - return (isAbsolute ? '/' : '') + path; -}; - -// posix version -exports.isAbsolute = function(path) { - return path.charAt(0) === '/'; -}; - -// posix version -exports.join = function() { - var paths = Array.prototype.slice.call(arguments, 0); - return exports.normalize(filter(paths, function(p, index) { - if (typeof p !== 'string') { - throw new TypeError('Arguments to path.join must be strings'); - } - return p; - }).join('/')); -}; - - -// path.relative(from, to) -// posix version -exports.relative = function(from, to) { - from = exports.resolve(from).substr(1); - to = exports.resolve(to).substr(1); - - function trim(arr) { - var start = 0; - for (; start < arr.length; start++) { - if (arr[start] !== '') break; - } - - var end = arr.length - 1; - for (; end >= 0; end--) { - if (arr[end] !== '') break; - } - - if (start > end) return []; - return arr.slice(start, end - start + 1); - } - - var fromParts = trim(from.split('/')); - var toParts = trim(to.split('/')); - - var length = Math.min(fromParts.length, toParts.length); - var samePartsLength = length; - for (var i = 0; i < length; i++) { - if (fromParts[i] !== toParts[i]) { - samePartsLength = i; - break; - } - } - - var outputParts = []; - for (var i = samePartsLength; i < fromParts.length; i++) { - outputParts.push('..'); - } - - outputParts = outputParts.concat(toParts.slice(samePartsLength)); - - return outputParts.join('/'); -}; - -exports.sep = '/'; -exports.delimiter = ':'; - -exports.dirname = function(path) { - var result = splitPath(path), - root = result[0], - dir = result[1]; - - if (!root && !dir) { - // No dirname whatsoever - return '.'; - } - - if (dir) { - // It has a dirname, strip trailing slash - dir = dir.substr(0, dir.length - 1); - } - - return root + dir; -}; - - -exports.basename = function(path, ext) { - var f = splitPath(path)[2]; - // TODO: make this comparison case-insensitive on windows? - if (ext && f.substr(-1 * ext.length) === ext) { - f = f.substr(0, f.length - ext.length); - } - return f; -}; - - -exports.extname = function(path) { - return splitPath(path)[3]; -}; - -function filter (xs, f) { - if (xs.filter) return xs.filter(f); - var res = []; - for (var i = 0; i < xs.length; i++) { - if (f(xs[i], i, xs)) res.push(xs[i]); - } - return res; -} - -// String.prototype.substr - negative index don't work in IE8 -var substr = 'ab'.substr(-1) === 'b' - ? function (str, start, len) { return str.substr(start, len) } - : function (str, start, len) { - if (start < 0) start = str.length + start; - return str.substr(start, len); - } -; - -}).call(this,require('_process')) -},{"_process":16}],15:[function(require,module,exports){ -(function (process){ -'use strict'; - -if (!process.version || - process.version.indexOf('v0.') === 0 || - process.version.indexOf('v1.') === 0 && process.version.indexOf('v1.8.') !== 0) { - module.exports = nextTick; -} else { - module.exports = process.nextTick; -} - -function nextTick(fn, arg1, arg2, arg3) { - if (typeof fn !== 'function') { - throw new TypeError('"callback" argument must be a function'); - } - var len = arguments.length; - var args, i; - switch (len) { - case 0: - case 1: - return process.nextTick(fn); - case 2: - return process.nextTick(function afterTickOne() { - fn.call(null, arg1); - }); - case 3: - return process.nextTick(function afterTickTwo() { - fn.call(null, arg1, arg2); - }); - case 4: - return process.nextTick(function afterTickThree() { - fn.call(null, arg1, arg2, arg3); - }); - default: - args = new Array(len - 1); - i = 0; - while (i < args.length) { - args[i++] = arguments[i]; - } - return process.nextTick(function afterTick() { - fn.apply(null, args); - }); - } -} - -}).call(this,require('_process')) -},{"_process":16}],16:[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.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; }; - -},{}],17:[function(require,module,exports){ -(function (global){ -/*! https://mths.be/punycode v1.4.1 by @mathias */ -;(function(root) { - - /** Detect free variables */ - var freeExports = typeof exports == 'object' && exports && - !exports.nodeType && exports; - var freeModule = typeof module == 'object' && module && - !module.nodeType && module; - var freeGlobal = typeof global == 'object' && global; - if ( - freeGlobal.global === freeGlobal || - freeGlobal.window === freeGlobal || - freeGlobal.self === freeGlobal - ) { - root = freeGlobal; - } - - /** - * The `punycode` object. - * @name punycode - * @type Object - */ - var punycode, - - /** Highest positive signed 32-bit float value */ - maxInt = 2147483647, // aka. 0x7FFFFFFF or 2^31-1 - - /** Bootstring parameters */ - base = 36, - tMin = 1, - tMax = 26, - skew = 38, - damp = 700, - initialBias = 72, - initialN = 128, // 0x80 - delimiter = '-', // '\x2D' - - /** Regular expressions */ - regexPunycode = /^xn--/, - regexNonASCII = /[^\x20-\x7E]/, // unprintable ASCII chars + non-ASCII chars - regexSeparators = /[\x2E\u3002\uFF0E\uFF61]/g, // RFC 3490 separators - - /** Error messages */ - errors = { - 'overflow': 'Overflow: input needs wider integers to process', - 'not-basic': 'Illegal input >= 0x80 (not a basic code point)', - 'invalid-input': 'Invalid input' - }, - - /** Convenience shortcuts */ - baseMinusTMin = base - tMin, - floor = Math.floor, - stringFromCharCode = String.fromCharCode, - - /** Temporary variable */ - key; - - /*--------------------------------------------------------------------------*/ - - /** - * A generic error utility function. - * @private - * @param {String} type The error type. - * @returns {Error} Throws a `RangeError` with the applicable error message. - */ - function error(type) { - throw new RangeError(errors[type]); - } - - /** - * A generic `Array#map` utility function. - * @private - * @param {Array} array The array to iterate over. - * @param {Function} callback The function that gets called for every array - * item. - * @returns {Array} A new array of values returned by the callback function. - */ - function map(array, fn) { - var length = array.length; - var result = []; - while (length--) { - result[length] = fn(array[length]); - } - return result; - } - - /** - * A simple `Array#map`-like wrapper to work with domain name strings or email - * addresses. - * @private - * @param {String} domain The domain name or email address. - * @param {Function} callback The function that gets called for every - * character. - * @returns {Array} A new string of characters returned by the callback - * function. - */ - function mapDomain(string, fn) { - var parts = string.split('@'); - var result = ''; - if (parts.length > 1) { - // In email addresses, only the domain name should be punycoded. Leave - // the local part (i.e. everything up to `@`) intact. - result = parts[0] + '@'; - string = parts[1]; - } - // Avoid `split(regex)` for IE8 compatibility. See #17. - string = string.replace(regexSeparators, '\x2E'); - var labels = string.split('.'); - var encoded = map(labels, fn).join('.'); - return result + encoded; - } - - /** - * Creates an array containing the numeric code points of each Unicode - * character in the string. While JavaScript uses UCS-2 internally, - * this function will convert a pair of surrogate halves (each of which - * UCS-2 exposes as separate characters) into a single code point, - * matching UTF-16. - * @see `punycode.ucs2.encode` - * @see - * @memberOf punycode.ucs2 - * @name decode - * @param {String} string The Unicode input string (UCS-2). - * @returns {Array} The new array of code points. - */ - function ucs2decode(string) { - var output = [], - counter = 0, - length = string.length, - value, - extra; - while (counter < length) { - value = string.charCodeAt(counter++); - if (value >= 0xD800 && value <= 0xDBFF && counter < length) { - // high surrogate, and there is a next character - extra = string.charCodeAt(counter++); - if ((extra & 0xFC00) == 0xDC00) { // low surrogate - output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000); - } else { - // unmatched surrogate; only append this code unit, in case the next - // code unit is the high surrogate of a surrogate pair - output.push(value); - counter--; - } - } else { - output.push(value); - } - } - return output; - } - - /** - * Creates a string based on an array of numeric code points. - * @see `punycode.ucs2.decode` - * @memberOf punycode.ucs2 - * @name encode - * @param {Array} codePoints The array of numeric code points. - * @returns {String} The new Unicode string (UCS-2). - */ - function ucs2encode(array) { - return map(array, function(value) { - var output = ''; - if (value > 0xFFFF) { - value -= 0x10000; - output += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800); - value = 0xDC00 | value & 0x3FF; - } - output += stringFromCharCode(value); - return output; - }).join(''); - } - - /** - * Converts a basic code point into a digit/integer. - * @see `digitToBasic()` - * @private - * @param {Number} codePoint The basic numeric code point value. - * @returns {Number} The numeric value of a basic code point (for use in - * representing integers) in the range `0` to `base - 1`, or `base` if - * the code point does not represent a value. - */ - function basicToDigit(codePoint) { - if (codePoint - 48 < 10) { - return codePoint - 22; - } - if (codePoint - 65 < 26) { - return codePoint - 65; - } - if (codePoint - 97 < 26) { - return codePoint - 97; - } - return base; - } - - /** - * Converts a digit/integer into a basic code point. - * @see `basicToDigit()` - * @private - * @param {Number} digit The numeric value of a basic code point. - * @returns {Number} The basic code point whose value (when used for - * representing integers) is `digit`, which needs to be in the range - * `0` to `base - 1`. If `flag` is non-zero, the uppercase form is - * used; else, the lowercase form is used. The behavior is undefined - * if `flag` is non-zero and `digit` has no uppercase form. - */ - function digitToBasic(digit, flag) { - // 0..25 map to ASCII a..z or A..Z - // 26..35 map to ASCII 0..9 - return digit + 22 + 75 * (digit < 26) - ((flag != 0) << 5); - } - - /** - * Bias adaptation function as per section 3.4 of RFC 3492. - * https://tools.ietf.org/html/rfc3492#section-3.4 - * @private - */ - function adapt(delta, numPoints, firstTime) { - var k = 0; - delta = firstTime ? floor(delta / damp) : delta >> 1; - delta += floor(delta / numPoints); - for (/* no initialization */; delta > baseMinusTMin * tMax >> 1; k += base) { - delta = floor(delta / baseMinusTMin); - } - return floor(k + (baseMinusTMin + 1) * delta / (delta + skew)); - } - - /** - * Converts a Punycode string of ASCII-only symbols to a string of Unicode - * symbols. - * @memberOf punycode - * @param {String} input The Punycode string of ASCII-only symbols. - * @returns {String} The resulting string of Unicode symbols. - */ - function decode(input) { - // Don't use UCS-2 - var output = [], - inputLength = input.length, - out, - i = 0, - n = initialN, - bias = initialBias, - basic, - j, - index, - oldi, - w, - k, - digit, - t, - /** Cached calculation results */ - baseMinusT; - - // Handle the basic code points: let `basic` be the number of input code - // points before the last delimiter, or `0` if there is none, then copy - // the first basic code points to the output. - - basic = input.lastIndexOf(delimiter); - if (basic < 0) { - basic = 0; - } - - for (j = 0; j < basic; ++j) { - // if it's not a basic code point - if (input.charCodeAt(j) >= 0x80) { - error('not-basic'); - } - output.push(input.charCodeAt(j)); - } - - // Main decoding loop: start just after the last delimiter if any basic code - // points were copied; start at the beginning otherwise. - - for (index = basic > 0 ? basic + 1 : 0; index < inputLength; /* no final expression */) { - - // `index` is the index of the next character to be consumed. - // Decode a generalized variable-length integer into `delta`, - // which gets added to `i`. The overflow checking is easier - // if we increase `i` as we go, then subtract off its starting - // value at the end to obtain `delta`. - for (oldi = i, w = 1, k = base; /* no condition */; k += base) { - - if (index >= inputLength) { - error('invalid-input'); - } - - digit = basicToDigit(input.charCodeAt(index++)); - - if (digit >= base || digit > floor((maxInt - i) / w)) { - error('overflow'); - } - - i += digit * w; - t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias); - - if (digit < t) { - break; - } - - baseMinusT = base - t; - if (w > floor(maxInt / baseMinusT)) { - error('overflow'); - } - - w *= baseMinusT; - - } - - out = output.length + 1; - bias = adapt(i - oldi, out, oldi == 0); - - // `i` was supposed to wrap around from `out` to `0`, - // incrementing `n` each time, so we'll fix that now: - if (floor(i / out) > maxInt - n) { - error('overflow'); - } - - n += floor(i / out); - i %= out; - - // Insert `n` at position `i` of the output - output.splice(i++, 0, n); - - } - - return ucs2encode(output); - } - - /** - * Converts a string of Unicode symbols (e.g. a domain name label) to a - * Punycode string of ASCII-only symbols. - * @memberOf punycode - * @param {String} input The string of Unicode symbols. - * @returns {String} The resulting Punycode string of ASCII-only symbols. - */ - function encode(input) { - var n, - delta, - handledCPCount, - basicLength, - bias, - j, - m, - q, - k, - t, - currentValue, - output = [], - /** `inputLength` will hold the number of code points in `input`. */ - inputLength, - /** Cached calculation results */ - handledCPCountPlusOne, - baseMinusT, - qMinusT; - - // Convert the input in UCS-2 to Unicode - input = ucs2decode(input); - - // Cache the length - inputLength = input.length; - - // Initialize the state - n = initialN; - delta = 0; - bias = initialBias; - - // Handle the basic code points - for (j = 0; j < inputLength; ++j) { - currentValue = input[j]; - if (currentValue < 0x80) { - output.push(stringFromCharCode(currentValue)); - } - } - - handledCPCount = basicLength = output.length; - - // `handledCPCount` is the number of code points that have been handled; - // `basicLength` is the number of basic code points. - - // Finish the basic string - if it is not empty - with a delimiter - if (basicLength) { - output.push(delimiter); - } - - // Main encoding loop: - while (handledCPCount < inputLength) { - - // All non-basic code points < n have been handled already. Find the next - // larger one: - for (m = maxInt, j = 0; j < inputLength; ++j) { - currentValue = input[j]; - if (currentValue >= n && currentValue < m) { - m = currentValue; - } - } - - // Increase `delta` enough to advance the decoder's state to , - // but guard against overflow - handledCPCountPlusOne = handledCPCount + 1; - if (m - n > floor((maxInt - delta) / handledCPCountPlusOne)) { - error('overflow'); - } - - delta += (m - n) * handledCPCountPlusOne; - n = m; - - for (j = 0; j < inputLength; ++j) { - currentValue = input[j]; - - if (currentValue < n && ++delta > maxInt) { - error('overflow'); - } - - if (currentValue == n) { - // Represent delta as a generalized variable-length integer - for (q = delta, k = base; /* no condition */; k += base) { - t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias); - if (q < t) { - break; - } - qMinusT = q - t; - baseMinusT = base - t; - output.push( - stringFromCharCode(digitToBasic(t + qMinusT % baseMinusT, 0)) - ); - q = floor(qMinusT / baseMinusT); - } - - output.push(stringFromCharCode(digitToBasic(q, 0))); - bias = adapt(delta, handledCPCountPlusOne, handledCPCount == basicLength); - delta = 0; - ++handledCPCount; - } - } - - ++delta; - ++n; - - } - return output.join(''); - } - - /** - * Converts a Punycode string representing a domain name or an email address - * to Unicode. Only the Punycoded parts of the input will be converted, i.e. - * it doesn't matter if you call it on a string that has already been - * converted to Unicode. - * @memberOf punycode - * @param {String} input The Punycoded domain name or email address to - * convert to Unicode. - * @returns {String} The Unicode representation of the given Punycode - * string. - */ - function toUnicode(input) { - return mapDomain(input, function(string) { - return regexPunycode.test(string) - ? decode(string.slice(4).toLowerCase()) - : string; - }); - } - - /** - * Converts a Unicode string representing a domain name or an email address to - * Punycode. Only the non-ASCII parts of the domain name will be converted, - * i.e. it doesn't matter if you call it with a domain that's already in - * ASCII. - * @memberOf punycode - * @param {String} input The domain name or email address to convert, as a - * Unicode string. - * @returns {String} The Punycode representation of the given domain name or - * email address. - */ - function toASCII(input) { - return mapDomain(input, function(string) { - return regexNonASCII.test(string) - ? 'xn--' + encode(string) - : string; - }); - } - - /*--------------------------------------------------------------------------*/ - - /** Define the public API */ - punycode = { - /** - * A string representing the current Punycode.js version number. - * @memberOf punycode - * @type String - */ - 'version': '1.4.1', - /** - * An object of methods to convert from JavaScript's internal character - * representation (UCS-2) to Unicode code points, and back. - * @see - * @memberOf punycode - * @type Object - */ - 'ucs2': { - 'decode': ucs2decode, - 'encode': ucs2encode - }, - 'decode': decode, - 'encode': encode, - 'toASCII': toASCII, - 'toUnicode': toUnicode - }; - - /** Expose `punycode` */ - // Some AMD build optimizers, like r.js, check for specific condition patterns - // like the following: - if ( - typeof define == 'function' && - typeof define.amd == 'object' && - define.amd - ) { - define('punycode', function() { - return punycode; - }); - } else if (freeExports && freeModule) { - if (module.exports == freeExports) { - // in Node.js, io.js, or RingoJS v0.8.0+ - freeModule.exports = punycode; - } else { - // in Narwhal or RingoJS v0.7.0- - for (key in punycode) { - punycode.hasOwnProperty(key) && (freeExports[key] = punycode[key]); - } - } - } else { - // in Rhino or a web browser - root.punycode = punycode; - } - -}(this)); - -}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{}],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. - -'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]'; -}; - -},{}],19:[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; -}; - -},{}],20:[function(require,module,exports){ -'use strict'; - -exports.decode = exports.parse = require('./decode'); -exports.encode = exports.stringify = require('./encode'); - -},{"./decode":18,"./encode":19}],21:[function(require,module,exports){ -// a duplex stream is just a stream that is both readable and writable. -// Since JS doesn't have multiple prototypal inheritance, this class -// prototypally inherits from Readable, and then parasitically from -// Writable. - -'use strict'; - -/**/ - -var objectKeys = Object.keys || function (obj) { - var keys = []; - for (var key in obj) { - keys.push(key); - }return keys; -}; -/**/ - -module.exports = Duplex; - -/**/ -var processNextTick = require('process-nextick-args'); -/**/ - -/**/ -var util = require('core-util-is'); -util.inherits = require('inherits'); -/**/ - -var Readable = require('./_stream_readable'); -var Writable = require('./_stream_writable'); - -util.inherits(Duplex, Readable); - -var keys = objectKeys(Writable.prototype); -for (var v = 0; v < keys.length; v++) { - var method = keys[v]; - if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable.prototype[method]; -} - -function Duplex(options) { - if (!(this instanceof Duplex)) return new Duplex(options); - - Readable.call(this, options); - Writable.call(this, options); - - if (options && options.readable === false) this.readable = false; - - if (options && options.writable === false) this.writable = false; - - this.allowHalfOpen = true; - if (options && options.allowHalfOpen === false) this.allowHalfOpen = false; - - this.once('end', onend); -} - -// the no-half-open enforcer -function onend() { - // if we allow half-open state, or if the writable side ended, - // then we're ok. - if (this.allowHalfOpen || this._writableState.ended) return; - - // no more data can be written. - // But allow more writes to happen in this tick. - processNextTick(onEndNT, this); -} - -function onEndNT(self) { - self.end(); -} - -function forEach(xs, f) { - for (var i = 0, l = xs.length; i < l; i++) { - f(xs[i], i); - } -} -},{"./_stream_readable":23,"./_stream_writable":25,"core-util-is":7,"inherits":11,"process-nextick-args":15}],22:[function(require,module,exports){ -// a passthrough stream. -// basically just the most minimal sort of Transform stream. -// Every written chunk gets output as-is. - -'use strict'; - -module.exports = PassThrough; - -var Transform = require('./_stream_transform'); - -/**/ -var util = require('core-util-is'); -util.inherits = require('inherits'); -/**/ - -util.inherits(PassThrough, Transform); - -function PassThrough(options) { - if (!(this instanceof PassThrough)) return new PassThrough(options); - - Transform.call(this, options); -} - -PassThrough.prototype._transform = function (chunk, encoding, cb) { - cb(null, chunk); -}; -},{"./_stream_transform":24,"core-util-is":7,"inherits":11}],23:[function(require,module,exports){ -(function (process){ -'use strict'; - -module.exports = Readable; - -/**/ -var processNextTick = require('process-nextick-args'); -/**/ - -/**/ -var isArray = require('isarray'); -/**/ - -Readable.ReadableState = ReadableState; - -/**/ -var EE = require('events').EventEmitter; - -var EElistenerCount = function (emitter, type) { - return emitter.listeners(type).length; -}; -/**/ - -/**/ -var Stream; -(function () { - try { - Stream = require('st' + 'ream'); - } catch (_) {} finally { - if (!Stream) Stream = require('events').EventEmitter; - } -})(); -/**/ - -var Buffer = require('buffer').Buffer; -/**/ -var bufferShim = require('buffer-shims'); -/**/ - -/**/ -var util = require('core-util-is'); -util.inherits = require('inherits'); -/**/ - -/**/ -var debugUtil = require('util'); -var debug = void 0; -if (debugUtil && debugUtil.debuglog) { - debug = debugUtil.debuglog('stream'); -} else { - debug = function () {}; -} -/**/ - -var BufferList = require('./internal/streams/BufferList'); -var StringDecoder; - -util.inherits(Readable, Stream); - -function prependListener(emitter, event, fn) { - if (typeof emitter.prependListener === 'function') { - return emitter.prependListener(event, fn); - } else { - // This is a hack to make sure that our error handler is attached before any - // userland ones. NEVER DO THIS. This is here only because this code needs - // to continue to work with older versions of Node.js that do not include - // the prependListener() method. The goal is to eventually remove this hack. - if (!emitter._events || !emitter._events[event]) emitter.on(event, fn);else if (isArray(emitter._events[event])) emitter._events[event].unshift(fn);else emitter._events[event] = [fn, emitter._events[event]]; - } -} - -var Duplex; -function ReadableState(options, stream) { - Duplex = Duplex || require('./_stream_duplex'); - - options = options || {}; - - // object stream flag. Used to make read(n) ignore n and to - // make all the buffer merging and length checks go away - this.objectMode = !!options.objectMode; - - if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.readableObjectMode; - - // the point at which it stops calling _read() to fill the buffer - // Note: 0 is a valid value, means "don't call _read preemptively ever" - var hwm = options.highWaterMark; - var defaultHwm = this.objectMode ? 16 : 16 * 1024; - this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm; - - // cast to ints. - this.highWaterMark = ~ ~this.highWaterMark; - - // A linked list is used to store data chunks instead of an array because the - // linked list can remove elements from the beginning faster than - // array.shift() - this.buffer = new BufferList(); - this.length = 0; - this.pipes = null; - this.pipesCount = 0; - this.flowing = null; - this.ended = false; - this.endEmitted = false; - this.reading = false; - - // a flag to be able to tell if the onwrite cb is called immediately, - // or on a later tick. We set this to true at first, because any - // actions that shouldn't happen until "later" should generally also - // not happen before the first write call. - this.sync = true; - - // whenever we return null, then we set a flag to say - // that we're awaiting a 'readable' event emission. - this.needReadable = false; - this.emittedReadable = false; - this.readableListening = false; - this.resumeScheduled = false; - - // Crypto is kind of old and crusty. Historically, its default string - // encoding is 'binary' so we have to make this configurable. - // Everything else in the universe uses 'utf8', though. - this.defaultEncoding = options.defaultEncoding || 'utf8'; - - // when piping, we only care about 'readable' events that happen - // after read()ing all the bytes and not getting any pushback. - this.ranOut = false; - - // the number of writers that are awaiting a drain event in .pipe()s - this.awaitDrain = 0; - - // if true, a maybeReadMore has been scheduled - this.readingMore = false; - - this.decoder = null; - this.encoding = null; - if (options.encoding) { - if (!StringDecoder) StringDecoder = require('string_decoder/').StringDecoder; - this.decoder = new StringDecoder(options.encoding); - this.encoding = options.encoding; - } -} - -var Duplex; -function Readable(options) { - Duplex = Duplex || require('./_stream_duplex'); - - if (!(this instanceof Readable)) return new Readable(options); - - this._readableState = new ReadableState(options, this); - - // legacy - this.readable = true; - - if (options && typeof options.read === 'function') this._read = options.read; - - Stream.call(this); -} - -// Manually shove something into the read() buffer. -// This returns true if the highWaterMark has not been hit yet, -// similar to how Writable.write() returns true if you should -// write() some more. -Readable.prototype.push = function (chunk, encoding) { - var state = this._readableState; - - if (!state.objectMode && typeof chunk === 'string') { - encoding = encoding || state.defaultEncoding; - if (encoding !== state.encoding) { - chunk = bufferShim.from(chunk, encoding); - encoding = ''; - } - } - - return readableAddChunk(this, state, chunk, encoding, false); -}; - -// Unshift should *always* be something directly out of read() -Readable.prototype.unshift = function (chunk) { - var state = this._readableState; - return readableAddChunk(this, state, chunk, '', true); -}; - -Readable.prototype.isPaused = function () { - return this._readableState.flowing === false; -}; - -function readableAddChunk(stream, state, chunk, encoding, addToFront) { - var er = chunkInvalid(state, chunk); - if (er) { - stream.emit('error', er); - } else if (chunk === null) { - state.reading = false; - onEofChunk(stream, state); - } else if (state.objectMode || chunk && chunk.length > 0) { - if (state.ended && !addToFront) { - var e = new Error('stream.push() after EOF'); - stream.emit('error', e); - } else if (state.endEmitted && addToFront) { - var _e = new Error('stream.unshift() after end event'); - stream.emit('error', _e); - } else { - var skipAdd; - if (state.decoder && !addToFront && !encoding) { - chunk = state.decoder.write(chunk); - skipAdd = !state.objectMode && chunk.length === 0; - } - - if (!addToFront) state.reading = false; - - // Don't add to the buffer if we've decoded to an empty string chunk and - // we're not in object mode - if (!skipAdd) { - // if we want the data now, just emit it. - if (state.flowing && state.length === 0 && !state.sync) { - stream.emit('data', chunk); - stream.read(0); - } else { - // update the buffer info. - state.length += state.objectMode ? 1 : chunk.length; - if (addToFront) state.buffer.unshift(chunk);else state.buffer.push(chunk); - - if (state.needReadable) emitReadable(stream); - } - } - - maybeReadMore(stream, state); - } - } else if (!addToFront) { - state.reading = false; - } - - return needMoreData(state); -} - -// if it's past the high water mark, we can push in some more. -// Also, if we have no data yet, we can stand some -// more bytes. This is to work around cases where hwm=0, -// such as the repl. Also, if the push() triggered a -// readable event, and the user called read(largeNumber) such that -// needReadable was set, then we ought to push more, so that another -// 'readable' event will be triggered. -function needMoreData(state) { - return !state.ended && (state.needReadable || state.length < state.highWaterMark || state.length === 0); -} - -// backwards compatibility. -Readable.prototype.setEncoding = function (enc) { - if (!StringDecoder) StringDecoder = require('string_decoder/').StringDecoder; - this._readableState.decoder = new StringDecoder(enc); - this._readableState.encoding = enc; - return this; -}; - -// Don't raise the hwm > 8MB -var MAX_HWM = 0x800000; -function computeNewHighWaterMark(n) { - if (n >= MAX_HWM) { - n = MAX_HWM; - } else { - // Get the next highest power of 2 to prevent increasing hwm excessively in - // tiny amounts - n--; - n |= n >>> 1; - n |= n >>> 2; - n |= n >>> 4; - n |= n >>> 8; - n |= n >>> 16; - n++; - } - return n; -} - -// This function is designed to be inlinable, so please take care when making -// changes to the function body. -function howMuchToRead(n, state) { - if (n <= 0 || state.length === 0 && state.ended) return 0; - if (state.objectMode) return 1; - if (n !== n) { - // Only flow one buffer at a time - if (state.flowing && state.length) return state.buffer.head.data.length;else return state.length; - } - // If we're asking for more than the current hwm, then raise the hwm. - if (n > state.highWaterMark) state.highWaterMark = computeNewHighWaterMark(n); - if (n <= state.length) return n; - // Don't have enough - if (!state.ended) { - state.needReadable = true; - return 0; - } - return state.length; -} - -// you can override either this method, or the async _read(n) below. -Readable.prototype.read = function (n) { - debug('read', n); - n = parseInt(n, 10); - var state = this._readableState; - var nOrig = n; - - if (n !== 0) state.emittedReadable = false; - - // if we're doing read(0) to trigger a readable event, but we - // already have a bunch of data in the buffer, then just trigger - // the 'readable' event and move on. - if (n === 0 && state.needReadable && (state.length >= state.highWaterMark || state.ended)) { - debug('read: emitReadable', state.length, state.ended); - if (state.length === 0 && state.ended) endReadable(this);else emitReadable(this); - return null; - } - - n = howMuchToRead(n, state); - - // if we've ended, and we're now clear, then finish it up. - if (n === 0 && state.ended) { - if (state.length === 0) endReadable(this); - return null; - } - - // All the actual chunk generation logic needs to be - // *below* the call to _read. The reason is that in certain - // synthetic stream cases, such as passthrough streams, _read - // may be a completely synchronous operation which may change - // the state of the read buffer, providing enough data when - // before there was *not* enough. - // - // So, the steps are: - // 1. Figure out what the state of things will be after we do - // a read from the buffer. - // - // 2. If that resulting state will trigger a _read, then call _read. - // Note that this may be asynchronous, or synchronous. Yes, it is - // deeply ugly to write APIs this way, but that still doesn't mean - // that the Readable class should behave improperly, as streams are - // designed to be sync/async agnostic. - // Take note if the _read call is sync or async (ie, if the read call - // has returned yet), so that we know whether or not it's safe to emit - // 'readable' etc. - // - // 3. Actually pull the requested chunks out of the buffer and return. - - // if we need a readable event, then we need to do some reading. - var doRead = state.needReadable; - debug('need readable', doRead); - - // if we currently have less than the highWaterMark, then also read some - if (state.length === 0 || state.length - n < state.highWaterMark) { - doRead = true; - debug('length less than watermark', doRead); - } - - // however, if we've ended, then there's no point, and if we're already - // reading, then it's unnecessary. - if (state.ended || state.reading) { - doRead = false; - debug('reading or ended', doRead); - } else if (doRead) { - debug('do read'); - state.reading = true; - state.sync = true; - // if the length is currently zero, then we *need* a readable event. - if (state.length === 0) state.needReadable = true; - // call internal read method - this._read(state.highWaterMark); - state.sync = false; - // If _read pushed data synchronously, then `reading` will be false, - // and we need to re-evaluate how much data we can return to the user. - if (!state.reading) n = howMuchToRead(nOrig, state); - } - - var ret; - if (n > 0) ret = fromList(n, state);else ret = null; - - if (ret === null) { - state.needReadable = true; - n = 0; - } else { - state.length -= n; - } - - if (state.length === 0) { - // If we have nothing in the buffer, then we want to know - // as soon as we *do* get something into the buffer. - if (!state.ended) state.needReadable = true; - - // If we tried to read() past the EOF, then emit end on the next tick. - if (nOrig !== n && state.ended) endReadable(this); - } - - if (ret !== null) this.emit('data', ret); - - return ret; -}; - -function chunkInvalid(state, chunk) { - var er = null; - if (!Buffer.isBuffer(chunk) && typeof chunk !== 'string' && chunk !== null && chunk !== undefined && !state.objectMode) { - er = new TypeError('Invalid non-string/buffer chunk'); - } - return er; -} - -function onEofChunk(stream, state) { - if (state.ended) return; - if (state.decoder) { - var chunk = state.decoder.end(); - if (chunk && chunk.length) { - state.buffer.push(chunk); - state.length += state.objectMode ? 1 : chunk.length; - } - } - state.ended = true; - - // emit 'readable' now to make sure it gets picked up. - emitReadable(stream); -} - -// Don't emit readable right away in sync mode, because this can trigger -// another read() call => stack overflow. This way, it might trigger -// a nextTick recursion warning, but that's not so bad. -function emitReadable(stream) { - var state = stream._readableState; - state.needReadable = false; - if (!state.emittedReadable) { - debug('emitReadable', state.flowing); - state.emittedReadable = true; - if (state.sync) processNextTick(emitReadable_, stream);else emitReadable_(stream); - } -} - -function emitReadable_(stream) { - debug('emit readable'); - stream.emit('readable'); - flow(stream); -} - -// at this point, the user has presumably seen the 'readable' event, -// and called read() to consume some data. that may have triggered -// in turn another _read(n) call, in which case reading = true if -// it's in progress. -// However, if we're not ended, or reading, and the length < hwm, -// then go ahead and try to read some more preemptively. -function maybeReadMore(stream, state) { - if (!state.readingMore) { - state.readingMore = true; - processNextTick(maybeReadMore_, stream, state); - } -} - -function maybeReadMore_(stream, state) { - var len = state.length; - while (!state.reading && !state.flowing && !state.ended && state.length < state.highWaterMark) { - debug('maybeReadMore read 0'); - stream.read(0); - if (len === state.length) - // didn't get any data, stop spinning. - break;else len = state.length; - } - state.readingMore = false; -} - -// abstract method. to be overridden in specific implementation classes. -// call cb(er, data) where data is <= n in length. -// for virtual (non-string, non-buffer) streams, "length" is somewhat -// arbitrary, and perhaps not very meaningful. -Readable.prototype._read = function (n) { - this.emit('error', new Error('not implemented')); -}; - -Readable.prototype.pipe = function (dest, pipeOpts) { - var src = this; - var state = this._readableState; - - switch (state.pipesCount) { - case 0: - state.pipes = dest; - break; - case 1: - state.pipes = [state.pipes, dest]; - break; - default: - state.pipes.push(dest); - break; - } - state.pipesCount += 1; - debug('pipe count=%d opts=%j', state.pipesCount, pipeOpts); - - var doEnd = (!pipeOpts || pipeOpts.end !== false) && dest !== process.stdout && dest !== process.stderr; - - var endFn = doEnd ? onend : cleanup; - if (state.endEmitted) processNextTick(endFn);else src.once('end', endFn); - - dest.on('unpipe', onunpipe); - function onunpipe(readable) { - debug('onunpipe'); - if (readable === src) { - cleanup(); - } - } - - function onend() { - debug('onend'); - dest.end(); - } - - // when the dest drains, it reduces the awaitDrain counter - // on the source. This would be more elegant with a .once() - // handler in flow(), but adding and removing repeatedly is - // too slow. - var ondrain = pipeOnDrain(src); - dest.on('drain', ondrain); - - var cleanedUp = false; - function cleanup() { - debug('cleanup'); - // cleanup event handlers once the pipe is broken - dest.removeListener('close', onclose); - dest.removeListener('finish', onfinish); - dest.removeListener('drain', ondrain); - dest.removeListener('error', onerror); - dest.removeListener('unpipe', onunpipe); - src.removeListener('end', onend); - src.removeListener('end', cleanup); - src.removeListener('data', ondata); - - cleanedUp = true; - - // if the reader is waiting for a drain event from this - // specific writer, then it would cause it to never start - // flowing again. - // So, if this is awaiting a drain, then we just call it now. - // If we don't know, then assume that we are waiting for one. - if (state.awaitDrain && (!dest._writableState || dest._writableState.needDrain)) ondrain(); - } - - // If the user pushes more data while we're writing to dest then we'll end up - // in ondata again. However, we only want to increase awaitDrain once because - // dest will only emit one 'drain' event for the multiple writes. - // => Introduce a guard on increasing awaitDrain. - var increasedAwaitDrain = false; - src.on('data', ondata); - function ondata(chunk) { - debug('ondata'); - increasedAwaitDrain = false; - var ret = dest.write(chunk); - if (false === ret && !increasedAwaitDrain) { - // If the user unpiped during `dest.write()`, it is possible - // to get stuck in a permanently paused state if that write - // also returned false. - // => Check whether `dest` is still a piping destination. - if ((state.pipesCount === 1 && state.pipes === dest || state.pipesCount > 1 && indexOf(state.pipes, dest) !== -1) && !cleanedUp) { - debug('false write response, pause', src._readableState.awaitDrain); - src._readableState.awaitDrain++; - increasedAwaitDrain = true; - } - src.pause(); - } - } - - // if the dest has an error, then stop piping into it. - // however, don't suppress the throwing behavior for this. - function onerror(er) { - debug('onerror', er); - unpipe(); - dest.removeListener('error', onerror); - if (EElistenerCount(dest, 'error') === 0) dest.emit('error', er); - } - - // Make sure our error handler is attached before userland ones. - prependListener(dest, 'error', onerror); - - // Both close and finish should trigger unpipe, but only once. - function onclose() { - dest.removeListener('finish', onfinish); - unpipe(); - } - dest.once('close', onclose); - function onfinish() { - debug('onfinish'); - dest.removeListener('close', onclose); - unpipe(); - } - dest.once('finish', onfinish); - - function unpipe() { - debug('unpipe'); - src.unpipe(dest); - } - - // tell the dest that it's being piped to - dest.emit('pipe', src); - - // start the flow if it hasn't been started already. - if (!state.flowing) { - debug('pipe resume'); - src.resume(); - } - - return dest; -}; - -function pipeOnDrain(src) { - return function () { - var state = src._readableState; - debug('pipeOnDrain', state.awaitDrain); - if (state.awaitDrain) state.awaitDrain--; - if (state.awaitDrain === 0 && EElistenerCount(src, 'data')) { - state.flowing = true; - flow(src); - } - }; -} - -Readable.prototype.unpipe = function (dest) { - var state = this._readableState; - - // if we're not piping anywhere, then do nothing. - if (state.pipesCount === 0) return this; - - // just one destination. most common case. - if (state.pipesCount === 1) { - // passed in one, but it's not the right one. - if (dest && dest !== state.pipes) return this; - - if (!dest) dest = state.pipes; - - // got a match. - state.pipes = null; - state.pipesCount = 0; - state.flowing = false; - if (dest) dest.emit('unpipe', this); - return this; - } - - // slow case. multiple pipe destinations. - - if (!dest) { - // remove all. - var dests = state.pipes; - var len = state.pipesCount; - state.pipes = null; - state.pipesCount = 0; - state.flowing = false; - - for (var _i = 0; _i < len; _i++) { - dests[_i].emit('unpipe', this); - }return this; - } - - // try to find the right one. - var i = indexOf(state.pipes, dest); - if (i === -1) return this; - - state.pipes.splice(i, 1); - state.pipesCount -= 1; - if (state.pipesCount === 1) state.pipes = state.pipes[0]; - - dest.emit('unpipe', this); - - return this; -}; - -// set up data events if they are asked for -// Ensure readable listeners eventually get something -Readable.prototype.on = function (ev, fn) { - var res = Stream.prototype.on.call(this, ev, fn); - - if (ev === 'data') { - // Start flowing on next tick if stream isn't explicitly paused - if (this._readableState.flowing !== false) this.resume(); - } else if (ev === 'readable') { - var state = this._readableState; - if (!state.endEmitted && !state.readableListening) { - state.readableListening = state.needReadable = true; - state.emittedReadable = false; - if (!state.reading) { - processNextTick(nReadingNextTick, this); - } else if (state.length) { - emitReadable(this, state); - } - } - } - - return res; -}; -Readable.prototype.addListener = Readable.prototype.on; - -function nReadingNextTick(self) { - debug('readable nexttick read 0'); - self.read(0); -} - -// pause() and resume() are remnants of the legacy readable stream API -// If the user uses them, then switch into old mode. -Readable.prototype.resume = function () { - var state = this._readableState; - if (!state.flowing) { - debug('resume'); - state.flowing = true; - resume(this, state); - } - return this; -}; - -function resume(stream, state) { - if (!state.resumeScheduled) { - state.resumeScheduled = true; - processNextTick(resume_, stream, state); - } -} - -function resume_(stream, state) { - if (!state.reading) { - debug('resume read 0'); - stream.read(0); - } - - state.resumeScheduled = false; - state.awaitDrain = 0; - stream.emit('resume'); - flow(stream); - if (state.flowing && !state.reading) stream.read(0); -} - -Readable.prototype.pause = function () { - debug('call pause flowing=%j', this._readableState.flowing); - if (false !== this._readableState.flowing) { - debug('pause'); - this._readableState.flowing = false; - this.emit('pause'); - } - return this; -}; - -function flow(stream) { - var state = stream._readableState; - debug('flow', state.flowing); - while (state.flowing && stream.read() !== null) {} -} - -// wrap an old-style stream as the async data source. -// This is *not* part of the readable stream interface. -// It is an ugly unfortunate mess of history. -Readable.prototype.wrap = function (stream) { - var state = this._readableState; - var paused = false; - - var self = this; - stream.on('end', function () { - debug('wrapped end'); - if (state.decoder && !state.ended) { - var chunk = state.decoder.end(); - if (chunk && chunk.length) self.push(chunk); - } - - self.push(null); - }); - - stream.on('data', function (chunk) { - debug('wrapped data'); - if (state.decoder) chunk = state.decoder.write(chunk); - - // don't skip over falsy values in objectMode - if (state.objectMode && (chunk === null || chunk === undefined)) return;else if (!state.objectMode && (!chunk || !chunk.length)) return; - - var ret = self.push(chunk); - if (!ret) { - paused = true; - stream.pause(); - } - }); - - // proxy all the other methods. - // important when wrapping filters and duplexes. - for (var i in stream) { - if (this[i] === undefined && typeof stream[i] === 'function') { - this[i] = function (method) { - return function () { - return stream[method].apply(stream, arguments); - }; - }(i); - } - } - - // proxy certain important events. - var events = ['error', 'close', 'destroy', 'pause', 'resume']; - forEach(events, function (ev) { - stream.on(ev, self.emit.bind(self, ev)); - }); - - // when we try to consume some more bytes, simply unpause the - // underlying stream. - self._read = function (n) { - debug('wrapped _read', n); - if (paused) { - paused = false; - stream.resume(); - } - }; - - return self; -}; - -// exposed for testing purposes only. -Readable._fromList = fromList; - -// Pluck off n bytes from an array of buffers. -// Length is the combined lengths of all the buffers in the list. -// This function is designed to be inlinable, so please take care when making -// changes to the function body. -function fromList(n, state) { - // nothing buffered - if (state.length === 0) return null; - - var ret; - if (state.objectMode) ret = state.buffer.shift();else if (!n || n >= state.length) { - // read it all, truncate the list - if (state.decoder) ret = state.buffer.join('');else if (state.buffer.length === 1) ret = state.buffer.head.data;else ret = state.buffer.concat(state.length); - state.buffer.clear(); - } else { - // read part of list - ret = fromListPartial(n, state.buffer, state.decoder); - } - - return ret; -} - -// Extracts only enough buffered data to satisfy the amount requested. -// This function is designed to be inlinable, so please take care when making -// changes to the function body. -function fromListPartial(n, list, hasStrings) { - var ret; - if (n < list.head.data.length) { - // slice is the same for buffers and strings - ret = list.head.data.slice(0, n); - list.head.data = list.head.data.slice(n); - } else if (n === list.head.data.length) { - // first chunk is a perfect match - ret = list.shift(); - } else { - // result spans more than one buffer - ret = hasStrings ? copyFromBufferString(n, list) : copyFromBuffer(n, list); - } - return ret; -} - -// Copies a specified amount of characters from the list of buffered data -// chunks. -// This function is designed to be inlinable, so please take care when making -// changes to the function body. -function copyFromBufferString(n, list) { - var p = list.head; - var c = 1; - var ret = p.data; - n -= ret.length; - while (p = p.next) { - var str = p.data; - var nb = n > str.length ? str.length : n; - if (nb === str.length) ret += str;else ret += str.slice(0, n); - n -= nb; - if (n === 0) { - if (nb === str.length) { - ++c; - if (p.next) list.head = p.next;else list.head = list.tail = null; - } else { - list.head = p; - p.data = str.slice(nb); - } - break; - } - ++c; - } - list.length -= c; - return ret; -} - -// Copies a specified amount of bytes from the list of buffered data chunks. -// This function is designed to be inlinable, so please take care when making -// changes to the function body. -function copyFromBuffer(n, list) { - var ret = bufferShim.allocUnsafe(n); - var p = list.head; - var c = 1; - p.data.copy(ret); - n -= p.data.length; - while (p = p.next) { - var buf = p.data; - var nb = n > buf.length ? buf.length : n; - buf.copy(ret, ret.length - n, 0, nb); - n -= nb; - if (n === 0) { - if (nb === buf.length) { - ++c; - if (p.next) list.head = p.next;else list.head = list.tail = null; - } else { - list.head = p; - p.data = buf.slice(nb); - } - break; - } - ++c; - } - list.length -= c; - return ret; -} - -function endReadable(stream) { - var state = stream._readableState; - - // If we get here before consuming all the bytes, then that is a - // bug in node. Should never happen. - if (state.length > 0) throw new Error('"endReadable()" called on non-empty stream'); - - if (!state.endEmitted) { - state.ended = true; - processNextTick(endReadableNT, state, stream); - } -} - -function endReadableNT(state, stream) { - // Check that we didn't get one last unshift. - if (!state.endEmitted && state.length === 0) { - state.endEmitted = true; - stream.readable = false; - stream.emit('end'); - } -} - -function forEach(xs, f) { - for (var i = 0, l = xs.length; i < l; i++) { - f(xs[i], i); - } -} - -function indexOf(xs, x) { - for (var i = 0, l = xs.length; i < l; i++) { - if (xs[i] === x) return i; - } - return -1; -} -}).call(this,require('_process')) -},{"./_stream_duplex":21,"./internal/streams/BufferList":26,"_process":16,"buffer":5,"buffer-shims":4,"core-util-is":7,"events":8,"inherits":11,"isarray":13,"process-nextick-args":15,"string_decoder/":32,"util":2}],24:[function(require,module,exports){ -// a transform stream is a readable/writable stream where you do -// something with the data. Sometimes it's called a "filter", -// but that's not a great name for it, since that implies a thing where -// some bits pass through, and others are simply ignored. (That would -// be a valid example of a transform, of course.) -// -// While the output is causally related to the input, it's not a -// necessarily symmetric or synchronous transformation. For example, -// a zlib stream might take multiple plain-text writes(), and then -// emit a single compressed chunk some time in the future. -// -// Here's how this works: -// -// The Transform stream has all the aspects of the readable and writable -// stream classes. When you write(chunk), that calls _write(chunk,cb) -// internally, and returns false if there's a lot of pending writes -// buffered up. When you call read(), that calls _read(n) until -// there's enough pending readable data buffered up. -// -// In a transform stream, the written data is placed in a buffer. When -// _read(n) is called, it transforms the queued up data, calling the -// buffered _write cb's as it consumes chunks. If consuming a single -// written chunk would result in multiple output chunks, then the first -// outputted bit calls the readcb, and subsequent chunks just go into -// the read buffer, and will cause it to emit 'readable' if necessary. -// -// This way, back-pressure is actually determined by the reading side, -// since _read has to be called to start processing a new chunk. However, -// a pathological inflate type of transform can cause excessive buffering -// here. For example, imagine a stream where every byte of input is -// interpreted as an integer from 0-255, and then results in that many -// bytes of output. Writing the 4 bytes {ff,ff,ff,ff} would result in -// 1kb of data being output. In this case, you could write a very small -// amount of input, and end up with a very large amount of output. In -// such a pathological inflating mechanism, there'd be no way to tell -// the system to stop doing the transform. A single 4MB write could -// cause the system to run out of memory. -// -// However, even in such a pathological case, only a single written chunk -// would be consumed, and then the rest would wait (un-transformed) until -// the results of the previous transformed chunk were consumed. - -'use strict'; - -module.exports = Transform; - -var Duplex = require('./_stream_duplex'); - -/**/ -var util = require('core-util-is'); -util.inherits = require('inherits'); -/**/ - -util.inherits(Transform, Duplex); - -function TransformState(stream) { - this.afterTransform = function (er, data) { - return afterTransform(stream, er, data); - }; - - this.needTransform = false; - this.transforming = false; - this.writecb = null; - this.writechunk = null; - this.writeencoding = null; -} - -function afterTransform(stream, er, data) { - var ts = stream._transformState; - ts.transforming = false; - - var cb = ts.writecb; - - if (!cb) return stream.emit('error', new Error('no writecb in Transform class')); - - ts.writechunk = null; - ts.writecb = null; - - if (data !== null && data !== undefined) stream.push(data); - - cb(er); - - var rs = stream._readableState; - rs.reading = false; - if (rs.needReadable || rs.length < rs.highWaterMark) { - stream._read(rs.highWaterMark); - } -} - -function Transform(options) { - if (!(this instanceof Transform)) return new Transform(options); - - Duplex.call(this, options); - - this._transformState = new TransformState(this); - - // when the writable side finishes, then flush out anything remaining. - var stream = this; - - // start out asking for a readable event once data is transformed. - this._readableState.needReadable = true; - - // we have implemented the _read method, and done the other things - // that Readable wants before the first _read call, so unset the - // sync guard flag. - this._readableState.sync = false; - - if (options) { - if (typeof options.transform === 'function') this._transform = options.transform; - - if (typeof options.flush === 'function') this._flush = options.flush; - } - - this.once('prefinish', function () { - if (typeof this._flush === 'function') this._flush(function (er) { - done(stream, er); - });else done(stream); - }); -} - -Transform.prototype.push = function (chunk, encoding) { - this._transformState.needTransform = false; - return Duplex.prototype.push.call(this, chunk, encoding); -}; - -// This is the part where you do stuff! -// override this function in implementation classes. -// 'chunk' is an input chunk. -// -// Call `push(newChunk)` to pass along transformed output -// to the readable side. You may call 'push' zero or more times. -// -// Call `cb(err)` when you are done with this chunk. If you pass -// an error, then that'll put the hurt on the whole operation. If you -// never call cb(), then you'll never get another chunk. -Transform.prototype._transform = function (chunk, encoding, cb) { - throw new Error('Not implemented'); -}; - -Transform.prototype._write = function (chunk, encoding, cb) { - var ts = this._transformState; - ts.writecb = cb; - ts.writechunk = chunk; - ts.writeencoding = encoding; - if (!ts.transforming) { - var rs = this._readableState; - if (ts.needTransform || rs.needReadable || rs.length < rs.highWaterMark) this._read(rs.highWaterMark); - } -}; - -// Doesn't matter what the args are here. -// _transform does all the work. -// That we got here means that the readable side wants more data. -Transform.prototype._read = function (n) { - var ts = this._transformState; - - if (ts.writechunk !== null && ts.writecb && !ts.transforming) { - ts.transforming = true; - this._transform(ts.writechunk, ts.writeencoding, ts.afterTransform); - } else { - // mark that we need a transform, so that any data that comes in - // will get processed, now that we've asked for it. - ts.needTransform = true; - } -}; - -function done(stream, er) { - if (er) return stream.emit('error', er); - - // if there's nothing in the write buffer, then that means - // that nothing more will ever be provided - var ws = stream._writableState; - var ts = stream._transformState; - - if (ws.length) throw new Error('Calling transform done when ws.length != 0'); - - if (ts.transforming) throw new Error('Calling transform done when still transforming'); - - return stream.push(null); -} -},{"./_stream_duplex":21,"core-util-is":7,"inherits":11}],25:[function(require,module,exports){ -(function (process){ -// A bit simpler than readable streams. -// Implement an async ._write(chunk, encoding, cb), and it'll handle all -// the drain event emission and buffering. - -'use strict'; - -module.exports = Writable; - -/**/ -var processNextTick = require('process-nextick-args'); -/**/ - -/**/ -var asyncWrite = !process.browser && ['v0.10', 'v0.9.'].indexOf(process.version.slice(0, 5)) > -1 ? setImmediate : processNextTick; -/**/ - -Writable.WritableState = WritableState; - -/**/ -var util = require('core-util-is'); -util.inherits = require('inherits'); -/**/ - -/**/ -var internalUtil = { - deprecate: require('util-deprecate') -}; -/**/ - -/**/ -var Stream; -(function () { - try { - Stream = require('st' + 'ream'); - } catch (_) {} finally { - if (!Stream) Stream = require('events').EventEmitter; - } -})(); -/**/ - -var Buffer = require('buffer').Buffer; -/**/ -var bufferShim = require('buffer-shims'); -/**/ - -util.inherits(Writable, Stream); - -function nop() {} - -function WriteReq(chunk, encoding, cb) { - this.chunk = chunk; - this.encoding = encoding; - this.callback = cb; - this.next = null; -} - -var Duplex; -function WritableState(options, stream) { - Duplex = Duplex || require('./_stream_duplex'); - - options = options || {}; - - // object stream flag to indicate whether or not this stream - // contains buffers or objects. - this.objectMode = !!options.objectMode; - - if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.writableObjectMode; - - // the point at which write() starts returning false - // Note: 0 is a valid value, means that we always return false if - // the entire buffer is not flushed immediately on write() - var hwm = options.highWaterMark; - var defaultHwm = this.objectMode ? 16 : 16 * 1024; - this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm; - - // cast to ints. - this.highWaterMark = ~ ~this.highWaterMark; - - this.needDrain = false; - // at the start of calling end() - this.ending = false; - // when end() has been called, and returned - this.ended = false; - // when 'finish' is emitted - this.finished = false; - - // should we decode strings into buffers before passing to _write? - // this is here so that some node-core streams can optimize string - // handling at a lower level. - var noDecode = options.decodeStrings === false; - this.decodeStrings = !noDecode; - - // Crypto is kind of old and crusty. Historically, its default string - // encoding is 'binary' so we have to make this configurable. - // Everything else in the universe uses 'utf8', though. - this.defaultEncoding = options.defaultEncoding || 'utf8'; - - // not an actual buffer we keep track of, but a measurement - // of how much we're waiting to get pushed to some underlying - // socket or file. - this.length = 0; - - // a flag to see when we're in the middle of a write. - this.writing = false; - - // when true all writes will be buffered until .uncork() call - this.corked = 0; - - // a flag to be able to tell if the onwrite cb is called immediately, - // or on a later tick. We set this to true at first, because any - // actions that shouldn't happen until "later" should generally also - // not happen before the first write call. - this.sync = true; - - // a flag to know if we're processing previously buffered items, which - // may call the _write() callback in the same tick, so that we don't - // end up in an overlapped onwrite situation. - this.bufferProcessing = false; - - // the callback that's passed to _write(chunk,cb) - this.onwrite = function (er) { - onwrite(stream, er); - }; - - // the callback that the user supplies to write(chunk,encoding,cb) - this.writecb = null; - - // the amount that is being written when _write is called. - this.writelen = 0; - - this.bufferedRequest = null; - this.lastBufferedRequest = null; - - // number of pending user-supplied write callbacks - // this must be 0 before 'finish' can be emitted - this.pendingcb = 0; - - // emit prefinish if the only thing we're waiting for is _write cbs - // This is relevant for synchronous Transform streams - this.prefinished = false; - - // True if the error was already emitted and should not be thrown again - this.errorEmitted = false; - - // count buffered requests - this.bufferedRequestCount = 0; - - // allocate the first CorkedRequest, there is always - // one allocated and free to use, and we maintain at most two - this.corkedRequestsFree = new CorkedRequest(this); -} - -WritableState.prototype.getBuffer = function writableStateGetBuffer() { - var current = this.bufferedRequest; - var out = []; - while (current) { - out.push(current); - current = current.next; - } - return out; -}; - -(function () { - try { - Object.defineProperty(WritableState.prototype, 'buffer', { - get: internalUtil.deprecate(function () { - return this.getBuffer(); - }, '_writableState.buffer is deprecated. Use _writableState.getBuffer ' + 'instead.') - }); - } catch (_) {} -})(); - -var Duplex; -function Writable(options) { - Duplex = Duplex || require('./_stream_duplex'); - - // Writable ctor is applied to Duplexes, though they're not - // instanceof Writable, they're instanceof Readable. - if (!(this instanceof Writable) && !(this instanceof Duplex)) return new Writable(options); - - this._writableState = new WritableState(options, this); - - // legacy. - this.writable = true; - - if (options) { - if (typeof options.write === 'function') this._write = options.write; - - if (typeof options.writev === 'function') this._writev = options.writev; - } - - Stream.call(this); -} - -// Otherwise people can pipe Writable streams, which is just wrong. -Writable.prototype.pipe = function () { - this.emit('error', new Error('Cannot pipe, not readable')); -}; - -function writeAfterEnd(stream, cb) { - var er = new Error('write after end'); - // TODO: defer error events consistently everywhere, not just the cb - stream.emit('error', er); - processNextTick(cb, er); -} - -// If we get something that is not a buffer, string, null, or undefined, -// and we're not in objectMode, then that's an error. -// Otherwise stream chunks are all considered to be of length=1, and the -// watermarks determine how many objects to keep in the buffer, rather than -// how many bytes or characters. -function validChunk(stream, state, chunk, cb) { - var valid = true; - var er = false; - // Always throw error if a null is written - // if we are not in object mode then throw - // if it is not a buffer, string, or undefined. - if (chunk === null) { - er = new TypeError('May not write null values to stream'); - } else if (!Buffer.isBuffer(chunk) && typeof chunk !== 'string' && chunk !== undefined && !state.objectMode) { - er = new TypeError('Invalid non-string/buffer chunk'); - } - if (er) { - stream.emit('error', er); - processNextTick(cb, er); - valid = false; - } - return valid; -} - -Writable.prototype.write = function (chunk, encoding, cb) { - var state = this._writableState; - var ret = false; - - if (typeof encoding === 'function') { - cb = encoding; - encoding = null; - } - - if (Buffer.isBuffer(chunk)) encoding = 'buffer';else if (!encoding) encoding = state.defaultEncoding; - - if (typeof cb !== 'function') cb = nop; - - if (state.ended) writeAfterEnd(this, cb);else if (validChunk(this, state, chunk, cb)) { - state.pendingcb++; - ret = writeOrBuffer(this, state, chunk, encoding, cb); - } - - return ret; -}; - -Writable.prototype.cork = function () { - var state = this._writableState; - - state.corked++; -}; - -Writable.prototype.uncork = function () { - var state = this._writableState; - - if (state.corked) { - state.corked--; - - if (!state.writing && !state.corked && !state.finished && !state.bufferProcessing && state.bufferedRequest) clearBuffer(this, state); - } -}; - -Writable.prototype.setDefaultEncoding = function setDefaultEncoding(encoding) { - // node::ParseEncoding() requires lower case. - if (typeof encoding === 'string') encoding = encoding.toLowerCase(); - if (!(['hex', 'utf8', 'utf-8', 'ascii', 'binary', 'base64', 'ucs2', 'ucs-2', 'utf16le', 'utf-16le', 'raw'].indexOf((encoding + '').toLowerCase()) > -1)) throw new TypeError('Unknown encoding: ' + encoding); - this._writableState.defaultEncoding = encoding; - return this; -}; - -function decodeChunk(state, chunk, encoding) { - if (!state.objectMode && state.decodeStrings !== false && typeof chunk === 'string') { - chunk = bufferShim.from(chunk, encoding); - } - return chunk; -} - -// if we're already writing something, then just put this -// in the queue, and wait our turn. Otherwise, call _write -// If we return false, then we need a drain event, so set that flag. -function writeOrBuffer(stream, state, chunk, encoding, cb) { - chunk = decodeChunk(state, chunk, encoding); - - if (Buffer.isBuffer(chunk)) encoding = 'buffer'; - var len = state.objectMode ? 1 : chunk.length; - - state.length += len; - - var ret = state.length < state.highWaterMark; - // we must ensure that previous needDrain will not be reset to false. - if (!ret) state.needDrain = true; - - if (state.writing || state.corked) { - var last = state.lastBufferedRequest; - state.lastBufferedRequest = new WriteReq(chunk, encoding, cb); - if (last) { - last.next = state.lastBufferedRequest; - } else { - state.bufferedRequest = state.lastBufferedRequest; - } - state.bufferedRequestCount += 1; - } else { - doWrite(stream, state, false, len, chunk, encoding, cb); - } - - return ret; -} - -function doWrite(stream, state, writev, len, chunk, encoding, cb) { - state.writelen = len; - state.writecb = cb; - state.writing = true; - state.sync = true; - if (writev) stream._writev(chunk, state.onwrite);else stream._write(chunk, encoding, state.onwrite); - state.sync = false; -} - -function onwriteError(stream, state, sync, er, cb) { - --state.pendingcb; - if (sync) processNextTick(cb, er);else cb(er); - - stream._writableState.errorEmitted = true; - stream.emit('error', er); -} - -function onwriteStateUpdate(state) { - state.writing = false; - state.writecb = null; - state.length -= state.writelen; - state.writelen = 0; -} - -function onwrite(stream, er) { - var state = stream._writableState; - var sync = state.sync; - var cb = state.writecb; - - onwriteStateUpdate(state); - - if (er) onwriteError(stream, state, sync, er, cb);else { - // Check if we're actually ready to finish, but don't emit yet - var finished = needFinish(state); - - if (!finished && !state.corked && !state.bufferProcessing && state.bufferedRequest) { - clearBuffer(stream, state); - } - - if (sync) { - /**/ - asyncWrite(afterWrite, stream, state, finished, cb); - /**/ - } else { - afterWrite(stream, state, finished, cb); - } - } -} - -function afterWrite(stream, state, finished, cb) { - if (!finished) onwriteDrain(stream, state); - state.pendingcb--; - cb(); - finishMaybe(stream, state); -} - -// Must force callback to be called on nextTick, so that we don't -// emit 'drain' before the write() consumer gets the 'false' return -// value, and has a chance to attach a 'drain' listener. -function onwriteDrain(stream, state) { - if (state.length === 0 && state.needDrain) { - state.needDrain = false; - stream.emit('drain'); - } -} - -// if there's something in the buffer waiting, then process it -function clearBuffer(stream, state) { - state.bufferProcessing = true; - var entry = state.bufferedRequest; - - if (stream._writev && entry && entry.next) { - // Fast case, write everything using _writev() - var l = state.bufferedRequestCount; - var buffer = new Array(l); - var holder = state.corkedRequestsFree; - holder.entry = entry; - - var count = 0; - while (entry) { - buffer[count] = entry; - entry = entry.next; - count += 1; - } - - doWrite(stream, state, true, state.length, buffer, '', holder.finish); - - // doWrite is almost always async, defer these to save a bit of time - // as the hot path ends with doWrite - state.pendingcb++; - state.lastBufferedRequest = null; - if (holder.next) { - state.corkedRequestsFree = holder.next; - holder.next = null; - } else { - state.corkedRequestsFree = new CorkedRequest(state); - } - } else { - // Slow case, write chunks one-by-one - while (entry) { - var chunk = entry.chunk; - var encoding = entry.encoding; - var cb = entry.callback; - var len = state.objectMode ? 1 : chunk.length; - - doWrite(stream, state, false, len, chunk, encoding, cb); - entry = entry.next; - // if we didn't call the onwrite immediately, then - // it means that we need to wait until it does. - // also, that means that the chunk and cb are currently - // being processed, so move the buffer counter past them. - if (state.writing) { - break; - } - } - - if (entry === null) state.lastBufferedRequest = null; - } - - state.bufferedRequestCount = 0; - state.bufferedRequest = entry; - state.bufferProcessing = false; -} - -Writable.prototype._write = function (chunk, encoding, cb) { - cb(new Error('not implemented')); -}; - -Writable.prototype._writev = null; - -Writable.prototype.end = function (chunk, encoding, cb) { - var state = this._writableState; - - if (typeof chunk === 'function') { - cb = chunk; - chunk = null; - encoding = null; - } else if (typeof encoding === 'function') { - cb = encoding; - encoding = null; - } - - if (chunk !== null && chunk !== undefined) this.write(chunk, encoding); - - // .end() fully uncorks - if (state.corked) { - state.corked = 1; - this.uncork(); - } - - // ignore unnecessary end() calls. - if (!state.ending && !state.finished) endWritable(this, state, cb); -}; - -function needFinish(state) { - return state.ending && state.length === 0 && state.bufferedRequest === null && !state.finished && !state.writing; -} - -function prefinish(stream, state) { - if (!state.prefinished) { - state.prefinished = true; - stream.emit('prefinish'); - } -} - -function finishMaybe(stream, state) { - var need = needFinish(state); - if (need) { - if (state.pendingcb === 0) { - prefinish(stream, state); - state.finished = true; - stream.emit('finish'); - } else { - prefinish(stream, state); - } - } - return need; -} - -function endWritable(stream, state, cb) { - state.ending = true; - finishMaybe(stream, state); - if (cb) { - if (state.finished) processNextTick(cb);else stream.once('finish', cb); - } - state.ended = true; - stream.writable = false; -} - -// It seems a linked list but it is not -// there will be only 2 of these for each stream -function CorkedRequest(state) { - var _this = this; - - this.next = null; - this.entry = null; - - this.finish = function (err) { - var entry = _this.entry; - _this.entry = null; - while (entry) { - var cb = entry.callback; - state.pendingcb--; - cb(err); - entry = entry.next; - } - if (state.corkedRequestsFree) { - state.corkedRequestsFree.next = _this; - } else { - state.corkedRequestsFree = _this; - } - }; -} -}).call(this,require('_process')) -},{"./_stream_duplex":21,"_process":16,"buffer":5,"buffer-shims":4,"core-util-is":7,"events":8,"inherits":11,"process-nextick-args":15,"util-deprecate":36}],26:[function(require,module,exports){ -'use strict'; - -var Buffer = require('buffer').Buffer; -/**/ -var bufferShim = require('buffer-shims'); -/**/ - -module.exports = BufferList; - -function BufferList() { - this.head = null; - this.tail = null; - this.length = 0; -} - -BufferList.prototype.push = function (v) { - var entry = { data: v, next: null }; - if (this.length > 0) this.tail.next = entry;else this.head = entry; - this.tail = entry; - ++this.length; -}; - -BufferList.prototype.unshift = function (v) { - var entry = { data: v, next: this.head }; - if (this.length === 0) this.tail = entry; - this.head = entry; - ++this.length; -}; - -BufferList.prototype.shift = function () { - if (this.length === 0) return; - var ret = this.head.data; - if (this.length === 1) this.head = this.tail = null;else this.head = this.head.next; - --this.length; - return ret; -}; - -BufferList.prototype.clear = function () { - this.head = this.tail = null; - this.length = 0; -}; - -BufferList.prototype.join = function (s) { - if (this.length === 0) return ''; - var p = this.head; - var ret = '' + p.data; - while (p = p.next) { - ret += s + p.data; - }return ret; -}; - -BufferList.prototype.concat = function (n) { - if (this.length === 0) return bufferShim.alloc(0); - if (this.length === 1) return this.head.data; - var ret = bufferShim.allocUnsafe(n >>> 0); - var p = this.head; - var i = 0; - while (p) { - p.data.copy(ret, i); - i += p.data.length; - p = p.next; - } - return ret; -}; -},{"buffer":5,"buffer-shims":4}],27:[function(require,module,exports){ -(function (process){ -var Stream = (function (){ - try { - return require('st' + 'ream'); // hack to fix a circular dependency issue when used with browserify - } catch(_){} -}()); -exports = module.exports = require('./lib/_stream_readable.js'); -exports.Stream = 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'); - -if (!process.browser && process.env.READABLE_STREAM === 'disable' && Stream) { - module.exports = Stream; -} - -}).call(this,require('_process')) -},{"./lib/_stream_duplex.js":21,"./lib/_stream_passthrough.js":22,"./lib/_stream_readable.js":23,"./lib/_stream_transform.js":24,"./lib/_stream_writable.js":25,"_process":16}],28:[function(require,module,exports){ -(function (global){ -var ClientRequest = require('./lib/request') -var extend = require('xtend') -var statusCodes = require('builtin-status-codes') -var url = require('url') - -var http = exports - -http.request = function (opts, cb) { - if (typeof opts === 'string') - opts = url.parse(opts) - else - opts = extend(opts) - - // Normally, the page is loaded from http or https, so not specifying a protocol - // will result in a (valid) protocol-relative url. However, this won't work if - // the protocol is something else, like 'file:' - var defaultProtocol = global.location.protocol.search(/^https?:$/) === -1 ? 'http:' : '' - - var protocol = opts.protocol || defaultProtocol - var host = opts.hostname || opts.host - var port = opts.port - var path = opts.path || '/' - - // Necessary for IPv6 addresses - if (host && host.indexOf(':') !== -1) - host = '[' + host + ']' - - // This may be a relative url. The browser should always be able to interpret it correctly. - opts.url = (host ? (protocol + '//' + host) : '') + (port ? ':' + port : '') + path - opts.method = (opts.method || 'GET').toUpperCase() - opts.headers = opts.headers || {} - - // Also valid opts.auth, opts.mode - - var req = new ClientRequest(opts) - if (cb) - req.on('response', cb) - return req -} - -http.get = function get (opts, cb) { - var req = http.request(opts, cb) - req.end() - return req -} - -http.Agent = function () {} -http.Agent.defaultMaxSockets = 4 - -http.STATUS_CODES = statusCodes - -http.METHODS = [ - 'CHECKOUT', - 'CONNECT', - 'COPY', - 'DELETE', - 'GET', - 'HEAD', - 'LOCK', - 'M-SEARCH', - 'MERGE', - 'MKACTIVITY', - 'MKCOL', - 'MOVE', - 'NOTIFY', - 'OPTIONS', - 'PATCH', - 'POST', - 'PROPFIND', - 'PROPPATCH', - 'PURGE', - 'PUT', - 'REPORT', - 'SEARCH', - 'SUBSCRIBE', - 'TRACE', - 'UNLOCK', - 'UNSUBSCRIBE' -] -}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"./lib/request":30,"builtin-status-codes":6,"url":34,"xtend":37}],29:[function(require,module,exports){ -(function (global){ -exports.fetch = isFunction(global.fetch) && isFunction(global.ReadableStream) - -exports.blobConstructor = false -try { - new Blob([new ArrayBuffer(1)]) - exports.blobConstructor = true -} catch (e) {} - -var xhr = new global.XMLHttpRequest() -// If location.host is empty, e.g. if this page/worker was loaded -// from a Blob, then use example.com to avoid an error -xhr.open('GET', global.location.host ? '/' : 'https://example.com') - -function checkTypeSupport (type) { - try { - xhr.responseType = type - return xhr.responseType === type - } catch (e) {} - return false -} - -// For some strange reason, Safari 7.0 reports typeof global.ArrayBuffer === 'object'. -// Safari 7.1 appears to have fixed this bug. -var haveArrayBuffer = typeof global.ArrayBuffer !== 'undefined' -var haveSlice = haveArrayBuffer && isFunction(global.ArrayBuffer.prototype.slice) - -exports.arraybuffer = haveArrayBuffer && checkTypeSupport('arraybuffer') -// These next two tests unavoidably show warnings in Chrome. Since fetch will always -// be used if it's available, just return false for these to avoid the warnings. -exports.msstream = !exports.fetch && haveSlice && checkTypeSupport('ms-stream') -exports.mozchunkedarraybuffer = !exports.fetch && haveArrayBuffer && - checkTypeSupport('moz-chunked-arraybuffer') -exports.overrideMimeType = isFunction(xhr.overrideMimeType) -exports.vbArray = isFunction(global.VBArray) - -function isFunction (value) { - return typeof value === 'function' -} - -xhr = null // Help gc - -}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{}],30:[function(require,module,exports){ -(function (process,global,Buffer){ -var capability = require('./capability') -var inherits = require('inherits') -var response = require('./response') -var stream = require('readable-stream') -var toArrayBuffer = require('to-arraybuffer') - -var IncomingMessage = response.IncomingMessage -var rStates = response.readyStates - -function decideMode (preferBinary, useFetch) { - if (capability.fetch && useFetch) { - return 'fetch' - } else if (capability.mozchunkedarraybuffer) { - return 'moz-chunked-arraybuffer' - } else if (capability.msstream) { - return 'ms-stream' - } else if (capability.arraybuffer && preferBinary) { - return 'arraybuffer' - } else if (capability.vbArray && preferBinary) { - return 'text:vbarray' - } else { - return 'text' - } -} - -var ClientRequest = module.exports = function (opts) { - var self = this - stream.Writable.call(self) - - self._opts = opts - self._body = [] - self._headers = {} - if (opts.auth) - self.setHeader('Authorization', 'Basic ' + new Buffer(opts.auth).toString('base64')) - Object.keys(opts.headers).forEach(function (name) { - self.setHeader(name, opts.headers[name]) - }) - - var preferBinary - var useFetch = true - if (opts.mode === 'disable-fetch') { - // If the use of XHR should be preferred and includes preserving the 'content-type' header - useFetch = false - preferBinary = true - } else if (opts.mode === 'prefer-streaming') { - // If streaming is a high priority but binary compatibility and - // the accuracy of the 'content-type' header aren't - preferBinary = false - } else if (opts.mode === 'allow-wrong-content-type') { - // If streaming is more important than preserving the 'content-type' header - preferBinary = !capability.overrideMimeType - } else if (!opts.mode || opts.mode === 'default' || opts.mode === 'prefer-fast') { - // Use binary if text streaming may corrupt data or the content-type header, or for speed - preferBinary = true - } else { - throw new Error('Invalid value for opts.mode') - } - self._mode = decideMode(preferBinary, useFetch) - - self.on('finish', function () { - self._onFinish() - }) -} - -inherits(ClientRequest, stream.Writable) - -ClientRequest.prototype.setHeader = function (name, value) { - var self = this - var lowerName = name.toLowerCase() - // This check is not necessary, but it prevents warnings from browsers about setting unsafe - // headers. To be honest I'm not entirely sure hiding these warnings is a good thing, but - // http-browserify did it, so I will too. - if (unsafeHeaders.indexOf(lowerName) !== -1) - return - - self._headers[lowerName] = { - name: name, - value: value - } -} - -ClientRequest.prototype.getHeader = function (name) { - var self = this - return self._headers[name.toLowerCase()].value -} - -ClientRequest.prototype.removeHeader = function (name) { - var self = this - delete self._headers[name.toLowerCase()] -} - -ClientRequest.prototype._onFinish = function () { - var self = this - - if (self._destroyed) - return - var opts = self._opts - - var headersObj = self._headers - var body - if (opts.method === 'POST' || opts.method === 'PUT' || opts.method === 'PATCH') { - if (capability.blobConstructor) { - body = new global.Blob(self._body.map(function (buffer) { - return toArrayBuffer(buffer) - }), { - type: (headersObj['content-type'] || {}).value || '' - }) - } else { - // get utf8 string - body = Buffer.concat(self._body).toString() - } - } - - if (self._mode === 'fetch') { - var headers = Object.keys(headersObj).map(function (name) { - return [headersObj[name].name, headersObj[name].value] - }) - - global.fetch(self._opts.url, { - method: self._opts.method, - headers: headers, - body: body, - mode: 'cors', - credentials: opts.withCredentials ? 'include' : 'same-origin' - }).then(function (response) { - self._fetchResponse = response - self._connect() - }, function (reason) { - self.emit('error', reason) - }) - } else { - var xhr = self._xhr = new global.XMLHttpRequest() - try { - xhr.open(self._opts.method, self._opts.url, true) - } catch (err) { - process.nextTick(function () { - self.emit('error', err) - }) - return - } - - // Can't set responseType on really old browsers - if ('responseType' in xhr) - xhr.responseType = self._mode.split(':')[0] - - if ('withCredentials' in xhr) - xhr.withCredentials = !!opts.withCredentials - - if (self._mode === 'text' && 'overrideMimeType' in xhr) - xhr.overrideMimeType('text/plain; charset=x-user-defined') - - Object.keys(headersObj).forEach(function (name) { - xhr.setRequestHeader(headersObj[name].name, headersObj[name].value) - }) - - 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.emit('response', self._response) -} - -ClientRequest.prototype._write = function (chunk, encoding, cb) { - var self = this - - self._body.push(chunk) - cb() -} - -ClientRequest.prototype.abort = ClientRequest.prototype.destroy = function () { - var self = this - self._destroyed = true - if (self._response) - self._response._destroyed = true - if (self._xhr) - self._xhr.abort() - // Currently, there isn't a way to truly abort a fetch. - // If you like bikeshedding, see https://github.com/whatwg/fetch/issues/27 -} - -ClientRequest.prototype.end = function (data, encoding, cb) { - var self = this - if (typeof data === 'function') { - cb = data - data = undefined - } - - stream.Writable.prototype.end.call(self, data, encoding, cb) -} - -ClientRequest.prototype.flushHeaders = function () {} -ClientRequest.prototype.setTimeout = function () {} -ClientRequest.prototype.setNoDelay = function () {} -ClientRequest.prototype.setSocketKeepAlive = function () {} - -// Taken from http://www.w3.org/TR/XMLHttpRequest/#the-setrequestheader%28%29-method -var unsafeHeaders = [ - 'accept-charset', - 'accept-encoding', - 'access-control-request-headers', - 'access-control-request-method', - 'connection', - 'content-length', - 'cookie', - 'cookie2', - 'date', - 'dnt', - 'expect', - 'host', - 'keep-alive', - 'origin', - 'referer', - 'te', - 'trailer', - 'transfer-encoding', - 'upgrade', - 'user-agent', - 'via' -] - -}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer) -},{"./capability":29,"./response":31,"_process":16,"buffer":5,"inherits":11,"readable-stream":27,"to-arraybuffer":33}],31:[function(require,module,exports){ -(function (process,global,Buffer){ -var capability = require('./capability') -var inherits = require('inherits') -var stream = require('readable-stream') - -var rStates = exports.readyStates = { - UNSENT: 0, - OPENED: 1, - HEADERS_RECEIVED: 2, - LOADING: 3, - DONE: 4 -} - -var IncomingMessage = exports.IncomingMessage = function (xhr, response, mode) { - var self = this - stream.Readable.call(self) - - self._mode = mode - self.headers = {} - self.rawHeaders = [] - self.trailers = {} - self.rawTrailers = [] - - // Fake the 'close' event, but only once 'end' fires - self.on('end', function () { - // The nextTick is necessary to prevent the 'request' module from causing an infinite loop - process.nextTick(function () { - self.emit('close') - }) - }) - - if (mode === 'fetch') { - self._fetchResponse = response - - self.url = response.url - self.statusCode = response.status - self.statusMessage = response.statusText - // backwards compatible version of for ( of ): - // for (var ,_i,_it = [Symbol.iterator](); = (_i = _it.next()).value,!_i.done;) - for (var header, _i, _it = response.headers[Symbol.iterator](); header = (_i = _it.next()).value, !_i.done;) { - self.headers[header[0].toLowerCase()] = header[1] - self.rawHeaders.push(header[0], header[1]) - } - - // TODO: this doesn't respect backpressure. Once WritableStream is available, this can be fixed - var reader = response.body.getReader() - function read () { - reader.read().then(function (result) { - if (self._destroyed) - return - if (result.done) { - self.push(null) - return - } - self.push(new Buffer(result.value)) - read() - }) - } - read() - - } else { - self._xhr = xhr - self._pos = 0 - - self.url = xhr.responseURL - self.statusCode = xhr.status - self.statusMessage = xhr.statusText - var headers = xhr.getAllResponseHeaders().split(/\r?\n/) - headers.forEach(function (header) { - var matches = header.match(/^([^:]+):\s*(.*)/) - if (matches) { - var key = matches[1].toLowerCase() - if (key === 'set-cookie') { - if (self.headers[key] === undefined) { - self.headers[key] = [] - } - self.headers[key].push(matches[2]) - } else if (self.headers[key] !== undefined) { - self.headers[key] += ', ' + matches[2] - } else { - self.headers[key] = matches[2] - } - self.rawHeaders.push(matches[1], matches[2]) - } - }) - - self._charset = 'x-user-defined' - if (!capability.overrideMimeType) { - var mimeType = self.rawHeaders['mime-type'] - if (mimeType) { - var charsetMatch = mimeType.match(/;\s*charset=([^;])(;|$)/) - if (charsetMatch) { - self._charset = charsetMatch[1].toLowerCase() - } - } - if (!self._charset) - self._charset = 'utf-8' // best guess - } - } -} - -inherits(IncomingMessage, stream.Readable) - -IncomingMessage.prototype._read = function () {} - -IncomingMessage.prototype._onXHRProgress = function () { - var self = this - - var xhr = self._xhr - - var response = null - switch (self._mode) { - case 'text:vbarray': // For IE9 - if (xhr.readyState !== rStates.DONE) - break - try { - // This fails in IE8 - response = new global.VBArray(xhr.responseBody).toArray() - } catch (e) {} - if (response !== null) { - self.push(new Buffer(response)) - break - } - // Falls through in IE8 - case 'text': - try { // This will fail when readyState = 3 in IE9. Switch mode and wait for readyState = 4 - response = xhr.responseText - } catch (e) { - self._mode = 'text:vbarray' - break - } - if (response.length > self._pos) { - var newData = response.substr(self._pos) - if (self._charset === 'x-user-defined') { - var buffer = new Buffer(newData.length) - for (var i = 0; i < newData.length; i++) - buffer[i] = newData.charCodeAt(i) & 0xff - - self.push(buffer) - } else { - self.push(newData, self._charset) - } - self._pos = response.length - } - break - case 'arraybuffer': - if (xhr.readyState !== rStates.DONE || !xhr.response) - break - response = xhr.response - self.push(new Buffer(new Uint8Array(response))) - break - case 'moz-chunked-arraybuffer': // take whole - response = xhr.response - if (xhr.readyState !== rStates.LOADING || !response) - break - self.push(new Buffer(new Uint8Array(response))) - break - case 'ms-stream': - response = xhr.response - if (xhr.readyState !== rStates.LOADING) - break - var reader = new global.MSStreamReader() - reader.onprogress = function () { - if (reader.result.byteLength > self._pos) { - self.push(new Buffer(new Uint8Array(reader.result.slice(self._pos)))) - self._pos = reader.result.byteLength - } - } - reader.onload = function () { - self.push(null) - } - // reader.onerror = ??? // TODO: this - reader.readAsArrayBuffer(response) - break - } - - // The ms-stream case handles end separately in reader.onload() - if (self._xhr.readyState === rStates.DONE && self._mode !== 'ms-stream') { - self.push(null) - } -} - -}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer) -},{"./capability":29,"_process":16,"buffer":5,"inherits":11,"readable-stream":27}],32:[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. - -var Buffer = require('buffer').Buffer; - -var isBufferEncoding = Buffer.isEncoding - || function(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 assertEncoding(encoding) { - if (encoding && !isBufferEncoding(encoding)) { - throw new Error('Unknown encoding: ' + encoding); - } -} - -// StringDecoder provides an interface for efficiently splitting a series of -// buffers into a series of JS strings without breaking apart multi-byte -// characters. CESU-8 is handled as part of the UTF-8 encoding. -// -// @TODO Handling all encodings inside a single object makes it very difficult -// to reason about this code, so it should be split up in the future. -// @TODO There should be a utf8-strict encoding that rejects invalid UTF-8 code -// points as used by CESU-8. -var StringDecoder = exports.StringDecoder = function(encoding) { - this.encoding = (encoding || 'utf8').toLowerCase().replace(/[-_]/, ''); - assertEncoding(encoding); - switch (this.encoding) { - case 'utf8': - // CESU-8 represents each of Surrogate Pair by 3-bytes - this.surrogateSize = 3; - break; - case 'ucs2': - case 'utf16le': - // UTF-16 represents each of Surrogate Pair by 2-bytes - this.surrogateSize = 2; - this.detectIncompleteChar = utf16DetectIncompleteChar; - break; - case 'base64': - // Base-64 stores 3 bytes in 4 chars, and pads the remainder. - this.surrogateSize = 3; - this.detectIncompleteChar = base64DetectIncompleteChar; - break; - default: - this.write = passThroughWrite; - return; - } - - // Enough space to store all bytes of a single character. UTF-8 needs 4 - // bytes, but CESU-8 may require up to 6 (3 bytes per surrogate). - this.charBuffer = new Buffer(6); - // Number of bytes received for the current incomplete multi-byte character. - this.charReceived = 0; - // Number of bytes expected for the current incomplete multi-byte character. - this.charLength = 0; -}; - - -// write decodes the given buffer and returns it as JS string that is -// guaranteed to not contain any partial multi-byte characters. Any partial -// character found at the end of the buffer is buffered up, and will be -// returned when calling write again with the remaining bytes. -// -// Note: Converting a Buffer containing an orphan surrogate to a String -// currently works, but converting a String to a Buffer (via `new Buffer`, or -// Buffer#write) will replace incomplete surrogates with the unicode -// replacement character. See https://codereview.chromium.org/121173009/ . -StringDecoder.prototype.write = function(buffer) { - var charStr = ''; - // if our last write ended with an incomplete multibyte character - while (this.charLength) { - // determine how many remaining bytes this buffer has to offer for this char - var available = (buffer.length >= this.charLength - this.charReceived) ? - this.charLength - this.charReceived : - buffer.length; - - // add the new bytes to the char buffer - buffer.copy(this.charBuffer, this.charReceived, 0, available); - this.charReceived += available; - - if (this.charReceived < this.charLength) { - // still not enough chars in this buffer? wait for more ... - return ''; - } - - // remove bytes belonging to the current character from the buffer - buffer = buffer.slice(available, buffer.length); - - // get the character that was split - charStr = this.charBuffer.slice(0, this.charLength).toString(this.encoding); - - // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character - var charCode = charStr.charCodeAt(charStr.length - 1); - if (charCode >= 0xD800 && charCode <= 0xDBFF) { - this.charLength += this.surrogateSize; - charStr = ''; - continue; - } - this.charReceived = this.charLength = 0; - - // if there are no more bytes in this buffer, just emit our char - if (buffer.length === 0) { - return charStr; - } - break; - } - - // determine and set charLength / charReceived - this.detectIncompleteChar(buffer); - - var end = buffer.length; - if (this.charLength) { - // buffer the incomplete character bytes we got - buffer.copy(this.charBuffer, 0, buffer.length - this.charReceived, end); - end -= this.charReceived; - } - - charStr += buffer.toString(this.encoding, 0, end); - - var end = charStr.length - 1; - var charCode = charStr.charCodeAt(end); - // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character - if (charCode >= 0xD800 && charCode <= 0xDBFF) { - var size = this.surrogateSize; - this.charLength += size; - this.charReceived += size; - this.charBuffer.copy(this.charBuffer, size, 0, size); - buffer.copy(this.charBuffer, 0, 0, size); - return charStr.substring(0, end); - } - - // or just emit the charStr - return charStr; -}; - -// detectIncompleteChar determines if there is an incomplete UTF-8 character at -// the end of the given buffer. If so, it sets this.charLength to the byte -// length that character, and sets this.charReceived to the number of bytes -// that are available for this character. -StringDecoder.prototype.detectIncompleteChar = function(buffer) { - // determine how many bytes we have to check at the end of this buffer - var i = (buffer.length >= 3) ? 3 : buffer.length; - - // Figure out if one of the last i bytes of our buffer announces an - // incomplete char. - for (; i > 0; i--) { - var c = buffer[buffer.length - i]; - - // See http://en.wikipedia.org/wiki/UTF-8#Description - - // 110XXXXX - if (i == 1 && c >> 5 == 0x06) { - this.charLength = 2; - break; - } - - // 1110XXXX - if (i <= 2 && c >> 4 == 0x0E) { - this.charLength = 3; - break; - } - - // 11110XXX - if (i <= 3 && c >> 3 == 0x1E) { - this.charLength = 4; - break; - } - } - this.charReceived = i; -}; - -StringDecoder.prototype.end = function(buffer) { - var res = ''; - if (buffer && buffer.length) - res = this.write(buffer); - - if (this.charReceived) { - var cr = this.charReceived; - var buf = this.charBuffer; - var enc = this.encoding; - res += buf.slice(0, cr).toString(enc); - } - - return res; -}; - -function passThroughWrite(buffer) { - return buffer.toString(this.encoding); -} - -function utf16DetectIncompleteChar(buffer) { - this.charReceived = buffer.length % 2; - this.charLength = this.charReceived ? 2 : 0; -} - -function base64DetectIncompleteChar(buffer) { - this.charReceived = buffer.length % 3; - this.charLength = this.charReceived ? 3 : 0; -} - -},{"buffer":5}],33:[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":5}],34:[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":35,"punycode":17,"querystring":20}],35:[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; - } -}; - -},{}],36:[function(require,module,exports){ -(function (global){ - -/** - * Module exports. - */ - -module.exports = deprecate; - -/** - * Mark that a method should not be used. - * Returns a modified function which warns once by default. - * - * If `localStorage.noDeprecation = true` is set, then it is a no-op. - * - * If `localStorage.throwDeprecation = true` is set, then deprecated functions - * will throw an Error when invoked. - * - * If `localStorage.traceDeprecation = true` is set, then deprecated functions - * will invoke `console.trace()` instead of `console.error()`. - * - * @param {Function} fn - the function to deprecate - * @param {String} msg - the string to print to the console when `fn` is invoked - * @returns {Function} a new "deprecated" version of `fn` - * @api public - */ - -function deprecate (fn, msg) { - if (config('noDeprecation')) { - return fn; - } - - var warned = false; - function deprecated() { - if (!warned) { - if (config('throwDeprecation')) { - throw new Error(msg); - } else if (config('traceDeprecation')) { - console.trace(msg); - } else { - console.warn(msg); - } - warned = true; - } - return fn.apply(this, arguments); - } - - return deprecated; -} - -/** - * Checks `localStorage` for boolean values for the given `name`. - * - * @param {String} name - * @returns {Boolean} - * @api private - */ - -function config (name) { - // accessing global.localStorage can trigger a DOMException in sandboxed iframes - try { - if (!global.localStorage) return false; - } catch (_) { - return false; - } - var val = global.localStorage[name]; - if (null == val) return false; - return String(val).toLowerCase() === 'true'; -} - -}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{}],37:[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 -} - -},{}],38:[function(require,module,exports){ -var ADDR_RE = /^\[?([^\]]+)\]?:(\d+)$/ // ipv4/ipv6/hostname + port - -var 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 -var size = 0 - -module.exports = function addrToIPPort (addr) { - if (size === 100000) module.exports.reset() - if (!cache[addr]) { - var 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 -} - -},{}],39:[function(require,module,exports){ -(function (Buffer){ -/** - * 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 (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)) - ? new Buffer(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 0x64: - return decode.dictionary() - case 0x6C: - return decode.list() - case 0x69: - 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] !== 0x65) { - dict[decode.buffer()] = decode.next() - } - - decode.position++ - - return dict -} - -decode.list = function () { - decode.position++ - - var lst = [] - - while (decode.data[decode.position] !== 0x65) { - lst.push(decode.next()) - } - - decode.position++ - - return lst -} - -decode.integer = function () { - var end = decode.find(0x65) - var number = decode.data.toString('ascii', decode.position + 1, end) - - decode.position += end + 1 - decode.position - - return parseInt(number, 10) -} - -decode.buffer = function () { - var sep = decode.find(0x3A) - var length = parseInt(decode.data.toString('ascii', decode.position, sep), 10) - 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 - -}).call(this,require("buffer").Buffer) -},{"buffer":5}],40:[function(require,module,exports){ -(function (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._encode = function (buffers, data) { - if (Buffer.isBuffer(data)) { - buffers.push(new Buffer(data.length + ':')) - buffers.push(data) - return - } - - switch (typeof data) { - case 'string': - encode.buffer(buffers, data) - break - case 'number': - encode.number(buffers, data) - break - case 'object': - data.constructor === Array - ? encode.list(buffers, data) - : encode.dict(buffers, data) - break - case 'boolean': - encode.number(buffers, data ? 1 : 0) - break - } -} - -var buffE = new Buffer('e') -var buffD = new Buffer('d') -var buffL = new Buffer('l') - -encode.buffer = function (buffers, data) { - buffers.push(new Buffer(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(new Buffer('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] - encode.buffer(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++) { - encode._encode(buffers, data[i]) - } - - buffers.push(buffE) -} - -module.exports = encode - -}).call(this,require("buffer").Buffer) -},{"buffer":5}],41:[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":39,"./encode":40}],42:[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) { - /* Note that "(low + high) >>> 1" may overflow, and results in a typecast - * to double (which gives the wrong results). */ - 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; -} - -},{}],43:[function(require,module,exports){ -(function (Buffer){ -var Container = typeof Buffer !== "undefined" ? Buffer //in node, use buffers - : typeof Int8Array !== "undefined" ? Int8Array //in newer browsers, use webgl int8arrays - : function(l){ var a = new Array(l); for(var i = 0; i < l; i++) a[i]=0; }; //else, do something similar - -function BitField(data, opts){ - if(!(this instanceof BitField)) { - return new BitField(data, opts); - } - - if(arguments.length === 0){ - data = 0; - } - - this.grow = opts && (isFinite(opts.grow) && getByteSize(opts.grow) || opts.grow) || 0; - - if(typeof data === "number" || data === undefined){ - data = new Container(getByteSize(data)); - if(data.fill && !data._isBuffer) data.fill(0); // clear node buffers of garbage - } - this.buffer = data; -} - -function getByteSize(num){ - var out = num >> 3; - if(num % 8 !== 0) out++; - return out; -} - -BitField.prototype.get = function(i){ - var j = i >> 3; - return (j < this.buffer.length) && - !!(this.buffer[j] & (128 >> (i % 8))); -}; - -BitField.prototype.set = function(i, b){ - var j = i >> 3; - if (b || arguments.length === 1){ - if (this.buffer.length < j + 1) this._grow(Math.max(j + 1, Math.min(2 * this.buffer.length, this.grow))); - // Set - this.buffer[j] |= 128 >> (i % 8); - } else if (j < this.buffer.length) { - /// Clear - this.buffer[j] &= ~(128 >> (i % 8)); - } -}; - -BitField.prototype._grow = function(length) { - if (this.buffer.length < length && length <= this.grow) { - var newBuffer = new Container(length); - if (newBuffer.fill) newBuffer.fill(0); - if (this.buffer.copy) this.buffer.copy(newBuffer, 0); - else { - for(var i = 0; i < this.buffer.length; i++) { - newBuffer[i] = this.buffer[i]; - } - } - this.buffer = newBuffer; - } -}; - -if(typeof module !== "undefined") module.exports = BitField; - -}).call(this,require("buffer").Buffer) -},{"buffer":5}],44:[function(require,module,exports){ -module.exports = Wire - -var bencode = require('bencode') -var BitField = require('bitfield') -var Buffer = require('safe-buffer').Buffer -var debug = require('debug')('bittorrent-protocol') -var extend = require('xtend') -var inherits = require('inherits') -var randombytes = require('randombytes') -var speedometer = require('speedometer') -var stream = require('readable-stream') - -var BITFIELD_GROW = 400000 -var KEEP_ALIVE_TIMEOUT = 55000 - -var MESSAGE_PROTOCOL = Buffer.from('\u0013BitTorrent protocol') -var MESSAGE_KEEP_ALIVE = Buffer.from([0x00, 0x00, 0x00, 0x00]) -var MESSAGE_CHOKE = Buffer.from([0x00, 0x00, 0x00, 0x01, 0x00]) -var MESSAGE_UNCHOKE = Buffer.from([0x00, 0x00, 0x00, 0x01, 0x01]) -var MESSAGE_INTERESTED = Buffer.from([0x00, 0x00, 0x00, 0x01, 0x02]) -var MESSAGE_UNINTERESTED = Buffer.from([0x00, 0x00, 0x00, 0x01, 0x03]) - -var MESSAGE_RESERVED = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] -var MESSAGE_PORT = [0x00, 0x00, 0x00, 0x03, 0x09, 0x00, 0x00] - -function Request (piece, offset, length, callback) { - this.piece = piece - this.offset = offset - this.length = length - this.callback = callback -} - -inherits(Wire, stream.Duplex) - -function Wire () { - if (!(this instanceof Wire)) return new Wire() - stream.Duplex.call(this) - - 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.on('finish', this._onFinish) - - this._parseHandshake() -} - -/** - * Set whether to send a "keep-alive" ping (sent every 55s) - * @param {boolean} enable - */ -Wire.prototype.setKeepAlive = function (enable) { - var self = this - self._debug('setKeepAlive %s', enable) - clearInterval(self._keepAliveInterval) - if (enable === false) return - self._keepAliveInterval = setInterval(function () { - self.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) - */ -Wire.prototype.setTimeout = function (ms, unref) { - this._debug('setTimeout ms=%d unref=%s', ms, unref) - this._clearTimeout() - this._timeoutMs = ms - this._timeoutUnref = !!unref - this._updateTimeout() -} - -Wire.prototype.destroy = function () { - if (this.destroyed) return - this.destroyed = true - this._debug('destroy') - this.emit('close') - this.end() -} - -Wire.prototype.end = function () { - this._debug('end') - this._onUninterested() - this._onChoke() - stream.Duplex.prototype.end.apply(this, arguments) -} - -/** - * Use the specified protocol extension. - * @param {function} Extension - */ -Wire.prototype.use = function (Extension) { - var 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) - - var ext = this._nextExt - var 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": - */ -Wire.prototype.keepAlive = function () { - 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 - */ -Wire.prototype.handshake = function (infoHash, peerId, extensions) { - var infoHashBuffer, peerIdBuffer - if (typeof infoHash === 'string') { - 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) - - var 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. - */ -Wire.prototype._sendExtendedHandshake = function () { - // Create extended message object from registered extensions - var msg = extend(this.extendedHandshake) - msg.m = {} - for (var ext in this.extendedMapping) { - var name = this.extendedMapping[ext] - msg.m[name] = Number(ext) - } - - // Send extended handshake - this.extended(0, bencode.encode(msg)) - this._extendedHandshakeSent = true -} - -/** - * Message "choke": - */ -Wire.prototype.choke = function () { - if (this.amChoking) return - this.amChoking = true - this._debug('choke') - this.peerRequests.splice(0, this.peerRequests.length) - this._push(MESSAGE_CHOKE) -} - -/** - * Message "unchoke": - */ -Wire.prototype.unchoke = function () { - if (!this.amChoking) return - this.amChoking = false - this._debug('unchoke') - this._push(MESSAGE_UNCHOKE) -} - -/** - * Message "interested": - */ -Wire.prototype.interested = function () { - if (this.amInterested) return - this.amInterested = true - this._debug('interested') - this._push(MESSAGE_INTERESTED) -} - -/** - * Message "uninterested": - */ -Wire.prototype.uninterested = function () { - if (!this.amInterested) return - this.amInterested = false - this._debug('uninterested') - this._push(MESSAGE_UNINTERESTED) -} - -/** - * Message "have": - * @param {number} index - */ -Wire.prototype.have = function (index) { - this._debug('have %d', index) - this._message(4, [index], null) -} - -/** - * Message "bitfield": - * @param {BitField|Buffer} bitfield - */ -Wire.prototype.bitfield = function (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 - */ -Wire.prototype.request = function (index, offset, length, cb) { - if (!cb) cb = function () {} - 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 - */ -Wire.prototype.piece = function (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 - */ -Wire.prototype.cancel = function (index, offset, length) { - this._debug('cancel index=%d offset=%d length=%d', index, offset, length) - this._callback( - pull(this.requests, index, offset, length), - new Error('request was cancelled'), - null - ) - this._message(8, [index, offset, length], null) -} - -/** - * Message: "port" - * @param {Number} port - */ -Wire.prototype.port = function (port) { - this._debug('port %d', port) - var message = Buffer.from(MESSAGE_PORT) - message.writeUInt16BE(port, 5) - this._push(message) -} - -/** - * Message: "extended" - * @param {number|string} ext - * @param {Object} obj - */ -Wire.prototype.extended = function (ext, obj) { - this._debug('extended ext=%s', ext) - if (typeof ext === 'string' && this.peerExtendedMapping[ext]) { - ext = this.peerExtendedMapping[ext] - } - if (typeof ext === 'number') { - var extId = Buffer.from([ext]) - var 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. - */ -Wire.prototype._read = function () {} - -/** - * Send a message to the remote peer. - */ -Wire.prototype._message = function (id, numbers, data) { - var dataLength = data ? data.length : 0 - var buffer = Buffer.allocUnsafe(5 + 4 * numbers.length) - - buffer.writeUInt32BE(buffer.length + dataLength - 4, 0) - buffer[4] = id - for (var i = 0; i < numbers.length; i++) { - buffer.writeUInt32BE(numbers[i], 5 + 4 * i) - } - - this._push(buffer) - if (data) this._push(data) -} - -Wire.prototype._push = function (data) { - if (this._finished) return - return this.push(data) -} - -// -// INCOMING MESSAGES -// - -Wire.prototype._onKeepAlive = function () { - this._debug('got keep-alive') - this.emit('keep-alive') -} - -Wire.prototype._onHandshake = function (infoHashBuffer, peerIdBuffer, extensions) { - var infoHash = infoHashBuffer.toString('hex') - var 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) - - var name - for (name in this._ext) { - this._ext[name].onHandshake(infoHash, peerId, extensions) - } - - if (extensions.extended && this._handshakeSent && - !this._extendedHandshakeSent) { - // outgoing connection - this._sendExtendedHandshake() - } -} - -Wire.prototype._onChoke = function () { - this.peerChoking = true - this._debug('got choke') - this.emit('choke') - while (this.requests.length) { - this._callback(this.requests.shift(), new Error('peer is choking'), null) - } -} - -Wire.prototype._onUnchoke = function () { - this.peerChoking = false - this._debug('got unchoke') - this.emit('unchoke') -} - -Wire.prototype._onInterested = function () { - this.peerInterested = true - this._debug('got interested') - this.emit('interested') -} - -Wire.prototype._onUninterested = function () { - this.peerInterested = false - this._debug('got uninterested') - this.emit('uninterested') -} - -Wire.prototype._onHave = function (index) { - if (this.peerPieces.get(index)) return - this._debug('got have %d', index) - - this.peerPieces.set(index, true) - this.emit('have', index) -} - -Wire.prototype._onBitField = function (buffer) { - this.peerPieces = new BitField(buffer) - this._debug('got bitfield') - this.emit('bitfield', this.peerPieces) -} - -Wire.prototype._onRequest = function (index, offset, length) { - var self = this - if (self.amChoking) return - self._debug('got request index=%d offset=%d length=%d', index, offset, length) - - var respond = function (err, buffer) { - if (request !== pull(self.peerRequests, index, offset, length)) return - if (err) return self._debug('error satisfying request index=%d offset=%d length=%d (%s)', index, offset, length, err.message) - self.piece(index, offset, buffer) - } - - var request = new Request(index, offset, length, respond) - self.peerRequests.push(request) - self.emit('request', index, offset, length, respond) -} - -Wire.prototype._onPiece = function (index, offset, buffer) { - this._debug('got piece index=%d offset=%d', index, offset) - this._callback(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) -} - -Wire.prototype._onCancel = function (index, offset, length) { - this._debug('got cancel index=%d offset=%d length=%d', index, offset, length) - pull(this.peerRequests, index, offset, length) - this.emit('cancel', index, offset, length) -} - -Wire.prototype._onPort = function (port) { - this._debug('got port %d', port) - this.emit('port', port) -} - -Wire.prototype._onExtended = function (ext, buf) { - if (ext === 0) { - var info - try { - info = bencode.decode(buf) - } catch (err) { - this._debug('ignoring invalid extended handshake: %s', err.message || err) - } - - if (!info) return - this.peerExtendedHandshake = info - - var 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) - } -} - -Wire.prototype._onTimeout = function () { - 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 - */ -Wire.prototype._write = function (data, encoding, cb) { - this._bufferSize += data.length - this._buffer.push(data) - - while (this._bufferSize >= this._parserSize) { - var 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 -} - -Wire.prototype._callback = function (request, err, buffer) { - if (!request) return - - this._clearTimeout() - - if (!this.peerChoking && !this._finished) this._updateTimeout() - request.callback(err, buffer) -} - -Wire.prototype._clearTimeout = function () { - if (!this._timeout) return - - clearTimeout(this._timeout) - this._timeout = null -} - -Wire.prototype._updateTimeout = function () { - var self = this - if (!self._timeoutMs || !self.requests.length || self._timeout) return - - self._timeout = setTimeout(function () { - self._onTimeout() - }, self._timeoutMs) - if (self._timeoutUnref && self._timeout.unref) self._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 - */ -Wire.prototype._parse = function (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 - */ -Wire.prototype._onMessageLength = function (buffer) { - var 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 - */ -Wire.prototype._onMessage = function (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) - } -} - -Wire.prototype._parseHandshake = function () { - var self = this - self._parse(1, function (buffer) { - var pstrlen = buffer.readUInt8(0) - self._parse(pstrlen + 48, function (handshake) { - var protocol = handshake.slice(0, pstrlen) - if (protocol.toString() !== 'BitTorrent protocol') { - self._debug('Error: wire not speaking BitTorrent protocol (%s)', protocol.toString()) - self.end() - return - } - handshake = handshake.slice(pstrlen) - self._onHandshake(handshake.slice(8, 28), handshake.slice(28, 48), { - dht: !!(handshake[7] & 0x01), // see bep_0005 - extended: !!(handshake[5] & 0x10) // see bep_0010 - }) - self._parse(4, self._onMessageLength) - }) - }) -} - -Wire.prototype._onFinish = function () { - this._finished = true - - this.push(null) // stream cannot be half open, so signal the end of it - while (this.read()) {} // consume and discard the rest of the stream data - - clearInterval(this._keepAliveInterval) - this._parse(Number.MAX_VALUE, function () {}) - this.peerRequests = [] - while (this.requests.length) { - this._callback(this.requests.shift(), new Error('wire was closed'), null) - } -} - -Wire.prototype._debug = function () { - var args = [].slice.call(arguments) - args[0] = '[' + this._debugId + '] ' + args[0] - debug.apply(null, args) -} - -function pull (requests, piece, offset, length) { - for (var i = 0; i < requests.length; i++) { - var req = requests[i] - if (req.piece !== piece || req.offset !== offset || req.length !== length) continue - - if (i === 0) requests.shift() - else requests.splice(i, 1) - - return req - } - return null -} - -},{"bencode":41,"bitfield":43,"debug":56,"inherits":65,"randombytes":90,"readable-stream":98,"safe-buffer":104,"speedometer":110,"xtend":137}],45:[function(require,module,exports){ -(function (process){ -module.exports = Client - -var Buffer = require('safe-buffer').Buffer -var debug = require('debug')('bittorrent-tracker') -var EventEmitter = require('events').EventEmitter -var extend = require('xtend') -var inherits = require('inherits') -var once = require('once') -var parallel = require('run-parallel') -var Peer = require('simple-peer') -var uniq = require('uniq') -var url = require('url') - -var common = require('./lib/common') -var HTTPTracker = require('./lib/client/http-tracker') // empty object in browser -var UDPTracker = require('./lib/client/udp-tracker') // empty object in browser -var WebSocketTracker = require('./lib/client/websocket-tracker') - -inherits(Client, EventEmitter) - -/** - * 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.wrtc custom webrtc impl (useful in node.js) - */ -function Client (opts) { - var self = this - if (!(self instanceof Client)) return new Client(opts) - EventEmitter.call(self) - if (!opts) opts = {} - - 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') - - // required - self.peerId = typeof opts.peerId === 'string' - ? opts.peerId - : opts.peerId.toString('hex') - self._peerIdBuffer = Buffer.from(self.peerId, 'hex') - self._peerIdBinary = self._peerIdBuffer.toString('binary') - - self.infoHash = typeof opts.infoHash === 'string' - ? opts.infoHash - : opts.infoHash.toString('hex') - self._infoHashBuffer = Buffer.from(self.infoHash, 'hex') - self._infoHashBinary = self._infoHashBuffer.toString('binary') - - self._port = opts.port - - self.destroyed = false - - self._rtcConfig = opts.rtcConfig - self._getAnnounceOpts = opts.getAnnounceOpts - self._wrtc = opts.wrtc - - // Support lazy 'wrtc' module initialization - // See: https://github.com/feross/webtorrent-hybrid/issues/46 - if (typeof self._wrtc === 'function') self._wrtc = self._wrtc() - - debug('new client %s', self.infoHash) - - var webrtcSupport = self._wrtc !== false && (!!self._wrtc || Peer.WEBRTC_SUPPORT) - - var announce = (typeof opts.announce === 'string') - ? [ opts.announce ] - : opts.announce == null - ? [] - : opts.announce - - announce = announce.map(function (announceUrl) { - announceUrl = announceUrl.toString() - if (announceUrl[announceUrl.length - 1] === '/') { - // remove trailing slash from trackers to catch duplicates - announceUrl = announceUrl.substring(0, announceUrl.length - 1) - } - return announceUrl - }) - - announce = uniq(announce) - - self._trackers = announce - .map(function (announceUrl) { - var protocol = url.parse(announceUrl).protocol - if ((protocol === 'http:' || protocol === 'https:') && - typeof HTTPTracker === 'function') { - return new HTTPTracker(self, announceUrl) - } else if (protocol === 'udp:' && typeof UDPTracker === 'function') { - return new UDPTracker(self, 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(self, announceUrl) - } else { - nextTickWarn(new Error('Unsupported tracker protocol: ' + announceUrl)) - return null - } - }) - .filter(Boolean) - - function nextTickWarn (err) { - process.nextTick(function () { - self.emit('warning', err) - }) - } -} - -/** - * 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 = function (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') - - var clientOpts = extend(opts, { - infoHash: Array.isArray(opts.infoHash) ? opts.infoHash[0] : opts.infoHash, - peerId: Buffer.from('01234567890123456789'), // dummy value - port: 6881 // dummy value - }) - - var client = new Client(clientOpts) - client.once('error', cb) - client.once('warning', cb) - - var len = Array.isArray(opts.infoHash) ? opts.infoHash.length : 1 - var results = {} - client.on('scrape', function (data) { - len -= 1 - results[data.infoHash] = data - if (len === 0) { - client.destroy() - var 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(function (infoHash) { - return Buffer.from(infoHash, 'hex') - }) - : Buffer.from(opts.infoHash, 'hex') - client.scrape({ infoHash: opts.infoHash }) - return client -} - -/** - * 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) - */ -Client.prototype.start = function (opts) { - var self = this - debug('send `start`') - opts = self._defaultAnnounceOpts(opts) - opts.event = 'started' - self._announce(opts) - - // start announcing on intervals - self._trackers.forEach(function (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) - */ -Client.prototype.stop = function (opts) { - var self = this - debug('send `stop`') - opts = self._defaultAnnounceOpts(opts) - opts.event = 'stopped' - self._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) - */ -Client.prototype.complete = function (opts) { - var self = this - debug('send `complete`') - if (!opts) opts = {} - opts = self._defaultAnnounceOpts(opts) - opts.event = 'completed' - self._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) - */ -Client.prototype.update = function (opts) { - var self = this - debug('send `update`') - opts = self._defaultAnnounceOpts(opts) - if (opts.event) delete opts.event - self._announce(opts) -} - -Client.prototype._announce = function (opts) { - var self = this - self._trackers.forEach(function (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 - */ -Client.prototype.scrape = function (opts) { - var self = this - debug('send `scrape`') - if (!opts) opts = {} - self._trackers.forEach(function (tracker) { - // tracker should not modify `opts` object, it's passed to all trackers - tracker.scrape(opts) - }) -} - -Client.prototype.setInterval = function (intervalMs) { - var self = this - debug('setInterval %d', intervalMs) - self._trackers.forEach(function (tracker) { - tracker.setInterval(intervalMs) - }) -} - -Client.prototype.destroy = function (cb) { - var self = this - if (self.destroyed) return - self.destroyed = true - debug('destroy') - - var tasks = self._trackers.map(function (tracker) { - return function (cb) { - tracker.destroy(cb) - } - }) - - parallel(tasks, cb) - - self._trackers = [] - self._getAnnounceOpts = null -} - -Client.prototype._defaultAnnounceOpts = function (opts) { - var self = this - if (!opts) 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 (self._getAnnounceOpts) opts = extend(opts, self._getAnnounceOpts()) - return opts -} - -}).call(this,require('_process')) -},{"./lib/client/http-tracker":2,"./lib/client/udp-tracker":2,"./lib/client/websocket-tracker":47,"./lib/common":48,"_process":16,"debug":56,"events":8,"inherits":65,"once":83,"run-parallel":102,"safe-buffer":104,"simple-peer":107,"uniq":122,"url":34,"xtend":137}],46:[function(require,module,exports){ -module.exports = Tracker - -var EventEmitter = require('events').EventEmitter -var inherits = require('inherits') - -inherits(Tracker, EventEmitter) - -function Tracker (client, announceUrl) { - var self = this - EventEmitter.call(self) - self.client = client - self.announceUrl = announceUrl - - self.interval = null - self.destroyed = false -} - -Tracker.prototype.setInterval = function (intervalMs) { - var self = this - if (intervalMs == null) intervalMs = self.DEFAULT_ANNOUNCE_INTERVAL - - clearInterval(self.interval) - - if (intervalMs) { - self.interval = setInterval(function () { - self.announce(self.client._defaultAnnounceOpts()) - }, intervalMs) - if (self.interval.unref) self.interval.unref() - } -} - -},{"events":8,"inherits":65}],47:[function(require,module,exports){ -module.exports = WebSocketTracker - -var debug = require('debug')('bittorrent-tracker:websocket-tracker') -var extend = require('xtend') -var inherits = require('inherits') -var Peer = require('simple-peer') -var randombytes = require('randombytes') -var Socket = require('simple-websocket') - -var common = require('../common') -var 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. -var socketPool = {} - -var RECONNECT_MINIMUM = 15 * 1000 -var RECONNECT_MAXIMUM = 30 * 60 * 1000 -var RECONNECT_VARIANCE = 30 * 1000 -var OFFER_TIMEOUT = 50 * 1000 - -inherits(WebSocketTracker, Tracker) - -function WebSocketTracker (client, announceUrl, opts) { - var self = this - Tracker.call(self, client, announceUrl) - debug('new websocket tracker %s', announceUrl) - - self.peers = {} // peers (offer id -> peer) - self.socket = null - - self.reconnecting = false - self.retries = 0 - self.reconnectTimer = null - - self._openSocket() -} - -WebSocketTracker.prototype.DEFAULT_ANNOUNCE_INTERVAL = 30 * 1000 // 30 seconds - -WebSocketTracker.prototype.announce = function (opts) { - var self = this - if (self.destroyed || self.reconnecting) return - if (!self.socket.connected) { - self.socket.once('connect', function () { - self.announce(opts) - }) - return - } - - var params = extend(opts, { - action: 'announce', - info_hash: self.client._infoHashBinary, - peer_id: self.client._peerIdBinary - }) - if (self._trackerId) params.trackerid = self._trackerId - - if (opts.event === 'stopped') { - // Don't include offers with 'stopped' event - self._send(params) - } else { - // Limit the number of offers that are generated, since it can be slow - var numwant = Math.min(opts.numwant, 10) - - self._generateOffers(numwant, function (offers) { - params.numwant = numwant - params.offers = offers - self._send(params) - }) - } -} - -WebSocketTracker.prototype.scrape = function (opts) { - var self = this - if (self.destroyed || self.reconnecting) return - if (!self.socket.connected) { - self.socket.once('connect', function () { - self.scrape(opts) - }) - return - } - - var infoHashes = (Array.isArray(opts.infoHash) && opts.infoHash.length > 0) - ? opts.infoHash.map(function (infoHash) { - return infoHash.toString('binary') - }) - : (opts.infoHash && opts.infoHash.toString('binary')) || self.client._infoHashBinary - var params = { - action: 'scrape', - info_hash: infoHashes - } - - self._send(params) -} - -WebSocketTracker.prototype.destroy = function (cb) { - var self = this - if (!cb) cb = noop - if (self.destroyed) return cb(null) - - self.destroyed = true - - clearInterval(self.interval) - clearTimeout(self.reconnectTimer) - - if (self.socket) { - self.socket.removeListener('connect', self._onSocketConnectBound) - self.socket.removeListener('data', self._onSocketDataBound) - self.socket.removeListener('close', self._onSocketCloseBound) - self.socket.removeListener('error', self._onSocketErrorBound) - } - - self._onSocketConnectBound = null - self._onSocketErrorBound = null - self._onSocketDataBound = null - self._onSocketCloseBound = null - - // Destroy peers - for (var peerId in self.peers) { - var peer = self.peers[peerId] - clearTimeout(peer.trackerTimeout) - peer.destroy() - } - self.peers = null - - if (socketPool[self.announceUrl]) { - socketPool[self.announceUrl].consumers -= 1 - } - - if (socketPool[self.announceUrl].consumers === 0) { - delete socketPool[self.announceUrl] - - try { - self.socket.on('error', noop) // ignore all future errors - self.socket.destroy(cb) - } catch (err) { - cb(null) - } - } else { - cb(null) - } - - self.socket = null -} - -WebSocketTracker.prototype._openSocket = function () { - var self = this - self.destroyed = false - - if (!self.peers) self.peers = {} - - self._onSocketConnectBound = function () { - self._onSocketConnect() - } - self._onSocketErrorBound = function (err) { - self._onSocketError(err) - } - self._onSocketDataBound = function (data) { - self._onSocketData(data) - } - self._onSocketCloseBound = function () { - self._onSocketClose() - } - - self.socket = socketPool[self.announceUrl] - if (self.socket) { - socketPool[self.announceUrl].consumers += 1 - } else { - self.socket = socketPool[self.announceUrl] = new Socket(self.announceUrl) - self.socket.consumers = 1 - self.socket.once('connect', self._onSocketConnectBound) - } - - self.socket.on('data', self._onSocketDataBound) - self.socket.once('close', self._onSocketCloseBound) - self.socket.once('error', self._onSocketErrorBound) -} - -WebSocketTracker.prototype._onSocketConnect = function () { - var self = this - if (self.destroyed) return - - if (self.reconnecting) { - self.reconnecting = false - self.retries = 0 - self.announce(self.client._defaultAnnounceOpts()) - } -} - -WebSocketTracker.prototype._onSocketData = function (data) { - var self = this - if (self.destroyed) return - - try { - data = JSON.parse(data) - } catch (err) { - self.client.emit('warning', new Error('Invalid tracker response')) - return - } - - if (data.action === 'announce') { - self._onAnnounceResponse(data) - } else if (data.action === 'scrape') { - self._onScrapeResponse(data) - } else { - self._onSocketError(new Error('invalid action in WS response: ' + data.action)) - } -} - -WebSocketTracker.prototype._onAnnounceResponse = function (data) { - var self = this - - if (data.info_hash !== self.client._infoHashBinary) { - debug( - 'ignoring websocket data from %s for %s (looking for %s: reused socket)', - self.announceUrl, common.binaryToHex(data.info_hash), self.client.infoHash - ) - return - } - - if (data.peer_id && data.peer_id === self.client._peerIdBinary) { - // ignore offers/answers from this client - return - } - - debug( - 'received %s from %s for %s', - JSON.stringify(data), self.announceUrl, self.client.infoHash - ) - - var failure = data['failure reason'] - if (failure) return self.client.emit('warning', new Error(failure)) - - var warning = data['warning message'] - if (warning) self.client.emit('warning', new Error(warning)) - - var interval = data.interval || data['min interval'] - if (interval) self.setInterval(interval * 1000) - - var trackerId = data['tracker id'] - if (trackerId) { - // If absent, do not discard previous trackerId value - self._trackerId = trackerId - } - - if (data.complete != null) { - self.client.emit('update', { - announce: self.announceUrl, - complete: data.complete, - incomplete: data.incomplete - }) - } - - var peer - if (data.offer && data.peer_id) { - debug('creating peer (from remote offer)') - peer = new Peer({ - trickle: false, - config: self.client._rtcConfig, - wrtc: self.client._wrtc - }) - peer.id = common.binaryToHex(data.peer_id) - peer.once('signal', function (answer) { - var params = { - action: 'announce', - info_hash: self.client._infoHashBinary, - peer_id: self.client._peerIdBinary, - to_peer_id: data.peer_id, - answer: answer, - offer_id: data.offer_id - } - if (self._trackerId) params.trackerid = self._trackerId - self._send(params) - }) - peer.signal(data.offer) - self.client.emit('peer', peer) - } - - if (data.answer && data.peer_id) { - var offerId = common.binaryToHex(data.offer_id) - peer = self.peers[offerId] - if (peer) { - peer.id = common.binaryToHex(data.peer_id) - peer.signal(data.answer) - self.client.emit('peer', peer) - - clearTimeout(peer.trackerTimeout) - peer.trackerTimeout = null - delete self.peers[offerId] - } else { - debug('got unexpected answer: ' + JSON.stringify(data.answer)) - } - } -} - -WebSocketTracker.prototype._onScrapeResponse = function (data) { - var self = this - data = data.files || {} - - var keys = Object.keys(data) - if (keys.length === 0) { - self.client.emit('warning', new Error('invalid scrape response')) - return - } - - keys.forEach(function (infoHash) { - var response = data[infoHash] - // TODO: optionally handle data.flags.min_request_interval - // (separate from announce interval) - self.client.emit('scrape', { - announce: self.announceUrl, - infoHash: common.binaryToHex(infoHash), - complete: response.complete, - incomplete: response.incomplete, - downloaded: response.downloaded - }) - }) -} - -WebSocketTracker.prototype._onSocketClose = function () { - var self = this - if (self.destroyed) return - self.destroy() - self._startReconnectTimer() -} - -WebSocketTracker.prototype._onSocketError = function (err) { - var self = this - if (self.destroyed) return - self.destroy() - // errors will often happen if a tracker is offline, so don't treat it as fatal - self.client.emit('warning', err) - self._startReconnectTimer() -} - -WebSocketTracker.prototype._startReconnectTimer = function () { - var self = this - var ms = Math.floor(Math.random() * RECONNECT_VARIANCE) + Math.min(Math.pow(2, self.retries) * RECONNECT_MINIMUM, RECONNECT_MAXIMUM) - - self.reconnecting = true - clearTimeout(self.reconnectTimer) - self.reconnectTimer = setTimeout(function () { - self.retries++ - self._openSocket() - }, ms) - if (self.reconnectTimer.unref) self.reconnectTimer.unref() - - debug('reconnecting socket in %s ms', ms) -} - -WebSocketTracker.prototype._send = function (params) { - var self = this - if (self.destroyed) return - - var message = JSON.stringify(params) - debug('send %s', message) - self.socket.send(message) -} - -WebSocketTracker.prototype._generateOffers = function (numwant, cb) { - var self = this - var offers = [] - debug('generating %s offers', numwant) - - for (var i = 0; i < numwant; ++i) { - generateOffer() - } - checkDone() - - function generateOffer () { - var offerId = randombytes(20).toString('hex') - debug('creating peer (from _generateOffers)') - var peer = self.peers[offerId] = new Peer({ - initiator: true, - trickle: false, - config: self.client._rtcConfig, - wrtc: self.client._wrtc - }) - peer.once('signal', function (offer) { - offers.push({ - offer: offer, - offer_id: common.hexToBinary(offerId) - }) - checkDone() - }) - peer.trackerTimeout = setTimeout(function () { - 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) - } - } -} - -function noop () {} - -},{"../common":48,"./tracker":46,"debug":56,"inherits":65,"randombytes":90,"simple-peer":107,"simple-websocket":109,"xtend":137}],48:[function(require,module,exports){ -/** - * Functions/constants needed by both the client and server. - */ - -var Buffer = require('safe-buffer').Buffer -var extend = require('xtend/mutable') - -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') -extend(exports, config) - -},{"./common-node":2,"safe-buffer":104,"xtend/mutable":138}],49:[function(require,module,exports){ -(function (Buffer){ -/* 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') - } - - var reader = new FileReader() - - function onLoadEnd (e) { - reader.removeEventListener('loadend', onLoadEnd, false) - if (e.error) cb(e.error) - else cb(null, new Buffer(reader.result)) - } - - reader.addEventListener('loadend', onLoadEnd, false) - reader.readAsArrayBuffer(blob) -} - -}).call(this,require("buffer").Buffer) -},{"buffer":5}],50:[function(require,module,exports){ -(function (Buffer){ -var inherits = require('inherits'); -var Transform = require('readable-stream').Transform; -var defined = require('defined'); - -module.exports = Block; -inherits(Block, Transform); - -function Block (size, opts) { - if (!(this instanceof Block)) return new Block(size, opts); - Transform.call(this); - if (!opts) opts = {}; - if (typeof size === 'object') { - opts = size; - size = opts.size; - } - this.size = size || 512; - - if (opts.nopad) this._zeroPadding = false; - else this._zeroPadding = defined(opts.zeroPadding, true); - - this._buffered = []; - this._bufferedBytes = 0; -} - -Block.prototype._transform = function (buf, enc, next) { - this._bufferedBytes += buf.length; - this._buffered.push(buf); - - while (this._bufferedBytes >= this.size) { - var 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(); -}; - -Block.prototype._flush = function () { - if (this._bufferedBytes && this._zeroPadding) { - var zeroes = new Buffer(this.size - this._bufferedBytes); - zeroes.fill(0); - 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); -}; - -}).call(this,require("buffer").Buffer) -},{"buffer":5,"defined":58,"inherits":65,"readable-stream":98}],51:[function(require,module,exports){ -arguments[4][4][0].apply(exports,arguments) -},{"buffer":5,"dup":4}],52:[function(require,module,exports){ -module.exports = ChunkStoreWriteStream - -var BlockStream = require('block-stream2') -var inherits = require('inherits') -var stream = require('readable-stream') - -inherits(ChunkStoreWriteStream, stream.Writable) - -function ChunkStoreWriteStream (store, chunkLength, opts) { - var self = this - if (!(self instanceof ChunkStoreWriteStream)) { - return new ChunkStoreWriteStream(store, chunkLength, opts) - } - stream.Writable.call(self, opts) - if (!opts) 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') - - self._blockstream = new BlockStream(chunkLength, { zeroPadding: false }) - - self._blockstream - .on('data', onData) - .on('error', function (err) { self.destroy(err) }) - - var index = 0 - function onData (chunk) { - if (self.destroyed) return - store.put(index, chunk) - index += 1 - } - - self.on('finish', function () { this._blockstream.end() }) -} - -ChunkStoreWriteStream.prototype._write = function (chunk, encoding, callback) { - this._blockstream.write(chunk, encoding, callback) -} - -ChunkStoreWriteStream.prototype.destroy = function (err) { - if (this.destroyed) return - this.destroyed = true - - if (err) this.emit('error', err) - this.emit('close') -} - -},{"block-stream2":50,"inherits":65,"readable-stream":98}],53:[function(require,module,exports){ -module.exports = function(target, numbers) { - var closest = Infinity - var difference = 0 - var winner = null - - numbers.sort(function(a, b) { - return a - b - }) - - for (var i = 0, l = numbers.length; i < l; i++) { - difference = Math.abs(target - numbers[i]) - if (difference >= closest) { - break - } - closest = difference - winner = numbers[i] - } - - return winner -} - -},{}],54:[function(require,module,exports){ -(function (Buffer){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -// NOTE: These type checking functions intentionally don't use `instanceof` -// because it is fragile and can be easily faked with `Object.create()`. - -function isArray(arg) { - if (Array.isArray) { - return Array.isArray(arg); - } - return objectToString(arg) === '[object Array]'; -} -exports.isArray = isArray; - -function isBoolean(arg) { - return typeof arg === 'boolean'; -} -exports.isBoolean = isBoolean; - -function isNull(arg) { - return arg === null; -} -exports.isNull = isNull; - -function isNullOrUndefined(arg) { - return arg == null; -} -exports.isNullOrUndefined = isNullOrUndefined; - -function isNumber(arg) { - return typeof arg === 'number'; -} -exports.isNumber = isNumber; - -function isString(arg) { - return typeof arg === 'string'; -} -exports.isString = isString; - -function isSymbol(arg) { - return typeof arg === 'symbol'; -} -exports.isSymbol = isSymbol; - -function isUndefined(arg) { - return arg === void 0; -} -exports.isUndefined = isUndefined; - -function isRegExp(re) { - return objectToString(re) === '[object RegExp]'; -} -exports.isRegExp = isRegExp; - -function isObject(arg) { - return typeof arg === 'object' && arg !== null; -} -exports.isObject = isObject; - -function isDate(d) { - return objectToString(d) === '[object Date]'; -} -exports.isDate = isDate; - -function isError(e) { - return (objectToString(e) === '[object Error]' || e instanceof Error); -} -exports.isError = isError; - -function isFunction(arg) { - return typeof arg === 'function'; -} -exports.isFunction = isFunction; - -function isPrimitive(arg) { - return arg === null || - typeof arg === 'boolean' || - typeof arg === 'number' || - typeof arg === 'string' || - typeof arg === 'symbol' || // ES6 symbol - typeof arg === 'undefined'; -} -exports.isPrimitive = isPrimitive; - -exports.isBuffer = Buffer.isBuffer; - -function objectToString(o) { - return Object.prototype.toString.call(o); -} - -}).call(this,{"isBuffer":require("../../../../../.nvm/versions/node/v5.5.0/lib/node_modules/watchify/node_modules/is-buffer/index.js")}) -},{"../../../../../.nvm/versions/node/v5.5.0/lib/node_modules/watchify/node_modules/is-buffer/index.js":12}],55:[function(require,module,exports){ -(function (process,global,Buffer){ -module.exports = createTorrent -module.exports.parseInput = parseInput - -module.exports.announceList = [ - [ 'udp://tracker.openbittorrent.com:80' ], - [ 'udp://tracker.internetwarriors.net:1337' ], - [ 'udp://tracker.leechers-paradise.org:6969' ], - [ 'udp://tracker.coppersurfer.tk:6969' ], - [ 'udp://exodus.desync.com:6969' ], - [ 'wss://tracker.btorrent.xyz' ], - [ 'wss://tracker.openwebtorrent.com' ], - [ 'wss://tracker.fastcast.nz' ] -] - -var bencode = require('bencode') -var BlockStream = require('block-stream2') -var calcPieceLength = require('piece-length') -var corePath = require('path') -var extend = require('xtend') -var FileReadStream = require('filestream/read') -var flatten = require('flatten') -var fs = require('fs') -var isFile = require('is-file') -var junk = require('junk') -var MultiStream = require('multistream') -var once = require('once') -var parallel = require('run-parallel') -var sha1 = require('simple-sha1') -var stream = require('readable-stream') - -/** - * 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 {function} cb - * @return {Buffer} buffer of .torrent file data - */ -function createTorrent (input, opts, cb) { - if (typeof opts === 'function') return createTorrent(input, null, opts) - opts = opts ? extend(opts) : {} - - _parseInput(input, opts, function (err, files, singleFileTorrent) { - if (err) return cb(err) - opts.singleFileTorrent = singleFileTorrent - onFiles(files, opts, cb) - }) -} - -function parseInput (input, opts, cb) { - if (typeof opts === 'function') return parseInput(input, null, opts) - opts = opts ? extend(opts) : {} - _parseInput(input, opts, cb) -} - -/** - * Parse input file and return file information. - */ -function _parseInput (input, opts, cb) { - if (Array.isArray(input) && input.length === 0) throw new Error('invalid input type') - - if (isFileList(input)) input = Array.prototype.slice.call(input) - if (!Array.isArray(input)) input = [ input ] - - // In Electron, use the true file path - input = input.map(function (item) { - if (isBlob(item) && typeof item.path === 'string' && typeof fs.stat === '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 - - var commonPrefix = null - input.forEach(function (item, i) { - if (typeof item === 'string') { - return - } - - var 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(function (item) { - if (typeof item === 'string') { - return true - } - var filename = item.path[item.path.length - 1] - return notHidden(filename) && junk.not(filename) - }) - - if (commonPrefix) { - input.forEach(function (item) { - var 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(function (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() - } - - var numPaths = input.reduce(function (sum, item) { - return sum + Number(typeof item === 'string') - }, 0) - - var isSingleFileTorrent = (input.length === 1) - - if (input.length === 1 && typeof input[0] === 'string') { - if (typeof fs.stat !== '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], function (err, pathIsFile) { - if (err) return cb(err) - isSingleFileTorrent = pathIsFile - processInput() - }) - } else { - process.nextTick(function () { - processInput() - }) - } - - function processInput () { - parallel(input.map(function (item) { - return function (cb) { - var 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 fs.stat !== 'function') { - throw new Error('filesystem paths do not work in the browser') - } - var 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) - } - }), function (err, files) { - if (err) return cb(err) - files = flatten(files) - cb(null, files, isSingleFileTorrent) - }) - } -} - -function getFiles (path, keepRoot, cb) { - traversePath(path, getFileInfo, function (err, files) { - if (err) return cb(err) - - if (Array.isArray(files)) files = flatten(files) - else files = [ files ] - - path = corePath.normalize(path) - if (keepRoot) { - path = path.slice(0, path.lastIndexOf(corePath.sep) + 1) - } - if (path[path.length - 1] !== corePath.sep) path += corePath.sep - - files.forEach(function (file) { - file.getStream = getFilePathStream(file.path) - file.path = file.path.replace(path, '').split(corePath.sep) - }) - cb(null, files) - }) -} - -function getFileInfo (path, cb) { - cb = once(cb) - fs.stat(path, function (err, stat) { - if (err) return cb(err) - var info = { - length: stat.size, - path: path - } - cb(null, info) - }) -} - -function traversePath (path, fn, cb) { - fs.readdir(path, function (err, entries) { - if (err && err.code === 'ENOTDIR') { - // this is a file - fn(path, cb) - } else if (err) { - // real error - cb(err) - } else { - // this is a folder - parallel(entries.filter(notHidden).filter(junk.not).map(function (entry) { - return function (cb) { - traversePath(corePath.join(path, entry), fn, cb) - } - }), cb) - } - }) -} - -function notHidden (file) { - return file[0] !== '.' -} - -function getPieceList (files, pieceLength, cb) { - cb = once(cb) - var pieces = [] - var length = 0 - - var streams = files.map(function (file) { - return file.getStream - }) - - var remainingHashes = 0 - var pieceNum = 0 - var ended = false - - var multistream = new MultiStream(streams) - var 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 - - var i = pieceNum - sha1(chunk, function (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, new Buffer(pieces.join(''), 'hex'), length) - } - } -} - -function onFiles (files, opts, cb) { - var announceList = opts.announceList - - if (!announceList) { - if (typeof opts.announce === 'string') announceList = [ [ opts.announce ] ] - else if (Array.isArray(opts.announce)) { - announceList = opts.announce.map(function (u) { return [ 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(function (u) { - return [ 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 ] - - var 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) - - // "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 - - var pieceLength = opts.pieceLength || calcPieceLength(files.reduce(sumLength, 0)) - torrent.info['piece length'] = pieceLength - - getPieceList(files, pieceLength, function (err, pieces, torrentLength) { - if (err) return cb(err) - torrent.info.pieces = pieces - - files.forEach(function (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 function () { - return new FileReadStream(file) - } -} - -/** - * Convert a `Buffer` to a lazy readable stream. - * @param {Buffer} buffer - * @return {function} - */ -function getBufferStream (buffer) { - return function () { - var s = new stream.PassThrough() - s.end(buffer) - return s - } -} - -/** - * Convert a file path to a lazy readable stream. - * @param {string} path - * @return {function} - */ -function getFilePathStream (path) { - return function () { - return fs.createReadStream(path) - } -} - -/** - * 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} stream - * @param {Object} file - * @return {function} - */ -function getStreamStream (readable, file) { - return function () { - var counter = new stream.Transform() - counter._transform = function (buf, enc, done) { - file.length += buf.length - this.push(buf) - done() - } - readable.pipe(counter) - return counter - } -} - -}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer) -},{"_process":16,"bencode":41,"block-stream2":50,"buffer":5,"filestream/read":61,"flatten":62,"fs":3,"is-file":67,"junk":70,"multistream":81,"once":83,"path":14,"piece-length":86,"readable-stream":98,"run-parallel":102,"simple-sha1":108,"xtend":137}],56:[function(require,module,exports){ - -/** - * This is the web browser implementation of `debug()`. - * - * Expose `debug()` as the module. - */ - -exports = module.exports = require('./debug'); -exports.log = log; -exports.formatArgs = formatArgs; -exports.save = save; -exports.load = load; -exports.useColors = useColors; -exports.storage = 'undefined' != typeof chrome - && 'undefined' != typeof chrome.storage - ? chrome.storage.local - : localstorage(); - -/** - * Colors. - */ - -exports.colors = [ - 'lightseagreen', - 'forestgreen', - 'goldenrod', - 'dodgerblue', - 'darkorchid', - 'crimson' -]; - -/** - * 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 - */ - -function useColors() { - // is webkit? http://stackoverflow.com/a/16459606/376773 - return ('WebkitAppearance' in document.documentElement.style) || - // is firebug? http://stackoverflow.com/a/398120/376773 - (window.console && (console.firebug || (console.exception && console.table))) || - // is firefox >= v31? - // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages - (navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31); -} - -/** - * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default. - */ - -exports.formatters.j = function(v) { - return JSON.stringify(v); -}; - - -/** - * Colorize log arguments if enabled. - * - * @api public - */ - -function formatArgs() { - var args = arguments; - var useColors = this.useColors; - - args[0] = (useColors ? '%c' : '') - + this.namespace - + (useColors ? ' %c' : ' ') - + args[0] - + (useColors ? '%c ' : ' ') - + '+' + exports.humanize(this.diff); - - if (!useColors) return args; - - var c = 'color: ' + this.color; - args = [args[0], c, 'color: inherit'].concat(Array.prototype.slice.call(args, 1)); - - // 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-z%]/g, function(match) { - if ('%%' === match) return; - index++; - if ('%c' === match) { - // we only are interested in the *last* %c - // (the user may have provided their own) - lastC = index; - } - }); - - args.splice(lastC, 0, c); - return args; -} - -/** - * Invokes `console.log()` when available. - * No-op when `console.log` is not a "function". - * - * @api public - */ - -function log() { - // this hackery is required for IE8/9, where - // the `console.log` function doesn't have 'apply' - return 'object' === typeof console - && console.log - && Function.prototype.apply.call(console.log, console, arguments); -} - -/** - * Save `namespaces`. - * - * @param {String} namespaces - * @api private - */ - -function save(namespaces) { - try { - if (null == namespaces) { - exports.storage.removeItem('debug'); - } else { - exports.storage.debug = namespaces; - } - } catch(e) {} -} - -/** - * Load `namespaces`. - * - * @return {String} returns the previously persisted debug modes - * @api private - */ - -function load() { - var r; - try { - r = exports.storage.debug; - } catch(e) {} - return r; -} - -/** - * Enable namespaces listed in `localStorage.debug` initially. - */ - -exports.enable(load()); - -/** - * 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 { - return window.localStorage; - } catch (e) {} -} - -},{"./debug":57}],57:[function(require,module,exports){ - -/** - * This is the common logic for both the Node.js and web browser - * implementations of `debug()`. - * - * Expose `debug()` as the module. - */ - -exports = module.exports = debug; -exports.coerce = coerce; -exports.disable = disable; -exports.enable = enable; -exports.enabled = enabled; -exports.humanize = require('ms'); - -/** - * The currently active debug mode names, and names to skip. - */ - -exports.names = []; -exports.skips = []; - -/** - * Map of special "%n" handling functions, for the debug "format" argument. - * - * Valid key names are a single, lowercased letter, i.e. "n". - */ - -exports.formatters = {}; - -/** - * Previously assigned color. - */ - -var prevColor = 0; - -/** - * Previous log timestamp. - */ - -var prevTime; - -/** - * Select a color. - * - * @return {Number} - * @api private - */ - -function selectColor() { - return exports.colors[prevColor++ % exports.colors.length]; -} - -/** - * Create a debugger with the given `namespace`. - * - * @param {String} namespace - * @return {Function} - * @api public - */ - -function debug(namespace) { - - // define the `disabled` version - function disabled() { - } - disabled.enabled = false; - - // define the `enabled` version - function enabled() { - - var self = enabled; - - // set `diff` timestamp - var curr = +new Date(); - var ms = curr - (prevTime || curr); - self.diff = ms; - self.prev = prevTime; - self.curr = curr; - prevTime = curr; - - // add the `color` if not set - if (null == self.useColors) self.useColors = exports.useColors(); - if (null == self.color && self.useColors) self.color = selectColor(); - - var args = Array.prototype.slice.call(arguments); - - args[0] = exports.coerce(args[0]); - - if ('string' !== typeof args[0]) { - // anything else let's inspect with %o - args = ['%o'].concat(args); - } - - // apply any `formatters` transformations - var index = 0; - args[0] = args[0].replace(/%([a-z%])/g, function(match, format) { - // if we encounter an escaped % then don't increase the array index - if (match === '%%') return match; - index++; - var formatter = exports.formatters[format]; - if ('function' === typeof formatter) { - 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; - }); - - if ('function' === typeof exports.formatArgs) { - args = exports.formatArgs.apply(self, args); - } - var logFn = enabled.log || exports.log || console.log.bind(console); - logFn.apply(self, args); - } - enabled.enabled = true; - - var fn = exports.enabled(namespace) ? enabled : disabled; - - fn.namespace = namespace; - - return fn; -} - -/** - * Enables a debug mode by namespaces. This can include modes - * separated by a colon and wildcards. - * - * @param {String} namespaces - * @api public - */ - -function enable(namespaces) { - exports.save(namespaces); - - var split = (namespaces || '').split(/[\s,]+/); - var len = split.length; - - for (var i = 0; i < len; i++) { - if (!split[i]) continue; // ignore empty strings - namespaces = split[i].replace(/\*/g, '.*?'); - if (namespaces[0] === '-') { - exports.skips.push(new RegExp('^' + namespaces.substr(1) + '$')); - } else { - exports.names.push(new RegExp('^' + namespaces + '$')); - } - } -} - -/** - * Disable debug output. - * - * @api public - */ - -function disable() { - exports.enable(''); -} - -/** - * Returns true if the given mode name is enabled, false otherwise. - * - * @param {String} name - * @return {Boolean} - * @api public - */ - -function enabled(name) { - var i, len; - for (i = 0, len = exports.skips.length; i < len; i++) { - if (exports.skips[i].test(name)) { - return false; - } - } - for (i = 0, len = exports.names.length; i < len; i++) { - if (exports.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; -} - -},{"ms":80}],58:[function(require,module,exports){ -module.exports = function () { - for (var i = 0; i < arguments.length; i++) { - if (arguments[i] !== undefined) return arguments[i]; - } -}; - -},{}],59:[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(); - }; - - var onend = function() { - readable = false; - if (!writable) callback(); - }; - - var onexit = function(exitCode) { - callback(exitCode ? new Error('exited with error code: ' + exitCode) : null); - }; - - var onclose = function() { - if (readable && !(rs && rs.ended)) return callback(new Error('premature close')); - if (writable && !(ws && ws.ended)) return callback(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', callback); - 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', callback); - stream.removeListener('close', onclose); - }; -}; - -module.exports = eos; -},{"once":60}],60:[function(require,module,exports){ -var wrappy = require('wrappy') -module.exports = wrappy(once) - -once.proto = once(function () { - Object.defineProperty(Function.prototype, 'once', { - value: function () { - return once(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 -} - -},{"wrappy":136}],61:[function(require,module,exports){ -var Readable = require('readable-stream').Readable; -var inherits = require('inherits'); -var reExtension = /^.*\.(\w+)$/; -var toBuffer = require('typedarray-to-buffer'); - -function FileReadStream(file, opts) { - var readStream = this; - if (! (this instanceof FileReadStream)) { - return new FileReadStream(file, opts); - } - opts = opts || {}; - - // inherit readable - Readable.call(this, 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 - this.reader = new FileReader(); - - // generate the header blocks that we will send as part of the initial payload - this._generateHeaderBlocks(file, opts, function(err, blocks) { - // if we encountered an error, emit it - if (err) { - return readStream.emit('error', err); - } - - // push the header blocks out to the stream - if (Array.isArray(blocks)) { - blocks.forEach(function (block) { - readStream.push(block); - }); - } - - readStream._ready = true; - readStream.emit('_ready'); - }); -} - -inherits(FileReadStream, Readable); -module.exports = FileReadStream; - -FileReadStream.prototype._generateHeaderBlocks = function(file, opts, callback) { - callback(null, []); -}; - -FileReadStream.prototype._read = function() { - if (!this._ready) { - this.once('_ready', this._read.bind(this)); - return; - } - var readStream = this; - var reader = this.reader; - - var startOffset = this._offset; - var endOffset = this._offset + this._chunkSize; - if (endOffset > this._size) endOffset = this._size; - - if (startOffset === this._size) { - this.destroy(); - this.push(null); - return; - } - - reader.onload = function() { - // update the stream offset - readStream._offset = endOffset; - - // get the data chunk - readStream.push(toBuffer(reader.result)); - } - reader.onerror = function() { - readStream.emit('error', reader.error); - } - - reader.readAsArrayBuffer(this._file.slice(startOffset, endOffset)); -}; - -FileReadStream.prototype.destroy = function() { - this._file = null; - if (this.reader) { - this.reader.onload = null; - this.reader.onerror = null; - try { this.reader.abort(); } catch (e) {}; - } - this.reader = null; -} - -},{"inherits":65,"readable-stream":98,"typedarray-to-buffer":120}],62:[function(require,module,exports){ -module.exports = function flatten(list, depth) { - depth = (typeof depth == 'number') ? depth : Infinity; - - if (!depth) { - if (Array.isArray(list)) { - return list.map(function(i) { return i; }); - } - return list; - } - - return _flatten(list, 1); - - function _flatten(list, d) { - return list.reduce(function (acc, item) { - if (Array.isArray(item) && d < depth) { - return acc.concat(_flatten(item, d + 1)); - } - else { - return acc.concat(item); - } - }, []); - } -}; - -},{}],63:[function(require,module,exports){ -// originally pulled out of simple-peer - -module.exports = function getBrowserRTC () { - if (typeof window === 'undefined') return null - var wrtc = { - RTCPeerConnection: window.RTCPeerConnection || window.mozRTCPeerConnection || - window.webkitRTCPeerConnection, - RTCSessionDescription: window.RTCSessionDescription || - window.mozRTCSessionDescription || window.webkitRTCSessionDescription, - RTCIceCandidate: window.RTCIceCandidate || window.mozRTCIceCandidate || - window.webkitRTCIceCandidate - } - if (!wrtc.RTCPeerConnection) return null - return wrtc -} - -},{}],64:[function(require,module,exports){ -(function (process){ -module.exports = ImmediateStore - -function ImmediateStore (store) { - if (!(this instanceof ImmediateStore)) return new ImmediateStore(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 = [] -} - -ImmediateStore.prototype.put = function (index, buf, cb) { - var self = this - self.mem[index] = buf - self.store.put(index, buf, function (err) { - self.mem[index] = null - if (cb) cb(err) - }) -} - -ImmediateStore.prototype.get = function (index, opts, cb) { - if (typeof opts === 'function') return this.get(index, null, opts) - - var start = (opts && opts.offset) || 0 - var end = opts && opts.length && (start + opts.length) - - var buf = this.mem[index] - if (buf) return nextTick(cb, null, opts ? buf.slice(start, end) : buf) - - this.store.get(index, opts, cb) -} - -ImmediateStore.prototype.close = function (cb) { - this.store.close(cb) -} - -ImmediateStore.prototype.destroy = function (cb) { - this.store.destroy(cb) -} - -function nextTick (cb, err, val) { - process.nextTick(function () { - if (cb) cb(err, val) - }) -} - -}).call(this,require('_process')) -},{"_process":16}],65:[function(require,module,exports){ -arguments[4][11][0].apply(exports,arguments) -},{"dup":11}],66:[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; -}; - -},{}],67:[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":3}],68:[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)] -} - -},{}],69:[function(require,module,exports){ -arguments[4][13][0].apply(exports,arguments) -},{"dup":13}],70:[function(require,module,exports){ -'use strict'; - -// // All -// /^npm-debug\.log$/, // npm error log -// /^\..*\.swp$/, // 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$/, // file 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 - -exports.re = /^npm-debug\.log$|^\..*\.swp$|^\.DS_Store$|^\.AppleDouble$|^\.LSOverride$|^Icon\r$|^\._.*|^\.Spotlight-V100$|\.Trashes|^__MACOSX$|~$|^Thumbs\.db$|^ehthumbs\.db$|^Desktop\.ini$/; - -exports.is = function (filename) { - return exports.re.test(filename); -}; - -exports.not = exports.isnt = function (filename) { - return !exports.is(filename); -}; - -},{}],71:[function(require,module,exports){ -(function (Buffer){ -module.exports = magnetURIDecode -module.exports.decode = magnetURIDecode -module.exports.encode = magnetURIEncode - -var base32 = require('thirty-two') -var extend = require('xtend') -var uniq = require('uniq') - -/** - * Parse a magnet URI and return an object of keys/values - * - * @param {string} uri - * @return {Object} parsed uri - */ -function magnetURIDecode (uri) { - var result = {} - - // Support 'magnet:' and 'stream-magnet:' uris - var data = uri.split('magnet:?')[1] - - var params = (data && data.length >= 0) - ? data.split('&') - : [] - - params.forEach(function (param) { - var keyval = param.split('=') - - // This keyval is invalid, skip it - if (keyval.length !== 2) return - - var key = keyval[0] - var 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('+') - - // If there are repeated parameters, return an array of values - if (result[key]) { - if (Array.isArray(result[key])) { - result[key].push(val) - } else { - var old = result[key] - result[key] = [old, val] - } - } else { - result[key] = val - } - }) - - // Convenience properties for parity with `parse-torrent-file` module - var m - if (result.xt) { - var xts = Array.isArray(result.xt) ? result.xt : [ result.xt ] - xts.forEach(function (xt) { - if ((m = xt.match(/^urn:btih:(.{40})/))) { - result.infoHash = m[1].toLowerCase() - } else if ((m = xt.match(/^urn:btih:(.{32})/))) { - var decodedStr = base32.decode(m[1]) - result.infoHash = new Buffer(decodedStr, 'binary').toString('hex') - } - }) - } - if (result.infoHash) result.infoHashBuffer = new Buffer(result.infoHash, 'hex') - - if (result.dn) result.name = result.dn - if (result.kt) result.keywords = result.kt - - if (typeof result.tr === 'string') result.announce = [ result.tr ] - else if (Array.isArray(result.tr)) result.announce = result.tr - else result.announce = [] - - 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) - } - - uniq(result.announce) - uniq(result.urlList) - - return result -} - -function magnetURIEncode (obj) { - obj = extend(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.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 - } - - var result = 'magnet:?' - Object.keys(obj) - .filter(function (key) { - return key.length === 2 - }) - .forEach(function (key, i) { - var values = Array.isArray(obj[key]) ? obj[key] : [ obj[key] ] - values.forEach(function (val, j) { - if ((i > 0 || j > 0) && (key !== 'kt' || j === 0)) result += '&' - - if (key === 'dn') val = encodeURIComponent(val).replace(/%20/g, '+') - if (key === 'tr' || key === 'xs' || key === 'as' || key === 'ws') { - val = encodeURIComponent(val) - } - if (key === 'kt') val = encodeURIComponent(val) - - if (key === 'kt' && j > 0) result += '+' + val - else result += key + '=' + val - }) - }) - - return result -} - -}).call(this,require("buffer").Buffer) -},{"buffer":5,"thirty-two":115,"uniq":122,"xtend":137}],72:[function(require,module,exports){ -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._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 - } - try { - self._mediaSource.endOfStream('decode') - } catch (err) {} -} - -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._openHandler = function () { - self._onSourceOpen() - } - self._flowHandler = function () { - self._flow() - } - - 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._sourceBuffer.addEventListener('updateend', self._flowHandler) - } 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 })) { - 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) - 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) - 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')) - } - - try { - self._sourceBuffer.appendBuffer(toArrayBuffer(chunk)) - } 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 -} - -},{"inherits":65,"readable-stream":98,"to-arraybuffer":117}],73:[function(require,module,exports){ -(function (process){ -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) return nextTick(cb, new Error('Chunk not found')) - 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,require('_process')) -},{"_process":16}],74:[function(require,module,exports){ -(function (Buffer){ -// This is an intentionally recursive require. I don't like it either. -var Box = require('./index') -var Descriptor = require('./descriptor') - -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', - '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) : new Buffer(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) : new Buffer(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) : new Buffer(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) { - buf = buf ? buf.slice(offset) : new Buffer(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) { - buf = buf.slice(offset) - 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) { - return 20 -} - -exports.vmhd = {} -exports.vmhd.encode = function (box, buf, offset) { - buf = buf ? buf.slice(offset) : new Buffer(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) : new Buffer(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) : new Buffer(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) : new Buffer(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(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: new Buffer(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) : new Buffer(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(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: new Buffer(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(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) : new Buffer(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.stts = {} -exports.stts.encode = function (box, buf, offset) { - var entries = box.entries || [] - buf = buf ? buf.slice(offset) : new Buffer(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) : new Buffer(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) : new Buffer(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) : new Buffer(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) : new Buffer(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) : new Buffer(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) : new Buffer(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) : new Buffer(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) : new Buffer(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) : new Buffer(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) : new Buffer(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) : new Buffer(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 - - buf.writeUInt32BE(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: new Buffer(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) -} - -// 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 = new Buffer(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 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,require("buffer").Buffer) -},{"./descriptor":75,"./index":76,"buffer":5}],75:[function(require,module,exports){ -(function (Buffer){ -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: new Buffer(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,require("buffer").Buffer) -},{"buffer":5}],76:[function(require,module,exports){ -(function (Buffer){ -// 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', 'trun', 'sbgps', 'sgpds', 'subss', 'saizs', 'saios', 'tfdt', 'meta'] -} - -Box.encode = function (obj, buffer, offset) { - Box.encodingLength(obj) // sets every level appropriately - offset = offset || 0 - buffer = buffer || new Buffer(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 = new Buffer(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,require("buffer").Buffer) -},{"./boxes":74,"buffer":5,"uint64be":121}],77:[function(require,module,exports){ -(function (Buffer){ -var stream = require('readable-stream') -var inherits = require('inherits') -var nextEvent = require('next-event') -var Box = require('mp4-box-encoding') - -var EMPTY = new Buffer(0) - -module.exports = Decoder - -function Decoder () { - if (!(this instanceof Decoder)) return new Decoder() - stream.Writable.call(this) - - this.destroyed = false - - this._pending = 0 - this._missing = 0 - this._buf = null - this._str = null - this._cb = null - this._ondrain = null - this._writeBuffer = null - this._writeCb = null - - this._ondrain = null - this._kick() -} - -inherits(Decoder, stream.Writable) - -Decoder.prototype.destroy = function (err) { - if (this.destroyed) return - this.destroyed = true - if (err) this.emit('error', err) - this.emit('close') -} - -Decoder.prototype._write = function (data, enc, next) { - if (this.destroyed) return - var drained = !this._str || !this._str._writableState.needDrain - - while (data.length && !this.destroyed) { - if (!this._missing) { - 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 - - 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) -} - -Decoder.prototype._buffer = function (size, cb) { - this._missing = size - this._buf = new Buffer(size) - this._cb = cb -} - -Decoder.prototype._stream = function (size, cb) { - var self = this - this._missing = size - this._str = new MediaData(this) - this._ondrain = nextEvent(this._str, 'drain') - this._pending++ - this._str.on('end', function () { - self._pending-- - self._kick() - }) - this._cb = cb - return this._str -} - -Decoder.prototype._readBox = function () { - var self = this - bufferHeaders(8) - - function bufferHeaders (len, buf) { - self._buffer(len, function (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 { - self._pending++ - self._headers = headers - self.emit('box', headers) - } - }) - } -} - -Decoder.prototype.stream = function () { - var self = this - if (!self._headers) throw new Error('this function can only be called once after \'box\' is emitted') - var headers = self._headers - self._headers = null - - return self._stream(headers.contentLen, null) -} - -Decoder.prototype.decode = function (cb) { - var self = this - if (!self._headers) throw new Error('this function can only be called once after \'box\' is emitted') - var headers = self._headers - self._headers = null - - self._buffer(headers.contentLen, function (buf) { - var box = Box.decodeWithoutHeaders(headers, buf) - cb(box) - self._pending-- - self._kick() - }) -} - -Decoder.prototype.ignore = function () { - var self = this - if (!self._headers) throw new Error('this function can only be called once after \'box\' is emitted') - var headers = self._headers - self._headers = null - - this._missing = headers.contentLen - this._cb = function () { - self._pending-- - self._kick() - } -} - -Decoder.prototype._kick = function () { - 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) - } -} - -function MediaData (parent) { - this._parent = parent - this.destroyed = false - stream.PassThrough.call(this) -} - -inherits(MediaData, stream.PassThrough) - -MediaData.prototype.destroy = function (err) { - if (this.destroyed) return - this.destroyed = true - this._parent.destroy(err) - if (err) this.emit('error', err) - this.emit('close') -} - -}).call(this,require("buffer").Buffer) -},{"buffer":5,"inherits":65,"mp4-box-encoding":76,"next-event":82,"readable-stream":98}],78:[function(require,module,exports){ -(function (process,Buffer){ -var stream = require('readable-stream') -var inherits = require('inherits') -var Box = require('mp4-box-encoding') - -module.exports = Encoder - -function noop () {} - -function Encoder () { - if (!(this instanceof Encoder)) return new Encoder() - stream.Readable.call(this) - - this.destroyed = false - - this._reading = false - this._stream = null - this._drain = null - this._want = false - this._onreadable = onreadable - this._onend = onend - - var self = this - - function onreadable () { - if (!self._want) return - self._want = false - self._read() - } - - function onend () { - self._stream = null - } -} - -inherits(Encoder, stream.Readable) - -Encoder.prototype.mediaData = -Encoder.prototype.mdat = function (size, cb) { - var stream = new MediaData(this) - this.box({type: 'mdat', contentLength: size, encodeBufferLen: 8, stream: stream}, cb) - return stream -} - -Encoder.prototype.box = function (box, cb) { - if (!cb) cb = noop - if (this.destroyed) return cb(new Error('Encoder is destroyed')) - - var buf - if (box.encodeBufferLen) { - buf = new Buffer(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 - } -} - -Encoder.prototype.destroy = function (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') -} - -Encoder.prototype.finalize = function () { - this.push(null) -} - -Encoder.prototype._forward = function () { - if (!this._stream) return - - while (!this.destroyed) { - var buf = this._stream.read() - - if (!buf) { - this._want = !!this._stream - return - } - - if (!this.push(buf)) return - } -} - -Encoder.prototype._read = function () { - 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 -} - -function MediaData (parent) { - this._parent = parent - this.destroyed = false - stream.PassThrough.call(this) -} - -inherits(MediaData, stream.PassThrough) - -MediaData.prototype.destroy = function (err) { - if (this.destroyed) return - this.destroyed = true - this._parent.destroy(err) - if (err) this.emit('error', err) - this.emit('close') -} - -}).call(this,require('_process'),require("buffer").Buffer) -},{"_process":16,"buffer":5,"inherits":65,"mp4-box-encoding":76,"readable-stream":98}],79:[function(require,module,exports){ -exports.decode = require('./decode') -exports.encode = require('./encode') - -},{"./decode":77,"./encode":78}],80:[function(require,module,exports){ -/** - * Helpers. - */ - -var s = 1000; -var m = s * 60; -var h = m * 60; -var d = h * 24; -var y = d * 365.25; - -/** - * Parse or format the given `val`. - * - * Options: - * - * - `long` verbose formatting [false] - * - * @param {String|Number} val - * @param {Object} options - * @return {String|Number} - * @api public - */ - -module.exports = function(val, options){ - options = options || {}; - if ('string' == typeof val) return parse(val); - return options.long - ? long(val) - : short(val); -}; - -/** - * Parse the given `str` and return milliseconds. - * - * @param {String} str - * @return {Number} - * @api private - */ - -function parse(str) { - str = '' + str; - if (str.length > 10000) return; - var match = /^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|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 '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; - } -} - -/** - * Short format for `ms`. - * - * @param {Number} ms - * @return {String} - * @api private - */ - -function short(ms) { - if (ms >= d) return Math.round(ms / d) + 'd'; - if (ms >= h) return Math.round(ms / h) + 'h'; - if (ms >= m) return Math.round(ms / m) + 'm'; - if (ms >= s) return Math.round(ms / s) + 's'; - return ms + 'ms'; -} - -/** - * Long format for `ms`. - * - * @param {Number} ms - * @return {String} - * @api private - */ - -function long(ms) { - return plural(ms, d, 'day') - || plural(ms, h, 'hour') - || plural(ms, m, 'minute') - || plural(ms, s, 'second') - || ms + ' ms'; -} - -/** - * Pluralization helper. - */ - -function plural(ms, n, name) { - if (ms < n) return; - if (ms < n * 1.5) return Math.floor(ms / n) + ' ' + name; - return Math.ceil(ms / n) + ' ' + name + 's'; -} - -},{}],81:[function(require,module,exports){ -module.exports = MultiStream - -var inherits = require('inherits') -var stream = require('readable-stream') - -inherits(MultiStream, stream.Readable) - -function MultiStream (streams, opts) { - var self = this - if (!(self instanceof MultiStream)) return new MultiStream(streams, opts) - stream.Readable.call(self, opts) - - self.destroyed = false - - self._drained = false - self._forwarding = false - self._current = null - - if (typeof streams === 'function') { - self._queue = streams - } else { - self._queue = streams.map(toStreams2) - self._queue.forEach(function (stream) { - if (typeof stream !== 'function') self._attachErrorListener(stream) - }) - } - - self._next() -} - -MultiStream.obj = function (streams) { - return new MultiStream(streams, { objectMode: true, highWaterMark: 16 }) -} - -MultiStream.prototype._read = function () { - this._drained = true - this._forward() -} - -MultiStream.prototype._forward = function () { - if (this._forwarding || !this._drained || !this._current) return - this._forwarding = true - - var chunk - while ((chunk = this._current.read()) !== null) { - this._drained = this.push(chunk) - } - - this._forwarding = false -} - -MultiStream.prototype.destroy = function (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(function (stream) { - if (stream.destroy) stream.destroy() - }) - } - - if (err) this.emit('error', err) - this.emit('close') -} - -MultiStream.prototype._next = function () { - var self = this - self._current = null - - if (typeof self._queue === 'function') { - self._queue(function (err, stream) { - if (err) return self.destroy(err) - stream = toStreams2(stream) - self._attachErrorListener(stream) - self._gotNextStream(stream) - }) - } else { - var stream = self._queue.shift() - if (typeof stream === 'function') { - stream = toStreams2(stream()) - self._attachErrorListener(stream) - } - self._gotNextStream(stream) - } -} - -MultiStream.prototype._gotNextStream = function (stream) { - var self = this - - if (!stream) { - self.push(null) - self.destroy() - return - } - - self._current = stream - self._forward() - - stream.on('readable', onReadable) - stream.once('end', onEnd) - stream.once('close', onClose) - - function onReadable () { - self._forward() - } - - function onClose () { - if (!stream._readableState.ended) { - self.destroy() - } - } - - function onEnd () { - self._current = null - stream.removeListener('readable', onReadable) - stream.removeListener('end', onEnd) - stream.removeListener('close', onClose) - self._next() - } -} - -MultiStream.prototype._attachErrorListener = function (stream) { - var self = this - if (!stream) return - - stream.once('error', onError) - - function onError (err) { - stream.removeListener('error', onError) - self.destroy(err) - } -} - -function toStreams2 (s) { - if (!s || typeof s === 'function' || s._readableState) return s - - var wrap = new stream.Readable().wrap(s) - if (s.destroy) { - wrap.destroy = s.destroy.bind(s) - } - return wrap -} - -},{"inherits":65,"readable-stream":98}],82:[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 - } -} - -},{}],83:[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":136}],84:[function(require,module,exports){ -(function (Buffer){ -module.exports = decodeTorrentFile -module.exports.decode = decodeTorrentFile -module.exports.encode = encodeTorrentFile - -var bencode = require('bencode') -var path = require('path') -var sha1 = require('simple-sha1') -var uniq = require('uniq') - -/** - * 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(function (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') - } - - var result = {} - result.info = torrent.info - result.infoBuffer = bencode.encode(torrent.info) - result.infoHash = sha1.sync(result.infoBuffer) - result.infoHashBuffer = new Buffer(result.infoHash, 'hex') - - result.name = (torrent.info['name.utf-8'] || torrent.info.name).toString() - - 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 - result.announce = [] - if (torrent['announce-list'] && torrent['announce-list'].length) { - torrent['announce-list'].forEach(function (urls) { - urls.forEach(function (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(function (url) { - return url.toString() - }) - - uniq(result.announce) - uniq(result.urlList) - - var files = torrent.info.files || [ torrent.info ] - result.files = files.map(function (file, i) { - var parts = [].concat(result.name, file['path.utf-8'] || file.path || []).map(function (p) { - return 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) - - var 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) { - var torrent = { - info: parsed.info - } - - torrent['announce-list'] = (parsed.announce || []).map(function (url) { - if (!torrent.announce) torrent.announce = url - url = new Buffer(url, 'utf8') - return [ url ] - }) - - torrent['url-list'] = parsed.urlList || [] - - 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) -} - -function sumLength (sum, file) { - return sum + file.length -} - -function splitPieces (buf) { - var pieces = [] - for (var 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) -} - -}).call(this,require("buffer").Buffer) -},{"bencode":41,"buffer":5,"path":14,"simple-sha1":108,"uniq":122}],85:[function(require,module,exports){ -(function (process,Buffer){ -/* global Blob */ - -module.exports = parseTorrent -module.exports.remote = parseTorrentRemote - -var blobToBuffer = require('blob-to-buffer') -var fs = require('fs') // browser exclude -var get = require('simple-get') -var magnet = require('magnet-uri') -var parseTorrentFile = require('parse-torrent-file') - -module.exports.toMagnetURI = magnet.encode -module.exports.toTorrentFile = parseTorrentFile.encode - -/** - * 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)) { - // magnet uri (string) - return magnet(torrentId) - } else if (typeof torrentId === 'string' && (/^[a-f0-9]{40}$/i.test(torrentId) || /^[a-z2-7]{32}$/i.test(torrentId))) { - // info hash (hex/base-32 string) - return magnet('magnet:?xt=urn:btih:' + torrentId) - } else if (Buffer.isBuffer(torrentId) && torrentId.length === 20) { - // info hash (buffer) - return magnet('magnet:?xt=urn:btih:' + torrentId.toString('hex')) - } else if (Buffer.isBuffer(torrentId)) { - // .torrent file (buffer) - return parseTorrentFile(torrentId) // might throw - } else if (torrentId && torrentId.infoHash) { - // parsed torrent (from `parse-torrent`, `parse-torrent-file`, or `magnet-uri`) - 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, cb) { - var parsedTorrent - if (typeof cb !== 'function') throw new Error('second argument must be a Function') - - 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(function () { - cb(null, parsedTorrent) - }) - } else if (isBlob(torrentId)) { - blobToBuffer(torrentId, function (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 - get.concat({ - url: torrentId, - headers: { 'user-agent': 'WebTorrent (http://webtorrent.io)' } - }, function (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, function (err, torrentBuf) { - if (err) return cb(new Error('Invalid torrent identifier')) - parseOrThrow(torrentBuf) - }) - } else { - process.nextTick(function () { - 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')) - } -} - -/** - * Check if `obj` is a W3C `Blob` or `File` object - * @param {*} obj - * @return {boolean} - */ -function isBlob (obj) { - return typeof Blob !== 'undefined' && obj instanceof Blob -} - -// Workaround Browserify v13 bug -// https://github.com/substack/node-browserify/issues/1483 -;(function () { Buffer(0) })() - -}).call(this,require('_process'),require("buffer").Buffer) -},{"_process":16,"blob-to-buffer":49,"buffer":5,"fs":3,"magnet-uri":71,"parse-torrent-file":84,"simple-get":106}],86:[function(require,module,exports){ -var closest = require('closest-to') - -// Create a range from 16kb–4mb -var sizes = [] -for (var i = 14; i <= 22; i++) { - sizes.push(Math.pow(2, i)) -} - -module.exports = function(size) { - return closest( - size / Math.pow(2, 10), sizes - ) -} - -},{"closest-to":53}],87:[function(require,module,exports){ -arguments[4][15][0].apply(exports,arguments) -},{"_process":16,"dup":15}],88:[function(require,module,exports){ -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 isFn = function (fn) { - return typeof fn === 'function' -} - -var isFS = function (stream) { - 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() // 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 - -},{"end-of-stream":59,"fs":3,"once":83}],89:[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 - -},{}],90:[function(require,module,exports){ -(function (process,global,Buffer){ -'use strict' - -function oldBrowser () { - throw new Error('secure random number generation not supported by this browser\nuse chrome, FireFox or Internet Explorer 11') -} - -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 > 65536) throw new Error('requested too many random bytes') - // in case browserify isn't using the Uint8Array version - var rawBytes = new global.Uint8Array(size) - - // This will not work in older browsers. - // See https://developer.mozilla.org/en-US/docs/Web/API/window.crypto.getRandomValues - if (size > 0) { // getRandomValues fails on IE if size == 0 - crypto.getRandomValues(rawBytes) - } - // phantomjs doesn't like a buffer being passed here - var bytes = new Buffer(rawBytes.buffer) - - if (typeof cb === 'function') { - return process.nextTick(function () { - cb(null, bytes) - }) - } - - return bytes -} - -}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer) -},{"_process":16,"buffer":5}],91:[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 - - -*/ -var inherits = require('inherits') -var stream = require('readable-stream') - -module.exports = RangeSliceStream - -inherits(RangeSliceStream, stream.Writable) - -function RangeSliceStream (offset) { - var self = this - if (!(self instanceof RangeSliceStream)) return new RangeSliceStream(offset) - stream.Writable.call(self) - - self.destroyed = false - self._queue = [] - self._position = offset || 0 - self._cb = null - self._buffer = null - self._out = null -} - -RangeSliceStream.prototype._write = function (chunk, encoding, cb) { - var self = this - - var drained = true - - while (true) { - if (self.destroyed) { - return - } - - // Wait for more queue entries - if (self._queue.length === 0) { - self._buffer = chunk - self._cb = cb - return - } - - self._buffer = null - var currRange = self._queue[0] - // Relative to the start of chunk, what data do we need? - var writeStart = Math.max(currRange.start - self._position, 0) - var writeEnd = currRange.end - self._position - - // Check if we need to throw it all away - if (writeStart >= chunk.length) { - self._position += chunk.length - return cb(null) - } - - // Check if we need to use it all - var toWrite - if (writeEnd > chunk.length) { - self._position += chunk.length - if (writeStart === 0) { - toWrite = chunk - } else { - toWrite = chunk.slice(writeStart) - } - drained = currRange.stream.write(toWrite) && drained - break - } - - self._position += writeEnd - if (writeStart === 0 && writeEnd === chunk.length) { - toWrite = chunk - } else { - toWrite = chunk.slice(writeStart, writeEnd) - } - drained = currRange.stream.write(toWrite) && drained - if (currRange.last) { - currRange.stream.end() - } - chunk = chunk.slice(writeEnd) - self._queue.shift() - } - - if (drained) { - cb(null) - } else { - currRange.stream.once('drain', cb.bind(null, null)) - } -} - -RangeSliceStream.prototype.slice = function (ranges) { - var self = this - - if (self.destroyed) return null - - if (!(ranges instanceof Array)) { - ranges = [ranges] - } - - var str = new stream.PassThrough() - - ranges.forEach(function (range, i) { - self._queue.push({ - start: range.start, - end: range.end, - stream: str, - last: i === (ranges.length - 1) - }) - }) - if (self._buffer) { - self._write(self._buffer, null, self._cb) - } - - return str -} - -RangeSliceStream.prototype.destroy = function (err) { - var self = this - if (self.destroyed) return - self.destroyed = true - - if (err) self.emit('error', err) -} - -},{"inherits":65,"readable-stream":98}],92:[function(require,module,exports){ -arguments[4][21][0].apply(exports,arguments) -},{"./_stream_readable":94,"./_stream_writable":96,"core-util-is":54,"dup":21,"inherits":65,"process-nextick-args":87}],93:[function(require,module,exports){ -arguments[4][22][0].apply(exports,arguments) -},{"./_stream_transform":95,"core-util-is":54,"dup":22,"inherits":65}],94:[function(require,module,exports){ -arguments[4][23][0].apply(exports,arguments) -},{"./_stream_duplex":92,"./internal/streams/BufferList":97,"_process":16,"buffer":5,"buffer-shims":51,"core-util-is":54,"dup":23,"events":8,"inherits":65,"isarray":69,"process-nextick-args":87,"string_decoder/":114,"util":2}],95:[function(require,module,exports){ -arguments[4][24][0].apply(exports,arguments) -},{"./_stream_duplex":92,"core-util-is":54,"dup":24,"inherits":65}],96:[function(require,module,exports){ -arguments[4][25][0].apply(exports,arguments) -},{"./_stream_duplex":92,"_process":16,"buffer":5,"buffer-shims":51,"core-util-is":54,"dup":25,"events":8,"inherits":65,"process-nextick-args":87,"util-deprecate":125}],97:[function(require,module,exports){ -arguments[4][26][0].apply(exports,arguments) -},{"buffer":5,"buffer-shims":51,"dup":26}],98:[function(require,module,exports){ -arguments[4][27][0].apply(exports,arguments) -},{"./lib/_stream_duplex.js":92,"./lib/_stream_passthrough.js":93,"./lib/_stream_readable.js":94,"./lib/_stream_transform.js":95,"./lib/_stream_writable.js":96,"_process":16,"dup":27}],99:[function(require,module,exports){ -exports.render = render -exports.append = append -exports.mime = require('./lib/mime.json') - -var debug = require('debug')('render-media') -var isAscii = require('is-ascii') -var MediaElementWrapper = require('mediasource') -var path = require('path') -var streamToBlobURL = require('stream-to-blob-url') -var videostream = require('videostream') - -var VIDEOSTREAM_EXTS = [ - '.m4a', - '.m4v', - '.mp4' -] - -var MEDIASOURCE_VIDEO_EXTS = [ - '.m4v', - '.mkv', - '.mp4', - '.webm' -] - -var MEDIASOURCE_AUDIO_EXTS = [ - '.m4a', - '.mp3' -] - -var MEDIASOURCE_EXTS = [].concat( - MEDIASOURCE_VIDEO_EXTS, - MEDIASOURCE_AUDIO_EXTS -) - -var AUDIO_EXTS = [ - '.aac', - '.oga', - '.ogg', - '.wav' -] - -var IMAGE_EXTS = [ - '.bmp', - '.gif', - '.jpeg', - '.jpg', - '.png' -] - -var IFRAME_EXTS = [ - '.css', - '.html', - '.js', - '.md', - '.pdf', - '.txt' -] - -// Maximum file length for which the Blob URL strategy will be attempted -// See: https://github.com/feross/render-media/issues/18 -var MAX_BLOB_LENGTH = 200 * 1000 * 1000 // 200 MB - -var 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 = function () {} - - validateFile(file) - parseOpts(opts) - - if (typeof elem === 'string') elem = document.querySelector(elem) - - renderMedia(file, function (tagName) { - if (elem.nodeName !== tagName.toUpperCase()) { - var extname = path.extname(file.name).toLowerCase() - - throw new Error( - 'Cannot render "' + extname + '" inside a "' + - elem.nodeName.toLowerCase() + '" element, expected "' + tagName + '"' - ) - } - - return elem - }, opts, cb) -} - -function append (file, rootElem, opts, cb) { - if (typeof opts === 'function') { - cb = opts - opts = {} - } - if (!opts) opts = {} - if (!cb) cb = function () {} - - 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) { - var elem = createElem(tagName) - if (opts.controls) elem.controls = true - if (opts.autoplay) elem.autoplay = true - rootElem.appendChild(elem) - return elem - } - - function createElem (tagName) { - var 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) { - var extname = path.extname(file.name).toLowerCase() - var currentTime = 0 - var elem - - if (MEDIASOURCE_EXTS.indexOf(extname) >= 0) { - renderMediaSource() - } else if (AUDIO_EXTS.indexOf(extname) >= 0) { - renderAudio() - } else if (IMAGE_EXTS.indexOf(extname) >= 0) { - renderImage() - } else if (IFRAME_EXTS.indexOf(extname) >= 0) { - renderIframe() - } else { - tryRenderIframe() - } - - function renderMediaSource () { - var tagName = MEDIASOURCE_VIDEO_EXTS.indexOf(extname) >= 0 ? 'video' : 'audio' - - if (MediaSource) { - if (VIDEOSTREAM_EXTS.indexOf(extname) >= 0) { - 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('canplay', onCanPlay) - videostream(file, elem) - } - - function useMediaSource () { - debug('Use MediaSource API for ' + file.name) - prepareElem() - elem.addEventListener('error', fallbackToBlobURL) - elem.addEventListener('loadstart', onLoadStart) - elem.addEventListener('canplay', onCanPlay) - - var wrapper = new MediaElementWrapper(elem) - var 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('canplay', onCanPlay) - getBlobURL(file, function (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('canplay', onCanPlay) - - useMediaSource() - } - - function fallbackToBlobURL (err) { - debug('MediaSource API error: fallback to Blob URL: %o', err.message || err) - - 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 - ) - return fatalError(new Error( - 'File length too large for Blob URL approach: ' + file.length + - ' (max: ' + opts.maxBlobLength + ')' - )) - } - - elem.removeEventListener('error', fallbackToBlobURL) - elem.removeEventListener('canplay', onCanPlay) - - useBlobURL() - } - - function prepareElem () { - if (!elem) { - elem = getElem(tagName) - - elem.addEventListener('progress', function () { - currentTime = elem.currentTime - }) - } - } - } - - function renderAudio () { - elem = getElem('audio') - getBlobURL(file, function (err, url) { - if (err) return fatalError(err) - elem.addEventListener('error', fatalError) - elem.addEventListener('loadstart', onLoadStart) - elem.addEventListener('canplay', onCanPlay) - elem.src = url - }) - } - - function onLoadStart () { - elem.removeEventListener('loadstart', onLoadStart) - if (opts.autoplay) elem.play() - } - - function onCanPlay () { - elem.removeEventListener('canplay', onCanPlay) - cb(null, elem) - } - - function renderImage () { - elem = getElem('img') - getBlobURL(file, function (err, url) { - if (err) return fatalError(err) - elem.src = url - elem.alt = file.name - cb(null, elem) - }) - } - - function renderIframe () { - elem = getElem('iframe') - - getBlobURL(file, function (err, url) { - if (err) return fatalError(err) - elem.src = url - if (extname !== '.pdf') elem.sandbox = 'allow-forms allow-scripts' - cb(null, elem) - }) - } - - function tryRenderIframe () { - debug('Unknown file extension "%s" - will attempt to render into iframe', extname) - - var str = '' - file.createReadStream({ start: 0, end: 1000 }) - .setEncoding('utf8') - .on('data', function (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) { - var extname = path.extname(file.name).toLowerCase() - streamToBlobURL(file.createReadStream(), exports.mime[extname], cb) -} - -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) { - var extname = path.extname(name).toLowerCase() - return { - '.m4a': '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 = true - if (opts.controls == null) opts.controls = true - if (opts.maxBlobLength == null) opts.maxBlobLength = MAX_BLOB_LENGTH -} - -},{"./lib/mime.json":100,"debug":56,"is-ascii":66,"mediasource":72,"path":14,"stream-to-blob-url":111,"videostream":127}],100:[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/csv", - ".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/mp4", - ".m4v": "video/mp4", - ".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" -} - -},{}],101:[function(require,module,exports){ -(function (process){ -module.exports = function (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,require('_process')) -},{"_process":16}],102:[function(require,module,exports){ -(function (process){ -module.exports = function (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,require('_process')) -},{"_process":16}],103:[function(require,module,exports){ -(function (global){ -(function () { - var /* - * Rusha, a JavaScript implementation of the Secure Hash Algorithm, SHA-1, - * as defined in FIPS PUB 180-1, tuned for high performance with large inputs. - * (http://github.com/srijs/rusha) - * - * Inspired by Paul Johnstons implementation (http://pajhome.org.uk/crypt/md5). - * - * Copyright (c) 2013 Sam Rijs (http://awesam.de). - * Released under the terms of the MIT license as follows: - * - * 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. - */ - util = { - getDataType: function (data) { - if (typeof data === 'string') { - return 'string'; - } - if (data instanceof Array) { - return 'array'; - } - if (typeof global !== 'undefined' && global.Buffer && global.Buffer.isBuffer(data)) { - return 'buffer'; - } - if (data instanceof ArrayBuffer) { - return 'arraybuffer'; - } - if (data.buffer instanceof ArrayBuffer) { - return 'view'; - } - if (data instanceof Blob) { - return 'blob'; - } - throw new Error('Unsupported data type.'); - } - }; - function Rusha(chunkSize) { - 'use strict'; - var // Private object structure. - self$2 = { fill: 0 }; - var // Calculate the length of buffer that the sha1 routine uses - // including the padding. - padlen = function (len) { - for (len += 9; len % 64 > 0; len += 1); - return len; - }; - var padZeroes = function (bin, len) { - for (var i$2 = len >> 2; i$2 < bin.length; i$2++) - bin[i$2] = 0; - }; - var padData = function (bin, chunkLen, msgLen) { - bin[chunkLen >> 2] |= 128 << 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 & ~15) + 14] = msgLen / (1 << 29) | 0; - bin[((chunkLen >> 2) + 2 & ~15) + 15] = msgLen << 3; - }; - var // Convert a binary string and write it to the heap. - // A binary string is expected to only contain char codes < 256. - convStr = function (H8, H32, start, len, off) { - var str = this, i$2, om = off % 4, lm = len % 4, j = len - lm; - if (j > 0) { - switch (om) { - case 0: - H8[off + 3 | 0] = str.charCodeAt(start); - case 1: - H8[off + 2 | 0] = str.charCodeAt(start + 1); - case 2: - H8[off + 1 | 0] = str.charCodeAt(start + 2); - case 3: - H8[off | 0] = str.charCodeAt(start + 3); - } - } - for (i$2 = om; i$2 < j; i$2 = i$2 + 4 | 0) { - H32[off + i$2 >> 2] = str.charCodeAt(start + i$2) << 24 | str.charCodeAt(start + i$2 + 1) << 16 | str.charCodeAt(start + i$2 + 2) << 8 | str.charCodeAt(start + i$2 + 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); - } - }; - var // Convert a buffer or array and write it to the heap. - // The buffer or array is expected to only contain elements < 256. - convBuf = function (H8, H32, start, len, off) { - var buf = this, i$2, om = off % 4, lm = len % 4, j = len - lm; - if (j > 0) { - switch (om) { - case 0: - H8[off + 3 | 0] = buf[start]; - case 1: - H8[off + 2 | 0] = buf[start + 1]; - case 2: - H8[off + 1 | 0] = buf[start + 2]; - case 3: - H8[off | 0] = buf[start + 3]; - } - } - for (i$2 = 4 - om; i$2 < j; i$2 = i$2 += 4 | 0) { - H32[off + i$2 >> 2] = buf[start + i$2] << 24 | buf[start + i$2 + 1] << 16 | buf[start + i$2 + 2] << 8 | buf[start + i$2 + 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 (H8, H32, start, len, off) { - var blob = this, i$2, om = off % 4, lm = len % 4, j = len - lm; - var buf = new Uint8Array(reader.readAsArrayBuffer(blob.slice(start, start + len))); - if (j > 0) { - switch (om) { - case 0: - H8[off + 3 | 0] = buf[0]; - case 1: - H8[off + 2 | 0] = buf[1]; - case 2: - H8[off + 1 | 0] = buf[2]; - case 3: - H8[off | 0] = buf[3]; - } - } - for (i$2 = 4 - om; i$2 < j; i$2 = i$2 += 4 | 0) { - H32[off + i$2 >> 2] = buf[i$2] << 24 | buf[i$2 + 1] << 16 | buf[i$2 + 2] << 8 | buf[i$2 + 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]; - } - }; - var convFn = function (data) { - switch (util.getDataType(data)) { - case 'string': - return convStr.bind(data); - case 'array': - return convBuf.bind(data); - case 'buffer': - return convBuf.bind(data); - case 'arraybuffer': - return convBuf.bind(new Uint8Array(data)); - case 'view': - return convBuf.bind(new Uint8Array(data.buffer, data.byteOffset, data.byteLength)); - case 'blob': - return convBlob.bind(data); - } - }; - var slice = function (data, offset) { - switch (util.getDataType(data)) { - case 'string': - return data.slice(offset); - case 'array': - return data.slice(offset); - case 'buffer': - return data.slice(offset); - case 'arraybuffer': - return data.slice(offset); - case 'view': - return data.buffer.slice(offset); - } - }; - var // Precompute 00 - ff strings - precomputedHex = new Array(256); - for (var i = 0; i < 256; i++) { - precomputedHex[i] = (i < 16 ? '0' : '') + i.toString(16); - } - var // Convert an ArrayBuffer into its hexadecimal string representation. - hex = function (arrayBuffer) { - var binarray = new Uint8Array(arrayBuffer); - var res = new Array(arrayBuffer.byteLength); - for (var i$2 = 0; i$2 < res.length; i$2++) { - res[i$2] = precomputedHex[binarray[i$2]]; - } - return res.join(''); - }; - var 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; - if (// If v is smaller than 2^16, the smallest possible solution - // is 2^16. - v <= 65536) - return 65536; - if (// If v < 2^24, we round up to 2^n, - // otherwise we round up to 2^24 * n. - v < 16777216) { - for (p = 1; p < v; p = p << 1); - } else { - for (p = 16777216; p < v; p += 16777216); - } - return p; - }; - var // Initialize the internal data structures to a new capacity. - init = function (size) { - if (size % 64 > 0) { - throw new Error('Chunk size must be a multiple of 128 bit'); - } - self$2.maxChunkLen = size; - self$2.padMaxChunkLen = padlen(size); - // 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 - self$2.heap = new ArrayBuffer(ceilHeapSize(self$2.padMaxChunkLen + 320 + 20)); - self$2.h32 = new Int32Array(self$2.heap); - self$2.h8 = new Int8Array(self$2.heap); - self$2.core = new Rusha._core({ - Int32Array: Int32Array, - DataView: DataView - }, {}, self$2.heap); - self$2.buffer = null; - }; - // Iinitializethe datastructures according - // to a chunk siyze. - init(chunkSize || 64 * 1024); - var initState = function (heap, padMsgLen) { - var io = new Int32Array(heap, padMsgLen + 320, 5); - io[0] = 1732584193; - io[1] = -271733879; - io[2] = -1732584194; - io[3] = 271733878; - io[4] = -1009589776; - }; - var padChunk = function (chunkLen, msgLen) { - var padChunkLen = padlen(chunkLen); - var view = new Int32Array(self$2.heap, 0, padChunkLen >> 2); - padZeroes(view, chunkLen); - padData(view, chunkLen, msgLen); - return padChunkLen; - }; - var // Write data to the heap. - write = function (data, chunkOffset, chunkLen) { - convFn(data)(self$2.h8, self$2.h32, chunkOffset, chunkLen, 0); - }; - var // Initialize and call the RushaCore, - // assuming an input buffer of length len * 4. - coreCall = function (data, chunkOffset, chunkLen, msgLen, finalize) { - var padChunkLen = chunkLen; - if (finalize) { - padChunkLen = padChunk(chunkLen, msgLen); - } - write(data, chunkOffset, chunkLen); - self$2.core.hash(padChunkLen, self$2.padMaxChunkLen); - }; - 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 // Calculate the hash digest as an array of 5 32bit integers. - rawDigest = this.rawDigest = function (str) { - var msgLen = str.byteLength || str.length || str.size || 0; - initState(self$2.heap, self$2.padMaxChunkLen); - var chunkOffset = 0, chunkLen = self$2.maxChunkLen, last; - for (chunkOffset = 0; msgLen > chunkOffset + chunkLen; chunkOffset += chunkLen) { - coreCall(str, chunkOffset, chunkLen, msgLen, false); - } - coreCall(str, chunkOffset, msgLen - chunkOffset, msgLen, true); - return getRawDigest(self$2.heap, self$2.padMaxChunkLen); - }; - // The digest and digestFrom* interface returns the hash digest - // as a hex string. - this.digest = this.digestFromString = this.digestFromBuffer = this.digestFromArrayBuffer = function (str) { - return hex(rawDigest(str).buffer); - }; - } - ; - // 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. - Rusha._core = function RushaCore(stdlib, foreign, heap) { - 'use asm'; - var H = new stdlib.Int32Array(heap); - function hash(k, x) { - // k in bytes - k = k | 0; - x = x | 0; - var i = 0, j = 0, y0 = 0, z0 = 0, y1 = 0, z1 = 0, y2 = 0, z2 = 0, y3 = 0, z3 = 0, y4 = 0, z4 = 0, t0 = 0, t1 = 0; - y0 = H[x + 320 >> 2] | 0; - y1 = H[x + 324 >> 2] | 0; - y2 = H[x + 328 >> 2] | 0; - y3 = H[x + 332 >> 2] | 0; - y4 = H[x + 336 >> 2] | 0; - for (i = 0; (i | 0) < (k | 0); i = i + 64 | 0) { - z0 = y0; - z1 = y1; - z2 = y2; - z3 = y3; - z4 = y4; - for (j = 0; (j | 0) < 64; j = j + 4 | 0) { - t1 = H[i + j >> 2] | 0; - t0 = ((y0 << 5 | y0 >>> 27) + (y1 & y2 | ~y1 & y3) | 0) + ((t1 + y4 | 0) + 1518500249 | 0) | 0; - y4 = y3; - y3 = y2; - y2 = y1 << 30 | y1 >>> 2; - y1 = y0; - y0 = t0; - H[k + j >> 2] = t1; - } - for (j = k + 64 | 0; (j | 0) < (k + 80 | 0); j = j + 4 | 0) { - t1 = (H[j - 12 >> 2] ^ H[j - 32 >> 2] ^ H[j - 56 >> 2] ^ H[j - 64 >> 2]) << 1 | (H[j - 12 >> 2] ^ H[j - 32 >> 2] ^ H[j - 56 >> 2] ^ H[j - 64 >> 2]) >>> 31; - t0 = ((y0 << 5 | y0 >>> 27) + (y1 & y2 | ~y1 & y3) | 0) + ((t1 + y4 | 0) + 1518500249 | 0) | 0; - y4 = y3; - y3 = y2; - y2 = y1 << 30 | y1 >>> 2; - y1 = y0; - y0 = t0; - H[j >> 2] = t1; - } - for (j = k + 80 | 0; (j | 0) < (k + 160 | 0); j = j + 4 | 0) { - t1 = (H[j - 12 >> 2] ^ H[j - 32 >> 2] ^ H[j - 56 >> 2] ^ H[j - 64 >> 2]) << 1 | (H[j - 12 >> 2] ^ H[j - 32 >> 2] ^ H[j - 56 >> 2] ^ H[j - 64 >> 2]) >>> 31; - t0 = ((y0 << 5 | y0 >>> 27) + (y1 ^ y2 ^ y3) | 0) + ((t1 + y4 | 0) + 1859775393 | 0) | 0; - y4 = y3; - y3 = y2; - y2 = y1 << 30 | y1 >>> 2; - y1 = y0; - y0 = t0; - H[j >> 2] = t1; - } - for (j = k + 160 | 0; (j | 0) < (k + 240 | 0); j = j + 4 | 0) { - t1 = (H[j - 12 >> 2] ^ H[j - 32 >> 2] ^ H[j - 56 >> 2] ^ H[j - 64 >> 2]) << 1 | (H[j - 12 >> 2] ^ H[j - 32 >> 2] ^ H[j - 56 >> 2] ^ H[j - 64 >> 2]) >>> 31; - t0 = ((y0 << 5 | y0 >>> 27) + (y1 & y2 | y1 & y3 | y2 & y3) | 0) + ((t1 + y4 | 0) - 1894007588 | 0) | 0; - y4 = y3; - y3 = y2; - y2 = y1 << 30 | y1 >>> 2; - y1 = y0; - y0 = t0; - H[j >> 2] = t1; - } - for (j = k + 240 | 0; (j | 0) < (k + 320 | 0); j = j + 4 | 0) { - t1 = (H[j - 12 >> 2] ^ H[j - 32 >> 2] ^ H[j - 56 >> 2] ^ H[j - 64 >> 2]) << 1 | (H[j - 12 >> 2] ^ H[j - 32 >> 2] ^ H[j - 56 >> 2] ^ H[j - 64 >> 2]) >>> 31; - t0 = ((y0 << 5 | y0 >>> 27) + (y1 ^ y2 ^ y3) | 0) + ((t1 + y4 | 0) - 899497514 | 0) | 0; - y4 = y3; - y3 = y2; - y2 = y1 << 30 | y1 >>> 2; - y1 = y0; - y0 = t0; - H[j >> 2] = t1; - } - y0 = y0 + z0 | 0; - y1 = y1 + z1 | 0; - y2 = y2 + z2 | 0; - y3 = y3 + z3 | 0; - y4 = y4 + z4 | 0; - } - H[x + 320 >> 2] = y0; - H[x + 324 >> 2] = y1; - H[x + 328 >> 2] = y2; - H[x + 332 >> 2] = y3; - H[x + 336 >> 2] = y4; - } - return { hash: hash }; - }; - if (// If we'e running in Node.JS, export a module. - typeof module !== 'undefined') { - module.exports = Rusha; - } else if (// If we're running in a DOM context, export - // the Rusha object to toplevel. - typeof window !== 'undefined') { - window.Rusha = Rusha; - } - if (// If we're running in a webworker, accept - // messages containing a jobid and a buffer - // or blob object, and return the hash result. - typeof FileReaderSync !== 'undefined') { - var reader = new FileReaderSync(), hasher = new Rusha(4 * 1024 * 1024); - self.onmessage = function onMessage(event) { - var hash, data = event.data.data; - try { - hash = hasher.digest(data); - self.postMessage({ - id: event.data.id, - hash: hash - }); - } catch (e) { - self.postMessage({ - id: event.data.id, - error: e.name - }); - } - }; - } -}()); -}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{}],104:[function(require,module,exports){ -module.exports = require('buffer') - -},{"buffer":5}],105:[function(require,module,exports){ -(function (Buffer){ -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,require("buffer").Buffer) -},{"buffer":5}],106:[function(require,module,exports){ -(function (Buffer){ -module.exports = simpleGet - -var concat = require('simple-concat') -var http = require('http') -var https = require('https') -var once = require('once') -var querystring = require('querystring') -var unzipResponse = require('unzip-response') // excluded from browser build -var url = require('url') - -function simpleGet (opts, cb) { - opts = typeof opts === 'string' ? {url: opts} : Object.assign({}, opts) - cb = once(cb) - - if (opts.url) parseOptsUrl(opts) - if (opts.headers == null) opts.headers = {} - if (opts.maxRedirects == null) opts.maxRedirects = 10 - - var body - if (opts.form) body = typeof opts.form === 'string' ? opts.form : querystring.stringify(opts.form) - if (opts.body) body = opts.json ? JSON.stringify(opts.body) : opts.body - - if (opts.json) opts.headers.accept = 'application/json' - if (opts.json && body) opts.headers['content-type'] = 'application/json' - if (opts.form) opts.headers['content-type'] = 'application/x-www-form-urlencoded' - if (body) opts.headers['content-length'] = Buffer.byteLength(body) - delete opts.body; delete opts.form - - if (body && !opts.method) opts.method = 'POST' - if (opts.method) opts.method = opts.method.toUpperCase() - - // Request gzip/deflate - var customAcceptEncoding = Object.keys(opts.headers).some(function (h) { - return h.toLowerCase() === 'accept-encoding' - }) - if (!customAcceptEncoding) opts.headers['accept-encoding'] = 'gzip, deflate' - - // Support http/https urls - var protocol = opts.protocol === 'https:' ? https : http - var req = protocol.request(opts, function (res) { - // Follow 3xx redirects - if (res.statusCode >= 300 && res.statusCode < 400 && 'location' in res.headers) { - opts.url = res.headers.location - parseOptsUrl(opts) - res.resume() // Discard response - - opts.maxRedirects -= 1 - if (opts.maxRedirects > 0) simpleGet(opts, cb) - else cb(new Error('too many redirects')) - - return - } - - var tryUnzip = typeof unzipResponse === 'function' && opts.method !== 'HEAD' - cb(null, tryUnzip ? unzipResponse(res) : res) - }) - req.on('error', cb) - req.end(body) - return req -} - -simpleGet.concat = function (opts, cb) { - return simpleGet(opts, function (err, res) { - if (err) return cb(err) - concat(res, function (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(function (method) { - simpleGet[method] = function (opts, cb) { - if (typeof opts === 'string') opts = {url: opts} - opts.method = method.toUpperCase() - return simpleGet(opts, cb) - } -}) - -function parseOptsUrl (opts) { - var loc = url.parse(opts.url) - if (loc.hostname) opts.hostname = loc.hostname - if (loc.port) opts.port = loc.port - if (loc.protocol) opts.protocol = loc.protocol - if (loc.auth) opts.auth = loc.auth - opts.path = loc.path - delete opts.url -} - -}).call(this,require("buffer").Buffer) -},{"buffer":5,"http":28,"https":9,"once":83,"querystring":20,"simple-concat":105,"unzip-response":2,"url":34}],107:[function(require,module,exports){ -(function (Buffer){ -module.exports = Peer - -var debug = require('debug')('simple-peer') -var getBrowserRTC = require('get-browser-rtc') -var inherits = require('inherits') -var randombytes = require('randombytes') -var stream = require('readable-stream') - -inherits(Peer, stream.Duplex) - -/** - * WebRTC peer connection. Same API as node core `net.Socket`, plus a few extra methods. - * Duplex stream. - * @param {Object} opts - */ -function Peer (opts) { - var self = this - if (!(self instanceof Peer)) return new Peer(opts) - - self.channelName = opts.initiator - ? opts.channelName || randombytes(20).toString('hex') - : null - - self._debug('new peer %o', opts) - - if (!opts) opts = {} - opts.allowHalfOpen = false - if (opts.highWaterMark == null) opts.highWaterMark = 1024 * 1024 - - stream.Duplex.call(self, opts) - - self.initiator = opts.initiator || false - self.channelConfig = opts.channelConfig || Peer.channelConfig - self.config = opts.config || Peer.config - self.constraints = opts.constraints || Peer.constraints - self.offerConstraints = opts.offerConstraints || {} - self.answerConstraints = opts.answerConstraints || {} - self.reconnectTimer = opts.reconnectTimer || false - self.sdpTransform = opts.sdpTransform || function (sdp) { return sdp } - self.stream = opts.stream || false - self.trickle = opts.trickle !== undefined ? opts.trickle : true - - self.destroyed = false - self.connected = false - - // so Peer object always has same shape (V8 optimization) - self.remoteAddress = undefined - self.remoteFamily = undefined - self.remotePort = undefined - self.localAddress = undefined - self.localPort = undefined - - self._isWrtc = !!opts.wrtc // HACK: to fix `wrtc` bug. See issue: #60 - self._wrtc = (opts.wrtc && typeof opts.wrtc === 'object') - ? opts.wrtc - : getBrowserRTC() - if (!self._wrtc) { - if (typeof window === 'undefined') { - throw new Error('No WebRTC support: Specify `opts.wrtc` option in this environment') - } else { - throw new Error('No WebRTC support: Not a supported browser') - } - } - - self._maxBufferedAmount = opts.highWaterMark - self._pcReady = false - self._channelReady = false - self._iceComplete = false // ice candidate trickle done (got null candidate) - self._channel = null - self._pendingCandidates = [] - - self._chunk = null - self._cb = null - self._interval = null - self._reconnectTimeout = null - - self._pc = new (self._wrtc.RTCPeerConnection)(self.config, self.constraints) - self._pc.oniceconnectionstatechange = function () { - self._onIceConnectionStateChange() - } - self._pc.onsignalingstatechange = function () { - self._onSignalingStateChange() - } - self._pc.onicecandidate = function (event) { - self._onIceCandidate(event) - } - - if (self.stream) self._pc.addStream(self.stream) - - if ('ontrack' in self._pc) { - // WebRTC Spec, Firefox - self._pc.ontrack = function (event) { - self._onTrack(event) - } - } else { - // Chrome, etc. This can be removed once all browsers support `ontrack` - self._pc.onaddstream = function (event) { - self._onAddStream(event) - } - } - - if (self.initiator) { - self._setupData({ - channel: self._pc.createDataChannel(self.channelName, self.channelConfig) - }) - - var createdOffer = false - self._pc.onnegotiationneeded = function () { - if (!createdOffer) self._createOffer() - createdOffer = true - } - // Only Chrome triggers "negotiationneeded"; this is a workaround for other - // implementations - if (typeof window === 'undefined' || !window.webkitRTCPeerConnection) { - self._pc.onnegotiationneeded() - } - } else { - self._pc.ondatachannel = function (event) { - self._setupData(event) - } - } - - self.on('finish', function () { - if (self.connected) { - // When local peer is finished writing, close connection to remote peer. - // Half open connections are currently not supported. - // Wait a bit before destroying so the datachannel flushes. - // TODO: is there a more reliable way to accomplish this? - setTimeout(function () { - self._destroy() - }, 100) - } else { - // If data channel is not connected when local peer is finished writing, wait until - // data is flushed to network at "connect" event. - // TODO: is there a more reliable way to accomplish this? - self.once('connect', function () { - setTimeout(function () { - self._destroy() - }, 100) - }) - } - }) -} - -Peer.WEBRTC_SUPPORT = !!getBrowserRTC() - -/** - * Expose config, constraints, and data channel config for overriding all Peer - * instances. Otherwise, just set opts.config, opts.constraints, or opts.channelConfig - * when constructing a Peer. - */ -Peer.config = { - iceServers: [ - { - url: 'stun:23.21.150.121', // deprecated, replaced by `urls` - urls: 'stun:23.21.150.121' - } - ] -} -Peer.constraints = {} -Peer.channelConfig = {} - -Object.defineProperty(Peer.prototype, 'bufferSize', { - get: function () { - var self = this - return (self._channel && self._channel.bufferedAmount) || 0 - } -}) - -Peer.prototype.address = function () { - var self = this - return { port: self.localPort, family: 'IPv4', address: self.localAddress } -} - -Peer.prototype.signal = function (data) { - var self = this - if (self.destroyed) throw new Error('cannot signal after peer is destroyed') - if (typeof data === 'string') { - try { - data = JSON.parse(data) - } catch (err) { - data = {} - } - } - self._debug('signal()') - - function addIceCandidate (candidate) { - try { - self._pc.addIceCandidate( - new self._wrtc.RTCIceCandidate(candidate), - noop, - function (err) { self._onError(err) } - ) - } catch (err) { - self._destroy(new Error('error adding candidate: ' + err.message)) - } - } - - if (data.sdp) { - self._pc.setRemoteDescription(new (self._wrtc.RTCSessionDescription)(data), function () { - if (self.destroyed) return - if (self._pc.remoteDescription.type === 'offer') self._createAnswer() - - self._pendingCandidates.forEach(addIceCandidate) - self._pendingCandidates = [] - }, function (err) { self._onError(err) }) - } - if (data.candidate) { - if (self._pc.remoteDescription) addIceCandidate(data.candidate) - else self._pendingCandidates.push(data.candidate) - } - if (!data.sdp && !data.candidate) { - self._destroy(new Error('signal() called with invalid signal data')) - } -} - -/** - * Send text/binary data to the remote peer. - * @param {TypedArrayView|ArrayBuffer|Buffer|string|Blob|Object} chunk - */ -Peer.prototype.send = function (chunk) { - var self = this - - // HACK: `wrtc` module doesn't accept node.js buffer. See issue: #60 - if (Buffer.isBuffer(chunk) && self._isWrtc) { - chunk = new Uint8Array(chunk) - } - - var len = chunk.length || chunk.byteLength || chunk.size - self._channel.send(chunk) - self._debug('write: %d bytes', len) -} - -Peer.prototype.destroy = function (onclose) { - var self = this - self._destroy(null, onclose) -} - -Peer.prototype._destroy = function (err, onclose) { - var self = this - if (self.destroyed) return - if (onclose) self.once('close', onclose) - - self._debug('destroy (error: %s)', err && err.message) - - self.readable = self.writable = false - - if (!self._readableState.ended) self.push(null) - if (!self._writableState.finished) self.end() - - self.destroyed = true - self.connected = false - self._pcReady = false - self._channelReady = false - - self._chunk = null - self._cb = null - clearInterval(self._interval) - clearTimeout(self._reconnectTimeout) - - if (self._pc) { - try { - self._pc.close() - } catch (err) {} - - self._pc.oniceconnectionstatechange = null - self._pc.onsignalingstatechange = null - self._pc.onicecandidate = null - if ('ontrack' in self._pc) { - self._pc.ontrack = null - } else { - self._pc.onaddstream = null - } - self._pc.onnegotiationneeded = null - self._pc.ondatachannel = null - } - - if (self._channel) { - try { - self._channel.close() - } catch (err) {} - - self._channel.onmessage = null - self._channel.onopen = null - self._channel.onclose = null - } - self._pc = null - self._channel = null - - if (err) self.emit('error', err) - self.emit('close') -} - -Peer.prototype._setupData = function (event) { - var self = this - self._channel = event.channel - self.channelName = self._channel.label - - self._channel.binaryType = 'arraybuffer' - self._channel.onmessage = function (event) { - self._onChannelMessage(event) - } - self._channel.onopen = function () { - self._onChannelOpen() - } - self._channel.onclose = function () { - self._onChannelClose() - } -} - -Peer.prototype._read = function () {} - -Peer.prototype._write = function (chunk, encoding, cb) { - var self = this - if (self.destroyed) return cb(new Error('cannot write after peer is destroyed')) - - if (self.connected) { - try { - self.send(chunk) - } catch (err) { - return self._onError(err) - } - if (self._channel.bufferedAmount > self._maxBufferedAmount) { - self._debug('start backpressure: bufferedAmount %d', self._channel.bufferedAmount) - self._cb = cb - } else { - cb(null) - } - } else { - self._debug('write before connect') - self._chunk = chunk - self._cb = cb - } -} - -Peer.prototype._createOffer = function () { - var self = this - if (self.destroyed) return - - self._pc.createOffer(function (offer) { - if (self.destroyed) return - offer.sdp = self.sdpTransform(offer.sdp) - self._pc.setLocalDescription(offer, noop, function (err) { self._onError(err) }) - var sendOffer = function () { - var signal = self._pc.localDescription || offer - self._debug('signal') - self.emit('signal', { - type: signal.type, - sdp: signal.sdp - }) - } - if (self.trickle || self._iceComplete) sendOffer() - else self.once('_iceComplete', sendOffer) // wait for candidates - }, function (err) { self._onError(err) }, self.offerConstraints) -} - -Peer.prototype._createAnswer = function () { - var self = this - if (self.destroyed) return - - self._pc.createAnswer(function (answer) { - if (self.destroyed) return - answer.sdp = self.sdpTransform(answer.sdp) - self._pc.setLocalDescription(answer, noop, function (err) { self._onError(err) }) - var sendAnswer = function () { - var signal = self._pc.localDescription || answer - self._debug('signal') - self.emit('signal', { - type: signal.type, - sdp: signal.sdp - }) - } - if (self.trickle || self._iceComplete) sendAnswer() - else self.once('_iceComplete', sendAnswer) - }, function (err) { self._onError(err) }, self.answerConstraints) -} - -Peer.prototype._onIceConnectionStateChange = function () { - var self = this - if (self.destroyed) return - var iceGatheringState = self._pc.iceGatheringState - var iceConnectionState = self._pc.iceConnectionState - self._debug('iceConnectionStateChange %s %s', iceGatheringState, iceConnectionState) - self.emit('iceConnectionStateChange', iceGatheringState, iceConnectionState) - if (iceConnectionState === 'connected' || iceConnectionState === 'completed') { - clearTimeout(self._reconnectTimeout) - self._pcReady = true - self._maybeReady() - } - if (iceConnectionState === 'disconnected') { - if (self.reconnectTimer) { - // If user has set `opt.reconnectTimer`, allow time for ICE to attempt a reconnect - clearTimeout(self._reconnectTimeout) - self._reconnectTimeout = setTimeout(function () { - self._destroy() - }, self.reconnectTimer) - } else { - self._destroy() - } - } - if (iceConnectionState === 'failed') { - self._destroy() - } - if (iceConnectionState === 'closed') { - self._destroy() - } -} - -Peer.prototype.getStats = function (cb) { - var self = this - if (!self._pc.getStats) { // No ability to call stats - cb([]) - } else if (typeof window !== 'undefined' && !!window.mozRTCPeerConnection) { // Mozilla - self._pc.getStats(null, function (res) { - var items = [] - res.forEach(function (item) { - items.push(item) - }) - cb(items) - }, function (err) { self._onError(err) }) - } else { - self._pc.getStats(function (res) { // Chrome - var items = [] - res.result().forEach(function (result) { - var item = {} - result.names().forEach(function (name) { - item[name] = result.stat(name) - }) - item.id = result.id - item.type = result.type - item.timestamp = result.timestamp - items.push(item) - }) - cb(items) - }) - } -} - -Peer.prototype._maybeReady = function () { - var self = this - self._debug('maybeReady pc %s channel %s', self._pcReady, self._channelReady) - if (self.connected || self._connecting || !self._pcReady || !self._channelReady) return - self._connecting = true - - self.getStats(function (items) { - self._connecting = false - self.connected = true - - var remoteCandidates = {} - var localCandidates = {} - - function setActiveCandidates (item) { - var local = localCandidates[item.localCandidateId] - var remote = remoteCandidates[item.remoteCandidateId] - - if (local) { - self.localAddress = local.ipAddress - self.localPort = Number(local.portNumber) - } else if (typeof item.googLocalAddress === 'string') { - // Sometimes `item.id` is undefined in `wrtc` and Chrome - // See: https://github.com/feross/simple-peer/issues/66 - local = item.googLocalAddress.split(':') - self.localAddress = local[0] - self.localPort = Number(local[1]) - } - self._debug('connect local: %s:%s', self.localAddress, self.localPort) - - if (remote) { - self.remoteAddress = remote.ipAddress - self.remotePort = Number(remote.portNumber) - self.remoteFamily = 'IPv4' - } else if (typeof item.googRemoteAddress === 'string') { - remote = item.googRemoteAddress.split(':') - self.remoteAddress = remote[0] - self.remotePort = Number(remote[1]) - self.remoteFamily = 'IPv4' - } - self._debug('connect remote: %s:%s', self.remoteAddress, self.remotePort) - } - - items.forEach(function (item) { - if (item.type === 'remotecandidate') remoteCandidates[item.id] = item - if (item.type === 'localcandidate') localCandidates[item.id] = item - }) - - items.forEach(function (item) { - var isCandidatePair = ( - (item.type === 'googCandidatePair' && item.googActiveConnection === 'true') || - (item.type === 'candidatepair' && item.selected) - ) - if (isCandidatePair) setActiveCandidates(item) - }) - - if (self._chunk) { - try { - self.send(self._chunk) - } catch (err) { - return self._onError(err) - } - self._chunk = null - self._debug('sent chunk from "write before connect"') - - var cb = self._cb - self._cb = null - cb(null) - } - - self._interval = setInterval(function () { - if (!self._cb || !self._channel || self._channel.bufferedAmount > self._maxBufferedAmount) return - self._debug('ending backpressure: bufferedAmount %d', self._channel.bufferedAmount) - var cb = self._cb - self._cb = null - cb(null) - }, 150) - if (self._interval.unref) self._interval.unref() - - self._debug('connect') - self.emit('connect') - }) -} - -Peer.prototype._onSignalingStateChange = function () { - var self = this - if (self.destroyed) return - self._debug('signalingStateChange %s', self._pc.signalingState) - self.emit('signalingStateChange', self._pc.signalingState) -} - -Peer.prototype._onIceCandidate = function (event) { - var self = this - if (self.destroyed) return - if (event.candidate && self.trickle) { - self.emit('signal', { - candidate: { - candidate: event.candidate.candidate, - sdpMLineIndex: event.candidate.sdpMLineIndex, - sdpMid: event.candidate.sdpMid - } - }) - } else if (!event.candidate) { - self._iceComplete = true - self.emit('_iceComplete') - } -} - -Peer.prototype._onChannelMessage = function (event) { - var self = this - if (self.destroyed) return - var data = event.data - self._debug('read: %d bytes', data.byteLength || data.length) - - if (data instanceof ArrayBuffer) data = new Buffer(data) - self.push(data) -} - -Peer.prototype._onChannelOpen = function () { - var self = this - if (self.connected || self.destroyed) return - self._debug('on channel open') - self._channelReady = true - self._maybeReady() -} - -Peer.prototype._onChannelClose = function () { - var self = this - if (self.destroyed) return - self._debug('on channel close') - self._destroy() -} - -Peer.prototype._onAddStream = function (event) { - var self = this - if (self.destroyed) return - self._debug('on add stream') - self.emit('stream', event.stream) -} - -Peer.prototype._onTrack = function (event) { - var self = this - if (self.destroyed) return - self._debug('on track') - self.emit('stream', event.streams[0]) -} - -Peer.prototype._onError = function (err) { - var self = this - if (self.destroyed) return - self._debug('error %s', err.message || err) - self._destroy(err) -} - -Peer.prototype._debug = function () { - var self = this - var args = [].slice.call(arguments) - var id = self.channelName && self.channelName.substring(0, 7) - args[0] = '[' + id + '] ' + args[0] - debug.apply(null, args) -} - -function noop () {} - -}).call(this,require("buffer").Buffer) -},{"buffer":5,"debug":56,"get-browser-rtc":63,"inherits":65,"randombytes":90,"readable-stream":98}],108:[function(require,module,exports){ -var Rusha = require('rusha') - -var rusha = new Rusha -var crypto = window.crypto || window.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) { - // Use Rusha - setTimeout(cb, 0, 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 (error) { - 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":103}],109:[function(require,module,exports){ -(function (process,Buffer){ -/* global WebSocket */ - -module.exports = Socket - -var debug = require('debug')('simple-websocket') -var inherits = require('inherits') -var stream = require('readable-stream') -var ws = require('ws') // websockets in node - will be empty object in browser - -var _WebSocket = typeof WebSocket !== 'undefined' ? WebSocket : ws - -inherits(Socket, stream.Duplex) - -/** - * WebSocket. Same API as node core `net.Socket`. Duplex stream. - * @param {string} url websocket server url - * @param {Object} opts options to stream.Duplex - */ -function Socket (url, opts) { - var self = this - if (!(self instanceof Socket)) return new Socket(url, opts) - if (!opts) opts = {} - debug('new websocket: %s %o', url, opts) - - opts.allowHalfOpen = false - if (opts.highWaterMark == null) opts.highWaterMark = 1024 * 1024 - - stream.Duplex.call(self, opts) - - self.url = url - self.connected = false - self.destroyed = false - - self._maxBufferedAmount = opts.highWaterMark - self._chunk = null - self._cb = null - self._interval = null - - try { - if (typeof WebSocket === 'undefined') { - // `ws` package accepts options - self._ws = new _WebSocket(self.url, opts) - } else { - self._ws = new _WebSocket(self.url) - } - } catch (err) { - process.nextTick(function () { - self._onError(err) - }) - return - } - self._ws.binaryType = 'arraybuffer' - self._ws.onopen = function () { - self._onOpen() - } - self._ws.onmessage = function (event) { - self._onMessage(event) - } - self._ws.onclose = function () { - self._onClose() - } - self._ws.onerror = function () { - self._onError(new Error('connection error to ' + self.url)) - } - - self.on('finish', function () { - if (self.connected) { - // When stream is finished writing, close socket connection. Half open connections - // are currently not supported. - // Wait a bit before destroying so the socket flushes. - // TODO: is there a more reliable way to accomplish this? - setTimeout(function () { - self._destroy() - }, 100) - } else { - // If socket is not connected when stream is finished writing, wait until data is - // flushed to network at "connect" event. - // TODO: is there a more reliable way to accomplish this? - self.once('connect', function () { - setTimeout(function () { - self._destroy() - }, 100) - }) - } - }) -} - -Socket.WEBSOCKET_SUPPORT = !!_WebSocket - -/** - * Send text/binary data to the WebSocket server. - * @param {TypedArrayView|ArrayBuffer|Buffer|string|Blob|Object} chunk - */ -Socket.prototype.send = function (chunk) { - var self = this - - var len = chunk.length || chunk.byteLength || chunk.size - self._ws.send(chunk) - debug('write: %d bytes', len) -} - -Socket.prototype.destroy = function (onclose) { - var self = this - self._destroy(null, onclose) -} - -Socket.prototype._destroy = function (err, onclose) { - var self = this - if (self.destroyed) return - if (onclose) self.once('close', onclose) - - debug('destroy (error: %s)', err && err.message) - - this.readable = this.writable = false - - if (!self._readableState.ended) self.push(null) - if (!self._writableState.finished) self.end() - - self.connected = false - self.destroyed = true - - clearInterval(self._interval) - self._interval = null - self._chunk = null - self._cb = null - - if (self._ws) { - var ws = self._ws - var onClose = function () { - ws.onclose = null - self.emit('close') - } - if (ws.readyState === _WebSocket.CLOSED) { - onClose() - } else { - try { - ws.onclose = onClose - ws.close() - } catch (err) { - onClose() - } - } - - ws.onopen = null - ws.onmessage = null - ws.onerror = null - } - self._ws = null - - if (err) self.emit('error', err) -} - -Socket.prototype._read = function () {} - -Socket.prototype._write = function (chunk, encoding, cb) { - var self = this - if (self.destroyed) return cb(new Error('cannot write after socket is destroyed')) - - if (self.connected) { - try { - self.send(chunk) - } catch (err) { - return self._onError(err) - } - if (typeof ws !== 'function' && self._ws.bufferedAmount > self._maxBufferedAmount) { - debug('start backpressure: bufferedAmount %d', self._ws.bufferedAmount) - self._cb = cb - } else { - cb(null) - } - } else { - debug('write before connect') - self._chunk = chunk - self._cb = cb - } -} - -Socket.prototype._onMessage = function (event) { - var self = this - if (self.destroyed) return - var data = event.data - debug('read: %d bytes', data.byteLength || data.length) - - if (data instanceof ArrayBuffer) data = new Buffer(data) - self.push(data) -} - -Socket.prototype._onOpen = function () { - var self = this - if (self.connected || self.destroyed) return - self.connected = true - - if (self._chunk) { - try { - self.send(self._chunk) - } catch (err) { - return self._onError(err) - } - self._chunk = null - debug('sent chunk from "write before connect"') - - var cb = self._cb - self._cb = null - cb(null) - } - - // No backpressure in node. The `ws` module has a buggy `bufferedAmount` property. - // See: https://github.com/websockets/ws/issues/492 - if (typeof ws !== 'function') { - self._interval = setInterval(function () { - if (!self._cb || !self._ws || self._ws.bufferedAmount > self._maxBufferedAmount) { - return - } - debug('ending backpressure: bufferedAmount %d', self._ws.bufferedAmount) - var cb = self._cb - self._cb = null - cb(null) - }, 150) - if (self._interval.unref) self._interval.unref() - } - - debug('connect') - self.emit('connect') -} - -Socket.prototype._onClose = function () { - var self = this - if (self.destroyed) return - debug('on close') - self._destroy() -} - -Socket.prototype._onError = function (err) { - var self = this - if (self.destroyed) return - debug('error: %s', err.message || err) - self._destroy(err) -} - -}).call(this,require('_process'),require("buffer").Buffer) -},{"_process":16,"buffer":5,"debug":56,"inherits":65,"readable-stream":98,"ws":2}],110:[function(require,module,exports){ -var tick = 1 -var maxTick = 65535 -var resolution = 4 -var inc = function () { - tick = (tick + 1) & maxTick -} - -var timer = setInterval(inc, (1000 / resolution) | 0) -if (timer.unref) timer.unref() - -module.exports = function (seconds) { - 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 - } -} - -},{}],111:[function(require,module,exports){ -/* global URL */ - -var getBlob = require('stream-to-blob') - -module.exports = function getBlobURL (stream, mimeType, cb) { - if (typeof mimeType === 'function') return getBlobURL(stream, null, mimeType) - getBlob(stream, mimeType, function (err, blob) { - if (err) return cb(err) - var url = URL.createObjectURL(blob) - cb(null, url) - }) -} - -},{"stream-to-blob":112}],112:[function(require,module,exports){ -/* global Blob */ - -var once = require('once') - -module.exports = function getBlob (stream, mimeType, cb) { - if (typeof mimeType === 'function') return getBlob(stream, null, mimeType) - cb = once(cb) - var chunks = [] - stream - .on('data', function (chunk) { - chunks.push(chunk) - }) - .on('end', function () { - var blob = mimeType - ? new Blob(chunks, { type: mimeType }) - : new Blob(chunks) - cb(null, blob) - }) - .on('error', cb) -} - -},{"once":83}],113:[function(require,module,exports){ -(function (Buffer){ -var once = require('once') - -module.exports = function getBuffer (stream, length, cb) { - cb = once(cb) - var buf = new Buffer(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,require("buffer").Buffer) -},{"buffer":5,"once":83}],114:[function(require,module,exports){ -arguments[4][32][0].apply(exports,arguments) -},{"buffer":5,"dup":32}],115:[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":116}],116:[function(require,module,exports){ -(function (Buffer){ -/* -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,require("buffer").Buffer) -},{"buffer":5}],117:[function(require,module,exports){ -arguments[4][33][0].apply(exports,arguments) -},{"buffer":5,"dup":33}],118:[function(require,module,exports){ -(function (process){ -module.exports = Discovery - -var debug = require('debug')('torrent-discovery') -var DHT = require('bittorrent-dht/client') // empty object in browser -var EventEmitter = require('events').EventEmitter -var extend = require('xtend') -var inherits = require('inherits') -var parallel = require('run-parallel') -var Tracker = require('bittorrent-tracker/client') - -inherits(Discovery, EventEmitter) - -function Discovery (opts) { - var self = this - if (!(self instanceof Discovery)) return new Discovery(opts) - EventEmitter.call(self) - - 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') - - self.peerId = typeof opts.peerId === 'string' - ? opts.peerId - : opts.peerId.toString('hex') - self.infoHash = typeof opts.infoHash === 'string' - ? opts.infoHash - : opts.infoHash.toString('hex') - self._port = opts.port // torrent port - - self.destroyed = false - - self._announce = opts.announce || [] - self._intervalMs = opts.intervalMs || (15 * 60 * 1000) - self._trackerOpts = null - self._dhtAnnouncing = false - self._dhtTimeout = false - self._internalDHT = false // is the DHT created internally? - - self._onWarning = function (err) { - self.emit('warning', err) - } - self._onError = function (err) { - self.emit('error', err) - } - self._onDHTPeer = function (peer, infoHash) { - if (infoHash.toString('hex') !== self.infoHash) return - self.emit('peer', peer.host + ':' + peer.port) - } - self._onTrackerPeer = function (peer) { - self.emit('peer', peer) - } - self._onTrackerAnnounce = function () { - self.emit('trackerAnnounce') - } - - if (opts.tracker === false) { - self.tracker = null - } else if (opts.tracker && typeof opts.tracker === 'object') { - self._trackerOpts = extend(opts.tracker) - self.tracker = self._createTracker() - } else { - self.tracker = self._createTracker() - } - - if (opts.dht === false || typeof DHT !== 'function') { - self.dht = null - } else if (opts.dht && typeof opts.dht.addNode === 'function') { - self.dht = opts.dht - } else if (opts.dht && typeof opts.dht === 'object') { - self.dht = createDHT(opts.dhtPort, opts.dht) - } else { - self.dht = createDHT(opts.dhtPort) - } - - if (self.dht) { - self.dht.on('peer', self._onDHTPeer) - self._dhtAnnounce() - } - - function createDHT (port, opts) { - var dht = new DHT(opts) - dht.on('warning', self._onWarning) - dht.on('error', self._onError) - dht.listen(port) - self._internalDHT = true - return dht - } -} - -Discovery.prototype.updatePort = function (port) { - var self = this - if (port === self._port) return - self._port = port - - if (self.dht) self._dhtAnnounce() - - if (self.tracker) { - self.tracker.stop() - self.tracker.destroy(function () { - self.tracker = self._createTracker() - }) - } -} - -Discovery.prototype.complete = function (opts) { - if (this.tracker) { - this.tracker.complete(opts) - } -} - -Discovery.prototype.destroy = function (cb) { - var self = this - if (self.destroyed) return - self.destroyed = true - - clearTimeout(self._dhtTimeout) - - var tasks = [] - - if (self.tracker) { - self.tracker.stop() - self.tracker.removeListener('warning', self._onWarning) - self.tracker.removeListener('error', self._onError) - self.tracker.removeListener('peer', self._onTrackerPeer) - self.tracker.removeListener('update', self._onTrackerAnnounce) - tasks.push(function (cb) { - self.tracker.destroy(cb) - }) - } - - if (self.dht) { - self.dht.removeListener('peer', self._onDHTPeer) - } - - if (self._internalDHT) { - self.dht.removeListener('warning', self._onWarning) - self.dht.removeListener('error', self._onError) - tasks.push(function (cb) { - self.dht.destroy(cb) - }) - } - - parallel(tasks, cb) - - // cleanup - self.dht = null - self.tracker = null - self._announce = null -} - -Discovery.prototype._createTracker = function () { - var opts = extend(this._trackerOpts, { - infoHash: this.infoHash, - announce: this._announce, - peerId: this.peerId, - port: this._port - }) - - var 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 -} - -Discovery.prototype._dhtAnnounce = function () { - var self = this - if (self._dhtAnnouncing) return - debug('dht announce') - - self._dhtAnnouncing = true - clearTimeout(self._dhtTimeout) - - self.dht.announce(self.infoHash, self._port, function (err) { - self._dhtAnnouncing = false - debug('dht announce complete') - - if (err) self.emit('warning', err) - self.emit('dhtAnnounce') - - if (!self.destroyed) { - self._dhtTimeout = setTimeout(function () { - self._dhtAnnounce() - }, getRandomTimeout()) - if (self._dhtTimeout.unref) self._dhtTimeout.unref() - } - }) - - // Returns timeout interval, with some random jitter - function getRandomTimeout () { - return self._intervalMs + Math.floor(Math.random() * self._intervalMs / 5) - } -} - -}).call(this,require('_process')) -},{"_process":16,"bittorrent-dht/client":2,"bittorrent-tracker/client":45,"debug":56,"events":8,"inherits":65,"run-parallel":102,"xtend":137}],119:[function(require,module,exports){ -(function (Buffer){ -module.exports = Piece - -var BLOCK_LENGTH = 1 << 14 - -function Piece (length) { - if (!(this instanceof Piece)) return new Piece(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 -} - -Piece.BLOCK_LENGTH = BLOCK_LENGTH - -Piece.prototype.chunkLength = function (i) { - return i === this._chunks - 1 ? this._remainder : BLOCK_LENGTH -} - -Piece.prototype.chunkLengthRemaining = function (i) { - return this.length - (i * BLOCK_LENGTH) -} - -Piece.prototype.chunkOffset = function (i) { - return i * BLOCK_LENGTH -} - -Piece.prototype.reserve = function () { - if (!this.init()) return -1 - if (this._cancellations.length) return this._cancellations.pop() - if (this._reservations < this._chunks) return this._reservations++ - return -1 -} - -Piece.prototype.reserveRemaining = function () { - if (!this.init()) return -1 - if (this._reservations < this._chunks) { - var min = this._reservations - this._reservations = this._chunks - return min - } - return -1 -} - -Piece.prototype.cancel = function (i) { - if (!this.init()) return - this._cancellations.push(i) -} - -Piece.prototype.cancelRemaining = function (i) { - if (!this.init()) return - this._reservations = i -} - -Piece.prototype.get = function (i) { - if (!this.init()) return null - return this._buffer[i] -} - -Piece.prototype.set = function (i, data, source) { - if (!this.init()) return false - var len = data.length - var blocks = Math.ceil(len / BLOCK_LENGTH) - for (var j = 0; j < blocks; j++) { - if (!this._buffer[i + j]) { - var offset = j * BLOCK_LENGTH - var splitData = data.slice(offset, offset + BLOCK_LENGTH) - this._buffered++ - this._buffer[i + j] = splitData - this.missing -= splitData.length - if (this.sources.indexOf(source) === -1) { - this.sources.push(source) - } - } - } - return this._buffered === this._chunks -} - -Piece.prototype.flush = function () { - if (!this._buffer || this._chunks !== this._buffered) return null - var buffer = Buffer.concat(this._buffer, this.length) - this._buffer = null - this._cancellations = null - this.sources = null - this._flushed = true - return buffer -} - -Piece.prototype.init = function () { - if (this._flushed) return false - if (this._buffer) return true - this._buffer = new Array(this._chunks) - this._cancellations = [] - this.sources = [] - return true -} - -}).call(this,require("buffer").Buffer) -},{"buffer":5}],120:[function(require,module,exports){ -(function (Buffer){ -/** - * 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 = new Buffer(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 the `Buffer` constructor - return new Buffer(arr) - } -} - -}).call(this,require("buffer").Buffer) -},{"buffer":5,"is-typedarray":68}],121:[function(require,module,exports){ -(function (Buffer){ -var UINT_32_MAX = 0xffffffff - -exports.encodingLength = function () { - return 8 -} - -exports.encode = function (num, buf, offset) { - if (!buf) buf = new Buffer(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 - - if (!buf) buf = new Buffer(4) - 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 - -}).call(this,require("buffer").Buffer) -},{"buffer":5}],122:[function(require,module,exports){ -"use strict" - -function unique_pred(list, compare) { - var ptr = 1 - , len = list.length - , a=list[0], b=list[0] - for(var i=1; i= arr.length || i < 0) return - var last = arr.pop() - if (i < arr.length) { - var tmp = arr[i] - arr[i] = last - return tmp - } - return last -} - -},{}],124:[function(require,module,exports){ -var bencode = require('bencode') -var BitField = require('bitfield') -var Buffer = require('safe-buffer').Buffer -var debug = require('debug')('ut_metadata') -var EventEmitter = require('events').EventEmitter -var inherits = require('inherits') -var sha1 = require('simple-sha1') - -var MAX_METADATA_SIZE = 10000000 // 10MB -var BITFIELD_GROW = 1000 -var PIECE_LENGTH = 16 * 1024 - -module.exports = function (metadata) { - inherits(utMetadata, EventEmitter) - - function utMetadata (wire) { - EventEmitter.call(this) - - this._wire = wire - - this._metadataComplete = false - this._metadataSize = null - this._remainingRejects = null // how many reject messages to tolerate before quitting - this._fetching = false - - // 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) - } - } - - // Name of the bittorrent-protocol extension - utMetadata.prototype.name = 'ut_metadata' - - utMetadata.prototype.onHandshake = function (infoHash, peerId, extensions) { - this._infoHash = infoHash - } - - utMetadata.prototype.onExtendedHandshake = function (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 - - if (this._fetching) { - this._requestPieces() - } - } - - utMetadata.prototype.onMessage = function (buf) { - var dict, trailer - try { - var str = buf.toString() - var 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 - */ - utMetadata.prototype.fetch = function () { - if (this._metadataComplete) { - return - } - this._fetching = true - if (this._metadataSize) { - this._requestPieces() - } - } - - /** - * Stop asking the peer to send metadata. - * @public - */ - utMetadata.prototype.cancel = function () { - this._fetching = false - } - - utMetadata.prototype.setMetadata = function (metadata) { - if (this._metadataComplete) return true - debug('set metadata') - - // if full torrent dictionary was passed in, pull out just `info` key - try { - var 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 - } - - utMetadata.prototype._send = function (dict, trailer) { - var buf = bencode.encode(dict) - if (Buffer.isBuffer(trailer)) { - buf = Buffer.concat([buf, trailer]) - } - this._wire.extended('ut_metadata', buf) - } - - utMetadata.prototype._request = function (piece) { - this._send({ msg_type: 0, piece: piece }) - } - - utMetadata.prototype._data = function (piece, buf, totalSize) { - var msg = { msg_type: 1, piece: piece } - if (typeof totalSize === 'number') { - msg.total_size = totalSize - } - this._send(msg, buf) - } - - utMetadata.prototype._reject = function (piece) { - this._send({ msg_type: 2, piece: piece }) - } - - utMetadata.prototype._onRequest = function (piece) { - if (!this._metadataComplete) { - this._reject(piece) - return - } - var start = piece * PIECE_LENGTH - var end = start + PIECE_LENGTH - if (end > this._metadataSize) { - end = this._metadataSize - } - var buf = this.metadata.slice(start, end) - this._data(piece, buf, this._metadataSize) - } - - utMetadata.prototype._onData = function (piece, buf, totalSize) { - if (buf.length > PIECE_LENGTH) { - return - } - buf.copy(this.metadata, piece * PIECE_LENGTH) - this._bitfield.set(piece) - this._checkDone() - } - - utMetadata.prototype._onReject = function (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')) - } - } - - utMetadata.prototype._requestPieces = function () { - this.metadata = Buffer.alloc(this._metadataSize) - for (var piece = 0; piece < this._numPieces; piece++) { - this._request(piece) - } - } - - utMetadata.prototype._checkDone = function () { - var done = true - for (var 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 - var success = this.setMetadata(this.metadata) - - if (!success) { - this._failedMetadata() - } - } - - utMetadata.prototype._failedMetadata = function () { - // 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')) - } - } - - return utMetadata -} - -},{"bencode":41,"bitfield":43,"debug":56,"events":8,"inherits":65,"safe-buffer":104,"simple-sha1":108}],125:[function(require,module,exports){ -arguments[4][36][0].apply(exports,arguments) -},{"dup":36}],126:[function(require,module,exports){ -(function (Buffer){ -var bs = require('binary-search') -var EventEmitter = require('events').EventEmitter -var inherits = require('inherits') -var mp4 = require('mp4-stream') -var Box = require('mp4-box-encoding') -var RangeSliceStream = require('range-slice-stream') - -module.exports = MP4Remuxer - -function MP4Remuxer (file) { - var self = this - EventEmitter.call(self) - self._tracks = [] - self._fragmentSequence = 1 - self._file = file - self._decoder = null - self._findMoov(0) -} - -inherits(MP4Remuxer, EventEmitter) - -MP4Remuxer.prototype._findMoov = function (offset) { - var self = this - - if (self._decoder) { - self._decoder.destroy() - } - - self._decoder = mp4.decode() - var fileStream = self._file.createReadStream({ - start: offset - }) - fileStream.pipe(self._decoder) - - self._decoder.once('box', function (headers) { - if (headers.type === 'moov') { - self._decoder.decode(function (moov) { - fileStream.destroy() - try { - self._processMoov(moov) - } catch (err) { - err.message = 'Cannot parse mp4 file: ' + err.message - self.emit('error', err) - } - }) - } else { - fileStream.destroy() - self._findMoov(offset + headers.length) - } - }) -} - -function RunLengthIndex (entries, countName) { - var self = this - self._entries = entries - self._countName = countName || 'count' - self._index = 0 - self._offset = 0 - - self.value = self._entries[0] -} - -RunLengthIndex.prototype.inc = function () { - var self = this - self._offset++ - if (self._offset >= self._entries[self._index][self._countName]) { - self._index++ - self._offset = 0 - } - - self.value = self._entries[self._index] -} - -MP4Remuxer.prototype._processMoov = function (moov) { - var self = this - - var traks = moov.traks - self._tracks = [] - self._hasVideo = false - self._hasAudio = false - for (var i = 0; i < traks.length; i++) { - var trak = traks[i] - var stbl = trak.mdia.minf.stbl - var stsdEntry = stbl.stsd.entries[0] - var handlerType = trak.mdia.hdlr.handlerType - var codec - var mime - if (handlerType === 'vide' && stsdEntry.type === 'avc1') { - if (self._hasVideo) { - continue - } - self._hasVideo = true - codec = 'avc1' - if (stsdEntry.avcC) { - codec += '.' + stsdEntry.avcC.mimeCodec - } - mime = 'video/mp4; codecs="' + codec + '"' - } else if (handlerType === 'soun' && stsdEntry.type === 'mp4a') { - if (self._hasAudio) { - continue - } - self._hasAudio = true - codec = 'mp4a' - if (stsdEntry.esds && stsdEntry.esds.mimeCodec) { - codec += '.' + stsdEntry.esds.mimeCodec - } - mime = 'audio/mp4; codecs="' + codec + '"' - } else { - continue - } - - var samples = [] - var sample = 0 - - // Chunk/position data - var sampleInChunk = 0 - var chunk = 0 - var offsetInChunk = 0 - var sampleToChunkIndex = 0 - - // Time data - var dts = 0 - var decodingTimeEntry = new RunLengthIndex(stbl.stts.entries) - var presentationOffsetEntry = null - if (stbl.ctts) { - presentationOffsetEntry = new RunLengthIndex(stbl.ctts.entries) - } - - // Sync table index - var syncSampleIndex = 0 - - while (true) { - var currChunkEntry = stbl.stsc.entries[sampleToChunkIndex] - - // Compute size - var size = stbl.stsz.entries[sample] - - // Compute time data - var duration = decodingTimeEntry.value.duration - var presentationOffset = presentationOffsetEntry ? presentationOffsetEntry.value.compositionOffset : 0 - - // Compute sync - var sync = true - if (stbl.stss) { - sync = stbl.stss.entries[syncSampleIndex] === sample + 1 - } - - // Create new sample entry - samples.push({ - size: size, - duration: duration, - dts: dts, - presentationOffset: presentationOffset, - sync: sync, - offset: offsetInChunk + stbl.stco.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 - var 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 - - var defaultSampleDescriptionIndex = currChunkEntry.sampleDescriptionId - - var 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: defaultSampleDescriptionIndex, - defaultSampleDuration: 0, - defaultSampleSize: 0, - defaultSampleFlags: 0 - }] - } - } - - self._tracks.push({ - trackId: trak.tkhd.trackId, - timeScale: trak.mdia.mdhd.timeScale, - samples: samples, - currSample: null, - currTime: null, - moov: trackMoov, - mime: mime - }) - } - - if (self._tracks.length === 0) { - self.emit('error', new Error('no playable tracks')) - return - } - - // Must be set last since this is used above - moov.mvhd.duration = 0 - - self._ftyp = { - type: 'ftyp', - brand: 'iso5', - brandVersion: 0, - compatibleBrands: [ - 'iso5' - ] - } - - var ftypBuf = Box.encode(self._ftyp) - var data = self._tracks.map(function (track) { - var moovBuf = Box.encode(track.moov) - return { - mime: track.mime, - init: Buffer.concat([ftypBuf, moovBuf]) - } - }) - - self.emit('ready', data) -} - -function empty () { - return { - version: 0, - flags: 0, - entries: [] - } -} - -MP4Remuxer.prototype.seek = function (time) { - var self = this - if (!self._tracks) { - throw new Error('Not ready yet; wait for \'ready\' event') - } - - if (self._fileStream) { - self._fileStream.destroy() - self._fileStream = null - } - - var startOffset = -1 - self._tracks.map(function (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 - } - var outStream = track.outStream = mp4.encode() - var fragment = self._generateFragment(i, time) - if (!fragment) { - return outStream.finalize() - } - - if (startOffset === -1 || fragment.ranges[0].start < startOffset) { - startOffset = fragment.ranges[0].start - } - - writeFragment(fragment) - - function writeFragment (frag) { - if (outStream.destroyed) return - outStream.box(frag.moof, function (err) { - if (err) return self.emit('error', err) - if (outStream.destroyed) return - var slicedStream = track.inStream.slice(frag.ranges) - slicedStream.pipe(outStream.mediaData(frag.length, function (err) { - if (err) return self.emit('error', err) - if (outStream.destroyed) return - var nextFrag = self._generateFragment(i) - if (!nextFrag) { - return outStream.finalize() - } - writeFragment(nextFrag) - })) - }) - } - }) - - if (startOffset >= 0) { - var fileStream = self._fileStream = self._file.createReadStream({ - start: startOffset - }) - - self._tracks.forEach(function (track) { - track.inStream = new RangeSliceStream(startOffset) - fileStream.pipe(track.inStream) - }) - } - - return self._tracks.map(function (track) { - return track.outStream - }) -} - -MP4Remuxer.prototype._findSampleBefore = function (trackInd, time) { - var self = this - - var track = self._tracks[trackInd] - var scaledTime = Math.floor(track.timeScale * time) - var sample = bs(track.samples, scaledTime, function (sample, t) { - var 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 -} - -var MIN_FRAGMENT_DURATION = 1 // second - -MP4Remuxer.prototype._generateFragment = function (track, time) { - var self = this - /* - 1. Find correct sample - 2. Process backward until sync sample found - 3. Process forward until next sync sample after MIN_FRAGMENT_DURATION found - */ - var currTrack = self._tracks[track] - var firstSample - if (time !== undefined) { - firstSample = self._findSampleBefore(track, time) - } else { - firstSample = currTrack.currSample - } - - if (firstSample >= currTrack.samples.length) - return null - - var startDts = currTrack.samples[firstSample].dts - - var totalLen = 0 - var ranges = [] - for (var currSample = firstSample; currSample < currTrack.samples.length; currSample++) { - var 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 - var 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: self._generateMoof(track, firstSample, currSample), - ranges: ranges, - length: totalLen - } -} - -MP4Remuxer.prototype._generateMoof = function (track, firstSample, lastSample) { - var self = this - - var currTrack = self._tracks[track] - - var entries = [] - for (var j = firstSample; j < lastSample; j++) { - var currSample = currTrack.samples[j] - entries.push({ - sampleDuration: currSample.duration, - sampleSize: currSample.size, - sampleFlags: currSample.sync ? 0x2000000 : 0x1010000, - sampleCompositionTimeOffset: currSample.presentationOffset - }) - } - - var moof = { - type: 'moof', - mfhd: { - sequenceNumber: self._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: entries - } - }] - } - - // Update the offset - moof.trafs[0].trun.dataOffset += Box.encodingLength(moof) - - return moof -} - -}).call(this,require("buffer").Buffer) -},{"binary-search":42,"buffer":5,"events":8,"inherits":65,"mp4-box-encoding":76,"mp4-stream":79,"range-slice-stream":91}],127:[function(require,module,exports){ -var MediaElementWrapper = require('mediasource') -var pump = require('pump') - -var MP4Remuxer = require('./mp4-remuxer') - -module.exports = VideoStream - -function VideoStream (file, mediaElem, opts) { - var self = this - if (!(this instanceof VideoStream)) return new VideoStream(file, mediaElem, opts) - opts = opts || {} - - self.detailedError = null - - self._elem = mediaElem - self._elemWrapper = new MediaElementWrapper(mediaElem) - self._waitingFired = false - self._trackMeta = null - self._file = file - self._tracks = null - if (self._elem.preload !== 'none') { - self._createMuxer() - } - - self._onError = function (err) { - self.detailedError = self._elemWrapper.detailedError - self.destroy() // don't pass err though so the user doesn't need to listen for errors - } - self._onWaiting = function () { - self._waitingFired = true - if (!self._muxer) { - self._createMuxer() - } else if (self._tracks) { - self._pump() - } - } - self._elem.addEventListener('waiting', self._onWaiting) - self._elem.addEventListener('error', self._onError) -} - -VideoStream.prototype._createMuxer = function () { - var self = this - self._muxer = new MP4Remuxer(self._file) - self._muxer.on('ready', function (data) { - self._tracks = data.map(function (trackData) { - var mediaSource = self._elemWrapper.createWriteStream(trackData.mime) - mediaSource.on('error', function (err) { - self._elemWrapper.error(err) - }) - var track = { - muxed: null, - mediaSource: mediaSource, - initFlushed: false, - onInitFlushed: null - } - mediaSource.write(trackData.init, function (err) { - track.initFlushed = true - if (track.onInitFlushed) { - track.onInitFlushed(err) - } - }) - return track - }) - - if (self._waitingFired || self._elem.preload === 'auto') { - self._pump() - } - }) - - self._muxer.on('error', function (err) { - self._elemWrapper.error(err) - }) -} - -VideoStream.prototype._pump = function () { - var self = this - - var muxed = self._muxer.seek(self._elem.currentTime, !self._tracks) - - self._tracks.forEach(function (track, i) { - var pumpTrack = function () { - if (track.muxed) { - track.muxed.destroy() - track.mediaSource = self._elemWrapper.createWriteStream(track.mediaSource) - track.mediaSource.on('error', function (err) { - self._elemWrapper.error(err) - }) - } - track.muxed = muxed[i] - pump(track.muxed, track.mediaSource) - } - if (!track.initFlushed) { - track.onInitFlushed = function (err) { - if (err) { - self._elemWrapper.error(err) - return - } - pumpTrack() - } - } else { - pumpTrack() - } - }) -} - -VideoStream.prototype.destroy = function () { - var self = this - if (self.destroyed) { - return - } - self.destroyed = true - - self._elem.removeEventListener('waiting', self._onWaiting) - self._elem.removeEventListener('error', self._onError) - - if (self._tracks) { - self._tracks.forEach(function (track) { - track.muxed.destroy() - }) - } - - self._elem.src = '' -} - -},{"./mp4-remuxer":126,"mediasource":72,"pump":88}],128:[function(require,module,exports){ -(function (process,global){ -/* global FileList */ - -module.exports = WebTorrent - -var Buffer = require('safe-buffer').Buffer -var concat = require('simple-concat') -var createTorrent = require('create-torrent') -var debug = require('debug')('webtorrent') -var DHT = require('bittorrent-dht/client') // browser exclude -var EventEmitter = require('events').EventEmitter -var extend = require('xtend') -var inherits = require('inherits') -var loadIPSet = require('load-ip-set') // browser exclude -var parallel = require('run-parallel') -var parseTorrent = require('parse-torrent') -var path = require('path') -var Peer = require('simple-peer') -var randombytes = require('randombytes') -var speedometer = require('speedometer') -var zeroFill = require('zero-fill') - -var TCPPool = require('./lib/tcp-pool') // browser exclude -var Torrent = require('./lib/torrent') - -/** - * WebTorrent version. - */ -var 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' - */ -var VERSION_STR = VERSION.match(/([0-9]+)/g) - .slice(0, 2) - .map(function (v) { return zeroFill(2, v) }) - .join('') - -/** - * 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-'... - */ -var VERSION_PREFIX = '-WW' + VERSION_STR + '-' - -inherits(WebTorrent, EventEmitter) - -/** - * WebTorrent Client - * @param {Object=} opts - */ -function WebTorrent (opts) { - var self = this - if (!(self instanceof WebTorrent)) return new WebTorrent(opts) - EventEmitter.call(self) - - if (!opts) opts = {} - - if (typeof opts.peerId === 'string') { - self.peerId = opts.peerId - } else if (Buffer.isBuffer(opts.peerId)) { - self.peerId = opts.peerId.toString('hex') - } else { - self.peerId = Buffer.from(VERSION_PREFIX + randombytes(9).toString('base64')).toString('hex') - } - self.peerIdBuffer = Buffer.from(self.peerId, 'hex') - - if (typeof opts.nodeId === 'string') { - self.nodeId = opts.nodeId - } else if (Buffer.isBuffer(opts.nodeId)) { - self.nodeId = opts.nodeId.toString('hex') - } else { - self.nodeId = randombytes(20).toString('hex') - } - self.nodeIdBuffer = Buffer.from(self.nodeId, 'hex') - - self.destroyed = false - self.listening = false - self.torrentPort = opts.torrentPort || 0 - self.dhtPort = opts.dhtPort || 0 - self.tracker = opts.tracker !== undefined ? opts.tracker : {} - self.torrents = [] - self.maxConns = Number(opts.maxConns) || 55 - - debug( - 'new webtorrent (peerId %s, nodeId %s, port %s)', - self.peerId, self.nodeId, self.torrentPort - ) - - if (self.tracker) { - if (typeof self.tracker !== 'object') self.tracker = {} - if (opts.rtcConfig) { - // TODO: remove in v1 - console.warn('WebTorrent: opts.rtcConfig is deprecated. Use opts.tracker.rtcConfig instead') - self.tracker.rtcConfig = opts.rtcConfig - } - if (opts.wrtc) { - // TODO: remove in v1 - console.warn('WebTorrent: opts.wrtc is deprecated. Use opts.tracker.wrtc instead') - self.tracker.wrtc = opts.wrtc - } - if (global.WRTC && !self.tracker.wrtc) { - self.tracker.wrtc = global.WRTC - } - } - - if (typeof TCPPool === 'function') { - self._tcpPool = new TCPPool(self) - } else { - process.nextTick(function () { - self._onListening() - }) - } - - // stats - self._downloadSpeed = speedometer() - self._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 - self.dht = new DHT(extend({ nodeId: self.nodeId }, opts.dht)) - - self.dht.once('error', function (err) { - self._destroy(err) - }) - - self.dht.once('listening', function () { - var address = self.dht.address() - if (address) self.dhtPort = address.port - }) - - // Ignore warning when there are > 10 torrents in the client - self.dht.setMaxListeners(0) - - self.dht.listen(self.dhtPort) - } else { - self.dht = false - } - - // Enable or disable BEP19 (Web Seeds). Enabled by default: - self.enableWebSeeds = opts.webSeeds !== false - - if (typeof loadIPSet === 'function' && opts.blocklist != null) { - loadIPSet(opts.blocklist, { - headers: { - 'user-agent': 'WebTorrent/' + VERSION + ' (https://webtorrent.io)' - } - }, function (err, ipSet) { - if (err) return self.error('Failed to load blocklist: ' + err.message) - self.blocked = ipSet - ready() - }) - } else { - process.nextTick(ready) - } - - function ready () { - if (self.destroyed) return - self.ready = true - self.emit('ready') - } -} - -WebTorrent.WEBRTC_SUPPORT = Peer.WEBRTC_SUPPORT - -Object.defineProperty(WebTorrent.prototype, 'downloadSpeed', { - get: function () { return this._downloadSpeed() } -}) - -Object.defineProperty(WebTorrent.prototype, 'uploadSpeed', { - get: function () { return this._uploadSpeed() } -}) - -Object.defineProperty(WebTorrent.prototype, 'progress', { - get: function () { - var torrents = this.torrents.filter(function (torrent) { - return torrent.progress !== 1 - }) - var downloaded = torrents.reduce(function (total, torrent) { - return total + torrent.downloaded - }, 0) - var length = torrents.reduce(function (total, torrent) { - return total + (torrent.length || 0) - }, 0) || 1 - return downloaded / length - } -}) - -Object.defineProperty(WebTorrent.prototype, 'ratio', { - get: function () { - var uploaded = this.torrents.reduce(function (total, torrent) { - return total + torrent.uploaded - }, 0) - var received = this.torrents.reduce(function (total, torrent) { - return 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} - */ -WebTorrent.prototype.get = function (torrentId) { - var self = this - var i, torrent - var len = self.torrents.length - - if (torrentId instanceof Torrent) { - for (i = 0; i < len; i++) { - torrent = self.torrents[i] - if (torrent === torrentId) return torrent - } - } else { - var parsed - try { parsed = parseTorrent(torrentId) } catch (err) {} - - if (!parsed) return null - if (!parsed.infoHash) throw new Error('Invalid torrent identifier') - - for (i = 0; i < len; i++) { - torrent = self.torrents[i] - if (torrent.infoHash === parsed.infoHash) return torrent - } - } - return null -} - -// TODO: remove in v1 -WebTorrent.prototype.download = function (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) - */ -WebTorrent.prototype.add = function (torrentId, opts, ontorrent) { - var self = this - if (self.destroyed) throw new Error('client is destroyed') - if (typeof opts === 'function') return self.add(torrentId, null, opts) - - debug('add') - opts = opts ? extend(opts) : {} - - var torrent = new Torrent(torrentId, self, opts) - self.torrents.push(torrent) - - torrent.once('_infoHash', onInfoHash) - torrent.once('ready', onReady) - torrent.once('close', onClose) - - function onInfoHash () { - if (self.destroyed) return - for (var i = 0, len = self.torrents.length; i < len; i++) { - var t = self.torrents[i] - if (t.infoHash === torrent.infoHash && t !== torrent) { - torrent._destroy(new Error('Cannot add duplicate torrent ' + torrent.infoHash)) - return - } - } - } - - function onReady () { - if (self.destroyed) return - if (typeof ontorrent === 'function') ontorrent(torrent) - self.emit('torrent', torrent) - } - - function onClose () { - torrent.removeListener('_infoHash', onInfoHash) - torrent.removeListener('ready', onReady) - torrent.removeListener('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 - */ -WebTorrent.prototype.seed = function (input, opts, onseed) { - var self = this - if (self.destroyed) throw new Error('client is destroyed') - if (typeof opts === 'function') return self.seed(input, null, opts) - - debug('seed') - opts = opts ? extend(opts) : {} - - // When seeding from fs path, initialize store from that path to avoid a copy - if (typeof input === 'string') opts.path = path.dirname(input) - if (!opts.createdBy) opts.createdBy = 'WebTorrent/' + VERSION_STR - - var torrent = self.add(null, opts, onTorrent) - var streams - - if (isFileList(input)) input = Array.prototype.slice.call(input) - if (!Array.isArray(input)) input = [ input ] - - parallel(input.map(function (item) { - return function (cb) { - if (isReadable(item)) concat(item, cb) - else cb(null, item) - } - }), function (err, input) { - if (self.destroyed) return - if (err) return torrent._destroy(err) - - createTorrent.parseInput(input, opts, function (err, files) { - if (self.destroyed) return - if (err) return torrent._destroy(err) - - streams = files.map(function (file) { - return file.getStream - }) - - createTorrent(input, opts, function (err, torrentBuf) { - if (self.destroyed) return - if (err) return torrent._destroy(err) - - var existingTorrent = self.get(torrentBuf) - if (existingTorrent) { - torrent._destroy(new Error('Cannot add duplicate torrent ' + existingTorrent.infoHash)) - } else { - torrent._onTorrentId(torrentBuf, opts.forced_id) - } - }) - }) - }) - - function onTorrent (torrent) { - var tasks = [ - function (cb) { - torrent.load(streams, cb) - } - ] - if (self.dht) { - tasks.push(function (cb) { - torrent.once('dhtAnnounce', cb) - }) - } - parallel(tasks, function (err) { - if (self.destroyed) return - if (err) return torrent._destroy(err) - _onseed(torrent) - }) - } - - function _onseed (torrent) { - debug('on seed') - if (typeof onseed === 'function') onseed(torrent) - torrent.emit('seed') - self.emit('seed', torrent) - } - - return torrent -} - -/** - * Remove a torrent from the client. - * @param {string|Buffer|Torrent} torrentId - * @param {function} cb - */ -WebTorrent.prototype.remove = function (torrentId, cb) { - debug('remove') - var torrent = this.get(torrentId) - if (!torrent) throw new Error('No torrent with id ' + torrentId) - this._remove(torrentId, cb) -} - -WebTorrent.prototype._remove = function (torrentId, cb) { - var torrent = this.get(torrentId) - if (!torrent) return - this.torrents.splice(this.torrents.indexOf(torrent), 1) - torrent.destroy(cb) -} - -WebTorrent.prototype.address = function () { - if (!this.listening) return null - return this._tcpPool - ? this._tcpPool.server.address() - : { address: '0.0.0.0', family: 'IPv4', port: 0 } -} - -/** - * Destroy the client, including all torrents and connections to peers. - * @param {function} cb - */ -WebTorrent.prototype.destroy = function (cb) { - if (this.destroyed) throw new Error('client already destroyed') - this._destroy(null, cb) -} - -WebTorrent.prototype._destroy = function (err, cb) { - var self = this - debug('client destroy') - self.destroyed = true - - var tasks = self.torrents.map(function (torrent) { - return function (cb) { - torrent.destroy(cb) - } - }) - - if (self._tcpPool) { - tasks.push(function (cb) { - self._tcpPool.destroy(cb) - }) - } - - if (self.dht) { - tasks.push(function (cb) { - self.dht.destroy(cb) - }) - } - - parallel(tasks, cb) - - if (err) self.emit('error', err) - - self.torrents = [] - self._tcpPool = null - self.dht = null -} - -WebTorrent.prototype._onListening = function () { - this.listening = true - - if (this._tcpPool) { - // Sometimes server.address() returns `null` in Docker. - // WebTorrent issue: https://github.com/feross/bittorrent-swarm/pull/18 - var address = this._tcpPool.server.address() - if (address) this.torrentPort = address.port - } - - this.emit('listening') -} - -/** - * 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 -} - -}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"./lib/tcp-pool":2,"./lib/torrent":133,"./package.json":135,"_process":16,"bittorrent-dht/client":2,"create-torrent":55,"debug":56,"events":8,"inherits":65,"load-ip-set":2,"parse-torrent":85,"path":14,"randombytes":90,"run-parallel":102,"safe-buffer":104,"simple-concat":105,"simple-peer":107,"speedometer":110,"xtend":137,"zero-fill":139}],129:[function(require,module,exports){ -module.exports = FileStream - -var debug = require('debug')('webtorrent:file-stream') -var inherits = require('inherits') -var stream = require('readable-stream') - -inherits(FileStream, stream.Readable) - -/** - * 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) - */ -function FileStream (file, opts) { - stream.Readable.call(this, opts) - - this.destroyed = false - this._torrent = file._torrent - - var start = (opts && opts.start) || 0 - var end = (opts && opts.end && opts.end < file.length) - ? opts.end - : file.length - 1 - - var 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) -} - -FileStream.prototype._read = function () { - if (this._reading) return - this._reading = true - this._notify() -} - -FileStream.prototype._notify = function () { - var self = this - - if (!self._reading || self._missing === 0) return - if (!self._torrent.bitfield.get(self._piece)) { - return self._torrent.critical(self._piece, self._piece + self._criticalLength) - } - - if (self._notifying) return - self._notifying = true - - var p = self._piece - self._torrent.store.get(p, function (err, buffer) { - self._notifying = false - if (self.destroyed) return - if (err) return self._destroy(err) - debug('read %s (length %s) (err %s)', p, buffer.length, err && err.message) - - if (self._offset) { - buffer = buffer.slice(self._offset) - self._offset = 0 - } - - if (self._missing < buffer.length) { - buffer = buffer.slice(0, self._missing) - } - self._missing -= buffer.length - - debug('pushing buffer of length %s', buffer.length) - self._reading = false - self.push(buffer) - - if (self._missing === 0) self.push(null) - }) - self._piece += 1 -} - -FileStream.prototype.destroy = function (onclose) { - this._destroy(null, onclose) -} - -FileStream.prototype._destroy = function (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() -} - -},{"debug":56,"inherits":65,"readable-stream":98}],130:[function(require,module,exports){ -(function (process){ -module.exports = File - -var eos = require('end-of-stream') -var EventEmitter = require('events').EventEmitter -var FileStream = require('./file-stream') -var inherits = require('inherits') -var path = require('path') -var render = require('render-media') -var stream = require('readable-stream') -var streamToBlob = require('stream-to-blob') -var streamToBlobURL = require('stream-to-blob-url') -var streamToBuffer = require('stream-with-known-length-to-buffer') - -inherits(File, EventEmitter) - -function File (torrent, file) { - EventEmitter.call(this) - - 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 - - var start = file.offset - var 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') - } -} - -File.prototype.select = function (priority) { - if (this.length === 0) return - this._torrent.select(this._startPiece, this._endPiece, priority) -} - -File.prototype.deselect = function () { - if (this.length === 0) return - this._torrent.deselect(this._startPiece, this._endPiece, false) -} - -File.prototype.createReadStream = function (opts) { - var self = this - if (this.length === 0) { - var empty = new stream.PassThrough() - process.nextTick(function () { - empty.end() - }) - return empty - } - - var fileStream = new FileStream(self, opts) - self._torrent.select(fileStream._startPiece, fileStream._endPiece, true, function () { - fileStream._notify() - }) - eos(fileStream, function () { - if (self._destroyed) return - if (!self._torrent.destroyed) { - self._torrent.deselect(fileStream._startPiece, fileStream._endPiece, true) - } - }) - return fileStream -} - -File.prototype.getBuffer = function (cb) { - streamToBuffer(this.createReadStream(), this.length, cb) -} - -File.prototype.getBlob = function (cb) { - if (typeof window === 'undefined') throw new Error('browser-only method') - streamToBlob(this.createReadStream(), this._getMimeType(), cb) -} - -File.prototype.getBlobURL = function (cb) { - if (typeof window === 'undefined') throw new Error('browser-only method') - streamToBlobURL(this.createReadStream(), this._getMimeType(), cb) -} - -File.prototype.appendTo = function (elem, opts, cb) { - if (typeof window === 'undefined') throw new Error('browser-only method') - render.append(this, elem, opts, cb) -} - -File.prototype.renderTo = function (elem, opts, cb) { - if (typeof window === 'undefined') throw new Error('browser-only method') - render.render(this, elem, opts, cb) -} - -File.prototype._getMimeType = function () { - return render.mime[path.extname(this.name).toLowerCase()] -} - -File.prototype._destroy = function () { - this._destroyed = true - this._torrent = null -} - -}).call(this,require('_process')) -},{"./file-stream":129,"_process":16,"end-of-stream":59,"events":8,"inherits":65,"path":14,"readable-stream":98,"render-media":99,"stream-to-blob":112,"stream-to-blob-url":111,"stream-with-known-length-to-buffer":113}],131:[function(require,module,exports){ -var arrayRemove = require('unordered-array-remove') -var debug = require('debug')('webtorrent:peer') -var Wire = require('bittorrent-protocol') - -var WebConn = require('./webconn') - -var CONNECT_TIMEOUT_TCP = 5000 -var CONNECT_TIMEOUT_WEBRTC = 25000 -var 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 = function (conn, swarm) { - var peer = new Peer(conn.id, 'webrtc') - peer.conn = conn - peer.swarm = swarm - - if (peer.conn.connected) { - peer.onConnect() - } else { - peer.conn.once('connect', function () { peer.onConnect() }) - peer.conn.once('error', function (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 = function (conn) { - var addr = conn.remoteAddress + ':' + conn.remotePort - var peer = new Peer(addr, 'tcpIncoming') - peer.conn = conn - peer.addr = addr - - peer.onConnect() - - return peer -} - -/** - * 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 = function (addr, swarm) { - var peer = new Peer(addr, 'tcpOutgoing') - peer.addr = addr - peer.swarm = swarm - - return peer -} - -/** - * Peer that represents a Web Seed (BEP17 / BEP19). - */ -exports.createWebSeedPeer = function (url, swarm) { - var 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 - */ -function Peer (id, type) { - var self = this - self.id = id - self.type = type - - debug('new Peer %s', id) - - self.addr = null - self.conn = null - self.swarm = null - self.wire = null - - self.connected = false - self.destroyed = false - self.timeout = null // handshake timeout - self.retries = 0 // outgoing TCP connection retry count - - self.sentHandshake = false -} - -/** - * Called once the peer is connected (i.e. fired 'connect' event) - * @param {Socket} conn - */ -Peer.prototype.onConnect = function () { - var self = this - if (self.destroyed) return - self.connected = true - - debug('Peer %s connected', self.id) - - clearTimeout(self.connectTimeout) - - var conn = self.conn - conn.once('end', function () { - self.destroy() - }) - conn.once('close', function () { - self.destroy() - }) - conn.once('finish', function () { - self.destroy() - }) - conn.once('error', function (err) { - self.destroy(err) - }) - - var wire = self.wire = new Wire() - wire.type = self.type - wire.once('end', function () { - self.destroy() - }) - wire.once('close', function () { - self.destroy() - }) - wire.once('finish', function () { - self.destroy() - }) - wire.once('error', function (err) { - self.destroy(err) - }) - - wire.once('handshake', function (infoHash, peerId) { - self.onHandshake(infoHash, peerId) - }) - self.startHandshakeTimeout() - - conn.pipe(wire).pipe(conn) - if (self.swarm && !self.sentHandshake) self.handshake() -} - -/** - * Called when handshake is received from remote peer. - * @param {string} infoHash - * @param {string} peerId - */ -Peer.prototype.onHandshake = function (infoHash, peerId) { - var self = this - if (!self.swarm) return // `self.swarm` not set yet, so do nothing - if (self.destroyed) return - - if (self.swarm.destroyed) { - return self.destroy(new Error('swarm already destroyed')) - } - if (infoHash !== self.swarm.infoHash) { - return self.destroy(new Error('unexpected handshake info hash for this swarm')) - } - if (peerId === self.swarm.peerId) { - return self.destroy(new Error('refusing to connect to ourselves')) - } - - debug('Peer %s got handshake %s', self.id, infoHash) - - clearTimeout(self.handshakeTimeout) - - self.retries = 0 - - var addr = self.addr - if (!addr && self.conn.remoteAddress) { - addr = self.conn.remoteAddress + ':' + self.conn.remotePort - } - self.swarm._onWire(self.wire, addr) - - // swarm could be destroyed in user's 'wire' event handler - if (!self.swarm || self.swarm.destroyed) return - - if (!self.sentHandshake) self.handshake() -} - -Peer.prototype.handshake = function () { - var self = this - var opts = { - dht: self.swarm.private ? false : !!self.swarm.client.dht - } - self.wire.handshake(self.swarm.infoHash, self.swarm.client.peerId, opts) - self.sentHandshake = true -} - -Peer.prototype.startConnectTimeout = function () { - var self = this - clearTimeout(self.connectTimeout) - self.connectTimeout = setTimeout(function () { - self.destroy(new Error('connect timeout')) - }, self.type === 'webrtc' ? CONNECT_TIMEOUT_WEBRTC : CONNECT_TIMEOUT_TCP) - if (self.connectTimeout.unref) self.connectTimeout.unref() -} - -Peer.prototype.startHandshakeTimeout = function () { - var self = this - clearTimeout(self.handshakeTimeout) - self.handshakeTimeout = setTimeout(function () { - self.destroy(new Error('handshake timeout')) - }, HANDSHAKE_TIMEOUT) - if (self.handshakeTimeout.unref) self.handshakeTimeout.unref() -} - -Peer.prototype.destroy = function (err) { - var self = this - if (self.destroyed) return - self.destroyed = true - self.connected = false - - debug('destroy %s (error: %s)', self.id, err && (err.message || err)) - - clearTimeout(self.connectTimeout) - clearTimeout(self.handshakeTimeout) - - var swarm = self.swarm - var conn = self.conn - var wire = self.wire - - self.swarm = null - self.conn = null - self.wire = null - - if (swarm && wire) { - arrayRemove(swarm.wires, swarm.wires.indexOf(wire)) - } - if (conn) { - conn.on('error', noop) - conn.destroy() - } - if (wire) wire.destroy() - if (swarm) swarm.removePeer(self.id) -} - -function noop () {} - -},{"./webconn":134,"bittorrent-protocol":44,"debug":56,"unordered-array-remove":123}],132:[function(require,module,exports){ -module.exports = RarityMap - -/** - * 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. - */ -function RarityMap (torrent) { - var self = this - - self._torrent = torrent - self._numPieces = torrent.pieces.length - self._pieces = [] - - self._onWire = function (wire) { - self.recalculate() - self._initWire(wire) - } - self._onWireHave = function (index) { - self._pieces[index] += 1 - } - self._onWireBitfield = function () { - self.recalculate() - } - - self._torrent.wires.forEach(function (wire) { - self._initWire(wire) - }) - self._torrent.on('wire', self._onWire) - self.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 - */ -RarityMap.prototype.getRarestPiece = function (pieceFilterFunc) { - if (!pieceFilterFunc) pieceFilterFunc = trueFn - - var candidates = [] - var min = Infinity - - for (var i = 0; i < this._numPieces; ++i) { - if (!pieceFilterFunc(i)) continue - - var availability = this._pieces[i] - if (availability === min) { - candidates.push(i) - } else if (availability < min) { - candidates = [ i ] - min = availability - } - } - - if (candidates.length > 0) { - // if there are multiple pieces with the same availability, choose one randomly - return candidates[Math.random() * candidates.length | 0] - } else { - return -1 - } -} - -RarityMap.prototype.destroy = function () { - var self = this - self._torrent.removeListener('wire', self._onWire) - self._torrent.wires.forEach(function (wire) { - self._cleanupWireEvents(wire) - }) - self._torrent = null - self._pieces = null - - self._onWire = null - self._onWireHave = null - self._onWireBitfield = null -} - -RarityMap.prototype._initWire = function (wire) { - var self = this - - wire._onClose = function () { - self._cleanupWireEvents(wire) - for (var i = 0; i < this._numPieces; ++i) { - self._pieces[i] -= wire.peerPieces.get(i) - } - } - - wire.on('have', self._onWireHave) - wire.on('bitfield', self._onWireBitfield) - wire.once('close', wire._onClose) -} - -/** - * Recalculates piece availability across all peers in the torrent. - */ -RarityMap.prototype.recalculate = function () { - var i - for (i = 0; i < this._numPieces; ++i) { - this._pieces[i] = 0 - } - - var numWires = this._torrent.wires.length - for (i = 0; i < numWires; ++i) { - var wire = this._torrent.wires[i] - for (var j = 0; j < this._numPieces; ++j) { - this._pieces[j] += wire.peerPieces.get(j) - } - } -} - -RarityMap.prototype._cleanupWireEvents = function (wire) { - wire.removeListener('have', this._onWireHave) - wire.removeListener('bitfield', this._onWireBitfield) - if (wire._onClose) wire.removeListener('close', wire._onClose) - wire._onClose = null -} - -function trueFn () { - return true -} - -},{}],133:[function(require,module,exports){ -(function (process,global){ -/* global URL, Blob */ - -module.exports = Torrent - -var addrToIPPort = require('addr-to-ip-port') -var BitField = require('bitfield') -var ChunkStoreWriteStream = require('chunk-store-stream/write') -var debug = require('debug')('webtorrent:torrent') -var Discovery = require('torrent-discovery') -var EventEmitter = require('events').EventEmitter -var extend = require('xtend') -var extendMutable = require('xtend/mutable') -var fs = require('fs') -var FSChunkStore = require('fs-chunk-store') // browser: `memory-chunk-store` -var get = require('simple-get') -var ImmediateChunkStore = require('immediate-chunk-store') -var inherits = require('inherits') -var MultiStream = require('multistream') -var net = require('net') // browser exclude -var os = require('os') // browser exclude -var parallel = require('run-parallel') -var parallelLimit = require('run-parallel-limit') -var parseTorrent = require('parse-torrent') -var path = require('path') -var Piece = require('torrent-piece') -var pump = require('pump') -var randomIterate = require('random-iterate') -var sha1 = require('simple-sha1') -var speedometer = require('speedometer') -var uniq = require('uniq') -var utMetadata = require('ut_metadata') -var utPex = require('ut_pex') // browser exclude - -var File = require('./file') -var Peer = require('./peer') -var RarityMap = require('./rarity-map') -var Server = require('./server') // browser exclude - -var MAX_BLOCK_LENGTH = 128 * 1024 -var PIECE_TIMEOUT = 30000 -var CHOKE_TIMEOUT = 5000 -var SPEED_THRESHOLD = 3 * Piece.BLOCK_LENGTH - -var PIPELINE_MIN_DURATION = 0.5 -var PIPELINE_MAX_DURATION = 1 - -var RECHOKE_INTERVAL = 10000 // 10 seconds -var RECHOKE_OPTIMISTIC_DURATION = 2 // 30 seconds - -var FILESYSTEM_CONCURRENCY = 2 - -var RECONNECT_WAIT = [ 1000, 5000, 15000 ] - -var VERSION = require('../package.json').version - -var TMP -try { - TMP = path.join(fs.statSync('/tmp') && '/tmp', 'webtorrent') -} catch (err) { - TMP = path.join(typeof os.tmpDir === 'function' ? os.tmpDir() : '/', 'webtorrent') -} - -inherits(Torrent, EventEmitter) - -function Torrent (torrentId, client, opts) { - EventEmitter.call(this) - - this.client = client - this._debugId = this.client.peerId.toString('hex').substring(0, 7) - - this._debug('new torrent') - - this.announce = opts.announce - this.urlList = opts.urlList - - this.path = opts.path - this._store = opts.store || FSChunkStore - this._getAnnounceOpts = opts.getAnnounceOpts - - 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) -} - -Object.defineProperty(Torrent.prototype, 'timeRemaining', { - get: function () { - if (this.done) return 0 - if (this.downloadSpeed === 0) return Infinity - return ((this.length - this.downloaded) / this.downloadSpeed) * 1000 - } -}) - -Object.defineProperty(Torrent.prototype, 'downloaded', { - get: function () { - if (!this.bitfield) return 0 - var downloaded = 0 - for (var 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 - var 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 -// } -// }) - -Object.defineProperty(Torrent.prototype, 'downloadSpeed', { - get: function () { return this._downloadSpeed() } -}) - -Object.defineProperty(Torrent.prototype, 'uploadSpeed', { - get: function () { return this._uploadSpeed() } -}) - -Object.defineProperty(Torrent.prototype, 'progress', { - get: function () { return this.length ? this.downloaded / this.length : 0 } -}) - -Object.defineProperty(Torrent.prototype, 'ratio', { - get: function () { return this.uploaded / (this.received || 1) } -}) - -Object.defineProperty(Torrent.prototype, 'numPeers', { - get: function () { return this.wires.length } -}) - -Object.defineProperty(Torrent.prototype, 'torrentFileBlobURL', { - get: function () { - 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' }) - ) - } -}) - -Object.defineProperty(Torrent.prototype, '_numQueued', { - get: function () { - return this._queue.length + (this._peersLength - this._numConns) - } -}) - -Object.defineProperty(Torrent.prototype, '_numConns', { - get: function () { - var self = this - var numConns = 0 - for (var id in self._peers) { - if (self._peers[id].connected) numConns += 1 - } - return numConns - } -}) - -// TODO: remove in v1 -Object.defineProperty(Torrent.prototype, 'swarm', { - get: function () { - console.warn('WebTorrent: `torrent.swarm` is deprecated. Use `torrent` directly instead.') - return this - } -}) - -Torrent.prototype._onTorrentId = function (torrentId, forcedId) { - var self = this - if (self.destroyed) return - - var parsedTorrent - try { parsedTorrent = parseTorrent(torrentId) } catch (err) {} - - if (parsedTorrent) { - // Attempt to set infoHash property synchronously - self.infoHash = parsedTorrent.infoHash - process.nextTick(function () { - if (self.destroyed) return - self._onParsedTorrent(parsedTorrent, forcedId) - }) - } 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, function (err, parsedTorrent) { - if (self.destroyed) return - if (err) return self._destroy(err) - self._onParsedTorrent(parsedTorrent, forcedId) - }) - } -} - -Torrent.prototype._onParsedTorrent = function (parsedTorrent, forcedId) { - var self = this - if (self.destroyed) return - self._processParsedTorrent(parsedTorrent) - - if (!self.infoHash) { - return self._destroy(new Error('Malformed torrent data: No info hash')) - } - - if (!self.path) self.path = path.join(TMP, self.infoHash) - - self._rechokeIntervalId = setInterval(function () { - self._rechoke() - }, RECHOKE_INTERVAL) - if (self._rechokeIntervalId.unref) self._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. - if(forcedId){ - self.emit('_infoHash', forcedId) - self.emit('infoHash', forcedId) - self.infoHash = forcedId - } else { - self.emit('_infoHash', self.infoHash) - self.emit('infoHash', self.infoHash) - } - if (self.destroyed) return - - if (self.client.listening) { - self._onListening() - } else { - self.client.once('listening', function () { - self._onListening() - }) - } -} - -Torrent.prototype._processParsedTorrent = function (parsedTorrent) { - if (this.announce) { - // Allow specifying trackers via `opts` parameter - parsedTorrent.announce = parsedTorrent.announce.concat(this.announce) - } - - if (this.client.tracker && global.WEBTORRENT_ANNOUNCE && !this.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) - } - - uniq(parsedTorrent.announce) - uniq(parsedTorrent.urlList) - - extendMutable(this, parsedTorrent) - - this.magnetURI = parseTorrent.toMagnetURI(parsedTorrent) - this.torrentFile = parseTorrent.toTorrentFile(parsedTorrent) -} - -Torrent.prototype._onListening = function () { - var self = this - if (self.discovery || self.destroyed) return - - var trackerOpts = self.client.tracker - if (trackerOpts) { - trackerOpts = extend(self.client.tracker, { - getAnnounceOpts: function () { - var opts = { - uploaded: self.uploaded, - downloaded: self.downloaded, - left: Math.max(self.length - self.downloaded, 0) - } - if (self.client.tracker.getAnnounceOpts) { - extendMutable(opts, self.client.tracker.getAnnounceOpts()) - } - if (self._getAnnounceOpts) { - // TODO: consider deprecating this, as it's redundant with the former case - extendMutable(opts, self._getAnnounceOpts()) - } - return opts - } - }) - } - - // begin discovering peers via DHT and trackers - self.discovery = new Discovery({ - infoHash: self.infoHash, - announce: self.announce, - peerId: self.client.peerId, - dht: !self.private && self.client.dht, - tracker: trackerOpts, - port: self.client.torrentPort - }) - - self.discovery.on('error', onError) - self.discovery.on('peer', onPeer) - self.discovery.on('trackerAnnounce', onTrackerAnnounce) - self.discovery.on('dhtAnnounce', onDHTAnnounce) - self.discovery.on('warning', onWarning) - - function onError (err) { - self._destroy(err) - } - - function onPeer (peer) { - // Don't create new outgoing TCP connections when torrent is done - if (typeof peer === 'string' && self.done) return - self.addPeer(peer) - } - - function onTrackerAnnounce () { - self.emit('trackerAnnounce') - if (self.numPeers === 0) self.emit('noPeers', 'tracker') - } - - function onDHTAnnounce () { - self.emit('dhtAnnounce') - if (self.numPeers === 0) self.emit('noPeers', 'dht') - } - - function onWarning (err) { - self.emit('warning', err) - } - - if (self.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. - self._onMetadata(self) - } else if (self.xs) { - self._getMetadataFromServer() - } -} - -Torrent.prototype._getMetadataFromServer = function () { - var self = this - var urls = Array.isArray(self.xs) ? self.xs : [ self.xs ] - - var tasks = urls.map(function (url) { - return function (cb) { - getMetadataFromURL(url, cb) - } - }) - parallel(tasks) - - function getMetadataFromURL (url, cb) { - if (url.indexOf('http://') !== 0 && url.indexOf('https://') !== 0) { - self._debug('skipping non-http xs param: %s', url) - return cb(null) - } - - var opts = { - url: url, - method: 'GET', - headers: { - 'user-agent': 'WebTorrent/' + VERSION + ' (https://webtorrent.io)' - } - } - var req - try { - req = get.concat(opts, onResponse) - } catch (err) { - self._debug('skipping invalid url xs param: %s', 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._debug('http error from xs param: %s', url) - return cb(null) - } - if (res.statusCode !== 200) { - self._debug('non-200 status code %s from xs param: %s', res.statusCode, url) - return cb(null) - } - - var parsedTorrent - try { - parsedTorrent = parseTorrent(torrent) - } catch (err) {} - - if (!parsedTorrent) { - self._debug('got invalid torrent file from xs param: %s', url) - return cb(null) - } - - if (parsedTorrent.infoHash !== self.infoHash) { - self._debug('got torrent file with incorrect info hash from xs param: %s', url) - return cb(null) - } - - self._onMetadata(parsedTorrent) - cb(null) - } - } -} - -/** - * Called when the full torrent metadata is received. - */ -Torrent.prototype._onMetadata = function (metadata) { - var self = this - if (self.metadata || self.destroyed) return - self._debug('got metadata') - - self._xsRequests.forEach(function (req) { - req.abort() - }) - self._xsRequests = [] - - var parsedTorrent - if (metadata && metadata.infoHash) { - // `metadata` is a parsed torrent (from parse-torrent module) - parsedTorrent = metadata - } else { - try { - parsedTorrent = parseTorrent(metadata) - } catch (err) { - return self._destroy(err) - } - } - - self._processParsedTorrent(parsedTorrent) - self.metadata = self.torrentFile - - // add web seed urls (BEP19) - if (self.client.enableWebSeeds) { - self.urlList.forEach(function (url) { - self.addWebSeed(url) - }) - } - - // start off selecting the entire torrent with low priority - if (self.pieces.length !== 0) { - self.select(0, self.pieces.length - 1, false) - } - - self._rarityMap = new RarityMap(self) - - self.store = new ImmediateChunkStore( - new self._store(self.pieceLength, { - torrent: { - infoHash: self.infoHash - }, - files: self.files.map(function (file) { - return { - path: path.join(self.path, file.path), - length: file.length, - offset: file.offset - } - }), - length: self.length - }) - ) - - self.files = self.files.map(function (file) { - return new File(self, file) - }) - - self._hashes = self.pieces - - self.pieces = self.pieces.map(function (hash, i) { - var pieceLength = (i === self.pieces.length - 1) - ? self.lastPieceLength - : self.pieceLength - return new Piece(pieceLength) - }) - - self._reservations = self.pieces.map(function () { - return [] - }) - - self.bitfield = new BitField(self.pieces.length) - - self.wires.forEach(function (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(self.metadata) - - self._onWireWithMetadata(wire) - }) - - self._debug('verifying existing torrent data') - if (self._fileModtimes && self._store === FSChunkStore) { - // don't verify if the files haven't been modified since we last checked - self.getFileModtimes(function (err, fileModtimes) { - if (err) return self._destroy(err) - - var unchanged = self.files.map(function (_, index) { - return fileModtimes[index] === self._fileModtimes[index] - }).every(function (x) { - return x - }) - - if (unchanged) { - for (var index = 0; index < self.pieces.length; index++) { - self._markVerified(index) - } - self._onStore() - } else { - self._verifyPieces() - } - }) - } else { - self._verifyPieces() - } - - self.emit('metadata') -} - -/* - * TODO: remove this - * Gets the last modified time of every file on disk for this torrent. - * Only valid in Node, not in the browser. - */ -Torrent.prototype.getFileModtimes = function (cb) { - var self = this - var ret = [] - parallelLimit(self.files.map(function (file, index) { - return function (cb) { - fs.stat(path.join(self.path, file.path), function (err, stat) { - if (err && err.code !== 'ENOENT') return cb(err) - ret[index] = stat && stat.mtime.getTime() - cb(null) - }) - } - }), FILESYSTEM_CONCURRENCY, function (err) { - self._debug('done getting file modtimes') - cb(err, ret) - }) -} - -Torrent.prototype._verifyPieces = function () { - var self = this - parallelLimit(self.pieces.map(function (_, index) { - return function (cb) { - if (self.destroyed) return cb(new Error('torrent is destroyed')) - self.store.get(index, function (err, buf) { - if (err) return process.nextTick(cb, null) // ignore error - sha1(buf, function (hash) { - if (hash === self._hashes[index]) { - if (!self.pieces[index]) return - self._debug('piece verified %s', index) - self._markVerified(index) - } else { - self._debug('piece invalid %s', index) - } - cb(null) - }) - }) - } - }), FILESYSTEM_CONCURRENCY, function (err) { - if (err) return self._destroy(err) - self._debug('done verifying') - self._onStore() - }) -} - -Torrent.prototype._markVerified = function (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. - */ -Torrent.prototype._onStore = function () { - var self = this - if (self.destroyed) return - self._debug('on store') - - self.ready = true - self.emit('ready') - - // Files may start out done if the file was already in the store - self._checkDone() - - // In case any selections were made before torrent was ready - self._updateSelections() -} - -Torrent.prototype.destroy = function (cb) { - var self = this - self._destroy(null, cb) -} - -Torrent.prototype._destroy = function (err, cb) { - var self = this - if (self.destroyed) return - self.destroyed = true - self._debug('destroy') - - self.client._remove(self) - - clearInterval(self._rechokeIntervalId) - - self._xsRequests.forEach(function (req) { - req.abort() - }) - - if (self._rarityMap) { - self._rarityMap.destroy() - } - - for (var id in self._peers) { - self.removePeer(id) - } - - self.files.forEach(function (file) { - if (file instanceof File) file._destroy() - }) - - var tasks = self._servers.map(function (server) { - return function (cb) { - server.destroy(cb) - } - }) - - if (self.discovery) { - tasks.push(function (cb) { - self.discovery.destroy(cb) - }) - } - - if (self.store) { - tasks.push(function (cb) { - self.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 (self.listenerCount('error') === 0) { - self.client.emit('error', err) - } else { - self.emit('error', err) - } - } - - self.emit('close') - - self.client = null - self.files = [] - self.discovery = null - self.store = null - self._rarityMap = null - self._peers = null - self._servers = null - self._xsRequests = null -} - -Torrent.prototype.addPeer = function (peer) { - var self = this - if (self.destroyed) throw new Error('torrent is destroyed') - if (!self.infoHash) throw new Error('addPeer() must not be called before the `infoHash` event') - - if (self.client.blocked) { - var host - if (typeof peer === 'string') { - var parts - try { - parts = addrToIPPort(peer) - } catch (e) { - self._debug('ignoring peer: invalid %s', peer) - self.emit('invalidPeer', peer) - return false - } - host = parts[0] - } else if (typeof peer.remoteAddress === 'string') { - host = peer.remoteAddress - } - - if (host && self.client.blocked.contains(host)) { - self._debug('ignoring peer: blocked %s', peer) - if (typeof peer !== 'string') peer.destroy() - self.emit('blockedPeer', peer) - return false - } - } - - var wasAdded = !!self._addPeer(peer) - if (wasAdded) { - self.emit('peer', peer) - } else { - self.emit('invalidPeer', peer) - } - return wasAdded -} - -Torrent.prototype._addPeer = function (peer) { - var self = this - if (self.destroyed) { - self._debug('ignoring peer: torrent is destroyed') - if (typeof peer !== 'string') peer.destroy() - return null - } - if (typeof peer === 'string' && !self._validAddr(peer)) { - self._debug('ignoring peer: invalid %s', peer) - return null - } - - var id = (peer && peer.id) || peer - if (self._peers[id]) { - self._debug('ignoring peer: duplicate (%s)', id) - if (typeof peer !== 'string') peer.destroy() - return null - } - - if (self.paused) { - self._debug('ignoring peer: torrent is paused') - if (typeof peer !== 'string') peer.destroy() - return null - } - - self._debug('add peer %s', id) - - var newPeer - if (typeof peer === 'string') { - // `peer` is an addr ("ip:port" string) - newPeer = Peer.createTCPOutgoingPeer(peer, self) - } else { - // `peer` is a WebRTC connection (simple-peer) - newPeer = Peer.createWebRTCPeer(peer, self) - } - - self._peers[newPeer.id] = newPeer - self._peersLength += 1 - - if (typeof peer === 'string') { - // `peer` is an addr ("ip:port" string) - self._queue.push(newPeer) - self._drain() - } - - return newPeer -} - -Torrent.prototype.addWebSeed = function (url) { - if (this.destroyed) throw new Error('torrent is destroyed') - - if (!/^https?:\/\/.+/.test(url)) { - this._debug('ignoring invalid web seed %s', url) - this.emit('invalidPeer', url) - return - } - - if (this._peers[url]) { - this._debug('ignoring duplicate web seed %s', url) - this.emit('invalidPeer', url) - return - } - - this._debug('add web seed %s', url) - - var 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. - */ -Torrent.prototype._addIncomingPeer = function (peer) { - var self = this - if (self.destroyed) return peer.destroy(new Error('torrent is destroyed')) - if (self.paused) return peer.destroy(new Error('torrent is paused')) - - this._debug('add incoming peer %s', peer.id) - - self._peers[peer.id] = peer - self._peersLength += 1 -} - -Torrent.prototype.removePeer = function (peer) { - var self = this - var id = (peer && peer.id) || peer - peer = self._peers[id] - - if (!peer) return - - this._debug('removePeer %s', id) - - delete self._peers[id] - self._peersLength -= 1 - - peer.destroy() - - // If torrent swarm was at capacity before, try to open a new connection now - self._drain() -} - -Torrent.prototype.select = function (start, end, priority, notify) { - var self = this - if (self.destroyed) throw new Error('torrent is destroyed') - - if (start < 0 || end < start || self.pieces.length <= end) { - throw new Error('invalid selection ', start, ':', end) - } - priority = Number(priority) || 0 - - self._debug('select %s-%s (priority %s)', start, end, priority) - - self._selections.push({ - from: start, - to: end, - offset: 0, - priority: priority, - notify: notify || noop - }) - - self._selections.sort(function (a, b) { - return b.priority - a.priority - }) - - self._updateSelections() -} - -Torrent.prototype.deselect = function (start, end, priority) { - var self = this - if (self.destroyed) throw new Error('torrent is destroyed') - - priority = Number(priority) || 0 - self._debug('deselect %s-%s (priority %s)', start, end, priority) - - for (var i = 0; i < self._selections.length; ++i) { - var s = self._selections[i] - if (s.from === start && s.to === end && s.priority === priority) { - self._selections.splice(i--, 1) - break - } - } - - self._updateSelections() -} - -Torrent.prototype.critical = function (start, end) { - var self = this - if (self.destroyed) throw new Error('torrent is destroyed') - - self._debug('critical %s-%s', start, end) - - for (var i = start; i <= end; ++i) { - self._critical[i] = true - } - - self._updateSelections() -} - -Torrent.prototype._onWire = function (wire, addr) { - var self = this - self._debug('got wire %s (%s)', wire._debugId, addr || 'Unknown') - - wire.on('download', function (downloaded) { - if (self.destroyed) return - self.received += downloaded - self._downloadSpeed(downloaded) - self.client._downloadSpeed(downloaded) - self.emit('download', downloaded) - self.client.emit('download', downloaded) - }) - - wire.on('upload', function (uploaded) { - if (self.destroyed) return - self.uploaded += uploaded - self._uploadSpeed(uploaded) - self.client._uploadSpeed(uploaded) - self.emit('upload', uploaded) - self.client.emit('upload', uploaded) - }) - - self.wires.push(wire) - - if (addr) { - // Sometimes RTCPeerConnection.getStats() doesn't return an ip:port for peers - var parts = addrToIPPort(addr) - wire.remoteAddress = parts[0] - wire.remotePort = parts[1] - } - - // When peer sends PORT message, add that DHT node to routing table - if (self.client.dht && self.client.dht.listening) { - wire.on('port', function (port) { - if (self.destroyed || self.client.dht.destroyed) { - return - } - if (!wire.remoteAddress) { - return self._debug('ignoring PORT from peer with no address') - } - if (port === 0 || port > 65536) { - return self._debug('ignoring invalid PORT from peer') - } - - self._debug('port: %s (from %s)', port, addr) - self.client.dht.addNode({ host: wire.remoteAddress, port: port }) - }) - } - - wire.on('timeout', function () { - self._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(self.metadata)) - - wire.ut_metadata.on('warning', function (err) { - self._debug('ut_metadata warning: %s', err.message) - }) - - if (!self.metadata) { - wire.ut_metadata.on('metadata', function (metadata) { - self._debug('got metadata via ut_metadata') - self._onMetadata(metadata) - }) - wire.ut_metadata.fetch() - } - - // use ut_pex extension if the torrent is not flagged as private - if (typeof utPex === 'function' && !self.private) { - wire.use(utPex()) - - wire.ut_pex.on('peer', function (peer) { - // Only add potential new peers when we're not seeding - if (self.done) return - self._debug('ut_pex: got peer: %s (from %s)', peer, addr) - self.addPeer(peer) - }) - - wire.ut_pex.on('dropped', function (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. - var peerObj = self._peers[peer] - if (peerObj && !peerObj.connected) { - self._debug('ut_pex: dropped peer: %s (from %s)', peer, addr) - self.removePeer(peer) - } - }) - - wire.once('close', function () { - // Stop sending updates to remote peer - wire.ut_pex.reset() - }) - } - - // Hook to allow user-defined `bittorrent-protocol` extensions - // More info: https://github.com/feross/bittorrent-protocol#extension-api - self.emit('wire', wire, addr) - - if (self.metadata) { - process.nextTick(function () { - // This allows wire.handshake() to be called (by Peer.onHandshake) before any - // messages get sent on the wire - self._onWireWithMetadata(wire) - }) - } -} - -Torrent.prototype._onWireWithMetadata = function (wire) { - var self = this - var timeoutId = null - - function onChokeTimeout () { - if (self.destroyed || wire.destroyed) return - - if (self._numQueued > 2 * (self._numConns - self.numPeers) && - wire.amInterested) { - wire.destroy() - } else { - timeoutId = setTimeout(onChokeTimeout, CHOKE_TIMEOUT) - if (timeoutId.unref) timeoutId.unref() - } - } - - var i = 0 - function updateSeedStatus () { - if (wire.peerPieces.length !== self.pieces.length) return - for (; i < self.pieces.length; ++i) { - if (!wire.peerPieces.get(i)) return - } - wire.isSeeder = true - wire.choke() // always choke seeders - } - - wire.on('bitfield', function () { - updateSeedStatus() - self._update() - }) - - wire.on('have', function () { - updateSeedStatus() - self._update() - }) - - wire.once('interested', function () { - wire.unchoke() - }) - - wire.once('close', function () { - clearTimeout(timeoutId) - }) - - wire.on('choke', function () { - clearTimeout(timeoutId) - timeoutId = setTimeout(onChokeTimeout, CHOKE_TIMEOUT) - if (timeoutId.unref) timeoutId.unref() - }) - - wire.on('unchoke', function () { - clearTimeout(timeoutId) - self._update() - }) - - wire.on('request', function (index, offset, length, cb) { - if (length > MAX_BLOCK_LENGTH) { - // Per spec, disconnect from peers that request >128KB - return wire.destroy() - } - if (self.pieces[index]) return - self.store.get(index, { offset: offset, length: length }, cb) - }) - - wire.bitfield(self.bitfield) // always send bitfield (required) - wire.interested() // always start out interested - - // Send PORT message to peers that support DHT - if (wire.peerExtensions.dht && self.client.dht && self.client.dht.listening) { - wire.port(self.client.dht.address().port) - } - - timeoutId = setTimeout(onChokeTimeout, CHOKE_TIMEOUT) - if (timeoutId.unref) timeoutId.unref() - - wire.isSeeder = false - updateSeedStatus() -} - -/** - * Called on selection changes. - */ -Torrent.prototype._updateSelections = function () { - var self = this - if (!self.ready || self.destroyed) return - - process.nextTick(function () { - self._gcSelections() - }) - self._updateInterest() - self._update() -} - -/** - * Garbage collect selections with respect to the store's current state. - */ -Torrent.prototype._gcSelections = function () { - var self = this - - for (var i = 0; i < self._selections.length; i++) { - var s = self._selections[i] - var oldOffset = s.offset - - // check for newly downloaded pieces in selection - while (self.bitfield.get(s.from + s.offset) && s.from + s.offset < s.to) { - s.offset++ - } - - if (oldOffset !== s.offset) s.notify() - if (s.to !== s.from + s.offset) continue - if (!self.bitfield.get(s.from + s.offset)) continue - - // remove fully downloaded selection - self._selections.splice(i--, 1) // decrement i to offset splice - s.notify() // TODO: this may notify twice in a row. is this a problem? - self._updateInterest() - } - - if (!self._selections.length) self.emit('idle') -} - -/** - * Update interested status for all peers. - */ -Torrent.prototype._updateInterest = function () { - var self = this - - var prev = self._amInterested - self._amInterested = !!self._selections.length - - self.wires.forEach(function (wire) { - // TODO: only call wire.interested if the wire has at least one piece we need - if (self._amInterested) wire.interested() - else wire.uninterested() - }) - - if (prev === self._amInterested) return - if (self._amInterested) self.emit('interested') - else self.emit('uninterested') -} - -/** - * Heartbeat to update all peers and their requests. - */ -Torrent.prototype._update = function () { - var self = this - if (self.destroyed) return - - // update wires in random order for better request distribution - var ite = randomIterate(self.wires) - var wire - while ((wire = ite())) { - self._updateWire(wire) - } -} - -/** - * Attempts to update a peer's requests - */ -Torrent.prototype._updateWire = function (wire) { - var self = this - - if (wire.peerChoking) return - if (!wire.downloaded) return validateWire() - - var minOutstandingRequests = getBlockPipelineLength(wire, PIPELINE_MIN_DURATION) - if (wire.requests.length >= minOutstandingRequests) return - var maxOutstandingRequests = getBlockPipelineLength(wire, PIPELINE_MAX_DURATION) - - trySelectWire(false) || trySelectWire(true) - - function genPieceFilterFunc (start, end, tried, rank) { - return function (i) { - return 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 - - var i = self._selections.length - while (i--) { - var next = self._selections[i] - var piece - if (self.strategy === 'rarest') { - var start = next.from + next.offset - var end = next.to - var len = end - start + 1 - var tried = {} - var tries = 0 - var 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 () { - var speed = wire.downloadSpeed() || 1 - if (speed > SPEED_THRESHOLD) return function () { return true } - - var secs = Math.max(1, wire.requests.length) * Piece.BLOCK_LENGTH / speed - var tries = 10 - var ptr = 0 - - return function (index) { - if (!tries || self.bitfield.get(index)) return true - - var missing = self.pieces[index].missing - - for (; ptr < self.wires.length; ptr++) { - var otherWire = self.wires[ptr] - var 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) { - var last = i - for (var j = i; j < self._selections.length && self._selections[j].priority; j++) { - last = j - } - var tmp = self._selections[i] - self._selections[i] = self._selections[last] - self._selections[last] = tmp - } - - function trySelectWire (hotswap) { - if (wire.requests.length >= maxOutstandingRequests) return true - var rank = speedRanker() - - for (var i = 0; i < self._selections.length; i++) { - var next = self._selections[i] - - var piece - if (self.strategy === 'rarest') { - var start = next.from + next.offset - var end = next.to - var len = end - start + 1 - var tried = {} - var tries = 0 - var filter = genPieceFilterFunc(start, end, tried, rank) - - while (tries < len) { - piece = self._rarityMap.getRarestPiece(filter) - if (piece < 0) break - - // request all non-reserved blocks in this piece - while (self._request(wire, piece, self._critical[piece] || hotswap)) {} - - 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 - - // request all non-reserved blocks in piece - while (self._request(wire, piece, self._critical[piece] || hotswap)) {} - - 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. - */ -Torrent.prototype._rechoke = function () { - var self = this - if (!self.ready) return - - if (self._rechokeOptimisticTime > 0) self._rechokeOptimisticTime -= 1 - else self._rechokeOptimisticWire = null - - var peers = [] - - self.wires.forEach(function (wire) { - if (!wire.isSeeder && wire !== self._rechokeOptimisticWire) { - peers.push({ - wire: wire, - downloadSpeed: wire.downloadSpeed(), - uploadSpeed: wire.uploadSpeed(), - salt: Math.random(), - isChoked: true - }) - } - }) - - peers.sort(rechokeSort) - - var unchokeInterested = 0 - var i = 0 - for (; i < peers.length && unchokeInterested < self._rechokeNumSlots; ++i) { - peers[i].isChoked = false - if (peers[i].wire.peerInterested) unchokeInterested += 1 - } - - // Optimistically unchoke a peer - if (!self._rechokeOptimisticWire && i < peers.length && self._rechokeNumSlots) { - var candidates = peers.slice(i).filter(function (peer) { return peer.wire.peerInterested }) - var optimistic = candidates[randomInt(candidates.length)] - - if (optimistic) { - optimistic.isChoked = false - self._rechokeOptimisticWire = optimistic.wire - self._rechokeOptimisticTime = RECHOKE_OPTIMISTIC_DURATION - } - } - - // Unchoke best peers - peers.forEach(function (peer) { - if (peer.wire.amChoking !== peer.isChoked) { - if (peer.isChoked) peer.wire.choke() - else peer.wire.unchoke() - } - }) - - function rechokeSort (peerA, peerB) { - // Prefer higher download speed - if (peerA.downloadSpeed !== peerB.downloadSpeed) { - return peerB.downloadSpeed - peerA.downloadSpeed - } - - // Prefer higher upload speed - if (peerA.uploadSpeed !== peerB.uploadSpeed) { - return peerB.uploadSpeed - peerA.uploadSpeed - } - - // Prefer unchoked - if (peerA.wire.amChoking !== peerB.wire.amChoking) { - return peerA.wire.amChoking ? 1 : -1 - } - - // Random order - return peerA.salt - peerB.salt - } -} - -/** - * 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. - */ -Torrent.prototype._hotswap = function (wire, index) { - var self = this - - var speed = wire.downloadSpeed() - if (speed < Piece.BLOCK_LENGTH) return false - if (!self._reservations[index]) return false - - var r = self._reservations[index] - if (!r) { - return false - } - - var minSpeed = Infinity - var minWire - - var i - for (i = 0; i < r.length; i++) { - var otherWire = r[i] - if (!otherWire || otherWire === wire) continue - - var 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++) { - var req = minWire.requests[i] - if (req.piece !== index) continue - - self.pieces[index].cancel((req.offset / Piece.BLOCK_LENGTH) | 0) - } - - self.emit('hotswap', minWire, wire, index) - return true -} - -/** - * Attempts to request a block from the given wire. - */ -Torrent.prototype._request = function (wire, index, hotswap) { - var self = this - var numRequests = wire.requests.length - var isWebSeed = wire.type === 'webSeed' - - if (self.bitfield.get(index)) return false - - var 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) - - var piece = self.pieces[index] - var 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 - - var r = self._reservations[index] - if (!r) r = self._reservations[index] = [] - var i = r.indexOf(null) - if (i === -1) i = r.length - r[i] = wire - - var chunkOffset = piece.chunkOffset(reservation) - var chunkLength = isWebSeed ? piece.chunkLengthRemaining(reservation) : piece.chunkLength(reservation) - - wire.request(index, chunkOffset, chunkLength, function onChunk (err, chunk) { - // TODO: what is this for? - if (!self.ready) return self.once('ready', function () { 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() - - var buf = piece.flush() - - // TODO: might need to set self.pieces[index] = null here since sha1 is async - - sha1(buf, function (hash) { - 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(function (wire) { - wire.have(index) - }) - - self._checkDone() - } else { - self.pieces[index] = new Piece(piece.length) - self.emit('warning', new Error('Piece ' + index + ' failed verification')) - } - onUpdateTick() - }) - }) - - function onUpdateTick () { - process.nextTick(function () { self._update() }) - } - - return true -} - -Torrent.prototype._checkDone = function () { - var self = this - if (self.destroyed) return - - // are any new files done? - self.files.forEach(function (file) { - if (file.done) return - for (var i = file._startPiece; i <= file._endPiece; ++i) { - if (!self.bitfield.get(i)) return - } - file.done = true - file.emit('done') - self._debug('file done: ' + file.name) - }) - - // is the torrent done? (if all current selections are satisfied, or there are - // no selections, then torrent is done) - var done = true - for (var i = 0; i < self._selections.length; i++) { - var selection = self._selections[i] - for (var piece = selection.from; piece <= selection.to; piece++) { - if (!self.bitfield.get(piece)) { - done = false - break - } - } - if (!done) break - } - if (!self.done && done) { - self.done = true - self._debug('torrent done: ' + self.infoHash) - self.discovery.complete() - self.emit('done') - } - - self._gcSelections() -} - -Torrent.prototype.load = function (streams, cb) { - var self = this - if (self.destroyed) throw new Error('torrent is destroyed') - if (!self.ready) return self.once('ready', function () { self.load(streams, cb) }) - - if (!Array.isArray(streams)) streams = [ streams ] - if (!cb) cb = noop - - var readable = new MultiStream(streams) - var writable = new ChunkStoreWriteStream(self.store, self.pieceLength) - - pump(readable, writable, function (err) { - if (err) return cb(err) - self.pieces.forEach(function (piece, index) { - self.pieces[index] = null - self._reservations[index] = null - self.bitfield.set(index, true) - }) - self._checkDone() - cb(null) - }) -} - -Torrent.prototype.createServer = function (opts) { - if (typeof Server !== 'function') throw new Error('node.js-only method') - if (this.destroyed) throw new Error('torrent is destroyed') - var server = new Server(this, opts) - this._servers.push(server) - return server -} - -Torrent.prototype.pause = function () { - if (this.destroyed) return - this._debug('pause') - this.paused = true -} - -Torrent.prototype.resume = function () { - if (this.destroyed) return - this._debug('resume') - this.paused = false - this._drain() -} - -Torrent.prototype._debug = function () { - var args = [].slice.call(arguments) - args[0] = '[' + this._debugId + '] ' + args[0] - debug.apply(null, 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. - */ -Torrent.prototype._drain = function () { - var self = this - this._debug('_drain numConns %s maxConns %s', self._numConns, self.client.maxConns) - if (typeof net.connect !== 'function' || self.destroyed || self.paused || - self._numConns >= self.client.maxConns) { - return - } - this._debug('drain (%s queued, %s/%s peers)', self._numQueued, self.numPeers, self.client.maxConns) - - var peer = self._queue.shift() - if (!peer) return // queue could be empty - - this._debug('tcp connect attempt to %s', peer.addr) - - var parts = addrToIPPort(peer.addr) - var opts = { - host: parts[0], - port: parts[1] - } - - var conn = peer.conn = net.connect(opts) - - conn.once('connect', function () { peer.onConnect() }) - conn.once('error', function (err) { peer.destroy(err) }) - peer.startConnectTimeout() - - // When connection closes, attempt reconnect after timeout (with exponential backoff) - conn.on('close', function () { - if (self.destroyed) return - - // TODO: If torrent is done, do not try to reconnect after a timeout - - if (peer.retries >= RECONNECT_WAIT.length) { - self._debug( - 'conn %s closed: will not re-add (max %s attempts)', - peer.addr, RECONNECT_WAIT.length - ) - return - } - - var ms = RECONNECT_WAIT[peer.retries] - self._debug( - 'conn %s closed: will re-add to queue in %sms (attempt %s)', - peer.addr, ms, peer.retries + 1 - ) - - var reconnectTimeout = setTimeout(function reconnectTimeout () { - var newPeer = self._addPeer(peer.addr) - 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} - */ -Torrent.prototype._validAddr = function (addr) { - var parts - try { - parts = addrToIPPort(addr) - } catch (e) { - return false - } - var host = parts[0] - var 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 () {} - -}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"../package.json":135,"./file":130,"./peer":131,"./rarity-map":132,"./server":2,"_process":16,"addr-to-ip-port":38,"bitfield":43,"chunk-store-stream/write":52,"debug":56,"events":8,"fs":3,"fs-chunk-store":73,"immediate-chunk-store":64,"inherits":65,"multistream":81,"net":2,"os":2,"parse-torrent":85,"path":14,"pump":88,"random-iterate":89,"run-parallel":102,"run-parallel-limit":101,"simple-get":106,"simple-sha1":108,"speedometer":110,"torrent-discovery":118,"torrent-piece":119,"uniq":122,"ut_metadata":124,"ut_pex":2,"xtend":137,"xtend/mutable":138}],134:[function(require,module,exports){ -module.exports = WebConn - -var BitField = require('bitfield') -var Buffer = require('safe-buffer').Buffer -var debug = require('debug')('webtorrent:webconn') -var get = require('simple-get') -var inherits = require('inherits') -var sha1 = require('simple-sha1') -var Wire = require('bittorrent-protocol') - -var VERSION = require('../package.json').version - -inherits(WebConn, Wire) - -/** - * Converts requests for torrent blocks into http range requests. - * @param {string} url web seed url - * @param {Object} torrent - */ -function WebConn (url, torrent) { - Wire.call(this) - - this.url = url - this.webPeerId = sha1.sync(url) - this._torrent = torrent - - this._init() -} - -WebConn.prototype._init = function () { - var self = this - self.setKeepAlive(true) - - self.once('handshake', function (infoHash, peerId) { - if (self.destroyed) return - self.handshake(infoHash, self.webPeerId) - var numPieces = self._torrent.pieces.length - var bitfield = new BitField(numPieces) - for (var i = 0; i <= numPieces; i++) { - bitfield.set(i, true) - } - self.bitfield(bitfield) - }) - - self.once('interested', function () { - debug('interested') - self.unchoke() - }) - - self.on('uninterested', function () { debug('uninterested') }) - self.on('choke', function () { debug('choke') }) - self.on('unchoke', function () { debug('unchoke') }) - self.on('bitfield', function () { debug('bitfield') }) - - self.on('request', function (pieceIndex, offset, length, callback) { - debug('request pieceIndex=%d offset=%d length=%d', pieceIndex, offset, length) - self.httpRequest(pieceIndex, offset, length, callback) - }) -} - -WebConn.prototype.httpRequest = function (pieceIndex, offset, length, cb) { - var self = this - var pieceOffset = pieceIndex * self._torrent.pieceLength - var rangeStart = pieceOffset + offset /* offset within whole torrent */ - var 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 - var files = self._torrent.files - var requests - if (files.length <= 1) { - requests = [{ - url: self.url, - start: rangeStart, - end: rangeEnd - }] - } else { - var requestedFiles = files.filter(function (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(function (requestedFile) { - var fileEnd = requestedFile.offset + requestedFile.length - 1 - var url = self.url + - (self.url[self.url.length - 1] === '/' ? '' : '/') + - requestedFile.path - return { - url: 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 - var numRequestsSucceeded = 0 - var hasError = false - - var ret - if (requests.length > 1) { - ret = Buffer.alloc(length) - } - - requests.forEach(function (request) { - var url = request.url - var start = request.start - var end = request.end - debug( - 'Requesting url=%s pieceIndex=%d offset=%d length=%d start=%d end=%d', - url, pieceIndex, offset, length, start, end - ) - var opts = { - url: 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, function (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, function (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, function (err, res, data) { - if (hasError) return - if (err) { - hasError = true - return cb(err) - } - onResponse(res, data) - }) - }) - } - onResponse(res, data) - }) - }) -} - -WebConn.prototype.destroy = function () { - Wire.prototype.destroy.call(this) - this._torrent = null -} - -},{"../package.json":135,"bitfield":43,"bittorrent-protocol":44,"debug":56,"inherits":65,"safe-buffer":104,"simple-get":106,"simple-sha1":108}],135:[function(require,module,exports){ -module.exports={"version":"0.97.2"} -},{}],136:[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 - } -} - -},{}],137:[function(require,module,exports){ -arguments[4][37][0].apply(exports,arguments) -},{"dup":37}],138:[function(require,module,exports){ -module.exports = extend - -var hasOwnProperty = Object.prototype.hasOwnProperty; - -function extend(target) { - for (var i = 1; i < arguments.length; i++) { - var source = arguments[i] - - for (var key in source) { - if (hasOwnProperty.call(source, key)) { - target[key] = source[key] - } - } - } - - return target -} - -},{}],139:[function(require,module,exports){ -/** - * Given a number, return a zero-filled string. - * From http://stackoverflow.com/questions/1267283/ - * @param {number} width - * @param {number} number - * @return {string} - */ -module.exports = function zeroFill (width, number, pad) { - if (number === undefined) { - return function (number, pad) { - return zeroFill(width, number, pad) - } - } - if (pad === undefined) pad = '0' - width -= number.toString().length - if (width > 0) return new Array(width + (/\./.test(number) ? 2 : 1)).join(pad) + number - return number + '' -} - -},{}],140:[function(require,module,exports){ - -module.exports = CacheP2P - -var WebTorrent = require('webtorrent'); -var sha = require('simple-sha1') -var client = new WebTorrent() -var Buffer = require('safe-buffer').Buffer -var debug = require('debug')('all') -var EventEmitter = require('events').EventEmitter -var inherits = require('inherits') - - -var cached_link_lists = {} -var all_links = [] -var added_links = [] -var history_initialized = false - -inherits(CacheP2P, EventEmitter) - -var cached_mark -function CacheP2P(opts, callback){ - var self = this - - if(typeof(opts)==='function'){ - callback = opts - } - if(document.security_sha1){ - self.security_sha1 = document.security_sha1 - } - cached_mark = opts && opts.cached_mark ? opts.cached_mark : "* "; - if (!(self instanceof CacheP2P)) return new CacheP2P(opts) - EventEmitter.call(self) - self.emit("message", "Initializing CacheP2P...") - - window.onpopstate = function(to) { - console.log('onpopstate called', to) - } - self.announceList = [ - [ 'udp://tracker.openbittorrent.com:80' ], - [ 'udp://tracker.internetwarriors.net:1337' ], - [ 'udp://tracker.leechers-paradise.org:6969' ], - [ 'udp://tracker.coppersurfer.tk:6969' ], - [ 'udp://exodus.desync.com:6969' ], - [ 'wss://tracker.btorrent.xyz' ], - [ 'wss://tracker.openwebtorrent.com' ], - ] - if(opts && opts.announceList){ - self.announceList = opts.announceList - } - - self.fetch = function(page_link){ - if(!document.security_sha1 || Object.keys(document.security_sha1).indexOf(page_link.href) > -1){ - if(Object.keys(cached_link_lists).indexOf(page_link.href) === -1){ - self.emit('message', "Pre-fetching '"+page_link.href + "' page from other peers browsing this website...") - self.emit('alert', "Please tell a friend to open this site's "+page_link.text+" to see it in action.") - added_links.push(page_link.href) - sha(page_link.href, function(result){ - - var magnet = 'magnet:?xt=urn:btih:'+result+'&dn=Unnamed+Torrent+1476541118022&tr=udp%3A%2F%2Fexodus.desync.com%3A6969&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Ftracker.internetwarriors.net%3A1337&tr=udp%3A%2F%2Ftracker.leechers-paradise.org%3A6969&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80&tr=wss%3A%2F%2Ftracker.openwebtorrent.com' - torrent = client.add(magnet, onTorrent) - - torrent.on('done', function (info) { - self.emit('webtorrent', 'Cache received') - }) - torrent.on('download', function (bytes) { - self.emit('webtorrent', 'Receiving Cache ('+bytes+' bytes)') - }) - torrent.on('wire', function (wire) { - self.emit('webtorrent', 'Peer ('+wire.remoteAddress+') connected over '+wire.type+' (Connection ID: '+wire.peerId.substr(0,10)+').') - }) - }) - } - } - } - self.scan_links = function(){ - self.emit('message', "Pre-fetching uncached links in this page... ") - var this_page_links = document.getElementsByTagName('a') - for(var i = 0; i < this_page_links.length ; i++){ - if(this_page_links[i].href && this_page_links[i].href.length !== window.location.href.length && this_page_links[i].href.indexOf(window.location.href+'#') == -1 && this_page_links[i].href.indexOf(document.domain) > -1){ - if(!document.security_sha1 || Object.keys(document.security_sha1).indexOf(this_page_links[i].href) > -1){ - if(Object.keys(cached_link_lists).indexOf(this_page_links[i].href) === -1){ - self.fetch(this_page_links[i]) - } - } - } - } - self.update_links() - } - - self.update_links = function(){ - var all_links = document.getElementsByTagName('a') - - Object.keys(cached_link_lists).forEach(function(each_url){ - var got_page = cached_link_lists[each_url] - for(var i = 0 ; i < all_links.length ; i++ ){ - if(all_links[i].href === got_page.url){ - console.log('found link that points to url', each_url) - var link_to_page = all_links[i] - self.emit('alert', "Checking sha1 of content received: "+sha.sync(got_page.page)+"...") - self.emit('success', "Got this site's '" +all_links[i].text+"' in Cache (sha1: "+got_page.page_hash+" ✔)") - self.emit('success', "The main server will not be used when '"+link_to_page.text+"' is clicked.") - - link_to_page.onclick = function(event){ - event.preventDefault(); - if(!history_initialized){ - window.history.pushState({page: document.documentElement.innerHTML, title: document.title},"", window.location.href); - } - document.documentElement.innerHTML = cached_link_lists[event.target.href].page - document.title = cached_mark+' '+cached_link_lists[event.target.href].title - // setTimeout(function(){ - // window.scrollTo(0, 0); - - // }, 10) - self.emit('cache', event) - self.emit('ready') - self.scan_links() - - window.history.pushState({page: got_page.page, title: got_page.title},"", got_page.url); - } - } - } - }) - } - - function onTorrent (torrent) { - torrent.files.forEach(function (file) { - file.getBuffer(function (err, b) { - if (err) return log(err.message) - // debug(b) - // debug(b.toString('utf8')) - var got_page = JSON.parse(b.toString('utf8')) - // self.emit('message', "Got cached version of "+got_page.url+" from web peer, modifying link to point to cache.") - - cached_link_lists[got_page.url] = got_page - self.update_links() - - window.onpopstate = function(to) { - document.documentElement.innerHTML = to.state.page - document.title = cached_mark+" "+to.state.title - window.scrollTo(0, 0); - self.emit('onpopstate', to) - - var this_page_links = document.getElementsByTagName('a') - for(var i = 0; i < this_page_links.length ; i++){ - if(Object.keys(cached_link_lists).indexOf(this_page_links[i].href) > -1){ - this_page_links[i].onclick = function(event){ - event.preventDefault(); - document.documentElement.innerHTML = cached_link_lists[event.target.href].page - document.title = cached_mark+' '+cached_link_lists[event.target.href].title - window.history.pushState({page: cached_link_lists[event.target.href].page, title: cached_link_lists[event.target.href].title},"", event.target.href); - setTimeout(function(){ - window.scrollTo(0, 0); - }, 10) - } - } else { - self.fetch(this_page_links[i]) - } - } - } - }) - }) - } - - setTimeout(function(){ - - self.emit('message', "Initializing CacheP2P") - - self.scan_links() - - var message = { - location_href: window.location.href.split('#')[0], - content: document.documentElement.innerHTML, - // css: pageCssCache, - command: 'page_loaded', - } - - var mergedPage = message.content - //mergedPage = mergedPage // + '' - sha(message.location_href, function (hash) { - sha(mergedPage, function (page_hash) { - var payload = {date: new Date(), page: mergedPage, page_hash: page_hash, url: message.location_href, title: document.title} - var buffer_payload = Buffer.from(JSON.stringify(payload), 'utf8') - self.emit('ready') - console.log('[CacheP2P] this page\'s security hash:',page_hash,'('+message.location_href+')') - var torrent = client.seed(buffer_payload,{forced_id: hash, announceList: self.announceList}, function(torrent){ - // add_to_list(torrent, message.location_href) - debug(torrent.magnetURI) - cached_link_lists[message.location_href] = payload - - torrent.on('upload', function (bytes) { - self.emit('webtorrent', 'Sending this page to peer ('+bytes+' bytes)') - }) - torrent.on('wire', function (wire) { - self.emit('webtorrent', 'Peer ('+wire.remoteAddress+') connected over '+wire.type+' (Connection ID: '+wire.peerId.substr(0,10)+').') - }) - // document.title = document.title - }); - }) - }) - - }, 100) -} - - -// document.CacheP2P = new CacheP2P() -// client.on('error', function(err){ -// document.CacheP2P.emit('webtorrent', err) -// }) -},{"debug":56,"events":8,"inherits":65,"safe-buffer":104,"simple-sha1":108,"webtorrent":128}]},{},[140])(140) -}); \ No newline at end of file +},e.reconnectTimer)):e._destroy()),"failed"===n&&e._destroy(),"closed"===n&&e._destroy()}},r.prototype.getStats=function(e){var t=this;t._pc.getStats?"undefined"!=typeof window&&window.mozRTCPeerConnection?t._pc.getStats(null,function(t){var n=[];t.forEach(function(e){n.push(e)}),e(n)},function(e){t._onError(e)}):t._pc.getStats(function(t){var n=[];t.result().forEach(function(e){var t={};e.names().forEach(function(n){t[n]=e.stat(n)}),t.id=e.id,t.type=e.type,t.timestamp=e.timestamp,n.push(t)}),e(n)}):e([])},r.prototype._maybeReady=function(){var e=this;e._debug("maybeReady pc %s channel %s",e._pcReady,e._channelReady),!e.connected&&!e._connecting&&e._pcReady&&e._channelReady&&(e._connecting=!0,e.getStats(function(t){function n(t){var n=o[t.localCandidateId],i=r[t.remoteCandidateId];n?(e.localAddress=n.ipAddress,e.localPort=Number(n.portNumber)):"string"==typeof t.googLocalAddress&&(n=t.googLocalAddress.split(":"),e.localAddress=n[0],e.localPort=Number(n[1])),e._debug("connect local: %s:%s",e.localAddress,e.localPort),i?(e.remoteAddress=i.ipAddress,e.remotePort=Number(i.portNumber),e.remoteFamily="IPv4"):"string"==typeof t.googRemoteAddress&&(i=t.googRemoteAddress.split(":"),e.remoteAddress=i[0],e.remotePort=Number(i[1]),e.remoteFamily="IPv4"),e._debug("connect remote: %s:%s",e.remoteAddress,e.remotePort)}e._connecting=!1,e.connected=!0;var r={},o={};if(t.forEach(function(e){"remotecandidate"===e.type&&(r[e.id]=e),"localcandidate"===e.type&&(o[e.id]=e)}),t.forEach(function(e){var t="googCandidatePair"===e.type&&"true"===e.googActiveConnection||"candidatepair"===e.type&&e.selected;t&&n(e)}),e._chunk){try{e.send(e._chunk)}catch(i){return e._onError(i)}e._chunk=null,e._debug('sent chunk from "write before connect"');var s=e._cb;e._cb=null,s(null)}e._interval=setInterval(function(){if(e._cb&&e._channel&&!(e._channel.bufferedAmount>e._maxBufferedAmount)){e._debug("ending backpressure: bufferedAmount %d",e._channel.bufferedAmount);var t=e._cb;e._cb=null,t(null)}},150),e._interval.unref&&e._interval.unref(),e._debug("connect"),e.emit("connect")}))},r.prototype._onSignalingStateChange=function(){var e=this;e.destroyed||(e._debug("signalingStateChange %s",e._pc.signalingState),e.emit("signalingStateChange",e._pc.signalingState))},r.prototype._onIceCandidate=function(e){var t=this;t.destroyed||(e.candidate&&t.trickle?t.emit("signal",{candidate:{candidate:e.candidate.candidate,sdpMLineIndex:e.candidate.sdpMLineIndex,sdpMid:e.candidate.sdpMid}}):e.candidate||(t._iceComplete=!0,t.emit("_iceComplete")))},r.prototype._onChannelMessage=function(e){var t=this;if(!t.destroyed){var r=e.data;t._debug("read: %d bytes",r.byteLength||r.length),r instanceof ArrayBuffer&&(r=new n(r)),t.push(r)}},r.prototype._onChannelOpen=function(){var e=this;e.connected||e.destroyed||(e._debug("on channel open"),e._channelReady=!0,e._maybeReady())},r.prototype._onChannelClose=function(){var e=this;e.destroyed||(e._debug("on channel close"),e._destroy())},r.prototype._onAddStream=function(e){var t=this;t.destroyed||(t._debug("on add stream"),t.emit("stream",e.stream))},r.prototype._onTrack=function(e){var t=this;t.destroyed||(t._debug("on track"),t.emit("stream",e.streams[0]))},r.prototype._onError=function(e){var t=this;t.destroyed||(t._debug("error %s",e.message||e),t._destroy(e))},r.prototype._debug=function(){var e=this,t=[].slice.call(arguments),n=e.channelName&&e.channelName.substring(0,7);t[0]="["+n+"] "+t[0],i.apply(null,t)}}).call(this,e("buffer").Buffer)},{buffer:5,debug:56,"get-browser-rtc":63,inherits:65,randombytes:90,"readable-stream":98}],108:[function(e,t){function n(e){return a.digest(e)}function r(e,t){return c?("string"==typeof e&&(e=o(e)),void c.digest({name:"sha-1"},e).then(function(e){t(i(new Uint8Array(e)))},function(){t(n(e))})):void setTimeout(t,0,n(e))}function o(e){for(var t=e.length,n=new Uint8Array(t),r=0;t>r;r++)n[r]=e.charCodeAt(r);return n}function i(e){for(var t=e.length,n=[],r=0;t>r;r++){var o=e[r];n.push((o>>>4).toString(16)),n.push((15&o).toString(16))}return n.join("")}var s=e("rusha"),a=new s,u=window.crypto||window.msCrypto||{},c=u.subtle||u.webkitSubtle;try{c.digest({name:"sha-1"},new Uint8Array)["catch"](function(){c=!1})}catch(f){c=!1}t.exports=r,t.exports.sync=n},{rusha:103}],109:[function(e,t){(function(n,r){function o(e,t){var r=this;if(!(r instanceof o))return new o(e,t);t||(t={}),i("new websocket: %s %o",e,t),t.allowHalfOpen=!1,null==t.highWaterMark&&(t.highWaterMark=1048576),a.Duplex.call(r,t),r.url=e,r.connected=!1,r.destroyed=!1,r._maxBufferedAmount=t.highWaterMark,r._chunk=null,r._cb=null,r._interval=null;try{r._ws="undefined"==typeof WebSocket?new c(r.url,t):new c(r.url)}catch(s){return void n.nextTick(function(){r._onError(s)})}r._ws.binaryType="arraybuffer",r._ws.onopen=function(){r._onOpen()},r._ws.onmessage=function(e){r._onMessage(e)},r._ws.onclose=function(){r._onClose()},r._ws.onerror=function(){r._onError(new Error("connection error to "+r.url))},r.on("finish",function(){r.connected?setTimeout(function(){r._destroy()},100):r.once("connect",function(){setTimeout(function(){r._destroy()},100)})})}t.exports=o;var i=e("debug")("simple-websocket"),s=e("inherits"),a=e("readable-stream"),u=e("ws"),c="undefined"!=typeof WebSocket?WebSocket:u;s(o,a.Duplex),o.WEBSOCKET_SUPPORT=!!c,o.prototype.send=function(e){var t=this,n=e.length||e.byteLength||e.size;t._ws.send(e),i("write: %d bytes",n)},o.prototype.destroy=function(e){var t=this;t._destroy(null,e)},o.prototype._destroy=function(e,t){var n=this;if(!n.destroyed){if(t&&n.once("close",t),i("destroy (error: %s)",e&&e.message),this.readable=this.writable=!1,n._readableState.ended||n.push(null),n._writableState.finished||n.end(),n.connected=!1,n.destroyed=!0,clearInterval(n._interval),n._interval=null,n._chunk=null,n._cb=null,n._ws){var r=n._ws,o=function(){r.onclose=null,n.emit("close")};if(r.readyState===c.CLOSED)o();else try{r.onclose=o,r.close()}catch(e){o()}r.onopen=null,r.onmessage=null,r.onerror=null}n._ws=null,e&&n.emit("error",e)}},o.prototype._read=function(){},o.prototype._write=function(e,t,n){var r=this;if(r.destroyed)return n(new Error("cannot write after socket is destroyed"));if(r.connected){try{r.send(e)}catch(o){return r._onError(o)}"function"!=typeof u&&r._ws.bufferedAmount>r._maxBufferedAmount?(i("start backpressure: bufferedAmount %d",r._ws.bufferedAmount),r._cb=n):n(null)}else i("write before connect"),r._chunk=e,r._cb=n},o.prototype._onMessage=function(e){var t=this;if(!t.destroyed){var n=e.data;i("read: %d bytes",n.byteLength||n.length),n instanceof ArrayBuffer&&(n=new r(n)),t.push(n)}},o.prototype._onOpen=function(){var e=this;if(!e.connected&&!e.destroyed){if(e.connected=!0,e._chunk){try{e.send(e._chunk)}catch(t){return e._onError(t)}e._chunk=null,i('sent chunk from "write before connect"');var n=e._cb;e._cb=null,n(null)}"function"!=typeof u&&(e._interval=setInterval(function(){if(e._cb&&e._ws&&!(e._ws.bufferedAmount>e._maxBufferedAmount)){i("ending backpressure: bufferedAmount %d",e._ws.bufferedAmount);var t=e._cb;e._cb=null,t(null)}},150),e._interval.unref&&e._interval.unref()),i("connect"),e.emit("connect")}},o.prototype._onClose=function(){var e=this;e.destroyed||(i("on close"),e._destroy())},o.prototype._onError=function(e){var t=this;t.destroyed||(i("error: %s",e.message||e),t._destroy(e))}}).call(this,e("_process"),e("buffer").Buffer)},{_process:16,buffer:5,debug:56,inherits:65,"readable-stream":98,ws:3}],110:[function(e,t){var n=1,r=65535,o=4,i=function(){n=n+1&r},s=setInterval(i,1e3/o|0);s.unref&&s.unref(),t.exports=function(e){var t=o*(e||5),i=[0],s=1,a=n-1&r;return function(e){var u=n-a&r;for(u>t&&(u=t),a=n;u--;)s===t&&(s=0),i[s]=i[0===s?t-1:s-1],s++;e&&(i[s-1]+=e);var c=i[s-1],f=i.length3?(a=c&255>>s,s=(s+5)%8,a=a<>8-s,o++):(a=c>>8-(s+5)&31,s=(s+5)%8,0===s&&o++),u[i]=r.charCodeAt(a),i++}for(o=i;o=r?(r=(r+5)%8,0===r?(n|=i,a[s]=n,s++,n=0):n|=255&i<<8-r):(r=(r+5)%8,n|=255&i>>>r,a[s]=n,s++,n=255&i<<8-r)}return a.slice(0,s)}}).call(this,e("buffer").Buffer)},{buffer:5}],117:[function(e,t,n){arguments[4][33][0].apply(n,arguments)},{buffer:5,dup:33}],118:[function(e,t){(function(n){function r(e){function t(e,t){var n=new i(t);return n.on("warning",o._onWarning),n.on("error",o._onError),n.listen(e),o._internalDHT=!0,n}var o=this;if(!(o instanceof r))return new r(e);if(s.call(o),!e.peerId)throw new Error("Option `peerId` is required");if(!e.infoHash)throw new Error("Option `infoHash` is required");if(!n.browser&&!e.port)throw new Error("Option `port` is required");o.peerId="string"==typeof e.peerId?e.peerId:e.peerId.toString("hex"),o.infoHash="string"==typeof e.infoHash?e.infoHash:e.infoHash.toString("hex"),o._port=e.port,o.destroyed=!1,o._announce=e.announce||[],o._intervalMs=e.intervalMs||9e5,o._trackerOpts=null,o._dhtAnnouncing=!1,o._dhtTimeout=!1,o._internalDHT=!1,o._onWarning=function(e){o.emit("warning",e)},o._onError=function(e){o.emit("error",e)},o._onDHTPeer=function(e,t){t.toString("hex")===o.infoHash&&o.emit("peer",e.host+":"+e.port)},o._onTrackerPeer=function(e){o.emit("peer",e)},o._onTrackerAnnounce=function(){o.emit("trackerAnnounce")},e.tracker===!1?o.tracker=null:e.tracker&&"object"==typeof e.tracker?(o._trackerOpts=a(e.tracker),o.tracker=o._createTracker()):o.tracker=o._createTracker(),o.dht=e.dht===!1||"function"!=typeof i?null:e.dht&&"function"==typeof e.dht.addNode?e.dht:e.dht&&"object"==typeof e.dht?t(e.dhtPort,e.dht):t(e.dhtPort),o.dht&&(o.dht.on("peer",o._onDHTPeer),o._dhtAnnounce())}t.exports=r;var o=e("debug")("torrent-discovery"),i=e("bittorrent-dht/client"),s=e("events").EventEmitter,a=e("xtend"),u=e("inherits"),c=e("run-parallel"),f=e("bittorrent-tracker/client");u(r,s),r.prototype.updatePort=function(e){var t=this;e!==t._port&&(t._port=e,t.dht&&t._dhtAnnounce(),t.tracker&&(t.tracker.stop(),t.tracker.destroy(function(){t.tracker=t._createTracker()})))},r.prototype.complete=function(e){this.tracker&&this.tracker.complete(e)},r.prototype.destroy=function(e){var t=this;if(!t.destroyed){t.destroyed=!0,clearTimeout(t._dhtTimeout);var n=[];t.tracker&&(t.tracker.stop(),t.tracker.removeListener("warning",t._onWarning),t.tracker.removeListener("error",t._onError),t.tracker.removeListener("peer",t._onTrackerPeer),t.tracker.removeListener("update",t._onTrackerAnnounce),n.push(function(e){t.tracker.destroy(e)})),t.dht&&t.dht.removeListener("peer",t._onDHTPeer),t._internalDHT&&(t.dht.removeListener("warning",t._onWarning),t.dht.removeListener("error",t._onError),n.push(function(e){t.dht.destroy(e)})),c(n,e),t.dht=null,t.tracker=null,t._announce=null}},r.prototype._createTracker=function(){var e=a(this._trackerOpts,{infoHash:this.infoHash,announce:this._announce,peerId:this.peerId,port:this._port}),t=new f(e);return t.on("warning",this._onWarning),t.on("error",this._onError),t.on("peer",this._onTrackerPeer),t.on("update",this._onTrackerAnnounce),t.setInterval(this._intervalMs),t.start(),t},r.prototype._dhtAnnounce=function(){function e(){return t._intervalMs+Math.floor(Math.random()*t._intervalMs/5)}var t=this;t._dhtAnnouncing||(o("dht announce"),t._dhtAnnouncing=!0,clearTimeout(t._dhtTimeout),t.dht.announce(t.infoHash,t._port,function(n){t._dhtAnnouncing=!1,o("dht announce complete"),n&&t.emit("warning",n),t.emit("dhtAnnounce"),t.destroyed||(t._dhtTimeout=setTimeout(function(){t._dhtAnnounce()},e()),t._dhtTimeout.unref&&t._dhtTimeout.unref())}))}}).call(this,e("_process"))},{_process:16,"bittorrent-dht/client":3,"bittorrent-tracker/client":45,debug:56,events:8,inherits:65,"run-parallel":102,xtend:137}],119:[function(e,t){(function(e){function n(e){return this instanceof n?(this.length=e,this.missing=e,this.sources=null,this._chunks=Math.ceil(e/r),this._remainder=e%r||r,this._buffered=0,this._buffer=null,this._cancellations=null,this._reservations=0,void(this._flushed=!1)):new n(e)}t.exports=n;var r=16384;n.BLOCK_LENGTH=r,n.prototype.chunkLength=function(e){return e===this._chunks-1?this._remainder:r},n.prototype.chunkLengthRemaining=function(e){return this.length-e*r},n.prototype.chunkOffset=function(e){return e*r},n.prototype.reserve=function(){return this.init()?this._cancellations.length?this._cancellations.pop():this._reservationss;s++)if(!this._buffer[e+s]){var a=s*r,u=t.slice(a,a+r);this._buffered++,this._buffer[e+s]=u,this.missing-=u.length,-1===this.sources.indexOf(n)&&this.sources.push(n)}return this._buffered===this._chunks},n.prototype.flush=function(){if(!this._buffer||this._chunks!==this._buffered)return null;var t=e.concat(this._buffer,this.length);return this._buffer=null,this._cancellations=null,this.sources=null,this._flushed=!0,t},n.prototype.init=function(){return this._flushed?!1:this._buffer?!0:(this._buffer=new Array(this._chunks),this._cancellations=[],this.sources=[],!0)}}).call(this,e("buffer").Buffer)},{buffer:5}],120:[function(e,t){(function(n){var r=e("is-typedarray").strict;t.exports=function(e){if(r(e)){var t=new n(e.buffer);return e.byteLength!==e.buffer.byteLength&&(t=t.slice(e.byteOffset,e.byteOffset+e.byteLength)),t}return new n(e)}}).call(this,e("buffer").Buffer)},{buffer:5,"is-typedarray":68}],121:[function(e,t,n){(function(e){var t=4294967295;n.encodingLength=function(){return 8},n.encode=function(n,r,o){r||(r=new e(8)),o||(o=0);var i=Math.floor(n/t),s=n-i*t;return r.writeUInt32BE(i,o),r.writeUInt32BE(s,o+4),r},n.decode=function(n,r){r||(r=0),n||(n=new e(4)),r||(r=0);var o=n.readUInt32BE(r),i=n.readUInt32BE(r+4);return o*t+i},n.encode.bytes=8,n.decode.bytes=8}).call(this,e("buffer").Buffer)},{buffer:5}],122:[function(e,t){"use strict";function n(e,t){for(var n=1,r=e.length,o=e[0],i=e[0],s=1;r>s;++s)if(i=o,o=e[s],t(o,i)){if(s===n){n++;continue}e[n++]=o}return e.length=n,e}function r(e){for(var t=1,n=e.length,r=e[0],o=e[0],i=1;n>i;++i,o=r)if(o=r,r=e[i],r!==o){if(i===t){t++;continue}e[t++]=r}return e.length=t,e}function o(e,t,o){return 0===e.length?e:t?(o||e.sort(t),n(e,t)):(o||e.sort(),r(e))}t.exports=o},{}],123:[function(e,t){function n(e,t){if(!(t>=e.length||0>t)){var n=e.pop();if(tthis._metadataSize&&(n=this._metadataSize);var r=this.metadata.slice(t,n);this._data(e,r,this._metadataSize)},t.prototype._onData=function(e,t){t.length>f||(t.copy(this.metadata,e*f),this._bitfield.set(e),this._checkDone())},t.prototype._onReject=function(e){this._remainingRejects>0&&this._fetching?(this._request(e),this._remainingRejects-=1):this.emit("warning",new Error('Peer sent "reject" too much'))},t.prototype._requestPieces=function(){this.metadata=o.alloc(this._metadataSize);for(var e=0;e0?this._requestPieces():this.emit("warning",new Error("Peer sent invalid metadata"))},t}},{bencode:41,bitfield:43,debug:56,events:8,inherits:65,"safe-buffer":104,"simple-sha1":108}],125:[function(e,t,n){arguments[4][36][0].apply(n,arguments)},{dup:36}],126:[function(e,t){(function(n){function r(e){var t=this;a.call(t),t._tracks=[],t._fragmentSequence=1,t._file=e,t._decoder=null,t._findMoov(0)}function o(e,t){var n=this;n._entries=e,n._countName=t||"count",n._index=0,n._offset=0,n.value=n._entries[0]}function i(){return{version:0,flags:0,entries:[]}}var s=e("binary-search"),a=e("events").EventEmitter,u=e("inherits"),c=e("mp4-stream"),f=e("mp4-box-encoding"),d=e("range-slice-stream");t.exports=r,u(r,a),r.prototype._findMoov=function(e){var t=this;t._decoder&&t._decoder.destroy(),t._decoder=c.decode();var n=t._file.createReadStream({start:e});n.pipe(t._decoder),t._decoder.once("box",function(r){"moov"===r.type?t._decoder.decode(function(e){n.destroy();try{t._processMoov(e)}catch(r){r.message="Cannot parse mp4 file: "+r.message,t.emit("error",r)}}):(n.destroy(),t._findMoov(e+r.length))})},o.prototype.inc=function(){var e=this;e._offset++,e._offset>=e._entries[e._index][e._countName]&&(e._index++,e._offset=0),e.value=e._entries[e._index]},r.prototype._processMoov=function(e){var t=this,r=e.traks;t._tracks=[],t._hasVideo=!1,t._hasAudio=!1;for(var s=0;s=d.stsz.entries.length)break;if(g++,_+=S,g>=x.samplesPerChunk){g=0,_=0,y++;var T=d.stsc.entries[v+1];T&&y+1>=T.firstChunk&&v++}b+=B,w.inc(),E&&E.inc(),I&&k++}c.mdia.mdhd.duration=0,c.tkhd.duration=0;var C=x.sampleDescriptionId,L={type:"moov",mvhd:e.mvhd,traks:[{tkhd:c.tkhd,mdia:{mdhd:c.mdia.mdhd,hdlr:c.mdia.hdlr,elng:c.mdia.elng,minf:{vmhd:c.mdia.minf.vmhd,smhd:c.mdia.minf.smhd,dinf:c.mdia.minf.dinf,stbl:{stsd:d.stsd,stts:i(),ctts:i(),stsc:i(),stsz:i(),stco:i(),stss:i()}}}}],mvex:{mehd:{fragmentDuration:e.mvhd.duration},trexs:[{trackId:c.tkhd.trackId,defaultSampleDescriptionIndex:C,defaultSampleDuration:0,defaultSampleSize:0,defaultSampleFlags:0}]}};t._tracks.push({trackId:c.tkhd.trackId,timeScale:c.mdia.mdhd.timeScale,samples:p,currSample:null,currTime:null,moov:L,mime:u})}if(0===t._tracks.length)return void t.emit("error",new Error("no playable tracks"));e.mvhd.duration=0,t._ftyp={type:"ftyp",brand:"iso5",brandVersion:0,compatibleBrands:["iso5"]};var R=f.encode(t._ftyp),U=t._tracks.map(function(e){var t=f.encode(e.moov);return{mime:e.mime,init:n.concat([R,t])}});t.emit("ready",U)},r.prototype.seek=function(e){var t=this;if(!t._tracks)throw new Error("Not ready yet; wait for 'ready' event");t._fileStream&&(t._fileStream.destroy(),t._fileStream=null);var n=-1;if(t._tracks.map(function(r,o){function i(e){s.destroyed||s.box(e.moof,function(n){if(n)return t.emit("error",n);if(!s.destroyed){var a=r.inStream.slice(e.ranges);a.pipe(s.mediaData(e.length,function(e){if(e)return t.emit("error",e);if(!s.destroyed){var n=t._generateFragment(o);return n?void i(n):s.finalize()}}))}})}r.outStream&&r.outStream.destroy(),r.inStream&&(r.inStream.destroy(),r.inStream=null);var s=r.outStream=c.encode(),a=t._generateFragment(o,e);return a?((-1===n||a.ranges[0].start=0){var r=t._fileStream=t._file.createReadStream({start:n});t._tracks.forEach(function(e){e.inStream=new d(n),r.pipe(e.inStream)})}return t._tracks.map(function(e){return e.outStream})},r.prototype._findSampleBefore=function(e,t){var n=this,r=n._tracks[e],o=Math.floor(r.timeScale*t),i=s(r.samples,o,function(e,t){var n=e.dts+e.presentationOffset;return n-t});for(-1===i?i=0:0>i&&(i=-i-2);!r.samples[i].sync;)i--;return i};var h=1;r.prototype._generateFragment=function(e,t){var n,r=this,o=r._tracks[e];if(n=void 0!==t?r._findSampleBefore(e,t):o.currSample,n>=o.samples.length)return null;for(var i=o.samples[n].dts,s=0,a=[],u=n;u=o.timeScale*h)break;s+=c.size;var f=a.length-1;0>f||a[f].end!==c.offset?a.push({start:c.offset,end:c.offset+c.size}):a[f].end+=c.size}return o.currSample=u,{moof:r._generateMoof(e,n,u),ranges:a,length:s}},r.prototype._generateMoof=function(e,t,n){for(var r=this,o=r._tracks[e],i=[],s=t;n>s;s++){var a=o.samples[s];i.push({sampleDuration:a.duration,sampleSize:a.size,sampleFlags:a.sync?33554432:16842752,sampleCompositionTimeOffset:a.presentationOffset})}var u={type:"moof",mfhd:{sequenceNumber:r._fragmentSequence++},trafs:[{tfhd:{flags:131072,trackId:o.trackId},tfdt:{baseMediaDecodeTime:o.samples[t].dts},trun:{flags:3841,dataOffset:8,entries:i}}]};return u.trafs[0].trun.dataOffset+=f.encodingLength(u),u}}).call(this,e("buffer").Buffer)},{"binary-search":42,buffer:5,events:8,inherits:65,"mp4-box-encoding":76,"mp4-stream":79,"range-slice-stream":91}],127:[function(e,t){function n(e,t,o){var i=this;return this instanceof n?(o=o||{},i.detailedError=null,i._elem=t,i._elemWrapper=new r(t),i._waitingFired=!1,i._trackMeta=null,i._file=e,i._tracks=null,"none"!==i._elem.preload&&i._createMuxer(),i._onError=function(){i.detailedError=i._elemWrapper.detailedError,i.destroy()},i._onWaiting=function(){i._waitingFired=!0,i._muxer?i._tracks&&i._pump():i._createMuxer()},i._elem.addEventListener("waiting",i._onWaiting),void i._elem.addEventListener("error",i._onError)):new n(e,t,o)}var r=e("mediasource"),o=e("pump"),i=e("./mp4-remuxer");t.exports=n,n.prototype._createMuxer=function(){var e=this;e._muxer=new i(e._file),e._muxer.on("ready",function(t){e._tracks=t.map(function(t){var n=e._elemWrapper.createWriteStream(t.mime);n.on("error",function(t){e._elemWrapper.error(t)});var r={muxed:null,mediaSource:n,initFlushed:!1,onInitFlushed:null};return n.write(t.init,function(e){r.initFlushed=!0,r.onInitFlushed&&r.onInitFlushed(e)}),r}),(e._waitingFired||"auto"===e._elem.preload)&&e._pump()}),e._muxer.on("error",function(t){e._elemWrapper.error(t)})},n.prototype._pump=function(){var e=this,t=e._muxer.seek(e._elem.currentTime,!e._tracks);e._tracks.forEach(function(n,r){var i=function(){n.muxed&&(n.muxed.destroy(),n.mediaSource=e._elemWrapper.createWriteStream(n.mediaSource),n.mediaSource.on("error",function(t){e._elemWrapper.error(t)})),n.muxed=t[r],o(n.muxed,n.mediaSource)};n.initFlushed?i():n.onInitFlushed=function(t){return t?void e._elemWrapper.error(t):void i()}})},n.prototype.destroy=function(){var e=this;e.destroyed||(e.destroyed=!0,e._elem.removeEventListener("waiting",e._onWaiting),e._elem.removeEventListener("error",e._onError),e._tracks&&e._tracks.forEach(function(e){e.muxed.destroy()}),e._elem.src="")}},{"./mp4-remuxer":126,mediasource:72,pump:88}],128:[function(e,t){(function(n,r){function o(e){function t(){i.destroyed||(i.ready=!0,i.emit("ready"))}var i=this;return i instanceof o?(h.call(i),e||(e={}),i.peerId="string"==typeof e.peerId?e.peerId:a.isBuffer(e.peerId)?e.peerId.toString("hex"):a.from(A+b(9).toString("base64")).toString("hex"),i.peerIdBuffer=a.from(i.peerId,"hex"),i.nodeId="string"==typeof e.nodeId?e.nodeId:a.isBuffer(e.nodeId)?e.nodeId.toString("hex"):b(20).toString("hex"),i.nodeIdBuffer=a.from(i.nodeId,"hex"),i.destroyed=!1,i.listening=!1,i.torrentPort=e.torrentPort||0,i.dhtPort=e.dhtPort||0,i.tracker=void 0!==e.tracker?e.tracker:{},i.torrents=[],i.maxConns=Number(e.maxConns)||55,f("new webtorrent (peerId %s, nodeId %s, port %s)",i.peerId,i.nodeId,i.torrentPort),i.tracker&&("object"!=typeof i.tracker&&(i.tracker={}),e.rtcConfig&&(console.warn("WebTorrent: opts.rtcConfig is deprecated. Use opts.tracker.rtcConfig instead"),i.tracker.rtcConfig=e.rtcConfig),e.wrtc&&(console.warn("WebTorrent: opts.wrtc is deprecated. Use opts.tracker.wrtc instead"),i.tracker.wrtc=e.wrtc),r.WRTC&&!i.tracker.wrtc&&(i.tracker.wrtc=r.WRTC)),"function"==typeof k?i._tcpPool=new k(i):n.nextTick(function(){i._onListening()}),i._downloadSpeed=w(),i._uploadSpeed=w(),e.dht!==!1&&"function"==typeof d?(i.dht=new d(l({nodeId:i.nodeId},e.dht)),i.dht.once("error",function(e){i._destroy(e)}),i.dht.once("listening",function(){var e=i.dht.address();e&&(i.dhtPort=e.port)}),i.dht.setMaxListeners(0),i.dht.listen(i.dhtPort)):i.dht=!1,i.enableWebSeeds=e.webSeeds!==!1,void("function"==typeof m&&null!=e.blocklist?m(e.blocklist,{headers:{"user-agent":"WebTorrent/"+S+" (https://webtorrent.io)"}},function(e,n){return e?i.error("Failed to load blocklist: "+e.message):(i.blocked=n,void t())}):n.nextTick(t))):new o(e)}function i(e){return"object"==typeof e&&null!=e&&"function"==typeof e.pipe}function s(e){return"undefined"!=typeof FileList&&e instanceof FileList}t.exports=o;var a=e("safe-buffer").Buffer,u=e("simple-concat"),c=e("create-torrent"),f=e("debug")("webtorrent"),d=e("bittorrent-dht/client"),h=e("events").EventEmitter,l=e("xtend"),p=e("inherits"),m=e("load-ip-set"),g=e("run-parallel"),y=e("parse-torrent"),_=e("path"),v=e("simple-peer"),b=e("randombytes"),w=e("speedometer"),E=e("zero-fill"),k=e("./lib/tcp-pool"),x=e("./lib/torrent"),S=e("./package.json").version,B=S.match(/([0-9]+)/g).slice(0,2).map(function(e){return E(2,e)}).join(""),A="-WW"+B+"-";p(o,h),o.WEBRTC_SUPPORT=v.WEBRTC_SUPPORT,Object.defineProperty(o.prototype,"downloadSpeed",{get:function(){return this._downloadSpeed()}}),Object.defineProperty(o.prototype,"uploadSpeed",{get:function(){return this._uploadSpeed()}}),Object.defineProperty(o.prototype,"progress",{get:function(){var e=this.torrents.filter(function(e){return 1!==e.progress}),t=e.reduce(function(e,t){return e+t.downloaded},0),n=e.reduce(function(e,t){return e+(t.length||0)},0)||1;return t/n}}),Object.defineProperty(o.prototype,"ratio",{get:function(){var e=this.torrents.reduce(function(e,t){return e+t.uploaded},0),t=this.torrents.reduce(function(e,t){return e+t.received},0)||1;return e/t}}),o.prototype.get=function(e){var t,n,r=this,o=r.torrents.length;if(e instanceof x){for(t=0;o>t;t++)if(n=r.torrents[t],n===e)return n}else{var i;try{i=y(e)}catch(s){}if(!i)return null;if(!i.infoHash)throw new Error("Invalid torrent identifier");for(t=0;o>t;t++)if(n=r.torrents[t],n.infoHash===i.infoHash)return n}return null},o.prototype.download=function(e,t,n){return console.warn("WebTorrent: client.download() is deprecated. Use client.add() instead"),this.add(e,t,n)},o.prototype.add=function(e,t,n){function r(){if(!s.destroyed)for(var e=0,t=s.torrents.length;t>e;e++){var n=s.torrents[e];if(n.infoHash===a.infoHash&&n!==a)return void a._destroy(new Error("Cannot add duplicate torrent "+a.infoHash))}}function o(){s.destroyed||("function"==typeof n&&n(a),s.emit("torrent",a))}function i(){a.removeListener("_infoHash",r),a.removeListener("ready",o),a.removeListener("close",i)}var s=this;if(s.destroyed)throw new Error("client is destroyed");if("function"==typeof t)return s.add(e,null,t);f("add"),t=t?l(t):{};var a=new x(e,s,t);return s.torrents.push(a),a.once("_infoHash",r),a.once("ready",o),a.once("close",i),a},o.prototype.seed=function(e,t,n){function r(e){var t=[function(t){e.load(d,t)}];a.dht&&t.push(function(t){e.once("dhtAnnounce",t)}),g(t,function(t){return a.destroyed?void 0:t?e._destroy(t):void o(e)})}function o(e){f("on seed"),"function"==typeof n&&n(e),e.emit("seed"),a.emit("seed",e)}var a=this;if(a.destroyed)throw new Error("client is destroyed");if("function"==typeof t)return a.seed(e,null,t);f("seed"),t=t?l(t):{},"string"==typeof e&&(t.path=_.dirname(e)),t.createdBy||(t.createdBy="WebTorrent/"+B);var d,h=a.add(null,t,r);return s(e)&&(e=Array.prototype.slice.call(e)),Array.isArray(e)||(e=[e]),g(e.map(function(e){return function(t){i(e)?u(e,t):t(null,e)}}),function(e,n){return a.destroyed?void 0:e?h._destroy(e):void c.parseInput(n,t,function(e,r){if(!a.destroyed){if(e)return h._destroy(e);d=r.map(function(e){return e.getStream}),c(n,t,function(e,n){ +if(!a.destroyed){if(e)return h._destroy(e);var r=a.get(n);r?h._destroy(new Error("Cannot add duplicate torrent "+r.infoHash)):h._onTorrentId(n,t.forced_id)}})}})}),h},o.prototype.remove=function(e,t){f("remove");var n=this.get(e);if(!n)throw new Error("No torrent with id "+e);this._remove(e,t)},o.prototype._remove=function(e,t){var n=this.get(e);n&&(this.torrents.splice(this.torrents.indexOf(n),1),n.destroy(t))},o.prototype.address=function(){return this.listening?this._tcpPool?this._tcpPool.server.address():{address:"0.0.0.0",family:"IPv4",port:0}:null},o.prototype.destroy=function(e){if(this.destroyed)throw new Error("client already destroyed");this._destroy(null,e)},o.prototype._destroy=function(e,t){var n=this;f("client destroy"),n.destroyed=!0;var r=n.torrents.map(function(e){return function(t){e.destroy(t)}});n._tcpPool&&r.push(function(e){n._tcpPool.destroy(e)}),n.dht&&r.push(function(e){n.dht.destroy(e)}),g(r,t),e&&n.emit("error",e),n.torrents=[],n._tcpPool=null,n.dht=null},o.prototype._onListening=function(){if(this.listening=!0,this._tcpPool){var e=this._tcpPool.server.address();e&&(this.torrentPort=e.port)}this.emit("listening")}}).call(this,e("_process"),"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./lib/tcp-pool":3,"./lib/torrent":133,"./package.json":135,_process:16,"bittorrent-dht/client":3,"create-torrent":55,debug:56,events:8,inherits:65,"load-ip-set":3,"parse-torrent":85,path:14,randombytes:90,"run-parallel":102,"safe-buffer":104,"simple-concat":105,"simple-peer":107,speedometer:110,xtend:137,"zero-fill":139}],129:[function(e,t){function n(e,t){i.Readable.call(this,t),this.destroyed=!1,this._torrent=e._torrent;var n=t&&t.start||0,r=t&&t.end&&t.endi&&(t=[o],n=i)}return t.length>0?t[Math.random()*t.length|0]:-1},n.prototype.destroy=function(){var e=this;e._torrent.removeListener("wire",e._onWire),e._torrent.wires.forEach(function(t){e._cleanupWireEvents(t)}),e._torrent=null,e._pieces=null,e._onWire=null,e._onWireHave=null,e._onWireBitfield=null},n.prototype._initWire=function(e){var t=this;e._onClose=function(){t._cleanupWireEvents(e);for(var n=0;ne;++e)for(var n=this._torrent.wires[e],r=0;rt;++t)if(this.bitfield.get(t))e+=t===n-1?this.lastPieceLength:this.pieceLength;else{var r=this.pieces[t];e+=r.length-r.missing}return e}}),Object.defineProperty(o.prototype,"downloadSpeed",{get:function(){return this._downloadSpeed()}}),Object.defineProperty(o.prototype,"uploadSpeed",{get:function(){return this._uploadSpeed()}}),Object.defineProperty(o.prototype,"progress",{get:function(){return this.length?this.downloaded/this.length:0}}),Object.defineProperty(o.prototype,"ratio",{get:function(){return this.uploaded/(this.received||1)}}),Object.defineProperty(o.prototype,"numPeers",{get:function(){return this.wires.length}}),Object.defineProperty(o.prototype,"torrentFileBlobURL",{get:function(){if("undefined"==typeof window)throw new Error("browser-only property");return this.torrentFile?URL.createObjectURL(new Blob([this.torrentFile],{type:"application/x-bittorrent"})):null}}),Object.defineProperty(o.prototype,"_numQueued",{get:function(){return this._queue.length+(this._peersLength-this._numConns)}}),Object.defineProperty(o.prototype,"_numConns",{get:function(){var e=this,t=0;for(var n in e._peers)e._peers[n].connected&&(t+=1);return t}}),Object.defineProperty(o.prototype,"swarm",{get:function(){return console.warn("WebTorrent: `torrent.swarm` is deprecated. Use `torrent` directly instead."),this}}),o.prototype._onTorrentId=function(e,t){var r=this;if(!r.destroyed){var o;try{o=I(e)}catch(i){}o?(r.infoHash=o.infoHash,n.nextTick(function(){r.destroyed||r._onParsedTorrent(o,t)})):I.remote(e,function(e,n){return r.destroyed?void 0:e?r._destroy(e):void r._onParsedTorrent(n,t)})}},o.prototype._onParsedTorrent=function(e,t){var n=this;if(!n.destroyed){if(n._processParsedTorrent(e),!n.infoHash)return n._destroy(new Error("Malformed torrent data: No info hash"));n.path||(n.path=T.join(c,n.infoHash)),n._rechokeIntervalId=setInterval(function(){n._rechoke()},$),n._rechokeIntervalId.unref&&n._rechokeIntervalId.unref(),t?(n.emit("_infoHash",t),n.emit("infoHash",t),n.infoHash=t):(n.emit("_infoHash",n.infoHash),n.emit("infoHash",n.infoHash)),n.destroyed||(n.client.listening?n._onListening():n.client.once("listening",function(){n._onListening()}))}},o.prototype._processParsedTorrent=function(e){this.announce&&(e.announce=e.announce.concat(this.announce)),this.client.tracker&&r.WEBTORRENT_ANNOUNCE&&!this["private"]&&(e.announce=e.announce.concat(r.WEBTORRENT_ANNOUNCE)),this.urlList&&(e.urlList=e.urlList.concat(this.urlList)),O(e.announce),O(e.urlList),y(this,e),this.magnetURI=I.toMagnetURI(e),this.torrentFile=I.toTorrentFile(e)},o.prototype._onListening=function(){function e(e){i._destroy(e)}function t(e){"string"==typeof e&&i.done||i.addPeer(e)}function n(){i.emit("trackerAnnounce"),0===i.numPeers&&i.emit("noPeers","tracker")}function r(){i.emit("dhtAnnounce"),0===i.numPeers&&i.emit("noPeers","dht")}function o(e){i.emit("warning",e)}var i=this;if(!i.discovery&&!i.destroyed){var s=i.client.tracker;s&&(s=g(i.client.tracker,{getAnnounceOpts:function(){var e={uploaded:i.uploaded,downloaded:i.downloaded,left:Math.max(i.length-i.downloaded,0)};return i.client.tracker.getAnnounceOpts&&y(e,i.client.tracker.getAnnounceOpts()),i._getAnnounceOpts&&y(e,i._getAnnounceOpts()),e}})),i.discovery=new p({infoHash:i.infoHash,announce:i.announce,peerId:i.client.peerId,dht:!i["private"]&&i.client.dht,tracker:s,port:i.client.torrentPort}),i.discovery.on("error",e),i.discovery.on("peer",t),i.discovery.on("trackerAnnounce",n),i.discovery.on("dhtAnnounce",r),i.discovery.on("warning",o),i.info?i._onMetadata(i):i.xs&&i._getMetadataFromServer()}},o.prototype._getMetadataFromServer=function(){function e(e,n){function r(r,o,i){if(t.destroyed)return n(null);if(t.metadata)return n(null);if(r)return t._debug("http error from xs param: %s",e),n(null);if(200!==o.statusCode)return t._debug("non-200 status code %s from xs param: %s",o.statusCode,e),n(null);var s;try{s=I(i)}catch(r){}return s?s.infoHash!==t.infoHash?(t._debug("got torrent file with incorrect info hash from xs param: %s",e),n(null)):(t._onMetadata(s),void n(null)):(t._debug("got invalid torrent file from xs param: %s",e),n(null))}if(0!==e.indexOf("http://")&&0!==e.indexOf("https://"))return t._debug("skipping non-http xs param: %s",e),n(null);var o,i={url:e,method:"GET",headers:{"user-agent":"WebTorrent/"+Q+" (https://webtorrent.io)"}};try{o=b.concat(i,r)}catch(s){return t._debug("skipping invalid url xs param: %s",e),n(null)}t._xsRequests.push(o)}var t=this,n=Array.isArray(t.xs)?t.xs:[t.xs],r=n.map(function(t){return function(n){e(t,n)}});B(r)},o.prototype._onMetadata=function(e){var t=this;if(!t.metadata&&!t.destroyed){t._debug("got metadata"),t._xsRequests.forEach(function(e){e.abort()}),t._xsRequests=[];var n;if(e&&e.infoHash)n=e;else try{n=I(e)}catch(r){return t._destroy(r)}t._processParsedTorrent(n),t.metadata=t.torrentFile,t.client.enableWebSeeds&&t.urlList.forEach(function(e){t.addWebSeed(e)}),0!==t.pieces.length&&t.select(0,t.pieces.length-1,!1),t._rarityMap=new q(t),t.store=new w(new t._store(t.pieceLength,{torrent:{infoHash:t.infoHash},files:t.files.map(function(e){return{path:T.join(t.path,e.path),length:e.length,offset:e.offset}}),length:t.length})),t.files=t.files.map(function(e){return new H(t,e)}),t._hashes=t.pieces,t.pieces=t.pieces.map(function(e,n){var r=n===t.pieces.length-1?t.lastPieceLength:t.pieceLength;return new C(r)}),t._reservations=t.pieces.map(function(){return[]}),t.bitfield=new d(t.pieces.length),t.wires.forEach(function(e){e.ut_metadata&&e.ut_metadata.setMetadata(t.metadata),t._onWireWithMetadata(e)}),t._debug("verifying existing torrent data"),t._fileModtimes&&t._store===v?t.getFileModtimes(function(e,n){if(e)return t._destroy(e);var r=t.files.map(function(e,r){return n[r]===t._fileModtimes[r]}).every(function(e){return e});if(r){for(var o=0;oe||e>t||o.pieces.length<=t)throw new Error("invalid selection ",e,":",t);n=Number(n)||0,o._debug("select %s-%s (priority %s)",e,t,n),o._selections.push({from:e,to:t,offset:0,priority:n,notify:r||u}),o._selections.sort(function(e,t){return t.priority-e.priority}),o._updateSelections()},o.prototype.deselect=function(e,t,n){var r=this;if(r.destroyed)throw new Error("torrent is destroyed");n=Number(n)||0,r._debug("deselect %s-%s (priority %s)",e,t,n);for(var o=0;o=r;++r)n._critical[r]=!0;n._updateSelections()},o.prototype._onWire=function(e,t){var r=this;if(r._debug("got wire %s (%s)",e._debugId,t||"Unknown"),e.on("download",function(e){r.destroyed||(r.received+=e,r._downloadSpeed(e),r.client._downloadSpeed(e),r.emit("download",e),r.client.emit("download",e))}),e.on("upload",function(e){r.destroyed||(r.uploaded+=e,r._uploadSpeed(e),r.client._uploadSpeed(e),r.emit("upload",e),r.client.emit("upload",e))}),r.wires.push(e),t){var o=f(t);e.remoteAddress=o[0],e.remotePort=o[1]}r.client.dht&&r.client.dht.listening&&e.on("port",function(n){if(!r.destroyed&&!r.client.dht.destroyed){if(!e.remoteAddress)return r._debug("ignoring PORT from peer with no address");if(0===n||n>65536)return r._debug("ignoring invalid PORT from peer");r._debug("port: %s (from %s)",n,t),r.client.dht.addNode({host:e.remoteAddress,port:n})}}),e.on("timeout",function(){r._debug("wire timeout (%s)",t),e.destroy()}),e.setTimeout(W,!0),e.setKeepAlive(!0),e.use(M(r.metadata)),e.ut_metadata.on("warning",function(e){r._debug("ut_metadata warning: %s",e.message)}),r.metadata||(e.ut_metadata.on("metadata",function(e){r._debug("got metadata via ut_metadata"),r._onMetadata(e)}),e.ut_metadata.fetch()),"function"!=typeof j||r["private"]||(e.use(j()),e.ut_pex.on("peer",function(e){r.done||(r._debug("ut_pex: got peer: %s (from %s)",e,t),r.addPeer(e))}),e.ut_pex.on("dropped",function(e){var n=r._peers[e];n&&!n.connected&&(r._debug("ut_pex: dropped peer: %s (from %s)",e,t),r.removePeer(e))}),e.once("close",function(){e.ut_pex.reset()})),r.emit("wire",e,t),r.metadata&&n.nextTick(function(){r._onWireWithMetadata(e)})},o.prototype._onWireWithMetadata=function(e){function t(){r.destroyed||e.destroyed||(r._numQueued>2*(r._numConns-r.numPeers)&&e.amInterested?e.destroy():(o=setTimeout(t,F),o.unref&&o.unref()))}function n(){if(e.peerPieces.length===r.pieces.length){for(;iz?e.destroy():void(r.pieces[t]||r.store.get(t,{offset:n,length:o},i))}),e.bitfield(r.bitfield),e.interested(),e.peerExtensions.dht&&r.client.dht&&r.client.dht.listening&&e.port(r.client.dht.address().port),o=setTimeout(t,F),o.unref&&o.unref(),e.isSeeder=!1,n()},o.prototype._updateSelections=function(){var e=this;e.ready&&!e.destroyed&&(n.nextTick(function(){e._gcSelections()}),e._updateInterest(),e._update())},o.prototype._gcSelections=function(){for(var e=this,t=0;t=t&&n>=i&&!(i in r)&&e.peerPieces.get(i)&&(!o||o(i))}}function n(){if(!e.requests.length)for(var n=a._selections.length;n--;){var r,o=a._selections[n];if("rarest"===a.strategy)for(var i=o.from+o.offset,s=o.to,u=s-i+1,c={},f=0,d=t(i,s,c);u>f&&(r=a._rarityMap.getRarestPiece(d),!(0>r));){if(a._request(e,r,!1))return;c[r]=!0,f+=1}else for(r=o.to;r>=o.from+o.offset;--r)if(e.peerPieces.get(r)&&a._request(e,r,!1))return}}function r(){var t=e.downloadSpeed()||1;if(t>Y)return function(){return!0};var n=Math.max(1,e.requests.length)*C.BLOCK_LENGTH/t,r=10,o=0;return function(e){if(!r||a.bitfield.get(e))return!0;for(var i=a.pieces[e].missing;ou||t>=u||!s.peerPieces.get(e)||(i-=u*n)>0))return r--,!1}return!0}}function o(e){for(var t=e,n=e;n=c)return!0;for(var i=r(),s=0;sm&&(u=a._rarityMap.getRarestPiece(g),!(0>u));){for(;a._request(e,u,a._critical[u]||n););if(!(e.requests.length=u)){var c=i(e,G);s(!1)||s(!0)}}},o.prototype._rechoke=function(){function e(e,t){return e.downloadSpeed!==t.downloadSpeed?t.downloadSpeed-e.downloadSpeed:e.uploadSpeed!==t.uploadSpeed?t.uploadSpeed-e.uploadSpeed:e.wire.amChoking!==t.wire.amChoking?e.wire.amChoking?1:-1:e.salt-t.salt}var t=this;if(t.ready){t._rechokeOptimisticTime>0?t._rechokeOptimisticTime-=1:t._rechokeOptimisticWire=null;var n=[];t.wires.forEach(function(e){e.isSeeder||e===t._rechokeOptimisticWire||n.push({wire:e,downloadSpeed:e.downloadSpeed(),uploadSpeed:e.uploadSpeed(),salt:Math.random(),isChoked:!0})}),n.sort(e);for(var r=0,o=0;o=Y||2*c>r||c>a||(i=u,a=c)}}if(!i)return!1;for(s=0;s=f)return!1;var d=a.pieces[t],h=c?d.reserveRemaining():d.reserve();if(-1===h&&r&&a._hotswap(e,t)&&(h=c?d.reserveRemaining():d.reserve()),-1===h)return!1;var l=a._reservations[t];l||(l=a._reservations[t]=[]);var p=l.indexOf(null);-1===p&&(p=l.length),l[p]=e;var m=d.chunkOffset(h),g=c?d.chunkLengthRemaining(h):d.chunkLength(h);return e.request(t,m,g,function y(n,r){if(!a.ready)return a.once("ready",function(){y(n,r)});if(l[p]===e&&(l[p]=null),d!==a.pieces[t])return o();if(n)return a._debug("error getting piece %s (offset: %s length: %s) from %s: %s",t,m,g,e.remoteAddress+":"+e.remotePort,n.message),c?d.cancelRemaining(h):d.cancel(h),void o();if(a._debug("got piece %s (offset: %s length: %s) from %s",t,m,g,e.remoteAddress+":"+e.remotePort),!d.set(h,r,e))return o();var i=d.flush();U(i,function(e){if(e===a._hashes[t]){if(!a.pieces[t])return;a._debug("piece verified %s",t),a.pieces[t]=null,a._reservations[t]=null,a.bitfield.set(t,!0),a.store.put(t,i),a.wires.forEach(function(e){e.have(t)}),a._checkDone()}else a.pieces[t]=new C(d.length),a.emit("warning",new Error("Piece "+t+" failed verification"));o()})}),!0},o.prototype._checkDone=function(){var e=this;if(!e.destroyed){e.files.forEach(function(t){if(!t.done){for(var n=t._startPiece;n<=t._endPiece;++n)if(!e.bitfield.get(n))return;t.done=!0,t.emit("done"),e._debug("file done: "+t.name)}});for(var t=!0,n=0;n=e.client.maxConns)){this._debug("drain (%s queued, %s/%s peers)",e._numQueued,e.numPeers,e.client.maxConns);var t=e._queue.shift();if(t){this._debug("tcp connect attempt to %s",t.addr);var n=f(t.addr),r={host:n[0],port:n[1]},o=t.conn=x.connect(r);o.once("connect",function(){t.onConnect()}),o.once("error",function(e){t.destroy(e)}),t.startConnectTimeout(),o.on("close",function(){if(!e.destroyed){if(t.retries>=J.length)return void e._debug("conn %s closed: will not re-add (max %s attempts)",t.addr,J.length);var n=J[t.retries];e._debug("conn %s closed: will re-add to queue in %sms (attempt %s)",t.addr,n,t.retries+1);var r=setTimeout(function(){var n=e._addPeer(t.addr);n&&(n.retries=t.retries+1)},n);r.unref&&r.unref()}})}}},o.prototype._validAddr=function(e){var t;try{t=f(e)}catch(n){return!1}var r=t[0],o=t[1];return o>0&&65535>o&&!("127.0.0.1"===r&&o===this.client.torrentPort)}}).call(this,e("_process"),"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"../package.json":135,"./file":130,"./peer":131,"./rarity-map":132,"./server":3,_process:16,"addr-to-ip-port":38,bitfield:43,"chunk-store-stream/write":52,debug:56,events:8,fs:1,"fs-chunk-store":73,"immediate-chunk-store":64,inherits:65,multistream:81,net:3,os:3,"parse-torrent":85,path:14,pump:88,"random-iterate":89,"run-parallel":102,"run-parallel-limit":101,"simple-get":106,"simple-sha1":108,speedometer:110,"torrent-discovery":118,"torrent-piece":119,uniq:122,ut_metadata:124,ut_pex:3,xtend:137,"xtend/mutable":138}],134:[function(e,t){function n(e,t){c.call(this),this.url=e,this.webPeerId=u.sync(e),this._torrent=t,this._init()}t.exports=n;var r=e("bitfield"),o=e("safe-buffer").Buffer,i=e("debug")("webtorrent:webconn"),s=e("simple-get"),a=e("inherits"),u=e("simple-sha1"),c=e("bittorrent-protocol"),f=e("../package.json").version;a(n,c),n.prototype._init=function(){var e=this;e.setKeepAlive(!0),e.once("handshake",function(t){if(!e.destroyed){e.handshake(t,e.webPeerId);for(var n=e._torrent.pieces.length,o=new r(n),i=0;n>=i;i++)o.set(i,!0);e.bitfield(o)}}),e.once("interested",function(){i("interested"),e.unchoke()}),e.on("uninterested",function(){i("uninterested")}),e.on("choke",function(){i("choke")}),e.on("unchoke",function(){i("unchoke")}),e.on("bitfield",function(){i("bitfield")}),e.on("request",function(t,n,r,o){i("request pieceIndex=%d offset=%d length=%d",t,n,r),e.httpRequest(t,n,r,o)})},n.prototype.httpRequest=function(e,t,n,r){var a,u=this,c=e*u._torrent.pieceLength,d=c+t,h=d+n-1,l=u._torrent.files;if(l.length<=1)a=[{url:u.url,start:d,end:h}];else{var p=l.filter(function(e){return e.offset<=h&&e.offset+e.length>d});if(p.length<1)return r(new Error("Could not find file corresponnding to web seed range request"));a=p.map(function(e){var t=e.offset+e.length-1,n=u.url+("/"===u.url[u.url.length-1]?"":"/")+e.path;return{url:n,fileOffsetInRange:Math.max(e.offset-d,0),start:Math.max(d-e.offset,0),end:Math.min(t,h-e.offset)}})}var m,g=0,y=!1;a.length>1&&(m=o.alloc(n)),a.forEach(function(o){function u(e,t){return e.statusCode<200||e.statusCode>=300?(y=!0,r(new Error("Unexpected HTTP status code "+e.statusCode))):(i("Got data of length %d",t.length),void(1===a.length?r(null,t):(t.copy(m,o.fileOffsetInRange),++g===a.length&&r(null,m))))}var c=o.url,d=o.start,h=o.end;i("Requesting url=%s pieceIndex=%d offset=%d length=%d start=%d end=%d",c,e,t,n,d,h);var l={url:c,method:"GET",headers:{"user-agent":"WebTorrent/"+f+" (https://webtorrent.io)",range:"bytes="+d+"-"+h}};s.concat(l,function(e,t,n){return y?void 0:e?"undefined"==typeof window||c.startsWith(window.location.origin+"/")?(y=!0,r(e)):s.head(c,function(t,n){if(!y){if(t)return y=!0,r(t);if(n.statusCode<200||n.statusCode>=300)return y=!0,r(new Error("Unexpected HTTP status code "+n.statusCode));if(n.url===c)return y=!0,r(e);l.url=n.url,s.concat(l,function(e,t,n){return y?void 0:e?(y=!0,r(e)):void u(t,n)})}}):void u(t,n)})})},n.prototype.destroy=function(){c.prototype.destroy.call(this),this._torrent=null}},{"../package.json":135,bitfield:43,"bittorrent-protocol":44,debug:56,inherits:65,"safe-buffer":104,"simple-get":106,"simple-sha1":108}],135:[function(e,t){t.exports={version:"0.97.2"}},{}],136:[function(e,t){function n(e,t){function r(){for(var t=new Array(arguments.length),n=0;n0?new Array(e+(/\./.test(t)?2:1)).join(r)+t:t+"")}},{}],140:[function(e,t){function n(e,t){function r(e){e.files.forEach(function(e){e.getBuffer(function(e,t){if(e)return log(e.message);var n=JSON.parse(t.toString("utf8"));f[n.url]=n,c.update_links(),window.onpopstate=function(e){document.documentElement.innerHTML=e.state.page,document.title=l+" "+e.state.title,window.scrollTo(0,0),c.emit("onpopstate",e);for(var t=document.getElementsByTagName("a"),n=0;n-1?t[n].onclick=function(e){e.preventDefault(),document.documentElement.innerHTML=f[e.target.href].page,document.title=l+" "+f[e.target.href].title,window.history.pushState({page:f[e.target.href].page,title:f[e.target.href].title},"",e.target.href),setTimeout(function(){window.scrollTo(0,0)},10)}:c.fetch(t[n])}})})}var c=this;return"function"==typeof e&&(t=e),document.security_sha1&&(c.security_sha1=document.security_sha1),l=e&&e.cached_mark?e.cached_mark:"* ",c instanceof n?(u.call(c),c.emit("message","Initializing CacheP2P..."),window.onpopstate=function(e){console.log("onpopstate called",e)},c.announceList=[["udp://tracker.openbittorrent.com:80"],["udp://tracker.internetwarriors.net:1337"],["udp://tracker.leechers-paradise.org:6969"],["udp://tracker.coppersurfer.tk:6969"],["udp://exodus.desync.com:6969"],["wss://tracker.btorrent.xyz"],["wss://tracker.openwebtorrent.com"]],e&&e.announceList&&(c.announceList=e.announceList),c.fetch=function(e){(!document.security_sha1||Object.keys(document.security_sha1).indexOf(e.href)>-1)&&-1===Object.keys(f).indexOf(e.href)&&(c.emit("message","Pre-fetching '"+e.href+"' page from other peers browsing this website..."),c.emit("alert","Please tell a friend to open this site's "+e.text+" to see it in action."),d.push(e.href),o(e.href,function(e){var t="magnet:?xt=urn:btih:"+e+"&dn=Unnamed+Torrent+1476541118022&tr=udp%3A%2F%2Fexodus.desync.com%3A6969&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Ftracker.internetwarriors.net%3A1337&tr=udp%3A%2F%2Ftracker.leechers-paradise.org%3A6969&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80&tr=wss%3A%2F%2Ftracker.openwebtorrent.com";torrent=i.add(t,r),torrent.on("done",function(){c.emit("webtorrent","Cache received")}),torrent.on("download",function(e){c.emit("webtorrent","Receiving Cache ("+e+" bytes)")}),torrent.on("wire",function(e){c.emit("webtorrent","Peer ("+e.remoteAddress+") connected over "+e.type+" (Connection ID: "+e.peerId.substr(0,10)+").")})}))},c.scan_links=function(){c.emit("message","Pre-fetching uncached links in this page... ");for(var e=document.getElementsByTagName("a"),t=0;t-1&&(!document.security_sha1||Object.keys(document.security_sha1).indexOf(e[t].href)>-1)&&-1===Object.keys(f).indexOf(e[t].href)&&c.fetch(e[t]);c.update_links()},c.update_links=function(){var e=document.getElementsByTagName("a");Object.keys(f).forEach(function(t){for(var n=f[t],r=0;r