{"version":3,"sources":["jsdelivr-header.js","/npm/torrent-xiv@0.0.7/torrent-xiv.js"],"names":[],"mappings":"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","file":"/npm/torrent-xiv@0.0.7/torrent-xiv.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.39.0.\n * Original file: /npm/torrent-xiv@0.0.7/torrent-xiv.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","var _ =             require('underscore');\r\nvar os =            require('os');\r\nvar path =          require('path');\r\nvar util =          require('util');\r\nvar filesize =      require('filesize');\r\nvar EventEmitter =  require('events').EventEmitter;\r\nvar parseTorrent =  require('parse-torrent');\r\nvar TorrentStream = require('torrent-stream');\r\n\r\n/**\r\n * Downloads a torrent\r\n *\r\n * @constructor\r\n * @param source    {Buffer | string | {source: Buffer | string}}\r\n * @param options   {Object}\r\n *\r\n * @emits Torrent#active     Started downloading and uploading         Passes getInfo()\r\n * @emits Torrent#inactive   Stopped downloading and uploading         Passes getInfo()\r\n * @emits Torrent#progress   The torrent has downloaded a piece.       Passes getInfo()\r\n * @emits Torrent#stats      Periodic update. (opts.statFrequency)     Passes getStats()\r\n * @emits Torrent#complete   Torrent has finished. Can override ready  Passes getInfo()\r\n */\r\nfunction Torrent(source, options)\r\n{\r\n\tvar opts =      options || {};\r\n\tvar busy =      false;\r\n\tvar cache =     {}; // used by various functions\r\n\tvar ready =     false;\r\n\tvar starts = \t0; // number of times the engine became ready\r\n\tvar paused =    true; // initial state must be true\r\n\tvar engine =    {};\r\n\tvar torrent =   this;\r\n\tvar complete =  false;\r\n\tvar verified =  0;\r\n\tvar defaults =  {connections: 100, uploads: 10, path: os.tmpdir(), mkdir: true, seed: false, start: true, statFrequency: 2000};\r\n\r\n\tthis.metadata = {};\r\n\r\n\tthis.pause = function(cb)\r\n\t{\r\n\t\tif (paused || busy) return;\r\n\t\tbusy = true;\r\n\t\tcache.status = getStatus();\r\n\t\tengine.destroy(function()\r\n\t\t{\r\n\t\t\tpaused = true;\r\n\t\t\tready = false;\r\n\t\t\tbusy = false;\r\n\t\t\ttorrent.emit('inactive');\r\n\t\t\tif (cb) cb();\r\n\t\t});\r\n\t};\r\n\r\n\tthis.start = function()\r\n\t{\r\n\t\tif (!paused || busy) return;\r\n\t\tpaused = false;\r\n\t\tstartEngine();\r\n\t};\r\n\r\n\tthis.status = function()\r\n\t{\r\n\t\treturn getStatus();\r\n\t};\r\n\r\n\tthis.stats = function()\r\n\t{\r\n\t\treturn getTrafficStats();\r\n\t};\r\n\r\n\t/**\r\n\t * Starts a torrent-stream instance and immediately begins the download\r\n\t */\r\n\tfunction startEngine()\r\n\t{\r\n\t\tengine = new TorrentStream(source, opts);\r\n\r\n\t\tengine.on('ready', function()\r\n\t\t{\r\n\t\t\tstarts++;\r\n\t\t\tready = true;\r\n\t\t\tengine.files.forEach(function(file) {file.select();});\r\n\t\t\ttorrent.metadata = getMetadata();\r\n\t\t\tif (starts === 1 ) torrent.emit('metadata', torrent.metadata);\r\n\t\t\ttorrent.emit('_engineReady');\r\n\t\t\ttorrent.emit('active');\r\n\t\t});\r\n\r\n\t\tengine.on('download', function()\r\n\t\t{\r\n\t\t\temitProgressThrottled();\r\n\t\t});\r\n\r\n\t\tengine.on('verify', function()\r\n\t\t{\r\n\t\t\tverified++;\r\n\t\t\tif (verified === engine.torrent.pieces.length) finish();\r\n\t\t});\r\n\t}\r\n\r\n\t/**\r\n\t * Obtain torrent metadata\r\n\t * @returns {{\r\n\t *     name: string,\r\n\t *     files: Array,\r\n\t *     infoHash: string\r\n\t *     directory: string,\r\n\t *     source: Buffer | string,\r\n\t * }}\r\n\t */\r\n\tfunction getMetadata()\r\n\t{\r\n\t\tvar meta = {\r\n\t\t\tsource: source,\r\n\t\t\tfiles: getFiles(),\r\n\t\t\tdirectory: engine.path,\r\n\t\t\tname: engine.torrent.name,\r\n\t\t\tinfoHash: engine.torrent.infoHash\r\n\t\t};\r\n\t\treturn jsonCopy(meta);\r\n\t}\r\n\r\n\t/**\r\n\t * Obtain torrent status\r\n\t * @returns {{active: boolean, percentage: number, infoHash: string}}\r\n\t */\r\n\tfunction getStatus()\r\n\t{\r\n\t\tvar status = {\r\n\t\t\tactive: !paused,\r\n\t\t\tpercentage: getPercentage(),\r\n\t\t\tinfoHash: torrent.metadata.infoHash\r\n\t\t};\r\n\t\treturn jsonCopy(status);\r\n\t}\r\n\r\n\t/**\r\n\t * Obtain network traffic status of the torrent.\r\n\t * Only returns data when the torrent is active.\r\n\t * i.e. not while paused or complete.\r\n\t * @returns {{\r\n\t *     percentage:     number,\r\n\t *     downSpeed:      number,\r\n\t *     upSpeed:        number,\r\n\t *     downloaded:     number,\r\n\t *     uploaded:       number,\r\n\t *     peersTotal:     number,\r\n\t *     peersUnchoked:  number\r\n\t * }}\r\n\t */\r\n\tfunction getTrafficStats()\r\n\t{\r\n\t\tvar s = ready? engine.swarm : null;\r\n\t\treturn {\r\n\t\t\tinfoHash:       torrent.metadata.infoHash,\r\n\t\t\tpercentage:     getPercentage(),\r\n\t\t\tdownSpeed:      ready? s.downloadSpeed() : 0,\r\n\t\t\tupSpeed:        ready? s.uploadSpeed() : 0,\r\n\t\t\tdownloaded:     ready? s.downloaded : 0,\r\n\t\t\tuploaded:       ready? s.uploaded : 0,\r\n\t\t\tpeersTotal:     ready? s.wires.length : 0,\r\n\t\t\tpeersUnchoked:  ready? s.wires.reduce(function(prev, wire) {return prev + !wire.peerChoking;}, 0) : 0\r\n\t\t};\r\n\t}\r\n\r\n\t/**\r\n\t * Obtain overall torrent percentage as a float, 2 decimal places\r\n\t * @returns {number}\r\n\t */\r\n\tfunction getPercentage()\r\n\t{\r\n\t\treturn ready? Math.floor((verified/engine.torrent.pieces.length) * 10000)/100 : cache.status.percentage;\r\n\t}\r\n\r\n\tfunction finish()\r\n\t{\r\n\t\tcomplete = true;\r\n\t\tif (ready)\r\n\t\t{\r\n\t\t\ttorrent.pause(function()\r\n\t\t\t{\r\n\t\t\t\ttorrent.emit('complete');\r\n\t\t\t});\r\n\t\t}\r\n\t\telse\r\n\t\t{\r\n\t\t\ttorrent.once('_engineReady', finish)\r\n\t\t}\r\n\t}\r\n\r\n\tfunction emitProgressThrottled()\r\n\t{\r\n\t\tif (!cache.emitProgressThrottled)\r\n\t\t{\r\n\t\t\tfunction emit() {torrent.emit('progress', getStatus());}\r\n\t\t\tcache.emitProgressThrottled = _(emit).throttle(1000, {trailing: false});\r\n\t\t}\r\n\r\n\t\tcache.emitProgressThrottled();\r\n\t}\r\n\r\n\t/**\r\n\t * Returns a copy of torrent-stream's files converted to our format\r\n\t * @returns {{}} TODO document\r\n\t */\r\n\tfunction getFiles()\r\n\t{\r\n\t\tvar fileList = engine.files.map(function(file)\r\n\t\t{\r\n\t\t\treturn {\r\n\t\t\t\tname: file.name,\r\n\t\t\t\tbytes: file.length,\r\n\t\t\t\ttorrentPath: file.path,\r\n\t\t\t\thumanBytes: filesize(file.length),\r\n\t\t\t\tpath: path.join(engine.path, file.path)\r\n\t\t\t};\r\n\t\t});\r\n\r\n\t\treturn jsonCopy(fileList);\r\n\t}\r\n\r\n\t/**\r\n\t * Checks that the torrent source from the user is valid and\r\n\t * applies defaults to the options parameter that the user provided\r\n\t */\r\n\tfunction processInput()\r\n\t{\r\n\t\tvar parsed = parseTorrent(source);\r\n\t\tif (!parsed || !parsed.infoHash) throw new Error('Please provide a valid torrent');\r\n\t\t_(opts).defaults(defaults);\r\n\t\tif (opts.mkdir) opts.path = path.join(opts.path, parsed.infoHash);\r\n\t}\r\n\r\n\tfunction jsonCopy(obj)\r\n\t{\r\n\t\treturn JSON.parse(JSON.stringify(obj));\r\n\t}\r\n\r\n\ttorrent.on('active', function()\r\n\t{\r\n\t\tcache.statsInterval = setInterval(function() {torrent.emit('stats', getTrafficStats());}, opts.statFrequency);\r\n\t});\r\n\r\n\ttorrent.on('inactive', function()\r\n\t{\r\n\t\tclearInterval(cache.statsInterval);\r\n\t});\r\n\r\n\tprocessInput();\r\n\tif (opts.start) this.start();\r\n}\r\n\r\nutil.inherits(Torrent, EventEmitter);\r\n\r\nmodule.exports = Torrent;"]}