diff --git a/bin/bundle.js b/bin/bundle.js index 78dd5b2..0683044 100644 --- a/bin/bundle.js +++ b/bin/bundle.js @@ -62552,10 +62552,13 @@ var removeWebseeds = document.getElementById('removeWebseeds'); var pieces = document.getElementById('pieces'); var files = document.getElementById('filesBody'); var getFiles = document.getElementById('getFiles'); +var openURLWrapper = document.getElementById('openURLWrapper'); +var openURL = document.getElementById('openURL'); var copyURL = document.getElementById('copyURL'); var copyMagnet = document.getElementById('copyMagnet'); var downloadTorrentWrapper = document.getElementById('downloadTorrentWrapper'); var downloadTorrent = document.getElementById('downloadTorrent'); +var openURLTooltip = tippy(openURL, {"theme": "torrent-parts", "animation": "shift-away-subtle", "content": "Open this Magnet URL in your Torrent client"}); var copyURLTooltip = tippy(copyURL, {"theme": "torrent-parts", "animation": "shift-away-subtle", "content": "Copy torrent.parts link to clipboard"}); var copyMagnetTooltip = tippy(copyMagnet, {"theme": "torrent-parts", "animation": "shift-away-subtle", "content": "Copy Magnet link to clipboard"}); var downloadTorrentTooltip = tippy(downloadTorrentWrapper, {"theme": "torrent-parts", "animation": "shift-away-subtle", "content": "Download Torrent file"}); @@ -62585,10 +62588,12 @@ var notyf = new Notyf({ function placeDownloadTooltips(e) { if (window.innerWidth > 1080) { + openURLTooltip.setProps({"placement": "right"}); copyURLTooltip.setProps({"placement": "right"}); copyMagnetTooltip.setProps({"placement": "right"}); downloadTorrentTooltip.setProps({"placement": "right"}); } else { + openURLTooltip.setProps({"placement": "top"}); copyURLTooltip.setProps({"placement": "top"}); copyMagnetTooltip.setProps({"placement": "top"}); downloadTorrentTooltip.setProps({"placement": "top"}); @@ -62841,6 +62846,7 @@ function display() { files.appendChild(createFileRow('', '...and another ' + (parsed.files.length - 100) + ' more files', '')); } files.appendChild(createFileRow('folder-tree', '', parsed.length)); + openURLWrapper.href = parser.toMagnetURI(parsed); downloadTorrentTooltip.setContent('Download Torrent file'); downloadTorrent.addEventListener('click', saveTorrent); downloadTorrent.disabled = false; diff --git a/bin/bundle.min.js b/bin/bundle.min.js index 2a026fc..4b3fce1 100644 --- a/bin/bundle.min.js +++ b/bin/bundle.min.js @@ -105,4 +105,4 @@ const i=16384;class n{constructor(e){this.length=e,this.missing=e,this.sources=n /*! ut_metadata. MIT License. WebTorrent LLC */ const{EventEmitter:n}=e("events"),r=e("bencode"),s=e("bitfield").default,a=e("debug")("ut_metadata"),o=e("simple-sha1"),c=16384;t.exports=e=>{class t extends n{constructor(t){super(),this._wire=t,this._fetching=!1,this._metadataComplete=!1,this._metadataSize=null,this._remainingRejects=null,this._bitfield=new s(0,{grow:1e3}),i.isBuffer(e)&&this.setMetadata(e)}onHandshake(e,t,i){this._infoHash=e}onExtendedHandshake(e){return e.m&&e.m.ut_metadata?e.metadata_size?"number"!=typeof e.metadata_size||1e7this._metadataSize&&(i=this._metadataSize);const n=this.metadata.slice(t,i);this._data(e,n,this._metadataSize)}_onData(e,t,i){t.length>c||!this._fetching||(t.copy(this.metadata,e*c),this._bitfield.set(e),this._checkDone())}_onReject(e){this._remainingRejects>0&&this._fetching?(this._request(e),this._remainingRejects-=1):this.emit("warning",new Error('Peer sent "reject" too much'))}_requestPieces(){if(this._fetching){this.metadata=i.alloc(this._metadataSize);for(let e=0;e0?this._requestPieces():this.emit("warning",new Error("Peer sent invalid metadata"))}}return t.prototype.name="ut_metadata",t}}).call(this)}).call(this,e("buffer").Buffer)},{bencode:22,bitfield:26,buffer:110,debug:146,events:178,"simple-sha1":366}],440:[function(e,t,i){(function(e){(function(){function i(t){try{if(!e.localStorage)return!1}catch(e){return!1}var i=e.localStorage[t];return null!=i&&"true"===String(i).toLowerCase()}t.exports=function(e,t){if(i("noDeprecation"))return e;var n=!1;return function(){if(!n){if(i("throwDeprecation"))throw new Error(t);i("traceDeprecation")?console.trace(t):console.warn(t),n=!0}return e.apply(this,arguments)}}}).call(this)}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],441:[function(e,t,i){(function(i){(function(){const n=e("binary-search"),r=e("events"),s=e("mp4-stream"),a=e("mp4-box-encoding"),o=e("range-slice-stream");class c{constructor(e,t){this._entries=e,this._countName=t||"count",this._index=0,this._offset=0,this.value=this._entries[0]}inc(){this._offset++,this._offset>=this._entries[this._index][this._countName]&&(this._index++,this._offset=0),this.value=this._entries[this._index]}}const l=1;t.exports=class extends r{constructor(e){super(),this._tracks=[],this._file=e,this._decoder=null,this._findMoov(0)}_findMoov(e){this._decoder&&this._decoder.destroy();let t=0;this._decoder=s.decode();const i=this._file.createReadStream({start:e});i.pipe(this._decoder);const n=r=>{"moov"===r.type?(this._decoder.removeListener("box",n),this._decoder.decode((e=>{i.destroy();try{this._processMoov(e)}catch(e){e.message=`Cannot parse mp4 file: ${e.message}`,this.emit("error",e)}}))):r.length<4096?(t+=r.length,this._decoder.ignore()):(this._decoder.removeListener("box",n),t+=r.length,i.destroy(),this._decoder.destroy(),this._findMoov(e+t))};this._decoder.on("box",n)}_processMoov(e){const t=e.traks;this._tracks=[],this._hasVideo=!1,this._hasAudio=!1;for(let i=0;i=s.stsz.entries.length)break;if(f++,m+=e,f>=n.samplesPerChunk){f=0,m=0,h++;const e=s.stsc.entries[b+1];e&&h+1>=e.firstChunk&&b++}v+=t,g.inc(),y&&y.inc(),r&&x++}r.mdia.mdhd.duration=0,r.tkhd.duration=0;const _=n.sampleDescriptionId,w={type:"moov",mvhd:e.mvhd,traks:[{tkhd:r.tkhd,mdia:{mdhd:r.mdia.mdhd,hdlr:r.mdia.hdlr,elng:r.mdia.elng,minf:{vmhd:r.mdia.minf.vmhd,smhd:r.mdia.minf.smhd,dinf:r.mdia.minf.dinf,stbl:{stsd:s.stsd,stts:{version:0,flags:0,entries:[]},ctts:{version:0,flags:0,entries:[]},stsc:{version:0,flags:0,entries:[]},stsz:{version:0,flags:0,entries:[]},stco:{version:0,flags:0,entries:[]},stss:{version:0,flags:0,entries:[]}}}}}],mvex:{mehd:{fragmentDuration:e.mvhd.duration},trexs:[{trackId:r.tkhd.trackId,defaultSampleDescriptionIndex:_,defaultSampleDuration:0,defaultSampleSize:0,defaultSampleFlags:0}]}};this._tracks.push({fragmentSequence:1,trackId:r.tkhd.trackId,timeScale:r.mdia.mdhd.timeScale,samples:p,currSample:null,currTime:null,moov:w,mime:u})}if(0===this._tracks.length)return void this.emit("error",new Error("no playable tracks"));e.mvhd.duration=0,this._ftyp={type:"ftyp",brand:"iso5",brandVersion:0,compatibleBrands:["iso5"]};const r=a.encode(this._ftyp),s=this._tracks.map((e=>{const t=a.encode(e.moov);return{mime:e.mime,init:i.concat([r,t])}}));this.emit("ready",s)}seek(e){if(!this._tracks)throw new Error("Not ready yet; wait for 'ready' event");this._fileStream&&(this._fileStream.destroy(),this._fileStream=null);let t=-1;if(this._tracks.map(((i,n)=>{i.outStream&&i.outStream.destroy(),i.inStream&&(i.inStream.destroy(),i.inStream=null);const r=i.outStream=s.encode(),a=this._generateFragment(n,e);if(!a)return r.finalize();(-1===t||a.ranges[0].start{r.destroyed||r.box(e.moof,(t=>{if(t)return this.emit("error",t);if(r.destroyed)return;i.inStream.slice(e.ranges).pipe(r.mediaData(e.length,(e=>{if(e)return this.emit("error",e);if(r.destroyed)return;const t=this._generateFragment(n);if(!t)return r.finalize();o(t)})))}))};o(a)})),t>=0){const e=this._fileStream=this._file.createReadStream({start:t});this._tracks.forEach((i=>{i.inStream=new o(t,{highWaterMark:1e7}),e.pipe(i.inStream)}))}return this._tracks.map((e=>e.outStream))}_findSampleBefore(e,t){const i=this._tracks[e],r=Math.floor(i.timeScale*t);let s=n(i.samples,r,((e,t)=>e.dts+e.presentationOffset-t));for(-1===s?s=0:s<0&&(s=-s-2);!i.samples[s].sync;)s--;return s}_generateFragment(e,t){const i=this._tracks[e];let n;if(n=void 0!==t?this._findSampleBefore(e,t):i.currSample,n>=i.samples.length)return null;const r=i.samples[n].dts;let s=0;const a=[];for(var o=n;o=i.timeScale*l)break;s+=e.size;const t=a.length-1;t<0||a[t].end!==e.offset?a.push({start:e.offset,end:e.offset+e.size}):a[t].end+=e.size}return i.currSample=o,{moof:this._generateMoof(e,n,o),ranges:a,length:s}}_generateMoof(e,t,i){const n=this._tracks[e],r=[];let s=0;for(let e=t;e{this.detailedError=this._elemWrapper.detailedError,this.destroy()},this._onWaiting=()=>{this._waitingFired=!0,this._muxer?this._tracks&&this._pump():this._createMuxer()},t.autoplay&&(t.preload="auto"),t.addEventListener("waiting",this._onWaiting),t.addEventListener("error",this._onError)}a.prototype={_createMuxer(){this._muxer=new s(this._file),this._muxer.on("ready",(e=>{this._tracks=e.map((e=>{const t=this._elemWrapper.createWriteStream(e.mime);t.on("error",(e=>{this._elemWrapper.error(e)}));const i={muxed:null,mediaSource:t,initFlushed:!1,onInitFlushed:null};return t.write(e.init,(e=>{i.initFlushed=!0,i.onInitFlushed&&i.onInitFlushed(e)})),i})),(this._waitingFired||"auto"===this._elem.preload)&&this._pump()})),this._muxer.on("error",(e=>{this._elemWrapper.error(e)}))},_pump(){const e=this._muxer.seek(this._elem.currentTime,!this._tracks);this._tracks.forEach(((t,i)=>{const n=()=>{t.muxed&&(t.muxed.destroy(),t.mediaSource=this._elemWrapper.createWriteStream(t.mediaSource),t.mediaSource.on("error",(e=>{this._elemWrapper.error(e)}))),t.muxed=e[i],r(t.muxed,t.mediaSource)};t.initFlushed?n():t.onInitFlushed=e=>{e?this._elemWrapper.error(e):n()}}))},destroy(){this.destroyed||(this.destroyed=!0,this._elem.removeEventListener("waiting",this._onWaiting),this._elem.removeEventListener("error",this._onError),this._tracks&&this._tracks.forEach((e=>{e.muxed&&e.muxed.destroy()})),this._elem.src="")}},t.exports=a},{"./mp4-remuxer":441,mediasource:230,pump:304}],443:[function(e,t,i){(function(i){(function(){ /*! webtorrent. MIT License. WebTorrent LLC */ -const n=e("events"),r=e("path"),s=e("simple-concat"),a=e("create-torrent"),o=e("debug"),c=e("bittorrent-dht/client"),l=e("load-ip-set"),u=e("run-parallel"),p=e("parse-torrent"),d=e("simple-peer"),f=e("queue-microtask"),h=e("randombytes"),m=e("simple-sha1"),b=e("throughput"),{ThrottleGroup:v}=e("speed-limiter"),g=e("./lib/conn-pool.js"),y=e("./lib/torrent.js"),{version:x}=e("./package.json"),_=o("webtorrent"),w=x.replace(/\d*./g,(e=>("0"+e%100).slice(-2))).slice(0,4),k=`-WW${w}-`;class E extends n{constructor(t={}){super(),"string"==typeof t.peerId?this.peerId=t.peerId:i.isBuffer(t.peerId)?this.peerId=t.peerId.toString("hex"):this.peerId=i.from(k+h(9).toString("base64")).toString("hex"),this.peerIdBuffer=i.from(this.peerId,"hex"),"string"==typeof t.nodeId?this.nodeId=t.nodeId:i.isBuffer(t.nodeId)?this.nodeId=t.nodeId.toString("hex"):this.nodeId=h(20).toString("hex"),this.nodeIdBuffer=i.from(this.nodeId,"hex"),this._debugId=this.peerId.toString("hex").substring(0,7),this.destroyed=!1,this.listening=!1,this.torrentPort=t.torrentPort||0,this.dhtPort=t.dhtPort||0,this.tracker=void 0!==t.tracker?t.tracker:{},this.lsd=!1!==t.lsd,this.torrents=[],this.maxConns=Number(t.maxConns)||55,this.utp=E.UTP_SUPPORT&&!1!==t.utp,this._downloadLimit=Math.max("number"==typeof t.downloadLimit?t.downloadLimit:-1,-1),this._uploadLimit=Math.max("number"==typeof t.uploadLimit?t.uploadLimit:-1,-1),this.serviceWorker=null,this.workerKeepAliveInterval=null,this.workerPortCount=0,!0===t.secure&&e("./lib/peer").enableSecure(),this._debug("new webtorrent (peerId %s, nodeId %s, port %s)",this.peerId,this.nodeId,this.torrentPort),this.throttleGroups={down:new v({rate:Math.max(this._downloadLimit,0),enabled:this._downloadLimit>=0}),up:new v({rate:Math.max(this._uploadLimit,0),enabled:this._uploadLimit>=0})},this.tracker&&("object"!=typeof this.tracker&&(this.tracker={}),globalThis.WRTC&&!this.tracker.wrtc&&(this.tracker.wrtc=globalThis.WRTC)),"function"==typeof g?this._connPool=new g(this):f((()=>{this._onListening()})),this._downloadSpeed=b(),this._uploadSpeed=b(),!1!==t.dht&&"function"==typeof c?(this.dht=new c(Object.assign({},{nodeId:this.nodeId},t.dht)),this.dht.once("error",(e=>{this._destroy(e)})),this.dht.once("listening",(()=>{const e=this.dht.address();e&&(this.dhtPort=e.port)})),this.dht.setMaxListeners(0),this.dht.listen(this.dhtPort)):this.dht=!1,this.enableWebSeeds=!1!==t.webSeeds;const n=()=>{this.destroyed||(this.ready=!0,this.emit("ready"))};"function"==typeof l&&null!=t.blocklist?l(t.blocklist,{headers:{"user-agent":`WebTorrent/${x} (https://webtorrent.io)`}},((e,t)=>{if(e)return console.error(`Failed to load blocklist: ${e.message}`);this.blocked=t,n()})):f(n)}loadWorker(e,t=(()=>{})){if(!(e instanceof ServiceWorker))throw new Error("Invalid worker registration");if("activated"!==e.state)throw new Error("Worker isn't activated");this.serviceWorker=e,navigator.serviceWorker.addEventListener("message",(e=>{const{data:t}=e;if(!t.type||"webtorrent"===!t.type||!t.url)return null;let[i,...n]=t.url.slice(t.url.indexOf(t.scope+"webtorrent/")+11+t.scope.length).split("/");if(n=decodeURI(n.join("/")),!i||!n)return null;const[r]=e.ports,s=this.get(i)&&this.get(i).files.find((e=>e.path===n));if(!s)return null;const[a,o,c]=s._serve(t),l=o&&o[Symbol.asyncIterator](),u=()=>{r.onmessage=null,o&&o.destroy(),c&&c.destroy(),this.workerPortCount--,this.workerPortCount||(clearInterval(this.workerKeepAliveInterval),this.workerKeepAliveInterval=null)};r.onmessage=async e=>{if(e.data){let e;try{e=(await l.next()).value}catch(e){}r.postMessage(e),e||u(),this.workerKeepAliveInterval||(this.workerKeepAliveInterval=setInterval((()=>fetch(`${this.serviceWorker.scriptURL.slice(0,this.serviceWorker.scriptURL.lastIndexOf("/")+1).slice(window.location.origin.length)}webtorrent/keepalive/`)),2e4))}else u()},this.workerPortCount++,r.postMessage(a)})),fetch(`${this.serviceWorker.scriptURL.slice(0,this.serviceWorker.scriptURL.lastIndexOf("/")+1).slice(window.location.origin.length)}webtorrent/cancel/`).then((e=>{e.body.cancel()})),t(null,this.serviceWorker)}get downloadSpeed(){return this._downloadSpeed()}get uploadSpeed(){return this._uploadSpeed()}get progress(){const e=this.torrents.filter((e=>1!==e.progress));return e.reduce(((e,t)=>e+t.downloaded),0)/(e.reduce(((e,t)=>e+(t.length||0)),0)||1)}get ratio(){return this.torrents.reduce(((e,t)=>e+t.uploaded),0)/(this.torrents.reduce(((e,t)=>e+t.received),0)||1)}get(e){if(e instanceof y){if(this.torrents.includes(e))return e}else{let t;try{t=p(e)}catch(e){}if(!t)return null;if(!t.infoHash)throw new Error("Invalid torrent identifier");for(const e of this.torrents)if(e.infoHash===t.infoHash)return e}return null}add(e,t={},i=(()=>{})){if(this.destroyed)throw new Error("client is destroyed");"function"==typeof t&&([t,i]=[{},t]);const n=()=>{if(!this.destroyed)for(const e of this.torrents)if(e.infoHash===s.infoHash&&e!==s)return s._destroy(new Error(`Cannot add duplicate torrent ${s.infoHash}`)),void i(e)},r=()=>{this.destroyed||(i(s),this.emit("torrent",s))};this._debug("add"),t=t?Object.assign({},t):{};const s=new y(e,this,t);return this.torrents.push(s),s.once("_infoHash",n),s.once("ready",r),s.once("close",(function e(){s.removeListener("_infoHash",n),s.removeListener("ready",r),s.removeListener("close",e)})),s}seed(e,t,i){if(this.destroyed)throw new Error("client is destroyed");"function"==typeof t&&([t,i]=[{},t]),this._debug("seed"),(t=t?Object.assign({},t):{}).skipVerify=!0;const n="string"==typeof e;n&&(t.path=r.dirname(e)),t.createdBy||(t.createdBy=`WebTorrent/${w}`);const o=e=>{this._debug("on seed"),"function"==typeof i&&i(e),e.emit("seed"),this.emit("seed",e)},c=this.add(null,t,(e=>{const i=[i=>{if(n||t.preloadedStore)return i();e.load(l,i)}];this.dht&&i.push((t=>{e.once("dhtAnnounce",t)})),u(i,(t=>{if(!this.destroyed)return t?e._destroy(t):void o(e)}))}));let l;var p;return p=e,"undefined"!=typeof FileList&&p instanceof FileList?e=Array.from(e):Array.isArray(e)||(e=[e]),u(e.map((e=>i=>{!t.preloadedStore&&function(e){return"object"==typeof e&&null!=e&&"function"==typeof e.pipe}(e)?s(e,((t,n)=>{if(t)return i(t);n.name=e.name,i(null,n)})):i(null,e)})),((e,n)=>{if(!this.destroyed)return e?c._destroy(e):void a.parseInput(n,t,((e,r)=>{if(!this.destroyed){if(e)return c._destroy(e);l=r.map((e=>e.getStream)),a(n,t,((e,t)=>{if(this.destroyed)return;if(e)return c._destroy(e);const n=this.get(t);n?(console.warn("A torrent with the same id is already being seeded"),c._destroy(),"function"==typeof i&&i(n)):c._onTorrentId(t)}))}}))})),c}remove(e,t,i){if("function"==typeof t)return this.remove(e,null,t);this._debug("remove");if(!this.get(e))throw new Error(`No torrent with id ${e}`);this._remove(e,t,i)}_remove(e,t,i){if("function"==typeof t)return this._remove(e,null,t);const n=this.get(e);n&&(this.torrents.splice(this.torrents.indexOf(n),1),n.destroy(t,i),this.dht&&this.dht._tables.remove(n.infoHash))}address(){return this.listening?this._connPool?this._connPool.tcpServer.address():{address:"0.0.0.0",family:"IPv4",port:0}:null}throttleDownload(e){return e=Number(e),!(isNaN(e)||!isFinite(e)||e<-1)&&(this._downloadLimit=e,this._downloadLimit<0?this.throttleGroups.down.setEnabled(!1):(this.throttleGroups.down.setEnabled(!0),void this.throttleGroups.down.setRate(this._downloadLimit)))}throttleUpload(e){return e=Number(e),!(isNaN(e)||!isFinite(e)||e<-1)&&(this._uploadLimit=e,this._uploadLimit<0?this.throttleGroups.up.setEnabled(!1):(this.throttleGroups.up.setEnabled(!0),void this.throttleGroups.up.setRate(this._uploadLimit)))}destroy(e){if(this.destroyed)throw new Error("client already destroyed");this._destroy(null,e)}_destroy(e,t){this._debug("client destroy"),this.destroyed=!0;const i=this.torrents.map((e=>t=>{e.destroy(t)}));this._connPool&&i.push((e=>{this._connPool.destroy(e)})),this.dht&&i.push((e=>{this.dht.destroy(e)})),u(i,t),e&&this.emit("error",e),this.torrents=[],this._connPool=null,this.dht=null,this.throttleGroups.down.destroy(),this.throttleGroups.up.destroy()}_onListening(){if(this._debug("listening"),this.listening=!0,this._connPool){const e=this._connPool.tcpServer.address();e&&(this.torrentPort=e.port)}this.emit("listening")}_debug(){const e=[].slice.call(arguments);e[0]=`[${this._debugId}] ${e[0]}`,_(...e)}_getByHash(e){for(const t of this.torrents)if(t.infoHashHash||(t.infoHashHash=m.sync(i.from("72657132"+t.infoHash,"hex"))),e===t.infoHashHash)return t;return null}}E.WEBRTC_SUPPORT=d.WEBRTC_SUPPORT,E.UTP_SUPPORT=g.UTP_SUPPORT,E.VERSION=x,t.exports=E}).call(this)}).call(this,e("buffer").Buffer)},{"./lib/conn-pool.js":67,"./lib/peer":446,"./lib/torrent.js":448,"./package.json":450,"bittorrent-dht/client":67,buffer:110,"create-torrent":144,debug:146,events:178,"load-ip-set":67,"parse-torrent":287,path:288,"queue-microtask":309,randombytes:312,"run-parallel":336,"simple-concat":348,"simple-peer":350,"simple-sha1":366,"speed-limiter":384,throughput:430}],444:[function(e,t,i){const{Readable:n}=e("streamx"),r=e("debug")("webtorrent:file-stream");t.exports=class extends n{constructor(e,t){super(t??{}),this._torrent=e._torrent;const i=t&&t.start||0,n=t&&t.end&&t.end{this._notify()}))}_read(e){this._reading||(this._reading=!0,this._notify(e))}_notify(e=(()=>{})){if(!this._reading||0===this._missing)return e();if(!this._torrent.bitfield.get(this._piece))return e(),this._torrent.critical(this._piece,this._piece+this._criticalLength);if(this._notifying)return e();if(this._notifying=!0,this._torrent.destroyed)return this.destroy(new Error("Torrent removed"));const t=this._piece,i={};t===this._torrent.pieces.length-1&&(i.length=this._torrent.lastPieceLength),this._torrent.store.get(t,i,((i,n)=>{if(this._notifying=!1,!this.destroyed){if(r("read %s (length %s) (err %s)",t,n&&n.length,i&&i.message),i)return this.destroy(i);this._offset&&(n=n.slice(this._offset),this._offset=0),this._missing{const s=r===e.length-1?n:i;return t.get(r)?s:s-e[r].missing};let o=0;for(let t=r;t<=s;t+=1){const c=a(t);if(o+=c,t===r){const e=this.offset%i;o-=Math.min(e,c)}if(t===s){const t=(s===e.length-1?n:i)-(this.offset+this.length)%i;o-=Math.min(t,c)}}return o}get progress(){return this.length?this.downloaded/this.length:0}select(e){0!==this.length&&this._torrent.select(this._startPiece,this._endPiece,e)}deselect(){0!==this.length&&this._torrent.deselect(this._startPiece,this._endPiece,!1)}createReadStream(e){if(0===this.length){const e=new r;return l((()=>{e.end()})),e}const t=new f(this,e);return this._fileStreams.add(t),t.once("close",(()=>{this._fileStreams.delete(t)})),t}getBuffer(e){c(this.createReadStream(),this.length,e)}getBlob(e){if("undefined"==typeof window)throw new Error("browser-only method");const t=new o((t=>{e(null,t)}),{mimeType:this._getMimeType()});this.createReadStream().pipe(t)}getBlobURL(e){this.getBlob(((t,i)=>{e(null,URL.createObjectURL(i))}))}appendTo(e,t,i){if("undefined"==typeof window)throw new Error("browser-only method");a.append(this,e,t,i)}renderTo(e,t,i){if("undefined"==typeof window)throw new Error("browser-only method");a.render(this,e,t,i)}_serve(e){const t={status:200,headers:{"Accept-Ranges":"bytes","Content-Type":p.getType(this.name),"Cache-Control":"no-cache, no-store, must-revalidate, max-age=0",Expires:"0"},body:"HEAD"===e.method?"":"STREAM"};"document"===e.destination&&(t.headers["Content-Type"]="application/octet-stream",t.headers["Content-Disposition"]="attachment",t.body="DOWNLOAD");let i=u(this.length,e.headers.range||"");i.constructor===Array?(t.status=206,i=i[0],t.headers["Content-Range"]=`bytes ${i.start}-${i.end}/${this.length}`,t.headers["Content-Length"]=""+(i.end-i.start+1)):t.headers["Content-Length"]=this.length;const n="GET"===e.method&&this.createReadStream(i);let r=null;return n&&this.emit("stream",{stream:n,req:e,file:this},(e=>{r=e,d(e,(()=>{e&&e.destroy(),n.destroy()}))})),[t,r||n,r&&n]}getStreamURL(e=(()=>{})){if("undefined"==typeof window)throw new Error("browser-only method");if(!this._serviceWorker)throw new Error("No worker registered");if("activated"!==this._serviceWorker.state)throw new Error("Worker isn't activated");e(null,`${this._serviceWorker.scriptURL.slice(0,this._serviceWorker.scriptURL.lastIndexOf("/")+1).slice(window.location.origin.length)}webtorrent/${this._torrent.infoHash}/${encodeURI(this.path)}`)}streamTo(e,t=(()=>{})){if("undefined"==typeof window)throw new Error("browser-only method");if(!this._serviceWorker)throw new Error("No worker registered");if("activated"!==this._serviceWorker.state)throw new Error("Worker isn't activated");const i=this._serviceWorker.scriptURL.slice(0,this._serviceWorker.scriptURL.lastIndexOf("/")+1).slice(window.location.origin.length);e.src=`${i}webtorrent/${this._torrent.infoHash}/${encodeURI(this.path)}`,t(null,e)}_getMimeType(){return a.mime[s.extname(this.name).toLowerCase()]}_destroy(){this._destroyed=!0,this._torrent=null;for(const e of this._fileStreams)e.destroy();this._fileStreams.clear()}}},{"./file-stream.js":444,"end-of-stream":176,events:178,"fast-blob-stream":180,mime:253,path:288,"queue-microtask":309,"range-parser":314,"render-media":332,"stream-with-known-length-to-buffer":425,streamx:426}],446:[function(e,t,i){const n=e("events"),{Transform:r}=e("stream"),s=e("unordered-array-remove"),a=e("debug"),o=e("bittorrent-protocol"),c=a("webtorrent:peer");let l=!1;i.enableSecure=()=>{l=!0},i.createWebRTCPeer=(e,t,i)=>{const n=new d(e.id,"webrtc");if(n.conn=e,n.swarm=t,n.throttleGroups=i,n.conn.connected)n.onConnect();else{const e=()=>{n.conn.removeListener("connect",t),n.conn.removeListener("error",i)},t=()=>{e(),n.onConnect()},i=t=>{e(),n.destroy(t)};n.conn.once("connect",t),n.conn.once("error",i),n.startConnectTimeout()}return n},i.createTCPIncomingPeer=(e,t)=>u(e,"tcpIncoming",t),i.createUTPIncomingPeer=(e,t)=>u(e,"utpIncoming",t),i.createTCPOutgoingPeer=(e,t,i)=>p(e,t,"tcpOutgoing",i),i.createUTPOutgoingPeer=(e,t,i)=>p(e,t,"utpOutgoing",i);const u=(e,t,i)=>{const n=`${e.remoteAddress}:${e.remotePort}`,r=new d(n,t);return r.conn=e,r.addr=n,r.throttleGroups=i,r.onConnect(),r},p=(e,t,i,n)=>{const r=new d(e,i);return r.addr=e,r.swarm=t,r.throttleGroups=n,r};i.createWebSeedPeer=(e,t,i,n)=>{const r=new d(t,"webSeed");return r.swarm=i,r.conn=e,r.throttleGroups=n,r.onConnect(),r};class d extends n{constructor(e,t){super(),this.id=e,this.type=t,c("new %s Peer %s",t,e),this.addr=null,this.conn=null,this.swarm=null,this.wire=null,this.connected=!1,this.destroyed=!1,this.timeout=null,this.retries=0,this.sentPe1=!1,this.sentPe2=!1,this.sentPe3=!1,this.sentPe4=!1,this.sentHandshake=!1}onConnect(){if(this.destroyed)return;this.connected=!0,c("Peer %s connected",this.id),clearTimeout(this.connectTimeout);const e=this.conn;e.once("end",(()=>{this.destroy()})),e.once("close",(()=>{this.destroy()})),e.once("finish",(()=>{this.destroy()})),e.once("error",(e=>{this.destroy(e)}));const t=this.wire=new o(this.type,this.retries,l);t.once("end",(()=>{this.destroy()})),t.once("close",(()=>{this.destroy()})),t.once("finish",(()=>{this.destroy()})),t.once("error",(e=>{this.destroy(e)})),t.once("pe1",(()=>{this.onPe1()})),t.once("pe2",(()=>{this.onPe2()})),t.once("pe3",(()=>{this.onPe3()})),t.once("pe4",(()=>{this.onPe4()})),t.once("handshake",((e,t)=>{this.onHandshake(e,t)})),this.startHandshakeTimeout(),this.setThrottlePipes(),this.swarm&&("tcpOutgoing"===this.type?l&&0===this.retries&&!this.sentPe1?this.sendPe1():this.sentHandshake||this.handshake():"tcpIncoming"===this.type||this.sentHandshake||this.handshake())}sendPe1(){this.wire.sendPe1(),this.sentPe1=!0}onPe1(){this.sendPe2()}sendPe2(){this.wire.sendPe2(),this.sentPe2=!0}onPe2(){this.sendPe3()}sendPe3(){this.wire.sendPe3(this.swarm.infoHash),this.sentPe3=!0}onPe3(e){this.swarm&&(this.swarm.infoHashHash!==e&&this.destroy(new Error("unexpected crypto handshake info hash for this swarm")),this.sendPe4())}sendPe4(){this.wire.sendPe4(this.swarm.infoHash),this.sentPe4=!0}onPe4(){this.sentHandshake||this.handshake()}clearPipes(){this.conn.unpipe(),this.wire.unpipe()}setThrottlePipes(){const e=this;this.conn.pipe(this.throttleGroups.down.throttle()).pipe(new r({transform(t,i,n){e.emit("download",t.length),e.destroyed||n(null,t)}})).pipe(this.wire).pipe(this.throttleGroups.up.throttle()).pipe(new r({transform(t,i,n){e.emit("upload",t.length),e.destroyed||n(null,t)}})).pipe(this.conn)}onHandshake(e,t){if(!this.swarm)return;if(this.destroyed)return;if(this.swarm.destroyed)return this.destroy(new Error("swarm already destroyed"));if(e!==this.swarm.infoHash)return this.destroy(new Error("unexpected handshake info hash for this swarm"));if(t===this.swarm.peerId)return this.destroy(new Error("refusing to connect to ourselves"));c("Peer %s got handshake %s",this.id,e),clearTimeout(this.handshakeTimeout),this.retries=0;let i=this.addr;!i&&this.conn.remoteAddress&&this.conn.remotePort&&(i=`${this.conn.remoteAddress}:${this.conn.remotePort}`),this.swarm._onWire(this.wire,i),this.swarm&&!this.swarm.destroyed&&(this.sentHandshake||this.handshake())}handshake(){const e={dht:!this.swarm.private&&!!this.swarm.client.dht,fast:!0};this.wire.handshake(this.swarm.infoHash,this.swarm.client.peerId,e),this.sentHandshake=!0}startConnectTimeout(){clearTimeout(this.connectTimeout);const e={webrtc:25e3,tcpOutgoing:5e3,utpOutgoing:5e3};this.connectTimeout=setTimeout((()=>{this.destroy(new Error("connect timeout"))}),e[this.type]),this.connectTimeout.unref&&this.connectTimeout.unref()}startHandshakeTimeout(){clearTimeout(this.handshakeTimeout),this.handshakeTimeout=setTimeout((()=>{this.destroy(new Error("handshake timeout"))}),25e3),this.handshakeTimeout.unref&&this.handshakeTimeout.unref()}destroy(e){if(this.destroyed)return;this.destroyed=!0,this.connected=!1,c("destroy %s %s (error: %s)",this.type,this.id,e&&(e.message||e)),clearTimeout(this.connectTimeout),clearTimeout(this.handshakeTimeout);const t=this.swarm,i=this.conn,n=this.wire;this.swarm=null,this.conn=null,this.wire=null,t&&n&&s(t.wires,t.wires.indexOf(n)),i&&(i.on("error",(()=>{})),i.destroy()),n&&n.destroy(),t&&t.removePeer(this.id)}}},{"bittorrent-protocol":27,debug:146,events:178,stream:389,"unordered-array-remove":436}],447:[function(e,t,i){t.exports=class{constructor(e){this._torrent=e,this._numPieces=e.pieces.length,this._pieces=new Array(this._numPieces),this._onWire=e=>{this.recalculate(),this._initWire(e)},this._onWireHave=e=>{this._pieces[e]+=1},this._onWireBitfield=()=>{this.recalculate()},this._torrent.wires.forEach((e=>{this._initWire(e)})),this._torrent.on("wire",this._onWire),this.recalculate()}getRarestPiece(e){let t=[],i=1/0;for(let n=0;n{this._cleanupWireEvents(e)})),this._torrent=null,this._pieces=null,this._onWire=null,this._onWireHave=null,this._onWireBitfield=null}_initWire(e){e._onClose=()=>{this._cleanupWireEvents(e);for(let t=0;t0&&(i=Math.min(i,t))}return i}function G(){}t.exports=class extends r{constructor(e,t,i){super(),this._debugId="unknown infohash",this.client=t,this.announce=i.announce,this.urlList=i.urlList,this.path=i.path||K,this.addUID=i.addUID||!1,this.skipVerify=!!i.skipVerify,this._store=i.store||b,this._preloadedStore=i.preloadedStore||null,this._storeCacheSlots=void 0!==i.storeCacheSlots?i.storeCacheSlots:20,this._destroyStoreOnDestroy=i.destroyStoreOnDestroy||!1,this._getAnnounceOpts=i.getAnnounceOpts,"boolean"==typeof i.private&&(this.private=i.private),this.strategy=i.strategy||"sequential",this.maxWebConns=i.maxWebConns||4,this._rechokeNumSlots=!1===i.uploads||0===i.uploads?0:+i.uploads||10,this._rechokeOptimisticWire=null,this._rechokeOptimisticTime=0,this._rechokeIntervalId=null,this.ready=!1,this.destroyed=!1,this.paused=i.paused||!1,this.done=!1,this.metadata=null,this.store=null,this.storeOpts=i.storeOpts,this.files=[],this.pieces=[],this._amInterested=!1,this._selections=[],this._critical=[],this.wires=[],this._queue=[],this._peers={},this._peersLength=0,this.received=0,this.uploaded=0,this._downloadSpeed=T(),this._uploadSpeed=T(),this._servers=[],this._xsRequests=[],this._fileModtimes=i.fileModtimes,null!==e&&this._onTorrentId(e),this._debug("new torrent")}get timeRemaining(){return this.done?0:0===this.downloadSpeed?1/0:(this.length-this.downloaded)/this.downloadSpeed*1e3}get downloaded(){if(!this.bitfield)return 0;let e=0;for(let t=0,i=this.pieces.length;t{this.destroyed||this._onParsedTorrent(t)}))):E.remote(e,((e,t)=>{if(!this.destroyed)return e?this._destroy(e):void this._onParsedTorrent(t)}))}_onParsedTorrent(e){if(!this.destroyed){if(this._processParsedTorrent(e),!this.infoHash)return this._destroy(new Error("Malformed torrent data: No info hash"));this._rechokeIntervalId=setInterval((()=>{this._rechoke()}),1e4),this._rechokeIntervalId.unref&&this._rechokeIntervalId.unref(),this.emit("_infoHash",this.infoHash),this.destroyed||(this.emit("infoHash",this.infoHash),this.destroyed||(this.client.listening?this._onListening():this.client.once("listening",(()=>{this._onListening()}))))}}_processParsedTorrent(e){this._debugId=e.infoHash.toString("hex").substring(0,7),void 0!==this.private&&(e.private=this.private),this.announce&&(e.announce=e.announce.concat(this.announce)),this.client.tracker&&n.WEBTORRENT_ANNOUNCE&&!e.private&&(e.announce=e.announce.concat(n.WEBTORRENT_ANNOUNCE)),this.urlList&&(e.urlList=e.urlList.concat(this.urlList)),e.announce=Array.from(new Set(e.announce)),e.urlList=Array.from(new Set(e.urlList)),Object.assign(this,e),this.magnetURI=E.toMagnetURI(e),this.torrentFile=E.toTorrentFile(e)}_onListening(){this.destroyed||(this.info?this._onMetadata(this):(this.xs&&this._getMetadataFromServer(),this._startDiscovery()))}_startDiscovery(){if(this.discovery||this.destroyed)return;let e=this.client.tracker;e&&(e=Object.assign({},this.client.tracker,{getAnnounceOpts:()=>{if(this.destroyed)return;const e={uploaded:this.uploaded,downloaded:this.downloaded,left:Math.max(this.length-this.downloaded,0)};return this.client.tracker.getAnnounceOpts&&Object.assign(e,this.client.tracker.getAnnounceOpts()),this._getAnnounceOpts&&Object.assign(e,this._getAnnounceOpts()),e}})),this.peerAddresses&&this.peerAddresses.forEach((e=>this.addPeer(e))),this.discovery=new m({infoHash:this.infoHash,announce:this.announce,peerId:this.client.peerId,dht:!this.private&&this.client.dht,tracker:e,port:this.client.torrentPort,userAgent:V,lsd:this.client.lsd}),this.discovery.on("error",(e=>{this._destroy(e)})),this.discovery.on("peer",((e,t)=>{this._debug("peer %s discovered via %s",e,t),"string"==typeof e&&this.done||this.addPeer(e)})),this.discovery.on("trackerAnnounce",(()=>{this.emit("trackerAnnounce"),0===this.numPeers&&this.emit("noPeers","tracker")})),this.discovery.on("dhtAnnounce",(()=>{this.emit("dhtAnnounce"),0===this.numPeers&&this.emit("noPeers","dht")})),this.discovery.on("warning",(e=>{this.emit("warning",e)}))}_getMetadataFromServer(){const e=this,t=(Array.isArray(this.xs)?this.xs:[this.xs]).map((t=>i=>{!function(t,i){if(0!==t.indexOf("http://")&&0!==t.indexOf("https://"))return e.emit("warning",new Error(`skipping non-http xs param: ${t}`)),i(null);const n={url:t,method:"GET",headers:{"user-agent":V}};let r;try{r=v.concat(n,s)}catch(n){return e.emit("warning",new Error(`skipping invalid url xs param: ${t}`)),i(null)}function s(n,r,s){if(e.destroyed)return i(null);if(e.metadata)return i(null);if(n)return e.emit("warning",new Error(`http error from xs param: ${t}`)),i(null);if(200!==r.statusCode)return e.emit("warning",new Error(`non-200 status code ${r.statusCode} from xs param: ${t}`)),i(null);let a;try{a=E(s)}catch(n){}return a?a.infoHash!==e.infoHash?(e.emit("warning",new Error(`got torrent file with incorrect info hash from xs param: ${t}`)),i(null)):(e._onMetadata(a),void i(null)):(e.emit("warning",new Error(`got invalid torrent file from xs param: ${t}`)),i(null))}e._xsRequests.push(r)}(t,i)}));w(t)}_onMetadata(e){if(this.metadata||this.destroyed)return;let t;if(this._debug("got metadata"),this._xsRequests.forEach((e=>{e.abort()})),this._xsRequests=[],e&&e.infoHash)t=e;else try{t=E(e)}catch(e){return this._destroy(e)}this._processParsedTorrent(t),this.metadata=this.torrentFile,this.client.enableWebSeeds&&this.urlList.forEach((e=>{this.addWebSeed(e)})),this._rarityMap=new P(this),this.files=this.files.map((e=>new L(this,e)));let i=this._preloadedStore;if(i||(i=new this._store(this.pieceLength,{...this.storeOpts,torrent:this,path:this.path,files:this.files,length:this.length,name:this.name+" - "+this.infoHash.slice(0,8),addUID:this.addUID})),this._storeCacheSlots>0&&!(i instanceof x)&&(i=new p(i,{max:this._storeCacheSlots})),this.store=new g(i),this.so?this.files.forEach(((e,t)=>{this.so.includes(t)?this.files[t].select():this.files[t].deselect()})):0!==this.pieces.length&&this.select(0,this.pieces.length-1,!1),this._hashes=this.pieces,this.pieces=this.pieces.map(((e,t)=>{const i=t===this.pieces.length-1?this.lastPieceLength:this.pieceLength;return new S(i)})),this._reservations=this.pieces.map((()=>[])),this.bitfield=new u(this.pieces.length),this.emit("metadata"),!this.destroyed)if(this.skipVerify)this._markAllVerified(),this._onStore();else{const e=e=>{if(e)return this._destroy(e);this._debug("done verifying"),this._onStore()};this._debug("verifying existing torrent data"),this._fileModtimes&&this._store===b?this.getFileModtimes(((t,i)=>{if(t)return this._destroy(t);this.files.map(((e,t)=>i[t]===this._fileModtimes[t])).every((e=>e))?(this._markAllVerified(),this._onStore()):this._verifyPieces(e)})):this._verifyPieces(e)}}getFileModtimes(e){const t=[];k(this.files.map(((e,i)=>n=>{const r=this.addUID?c.join(this.name+" - "+this.infoHash.slice(0,8)):c.join(this.path,e.path);s.stat(r,((e,r)=>{if(e&&"ENOENT"!==e.code)return n(e);t[i]=r&&r.mtime.getTime(),n(null)}))})),F,(i=>{this._debug("done getting file modtimes"),e(i,t)}))}_verifyPieces(e){k(this.pieces.map(((e,t)=>e=>{if(this.destroyed)return e(new Error("torrent is destroyed"));const i={};t===this.pieces.length-1&&(i.length=this.lastPieceLength),this.store.get(t,i,((i,n)=>this.destroyed?e(new Error("torrent is destroyed")):i?A((()=>e(null))):void I(n,(i=>{if(this.destroyed)return e(new Error("torrent is destroyed"));i===this._hashes[t]?(this._debug("piece verified %s",t),this._markVerified(t)):this._debug("piece invalid %s",t),e(null)}))))})),F,e)}rescanFiles(e){if(this.destroyed)throw new Error("torrent is destroyed");e||(e=G),this._verifyPieces((t=>{if(t)return this._destroy(t),e(t);this._checkDone(),e(null)}))}_markAllVerified(){for(let e=0;ee))return!0;return!1}_onStore(){this.destroyed||(this._debug("on store"),this._startDiscovery(),this.ready=!0,this.emit("ready"),this._checkDone(),this._updateSelections(),this.wires.forEach((e=>{e.ut_metadata&&e.ut_metadata.setMetadata(this.metadata),this._onWireWithMetadata(e)})))}destroy(e,t){if("function"==typeof e)return this.destroy(null,e);this._destroy(null,e,t)}_destroy(e,t,i){if("function"==typeof t)return this._destroy(e,null,t);if(this.destroyed)return;this.destroyed=!0,this._debug("destroy"),this.client._remove(this),clearInterval(this._rechokeIntervalId),this._xsRequests.forEach((e=>{e.abort()})),this._rarityMap&&this._rarityMap.destroy();for(const e in this._peers)this.removePeer(e);this.files.forEach((e=>{e instanceof L&&e._destroy()}));const n=this._servers.map((e=>t=>{e.destroy(t)}));if(this.discovery&&n.push((e=>{this.discovery.destroy(e)})),this.store){let e=this._destroyStoreOnDestroy;t&&void 0!==t.destroyStore&&(e=t.destroyStore),n.push((t=>{e?this.store.destroy(t):this.store.close(t)}))}w(n,i),e&&(0===this.listenerCount("error")?this.client.emit("error",e):this.emit("error",e)),this.emit("close"),this.client=null,this.files=[],this.discovery=null,this.store=null,this._rarityMap=null,this._peers=null,this._servers=null,this._xsRequests=null}addPeer(e){if(this.destroyed)throw new Error("torrent is destroyed");if(!this.infoHash)throw new Error("addPeer() must not be called before the `infoHash` event");let t;if(this.client.blocked){if("string"==typeof e){let i;try{i=l(e)}catch(t){return this._debug("ignoring peer: invalid %s",e),this.emit("invalidPeer",e),!1}t=i[0]}else"string"==typeof e.remoteAddress&&(t=e.remoteAddress);if(t&&this.client.blocked.contains(t))return this._debug("ignoring peer: blocked %s",e),"string"!=typeof e&&e.destroy(),this.emit("blockedPeer",e),!1}const i=this.client.utp&&this._isIPv4(t)?"utp":"tcp",n=!!this._addPeer(e,i);return n?this.emit("peer",e):this.emit("invalidPeer",e),n}_addPeer(e,t){if(this.destroyed)return"string"!=typeof e&&e.destroy(),null;if("string"==typeof e&&!this._validAddr(e))return this._debug("ignoring peer: invalid %s",e),null;const i=e&&e.id||e;if(this._peers[i])return this._debug("ignoring peer: duplicate (%s)",i),"string"!=typeof e&&e.destroy(),null;if(this.paused)return this._debug("ignoring peer: torrent is paused"),"string"!=typeof e&&e.destroy(),null;let n;return this._debug("add peer %s",i),n="string"==typeof e?"utp"===t?O.createUTPOutgoingPeer(e,this,this.client.throttleGroups):O.createTCPOutgoingPeer(e,this,this.client.throttleGroups):O.createWebRTCPeer(e,this,this.client.throttleGroups),this._registerPeer(n),"string"==typeof e&&(this._queue.push(n),this._drain()),n}addWebSeed(e){if(this.destroyed)throw new Error("torrent is destroyed");let t,i;if("string"==typeof e){if(t=e,!/^https?:\/\/.+/.test(t))return this.emit("warning",new Error(`ignoring invalid web seed: ${t}`)),void this.emit("invalidPeer",t);if(this._peers[t])return this.emit("warning",new Error(`ignoring duplicate web seed: ${t}`)),void this.emit("invalidPeer",t);i=new N(t,this)}else{if(!e||"string"!=typeof e.connId)return void this.emit("warning",new Error("addWebSeed must be passed a string or connection object with id property"));if(i=e,t=i.connId,this._peers[t])return this.emit("warning",new Error(`ignoring duplicate web seed: ${t}`)),void this.emit("invalidPeer",t)}this._debug("add web seed %s",t);const n=O.createWebSeedPeer(i,t,this,this.client.throttleGroups);this._registerPeer(n),this.emit("peer",t)}_addIncomingPeer(e){return this.destroyed?e.destroy(new Error("torrent is destroyed")):this.paused?e.destroy(new Error("torrent is paused")):(this._debug("add incoming peer %s",e.id),void this._registerPeer(e))}_registerPeer(e){e.on("download",(e=>{this.destroyed||(this.received+=e,this._downloadSpeed(e),this.client._downloadSpeed(e),this.emit("download",e),this.destroyed||this.client.emit("download",e))})),e.on("upload",(e=>{this.destroyed||(this.uploaded+=e,this._uploadSpeed(e),this.client._uploadSpeed(e),this.emit("upload",e),this.destroyed||this.client.emit("upload",e))})),this._peers[e.id]=e,this._peersLength+=1}removePeer(e){const t=e?.id||e;e&&!e.id&&(e=this._peers?.[t]),e&&(e.destroy(),this.destroyed||(this._debug("removePeer %s",t),delete this._peers[t],this._peersLength-=1,this._drain()))}select(e,t,i,n){if(this.destroyed)throw new Error("torrent is destroyed");if(e<0||tt.priority-e.priority)),this._updateSelections()}deselect(e,t,i){if(this.destroyed)throw new Error("torrent is destroyed");i=Number(i)||0,this._debug("deselect %s-%s (priority %s)",e,t,i);for(let n=0;n{if(!this.destroyed&&!this.client.dht.destroyed){if(!e.remoteAddress)return this._debug("ignoring PORT from peer with no address");if(0===i||i>65536)return this._debug("ignoring invalid PORT from peer");this._debug("port: %s (from %s)",i,t),this.client.dht.addNode({host:e.remoteAddress,port:i})}})),e.on("timeout",(()=>{this._debug("wire timeout (%s)",t),e.destroy()})),"webSeed"!==e.type&&e.setTimeout(3e4,!0),e.setKeepAlive(!0),e.use(C(this.metadata)),e.ut_metadata.on("warning",(e=>{this._debug("ut_metadata warning: %s",e.message)})),this.metadata||(e.ut_metadata.on("metadata",(e=>{this._debug("got metadata via ut_metadata"),this._onMetadata(e)})),e.ut_metadata.fetch()),"function"!=typeof B||this.private||(e.use(B()),e.ut_pex.on("peer",(e=>{this.done||(this._debug("ut_pex: got peer: %s (from %s)",e,t),this.addPeer(e))})),e.ut_pex.on("dropped",(e=>{const i=this._peers[e];i&&!i.connected&&(this._debug("ut_pex: dropped peer: %s (from %s)",e,t),this.removePeer(e))})),e.once("close",(()=>{e.ut_pex.reset()}))),e.use(y()),this.emit("wire",e,t),this.ready&&A((()=>{this._onWireWithMetadata(e)}))}_onWireWithMetadata(e){let t=null;const i=()=>{this.destroyed||e.destroyed||(this._numQueued>2*(this._numConns-this.numPeers)&&e.amInterested?e.destroy():(t=setTimeout(i,z),t.unref&&t.unref()))};let n;const r=()=>{if(e.peerPieces.buffer.length===this.bitfield.buffer.length){for(n=0;n{r(),this._update(),this._updateWireInterest(e)})),e.on("have",(()=>{r(),this._update(),this._updateWireInterest(e)})),e.lt_donthave.on("donthave",(()=>{r(),this._update(),this._updateWireInterest(e)})),e.on("have-all",(()=>{e.isSeeder=!0,e.choke(),this._update(),this._updateWireInterest(e)})),e.on("have-none",(()=>{e.isSeeder=!1,this._update(),this._updateWireInterest(e)})),e.on("allowed-fast",(e=>{this._update()})),e.once("interested",(()=>{e.unchoke()})),e.once("close",(()=>{clearTimeout(t)})),e.on("choke",(()=>{clearTimeout(t),t=setTimeout(i,z),t.unref&&t.unref()})),e.on("unchoke",(()=>{clearTimeout(t),this._update()})),e.on("request",((t,i,n,r)=>{if(n>131072)return e.destroy();this.pieces[t]||this.store.get(t,{offset:i,length:n},r)})),e.hasFast&&this._hasAllPieces()?e.haveAll():e.hasFast&&this._hasNoPieces()?e.haveNone():e.bitfield(this.bitfield),this._updateWireInterest(e),e.peerExtensions.dht&&this.client.dht&&this.client.dht.listening&&e.port(this.client.dht.address().port),"webSeed"!==e.type&&(t=setTimeout(i,z),t.unref&&t.unref()),e.isSeeder=!1,r()}_updateSelections(){this.ready&&!this.destroyed&&(A((()=>{this._gcSelections()})),this._updateInterest(),this._update())}_gcSelections(){for(let e=0;ethis._updateWireInterest(e))),e!==this._amInterested&&(this._amInterested?this.emit("interested"):this.emit("uninterested"))}_updateWireInterest(e){let t=!1;for(let i=0;i{t._updateWire(e)}),{timeout:250}):t._updateWire(e)}_updateWire(e){if(e.destroyed)return!1;const t=this,i=$(e,.5);if(e.requests.length>=i)return;const n=$(e,1);if(e.peerChoking)e.hasFast&&e.peerAllowedFastSet.length>0&&!this._hasMorePieces(e.peerAllowedFastSet.length-1)&&function(){if(e.requests.length>=n)return!1;for(const i of e.peerAllowedFastSet){if(e.peerPieces.get(i)&&!t.bitfield.get(i))for(;t._request(e,i,!1)&&e.requests.length=n.from+n.offset;--s)if(e.peerPieces.get(s)&&t._request(e,s,!1))return}}();a(!1)||a(!0)}function r(t,i,n,r){return s=>s>=t&&s<=i&&!(s in n)&&e.peerPieces.get(s)&&(!r||r(s))}function s(e){let i=e;for(let n=e;n=n)return!0;const a=function(){const i=e.downloadSpeed()||1;if(i>H)return()=>!0;const n=Math.max(1,e.requests.length)*S.BLOCK_LENGTH/i;let r=10,s=0;return e=>{if(!r||t.bitfield.get(e))return!0;let a=t.pieces[e].missing;for(;s0))return r--,!1}return!0}}();for(let o=0;o({wire:e,random:Math.random()}))).sort(((e,t)=>{const i=e.wire,n=t.wire;return i.downloadSpeed()!==n.downloadSpeed()?i.downloadSpeed()-n.downloadSpeed():i.uploadSpeed()!==n.uploadSpeed()?i.uploadSpeed()-n.uploadSpeed():i.amChoking!==n.amChoking?i.amChoking?-1:1:e.random-t.random})).map((e=>e.wire));this._rechokeOptimisticTime<=0?this._rechokeOptimisticWire=null:this._rechokeOptimisticTime-=1;let t=0;for(;e.length>0&&t0){const t=e.filter((e=>e.peerInterested));if(t.length>0){const e=t[(i=t.length,Math.random()*i|0)];e.unchoke(),this._rechokeOptimisticWire=e,this._rechokeOptimisticTime=2}}var i;e.filter((e=>e!==this._rechokeOptimisticWire)).forEach((e=>e.choke()))}_hotswap(e,t){const i=e.downloadSpeed();if(i=H||(2*o>i||o>a||(r=t,a=o))}if(!r)return!1;for(s=0;s=a)return!1;const o=n.pieces[t];let c=s?o.reserveRemaining():o.reserve();if(-1===c&&i&&n._hotswap(e,t)&&(c=s?o.reserveRemaining():o.reserve()),-1===c)return!1;let l=n._reservations[t];l||(l=n._reservations[t]=[]);let u=l.indexOf(null);-1===u&&(u=l.length),l[u]=e;const p=o.chunkOffset(c),d=s?o.chunkLengthRemaining(c):o.chunkLength(c);function f(){A((()=>{n._update()}))}return e.request(t,p,d,(function i(r,a){if(n.destroyed)return;if(!n.ready)return n.once("ready",(()=>{i(r,a)}));if(l[u]===e&&(l[u]=null),o!==n.pieces[t])return f();if(r)return n._debug("error getting piece %s (offset: %s length: %s) from %s: %s",t,p,d,`${e.remoteAddress}:${e.remotePort}`,r.message),s?o.cancelRemaining(c):o.cancel(c),void f();if(n._debug("got piece %s (offset: %s length: %s) from %s",t,p,d,`${e.remoteAddress}:${e.remotePort}`),!o.set(c,a,e))return f();const h=o.flush();I(h,(e=>{n.destroyed||(e===n._hashes[t]?(n._debug("piece verified %s",t),n.store.put(t,h,(e=>{e?n._destroy(e):(n.pieces[t]=null,n._markVerified(t),n.wires.forEach((e=>{e.have(t)})),n._checkDone()&&!n.destroyed&&n.discovery.complete(),f())}))):(n.pieces[t]=new S(o.length),n.emit("warning",new Error(`Piece ${t} failed verification`)),f()))}))})),!0}_checkDone(){if(this.destroyed)return;this.files.forEach((e=>{if(!e.done){for(let t=e._startPiece;t<=e._endPiece;++t)if(!this.bitfield.get(t))return;e.done=!0,e.emit("done"),this._debug(`file done: ${e.name}`)}}));let e=!0;for(const t of this._selections){for(let i=t.from;i<=t.to;i++)if(!this.bitfield.get(i)){e=!1;break}if(!e)break}return!this.done&&e?(this.done=!0,this._debug(`torrent done: ${this.infoHash}`),this.emit("done")):this.done=!1,this._gcSelections(),e}load(e,t){if(this.destroyed)throw new Error("torrent is destroyed");if(!this.ready)return this.once("ready",(()=>{this.load(e,t)}));Array.isArray(e)||(e=[e]),t||(t=G);const i=R.from(_(e)),n=new d(this.store,this.pieceLength);M(i,n,(e=>{if(e)return t(e);this._markAllVerified(),this._checkDone(),t(null)}))}createServer(e){if("function"!=typeof U)throw new Error("node.js-only method");if(this.destroyed)throw new Error("torrent is destroyed");const t=new U(this,e);return this._servers.push(t),t}pause(){this.destroyed||(this._debug("pause"),this.paused=!0)}resume(){this.destroyed||(this._debug("resume"),this.paused=!1,this._drain())}_debug(){const e=[].slice.call(arguments);e[0]=`[${this.client?this.client._debugId:"No Client"}] [${this._debugId}] ${e[0]}`,D(...e)}_drain(){if(this._debug("_drain numConns %s maxConns %s",this._numConns,this.client.maxConns),"function"!=typeof a.connect||this.destroyed||this.paused||this._numConns>=this.client.maxConns)return;this._debug("drain (%s queued, %s/%s peers)",this._numQueued,this.numPeers,this.client.maxConns);const e=this._queue.shift();if(!e)return;this._debug("%s connect attempt to %s",e.type,e.addr);const t=l(e.addr),i={host:t[0],port:t[1]};this.client.utp&&"utpOutgoing"===e.type?e.conn=q.connect(i.port,i.host):e.conn=a.connect(i);const n=e.conn;n.once("connect",(()=>{this.destroyed||e.onConnect()})),n.once("error",(t=>{e.destroy(t)})),e.startConnectTimeout(),n.on("close",(()=>{if(this.destroyed)return;if(e.retries>=W.length){if(this.client.utp){const t=this._addPeer(e.addr,"tcp");t&&(t.retries=0)}else this._debug("conn %s closed: will not re-add (max %s attempts)",e.addr,W.length);return}const t=W[e.retries];this._debug("conn %s closed: will re-add to queue in %sms (attempt %s)",e.addr,t,e.retries+1);const i=setTimeout((()=>{if(this.destroyed)return;const t=l(e.addr)[0],i=this.client.utp&&this._isIPv4(t)?"utp":"tcp",n=this._addPeer(e.addr,i);n&&(n.retries=e.retries+1)}),t);i.unref&&i.unref()}))}_validAddr(e){let t;try{t=l(e)}catch(e){return!1}const i=t[0],n=t[1];return n>0&&n<65535&&!("127.0.0.1"===i&&n===this.client.torrentPort)}_isIPv4(e){return/^((?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])[.]){3}(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])$/.test(e)}}}).call(this)}).call(this,e("_process"),"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"../package.json":450,"./file.js":445,"./peer.js":446,"./rarity-map.js":447,"./server.js":67,"./utp.js":67,"./webconn.js":449,_process:296,"addr-to-ip-port":2,bitfield:26,"cache-chunk-store":117,"chunk-store-stream/write":133,cpus:137,debug:146,events:178,fs:67,"fs-chunk-store":246,"immediate-chunk-store":216,"join-async-iterator":220,lt_donthave:227,"memory-chunk-store":246,net:67,os:67,"parse-torrent":287,path:288,pump:304,"queue-microtask":309,"random-iterate":311,"run-parallel":336,"run-parallel-limit":335,"simple-get":349,"simple-sha1":366,streamx:426,throughput:430,"torrent-discovery":433,"torrent-piece":434,ut_metadata:439,ut_pex:67}],449:[function(e,t,i){(function(i){(function(){const{default:n}=e("bitfield"),r=e("debug"),s=e("simple-get"),a=e("lt_donthave"),o=e("simple-sha1"),c=e("bittorrent-protocol"),l=r("webtorrent:webconn"),u=e("../package.json").version;t.exports=class extends c{constructor(e,t){super(),this.url=e,this.connId=e,this.webPeerId=o.sync(e),this._torrent=t,this._init()}_init(){this.setKeepAlive(!0),this.use(a()),this.once("handshake",((e,t)=>{if(this.destroyed)return;this.handshake(e,this.webPeerId);const i=this._torrent.pieces.length,r=new n(i);for(let e=0;e<=i;e++)r.set(e,!0);this.bitfield(r)})),this.once("interested",(()=>{l("interested"),this.unchoke()})),this.on("uninterested",(()=>{l("uninterested")})),this.on("choke",(()=>{l("choke")})),this.on("unchoke",(()=>{l("unchoke")})),this.on("bitfield",(()=>{l("bitfield")})),this.lt_donthave.on("donthave",(()=>{l("donthave")})),this.on("request",((e,t,i,n)=>{l("request pieceIndex=%d offset=%d length=%d",e,t,i),this.httpRequest(e,t,i,((t,i)=>{if(t){this.lt_donthave.donthave(e);const t=setTimeout((()=>{this.destroyed||this.have(e)}),1e4);t.unref&&t.unref()}n(t,i)}))}))}httpRequest(e,t,n,r){const a=e*this._torrent.pieceLength+t,o=a+n-1,c=this._torrent.files;let p;if(c.length<=1)p=[{url:this.url,start:a,end:o}];else{const e=c.filter((e=>e.offset<=o&&e.offset+e.length>a));if(e.length<1)return r(new Error("Could not find file corresponding to web seed range request"));p=e.map((e=>{const t=e.offset+e.length-1;return{url:this.url+("/"===this.url[this.url.length-1]?"":"/")+e.path.replace(this._torrent.path,""),fileOffsetInRange:Math.max(e.offset-a,0),start:Math.max(a-e.offset,0),end:Math.min(t,o-e.offset)}}))}let d,f=0,h=!1;p.length>1&&(d=i.alloc(n)),p.forEach((i=>{const a=i.url,o=i.start,c=i.end;l("Requesting url=%s pieceIndex=%d offset=%d length=%d start=%d end=%d",a,e,t,n,o,c);const m={url:a,method:"GET",headers:{"user-agent":`WebTorrent/${u} (https://webtorrent.io)`,range:`bytes=${o}-${c}`},timeout:6e4};function b(e,t){if(e.statusCode<200||e.statusCode>=300){if(h)return;return h=!0,r(new Error(`Unexpected HTTP status code ${e.statusCode}`))}l("Got data of length %d",t.length),1===p.length?r(null,t):(t.copy(d,i.fileOffsetInRange),++f===p.length&&r(null,d))}s.concat(m,((e,t,i)=>{if(!h)return e?"undefined"==typeof window||a.startsWith(`${window.location.origin}/`)?(h=!0,r(e)):s.head(a,((t,i)=>{if(!h){if(t)return h=!0,r(t);if(i.statusCode<200||i.statusCode>=300)return h=!0,r(new Error(`Unexpected HTTP status code ${i.statusCode}`));if(i.url===a)return h=!0,r(e);m.url=i.url,s.concat(m,((e,t,i)=>{if(!h)return e?(h=!0,r(e)):void b(t,i)}))}})):void b(t,i)}))}))}destroy(){super.destroy(),this._torrent=null}}}).call(this)}).call(this,e("buffer").Buffer)},{"../package.json":450,bitfield:26,"bittorrent-protocol":27,buffer:110,debug:146,lt_donthave:227,"simple-get":349,"simple-sha1":366}],450:[function(e,t,i){t.exports={version:"1.9.7"}},{}],451:[function(e,t,i){t.exports=function e(t,i){if(t&&i)return e(t)(i);if("function"!=typeof t)throw new TypeError("need wrapper function");return Object.keys(t).forEach((function(e){n[e]=t[e]})),n;function n(){for(var e=new Array(arguments.length),i=0;i1080?(U.setProps({placement:"right"}),q.setProps({placement:"right"}),N.setProps({placement:"right"})):(U.setProps({placement:"top"}),q.setProps({placement:"top"}),N.setProps({placement:"top"}))}function F(e){X();try{console.info("Attempting parse"),l=n(e),V(),l.xs&&(console.info("Magnet includes xs, attempting remote parse"),W(l.xs))}catch(t){console.warn(t),"magnet"==c?(console.info("Attempting remote parse"),W(e)):(z.error("Problem parsing input. Is this a .torrent file?"),console.error("Problem parsing input"))}}function W(e){n.remote(e,(function(e,t){if(e)return z.error("Problem remotely fetching that file or parsing result"),console.warn(e),void X();c="remote-torrent-file",m.innerHTML='',b.setContent("Currently loaded information sourced from remotely fetched Torrent file"),l=t,V()}))}function V(){if(console.log(l),w.value=l.infoHash,v.value=l.name?l.name:"",l.created?(y.value=l.created.toISOString().slice(0,19),y.type="datetime-local"):y.type="text",x.value=l.createdBy?" by "+l.createdBy:"",_.value=l.comment?l.comment:"",T.value=l.pieces?l.pieces.length.toLocaleString()+" "+r.format(l.pieceLength,{decimalPlaces:1,unitSeparator:" "})+" pieces (last piece "+r.format(l.lastPieceLength,{decimalPlaces:1,unitSeparator:" "})+")":"",M.innerHTML="",l.announce&&l.announce.length)for(let e=0;e',n.addEventListener("click",J),t.appendChild(n),M.appendChild(t)}if(A.innerHTML="",l.urlList&&l.urlList.length)for(let e=0;e',n.addEventListener("click",J),t.appendChild(n),A.appendChild(t)}if(C.innerHTML="",l.files&&l.files.length){if(B.style.display="none",l.files.length<100)for(let e of l.files){let t=$(s.lookup(e.name));C.appendChild(K(t,e.name,e.length))}else{for(let e=0;e<100;e++){let t=$(s.lookup(l.files[e].name));C.appendChild(K(t,l.files[e].name,l.files[e].length))}C.appendChild(K("","...and another "+(l.files.length-100)+" more files",""))}C.appendChild(K("folder-tree","",l.length)),N.setContent("Download Torrent file"),P.addEventListener("click",ie),P.disabled=!1}else D.torrents.length>0?(B.style.display="none",C.innerHTML=''):(B.style.display="block",C.innerHTML=''),N.setContent("Files metadata is required to generate a Torrent file. Try fetching files list from WebTorrent."),P.removeEventListener("click",ie),P.disabled=!0;R.setAttribute("data-clipboard-text",window.location.origin+"#"+n.toMagnetURI(l)),L.setAttribute("data-clipboard-text",n.toMagnetURI(l)),u.style.display="none",h.style.display="flex",window.location.hash=n.toMagnetURI(l),l.name?document.title="Torrent Parts | "+l.name:document.title="Torrent Parts | Inspect and edit what's in your Torrent file or Magnet link",b.enable()}function K(e,t,i){let n=document.createElement("tr"),s=document.createElement("td");e&&(s.innerHTML=''),n.appendChild(s);let a=document.createElement("td");a.innerHTML=t,n.appendChild(a);let o=document.createElement("td");return o.innerHTML=r.format(i,{decimalPlaces:1,unitSeparator:" "}),n.appendChild(o),n}function $(e){if(!e)return"file";switch(!0){case e.includes("msword"):case e.includes("wordprocessingml"):case e.includes("opendocument.text"):case e.includes("abiword"):return"file-word";case e.includes("ms-excel"):case e.includes("spreadsheet"):case e.includes("powerpoint"):case e.includes("presentation"):return"file-powerpoint";case e.includes("7z-"):case e.includes("iso9660"):case e.includes("zip"):case e.includes("octet-stream"):return"file-archive";case e.includes("csv"):return"file-csv";case e.includes("pdf"):return"file-pdf";case e.includes("font"):return"file-contract";case e.includes("text"):case e.includes("subrip"):case e.includes("vtt"):return"file-alt";case e.includes("audio"):return"file-audio";case e.includes("image"):return"file-image";case e.includes("video"):return"file-video";default:return"file"}}function G(e){this.dataset.group?l[this.dataset.group][this.dataset.index]=this.value?this.value:"":l[this.id]=this.value?this.value:"",window.location.hash=n.toMagnetURI(l),ee()}function X(){document.getElementById("magnet").value="",document.getElementById("torrent").value="",u.style.display="flex",h.style.display="none",v.value="",y.value="",x.value="",_.value="",w.value="",M.innerHTML="",A.innerHTML="",D.torrents.forEach((e=>e.destroy())),B.style.display="block",C.innerHTML="",window.location.hash="",R.setAttribute("data-clipboard-text",""),L.setAttribute("data-clipboard-text",""),document.title="Torrent Parts | Inspect and edit what's in your Torrent file or Magnet link",b.disable()}async function Y(){k.className="disabled",k.innerHTML="Adding...";try{let e=await fetch("https://newtrackon.com/api/stable"),t=await e.text();l.announce=l.announce.concat(t.split("\n\n")),l.announce.push("http://bt1.archive.org:6969/announce"),l.announce.push("http://bt2.archive.org:6969/announce"),l.announce=l.announce.filter(((e,t)=>e&&l.announce.indexOf(e)===t)),z.success("Added known working trackers from newTrackon"),ee()}catch(e){z.error("Problem fetching trackers from newTrackon"),console.warn(e)}k.className="",k.innerHTML="Add Known Working Trackers",V()}function Z(){l[this.dataset.type].unshift(""),V()}function J(){l[this.parentElement.className].splice(this.parentElement.dataset.index,1),V()}function Q(e){l[e]=[],ee(),V()}function ee(){l.created=new Date,l.createdBy="Torrent Parts ",l.created?(y.value=l.created.toISOString().slice(0,19),y.type="datetime-local"):y.type="text",x.value=l.createdBy?" by "+l.createdBy:""}function te(){console.info("Attempting fetching files from Webtorrent..."),B.style.display="none",l.announce.push("wss://tracker.webtorrent.io"),l.announce.push("wss://tracker.openwebtorrent.com"),l.announce.push("wss://tracker.btorrent.xyz"),l.announce.push("wss://tracker.fastcast.nz"),l.announce=l.announce.filter(((e,t)=>e&&l.announce.indexOf(e)===t)),D.add(n.toMagnetURI(l),(e=>{l.info=Object.assign({},e.info),l.files=e.files,l.infoBuffer=e.infoBuffer,l.length=e.length,l.lastPieceLength=e.lastPieceLength,ee(),V(),z.success("Fetched file details from Webtorrent peers"),e.destroy()})),V()}function ie(){let e=n.toTorrentFile(l);if(null!==e&&navigator.msSaveBlob)return navigator.msSaveBlob(new Blob([e],{type:"application/x-bittorrent"}),l.name+".torrent");let t=document.createElement("a");t.style.display="none";let i=window.URL.createObjectURL(new Blob([e],{type:"application/x-bittorrent"}));t.setAttribute("href",i),t.setAttribute("download",l.name+".torrent"),document.body.appendChild(t),t.click(),window.URL.revokeObjectURL(i),t.remove()}window.addEventListener("resize",H),H(),document.addEventListener("DOMContentLoaded",(function(){document.getElementById("magnet").addEventListener("keyup",(function(e){e.preventDefault(),"Enter"===e.key&&(c="magnet",m.innerHTML='',b.setContent("Currently loaded information sourced from Magnet URL"),F(magnet.value))})),document.getElementById("torrent").addEventListener("change",(function(e){e.preventDefault(),e.target.files[0].arrayBuffer().then((function(e){c="torrent-file",m.innerHTML='',b.setContent("Currently loaded information sourced from Torrent file"),F(t.from(e))}))})),document.addEventListener("dragover",(function(e){e.preventDefault()})),document.addEventListener("drop",(function(e){e.preventDefault(),e.dataTransfer.items[0].getAsFile().arrayBuffer().then((function(e){c="torrent-file",m.innerHTML='',b.setContent("Currently loaded information sourced from Torrent file"),F(t.from(e))}))})),p.addEventListener("click",(function(e){e.preventDefault(),z.success("Parsing Ubuntu 22.04 Magnet URL"),c="magnet",m.innerHTML='',b.setContent("Currently loaded information sourced from Magnet URL"),F("magnet:?xt=urn:btih:2c6b6858d61da9543d4231a71db4b1c9264b0685&dn=ubuntu-22.04-desktop-amd64.iso&tr=https%3A%2F%2Ftorrent.ubuntu.com%2Fannounce&tr=https%3A%2F%2Fipv6.torrent.ubuntu.com%2Fannounce")})),d.addEventListener("click",(async function(e){e.preventDefault(),z.success("Fetching and Parsing “The WIRED CD” Torrent File..."),c="remote-torrent-file",m.innerHTML='',b.setContent("Currently loaded information sourced from remotely fetched Torrent file"),W("https://webtorrent.io/torrents/wired-cd.torrent")})),f.addEventListener("click",(async function(e){e.preventDefault(),z.success("Parsing Jack Johnson Archive.org Torrent File");let i=await fetch("/ext/jj2008-06-14.mk4_archive.torrent"),n=await i.arrayBuffer();c="torrent-file",m.innerHTML='',b.setContent("Currently loaded information sourced from Torrent file"),F(t.from(n))}));let e=new i("#copyURL");e.on("success",(function(e){z.success("Copied site URL to clipboard!"),console.info(e)})),e.on("failure",(function(e){z.error("Problem copying to clipboard"),console.warn(e)}));let n=new i("#copyMagnet");n.on("success",(function(e){z.success("Copied Magnet URL to clipboard!")})),n.on("failure",(function(e){z.error("Problem copying to clipboard"),console.warn(e)})),v.addEventListener("input",G),v.addEventListener("change",G),v.addEventListener("reset",G),v.addEventListener("paste",G),g.addEventListener("click",X),_.addEventListener("input",G),_.addEventListener("change",G),_.addEventListener("reset",G),_.addEventListener("paste",G),k.addEventListener("click",Y),E.addEventListener("click",Z),S.addEventListener("click",(()=>Q("announce"))),j.addEventListener("click",Z),I.addEventListener("click",(()=>Q("urlList"))),B.addEventListener("click",te),o("[data-tippy-content]",{theme:"torrent-parts",animation:"shift-away-subtle"}),b.disable(),window.location.hash&&(c="shared-url",m.innerHTML='',b.setContent("Currently loaded information sourced from shared torrent.parts link"),F(window.location.hash.split("#")[1]))}))}).call(this)}).call(this,e("buffer").Buffer)},{buffer:110,bytes:116,clipboard:135,"mime-types":251,"parse-torrent":287,"tippy.js":431,webtorrent:443}]},{},[453]); \ No newline at end of file +const n=e("events"),r=e("path"),s=e("simple-concat"),a=e("create-torrent"),o=e("debug"),c=e("bittorrent-dht/client"),l=e("load-ip-set"),u=e("run-parallel"),p=e("parse-torrent"),d=e("simple-peer"),f=e("queue-microtask"),h=e("randombytes"),m=e("simple-sha1"),b=e("throughput"),{ThrottleGroup:v}=e("speed-limiter"),g=e("./lib/conn-pool.js"),y=e("./lib/torrent.js"),{version:x}=e("./package.json"),_=o("webtorrent"),w=x.replace(/\d*./g,(e=>("0"+e%100).slice(-2))).slice(0,4),k=`-WW${w}-`;class E extends n{constructor(t={}){super(),"string"==typeof t.peerId?this.peerId=t.peerId:i.isBuffer(t.peerId)?this.peerId=t.peerId.toString("hex"):this.peerId=i.from(k+h(9).toString("base64")).toString("hex"),this.peerIdBuffer=i.from(this.peerId,"hex"),"string"==typeof t.nodeId?this.nodeId=t.nodeId:i.isBuffer(t.nodeId)?this.nodeId=t.nodeId.toString("hex"):this.nodeId=h(20).toString("hex"),this.nodeIdBuffer=i.from(this.nodeId,"hex"),this._debugId=this.peerId.toString("hex").substring(0,7),this.destroyed=!1,this.listening=!1,this.torrentPort=t.torrentPort||0,this.dhtPort=t.dhtPort||0,this.tracker=void 0!==t.tracker?t.tracker:{},this.lsd=!1!==t.lsd,this.torrents=[],this.maxConns=Number(t.maxConns)||55,this.utp=E.UTP_SUPPORT&&!1!==t.utp,this._downloadLimit=Math.max("number"==typeof t.downloadLimit?t.downloadLimit:-1,-1),this._uploadLimit=Math.max("number"==typeof t.uploadLimit?t.uploadLimit:-1,-1),this.serviceWorker=null,this.workerKeepAliveInterval=null,this.workerPortCount=0,!0===t.secure&&e("./lib/peer").enableSecure(),this._debug("new webtorrent (peerId %s, nodeId %s, port %s)",this.peerId,this.nodeId,this.torrentPort),this.throttleGroups={down:new v({rate:Math.max(this._downloadLimit,0),enabled:this._downloadLimit>=0}),up:new v({rate:Math.max(this._uploadLimit,0),enabled:this._uploadLimit>=0})},this.tracker&&("object"!=typeof this.tracker&&(this.tracker={}),globalThis.WRTC&&!this.tracker.wrtc&&(this.tracker.wrtc=globalThis.WRTC)),"function"==typeof g?this._connPool=new g(this):f((()=>{this._onListening()})),this._downloadSpeed=b(),this._uploadSpeed=b(),!1!==t.dht&&"function"==typeof c?(this.dht=new c(Object.assign({},{nodeId:this.nodeId},t.dht)),this.dht.once("error",(e=>{this._destroy(e)})),this.dht.once("listening",(()=>{const e=this.dht.address();e&&(this.dhtPort=e.port)})),this.dht.setMaxListeners(0),this.dht.listen(this.dhtPort)):this.dht=!1,this.enableWebSeeds=!1!==t.webSeeds;const n=()=>{this.destroyed||(this.ready=!0,this.emit("ready"))};"function"==typeof l&&null!=t.blocklist?l(t.blocklist,{headers:{"user-agent":`WebTorrent/${x} (https://webtorrent.io)`}},((e,t)=>{if(e)return console.error(`Failed to load blocklist: ${e.message}`);this.blocked=t,n()})):f(n)}loadWorker(e,t=(()=>{})){if(!(e instanceof ServiceWorker))throw new Error("Invalid worker registration");if("activated"!==e.state)throw new Error("Worker isn't activated");this.serviceWorker=e,navigator.serviceWorker.addEventListener("message",(e=>{const{data:t}=e;if(!t.type||"webtorrent"===!t.type||!t.url)return null;let[i,...n]=t.url.slice(t.url.indexOf(t.scope+"webtorrent/")+11+t.scope.length).split("/");if(n=decodeURI(n.join("/")),!i||!n)return null;const[r]=e.ports,s=this.get(i)&&this.get(i).files.find((e=>e.path===n));if(!s)return null;const[a,o,c]=s._serve(t),l=o&&o[Symbol.asyncIterator](),u=()=>{r.onmessage=null,o&&o.destroy(),c&&c.destroy(),this.workerPortCount--,this.workerPortCount||(clearInterval(this.workerKeepAliveInterval),this.workerKeepAliveInterval=null)};r.onmessage=async e=>{if(e.data){let e;try{e=(await l.next()).value}catch(e){}r.postMessage(e),e||u(),this.workerKeepAliveInterval||(this.workerKeepAliveInterval=setInterval((()=>fetch(`${this.serviceWorker.scriptURL.slice(0,this.serviceWorker.scriptURL.lastIndexOf("/")+1).slice(window.location.origin.length)}webtorrent/keepalive/`)),2e4))}else u()},this.workerPortCount++,r.postMessage(a)})),fetch(`${this.serviceWorker.scriptURL.slice(0,this.serviceWorker.scriptURL.lastIndexOf("/")+1).slice(window.location.origin.length)}webtorrent/cancel/`).then((e=>{e.body.cancel()})),t(null,this.serviceWorker)}get downloadSpeed(){return this._downloadSpeed()}get uploadSpeed(){return this._uploadSpeed()}get progress(){const e=this.torrents.filter((e=>1!==e.progress));return e.reduce(((e,t)=>e+t.downloaded),0)/(e.reduce(((e,t)=>e+(t.length||0)),0)||1)}get ratio(){return this.torrents.reduce(((e,t)=>e+t.uploaded),0)/(this.torrents.reduce(((e,t)=>e+t.received),0)||1)}get(e){if(e instanceof y){if(this.torrents.includes(e))return e}else{let t;try{t=p(e)}catch(e){}if(!t)return null;if(!t.infoHash)throw new Error("Invalid torrent identifier");for(const e of this.torrents)if(e.infoHash===t.infoHash)return e}return null}add(e,t={},i=(()=>{})){if(this.destroyed)throw new Error("client is destroyed");"function"==typeof t&&([t,i]=[{},t]);const n=()=>{if(!this.destroyed)for(const e of this.torrents)if(e.infoHash===s.infoHash&&e!==s)return s._destroy(new Error(`Cannot add duplicate torrent ${s.infoHash}`)),void i(e)},r=()=>{this.destroyed||(i(s),this.emit("torrent",s))};this._debug("add"),t=t?Object.assign({},t):{};const s=new y(e,this,t);return this.torrents.push(s),s.once("_infoHash",n),s.once("ready",r),s.once("close",(function e(){s.removeListener("_infoHash",n),s.removeListener("ready",r),s.removeListener("close",e)})),s}seed(e,t,i){if(this.destroyed)throw new Error("client is destroyed");"function"==typeof t&&([t,i]=[{},t]),this._debug("seed"),(t=t?Object.assign({},t):{}).skipVerify=!0;const n="string"==typeof e;n&&(t.path=r.dirname(e)),t.createdBy||(t.createdBy=`WebTorrent/${w}`);const o=e=>{this._debug("on seed"),"function"==typeof i&&i(e),e.emit("seed"),this.emit("seed",e)},c=this.add(null,t,(e=>{const i=[i=>{if(n||t.preloadedStore)return i();e.load(l,i)}];this.dht&&i.push((t=>{e.once("dhtAnnounce",t)})),u(i,(t=>{if(!this.destroyed)return t?e._destroy(t):void o(e)}))}));let l;var p;return p=e,"undefined"!=typeof FileList&&p instanceof FileList?e=Array.from(e):Array.isArray(e)||(e=[e]),u(e.map((e=>i=>{!t.preloadedStore&&function(e){return"object"==typeof e&&null!=e&&"function"==typeof e.pipe}(e)?s(e,((t,n)=>{if(t)return i(t);n.name=e.name,i(null,n)})):i(null,e)})),((e,n)=>{if(!this.destroyed)return e?c._destroy(e):void a.parseInput(n,t,((e,r)=>{if(!this.destroyed){if(e)return c._destroy(e);l=r.map((e=>e.getStream)),a(n,t,((e,t)=>{if(this.destroyed)return;if(e)return c._destroy(e);const n=this.get(t);n?(console.warn("A torrent with the same id is already being seeded"),c._destroy(),"function"==typeof i&&i(n)):c._onTorrentId(t)}))}}))})),c}remove(e,t,i){if("function"==typeof t)return this.remove(e,null,t);this._debug("remove");if(!this.get(e))throw new Error(`No torrent with id ${e}`);this._remove(e,t,i)}_remove(e,t,i){if("function"==typeof t)return this._remove(e,null,t);const n=this.get(e);n&&(this.torrents.splice(this.torrents.indexOf(n),1),n.destroy(t,i),this.dht&&this.dht._tables.remove(n.infoHash))}address(){return this.listening?this._connPool?this._connPool.tcpServer.address():{address:"0.0.0.0",family:"IPv4",port:0}:null}throttleDownload(e){return e=Number(e),!(isNaN(e)||!isFinite(e)||e<-1)&&(this._downloadLimit=e,this._downloadLimit<0?this.throttleGroups.down.setEnabled(!1):(this.throttleGroups.down.setEnabled(!0),void this.throttleGroups.down.setRate(this._downloadLimit)))}throttleUpload(e){return e=Number(e),!(isNaN(e)||!isFinite(e)||e<-1)&&(this._uploadLimit=e,this._uploadLimit<0?this.throttleGroups.up.setEnabled(!1):(this.throttleGroups.up.setEnabled(!0),void this.throttleGroups.up.setRate(this._uploadLimit)))}destroy(e){if(this.destroyed)throw new Error("client already destroyed");this._destroy(null,e)}_destroy(e,t){this._debug("client destroy"),this.destroyed=!0;const i=this.torrents.map((e=>t=>{e.destroy(t)}));this._connPool&&i.push((e=>{this._connPool.destroy(e)})),this.dht&&i.push((e=>{this.dht.destroy(e)})),u(i,t),e&&this.emit("error",e),this.torrents=[],this._connPool=null,this.dht=null,this.throttleGroups.down.destroy(),this.throttleGroups.up.destroy()}_onListening(){if(this._debug("listening"),this.listening=!0,this._connPool){const e=this._connPool.tcpServer.address();e&&(this.torrentPort=e.port)}this.emit("listening")}_debug(){const e=[].slice.call(arguments);e[0]=`[${this._debugId}] ${e[0]}`,_(...e)}_getByHash(e){for(const t of this.torrents)if(t.infoHashHash||(t.infoHashHash=m.sync(i.from("72657132"+t.infoHash,"hex"))),e===t.infoHashHash)return t;return null}}E.WEBRTC_SUPPORT=d.WEBRTC_SUPPORT,E.UTP_SUPPORT=g.UTP_SUPPORT,E.VERSION=x,t.exports=E}).call(this)}).call(this,e("buffer").Buffer)},{"./lib/conn-pool.js":67,"./lib/peer":446,"./lib/torrent.js":448,"./package.json":450,"bittorrent-dht/client":67,buffer:110,"create-torrent":144,debug:146,events:178,"load-ip-set":67,"parse-torrent":287,path:288,"queue-microtask":309,randombytes:312,"run-parallel":336,"simple-concat":348,"simple-peer":350,"simple-sha1":366,"speed-limiter":384,throughput:430}],444:[function(e,t,i){const{Readable:n}=e("streamx"),r=e("debug")("webtorrent:file-stream");t.exports=class extends n{constructor(e,t){super(t??{}),this._torrent=e._torrent;const i=t&&t.start||0,n=t&&t.end&&t.end{this._notify()}))}_read(e){this._reading||(this._reading=!0,this._notify(e))}_notify(e=(()=>{})){if(!this._reading||0===this._missing)return e();if(!this._torrent.bitfield.get(this._piece))return e(),this._torrent.critical(this._piece,this._piece+this._criticalLength);if(this._notifying)return e();if(this._notifying=!0,this._torrent.destroyed)return this.destroy(new Error("Torrent removed"));const t=this._piece,i={};t===this._torrent.pieces.length-1&&(i.length=this._torrent.lastPieceLength),this._torrent.store.get(t,i,((i,n)=>{if(this._notifying=!1,!this.destroyed){if(r("read %s (length %s) (err %s)",t,n&&n.length,i&&i.message),i)return this.destroy(i);this._offset&&(n=n.slice(this._offset),this._offset=0),this._missing{const s=r===e.length-1?n:i;return t.get(r)?s:s-e[r].missing};let o=0;for(let t=r;t<=s;t+=1){const c=a(t);if(o+=c,t===r){const e=this.offset%i;o-=Math.min(e,c)}if(t===s){const t=(s===e.length-1?n:i)-(this.offset+this.length)%i;o-=Math.min(t,c)}}return o}get progress(){return this.length?this.downloaded/this.length:0}select(e){0!==this.length&&this._torrent.select(this._startPiece,this._endPiece,e)}deselect(){0!==this.length&&this._torrent.deselect(this._startPiece,this._endPiece,!1)}createReadStream(e){if(0===this.length){const e=new r;return l((()=>{e.end()})),e}const t=new f(this,e);return this._fileStreams.add(t),t.once("close",(()=>{this._fileStreams.delete(t)})),t}getBuffer(e){c(this.createReadStream(),this.length,e)}getBlob(e){if("undefined"==typeof window)throw new Error("browser-only method");const t=new o((t=>{e(null,t)}),{mimeType:this._getMimeType()});this.createReadStream().pipe(t)}getBlobURL(e){this.getBlob(((t,i)=>{e(null,URL.createObjectURL(i))}))}appendTo(e,t,i){if("undefined"==typeof window)throw new Error("browser-only method");a.append(this,e,t,i)}renderTo(e,t,i){if("undefined"==typeof window)throw new Error("browser-only method");a.render(this,e,t,i)}_serve(e){const t={status:200,headers:{"Accept-Ranges":"bytes","Content-Type":p.getType(this.name),"Cache-Control":"no-cache, no-store, must-revalidate, max-age=0",Expires:"0"},body:"HEAD"===e.method?"":"STREAM"};"document"===e.destination&&(t.headers["Content-Type"]="application/octet-stream",t.headers["Content-Disposition"]="attachment",t.body="DOWNLOAD");let i=u(this.length,e.headers.range||"");i.constructor===Array?(t.status=206,i=i[0],t.headers["Content-Range"]=`bytes ${i.start}-${i.end}/${this.length}`,t.headers["Content-Length"]=""+(i.end-i.start+1)):t.headers["Content-Length"]=this.length;const n="GET"===e.method&&this.createReadStream(i);let r=null;return n&&this.emit("stream",{stream:n,req:e,file:this},(e=>{r=e,d(e,(()=>{e&&e.destroy(),n.destroy()}))})),[t,r||n,r&&n]}getStreamURL(e=(()=>{})){if("undefined"==typeof window)throw new Error("browser-only method");if(!this._serviceWorker)throw new Error("No worker registered");if("activated"!==this._serviceWorker.state)throw new Error("Worker isn't activated");e(null,`${this._serviceWorker.scriptURL.slice(0,this._serviceWorker.scriptURL.lastIndexOf("/")+1).slice(window.location.origin.length)}webtorrent/${this._torrent.infoHash}/${encodeURI(this.path)}`)}streamTo(e,t=(()=>{})){if("undefined"==typeof window)throw new Error("browser-only method");if(!this._serviceWorker)throw new Error("No worker registered");if("activated"!==this._serviceWorker.state)throw new Error("Worker isn't activated");const i=this._serviceWorker.scriptURL.slice(0,this._serviceWorker.scriptURL.lastIndexOf("/")+1).slice(window.location.origin.length);e.src=`${i}webtorrent/${this._torrent.infoHash}/${encodeURI(this.path)}`,t(null,e)}_getMimeType(){return a.mime[s.extname(this.name).toLowerCase()]}_destroy(){this._destroyed=!0,this._torrent=null;for(const e of this._fileStreams)e.destroy();this._fileStreams.clear()}}},{"./file-stream.js":444,"end-of-stream":176,events:178,"fast-blob-stream":180,mime:253,path:288,"queue-microtask":309,"range-parser":314,"render-media":332,"stream-with-known-length-to-buffer":425,streamx:426}],446:[function(e,t,i){const n=e("events"),{Transform:r}=e("stream"),s=e("unordered-array-remove"),a=e("debug"),o=e("bittorrent-protocol"),c=a("webtorrent:peer");let l=!1;i.enableSecure=()=>{l=!0},i.createWebRTCPeer=(e,t,i)=>{const n=new d(e.id,"webrtc");if(n.conn=e,n.swarm=t,n.throttleGroups=i,n.conn.connected)n.onConnect();else{const e=()=>{n.conn.removeListener("connect",t),n.conn.removeListener("error",i)},t=()=>{e(),n.onConnect()},i=t=>{e(),n.destroy(t)};n.conn.once("connect",t),n.conn.once("error",i),n.startConnectTimeout()}return n},i.createTCPIncomingPeer=(e,t)=>u(e,"tcpIncoming",t),i.createUTPIncomingPeer=(e,t)=>u(e,"utpIncoming",t),i.createTCPOutgoingPeer=(e,t,i)=>p(e,t,"tcpOutgoing",i),i.createUTPOutgoingPeer=(e,t,i)=>p(e,t,"utpOutgoing",i);const u=(e,t,i)=>{const n=`${e.remoteAddress}:${e.remotePort}`,r=new d(n,t);return r.conn=e,r.addr=n,r.throttleGroups=i,r.onConnect(),r},p=(e,t,i,n)=>{const r=new d(e,i);return r.addr=e,r.swarm=t,r.throttleGroups=n,r};i.createWebSeedPeer=(e,t,i,n)=>{const r=new d(t,"webSeed");return r.swarm=i,r.conn=e,r.throttleGroups=n,r.onConnect(),r};class d extends n{constructor(e,t){super(),this.id=e,this.type=t,c("new %s Peer %s",t,e),this.addr=null,this.conn=null,this.swarm=null,this.wire=null,this.connected=!1,this.destroyed=!1,this.timeout=null,this.retries=0,this.sentPe1=!1,this.sentPe2=!1,this.sentPe3=!1,this.sentPe4=!1,this.sentHandshake=!1}onConnect(){if(this.destroyed)return;this.connected=!0,c("Peer %s connected",this.id),clearTimeout(this.connectTimeout);const e=this.conn;e.once("end",(()=>{this.destroy()})),e.once("close",(()=>{this.destroy()})),e.once("finish",(()=>{this.destroy()})),e.once("error",(e=>{this.destroy(e)}));const t=this.wire=new o(this.type,this.retries,l);t.once("end",(()=>{this.destroy()})),t.once("close",(()=>{this.destroy()})),t.once("finish",(()=>{this.destroy()})),t.once("error",(e=>{this.destroy(e)})),t.once("pe1",(()=>{this.onPe1()})),t.once("pe2",(()=>{this.onPe2()})),t.once("pe3",(()=>{this.onPe3()})),t.once("pe4",(()=>{this.onPe4()})),t.once("handshake",((e,t)=>{this.onHandshake(e,t)})),this.startHandshakeTimeout(),this.setThrottlePipes(),this.swarm&&("tcpOutgoing"===this.type?l&&0===this.retries&&!this.sentPe1?this.sendPe1():this.sentHandshake||this.handshake():"tcpIncoming"===this.type||this.sentHandshake||this.handshake())}sendPe1(){this.wire.sendPe1(),this.sentPe1=!0}onPe1(){this.sendPe2()}sendPe2(){this.wire.sendPe2(),this.sentPe2=!0}onPe2(){this.sendPe3()}sendPe3(){this.wire.sendPe3(this.swarm.infoHash),this.sentPe3=!0}onPe3(e){this.swarm&&(this.swarm.infoHashHash!==e&&this.destroy(new Error("unexpected crypto handshake info hash for this swarm")),this.sendPe4())}sendPe4(){this.wire.sendPe4(this.swarm.infoHash),this.sentPe4=!0}onPe4(){this.sentHandshake||this.handshake()}clearPipes(){this.conn.unpipe(),this.wire.unpipe()}setThrottlePipes(){const e=this;this.conn.pipe(this.throttleGroups.down.throttle()).pipe(new r({transform(t,i,n){e.emit("download",t.length),e.destroyed||n(null,t)}})).pipe(this.wire).pipe(this.throttleGroups.up.throttle()).pipe(new r({transform(t,i,n){e.emit("upload",t.length),e.destroyed||n(null,t)}})).pipe(this.conn)}onHandshake(e,t){if(!this.swarm)return;if(this.destroyed)return;if(this.swarm.destroyed)return this.destroy(new Error("swarm already destroyed"));if(e!==this.swarm.infoHash)return this.destroy(new Error("unexpected handshake info hash for this swarm"));if(t===this.swarm.peerId)return this.destroy(new Error("refusing to connect to ourselves"));c("Peer %s got handshake %s",this.id,e),clearTimeout(this.handshakeTimeout),this.retries=0;let i=this.addr;!i&&this.conn.remoteAddress&&this.conn.remotePort&&(i=`${this.conn.remoteAddress}:${this.conn.remotePort}`),this.swarm._onWire(this.wire,i),this.swarm&&!this.swarm.destroyed&&(this.sentHandshake||this.handshake())}handshake(){const e={dht:!this.swarm.private&&!!this.swarm.client.dht,fast:!0};this.wire.handshake(this.swarm.infoHash,this.swarm.client.peerId,e),this.sentHandshake=!0}startConnectTimeout(){clearTimeout(this.connectTimeout);const e={webrtc:25e3,tcpOutgoing:5e3,utpOutgoing:5e3};this.connectTimeout=setTimeout((()=>{this.destroy(new Error("connect timeout"))}),e[this.type]),this.connectTimeout.unref&&this.connectTimeout.unref()}startHandshakeTimeout(){clearTimeout(this.handshakeTimeout),this.handshakeTimeout=setTimeout((()=>{this.destroy(new Error("handshake timeout"))}),25e3),this.handshakeTimeout.unref&&this.handshakeTimeout.unref()}destroy(e){if(this.destroyed)return;this.destroyed=!0,this.connected=!1,c("destroy %s %s (error: %s)",this.type,this.id,e&&(e.message||e)),clearTimeout(this.connectTimeout),clearTimeout(this.handshakeTimeout);const t=this.swarm,i=this.conn,n=this.wire;this.swarm=null,this.conn=null,this.wire=null,t&&n&&s(t.wires,t.wires.indexOf(n)),i&&(i.on("error",(()=>{})),i.destroy()),n&&n.destroy(),t&&t.removePeer(this.id)}}},{"bittorrent-protocol":27,debug:146,events:178,stream:389,"unordered-array-remove":436}],447:[function(e,t,i){t.exports=class{constructor(e){this._torrent=e,this._numPieces=e.pieces.length,this._pieces=new Array(this._numPieces),this._onWire=e=>{this.recalculate(),this._initWire(e)},this._onWireHave=e=>{this._pieces[e]+=1},this._onWireBitfield=()=>{this.recalculate()},this._torrent.wires.forEach((e=>{this._initWire(e)})),this._torrent.on("wire",this._onWire),this.recalculate()}getRarestPiece(e){let t=[],i=1/0;for(let n=0;n{this._cleanupWireEvents(e)})),this._torrent=null,this._pieces=null,this._onWire=null,this._onWireHave=null,this._onWireBitfield=null}_initWire(e){e._onClose=()=>{this._cleanupWireEvents(e);for(let t=0;t0&&(i=Math.min(i,t))}return i}function G(){}t.exports=class extends r{constructor(e,t,i){super(),this._debugId="unknown infohash",this.client=t,this.announce=i.announce,this.urlList=i.urlList,this.path=i.path||K,this.addUID=i.addUID||!1,this.skipVerify=!!i.skipVerify,this._store=i.store||b,this._preloadedStore=i.preloadedStore||null,this._storeCacheSlots=void 0!==i.storeCacheSlots?i.storeCacheSlots:20,this._destroyStoreOnDestroy=i.destroyStoreOnDestroy||!1,this._getAnnounceOpts=i.getAnnounceOpts,"boolean"==typeof i.private&&(this.private=i.private),this.strategy=i.strategy||"sequential",this.maxWebConns=i.maxWebConns||4,this._rechokeNumSlots=!1===i.uploads||0===i.uploads?0:+i.uploads||10,this._rechokeOptimisticWire=null,this._rechokeOptimisticTime=0,this._rechokeIntervalId=null,this.ready=!1,this.destroyed=!1,this.paused=i.paused||!1,this.done=!1,this.metadata=null,this.store=null,this.storeOpts=i.storeOpts,this.files=[],this.pieces=[],this._amInterested=!1,this._selections=[],this._critical=[],this.wires=[],this._queue=[],this._peers={},this._peersLength=0,this.received=0,this.uploaded=0,this._downloadSpeed=T(),this._uploadSpeed=T(),this._servers=[],this._xsRequests=[],this._fileModtimes=i.fileModtimes,null!==e&&this._onTorrentId(e),this._debug("new torrent")}get timeRemaining(){return this.done?0:0===this.downloadSpeed?1/0:(this.length-this.downloaded)/this.downloadSpeed*1e3}get downloaded(){if(!this.bitfield)return 0;let e=0;for(let t=0,i=this.pieces.length;t{this.destroyed||this._onParsedTorrent(t)}))):E.remote(e,((e,t)=>{if(!this.destroyed)return e?this._destroy(e):void this._onParsedTorrent(t)}))}_onParsedTorrent(e){if(!this.destroyed){if(this._processParsedTorrent(e),!this.infoHash)return this._destroy(new Error("Malformed torrent data: No info hash"));this._rechokeIntervalId=setInterval((()=>{this._rechoke()}),1e4),this._rechokeIntervalId.unref&&this._rechokeIntervalId.unref(),this.emit("_infoHash",this.infoHash),this.destroyed||(this.emit("infoHash",this.infoHash),this.destroyed||(this.client.listening?this._onListening():this.client.once("listening",(()=>{this._onListening()}))))}}_processParsedTorrent(e){this._debugId=e.infoHash.toString("hex").substring(0,7),void 0!==this.private&&(e.private=this.private),this.announce&&(e.announce=e.announce.concat(this.announce)),this.client.tracker&&n.WEBTORRENT_ANNOUNCE&&!e.private&&(e.announce=e.announce.concat(n.WEBTORRENT_ANNOUNCE)),this.urlList&&(e.urlList=e.urlList.concat(this.urlList)),e.announce=Array.from(new Set(e.announce)),e.urlList=Array.from(new Set(e.urlList)),Object.assign(this,e),this.magnetURI=E.toMagnetURI(e),this.torrentFile=E.toTorrentFile(e)}_onListening(){this.destroyed||(this.info?this._onMetadata(this):(this.xs&&this._getMetadataFromServer(),this._startDiscovery()))}_startDiscovery(){if(this.discovery||this.destroyed)return;let e=this.client.tracker;e&&(e=Object.assign({},this.client.tracker,{getAnnounceOpts:()=>{if(this.destroyed)return;const e={uploaded:this.uploaded,downloaded:this.downloaded,left:Math.max(this.length-this.downloaded,0)};return this.client.tracker.getAnnounceOpts&&Object.assign(e,this.client.tracker.getAnnounceOpts()),this._getAnnounceOpts&&Object.assign(e,this._getAnnounceOpts()),e}})),this.peerAddresses&&this.peerAddresses.forEach((e=>this.addPeer(e))),this.discovery=new m({infoHash:this.infoHash,announce:this.announce,peerId:this.client.peerId,dht:!this.private&&this.client.dht,tracker:e,port:this.client.torrentPort,userAgent:V,lsd:this.client.lsd}),this.discovery.on("error",(e=>{this._destroy(e)})),this.discovery.on("peer",((e,t)=>{this._debug("peer %s discovered via %s",e,t),"string"==typeof e&&this.done||this.addPeer(e)})),this.discovery.on("trackerAnnounce",(()=>{this.emit("trackerAnnounce"),0===this.numPeers&&this.emit("noPeers","tracker")})),this.discovery.on("dhtAnnounce",(()=>{this.emit("dhtAnnounce"),0===this.numPeers&&this.emit("noPeers","dht")})),this.discovery.on("warning",(e=>{this.emit("warning",e)}))}_getMetadataFromServer(){const e=this,t=(Array.isArray(this.xs)?this.xs:[this.xs]).map((t=>i=>{!function(t,i){if(0!==t.indexOf("http://")&&0!==t.indexOf("https://"))return e.emit("warning",new Error(`skipping non-http xs param: ${t}`)),i(null);const n={url:t,method:"GET",headers:{"user-agent":V}};let r;try{r=v.concat(n,s)}catch(n){return e.emit("warning",new Error(`skipping invalid url xs param: ${t}`)),i(null)}function s(n,r,s){if(e.destroyed)return i(null);if(e.metadata)return i(null);if(n)return e.emit("warning",new Error(`http error from xs param: ${t}`)),i(null);if(200!==r.statusCode)return e.emit("warning",new Error(`non-200 status code ${r.statusCode} from xs param: ${t}`)),i(null);let a;try{a=E(s)}catch(n){}return a?a.infoHash!==e.infoHash?(e.emit("warning",new Error(`got torrent file with incorrect info hash from xs param: ${t}`)),i(null)):(e._onMetadata(a),void i(null)):(e.emit("warning",new Error(`got invalid torrent file from xs param: ${t}`)),i(null))}e._xsRequests.push(r)}(t,i)}));w(t)}_onMetadata(e){if(this.metadata||this.destroyed)return;let t;if(this._debug("got metadata"),this._xsRequests.forEach((e=>{e.abort()})),this._xsRequests=[],e&&e.infoHash)t=e;else try{t=E(e)}catch(e){return this._destroy(e)}this._processParsedTorrent(t),this.metadata=this.torrentFile,this.client.enableWebSeeds&&this.urlList.forEach((e=>{this.addWebSeed(e)})),this._rarityMap=new P(this),this.files=this.files.map((e=>new L(this,e)));let i=this._preloadedStore;if(i||(i=new this._store(this.pieceLength,{...this.storeOpts,torrent:this,path:this.path,files:this.files,length:this.length,name:this.name+" - "+this.infoHash.slice(0,8),addUID:this.addUID})),this._storeCacheSlots>0&&!(i instanceof x)&&(i=new p(i,{max:this._storeCacheSlots})),this.store=new g(i),this.so?this.files.forEach(((e,t)=>{this.so.includes(t)?this.files[t].select():this.files[t].deselect()})):0!==this.pieces.length&&this.select(0,this.pieces.length-1,!1),this._hashes=this.pieces,this.pieces=this.pieces.map(((e,t)=>{const i=t===this.pieces.length-1?this.lastPieceLength:this.pieceLength;return new S(i)})),this._reservations=this.pieces.map((()=>[])),this.bitfield=new u(this.pieces.length),this.emit("metadata"),!this.destroyed)if(this.skipVerify)this._markAllVerified(),this._onStore();else{const e=e=>{if(e)return this._destroy(e);this._debug("done verifying"),this._onStore()};this._debug("verifying existing torrent data"),this._fileModtimes&&this._store===b?this.getFileModtimes(((t,i)=>{if(t)return this._destroy(t);this.files.map(((e,t)=>i[t]===this._fileModtimes[t])).every((e=>e))?(this._markAllVerified(),this._onStore()):this._verifyPieces(e)})):this._verifyPieces(e)}}getFileModtimes(e){const t=[];k(this.files.map(((e,i)=>n=>{const r=this.addUID?c.join(this.name+" - "+this.infoHash.slice(0,8)):c.join(this.path,e.path);s.stat(r,((e,r)=>{if(e&&"ENOENT"!==e.code)return n(e);t[i]=r&&r.mtime.getTime(),n(null)}))})),F,(i=>{this._debug("done getting file modtimes"),e(i,t)}))}_verifyPieces(e){k(this.pieces.map(((e,t)=>e=>{if(this.destroyed)return e(new Error("torrent is destroyed"));const i={};t===this.pieces.length-1&&(i.length=this.lastPieceLength),this.store.get(t,i,((i,n)=>this.destroyed?e(new Error("torrent is destroyed")):i?A((()=>e(null))):void I(n,(i=>{if(this.destroyed)return e(new Error("torrent is destroyed"));i===this._hashes[t]?(this._debug("piece verified %s",t),this._markVerified(t)):this._debug("piece invalid %s",t),e(null)}))))})),F,e)}rescanFiles(e){if(this.destroyed)throw new Error("torrent is destroyed");e||(e=G),this._verifyPieces((t=>{if(t)return this._destroy(t),e(t);this._checkDone(),e(null)}))}_markAllVerified(){for(let e=0;ee))return!0;return!1}_onStore(){this.destroyed||(this._debug("on store"),this._startDiscovery(),this.ready=!0,this.emit("ready"),this._checkDone(),this._updateSelections(),this.wires.forEach((e=>{e.ut_metadata&&e.ut_metadata.setMetadata(this.metadata),this._onWireWithMetadata(e)})))}destroy(e,t){if("function"==typeof e)return this.destroy(null,e);this._destroy(null,e,t)}_destroy(e,t,i){if("function"==typeof t)return this._destroy(e,null,t);if(this.destroyed)return;this.destroyed=!0,this._debug("destroy"),this.client._remove(this),clearInterval(this._rechokeIntervalId),this._xsRequests.forEach((e=>{e.abort()})),this._rarityMap&&this._rarityMap.destroy();for(const e in this._peers)this.removePeer(e);this.files.forEach((e=>{e instanceof L&&e._destroy()}));const n=this._servers.map((e=>t=>{e.destroy(t)}));if(this.discovery&&n.push((e=>{this.discovery.destroy(e)})),this.store){let e=this._destroyStoreOnDestroy;t&&void 0!==t.destroyStore&&(e=t.destroyStore),n.push((t=>{e?this.store.destroy(t):this.store.close(t)}))}w(n,i),e&&(0===this.listenerCount("error")?this.client.emit("error",e):this.emit("error",e)),this.emit("close"),this.client=null,this.files=[],this.discovery=null,this.store=null,this._rarityMap=null,this._peers=null,this._servers=null,this._xsRequests=null}addPeer(e){if(this.destroyed)throw new Error("torrent is destroyed");if(!this.infoHash)throw new Error("addPeer() must not be called before the `infoHash` event");let t;if(this.client.blocked){if("string"==typeof e){let i;try{i=l(e)}catch(t){return this._debug("ignoring peer: invalid %s",e),this.emit("invalidPeer",e),!1}t=i[0]}else"string"==typeof e.remoteAddress&&(t=e.remoteAddress);if(t&&this.client.blocked.contains(t))return this._debug("ignoring peer: blocked %s",e),"string"!=typeof e&&e.destroy(),this.emit("blockedPeer",e),!1}const i=this.client.utp&&this._isIPv4(t)?"utp":"tcp",n=!!this._addPeer(e,i);return n?this.emit("peer",e):this.emit("invalidPeer",e),n}_addPeer(e,t){if(this.destroyed)return"string"!=typeof e&&e.destroy(),null;if("string"==typeof e&&!this._validAddr(e))return this._debug("ignoring peer: invalid %s",e),null;const i=e&&e.id||e;if(this._peers[i])return this._debug("ignoring peer: duplicate (%s)",i),"string"!=typeof e&&e.destroy(),null;if(this.paused)return this._debug("ignoring peer: torrent is paused"),"string"!=typeof e&&e.destroy(),null;let n;return this._debug("add peer %s",i),n="string"==typeof e?"utp"===t?O.createUTPOutgoingPeer(e,this,this.client.throttleGroups):O.createTCPOutgoingPeer(e,this,this.client.throttleGroups):O.createWebRTCPeer(e,this,this.client.throttleGroups),this._registerPeer(n),"string"==typeof e&&(this._queue.push(n),this._drain()),n}addWebSeed(e){if(this.destroyed)throw new Error("torrent is destroyed");let t,i;if("string"==typeof e){if(t=e,!/^https?:\/\/.+/.test(t))return this.emit("warning",new Error(`ignoring invalid web seed: ${t}`)),void this.emit("invalidPeer",t);if(this._peers[t])return this.emit("warning",new Error(`ignoring duplicate web seed: ${t}`)),void this.emit("invalidPeer",t);i=new N(t,this)}else{if(!e||"string"!=typeof e.connId)return void this.emit("warning",new Error("addWebSeed must be passed a string or connection object with id property"));if(i=e,t=i.connId,this._peers[t])return this.emit("warning",new Error(`ignoring duplicate web seed: ${t}`)),void this.emit("invalidPeer",t)}this._debug("add web seed %s",t);const n=O.createWebSeedPeer(i,t,this,this.client.throttleGroups);this._registerPeer(n),this.emit("peer",t)}_addIncomingPeer(e){return this.destroyed?e.destroy(new Error("torrent is destroyed")):this.paused?e.destroy(new Error("torrent is paused")):(this._debug("add incoming peer %s",e.id),void this._registerPeer(e))}_registerPeer(e){e.on("download",(e=>{this.destroyed||(this.received+=e,this._downloadSpeed(e),this.client._downloadSpeed(e),this.emit("download",e),this.destroyed||this.client.emit("download",e))})),e.on("upload",(e=>{this.destroyed||(this.uploaded+=e,this._uploadSpeed(e),this.client._uploadSpeed(e),this.emit("upload",e),this.destroyed||this.client.emit("upload",e))})),this._peers[e.id]=e,this._peersLength+=1}removePeer(e){const t=e?.id||e;e&&!e.id&&(e=this._peers?.[t]),e&&(e.destroy(),this.destroyed||(this._debug("removePeer %s",t),delete this._peers[t],this._peersLength-=1,this._drain()))}select(e,t,i,n){if(this.destroyed)throw new Error("torrent is destroyed");if(e<0||tt.priority-e.priority)),this._updateSelections()}deselect(e,t,i){if(this.destroyed)throw new Error("torrent is destroyed");i=Number(i)||0,this._debug("deselect %s-%s (priority %s)",e,t,i);for(let n=0;n{if(!this.destroyed&&!this.client.dht.destroyed){if(!e.remoteAddress)return this._debug("ignoring PORT from peer with no address");if(0===i||i>65536)return this._debug("ignoring invalid PORT from peer");this._debug("port: %s (from %s)",i,t),this.client.dht.addNode({host:e.remoteAddress,port:i})}})),e.on("timeout",(()=>{this._debug("wire timeout (%s)",t),e.destroy()})),"webSeed"!==e.type&&e.setTimeout(3e4,!0),e.setKeepAlive(!0),e.use(C(this.metadata)),e.ut_metadata.on("warning",(e=>{this._debug("ut_metadata warning: %s",e.message)})),this.metadata||(e.ut_metadata.on("metadata",(e=>{this._debug("got metadata via ut_metadata"),this._onMetadata(e)})),e.ut_metadata.fetch()),"function"!=typeof B||this.private||(e.use(B()),e.ut_pex.on("peer",(e=>{this.done||(this._debug("ut_pex: got peer: %s (from %s)",e,t),this.addPeer(e))})),e.ut_pex.on("dropped",(e=>{const i=this._peers[e];i&&!i.connected&&(this._debug("ut_pex: dropped peer: %s (from %s)",e,t),this.removePeer(e))})),e.once("close",(()=>{e.ut_pex.reset()}))),e.use(y()),this.emit("wire",e,t),this.ready&&A((()=>{this._onWireWithMetadata(e)}))}_onWireWithMetadata(e){let t=null;const i=()=>{this.destroyed||e.destroyed||(this._numQueued>2*(this._numConns-this.numPeers)&&e.amInterested?e.destroy():(t=setTimeout(i,z),t.unref&&t.unref()))};let n;const r=()=>{if(e.peerPieces.buffer.length===this.bitfield.buffer.length){for(n=0;n{r(),this._update(),this._updateWireInterest(e)})),e.on("have",(()=>{r(),this._update(),this._updateWireInterest(e)})),e.lt_donthave.on("donthave",(()=>{r(),this._update(),this._updateWireInterest(e)})),e.on("have-all",(()=>{e.isSeeder=!0,e.choke(),this._update(),this._updateWireInterest(e)})),e.on("have-none",(()=>{e.isSeeder=!1,this._update(),this._updateWireInterest(e)})),e.on("allowed-fast",(e=>{this._update()})),e.once("interested",(()=>{e.unchoke()})),e.once("close",(()=>{clearTimeout(t)})),e.on("choke",(()=>{clearTimeout(t),t=setTimeout(i,z),t.unref&&t.unref()})),e.on("unchoke",(()=>{clearTimeout(t),this._update()})),e.on("request",((t,i,n,r)=>{if(n>131072)return e.destroy();this.pieces[t]||this.store.get(t,{offset:i,length:n},r)})),e.hasFast&&this._hasAllPieces()?e.haveAll():e.hasFast&&this._hasNoPieces()?e.haveNone():e.bitfield(this.bitfield),this._updateWireInterest(e),e.peerExtensions.dht&&this.client.dht&&this.client.dht.listening&&e.port(this.client.dht.address().port),"webSeed"!==e.type&&(t=setTimeout(i,z),t.unref&&t.unref()),e.isSeeder=!1,r()}_updateSelections(){this.ready&&!this.destroyed&&(A((()=>{this._gcSelections()})),this._updateInterest(),this._update())}_gcSelections(){for(let e=0;ethis._updateWireInterest(e))),e!==this._amInterested&&(this._amInterested?this.emit("interested"):this.emit("uninterested"))}_updateWireInterest(e){let t=!1;for(let i=0;i{t._updateWire(e)}),{timeout:250}):t._updateWire(e)}_updateWire(e){if(e.destroyed)return!1;const t=this,i=$(e,.5);if(e.requests.length>=i)return;const n=$(e,1);if(e.peerChoking)e.hasFast&&e.peerAllowedFastSet.length>0&&!this._hasMorePieces(e.peerAllowedFastSet.length-1)&&function(){if(e.requests.length>=n)return!1;for(const i of e.peerAllowedFastSet){if(e.peerPieces.get(i)&&!t.bitfield.get(i))for(;t._request(e,i,!1)&&e.requests.length=n.from+n.offset;--s)if(e.peerPieces.get(s)&&t._request(e,s,!1))return}}();a(!1)||a(!0)}function r(t,i,n,r){return s=>s>=t&&s<=i&&!(s in n)&&e.peerPieces.get(s)&&(!r||r(s))}function s(e){let i=e;for(let n=e;n=n)return!0;const a=function(){const i=e.downloadSpeed()||1;if(i>H)return()=>!0;const n=Math.max(1,e.requests.length)*S.BLOCK_LENGTH/i;let r=10,s=0;return e=>{if(!r||t.bitfield.get(e))return!0;let a=t.pieces[e].missing;for(;s0))return r--,!1}return!0}}();for(let o=0;o({wire:e,random:Math.random()}))).sort(((e,t)=>{const i=e.wire,n=t.wire;return i.downloadSpeed()!==n.downloadSpeed()?i.downloadSpeed()-n.downloadSpeed():i.uploadSpeed()!==n.uploadSpeed()?i.uploadSpeed()-n.uploadSpeed():i.amChoking!==n.amChoking?i.amChoking?-1:1:e.random-t.random})).map((e=>e.wire));this._rechokeOptimisticTime<=0?this._rechokeOptimisticWire=null:this._rechokeOptimisticTime-=1;let t=0;for(;e.length>0&&t0){const t=e.filter((e=>e.peerInterested));if(t.length>0){const e=t[(i=t.length,Math.random()*i|0)];e.unchoke(),this._rechokeOptimisticWire=e,this._rechokeOptimisticTime=2}}var i;e.filter((e=>e!==this._rechokeOptimisticWire)).forEach((e=>e.choke()))}_hotswap(e,t){const i=e.downloadSpeed();if(i=H||(2*o>i||o>a||(r=t,a=o))}if(!r)return!1;for(s=0;s=a)return!1;const o=n.pieces[t];let c=s?o.reserveRemaining():o.reserve();if(-1===c&&i&&n._hotswap(e,t)&&(c=s?o.reserveRemaining():o.reserve()),-1===c)return!1;let l=n._reservations[t];l||(l=n._reservations[t]=[]);let u=l.indexOf(null);-1===u&&(u=l.length),l[u]=e;const p=o.chunkOffset(c),d=s?o.chunkLengthRemaining(c):o.chunkLength(c);function f(){A((()=>{n._update()}))}return e.request(t,p,d,(function i(r,a){if(n.destroyed)return;if(!n.ready)return n.once("ready",(()=>{i(r,a)}));if(l[u]===e&&(l[u]=null),o!==n.pieces[t])return f();if(r)return n._debug("error getting piece %s (offset: %s length: %s) from %s: %s",t,p,d,`${e.remoteAddress}:${e.remotePort}`,r.message),s?o.cancelRemaining(c):o.cancel(c),void f();if(n._debug("got piece %s (offset: %s length: %s) from %s",t,p,d,`${e.remoteAddress}:${e.remotePort}`),!o.set(c,a,e))return f();const h=o.flush();I(h,(e=>{n.destroyed||(e===n._hashes[t]?(n._debug("piece verified %s",t),n.store.put(t,h,(e=>{e?n._destroy(e):(n.pieces[t]=null,n._markVerified(t),n.wires.forEach((e=>{e.have(t)})),n._checkDone()&&!n.destroyed&&n.discovery.complete(),f())}))):(n.pieces[t]=new S(o.length),n.emit("warning",new Error(`Piece ${t} failed verification`)),f()))}))})),!0}_checkDone(){if(this.destroyed)return;this.files.forEach((e=>{if(!e.done){for(let t=e._startPiece;t<=e._endPiece;++t)if(!this.bitfield.get(t))return;e.done=!0,e.emit("done"),this._debug(`file done: ${e.name}`)}}));let e=!0;for(const t of this._selections){for(let i=t.from;i<=t.to;i++)if(!this.bitfield.get(i)){e=!1;break}if(!e)break}return!this.done&&e?(this.done=!0,this._debug(`torrent done: ${this.infoHash}`),this.emit("done")):this.done=!1,this._gcSelections(),e}load(e,t){if(this.destroyed)throw new Error("torrent is destroyed");if(!this.ready)return this.once("ready",(()=>{this.load(e,t)}));Array.isArray(e)||(e=[e]),t||(t=G);const i=R.from(_(e)),n=new d(this.store,this.pieceLength);M(i,n,(e=>{if(e)return t(e);this._markAllVerified(),this._checkDone(),t(null)}))}createServer(e){if("function"!=typeof U)throw new Error("node.js-only method");if(this.destroyed)throw new Error("torrent is destroyed");const t=new U(this,e);return this._servers.push(t),t}pause(){this.destroyed||(this._debug("pause"),this.paused=!0)}resume(){this.destroyed||(this._debug("resume"),this.paused=!1,this._drain())}_debug(){const e=[].slice.call(arguments);e[0]=`[${this.client?this.client._debugId:"No Client"}] [${this._debugId}] ${e[0]}`,D(...e)}_drain(){if(this._debug("_drain numConns %s maxConns %s",this._numConns,this.client.maxConns),"function"!=typeof a.connect||this.destroyed||this.paused||this._numConns>=this.client.maxConns)return;this._debug("drain (%s queued, %s/%s peers)",this._numQueued,this.numPeers,this.client.maxConns);const e=this._queue.shift();if(!e)return;this._debug("%s connect attempt to %s",e.type,e.addr);const t=l(e.addr),i={host:t[0],port:t[1]};this.client.utp&&"utpOutgoing"===e.type?e.conn=q.connect(i.port,i.host):e.conn=a.connect(i);const n=e.conn;n.once("connect",(()=>{this.destroyed||e.onConnect()})),n.once("error",(t=>{e.destroy(t)})),e.startConnectTimeout(),n.on("close",(()=>{if(this.destroyed)return;if(e.retries>=W.length){if(this.client.utp){const t=this._addPeer(e.addr,"tcp");t&&(t.retries=0)}else this._debug("conn %s closed: will not re-add (max %s attempts)",e.addr,W.length);return}const t=W[e.retries];this._debug("conn %s closed: will re-add to queue in %sms (attempt %s)",e.addr,t,e.retries+1);const i=setTimeout((()=>{if(this.destroyed)return;const t=l(e.addr)[0],i=this.client.utp&&this._isIPv4(t)?"utp":"tcp",n=this._addPeer(e.addr,i);n&&(n.retries=e.retries+1)}),t);i.unref&&i.unref()}))}_validAddr(e){let t;try{t=l(e)}catch(e){return!1}const i=t[0],n=t[1];return n>0&&n<65535&&!("127.0.0.1"===i&&n===this.client.torrentPort)}_isIPv4(e){return/^((?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])[.]){3}(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])$/.test(e)}}}).call(this)}).call(this,e("_process"),"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"../package.json":450,"./file.js":445,"./peer.js":446,"./rarity-map.js":447,"./server.js":67,"./utp.js":67,"./webconn.js":449,_process:296,"addr-to-ip-port":2,bitfield:26,"cache-chunk-store":117,"chunk-store-stream/write":133,cpus:137,debug:146,events:178,fs:67,"fs-chunk-store":246,"immediate-chunk-store":216,"join-async-iterator":220,lt_donthave:227,"memory-chunk-store":246,net:67,os:67,"parse-torrent":287,path:288,pump:304,"queue-microtask":309,"random-iterate":311,"run-parallel":336,"run-parallel-limit":335,"simple-get":349,"simple-sha1":366,streamx:426,throughput:430,"torrent-discovery":433,"torrent-piece":434,ut_metadata:439,ut_pex:67}],449:[function(e,t,i){(function(i){(function(){const{default:n}=e("bitfield"),r=e("debug"),s=e("simple-get"),a=e("lt_donthave"),o=e("simple-sha1"),c=e("bittorrent-protocol"),l=r("webtorrent:webconn"),u=e("../package.json").version;t.exports=class extends c{constructor(e,t){super(),this.url=e,this.connId=e,this.webPeerId=o.sync(e),this._torrent=t,this._init()}_init(){this.setKeepAlive(!0),this.use(a()),this.once("handshake",((e,t)=>{if(this.destroyed)return;this.handshake(e,this.webPeerId);const i=this._torrent.pieces.length,r=new n(i);for(let e=0;e<=i;e++)r.set(e,!0);this.bitfield(r)})),this.once("interested",(()=>{l("interested"),this.unchoke()})),this.on("uninterested",(()=>{l("uninterested")})),this.on("choke",(()=>{l("choke")})),this.on("unchoke",(()=>{l("unchoke")})),this.on("bitfield",(()=>{l("bitfield")})),this.lt_donthave.on("donthave",(()=>{l("donthave")})),this.on("request",((e,t,i,n)=>{l("request pieceIndex=%d offset=%d length=%d",e,t,i),this.httpRequest(e,t,i,((t,i)=>{if(t){this.lt_donthave.donthave(e);const t=setTimeout((()=>{this.destroyed||this.have(e)}),1e4);t.unref&&t.unref()}n(t,i)}))}))}httpRequest(e,t,n,r){const a=e*this._torrent.pieceLength+t,o=a+n-1,c=this._torrent.files;let p;if(c.length<=1)p=[{url:this.url,start:a,end:o}];else{const e=c.filter((e=>e.offset<=o&&e.offset+e.length>a));if(e.length<1)return r(new Error("Could not find file corresponding to web seed range request"));p=e.map((e=>{const t=e.offset+e.length-1;return{url:this.url+("/"===this.url[this.url.length-1]?"":"/")+e.path.replace(this._torrent.path,""),fileOffsetInRange:Math.max(e.offset-a,0),start:Math.max(a-e.offset,0),end:Math.min(t,o-e.offset)}}))}let d,f=0,h=!1;p.length>1&&(d=i.alloc(n)),p.forEach((i=>{const a=i.url,o=i.start,c=i.end;l("Requesting url=%s pieceIndex=%d offset=%d length=%d start=%d end=%d",a,e,t,n,o,c);const m={url:a,method:"GET",headers:{"user-agent":`WebTorrent/${u} (https://webtorrent.io)`,range:`bytes=${o}-${c}`},timeout:6e4};function b(e,t){if(e.statusCode<200||e.statusCode>=300){if(h)return;return h=!0,r(new Error(`Unexpected HTTP status code ${e.statusCode}`))}l("Got data of length %d",t.length),1===p.length?r(null,t):(t.copy(d,i.fileOffsetInRange),++f===p.length&&r(null,d))}s.concat(m,((e,t,i)=>{if(!h)return e?"undefined"==typeof window||a.startsWith(`${window.location.origin}/`)?(h=!0,r(e)):s.head(a,((t,i)=>{if(!h){if(t)return h=!0,r(t);if(i.statusCode<200||i.statusCode>=300)return h=!0,r(new Error(`Unexpected HTTP status code ${i.statusCode}`));if(i.url===a)return h=!0,r(e);m.url=i.url,s.concat(m,((e,t,i)=>{if(!h)return e?(h=!0,r(e)):void b(t,i)}))}})):void b(t,i)}))}))}destroy(){super.destroy(),this._torrent=null}}}).call(this)}).call(this,e("buffer").Buffer)},{"../package.json":450,bitfield:26,"bittorrent-protocol":27,buffer:110,debug:146,lt_donthave:227,"simple-get":349,"simple-sha1":366}],450:[function(e,t,i){t.exports={version:"1.9.7"}},{}],451:[function(e,t,i){t.exports=function e(t,i){if(t&&i)return e(t)(i);if("function"!=typeof t)throw new TypeError("need wrapper function");return Object.keys(t).forEach((function(e){n[e]=t[e]})),n;function n(){for(var e=new Array(arguments.length),i=0;i1080?(N.setProps({placement:"right"}),D.setProps({placement:"right"}),z.setProps({placement:"right"}),H.setProps({placement:"right"})):(N.setProps({placement:"top"}),D.setProps({placement:"top"}),z.setProps({placement:"top"}),H.setProps({placement:"top"}))}function K(e){J();try{console.info("Attempting parse"),l=n(e),G(),l.xs&&(console.info("Magnet includes xs, attempting remote parse"),$(l.xs))}catch(t){console.warn(t),"magnet"==c?(console.info("Attempting remote parse"),$(e)):(W.error("Problem parsing input. Is this a .torrent file?"),console.error("Problem parsing input"))}}function $(e){n.remote(e,(function(e,t){if(e)return W.error("Problem remotely fetching that file or parsing result"),console.warn(e),void J();c="remote-torrent-file",m.innerHTML='',b.setContent("Currently loaded information sourced from remotely fetched Torrent file"),l=t,G()}))}function G(){if(console.log(l),w.value=l.infoHash,v.value=l.name?l.name:"",l.created?(y.value=l.created.toISOString().slice(0,19),y.type="datetime-local"):y.type="text",x.value=l.createdBy?" by "+l.createdBy:"",_.value=l.comment?l.comment:"",T.value=l.pieces?l.pieces.length.toLocaleString()+" "+r.format(l.pieceLength,{decimalPlaces:1,unitSeparator:" "})+" pieces (last piece "+r.format(l.lastPieceLength,{decimalPlaces:1,unitSeparator:" "})+")":"",M.innerHTML="",l.announce&&l.announce.length)for(let e=0;e',n.addEventListener("click",te),t.appendChild(n),M.appendChild(t)}if(A.innerHTML="",l.urlList&&l.urlList.length)for(let e=0;e',n.addEventListener("click",te),t.appendChild(n),A.appendChild(t)}if(C.innerHTML="",l.files&&l.files.length){if(B.style.display="none",l.files.length<100)for(let e of l.files){let t=Y(s.lookup(e.name));C.appendChild(X(t,e.name,e.length))}else{for(let e=0;e<100;e++){let t=Y(s.lookup(l.files[e].name));C.appendChild(X(t,l.files[e].name,l.files[e].length))}C.appendChild(X("","...and another "+(l.files.length-100)+" more files",""))}C.appendChild(X("folder-tree","",l.length)),R.href=n.toMagnetURI(l),H.setContent("Download Torrent file"),q.addEventListener("click",se),q.disabled=!1}else F.torrents.length>0?(B.style.display="none",C.innerHTML=''):(B.style.display="block",C.innerHTML=''),H.setContent("Files metadata is required to generate a Torrent file. Try fetching files list from WebTorrent."),q.removeEventListener("click",se),q.disabled=!0;O.setAttribute("data-clipboard-text",window.location.origin+"#"+n.toMagnetURI(l)),P.setAttribute("data-clipboard-text",n.toMagnetURI(l)),u.style.display="none",h.style.display="flex",window.location.hash=n.toMagnetURI(l),l.name?document.title="Torrent Parts | "+l.name:document.title="Torrent Parts | Inspect and edit what's in your Torrent file or Magnet link",b.enable()}function X(e,t,i){let n=document.createElement("tr"),s=document.createElement("td");e&&(s.innerHTML=''),n.appendChild(s);let a=document.createElement("td");a.innerHTML=t,n.appendChild(a);let o=document.createElement("td");return o.innerHTML=r.format(i,{decimalPlaces:1,unitSeparator:" "}),n.appendChild(o),n}function Y(e){if(!e)return"file";switch(!0){case e.includes("msword"):case e.includes("wordprocessingml"):case e.includes("opendocument.text"):case e.includes("abiword"):return"file-word";case e.includes("ms-excel"):case e.includes("spreadsheet"):case e.includes("powerpoint"):case e.includes("presentation"):return"file-powerpoint";case e.includes("7z-"):case e.includes("iso9660"):case e.includes("zip"):case e.includes("octet-stream"):return"file-archive";case e.includes("csv"):return"file-csv";case e.includes("pdf"):return"file-pdf";case e.includes("font"):return"file-contract";case e.includes("text"):case e.includes("subrip"):case e.includes("vtt"):return"file-alt";case e.includes("audio"):return"file-audio";case e.includes("image"):return"file-image";case e.includes("video"):return"file-video";default:return"file"}}function Z(e){this.dataset.group?l[this.dataset.group][this.dataset.index]=this.value?this.value:"":l[this.id]=this.value?this.value:"",window.location.hash=n.toMagnetURI(l),ne()}function J(){document.getElementById("magnet").value="",document.getElementById("torrent").value="",u.style.display="flex",h.style.display="none",v.value="",y.value="",x.value="",_.value="",w.value="",M.innerHTML="",A.innerHTML="",F.torrents.forEach((e=>e.destroy())),B.style.display="block",C.innerHTML="",window.location.hash="",O.setAttribute("data-clipboard-text",""),P.setAttribute("data-clipboard-text",""),document.title="Torrent Parts | Inspect and edit what's in your Torrent file or Magnet link",b.disable()}async function Q(){k.className="disabled",k.innerHTML="Adding...";try{let e=await fetch("https://newtrackon.com/api/stable"),t=await e.text();l.announce=l.announce.concat(t.split("\n\n")),l.announce.push("http://bt1.archive.org:6969/announce"),l.announce.push("http://bt2.archive.org:6969/announce"),l.announce=l.announce.filter(((e,t)=>e&&l.announce.indexOf(e)===t)),W.success("Added known working trackers from newTrackon"),ne()}catch(e){W.error("Problem fetching trackers from newTrackon"),console.warn(e)}k.className="",k.innerHTML="Add Known Working Trackers",G()}function ee(){l[this.dataset.type].unshift(""),G()}function te(){l[this.parentElement.className].splice(this.parentElement.dataset.index,1),G()}function ie(e){l[e]=[],ne(),G()}function ne(){l.created=new Date,l.createdBy="Torrent Parts ",l.created?(y.value=l.created.toISOString().slice(0,19),y.type="datetime-local"):y.type="text",x.value=l.createdBy?" by "+l.createdBy:""}function re(){console.info("Attempting fetching files from Webtorrent..."),B.style.display="none",l.announce.push("wss://tracker.webtorrent.io"),l.announce.push("wss://tracker.openwebtorrent.com"),l.announce.push("wss://tracker.btorrent.xyz"),l.announce.push("wss://tracker.fastcast.nz"),l.announce=l.announce.filter(((e,t)=>e&&l.announce.indexOf(e)===t)),F.add(n.toMagnetURI(l),(e=>{l.info=Object.assign({},e.info),l.files=e.files,l.infoBuffer=e.infoBuffer,l.length=e.length,l.lastPieceLength=e.lastPieceLength,ne(),G(),W.success("Fetched file details from Webtorrent peers"),e.destroy()})),G()}function se(){let e=n.toTorrentFile(l);if(null!==e&&navigator.msSaveBlob)return navigator.msSaveBlob(new Blob([e],{type:"application/x-bittorrent"}),l.name+".torrent");let t=document.createElement("a");t.style.display="none";let i=window.URL.createObjectURL(new Blob([e],{type:"application/x-bittorrent"}));t.setAttribute("href",i),t.setAttribute("download",l.name+".torrent"),document.body.appendChild(t),t.click(),window.URL.revokeObjectURL(i),t.remove()}window.addEventListener("resize",V),V(),document.addEventListener("DOMContentLoaded",(function(){document.getElementById("magnet").addEventListener("keyup",(function(e){e.preventDefault(),"Enter"===e.key&&(c="magnet",m.innerHTML='',b.setContent("Currently loaded information sourced from Magnet URL"),K(magnet.value))})),document.getElementById("torrent").addEventListener("change",(function(e){e.preventDefault(),e.target.files[0].arrayBuffer().then((function(e){c="torrent-file",m.innerHTML='',b.setContent("Currently loaded information sourced from Torrent file"),K(t.from(e))}))})),document.addEventListener("dragover",(function(e){e.preventDefault()})),document.addEventListener("drop",(function(e){e.preventDefault(),e.dataTransfer.items[0].getAsFile().arrayBuffer().then((function(e){c="torrent-file",m.innerHTML='',b.setContent("Currently loaded information sourced from Torrent file"),K(t.from(e))}))})),p.addEventListener("click",(function(e){e.preventDefault(),W.success("Parsing Ubuntu 22.04 Magnet URL"),c="magnet",m.innerHTML='',b.setContent("Currently loaded information sourced from Magnet URL"),K("magnet:?xt=urn:btih:2c6b6858d61da9543d4231a71db4b1c9264b0685&dn=ubuntu-22.04-desktop-amd64.iso&tr=https%3A%2F%2Ftorrent.ubuntu.com%2Fannounce&tr=https%3A%2F%2Fipv6.torrent.ubuntu.com%2Fannounce")})),d.addEventListener("click",(async function(e){e.preventDefault(),W.success("Fetching and Parsing “The WIRED CD” Torrent File..."),c="remote-torrent-file",m.innerHTML='',b.setContent("Currently loaded information sourced from remotely fetched Torrent file"),$("https://webtorrent.io/torrents/wired-cd.torrent")})),f.addEventListener("click",(async function(e){e.preventDefault(),W.success("Parsing Jack Johnson Archive.org Torrent File");let i=await fetch("/ext/jj2008-06-14.mk4_archive.torrent"),n=await i.arrayBuffer();c="torrent-file",m.innerHTML='',b.setContent("Currently loaded information sourced from Torrent file"),K(t.from(n))}));let e=new i("#copyURL");e.on("success",(function(e){W.success("Copied site URL to clipboard!"),console.info(e)})),e.on("failure",(function(e){W.error("Problem copying to clipboard"),console.warn(e)}));let n=new i("#copyMagnet");n.on("success",(function(e){W.success("Copied Magnet URL to clipboard!")})),n.on("failure",(function(e){W.error("Problem copying to clipboard"),console.warn(e)})),v.addEventListener("input",Z),v.addEventListener("change",Z),v.addEventListener("reset",Z),v.addEventListener("paste",Z),g.addEventListener("click",J),_.addEventListener("input",Z),_.addEventListener("change",Z),_.addEventListener("reset",Z),_.addEventListener("paste",Z),k.addEventListener("click",Q),E.addEventListener("click",ee),S.addEventListener("click",(()=>ie("announce"))),j.addEventListener("click",ee),I.addEventListener("click",(()=>ie("urlList"))),B.addEventListener("click",re),o("[data-tippy-content]",{theme:"torrent-parts",animation:"shift-away-subtle"}),b.disable(),window.location.hash&&(c="shared-url",m.innerHTML='',b.setContent("Currently loaded information sourced from shared torrent.parts link"),K(window.location.hash.split("#")[1]))}))}).call(this)}).call(this,e("buffer").Buffer)},{buffer:110,bytes:116,clipboard:135,"mime-types":251,"parse-torrent":287,"tippy.js":431,webtorrent:443}]},{},[453]); \ No newline at end of file diff --git a/ext/TorrentPartsFASubset.yaml b/ext/TorrentPartsFASubset.yaml index f33f2e3..f4c8668 100644 --- a/ext/TorrentPartsFASubset.yaml +++ b/ext/TorrentPartsFASubset.yaml @@ -1,5 +1,5 @@ projectName: 'C:\Users\Leo\Desktop\TorrentPartsFASubset' -version: 6.1.2 +version: 6.2.1 icons: - magnet: - light @@ -13,11 +13,12 @@ icons: - solid - link: - light - - duotone - - share-nodes: - solid + - duotone - file-arrow-down: - solid + - arrow-up-right-from-square: + - solid - file: - regular - file-word: diff --git a/ext/fa.min.js b/ext/fa.min.js index 3a7fd46..21aca81 100644 --- a/ext/fa.min.js +++ b/ext/fa.min.js @@ -1,6 +1,6 @@ /*! - * Font Awesome Pro 6.1.2 by @fontawesome - https://fontawesome.com + * Font Awesome Pro 6.2.1 by @fontawesome - https://fontawesome.com * License - https://fontawesome.com/license (Commercial License) - * Copyright 2022 Fonticons, Inc. + * Copyright 2023 Fonticons, Inc. */ -!function(){"use strict";var t={},e={};try{"undefined"!=typeof window&&(t=window),"undefined"!=typeof document&&(e=document)}catch(t){}var a=(t.navigator||{}).userAgent,a=void 0===a?"":a;t.document,e.documentElement&&e.head&&"function"==typeof e.addEventListener&&e.createElement,~a.indexOf("MSIE")||a.indexOf("Trident/");function i(e,t){var a,n=Object.keys(e);return Object.getOwnPropertySymbols&&(a=Object.getOwnPropertySymbols(e),t&&(a=a.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,a)),n}function r(n){for(var t=1;tt.length)&&(e=t.length);for(var a=0,n=new Array(e);at.length)&&(e=t.length);for(var a=0,n=new Array(e);at.length)&&(e=t.length);for(var a=0,n=new Array(e);at.length)&&(e=t.length);for(var a=0,n=new Array(e);at.length)&&(e=t.length);for(var a=0,n=new Array(e);a>>0;a--;)e[a]=t[a];return e}function dt(t){return t.classList?x(t.classList):(t.getAttribute("class")||"").split(" ").filter(function(t){return t})}function pt(t){return"".concat(t).replace(/&/g,"&").replace(/"/g,""").replace(/'/g,"'").replace(//g,">")}function M(a){return Object.keys(a||{}).reduce(function(t,e){return t+"".concat(e,": ").concat(a[e].trim(),";")},"")}function bt(t){return t.size!==k.size||t.x!==k.x||t.y!==k.y||t.rotate!==k.rotate||t.flipX||t.flipY}function vt(){var t,e,a=B,n=C.familyPrefix,r=C.replacementClass,i=':host,:root{--fa-font-solid:normal 900 1em/1 "Font Awesome 6 Solid";--fa-font-regular:normal 400 1em/1 "Font Awesome 6 Regular";--fa-font-light:normal 300 1em/1 "Font Awesome 6 Light";--fa-font-thin:normal 100 1em/1 "Font Awesome 6 Thin";--fa-font-duotone:normal 900 1em/1 "Font Awesome 6 Duotone";--fa-font-brands:normal 400 1em/1 "Font Awesome 6 Brands"}svg:not(:host).svg-inline--fa,svg:not(:root).svg-inline--fa{overflow:visible;box-sizing:content-box}.svg-inline--fa{display:var(--fa-display,inline-block);height:1em;overflow:visible;vertical-align:-.125em}.svg-inline--fa.fa-2xs{vertical-align:.1em}.svg-inline--fa.fa-xs{vertical-align:0}.svg-inline--fa.fa-sm{vertical-align:-.0714285705em}.svg-inline--fa.fa-lg{vertical-align:-.2em}.svg-inline--fa.fa-xl{vertical-align:-.25em}.svg-inline--fa.fa-2xl{vertical-align:-.3125em}.svg-inline--fa.fa-pull-left{margin-right:var(--fa-pull-margin,.3em);width:auto}.svg-inline--fa.fa-pull-right{margin-left:var(--fa-pull-margin,.3em);width:auto}.svg-inline--fa.fa-li{width:var(--fa-li-width,2em);top:.25em}.svg-inline--fa.fa-fw{width:var(--fa-fw-width,1.25em)}.fa-layers svg.svg-inline--fa{bottom:0;left:0;margin:auto;position:absolute;right:0;top:0}.fa-layers-counter,.fa-layers-text{display:inline-block;position:absolute;text-align:center}.fa-layers{display:inline-block;height:1em;position:relative;text-align:center;vertical-align:-.125em;width:1em}.fa-layers svg.svg-inline--fa{-webkit-transform-origin:center center;transform-origin:center center}.fa-layers-text{left:50%;top:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);-webkit-transform-origin:center center;transform-origin:center center}.fa-layers-counter{background-color:var(--fa-counter-background-color,#ff253a);border-radius:var(--fa-counter-border-radius,1em);box-sizing:border-box;color:var(--fa-inverse,#fff);line-height:var(--fa-counter-line-height,1);max-width:var(--fa-counter-max-width,5em);min-width:var(--fa-counter-min-width,1.5em);overflow:hidden;padding:var(--fa-counter-padding,.25em .5em);right:var(--fa-right,0);text-overflow:ellipsis;top:var(--fa-top,0);-webkit-transform:scale(var(--fa-counter-scale,.25));transform:scale(var(--fa-counter-scale,.25));-webkit-transform-origin:top right;transform-origin:top right}.fa-layers-bottom-right{bottom:var(--fa-bottom,0);right:var(--fa-right,0);top:auto;-webkit-transform:scale(var(--fa-layers-scale,.25));transform:scale(var(--fa-layers-scale,.25));-webkit-transform-origin:bottom right;transform-origin:bottom right}.fa-layers-bottom-left{bottom:var(--fa-bottom,0);left:var(--fa-left,0);right:auto;top:auto;-webkit-transform:scale(var(--fa-layers-scale,.25));transform:scale(var(--fa-layers-scale,.25));-webkit-transform-origin:bottom left;transform-origin:bottom left}.fa-layers-top-right{top:var(--fa-top,0);right:var(--fa-right,0);-webkit-transform:scale(var(--fa-layers-scale,.25));transform:scale(var(--fa-layers-scale,.25));-webkit-transform-origin:top right;transform-origin:top right}.fa-layers-top-left{left:var(--fa-left,0);right:auto;top:var(--fa-top,0);-webkit-transform:scale(var(--fa-layers-scale,.25));transform:scale(var(--fa-layers-scale,.25));-webkit-transform-origin:top left;transform-origin:top left}.fa-1x{font-size:1em}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-6x{font-size:6em}.fa-7x{font-size:7em}.fa-8x{font-size:8em}.fa-9x{font-size:9em}.fa-10x{font-size:10em}.fa-2xs{font-size:.625em;line-height:.1em;vertical-align:.225em}.fa-xs{font-size:.75em;line-height:.0833333337em;vertical-align:.125em}.fa-sm{font-size:.875em;line-height:.0714285718em;vertical-align:.0535714295em}.fa-lg{font-size:1.25em;line-height:.05em;vertical-align:-.075em}.fa-xl{font-size:1.5em;line-height:.0416666682em;vertical-align:-.125em}.fa-2xl{font-size:2em;line-height:.03125em;vertical-align:-.1875em}.fa-fw{text-align:center;width:1.25em}.fa-ul{list-style-type:none;margin-left:var(--fa-li-margin,2.5em);padding-left:0}.fa-ul>li{position:relative}.fa-li{left:calc(var(--fa-li-width,2em) * -1);position:absolute;text-align:center;width:var(--fa-li-width,2em);line-height:inherit}.fa-border{border-color:var(--fa-border-color,#eee);border-radius:var(--fa-border-radius,.1em);border-style:var(--fa-border-style,solid);border-width:var(--fa-border-width,.08em);padding:var(--fa-border-padding,.2em .25em .15em)}.fa-pull-left{float:left;margin-right:var(--fa-pull-margin,.3em)}.fa-pull-right{float:right;margin-left:var(--fa-pull-margin,.3em)}.fa-beat{-webkit-animation-name:fa-beat;animation-name:fa-beat;-webkit-animation-delay:var(--fa-animation-delay,0);animation-delay:var(--fa-animation-delay,0);-webkit-animation-direction:var(--fa-animation-direction,normal);animation-direction:var(--fa-animation-direction,normal);-webkit-animation-duration:var(--fa-animation-duration,1s);animation-duration:var(--fa-animation-duration,1s);-webkit-animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-iteration-count:var(--fa-animation-iteration-count,infinite);-webkit-animation-timing-function:var(--fa-animation-timing,ease-in-out);animation-timing-function:var(--fa-animation-timing,ease-in-out)}.fa-bounce{-webkit-animation-name:fa-bounce;animation-name:fa-bounce;-webkit-animation-delay:var(--fa-animation-delay,0);animation-delay:var(--fa-animation-delay,0);-webkit-animation-direction:var(--fa-animation-direction,normal);animation-direction:var(--fa-animation-direction,normal);-webkit-animation-duration:var(--fa-animation-duration,1s);animation-duration:var(--fa-animation-duration,1s);-webkit-animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-iteration-count:var(--fa-animation-iteration-count,infinite);-webkit-animation-timing-function:var(--fa-animation-timing,cubic-bezier(.28,.84,.42,1));animation-timing-function:var(--fa-animation-timing,cubic-bezier(.28,.84,.42,1))}.fa-fade{-webkit-animation-name:fa-fade;animation-name:fa-fade;-webkit-animation-delay:var(--fa-animation-delay,0);animation-delay:var(--fa-animation-delay,0);-webkit-animation-direction:var(--fa-animation-direction,normal);animation-direction:var(--fa-animation-direction,normal);-webkit-animation-duration:var(--fa-animation-duration,1s);animation-duration:var(--fa-animation-duration,1s);-webkit-animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-iteration-count:var(--fa-animation-iteration-count,infinite);-webkit-animation-timing-function:var(--fa-animation-timing,cubic-bezier(.4,0,.6,1));animation-timing-function:var(--fa-animation-timing,cubic-bezier(.4,0,.6,1))}.fa-beat-fade{-webkit-animation-name:fa-beat-fade;animation-name:fa-beat-fade;-webkit-animation-delay:var(--fa-animation-delay,0);animation-delay:var(--fa-animation-delay,0);-webkit-animation-direction:var(--fa-animation-direction,normal);animation-direction:var(--fa-animation-direction,normal);-webkit-animation-duration:var(--fa-animation-duration,1s);animation-duration:var(--fa-animation-duration,1s);-webkit-animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-iteration-count:var(--fa-animation-iteration-count,infinite);-webkit-animation-timing-function:var(--fa-animation-timing,cubic-bezier(.4,0,.6,1));animation-timing-function:var(--fa-animation-timing,cubic-bezier(.4,0,.6,1))}.fa-flip{-webkit-animation-name:fa-flip;animation-name:fa-flip;-webkit-animation-delay:var(--fa-animation-delay,0);animation-delay:var(--fa-animation-delay,0);-webkit-animation-direction:var(--fa-animation-direction,normal);animation-direction:var(--fa-animation-direction,normal);-webkit-animation-duration:var(--fa-animation-duration,1s);animation-duration:var(--fa-animation-duration,1s);-webkit-animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-iteration-count:var(--fa-animation-iteration-count,infinite);-webkit-animation-timing-function:var(--fa-animation-timing,ease-in-out);animation-timing-function:var(--fa-animation-timing,ease-in-out)}.fa-shake{-webkit-animation-name:fa-shake;animation-name:fa-shake;-webkit-animation-delay:var(--fa-animation-delay,0);animation-delay:var(--fa-animation-delay,0);-webkit-animation-direction:var(--fa-animation-direction,normal);animation-direction:var(--fa-animation-direction,normal);-webkit-animation-duration:var(--fa-animation-duration,1s);animation-duration:var(--fa-animation-duration,1s);-webkit-animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-iteration-count:var(--fa-animation-iteration-count,infinite);-webkit-animation-timing-function:var(--fa-animation-timing,linear);animation-timing-function:var(--fa-animation-timing,linear)}.fa-spin{-webkit-animation-name:fa-spin;animation-name:fa-spin;-webkit-animation-delay:var(--fa-animation-delay,0);animation-delay:var(--fa-animation-delay,0);-webkit-animation-direction:var(--fa-animation-direction,normal);animation-direction:var(--fa-animation-direction,normal);-webkit-animation-duration:var(--fa-animation-duration,2s);animation-duration:var(--fa-animation-duration,2s);-webkit-animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-iteration-count:var(--fa-animation-iteration-count,infinite);-webkit-animation-timing-function:var(--fa-animation-timing,linear);animation-timing-function:var(--fa-animation-timing,linear)}.fa-spin-reverse{--fa-animation-direction:reverse}.fa-pulse,.fa-spin-pulse{-webkit-animation-name:fa-spin;animation-name:fa-spin;-webkit-animation-direction:var(--fa-animation-direction,normal);animation-direction:var(--fa-animation-direction,normal);-webkit-animation-duration:var(--fa-animation-duration,1s);animation-duration:var(--fa-animation-duration,1s);-webkit-animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-iteration-count:var(--fa-animation-iteration-count,infinite);-webkit-animation-timing-function:var(--fa-animation-timing,steps(8));animation-timing-function:var(--fa-animation-timing,steps(8))}@media (prefers-reduced-motion:reduce){.fa-beat,.fa-beat-fade,.fa-bounce,.fa-fade,.fa-flip,.fa-pulse,.fa-shake,.fa-spin,.fa-spin-pulse{-webkit-animation-delay:-1ms;animation-delay:-1ms;-webkit-animation-duration:1ms;animation-duration:1ms;-webkit-animation-iteration-count:1;animation-iteration-count:1;transition-delay:0s;transition-duration:0s}}@-webkit-keyframes fa-beat{0%,90%{-webkit-transform:scale(1);transform:scale(1)}45%{-webkit-transform:scale(var(--fa-beat-scale,1.25));transform:scale(var(--fa-beat-scale,1.25))}}@keyframes fa-beat{0%,90%{-webkit-transform:scale(1);transform:scale(1)}45%{-webkit-transform:scale(var(--fa-beat-scale,1.25));transform:scale(var(--fa-beat-scale,1.25))}}@-webkit-keyframes fa-bounce{0%{-webkit-transform:scale(1,1) translateY(0);transform:scale(1,1) translateY(0)}10%{-webkit-transform:scale(var(--fa-bounce-start-scale-x,1.1),var(--fa-bounce-start-scale-y,.9)) translateY(0);transform:scale(var(--fa-bounce-start-scale-x,1.1),var(--fa-bounce-start-scale-y,.9)) translateY(0)}30%{-webkit-transform:scale(var(--fa-bounce-jump-scale-x,.9),var(--fa-bounce-jump-scale-y,1.1)) translateY(var(--fa-bounce-height,-.5em));transform:scale(var(--fa-bounce-jump-scale-x,.9),var(--fa-bounce-jump-scale-y,1.1)) translateY(var(--fa-bounce-height,-.5em))}50%{-webkit-transform:scale(var(--fa-bounce-land-scale-x,1.05),var(--fa-bounce-land-scale-y,.95)) translateY(0);transform:scale(var(--fa-bounce-land-scale-x,1.05),var(--fa-bounce-land-scale-y,.95)) translateY(0)}57%{-webkit-transform:scale(1,1) translateY(var(--fa-bounce-rebound,-.125em));transform:scale(1,1) translateY(var(--fa-bounce-rebound,-.125em))}64%{-webkit-transform:scale(1,1) translateY(0);transform:scale(1,1) translateY(0)}100%{-webkit-transform:scale(1,1) translateY(0);transform:scale(1,1) translateY(0)}}@keyframes fa-bounce{0%{-webkit-transform:scale(1,1) translateY(0);transform:scale(1,1) translateY(0)}10%{-webkit-transform:scale(var(--fa-bounce-start-scale-x,1.1),var(--fa-bounce-start-scale-y,.9)) translateY(0);transform:scale(var(--fa-bounce-start-scale-x,1.1),var(--fa-bounce-start-scale-y,.9)) translateY(0)}30%{-webkit-transform:scale(var(--fa-bounce-jump-scale-x,.9),var(--fa-bounce-jump-scale-y,1.1)) translateY(var(--fa-bounce-height,-.5em));transform:scale(var(--fa-bounce-jump-scale-x,.9),var(--fa-bounce-jump-scale-y,1.1)) translateY(var(--fa-bounce-height,-.5em))}50%{-webkit-transform:scale(var(--fa-bounce-land-scale-x,1.05),var(--fa-bounce-land-scale-y,.95)) translateY(0);transform:scale(var(--fa-bounce-land-scale-x,1.05),var(--fa-bounce-land-scale-y,.95)) translateY(0)}57%{-webkit-transform:scale(1,1) translateY(var(--fa-bounce-rebound,-.125em));transform:scale(1,1) translateY(var(--fa-bounce-rebound,-.125em))}64%{-webkit-transform:scale(1,1) translateY(0);transform:scale(1,1) translateY(0)}100%{-webkit-transform:scale(1,1) translateY(0);transform:scale(1,1) translateY(0)}}@-webkit-keyframes fa-fade{50%{opacity:var(--fa-fade-opacity,.4)}}@keyframes fa-fade{50%{opacity:var(--fa-fade-opacity,.4)}}@-webkit-keyframes fa-beat-fade{0%,100%{opacity:var(--fa-beat-fade-opacity,.4);-webkit-transform:scale(1);transform:scale(1)}50%{opacity:1;-webkit-transform:scale(var(--fa-beat-fade-scale,1.125));transform:scale(var(--fa-beat-fade-scale,1.125))}}@keyframes fa-beat-fade{0%,100%{opacity:var(--fa-beat-fade-opacity,.4);-webkit-transform:scale(1);transform:scale(1)}50%{opacity:1;-webkit-transform:scale(var(--fa-beat-fade-scale,1.125));transform:scale(var(--fa-beat-fade-scale,1.125))}}@-webkit-keyframes fa-flip{50%{-webkit-transform:rotate3d(var(--fa-flip-x,0),var(--fa-flip-y,1),var(--fa-flip-z,0),var(--fa-flip-angle,-180deg));transform:rotate3d(var(--fa-flip-x,0),var(--fa-flip-y,1),var(--fa-flip-z,0),var(--fa-flip-angle,-180deg))}}@keyframes fa-flip{50%{-webkit-transform:rotate3d(var(--fa-flip-x,0),var(--fa-flip-y,1),var(--fa-flip-z,0),var(--fa-flip-angle,-180deg));transform:rotate3d(var(--fa-flip-x,0),var(--fa-flip-y,1),var(--fa-flip-z,0),var(--fa-flip-angle,-180deg))}}@-webkit-keyframes fa-shake{0%{-webkit-transform:rotate(-15deg);transform:rotate(-15deg)}4%{-webkit-transform:rotate(15deg);transform:rotate(15deg)}24%,8%{-webkit-transform:rotate(-18deg);transform:rotate(-18deg)}12%,28%{-webkit-transform:rotate(18deg);transform:rotate(18deg)}16%{-webkit-transform:rotate(-22deg);transform:rotate(-22deg)}20%{-webkit-transform:rotate(22deg);transform:rotate(22deg)}32%{-webkit-transform:rotate(-12deg);transform:rotate(-12deg)}36%{-webkit-transform:rotate(12deg);transform:rotate(12deg)}100%,40%{-webkit-transform:rotate(0);transform:rotate(0)}}@keyframes fa-shake{0%{-webkit-transform:rotate(-15deg);transform:rotate(-15deg)}4%{-webkit-transform:rotate(15deg);transform:rotate(15deg)}24%,8%{-webkit-transform:rotate(-18deg);transform:rotate(-18deg)}12%,28%{-webkit-transform:rotate(18deg);transform:rotate(18deg)}16%{-webkit-transform:rotate(-22deg);transform:rotate(-22deg)}20%{-webkit-transform:rotate(22deg);transform:rotate(22deg)}32%{-webkit-transform:rotate(-12deg);transform:rotate(-12deg)}36%{-webkit-transform:rotate(12deg);transform:rotate(12deg)}100%,40%{-webkit-transform:rotate(0);transform:rotate(0)}}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.fa-rotate-90{-webkit-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-webkit-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-webkit-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-webkit-transform:scale(-1,1);transform:scale(-1,1)}.fa-flip-vertical{-webkit-transform:scale(1,-1);transform:scale(1,-1)}.fa-flip-both,.fa-flip-horizontal.fa-flip-vertical{-webkit-transform:scale(-1,-1);transform:scale(-1,-1)}.fa-rotate-by{-webkit-transform:rotate(var(--fa-rotate-angle,none));transform:rotate(var(--fa-rotate-angle,none))}.fa-stack{display:inline-block;vertical-align:middle;height:2em;position:relative;width:2.5em}.fa-stack-1x,.fa-stack-2x{bottom:0;left:0;margin:auto;position:absolute;right:0;top:0;z-index:var(--fa-stack-z-index,auto)}.svg-inline--fa.fa-stack-1x{height:1em;width:1.25em}.svg-inline--fa.fa-stack-2x{height:2em;width:2.5em}.fa-inverse{color:var(--fa-inverse,#fff)}.fa-sr-only,.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.fa-sr-only-focusable:not(:focus),.sr-only-focusable:not(:focus){position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.svg-inline--fa .fa-primary{fill:var(--fa-primary-color,currentColor);opacity:var(--fa-primary-opacity,1)}.svg-inline--fa .fa-secondary{fill:var(--fa-secondary-color,currentColor);opacity:var(--fa-secondary-opacity,.4)}.svg-inline--fa.fa-swap-opacity .fa-primary{opacity:var(--fa-secondary-opacity,.4)}.svg-inline--fa.fa-swap-opacity .fa-secondary{opacity:var(--fa-primary-opacity,1)}.svg-inline--fa mask .fa-primary,.svg-inline--fa mask .fa-secondary{fill:#000}.fa-duotone.fa-inverse,.fad.fa-inverse{color:var(--fa-inverse,#fff)}';return"fa"===n&&r===a||(t=new RegExp("\\.".concat("fa","\\-"),"g"),e=new RegExp("\\--".concat("fa","\\-"),"g"),a=new RegExp("\\.".concat(a),"g"),i=i.replace(t,".".concat(n,"-")).replace(e,"--".concat(n,"-")).replace(a,".".concat(r))),i}var ht=!1;function gt(){if(C.autoAddCss&&!ht){var t=vt();if(t&&f){for(var e=g.createElement("style"),a=(e.setAttribute("type","text/css"),e.innerHTML=t,g.head.childNodes),n=null,r=a.length-1;-1").concat(r.map(z).join(""),"")}function xt(t,e,a){if(t&&t[e]&&t[e][a])return{prefix:e,iconName:a,icon:t[e][a]}}f&&!(kt=(g.documentElement.doScroll?/^loaded|^c/:/^loaded|^i|^c/).test(g.readyState))&&g.addEventListener("DOMContentLoaded",yt);function Mt(t,e,a,n){for(var r,i,o=Object.keys(t),c=o.length,s=void 0!==n?zt(e,n):e,f=void 0===a?(r=1,t[o[0]]):(r=0,a);rt.length)&&(a=t.length);for(var e=0,n=new Array(a);et.length)&&(a=t.length);for(var e=0,n=new Array(a);et.length)&&(a=t.length);for(var e=0,n=new Array(a);et.length)&&(a=t.length);for(var e=0,n=new Array(a);et.length)&&(a=t.length);for(var e=0,n=new Array(a);e>>0;e--;)a[e]=t[e];return a}function d2(t){return t.classList?k(t.classList):(t.getAttribute("class")||"").split(" ").filter(function(t){return t})}function m2(t){return"".concat(t).replace(/&/g,"&").replace(/"/g,""").replace(/'/g,"'").replace(//g,">")}function C2(e){return Object.keys(e||{}).reduce(function(t,a){return t+"".concat(a,": ").concat(e[a].trim(),";")},"")}function h2(t){return t.size!==V.size||t.x!==V.x||t.y!==V.y||t.rotate!==V.rotate||t.flipX||t.flipY}function p2(){var t,a,e=B,n=z.cssPrefix,r=z.replacementClass,i=':host,:root{--fa-font-solid:normal 900 1em/1 "Font Awesome 6 Solid";--fa-font-regular:normal 400 1em/1 "Font Awesome 6 Regular";--fa-font-light:normal 300 1em/1 "Font Awesome 6 Light";--fa-font-thin:normal 100 1em/1 "Font Awesome 6 Thin";--fa-font-duotone:normal 900 1em/1 "Font Awesome 6 Duotone";--fa-font-sharp-solid:normal 900 1em/1 "Font Awesome 6 Sharp";--fa-font-brands:normal 400 1em/1 "Font Awesome 6 Brands"}svg:not(:host).svg-inline--fa,svg:not(:root).svg-inline--fa{overflow:visible;box-sizing:content-box}.svg-inline--fa{display:var(--fa-display,inline-block);height:1em;overflow:visible;vertical-align:-.125em}.svg-inline--fa.fa-2xs{vertical-align:.1em}.svg-inline--fa.fa-xs{vertical-align:0}.svg-inline--fa.fa-sm{vertical-align:-.0714285705em}.svg-inline--fa.fa-lg{vertical-align:-.2em}.svg-inline--fa.fa-xl{vertical-align:-.25em}.svg-inline--fa.fa-2xl{vertical-align:-.3125em}.svg-inline--fa.fa-pull-left{margin-right:var(--fa-pull-margin,.3em);width:auto}.svg-inline--fa.fa-pull-right{margin-left:var(--fa-pull-margin,.3em);width:auto}.svg-inline--fa.fa-li{width:var(--fa-li-width,2em);top:.25em}.svg-inline--fa.fa-fw{width:var(--fa-fw-width,1.25em)}.fa-layers svg.svg-inline--fa{bottom:0;left:0;margin:auto;position:absolute;right:0;top:0}.fa-layers-counter,.fa-layers-text{display:inline-block;position:absolute;text-align:center}.fa-layers{display:inline-block;height:1em;position:relative;text-align:center;vertical-align:-.125em;width:1em}.fa-layers svg.svg-inline--fa{-webkit-transform-origin:center center;transform-origin:center center}.fa-layers-text{left:50%;top:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);-webkit-transform-origin:center center;transform-origin:center center}.fa-layers-counter{background-color:var(--fa-counter-background-color,#ff253a);border-radius:var(--fa-counter-border-radius,1em);box-sizing:border-box;color:var(--fa-inverse,#fff);line-height:var(--fa-counter-line-height,1);max-width:var(--fa-counter-max-width,5em);min-width:var(--fa-counter-min-width,1.5em);overflow:hidden;padding:var(--fa-counter-padding,.25em .5em);right:var(--fa-right,0);text-overflow:ellipsis;top:var(--fa-top,0);-webkit-transform:scale(var(--fa-counter-scale,.25));transform:scale(var(--fa-counter-scale,.25));-webkit-transform-origin:top right;transform-origin:top right}.fa-layers-bottom-right{bottom:var(--fa-bottom,0);right:var(--fa-right,0);top:auto;-webkit-transform:scale(var(--fa-layers-scale,.25));transform:scale(var(--fa-layers-scale,.25));-webkit-transform-origin:bottom right;transform-origin:bottom right}.fa-layers-bottom-left{bottom:var(--fa-bottom,0);left:var(--fa-left,0);right:auto;top:auto;-webkit-transform:scale(var(--fa-layers-scale,.25));transform:scale(var(--fa-layers-scale,.25));-webkit-transform-origin:bottom left;transform-origin:bottom left}.fa-layers-top-right{top:var(--fa-top,0);right:var(--fa-right,0);-webkit-transform:scale(var(--fa-layers-scale,.25));transform:scale(var(--fa-layers-scale,.25));-webkit-transform-origin:top right;transform-origin:top right}.fa-layers-top-left{left:var(--fa-left,0);right:auto;top:var(--fa-top,0);-webkit-transform:scale(var(--fa-layers-scale,.25));transform:scale(var(--fa-layers-scale,.25));-webkit-transform-origin:top left;transform-origin:top left}.fa-1x{font-size:1em}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-6x{font-size:6em}.fa-7x{font-size:7em}.fa-8x{font-size:8em}.fa-9x{font-size:9em}.fa-10x{font-size:10em}.fa-2xs{font-size:.625em;line-height:.1em;vertical-align:.225em}.fa-xs{font-size:.75em;line-height:.0833333337em;vertical-align:.125em}.fa-sm{font-size:.875em;line-height:.0714285718em;vertical-align:.0535714295em}.fa-lg{font-size:1.25em;line-height:.05em;vertical-align:-.075em}.fa-xl{font-size:1.5em;line-height:.0416666682em;vertical-align:-.125em}.fa-2xl{font-size:2em;line-height:.03125em;vertical-align:-.1875em}.fa-fw{text-align:center;width:1.25em}.fa-ul{list-style-type:none;margin-left:var(--fa-li-margin,2.5em);padding-left:0}.fa-ul>li{position:relative}.fa-li{left:calc(var(--fa-li-width,2em) * -1);position:absolute;text-align:center;width:var(--fa-li-width,2em);line-height:inherit}.fa-border{border-color:var(--fa-border-color,#eee);border-radius:var(--fa-border-radius,.1em);border-style:var(--fa-border-style,solid);border-width:var(--fa-border-width,.08em);padding:var(--fa-border-padding,.2em .25em .15em)}.fa-pull-left{float:left;margin-right:var(--fa-pull-margin,.3em)}.fa-pull-right{float:right;margin-left:var(--fa-pull-margin,.3em)}.fa-beat{-webkit-animation-name:fa-beat;animation-name:fa-beat;-webkit-animation-delay:var(--fa-animation-delay,0s);animation-delay:var(--fa-animation-delay,0s);-webkit-animation-direction:var(--fa-animation-direction,normal);animation-direction:var(--fa-animation-direction,normal);-webkit-animation-duration:var(--fa-animation-duration,1s);animation-duration:var(--fa-animation-duration,1s);-webkit-animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-iteration-count:var(--fa-animation-iteration-count,infinite);-webkit-animation-timing-function:var(--fa-animation-timing,ease-in-out);animation-timing-function:var(--fa-animation-timing,ease-in-out)}.fa-bounce{-webkit-animation-name:fa-bounce;animation-name:fa-bounce;-webkit-animation-delay:var(--fa-animation-delay,0s);animation-delay:var(--fa-animation-delay,0s);-webkit-animation-direction:var(--fa-animation-direction,normal);animation-direction:var(--fa-animation-direction,normal);-webkit-animation-duration:var(--fa-animation-duration,1s);animation-duration:var(--fa-animation-duration,1s);-webkit-animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-iteration-count:var(--fa-animation-iteration-count,infinite);-webkit-animation-timing-function:var(--fa-animation-timing,cubic-bezier(.28,.84,.42,1));animation-timing-function:var(--fa-animation-timing,cubic-bezier(.28,.84,.42,1))}.fa-fade{-webkit-animation-name:fa-fade;animation-name:fa-fade;-webkit-animation-delay:var(--fa-animation-delay,0s);animation-delay:var(--fa-animation-delay,0s);-webkit-animation-direction:var(--fa-animation-direction,normal);animation-direction:var(--fa-animation-direction,normal);-webkit-animation-duration:var(--fa-animation-duration,1s);animation-duration:var(--fa-animation-duration,1s);-webkit-animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-iteration-count:var(--fa-animation-iteration-count,infinite);-webkit-animation-timing-function:var(--fa-animation-timing,cubic-bezier(.4,0,.6,1));animation-timing-function:var(--fa-animation-timing,cubic-bezier(.4,0,.6,1))}.fa-beat-fade{-webkit-animation-name:fa-beat-fade;animation-name:fa-beat-fade;-webkit-animation-delay:var(--fa-animation-delay,0s);animation-delay:var(--fa-animation-delay,0s);-webkit-animation-direction:var(--fa-animation-direction,normal);animation-direction:var(--fa-animation-direction,normal);-webkit-animation-duration:var(--fa-animation-duration,1s);animation-duration:var(--fa-animation-duration,1s);-webkit-animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-iteration-count:var(--fa-animation-iteration-count,infinite);-webkit-animation-timing-function:var(--fa-animation-timing,cubic-bezier(.4,0,.6,1));animation-timing-function:var(--fa-animation-timing,cubic-bezier(.4,0,.6,1))}.fa-flip{-webkit-animation-name:fa-flip;animation-name:fa-flip;-webkit-animation-delay:var(--fa-animation-delay,0s);animation-delay:var(--fa-animation-delay,0s);-webkit-animation-direction:var(--fa-animation-direction,normal);animation-direction:var(--fa-animation-direction,normal);-webkit-animation-duration:var(--fa-animation-duration,1s);animation-duration:var(--fa-animation-duration,1s);-webkit-animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-iteration-count:var(--fa-animation-iteration-count,infinite);-webkit-animation-timing-function:var(--fa-animation-timing,ease-in-out);animation-timing-function:var(--fa-animation-timing,ease-in-out)}.fa-shake{-webkit-animation-name:fa-shake;animation-name:fa-shake;-webkit-animation-delay:var(--fa-animation-delay,0s);animation-delay:var(--fa-animation-delay,0s);-webkit-animation-direction:var(--fa-animation-direction,normal);animation-direction:var(--fa-animation-direction,normal);-webkit-animation-duration:var(--fa-animation-duration,1s);animation-duration:var(--fa-animation-duration,1s);-webkit-animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-iteration-count:var(--fa-animation-iteration-count,infinite);-webkit-animation-timing-function:var(--fa-animation-timing,linear);animation-timing-function:var(--fa-animation-timing,linear)}.fa-spin{-webkit-animation-name:fa-spin;animation-name:fa-spin;-webkit-animation-delay:var(--fa-animation-delay,0s);animation-delay:var(--fa-animation-delay,0s);-webkit-animation-direction:var(--fa-animation-direction,normal);animation-direction:var(--fa-animation-direction,normal);-webkit-animation-duration:var(--fa-animation-duration,2s);animation-duration:var(--fa-animation-duration,2s);-webkit-animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-iteration-count:var(--fa-animation-iteration-count,infinite);-webkit-animation-timing-function:var(--fa-animation-timing,linear);animation-timing-function:var(--fa-animation-timing,linear)}.fa-spin-reverse{--fa-animation-direction:reverse}.fa-pulse,.fa-spin-pulse{-webkit-animation-name:fa-spin;animation-name:fa-spin;-webkit-animation-direction:var(--fa-animation-direction,normal);animation-direction:var(--fa-animation-direction,normal);-webkit-animation-duration:var(--fa-animation-duration,1s);animation-duration:var(--fa-animation-duration,1s);-webkit-animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-iteration-count:var(--fa-animation-iteration-count,infinite);-webkit-animation-timing-function:var(--fa-animation-timing,steps(8));animation-timing-function:var(--fa-animation-timing,steps(8))}@media (prefers-reduced-motion:reduce){.fa-beat,.fa-beat-fade,.fa-bounce,.fa-fade,.fa-flip,.fa-pulse,.fa-shake,.fa-spin,.fa-spin-pulse{-webkit-animation-delay:-1ms;animation-delay:-1ms;-webkit-animation-duration:1ms;animation-duration:1ms;-webkit-animation-iteration-count:1;animation-iteration-count:1;transition-delay:0s;transition-duration:0s}}@-webkit-keyframes fa-beat{0%,90%{-webkit-transform:scale(1);transform:scale(1)}45%{-webkit-transform:scale(var(--fa-beat-scale,1.25));transform:scale(var(--fa-beat-scale,1.25))}}@keyframes fa-beat{0%,90%{-webkit-transform:scale(1);transform:scale(1)}45%{-webkit-transform:scale(var(--fa-beat-scale,1.25));transform:scale(var(--fa-beat-scale,1.25))}}@-webkit-keyframes fa-bounce{0%{-webkit-transform:scale(1,1) translateY(0);transform:scale(1,1) translateY(0)}10%{-webkit-transform:scale(var(--fa-bounce-start-scale-x,1.1),var(--fa-bounce-start-scale-y,.9)) translateY(0);transform:scale(var(--fa-bounce-start-scale-x,1.1),var(--fa-bounce-start-scale-y,.9)) translateY(0)}30%{-webkit-transform:scale(var(--fa-bounce-jump-scale-x,.9),var(--fa-bounce-jump-scale-y,1.1)) translateY(var(--fa-bounce-height,-.5em));transform:scale(var(--fa-bounce-jump-scale-x,.9),var(--fa-bounce-jump-scale-y,1.1)) translateY(var(--fa-bounce-height,-.5em))}50%{-webkit-transform:scale(var(--fa-bounce-land-scale-x,1.05),var(--fa-bounce-land-scale-y,.95)) translateY(0);transform:scale(var(--fa-bounce-land-scale-x,1.05),var(--fa-bounce-land-scale-y,.95)) translateY(0)}57%{-webkit-transform:scale(1,1) translateY(var(--fa-bounce-rebound,-.125em));transform:scale(1,1) translateY(var(--fa-bounce-rebound,-.125em))}64%{-webkit-transform:scale(1,1) translateY(0);transform:scale(1,1) translateY(0)}100%{-webkit-transform:scale(1,1) translateY(0);transform:scale(1,1) translateY(0)}}@keyframes fa-bounce{0%{-webkit-transform:scale(1,1) translateY(0);transform:scale(1,1) translateY(0)}10%{-webkit-transform:scale(var(--fa-bounce-start-scale-x,1.1),var(--fa-bounce-start-scale-y,.9)) translateY(0);transform:scale(var(--fa-bounce-start-scale-x,1.1),var(--fa-bounce-start-scale-y,.9)) translateY(0)}30%{-webkit-transform:scale(var(--fa-bounce-jump-scale-x,.9),var(--fa-bounce-jump-scale-y,1.1)) translateY(var(--fa-bounce-height,-.5em));transform:scale(var(--fa-bounce-jump-scale-x,.9),var(--fa-bounce-jump-scale-y,1.1)) translateY(var(--fa-bounce-height,-.5em))}50%{-webkit-transform:scale(var(--fa-bounce-land-scale-x,1.05),var(--fa-bounce-land-scale-y,.95)) translateY(0);transform:scale(var(--fa-bounce-land-scale-x,1.05),var(--fa-bounce-land-scale-y,.95)) translateY(0)}57%{-webkit-transform:scale(1,1) translateY(var(--fa-bounce-rebound,-.125em));transform:scale(1,1) translateY(var(--fa-bounce-rebound,-.125em))}64%{-webkit-transform:scale(1,1) translateY(0);transform:scale(1,1) translateY(0)}100%{-webkit-transform:scale(1,1) translateY(0);transform:scale(1,1) translateY(0)}}@-webkit-keyframes fa-fade{50%{opacity:var(--fa-fade-opacity,.4)}}@keyframes fa-fade{50%{opacity:var(--fa-fade-opacity,.4)}}@-webkit-keyframes fa-beat-fade{0%,100%{opacity:var(--fa-beat-fade-opacity,.4);-webkit-transform:scale(1);transform:scale(1)}50%{opacity:1;-webkit-transform:scale(var(--fa-beat-fade-scale,1.125));transform:scale(var(--fa-beat-fade-scale,1.125))}}@keyframes fa-beat-fade{0%,100%{opacity:var(--fa-beat-fade-opacity,.4);-webkit-transform:scale(1);transform:scale(1)}50%{opacity:1;-webkit-transform:scale(var(--fa-beat-fade-scale,1.125));transform:scale(var(--fa-beat-fade-scale,1.125))}}@-webkit-keyframes fa-flip{50%{-webkit-transform:rotate3d(var(--fa-flip-x,0),var(--fa-flip-y,1),var(--fa-flip-z,0),var(--fa-flip-angle,-180deg));transform:rotate3d(var(--fa-flip-x,0),var(--fa-flip-y,1),var(--fa-flip-z,0),var(--fa-flip-angle,-180deg))}}@keyframes fa-flip{50%{-webkit-transform:rotate3d(var(--fa-flip-x,0),var(--fa-flip-y,1),var(--fa-flip-z,0),var(--fa-flip-angle,-180deg));transform:rotate3d(var(--fa-flip-x,0),var(--fa-flip-y,1),var(--fa-flip-z,0),var(--fa-flip-angle,-180deg))}}@-webkit-keyframes fa-shake{0%{-webkit-transform:rotate(-15deg);transform:rotate(-15deg)}4%{-webkit-transform:rotate(15deg);transform:rotate(15deg)}24%,8%{-webkit-transform:rotate(-18deg);transform:rotate(-18deg)}12%,28%{-webkit-transform:rotate(18deg);transform:rotate(18deg)}16%{-webkit-transform:rotate(-22deg);transform:rotate(-22deg)}20%{-webkit-transform:rotate(22deg);transform:rotate(22deg)}32%{-webkit-transform:rotate(-12deg);transform:rotate(-12deg)}36%{-webkit-transform:rotate(12deg);transform:rotate(12deg)}100%,40%{-webkit-transform:rotate(0);transform:rotate(0)}}@keyframes fa-shake{0%{-webkit-transform:rotate(-15deg);transform:rotate(-15deg)}4%{-webkit-transform:rotate(15deg);transform:rotate(15deg)}24%,8%{-webkit-transform:rotate(-18deg);transform:rotate(-18deg)}12%,28%{-webkit-transform:rotate(18deg);transform:rotate(18deg)}16%{-webkit-transform:rotate(-22deg);transform:rotate(-22deg)}20%{-webkit-transform:rotate(22deg);transform:rotate(22deg)}32%{-webkit-transform:rotate(-12deg);transform:rotate(-12deg)}36%{-webkit-transform:rotate(12deg);transform:rotate(12deg)}100%,40%{-webkit-transform:rotate(0);transform:rotate(0)}}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.fa-rotate-90{-webkit-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-webkit-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-webkit-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-webkit-transform:scale(-1,1);transform:scale(-1,1)}.fa-flip-vertical{-webkit-transform:scale(1,-1);transform:scale(1,-1)}.fa-flip-both,.fa-flip-horizontal.fa-flip-vertical{-webkit-transform:scale(-1,-1);transform:scale(-1,-1)}.fa-rotate-by{-webkit-transform:rotate(var(--fa-rotate-angle,none));transform:rotate(var(--fa-rotate-angle,none))}.fa-stack{display:inline-block;vertical-align:middle;height:2em;position:relative;width:2.5em}.fa-stack-1x,.fa-stack-2x{bottom:0;left:0;margin:auto;position:absolute;right:0;top:0;z-index:var(--fa-stack-z-index,auto)}.svg-inline--fa.fa-stack-1x{height:1em;width:1.25em}.svg-inline--fa.fa-stack-2x{height:2em;width:2.5em}.fa-inverse{color:var(--fa-inverse,#fff)}.fa-sr-only,.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.fa-sr-only-focusable:not(:focus),.sr-only-focusable:not(:focus){position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.svg-inline--fa .fa-primary{fill:var(--fa-primary-color,currentColor);opacity:var(--fa-primary-opacity,1)}.svg-inline--fa .fa-secondary{fill:var(--fa-secondary-color,currentColor);opacity:var(--fa-secondary-opacity,.4)}.svg-inline--fa.fa-swap-opacity .fa-primary{opacity:var(--fa-secondary-opacity,.4)}.svg-inline--fa.fa-swap-opacity .fa-secondary{opacity:var(--fa-primary-opacity,1)}.svg-inline--fa mask .fa-primary,.svg-inline--fa mask .fa-secondary{fill:#000}.fa-duotone.fa-inverse,.fad.fa-inverse{color:var(--fa-inverse,#fff)}';return"fa"===n&&r===e||(t=new RegExp("\\.".concat("fa","\\-"),"g"),a=new RegExp("\\--".concat("fa","\\-"),"g"),e=new RegExp("\\.".concat(e),"g"),i=i.replace(t,".".concat(n,"-")).replace(a,"--".concat(n,"-")).replace(e,".".concat(r))),i}var v2=!1;function b2(){if(z.autoAddCss&&!v2){var t=p2();if(t&&f){for(var a=b.createElement("style"),e=(a.setAttribute("type","text/css"),a.innerHTML=t,b.head.childNodes),n=null,r=e.length-1;-1").concat(r.map(L).join(""),"")}function V2(t,a,e){if(t&&t[a]&&t[a][e])return{prefix:a,iconName:e,icon:t[a][e]}}f&&!(H2=(b.documentElement.doScroll?/^loaded|^c/:/^loaded|^i|^c/).test(b.readyState))&&b.addEventListener("DOMContentLoaded",g2);function M2(t,a,e,n){for(var r,i,o=Object.keys(t),c=o.length,s=void 0!==n?k2(a,n):a,f=void 0===e?(r=1,t[o[0]]):(r=0,e);r
+ + +
diff --git a/src/parse.js b/src/parse.js index da83aa3..5470b30 100644 --- a/src/parse.js +++ b/src/parse.js @@ -30,10 +30,13 @@ var removeWebseeds = document.getElementById('removeWebseeds'); var pieces = document.getElementById('pieces'); var files = document.getElementById('filesBody'); var getFiles = document.getElementById('getFiles'); +var openURLWrapper = document.getElementById('openURLWrapper'); +var openURL = document.getElementById('openURL'); var copyURL = document.getElementById('copyURL'); var copyMagnet = document.getElementById('copyMagnet'); var downloadTorrentWrapper = document.getElementById('downloadTorrentWrapper'); var downloadTorrent = document.getElementById('downloadTorrent'); +var openURLTooltip = tippy(openURL, {"theme": "torrent-parts", "animation": "shift-away-subtle", "content": "Open this Magnet URL in your Torrent client"}); var copyURLTooltip = tippy(copyURL, {"theme": "torrent-parts", "animation": "shift-away-subtle", "content": "Copy torrent.parts link to clipboard"}); var copyMagnetTooltip = tippy(copyMagnet, {"theme": "torrent-parts", "animation": "shift-away-subtle", "content": "Copy Magnet link to clipboard"}); var downloadTorrentTooltip = tippy(downloadTorrentWrapper, {"theme": "torrent-parts", "animation": "shift-away-subtle", "content": "Download Torrent file"}); @@ -63,10 +66,12 @@ var notyf = new Notyf({ function placeDownloadTooltips(e) { if (window.innerWidth > 1080) { + openURLTooltip.setProps({"placement": "right"}); copyURLTooltip.setProps({"placement": "right"}); copyMagnetTooltip.setProps({"placement": "right"}); downloadTorrentTooltip.setProps({"placement": "right"}); } else { + openURLTooltip.setProps({"placement": "top"}); copyURLTooltip.setProps({"placement": "top"}); copyMagnetTooltip.setProps({"placement": "top"}); downloadTorrentTooltip.setProps({"placement": "top"}); @@ -319,6 +324,7 @@ function display() { files.appendChild(createFileRow('', '...and another ' + (parsed.files.length - 100) + ' more files', '')); } files.appendChild(createFileRow('folder-tree', '', parsed.length)); + openURLWrapper.href = parser.toMagnetURI(parsed); downloadTorrentTooltip.setContent('Download Torrent file'); downloadTorrent.addEventListener('click', saveTorrent); downloadTorrent.disabled = false; diff --git a/src/style.css b/src/style.css index fdc016a..0d15cf9 100644 --- a/src/style.css +++ b/src/style.css @@ -251,7 +251,7 @@ label[for="torrent"] { flex-direction: column; } -#share > div > button { +#share > * > button { width: 64px; height: 64px; border-radius: 50%;