From 6097ae410975426adba18ce8554aa9302f530a42 Mon Sep 17 00:00:00 2001 From: Jocelyn Liu Date: Wed, 8 Aug 2018 21:38:57 -0700 Subject: [PATCH 1/9] package.json update --- package-lock.json | 1158 ++++++++++++++++++++++++++++++++++++++++++--- package.json | 13 + 2 files changed, 1101 insertions(+), 70 deletions(-) diff --git a/package-lock.json b/package-lock.json index 64cd0aa1a4b8..bdbf3b8b8f56 100644 --- a/package-lock.json +++ b/package-lock.json @@ -67,6 +67,14 @@ } } }, + "@types/bittorrent-protocol": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/@types/bittorrent-protocol/-/bittorrent-protocol-2.2.2.tgz", + "integrity": "sha512-VAPyW8eGh8FjyGxBSKyPSH60Qkxo3r2W4sDYXCQJYfYD49UnA1SUP+5GQ/4MgbdiEDSp9YW4yuebpIR/vstD5Q==", + "requires": { + "@types/node": "*" + } + }, "@types/cheerio": { "version": "0.22.8", "resolved": "https://registry.npmjs.org/@types/cheerio/-/cheerio-0.22.8.tgz", @@ -122,11 +130,36 @@ "integrity": "sha512-/UMY+2GkOZ27Vrc51pqC5J8SPd39FKt7kkoGAtWJ8s4msj0b15KehDWIiJpWY3/7tLxBQLLzJhIBhnEsXdzpgw==", "dev": true }, + "@types/magnet-uri": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@types/magnet-uri/-/magnet-uri-5.1.1.tgz", + "integrity": "sha1-hhqvZMkqMTfdhI/vxVzTUqjqhRo=", + "requires": { + "@types/node": "*" + } + }, "@types/node": { "version": "10.5.5", "resolved": "https://registry.npmjs.org/@types/node/-/node-10.5.5.tgz", - "integrity": "sha512-6Qnb1gXbp3g1JX9QVJj3A6ORzc9XCyhokxUKaoonHgNXcQhmk8adhotxfkeK8El9TnFeUuH72yI6jQ5nDJKS6w==", - "dev": true + "integrity": "sha512-6Qnb1gXbp3g1JX9QVJj3A6ORzc9XCyhokxUKaoonHgNXcQhmk8adhotxfkeK8El9TnFeUuH72yI6jQ5nDJKS6w==" + }, + "@types/parse-torrent": { + "version": "5.8.2", + "resolved": "https://registry.npmjs.org/@types/parse-torrent/-/parse-torrent-5.8.2.tgz", + "integrity": "sha512-wfXO0N2vNkk/W1CEiPbT+7GPiOe3fnRLecdFBw/HNxPyx6czOGqUYi8bw2dbjEmYqWSsqhMdrajEd6o5ry2p4w==", + "requires": { + "@types/magnet-uri": "*", + "@types/node": "*", + "@types/parse-torrent-file": "*" + } + }, + "@types/parse-torrent-file": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/parse-torrent-file/-/parse-torrent-file-4.0.1.tgz", + "integrity": "sha1-BWpsGPP6wM18bHRUDwBJajIll2s=", + "requires": { + "@types/node": "*" + } }, "@types/react": { "version": "16.4.7", @@ -166,6 +199,46 @@ "redux": "^4.0.0" } }, + "@types/redux-logger": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/redux-logger/-/redux-logger-3.0.6.tgz", + "integrity": "sha512-HXVJnbyuTcVtQ+qiwDcbLEMoOgNjKnNYVKx29P4NhV+FIgVVRCFILEPzjgSxlmMLc6aBVaEew7PfE3421DZ6Jw==", + "requires": { + "redux": "^3.6.0" + }, + "dependencies": { + "redux": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/redux/-/redux-3.7.2.tgz", + "integrity": "sha512-pNqnf9q1hI5HHZRBkj3bAngGZW/JMCmexDlOxw4XagXY2o1327nHH54LoTjiPJ0gizoqPDRqWyX/00g0hD6w+A==", + "requires": { + "lodash": "^4.2.1", + "lodash-es": "^4.2.1", + "loose-envify": "^1.1.0", + "symbol-observable": "^1.0.3" + } + } + } + }, + "@types/simple-peer": { + "version": "6.1.5", + "resolved": "https://registry.npmjs.org/@types/simple-peer/-/simple-peer-6.1.5.tgz", + "integrity": "sha512-huXri3g0rQpIO5jkG630a2sBrh1WXgsd2Gsoc9MqWTRZ0AWqyMEcMCfLXmw5i8AvrZbjAT6BIxW2gEqvpqSYwA==", + "requires": { + "@types/node": "*" + } + }, + "@types/webtorrent": { + "version": "0.98.4", + "resolved": "https://registry.npmjs.org/@types/webtorrent/-/webtorrent-0.98.4.tgz", + "integrity": "sha1-z42+IuPVz2kVMF9/lwtSvKAb+LQ=", + "requires": { + "@types/bittorrent-protocol": "*", + "@types/node": "*", + "@types/parse-torrent": "*", + "@types/simple-peer": "*" + } + }, "@webassemblyjs/ast": { "version": "1.5.13", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.5.13.tgz", @@ -455,6 +528,11 @@ "acorn": "^5.0.0" } }, + "addr-to-ip-port": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/addr-to-ip-port/-/addr-to-ip-port-1.5.1.tgz", + "integrity": "sha512-bA+dyydTNuQtrEDJ0g9eR7XabNhvrM5yZY0hvTbNK3yvoeC73ZqMES6E1cEqH9WPxs4uMtMsOjfwS4FmluhsAA==" + }, "ajv": { "version": "6.5.2", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.5.2.tgz", @@ -716,8 +794,7 @@ "async-limiter": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", - "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==", - "dev": true + "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==" }, "asynckit": { "version": "0.4.0", @@ -1814,8 +1891,7 @@ "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" }, "base": { "version": "0.11.2", @@ -1894,6 +1970,14 @@ "tweetnacl": "^0.14.3" } }, + "bencode": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/bencode/-/bencode-2.0.0.tgz", + "integrity": "sha512-wr2HwwrUpfB5c68zmAudOltC7rZ1G0+lQOcnuEcfIM3AWAVnB3rHI3nlgd/2CWTfQ3w3zagKt89zni/M+VLZ8g==", + "requires": { + "safe-buffer": "^5.1.1" + } + }, "big.js": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.2.0.tgz", @@ -1906,6 +1990,145 @@ "integrity": "sha1-RqoXUftqL5PuXmibsQh9SxTGwgU=", "dev": true }, + "binary-search": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/binary-search/-/binary-search-1.3.4.tgz", + "integrity": "sha512-dPxU/vZLnH0tEVjVPgi015oSwqu6oLfCeHywuFRhBE0yM0mYocvleTl8qsdM1YFhRzTRhM1+VzS8XLDVrHPopg==" + }, + "bitfield": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/bitfield/-/bitfield-2.0.0.tgz", + "integrity": "sha512-4xM4DYejOHQ/qWBfeqBXNA4mJ12PwcOibFYnH1kYh5U9BHciCqEJBqGNVnMJXUhm8mflujNRLSv7IiVQxovgjw==" + }, + "bittorrent-dht": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/bittorrent-dht/-/bittorrent-dht-8.4.0.tgz", + "integrity": "sha512-FRe/+MYBePev7Yb+BXSclkVuDxb/w+gUbao6nVHYQRaKO7aXE+ARRlL3phqm6Rdhw5CRVoLMbLd49nxmCuUhUQ==", + "requires": { + "bencode": "^2.0.0", + "buffer-equals": "^1.0.3", + "debug": "^3.1.0", + "inherits": "^2.0.1", + "k-bucket": "^4.0.0", + "k-rpc": "^5.0.0", + "last-one-wins": "^1.0.4", + "lru": "^3.1.0", + "randombytes": "^2.0.5", + "record-cache": "^1.0.2", + "safe-buffer": "^5.0.1", + "simple-sha1": "^2.1.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + } + } + }, + "bittorrent-peerid": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/bittorrent-peerid/-/bittorrent-peerid-1.3.0.tgz", + "integrity": "sha512-SYd5H3RbN1ex+TrWAKXkEkASFWxAR7Tk6iLt9tfAT9ehBvZb/Y3AQDVRVJynlrixcWpnmsLYKI7tkRWgp7ORoQ==" + }, + "bittorrent-protocol": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/bittorrent-protocol/-/bittorrent-protocol-3.0.1.tgz", + "integrity": "sha512-hnvOzAu9u+2H0OLLL5byoFdz6oz5f3bx5f7R+ItUohTHMq9TgUhEJfcjo7xWtQHSKOVciYWwYTJ4EjczF5RX2A==", + "requires": { + "bencode": "^2.0.0", + "bitfield": "^2.0.0", + "debug": "^3.1.0", + "randombytes": "^2.0.5", + "readable-stream": "^2.3.2", + "speedometer": "^1.0.0", + "unordered-array-remove": "^1.0.2", + "xtend": "^4.0.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + } + } + }, + "bittorrent-tracker": { + "version": "9.10.0", + "resolved": "https://registry.npmjs.org/bittorrent-tracker/-/bittorrent-tracker-9.10.0.tgz", + "integrity": "sha512-mL/hLX5aT9D0ywIcleksJ3vaggxguwzyBTWEYU/8s7f3x8rvtB2SDNaQ548/CezqfVVxGNAHlBxctw4EeXSp8Q==", + "requires": { + "bencode": "^2.0.0", + "bittorrent-peerid": "^1.0.2", + "bn.js": "^4.4.0", + "bufferutil": "^4.0.0", + "compact2string": "^1.2.0", + "debug": "^3.1.0", + "inherits": "^2.0.1", + "ip": "^1.0.1", + "lru": "^3.0.0", + "minimist": "^1.1.1", + "once": "^1.3.0", + "random-iterate": "^1.0.1", + "randombytes": "^2.0.3", + "run-parallel": "^1.1.2", + "run-series": "^1.0.2", + "safe-buffer": "^5.0.0", + "simple-get": "^3.0.0", + "simple-peer": "^9.0.0", + "simple-websocket": "^7.0.1", + "string2compact": "^1.1.1", + "uniq": "^1.0.1", + "unordered-array-remove": "^1.0.2", + "utf-8-validate": "^5.0.1", + "ws": "^6.0.0", + "xtend": "^4.0.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + }, + "ws": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.0.0.tgz", + "integrity": "sha512-c2UlYcAZp1VS8AORtpq6y4RJIkJ9dQz18W32SpR/qXGfLDZ2jU4y4wKvvZwqbi7U6gxFQTeE+urMbXU/tsDy4w==", + "requires": { + "async-limiter": "~1.0.0" + } + } + } + }, + "blob-to-buffer": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/blob-to-buffer/-/blob-to-buffer-1.2.8.tgz", + "integrity": "sha512-re0AIxakF504MgeMtIyJkVcZ8T5aUxtp/QmTMlmjyb3P44E1BEv5x3LATBGApWAJATyXHtkXRD+gWTmeyYLiQA==" + }, + "block-stream2": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/block-stream2/-/block-stream2-1.1.0.tgz", + "integrity": "sha1-xzjjqRupd+u14f70MeE8oR2GOeI=", + "requires": { + "defined": "^1.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.0.4" + } + }, "bluebird": { "version": "3.5.1", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", @@ -1915,8 +2138,7 @@ "bn.js": { "version": "4.11.8", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true + "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==" }, "boolbase": { "version": "1.0.0", @@ -1928,7 +2150,6 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -2031,6 +2252,11 @@ "safe-buffer": "^5.1.2" } }, + "browserify-package-json": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browserify-package-json/-/browserify-package-json-1.0.1.tgz", + "integrity": "sha1-mN3oqlxWH9bT/km7qhArdLOW/eo=" + }, "browserify-rsa": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", @@ -2094,11 +2320,34 @@ "ieee754": "^1.1.4" } }, + "buffer-alloc": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", + "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", + "requires": { + "buffer-alloc-unsafe": "^1.1.0", + "buffer-fill": "^1.0.0" + } + }, + "buffer-alloc-unsafe": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", + "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==" + }, + "buffer-equals": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/buffer-equals/-/buffer-equals-1.0.4.tgz", + "integrity": "sha1-A1O1T9B/2VZBcGca5vZrnPENJ/U=" + }, + "buffer-fill": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", + "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=" + }, "buffer-from": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" }, "buffer-xor": { "version": "1.0.3", @@ -2106,6 +2355,15 @@ "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", "dev": true }, + "bufferutil": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.0.tgz", + "integrity": "sha512-jpnqMVLo7sqfUY2W92RC4jjj9TuiOSkjB0k43TxPcrBSntZwXUOl8Krfd3eVEdApuScpSTwYKntm/dXU2T8gnw==", + "optional": true, + "requires": { + "node-gyp-build": "~3.4.0" + } + }, "builtin-modules": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", @@ -2295,6 +2553,23 @@ "integrity": "sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE=", "dev": true }, + "chrome-dgram": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/chrome-dgram/-/chrome-dgram-3.0.1.tgz", + "integrity": "sha1-QqOI0E2gY4ZaeeO6KuX7+KsPHbo=", + "requires": { + "inherits": "^2.0.1", + "run-series": "^1.1.2" + } + }, + "chrome-net": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/chrome-net/-/chrome-net-3.3.1.tgz", + "integrity": "sha512-erjHzaLGOOn1WTDdVtEYxeltKLhWpL3TNAv5ODqgseOCWMmV0GueWUR3by3LH9gr3BKPJRzyqPROJpaOCXz22w==", + "requires": { + "inherits": "^2.0.1" + } + }, "chrome-trace-event": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.0.tgz", @@ -2304,6 +2579,15 @@ "tslib": "^1.9.0" } }, + "chunk-store-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chunk-store-stream/-/chunk-store-stream-3.0.0.tgz", + "integrity": "sha512-eKmlEJ3qpHvHedRdoJA1sixqKF2iNL9mNPu3eev5wO0zg/YXKqda9rBnCfxsIUzxqFkPwyf7fPWcQuFKUCqARw==", + "requires": { + "block-stream2": "^1.0.0", + "readable-stream": "^2.0.5" + } + }, "ci-info": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.1.3.tgz", @@ -2367,6 +2651,11 @@ "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", "dev": true }, + "clipboard-copy": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/clipboard-copy/-/clipboard-copy-2.0.0.tgz", + "integrity": "sha512-7goBFzT1qI6TnzmaKUq9afyT3+hodAk3zNpktsK00a9vRwACUliCZzBBxBqRWVWNhBy+aQ1Uw6E/rlbuoqkBMg==" + }, "cliui": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", @@ -2394,6 +2683,11 @@ "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", "dev": true }, + "closest-to": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/closest-to/-/closest-to-2.0.0.tgz", + "integrity": "sha1-uyqGDtt3abYtBIIXSK5Q2iTb76o=" + }, "co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", @@ -2498,6 +2792,14 @@ "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", "dev": true }, + "compact2string": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/compact2string/-/compact2string-1.4.0.tgz", + "integrity": "sha1-qZzZbqAAUlaEsmloOuIiLW7qe0k=", + "requires": { + "ipaddr.js": ">= 0.1.5" + } + }, "compare-versions": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-3.3.0.tgz", @@ -2513,8 +2815,7 @@ "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, "concat-stream": { "version": "1.6.2", @@ -2578,8 +2879,7 @@ "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, "cpx": { "version": "1.5.0", @@ -2637,6 +2937,34 @@ "sha.js": "^2.4.8" } }, + "create-torrent": { + "version": "3.32.1", + "resolved": "https://registry.npmjs.org/create-torrent/-/create-torrent-3.32.1.tgz", + "integrity": "sha512-8spZUeFyVc+2mGnWBRTuLOhuHmHrmUomFWf7QvxztCEvTpn5SIrvF8F+HKdkzBPM9B7v/2w+f/65jqLWBXSndg==", + "requires": { + "bencode": "^2.0.0", + "block-stream2": "^1.0.0", + "filestream": "^4.0.0", + "flatten": "^1.0.2", + "is-file": "^1.0.0", + "junk": "^2.1.0", + "minimist": "^1.1.0", + "multistream": "^2.0.2", + "once": "^1.3.0", + "piece-length": "^1.0.0", + "readable-stream": "^2.0.5", + "run-parallel": "^1.0.0", + "simple-sha1": "^2.0.0", + "xtend": "^4.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + } + } + }, "cross-spawn": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", @@ -2892,6 +3220,19 @@ "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", "dev": true }, + "decompress-response": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", + "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", + "requires": { + "mimic-response": "^1.0.0" + } + }, + "deep-diff": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/deep-diff/-/deep-diff-0.3.8.tgz", + "integrity": "sha1-wB3mPvsO7JeYgB1Ax+Da4ltYLIQ=" + }, "deep-is": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", @@ -2967,8 +3308,7 @@ "defined": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", - "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=", - "dev": true + "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=" }, "delayed-stream": { "version": "1.0.0", @@ -3193,7 +3533,6 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", - "dev": true, "requires": { "once": "^1.4.0" } @@ -3731,6 +4070,17 @@ "minimatch": "^3.0.3" } }, + "filestream": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/filestream/-/filestream-4.1.3.tgz", + "integrity": "sha1-lI/KregiH3FfXsrdxUhi+qrMkyU=", + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.5", + "typedarray-to-buffer": "^3.0.0", + "xtend": "^4.0.1" + } + }, "fill-range": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", @@ -3783,8 +4133,7 @@ "flatten": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.2.tgz", - "integrity": "sha1-2uRqnXj74lKSJYzB54CkHZXAN4I=", - "dev": true + "integrity": "sha1-2uRqnXj74lKSJYzB54CkHZXAN4I=" }, "flush-write-stream": { "version": "1.0.3", @@ -3849,6 +4198,11 @@ "map-cache": "^0.2.2" } }, + "freelist": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/freelist/-/freelist-1.0.3.tgz", + "integrity": "sha1-AGd1UJ85NXAXhNPtL8nxLJ3xurI=" + }, "from2": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", @@ -3859,6 +4213,19 @@ "readable-stream": "^2.0.0" } }, + "fs-chunk-store": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/fs-chunk-store/-/fs-chunk-store-1.7.0.tgz", + "integrity": "sha512-KhjJmZAs2eqfhCb6PdPx4RcZtheGTz86tpTC5JTvqBn/xda+Nb+0C7dCyjOSN7T76H6a56LvH0SVXQMchLXDRw==", + "requires": { + "mkdirp": "^0.5.1", + "random-access-file": "^2.0.1", + "randombytes": "^2.0.3", + "rimraf": "^2.4.2", + "run-parallel": "^1.1.2", + "thunky": "^1.0.1" + } + }, "fs-extra": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-6.0.1.tgz", @@ -3885,8 +4252,7 @@ "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, "fsevents": { "version": "1.2.4", @@ -4434,12 +4800,22 @@ "is-callable": "^1.1.3" } }, + "get-browser-rtc": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-browser-rtc/-/get-browser-rtc-1.0.2.tgz", + "integrity": "sha1-u81AyEUaftTvXDc7gWmkCd0dEdk=" + }, "get-caller-file": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", "dev": true }, + "get-stdin": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", + "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==" + }, "get-stream": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", @@ -4465,7 +4841,6 @@ "version": "7.1.2", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -4748,6 +5123,20 @@ "readable-stream": "^2.0.2" } }, + "http-node": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-node/-/http-node-1.2.0.tgz", + "integrity": "sha1-Yfn6wajFb/XOOJwv1Qnl/RvucEM=", + "requires": { + "freelist": "^1.0.3", + "http-parser-js": "^0.4.3" + } + }, + "http-parser-js": { + "version": "0.4.13", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.13.tgz", + "integrity": "sha1-O9bW/ebjFyyTNMOzO2wZPYD+ETc=" + }, "http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", @@ -4871,6 +5260,11 @@ "dev": true, "optional": true }, + "immediate-chunk-store": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/immediate-chunk-store/-/immediate-chunk-store-2.0.0.tgz", + "integrity": "sha512-5s6NiCGbtWc+OQA60jrre54w12U7tynIyUNjO5LJjNA5lWwvCv6640roq8Wk/wIuaqnd4Pgtp453OyJ7hbONkQ==" + }, "import-local": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/import-local/-/import-local-1.0.0.tgz", @@ -4903,7 +5297,6 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, "requires": { "once": "^1.3.0", "wrappy": "1" @@ -4912,8 +5305,7 @@ "inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" }, "inquirer": { "version": "6.0.0", @@ -5009,6 +5401,24 @@ "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", "dev": true }, + "ip": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", + "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=" + }, + "ip-set": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ip-set/-/ip-set-1.0.1.tgz", + "integrity": "sha1-Yztm0L1sjQ3paNBTJjyRINO2cn4=", + "requires": { + "ip": "^1.1.3" + } + }, + "ipaddr.js": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.8.1.tgz", + "integrity": "sha1-+kt5+kf9Pe9eOxWYJRYcClGclCc=" + }, "is-absolute-url": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-2.1.0.tgz", @@ -5030,6 +5440,11 @@ "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", "dev": true }, + "is-ascii": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-ascii/-/is-ascii-1.0.0.tgz", + "integrity": "sha1-8CrQJZoJIc0Zn/Ic4bCeD2tOOSk=" + }, "is-binary-path": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", @@ -5136,6 +5551,11 @@ "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", "dev": true }, + "is-file": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-file/-/is-file-1.0.0.tgz", + "integrity": "sha1-KKRM+9nT2xkwRfIrZfzo7fliBZY=" + }, "is-finite": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", @@ -5259,8 +5679,7 @@ "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" }, "is-utf8": { "version": "0.2.1", @@ -5277,8 +5696,7 @@ "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" }, "isexe": { "version": "2.0.0", @@ -6308,8 +6726,7 @@ "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, "js-yaml": { "version": "3.7.0", @@ -6433,6 +6850,42 @@ "verror": "1.10.0" } }, + "junk": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/junk/-/junk-2.1.0.tgz", + "integrity": "sha1-9DG0t/By3FAKXxDOf07HGTDnATQ=" + }, + "k-bucket": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/k-bucket/-/k-bucket-4.0.1.tgz", + "integrity": "sha512-YvDpmY3waI999h1zZoW1rJ04fZrgZ+5PAlVmvwDHT6YO/Q1AOhdel07xsKy9eAvJjQ9xZV1wz3rXKqEfaWvlcQ==", + "requires": { + "inherits": "^2.0.1", + "randombytes": "^2.0.3" + } + }, + "k-rpc": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/k-rpc/-/k-rpc-5.0.0.tgz", + "integrity": "sha512-vCH2rQdfMOS+MlUuTSuar1pS2EMrltURf9LmAR9xR6Jik0XPlMX3vEixgqMn17wKmFVCublJqSJ4hJIP7oKZ3Q==", + "requires": { + "buffer-equals": "^1.0.3", + "k-bucket": "^4.0.0", + "k-rpc-socket": "^1.7.2", + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.1" + } + }, + "k-rpc-socket": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/k-rpc-socket/-/k-rpc-socket-1.8.0.tgz", + "integrity": "sha512-f/9TynsO8YYjZ6JjNNtSSH7CJcIHcio1buy3zqByGxb/GX8AWLdL6FZEWTrN8V3/J7W4/E0ZTQQ+Jt2rVq7ELg==", + "requires": { + "bencode": "^2.0.0", + "buffer-equals": "^1.0.4", + "safe-buffer": "^5.1.1" + } + }, "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", @@ -6448,6 +6901,11 @@ "integrity": "sha512-Zq/jyANIJ2uX8UZjWlqLwbyhcxSXJtT/Y89lClyeZd3l++3ztL1I5SSCYrbcbwSunTjC88N3WuMk0kRDQD6gzA==", "dev": true }, + "last-one-wins": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/last-one-wins/-/last-one-wins-1.0.4.tgz", + "integrity": "sha1-wb/Qy8tGeQ7JFWuNGu6Py4bNoio=" + }, "lazy-cache": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", @@ -6530,6 +6988,18 @@ "type-check": "~0.3.2" } }, + "load-ip-set": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/load-ip-set/-/load-ip-set-2.1.0.tgz", + "integrity": "sha512-taz7U6B+F7Zq90dfIKwqsB1CrFKelSEmMGC68OUqem8Cgd1QZygQBYb2Fk9i6muBSfH4xwF/Pjt4KKlAdOyWZw==", + "requires": { + "ip-set": "^1.0.0", + "netmask": "^1.0.6", + "once": "^1.3.0", + "simple-get": "^3.0.0", + "split": "^1.0.0" + } + }, "load-json-file": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", @@ -6590,14 +7060,12 @@ "lodash": { "version": "4.17.10", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", - "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", - "dev": true + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==" }, "lodash-es": { "version": "4.17.10", "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.10.tgz", - "integrity": "sha512-iesFYPmxYYGTcmQK0sL8bX3TGHyM6b2qREaB4kamHfQyfPJP0xgoGxp19nsH16nsfquLdiyKyX3mQkfiSGV8Rg==", - "dev": true + "integrity": "sha512-iesFYPmxYYGTcmQK0sL8bX3TGHyM6b2qREaB4kamHfQyfPJP0xgoGxp19nsH16nsfquLdiyKyX3mQkfiSGV8Rg==" }, "lodash.camelcase": { "version": "4.3.0", @@ -6651,11 +7119,18 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "dev": true, "requires": { "js-tokens": "^3.0.0 || ^4.0.0" } }, + "lru": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/lru/-/lru-3.1.0.tgz", + "integrity": "sha1-6n+4VG2DczOWoTCR12z+tMBoN9U=", + "requires": { + "inherits": "^2.0.1" + } + }, "lru-cache": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz", @@ -6666,8 +7141,18 @@ "yallist": "^2.1.2" } }, - "make-dir": { - "version": "1.3.0", + "magnet-uri": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/magnet-uri/-/magnet-uri-5.2.3.tgz", + "integrity": "sha512-INWVwcpWfZTVM+Yb4EXVBpm0FTd8Q98Fn5x7nuHv1hkFDRELgdIM+eJ3zYLbNTFpFPYtHs6B+sx8exs29IYwgA==", + "requires": { + "thirty-two": "^1.0.1", + "uniq": "^1.0.1", + "xtend": "^4.0.0" + } + }, + "make-dir": { + "version": "1.3.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", "dev": true, @@ -6727,6 +7212,16 @@ "inherits": "^2.0.1" } }, + "mediasource": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/mediasource/-/mediasource-2.2.2.tgz", + "integrity": "sha512-yIyAJMcu1mudTkxZ0jDAKnZJJba4eWPCxxtZRMpoaA4/AI7m7nqbRjmdxmi+x3hKTohb5vC9Yd3IBF/SUzp1vQ==", + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.5", + "to-arraybuffer": "^1.0.1" + } + }, "mem": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", @@ -6736,6 +7231,11 @@ "mimic-fn": "^1.0.0" } }, + "memory-chunk-store": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/memory-chunk-store/-/memory-chunk-store-1.3.0.tgz", + "integrity": "sha512-6LsOpHKKhxYrLhHmOJdBCUtSO7op5rUs1pag0fhjHo0QiXRyna0bwYf4EmQuL7InUeF2J7dUMPr6VMogRyf9NA==" + }, "memory-fs": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", @@ -6865,6 +7365,11 @@ "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", "dev": true }, + "mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==" + }, "minimalistic-assert": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", @@ -6881,7 +7386,6 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, "requires": { "brace-expansion": "^1.1.7" } @@ -6889,8 +7393,7 @@ "minimist": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" }, "mississippi": { "version": "2.0.0", @@ -6935,7 +7438,6 @@ "version": "0.5.1", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, "requires": { "minimist": "0.0.8" } @@ -6960,11 +7462,41 @@ "run-queue": "^1.0.3" } }, + "mp4-box-encoding": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/mp4-box-encoding/-/mp4-box-encoding-1.3.0.tgz", + "integrity": "sha512-U4pMLpjT/UzB8d36dxj6Mf1bG9xypEvgbuRIa1fztRXNKKTCAtRxsnFZhNOd7YDFOKtjBgssYGvo4H/Q3ZY1MA==", + "requires": { + "buffer-alloc": "^1.2.0", + "buffer-from": "^1.1.0", + "uint64be": "^2.0.2" + } + }, + "mp4-stream": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/mp4-stream/-/mp4-stream-2.0.3.tgz", + "integrity": "sha512-5NzgI0+bGakoZEwnIYINXqB3mnewkt3Y7jcvkXsTubnCNUSdM8cpP0Vemxf6FLg0qUN8fydTgNMVAc3QU8B92g==", + "requires": { + "buffer-alloc": "^1.1.0", + "inherits": "^2.0.1", + "mp4-box-encoding": "^1.1.0", + "next-event": "^1.0.0", + "readable-stream": "^2.0.3" + } + }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "multistream": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/multistream/-/multistream-2.1.1.tgz", + "integrity": "sha512-xasv76hl6nr1dEy3lPvy7Ej7K/Lx3O/FCvwge8PeVJpciPPoNCbaANcNiBug3IpdvTveZUcAV0DJzdnUDMesNQ==", + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.5" + } }, "mute-stream": { "version": "0.0.7", @@ -7031,6 +7563,16 @@ "integrity": "sha512-3KL3fvuRkZ7s4IFOMfztb7zJp3QaVWnBeGoJlgB38XnCRPj/0tLzzLG5IB8NYOHbJ8g8UGrgZv44GLDk6CxTxA==", "dev": true }, + "netmask": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/netmask/-/netmask-1.0.6.tgz", + "integrity": "sha1-ICl+idhvb2QA8lDZ9Pa0wZRfzTU=" + }, + "next-event": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/next-event/-/next-event-1.0.0.tgz", + "integrity": "sha1-53eKzeLlWALgrRh5w5z2917aYdg=" + }, "nice-try": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.4.tgz", @@ -7047,6 +7589,12 @@ "is-stream": "^1.0.1" } }, + "node-gyp-build": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-3.4.0.tgz", + "integrity": "sha512-YoviGBJYGrPdLOKDIQB0sKxuKy/EEsxzooNkOZak4vSTKT/qH0Pa6dj3t1MJjEQGsefih61IyHDmO1WW7xOFfw==", + "optional": true + }, "node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", @@ -7338,7 +7886,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, "requires": { "wrappy": "1" } @@ -7443,6 +7990,14 @@ "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", "dev": true }, + "package-json-versionify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/package-json-versionify/-/package-json-versionify-1.0.4.tgz", + "integrity": "sha1-WGBYepRIc6a35tJujlH/siMVvxc=", + "requires": { + "browserify-package-json": "^1.0.0" + } + }, "pako": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.6.tgz", @@ -7494,6 +8049,25 @@ "error-ex": "^1.2.0" } }, + "parse-numeric-range": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/parse-numeric-range/-/parse-numeric-range-0.0.2.tgz", + "integrity": "sha1-tPCdQTx6282Yf26SM8e0shDJOOQ=" + }, + "parse-torrent": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/parse-torrent/-/parse-torrent-6.1.1.tgz", + "integrity": "sha512-VOQseFSgXOJE1tnwLJHA6GAILC62GaXRtoCkf3cOiTxMt2P/Xjz1Oe6TVJB7BCm4WkgOY7QS22bjqA7Z4ryuJA==", + "requires": { + "bencode": "^2.0.0", + "blob-to-buffer": "^1.2.6", + "get-stdin": "^6.0.0", + "magnet-uri": "^5.1.3", + "simple-get": "^3.0.1", + "simple-sha1": "^2.0.0", + "uniq": "^1.0.1" + } + }, "parse5": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/parse5/-/parse5-3.0.3.tgz", @@ -7530,8 +8104,7 @@ "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" }, "path-key": { "version": "2.0.1", @@ -7583,6 +8156,14 @@ "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", "dev": true }, + "piece-length": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/piece-length/-/piece-length-1.0.0.tgz", + "integrity": "sha1-TbcWcVf9af7xTK9yYs058YmyRQg=", + "requires": { + "closest-to": "~2.0.0" + } + }, "pify": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", @@ -8204,6 +8785,11 @@ "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", "dev": true }, + "prettier-bytes": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/prettier-bytes/-/prettier-bytes-1.0.4.tgz", + "integrity": "sha1-mUsCqkb2mcULYle1+qp/4lV+YtY=" + }, "pretty-format": { "version": "23.2.0", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-23.2.0.tgz", @@ -8246,8 +8832,7 @@ "process-nextick-args": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", - "dev": true + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" }, "promise": { "version": "7.3.1", @@ -8401,6 +8986,28 @@ "ret": "~0.1.10" } }, + "random-access-file": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/random-access-file/-/random-access-file-2.0.1.tgz", + "integrity": "sha512-nb4fClpzoUY+v1SHrro+9yykN90eMA1rc+xM39tnZ5R3BgFY+J/NxPZ0KuUpishEsvnwou9Fvm2wa3cjeuG7vg==", + "requires": { + "mkdirp": "^0.5.1", + "random-access-storage": "^1.1.1" + } + }, + "random-access-storage": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/random-access-storage/-/random-access-storage-1.3.0.tgz", + "integrity": "sha512-pdS9Mcb9TB7oICypPRALlheaSuszuAKmLVEPKJMuYor7R/zDuHh5ALuQoS+ox31XRwQUL+tDwWH2GPdyspwelA==", + "requires": { + "inherits": "^2.0.3" + } + }, + "random-iterate": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/random-iterate/-/random-iterate-1.0.1.tgz", + "integrity": "sha1-99l9kt7mZl7F9toIx/ljytSyrJk=" + }, "randomatic": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.0.0.tgz", @@ -8430,7 +9037,6 @@ "version": "2.0.6", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.6.tgz", "integrity": "sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A==", - "dev": true, "requires": { "safe-buffer": "^5.1.0" } @@ -8445,6 +9051,20 @@ "safe-buffer": "^5.1.0" } }, + "range-parser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", + "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=" + }, + "range-slice-stream": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/range-slice-stream/-/range-slice-stream-1.2.0.tgz", + "integrity": "sha1-AbqVQnYFK3g5AOY9YRjY/POHXX8=", + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.5" + } + }, "react": { "version": "16.4.1", "resolved": "https://registry.npmjs.org/react/-/react-16.4.1.tgz", @@ -8457,6 +9077,28 @@ "prop-types": "^15.6.0" } }, + "react-chrome-redux": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/react-chrome-redux/-/react-chrome-redux-1.5.1.tgz", + "integrity": "sha1-ucbVamg+cexeEDp1/JKVnovqE9s=", + "requires": { + "lodash": "^4.5.1", + "redux": "^3.7.2" + }, + "dependencies": { + "redux": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/redux/-/redux-3.7.2.tgz", + "integrity": "sha512-pNqnf9q1hI5HHZRBkj3bAngGZW/JMCmexDlOxw4XagXY2o1327nHH54LoTjiPJ0gizoqPDRqWyX/00g0hD6w+A==", + "requires": { + "lodash": "^4.2.1", + "lodash-es": "^4.2.1", + "loose-envify": "^1.1.0", + "symbol-observable": "^1.0.3" + } + } + } + }, "react-dnd": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/react-dnd/-/react-dnd-5.0.0.tgz", @@ -8591,7 +9233,6 @@ "version": "2.3.6", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -8637,6 +9278,11 @@ "symbol-observable": "^1.0.4" } }, + "record-cache": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/record-cache/-/record-cache-1.1.0.tgz", + "integrity": "sha512-u8rbtLEJV7HRacl/ZYwSBFD8NFyB3PfTTfGLP37IW3hftQCwu6z4Q2RLyxo1YJUNRTEzJfpLpGwVuEYdaIkG9Q==" + }, "reduce-css-calc": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/reduce-css-calc/-/reduce-css-calc-1.3.0.tgz", @@ -8683,6 +9329,14 @@ "symbol-observable": "^1.2.0" } }, + "redux-logger": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/redux-logger/-/redux-logger-3.0.6.tgz", + "integrity": "sha1-91VZZvMJjzyIYExEnPC69XeCdL8=", + "requires": { + "deep-diff": "^0.3.5" + } + }, "regenerate": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", @@ -8765,6 +9419,28 @@ "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", "dev": true }, + "render-media": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/render-media/-/render-media-3.1.3.tgz", + "integrity": "sha512-K7ziKKlIcgYpAovRsABDiSaNn7TzDDyyuFGpRwM52cloNcajInB6sCxFPUEzOuTJUeyvKCqT/k5INOjpKLCjhQ==", + "requires": { + "debug": "^3.1.0", + "is-ascii": "^1.0.0", + "mediasource": "^2.1.0", + "stream-to-blob-url": "^2.0.0", + "videostream": "^2.5.1" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + } + } + }, "repeat-element": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz", @@ -8920,7 +9596,6 @@ "version": "2.6.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", - "dev": true, "requires": { "glob": "^7.0.5" } @@ -8960,6 +9635,16 @@ "is-promise": "^2.1.0" } }, + "run-parallel": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz", + "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==" + }, + "run-parallel-limit": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/run-parallel-limit/-/run-parallel-limit-1.0.5.tgz", + "integrity": "sha512-NsY+oDngvrvMxKB3G8ijBzIema6aYbQMD2bHOamvN52BysbIGTnEY2xsNyfrcr9GhY995/t/0nQN3R3oZvaDlg==" + }, "run-queue": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", @@ -8969,6 +9654,16 @@ "aproba": "^1.1.1" } }, + "run-series": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/run-series/-/run-series-1.1.8.tgz", + "integrity": "sha512-+GztYEPRpIsQoCSraWHDBs9WVy4eVME16zhOtDB4H9J4xN0XRhknnmLOl+4gRgZtu8dpp9N/utSPjKH/xmDzXg==" + }, + "rusha": { + "version": "0.8.13", + "resolved": "https://registry.npmjs.org/rusha/-/rusha-0.8.13.tgz", + "integrity": "sha1-mghOe4YLF7/zAVuSxnpqM2GRUTo=" + }, "rxjs": { "version": "6.2.2", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.2.2.tgz", @@ -8981,8 +9676,7 @@ "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, "safe-regex": { "version": "1.1.0", @@ -9175,6 +9869,81 @@ "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", "dev": true }, + "simple-concat": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.0.tgz", + "integrity": "sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY=" + }, + "simple-get": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.0.2.tgz", + "integrity": "sha512-dU3TBVIGkP5Hzw6o74hJx+VzTBTX2rqIiLfugs0HdmdVQCQp76XGg2jlBCqfRJfW/n6/mUKTi+s3rnzX7SgbBA==", + "requires": { + "decompress-response": "^3.3.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "simple-peer": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/simple-peer/-/simple-peer-9.1.2.tgz", + "integrity": "sha512-MUWWno5o5cvISKOH4pYQ18PQJLpDaNWoKUbrPPKuspCLCkkh+zhtuQyTE8h2U2Ags+/OUN5wnUe92+9B8/Sm2Q==", + "requires": { + "debug": "^3.1.0", + "get-browser-rtc": "^1.0.0", + "inherits": "^2.0.1", + "randombytes": "^2.0.3", + "readable-stream": "^2.3.4" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + } + } + }, + "simple-sha1": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/simple-sha1/-/simple-sha1-2.1.1.tgz", + "integrity": "sha512-pFMPd+I/lQkpf4wFUeS/sED5IqdIG1lUlrQviBMV4u4mz8BRAcB5fvUx5Ckfg3kBigEglAjHg7E9k/yy2KlCqA==", + "requires": { + "rusha": "^0.8.1" + } + }, + "simple-websocket": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/simple-websocket/-/simple-websocket-7.2.0.tgz", + "integrity": "sha512-wdxFg1fHw1yqFKWDcw+yNb4VIYqtl+vknZMlpLhvZSlR6l7/iVuwozqo+Qtl73mB1IH5QnXzonD1S+hAaLNTvQ==", + "requires": { + "debug": "^3.1.0", + "inherits": "^2.0.1", + "randombytes": "^2.0.3", + "readable-stream": "^2.0.5", + "ws": "^6.0.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "ws": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.0.0.tgz", + "integrity": "sha512-c2UlYcAZp1VS8AORtpq6y4RJIkJ9dQz18W32SpR/qXGfLDZ2jU4y4wKvvZwqbi7U6gxFQTeE+urMbXU/tsDy4w==", + "requires": { + "async-limiter": "~1.0.0" + } + } + } + }, "sisteransi": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-0.1.1.tgz", @@ -9370,6 +10139,19 @@ "integrity": "sha512-2+EPwgbnmOIl8HjGBXXMd9NAu02vLjOO1nWw4kmeRDFyHn+M/ETfHxQUK0oXg8ctgVnl9t3rosNVsZ1jG61nDA==", "dev": true }, + "speedometer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/speedometer/-/speedometer-1.1.0.tgz", + "integrity": "sha512-z/wAiTESw2XVPssY2XRcme4niTc4S5FkkJ4gknudtVoc33Zil8TdTxHy5torRcgqMqksJV2Yz8HQcvtbsnw0mQ==" + }, + "split": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", + "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", + "requires": { + "through": "2" + } + }, "split-string": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", @@ -9483,6 +10265,30 @@ "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=", "dev": true }, + "stream-to-blob": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/stream-to-blob/-/stream-to-blob-1.0.1.tgz", + "integrity": "sha512-aRy4neA4rf+qMtLT9fCRLPGWdrsIKtCx4kUdNTIPgPQ2hkHkdxbViVAvABMx9oRM6yCWfngHx6pwXfbYkVuPuw==", + "requires": { + "once": "^1.3.3" + } + }, + "stream-to-blob-url": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/stream-to-blob-url/-/stream-to-blob-url-2.1.1.tgz", + "integrity": "sha512-DKJPEmCmIZoBfGVle9IhSfERiWaN5cuOtmfPxP2dZbLDRZxkBWZ4QbYxEJOSALk1Kf+WjBgedAMO6qkkf7Lmrg==", + "requires": { + "stream-to-blob": "^1.0.0" + } + }, + "stream-with-known-length-to-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/stream-with-known-length-to-buffer/-/stream-with-known-length-to-buffer-1.0.2.tgz", + "integrity": "sha512-UxSISjxmguvfYzZdq6d4XAjc3gAocqTIOS1CjgwkDkkGT/LMTsIYiV8agIw42IHFFHf8k4lPOoroCCf4W9oqzg==", + "requires": { + "once": "^1.3.3" + } + }, "strict-uri-encode": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", @@ -9543,11 +10349,19 @@ } } }, + "string2compact": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string2compact/-/string2compact-1.3.0.tgz", + "integrity": "sha512-004ulKKANDuQilQsNxy2lisrpMG0qUJxBU+2YCEF7KziRyNR0Nredm2qk0f1V82nva59H3y9GWeHXE63HzGRFw==", + "requires": { + "addr-to-ip-port": "^1.0.1", + "ipaddr.js": "^1.0.1" + } + }, "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, "requires": { "safe-buffer": "~5.1.0" } @@ -9700,8 +10514,7 @@ "symbol-observable": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", - "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==", - "dev": true + "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==" }, "symbol-tree": { "version": "3.2.2", @@ -9757,17 +10570,26 @@ } } }, + "thirty-two": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/thirty-two/-/thirty-two-1.0.2.tgz", + "integrity": "sha1-TKL//AKlEpDSdEueP1V2k8prYno=" + }, "throat": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/throat/-/throat-4.1.0.tgz", "integrity": "sha1-iQN8vJLFarGJJua6TLsgDhVnKmo=", "dev": true }, + "throttleit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.0.tgz", + "integrity": "sha1-nnhYNtr0Z0MUWlmEtiaNgoUorGw=" + }, "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", - "dev": true + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" }, "through2": { "version": "2.0.3", @@ -9779,6 +10601,11 @@ "xtend": "~4.0.1" } }, + "thunky": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.0.2.tgz", + "integrity": "sha1-qGLgGOP7HqLsP85dVWBc9X8kc3E=" + }, "timers-browserify": { "version": "2.0.10", "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.10.tgz", @@ -9806,8 +10633,7 @@ "to-arraybuffer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", - "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", - "dev": true + "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=" }, "to-fast-properties": { "version": "1.0.3", @@ -9846,6 +10672,33 @@ "repeat-string": "^1.6.1" } }, + "torrent-discovery": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/torrent-discovery/-/torrent-discovery-9.0.2.tgz", + "integrity": "sha512-UpkOyi/QUXRAwts8vSsFu/jRQ1mwGkaqv2OxLTJGr4DJKCiXpLHZ1+A4rxabcOWinM9RiqmS5mAjDuFfPHiJvw==", + "requires": { + "bittorrent-dht": "^8.0.1", + "bittorrent-tracker": "^9.0.0", + "debug": "^3.1.0", + "run-parallel": "^1.1.2", + "xtend": "^4.0.1" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + } + } + }, + "torrent-piece": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/torrent-piece/-/torrent-piece-2.0.0.tgz", + "integrity": "sha512-H/Z/yCuvZJj1vl1IQHI8dvF2QrUuXRJoptT5DW5967/dsLpXlCg+uyhFR5lfNj5mNaYePUbKtnL+qKWZGXv4Nw==" + }, "tough-cookie": { "version": "2.4.3", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", @@ -10260,6 +11113,14 @@ "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", "dev": true }, + "typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "requires": { + "is-typedarray": "^1.0.0" + } + }, "typesafe-actions": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/typesafe-actions/-/typesafe-actions-2.0.4.tgz", @@ -10352,6 +11213,14 @@ } } }, + "uint64be": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/uint64be/-/uint64be-2.0.2.tgz", + "integrity": "sha512-9QqdvpGQTXgxthP+lY4e/gIBy+RuqcBaC6JVwT5I3bDLgT/btL6twZMR0pI3/Fgah9G/pdwzIprE5gL6v9UvyQ==", + "requires": { + "buffer-alloc": "^1.1.0" + } + }, "underscore": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.4.4.tgz", @@ -10396,8 +11265,7 @@ "uniq": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", - "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=", - "dev": true + "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=" }, "uniqs": { "version": "2.0.0", @@ -10429,6 +11297,11 @@ "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", "dev": true }, + "unordered-array-remove": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unordered-array-remove/-/unordered-array-remove-1.0.2.tgz", + "integrity": "sha1-xUbo+I4xegzyZEyX7LV9umbSUO8=" + }, "unset-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", @@ -10560,6 +11433,49 @@ "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", "dev": true }, + "ut_metadata": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/ut_metadata/-/ut_metadata-3.2.2.tgz", + "integrity": "sha512-PltK6kZ85DMscFl1gwyvOyja6UGROdyLI1ufWCTLsYnLfBaMyhtOEcbtgEgOwYEz8QuchR49qgHXTdJ2H05VHA==", + "requires": { + "bencode": "^2.0.0", + "bitfield": "^2.0.0", + "debug": "^3.1.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1", + "simple-sha1": "^2.0.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + } + } + }, + "ut_pex": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ut_pex/-/ut_pex-1.2.1.tgz", + "integrity": "sha512-ZrxMCbffYtxQDqvREN9kBXK2CB9tPnd5PylHoqQX9ai+3HV9/S39FnA5JnhLOC82dxIQQg0nTN2wmhtAdGNtOA==", + "requires": { + "bencode": "^2.0.0", + "compact2string": "^1.2.0", + "inherits": "^2.0.1", + "string2compact": "^1.2.5" + } + }, + "utf-8-validate": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.1.tgz", + "integrity": "sha512-Qef1AuiWWxQeZ1Oa4DTV3ArRafpZvsK+CLrlB8khLfsV+9mwhj58hNSGmel0ns5jYP+3yEwav6vxxW7Gz85bVw==", + "optional": true, + "requires": { + "node-gyp-build": "~3.4.0" + } + }, "util": { "version": "0.10.4", "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz", @@ -10572,8 +11488,7 @@ "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, "util.promisify": { "version": "1.0.0", @@ -10624,6 +11539,32 @@ "extsprintf": "^1.2.0" } }, + "videostream": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/videostream/-/videostream-2.5.1.tgz", + "integrity": "sha512-S3f34WE6NB1d/YUAa/EYcTURTkGaxsUqcDmsGWV1jQpQQJxeagc79/XA7ygNjzBf3DoQQ1MKTD+SocPsWSniAg==", + "requires": { + "binary-search": "^1.3.4", + "inherits": "^2.0.1", + "mediasource": "^2.0.0", + "mp4-box-encoding": "^1.3.0", + "mp4-stream": "^2.0.0", + "multistream": "^2.0.2", + "pump": "^3.0.0", + "range-slice-stream": "^1.2.0" + }, + "dependencies": { + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + } + } + }, "vm-browserify": { "version": "0.0.4", "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz", @@ -11007,6 +11948,80 @@ } } }, + "webtorrent": { + "version": "0.102.0", + "resolved": "https://registry.npmjs.org/webtorrent/-/webtorrent-0.102.0.tgz", + "integrity": "sha512-AyVAyshBctfefPFNSDKvyX3Fd/4bVhkaTQlug3/pVYeZRLxxGRsa4CmkPRK3Xl0elEcamcCjeleli0huJCmWyw==", + "requires": { + "addr-to-ip-port": "^1.4.2", + "bitfield": "^2.0.0", + "bittorrent-dht": "^8.0.0", + "bittorrent-protocol": "^3.0.0", + "chunk-store-stream": "^3.0.0", + "create-torrent": "^3.24.5", + "debug": "^3.1.0", + "end-of-stream": "^1.1.0", + "fs-chunk-store": "^1.6.2", + "immediate-chunk-store": "^2.0.0", + "inherits": "^2.0.1", + "load-ip-set": "^2.1.0", + "memory-chunk-store": "^1.2.0", + "mime": "^2.2.0", + "multistream": "^2.0.5", + "package-json-versionify": "^1.0.2", + "parse-numeric-range": "^0.0.2", + "parse-torrent": "^6.0.0", + "pump": "^3.0.0", + "random-iterate": "^1.0.1", + "randombytes": "^2.0.3", + "range-parser": "^1.2.0", + "readable-stream": "^2.1.4", + "render-media": "^3.0.0", + "run-parallel": "^1.1.6", + "run-parallel-limit": "^1.0.3", + "safe-buffer": "^5.0.1", + "simple-concat": "^1.0.0", + "simple-get": "^3.0.1", + "simple-peer": "^9.0.0", + "simple-sha1": "^2.0.8", + "speedometer": "^1.0.0", + "stream-to-blob": "^1.0.0", + "stream-to-blob-url": "^2.1.0", + "stream-with-known-length-to-buffer": "^1.0.0", + "torrent-discovery": "^9.0.2", + "torrent-piece": "^2.0.0", + "uniq": "^1.0.1", + "unordered-array-remove": "^1.0.2", + "ut_metadata": "^3.0.8", + "ut_pex": "^1.1.1", + "xtend": "^4.0.1", + "zero-fill": "^2.2.3" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "mime": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.3.1.tgz", + "integrity": "sha512-OEUllcVoydBHGN1z84yfQDimn58pZNNNXgZlHXSboxMlFvgI6MXSWpWKpFRra7H1HxpVhHTkrghfRW49k6yjeg==" + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + } + } + }, "whatwg-encoding": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.3.tgz", @@ -11125,8 +12140,7 @@ "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, "write-file-atomic": { "version": "2.3.0", @@ -11163,8 +12177,7 @@ "xtend": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", - "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", - "dev": true + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" }, "y18n": { "version": "3.2.1", @@ -11242,6 +12255,11 @@ "dev": true } } + }, + "zero-fill": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/zero-fill/-/zero-fill-2.2.3.tgz", + "integrity": "sha1-o97wa6XjmuZEhQu0yirUEStIVek=" } } } diff --git a/package.json b/package.json index 40f373b17a02..ae1b69f4c2a3 100644 --- a/package.json +++ b/package.json @@ -122,5 +122,18 @@ "url-loader": "^0.6.2", "webpack": "^4.16.0", "webpack-cli": "^3.0.8" + }, + "dependencies": { + "@types/redux-logger": "^3.0.6", + "@types/webtorrent": "^0.98.4", + "chrome-dgram": "^3.0.1", + "chrome-net": "^3.3.1", + "clipboard-copy": "^2.0.0", + "http-node": "^1.2.0", + "prettier-bytes": "^1.0.4", + "react-chrome-redux": "^1.5.1", + "redux-logger": "^3.0.6", + "throttleit": "^1.0.0", + "webtorrent": "^0.102.0" } } From 10e441400550696a57d15d304153e8756f33163d Mon Sep 17 00:00:00 2001 From: Jocelyn Liu Date: Wed, 8 Aug 2018 22:08:35 -0700 Subject: [PATCH 2/9] implement MagnetProtocolHandler --- net/BUILD.gn | 9 ++++ net/url_request/magnet_protocol_handler.cc | 43 +++++++++++++++++++ net/url_request/magnet_protocol_handler.h | 24 +++++++++++ patches/net-BUILD.gn.patch | 13 ++++++ ...quest-url_request_context_builder.cc.patch | 21 +++++++++ 5 files changed, 110 insertions(+) create mode 100644 net/BUILD.gn create mode 100644 net/url_request/magnet_protocol_handler.cc create mode 100644 net/url_request/magnet_protocol_handler.h create mode 100644 patches/net-BUILD.gn.patch create mode 100644 patches/net-url_request-url_request_context_builder.cc.patch diff --git a/net/BUILD.gn b/net/BUILD.gn new file mode 100644 index 000000000000..1537e800b91d --- /dev/null +++ b/net/BUILD.gn @@ -0,0 +1,9 @@ +source_set("net") { + sources = [ + "url_request/magnet_protocol_handler.cc", + "url_request/magnet_protocol_handler.h", + ] + deps = [ + "//net" + ] +} diff --git a/net/url_request/magnet_protocol_handler.cc b/net/url_request/magnet_protocol_handler.cc new file mode 100644 index 000000000000..afaf41951fbc --- /dev/null +++ b/net/url_request/magnet_protocol_handler.cc @@ -0,0 +1,43 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "brave/net/url_request/magnet_protocol_handler.h" + +#include "brave/common/network_constants.h" +#include "base/strings/string_util.h" +#include "net/base/escape.h" +#include "net/base/net_errors.h" +#include "net/url_request/url_request_error_job.h" +#include "net/url_request/url_request_redirect_job.h" + +MagnetProtocolHandler::MagnetProtocolHandler() { +} + +MagnetProtocolHandler::~MagnetProtocolHandler() { +} + +GURL MagnetProtocolHandler::TranslateURL(const GURL& url) const { + GURL extension_page_url( + "chrome-extension://lgjmpdmojkpocjcopdikifhejkkjglho/brave_webtorrent.html?%s"); + std::string translatedSpec(extension_page_url.spec()); + base::ReplaceFirstSubstringAfterOffset( + &translatedSpec, 0, "%s", + net::EscapeQueryParamValue(url.spec(), true)); + return GURL(translatedSpec); +} + +net::URLRequestJob* MagnetProtocolHandler::MaybeCreateJob( + net::URLRequest* request, net::NetworkDelegate* network_delegate) const { + + GURL translated_url(TranslateURL(request->url())); + if (!translated_url.is_valid()) { + return new net::URLRequestErrorJob( + request, network_delegate, net::ERR_INVALID_URL); + } + + return new net::URLRequestRedirectJob( + request, network_delegate, translated_url, + net::URLRequestRedirectJob::REDIRECT_307_TEMPORARY_REDIRECT, + "WebTorrent"); +} diff --git a/net/url_request/magnet_protocol_handler.h b/net/url_request/magnet_protocol_handler.h new file mode 100644 index 000000000000..25d80732a965 --- /dev/null +++ b/net/url_request/magnet_protocol_handler.h @@ -0,0 +1,24 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef BRAVE_NET_URL_REQUEST_MAGNET_PROTOCOL_HANDLER_H_ +#define BRAVE_NET_URL_REQUEST_MAGNET_PROTOCOL_HANDLER_H_ + +#include "net/url_request/url_request_job_factory.h" + +class MagnetProtocolHandler : public net::URLRequestJobFactory::ProtocolHandler { + public: + MagnetProtocolHandler(); + ~MagnetProtocolHandler() override; + + net::URLRequestJob* MaybeCreateJob( + net::URLRequest* request, + net::NetworkDelegate* network_delegate) const override; + + private: + GURL TranslateURL(const GURL& url) const; + DISALLOW_COPY_AND_ASSIGN(MagnetProtocolHandler); +}; + +#endif // BRAVE_NET_URL_REQUEST_MAGNET_PROTOCOL_HANDLER_H_ diff --git a/patches/net-BUILD.gn.patch b/patches/net-BUILD.gn.patch new file mode 100644 index 000000000000..48bd1cea4d48 --- /dev/null +++ b/patches/net-BUILD.gn.patch @@ -0,0 +1,13 @@ +diff --git a/net/BUILD.gn b/net/BUILD.gn +index 7f9901a8826ce131181b3febdef9b911bae23d12..065e37608dad0cea7903830bab956903463441bb 100644 +--- a/net/BUILD.gn ++++ b/net/BUILD.gn +@@ -1713,6 +1713,8 @@ component("net") { + "url_request/view_cache_helper.h", + "url_request/websocket_handshake_userdata_key.cc", + "url_request/websocket_handshake_userdata_key.h", ++ "//brave/net/url_request/magnet_protocol_handler.cc", ++ "//brave/net/url_request/magnet_protocol_handler.h", + ] + + if (enable_reporting) { diff --git a/patches/net-url_request-url_request_context_builder.cc.patch b/patches/net-url_request-url_request_context_builder.cc.patch new file mode 100644 index 000000000000..7b7b01e423ad --- /dev/null +++ b/patches/net-url_request-url_request_context_builder.cc.patch @@ -0,0 +1,21 @@ +diff --git a/net/url_request/url_request_context_builder.cc b/net/url_request/url_request_context_builder.cc +index 800515a58cfa8546288d961fc9d14ae4676fcb5f..370dad80825d373f9fe1284adeb69e920ba86aa9 100644 +--- a/net/url_request/url_request_context_builder.cc ++++ b/net/url_request/url_request_context_builder.cc +@@ -14,6 +14,7 @@ + #include "base/single_thread_task_runner.h" + #include "base/strings/string_util.h" + #include "base/task_scheduler/post_task.h" ++#include "brave/net/url_request/magnet_protocol_handler.h" + #include "net/base/cache_type.h" + #include "net/base/net_errors.h" + #include "net/base/network_delegate_impl.h" +@@ -621,6 +622,8 @@ std::unique_ptr URLRequestContextBuilder::Build() { + } + #endif // !BUILDFLAG(DISABLE_FTP_SUPPORT) + ++ job_factory->SetProtocolHandler("magnet", std::make_unique()); ++ + std::unique_ptr top_job_factory(job_factory); + if (!url_request_interceptors_.empty()) { + // Set up interceptors in the reverse order. From c6bdc63edc167e251a2f9f8bdb08ea8b57b092db Mon Sep 17 00:00:00 2001 From: Jocelyn Liu Date: Mon, 13 Aug 2018 09:30:59 -0700 Subject: [PATCH 3/9] expose sockets API to webtorrent ext --- common/extensions/api/BUILD.gn | 1 + common/extensions/api/_api_features.json | 17 ++++++++++++++++- common/extensions/api/_manifest_features.json | 10 ++++++++++ ...on_schema_compiler-feature_compiler.py.patch | 8 ++++++-- 4 files changed, 33 insertions(+), 3 deletions(-) create mode 100644 common/extensions/api/_manifest_features.json diff --git a/common/extensions/api/BUILD.gn b/common/extensions/api/BUILD.gn index 312d2fda535d..d32f5769b4e5 100644 --- a/common/extensions/api/BUILD.gn +++ b/common/extensions/api/BUILD.gn @@ -26,6 +26,7 @@ json_features("manifest_features") { sources = [ "//chrome/common/extensions/api/_manifest_features.json", "//extensions/common/api/_manifest_features.json", + "_manifest_features.json", ] } diff --git a/common/extensions/api/_api_features.json b/common/extensions/api/_api_features.json index 124160009744..0c4f663ed00a 100644 --- a/common/extensions/api/_api_features.json +++ b/common/extensions/api/_api_features.json @@ -48,5 +48,20 @@ "matches": [ "chrome://newtab/*" ] - }] + }], + "sockets.tcp": { + "dependencies": ["manifest:sockets"], + "contexts": ["blessed_extension"], + "whitelist": ["3D9518A72EB02667A773B69DBA9E72E0F4A37423"] + }, + "sockets.tcpServer": { + "dependencies": ["manifest:sockets"], + "contexts": ["blessed_extension"], + "whitelist": ["3D9518A72EB02667A773B69DBA9E72E0F4A37423"] + }, + "sockets.udp": { + "dependencies": ["manifest:sockets"], + "contexts": ["blessed_extension"], + "whitelist": ["3D9518A72EB02667A773B69DBA9E72E0F4A37423"] + } } diff --git a/common/extensions/api/_manifest_features.json b/common/extensions/api/_manifest_features.json new file mode 100644 index 000000000000..b9a201d17a40 --- /dev/null +++ b/common/extensions/api/_manifest_features.json @@ -0,0 +1,10 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +{ + "sockets": { + "channel": "stable", + "extension_types": ["extension", "platform_app"] + } +} diff --git a/patches/tools-json_schema_compiler-feature_compiler.py.patch b/patches/tools-json_schema_compiler-feature_compiler.py.patch index 731997ec7c45..dd9f932c0943 100644 --- a/patches/tools-json_schema_compiler-feature_compiler.py.patch +++ b/patches/tools-json_schema_compiler-feature_compiler.py.patch @@ -1,14 +1,18 @@ diff --git a/tools/json_schema_compiler/feature_compiler.py b/tools/json_schema_compiler/feature_compiler.py -index fbfcf575a59d33ca311b0feb526a62dafbbdbd0a..02b369286e05a1724c8b90f383ad1bba47e281f0 100644 +index fbfcf575a59d33ca311b0feb526a62dafbbdbd0a..7af070c9e0166c50f2991402742cb31228b74af1 100644 --- a/tools/json_schema_compiler/feature_compiler.py +++ b/tools/json_schema_compiler/feature_compiler.py -@@ -647,6 +647,9 @@ class FeatureCompiler(object): +@@ -647,6 +647,13 @@ class FeatureCompiler(object): abs_source_file) raise dupes = set(f_json) & set(self._json) + dupes.discard('topSites') + dupes.discard('extension.inIncognitoContext') + dupes.discard('bookmarks') ++ dupes.discard('sockets') ++ dupes.discard('sockets.tcp') ++ dupes.discard('sockets.udp') ++ dupes.discard('sockets.tcpServer') assert not dupes, 'Duplicate keys found: %s' % list(dupes) self._json.update(f_json) From 353bf79e546490cd79ee639fa98c616def1f148f Mon Sep 17 00:00:00 2001 From: Jocelyn Liu Date: Mon, 6 Aug 2018 21:55:52 -0700 Subject: [PATCH 4/9] webtorrent component extension implementation --- .gitignore | 3 +- browser/extensions/brave_component_loader.cc | 5 + .../extensions/brave_extension_provider.cc | 4 +- browser/resources/BUILD.gn | 1 + browser/resources/brave_extension.grd | 5 + browser/resources/brave_webtorrent/BUILD.gn | 22 ++ .../brave_webtorrent/actions/tab_actions.ts | 25 ++ .../actions/webtorrent_actions.ts | 16 ++ .../actions/window_actions.ts | 20 ++ .../resources/brave_webtorrent/background.ts | 10 + .../background/actions/tabActions.ts | 8 + .../background/actions/webtorrentActions.ts | 8 + .../background/actions/windowActions.ts | 8 + .../background/events/tabsEvents.ts | 21 ++ .../background/events/torrentEvents.ts | 41 ++++ .../background/events/webtorrentEvents.ts | 11 + .../background/events/windowsEvents.ts | 17 ++ .../background/reducers/index.ts | 13 ++ .../background/reducers/webtorrent_reducer.ts | 221 ++++++++++++++++++ .../brave_webtorrent/background/store.ts | 33 +++ .../brave_webtorrent/background/webtorrent.ts | 57 +++++ .../brave_webtorrent/brave_webtorrent.html | 14 ++ .../brave_webtorrent/brave_webtorrent.tsx | 30 +++ .../brave_webtorrent/components/app.tsx | 73 ++++++ .../components/mediaViewer.tsx | 72 ++++++ .../components/torrentFileList.tsx | 94 ++++++++ .../components/torrentStatus.tsx | 102 ++++++++ .../components/torrentViewer.tsx | 53 +++++ .../components/torrentViewerFooter.tsx | 43 ++++ .../components/torrentViewerHeader.tsx | 72 ++++++ .../brave_webtorrent/constants/tab_types.ts | 10 + .../brave_webtorrent/constants/theme.ts | 17 ++ .../constants/webtorrentState.ts | 74 ++++++ .../constants/webtorrent_types.ts | 11 + .../constants/window_types.ts | 9 + .../resources/brave_webtorrent/manifest.json | 24 ++ common/extensions/api/_manifest_features.json | 3 +- common/extensions/extension_constants.cc | 1 + common/extensions/extension_constants.h | 1 + components/definitions/prettier-bytes.d.ts | 5 + components/definitions/throttleit.d.ts | 5 + .../resources/brave_components_resources.grd | 1 + components/styles/webtorrent.less | 16 ++ components/webpack/dev.config.js | 13 +- components/webpack/prod.config.js | 13 +- ...nt_extensions_whitelist-whitelist.cc.patch | 5 +- script/build-brave-webtorrent.py | 51 ++++ tsconfig.json | 3 +- 48 files changed, 1354 insertions(+), 10 deletions(-) create mode 100644 browser/resources/brave_webtorrent/BUILD.gn create mode 100644 browser/resources/brave_webtorrent/actions/tab_actions.ts create mode 100644 browser/resources/brave_webtorrent/actions/webtorrent_actions.ts create mode 100644 browser/resources/brave_webtorrent/actions/window_actions.ts create mode 100644 browser/resources/brave_webtorrent/background.ts create mode 100644 browser/resources/brave_webtorrent/background/actions/tabActions.ts create mode 100644 browser/resources/brave_webtorrent/background/actions/webtorrentActions.ts create mode 100644 browser/resources/brave_webtorrent/background/actions/windowActions.ts create mode 100644 browser/resources/brave_webtorrent/background/events/tabsEvents.ts create mode 100644 browser/resources/brave_webtorrent/background/events/torrentEvents.ts create mode 100644 browser/resources/brave_webtorrent/background/events/webtorrentEvents.ts create mode 100644 browser/resources/brave_webtorrent/background/events/windowsEvents.ts create mode 100644 browser/resources/brave_webtorrent/background/reducers/index.ts create mode 100644 browser/resources/brave_webtorrent/background/reducers/webtorrent_reducer.ts create mode 100644 browser/resources/brave_webtorrent/background/store.ts create mode 100644 browser/resources/brave_webtorrent/background/webtorrent.ts create mode 100644 browser/resources/brave_webtorrent/brave_webtorrent.html create mode 100644 browser/resources/brave_webtorrent/brave_webtorrent.tsx create mode 100644 browser/resources/brave_webtorrent/components/app.tsx create mode 100644 browser/resources/brave_webtorrent/components/mediaViewer.tsx create mode 100644 browser/resources/brave_webtorrent/components/torrentFileList.tsx create mode 100644 browser/resources/brave_webtorrent/components/torrentStatus.tsx create mode 100644 browser/resources/brave_webtorrent/components/torrentViewer.tsx create mode 100644 browser/resources/brave_webtorrent/components/torrentViewerFooter.tsx create mode 100644 browser/resources/brave_webtorrent/components/torrentViewerHeader.tsx create mode 100644 browser/resources/brave_webtorrent/constants/tab_types.ts create mode 100644 browser/resources/brave_webtorrent/constants/theme.ts create mode 100644 browser/resources/brave_webtorrent/constants/webtorrentState.ts create mode 100644 browser/resources/brave_webtorrent/constants/webtorrent_types.ts create mode 100644 browser/resources/brave_webtorrent/constants/window_types.ts create mode 100644 browser/resources/brave_webtorrent/manifest.json create mode 100644 components/definitions/prettier-bytes.d.ts create mode 100644 components/definitions/throttleit.d.ts create mode 100644 components/styles/webtorrent.less create mode 100755 script/build-brave-webtorrent.py diff --git a/.gitignore b/.gitignore index f36f431cd3d5..5c160e9e6533 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ .tags* /.idea/ /browser/resources/brave_extension/ +/browser/resources/brave_webtorrent/*.bundle.js /dist/ /out/ /vendor/requests @@ -39,4 +40,4 @@ npm-debug.log *~ CMakeLists.txt cmake-build-debug/ -coverage/ \ No newline at end of file +coverage/ diff --git a/browser/extensions/brave_component_loader.cc b/browser/extensions/brave_component_loader.cc index b1966688c122..5dcccbb9c393 100644 --- a/browser/extensions/brave_component_loader.cc +++ b/browser/extensions/brave_component_loader.cc @@ -33,6 +33,11 @@ void BraveComponentLoader::AddDefaultComponentExtensions( brave_extension_path.Append(FILE_PATH_LITERAL("brave_extension")); Add(IDR_BRAVE_EXTENSON, brave_extension_path); } + + base::FilePath brave_webtorrent_path(FILE_PATH_LITERAL("")); + brave_webtorrent_path = + brave_webtorrent_path.Append(FILE_PATH_LITERAL("brave_webtorrent")); + Add(IDR_BRAVE_WEBTORRENT, brave_webtorrent_path); } } // namespace extensions diff --git a/browser/extensions/brave_extension_provider.cc b/browser/extensions/brave_extension_provider.cc index 4426f00f0e6e..561140721eff 100644 --- a/browser/extensions/brave_extension_provider.cc +++ b/browser/extensions/brave_extension_provider.cc @@ -22,6 +22,7 @@ bool IsWhitelisted(const extensions::Extension* extension) { } static std::vector whitelist({ brave_extension_id, + brave_webtorrent_extension_id, pdfjs_extension_id, // 1Password "aomjjhallfgjeglblehebfpbcfeobpgk", @@ -126,7 +127,8 @@ bool BraveExtensionProvider::UserMayLoad(const Extension* extension, bool BraveExtensionProvider::MustRemainInstalled(const Extension* extension, base::string16* error) const { - return extension->id() == brave_extension_id; + return extension->id() == brave_extension_id || + extension->id() == brave_webtorrent_extension_id; } } // namespace extensions diff --git a/browser/resources/BUILD.gn b/browser/resources/BUILD.gn index e8dbfc5d7af8..134b98e8fd07 100644 --- a/browser/resources/BUILD.gn +++ b/browser/resources/BUILD.gn @@ -19,6 +19,7 @@ grit("brave_extension_grit") { deps = [ "//brave/vendor/brave-extension", + "//brave/browser/resources/brave_webtorrent", ] output_dir = "$target_gen_dir" diff --git a/browser/resources/brave_extension.grd b/browser/resources/brave_extension.grd index e2157bbc4967..354aa93b8467 100644 --- a/browser/resources/brave_extension.grd +++ b/browser/resources/brave_extension.grd @@ -20,6 +20,11 @@ + + + + + diff --git a/browser/resources/brave_webtorrent/BUILD.gn b/browser/resources/brave_webtorrent/BUILD.gn new file mode 100644 index 000000000000..ad89a03e79a1 --- /dev/null +++ b/browser/resources/brave_webtorrent/BUILD.gn @@ -0,0 +1,22 @@ +import("//tools/grit/grit_rule.gni") + +action("brave_webtorrent") { + script = "//brave/script/build-brave-webtorrent.py" + inputs = [ + "background.ts", + "brave_webtorrent.tsx", + ] + outputs = [ + "$target_out_dir/brave_webtorrent_background.bundle.js", + "$target_out_dir/brave_webtorrent.bundle.js", + ] + gen_dir = rebase_path(root_gen_dir, "//") + args = [ + "--target_gen_dir=$gen_dir" + ] + if (is_official_build) { + args += [ + "--production", + ] + } +} diff --git a/browser/resources/brave_webtorrent/actions/tab_actions.ts b/browser/resources/brave_webtorrent/actions/tab_actions.ts new file mode 100644 index 000000000000..ed4eca7f926b --- /dev/null +++ b/browser/resources/brave_webtorrent/actions/tab_actions.ts @@ -0,0 +1,25 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +import { action } from 'typesafe-actions' + +// Constants +import { types } from '../constants/tab_types' + +export const tabCreated = (tab: chrome.tabs.Tab) => action(types.TAB_CREATED, { + tab +}) + +export const tabUpdated = (tabId: number, changeInfo: chrome.tabs.TabChangeInfo, tab: chrome.tabs.Tab) => + action(types.TAB_UPDATED, { + tabId, changeInfo, tab +}) + +export const tabRemoved = (tabId: number) => action(types.TAB_REMOVED, { + tabId +}) + +export const activeTabChanged = (tabId: number, windowId: number) => action(types.ACTIVE_TAB_CHANGED, { + tabId, windowId +}) diff --git a/browser/resources/brave_webtorrent/actions/webtorrent_actions.ts b/browser/resources/brave_webtorrent/actions/webtorrent_actions.ts new file mode 100644 index 000000000000..d2f558515c45 --- /dev/null +++ b/browser/resources/brave_webtorrent/actions/webtorrent_actions.ts @@ -0,0 +1,16 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +import { action } from 'typesafe-actions' +import { Torrent } from 'webtorrent' + +// Constants +import { types } from '../constants/webtorrent_types' + +export const progressUpdated = (torrent: Torrent) => action(types.WEBTORRENT_PROGRESS_UPDATED, { torrent }) +export const infoUpdated = (torrent: Torrent) => action(types.WEBTORRENT_INFO_UPDATED, { torrent }) +export const serverUpdated = (torrent: Torrent, serverURL: string) => + action(types.WEBTORRENT_SERVER_UPDATED, { torrent, serverURL }) +export const startTorrent = (torrentId: string, tabId: number) => action(types.WEBTORRENT_START_TORRENT, { torrentId, tabId }) +export const stopDownload = (tabId: number) => action(types.WEBTORRENT_STOP_DOWNLOAD, { tabId }) diff --git a/browser/resources/brave_webtorrent/actions/window_actions.ts b/browser/resources/brave_webtorrent/actions/window_actions.ts new file mode 100644 index 000000000000..b54a4fed7326 --- /dev/null +++ b/browser/resources/brave_webtorrent/actions/window_actions.ts @@ -0,0 +1,20 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +import { action } from 'typesafe-actions' + +// Constants +import { types } from '../constants/window_types' + +export const windowCreated = (window: chrome.windows.Window) => action(types.WINDOW_CREATED, { + window +}) + +export const windowRemoved = (windowId: number) => action(types.WINDOW_REMOVED, { + windowId +}) + +export const windowFocusChanged = (windowId: number) => action(types.WINDOW_FOCUS_CHANGED, { + windowId +}) diff --git a/browser/resources/brave_webtorrent/background.ts b/browser/resources/brave_webtorrent/background.ts new file mode 100644 index 000000000000..3d4da61e3ef1 --- /dev/null +++ b/browser/resources/brave_webtorrent/background.ts @@ -0,0 +1,10 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +import { init } from './background/webtorrent' +init() + +require('./background/store') +require('./background/events/tabsEvents') +require('./background/events/windowsEvents') diff --git a/browser/resources/brave_webtorrent/background/actions/tabActions.ts b/browser/resources/brave_webtorrent/background/actions/tabActions.ts new file mode 100644 index 000000000000..751bf84a80f2 --- /dev/null +++ b/browser/resources/brave_webtorrent/background/actions/tabActions.ts @@ -0,0 +1,8 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +import { bindActionCreators } from 'redux' +import store from '../store' +import * as tabActions from '../../actions/tab_actions' +export default bindActionCreators(tabActions, store.dispatch) diff --git a/browser/resources/brave_webtorrent/background/actions/webtorrentActions.ts b/browser/resources/brave_webtorrent/background/actions/webtorrentActions.ts new file mode 100644 index 000000000000..b7eef7ab074d --- /dev/null +++ b/browser/resources/brave_webtorrent/background/actions/webtorrentActions.ts @@ -0,0 +1,8 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +import { bindActionCreators } from 'redux' +import store from '../store' +import * as webtorrentActions from '../../actions/webtorrent_actions' +export default bindActionCreators(webtorrentActions, store.dispatch) diff --git a/browser/resources/brave_webtorrent/background/actions/windowActions.ts b/browser/resources/brave_webtorrent/background/actions/windowActions.ts new file mode 100644 index 000000000000..948d7c928798 --- /dev/null +++ b/browser/resources/brave_webtorrent/background/actions/windowActions.ts @@ -0,0 +1,8 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +import { bindActionCreators } from 'redux' +import store from '../store' +import * as windowActions from '../../actions/window_actions' +export default bindActionCreators(windowActions, store.dispatch) diff --git a/browser/resources/brave_webtorrent/background/events/tabsEvents.ts b/browser/resources/brave_webtorrent/background/events/tabsEvents.ts new file mode 100644 index 000000000000..e6c07b834112 --- /dev/null +++ b/browser/resources/brave_webtorrent/background/events/tabsEvents.ts @@ -0,0 +1,21 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +import tabActions from '../actions/tabActions' + +chrome.tabs.onCreated.addListener((tab: chrome.tabs.Tab) => { + tabActions.tabCreated(tab) +}) + +chrome.tabs.onUpdated.addListener((tabId: number, changeInfo: chrome.tabs.TabChangeInfo, tab: chrome.tabs.Tab) => { + tabActions.tabUpdated(tabId, changeInfo, tab) +}) + +chrome.tabs.onRemoved.addListener((tabId: number, removeInfo: chrome.tabs.TabRemoveInfo) => { + tabActions.tabRemoved(tabId) +}) + +chrome.tabs.onActivated.addListener((activeInfo: chrome.tabs.TabActiveInfo) => { + tabActions.activeTabChanged(activeInfo.tabId, activeInfo.windowId) +}) diff --git a/browser/resources/brave_webtorrent/background/events/torrentEvents.ts b/browser/resources/brave_webtorrent/background/events/torrentEvents.ts new file mode 100644 index 000000000000..99f955310d6f --- /dev/null +++ b/browser/resources/brave_webtorrent/background/events/torrentEvents.ts @@ -0,0 +1,41 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +import { Torrent } from 'webtorrent' +import * as throttle from 'throttleit' + +import webtorrentActions from '../actions/webtorrentActions' +import { createServer } from '../webtorrent' + +export const addTorrentEvents = (torrent: Torrent) => { + torrent.on('done', () => { + webtorrentActions.progressUpdated(torrent) + }) + torrent.on('infoHash', () => { + console.log('infoHash event') + webtorrentActions.infoUpdated(torrent) + }) + torrent.on('metadata', () => { + console.log('metadata event') + webtorrentActions.infoUpdated(torrent) + }) + torrent.on('download', throttle((bytes: number) => { + webtorrentActions.progressUpdated(torrent) + }, 1000)) + torrent.on('upload', throttle((bytes: number) => { + webtorrentActions.progressUpdated(torrent) + }, 1000)) + torrent.on('ready', () => { + console.log('ready', torrent) + createServer(torrent, (serverURL: string) => { + webtorrentActions.serverUpdated(torrent, serverURL) + }) + }) + torrent.on('warning', (e: Error | string) => { + console.log('warning: ', torrent, e) + }) + torrent.on('error', (e: Error | string) => { + console.log('error: ', torrent, e) + }) +} diff --git a/browser/resources/brave_webtorrent/background/events/webtorrentEvents.ts b/browser/resources/brave_webtorrent/background/events/webtorrentEvents.ts new file mode 100644 index 000000000000..3c6f7e774144 --- /dev/null +++ b/browser/resources/brave_webtorrent/background/events/webtorrentEvents.ts @@ -0,0 +1,11 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +import { Instance } from 'webtorrent' + +export const addWebtorrentEvents = (webtorrent: Instance) => { + webtorrent.on('error', (e: Error | string) => { + console.log('WebTorrent error: ', e) + }) +} diff --git a/browser/resources/brave_webtorrent/background/events/windowsEvents.ts b/browser/resources/brave_webtorrent/background/events/windowsEvents.ts new file mode 100644 index 000000000000..9a8a328f390c --- /dev/null +++ b/browser/resources/brave_webtorrent/background/events/windowsEvents.ts @@ -0,0 +1,17 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +import windowActions from '../actions/windowActions' + +chrome.windows.onFocusChanged.addListener((windowId: number) => { + windowActions.windowFocusChanged(windowId) +}) + +chrome.windows.onCreated.addListener((window: chrome.windows.Window) => { + windowActions.windowCreated(window) +}) + +chrome.windows.onRemoved.addListener((windowId: number) => { + windowActions.windowRemoved(windowId) +}) diff --git a/browser/resources/brave_webtorrent/background/reducers/index.ts b/browser/resources/brave_webtorrent/background/reducers/index.ts new file mode 100644 index 000000000000..2a5fb58e099b --- /dev/null +++ b/browser/resources/brave_webtorrent/background/reducers/index.ts @@ -0,0 +1,13 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +import { combineReducers } from 'redux' + +// Utils +import webtorrentReducer from './webtorrent_reducer' +import { ApplicationState } from '../../constants/webtorrentState' + +export default combineReducers({ + torrentsData: webtorrentReducer +}) diff --git a/browser/resources/brave_webtorrent/background/reducers/webtorrent_reducer.ts b/browser/resources/brave_webtorrent/background/reducers/webtorrent_reducer.ts new file mode 100644 index 000000000000..2c7336de16cb --- /dev/null +++ b/browser/resources/brave_webtorrent/background/reducers/webtorrent_reducer.ts @@ -0,0 +1,221 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +import * as ParseTorrent from 'parse-torrent' +import { Torrent } from 'webtorrent' + +// Constants +import * as tabTypes from '../../constants/tab_types' +import * as windowTypes from '../../constants/window_types' +import * as torrentTypes from '../../constants/webtorrent_types' +import { File, TorrentState, TorrentsState } from '../../constants/webtorrentState' + +// Utils +import { addTorrent, delTorrent, findTorrent } from '../webtorrent' + +const isTorrentPage = (url: URL) => { + const fullpath = url.origin + url.pathname + return fullpath === chrome.runtime.getURL('brave_webtorrent.html') +} + +const focusedWindowChanged = (windowId: number, state: TorrentsState) => { + return { ...state, currentWindowId: windowId} +} + +const windowRemoved = (windowId: number, state: TorrentsState) => { + const { activeTabIds } = state + delete activeTabIds[windowId] + return { ...state, activeTabIds } +} + +const activeTabChanged = (tabId: number, windowId: number, state: TorrentsState) => { + const { activeTabIds } = state + activeTabIds[windowId] = tabId + return { ...state, activeTabIds } +} + +const tabUpdated = (tabId: number, url: string, state: TorrentsState) => { + const { torrentStateMap, torrentObjMap } = state + const origTorrentState: TorrentState = torrentStateMap[tabId] + const origInfoHash = origTorrentState ? origTorrentState.infoHash : undefined + let newTorrentState, newInfoHash + + // delete old torrent state + delete torrentStateMap[tabId] // delete old torrent state + + // create new torrent state + const parsedURL = new window.URL(url) + if (isTorrentPage(parsedURL)) { // parse torrent + const torrentId = decodeURIComponent(parsedURL.search.substring(1)) + try { + const { name, infoHash, ix } = ParseTorrent(torrentId) + newInfoHash = infoHash + newTorrentState = { tabId, torrentId, name, infoHash, ix } + } catch (error) { + newTorrentState = { tabId, torrentId, errorMsg: error.message } + } + } + + // unsubscribe old torrent if not the same + const isSameTorrent = newInfoHash && origInfoHash === newInfoHash + if (origInfoHash && torrentObjMap[origInfoHash] && !isSameTorrent) { + torrentObjMap[origInfoHash].tabClients.delete(tabId) + if (!torrentObjMap[origInfoHash].tabClients.size) { + delete torrentObjMap[origInfoHash] + delTorrent(origInfoHash) + } + } + + // save new torrent state and subscribe directly if torrent already existed + if (newTorrentState) { + torrentStateMap[tabId] = newTorrentState + if (newInfoHash && torrentObjMap[newInfoHash]) { + torrentObjMap[newInfoHash].tabClients.add(tabId) + } + } + + return { ...state, torrentStateMap, torrentObjMap } +} + +const tabRemoved = (tabId: number, state: TorrentsState) => { + const { torrentStateMap, torrentObjMap } = state + const torrentState = torrentStateMap[tabId] + if (torrentState) { + const infoHash = torrentState.infoHash + if (infoHash && torrentObjMap[infoHash]) { // unsubscribe + torrentObjMap[infoHash].tabClients.delete(tabId) + if (!torrentObjMap[infoHash].tabClients.size) { + delete torrentObjMap[infoHash] + delTorrent(infoHash) + } + } + delete torrentStateMap[tabId] + } + + return { ...state, torrentStateMap, torrentObjMap } +} + +const startTorrent = (torrentId: string, tabId: number, state: TorrentsState) => { + const { torrentStateMap, torrentObjMap } = state + const torrentState = torrentStateMap[tabId] + + if (torrentState && torrentState.infoHash && + !findTorrent(torrentState.infoHash)) { + addTorrent(torrentId) // objectMap will be updated when info event is emitted + } + + return { ...state, torrentObjMap } +} + +const stopDownload = (tabId: number, state: TorrentsState) => { + const { torrentStateMap, torrentObjMap } = state + const infoHash = torrentStateMap[tabId].infoHash + + if (infoHash && torrentObjMap[infoHash]) { + delete torrentObjMap[infoHash] + delTorrent(infoHash) + } + + return { ...state, torrentStateMap, torrentObjMap } +} + +const updateProgress = (state: TorrentsState, torrent: Torrent) => { + const { torrentObjMap } = state + // don't add a new entry since the download might be stopped already + if (!torrentObjMap[torrent.infoHash]) { + return state + } + + const { downloaded, uploaded, downloadSpeed, uploadSpeed, progress, ratio, + numPeers, timeRemaining } = torrent + torrentObjMap[torrent.infoHash] = { ...torrentObjMap[torrent.infoHash], + downloaded, uploaded, downloadSpeed, uploadSpeed, progress, ratio, + numPeers, timeRemaining } + + return { ...state, torrentObjMap } +} + +const updateInfo = (state: TorrentsState, torrent: Torrent) => { + const { torrentStateMap, torrentObjMap } = state + const { downloaded, uploaded, downloadSpeed, uploadSpeed, progress, ratio, + numPeers, timeRemaining, infoHash } = torrent + let length = 0 + const files : File[] = torrent.files.map((file) => { + length += file.length + return { name: file.name, length: file.length } + }) + + const tabClients : Set = new Set() + Object.keys(torrentStateMap).filter( + key => torrentStateMap[key].infoHash === infoHash).map( + key => { + tabClients.add(torrentStateMap[key].tabId) + } + ) + + torrentObjMap[torrent.infoHash] = { ...torrentObjMap[torrent.infoHash], + files, downloaded, uploaded, downloadSpeed, uploadSpeed, progress, ratio, + numPeers, timeRemaining, length, tabClients } + + return { ...state, torrentStateMap, torrentObjMap } +} + +const updateServer = (state: TorrentsState, torrent: Torrent, serverURL: string) => { + const { torrentObjMap } = state + torrentObjMap[torrent.infoHash] = { ...torrentObjMap[torrent.infoHash], serverURL } + return { ...state, torrentObjMap } +} + +const defaultState : TorrentsState = { currentWindowId: -1, activeTabIds: {}, torrentStateMap: {}, torrentObjMap: {} } +const webtorrentReducer = (state: TorrentsState = defaultState, action: any) => { // TODO: modify any to be actual action type + const payload = action.payload + switch (action.type) { + case windowTypes.types.WINDOW_CREATED: + if (payload.window.focused || Object.keys(state.activeTabIds).length === 0) { + state = focusedWindowChanged(payload.window.id, state) + } + break + case windowTypes.types.WINDOW_REMOVED: + state = windowRemoved(payload.windowId, state) + break + case windowTypes.types.WINDOW_FOCUS_CHANGED: + state = focusedWindowChanged(payload.windowId, state) + break + case tabTypes.types.ACTIVE_TAB_CHANGED: + state = activeTabChanged(payload.tabId, payload.windowId, state) + break + case tabTypes.types.TAB_CREATED: + if (payload.tab.id && payload.tab.url) { + state = tabUpdated(payload.tab, payload.tab.url, state) + } + break + case tabTypes.types.TAB_UPDATED: + if (payload.changeInfo.url) { + state = tabUpdated(payload.tab.id, payload.changeInfo.url, state) + } + break + case tabTypes.types.TAB_REMOVED: + state = tabRemoved(payload.tabId, state) + break + case torrentTypes.types.WEBTORRENT_PROGRESS_UPDATED: + state = updateProgress(state, payload.torrent) + break + case torrentTypes.types.WEBTORRENT_INFO_UPDATED: + state = updateInfo(state, payload.torrent) + break + case torrentTypes.types.WEBTORRENT_SERVER_UPDATED: + state = updateServer(state, payload.torrent, payload.serverURL) + break + case torrentTypes.types.WEBTORRENT_START_TORRENT: + state = startTorrent(payload.torrentId, payload.tabId, state) + break + case torrentTypes.types.WEBTORRENT_STOP_DOWNLOAD: + state = stopDownload(payload.tabId, state) + break + } + + return state +} + +export default webtorrentReducer diff --git a/browser/resources/brave_webtorrent/background/store.ts b/browser/resources/brave_webtorrent/background/store.ts new file mode 100644 index 000000000000..8dc15713a589 --- /dev/null +++ b/browser/resources/brave_webtorrent/background/store.ts @@ -0,0 +1,33 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +import { applyMiddleware, createStore, Middleware } from 'redux' +import { wrapStore } from 'react-chrome-redux' +import { createLogger } from 'redux-logger' + +import reducers from './reducers' + +const logger = createLogger({ + collapsed: true +}) + + +const getMiddleware = () => { + const args : Middleware[] = [] + if (process.env.NODE_ENV === `development`) { + args.push(logger) + } + + return applyMiddleware(...args) +} + + +const initialState = {} +const store = createStore(reducers, initialState, getMiddleware()) + +wrapStore(store, { + portName: 'WEBTORRENT' +}) + +export default store diff --git a/browser/resources/brave_webtorrent/background/webtorrent.ts b/browser/resources/brave_webtorrent/background/webtorrent.ts new file mode 100644 index 000000000000..d74b6e1af36e --- /dev/null +++ b/browser/resources/brave_webtorrent/background/webtorrent.ts @@ -0,0 +1,57 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +import * as WebTorrent from 'webtorrent' +import { addTorrentEvents } from './events/torrentEvents' +import { addWebtorrentEvents } from './events/webtorrentEvents' +import { AddressInfo } from 'net' + +let webTorrent: WebTorrent.Instance +let servers: { [key: string] : any } = { } + +export const init = () => { + webTorrent = new WebTorrent({tracker: {wrtc: false}}) + addWebtorrentEvents(webTorrent) +} + +export const getWebTorrent = () => webTorrent + +export const createServer = (torrent: WebTorrent.Torrent, cb: (serverURL: string) => void) => { + if (!torrent.infoHash) return // torrent is not ready + + const server = torrent.createServer() + if (!server) return + + try { + server.listen(0, '127.0.0.1', undefined, () => { + // Explicitly cast server.address() to AddressInfo to access its + // properties. It's safe to cast here because the only possible type of + // server.address() here is AddressInfo since pipe name (as string) is + // not supported in chrome-net. + const addrInfo = server.address() + servers[torrent.infoHash] = server + cb('http://' + addrInfo.address + ':' + addrInfo.port.toString()) + }) + } catch(error) { + console.log('server listen error: ', error) + } +} + +export const addTorrent = (torrentId: string) => { + const torrentObj = webTorrent.add(torrentId) + addTorrentEvents(torrentObj) +} + +export const delTorrent = (infoHash: string) => { + const torrent = findTorrent(infoHash) + if (torrent) torrent.destroy() + if (servers[infoHash]) { + servers[infoHash].close() + delete servers[infoHash] + } +} + +export const findTorrent = (infoHash: string) => { + return webTorrent.torrents.find(torrent => torrent.infoHash === infoHash) +} diff --git a/browser/resources/brave_webtorrent/brave_webtorrent.html b/browser/resources/brave_webtorrent/brave_webtorrent.html new file mode 100644 index 000000000000..63d9de154ddb --- /dev/null +++ b/browser/resources/brave_webtorrent/brave_webtorrent.html @@ -0,0 +1,14 @@ + + + + +Webtorrent + + + + +
+ + diff --git a/browser/resources/brave_webtorrent/brave_webtorrent.tsx b/browser/resources/brave_webtorrent/brave_webtorrent.tsx new file mode 100644 index 000000000000..1d98b2ba66c3 --- /dev/null +++ b/browser/resources/brave_webtorrent/brave_webtorrent.tsx @@ -0,0 +1,30 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +import * as React from 'react' +import { render } from 'react-dom' +import { Provider } from 'react-redux' +import { Store } from 'react-chrome-redux' + +// Components +import App from './components/app' + +// Constants +import { TorrentsState } from './constants/webtorrentState' + +const store: Store = new Store({ + portName: 'WEBTORRENT' +}) + +store.ready().then( + () => { + render( + + + , + document.getElementById('root')) + }) + .catch(() => { + console.error('Problem mounting webtorrent') + }) diff --git a/browser/resources/brave_webtorrent/components/app.tsx b/browser/resources/brave_webtorrent/components/app.tsx new file mode 100644 index 000000000000..7cdb7e5ffb2c --- /dev/null +++ b/browser/resources/brave_webtorrent/components/app.tsx @@ -0,0 +1,73 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +import * as React from 'react' +import { bindActionCreators, Dispatch } from 'redux' +import { connect } from 'react-redux' + +// Components +import MediaViewer from './mediaViewer' +import TorrentViewer from './torrentViewer' + +// Constants +import { TorrentObj } from '../constants/webtorrentState' + +// Utils +import * as torrentActions from '../actions/webtorrent_actions' +import { TorrentState, ApplicationState, getTorrentObj, getTorrentState } from '../constants/webtorrentState' + +// Assets +require('../../../../components/styles/webtorrent.less') + +interface Props { + torrentState: TorrentState + torrentObj?: TorrentObj + actions: any +} + +export class BraveWebtorrentPage extends React.Component { + render() { + const { actions, torrentState, torrentObj } = this.props + const torrentId = decodeURIComponent(window.location.search.substring(1)) + + // The active tab change might not be propagated here yet, so we might get + // the old active tabId here which might be a different torrent page or a + // non-torrent page. + if (!torrentState || torrentId != torrentState.torrentId) { + return (
Loading...
) + } + + if (torrentObj && typeof(torrentState.ix) === 'number') { + return ( + ) + } + + return ( + ) + } +} + +export const mapStateToProps = (state: ApplicationState) => { + return { torrentState: getTorrentState(state.torrentsData), + torrentObj: getTorrentObj(state.torrentsData) } +} + +export const mapDispatchToProps = (dispatch: Dispatch) => ({ + actions: bindActionCreators(torrentActions, dispatch) +}) + +export default connect( + mapStateToProps, + mapDispatchToProps +)(BraveWebtorrentPage) diff --git a/browser/resources/brave_webtorrent/components/mediaViewer.tsx b/browser/resources/brave_webtorrent/components/mediaViewer.tsx new file mode 100644 index 000000000000..a1941b0bd28e --- /dev/null +++ b/browser/resources/brave_webtorrent/components/mediaViewer.tsx @@ -0,0 +1,72 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +import * as React from 'react' + +// Constants +import { TorrentObj } from '../constants/webtorrentState' + +const SUPPORTED_VIDEO_EXTENSIONS = [ + 'm4v', + 'mkv', + 'mov', + 'mp4', + 'ogv', + 'webm' +] + +const SUPPORTED_AUDIO_EXTENSIONS = [ + 'aac', + 'mp3', + 'ogg', + 'wav', + 'm4a' +] + +// Given 'foo.txt', returns 'txt' +// Given eg. null, undefined, '', or 'README', returns null +const getExtension = (filename: string) => { + if (!filename) return null + const ix = filename.lastIndexOf('.') + if (ix < 0) return null + return filename.substring(ix + 1) +} + +interface Props { + torrent: TorrentObj + ix: number +} + +export default class MediaViewer extends React.PureComponent { + render() { + const { torrent, ix } = this.props + + const file = torrent.files ? torrent.files[ix] : undefined + const fileURL = torrent.serverURL && (torrent.serverURL + '/' + ix) + + const fileExt = file && getExtension(file.name) + const isVideo = fileExt ? SUPPORTED_VIDEO_EXTENSIONS.includes(fileExt) : false + const isAudio = fileExt ? SUPPORTED_AUDIO_EXTENSIONS.includes(fileExt) : false + + let content + if (!file || !torrent.serverURL) { + content =
Loading Media
+ } else if (isVideo) { + content =