diff --git a/.gitignore b/.gitignore index efbd70d72..58584c897 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ **/output/* +**/eth-states*/* **/__pycache__/* *.out *.o @@ -21,4 +22,4 @@ client/frontend/node_modules client/backend/node_modules client/backend/bin *.bin -output \ No newline at end of file +output diff --git a/blockchain-client/src/.gitignore b/blockchain-client/src/.gitignore deleted file mode 100644 index 3c3629e64..000000000 --- a/blockchain-client/src/.gitignore +++ /dev/null @@ -1 +0,0 @@ -node_modules diff --git a/blockchain-client/src/DockerOdeWrapper.ts b/blockchain-client/src/DockerOdeWrapper.ts deleted file mode 100644 index 690963004..000000000 --- a/blockchain-client/src/DockerOdeWrapper.ts +++ /dev/null @@ -1,46 +0,0 @@ -const fs = require('fs'); -const helpers = require('./common/helpers.ts') - -const DockerOdeWrapper = { - docker: { - listContainers(dockerInstance) { - return new Promise((resolve, reject) => { - dockerInstance.listContainers((error, containers) => { - if(error) { - reject(error); - } else { - resolve(containers); - } - }); - }) - }, - getContainer(dockerInstance, id) { - return new Promise((resolve) => { - resolve(dockerInstance.getContainer(id)); - }); - }, - }, - container: { - exec(dockerInstance, container, command) { - return new Promise((resolve, reject) => { - container.exec({ Cmd: command.split(" "), AttachStdIn: true, AttachStdout: true}, (error, exec) => { - exec.start({hijack: true, stdin: false}, (err, stream) => { - if (error) { - console.log(`Command \"${command}\" failed to run`); - reject(err); - } else { - console.log(`Command \"${command}\" executed successfully`); - return helpers.demuxStream(stream) - .then((output) => { - return resolve(output) - }) - - } - }) - }) - }) - } - } -} - -module.exports = DockerOdeWrapper; diff --git a/blockchain-client/src/Dockerfile b/blockchain-client/src/Dockerfile deleted file mode 100644 index 151af946a..000000000 --- a/blockchain-client/src/Dockerfile +++ /dev/null @@ -1,6 +0,0 @@ -FROM node:14 -COPY start.sh / -WORKDIR /usr/src/app/blockchain-client/src -COPY . . -RUN npm i -ENTRYPOINT ["sh", "/start.sh"] diff --git a/blockchain-client/src/apis.ts b/blockchain-client/src/apis.ts deleted file mode 100644 index 3896b82de..000000000 --- a/blockchain-client/src/apis.ts +++ /dev/null @@ -1,51 +0,0 @@ -const apis = [ - { - name: "Get Accounts", - description: "Returns the list of ethereum accounts in the container.", - command: "getAccounts", - parameters: [] - }, - { - name: "Get Balance", - description: "Returns the balance of the account specified as parameter.", - command: "getBalance", - parameters: [{el: "input", name: "Account index", required: true}] - }, - { - name: "Set Etherbase", - description: "Sets the account which will be receiving ether when mining.", - command: "setEtherBase", - parameters: [{el: "input", name: "Account index", required: true}] - }, - { - name: "Get Coinbase", - description: "Returns the address of the account collecting ether when mining", - command: "getCoinBase", - }, - { - name: "Start Mining", - description: "Starts the mining process on the coinbase account.", - command: "startMiner", - parameters: [{el: "input", name: "Number of threads", required: false}] - }, - { - name: "Stop Mining", - description: "Stop the mining process.", - command: "stopMiner", - parameters: [] - }, - { - name: "Send Transaction", - description: "Send ether from one account to the other.", - command: "sendTransaction", - parameters: [{el: "input", name:"From address", required: true},{el: "input", name: "To address", required: true},{el: "input", name: "Value in ether", required: true}] - }, - { - name: "View Pending Transactions", - description: "View a list of pending transactions in the network.", - command: "viewPendingTransactions", - parameters: [] - } -] - -module.exports = apis; diff --git a/blockchain-client/src/commands.ts b/blockchain-client/src/commands.ts deleted file mode 100644 index d4ef15526..000000000 --- a/blockchain-client/src/commands.ts +++ /dev/null @@ -1,104 +0,0 @@ -const helpers = require('./common/helpers.ts') - -// @todo use the castGethParameters for all other commands -const commands = { - getAccounts() { - return "geth attach --exec eth.accounts" - }, - getBalance(account) { - account = account || 0; - return `geth attach --exec eth.getBalance(eth.accounts[${account}])` - }, - setDefaultAccount(account) { - account = account || 0; - // spaces matter here when writing the equality, remove the spaces. - return `geth attach --exec eth.defaultAccount=eth.accounts[${account}]` - }, - getDefaultAccount() { - return `geth attach --exec eth.defaultAccount` - }, - setEtherBase(account) { - account = account || 0 - return `geth attach --exec miner.setEtherbase(eth.accounts[${account}])` - }, - getCoinBase() { - return `geth attach --exec eth.coinbase` - }, - startMiner(threads) { - threads = threads || 20; - return `geth attach --exec miner.start(${threads})` - }, - stopMiner() { - return `geth attach --exec miner.stop()` - }, - sendTransaction(sender, receiver, amount) { - return `geth attach --exec eth.sendTransaction({from:"${sender}",to:"${receiver}",value:web3.toWei(${amount},\"ether\")})` - }, - viewPendingTransactions() { - return `geth attach --exec eth.pendingTransactions` - }, - deploySmartContract(account, abi, bytecode, params, value) { - abi = abi.replace(" ", "\t") - let base = `{from:"${account}",data:"${bytecode}",gas:1000000` - if(params.length) { - base = params +',' + base; - } - if(value) { - base += `,value:${value}` - } - base += '}' - - //if(params.length) { - // return `geth attach --exec eth.contract(${abi}).new(${params},{from:"${account}",data:"${bytecode}",gas:1000000})` - //} else { - // return `geth attach --exec eth.contract(${abi}).new()` - //} - return `geth attach --exec eth.contract(${abi}).new(${base})` - }, - getTransactionReceipt(hash) { - return `geth attach --exec eth.getTransactionReceipt("${hash}")` - }, - getContractByAddress(abi,address) { - abi = abi.replace(" ", "\t") - return `geth attach --exec eth.contract(${abi}).at("${address}")` - }, - invokeContractFunction(funcInfo, parameters, additional=[]) { - const {funcName, payable} = funcInfo - const [defaultAccount, {abi, address}, value] = additional; - const parameterString = this.generateCallString(parameters, {payable, value}) - const tail = this.options.call ? '.call' + parameterString : parameterString; - - sanitizedAbi = abi.replace(" ", "\t") - - return `geth attach --exec eth.defaultAccount="${defaultAccount}";` + - `sc=eth.contract(${sanitizedAbi}).at("${address}");` + - `sc["${funcName}"]${tail}` - }, - generateCallString(parameters=[], options={}) { - let command = "(" - if(parameters.length) { - let i = 0; - command += `"${parameters[i].value}"` - for(i = 1; i < parameters.length; i++) { - command+=`,"${parameters[i].value}"`; - } - } - if(options.payable) { - const stringObj = `{value:${options.value * Math.pow(10,18)}}` - command += parameters.length ?`,${stringObj}` : stringObj - } - command += ")" - return command; - } - -} - -function getCommand(name, params=[], options={}) { - if(commands[name]) { - commands.options = options - //console.log("spread params are: ", ...params) - return commands[name](...params) - } -} - -module.exports = getCommand diff --git a/blockchain-client/src/common/helpers.ts b/blockchain-client/src/common/helpers.ts deleted file mode 100644 index 873c3de03..000000000 --- a/blockchain-client/src/common/helpers.ts +++ /dev/null @@ -1,68 +0,0 @@ -const helpers = { - - demuxStream(stream, output, error) { - return new Promise((resolve, reject) => { - let output = ''; - let error = ''; - let nextDataType = null; - let nextDataLength = null; - let buffer = Buffer.from(''); - function processData(data) { - if (data) { - buffer = Buffer.concat([buffer, data]); - } - if (!nextDataType) { - if (buffer.length >= 8) { - let header = bufferSlice(8); - nextDataType = header.readUInt8(0); - nextDataLength = header.readUInt32BE(4); - // It's possible we got a "data" that contains multiple messages - // Process the next one - processData(); - } - } else { - if (buffer.length >= nextDataLength) { - let content = bufferSlice(nextDataLength); - if (nextDataType === 1) { - output += content; - } else { - error += content - } - nextDataType = null; - // It's possible we got a "data" that contains multiple messages - // Process the next one - processData(); - } - } - } - - function bufferSlice(end) { - let out = buffer.slice(0, end); - buffer = Buffer.from(buffer.slice(end, buffer.length)); - return out; - } - stream.on('data', (data) => { - processData(data) - }) - stream.on('end', () => { - resolve(output) - }) - }) - }, - regex: /([{,]\s*)(\S+)\s*(:)/mg, - stringToJsonString(s) { - console.log("converting string: ", s) - return s.replace(this.regex, '$1"$2"$3') - }, - sanitizeGethStreamString(s) { - return s.replace(/\.\.\./g, "").replace(/function\(\)/g, "\"function()\"").replace(/undefined/g, null) - }, - castGethParameters(value, type) { - if(type === 'string' || type === 'address') { - return `"${value}"` - } - return value - } -} - -module.exports = helpers; diff --git a/blockchain-client/src/docker-compose.yml b/blockchain-client/src/docker-compose.yml deleted file mode 100644 index 4b19cb247..000000000 --- a/blockchain-client/src/docker-compose.yml +++ /dev/null @@ -1,10 +0,0 @@ -version: "3" - -services: - seedemu-eth-client: - build: . - container_name: seedemu-eth-client - volumes: - - /var/run/docker.sock:/var/run/docker.sock - ports: - - 3000:3000 diff --git a/blockchain-client/src/docker/index.ts b/blockchain-client/src/docker/index.ts deleted file mode 100644 index 1d7713314..000000000 --- a/blockchain-client/src/docker/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -const Docker = require('dockerode') - -const docker = new Docker(); - -module.exports = docker; diff --git a/blockchain-client/src/index.ts b/blockchain-client/src/index.ts deleted file mode 100644 index b8c48c69d..000000000 --- a/blockchain-client/src/index.ts +++ /dev/null @@ -1,25 +0,0 @@ -const express = require('express'); -const handlebars = require('express-handlebars'); -const path = require('path'); -const bodyParser = require('body-parser'); - -const app = express(); -const port = process.env.PORT; - -const indexRouter = require('./routes/index.ts'); -const smartContractRouter = require('./routes/smartcontracts.ts'); - -app.engine('handlebars', handlebars()); -app.set('view engine', 'handlebars'); - -app.use(express.static(path.join(__dirname, "/public"))); -app.use(bodyParser.urlencoded({extended: false})) -app.use(bodyParser.json()) - -app.use('/', indexRouter); -app.use('/smartcontracts', smartContractRouter); - - -app.listen(port, () => { - console.log(`server started at http://localhost:${port}`) -}) diff --git a/blockchain-client/src/package-lock.json b/blockchain-client/src/package-lock.json deleted file mode 100644 index f3a6b0d15..000000000 --- a/blockchain-client/src/package-lock.json +++ /dev/null @@ -1,763 +0,0 @@ -{ - "name": "src", - "version": "1.0.0", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "accepts": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", - "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", - "requires": { - "mime-types": "~2.1.24", - "negotiator": "0.6.2" - } - }, - "array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" - }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "requires": { - "tweetnacl": "^0.14.3" - } - }, - "bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "requires": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "body-parser": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", - "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", - "requires": { - "bytes": "3.1.0", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.7.0", - "raw-body": "2.4.0", - "type-is": "~1.6.17" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } - } - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "bytes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" - }, - "chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "content-disposition": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", - "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", - "requires": { - "safe-buffer": "5.1.2" - }, - "dependencies": { - "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==" - } - } - }, - "content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" - }, - "cookie": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", - "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" - }, - "cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" - }, - "cpu-features": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/cpu-features/-/cpu-features-0.0.2.tgz", - "integrity": "sha512-/2yieBqvMcRj8McNzkycjW2v3OIUOibBfd2dLEJ0nWts8NobAxwiyw9phVNS6oDL8x8tz9F7uNVFEVpJncQpeA==", - "optional": true, - "requires": { - "nan": "^2.14.1" - } - }, - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "requires": { - "ms": "2.1.2" - } - }, - "depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" - }, - "destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" - }, - "docker-modem": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/docker-modem/-/docker-modem-3.0.3.tgz", - "integrity": "sha512-Tgkn2a+yiNP9FoZgMa/D9Wk+D2Db///0KOyKSYZRJa8w4+DzKyzQMkczKSdR/adQ0x46BOpeNkoyEOKjPhCzjw==", - "requires": { - "debug": "^4.1.1", - "readable-stream": "^3.5.0", - "split-ca": "^1.0.1", - "ssh2": "^1.4.0" - } - }, - "dockerode": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/dockerode/-/dockerode-3.3.1.tgz", - "integrity": "sha512-AS2mr8Lp122aa5n6d99HkuTNdRV1wkkhHwBdcnY6V0+28D3DSYwhxAk85/mM9XwD3RMliTxyr63iuvn5ZblFYQ==", - "requires": { - "docker-modem": "^3.0.0", - "tar-fs": "~2.0.1" - } - }, - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" - }, - "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "requires": { - "once": "^1.4.0" - } - }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" - }, - "etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" - }, - "express": { - "version": "4.17.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", - "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", - "requires": { - "accepts": "~1.3.7", - "array-flatten": "1.1.1", - "body-parser": "1.19.0", - "content-disposition": "0.5.3", - "content-type": "~1.0.4", - "cookie": "0.4.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "~1.1.2", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "~1.1.2", - "fresh": "0.5.2", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.5", - "qs": "6.7.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.1.2", - "send": "0.17.1", - "serve-static": "1.14.1", - "setprototypeof": "1.1.1", - "statuses": "~1.5.0", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "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==" - } - } - }, - "express-handlebars": { - "version": "5.3.4", - "resolved": "https://registry.npmjs.org/express-handlebars/-/express-handlebars-5.3.4.tgz", - "integrity": "sha512-b36grfkbXZItLLQV6cwzA20o6Zg4Eckke3PjHF4EGQIQLGs5IPMjpAxepdGb45A/bECekXzA9STzNqvEgrdRPw==", - "requires": { - "glob": "^7.2.0", - "graceful-fs": "^4.2.7", - "handlebars": "^4.7.7" - } - }, - "finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", - "requires": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "statuses": "~1.5.0", - "unpipe": "~1.0.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } - } - }, - "forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" - }, - "fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" - }, - "fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "graceful-fs": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", - "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==" - }, - "handlebars": { - "version": "4.7.7", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", - "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", - "requires": { - "minimist": "^1.2.5", - "neo-async": "^2.6.0", - "source-map": "^0.6.1", - "uglify-js": "^3.1.4", - "wordwrap": "^1.0.0" - } - }, - "http-errors": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", - "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.1", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.0" - }, - "dependencies": { - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" - } - } - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" - }, - "media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" - }, - "merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" - }, - "methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" - }, - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" - }, - "mime-db": { - "version": "1.50.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.50.0.tgz", - "integrity": "sha512-9tMZCDlYHqeERXEHO9f/hKfNXhre5dK2eE/krIvUjZbS2KPcqGDfNShIWS1uW9XOTKQKqK6qbeOci18rbfW77A==" - }, - "mime-types": { - "version": "2.1.33", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.33.tgz", - "integrity": "sha512-plLElXp7pRDd0bNZHw+nMd52vRYjLwQjygaNg7ddJ2uJtTlmnTCjWuPKxVu6//AdaRuME84SvLW91sIkBqGT0g==", - "requires": { - "mime-db": "1.50.0" - } - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" - }, - "mkdirp-classic": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "nan": { - "version": "2.15.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz", - "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==", - "optional": true - }, - "negotiator": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", - "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" - }, - "neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" - }, - "on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", - "requires": { - "ee-first": "1.1.1" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" - }, - "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=" - }, - "path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" - }, - "proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "requires": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - } - }, - "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" - } - }, - "qs": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", - "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" - }, - "range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" - }, - "raw-body": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", - "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", - "requires": { - "bytes": "3.1.0", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - } - }, - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "send": { - "version": "0.17.1", - "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", - "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", - "requires": { - "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "~1.7.2", - "mime": "1.6.0", - "ms": "2.1.1", - "on-finished": "~2.3.0", - "range-parser": "~1.2.1", - "statuses": "~1.5.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - }, - "dependencies": { - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } - } - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" - } - } - }, - "serve-static": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", - "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", - "requires": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.17.1" - } - }, - "setprototypeof": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", - "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - }, - "split-ca": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/split-ca/-/split-ca-1.0.1.tgz", - "integrity": "sha1-bIOv82kvphJW4M0ZfgXp3hV2kaY=" - }, - "ssh2": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/ssh2/-/ssh2-1.5.0.tgz", - "integrity": "sha512-iUmRkhH9KGeszQwDW7YyyqjsMTf4z+0o48Cp4xOwlY5LjtbIAvyd3fwnsoUZW/hXmTCRA3yt7S/Jb9uVjErVlA==", - "requires": { - "asn1": "^0.2.4", - "bcrypt-pbkdf": "^1.0.2", - "cpu-features": "0.0.2", - "nan": "^2.15.0" - } - }, - "statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "requires": { - "safe-buffer": "~5.2.0" - } - }, - "tar-fs": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.0.1.tgz", - "integrity": "sha512-6tzWDMeroL87uF/+lin46k+Q+46rAJ0SyPGz7OW7wTgblI273hsBqk2C1j0/xNadNLKDTUL9BukSjB7cwgmlPA==", - "requires": { - "chownr": "^1.1.1", - "mkdirp-classic": "^0.5.2", - "pump": "^3.0.0", - "tar-stream": "^2.0.0" - } - }, - "tar-stream": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", - "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", - "requires": { - "bl": "^4.0.3", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - } - }, - "toidentifier": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", - "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" - }, - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - }, - "type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "requires": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - } - }, - "typescript": { - "version": "4.4.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.4.tgz", - "integrity": "sha512-DqGhF5IKoBl8WNf8C1gu8q0xZSInh9j1kJJMqT3a94w1JzVaBU4EXOSMrz9yDqMT0xt3selp83fuFMQ0uzv6qA==", - "dev": true - }, - "uglify-js": { - "version": "3.14.2", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.14.2.tgz", - "integrity": "sha512-rtPMlmcO4agTUfz10CbgJ1k6UAoXM2gWb3GoMPPZB/+/Ackf8lNWk11K4rYi2D0apgoFRLtQOZhb+/iGNJq26A==", - "optional": true - }, - "unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" - }, - "vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" - }, - "wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=" - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - } - } -} diff --git a/blockchain-client/src/package.json b/blockchain-client/src/package.json deleted file mode 100644 index 43576bc98..000000000 --- a/blockchain-client/src/package.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "name": "src", - "version": "1.0.0", - "description": "", - "main": "index.js", - "scripts": { - "test": "node test.ts", - "start": "export PORT=3000 && export CONTAINER=Ethereum-6 && node index.ts" - }, - "keywords": [], - "author": "", - "license": "ISC", - "dependencies": { - "body-parser": "^1.19.0", - "dockerode": "^3.3.1", - "express": "^4.17.1", - "express-handlebars": "^5.3.4" - }, - "devDependencies": { - "typescript": "^4.4.4" - } -} diff --git a/blockchain-client/src/public/css/index.css b/blockchain-client/src/public/css/index.css deleted file mode 100644 index 6e01930ff..000000000 --- a/blockchain-client/src/public/css/index.css +++ /dev/null @@ -1,68 +0,0 @@ -#apis,#smartContractContainer { - display: flex; - flex-direction: column; - flex-wrap: wrap; - align-content: flex-start; -} - -.margin-10-0 { - margin: 10px 0 !important; -} - -.flex-direction-column { - flex-direction: column !important; -} - -.section { - border: 1px solid lightblue; - padding: 5px; - margin: 0 0 10px 0; - width: 100%; -} - -.action-section { - display: flex; - flex-direction: row; - flex-wrap: wrap; - justify-content: flex-start; - align-content: start; - align-items: start; -} - -.apiBtn { - text-align: center; -} - -.apiBtn, .apiParams { - height: 100%; -} - -#accountsSection { - display: flex; - flex-direction: row; -} - -#deploymentSection { - display: flex; - flex-direction: column; - flex-wrap: wrap; - justify-content: center; -} - -#units { - display: none; -} - -#displayContract { - display: flex; - flex-direction: column; - flex-wrap: wrap; - justify-content: flex-start; - align-items: flex-start; - gap: 20px; -} - -.deployedContractContainer { - display: flex; - flex-direction: column; -} diff --git a/blockchain-client/src/public/js/index.js b/blockchain-client/src/public/js/index.js deleted file mode 100644 index ea93440e5..000000000 --- a/blockchain-client/src/public/js/index.js +++ /dev/null @@ -1,55 +0,0 @@ -function xmlHttpRequestHandler(type, url, data={}, callback) { - const http = new XMLHttpRequest(); - http.open(type, url, true); - http.onreadystatechange = function() { - if(http.readyState === XMLHttpRequest.DONE) { - callback(JSON.parse(http.responseText)) - } - } - http.setRequestHeader('Content-Type', 'application/json;charset=UTF-8'); - http.send(JSON.stringify(data)); -} - - -function responseHandler({command, output}) { - const div = document.getElementById(command).querySelector('.apiOutputContainer') - const outputElement = document.getElementById(command + "-output") || document.createElement('p') - const sanitizedOutput = output.replace(/[^ -~]+/g, "") - outputElement.innerHTML = ""; - outputElement.id = command + "-output" - outputElement.innerHTML = sanitizedOutput; - div.appendChild(outputElement) -} - - - -document.addEventListener('DOMContentLoaded',function () { - - const nodesParentContainer = document.getElementById('nodes'); - - window.containerId = nodesParentContainer.options[nodesParentContainer.selectedIndex].dataset.id; - nodesParentContainer.addEventListener('change', (event) => { - window.containerId = event.target.options[event.target.selectedIndex].dataset.id; - }) - - const apiButtons = document.getElementsByClassName('apiBtn'); - for (let i = 0; i { - xmlHttpRequestHandler('POST', 'http://localhost:'+window.blockchainPort, { - command: event.target.dataset.command, - containerId: window.containerId, - params: (function(){ - const parentContainer = event.target.parentElement; - const inputs = parentContainer.querySelectorAll(".apiParams"); - const paramValues = []; - inputs.forEach((input) => { - paramValues.push(input.value) - }) - return paramValues - })() - }, responseHandler) - }) - } -}) - - diff --git a/blockchain-client/src/public/js/smartcontracts.js b/blockchain-client/src/public/js/smartcontracts.js deleted file mode 100644 index 44563221e..000000000 --- a/blockchain-client/src/public/js/smartcontracts.js +++ /dev/null @@ -1,204 +0,0 @@ -let url; -const deployedContracts = [] - -function getSanitizedAbiValue(abi) { - return JSON.stringify(JSON.parse(abi) - .map((f)=>{ - if(f.stateMutability === 'payable') { - f.payable=true - } - return f; - })) -} - -function displayDeployedContractFunctions(func) { - if(func.name) { - const numOfParameters = func.inputs.length; - const functionButton = document.createElement('input') - functionButton.type = "button" - functionButton.value = func.name; - functionButton.setAttribute('data-action', 'invokeContractFunction') - functionButton.setAttribute('data-abi', deployedContracts.length - 1) - - if(func.payable) { - functionButton.setAttribute('data-payable', true) - } - - const parentContainer = document.querySelector(`.deployedContractContainer[data-abi="${deployedContracts.length-1}"]`); - parentContainer.appendChild(functionButton) - - func.inputs.forEach((input) => { - const paramInput = document.createElement('input') - paramInput.placeholder = input.name - paramInput.className = func.name + "-param" - paramInput.setAttribute('data-type', input.type) - parentContainer.appendChild(paramInput) - }) - - const outputContainer = document.createElement('div') - outputContainer.className= func.name + "-output" - outputContainer.setAttribute('data-abi', deployedContracts.length - 1) - parentContainer.appendChild(outputContainer); - - functionButton.addEventListener('click', (event) =>{ - const params = document.getElementsByClassName(func.name+"-param") - const functionInfo = { - funcName: event.target.value, - abiIndex: event.target.dataset.abi, - payable: event.target.dataset.payable - } - const functionParameters = Array.from(params).map((param) => { - return { - value: param.value, - type: param.dataset.type - } - }) - const {abi, address} = deployedContracts[event.target.dataset.abi] - const valueEl = document.querySelector('#paymentSection input') - const value = valueEl.value || undefined - const additionalData = [ - window.selectedAccount, - {abi: getSanitizedAbiValue(abi), address}, - document.querySelector('#paymentSection input').value || undefined - ] - xmlHttpRequestHandler('POST', url, { - action: event.target.dataset.action, - params: [functionInfo, functionParameters, additionalData], - containerId: window.containerId - }, responseHandler) - - valueEl.value = '' - }) - } -} - -function xmlHttpRequestHandler(type, url, data={}, callback) { - const http = new XMLHttpRequest(); - http.open(type, url, true); - http.onreadystatechange = function() { - if(http.readyState === XMLHttpRequest.DONE) { - callback(JSON.parse(http.responseText)) - } - } - http.setRequestHeader('Content-Type', 'application/json;charset=UTF-8'); - http.send(JSON.stringify(data)); -} - - -function responseHandler({action, response}) { - if(responseHandler[action]) { - responseHandler[action](response); - } -} - -responseHandler.deploySmartContract = function(response) { - document.getElementById('displayTransactionOutput').innerHTML = response -} - -responseHandler.getTransactionReceipt = function(response) { - document.getElementById('displayTransactionReceipt').innerHTML = response -} - -responseHandler.getContractByAddress = function(response) { - const abi = getSanitizedAbiValue(document.getElementById("abi").value) - const address = document.getElementById("smartContractAddress").value - deployedContracts.push({abi, address}) - const contractContainer = document.createElement('div') - contractContainer.className = 'deployedContractContainer' - contractContainer.setAttribute('data-abi', deployedContracts.length - 1) - document.getElementById('displayContract').appendChild(contractContainer) - JSON.parse(abi).forEach((f) => { - displayDeployedContractFunctions(f); - }) -} - -responseHandler.invokeContractFunction = function(response) { - console.log('Invoked smart contract function: ', response); - const {output, funcName, abiIndex} = JSON.parse(response); - const el = document.querySelector(`.${funcName}-output[data-abi="${abiIndex}"]`) - if(el) { - el.innerHTML = output - } - -} - -async function copyToClipboard(text) { - /*const dummy = document.createElement("textarea"); - document.body.appendChild(dummy); - dummy.value = text; - dummy.select(); - document.execCommand("copy"); - document.body.removeChild(dummy); - */ - return await navigator.clipboard.writeText(text) -} - -window.addEventListener('DOMContentLoaded', ()=> { - - url = `http://localhost:${window.blockchainPort}/smartcontracts` - - const accounts = document.getElementById('accounts'); - window.selectedAccount = accounts.options[accounts.selectedIndex].value; - accounts.addEventListener('change', (event)=> { - window.selectedAccount = event.target.options[event.target.selectedIndex].value - }) - - const copy = document.getElementById("copySelectedAccount") - - copy.addEventListener('click', ()=> { - copyToClipboard(window.selectedAccount) - }) - - const abiTextArea = document.getElementById('abi'); - const bytecodeTextArea = document.getElementById('bytecode'); - const parametersInput = document.getElementById('contract-params'); - const deployButton = document.getElementById('deploy') - - const valueEl = document.querySelector('#paymentSection input') - - deployButton.addEventListener('click', (event) => { - const abi = getSanitizedAbiValue(abiTextArea.value); - window.deployedAbi = abi - const bytecode = bytecodeTextArea.value.substring(0,2) !== '0x' ? '0x' + bytecodeTextArea.value : bytecodeTextArea.value; - const params = parametersInput.value.split(",").map(p => JSON.stringify(p)).join(","); - const value = valueEl.value || undefined; - - if(!abi || !bytecode) { - alert("Abi and Bytecode are mandatory") - return - } - - xmlHttpRequestHandler('POST', url, { - params: [window.selectedAccount, abi, bytecode, params, value], - action: event.target.dataset.action, - containerId: window.containerId - }, responseHandler) - - //bytecodeTextArea.value = '' - //parametersInput.value = '' - valueEl.value = '' - }) - - const getTransactionReceiptButton = document.getElementById("getTransactionReceipt"); - const transactionHashInput = document.getElementById("transactionHash") - - getTransactionReceiptButton.addEventListener('click', (event)=>{ - xmlHttpRequestHandler('POST', url, { - action: event.target.dataset.action, - params: [transactionHashInput.value], - containerId: window.containerId - }, responseHandler) - }) - - const getContractButton = document.getElementById("getSmartContract"); - const contractAddressInput = document.getElementById("smartContractAddress"); - - getContractButton.addEventListener('click', (event)=> { - xmlHttpRequestHandler('POST', url, { - action: event.target.dataset.action, - params: [getSanitizedAbiValue(abiTextArea.value), contractAddressInput.value], - containerId: window.containerId - }, responseHandler) - }) - -}) diff --git a/blockchain-client/src/routes/index.ts b/blockchain-client/src/routes/index.ts deleted file mode 100644 index a6d3d3251..000000000 --- a/blockchain-client/src/routes/index.ts +++ /dev/null @@ -1,36 +0,0 @@ -const express = require('express'); -const docker = require('../docker/index.ts'); -const DockerOdeWrapper = require('../DockerOdeWrapper.ts'); -const apis = require('../apis.ts'); -const getCommand = require('../commands.ts'); - -const router = express.Router(); - -router.get('/', async (req, res) => { - try { - const containers = await DockerOdeWrapper.docker.listContainers(docker) - res.render('home', { - port: process.env.PORT, - apis, - containers: containers.filter(container => container.Names[0].includes('Ethereum')) - }) - } catch(e) { - console.log(e) - } -}) - -router.post('/', async (req, res) => { - try { - const {containerId, command, params} = req.body; - const container = await DockerOdeWrapper.docker.getContainer(docker, containerId) - const output = await DockerOdeWrapper.container.exec(docker, container, getCommand(command, params)) - res.send(JSON.stringify({ - command, - output - })) - } catch(e) { - console.log(e) - } -}) - -module.exports = router; diff --git a/blockchain-client/src/routes/smartcontracts.ts b/blockchain-client/src/routes/smartcontracts.ts deleted file mode 100644 index f625e74ad..000000000 --- a/blockchain-client/src/routes/smartcontracts.ts +++ /dev/null @@ -1,72 +0,0 @@ -const express = require('express') -const docker = require('../docker/index.ts'); -const DockerOdeWrapper = require('../DockerOdeWrapper.ts'); -const getCommand = require('../commands.ts'); -const helpers = require('../common/helpers.ts') - - -const router = express.Router(); - -const sanitizeOutputForAction = { - deploySmartContract(output) { - return JSON.parse(helpers.stringToJsonString(helpers.sanitizeGethStreamString(output))).transactionHash; - }, - getTransactionReceipt(output) { - const res = JSON.parse(helpers.stringToJsonString(helpers.sanitizeGethStreamString(output))) - if(!res) { - return res - } - return res.contractAddress - }, - getContractByAddress(output) { - return helpers.stringToJsonString(helpers.sanitizeGethStreamString(output)) - }, - invokeContractFunction(output) { - return output - } -} - - -router.get('/', async (req, res) => { - try { - const containers = await DockerOdeWrapper.docker.listContainers(docker) - const [openForConnectionContainer] = containers.filter(container => container.Names[0].includes(process.env.CONTAINER)) - const container = await DockerOdeWrapper.docker.getContainer(docker, openForConnectionContainer.Id) - const accounts = await DockerOdeWrapper.container.exec(docker, container, getCommand("getAccounts")); - - res.render('smartcontract', { - accounts: JSON.parse(accounts), - port: process.env.PORT, - containerId: container.id, - }) - } catch(e) { - console.log(e) - } -}) - -router.post('/', async(req, res) => { - try { - const {params, action, containerId} = req.body; - const container = await DockerOdeWrapper.docker.getContainer(docker, containerId); - let output = await DockerOdeWrapper.container.exec(docker, container, getCommand(action, params)) - - if(action === 'invokeContractFunction') { - // giving some time for the network to mine the actual transaction - output = JSON.stringify({ - output: await DockerOdeWrapper.container.exec(docker, container, getCommand(action, params, {call:true})), - funcName: params[0].funcName, - abiIndex: params[0].abiIndex - }) - } - - res.send({ - action, - response: sanitizeOutputForAction[action](output) - }) - } catch(e) { - console.log(e) - } - -}) - -module.exports = router; diff --git a/blockchain-client/src/start.sh b/blockchain-client/src/start.sh deleted file mode 100644 index dfa2277d4..000000000 --- a/blockchain-client/src/start.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh -cd /usr/src/app/blockchain-client/src -while true; do npm run start; done diff --git a/blockchain-client/src/views/home.handlebars b/blockchain-client/src/views/home.handlebars deleted file mode 100644 index 82c5916de..000000000 --- a/blockchain-client/src/views/home.handlebars +++ /dev/null @@ -1,37 +0,0 @@ -
- -
- - - -
- -
- {{#each apis}} -
-
-

Description

-

{{description}}

-
-
- - {{#each parameters}} - <{{el}} class="apiParams" placeholder="{{name}}" required="{{required}}"/> - {{/each}} -
-
-

Output

-
-
- {{/each}} -
- -
- diff --git a/blockchain-client/src/views/layouts/main.handlebars b/blockchain-client/src/views/layouts/main.handlebars deleted file mode 100644 index 2d9005d21..000000000 --- a/blockchain-client/src/views/layouts/main.handlebars +++ /dev/null @@ -1,14 +0,0 @@ - - - - - Blockchain Interface - - - - {{{body}}} - - - diff --git a/blockchain-client/src/views/smartcontract.handlebars b/blockchain-client/src/views/smartcontract.handlebars deleted file mode 100644 index 1e7cb7284..000000000 --- a/blockchain-client/src/views/smartcontract.handlebars +++ /dev/null @@ -1,65 +0,0 @@ -
-
- - -
-
- - - -
-
-
-

Deploy contract

-
-
- - - - -
-
-

Transaction Hash

-
-
-
-
-
-

Get Contract Address

-
-
- - -
-
-

Contract address

-
-
-
-
-
-

Deployed Contracts

-
-
- - -
-
-

Contracts

-
-
-
-
- - diff --git a/client/backend/package-lock.json b/client/backend/package-lock.json index e6441d61f..1ddbaff2b 100644 --- a/client/backend/package-lock.json +++ b/client/backend/package-lock.json @@ -1,241 +1,941 @@ { "name": "container-manager-server", "version": "0.0.1", - "lockfileVersion": 1, + "lockfileVersion": 2, "requires": true, - "dependencies": { - "@ethereumjs/common": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/@ethereumjs/common/-/common-2.6.3.tgz", - "integrity": "sha512-mQwPucDL7FDYIg9XQ8DL31CnIYZwGhU5hyOO5E+BMmT71G0+RHvIT5rIkLBirJEKxV6+Rcf9aEIY0kXInxUWpQ==", - "requires": { - "crc-32": "^1.2.0", - "ethereumjs-util": "^7.1.4" + "packages": { + "": { + "name": "container-manager-server", + "version": "0.0.1", + "license": "MIT", + "dependencies": { + "@types/dockerode": "^3.2.2", + "@types/express": "^4.17.11", + "@types/express-ws": "^3.0.0", + "@types/node": "^14.10.1", + "@types/ws": "^7.2.6", + "dockerode": "^3.2.1", + "express": "^4.17.1", + "express-ws": "^4.0.0", + "tslog": "^3.0.5", + "ws": "^7.3.1" + } + }, + "node_modules/@types/body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ==", + "dependencies": { + "@types/connect": "*", + "@types/node": "*" } }, - "@ethereumjs/tx": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/@ethereumjs/tx/-/tx-3.5.1.tgz", - "integrity": "sha512-xzDrTiu4sqZXUcaBxJ4n4W5FrppwxLxZB4ZDGVLtxSQR4lVuOnFR6RcUHdg1mpUhAPVrmnzLJpxaeXnPxIyhWA==", - "requires": { - "@ethereumjs/common": "^2.6.3", - "ethereumjs-util": "^7.1.4" + "node_modules/@types/connect": { + "version": "3.4.34", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.34.tgz", + "integrity": "sha512-ePPA/JuI+X0vb+gSWlPKOY0NdNAie/rPUqX2GUPpbZwiKTkSPhjXWuee47E4MtE54QVzGCQMQkAL6JhV2E1+cQ==", + "dependencies": { + "@types/node": "*" } }, - "@ethersproject/abi": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.0.7.tgz", - "integrity": "sha512-Cqktk+hSIckwP/W8O47Eef60VwmoSC/L3lY0+dIBhQPCNn9E4V7rwmm2aFrNRRDJfFlGuZ1khkQUOc3oBX+niw==", - "requires": { - "@ethersproject/address": "^5.0.4", - "@ethersproject/bignumber": "^5.0.7", - "@ethersproject/bytes": "^5.0.4", - "@ethersproject/constants": "^5.0.4", - "@ethersproject/hash": "^5.0.4", - "@ethersproject/keccak256": "^5.0.3", - "@ethersproject/logger": "^5.0.5", - "@ethersproject/properties": "^5.0.3", - "@ethersproject/strings": "^5.0.4" - } - }, - "@ethersproject/abstract-provider": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.6.0.tgz", - "integrity": "sha512-oPMFlKLN+g+y7a79cLK3WiLcjWFnZQtXWgnLAbHZcN3s7L4v90UHpTOrLk+m3yr0gt+/h9STTM6zrr7PM8uoRw==", - "requires": { - "@ethersproject/bignumber": "^5.6.0", - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/networks": "^5.6.0", - "@ethersproject/properties": "^5.6.0", - "@ethersproject/transactions": "^5.6.0", - "@ethersproject/web": "^5.6.0" - } - }, - "@ethersproject/abstract-signer": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.6.0.tgz", - "integrity": "sha512-WOqnG0NJKtI8n0wWZPReHtaLkDByPL67tn4nBaDAhmVq8sjHTPbCdz4DRhVu/cfTOvfy9w3iq5QZ7BX7zw56BQ==", - "requires": { - "@ethersproject/abstract-provider": "^5.6.0", - "@ethersproject/bignumber": "^5.6.0", - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/properties": "^5.6.0" + "node_modules/@types/dockerode": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@types/dockerode/-/dockerode-3.2.2.tgz", + "integrity": "sha512-YtdVvc+WmxShwx0iBmn0AtiLL2Zbcak9gXqdeBp0UpiRyOcshZM0eVTOEkUKd4mIjHzSEpA+1P3lXb7ouYvDtQ==", + "dependencies": { + "@types/node": "*" } }, - "@ethersproject/address": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.6.0.tgz", - "integrity": "sha512-6nvhYXjbXsHPS+30sHZ+U4VMagFC/9zAk6Gd/h3S21YW4+yfb0WfRtaAIZ4kfM4rrVwqiy284LP0GtL5HXGLxQ==", - "requires": { - "@ethersproject/bignumber": "^5.6.0", - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/keccak256": "^5.6.0", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/rlp": "^5.6.0" + "node_modules/@types/express": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.11.tgz", + "integrity": "sha512-no+R6rW60JEc59977wIxreQVsIEOAYwgCqldrA/vkpCnbD7MqTefO97lmoBe4WE0F156bC4uLSP1XHDOySnChg==", + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.18", + "@types/qs": "*", + "@types/serve-static": "*" } }, - "@ethersproject/base64": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.6.0.tgz", - "integrity": "sha512-2Neq8wxJ9xHxCF9TUgmKeSh9BXJ6OAxWfeGWvbauPh8FuHEjamgHilllx8KkSd5ErxyHIX7Xv3Fkcud2kY9ezw==", - "requires": { - "@ethersproject/bytes": "^5.6.0" + "node_modules/@types/express-serve-static-core": { + "version": "4.17.18", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.18.tgz", + "integrity": "sha512-m4JTwx5RUBNZvky/JJ8swEJPKFd8si08pPF2PfizYjGZOKr/svUWPcoUmLow6MmPzhasphB7gSTINY67xn3JNA==", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*" } }, - "@ethersproject/bignumber": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.6.0.tgz", - "integrity": "sha512-VziMaXIUHQlHJmkv1dlcd6GY2PmT0khtAqaMctCIDogxkrarMzA9L94KN1NeXqqOfFD6r0sJT3vCTOFSmZ07DA==", - "requires": { - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/logger": "^5.6.0", - "bn.js": "^4.11.9" + "node_modules/@types/express-ws": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/express-ws/-/express-ws-3.0.0.tgz", + "integrity": "sha512-GxsWec7Vp6h7sJuK0PwnZHeXNZnOwQn8kHAbCfvii66it5jXHTWzSg5cgHVtESwJfBLOe9SJ5wmM7C6gsDoyQw==", + "dependencies": { + "@types/express": "*", + "@types/express-serve-static-core": "*", + "@types/ws": "*" } }, - "@ethersproject/bytes": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.6.1.tgz", - "integrity": "sha512-NwQt7cKn5+ZE4uDn+X5RAXLp46E1chXoaMmrxAyA0rblpxz8t58lVkrHXoRIn0lz1joQElQ8410GqhTqMOwc6g==", - "requires": { - "@ethersproject/logger": "^5.6.0" + "node_modules/@types/mime": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-2.0.3.tgz", + "integrity": "sha512-Jus9s4CDbqwocc5pOAnh8ShfrnMcPHuJYzVcSUU7lrh8Ni5HuIqX3oilL86p3dlTrk0LzHRCgA/GQ7uNCw6l2Q==" + }, + "node_modules/@types/node": { + "version": "14.14.20", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.20.tgz", + "integrity": "sha512-Y93R97Ouif9JEOWPIUyU+eyIdyRqQR0I8Ez1dzku4hDx34NWh4HbtIc3WNzwB1Y9ULvNGeu5B8h8bVL5cAk4/A==" + }, + "node_modules/@types/qs": { + "version": "6.9.5", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.5.tgz", + "integrity": "sha512-/JHkVHtx/REVG0VVToGRGH2+23hsYLHdyG+GrvoUGlGAd0ErauXDyvHtRI/7H7mzLm+tBCKA7pfcpkQ1lf58iQ==" + }, + "node_modules/@types/range-parser": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.3.tgz", + "integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==" + }, + "node_modules/@types/serve-static": { + "version": "1.13.8", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.8.tgz", + "integrity": "sha512-MoJhSQreaVoL+/hurAZzIm8wafFR6ajiTM1m4A0kv6AGeVBl4r4pOV8bGFrjjq1sGxDTnCoF8i22o0/aE5XCyA==", + "dependencies": { + "@types/mime": "*", + "@types/node": "*" } }, - "@ethersproject/constants": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.6.0.tgz", - "integrity": "sha512-SrdaJx2bK0WQl23nSpV/b1aq293Lh0sUaZT/yYKPDKn4tlAbkH96SPJwIhwSwTsoQQZxuh1jnqsKwyymoiBdWA==", - "requires": { - "@ethersproject/bignumber": "^5.6.0" + "node_modules/@types/ws": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.4.0.tgz", + "integrity": "sha512-Y29uQ3Uy+58bZrFLhX36hcI3Np37nqWE7ky5tjiDoy1GDZnIwVxS0CgF+s+1bXMzjKBFy+fqaRfb708iNzdinw==", + "dependencies": { + "@types/node": "*" } }, - "@ethersproject/hash": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.6.0.tgz", - "integrity": "sha512-fFd+k9gtczqlr0/BruWLAu7UAOas1uRRJvOR84uDf4lNZ+bTkGl366qvniUZHKtlqxBRU65MkOobkmvmpHU+jA==", - "requires": { - "@ethersproject/abstract-signer": "^5.6.0", - "@ethersproject/address": "^5.6.0", - "@ethersproject/bignumber": "^5.6.0", - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/keccak256": "^5.6.0", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/properties": "^5.6.0", - "@ethersproject/strings": "^5.6.0" - } - }, - "@ethersproject/keccak256": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.6.0.tgz", - "integrity": "sha512-tk56BJ96mdj/ksi7HWZVWGjCq0WVl/QvfhFQNeL8fxhBlGoP+L80uDCiQcpJPd+2XxkivS3lwRm3E0CXTfol0w==", - "requires": { - "@ethersproject/bytes": "^5.6.0", - "js-sha3": "0.8.0" + "node_modules/accepts": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "dependencies": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + }, + "engines": { + "node": ">= 0.6" } }, - "@ethersproject/logger": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.6.0.tgz", - "integrity": "sha512-BiBWllUROH9w+P21RzoxJKzqoqpkyM1pRnEKG69bulE9TSQD8SAIvTQqIMZmmCO8pUNkgLP1wndX1gKghSpBmg==" + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" }, - "@ethersproject/networks": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.6.1.tgz", - "integrity": "sha512-b2rrupf3kCTcc3jr9xOWBuHylSFtbpJf79Ga7QR98ienU2UqGimPGEsYMgbI29KHJfA5Us89XwGVmxrlxmSrMg==", - "requires": { - "@ethersproject/logger": "^5.6.0" + "node_modules/asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "dependencies": { + "safer-buffer": "~2.1.0" } }, - "@ethersproject/properties": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.6.0.tgz", - "integrity": "sha512-szoOkHskajKePTJSZ46uHUWWkbv7TzP2ypdEK6jGMqJaEt2sb0jCgfBo0gH0m2HBpRixMuJ6TBRaQCF7a9DoCg==", - "requires": { - "@ethersproject/logger": "^5.6.0" + "node_modules/async-limiter": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", + "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==" + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + }, + "node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dependencies": { + "tweetnacl": "^0.14.3" } }, - "@ethersproject/rlp": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.6.0.tgz", - "integrity": "sha512-dz9WR1xpcTL+9DtOT/aDO+YyxSSdO8YIS0jyZwHHSlAmnxA6cKU3TrTd4Xc/bHayctxTgGLYNuVVoiXE4tTq1g==", - "requires": { - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/logger": "^5.6.0" + "node_modules/bl": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.0.3.tgz", + "integrity": "sha512-fs4G6/Hu4/EE+F75J8DuN/0IpQqNjAdC7aEQv7Qt8MHGUH7Ckv2MwTEEeN9QehD0pfIDkMI1bkHYkKy7xHyKIg==", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" } }, - "@ethersproject/signing-key": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.6.0.tgz", - "integrity": "sha512-S+njkhowmLeUu/r7ir8n78OUKx63kBdMCPssePS89So1TH4hZqnWFsThEd/GiXYp9qMxVrydf7KdM9MTGPFukA==", - "requires": { - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/properties": "^5.6.0", - "bn.js": "^4.11.9", - "elliptic": "6.5.4", - "hash.js": "1.1.7" - } - }, - "@ethersproject/strings": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.6.0.tgz", - "integrity": "sha512-uv10vTtLTZqrJuqBZR862ZQjTIa724wGPWQqZrofaPI/kUsf53TBG0I0D+hQ1qyNtllbNzaW+PDPHHUI6/65Mg==", - "requires": { - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/constants": "^5.6.0", - "@ethersproject/logger": "^5.6.0" + "node_modules/body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "dependencies": { + "bytes": "3.1.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" + }, + "engines": { + "node": ">= 0.8" } }, - "@ethersproject/transactions": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.6.0.tgz", - "integrity": "sha512-4HX+VOhNjXHZyGzER6E/LVI2i6lf9ejYeWD6l4g50AdmimyuStKc39kvKf1bXWQMg7QNVh+uC7dYwtaZ02IXeg==", - "requires": { - "@ethersproject/address": "^5.6.0", - "@ethersproject/bignumber": "^5.6.0", - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/constants": "^5.6.0", - "@ethersproject/keccak256": "^5.6.0", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/properties": "^5.6.0", - "@ethersproject/rlp": "^5.6.0", - "@ethersproject/signing-key": "^5.6.0" - } - }, - "@ethersproject/web": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.6.0.tgz", - "integrity": "sha512-G/XHj0hV1FxI2teHRfCGvfBUHFmU+YOSbCxlAMqJklxSa7QMiHFQfAxvwY2PFqgvdkxEKwRNr/eCjfAPEm2Ctg==", - "requires": { - "@ethersproject/base64": "^5.6.0", - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/properties": "^5.6.0", - "@ethersproject/strings": "^5.6.0" + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/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==" + }, + "node_modules/bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" + }, + "node_modules/content-disposition": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", + "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", + "dependencies": { + "safe-buffer": "5.1.2" + }, + "engines": { + "node": ">= 0.6" } }, - "@sindresorhus/is": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", - "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==" + "node_modules/content-disposition/node_modules/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==" }, - "@szmarczak/http-timer": { + "node_modules/content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", + "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + }, + "node_modules/debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/depd": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", - "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", - "requires": { - "defer-to-connect": "^1.0.1" + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "engines": { + "node": ">= 0.6" } }, - "@types/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", - "requires": { - "@types/node": "*" + "node_modules/destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + }, + "node_modules/docker-modem": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/docker-modem/-/docker-modem-2.1.4.tgz", + "integrity": "sha512-vDTzZjjO1sXMY7m0xKjGdFMMZL7vIUerkC3G4l6rnrpOET2M6AOufM8ajmQoOB+6RfSn6I/dlikCUq/Y91Q1sQ==", + "dependencies": { + "debug": "^4.1.1", + "readable-stream": "^3.5.0", + "split-ca": "^1.0.1", + "ssh2": "^0.8.7" + }, + "engines": { + "node": ">= 8.0" + } + }, + "node_modules/dockerode": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/dockerode/-/dockerode-3.2.1.tgz", + "integrity": "sha512-XsSVB5Wu5HWMg1aelV5hFSqFJaKS5x1aiV/+sT7YOzOq1IRl49I/UwV8Pe4x6t0iF9kiGkWu5jwfvbkcFVupBw==", + "dependencies": { + "docker-modem": "^2.1.0", + "tar-fs": "~2.0.1" + }, + "engines": { + "node": ">= 8.0" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", + "engines": { + "node": ">= 0.6" } }, + "node_modules/express": { + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", + "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", + "dependencies": { + "accepts": "~1.3.7", + "array-flatten": "1.1.1", + "body-parser": "1.19.0", + "content-disposition": "0.5.3", + "content-type": "~1.0.4", + "cookie": "0.4.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.1.2", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.5", + "qs": "6.7.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.1.2", + "send": "0.17.1", + "serve-static": "1.14.1", + "setprototypeof": "1.1.1", + "statuses": "~1.5.0", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/express-ws": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/express-ws/-/express-ws-4.0.0.tgz", + "integrity": "sha512-KEyUw8AwRET2iFjFsI1EJQrJ/fHeGiJtgpYgEWG3yDv4l/To/m3a2GaYfeGyB3lsWdvbesjF5XCMx+SVBgAAYw==", + "dependencies": { + "ws": "^5.2.0" + }, + "engines": { + "node": ">=4.5.0" + } + }, + "node_modules/express-ws/node_modules/ws": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz", + "integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==", + "dependencies": { + "async-limiter": "~1.0.0" + } + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "node_modules/express/node_modules/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==" + }, + "node_modules/finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "node_modules/forwarded": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" + }, + "node_modules/http-errors": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", + "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/http-errors/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.45.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.45.0.tgz", + "integrity": "sha512-CkqLUxUk15hofLoLyljJSrukZi8mAtgd+yE5uO4tqRZsdsAJKv0O+rFMhVDRJgozy+yG6md5KwuXhD4ocIoP+w==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.28", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.28.tgz", + "integrity": "sha512-0TO2yJ5YHYr7M2zzT7gDU1tbwHxEUWBCLt0lscSNpcdAfFyJOVEpRYNS7EXVcTLNj/25QO8gulHC5JtTzSE2UQ==", + "dependencies": { + "mime-db": "1.45.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/negotiator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + }, + "node_modules/proxy-addr": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", + "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", + "dependencies": { + "forwarded": "~0.1.2", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", + "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", + "dependencies": { + "bytes": "3.1.0", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/send": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", + "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", + "dependencies": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.7.2", + "mime": "1.6.0", + "ms": "2.1.1", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" + }, + "node_modules/serve-static": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", + "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/split-ca": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/split-ca/-/split-ca-1.0.1.tgz", + "integrity": "sha1-bIOv82kvphJW4M0ZfgXp3hV2kaY=" + }, + "node_modules/ssh2": { + "version": "0.8.9", + "resolved": "https://registry.npmjs.org/ssh2/-/ssh2-0.8.9.tgz", + "integrity": "sha512-GmoNPxWDMkVpMFa9LVVzQZHF6EW3WKmBwL+4/GeILf2hFmix5Isxm7Amamo8o7bHiU0tC+wXsGcUXOxp8ChPaw==", + "dependencies": { + "ssh2-streams": "~0.4.10" + }, + "engines": { + "node": ">=5.2.0" + } + }, + "node_modules/ssh2-streams": { + "version": "0.4.10", + "resolved": "https://registry.npmjs.org/ssh2-streams/-/ssh2-streams-0.4.10.tgz", + "integrity": "sha512-8pnlMjvnIZJvmTzUIIA5nT4jr2ZWNNVHwyXfMGdRJbug9TpI3kd99ffglgfSWqujVv/0gxwMsDn9j9RVst8yhQ==", + "dependencies": { + "asn1": "~0.2.0", + "bcrypt-pbkdf": "^1.0.2", + "streamsearch": "~0.1.2" + }, + "engines": { + "node": ">=5.2.0" + } + }, + "node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/streamsearch": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", + "integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/tar-fs": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.0.1.tgz", + "integrity": "sha512-6tzWDMeroL87uF/+lin46k+Q+46rAJ0SyPGz7OW7wTgblI273hsBqk2C1j0/xNadNLKDTUL9BukSjB7cwgmlPA==", + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.0.0" + } + }, + "node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/tslog": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/tslog/-/tslog-3.0.5.tgz", + "integrity": "sha512-WyI2zFa6rVzXja6bKIZ9VeRKwHceqlUzCCo2IMsi6X5oswij95s3GJKve1Pr5bdlVIUMTsWaT/wtBiL7MT4PLQ==", + "dependencies": { + "source-map-support": "^0.5.19" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "node_modules/ws": { + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.2.tgz", + "integrity": "sha512-T4tewALS3+qsrpGI/8dqNMLIVdq/g/85U98HPMa6F0m6xTbvhXU6RCQLqPH3+SlomNV/LdY6RXEbBpMH6EOJnA==", + "engines": { + "node": ">=8.3.0" + } + } + }, + "dependencies": { "@types/body-parser": { "version": "1.19.0", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.0.tgz", @@ -302,14 +1002,6 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.20.tgz", "integrity": "sha512-Y93R97Ouif9JEOWPIUyU+eyIdyRqQR0I8Ez1dzku4hDx34NWh4HbtIc3WNzwB1Y9ULvNGeu5B8h8bVL5cAk4/A==" }, - "@types/pbkdf2": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.0.tgz", - "integrity": "sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==", - "requires": { - "@types/node": "*" - } - }, "@types/qs": { "version": "6.9.5", "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.5.tgz", @@ -320,14 +1012,6 @@ "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.3.tgz", "integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==" }, - "@types/secp256k1": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.3.tgz", - "integrity": "sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w==", - "requires": { - "@types/node": "*" - } - }, "@types/serve-static": { "version": "1.13.8", "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.8.tgz", @@ -354,17 +1038,6 @@ "negotiator": "0.6.2" } }, - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, "array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", @@ -378,55 +1051,11 @@ "safer-buffer": "~2.1.0" } }, - "asn1.js": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", - "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", - "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "safer-buffer": "^2.1.0" - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - }, "async-limiter": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==" }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, - "available-typed-arrays": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==" - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" - }, - "aws4": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", - "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==" - }, - "base-x": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz", - "integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==", - "requires": { - "safe-buffer": "^5.0.1" - } - }, "base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", @@ -440,11 +1069,6 @@ "tweetnacl": "^0.14.3" } }, - "bignumber.js": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.2.tgz", - "integrity": "sha512-GAcQvbpsM0pUb0zw1EI0KhQEZ+lRwR5fYaAp3vPOYuP7aDvGy6cVN6XHLauvF8SOga2y0dcLcjt3iQDTSEliyw==" - }, "bl": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/bl/-/bl-4.0.3.tgz", @@ -455,38 +1079,21 @@ "readable-stream": "^3.4.0" } }, - "blakejs": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.2.1.tgz", - "integrity": "sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==" - }, - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" - }, - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - }, "body-parser": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz", - "integrity": "sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==", + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", "requires": { - "bytes": "3.1.2", + "bytes": "3.1.0", "content-type": "~1.0.4", "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", + "depd": "~1.1.2", + "http-errors": "1.7.2", "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.10.3", - "raw-body": "2.5.1", - "type-is": "~1.6.18", - "unpipe": "1.0.0" + "on-finished": "~2.3.0", + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" }, "dependencies": { "debug": { @@ -497,162 +1104,13 @@ "ms": "2.0.0" } }, - "depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" - }, - "destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==" - }, - "http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "requires": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - } - }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "requires": { - "ee-first": "1.1.1" - } - }, - "qs": { - "version": "6.10.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", - "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", - "requires": { - "side-channel": "^1.0.4" - } - }, - "setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" - }, - "statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" - }, - "toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" - } - } - }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" - }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "browserify-rsa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", - "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", - "requires": { - "bn.js": "^5.0.0", - "randombytes": "^2.0.1" - }, - "dependencies": { - "bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" - } - } - }, - "browserify-sign": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz", - "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==", - "requires": { - "bn.js": "^5.1.1", - "browserify-rsa": "^4.0.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.3", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.5", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "dependencies": { - "bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" } } }, - "bs58": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", - "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=", - "requires": { - "base-x": "^3.0.2" - } - }, - "bs58check": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", - "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", - "requires": { - "bs58": "^4.0.0", - "create-hash": "^1.1.0", - "safe-buffer": "^5.1.2" - } - }, "buffer": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", @@ -667,130 +1125,16 @@ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" }, - "buffer-to-arraybuffer": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/buffer-to-arraybuffer/-/buffer-to-arraybuffer-0.0.5.tgz", - "integrity": "sha1-YGSkD6dutDxyOrqe+PbhIW0QURo=" - }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=" - }, - "bufferutil": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.6.tgz", - "integrity": "sha512-jduaYOYtnio4aIAyc6UbvPCVcgq7nYpVnucyxr6eCYg/Woad9Hf/oxxBRDnGGjPfjUm6j5O/uBWhIu4iLebFaw==", - "requires": { - "node-gyp-build": "^4.3.0" - } - }, "bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" - }, - "cacheable-request": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", - "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", - "requires": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^3.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^4.1.0", - "responselike": "^1.0.2" - }, - "dependencies": { - "get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "requires": { - "pump": "^3.0.0" - } - }, - "lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==" - } - } - }, - "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" }, "chownr": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" }, - "cids": { - "version": "0.7.5", - "resolved": "https://registry.npmjs.org/cids/-/cids-0.7.5.tgz", - "integrity": "sha512-zT7mPeghoWAu+ppn8+BS1tQ5qGmbMfB4AregnQjA/qHY3GC1m1ptI9GkWNlgeu38r7CuRdXB47uY2XgAYt6QVA==", - "requires": { - "buffer": "^5.5.0", - "class-is": "^1.1.0", - "multibase": "~0.6.0", - "multicodec": "^1.0.0", - "multihashes": "~0.4.15" - }, - "dependencies": { - "multicodec": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/multicodec/-/multicodec-1.0.4.tgz", - "integrity": "sha512-NDd7FeS3QamVtbgfvu5h7fd1IlbaC4EQ0/pgU4zqE2vdHCmBGsUa0TiM8/TdSeG6BMPC92OOCf8F1ocE/Wkrrg==", - "requires": { - "buffer": "^5.6.0", - "varint": "^5.0.0" - } - } - } - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "class-is": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/class-is/-/class-is-1.1.0.tgz", - "integrity": "sha512-rhjH9AG1fvabIDoGRVH587413LPjTZgmDF9fOFCbFJQV4yuocX1mHxxvXI4g3cGwbVY9wAYIoKlg1N79frJKQw==" - }, - "clone-response": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", - "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", - "requires": { - "mimic-response": "^1.0.0" - } - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "requires": { - "delayed-stream": "~1.0.0" - } - }, "content-disposition": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", @@ -806,16 +1150,6 @@ } } }, - "content-hash": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/content-hash/-/content-hash-2.5.2.tgz", - "integrity": "sha512-FvIQKy0S1JaWV10sMsA7TRx8bpU+pqPkhbsfvOJAdjRXvYxEckAwQWGwtRjiaJfh+E0DvcWUGqcdjwMGFjsSdw==", - "requires": { - "cids": "^0.7.1", - "multicodec": "^0.5.5", - "multihashes": "^0.4.15" - } - }, "content-type": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", @@ -831,99 +1165,6 @@ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" }, - "cookiejar": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.3.tgz", - "integrity": "sha512-JxbCBUdrfr6AQjOXrxoTvAMJO4HBTUIlBzslcJPAz+/KT8yk53fXun51u+RenNYvad/+Vc2DIz5o9UxlCDymFQ==" - }, - "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=" - }, - "cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", - "requires": { - "object-assign": "^4", - "vary": "^1" - } - }, - "crc-32": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", - "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==" - }, - "create-ecdh": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", - "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", - "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.5.3" - } - }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "requires": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - } - }, - "d": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", - "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", - "requires": { - "es5-ext": "^0.10.50", - "type": "^1.0.1" - } - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "requires": { - "assert-plus": "^1.0.0" - } - }, "debug": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", @@ -932,66 +1173,16 @@ "ms": "2.1.2" } }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=" - }, - "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" - } - }, - "defer-to-connect": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", - "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==" - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "requires": { - "object-keys": "^1.0.12" - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" - }, "depd": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" }, - "des.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", - "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", - "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, "destroy": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" }, - "diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - } - }, "docker-modem": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/docker-modem/-/docker-modem-2.1.4.tgz", @@ -1012,44 +1203,11 @@ "tar-fs": "~2.0.1" } }, - "dom-walk": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz", - "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==" - }, - "duplexer3": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", - "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=" - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, "ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, - "elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", - "requires": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - } - }, "encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", @@ -1063,72 +1221,6 @@ "once": "^1.4.0" } }, - "es-abstract": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.2.tgz", - "integrity": "sha512-gfSBJoZdlL2xRiOCy0g8gLMryhoe1TlimjzU99L/31Z8QEGIhVQI+EWwt5lT+AuU9SnorVupXFqqOGqGfsyO6w==", - "requires": { - "call-bind": "^1.0.2", - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "get-intrinsic": "^1.1.1", - "get-symbol-description": "^1.0.0", - "has": "^1.0.3", - "has-symbols": "^1.0.3", - "internal-slot": "^1.0.3", - "is-callable": "^1.2.4", - "is-negative-zero": "^2.0.2", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.1", - "is-string": "^1.0.7", - "is-weakref": "^1.0.2", - "object-inspect": "^1.12.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.2", - "string.prototype.trimend": "^1.0.4", - "string.prototype.trimstart": "^1.0.4", - "unbox-primitive": "^1.0.1" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "es5-ext": { - "version": "0.10.59", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.59.tgz", - "integrity": "sha512-cOgyhW0tIJyQY1Kfw6Kr0viu9ZlUctVchRMZ7R0HiH3dxTSp5zJDLecwxUqPUrGKMsgBI1wd1FL+d9Jxfi4cLw==", - "requires": { - "es6-iterator": "^2.0.3", - "es6-symbol": "^3.1.3", - "next-tick": "^1.1.0" - } - }, - "es6-iterator": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", - "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", - "requires": { - "d": "1", - "es5-ext": "^0.10.35", - "es6-symbol": "^3.1.1" - } - }, - "es6-symbol": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", - "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", - "requires": { - "d": "^1.0.1", - "ext": "^1.1.2" - } - }, "escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", @@ -1139,139 +1231,6 @@ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" }, - "eth-ens-namehash": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/eth-ens-namehash/-/eth-ens-namehash-2.0.8.tgz", - "integrity": "sha1-IprEbsqG1S4MmR58sq74P/D2i88=", - "requires": { - "idna-uts46-hx": "^2.3.1", - "js-sha3": "^0.5.7" - }, - "dependencies": { - "js-sha3": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", - "integrity": "sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc=" - } - } - }, - "eth-lib": { - "version": "0.1.29", - "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.1.29.tgz", - "integrity": "sha512-bfttrr3/7gG4E02HoWTDUcDDslN003OlOoBxk9virpAZQ1ja/jDgwkWB8QfJF7ojuEowrqy+lzp9VcJG7/k5bQ==", - "requires": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "nano-json-stream-parser": "^0.1.2", - "servify": "^0.1.12", - "ws": "^3.0.0", - "xhr-request-promise": "^0.1.2" - }, - "dependencies": { - "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==" - }, - "ws": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", - "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", - "requires": { - "async-limiter": "~1.0.0", - "safe-buffer": "~5.1.0", - "ultron": "~1.1.0" - } - } - } - }, - "ethereum-bloom-filters": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/ethereum-bloom-filters/-/ethereum-bloom-filters-1.0.10.tgz", - "integrity": "sha512-rxJ5OFN3RwjQxDcFP2Z5+Q9ho4eIdEmSc2ht0fCu8Se9nbXjZ7/031uXoUYJ87KHCOdVeiUuwSnoS7hmYAGVHA==", - "requires": { - "js-sha3": "^0.8.0" - } - }, - "ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "requires": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - }, - "ethereumjs-util": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.4.tgz", - "integrity": "sha512-p6KmuPCX4mZIqsQzXfmSx9Y0l2hqf+VkAiwSisW3UKUFdk8ZkAt+AYaor83z2nSi6CU2zSsXMlD80hAbNEGM0A==", - "requires": { - "@types/bn.js": "^5.1.0", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.2.4" - }, - "dependencies": { - "@types/bn.js": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz", - "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==", - "requires": { - "@types/node": "*" - } - }, - "bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" - } - } - }, - "ethjs-unit": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz", - "integrity": "sha1-xmWSHkduh7ziqdWIpv4EBbLEFpk=", - "requires": { - "bn.js": "4.11.6", - "number-to-bn": "1.7.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=" - } - } - }, - "eventemitter3": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.4.tgz", - "integrity": "sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ==" - }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, "express": { "version": "4.17.1", "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", @@ -1309,28 +1268,6 @@ "vary": "~1.1.2" }, "dependencies": { - "body-parser": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", - "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", - "requires": { - "bytes": "3.1.0", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.7.0", - "raw-body": "2.4.0", - "type-is": "~1.6.17" - } - }, - "bytes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" - }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -1344,17 +1281,6 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, - "raw-body": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", - "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", - "requires": { - "bytes": "3.1.0", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - } - }, "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -1380,41 +1306,6 @@ } } }, - "ext": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/ext/-/ext-1.6.0.tgz", - "integrity": "sha512-sdBImtzkq2HpkdRLtlLWDa6w4DX22ijZLKx8BMPUuKe1c5lbN6xwQDQCxSfxBQnHZ13ls/FH0MQZx/q/gr6FQg==", - "requires": { - "type": "^2.5.0" - }, - "dependencies": { - "type": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/type/-/type-2.6.0.tgz", - "integrity": "sha512-eiDBDOmkih5pMbo9OqsqPRGMljLodLcwd5XD5JbtNB0o89xZAwynY9EdCDsJU7LtcVCClu9DvM7/0Ep1hYX3EQ==" - } - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" - }, "finalhandler": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", @@ -1444,26 +1335,6 @@ } } }, - "foreach": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", - "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=" - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" - }, - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, "forwarded": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", @@ -1479,183 +1350,6 @@ "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" }, - "fs-extra": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", - "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "fs-minipass": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", - "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", - "requires": { - "minipass": "^2.6.0" - } - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" - } - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "requires": { - "pump": "^3.0.0" - } - }, - "get-symbol-description": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", - "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" - } - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "global": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz", - "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==", - "requires": { - "min-document": "^2.19.0", - "process": "^0.11.10" - } - }, - "got": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", - "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", - "requires": { - "@sindresorhus/is": "^0.14.0", - "@szmarczak/http-timer": "^1.1.2", - "cacheable-request": "^6.0.0", - "decompress-response": "^3.3.0", - "duplexer3": "^0.1.4", - "get-stream": "^4.1.0", - "lowercase-keys": "^1.0.1", - "mimic-response": "^1.0.1", - "p-cancelable": "^1.0.0", - "to-readable-stream": "^1.0.0", - "url-parse-lax": "^3.0.0" - } - }, - "graceful-fs": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" - }, - "har-validator": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", - "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", - "requires": { - "ajv": "^6.12.3", - "har-schema": "^2.0.0" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-bigints": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", - "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==" - }, - "has-symbol-support-x": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz", - "integrity": "sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==" - }, - "has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" - }, - "has-to-string-tag-x": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz", - "integrity": "sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==", - "requires": { - "has-symbol-support-x": "^1.4.1" - } - }, - "has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "requires": { - "has-symbols": "^1.0.2" - } - }, - "hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "requires": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - } - }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "http-cache-semantics": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", - "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==" - }, "http-errors": { "version": "1.7.2", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", @@ -1675,21 +1369,6 @@ } } }, - "http-https": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/http-https/-/http-https-1.0.0.tgz", - "integrity": "sha1-L5CN1fHbQGjAWM1ubUzjkskTOJs=" - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, "iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -1698,21 +1377,6 @@ "safer-buffer": ">= 2.1.2 < 3" } }, - "idna-uts46-hx": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/idna-uts46-hx/-/idna-uts46-hx-2.3.1.tgz", - "integrity": "sha512-PWoF9Keq6laYdIRwwCdhTPl60xRqAloYNMQLiyUnG42VjT53oW07BXIRM+NK7eQjzXjAk2gUvX9caRxlnF9TAA==", - "requires": { - "punycode": "2.1.0" - }, - "dependencies": { - "punycode": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.0.tgz", - "integrity": "sha1-X4Y+3Im5bbCQdLrXlHvwkFbKTn0=" - } - } - }, "ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", @@ -1723,265 +1387,11 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, - "internal-slot": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", - "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", - "requires": { - "get-intrinsic": "^1.1.0", - "has": "^1.0.3", - "side-channel": "^1.0.4" - } - }, "ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" }, - "is-arguments": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", - "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "requires": { - "has-bigints": "^1.0.1" - } - }, - "is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-callable": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", - "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==" - }, - "is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-function": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.2.tgz", - "integrity": "sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==" - }, - "is-generator-function": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", - "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-hex-prefixed": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz", - "integrity": "sha1-fY035q135dEnFIkTxXPggtd39VQ=" - }, - "is-negative-zero": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", - "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==" - }, - "is-number-object": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.2.tgz", - "integrity": "sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA==" - }, - "is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=" - }, - "is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-retry-allowed": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz", - "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==" - }, - "is-shared-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", - "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", - "requires": { - "call-bind": "^1.0.2" - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, - "is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "requires": { - "has-symbols": "^1.0.2" - } - }, - "is-typed-array": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.8.tgz", - "integrity": "sha512-HqH41TNZq2fgtGT8WHVFVJhBVGuY3AnP3Q36K8JKXUxSxRgk/d+7NjmwG2vo2mYmXK8UYZKu0qH8bVP5gEisjA==", - "requires": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "es-abstract": "^1.18.5", - "foreach": "^2.0.5", - "has-tostringtag": "^1.0.0" - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" - }, - "is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", - "requires": { - "call-bind": "^1.0.2" - } - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" - }, - "isurl": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isurl/-/isurl-1.0.0.tgz", - "integrity": "sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==", - "requires": { - "has-to-string-tag-x": "^1.2.0", - "is-object": "^1.0.1" - } - }, - "js-sha3": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", - "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==" - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" - }, - "json-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", - "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=" - }, - "json-schema": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", - "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==" - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "jsprim": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", - "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.4.0", - "verror": "1.10.0" - } - }, - "keccak": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.2.tgz", - "integrity": "sha512-PyKKjkH53wDMLGrvmRGSNWgmSxZOUqbnXwKL9tmgbFYA1iAYqW21kfR7mZXV0MlESiefxQQE9X9fTa3X+2MPDQ==", - "requires": { - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0", - "readable-stream": "^3.6.0" - } - }, - "keyv": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", - "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", - "requires": { - "json-buffer": "3.0.0" - } - }, - "lowercase-keys": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", - "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==" - }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, "media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -1997,15 +1407,6 @@ "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" }, - "miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - } - }, "mime": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", @@ -2024,202 +1425,21 @@ "mime-db": "1.45.0" } }, - "mimic-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==" - }, - "min-document": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", - "integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=", - "requires": { - "dom-walk": "^0.1.0" - } - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" - }, - "minimist": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" - }, - "minipass": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", - "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, - "minizlib": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", - "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", - "requires": { - "minipass": "^2.9.0" - } - }, - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" - }, "mkdirp-classic": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" }, - "mkdirp-promise": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/mkdirp-promise/-/mkdirp-promise-5.0.1.tgz", - "integrity": "sha1-6bj2jlUsaKnBcTuEiD96HdA5uKE=", - "requires": { - "mkdirp": "*" - } - }, - "mock-fs": { - "version": "4.14.0", - "resolved": "https://registry.npmjs.org/mock-fs/-/mock-fs-4.14.0.tgz", - "integrity": "sha512-qYvlv/exQ4+svI3UOvPUpLDF0OMX5euvUH0Ny4N5QyRyhNdgAgUrVH3iUINSzEPLvx0kbo/Bp28GJKIqvE7URw==" - }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, - "multibase": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/multibase/-/multibase-0.6.1.tgz", - "integrity": "sha512-pFfAwyTjbbQgNc3G7D48JkJxWtoJoBMaR4xQUOuB8RnCgRqaYmWNFeJTTvrJ2w51bjLq2zTby6Rqj9TQ9elSUw==", - "requires": { - "base-x": "^3.0.8", - "buffer": "^5.5.0" - } - }, - "multicodec": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/multicodec/-/multicodec-0.5.7.tgz", - "integrity": "sha512-PscoRxm3f+88fAtELwUnZxGDkduE2HD9Q6GHUOywQLjOGT/HAdhjLDYNZ1e7VR0s0TP0EwZ16LNUTFpoBGivOA==", - "requires": { - "varint": "^5.0.0" - } - }, - "multihashes": { - "version": "0.4.21", - "resolved": "https://registry.npmjs.org/multihashes/-/multihashes-0.4.21.tgz", - "integrity": "sha512-uVSvmeCWf36pU2nB4/1kzYZjsXD9vofZKpgudqkceYY5g2aZZXJ5r9lxuzoRLl1OAp28XljXsEJ/X/85ZsKmKw==", - "requires": { - "buffer": "^5.5.0", - "multibase": "^0.7.0", - "varint": "^5.0.0" - }, - "dependencies": { - "multibase": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/multibase/-/multibase-0.7.0.tgz", - "integrity": "sha512-TW8q03O0f6PNFTQDvh3xxH03c8CjGaaYrjkl9UQPG6rz53TQzzxJVCIWVjzcbN/Q5Y53Zd0IBQBMVktVgNx4Fg==", - "requires": { - "base-x": "^3.0.8", - "buffer": "^5.5.0" - } - } - } - }, - "nano-json-stream-parser": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/nano-json-stream-parser/-/nano-json-stream-parser-0.1.2.tgz", - "integrity": "sha1-DMj20OK2IrR5xA1JnEbWS3Vcb18=" - }, "negotiator": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" }, - "next-tick": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", - "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==" - }, - "node-addon-api": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", - "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==" - }, - "node-gyp-build": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.4.0.tgz", - "integrity": "sha512-amJnQCcgtRVw9SvoebO3BKGESClrfXGCUTX9hSn1OuGQTQBOZmVd0Z0OlecpuRksKvbsUqALE8jls/ErClAPuQ==" - }, - "normalize-url": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", - "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==" - }, - "number-to-bn": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/number-to-bn/-/number-to-bn-1.7.0.tgz", - "integrity": "sha1-uzYjWS9+X54AMLGXe9QaDFP+HqA=", - "requires": { - "bn.js": "4.11.6", - "strip-hex-prefix": "1.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=" - } - } - }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" - }, - "object-inspect": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", - "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==" - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" - }, - "object.assign": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", - "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", - "object-keys": "^1.1.1" - } - }, - "oboe": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/oboe/-/oboe-2.1.5.tgz", - "integrity": "sha1-VVQoTFQ6ImbXo48X4HOCH73jk80=", - "requires": { - "http-https": "^1.0.0" - } - }, "on-finished": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", @@ -2236,41 +1456,6 @@ "wrappy": "1" } }, - "p-cancelable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", - "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==" - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" - }, - "p-timeout": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-1.2.1.tgz", - "integrity": "sha1-XrOzU7f86Z8QGhA4iAuwVOu+o4Y=", - "requires": { - "p-finally": "^1.0.0" - } - }, - "parse-asn1": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", - "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", - "requires": { - "asn1.js": "^5.2.0", - "browserify-aes": "^1.0.0", - "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3", - "safe-buffer": "^5.1.1" - } - }, - "parse-headers": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.5.tgz", - "integrity": "sha512-ft3iAoLOB/MlwbNXgzy43SWGP6sQki2jQvAyBg/zDFAgr9bfNWZIUj42Kw2eJIl8kEi4PbgE6U1Zau/HwI75HA==" - }, "parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -2281,58 +1466,13 @@ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" }, - "pbkdf2": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", - "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" - }, - "prepend-http": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", - "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=" - }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=" - }, "proxy-addr": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", - "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", - "requires": { - "forwarded": "~0.1.2", - "ipaddr.js": "1.9.1" - } - }, - "psl": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", - "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" - }, - "public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", + "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", "requires": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" + "forwarded": "~0.1.2", + "ipaddr.js": "1.9.1" } }, "pump": { @@ -2344,91 +1484,25 @@ "once": "^1.3.1" } }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" - }, "qs": { "version": "6.7.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" }, - "query-string": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz", - "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==", - "requires": { - "decode-uri-component": "^0.2.0", - "object-assign": "^4.1.0", - "strict-uri-encode": "^1.0.0" - } - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, "range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" }, "raw-body": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", - "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", + "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", "requires": { - "bytes": "3.1.2", - "http-errors": "2.0.0", + "bytes": "3.1.0", + "http-errors": "1.7.2", "iconv-lite": "0.4.24", "unpipe": "1.0.0" - }, - "dependencies": { - "depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" - }, - "http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "requires": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - } - }, - "setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" - }, - "statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" - }, - "toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" - } } }, "readable-stream": { @@ -2441,72 +1515,6 @@ "util-deprecate": "^1.0.1" } }, - "request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - }, - "dependencies": { - "qs": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", - "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==" - } - } - }, - "responselike": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", - "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", - "requires": { - "lowercase-keys": "^1.0.0" - } - }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "rlp": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.7.tgz", - "integrity": "sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ==", - "requires": { - "bn.js": "^5.2.0" - }, - "dependencies": { - "bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" - } - } - }, "safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -2517,21 +1525,6 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, - "scrypt-js": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", - "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==" - }, - "secp256k1": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.3.tgz", - "integrity": "sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA==", - "requires": { - "elliptic": "^6.5.4", - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0" - } - }, "send": { "version": "0.17.1", "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", @@ -2585,62 +1578,11 @@ "send": "0.17.1" } }, - "servify": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/servify/-/servify-0.1.12.tgz", - "integrity": "sha512-/xE6GvsKKqyo1BAY+KxOWXcLpPsUUyji7Qg3bVD7hh1eRze5bR1uYiuDA/k3Gof1s9BTzQZEJK8sNcNGFIzeWw==", - "requires": { - "body-parser": "^1.16.0", - "cors": "^2.8.1", - "express": "^4.14.0", - "request": "^2.79.0", - "xhr": "^2.3.3" - } - }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" - }, "setprototypeof": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "requires": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - } - }, - "simple-concat": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", - "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==" - }, - "simple-get": { - "version": "2.8.2", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.8.2.tgz", - "integrity": "sha512-Ijd/rV5o+mSBBs4F/x9oDPtTx9Zb6X9brmnXvMW4J7IR15ngi9q5xxqWBKU744jTZiaXtxaPL7uHG6vtN8kUkw==", - "requires": { - "decompress-response": "^3.3.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" - } - }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -2678,22 +1620,6 @@ "streamsearch": "~0.1.2" } }, - "sshpk": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz", - "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==", - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - } - }, "statuses": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", @@ -2704,29 +1630,6 @@ "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", "integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=" }, - "strict-uri-encode": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", - "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=" - }, - "string.prototype.trimend": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", - "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "string.prototype.trimstart": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", - "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, "string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -2735,102 +1638,6 @@ "safe-buffer": "~5.2.0" } }, - "strip-hex-prefix": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz", - "integrity": "sha1-DF8VX+8RUTczd96du1iNoFUA428=", - "requires": { - "is-hex-prefixed": "1.0.0" - } - }, - "swarm-js": { - "version": "0.1.40", - "resolved": "https://registry.npmjs.org/swarm-js/-/swarm-js-0.1.40.tgz", - "integrity": "sha512-yqiOCEoA4/IShXkY3WKwP5PvZhmoOOD8clsKA7EEcRILMkTEYHCQ21HDCAcVpmIxZq4LyZvWeRJ6quIyHk1caA==", - "requires": { - "bluebird": "^3.5.0", - "buffer": "^5.0.5", - "eth-lib": "^0.1.26", - "fs-extra": "^4.0.2", - "got": "^7.1.0", - "mime-types": "^2.1.16", - "mkdirp-promise": "^5.0.1", - "mock-fs": "^4.1.0", - "setimmediate": "^1.0.5", - "tar": "^4.0.2", - "xhr-request": "^1.0.1" - }, - "dependencies": { - "get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=" - }, - "got": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/got/-/got-7.1.0.tgz", - "integrity": "sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw==", - "requires": { - "decompress-response": "^3.2.0", - "duplexer3": "^0.1.4", - "get-stream": "^3.0.0", - "is-plain-obj": "^1.1.0", - "is-retry-allowed": "^1.0.0", - "is-stream": "^1.0.0", - "isurl": "^1.0.0-alpha5", - "lowercase-keys": "^1.0.0", - "p-cancelable": "^0.3.0", - "p-timeout": "^1.1.1", - "safe-buffer": "^5.0.1", - "timed-out": "^4.0.0", - "url-parse-lax": "^1.0.0", - "url-to-options": "^1.0.1" - } - }, - "p-cancelable": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.3.0.tgz", - "integrity": "sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw==" - }, - "prepend-http": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", - "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=" - }, - "url-parse-lax": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", - "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", - "requires": { - "prepend-http": "^1.0.1" - } - } - } - }, - "tar": { - "version": "4.4.19", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.19.tgz", - "integrity": "sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA==", - "requires": { - "chownr": "^1.1.4", - "fs-minipass": "^1.2.7", - "minipass": "^2.9.0", - "minizlib": "^1.3.3", - "mkdirp": "^0.5.5", - "safe-buffer": "^5.2.1", - "yallist": "^3.1.1" - }, - "dependencies": { - "mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "requires": { - "minimist": "^1.2.6" - } - } - } - }, "tar-fs": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.0.1.tgz", @@ -2854,30 +1661,11 @@ "readable-stream": "^3.1.1" } }, - "timed-out": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", - "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=" - }, - "to-readable-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", - "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==" - }, "toidentifier": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" }, - "tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "requires": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - } - }, "tslog": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/tslog/-/tslog-3.0.5.tgz", @@ -2886,24 +1674,11 @@ "source-map-support": "^0.5.19" } }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "requires": { - "safe-buffer": "^5.0.1" - } - }, "tweetnacl": { "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" }, - "type": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", - "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==" - }, "type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", @@ -2913,92 +1688,11 @@ "mime-types": "~2.1.24" } }, - "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" - } - }, - "ultron": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", - "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==" - }, - "unbox-primitive": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", - "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", - "requires": { - "function-bind": "^1.1.1", - "has-bigints": "^1.0.1", - "has-symbols": "^1.0.2", - "which-boxed-primitive": "^1.0.2" - } - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" - }, "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" }, - "uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "requires": { - "punycode": "^2.1.0" - } - }, - "url-parse-lax": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", - "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", - "requires": { - "prepend-http": "^2.0.0" - } - }, - "url-set-query": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/url-set-query/-/url-set-query-1.0.0.tgz", - "integrity": "sha1-AW6M/Xwg7gXK/neV6JK9BwL6ozk=" - }, - "url-to-options": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/url-to-options/-/url-to-options-1.0.1.tgz", - "integrity": "sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k=" - }, - "utf-8-validate": { - "version": "5.0.9", - "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.9.tgz", - "integrity": "sha512-Yek7dAy0v3Kl0orwMlvi7TPtiCNrdfHNd7Gcc/pLq4BLXqfAmd0J7OWMizUQnTTJsyjKn02mU7anqwfmUP4J8Q==", - "requires": { - "node-gyp-build": "^4.3.0" - } - }, - "utf8": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz", - "integrity": "sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==" - }, - "util": { - "version": "0.12.4", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.4.tgz", - "integrity": "sha512-bxZ9qtSlGUWSOy9Qa9Xgk11kSslpuZwaxCg4sNIDj6FLucDab2JxnHwyNTCpHMtK1MjoQiWQ6DiUMZYbSrO+Sw==", - "requires": { - "inherits": "^2.0.3", - "is-arguments": "^1.0.4", - "is-generator-function": "^1.0.7", - "is-typed-array": "^1.1.3", - "safe-buffer": "^5.1.2", - "which-typed-array": "^1.1.2" - } - }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -3009,371 +1703,11 @@ "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" }, - "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" - }, - "varint": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/varint/-/varint-5.0.2.tgz", - "integrity": "sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow==" - }, "vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "web3": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3/-/web3-1.7.1.tgz", - "integrity": "sha512-RKVdyZ5FuVEykj62C1o2tc0teJciSOh61jpVB9yb344dBHO3ZV4XPPP24s/PPqIMXmVFN00g2GD9M/v1SoHO/A==", - "requires": { - "web3-bzz": "1.7.1", - "web3-core": "1.7.1", - "web3-eth": "1.7.1", - "web3-eth-personal": "1.7.1", - "web3-net": "1.7.1", - "web3-shh": "1.7.1", - "web3-utils": "1.7.1" - } - }, - "web3-bzz": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.7.1.tgz", - "integrity": "sha512-sVeUSINx4a4pfdnT+3ahdRdpDPvZDf4ZT/eBF5XtqGWq1mhGTl8XaQAk15zafKVm6Onq28vN8abgB/l+TrG8kA==", - "requires": { - "@types/node": "^12.12.6", - "got": "9.6.0", - "swarm-js": "^0.1.40" - }, - "dependencies": { - "@types/node": { - "version": "12.20.47", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.47.tgz", - "integrity": "sha512-BzcaRsnFuznzOItW1WpQrDHM7plAa7GIDMZ6b5pnMbkqEtM/6WCOhvZar39oeMQP79gwvFUWjjptE7/KGcNqFg==" - } - } - }, - "web3-core": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.7.1.tgz", - "integrity": "sha512-HOyDPj+4cNyeNPwgSeUkhtS0F+Pxc2obcm4oRYPW5ku6jnTO34pjaij0us+zoY3QEusR8FfAKVK1kFPZnS7Dzw==", - "requires": { - "@types/bn.js": "^4.11.5", - "@types/node": "^12.12.6", - "bignumber.js": "^9.0.0", - "web3-core-helpers": "1.7.1", - "web3-core-method": "1.7.1", - "web3-core-requestmanager": "1.7.1", - "web3-utils": "1.7.1" - }, - "dependencies": { - "@types/node": { - "version": "12.20.47", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.47.tgz", - "integrity": "sha512-BzcaRsnFuznzOItW1WpQrDHM7plAa7GIDMZ6b5pnMbkqEtM/6WCOhvZar39oeMQP79gwvFUWjjptE7/KGcNqFg==" - } - } - }, - "web3-core-helpers": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.7.1.tgz", - "integrity": "sha512-xn7Sx+s4CyukOJdlW8bBBDnUCWndr+OCJAlUe/dN2wXiyaGRiCWRhuQZrFjbxLeBt1fYFH7uWyYHhYU6muOHgw==", - "requires": { - "web3-eth-iban": "1.7.1", - "web3-utils": "1.7.1" - } - }, - "web3-core-method": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.7.1.tgz", - "integrity": "sha512-383wu5FMcEphBFl5jCjk502JnEg3ugHj7MQrsX7DY76pg5N5/dEzxeEMIJFCN6kr5Iq32NINOG3VuJIyjxpsEg==", - "requires": { - "@ethersproject/transactions": "^5.0.0-beta.135", - "web3-core-helpers": "1.7.1", - "web3-core-promievent": "1.7.1", - "web3-core-subscriptions": "1.7.1", - "web3-utils": "1.7.1" - } - }, - "web3-core-promievent": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.7.1.tgz", - "integrity": "sha512-Vd+CVnpPejrnevIdxhCkzMEywqgVbhHk/AmXXceYpmwA6sX41c5a65TqXv1i3FWRJAz/dW7oKz9NAzRIBAO/kA==", - "requires": { - "eventemitter3": "4.0.4" - } - }, - "web3-core-requestmanager": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.7.1.tgz", - "integrity": "sha512-/EHVTiMShpZKiq0Jka0Vgguxi3vxq1DAHKxg42miqHdUsz4/cDWay2wGALDR2x3ofDB9kqp7pb66HsvQImQeag==", - "requires": { - "util": "^0.12.0", - "web3-core-helpers": "1.7.1", - "web3-providers-http": "1.7.1", - "web3-providers-ipc": "1.7.1", - "web3-providers-ws": "1.7.1" - } - }, - "web3-core-subscriptions": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.7.1.tgz", - "integrity": "sha512-NZBsvSe4J+Wt16xCf4KEtBbxA9TOwSVr8KWfUQ0tC2KMdDYdzNswl0Q9P58xaVuNlJ3/BH+uDFZJJ5E61BSA1Q==", - "requires": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.7.1" - } - }, - "web3-eth": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.7.1.tgz", - "integrity": "sha512-Uz3gO4CjTJ+hMyJZAd2eiv2Ur1uurpN7sTMATWKXYR/SgG+SZgncnk/9d8t23hyu4lyi2GiVL1AqVqptpRElxg==", - "requires": { - "web3-core": "1.7.1", - "web3-core-helpers": "1.7.1", - "web3-core-method": "1.7.1", - "web3-core-subscriptions": "1.7.1", - "web3-eth-abi": "1.7.1", - "web3-eth-accounts": "1.7.1", - "web3-eth-contract": "1.7.1", - "web3-eth-ens": "1.7.1", - "web3-eth-iban": "1.7.1", - "web3-eth-personal": "1.7.1", - "web3-net": "1.7.1", - "web3-utils": "1.7.1" - } - }, - "web3-eth-abi": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.7.1.tgz", - "integrity": "sha512-8BVBOoFX1oheXk+t+uERBibDaVZ5dxdcefpbFTWcBs7cdm0tP8CD1ZTCLi5Xo+1bolVHNH2dMSf/nEAssq5pUA==", - "requires": { - "@ethersproject/abi": "5.0.7", - "web3-utils": "1.7.1" - } - }, - "web3-eth-accounts": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.7.1.tgz", - "integrity": "sha512-3xGQ2bkTQc7LFoqGWxp5cQDrKndlX05s7m0rAFVoyZZODMqrdSGjMPMqmWqHzJRUswNEMc+oelqSnGBubqhguQ==", - "requires": { - "@ethereumjs/common": "^2.5.0", - "@ethereumjs/tx": "^3.3.2", - "crypto-browserify": "3.12.0", - "eth-lib": "0.2.8", - "ethereumjs-util": "^7.0.10", - "scrypt-js": "^3.0.1", - "uuid": "3.3.2", - "web3-core": "1.7.1", - "web3-core-helpers": "1.7.1", - "web3-core-method": "1.7.1", - "web3-utils": "1.7.1" - }, - "dependencies": { - "eth-lib": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", - "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", - "requires": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "xhr-request-promise": "^0.1.2" - } - }, - "uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" - } - } - }, - "web3-eth-contract": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.7.1.tgz", - "integrity": "sha512-HpnbkPYkVK3lOyos2SaUjCleKfbF0SP3yjw7l551rAAi5sIz/vwlEzdPWd0IHL7ouxXbO0tDn7jzWBRcD3sTbA==", - "requires": { - "@types/bn.js": "^4.11.5", - "web3-core": "1.7.1", - "web3-core-helpers": "1.7.1", - "web3-core-method": "1.7.1", - "web3-core-promievent": "1.7.1", - "web3-core-subscriptions": "1.7.1", - "web3-eth-abi": "1.7.1", - "web3-utils": "1.7.1" - } - }, - "web3-eth-ens": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-1.7.1.tgz", - "integrity": "sha512-DVCF76i9wM93DrPQwLrYiCw/UzxFuofBsuxTVugrnbm0SzucajLLNftp3ITK0c4/lV3x9oo5ER/wD6RRMHQnvw==", - "requires": { - "content-hash": "^2.5.2", - "eth-ens-namehash": "2.0.8", - "web3-core": "1.7.1", - "web3-core-helpers": "1.7.1", - "web3-core-promievent": "1.7.1", - "web3-eth-abi": "1.7.1", - "web3-eth-contract": "1.7.1", - "web3-utils": "1.7.1" - } - }, - "web3-eth-iban": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.7.1.tgz", - "integrity": "sha512-XG4I3QXuKB/udRwZdNEhdYdGKjkhfb/uH477oFVMLBqNimU/Cw8yXUI5qwFKvBHM+hMQWfzPDuSDEDKC2uuiMg==", - "requires": { - "bn.js": "^4.11.9", - "web3-utils": "1.7.1" - } - }, - "web3-eth-personal": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.7.1.tgz", - "integrity": "sha512-02H6nFBNfNmFjMGZL6xcDi0r7tUhxrUP91FTFdoLyR94eIJDadPp4rpXfG7MVES873i1PReh4ep5pSCHbc3+Pg==", - "requires": { - "@types/node": "^12.12.6", - "web3-core": "1.7.1", - "web3-core-helpers": "1.7.1", - "web3-core-method": "1.7.1", - "web3-net": "1.7.1", - "web3-utils": "1.7.1" - }, - "dependencies": { - "@types/node": { - "version": "12.20.47", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.47.tgz", - "integrity": "sha512-BzcaRsnFuznzOItW1WpQrDHM7plAa7GIDMZ6b5pnMbkqEtM/6WCOhvZar39oeMQP79gwvFUWjjptE7/KGcNqFg==" - } - } - }, - "web3-net": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.7.1.tgz", - "integrity": "sha512-8yPNp2gvjInWnU7DCoj4pIPNhxzUjrxKlODsyyXF8j0q3Z2VZuQp+c63gL++r2Prg4fS8t141/HcJw4aMu5sVA==", - "requires": { - "web3-core": "1.7.1", - "web3-core-method": "1.7.1", - "web3-utils": "1.7.1" - } - }, - "web3-providers-http": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.7.1.tgz", - "integrity": "sha512-dmiO6G4dgAa3yv+2VD5TduKNckgfR97VI9YKXVleWdcpBoKXe2jofhdvtafd42fpIoaKiYsErxQNcOC5gI/7Vg==", - "requires": { - "web3-core-helpers": "1.7.1", - "xhr2-cookies": "1.1.0" - } - }, - "web3-providers-ipc": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.7.1.tgz", - "integrity": "sha512-uNgLIFynwnd5M9ZC0lBvRQU5iLtU75hgaPpc7ZYYR+kjSk2jr2BkEAQhFVJ8dlqisrVmmqoAPXOEU0flYZZgNQ==", - "requires": { - "oboe": "2.1.5", - "web3-core-helpers": "1.7.1" - } - }, - "web3-providers-ws": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.7.1.tgz", - "integrity": "sha512-Uj0n5hdrh0ESkMnTQBsEUS2u6Unqdc7Pe4Zl+iZFb7Yn9cIGsPJBl7/YOP4137EtD5ueXAv+MKwzcelpVhFiFg==", - "requires": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.7.1", - "websocket": "^1.0.32" - } - }, - "web3-shh": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-shh/-/web3-shh-1.7.1.tgz", - "integrity": "sha512-NO+jpEjo8kYX6c7GiaAm57Sx93PLYkWYUCWlZmUOW7URdUcux8VVluvTWklGPvdM9H1WfDrol91DjuSW+ykyqg==", - "requires": { - "web3-core": "1.7.1", - "web3-core-method": "1.7.1", - "web3-core-subscriptions": "1.7.1", - "web3-net": "1.7.1" - } - }, - "web3-utils": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.1.tgz", - "integrity": "sha512-fef0EsqMGJUgiHPdX+KN9okVWshbIumyJPmR+btnD1HgvoXijKEkuKBv0OmUqjbeqmLKP2/N9EiXKJel5+E1Dw==", - "requires": { - "bn.js": "^4.11.9", - "ethereum-bloom-filters": "^1.0.6", - "ethereumjs-util": "^7.1.0", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "utf8": "3.0.0" - } - }, - "websocket": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/websocket/-/websocket-1.0.34.tgz", - "integrity": "sha512-PRDso2sGwF6kM75QykIesBijKSVceR6jL2G8NGYyq2XrItNC2P5/qL5XeR056GhA+Ly7JMFvJb9I312mJfmqnQ==", - "requires": { - "bufferutil": "^4.0.1", - "debug": "^2.2.0", - "es5-ext": "^0.10.50", - "typedarray-to-buffer": "^3.1.5", - "utf-8-validate": "^5.0.2", - "yaeti": "^0.0.6" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } - } - }, - "which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "requires": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - } - }, - "which-typed-array": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.7.tgz", - "integrity": "sha512-vjxaB4nfDqwKI0ws7wZpxIlde1XrLX5uB0ZjpfshgmapJMD7jJWhZI+yToJTqaFByF0eNBcYxbjmCzoRP7CfEw==", - "requires": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "es-abstract": "^1.18.5", - "foreach": "^2.0.5", - "has-tostringtag": "^1.0.0", - "is-typed-array": "^1.1.7" - } - }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -3383,62 +1717,6 @@ "version": "7.4.2", "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.2.tgz", "integrity": "sha512-T4tewALS3+qsrpGI/8dqNMLIVdq/g/85U98HPMa6F0m6xTbvhXU6RCQLqPH3+SlomNV/LdY6RXEbBpMH6EOJnA==" - }, - "xhr": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.6.0.tgz", - "integrity": "sha512-/eCGLb5rxjx5e3mF1A7s+pLlR6CGyqWN91fv1JgER5mVWg1MZmlhBvy9kjcsOdRk8RrIujotWyJamfyrp+WIcA==", - "requires": { - "global": "~4.4.0", - "is-function": "^1.0.1", - "parse-headers": "^2.0.0", - "xtend": "^4.0.0" - } - }, - "xhr-request": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/xhr-request/-/xhr-request-1.1.0.tgz", - "integrity": "sha512-Y7qzEaR3FDtL3fP30k9wO/e+FBnBByZeybKOhASsGP30NIkRAAkKD/sCnLvgEfAIEC1rcmK7YG8f4oEnIrrWzA==", - "requires": { - "buffer-to-arraybuffer": "^0.0.5", - "object-assign": "^4.1.1", - "query-string": "^5.0.1", - "simple-get": "^2.7.0", - "timed-out": "^4.0.1", - "url-set-query": "^1.0.0", - "xhr": "^2.0.4" - } - }, - "xhr-request-promise": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/xhr-request-promise/-/xhr-request-promise-0.1.3.tgz", - "integrity": "sha512-YUBytBsuwgitWtdRzXDDkWAXzhdGB8bYm0sSzMPZT7Z2MBjMSTHFsyCT1yCRATY+XC69DUrQraRAEgcoCRaIPg==", - "requires": { - "xhr-request": "^1.1.0" - } - }, - "xhr2-cookies": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/xhr2-cookies/-/xhr2-cookies-1.1.0.tgz", - "integrity": "sha1-fXdEnQmZGX8VXLc7I99yUF7YnUg=", - "requires": { - "cookiejar": "^2.1.1" - } - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" - }, - "yaeti": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz", - "integrity": "sha1-8m9ITXJoTPQr7ft2lwqhYI+/lXc=" - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" } } } diff --git a/client/backend/package.json b/client/backend/package.json index 4f7538abe..50b525d94 100644 --- a/client/backend/package.json +++ b/client/backend/package.json @@ -14,13 +14,10 @@ "@types/express-ws": "^3.0.0", "@types/node": "^14.10.1", "@types/ws": "^7.2.6", - "axios": "^0.27.0", - "body-parser": "^1.20.0", "dockerode": "^3.2.1", "express": "^4.17.1", "express-ws": "^4.0.0", "tslog": "^3.0.5", - "web3": "^1.7.1", "ws": "^7.3.1" } } diff --git a/client/backend/src/api/v1/main.ts b/client/backend/src/api/v1/main.ts index 2211d4274..6e826b65e 100644 --- a/client/backend/src/api/v1/main.ts +++ b/client/backend/src/api/v1/main.ts @@ -5,7 +5,6 @@ import { SeedContainerInfo, Emulator, SeedNetInfo } from '../../utils/seedemu-me import { Sniffer } from '../../utils/sniffer'; import WebSocket from 'ws'; import { Controller } from '../../utils/controller'; -import BasePlugin from '../../plugin/BasePlugin' const router = express.Router(); const docker = new dockerode(); @@ -43,88 +42,6 @@ controller.getLoggers().forEach(logger => logger.setSettings({ minLevel: 'warn' })); -// used to be able to run many plugins simultaneously -const instantiated_types: number[] = []; -const instantiated_plugins: {[key: number]: BasePlugin} = {}; - - -router.post('/plugin/:type/init', async (req, res, next) => { - const type = parseInt(req.params.type); - if(instantiated_types.includes(type)) { - console.log(`Plugin of type ${type} is already running`); - res.json({ - ok: true - }); - next(); - return; - } - instantiated_types.push(type); - instantiated_plugins[type] = new BasePlugin(type); - console.log(`Done creating plugin of type ${type}`) - res.json({ - ok: true - }); - next(); -}) - -// Used to be able to run many plugins simultaneously -const running_listeners: number[] = [] -const running_ws: {[key: number]: WebSocket} = {}; - -router.ws('/plugin/:type/command/', async (ws, req, next) => { - - const type = parseInt(req.params.type); - if(running_ws[type]) { - console.log(`Clearing previous socket for type ${type}`) - running_ws[type].close(); - } - running_ws[type] = ws - - if(!instantiated_types.includes(type)) { - console.log(`Cannot run command with uninitialized plugin of type ${type}`) - next(); - return; - } - - - // This is triggered when the user enters a command in the map - running_ws[type].on('message', (message) => { - const data = message.toString() - // Need to handle json.parse with try and catch! - const [command, subscription, params] = JSON.parse(data).command.split(" "); - - switch(command) { - case "start": { - instantiated_plugins[type].attach(subscription, params) - break; - } - case "stop": { - instantiated_plugins[type].detach(subscription) - break; - } - default: { - break; - } - } - }) - - // This runs when the socket connection is established from the client - if(!running_listeners.includes(type)) { - instantiated_plugins[type].onMessage(function(data) { - // readyState 1 means open - // Sending data to client - if(running_ws[type].readyState == 1) { - running_ws[type].send(JSON.stringify(data)) - } - }) - instantiated_plugins[type].run(await getContainers()) - running_listeners.push(type) - } - - next() -}) - - router.get('/network', async function(req, res, next) { var networks = await docker.listNetworks(); @@ -359,4 +276,4 @@ router.post('/container/:id/bgp/:peer', express.json(), async function (req, res next(); }); -export = router; +export = router; \ No newline at end of file diff --git a/client/backend/src/main.ts b/client/backend/src/main.ts index f14afd0a1..b8f685bd6 100644 --- a/client/backend/src/main.ts +++ b/client/backend/src/main.ts @@ -1,16 +1,12 @@ import express from 'express'; import expressWs from 'express-ws'; -import bodyParser from 'body-parser'; - const app = express(); expressWs(app); import apiV1Router from './api/v1/main'; -app.use(bodyParser.urlencoded({extended: false})) -app.use(bodyParser.json()) app.use(express.static('../frontend/public')); app.use('/api/v1', apiV1Router); -app.listen(8080, '0.0.0.0'); +app.listen(8080, '0.0.0.0'); \ No newline at end of file diff --git a/client/backend/src/plugin/BasePlugin.ts b/client/backend/src/plugin/BasePlugin.ts deleted file mode 100644 index 77ec2632c..000000000 --- a/client/backend/src/plugin/BasePlugin.ts +++ /dev/null @@ -1,52 +0,0 @@ -import EventEmitter from './EventEmitter'; -import PluginEnum from './PluginEnum'; -import BlockchainPlugin from './BlockchainPlugin'; -import { SeedContainerInfo } from '../utils/seedemu-meta'; - -const supported_plugins = [...Object.values(PluginEnum)]; - - -class BasePlugin { - private __type: number; - private __local_emitter: EventEmitter; - private __plugin: any; - - constructor(type: number) { - - if (!supported_plugins.includes(type)) { - throw new Error('Plugin type not supported'); - } - this.__type = type; - this.__local_emitter = new EventEmitter(type); - } - - run(containers?:SeedContainerInfo[]) { - // find a way to run/fetch modules based type - if (this.__type === PluginEnum.blockchain) { - this.__plugin = new BlockchainPlugin(containers); - console.log("created plugin of type blockchain") - } - } - - attach(filter:string, params:string) { - this.__plugin.attach(filter, params); - } - - detach(filter:string) { - this.__plugin.detach(filter); - } - - onMessage(callback:(...args: any[]) => void) { - this.__local_emitter.on('message', callback); - } - - onError(callback:(...args: any[]) => void) { - this.__local_emitter.on('error', callback); - } - - getType() { - return this.__type; - } -} - -export default BasePlugin; diff --git a/client/backend/src/plugin/BlockchainPlugin.ts b/client/backend/src/plugin/BlockchainPlugin.ts deleted file mode 100644 index 535baf3ed..000000000 --- a/client/backend/src/plugin/BlockchainPlugin.ts +++ /dev/null @@ -1,235 +0,0 @@ -import Web3 from 'web3' -import axios from 'axios' -import EventEmitter from './EventEmitter'; -import PluginEnum from './PluginEnum'; -import PluginInterface from './PluginInterface'; -import { SeedContainerInfo } from '../utils/seedemu-meta'; - -const subscriptions = { - pendingTransactions: 'pendingTransactions', - newBlockHeaders: 'newBlockHeaders' -} - -const status = { - success: 'success', - error: 'error' -} - -const event_type = { - settings: 'settings', - data: 'data', -}; - -const settings = { - filters: [subscriptions.newBlockHeaders, subscriptions.pendingTransactions], -}; - -// need to create an interface for all plugins to follow this one -class BlockchainPlugin implements PluginInterface { - private __message_event: string; - private __local_emitter: any; - private __accountsToContainerMap: {[key: string]: string}; - private __containers: SeedContainerInfo[]; - private __http_url: string; - private __websocket_url: string; - private __settings: { - filters: string[]; - }; - private __web3: Web3; - - constructor(containers?:SeedContainerInfo[]) { - this.__message_event = `message:${PluginEnum.blockchain}`; - this.__local_emitter = EventEmitter.emitters[PluginEnum.blockchain]; - this.__settings = settings; - this.__accountsToContainerMap = {}; - this.__containers = this.__setContainers(containers); - this.__driver() - } - - async __driver() { - this.emit({ - eventType: event_type.settings, - data: this.__settings, - status: status.success - }); - - this.__containers.map((container, index) => { - const split = container.Names[0].split("-"); - const ip = split[split.length - 1]; - this.__http_url = `http://${ip}:8545` - this.__websocket_url = `ws://${ip}:8546` - const web3 = new Web3(new Web3.providers.WebsocketProvider(this.__websocket_url, { - clientConfig: { - // Useful to keep a connection alive - keepalive: true, - keepaliveInterval: 60000 // ms - }, - })); - if (!this.__web3) { - this.__web3 = web3; - } - return (web3.eth.getAccounts()) - .then((accounts:string[]) => { - accounts.forEach(account => { - this.__accountsToContainerMap[account.toLowerCase()] = container.Id; - }); - }) - }) - - setTimeout(() => { - console.log(this.__accountsToContainerMap) - },3000) - } - - getMessageEvent():string { - return this.__message_event; - } - - getLocalEmitter():any { - return this.__local_emitter; - } - - getSettings(): { filters: string[]; } { - return this.__settings; - } - - getContainers(): SeedContainerInfo[] { - return this.__containers; - } - - __setContainers(containers:SeedContainerInfo[] = []) { - return containers.filter(container => container.Names[0].includes('Ethereum')) - } - - emit(data:object) { - console.log(`FROM type ${PluginEnum.blockchain} - emitting data ${JSON.stringify(data)} to main handler`); - this.__local_emitter.emit(this.__message_event, data); - } - - attach(supportedEvent: any, params: string) { - console.log(`FROM type ${PluginEnum.blockchain} - attaching event ${supportedEvent}`); - const subscription = this.__web3.eth.subscribe(supportedEvent, (error: any, result:any) => { - if(error) { - this.emit({ - status: status.error, - error - }) - return; - } - this.__handleSubscriptionResults(supportedEvent, result); - }) - this.__local_emitter.on(`detach:${PluginEnum.blockchain}:${supportedEvent}`, () => { - subscription.unsubscribe(function(error, success){ - if(success) - console.log('Successfully unsubscribed!'); - }); - }) - } - async __handleSubscriptionResults(supportedEvent:any, result:any) { - - if(supportedEvent === subscriptions.newBlockHeaders) { - this.emit(this.structureData({ - status: status.success, - containerId: await this.__getContainerId(result.miner, result.number), - data: { - borderWidth: 4, - color: { - background: "purple", - border: "purple" - } - } - })) - } else if (supportedEvent === subscriptions.pendingTransactions) { - this.__getTransactionReceipt(result) - } - } - - /* - @desc This function is one of the most important functions in this code - In our current implementation, we have support for two events: newBlockHeaders and pendingTransactions - When listening to the pendingTransactions, regardless of whether we are using Proof of work or Proof of authority, all of the transactions have the "from" attribute - which refers to the ethereum account that triggered the transaction. This "from" attribute always has a valid address - The problem comes when we are listening to newBlockHeaders with Proof of authority. - When using Proof of work and the newBlockHeaders event is triggered, we get the miner's address in the result through the "miner" property. We then figure out in what - container this address is and we flash this container on the frontend. - When using Proof of authority, the "miner" attribute always has a value of "0x000000..." which doesn't match with any of the existing accounts or containers. Flashing then fails - because account "0x000000..." is not in any container. - To be able to get the signer of a certain block we have to use axios to create a jsonrpc request as web3 does not have a direct api to fetch them. For example, in PoW, if i want - to fetch all accounts, i can write "web3.eth.accounts", but I cannot write "web3.clique.getSigners" as clique is not available. - Documentation states that performing a jsonrpc will solve our issue - This function is the one that handles all cases including the PoA edge case that we currently described. - - @fix The assumption mentioned above about having the "miner" field always set to 0x00000... when running PoA and listening to the newBlockHeaders event is wrong. In PoA, the "miner" - field is true unless a proposal is made. Assuming A proposes that B becomes a new signer on the blockchain, the "miner" property of the block header will be set to B. - How could this affect the visualization? We will be flashing a node that we don't want - @solution Figure out what consensus was run by the node that added the block (in case we run more than one consensus in our emulator), and run the axios code if we have PoA and newBlockHeaders at the same time instead of checking if - __accountsToContainerMap has the address (this will be true when A proposes B) - */ - - async __getContainerId(address:string, blockNumber:number) { - const addr = address.toLowerCase() - const self = this; - return new Promise((resolve, reject) => { - if(self.__accountsToContainerMap[addr]) { - return resolve(self.__accountsToContainerMap[addr]) - } else { - return axios.post(this.__http_url, { - jsonrpc: '2.0', - id: Date.now(), - method: 'clique_getSnapshot', - params: [self.__web3.utils.toHex(blockNumber)] - }, { - headers: { - 'Content-Type': 'application/json', - 'Access-Control-Allow-Origin': '*' - } - }).then(function(result) { - return resolve(self.__accountsToContainerMap[result.data.result.recents[blockNumber]]) - }).catch(function(e) { - return reject(e) - }) - } - }) - } - - __getTransactionReceipt(transactionHash: any) { - const self = this; - this.__web3.eth.getTransactionReceipt(transactionHash, async (error:any, receipt:any) => { - if(receipt !== null) { - this.emit(this.structureData({ - status: status.success, - containerId: await self.__getContainerId(receipt.from, receipt.number), - data: { - borderWidth: 4, - color: { - background: !!receipt.contractAddress ? "pink" : "orange", - border: !!receipt.contractAddress ? "pink" : "orange" - } - } - })) - } else { - setTimeout(() => { - this.__getTransactionReceipt(transactionHash) - },1000) - } - }) - } - - detach(supportedEvent:any) { - console.log(`About to detach event ${supportedEvent}`) - // unsubscribe using web3 - this.__local_emitter.emit(`detach:${PluginEnum.blockchain}:${supportedEvent}`) - } - - structureData(data:any) { - return { - eventType: event_type.data, - timestamp: Date.now(), - status: data.status, - containerId: data.containerId, - data: data.data, - }; - } -} - -export default BlockchainPlugin; diff --git a/client/backend/src/plugin/EventEmitter.ts b/client/backend/src/plugin/EventEmitter.ts deleted file mode 100644 index 4cce1013f..000000000 --- a/client/backend/src/plugin/EventEmitter.ts +++ /dev/null @@ -1,36 +0,0 @@ -import {EventEmitter as Emitter} from 'events'; -// import PluginEnum from './PluginEnum'; - -interface Emitters { - [key:number]: Emitter -} - -class EventEmitter { - static emitters:Emitters = {} - private __type: number; - private __local_emitter: Emitter; - - constructor(type:number) { - this.__type = type; - this.__local_emitter = new Emitter(); - EventEmitter.emitters[type] = this.__local_emitter; - } - - on(event:string, callback:(...args: any[]) => void) { - this.__local_emitter.on(`${event}:${this.__type}`, callback); - } - - once(event:string, callback:(...args: any[]) => void) { - this.__local_emitter.once(`${event}:${this.__type}`, callback); - } - - off(event:string, callback:(...args: any[]) => void) { - this.__local_emitter.off(`${event}:${this.__type}`, callback); - } - - emit(event:string, data:any) { - this.__local_emitter.emit(`${event}:${this.__type}`, data); - } -} - -export default EventEmitter; \ No newline at end of file diff --git a/client/backend/src/plugin/PluginEnum.ts b/client/backend/src/plugin/PluginEnum.ts deleted file mode 100644 index 4950f6bb0..000000000 --- a/client/backend/src/plugin/PluginEnum.ts +++ /dev/null @@ -1,5 +0,0 @@ -const PluginEnum = { - blockchain: 1, -}; - -export default PluginEnum; \ No newline at end of file diff --git a/client/backend/src/plugin/PluginInterface.ts b/client/backend/src/plugin/PluginInterface.ts deleted file mode 100644 index b1d3ac9bf..000000000 --- a/client/backend/src/plugin/PluginInterface.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { SeedContainerInfo } from '../utils/seedemu-meta'; - -interface PluginInterface { - getMessageEvent():string; - getLocalEmitter():any; - getContainers():SeedContainerInfo[]; - getSettings():{filters: string[]} - emit: (data:object) => void; - attach:(event:string, params:string) => void; - detach:(event:string) => void; - structureData:(data: object) =>void; -} - -export default PluginInterface; diff --git a/client/frontend/package-lock.json b/client/frontend/package-lock.json index dcf811122..e7efadc7b 100644 --- a/client/frontend/package-lock.json +++ b/client/frontend/package-lock.json @@ -1,8 +1,1521 @@ { "name": "container-manager-client", "version": "0.0.1", - "lockfileVersion": 1, + "lockfileVersion": 2, "requires": true, + "packages": { + "": { + "name": "container-manager-client", + "version": "0.0.1", + "license": "MIT", + "dependencies": { + "@egjs/hammerjs": "^2.0.17", + "@types/bootstrap": "^5.0.4", + "@types/datatables.net": "^1.10.19", + "@types/datatables.net-select": "^1.2.6", + "@types/hammerjs": "^2.0.36", + "@types/jquery": "^3.5.5", + "@types/jqueryui": "^1.12.14", + "bootstrap": "^4.5.3", + "bootstrap-icons": "^1.3.0", + "component-emitter": "^1.3.0", + "datatables.net": "^1.10.23", + "datatables.net-bs4": "^1.10.23", + "datatables.net-select": "^1.3.1", + "datatables.net-select-bs4": "^1.3.1", + "file-loader": "^6.2.0", + "hammerjs": "^2.0.8", + "jquery": "^3.5.1", + "jquery-ui": "^1.12.1", + "keycharm": "^0.4.0", + "popper.js": "^1.16.1", + "timsort": "^0.3.0", + "uuid": "^8.3.2", + "vis-data": "^7.1.2", + "vis-network": "^9.0.4", + "vis-util": "^5.0.2", + "xterm": "^4.9.0", + "xterm-addon-attach": "^0.6.0", + "xterm-addon-fit": "^0.4.0" + }, + "devDependencies": { + "css-loader": "^5.0.1", + "style-loader": "^2.0.0", + "ts-loader": "^8.0.14", + "typescript": "^4.1.3", + "webpack": "^5.14.0" + } + }, + "node_modules/@egjs/hammerjs": { + "version": "2.0.17", + "resolved": "https://registry.npmjs.org/@egjs/hammerjs/-/hammerjs-2.0.17.tgz", + "integrity": "sha512-XQsZgjm2EcVUiZQf11UBJQfmZeEmOW8DpI1gsFeln6w0ae0ii4dMQEQ0kjl6DspdWX1aGY1/loyXnP0JS06e/A==", + "dependencies": { + "@types/hammerjs": "^2.0.36" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@popperjs/core": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.6.0.tgz", + "integrity": "sha512-cPqjjzuFWNK3BSKLm0abspP0sp/IGOli4p5I5fKFAzdS8fvjdOwDCfZqAaIiXd9lPkOWi3SUUfZof3hEb7J/uw==" + }, + "node_modules/@types/bootstrap": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@types/bootstrap/-/bootstrap-5.0.4.tgz", + "integrity": "sha512-Awa1onTcDziszyFDAAa2AawwYCQamGBLqR3YuRhJHJNlAFKwpfzsE+lfSyKtwxRNEImpkWevhOuwo0yPadd3hA==", + "dependencies": { + "@popperjs/core": "^2.6.0", + "@types/jquery": "*" + } + }, + "node_modules/@types/datatables.net": { + "version": "1.10.19", + "resolved": "https://registry.npmjs.org/@types/datatables.net/-/datatables.net-1.10.19.tgz", + "integrity": "sha512-WuzgytEmsIpVYZbkce+EvK1UqBI7/cwcC/WgYeAtXdq2zi+yWzJwMT5Yb6irAiOi52DBjeAEeRt3bYzFYvHWCQ==", + "dependencies": { + "@types/jquery": "*" + } + }, + "node_modules/@types/datatables.net-select": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@types/datatables.net-select/-/datatables.net-select-1.2.6.tgz", + "integrity": "sha512-F114lcN6EuAELInU/ZSb1gGyQNfUFCAdZRbo12dRNtdt+HYxiRHVmow46J7Qy0Hv44/6DaPHwHKhVq35eY3LPg==", + "dependencies": { + "@types/datatables.net": "*", + "@types/jquery": "*" + } + }, + "node_modules/@types/eslint": { + "version": "7.2.6", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.2.6.tgz", + "integrity": "sha512-I+1sYH+NPQ3/tVqCeUSBwTE/0heyvtXqpIopUUArlBm0Kpocb8FbMa3AZ/ASKIFpN3rnEx932TTXDbt9OXsNDw==", + "dev": true, + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.0.tgz", + "integrity": "sha512-O/ql2+rrCUe2W2rs7wMR+GqPRcgB6UiqN5RhrR5xruFlY7l9YLMn0ZkDzjoHLeiFkR8MCQZVudUuuvQ2BLC9Qw==", + "dev": true, + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "node_modules/@types/estree": { + "version": "0.0.45", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.45.tgz", + "integrity": "sha512-jnqIUKDUqJbDIUxm0Uj7bnlMnRm1T/eZ9N+AVMqhPgzrba2GhGG5o/jCTwmdPK709nEZsGoMzXEDUjcXHa3W0g==", + "dev": true + }, + "node_modules/@types/hammerjs": { + "version": "2.0.36", + "resolved": "https://registry.npmjs.org/@types/hammerjs/-/hammerjs-2.0.36.tgz", + "integrity": "sha512-7TUK/k2/QGpEAv/BCwSHlYu3NXZhQ9ZwBYpzr9tjlPIL2C5BeGhH3DmVavRx3ZNyELX5TLC91JTz/cen6AAtIQ==" + }, + "node_modules/@types/jquery": { + "version": "3.5.5", + "resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.5.5.tgz", + "integrity": "sha512-6RXU9Xzpc6vxNrS6FPPapN1SxSHgQ336WC6Jj/N8q30OiaBZ00l1GBgeP7usjVZPivSkGUfL1z/WW6TX989M+w==", + "dependencies": { + "@types/sizzle": "*" + } + }, + "node_modules/@types/jqueryui": { + "version": "1.12.14", + "resolved": "https://registry.npmjs.org/@types/jqueryui/-/jqueryui-1.12.14.tgz", + "integrity": "sha512-fR9PoOI0yauBS0sjGaU3ao0s2pJWjBi0yVYnPdYbllNoimaPUlHMOh0Ubq+hy8OB258hRSlK2hWCJk40kNhrZQ==", + "dependencies": { + "@types/jquery": "*" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.6.tgz", + "integrity": "sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw==" + }, + "node_modules/@types/node": { + "version": "14.14.20", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.20.tgz", + "integrity": "sha512-Y93R97Ouif9JEOWPIUyU+eyIdyRqQR0I8Ez1dzku4hDx34NWh4HbtIc3WNzwB1Y9ULvNGeu5B8h8bVL5cAk4/A==", + "dev": true + }, + "node_modules/@types/sizzle": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.2.tgz", + "integrity": "sha512-7EJYyKTL7tFR8+gDbB6Wwz/arpGa0Mywk1TJbNzKzHtzbwVmY4HR9WqS5VV7dsBUKQmPNr192jHr/VpBluj/hg==" + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.0.tgz", + "integrity": "sha512-kX2W49LWsbthrmIRMbQZuQDhGtjyqXfEmmHyEi4XWnSZtPmxY0+3anPIzsnRb45VH/J55zlOfWvZuY47aJZTJg==", + "dev": true, + "dependencies": { + "@webassemblyjs/helper-numbers": "1.11.0", + "@webassemblyjs/helper-wasm-bytecode": "1.11.0" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.0.tgz", + "integrity": "sha512-Q/aVYs/VnPDVYvsCBL/gSgwmfjeCb4LW8+TMrO3cSzJImgv8lxxEPM2JA5jMrivE7LSz3V+PFqtMbls3m1exDA==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.0.tgz", + "integrity": "sha512-baT/va95eXiXb2QflSx95QGT5ClzWpGaa8L7JnJbgzoYeaA27FCvuBXU758l+KXWRndEmUXjP0Q5fibhavIn8w==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.0.tgz", + "integrity": "sha512-u9HPBEl4DS+vA8qLQdEQ6N/eJQ7gT7aNvMIo8AAWvAl/xMrcOSiI2M0MAnMCy3jIFke7bEee/JwdX1nUpCtdyA==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.0.tgz", + "integrity": "sha512-DhRQKelIj01s5IgdsOJMKLppI+4zpmcMQ3XboFPLwCpSNH6Hqo1ritgHgD0nqHeSYqofA6aBN/NmXuGjM1jEfQ==", + "dev": true, + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.11.0", + "@webassemblyjs/helper-api-error": "1.11.0", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.0.tgz", + "integrity": "sha512-MbmhvxXExm542tWREgSFnOVo07fDpsBJg3sIl6fSp9xuu75eGz5lz31q7wTLffwL3Za7XNRCMZy210+tnsUSEA==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.0.tgz", + "integrity": "sha512-3Eb88hcbfY/FCukrg6i3EH8H2UsD7x8Vy47iVJrP967A9JGqgBVL9aH71SETPx1JrGsOUVLo0c7vMCN22ytJew==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.0", + "@webassemblyjs/helper-buffer": "1.11.0", + "@webassemblyjs/helper-wasm-bytecode": "1.11.0", + "@webassemblyjs/wasm-gen": "1.11.0" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.0.tgz", + "integrity": "sha512-KXzOqpcYQwAfeQ6WbF6HXo+0udBNmw0iXDmEK5sFlmQdmND+tr773Ti8/5T/M6Tl/413ArSJErATd8In3B+WBA==", + "dev": true, + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.0.tgz", + "integrity": "sha512-aqbsHa1mSQAbeeNcl38un6qVY++hh8OpCOzxhixSYgbRfNWcxJNJQwe2rezK9XEcssJbbWIkblaJRwGMS9zp+g==", + "dev": true, + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.0.tgz", + "integrity": "sha512-A/lclGxH6SpSLSyFowMzO/+aDEPU4hvEiooCMXQPcQFPPJaYcPQNKGOCLUySJsYJ4trbpr+Fs08n4jelkVTGVw==", + "dev": true + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.0.tgz", + "integrity": "sha512-JHQ0damXy0G6J9ucyKVXO2j08JVJ2ntkdJlq1UTiUrIgfGMmA7Ik5VdC/L8hBK46kVJgujkBIoMtT8yVr+yVOQ==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.0", + "@webassemblyjs/helper-buffer": "1.11.0", + "@webassemblyjs/helper-wasm-bytecode": "1.11.0", + "@webassemblyjs/helper-wasm-section": "1.11.0", + "@webassemblyjs/wasm-gen": "1.11.0", + "@webassemblyjs/wasm-opt": "1.11.0", + "@webassemblyjs/wasm-parser": "1.11.0", + "@webassemblyjs/wast-printer": "1.11.0" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.0.tgz", + "integrity": "sha512-BEUv1aj0WptCZ9kIS30th5ILASUnAPEvE3tVMTrItnZRT9tXCLW2LEXT8ezLw59rqPP9klh9LPmpU+WmRQmCPQ==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.0", + "@webassemblyjs/helper-wasm-bytecode": "1.11.0", + "@webassemblyjs/ieee754": "1.11.0", + "@webassemblyjs/leb128": "1.11.0", + "@webassemblyjs/utf8": "1.11.0" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.0.tgz", + "integrity": "sha512-tHUSP5F4ywyh3hZ0+fDQuWxKx3mJiPeFufg+9gwTpYp324mPCQgnuVKwzLTZVqj0duRDovnPaZqDwoyhIO8kYg==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.0", + "@webassemblyjs/helper-buffer": "1.11.0", + "@webassemblyjs/wasm-gen": "1.11.0", + "@webassemblyjs/wasm-parser": "1.11.0" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.0.tgz", + "integrity": "sha512-6L285Sgu9gphrcpDXINvm0M9BskznnzJTE7gYkjDbxET28shDqp27wpruyx3C2S/dvEwiigBwLA1cz7lNUi0kw==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.0", + "@webassemblyjs/helper-api-error": "1.11.0", + "@webassemblyjs/helper-wasm-bytecode": "1.11.0", + "@webassemblyjs/ieee754": "1.11.0", + "@webassemblyjs/leb128": "1.11.0", + "@webassemblyjs/utf8": "1.11.0" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.0.tgz", + "integrity": "sha512-Fg5OX46pRdTgB7rKIUojkh9vXaVN6sGYCnEiJN1GYkb0RPwShZXp6KTDqmoMdQPKhcroOXh3fEzmkWmCYaKYhQ==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.0", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true + }, + "node_modules/acorn": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.0.4.tgz", + "integrity": "sha512-XNP0PqF1XD19ZlLKvB7cMmnZswW4C/03pRHgirB30uSJTaS3A3V1/P4sS3HPvFmjoriPCJQs+JDSbm4bL1TxGQ==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==" + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "engines": { + "node": "*" + } + }, + "node_modules/bootstrap": { + "version": "4.5.3", + "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.5.3.tgz", + "integrity": "sha512-o9ppKQioXGqhw8Z7mah6KdTYpNQY//tipnkxppWhPbiSWdD+1raYsnhwEZjkTHYbGee4cVQ0Rx65EhOY/HNLcQ==" + }, + "node_modules/bootstrap-icons": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/bootstrap-icons/-/bootstrap-icons-1.3.0.tgz", + "integrity": "sha512-w6zQ93p626zmPDqDtET7VdB9EkoDtfmCBV53hunjntoCke6X5LafXf6TxPAP+ImjRAhhxAyA/sjzQnHBY0uoiQ==", + "engines": { + "node": ">=10" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.16.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.1.tgz", + "integrity": "sha512-UXhDrwqsNcpTYJBTZsbGATDxZbiVDsx6UjpmRUmtnP10pr8wAYr5LgFoEFw9ixriQH2mv/NX2SfGzE/o8GndLA==", + "dev": true, + "dependencies": { + "caniuse-lite": "^1.0.30001173", + "colorette": "^1.2.1", + "electron-to-chromium": "^1.3.634", + "escalade": "^3.1.1", + "node-releases": "^1.1.69" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/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 + }, + "node_modules/camelcase": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001176", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001176.tgz", + "integrity": "sha512-VWdkYmqdkDLRe0lvfJlZQ43rnjKqIGKHWhWWRbkqMsJIUaYDNf/K/sdZZcVO6YKQklubokdkJY+ujArsuJ5cag==", + "dev": true + }, + "node_modules/chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/chrome-trace-event": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz", + "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==", + "dev": true, + "dependencies": { + "tslib": "^1.9.0" + }, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/colorette": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.1.tgz", + "integrity": "sha512-puCDz0CzydiSYOrnXpz/PKd69zRrribezjtE9yd4zvytoRc8+RY/KJPvtPFKZS3E3wP6neGyMe0vOTlHO5L3Pw==", + "dev": true + }, + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "node_modules/component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" + }, + "node_modules/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 + }, + "node_modules/css-loader": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-5.0.1.tgz", + "integrity": "sha512-cXc2ti9V234cq7rJzFKhirb2L2iPy8ZjALeVJAozXYz9te3r4eqLSixNAbMDJSgJEQywqXzs8gonxaboeKqwiw==", + "dev": true, + "dependencies": { + "camelcase": "^6.2.0", + "cssesc": "^3.0.0", + "icss-utils": "^5.0.0", + "loader-utils": "^2.0.0", + "postcss": "^8.1.4", + "postcss-modules-extract-imports": "^3.0.0", + "postcss-modules-local-by-default": "^4.0.0", + "postcss-modules-scope": "^3.0.0", + "postcss-modules-values": "^4.0.0", + "postcss-value-parser": "^4.1.0", + "schema-utils": "^3.0.0", + "semver": "^7.3.2" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/datatables.net": { + "version": "1.10.23", + "resolved": "https://registry.npmjs.org/datatables.net/-/datatables.net-1.10.23.tgz", + "integrity": "sha512-we3tlNkzpxvgkKKlTxTMXPCt35untVXNg8zUYWpQyC1U5vJc+lT0+Zdc1ztK8d3lh5CfdnuFde2p8n3XwaGl3Q==", + "dependencies": { + "jquery": ">=1.7" + } + }, + "node_modules/datatables.net-bs4": { + "version": "1.10.23", + "resolved": "https://registry.npmjs.org/datatables.net-bs4/-/datatables.net-bs4-1.10.23.tgz", + "integrity": "sha512-ChUB8t5t5uzPnJYTPXx2DOvnlm2shz8OadXrKoFavOadB308OuwHVxSldYq9+KGedCeiVxEjNqcaV4nFSXkRsw==", + "dependencies": { + "datatables.net": "1.10.23", + "jquery": ">=1.7" + } + }, + "node_modules/datatables.net-select": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/datatables.net-select/-/datatables.net-select-1.3.1.tgz", + "integrity": "sha512-PeVd/hlAX58QzL0+mGvxnXP7ylLtzZMeAots/uZkQi+6c/KI6JuP8LCJoEMHAsSjQM/BnG7Uw8E1YGOz1tZpQQ==", + "dependencies": { + "datatables.net": "^1.10.15", + "jquery": ">=1.7" + } + }, + "node_modules/datatables.net-select-bs4": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/datatables.net-select-bs4/-/datatables.net-select-bs4-1.3.1.tgz", + "integrity": "sha512-8UOBxChTsn24nP/ZOsIMGZOdTJymQZ8WcQ81NcGgyDz6b4JlsQl8Bwb89AcVT7hncMquPJ3d5WUGG4I9WMhAlw==", + "dependencies": { + "datatables.net-bs4": "^1.10.15", + "datatables.net-select": "1.3.1", + "jquery": ">=1.7" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.3.638", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.638.tgz", + "integrity": "sha512-vbTdlXeu3pAtPt0/T3+HVyX9bu6Lx/iXUYSWBCCRDI+JQiq48m6o4BnZPLBy40+4E0dLbt/Ix9VIJ/06XztfoA==", + "dev": true + }, + "node_modules/emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "engines": { + "node": ">= 4" + } + }, + "node_modules/enhanced-resolve": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.5.0.tgz", + "integrity": "sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "memory-fs": "^0.5.0", + "tapable": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/errno": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", + "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", + "dev": true, + "dependencies": { + "prr": "~1.0.1" + }, + "bin": { + "errno": "cli.js" + } + }, + "node_modules/es-module-lexer": { + "version": "0.3.26", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.3.26.tgz", + "integrity": "sha512-Va0Q/xqtrss45hWzP8CZJwzGSZJjDM5/MJRE3IXXnUCcVLElR9BRaE9F62BopysASyc4nM3uwhSW7FFB9nlWAA==", + "dev": true + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/events": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.2.0.tgz", + "integrity": "sha512-/46HWwbfCX2xTawVfkKLGxMifJYQBWMwY1mjywRtb4c9x8l5NP3KoJtnIOiL1hfdRkIuYhETxQlo62IF8tcnlg==", + "dev": true, + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + }, + "node_modules/file-loader": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz", + "integrity": "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==", + "dependencies": { + "loader-utils": "^2.0.0", + "schema-utils": "^3.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true + }, + "node_modules/graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "node_modules/hammerjs": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/hammerjs/-/hammerjs-2.0.8.tgz", + "integrity": "sha1-BO93hiz/K7edMPdpIJWTAiK/YPE=", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/icss-utils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", + "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", + "dev": true, + "engines": { + "node": "^10 || ^12 || >= 14" + } + }, + "node_modules/indexes-of": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", + "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=", + "dev": true + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "node_modules/jest-worker": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", + "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", + "dev": true, + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/jquery": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.5.1.tgz", + "integrity": "sha512-XwIBPqcMn57FxfT+Go5pzySnm4KWkT1Tv7gjrpT1srtf8Weynl6R273VJ5GjkRb51IzMp5nbaPjJXMWeju2MKg==" + }, + "node_modules/jquery-ui": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/jquery-ui/-/jquery-ui-1.12.1.tgz", + "integrity": "sha1-vLQEXI3QU5wTS8FIjN0+dop6nlE=" + }, + "node_modules/json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "node_modules/json5": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", + "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/keycharm": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/keycharm/-/keycharm-0.4.0.tgz", + "integrity": "sha512-TyQTtsabOVv3MeOpR92sIKk/br9wxS+zGj4BG7CR8YbK4jM3tyIBaF0zhzeBUMx36/Q/iQLOKKOT+3jOQtemRQ==" + }, + "node_modules/loader-runner": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.2.0.tgz", + "integrity": "sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw==", + "dev": true, + "engines": { + "node": ">=6.11.5" + } + }, + "node_modules/loader-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", + "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/memory-fs": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", + "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", + "dev": true, + "dependencies": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + }, + "engines": { + "node": ">=4.3.0 <5.0.0 || >=5.10" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true, + "dependencies": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/mime-db": { + "version": "1.45.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.45.0.tgz", + "integrity": "sha512-CkqLUxUk15hofLoLyljJSrukZi8mAtgd+yE5uO4tqRZsdsAJKv0O+rFMhVDRJgozy+yG6md5KwuXhD4ocIoP+w==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.28", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.28.tgz", + "integrity": "sha512-0TO2yJ5YHYr7M2zzT7gDU1tbwHxEUWBCLt0lscSNpcdAfFyJOVEpRYNS7EXVcTLNj/25QO8gulHC5JtTzSE2UQ==", + "dev": true, + "dependencies": { + "mime-db": "1.45.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + }, + "node_modules/nanoid": { + "version": "3.1.20", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.20.tgz", + "integrity": "sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw==", + "dev": true, + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, + "node_modules/node-releases": { + "version": "1.1.69", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.69.tgz", + "integrity": "sha512-DGIjo79VDEyAnRlfSqYTsy+yoHd2IOjJiKUozD2MV2D85Vso6Bug56mb9tT/fY5Urt0iqk01H7x+llAruDR2zA==", + "dev": true + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/picomatch": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "dev": true, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/pkg-dir": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-5.0.0.tgz", + "integrity": "sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA==", + "dev": true, + "dependencies": { + "find-up": "^5.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/popper.js": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1.tgz", + "integrity": "sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ==" + }, + "node_modules/postcss": { + "version": "8.2.4", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.2.4.tgz", + "integrity": "sha512-kRFftRoExRVXZlwUuay9iC824qmXPcQQVzAjbCCgjpXnkdMCJYBu2gTwAaFBzv8ewND6O8xFb3aELmEkh9zTzg==", + "dev": true, + "dependencies": { + "colorette": "^1.2.1", + "nanoid": "^3.1.20", + "source-map": "^0.6.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-modules-extract-imports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", + "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==", + "dev": true, + "engines": { + "node": "^10 || ^12 || >= 14" + } + }, + "node_modules/postcss-modules-local-by-default": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz", + "integrity": "sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ==", + "dev": true, + "dependencies": { + "icss-utils": "^5.0.0", + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.1.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + } + }, + "node_modules/postcss-modules-scope": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz", + "integrity": "sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==", + "dev": true, + "dependencies": { + "postcss-selector-parser": "^6.0.4" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + } + }, + "node_modules/postcss-modules-values": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", + "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", + "dev": true, + "dependencies": { + "icss-utils": "^5.0.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.4.tgz", + "integrity": "sha512-gjMeXBempyInaBqpp8gODmwZ52WaYsVOsfr4L4lDQ7n3ncD6mEyySiDtgzCT+NYC0mmeOLvtsF8iaEf0YT6dBw==", + "dev": true, + "dependencies": { + "cssesc": "^3.0.0", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz", + "integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==", + "dev": true + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "node_modules/prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", + "dev": true + }, + "node_modules/punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/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 + }, + "node_modules/schema-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", + "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", + "dependencies": { + "@types/json-schema": "^7.0.6", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/semver": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", + "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/serialize-javascript": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", + "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", + "dev": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/source-list-map": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", + "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", + "dev": true + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/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, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/style-loader": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-2.0.0.tgz", + "integrity": "sha512-Z0gYUJmzZ6ZdRUqpg1r8GsaFKypE+3xAzuFeMuoHgjc9KZv3wMyCRjQIWEbhoFSq7+7yoHXySDJyyWQaPajeiQ==", + "dev": true, + "dependencies": { + "loader-utils": "^2.0.0", + "schema-utils": "^3.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tapable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", + "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/terser": { + "version": "5.5.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.5.1.tgz", + "integrity": "sha512-6VGWZNVP2KTUcltUQJ25TtNjx/XgdDsBDKGt8nN0MpydU36LmbPPcMBd2kmtZNNGVVDLg44k7GKeHHj+4zPIBQ==", + "dev": true, + "dependencies": { + "commander": "^2.20.0", + "source-map": "~0.7.2", + "source-map-support": "~0.5.19" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.1.1.tgz", + "integrity": "sha512-5XNNXZiR8YO6X6KhSGXfY0QrGrCRlSwAEjIIrlRQR4W8nP69TaJUlh3bkuac6zzgspiGPfKEHcY295MMVExl5Q==", + "dev": true, + "dependencies": { + "jest-worker": "^26.6.2", + "p-limit": "^3.1.0", + "schema-utils": "^3.0.0", + "serialize-javascript": "^5.0.1", + "source-map": "^0.6.1", + "terser": "^5.5.1" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/terser/node_modules/source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/timsort": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz", + "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=" + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/ts-loader": { + "version": "8.0.14", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-8.0.14.tgz", + "integrity": "sha512-Jt/hHlUnApOZjnSjTmZ+AbD5BGlQFx3f1D0nYuNKwz0JJnuDGHJas6az+FlWKwwRTu+26GXpv249A8UAnYUpqA==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "enhanced-resolve": "^4.0.0", + "loader-utils": "^2.0.0", + "micromatch": "^4.0.0", + "semver": "^7.3.4" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "node_modules/typescript": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.1.3.tgz", + "integrity": "sha512-B3ZIOf1IKeH2ixgHhj6la6xdwR9QrLC5d1VKeCSY4tvkqhF2eqd9O7txNlS0PO3GrBAFIdr3L1ndNwteUbZLYg==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/uniq": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", + "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=", + "dev": true + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/vis-data": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/vis-data/-/vis-data-7.1.2.tgz", + "integrity": "sha512-RPSegFxEcnp3HUEJSzhS2vBdbJ2PSsrYYuhRlpHp2frO/MfRtTYbIkkLZmPkA/Sg3pPfBlR235gcoKbtdm4mbw==", + "hasInstallScript": true + }, + "node_modules/vis-network": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/vis-network/-/vis-network-9.0.4.tgz", + "integrity": "sha512-F/pq8yBJUuB9lNKXHhtn4GP2h91FV0c2O2nvfU34RX4VCYOlqs+mINdz+J+QkWiYhiPdlVy15gzVEzkhJ9hpaw==", + "hasInstallScript": true + }, + "node_modules/vis-util": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vis-util/-/vis-util-5.0.2.tgz", + "integrity": "sha512-oPDmPc4o0uQLoKpKai2XD1DjrhYsA7MRz75Wx9KmfX84e9LLgsbno7jVL5tR0K9eNVQkD6jf0Ei8NtbBHDkF1A==", + "engines": { + "node": ">=8" + } + }, + "node_modules/watchpack": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.1.0.tgz", + "integrity": "sha512-UjgD1mqjkG99+3lgG36at4wPnUXNvis2v1utwTgQ43C22c4LD71LsYMExdWXh4HZ+RmW+B0t1Vrg2GpXAkTOQw==", + "dev": true, + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack": { + "version": "5.14.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.14.0.tgz", + "integrity": "sha512-PFtfqXIKT6EG+k4L7d9whUPacN2XvxlUMc8NAQvN+sF9G8xPQqrCDGDiXbAdyGNz+/OP6ioxnUKybBBZ1kp/2A==", + "dev": true, + "dependencies": { + "@types/eslint-scope": "^3.7.0", + "@types/estree": "^0.0.45", + "@webassemblyjs/ast": "1.11.0", + "@webassemblyjs/wasm-edit": "1.11.0", + "@webassemblyjs/wasm-parser": "1.11.0", + "acorn": "^8.0.4", + "browserslist": "^4.14.5", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.7.0", + "es-module-lexer": "^0.3.26", + "eslint-scope": "^5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.4", + "json-parse-better-errors": "^1.0.2", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "pkg-dir": "^5.0.0", + "schema-utils": "^3.0.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.1.1", + "watchpack": "^2.0.0", + "webpack-sources": "^2.1.1" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack-sources": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-2.2.0.tgz", + "integrity": "sha512-bQsA24JLwcnWGArOKUxYKhX3Mz/nK1Xf6hxullKERyktjNMC4x8koOeaDNTA2fEJ09BdWLbM/iTW0ithREUP0w==", + "dev": true, + "dependencies": { + "source-list-map": "^2.0.1", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack/node_modules/enhanced-resolve": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.7.0.tgz", + "integrity": "sha512-6njwt/NsZFUKhM6j9U8hzVyD4E4r0x7NQzhTCbcWOJ0IQjNSAoalWmb0AE51Wn+fwan5qVESWi7t2ToBxs9vrw==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack/node_modules/tapable": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.0.tgz", + "integrity": "sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/xterm": { + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/xterm/-/xterm-4.9.0.tgz", + "integrity": "sha512-wGfqufmioctKr8VkbRuZbVDfjlXWGZZ1PWHy1yqqpGT3Nm6yaJx8lxDbSEBANtgaiVPTcKSp97sxOy5IlpqYfw==" + }, + "node_modules/xterm-addon-attach": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/xterm-addon-attach/-/xterm-addon-attach-0.6.0.tgz", + "integrity": "sha512-Mo8r3HTjI/EZfczVCwRU6jh438B4WLXxdFO86OB7bx0jGhwh2GdF4ifx/rP+OB+Cb2vmLhhVIZ00/7x3YSP3dg==" + }, + "node_modules/xterm-addon-fit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/xterm-addon-fit/-/xterm-addon-fit-0.4.0.tgz", + "integrity": "sha512-p4BESuV/g2L6pZzFHpeNLLnep9mp/DkF3qrPglMiucSFtD8iJxtMufEoEJbN8LZwB4i+8PFpFvVuFrGOSpW05w==" + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + } + } + }, "dependencies": { "@egjs/hammerjs": { "version": "2.0.17", @@ -295,61 +1808,11 @@ "color-convert": "^2.0.1" } }, - "asn1.js": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", - "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "safer-buffer": "^2.1.0" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - } - } - }, - "assert": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/assert/-/assert-2.0.0.tgz", - "integrity": "sha512-se5Cd+js9dXJnu6Ag2JFc00t+HmHOen+8Q+L7O9zI0PqQXr20uk2J0XQqMxZEeo5U50o8Nvmmx7dZrl+Ufr35A==", - "dev": true, - "requires": { - "es6-object-assign": "^1.1.0", - "is-nan": "^1.2.1", - "object-is": "^1.0.1", - "util": "^0.12.0" - } - }, - "available-typed-arrays": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", - "dev": true - }, - "base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true - }, "big.js": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==" }, - "bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==", - "dev": true - }, "bootstrap": { "version": "4.5.3", "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.5.3.tgz", @@ -369,104 +1832,6 @@ "fill-range": "^7.0.1" } }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", - "dev": true - }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dev": true, - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "dev": true, - "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "browserify-rsa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", - "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", - "dev": true, - "requires": { - "bn.js": "^5.0.0", - "randombytes": "^2.0.1" - } - }, - "browserify-sign": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz", - "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==", - "dev": true, - "requires": { - "bn.js": "^5.1.1", - "browserify-rsa": "^4.0.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.3", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.5", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true - } - } - }, - "browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", - "dev": true, - "requires": { - "pako": "~1.0.5" - } - }, "browserslist": { "version": "4.16.1", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.1.tgz", @@ -480,44 +1845,12 @@ "node-releases": "^1.1.69" } }, - "buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "dev": true, - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, "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 }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", - "dev": true - }, - "builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", - "dev": true - }, - "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, "camelcase": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", @@ -549,16 +1882,6 @@ "tslib": "^1.9.0" } }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -591,88 +1914,12 @@ "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" }, - "console-browserify": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", - "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", - "dev": true - }, - "constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", - "dev": true - }, "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 }, - "create-ecdh": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", - "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.5.3" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - } - } - }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "dev": true, - "requires": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - } - }, "css-loader": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-5.0.1.tgz", @@ -735,79 +1982,12 @@ "jquery": ">=1.7" } }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, - "requires": { - "object-keys": "^1.0.12" - } - }, - "des.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", - "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - } - } - }, - "domain-browser": { - "version": "4.22.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-4.22.0.tgz", - "integrity": "sha512-IGBwjF7tNk3cwypFNH/7bfzBcgSCbaMOD3GsaY1AU/JRrnHnYgEM0+9kQt52iZxjNsjBtJYtao146V+f8jFZNw==", - "dev": true - }, "electron-to-chromium": { "version": "1.3.638", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.638.tgz", "integrity": "sha512-vbTdlXeu3pAtPt0/T3+HVyX9bu6Lx/iXUYSWBCCRDI+JQiq48m6o4BnZPLBy40+4E0dLbt/Ix9VIJ/06XztfoA==", "dev": true }, - "elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", - "dev": true, - "requires": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - } - } - }, "emojis-list": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", @@ -833,57 +2013,12 @@ "prr": "~1.0.1" } }, - "es-abstract": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.2.tgz", - "integrity": "sha512-gfSBJoZdlL2xRiOCy0g8gLMryhoe1TlimjzU99L/31Z8QEGIhVQI+EWwt5lT+AuU9SnorVupXFqqOGqGfsyO6w==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "get-intrinsic": "^1.1.1", - "get-symbol-description": "^1.0.0", - "has": "^1.0.3", - "has-symbols": "^1.0.3", - "internal-slot": "^1.0.3", - "is-callable": "^1.2.4", - "is-negative-zero": "^2.0.2", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.1", - "is-string": "^1.0.7", - "is-weakref": "^1.0.2", - "object-inspect": "^1.12.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.2", - "string.prototype.trimend": "^1.0.4", - "string.prototype.trimstart": "^1.0.4", - "unbox-primitive": "^1.0.1" - } - }, "es-module-lexer": { "version": "0.3.26", "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.3.26.tgz", "integrity": "sha512-Va0Q/xqtrss45hWzP8CZJwzGSZJjDM5/MJRE3IXXnUCcVLElR9BRaE9F62BopysASyc4nM3uwhSW7FFB9nlWAA==", "dev": true }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "es6-object-assign": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/es6-object-assign/-/es6-object-assign-1.1.0.tgz", - "integrity": "sha1-wsNYJlYkfDnqEHyx5mUrb58kUjw=", - "dev": true - }, "escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -929,16 +2064,6 @@ "integrity": "sha512-/46HWwbfCX2xTawVfkKLGxMifJYQBWMwY1mjywRtb4c9x8l5NP3KoJtnIOiL1hfdRkIuYhETxQlo62IF8tcnlg==", "dev": true }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dev": true, - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -967,163 +2092,37 @@ "to-regex-range": "^5.0.1" } }, - "filter-obj": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-2.0.2.tgz", - "integrity": "sha512-lO3ttPjHZRfjMcxWKb1j1eDhTFsu4meeR3lnMcnBFhk6RuLhvEiuALu2TlfL310ph4lCYYwgF/ElIjdP739tdg==", - "dev": true - }, "find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, "requires": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - } - }, - "foreach": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", - "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=", - "dev": true - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" - } - }, - "get-symbol-description": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" - } - }, - "glob-to-regexp": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", - "dev": true - }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, - "hammerjs": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/hammerjs/-/hammerjs-2.0.8.tgz", - "integrity": "sha1-BO93hiz/K7edMPdpIJWTAiK/YPE=" - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-bigints": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", - "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "dev": true - }, - "has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "dev": true, - "requires": { - "has-symbols": "^1.0.2" - } - }, - "hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "dev": true, - "requires": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true - } - } - }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "dev": true, - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" } }, - "https-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", + "glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "hammerjs": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/hammerjs/-/hammerjs-2.0.8.tgz", + "integrity": "sha1-BO93hiz/K7edMPdpIJWTAiK/YPE=" + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, "icss-utils": { @@ -1132,12 +2131,6 @@ "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", "dev": true }, - "ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true - }, "indexes-of": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", @@ -1150,157 +2143,12 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, - "internal-slot": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", - "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", - "dev": true, - "requires": { - "get-intrinsic": "^1.1.0", - "has": "^1.0.3", - "side-channel": "^1.0.4" - } - }, - "is-arguments": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", - "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "dev": true, - "requires": { - "has-bigints": "^1.0.1" - } - }, - "is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-callable": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", - "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", - "dev": true - }, - "is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-generator-function": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", - "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-nan": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz", - "integrity": "sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3" - } - }, - "is-negative-zero": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", - "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", - "dev": true - }, "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true }, - "is-number-object": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz", - "integrity": "sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-shared-array-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz", - "integrity": "sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==", - "dev": true - }, - "is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "dev": true, - "requires": { - "has-symbols": "^1.0.2" - } - }, - "is-typed-array": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.8.tgz", - "integrity": "sha512-HqH41TNZq2fgtGT8WHVFVJhBVGuY3AnP3Q36K8JKXUxSxRgk/d+7NjmwG2vo2mYmXK8UYZKu0qH8bVP5gEisjA==", - "dev": true, - "requires": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "es-abstract": "^1.18.5", - "foreach": "^2.0.5", - "has-tostringtag": "^1.0.0" - } - }, - "is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2" - } - }, "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", @@ -1386,17 +2234,6 @@ "yallist": "^4.0.0" } }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, "memory-fs": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", @@ -1423,24 +2260,6 @@ "picomatch": "^2.0.5" } }, - "miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - } - } - }, "mime-db": { "version": "1.45.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.45.0.tgz", @@ -1456,18 +2275,6 @@ "mime-db": "1.45.0" } }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", - "dev": true - }, "minimist": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", @@ -1485,118 +2292,12 @@ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", "dev": true }, - "node-polyfill-webpack-plugin": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/node-polyfill-webpack-plugin/-/node-polyfill-webpack-plugin-1.1.4.tgz", - "integrity": "sha512-Z0XTKj1wRWO8o/Vjobsw5iOJCN+Sua3EZEUc2Ziy9CyVvmHKu6o+t4gUH9GOE0czyPR94LI6ZCV/PpcM8b5yow==", - "dev": true, - "requires": { - "assert": "^2.0.0", - "browserify-zlib": "^0.2.0", - "buffer": "^6.0.3", - "console-browserify": "^1.2.0", - "constants-browserify": "^1.0.0", - "crypto-browserify": "^3.12.0", - "domain-browser": "^4.19.0", - "events": "^3.3.0", - "filter-obj": "^2.0.2", - "https-browserify": "^1.0.0", - "os-browserify": "^0.3.0", - "path-browserify": "^1.0.1", - "process": "^0.11.10", - "punycode": "^2.1.1", - "querystring-es3": "^0.2.1", - "readable-stream": "^3.6.0", - "stream-browserify": "^3.0.0", - "stream-http": "^3.2.0", - "string_decoder": "^1.3.0", - "timers-browserify": "^2.0.12", - "tty-browserify": "^0.0.1", - "url": "^0.11.0", - "util": "^0.12.4", - "vm-browserify": "^1.1.2" - }, - "dependencies": { - "events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "dev": true - }, - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, - "requires": { - "safe-buffer": "~5.2.0" - } - } - } - }, "node-releases": { "version": "1.1.69", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.69.tgz", "integrity": "sha512-DGIjo79VDEyAnRlfSqYTsy+yoHd2IOjJiKUozD2MV2D85Vso6Bug56mb9tT/fY5Urt0iqk01H7x+llAruDR2zA==", "dev": true }, - "object-inspect": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", - "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==", - "dev": true - }, - "object-is": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", - "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "object.assign": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", - "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", - "object-keys": "^1.1.1" - } - }, - "os-browserify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", - "dev": true - }, "p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -1615,50 +2316,12 @@ "p-limit": "^3.0.2" } }, - "pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "dev": true - }, - "parse-asn1": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", - "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", - "dev": true, - "requires": { - "asn1.js": "^5.2.0", - "browserify-aes": "^1.0.0", - "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3", - "safe-buffer": "^5.1.1" - } - }, - "path-browserify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", - "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", - "dev": true - }, "path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true }, - "pbkdf2": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", - "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", - "dev": true, - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, "picomatch": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", @@ -1743,12 +2406,6 @@ "integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==", "dev": true }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", - "dev": true - }, "process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -1761,45 +2418,11 @@ "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", "dev": true }, - "public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - } - } - }, "punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", - "dev": true - }, - "querystring-es3": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", - "dev": true - }, "randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -1809,16 +2432,6 @@ "safe-buffer": "^5.1.0" } }, - "randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "dev": true, - "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, "readable-stream": { "version": "2.3.7", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", @@ -1834,28 +2447,12 @@ "util-deprecate": "~1.0.1" } }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, "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 }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, "schema-utils": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", @@ -1884,33 +2481,6 @@ "randombytes": "^2.1.0" } }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", - "dev": true - }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - } - }, "source-list-map": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", @@ -1933,74 +2503,6 @@ "source-map": "^0.6.0" } }, - "stream-browserify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-3.0.0.tgz", - "integrity": "sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==", - "dev": true, - "requires": { - "inherits": "~2.0.4", - "readable-stream": "^3.5.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "stream-http": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-3.2.0.tgz", - "integrity": "sha512-Oq1bLqisTyK3TSCXpPbT4sdeYNdmyZJv1LxpEm2vu1ZhK89kSE5YXwZc3cWk0MagGaKriBh9mCFbVGtO+vY29A==", - "dev": true, - "requires": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "xtend": "^4.0.2" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "string.prototype.trimend": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", - "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "string.prototype.trimstart": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", - "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -2068,15 +2570,6 @@ "terser": "^5.5.1" } }, - "timers-browserify": { - "version": "2.0.12", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz", - "integrity": "sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==", - "dev": true, - "requires": { - "setimmediate": "^1.0.4" - } - }, "timsort": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz", @@ -2110,30 +2603,12 @@ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", "dev": true }, - "tty-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.1.tgz", - "integrity": "sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==", - "dev": true - }, "typescript": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.1.3.tgz", "integrity": "sha512-B3ZIOf1IKeH2ixgHhj6la6xdwR9QrLC5d1VKeCSY4tvkqhF2eqd9O7txNlS0PO3GrBAFIdr3L1ndNwteUbZLYg==", "dev": true }, - "unbox-primitive": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", - "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "has-bigints": "^1.0.1", - "has-symbols": "^1.0.2", - "which-boxed-primitive": "^1.0.2" - } - }, "uniq": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", @@ -2148,38 +2623,6 @@ "punycode": "^2.1.0" } }, - "url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", - "dev": true, - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - }, - "dependencies": { - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", - "dev": true - } - } - }, - "util": { - "version": "0.12.4", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.4.tgz", - "integrity": "sha512-bxZ9qtSlGUWSOy9Qa9Xgk11kSslpuZwaxCg4sNIDj6FLucDab2JxnHwyNTCpHMtK1MjoQiWQ6DiUMZYbSrO+Sw==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "is-arguments": "^1.0.4", - "is-generator-function": "^1.0.7", - "is-typed-array": "^1.1.3", - "safe-buffer": "^5.1.2", - "which-typed-array": "^1.1.2" - } - }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -2206,12 +2649,6 @@ "resolved": "https://registry.npmjs.org/vis-util/-/vis-util-5.0.2.tgz", "integrity": "sha512-oPDmPc4o0uQLoKpKai2XD1DjrhYsA7MRz75Wx9KmfX84e9LLgsbno7jVL5tR0K9eNVQkD6jf0Ei8NtbBHDkF1A==" }, - "vm-browserify": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", - "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", - "dev": true - }, "watchpack": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.1.0.tgz", @@ -2282,39 +2719,6 @@ "source-map": "^0.6.1" } }, - "which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dev": true, - "requires": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - } - }, - "which-typed-array": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.7.tgz", - "integrity": "sha512-vjxaB4nfDqwKI0ws7wZpxIlde1XrLX5uB0ZjpfshgmapJMD7jJWhZI+yToJTqaFByF0eNBcYxbjmCzoRP7CfEw==", - "dev": true, - "requires": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "es-abstract": "^1.18.5", - "foreach": "^2.0.5", - "has-tostringtag": "^1.0.0", - "is-typed-array": "^1.1.7" - } - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true - }, "xterm": { "version": "4.9.0", "resolved": "https://registry.npmjs.org/xterm/-/xterm-4.9.0.tgz", diff --git a/client/frontend/public/map.html b/client/frontend/public/map.html index fb6007bad..11356b0a8 100644 --- a/client/frontend/public/map.html +++ b/client/frontend/public/map.html @@ -15,8 +15,7 @@
Filter
Search
-
Blockchain
-
+
@@ -85,4 +84,4 @@ - + \ No newline at end of file diff --git a/client/frontend/src/map/datasource.ts b/client/frontend/src/map/datasource.ts index d841ee853..62129fd09 100644 --- a/client/frontend/src/map/datasource.ts +++ b/client/frontend/src/map/datasource.ts @@ -148,14 +148,6 @@ export class DataSource { this._socket.close(); } - async initPlugin(type:number) { - try { - (await this._load('POST', `${this._apiBase}/plugin/${type}/init`)) - } catch(e) { - console.log(e) - } - } - /** * get current sniff filter expression. * @@ -312,4 +304,4 @@ export class DataSource { return groups; } -} +} \ No newline at end of file diff --git a/client/frontend/src/map/map.ts b/client/frontend/src/map/map.ts index b043cc734..390e273bb 100644 --- a/client/frontend/src/map/map.ts +++ b/client/frontend/src/map/map.ts @@ -27,8 +27,7 @@ const mapUi = new MapUi({ filterControls: { filterModeTabElementId: 'tab-filter-mode', nodeSearchModeTabElementId: 'tab-node-search-mode', - suggestionsElementId: 'filter-suggestions', - blockchainTabElementId: 'tab-node-blockchain-plugin' + suggestionsElementId: 'filter-suggestions' }, replayControls: { recordButtonElementId: 'replay-record', @@ -46,4 +45,4 @@ const mapUi = new MapUi({ } }); -mapUi.start(); +mapUi.start(); \ No newline at end of file diff --git a/client/frontend/src/map/ui.ts b/client/frontend/src/map/ui.ts index 7e17c1b93..506a7ad6f 100644 --- a/client/frontend/src/map/ui.ts +++ b/client/frontend/src/map/ui.ts @@ -5,8 +5,6 @@ import { Completion } from '../common/completion'; import { EmulatorNetwork, EmulatorNode } from '../common/types'; import { WindowManager } from '../common/window-manager'; import { DataSource, Edge, Vertex } from './datasource'; -import { data, event } from 'jquery'; - /** * map UI element bindings. @@ -31,8 +29,7 @@ export interface MapUiConfiguration { filterControls: { // filter controls filterModeTabElementId: string, // element id of tab for setting mode to filter nodeSearchModeTabElementId: string, // element id of tab for setting mode to search - suggestionsElementId: string, // element id of search suggestions - blockchainTabElementId: string + suggestionsElementId: string // element id of search suggestions }, replayControls: { // replay controls recordButtonElementId: string, // element id of record button @@ -50,7 +47,7 @@ export interface MapUiConfiguration { } } -type FilterMode = 'node-search' | 'filter' | 'blockchain'; +type FilterMode = 'node-search' | 'filter'; type SuggestionSelectionAction = 'up' | 'down' | 'clear'; @@ -84,7 +81,6 @@ export class MapUi { private _filterModeTab: HTMLElement; private _searchModeTab: HTMLElement; private _suggestions: HTMLElement; - private _blockchain: HTMLElement; private _logToggle: HTMLElement; private _logToggleChevron: HTMLElement; @@ -104,8 +100,6 @@ export class MapUi { private _edges: DataSet; private _graph: Network; - private _groups: any; - /** list of log elements to be rendered to log body */ private _logQueue: HTMLElement[]; @@ -113,9 +107,6 @@ export class MapUi { private _flashQueue: Set; /** set of vertex ids scheduled for un-flash */ private _flashingNodes: Set; - - private __filters: string[]; - /** save the filter type for plugin in */ private _logPrinter: number; private _flasher: number; @@ -180,7 +171,6 @@ export class MapUi { this._filterModeTab = document.getElementById(config.filterControls.filterModeTabElementId); this._searchModeTab = document.getElementById(config.filterControls.nodeSearchModeTabElementId); this._suggestions = document.getElementById(config.filterControls.suggestionsElementId); - this._blockchain = document.getElementById(config.filterControls.blockchainTabElementId); this._logToggle = document.getElementById(config.logControls.minimizeToggleElementId); this._logToggleChevron = document.getElementById(config.logControls.minimizeChevronElementId); @@ -323,60 +313,6 @@ export class MapUi { this._filterInput.onclick = () => { this._updateFilterSuggestions(this._filterInput.value); }; - - this._blockchain.onclick = async() => { - this._setFilterMode('blockchain'); - // send post request - const type = 1 // 1 represents blockchain in PluginEnum.ts - await this._datasource.initPlugin(type) - const url = `ws://localhost:8080/api/v1/plugin/${type}/command/` - const ws = new WebSocket(url) - ws.onmessage = (event) => { - const data = JSON.parse(event.data) - if(data.eventType === "settings"){ - this.__filters = data.data.filters; - return; - } - if(!data.containerId) { - return; - } - - const node = Array.from(this._nodes.map(node => { - return { - id: node.id, - group: node.group - } - })).filter(node => node.id === data.containerId)[0] - console.log(node) - const {color} = this._groups[node.group] - - this._nodes.update({ - ...data.data, - id: data.containerId - }); - - //un-flash - setTimeout(() => { - this._nodes.update({ - id: data.containerId, - borderWidth: 1, - color - }) - },500) - } - - this._filterInput.addEventListener("keypress",function(event){ - const keyCode =( document.getElementById("filter")); - - if(event.key == "Enter"){ - - ws.send(JSON.stringify({ - command: new String(keyCode.value) - })) - - } - }) - }; this._windowManager.on('taskbarchanges', (shown: boolean) => { if (shown) { @@ -613,7 +549,6 @@ export class MapUi { this._filterInput.placeholder = 'Type a BPF expression to animate packet flows on the map...'; this._filterModeTab.classList.remove('inactive'); this._searchModeTab.classList.add('inactive'); - this._blockchain.classList.add('inactive'); } if (mode == 'node-search') { @@ -621,18 +556,8 @@ export class MapUi { this._filterInput.placeholder = 'Search networks and nodes...'; this._filterModeTab.classList.add('inactive'); this._searchModeTab.classList.remove('inactive'); - this._blockchain.classList.add('inactive'); this._filterUpdateHandler(null, true); } - - if(mode == 'blockchain'){ - - this._filterInput.placeholder = 'Please input the blockchain command... '; - - this._filterModeTab.classList.add('inactive'); - this._searchModeTab.classList.add('inactive'); - this._blockchain.classList.remove('inactive'); - } } /** @@ -869,38 +794,6 @@ export class MapUi { }); } - if(this._filterMode =="blockchain"){ - let command: string[] = ['start ', 'stop ']; - let eventType: string[] = this.__filters || ['newBlockHeaders', 'pendingTransactions']; - command.forEach(mycmd =>{ - eventType.forEach(myEvent =>{ - var itemName = myEvent; - var itemDetails = ''; - - let item = document.createElement('div'); - item.className = 'suggestion'; - - let name = document.createElement('span'); - name.className = 'name'; - itemName = mycmd.concat(myEvent); - name.innerText = itemName; - - let details = document.createElement('span'); - details.className = 'details'; - details.innerText = itemDetails; - - item.appendChild(name); - item.appendChild(details); - item.onclick = () => { - this._moveSuggestionSelection('clear'); - this._updateFilterSuggestions(this._filterInput.value); - }; - - this._suggestions.appendChild(item); - }) - }) - } - } /** @@ -1428,8 +1321,6 @@ export class MapUi { } }); - this._groups = groups; - this._graph = new Network(this._mapElement, { nodes: this._nodes, edges: this._edges diff --git a/examples/B06-blockchain/README.md b/examples/B06-blockchain/README.md index 129213fd1..ecee0d8c9 100644 --- a/examples/B06-blockchain/README.md +++ b/examples/B06-blockchain/README.md @@ -1,22 +1,151 @@ ## Table of Content +- [Build a Blockchain Component](#blockchain-component) - [Build emulator with blockchain](#emulator) - [Use blockchain](#use-blockchain) - [Smart contract](#smart-contract) - [Manually deploy a smart contract](#smart-contract-manual) -------------------- - -# Build Emulator with Blockchain + +# Build a Blockchain Component + +## A.1 Creating Virtual Blockchain Node + +We will create the Blockchain nodes at the Ethereum layer, +so each node created is a virtual node so that they can be deployed +in different emulators. + +```python +# Create the Ethereum layer +# saveState=True: will set the blockchain folder using `volumes`, +# so the blockchain data will be preserved when containers are deleted. +eth = EthereumService(saveState = True, override=True) + + +# Create POW Ethereum nodes (nodes in this layer are virtual) +# Default consensus mechanism is POW. +e1 = eth.install("eth1").setConsensusMechanism(ConsensusMechanism.POW) +e2 = eth.install("eth2") +e3 = eth.install("eth3") +e4 = eth.install("eth4") + +# Create POA Ethereum nodes +e5 = eth.install("eth5").setConsensusMechanism(ConsensusMechanism.POA) +e6 = eth.install("eth6").setConsensusMechanism(ConsensusMechanism.POA) +e7 = eth.install("eth7").setConsensusMechanism(ConsensusMechanism.POA) +e8 = eth.install("eth8").setConsensusMechanism(ConsensusMechanism.POA) +``` + + +## A.2 Setting a Node as a Bootnode + +We can set a node as a bootnode that bootstraps all blockchain nodes. +If a node is set as a bootnode, it will run a http server that sends +its blockchain node url so that the other nodes can connect to it. +The default port number of the http server is 8088 and it can be +customized. If bootnode does not set to any node, we should specify +peer nodes urls manually. + +```python +# Set bootnode on e1. The other nodes can use these bootnodes to find peers. +e1.setBootNode(True).setBootNodeHttpPort(8090) +``` + +## A.3 Creating Accounts + +By default, one account will be created per node. In POW Consensus, +the account will be created with no balance. In the case of POA Consensus, +the account will have 32*pow(10,18) balance as the node will not get sealing +(mining) rewards in POA. +If you want to create additional accounts you can use `createAccount` +or `createAccounts` method. Using a `createAccount`, you can create +an individual account customizing balance and password. On the other +hand, using a `createAccounts` method, you create a bulk of accounts +that have same amount of balance and a same password. + +```python +# Create more accounts with Balance on e3 and e7 +# Create one account with createAccount() method +# Create multiple accounts with createAccounts() method +e3.createAccount(balance= 32 * pow(10,18), password="admin") +e7.createAccounts(3, balance = 32*pow(10,18), password="admin") +``` + +## A.4 Importing Accounts + +When you want to reuse an existing account, you can use `importAccount` method. + +```python +# Import account with balance 0 on e2 +e2.importAccount(keyfilePath='./resources/keyfile_to_import', password="admin", balance=0) +``` -## A.1 Automated setup +## A.5 Setting Geth Command Options -Make sure driver.sh has the executable permission by running `chmod +x driver.sh` -./driver.sh will automate each of the steps mentioned below. -If any issue occurs, it would be best to do them manually. +We use `go-ethereum;geth` software to run blockchains on emulator. +When the containers are up, they will install `geth` and run it with the command +which is generated from EthereumService Class. We can customized the +`geth start command` with the following methods. +The `base start command` is `geth --datadir /root/.ethereum --identity="NODE_5" --networkid=10 --syncmode full --verbosity=2 --allow-insecure-unlock --port 30303` +- `setNoDiscover()` = --nodiscover +- `enableGethHttp()` = --http --http.addr 0.0.0.0 --http.port 8545 --http.corsdomain "*" --http.api web3,eth,debug,personal,net,clique +- `enableGethWs()` = --ws --ws.addr 0.0.0.0 --ws.port 8546 --ws.origins "*" --ws.api web3,eth,debug,personal,net,clique +- `unlockAccounts()` = --unlock "{accounts}" --password "{accounts_passwords}" +- `startMiner()` = --mine --miner.threads=1 -## A.2 Create the Blockchain Component +You can also set further options using `setCustomGethCommandOption()` method. +The options will append to the `base start command`. + +```python +# Start mining on e1,e2 and e5,e6 +# To start mine(seal) in POA consensus, the account should be unlocked first. +e1.setBootNode(True).setBootNodeHttpPort(8090).startMiner() +e2.startMiner() +e5.setBootNode(True).unlockAccounts().startMiner() +e6.unlockAccounts().startMiner() + +# Enable http connection on e3 +# Set geth http port to 8540 (Default : 8545) +e3.enableGethHttp().setGethHttpPort(8540) + +# Set custom geth command option on e4 +# Possible to enable geth http using setCustomGethCommandOption() method +# instead of using enableGethHttp() method +e4.setCustomGethCommandOption("--http --http.addr 0.0.0.0") + +# Enable ws connection on e5 geth +# Set geth ws port to 8541 (Default : 8546) +e5.enableGethWs().setGethWsPort(8541) + +# Set nodiscover option on e8 geth +e8.setNoDiscover() +``` +## A.6 Setting Custom Geth Binary + +Occationally, it is needed to set customed `geth` binary instead of the original one +to conduct experiment. In this case, you can use `setCustomGeth()` method. + +```python +# Set custom geth binary file instead of installing an original file. +e3.setCustomGeth("./resources/custom_geth") +``` + +## A.7 Setting Custom Genesis + +If you want to deploy your customed genesis file on a blockchain, +you can set the customed genesis using the `setGenesis()` method. + +```python +# Set custom genesis on e4 geth +e4.setGenesis(CustomGenesisFileContent) +``` + + +# Build Emulator with Blockchain + +## B.1 Create the Blockchain Component We create the Blockchain in `component-blockchain.py`. This program generates a Ethereum component, which can be deployed @@ -28,7 +157,7 @@ Please refer to the comments in the code to understand how the layer is built. -## A.3 Deploying the Blockchain +## B.2 Deploying the Blockchain We deploy the blockchain in `blockchain.py`. It first loads two pre-built components, a base-layer component and a blockchain component. The @@ -50,26 +179,18 @@ emu.addBinding(Binding('eth1', filter = Filter(asn = 151))) ... ``` -## A.4 Generate the Emulation Files and Set Up the Data Folders +## B.4 Generate the Emulation Files and Set Up the Data Folders After running the two Python programs (make sure to also run the B00 example to generate the base layer first), we will get the `output` folder, which contains all the Docker files for the emulation. If we set `saveState=True` when creating the `EthereumService` object, -we need to manually create the folders inside the `output` folder, because -these folders will be used to hold the blockchain data on each ethereum node. -In the future, we will do it automatically. +`eth-states` folder will be created automatically and +used to hold the blockchain data on each ethereum node. -``` -$ cd output -$ mkdir -p eth-states/1 -$ mkdir -p eth-states/2 -... -$ mkdir -p eth-states/6 -``` -## A.5 Start the Emulator +## B.5 Start the Emulator Now we can run the docker-compose commands inside the `output` folder to build the containers and then start them. @@ -108,7 +229,7 @@ root@f6fb88f9e09d / # # Use Blockchain -## B.1 Access the Blockchain Network +## C.1 Access the Blockchain Network Once we are inside an Ethereum container, we can use the `geth` command to access the Blockchain. @@ -146,7 +267,7 @@ theirs will still be zero. 527937500000000000000 ``` -## B.2 Get Account Numbers +## C.2 Get Account Numbers A typical transaction involves sending some ethers from our account to another account. First, we need to get the account numbers. All the @@ -191,7 +312,7 @@ so its balance is zero. We will send some ethers to this account. 897750000000000000000 ``` -## B.3 Create Transactions +## C.3 Create Transactions Now from the geth console, we can create a transaction to send ethers to the target account. After waiting for a few seconds, we check the balance again. We will @@ -214,7 +335,7 @@ account, or the unlocking period has already expired (you need to unlock it again). -## B.4 Get Transaction Information +## C.4 Get Transaction Information The transaction hash value will be printed out after we run `eth.sendTransaction()`. We can use this hash to get the details about this transaction. @@ -245,7 +366,7 @@ It shows which block this transaction is added to. # Smart Contract -## C.1 Example +## D.1 Example In this example, we have provided an smart contract program inside the `Contract/` folder. You can also write one yourself. @@ -261,7 +382,7 @@ solc --abi | awk '/JSON ABI/{x=1}x' | sed 1d > contract.abi solc --bin | awk '/Binary:/{x=1;next}x' | sed 1d > contract.abi ``` -## C.2 Deploy Smart Contract +## D.2 Deploy Smart Contract To deploy a smart contract in the Emulator, we first need to create a `SmartContract` object using the generated `abi` and `bin` files, and @@ -283,7 +404,7 @@ to deploy a smart contract is 1000000 (in wei). Our further development will make this value configurable. -## C.3 Get the Smart Contract Address +## D.3 Get the Smart Contract Address Once the contract is deployed, we can perform certain tasks on it. The supplied program `contract.sol` acts as a bank account. We can @@ -341,7 +462,7 @@ done on any node. } ``` -## C.4 Send Ethers to Contract +## D.4 Send Ethers to Contract We can treat the contract as a bank account, and can send ethers to this account. This is similar to sending ethers to a normal account. All we need to do is to @@ -361,7 +482,7 @@ create a transaction. **Note:** It takes a little bit of time for the transaction to be added to the blockchain. -## C.5 Invoke Smart Contract APIs +## D.5 Invoke Smart Contract APIs To invoke the APIs in a smart contract is little bit more complicated. Let us look at the source code of the smart contract example (in `Contracts/contract.sol`). diff --git a/examples/B06-blockchain/blockchain.py b/examples/B06-blockchain/blockchain.py index d1fa3dd5d..d84e83e4e 100755 --- a/examples/B06-blockchain/blockchain.py +++ b/examples/B06-blockchain/blockchain.py @@ -4,7 +4,6 @@ from seedemu.core import Emulator, Binding, Filter from seedemu.mergers import DEFAULT_MERGERS from seedemu.compiler import Docker -from os import mkdir, chdir, getcwd, path emuA = Emulator() @@ -22,30 +21,12 @@ emu.addBinding(Binding('eth4', filter = Filter(asn = 164))) emu.addBinding(Binding('eth5', filter = Filter(asn = 150))) emu.addBinding(Binding('eth6', filter = Filter(asn = 170))) - -output = './output' - -def createDirectoryAtBase(base:str, directory:str, override:bool = False): - cur = getcwd() - if path.exists(base): - chdir(base) - if override: - rmtree(directory) - mkdir(directory) - chdir(cur) - - -saveState = True -def updateEthStates(): - if saveState: - createDirectoryAtBase(output, "eth-states/") - for i in range(1, 7): - createDirectoryAtBase(output, "eth-states/" + str(i)) +emu.addBinding(Binding('eth7', filter = Filter(asn = 161))) +emu.addBinding(Binding('eth8', filter = Filter(asn = 162))) # Render and compile emu.render() # If output directory exists and override is set to false, we call exit(1) # updateOutputdirectory will not be called -emu.compile(Docker(), output) -updateEthStates() +emu.compile(Docker(), './output') diff --git a/examples/B06-blockchain/component-blockchain.py b/examples/B06-blockchain/component-blockchain.py index d0a1e697d..e77bbd97a 100755 --- a/examples/B06-blockchain/component-blockchain.py +++ b/examples/B06-blockchain/component-blockchain.py @@ -3,46 +3,107 @@ from seedemu import * +CustomGenesisFileContent = '''\ +{ + "nonce":"0x0", + "timestamp":"0x621549f1", + "parentHash":"0x0000000000000000000000000000000000000000000000000000000000000000", + "extraData":"0x", + "gasLimit":"0x80000000", + "difficulty":"0x0", + "mixhash":"0x0000000000000000000000000000000000000000000000000000000000000000", + "coinbase":"0x0000000000000000000000000000000000000000", + "number": "0x0", + "gasUsed": "0x0", + "baseFeePerGas": null, + "config": { + "chainId": 11, + "homesteadBlock": 0, + "eip150Block": 0, + "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "eip155Block": 0, + "eip158Block": 0, + "byzantiumBlock": 0, + "constantinopleBlock": 0, + "petersburgBlock": 0, + "istanbulBlock": 0, + "ethash": { + } + }, + "alloc": { + } +} +''' + emu = Emulator() # Create the Ethereum layer # saveState=True: will set the blockchain folder using `volumes`, # so the blockchain data will be preserved when containers are deleted. -# Note: right now we need to manually create the folder for each node (see README.md). -eth = EthereumService(saveState = True) +eth = EthereumService(saveState = True, override=True) -# Create Ethereum nodes (nodes in this layer are virtual) -e1 = eth.install("eth1") +# Create POW Ethereum nodes (nodes in this layer are virtual) +# Default consensus mechanism is POW. +e1 = eth.install("eth1").setConsensusMechanism(ConsensusMechanism.POW) e2 = eth.install("eth2") e3 = eth.install("eth3") e4 = eth.install("eth4") -e5 = eth.install("eth5") -e6 = eth.install("eth6") -# Set bootnodes on e1 and e2. The other nodes can use these bootnodes to find peers. -# Start mining on e1 - e4 -e1.setBootNode(True).setBootNodeHttpPort(8081).startMiner() -e2.setBootNode(True).startMiner() -e3.startMiner() -e4.startMiner() +# Create POA Ethereum nodes +e5 = eth.install("eth5").setConsensusMechanism(ConsensusMechanism.POA) +e6 = eth.install("eth6").setConsensusMechanism(ConsensusMechanism.POA) +e7 = eth.install("eth7").setConsensusMechanism(ConsensusMechanism.POA) +e8 = eth.install("eth8").setConsensusMechanism(ConsensusMechanism.POA) + +# Set bootnodes on e1 and e5. The other nodes can use these bootnodes to find peers. +# Start mining on e1,e2 and e5,e6 +# To start mine(seal) in POA consensus, the account should be unlocked first. +e1.setBootNode(True).setBootNodeHttpPort(8090).startMiner() +e2.startMiner() +e5.setBootNode(True).unlockAccounts().startMiner() +e6.unlockAccounts().startMiner() + +# Create more accounts with Balance on e3 and e7 +# Create one account with createAccount() method +# Create multiple accounts with createAccounts() method +e3.createAccount(balance= 32 * pow(10,18), password="admin").unlockAccounts() +e7.createAccounts(3, balance = 32*pow(10,18), password="admin") + +# Import account with balance 0 on e2 +e2.importAccount(keyfilePath='./resources/keyfile_to_import', password="admin", balance=0) + +# Enable http connection on e3 +# Set geth http port to 8540 (Default : 8545) +e3.enableGethHttp().setGethHttpPort(8540) + +# Set custom genesis on e4 geth +e4.setGenesis(CustomGenesisFileContent) + +# Set custom geth command option on e4 +# Possible to enable geth http using setCustomGethCommandOption() method +# instead of using enableGethHttp() method +e4.setCustomGethCommandOption("--http --http.addr 0.0.0.0") + +# Enable ws connection on e5 geth +# Set geth ws port to 8541 (Default : 8546) +e5.enableGethWs().setGethWsPort(8541) -# Create more accounts on e5 and e6 -e5.startMiner().createNewAccount(3) -e6.createNewAccount().createNewAccount() +# Set nodiscover option on e8 geth +e8.setNoDiscover() -# Create a smart contract and deploy it from node e3 -# We need to put the compiled smart contracts inside the Contracts/ folder -smart_contract = SmartContract("./Contracts/contract.bin", "./Contracts/contract.abi") -e3.deploySmartContract(smart_contract) +# Set custom geth binary file instead of installing an original file. +e3.setCustomGeth("./resources/custom_geth") # Customizing the display names (for visualization purpose) -emu.getVirtualNode('eth1').setDisplayName('Ethereum-1') -emu.getVirtualNode('eth2').setDisplayName('Ethereum-2') -emu.getVirtualNode('eth3').setDisplayName('Ethereum-3') -emu.getVirtualNode('eth4').setDisplayName('Ethereum-4') -emu.getVirtualNode('eth5').setDisplayName('Ethereum-5') -emu.getVirtualNode('eth6').setDisplayName('Ethereum-6') +emu.getVirtualNode('eth1').setDisplayName('Ethereum-POW-1') +emu.getVirtualNode('eth2').setDisplayName('Ethereum-POW-2') +emu.getVirtualNode('eth3').setDisplayName('Ethereum-POW-3').addPortForwarding(8545, 8540) +emu.getVirtualNode('eth4').setDisplayName('Ethereum-POW-4') +emu.getVirtualNode('eth5').setDisplayName('Ethereum-POA-5') +emu.getVirtualNode('eth6').setDisplayName('Ethereum-POA-6') +emu.getVirtualNode('eth7').setDisplayName('Ethereum-POA-7') +emu.getVirtualNode('eth8').setDisplayName('Ethereum-POA-8') # Add the layer and save the component to a file emu.addLayer(eth) diff --git a/examples/B06-blockchain/resources/custom_geth b/examples/B06-blockchain/resources/custom_geth new file mode 100755 index 000000000..c45ea1207 Binary files /dev/null and b/examples/B06-blockchain/resources/custom_geth differ diff --git a/examples/B06-blockchain/resources/keyfile_to_import b/examples/B06-blockchain/resources/keyfile_to_import new file mode 100755 index 000000000..5104349a3 --- /dev/null +++ b/examples/B06-blockchain/resources/keyfile_to_import @@ -0,0 +1 @@ +{"address": "9f189536def35811e1a759860672fe49a4f89e94", "crypto": {"cipher": "aes-128-ctr", "cipherparams": {"iv": "25d878dfbfb307b4a25a61b1141c0b70"}, "ciphertext": "d6e55dfecc95d007738b9c6c861dbb2ab9ae1e0e6bc2207a85a898235f755563", "kdf": "scrypt", "kdfparams": {"dklen": 32, "n": 262144, "r": 1, "p": 8, "salt": "500998de07ce25a9cae9fff17973dcb3"}, "mac": "ddc1fd35d3fd6e7a9f4296953a36aac8f09812c864b4bb6ed9e688a7d3e3ac65"}, "id": "d672b132-e346-40eb-bf04-ecc8fbe535e1", "version": 3} diff --git a/examples/B08-Remix-Connection/blockchain.py b/examples/B08-Remix-Connection/blockchain.py index 1a2abccc3..f258331cb 100755 --- a/examples/B08-Remix-Connection/blockchain.py +++ b/examples/B08-Remix-Connection/blockchain.py @@ -4,8 +4,6 @@ from seedemu.core import Emulator, Binding, Filter from seedemu.mergers import DEFAULT_MERGERS from seedemu.compiler import Docker -from os import mkdir, chdir, getcwd, path - emuA = Emulator() emuB = Emulator() @@ -23,29 +21,9 @@ emu.addBinding(Binding('eth5', filter = Filter(asn = 150))) emu.addBinding(Binding('eth6', filter = Filter(asn = 170))) -output = './output' - -def createDirectoryAtBase(base:str, directory:str, override:bool = False): - cur = getcwd() - if path.exists(base): - chdir(base) - if override: - rmtree(directory) - mkdir(directory) - chdir(cur) - - -saveState = True -def updateEthStates(): - if saveState: - createDirectoryAtBase(output, "eth-states/") - for i in range(1, 7): - createDirectoryAtBase(output, "eth-states/" + str(i)) - # Render and compile emu.render() # If output directory exists and override is set to false, we call exit(1) # updateOutputdirectory will not be called -emu.compile(Docker(ethClientEnabled=False, clientEnabled=True), output) -updateEthStates() +emu.compile(Docker(clientEnabled=True), './output') diff --git a/examples/B08-Remix-Connection/component-blockchain.py b/examples/B08-Remix-Connection/component-blockchain.py index 7d7ef376a..c4063b0bd 100755 --- a/examples/B08-Remix-Connection/component-blockchain.py +++ b/examples/B08-Remix-Connection/component-blockchain.py @@ -28,7 +28,7 @@ # Create more accounts on e5 and e6 e5.startMiner() -e6.startMiner().createNewAccount(2).unlockAccounts() +e6.startMiner().createAccounts(2).unlockAccounts() # Create a smart contract and deploy it from node e3 # We need to put the compiled smart contracts inside the Contracts/ folder @@ -36,8 +36,8 @@ e3.deploySmartContract(smart_contract) # Set node port that accepts connections -e3.enableExternalConnection() -e6.enableExternalConnection().setGethHttpPort(8545) +e3.enableGethHttp() +e6.enableGethHttp().setGethHttpPort(8545) # Get node port that accepts connections # Same api used in the EthereumService to set the listening port diff --git a/examples/not-ready-examples/C00-hybrid-internet/README.md b/examples/C00-hybrid-internet/README.md similarity index 100% rename from examples/not-ready-examples/C00-hybrid-internet/README.md rename to examples/C00-hybrid-internet/README.md diff --git a/examples/not-ready-examples/C00-hybrid-internet/hybrid-internet.py b/examples/C00-hybrid-internet/hybrid-internet.py similarity index 100% rename from examples/not-ready-examples/C00-hybrid-internet/hybrid-internet.py rename to examples/C00-hybrid-internet/hybrid-internet.py diff --git a/examples/C01-Blockchain-visualization/5_send_transaction.sh b/examples/C01-Blockchain-visualization/5_send_transaction.sh deleted file mode 100755 index 5a917c1ab..000000000 --- a/examples/C01-Blockchain-visualization/5_send_transaction.sh +++ /dev/null @@ -1,14 +0,0 @@ -# In component-blockchain.py, i am using mod 3 -# These are the same commands for both proof of work and proof of authority -start=1 -end=$(docker ps | grep Ethereum | wc -l) - -echo "Unlocking sealers ..." -for (( node=$start; node<=$end; node++ )) -do - if (($node % 3)); then - container=$(docker ps | grep "Ethereum-$node-" | awk '{print $1}') - docker exec -t $container geth attach --exec "eth.sendTransaction({from:eth.coinbase, to:eth.accounts[1], value:1})" - echo "Sending transaction inside node $node" - fi -done diff --git a/examples/C01-Blockchain-visualization/README.md b/examples/C01-Blockchain-visualization/README.md deleted file mode 100644 index 365aed855..000000000 --- a/examples/C01-Blockchain-visualization/README.md +++ /dev/null @@ -1,203 +0,0 @@ -# Visualization - -## Build -- Run either `mini-blockchain-emulator.py` or `nano-blockchain-emulator.py` to generate a bin file -- Run the `component-blockchain.py` -- Go to the `emulator` folder -- Run `dcbuild` -- Check the section below for the `dcup` - -## Notice -- Due to a bug in docker, you might not be able to bring the containers up -- We provide a file called `lazy_start.sh` which brings up containers gradually -- Copy the file in the `emulator` folder and run it after executing the `dcbuild` alias - -## Concept -- The visualization is built on a plugin-type architecture. -- We can now create a new plugin for different projects that fetch data from the emulator and passes it to the frontend - -## Client architecture -- The client is divided into two project, the frontend, and the backend -- Both projects use typescript as a base language -- Both projects are technically node projects where we can install external npm packages -- The frontend is clueless about the processing that happens on the backend. -- The data received on the frontend is in no way an indicator of which plugin is running - -## Frontend -- The three main npm packages for visualization are the `vis-data`, `vis-network`, and `vis-util` -- We can generate the emulator's graph using these libraries - -## Backend -- The backend is built as a node express server -- You can send POST and GET requests to the server depending on what routes are created -- You can also create a websocket connection from the frontend to one of the websocket routes - -## Plugin architecture - -## Frontend - -- Most of the work was added to the `frontend/src/map/ui.ts` file -- The bulk of the work happens when the user clicks on the `Blockchain` tab above the search bar -- For all plugins, we will make use of two APIs provided on the backend server to be able to fetch data -- To create a new plugin, call -``` - await this._datasource.initPlugin(type) -``` -- This function sends a POST request to `/api/v1/plugin/:type/init` on the server side -- The type must match one of the types in `backend/src/plugin/PluginEnum.ts` -- Once this is called on the frontend, a new manager plugin of type `type` is created on the server side -- After that, we need create a WebSocket connection with the server -- The socket is created in this way: -``` - const url = 'ws://localhost:8080/api/v1/plugin/${type}/command/'; - const ws = new WebSocket(url); -``` -- This connection is the one which we will make use of to pass data to/from frontend/backend -- To get messages from the backend, we add an `onmessage` listener by writing -``` - ws.onmessage = (event) => {...} -``` -- To send data to the backend, we use the function -``` - ws.send(JSON.stringify(...)) -``` -- One example of data sent from the frontend to the backend is -``` - { - command: "start newBlockHeaders xyz" - } -``` - -## Backend - -- There are two parts to cover on the backend: the routes, and the plugin architecture - -### Routes -- The routes are added in `/backend/src/api/v1/main.ts` -- We created two new express routes which will be used by all future plugins -- The first one is reached by doing a POST request to `/api/v1/plugin/:type/init`. This is the route that creates a new plugin on the backend side. This plugin is the one that will fetch data from the emulator's docker containers -- To receive data from the plugin instance itself, we add -``` - instantiated_plugins[type].onMessage(function(data) {...}) -``` -- The second express route is reached by creating a new socket connection to `ap1/v1//plugin/:type/command/`. In this route, we set a `message` listener to get data from the frontend by writing -``` - running_ws[type].on('message', (message) => {...}) -``` -- The data received by the frontend should be an object that has the `command` property. This `command` property is a string of the from ` ` where the `` takes the values of `start` or `stop`, the `` takes the values of the events you want listen to from the emulator (plugin specific), and the `params` field is optional -- Now that the socket connection received the full command from the frontend, we can run our plugin code depending on the `` provided -- To send data to the frontend, we use the -``` - running_ws[type].send(JSON.stringify(...)) -``` - - -### Plugin architecture -- On the backend side, when the POST request is sent to `/api/v1/plugin/:type/init`, we create a new plugin of type `BasePlugin` -- When we create a new `BasePlugin`, we need to specify the `type` of the plugin as parameter. For blockchain, the type is equal to `1` -- The type must match one of the types in `backend/src/plugin/PluginEnum.ts` as these are the currently supported plugins -- Under the hood, this class creates a new `EventEmitter` which we can use to listen to new messages -- The `onMessage` function that we mentioned above makes use of the `EventEmitter` to get data from the plugin itself -- To create a new plugin, your class has to implement the `PluginInterface` to add the proper functions. You also need to add your class inside `BasePlugin.ts` -- You plugin is the one that will fetch data from the emulator and pass it to the `onMessage` inside the websocket route - -![](./images/plugin-architecture.png) - -### Blockchain plugin -- The `BlockchainPlugin.ts` implements `PluginInterface.ts` -- This plugin is the one that connects to the Ethereum nodes using Web3 and fetches the data from the emulator -- When the user sends `start newBlockHeaders xyz`, we use Web3 to attach event listeners inside the Ethereum nodes. -- To connect to the Ethereum nodes using web3, we use -``` -const web3 = new Web3(new Web3.providers.WebsocketProvider(ws://${ip}:8546, { - clientConfig: { - // Useful to keep a connection alive - keepalive: true, - keepaliveInterval: 60000 // ms - }, - })); -``` -- Our ethereum nodes expose port 8546 for external websocket connections. We do this using the `geth` ethereum client. -- The data received by web3 includes new blocks that are mined, and new trddansactions that are performed. -- To listen to `newBlockHeaders`, we use: -``` - const subscription = web3.eth.subscribe("newBlockHeaders", (error, result) => {...}) -``` -- The Ethereum nodes will now start sending to our Plugin instance data which we will relay using the `onMessage` and then uses this command to send data to the frontend -``` - running_ws[type].send(JSON.stringify(...)) -``` -- When the user sends `stop newBlockHeaders`, we use -``` - subscription.unsubscribe((error, success) => {...}) -``` -- The Ethereum nodes will now stop sending us data. - - -### Data - -- The data sent to the frontend is in no way representative of what plugin is running on the backend. -- The data is only relevant to the visualization itself. -- The data is structured in the following way: -``` - { - eventType: event_type.data, - timestamp: Date.now(), - status: data.status, // success or error - containerId: data.containerId, // node to highlight - data: data.data, // configs for vis-network library to highligh nodes - } -``` -- `data.data` looks like: -``` - { - borderWidth: 4, - color: { - background: "purple", - border: "purple" - } - } -``` - -### docker-compose.yml - -- Since the client is built and brought up separately from the emulator, we need to do 2 configurations for it to be connected to the network -- The first configuration requires you to modify the `docker-compose.yml` inside the client folder -- We need to add the `networks` keyword, both inside the service and at the top level. Below is an example of how to do that. -- After running the emulator, you need to find any network to which an ethereum node is connected -- To do so, first use the `docker ps | grep Ethereum` command to find the Ethereum containers -- After that, locate any ip address such as `10.151.0.77`. 151 represents the ASN, and 0 represents the network -- In the docker-compose.yml below, you will replace `net_3_net3` by `net_151_net0`. In addition to that, we use the word `emulator` when setting up the networks (`emulator_net_3_net3`), this represents the folder in which you built your emulator. -- You can now `dcbuild` and `dcup` the client folder. -- Once this is done we will need to change the default routing of the container. -- Start by getting shell access to the client container using the `docksh` alias, -- To see the current ip table, type `ip route show`. You will see an entry for a `default` route -- Delete this default route using `ip route del default` then add a new default route using `ip route add default via ` where is the ip of the BGP router in the map. Any packet that doesn't match other routing rules will be routed by default to this new ip that you provide. -- Go to the map, select the search tab, and look for your ASN, in this case `151`. In our convention, all of the nodes in the same network are of the same color. Find the BGP router of the same color, click on it, and copy its ip address from the side panel on the map. This will be the mentioned above. - -``` -version: "3" - -services: - seedemu-client: - build: . - container_name: seedemu_client - volumes: - - /var/run/docker.sock:/var/run/docker.sock - ports: - - 8080:8080 - cap_add: - - ALL - sysctls: - - net.ipv4.ip_forward=1 - - net.ipv4.conf.default.rp_filter=0 - - net.ipv4.conf.all.rp_filter=0 - privileged: true - networks: - emulator_net_3_net3: - ipv4_address: 10.3.3.99 -networks: - emulator_net_3_net3: - external: true - -``` diff --git a/examples/C01-Blockchain-visualization/blockchain.py b/examples/C01-Blockchain-visualization/blockchain.py deleted file mode 100755 index 28af7047f..000000000 --- a/examples/C01-Blockchain-visualization/blockchain.py +++ /dev/null @@ -1,49 +0,0 @@ -#!/usr/bin/env python3 -# encoding: utf-8 - -from seedemu.core import Emulator, Binding, Filter -from seedemu.mergers import DEFAULT_MERGERS -from seedemu.compiler import Docker -from os import mkdir, chdir, getcwd, path - - -emuA = Emulator() -emuB = Emulator() - -# Load the pre-built components and merge them -emuA.load('../B00-mini-internet/base-component.bin') -emuB.load('./component-blockchain.bin') -emu = emuA.merge(emuB, DEFAULT_MERGERS) - -# Binding virtual nodes to physical nodes -start=1 -end=16 -for i in range(start, end): - emu.addBinding(Binding('eth{}'.format(i))) - -output = './emulator' - -def createDirectoryAtBase(base:str, directory:str, override:bool = False): - cur = getcwd() - if path.exists(base): - chdir(base) - if override: - rmtree(directory) - mkdir(directory) - chdir(cur) - - -saveState = True -def updateEthStates(): - if saveState: - createDirectoryAtBase(output, "eth-states/") - for i in range(start, end): - createDirectoryAtBase(output, "eth-states/" + str(i)) - -# Render and compile -emu.render() - -# If output directory exists and override is set to false, we call exit(1) -# updateOutputdirectory will not be called -emu.compile(Docker(ethClientEnabled=False, clientEnabled=False), output) -updateEthStates() diff --git a/examples/C01-Blockchain-visualization/component-blockchain.py b/examples/C01-Blockchain-visualization/component-blockchain.py deleted file mode 100755 index e2373ae42..000000000 --- a/examples/C01-Blockchain-visualization/component-blockchain.py +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/env python3 -# encoding: utf-8 - -from seedemu import * - -emu = Emulator() - -# Create the Ethereum layer -# saveState=True: will set the blockchain folder using `volumes`, -# manual: requires you to trigger the /tmp/run.sh bash files in each container to lunch the ethereum nodes -# so the blockchain data will be preserved when containers are deleted. -# Note: right now we need to manually create the folder for each node (see README.md). -eth = EthereumService(saveState = True, manual=False) - -eth.setBaseConsensusMechanism(ConsensusMechanism.POA) - -# Create Ethereum nodes (nodes in this layer are virtual) -start=1 -end=16 -sealers=[] -bootnodes=[] -hport=8544 -#cport=8545 remix -cport=8546 # visualization - -# Currently the minimum amount to have to be a validator in proof of stake -balance = 32 * pow(10, 18) - -# Setting a third of nodes as bootnodes -for i in range(start, end): - e = eth.install("eth{}".format(i)) - if i%3 == 0: - e.setBootNode(True) - bootnodes.append(i) - else: - e.createPrefundedAccounts(balance, 1) - e.unlockAccounts().startMiner() - sealers.append(i) - - e.enableExternalConnection() # not recommended for sealers in production mode - emu.getVirtualNode('eth{}'.format(i)).setDisplayName('Ethereum-{}-poa'.format(i)).addPortForwarding(hport, cport) - hport = hport + 1 - -print("There are {} miners and {} bootnodes".format(len(sealers), len(bootnodes))) -print("Miner {}".format(sealers)) -print("Bootnodes {}".format(bootnodes)) - -# Add the layer and save the component to a file -emu.addLayer(eth) -emu.dump('component-blockchain.bin') diff --git a/examples/C01-Blockchain-visualization/images/newBH-Flash.png b/examples/C01-Blockchain-visualization/images/newBH-Flash.png deleted file mode 100644 index d1a223b25..000000000 Binary files a/examples/C01-Blockchain-visualization/images/newBH-Flash.png and /dev/null differ diff --git a/examples/C01-Blockchain-visualization/images/pendTr-Flash.png b/examples/C01-Blockchain-visualization/images/pendTr-Flash.png deleted file mode 100644 index 88cdb0086..000000000 Binary files a/examples/C01-Blockchain-visualization/images/pendTr-Flash.png and /dev/null differ diff --git a/examples/C01-Blockchain-visualization/images/plugin-architecture.png b/examples/C01-Blockchain-visualization/images/plugin-architecture.png deleted file mode 100644 index 14224a0e6..000000000 Binary files a/examples/C01-Blockchain-visualization/images/plugin-architecture.png and /dev/null differ diff --git a/examples/C01-Blockchain-visualization/lazy_start.sh b/examples/C01-Blockchain-visualization/lazy_start.sh deleted file mode 100755 index 7391b5225..000000000 --- a/examples/C01-Blockchain-visualization/lazy_start.sh +++ /dev/null @@ -1 +0,0 @@ - (ls | grep -Ev '.yml$|^dummies$|^eth-states|^lazy_start' | xargs -n10 -exec docker-compose up -d) > /dev/pts/0 diff --git a/examples/C01-Blockchain-visualization/mini-blockchain-emulator.py b/examples/C01-Blockchain-visualization/mini-blockchain-emulator.py deleted file mode 100755 index 764952844..000000000 --- a/examples/C01-Blockchain-visualization/mini-blockchain-emulator.py +++ /dev/null @@ -1,102 +0,0 @@ -#!/usr/bin/env python3 -# encoding: utf-8 -import sys, os -from seedemu import * - -def makeStubAs(emu: Emulator, base: Base, asn: int, exchange: int): - - # Create AS and internal network - stub_as = base.createAutonomousSystem(asn) - stub_as.createNetwork("net0") - stub_as.createNetwork("net1") - # Create a BGP router - # Attach the router to both the internal and external networks - router = stub_as.createRouter('router0') - router.joinNetwork("net0") - router.joinNetwork("net1") - router.joinNetwork('ix{}'.format(exchange)) - - for counter in range(3): - host = stub_as.createHost('host_{}'.format(counter)) - host.joinNetwork("net0") - - for counter in range(3, 6): - host = stub_as.createHost('host_{}'.format(counter)) - host.joinNetwork("net1") - -############################################################################### -emu = Emulator() -base = Base() -routing = Routing() -ebgp = Ebgp() -ibgp = Ibgp() -ospf = Ospf() -############################################################################### -ix100 = base.createInternetExchange(100) -ix101 = base.createInternetExchange(101) -ix102 = base.createInternetExchange(102) -ix103 = base.createInternetExchange(103) -ix104 = base.createInternetExchange(104) -ix105 = base.createInternetExchange(105) - -############################################################################### -# Create Transit Autonomous Systems -## Tier 1 ASes -Makers.makeTransitAs(base, 2, [100, 101, 102, 105], - [(100, 101), (101, 102), (100, 105)] -) -Makers.makeTransitAs(base, 3, [100, 103, 104, 105], - [(100, 103), (100, 105), (103, 105), (103, 104)] -) -Makers.makeTransitAs(base, 4, [100, 102, 104], - [(100, 104), (102, 104)] -) -## Tier 2 ASes -Makers.makeTransitAs(base, 11, [102, 105], [(102, 105)]) -Makers.makeTransitAs(base, 12, [101, 104], [(101, 104)]) -############################################################################### -# Create single-homed stub ASes. "None" means create a host only -makeStubAs(emu, base, 150, 100) -makeStubAs(emu, base, 151, 100) -makeStubAs(emu, base, 152, 101) -makeStubAs(emu, base, 153, 101) -makeStubAs(emu, base, 154, 102) -makeStubAs(emu, base, 160, 103) -makeStubAs(emu, base, 161, 103) -makeStubAs(emu, base, 162, 103) -makeStubAs(emu, base, 163, 104) -makeStubAs(emu, base, 164, 104) -makeStubAs(emu, base, 170, 105) -makeStubAs(emu, base, 171, 105) -############################################################################### -# Peering via RS (route server). The default peering mode for RS is PeerRelationship.Peer, -# which means each AS will only export its customers and their own prefixes. -# We will use this peering relationship to peer all the ASes in an IX. -# None of them will provide transit service for others. -ebgp.addRsPeers(100, [2, 3, 4]) -ebgp.addRsPeers(102, [2, 4]) -ebgp.addRsPeers(104, [3, 4]) -ebgp.addRsPeers(105, [2, 3]) -# To buy transit services from another autonomous system, -# we will use private peering -ebgp.addPrivatePeerings(100, [2], [150, 151], PeerRelationship.Provider) -ebgp.addPrivatePeerings(100, [3], [150], PeerRelationship.Provider) -ebgp.addPrivatePeerings(101, [2], [12], PeerRelationship.Provider) -ebgp.addPrivatePeerings(101, [12], [152, 153], PeerRelationship.Provider) -ebgp.addPrivatePeerings(102, [2, 4], [11, 154], PeerRelationship.Provider) -ebgp.addPrivatePeerings(103, [3], [160, 161, 162], PeerRelationship.Provider) -ebgp.addPrivatePeerings(104, [3, 4], [12], PeerRelationship.Provider) -ebgp.addPrivatePeerings(104, [4], [163], PeerRelationship.Provider) -ebgp.addPrivatePeerings(104, [12], [164], PeerRelationship.Provider) -ebgp.addPrivatePeerings(105, [3], [11, 170], PeerRelationship.Provider) -ebgp.addPrivatePeerings(105, [11], [171], PeerRelationship.Provider) - -############################################################################### -# Add layers to the emulator -emu.addLayer(base) -emu.addLayer(routing) -emu.addLayer(ebgp) -emu.addLayer(ibgp) -emu.addLayer(ospf) - -emu.dump('base-component.bin') \ No newline at end of file diff --git a/examples/C01-Blockchain-visualization/nano-blockchain-emulator.py b/examples/C01-Blockchain-visualization/nano-blockchain-emulator.py deleted file mode 100755 index 8fe353f78..000000000 --- a/examples/C01-Blockchain-visualization/nano-blockchain-emulator.py +++ /dev/null @@ -1,81 +0,0 @@ -#!/usr/bin/env python3 -# encoding: utf-8 -import sys, os -from seedemu import * - -def makeStubAs(emu: Emulator, base: Base, asn: int, exchange: int): - - # Create AS and internal network - stub_as = base.createAutonomousSystem(asn) - stub_as.createNetwork("net0") - - # Create a BGP router - # Attach the router to both the internal and external networks - router = stub_as.createRouter('router0') - router.joinNetwork("net0") - router.joinNetwork('ix{}'.format(exchange)) - - for counter in range(5): - host = stub_as.createHost('host_{}'.format(counter)) - host.joinNetwork("net0") - - -############################################################################### -emu = Emulator() -base = Base() -routing = Routing() -ebgp = Ebgp() -ibgp = Ibgp() -ospf = Ospf() -############################################################################### -ix100 = base.createInternetExchange(100) -ix101 = base.createInternetExchange(101) -ix102 = base.createInternetExchange(102) - -ix103 = base.createInternetExchange(103) -ix104 = base.createInternetExchange(104) - - -Makers.makeTransitAs(base, 6, [100, 101], [(100, 101)]) -Makers.makeTransitAs(base, 2, [101, 102], [(101, 102)]) -Makers.makeTransitAs(base, 3, [102, 103], [(102, 103)]) -Makers.makeTransitAs(base, 4, [103, 104], [(103, 104)]) -Makers.makeTransitAs(base, 5, [104, 100], [(104, 100)]) - - -ebgp.addRsPeers(100, [6, 5]) -ebgp.addRsPeers(101, [6, 2]) -ebgp.addRsPeers(102, [2, 3]) -ebgp.addRsPeers(103, [3, 4]) -ebgp.addRsPeers(104, [4, 5]) - -# Create single-homed stub ASes. "None" means create a host only -makeStubAs(emu, base, 150, 100) -makeStubAs(emu, base, 151, 101) -makeStubAs(emu, base, 152, 102) -makeStubAs(emu, base, 153, 103) -makeStubAs(emu, base, 154, 104) - - -ebgp.addPrivatePeerings(101, [6], [2], PeerRelationship.Provider) -ebgp.addPrivatePeerings(102, [2], [3], PeerRelationship.Provider) -ebgp.addPrivatePeerings(103, [3], [4], PeerRelationship.Provider) -ebgp.addPrivatePeerings(104, [4], [5], PeerRelationship.Provider) -ebgp.addPrivatePeerings(100, [5], [6], PeerRelationship.Provider) - - -ebgp.addPrivatePeerings(100, [6], [150], PeerRelationship.Provider) -ebgp.addPrivatePeerings(101, [2], [151], PeerRelationship.Provider) -ebgp.addPrivatePeerings(102, [3], [152], PeerRelationship.Provider) -ebgp.addPrivatePeerings(103, [4], [153], PeerRelationship.Provider) -ebgp.addPrivatePeerings(104, [5], [154], PeerRelationship.Provider) - - -# Add layers to the emulator -emu.addLayer(base) -emu.addLayer(routing) -emu.addLayer(ebgp) -emu.addLayer(ibgp) -emu.addLayer(ospf) - -emu.dump('base-component.bin') diff --git a/examples/not-ready-examples/C01-hybrid-dns-component/README.md b/examples/C01-hybrid-dns-component/README.md similarity index 100% rename from examples/not-ready-examples/C01-hybrid-dns-component/README.md rename to examples/C01-hybrid-dns-component/README.md diff --git a/examples/not-ready-examples/C01-hybrid-dns-component/hybrid-dns-component.py b/examples/C01-hybrid-dns-component/hybrid-dns-component.py similarity index 100% rename from examples/not-ready-examples/C01-hybrid-dns-component/hybrid-dns-component.py rename to examples/C01-hybrid-dns-component/hybrid-dns-component.py diff --git a/examples/not-ready-examples/C02-hybrid-internet-with-dns/README.md b/examples/C02-hybrid-internet-with-dns/README.md similarity index 100% rename from examples/not-ready-examples/C02-hybrid-internet-with-dns/README.md rename to examples/C02-hybrid-internet-with-dns/README.md diff --git a/examples/not-ready-examples/C02-hybrid-internet-with-dns/hybrid-internet-with-dns.py b/examples/C02-hybrid-internet-with-dns/hybrid-internet-with-dns.py similarity index 100% rename from examples/not-ready-examples/C02-hybrid-internet-with-dns/hybrid-internet-with-dns.py rename to examples/C02-hybrid-internet-with-dns/hybrid-internet-with-dns.py diff --git a/examples/not-ready-examples/C03-bring-your-own-internet/README.md b/examples/C03-bring-your-own-internet/README.md similarity index 100% rename from examples/not-ready-examples/C03-bring-your-own-internet/README.md rename to examples/C03-bring-your-own-internet/README.md diff --git a/examples/not-ready-examples/C03-bring-your-own-internet/bridge.sh b/examples/C03-bring-your-own-internet/bridge.sh similarity index 100% rename from examples/not-ready-examples/C03-bring-your-own-internet/bridge.sh rename to examples/C03-bring-your-own-internet/bridge.sh diff --git a/examples/not-ready-examples/C03-bring-your-own-internet/bring-your-own-internet-clients.py b/examples/C03-bring-your-own-internet/bring-your-own-internet-clients.py similarity index 100% rename from examples/not-ready-examples/C03-bring-your-own-internet/bring-your-own-internet-clients.py rename to examples/C03-bring-your-own-internet/bring-your-own-internet-clients.py diff --git a/examples/not-ready-examples/C03-bring-your-own-internet/bring-your-own-internet.py b/examples/C03-bring-your-own-internet/bring-your-own-internet.py similarity index 100% rename from examples/not-ready-examples/C03-bring-your-own-internet/bring-your-own-internet.py rename to examples/C03-bring-your-own-internet/bring-your-own-internet.py diff --git a/examples/not-ready-examples/C03-bring-your-own-internet/pics/BYOI-1.jpg b/examples/C03-bring-your-own-internet/pics/BYOI-1.jpg similarity index 100% rename from examples/not-ready-examples/C03-bring-your-own-internet/pics/BYOI-1.jpg rename to examples/C03-bring-your-own-internet/pics/BYOI-1.jpg diff --git a/examples/not-ready-examples/C03-bring-your-own-internet/pics/BYOI-docker-network.jpg b/examples/C03-bring-your-own-internet/pics/BYOI-docker-network.jpg similarity index 100% rename from examples/not-ready-examples/C03-bring-your-own-internet/pics/BYOI-docker-network.jpg rename to examples/C03-bring-your-own-internet/pics/BYOI-docker-network.jpg diff --git a/examples/not-ready-examples/C03-bring-your-own-internet/pics/BYOI-multiple-wifis.jpg b/examples/C03-bring-your-own-internet/pics/BYOI-multiple-wifis.jpg similarity index 100% rename from examples/not-ready-examples/C03-bring-your-own-internet/pics/BYOI-multiple-wifis.jpg rename to examples/C03-bring-your-own-internet/pics/BYOI-multiple-wifis.jpg diff --git a/examples/not-ready-examples/C03-bring-your-own-internet/pics/BYOI-single-wifi.jpg b/examples/C03-bring-your-own-internet/pics/BYOI-single-wifi.jpg similarity index 100% rename from examples/not-ready-examples/C03-bring-your-own-internet/pics/BYOI-single-wifi.jpg rename to examples/C03-bring-your-own-internet/pics/BYOI-single-wifi.jpg diff --git a/examples/not-ready-examples/C03-bring-your-own-internet/pics/BYOI-switch.jpg b/examples/C03-bring-your-own-internet/pics/BYOI-switch.jpg similarity index 100% rename from examples/not-ready-examples/C03-bring-your-own-internet/pics/BYOI-switch.jpg rename to examples/C03-bring-your-own-internet/pics/BYOI-switch.jpg diff --git a/examples/not-ready-examples/C03-bring-your-own-internet/pics/addForwardZone-1.png b/examples/C03-bring-your-own-internet/pics/addForwardZone-1.png similarity index 100% rename from examples/not-ready-examples/C03-bring-your-own-internet/pics/addForwardZone-1.png rename to examples/C03-bring-your-own-internet/pics/addForwardZone-1.png diff --git a/examples/not-ready-examples/C03-bring-your-own-internet/pics/createRealWorldRouter-1.png b/examples/C03-bring-your-own-internet/pics/createRealWorldRouter-1.png similarity index 100% rename from examples/not-ready-examples/C03-bring-your-own-internet/pics/createRealWorldRouter-1.png rename to examples/C03-bring-your-own-internet/pics/createRealWorldRouter-1.png diff --git a/examples/not-ready-examples/C03-bring-your-own-internet/pics/createRealWorldRouter-2.png b/examples/C03-bring-your-own-internet/pics/createRealWorldRouter-2.png similarity index 100% rename from examples/not-ready-examples/C03-bring-your-own-internet/pics/createRealWorldRouter-2.png rename to examples/C03-bring-your-own-internet/pics/createRealWorldRouter-2.png diff --git a/examples/not-ready-examples/C03-bring-your-own-internet/pics/diagram-1.jpg b/examples/C03-bring-your-own-internet/pics/diagram-1.jpg similarity index 100% rename from examples/not-ready-examples/C03-bring-your-own-internet/pics/diagram-1.jpg rename to examples/C03-bring-your-own-internet/pics/diagram-1.jpg diff --git a/examples/not-ready-examples/C03-bring-your-own-internet/pics/diagram-2.jpg b/examples/C03-bring-your-own-internet/pics/diagram-2.jpg similarity index 100% rename from examples/not-ready-examples/C03-bring-your-own-internet/pics/diagram-2.jpg rename to examples/C03-bring-your-own-internet/pics/diagram-2.jpg diff --git a/examples/not-ready-examples/C03-bring-your-own-internet/pics/diagram-3.jpg b/examples/C03-bring-your-own-internet/pics/diagram-3.jpg similarity index 100% rename from examples/not-ready-examples/C03-bring-your-own-internet/pics/diagram-3.jpg rename to examples/C03-bring-your-own-internet/pics/diagram-3.jpg diff --git a/examples/not-ready-examples/C03-bring-your-own-internet/pics/peering_relationship.jpg b/examples/C03-bring-your-own-internet/pics/peering_relationship.jpg similarity index 100% rename from examples/not-ready-examples/C03-bring-your-own-internet/pics/peering_relationship.jpg rename to examples/C03-bring-your-own-internet/pics/peering_relationship.jpg diff --git a/examples/not-ready-examples/C03-bring-your-own-internet/pics/switch-VLAN.png b/examples/C03-bring-your-own-internet/pics/switch-VLAN.png similarity index 100% rename from examples/not-ready-examples/C03-bring-your-own-internet/pics/switch-VLAN.png rename to examples/C03-bring-your-own-internet/pics/switch-VLAN.png diff --git a/examples/not-ready-examples/C03-bring-your-own-internet/pics/switch-pvid.png b/examples/C03-bring-your-own-internet/pics/switch-pvid.png similarity index 100% rename from examples/not-ready-examples/C03-bring-your-own-internet/pics/switch-pvid.png rename to examples/C03-bring-your-own-internet/pics/switch-pvid.png diff --git a/examples/not-ready-examples/C03-bring-your-own-internet/pics/switch_login.png b/examples/C03-bring-your-own-internet/pics/switch_login.png similarity index 100% rename from examples/not-ready-examples/C03-bring-your-own-internet/pics/switch_login.png rename to examples/C03-bring-your-own-internet/pics/switch_login.png diff --git a/examples/not-ready-examples/C03-bring-your-own-internet/pics/vm-usb-connect.png b/examples/C03-bring-your-own-internet/pics/vm-usb-connect.png similarity index 100% rename from examples/not-ready-examples/C03-bring-your-own-internet/pics/vm-usb-connect.png rename to examples/C03-bring-your-own-internet/pics/vm-usb-connect.png diff --git a/examples/not-ready-examples/C03-bring-your-own-internet/pics/wifi-ssid-vlan1.png b/examples/C03-bring-your-own-internet/pics/wifi-ssid-vlan1.png similarity index 100% rename from examples/not-ready-examples/C03-bring-your-own-internet/pics/wifi-ssid-vlan1.png rename to examples/C03-bring-your-own-internet/pics/wifi-ssid-vlan1.png diff --git a/examples/not-ready-examples/C03-bring-your-own-internet/pics/wifi-ssid-vlan2.png b/examples/C03-bring-your-own-internet/pics/wifi-ssid-vlan2.png similarity index 100% rename from examples/not-ready-examples/C03-bring-your-own-internet/pics/wifi-ssid-vlan2.png rename to examples/C03-bring-your-own-internet/pics/wifi-ssid-vlan2.png diff --git a/examples/not-ready-examples/C03-bring-your-own-internet/pics/wifi-vlan.png b/examples/C03-bring-your-own-internet/pics/wifi-vlan.png similarity index 100% rename from examples/not-ready-examples/C03-bring-your-own-internet/pics/wifi-vlan.png rename to examples/C03-bring-your-own-internet/pics/wifi-vlan.png diff --git a/examples/C00-Proof-of-authority/1_start.sh b/examples/not-ready-examples/26-proof-of-authority/1_start.sh similarity index 100% rename from examples/C00-Proof-of-authority/1_start.sh rename to examples/not-ready-examples/26-proof-of-authority/1_start.sh diff --git a/examples/C00-Proof-of-authority/2_bootstrapper.sh b/examples/not-ready-examples/26-proof-of-authority/2_bootstrapper.sh similarity index 100% rename from examples/C00-Proof-of-authority/2_bootstrapper.sh rename to examples/not-ready-examples/26-proof-of-authority/2_bootstrapper.sh diff --git a/examples/C00-Proof-of-authority/3_geth_attach.sh b/examples/not-ready-examples/26-proof-of-authority/3_geth_attach.sh similarity index 100% rename from examples/C00-Proof-of-authority/3_geth_attach.sh rename to examples/not-ready-examples/26-proof-of-authority/3_geth_attach.sh diff --git a/examples/C00-Proof-of-authority/4_unlock_and_seal.sh b/examples/not-ready-examples/26-proof-of-authority/4_unlock_and_seal.sh similarity index 100% rename from examples/C00-Proof-of-authority/4_unlock_and_seal.sh rename to examples/not-ready-examples/26-proof-of-authority/4_unlock_and_seal.sh diff --git a/examples/C00-Proof-of-authority/README.md b/examples/not-ready-examples/26-proof-of-authority/README.md similarity index 100% rename from examples/C00-Proof-of-authority/README.md rename to examples/not-ready-examples/26-proof-of-authority/README.md diff --git a/examples/C00-Proof-of-authority/blockchain.py b/examples/not-ready-examples/26-proof-of-authority/blockchain.py similarity index 100% rename from examples/C00-Proof-of-authority/blockchain.py rename to examples/not-ready-examples/26-proof-of-authority/blockchain.py diff --git a/examples/C00-Proof-of-authority/component-blockchain.py b/examples/not-ready-examples/26-proof-of-authority/component-blockchain.py similarity index 100% rename from examples/C00-Proof-of-authority/component-blockchain.py rename to examples/not-ready-examples/26-proof-of-authority/component-blockchain.py diff --git a/examples/C00-Proof-of-authority/images/blockchain-running.png b/examples/not-ready-examples/26-proof-of-authority/images/blockchain-running.png similarity index 100% rename from examples/C00-Proof-of-authority/images/blockchain-running.png rename to examples/not-ready-examples/26-proof-of-authority/images/blockchain-running.png diff --git a/examples/C00-Proof-of-authority/images/bootstrapper-done.png b/examples/not-ready-examples/26-proof-of-authority/images/bootstrapper-done.png similarity index 100% rename from examples/C00-Proof-of-authority/images/bootstrapper-done.png rename to examples/not-ready-examples/26-proof-of-authority/images/bootstrapper-done.png diff --git a/examples/C00-Proof-of-authority/images/component-blockchain-output.png b/examples/not-ready-examples/26-proof-of-authority/images/component-blockchain-output.png similarity index 100% rename from examples/C00-Proof-of-authority/images/component-blockchain-output.png rename to examples/not-ready-examples/26-proof-of-authority/images/component-blockchain-output.png diff --git a/examples/C00-Proof-of-authority/images/emulator-ready.png b/examples/not-ready-examples/26-proof-of-authority/images/emulator-ready.png similarity index 100% rename from examples/C00-Proof-of-authority/images/emulator-ready.png rename to examples/not-ready-examples/26-proof-of-authority/images/emulator-ready.png diff --git a/examples/C00-Proof-of-authority/images/geth-attach-done.png b/examples/not-ready-examples/26-proof-of-authority/images/geth-attach-done.png similarity index 100% rename from examples/C00-Proof-of-authority/images/geth-attach-done.png rename to examples/not-ready-examples/26-proof-of-authority/images/geth-attach-done.png diff --git a/examples/C00-Proof-of-authority/images/manual-mode.png b/examples/not-ready-examples/26-proof-of-authority/images/manual-mode.png similarity index 100% rename from examples/C00-Proof-of-authority/images/manual-mode.png rename to examples/not-ready-examples/26-proof-of-authority/images/manual-mode.png diff --git a/examples/C00-Proof-of-authority/images/unlock-and-seal.png b/examples/not-ready-examples/26-proof-of-authority/images/unlock-and-seal.png similarity index 100% rename from examples/C00-Proof-of-authority/images/unlock-and-seal.png rename to examples/not-ready-examples/26-proof-of-authority/images/unlock-and-seal.png diff --git a/seedemu/compiler/Docker.py b/seedemu/compiler/Docker.py index 2e4b0499a..3d3ac0222 100644 --- a/seedemu/compiler/Docker.py +++ b/seedemu/compiler/Docker.py @@ -11,7 +11,6 @@ import json SEEDEMU_CLIENT_IMAGE='magicnat/seedemu-client' -ETH_SEEDEMU_CLIENT_IMAGE='rawisader/seedemu-eth-client' DockerCompilerFileTemplates: Dict[str, str] = {} @@ -185,16 +184,6 @@ - {clientPort}:8080/tcp """ -DockerCompilerFileTemplates['seedemu-eth-client'] = """\ - seedemu-eth-client: - image: {ethClientImage} - container_name: seedemu-eth-client - volumes: - - /var/run/docker.sock:/var/run/docker.sock - ports: - - {ethClientPort}:3000/tcp -""" - DockerCompilerFileTemplates['zshrc_pre'] = """\ export NOPRECMD=1 alias st=set_title @@ -295,9 +284,6 @@ class Docker(Compiler): __client_enabled: bool __client_port: int - __eth_client_enabled: bool - __eth_client_port: int - __client_hide_svcnet: bool __images: Dict[str, Tuple[DockerImage, int]] @@ -314,8 +300,6 @@ def __init__( dummyNetworksMask: int = 24, clientEnabled: bool = False, clientPort: int = 8080, - ethClientEnabled: bool = False, - ethClientPort: int = 3000, clientHideServiceNet: bool = True ): """! @@ -356,9 +340,6 @@ def __init__( self.__client_enabled = clientEnabled self.__client_port = clientPort - self.__eth_client_enabled = ethClientEnabled - self.__eth_client_port = ethClientPort - self.__client_hide_svcnet = clientHideServiceNet self.__images = {} @@ -682,6 +663,11 @@ def _getNodeMeta(self, node: Node) -> str: value = json.dumps(node.getClasses()).replace("\"", "\\\"") ) + for key, value in node.getLabel().items(): + labels += DockerCompilerFileTemplates['compose_label_meta'].format( + key = key, + value = value + ) n = 0 for iface in node.getInterfaces(): net = iface.getNet() @@ -1004,14 +990,6 @@ def _doCompile(self, emulator: Emulator): clientPort = self.__client_port ) - if self.__eth_client_enabled: - self._log('enabling seedemu-eth-client...') - - self.__services += DockerCompilerFileTemplates['seedemu-eth-client'].format( - ethClientImage = ETH_SEEDEMU_CLIENT_IMAGE, - ethClientPort = self.__eth_client_port, - ) - local_images = '' for (image, _) in self.__images.values(): diff --git a/seedemu/core/Compiler.py b/seedemu/core/Compiler.py index e2836c321..2d245a080 100644 --- a/seedemu/core/Compiler.py +++ b/seedemu/core/Compiler.py @@ -55,29 +55,6 @@ def compile(self, emulator: Emulator, output: str, override: bool = False): self._doCompile(emulator) chdir(cur) - def createDirectoryAtBase(self, base:str, directory: str, override: bool = False): - """! - @brief Creating a directory at a certain base depending on your current directory - @param base is the folder in which we want to create an inner directory - @param directory is the name of the directory that will be created - @param override (optional) overrides the inner directory if it already exists. False by default. - """ - cur = getcwd() - if path.exists(base): - chdir(base) - if override: - self._log('folder "{}" already exists, overriding.'.format(directory)) - rmtree(directory) - mkdir(directory) - chdir(cur) - - def deleteDirectoryAtBase(self, base: str, directory: str): - cur = getcwd() - if path.exists(base): - chdir(base) - if path.exists(directory): - rmtree(directory) - def _log(self, message: str) -> None: """! @brief Log to stderr. diff --git a/seedemu/core/Node.py b/seedemu/core/Node.py index e58480db7..911db0ed6 100644 --- a/seedemu/core/Node.py +++ b/seedemu/core/Node.py @@ -208,6 +208,7 @@ class Node(Printable, Registrable, Configurable, Vertex): __scope: str __role: NodeRole __classes: List[str] + __label: Dict[str, str] __interfaces: List[Interface] __files: Dict[str, File] __imported_files: Dict[str, str] @@ -244,6 +245,7 @@ def __init__(self, name: str, role: NodeRole, asn: int, scope: str = None): self.__role = role self.__name = name self.__classes = [] + self.__label = {} self.__scope = scope if scope != None else str(asn) self.__softwares = set() self.__build_commands = [] @@ -548,7 +550,7 @@ def appendClassName(self, className:str) -> Node: return self - def getClasses(self) -> str: + def getClasses(self) -> list: """! @brief Get service of current node @@ -556,6 +558,19 @@ def getClasses(self) -> str: """ return self.__classes + + def setLabel(self, key:str, value:str) -> Node: + """! + @brief Add Label to a current node + + @returns self, for chaining API calls. + """ + + self.__label[key] = value + return self + + def getLabel(self) -> dict: + return self.__label def getFile(self, path: str) -> File: """! diff --git a/seedemu/services/EthereumService.py b/seedemu/services/EthereumService.py index aa35f68c3..3f456dc36 100644 --- a/seedemu/services/EthereumService.py +++ b/seedemu/services/EthereumService.py @@ -4,18 +4,20 @@ from __future__ import annotations from enum import Enum -from operator import ge -import os -from seedemu.core import Node, Service, Server -from typing import Dict, List +from os import mkdir, path, makedirs, rename +from shutil import rmtree +from seedemu.core import Node, Service, Server, Emulator +from typing import Dict, List, Tuple import json from datetime import datetime, timezone -import re ETHServerFileTemplates: Dict[str, str] = {} +GenesisFileTemplates: Dict[str, str] = {} +GethCommandTemplates: Dict[str, str] = {} -# bootstraper: get enode urls from other eth nodes. + +# bootstrapper: get enode urls from other eth nodes. ETHServerFileTemplates['bootstrapper'] = '''\ #!/bin/bash while read -r node; do { @@ -44,11 +46,8 @@ class ConsensusMechanism(Enum): POA = 'poa' POW = 'pow' -class Genesis(): - ''' - @brief Genesis manage class - ''' - __genesisPoA = '''{ +GenesisFileTemplates['POA'] = '''\ +{ "config": { "chainId": 10, "homesteadBlock": 0, @@ -81,7 +80,8 @@ class Genesis(): } ''' - __genesisPoW = '''{ +GenesisFileTemplates['POW'] = '''\ +{ "nonce":"0x0", "timestamp":"0x621549f1", "parentHash":"0x0000000000000000000000000000000000000000000000000000000000000000", @@ -109,63 +109,131 @@ class Genesis(): }, "alloc": { } - } - ''' - - def __init__(self, consensus:ConsensusMechanism) -> None: - self.__consensusMechaism = consensus - self.__genesis = json.loads(self.__genesisPoA) if self.__consensusMechaism == ConsensusMechanism.POA else json.loads(self.__genesisPoW) +} +''' + +GenesisFileTemplates['POA_extra_data'] = '''\ +0x0000000000000000000000000000000000000000000000000000000000000000{signer_addresses}0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000''' + +GethCommandTemplates['base'] = '''\ +nice -n 19 geth --datadir {datadir} --identity="NODE_5" --networkid=10 --syncmode full --verbosity=2 --allow-insecure-unlock --port 30303 ''' + +GethCommandTemplates['mine'] = '''\ +--miner.etherbase "{coinbase}" --mine --miner.threads={num_of_threads} ''' + +GethCommandTemplates['unlock'] = '''\ +--unlock "{accounts}" --password "/tmp/eth-password" ''' + +GethCommandTemplates['http'] = '''\ +--http --http.addr 0.0.0.0 --http.port {gethHttpPort} --http.corsdomain "*" --http.api web3,eth,debug,personal,net,clique ''' + +GethCommandTemplates['ws'] = '''\ +--ws --ws.addr 0.0.0.0 --ws.port {gethWsPort} --ws.origins "*" --ws.api web3,eth,debug,personal,net,clique ''' + +GethCommandTemplates['nodiscover'] = '''\ +--nodiscover ''' + +GethCommandTemplates['bootnodes'] = '''\ +--bootnodes "$(cat /tmp/eth-node-urls)" ''' +class ConsensusMechanism(Enum): + """! + @brief Consensus Mechanism Enum. + """ + + # POA for Proof of Authority + POA = 'POA' + # POW for Proof of Work + POW = 'POW' + + +class Genesis(): + """! + @brief Genesis manage class + """ + + __genesis:dict + __consensusMechanism:ConsensusMechanism + def __init__(self, consensus:ConsensusMechanism): + self.__consensusMechanism = consensus + self.__genesis = json.loads(GenesisFileTemplates[self.__consensusMechanism.value]) + + + def setGenesis(self, customGenesis:str): + """! + @brief set custom genesis + + @param customGenesis genesis file contents to set. + + @returns self, for chaining calls. + """ + self.__genesis = json.loads(customGenesis) + + return self + + def getGenesis(self) -> str: + """! + @brief get a string format of genesis block. + + returns genesis. + """ + return json.dumps(self.__genesis) + def allocateBalance(self, accounts:List[EthAccount]) -> Genesis: - ''' - @brief allocate balance to account on genesis. It will update the genesis file - ''' + """! + @brief allocate balance to account by setting alloc field of genesis file. + + @param accounts list of accounts to allocate balance. + + @returns self, for chaining calls. + """ for account in accounts: - self.__allocateBalance(account.address,account.alloc_balance) - return self + address = account.getAddress() + balance = account.getAllocBalance() + + assert balance >= 0, "Genesis::allocateBalance: balance cannot have a negative value. Requested Balance Value : {}".format(account.getAllocBalance()) + self.__genesis["alloc"][address[2:]] = {"balance":"{}".format(balance)} - def setSealer(self, accounts:List[EthAccount]) -> Genesis: - if len(accounts) > 0: self.__replaceExtraData(self.__generateGenesisExtraData(accounts)) return self - def __generateGenesisExtraData(self, prefunded_accounts: List[EthAccount]) -> str: - ''' - @brief Clique extradata field, used to define PoA validators/sealers must match the following format: - First part: 32bytes vanity, meaning whatever you want here since it’s expressed as an hex string (64 chars long as one byte is 2 chars), using puppeth tool, it's filled with 0s. - Second part: concatenated list of sealers/validators nodes addresses. Each address written as hex string without the “0x” prefix and must be 20 bytes long (40 chars long as one byte is 2 chars). - Third part: a 65 bytes signature suffix called proposer seal. It’s used to identify the proposer of the new validator in a block. Given we talk here about the genesis file, this seal has no reason to be because no specific node proposed it, it’s the base on which everyone agree before starting. So it must be filled with zeros (65 zeros). Puppeth tool puts 130 0s. - - @returns the fully generated extraData field for the genesis - ''' - extraData = "0x" + "0" * 64 - for account in prefunded_accounts: - extraData = extraData + account.address[2:] + def setSigner(self, accounts:List[EthAccount]) -> Genesis: + """! + @brief set initial signers by setting extraData field of genesis file. - return extraData + "0" * 130 - - def __allocateBalance(self, address:str, balance:str) -> None: - self.__genesis["alloc"][address[2:]] = {"balance":"{}".format(balance)} + extraData property in genesis block consists of + 32bytes of vanity data, a list of iinitial signer addresses, + and 65bytes of vanity data. + + @param accounts account lists to set as signers. + + @returns self, for chaning API calls. + """ + + assert self.__consensusMechanism == ConsensusMechanism.POA, 'setSigner method supported only in POA consensus.' + + signerAddresses = '' + + for account in accounts: + signerAddresses = signerAddresses + account.getAddress()[2:] - def __replaceExtraData(self, content:str) -> None: - self.__genesis["extraData"] = content + self.__genesis["extraData"] = GenesisFileTemplates['POA_extra_data'].format(signer_addresses=signerAddresses) - def __str__(self) -> str: - return json.dumps(self.__genesis) + return self - def __repr__(self) -> str: - return json.dumps(self.__genesis) class EthAccount(): """ @brief Ethereum Local Account. """ - address: str # account address - keystore_content: str # the content of keystore file - keystore_filename:str # the name of keystore file - alloc_balance: int + __address: str + __keystore_content: str + __keystore_filename:str + __alloc_balance: int + __password: str + - def __init__(self, alloc_balance:int = 0,password:str = "admin", keyfile: str = None) -> None: + def __init__(self, alloc_balance:int = 0,password:str = "admin", keyfilePath: str = None): """ @brief create a Ethereum Local Account when initialize @param alloc_balance the balance need to be alloc @@ -174,16 +242,21 @@ def __init__(self, alloc_balance:int = 0,password:str = "admin", keyfile: str = """ from eth_account import Account self.lib_eth_account = Account - self.account = self.__importAccout(keyfile=keyfile, password=password) if keyfile else self.__createAccount() - self.address = self.account.address - self.__validate_balance(alloc_balance=alloc_balance) - self.alloc_balance = alloc_balance - # encrypt private for Ethereum Client, like geth and generate the content of keystore file - encrypted = self.lib_eth_account.encrypt(self.account.key, password=password) - self.keystore_content = json.dumps(encrypted) + + self.__account = self.__importAccount(keyfilePath=keyfilePath, password=password) if keyfilePath else self.__createAccount() + self.__address = self.__account.address + + assert alloc_balance >= 0, "EthAccount::__init__: balance cannot have a negative value. Requested Balance Value : {}".format(alloc_balance) + + self.__alloc_balance = alloc_balance + + encrypted = self.lib_eth_account.encrypt(self.__account.key, password=password) + self.__keystore_content = json.dumps(encrypted) + # generate the name of the keyfile datastr = datetime.now(timezone.utc).isoformat().replace("+00:00", "000Z").replace(":","-") - self.keystore_filename = "UTC--"+datastr+"--"+encrypted["address"] + self.__keystore_filename = "UTC--"+datastr+"--"+encrypted["address"] + self.__password = password def __validate_balance(self, alloc_balance:int): """ @@ -192,20 +265,37 @@ def __validate_balance(self, alloc_balance:int): """ assert alloc_balance>=0 , "Invalid Balance Range: {}".format(alloc_balance) - def __importAccout(self, keyfile: str, password = "admin"): + def __importAccount(self, keyfilePath: str, password = "admin"): """ @brief import account from keyfile """ - print("importing account...") - return self.lib_eth_account.from_key(self.lib_eth_account.decrypt(keyfile_json=keyfile,password=password)) + assert path.exists(keyfilePath), "EthAccount::__importAccount: keyFile does not exist. path : {}".format(keyfilePath) + f = open(keyfilePath, "r") + keyfileContent = f.read() + f.close() + return self.lib_eth_account.from_key(self.lib_eth_account.decrypt(keyfile_json=keyfileContent,password=password)) def __createAccount(self): """ @brief create account """ - print("creating account...") return self.lib_eth_account.create() + def getAddress(self) -> str: + return self.__address + + def getAllocBalance(self) -> str: + return self.__alloc_balance + + def getKeyStoreFileName(self) -> str: + return self.__keystore_filename + + def getKeyStoreContent(self) -> str: + return self.__keystore_content + + def getPassword(self) -> str: + return self.__password + class SmartContract(): @@ -274,18 +364,25 @@ class EthereumServer(Server): __id: int __is_bootnode: bool - __auto_discover: bool __bootnode_http_port: int - __geth_http_port: int __smart_contract: SmartContract - __start_Miner_node: bool - __create_new_account: int - __enable_external_connection: bool - __unlockAccounts: bool - __prefunded_accounts: List[EthAccount] + __accounts: List[EthAccount] + __accounts_info: List[Tuple[int, str, str]] __consensus_mechanism: ConsensusMechanism - __geth_binary: str - __geth_client: str + + __custom_geth_binary_path: str + __custom_geth_command_option: str + + __data_dir: str + __no_discover: bool + __enable_http: bool + __geth_http_port: int + __enable_ws: bool + __geth_ws_port: int + __unlock_accounts: bool + __start_mine: bool + __miner_thread: int + __coinbase: str def __init__(self, id: int): """! @@ -294,82 +391,60 @@ def __init__(self, id: int): """ self.__id = id self.__is_bootnode = False - self.__auto_discover = True + self.__bootnode_http_port = 8088 - self.__geth_http_port = 8545 self.__smart_contract = None - self.__start_Miner_node = False - self.__create_new_account = 0 - self.__enable_external_connection = False - self.__unlockAccounts = False - self.__prefunded_accounts = [EthAccount(alloc_balance=32 * pow(10, 18), password="admin")] #create a prefunded account by default. It ensure POA network works when create/import prefunded account is not called. - self.__consensus_mechanism = None # keep as empty to make sure the OR statement works in the install function - self.__geth_binary = "" - - def __createNewAccountCommand(self, node: Node): - if self.__create_new_account > 0: - """! - @brief generates a shell command which creates a new account in ethereum network. - - @param ethereum node on which we want to deploy the changes. - - """ - command = " sleep 20\n\ - {} --password /tmp/eth-password account new \n\ - ".format(self.__geth_client) - - for count in range(self.__create_new_account): - node.appendStartCommand('(\n {})&'.format(command)) - - def __unlockAccountsCommand(self, node: Node): - if self.__unlockAccounts: - """! - @brief automatically unlocking the accounts in a node. - Currently used to automatically be able to use our emulator using Remix. - """ - - base_command = "sleep 20\n\ - {} --exec 'personal.unlockAccount(eth.accounts[{}],\"admin\",0)' attach\n\ - " - - full_command = "" - for i in range(self.__create_new_account + 1): - full_command += base_command.format(self.__geth_client, str(i)) + self.__accounts = [] + self.__accounts_info = [(0, "admin", None)] + self.__consensus_mechanism = ConsensusMechanism.POW + self.__genesis = Genesis(self.__consensus_mechanism) + + self.__custom_geth_binary_path = None + self.__custom_geth_command_option = None + + self.__data_dir = "/root/.ethereum" + self.__no_discover = False + self.__enable_ws = False + self.__enable_http = False + self.__geth_http_port = 8545 + self.__geth_ws_port = 8546 + self.__unlock_accounts = False + self.__start_mine = False + self.__miner_thread = 1 + self.__coinbase = "" - node.appendStartCommand('(\n {})&'.format(full_command)) + def __generateGethStartCommand(self): + """! + @brief generate geth start commands from the properties. - def __addMinerStartCommand(self, node: Node): - if self.__start_Miner_node: - """! - @brief generates a shell command which start miner as soon as it the miner is booted up. - - @param ethereum node on which we want to deploy the changes. - - """ - command = " sleep 20\n\ - {} --exec 'eth.defaultAccount = eth.accounts[0]' attach \n\ - {} --exec 'miner.start(1)' attach \n\ - ".format(self.__geth_client, self.__geth_client) - node.appendStartCommand('(\n {})&'.format(command)) - - def __deploySmartContractCommand(self, node: Node): - if self.__smart_contract != None : - smartContractCommand = self.__smart_contract.generateSmartContractCommand() - node.appendStartCommand('(\n {})&'.format(smartContractCommand)) - - def __updateGenesis(self, genesis: Genesis, prefunded_accounts:List[EthAccount]) -> Genesis: - genesis.allocateBalance(prefunded_accounts) - genesis.setSealer(prefunded_accounts) - return genesis - - def __saveAccountKeystoreFile(self, account: EthAccount, saveDirectory: str): - saveDirectory = saveDirectory+'/{}/'.format(self.__id) - os.makedirs(saveDirectory, exist_ok=True) - f = open(saveDirectory+account.keystore_filename, "w") - f.write(account.keystore_content) - f.close() + @returns geth command. + """ + geth_start_command = GethCommandTemplates['base'].format(datadir=self.__data_dir) + + if self.__no_discover: + geth_start_command += GethCommandTemplates['nodiscover'] + else: + geth_start_command += GethCommandTemplates['bootnodes'] + if self.__enable_http: + geth_start_command += GethCommandTemplates['http'].format(gethHttpPort=self.__geth_http_port) + if self.__enable_ws: + geth_start_command += GethCommandTemplates['ws'].format(gethWsPort=self.__geth_ws_port) + if self.__custom_geth_command_option: + geth_start_command += self.__custom_geth_command_option + if self.__unlock_accounts: + accounts = [] + for account in self.__accounts: + accounts.append(account.getAddress()) + geth_start_command += GethCommandTemplates['unlock'].format(accounts=', '.join(accounts)) + if self.__start_mine: + assert len(self.__accounts) > 0, 'EthereumServer::__generateGethStartCommand: To start mine, ethereum server need at least one account.' + if self.__consensus_mechanism == ConsensusMechanism.POA: + assert self.__unlock_accounts, 'EthereumServer::__generateGethStartCommand: To start mine in POA(clique), accounts should be unlocked first.' + geth_start_command += GethCommandTemplates['mine'].format(coinbase=self.__coinbase, num_of_threads=self.__miner_thread) + + return geth_start_command - def install(self, node: Node, eth: 'EthereumService', allBootnode: bool): + def install(self, node: Node, eth: EthereumService): """! @brief ETH server installation step. @param node node object @@ -377,149 +452,138 @@ def install(self, node: Node, eth: 'EthereumService', allBootnode: bool): @param allBootnode all-bootnode mode: all nodes are boot node. """ + node.appendClassName('EthereumService') + node.setLabel('node_id', self.getId()) + node.setLabel('consensus', self.__consensus_mechanism.value) + ifaces = node.getInterfaces() - assert len(ifaces) > 0, 'EthereumServer::install: node as{}/{} has not interfaces'.format(node.getAsn(), node.getName()) + assert len(ifaces) > 0, 'EthereumServer::install: node as{}/{} has no interfaces'.format(node.getAsn(), node.getName()) addr = str(ifaces[0].getAddress()) - this_url = '{}:{}'.format(addr, self.getBootNodeHttpPort()) - # get other nodes IP for the bootstrapper. - bootnodes = eth.getBootNodes()[:] - if this_url in bootnodes: bootnodes.remove(this_url) - - isEthereumNode = len(bootnodes) > 0 - - # import keystore file to /tmp/keystore - node_specific_prefunded_accounts = self.getPrefundedAccounts() - if len(node_specific_prefunded_accounts) > 0: - for account in node_specific_prefunded_accounts: - node.appendFile("/tmp/keystore/"+account.keystore_filename, account.keystore_content) - - # We can specify nodes to use a consensus different from the base one - consensus = self.getConsensusMechanism() or eth.getBaseConsensusMechanism() - genesis = Genesis(consensus=consensus) # update genesis.json - genesis = self.__updateGenesis(genesis, eth.getAllPrefundedAccounts()) + self.__genesis.allocateBalance(eth.getAllAccounts()) + if self.__consensus_mechanism == ConsensusMechanism.POA: + self.__genesis.setSigner(eth.getAllSignerAccounts()) + + node.setFile('/tmp/eth-genesis.json', self.__genesis.getGenesis()) - node.appendFile('/tmp/eth-genesis.json', str(genesis)) - node.appendFile('/tmp/eth-nodes', '\n'.join(eth.getBootNodes()[:])) - node.appendFile('/tmp/eth-bootstrapper', ETHServerFileTemplates['bootstrapper']) - node.appendFile('/tmp/eth-password', 'admin') + account_passwords = [] + + for account in self.__accounts: + node.setFile("/tmp/keystore/"+account.getKeyStoreFileName(), account.getKeyStoreContent()) + account_passwords.append(account.getPassword()) + + node.setFile('/tmp/eth-password', '\n'.join(account_passwords)) + node.addSoftware('software-properties-common') # tap the eth repo - node.addBuildCommand('add-apt-repository ppa:ethereum/ethereum') + node.addBuildCommand('add-apt-repository ppa:ethereum/ethereum') + # install geth and bootnode - install_command = 'apt-get update && apt-get install --yes bootnode {}' - #node.addBuildCommand('apt-get update && apt-get install --yes geth bootnode') - - - geth_client = "geth" - if self.getLocalGethBinary(): - geth_client = "bash -c /root/.ethereum/{}".format(self.__geth_binary) - node.addBuildCommand(install_command.format('')) + if self.__custom_geth_binary_path : + node.addBuildCommand('apt-get update && apt-get install --yes bootnode') + node.importFile("../../"+self.__custom_geth_binary_path, '/usr/bin/geth') + node.appendStartCommand("chmod +x /usr/bin/geth") else: - node.addBuildCommand(install_command.format(geth_client)) - - self.__geth_client = geth_client - # set the data directory - datadir_option = "--datadir /root/.ethereum" + node.addBuildCommand('apt-get update && apt-get install --yes geth bootnode') # genesis - node.appendStartCommand('[ ! -e "/root/.ethereum/geth/nodekey" ] && {} {} init /tmp/eth-genesis.json'.format(geth_client,datadir_option)) + node.appendStartCommand('[ ! -e "/root/.ethereum/geth/nodekey" ] && geth --datadir {} init /tmp/eth-genesis.json'.format(self.__data_dir)) + # copy keystore to the proper folder + for account in self.__accounts: + node.appendStartCommand("cp /tmp/keystore/{} /root/.ethereum/keystore/".format(account.getKeyStoreFileName())) - # create account via pre-defined password - node.appendStartCommand('[ -z `ls -A /root/.ethereum/keystore` ] && {} {} --password /tmp/eth-password account new'.format(geth_client, datadir_option)) - if allBootnode or self.__is_bootnode: + if self.__is_bootnode: # generate enode url. other nodes will access this to bootstrap the network. - # Default port is 30301, you can change the custom port with the next command - node.appendStartCommand('echo "enode://$(bootnode -nodekey /root/.ethereum/geth/nodekey -writeaddress)@{}:30301" > /tmp/eth-enode-url'.format(addr)) + node.appendStartCommand('[ ! -e "/root/.ethereum/geth/bootkey" ] && bootnode -genkey /root/.ethereum/geth/bootkey') + node.appendStartCommand('echo "enode://$(bootnode -nodekey /root/.ethereum/geth/bootkey -writeaddress)@{}:30301" > /tmp/eth-enode-url'.format(addr)) + # Default port is 30301, use -addr : to specify a custom port - node.appendStartCommand('bootnode -nodekey /root/.ethereum/geth/nodekey -verbosity 9 -addr {}:30301 > /tmp/bootnode-logs &'.format(addr)) + node.appendStartCommand('bootnode -nodekey /root/.ethereum/geth/bootkey -verbosity 9 -addr {}:30301 2> /tmp/bootnode-logs &'.format(addr)) + # host the eth-enode-url for other nodes. node.appendStartCommand('python3 -m http.server {} -d /tmp'.format(self.__bootnode_http_port), True) + + # get other nodes IP for the bootstrapper. + bootnodes = eth.getBootNodes(self.__consensus_mechanism)[:] + if len(bootnodes) > 0 : + node.setFile('/tmp/eth-nodes', '\n'.join(bootnodes)) + node.setFile('/tmp/eth-bootstrapper', ETHServerFileTemplates['bootstrapper']) - # load enode urls from other nodes - node.appendStartCommand('chmod +x /tmp/eth-bootstrapper') - if not(eth.isManual()): + # load enode urls from other nodes + node.appendStartCommand('chmod +x /tmp/eth-bootstrapper') node.appendStartCommand('/tmp/eth-bootstrapper') - - # launch Ethereum process. - # Base common geth flags - base_port = 30301 + self.__id - common_flags = '{} --identity="NODE_{}" --networkid=10 --syncmode full --verbosity=2 --allow-insecure-unlock --port {} --http --http.addr 0.0.0.0 --http.port {}'.format(datadir_option, self.__id, base_port, self.getGethHttpPort()) - - # Flags updated to accept external connections - if self.externalConnectionEnabled(): - apis = "web3,eth,debug,personal,net,clique" - http_whitelist_domains = "*" - ws_whitelist_domains = "*" - whitelist_flags = "--http.corsdomain \"{}\" --http.api {} --ws --ws.addr 0.0.0.0 --ws.port {} --ws.api {} --ws.origins \"{}\" ".format(http_whitelist_domains, apis, 8546, apis, ws_whitelist_domains) - common_flags = '{} {}'.format(common_flags, whitelist_flags) - - if not self.isAutoDiscover(): - common_flags = '{} {}'.format(common_flags, "--nodiscover") - # Base geth command - geth_command = 'nice -n 19 {} {}'.format(geth_client, common_flags) - - # Manual vs automated geth command execution - # In the manual approach, the geth command is only thrown in a file in /tmp/run.sh - # In the automated approach, the /tmp/run.sh file is executed by the start.sh (Virtual node) - - # Echoing the geth command to /tmp/run.sh in each container - node.appendStartCommand('echo \'{} --bootnodes "$(cat /tmp/eth-node-urls)"\' > /tmp/run.sh'.format(geth_command), True) + # launch Ethereum process. + node.appendStartCommand(self.__generateGethStartCommand(), True) - # Making run.sh executable - node.appendStartCommand('sleep 10') - node.appendStartCommand('chmod +x /tmp/run.sh') - - # moving keystore to the proper folder - for account in self.getPrefundedAccounts(): - node.appendStartCommand("cp /tmp/keystore/{} /root/.ethereum/keystore/".format(account.keystore_filename),True) + if self.__smart_contract != None : + smartContractCommand = self.__smart_contract.generateSmartContractCommand() + node.appendStartCommand('(\n {})&'.format(smartContractCommand)) - # Adding /tmp/run.sh in start.sh file to automate them - if not(eth.isManual()): - node.appendStartCommand('/tmp/run.sh &') + def setCustomGeth(self, customGethBinaryPath:str) -> EthereumServer: + """ + @brief set custom geth binary file - self.__createNewAccountCommand(node) - self.__unlockAccountsCommand(node) - self.__addMinerStartCommand(node) - self.__deploySmartContractCommand(node) + @param customGethBinaryPath set abosolute path of geth binary to move to the service. - def useLocalGethBinary(self, executable:str) -> EthereumServer: - """ - @brief setting the filename of modified geth binary + @returns self, for chaining API calls. """ - self.__geth_binary = executable + assert path.exists(customGethBinaryPath), "EthereumServer::setCustomGeth: custom geth binary file does not exist. path : {}".format(customGethBinaryPath) + + self.__custom_geth_binary_path = customGethBinaryPath return self - def getLocalGethBinary(self) -> str: + def setCustomGethCommandOption(self, customOptions:str) -> EthereumServer: """ - @brief getting the binary name + @brief set custom geth start command option + + @param customOptions options to set + + @returns self, for chaining API calls. """ - return self.__geth_binary + assert customOptions.startswith("--"), "option should start with '--'" + assert ";" not in customOptions, "letter ';' cannot contain in the options" + assert "&" not in customOptions, "letter '|' cannot contain in the options" + assert "|" not in customOptions, "letter '|' cannot contain in the options" - def setAutoDiscover(self, autoDiscover = True) -> EthereumServer: + self.__custom_geth_command_option = customOptions + return self + + def setGenesis(self, genesis:str) -> EthereumServer: """ - @brief setting the automatic peer discovery to true/false + @brief set custom genesis + + @returns self, for chaining API calls. """ - self.__auto_discover = autoDiscover + self.__genesis.setGenesis(genesis) + return self - def isAutoDiscover(self) -> str: + def setNoDiscover(self, noDiscover:bool = True) -> EthereumServer: """ - @brief making sure nodes can automatically discover their peers + @brief setting the automatic peer discovery to true/false """ - return self.__auto_discover + self.__no_discover = noDiscover + return self + - def setConsensusMechanism(self, consensus:ConsensusMechanism=ConsensusMechanism.POA) -> EthereumServer: + def setConsensusMechanism(self, consensusMechanism:ConsensusMechanism) -> EthereumServer: ''' - @brief We can have more than one consensus mechanism at the same time - The base consensus (poa) applies to all of the nodes by default except if this API is called - We can set a different consensus for the nodes of our choice + @brief set ConsensusMechanism + + @param consensusMechanism supports POW and POA. + + @returns self, for chaining API calls. ''' - self.__consensus_mechanism = consensus + self.__consensus_mechanism = consensusMechanism + self.__genesis = Genesis(self.__consensus_mechanism) + if consensusMechanism == ConsensusMechanism.POA: + self.__accounts_info[0] = (32 * pow(10, 18), "admin", None) + elif consensusMechanism == ConsensusMechanism.POW: + self.__accounts_info[0] = (0, "admin", None) return self @@ -593,65 +657,141 @@ def getGethHttpPort(self) -> int: return self.__geth_http_port + def setGethWsPort(self, port: int) -> EthereumServer: + """! + @brief set the ws server port number for normal ethereum nodes + + @param port port + + @returns self, for chaining API calls + """ + + self.__geth_ws_port = port + + return self + + def getGethWsPort(self) -> int: + """! + @brief get the ws server port number for normal ethereum nodes + + @returns int + """ + + return self.__geth_ws_port + - def enableExternalConnection(self) -> EthereumServer: + def enableGethHttp(self) -> EthereumServer: """! - @brief setting a node as a remix node makes it possible for the remix IDE to connect to the node + @brief setting a geth to enable http connection """ - self.__enable_external_connection = True + self.__enable_http = True return self - def externalConnectionEnabled(self) -> bool: + def isGethHttpEnabled(self) -> bool: """! - @brief returns wheter a node is a remix node or not + @brief returns whether a geth enabled http connection or not """ - return self.__enable_external_connection + return self.__enable_http - def createNewAccount(self, number_of_accounts = 0) -> EthereumServer: + def enableGethWs(self) -> EthereumServer: """! - @brief Call this api to create a new account. + @brief setting a geth to enable ws connection + """ + self.__enable_ws = True + + return self + + def isGethWsEnabled(self) -> bool: + """! + @brief returns whether a geth enabled ws connection or not + """ + + return self.__enable_ws + + def createAccount(self, balance:int=0, password:str="admin") -> EthereumServer: + """ + @brief call this api to create new accounts + + @param balance the balance to be allocated to the account + @param password the password to encrypt private key + @returns self, for chaining API calls. + """ - self.__create_new_account = number_of_accounts or self.__create_new_account + 1 - + + self.__accounts_info.append((balance, password, None)) + return self + - def createPrefundedAccounts(self, balance: int = 0, number: int = 1, password: str = "admin", saveDirectory:str = None) -> EthereumServer: + def createAccounts(self, number: int = 1, balance: int=0, password: str = "admin") -> EthereumServer: """ - @brief Call this api to create new prefunded account with balance - @param number the number of prefunded account need to create - @param balance the balance need to be allocated to the prefunded accounts + @brief Call this api to create new accounts + + @param number the number of account need to create + @param balance the balance need to be allocated to the accounts @param password the password of account for the Ethereum client - @returns self + + @returns self, for chaining API calls. """ + for _ in range(number): - account = EthAccount(alloc_balance=balance,password=password) - if saveDirectory: - self.__saveAccountKeystoreFile(account=account, saveDirectory=saveDirectory) - self.__prefunded_accounts.append(account) + self.__accounts_info.append((balance, password, None)) + return self + + def _createAccounts(self, eth:EthereumService) -> EthereumServer: + """ + @brief Call this api to create new accounts from account_info + + @returns self, for chaining API calls. + """ + for balance, password, keyfilePath in self.__accounts_info: + if keyfilePath: + eth._log('importing eth account...') + else: + eth._log('creating eth account...') + + account = EthAccount(alloc_balance=balance,password=password, keyfilePath=keyfilePath) + self.__accounts.append(account) + + return self - def importPrefundedAccount(self, keyfileDirectory:str, password:str = "admin", balance: int = 0) -> EthereumServer: - f = open(keyfileDirectory, "r") - keystoreFileContent = f.read() - account = EthAccount(alloc_balance=balance, password=password,keyfile=keystoreFileContent) - self.__prefunded_accounts.append(account) + def importAccount(self, keyfilePath:str, password:str = "admin", balance: int = 0) -> EthereumServer: + + assert path.exists(keyfilePath), "EthereumServer::importAccount: keyFile does not exist. path : {}".format(keyfilePath) + + self.__accounts_info.append((balance, password, keyfilePath)) return self - def getPrefundedAccounts(self) -> List[EthAccount]: + def getAccounts(self) -> List[Tuple(int, str, str)]: + """ + @brief Call this api to get the accounts for this node + + @returns accounts_info. """ - @brief Call this api to get the prefunded accounts for this node + + return self.__accounts_info + + def _getAccounts(self) -> List[EthAccount]: + """ + @brief Call this api to get the accounts for this node + + @returns accounts """ - return self.__prefunded_accounts + return self.__accounts + def unlockAccounts(self) -> EthereumServer: """! @brief This is mainly used to unlock the accounts in the remix node to make it directly possible for transactions to be executed through Remix without the need to access the geth account in the docker container and unlocking manually + + @returns self, for chaining API calls. """ - self.__unlockAccounts = True + self.__unlock_accounts = True return self @@ -660,10 +800,18 @@ def startMiner(self) -> EthereumServer: @brief Call this api to start Miner in the node. @returns self, for chaining API calls. """ - self.__start_Miner_node = True + self.__start_mine = True return self + def isStartMiner(self) -> bool: + """! + @brief call this api to get startMiner status in the node. + + @returns __start_mine status. + """ + return self.__start_mine + def deploySmartContract(self, smart_contract: SmartContract) -> EthereumServer: """! @brief Call this api to deploy smartContract on the node. @@ -681,79 +829,61 @@ class EthereumService(Service): """ __serial: int - __all_node_ips: List[str] - __boot_node_addresses: List[str] - __joined_prefunded_accounts: List[EthAccount] + __boot_node_addresses: Dict[ConsensusMechanism, List[str]] + __joined_accounts: List[EthAccount] + __joined_signer_accounts: List[EthAccount] __save_state: bool __save_path: str - - __manual_execution: bool - __base_consensus_mechanism: ConsensusMechanism + __override: bool - def __init__(self, saveState: bool = False, manual: bool = False, statePath: str = './eth-states'): + def __init__(self, saveState: bool = False, savePath: str = './eth-states', override:bool=False): """! @brief create a new Ethereum service. @param saveState (optional) if true, the service will try to save state of the block chain by saving the datadir of every node. Default to false. - @param manual (optional) if true, the user will have to execute a shell script - provided in the directory to trigger some commands inside the containers and start - mining - @param statePath (optional) path to save containers' datadirs on the + + @param savePath (optional) path to save containers' datadirs on the host. Default to "./eth-states". + + @param override (optional) override the output folder if it already + exist. False by defualt. + """ super().__init__() self.__serial = 0 - self.__all_node_ips = [] - self.__boot_node_addresses = [] - self.__joined_prefunded_accounts = [] + self.__boot_node_addresses = {} + self.__boot_node_addresses[ConsensusMechanism.POW] = [] + self.__boot_node_addresses[ConsensusMechanism.POA] = [] + self.__joined_accounts = [] + self.__joined_signer_accounts = [] self.__save_state = saveState - self.__save_path = statePath - - self.__manual_execution = manual - self.__base_consensus_mechanism = ConsensusMechanism.POW # set by default in case the API is not used + self.__save_path = savePath + self.__override = override def getName(self): return 'EthereumService' - def getBootNodes(self) -> List[str]: + def getBootNodes(self, consensusMechanism:ConsensusMechanism) -> List[str]: """ @brief get bootnode IPs. @returns list of IP addresses. """ - return self.__all_node_ips if len(self.__boot_node_addresses) == 0 else self.__boot_node_addresses - - def isManual(self) -> bool: - """ - @brief Returns whether the nodes execution will be manual or not - @returns bool - """ - return self.__manual_execution + return self.__boot_node_addresses[consensusMechanism] - def getAllPrefundedAccounts(self) -> List[EthAccount]: + def getAllAccounts(self) -> List[EthAccount]: """ - @brief Get a joined list of all the created prefunded accounts on all nodes + @brief Get a joined list of all the created accounts on all nodes @returns list of EthAccount """ - return self.__joined_prefunded_accounts + return self.__joined_accounts - def setBaseConsensusMechanism(self, mechanism:ConsensusMechanism = ConsensusMechanism.POA) -> bool: - """ - @brief select a consensus mechanism for the blockchain network. Default is Proof of authority - @returns bool - """ - self.__base_consensus_mechanism = mechanism - return True - - def getBaseConsensusMechanism(self) -> ConsensusMechanism: - """ - @returns the consensus mechanism for the current network - """ - return self.__base_consensus_mechanism + def getAllSignerAccounts(self) -> List[EthAccount]: + return self.__joined_signer_accounts def _doConfigure(self, node: Node, server: EthereumServer): self._log('configuring as{}/{} as an eth node...'.format(node.getAsn(), node.getName())) @@ -763,31 +893,48 @@ def _doConfigure(self, node: Node, server: EthereumServer): addr = '{}:{}'.format(str(ifaces[0].getAddress()), server.getBootNodeHttpPort()) if server.isBootNode(): - self._log('adding as{}/{} as bootnode...'.format(node.getAsn(), node.getName())) - self.__boot_node_addresses.append(addr) - - if len(server.getPrefundedAccounts()) > 0: - self.__joined_prefunded_accounts.extend(server.getPrefundedAccounts()) - + self._log('adding as{}/{} as consensus-{} bootnode...'.format(node.getAsn(), node.getName(), server.getConsensusMechanism().value)) + self.__boot_node_addresses[server.getConsensusMechanism()].append(addr) + + server._createAccounts(self) + + if len(server._getAccounts()) > 0: + self.__joined_accounts.extend(server._getAccounts()) + if server.getConsensusMechanism() == ConsensusMechanism.POA and server.isStartMiner(): + self.__joined_signer_accounts.append(server._getAccounts()[0]) + if self.__save_state: - node.addSharedFolder('/root/.ethereum', '{}/{}'.format(self.__save_path, server.getId())) + node.addSharedFolder('/root/.ethereum', '../{}/{}/ethereum'.format(self.__save_path, server.getId())) + node.addSharedFolder('/root/.ethash', '../{}/{}/ethash'.format(self.__save_path, server.getId())) + makedirs('{}/{}/ethereum'.format(self.__save_path, server.getId())) + makedirs('{}/{}/ethash'.format(self.__save_path, server.getId())) - def install(self, vnode: str) -> EthereumServer: - """! - @brief Override function of Sevice.install - Here is downcasting the return for IntelliSense :) - """ - return super().install(vnode) - + def configure(self, emulator: Emulator): + if self.__save_state: + self._createSharedFolder() + super().configure(emulator) + + def _createSharedFolder(self): + if path.exists(self.__save_path): + if self.__override: + self._log('eth_state folder "{}" already exist, overriding.'.format(self.__save_path)) + i = 1 + while True: + rename_save_path = "{}-{}".format(self.__save_path, i) + if not path.exists(rename_save_path): + rename(self.__save_path, rename_save_path) + break + else: + i = i+1 + else: + self._log('eth_state folder "{}" already exist. Set "override = True" when calling compile() to override.'.format(self.__save_path)) + exit(1) + mkdir(self.__save_path) + def _doInstall(self, node: Node, server: EthereumServer): self._log('installing eth on as{}/{}...'.format(node.getAsn(), node.getName())) - - all_bootnodes = len(self.__boot_node_addresses) == 0 - if all_bootnodes: - self._log('note: no bootnode configured. all nodes will be each other\'s boot node.') - - server.install(node, self, all_bootnodes) + server.install(node, self) def _createServer(self) -> Server: self.__serial += 1 @@ -804,8 +951,12 @@ def print(self, indent: int) -> str: indent += 4 - for node in self.getBootNodes(): + for node in self.getBootNodes(ConsensusMechanism.POW): + out += ' ' * indent + out += 'POW-{}\n'.format(node) + + for node in self.getBootNodes(ConsensusMechanism.POA): out += ' ' * indent - out += '{}\n'.format(node) + out += 'POA-{}\n'.format(node) return out \ No newline at end of file diff --git a/test/ethereum/README.md b/test/ethereum/README.md deleted file mode 100644 index 2a05e9a39..000000000 --- a/test/ethereum/README.md +++ /dev/null @@ -1,85 +0,0 @@ -# Unit testing for EthereumSevice - -## Overview - -This folder contains the all unit testing cases for EthereumService using library [unittest](https://docs.python.org/3/library/unittest.html), a unit testing included in python. This unit testing will going to build and run the container for unit testing by asserting the output of command run on specific container. - -This unit testing is an example to show how to write the unit test cases for seed-emulator. - -## How to run - -### Run all test cases - -Before running the testing, you should make sure loading the environment of emulator. - -```sh -source development.env -``` - -1. Run all test cases - -This unit testing have a loader to load all the ethereum service unit testing cases. - -```sh -python3 loader_ethereum.py -``` - -Then wait some time for testing, it may need half an hours to run all the case depend on the computer. - -### Run single test cases - -For example, we can run single test case `test_Run_POA`. - -1. Go to test cases folder - -```sh -cd cases -``` - -2. Run the test case - -```sh -python3 test_Run_POA.py -``` - -Then wait some time for testing, it may need 10 minutes to run this case depend on the computer. - -## Folder Structure Explain - -In side this case, there are two essential folders. - -`cases` for test cases python code. - -`resources` for the resource for a single test case, normally it contains python code that defines the network for testing and some bash scripts to build and run the containers for testing. - -## How to write a Test Case - -We are highly recommended to read the unittest document and learn the base concepts before starting reading the test case. - -You could look at a well-commented test case example `cases/test_Run_POA.py` to learn how to write a test case. - -## Test Cases - -- test_EthAccount - - This test case test the EthAccount class in `Ethereum Service`. It will test do the methods work correctly, especially create account and import account. - -- test_Genesis - - This test case test the Genesis class in `Ethereum Service`. It will test do the methods work correctly, especially for POA and POW genesis file content output. - -- test_Run_POA - - This test case test a ethereum network only using Proof-Of-Authority consensus. - -- test_Run_POW - - This test case test a ethereum network only using Proof-Of-Work consensus. - -- test_Run_POA - - This test case test a ethereum network using both Proof-Of-Authority and Proof-Of-Work consensus. - -## Reference - -1. [unittest document](https://docs.python.org/3/library/unittest.html) \ No newline at end of file diff --git a/test/ethereum/cases/test_EthAccount.py b/test/ethereum/cases/test_EthAccount.py deleted file mode 100644 index 62da1c296..000000000 --- a/test/ethereum/cases/test_EthAccount.py +++ /dev/null @@ -1,78 +0,0 @@ -import unittest -import re -from seedemu.services.EthereumService import * - -''' -Code from https://github.com/vgaicuks/ethereum-address -''' -from Crypto.Hash import keccak - -def is_checksum_address(address): - address = address.replace('0x', '') - address_hash = keccak.new(digest_bits=256) - address_hash = address_hash.update(address.lower().encode('utf-8')).hexdigest() - - for i in range(0, 40): - # The nth letter should be uppercase if the nth digit of casemap is 1 - if ((int(address_hash[i], 16) > 7 and address[i].upper() != address[i]) or - (int(address_hash[i], 16) <= 7 and address[i].lower() != address[i])): - return False - return True - -def is_address(address): - if not re.match(r'^(0x)?[0-9a-f]{40}$', address, flags=re.IGNORECASE): - # Check if it has the basic requirements of an address - return False - elif re.match(r'^(0x)?[0-9a-f]{40}$', address) or re.match(r'^(0x)?[0-9A-F]{40}$', address): - # If it's all small caps or all all caps, return true - return True - else: - # Otherwise check each case - return is_checksum_address(address) - - -def isArray(test:str): - regex = re.compile(r'\[[a-z,\",\',0-9,\,,\ ]*\]') - res = re.match(regex, test) - return bool(res) - -class TestEthAccount(unittest.TestCase): - # @classmethod - # def setUpClass(self): - # os.system("pip3 install eth_account > /dev/null") - # print("prepare testing: install eth_account") - - - # def test_init_without_lib(self): - # os.system("pip3 uninstall eth_account") - # self.assertRaises(EthAccount(), ) - # # self.assertEqual(sum([1, 2, 3]), 6, "Should be 6") - - def test_create_account(self): - account = EthAccount(alloc_balance=0, password="admin", keyfile = None) - self.assertIsNotNone(account.keystore_content) - self.assertIsNotNone(account.keystore_filename) - self.assertIsNotNone(account.alloc_balance) - self.assertTrue(is_address(account.address)) - - def test_create_account_invalid_balance_negative_decimal(self): - with self.assertRaises(AssertionError) as ctx: - EthAccount(alloc_balance=-1, password="admin", keyfile = None) - self.assertEqual("Invalid Balance Range: -1", str(ctx.exception)) - - def test_create_account_valid_balance_decimal(self): - account = EthAccount(alloc_balance=14124, password="admin", keyfile = None) - self.assertEqual(account.alloc_balance, 14124) - - def test_import_account(self): - correct_keystore_file = '{"address": "675eb8226a35256f638712db74878f0a15d3d56e", "crypto": {"cipher": "aes-128-ctr", "cipherparams": {"iv": "cbc176365f3894af5e95cd2704ee61c4"}, "ciphertext": "371c37784906c9d37abc3900c958c752f41b60f6dfaeddc4bf2a6d2d774b028b", "kdf": "scrypt", "kdfparams": {"dklen": 32, "n": 262144, "r": 1, "p": 8, "salt": "93794d233d59b0ff5daa6e5eca345c4a"}, "mac": "b139214451b8559567a2d06d7a6d1109b107b23ed8b809c1e6ca6d1c9ec15526"}, "id": "464b1168-fcb5-45c0-8c48-5adc0f255ade", "version": 3}' - correct_address = '0x675eb8226a35256f638712db74878f0a15d3d56e' - account = EthAccount(alloc_balance=0, password="admin", keyfile=correct_keystore_file) - self.assertIsNotNone(account.keystore_content) - self.assertIsNotNone(account.keystore_filename) - self.assertIsNotNone(account.alloc_balance) - self.assertTrue(is_address(account.address)) - self.assertEqual(account.address.lower(), correct_address) #lower() removes the address's checksum - -if __name__ == '__main__': - unittest.main() \ No newline at end of file diff --git a/test/ethereum/cases/test_EthereumService.py b/test/ethereum/cases/test_EthereumService.py deleted file mode 100755 index 1166a663a..000000000 --- a/test/ethereum/cases/test_EthereumService.py +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/env python3 -# encoding: utf-8 - -import os -from time import sleep -import unittest -import subprocess -# from subprocess import CalledProcessError -from seedemu.services.EthereumService import * - -class TestEthereumService(unittest.TestCase): - pass - -if __name__ == '__main__': - unittest.main() \ No newline at end of file diff --git a/test/ethereum/cases/test_Genesis.py b/test/ethereum/cases/test_Genesis.py deleted file mode 100644 index e9710b18d..000000000 --- a/test/ethereum/cases/test_Genesis.py +++ /dev/null @@ -1,65 +0,0 @@ -import unittest -from seedemu.services.EthereumService import * - -test_account_file_name = ['UTC--2022-03-25T16-41-21.542086000Z--675eb8226a35256f638712db74878f0a15d3d56e','UTC--2022-04-05T19-21-59.864345000Z--726808f08d63adba50137132a18170de98326c98','UTC--2022-04-05T19-21-56.904952000Z--20cc565f1ac407d24a2a35ab9312cec736880122','UTC--2022-04-05T19-22-01.348137000Z--1a5f6c239ceffb300cdba3031ba4ea5309e60380','UTC--2022-04-05T19-21-58.462119000Z--bb3e9561502ceaed131257765519876a250d374f'] - -class TestGenesis(unittest.TestCase): - @classmethod - def setUpClass(cls) -> None: - cls.eth_accounts = [] - for i in range(5): - with open('../resources/keystore/'+test_account_file_name[i]) as f: - cls.eth_accounts.append(EthAccount(alloc_balance=999999999,password="admin", keyfile=f.read())) - return super().setUpClass - - def test_init_poa(self) -> None: - genesisCorrect = '{"config": {"chainId": 10, "homesteadBlock": 0, "eip150Block": 0, "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000", "eip155Block": 0, "eip158Block": 0, "byzantiumBlock": 0, "constantinopleBlock": 0, "petersburgBlock": 0, "istanbulBlock": 0, "clique": {"period": 15, "epoch": 30000}}, "nonce": "0x0", "timestamp": "0x622a4e1a", "extraData": "0x0", "gasLimit": "0x47b760", "difficulty": "0x1", "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "coinbase": "0x0000000000000000000000000000000000000000", "alloc": {}, "number": "0x0", "gasUsed": "0x0", "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "baseFeePerGas": null}' - genesis = Genesis(ConsensusMechanism.POA) - self.assertEqual(str(genesis),genesisCorrect) - - def test_init_pow(self) -> None: - genesisCorrect = '{"nonce": "0x0", "timestamp": "0x621549f1", "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "extraData": "0x", "gasLimit": "0x80000000", "difficulty": "0x0", "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000", "coinbase": "0x0000000000000000000000000000000000000000", "number": "0x0", "gasUsed": "0x0", "baseFeePerGas": null, "config": {"chainId": 10, "homesteadBlock": 0, "eip150Block": 0, "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000", "eip155Block": 0, "eip158Block": 0, "byzantiumBlock": 0, "constantinopleBlock": 0, "petersburgBlock": 0, "istanbulBlock": 0, "ethash": {}}, "alloc": {}}' - genesis = Genesis(ConsensusMechanism.POW) - self.assertEqual(str(genesis),genesisCorrect) - - def test_allocateBalance_POW(self) -> None: - genesisCorrect = '{"nonce": "0x0", "timestamp": "0x621549f1", "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "extraData": "0x", "gasLimit": "0x80000000", "difficulty": "0x0", "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000", "coinbase": "0x0000000000000000000000000000000000000000", "number": "0x0", "gasUsed": "0x0", "baseFeePerGas": null, "config": {"chainId": 10, "homesteadBlock": 0, "eip150Block": 0, "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000", "eip155Block": 0, "eip158Block": 0, "byzantiumBlock": 0, "constantinopleBlock": 0, "petersburgBlock": 0, "istanbulBlock": 0, "ethash": {}}, "alloc": {"675eB8226a35256F638712Db74878f0A15d3D56E": {"balance": "999999999"}, "726808F08d63ADBa50137132a18170dE98326c98": {"balance": "999999999"}, "20cc565f1ac407d24a2a35AB9312cEC736880122": {"balance": "999999999"}, "1a5F6c239CeFfb300CDbA3031Ba4Ea5309E60380": {"balance": "999999999"}, "BB3E9561502ceaED131257765519876A250D374F": {"balance": "999999999"}}}' - genesis = Genesis(ConsensusMechanism.POW) - genesis.allocateBalance(self.eth_accounts) - self.assertEqual(str(genesis),genesisCorrect) - - def test_allocateBalance_POA(self) -> None: - genesisCorrect = '{"config": {"chainId": 10, "homesteadBlock": 0, "eip150Block": 0, "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000", "eip155Block": 0, "eip158Block": 0, "byzantiumBlock": 0, "constantinopleBlock": 0, "petersburgBlock": 0, "istanbulBlock": 0, "clique": {"period": 15, "epoch": 30000}}, "nonce": "0x0", "timestamp": "0x622a4e1a", "extraData": "0x0", "gasLimit": "0x47b760", "difficulty": "0x1", "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "coinbase": "0x0000000000000000000000000000000000000000", "alloc": {"675eB8226a35256F638712Db74878f0A15d3D56E": {"balance": "999999999"}, "726808F08d63ADBa50137132a18170dE98326c98": {"balance": "999999999"}, "20cc565f1ac407d24a2a35AB9312cEC736880122": {"balance": "999999999"}, "1a5F6c239CeFfb300CDbA3031Ba4Ea5309E60380": {"balance": "999999999"}, "BB3E9561502ceaED131257765519876A250D374F": {"balance": "999999999"}}, "number": "0x0", "gasUsed": "0x0", "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "baseFeePerGas": null}' - genesis = Genesis(ConsensusMechanism.POA) - genesis.allocateBalance(self.eth_accounts) - self.assertEqual(str(genesis),genesisCorrect) - - def test_setSealer_POW(self) -> None: - genesisCorrect = '{"nonce": "0x0", "timestamp": "0x621549f1", "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "extraData": "0x0000000000000000000000000000000000000000000000000000000000000000675eB8226a35256F638712Db74878f0A15d3D56E726808F08d63ADBa50137132a18170dE98326c9820cc565f1ac407d24a2a35AB9312cEC7368801221a5F6c239CeFfb300CDbA3031Ba4Ea5309E60380BB3E9561502ceaED131257765519876A250D374F0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "gasLimit": "0x80000000", "difficulty": "0x0", "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000", "coinbase": "0x0000000000000000000000000000000000000000", "number": "0x0", "gasUsed": "0x0", "baseFeePerGas": null, "config": {"chainId": 10, "homesteadBlock": 0, "eip150Block": 0, "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000", "eip155Block": 0, "eip158Block": 0, "byzantiumBlock": 0, "constantinopleBlock": 0, "petersburgBlock": 0, "istanbulBlock": 0, "ethash": {}}, "alloc": {}}' - genesis = Genesis(ConsensusMechanism.POW) - genesis.setSealer(self.eth_accounts) - self.assertEqual(str(genesis),genesisCorrect) - - def test_setSealer_POA(self) -> None: - genesisCorrect = '{"config": {"chainId": 10, "homesteadBlock": 0, "eip150Block": 0, "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000", "eip155Block": 0, "eip158Block": 0, "byzantiumBlock": 0, "constantinopleBlock": 0, "petersburgBlock": 0, "istanbulBlock": 0, "clique": {"period": 15, "epoch": 30000}}, "nonce": "0x0", "timestamp": "0x622a4e1a", "extraData": "0x0000000000000000000000000000000000000000000000000000000000000000675eB8226a35256F638712Db74878f0A15d3D56E726808F08d63ADBa50137132a18170dE98326c9820cc565f1ac407d24a2a35AB9312cEC7368801221a5F6c239CeFfb300CDbA3031Ba4Ea5309E60380BB3E9561502ceaED131257765519876A250D374F0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "gasLimit": "0x47b760", "difficulty": "0x1", "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "coinbase": "0x0000000000000000000000000000000000000000", "alloc": {}, "number": "0x0", "gasUsed": "0x0", "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "baseFeePerGas": null}' - genesis = Genesis(ConsensusMechanism.POA) - genesis.setSealer(self.eth_accounts) - self.assertEqual(str(genesis),genesisCorrect) - - def test_allocate_balance_and_setSealer_POW(self) -> None: - genesisCorrect = '{"nonce": "0x0", "timestamp": "0x621549f1", "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "extraData": "0x0000000000000000000000000000000000000000000000000000000000000000675eB8226a35256F638712Db74878f0A15d3D56E726808F08d63ADBa50137132a18170dE98326c9820cc565f1ac407d24a2a35AB9312cEC7368801221a5F6c239CeFfb300CDbA3031Ba4Ea5309E60380BB3E9561502ceaED131257765519876A250D374F0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "gasLimit": "0x80000000", "difficulty": "0x0", "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000", "coinbase": "0x0000000000000000000000000000000000000000", "number": "0x0", "gasUsed": "0x0", "baseFeePerGas": null, "config": {"chainId": 10, "homesteadBlock": 0, "eip150Block": 0, "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000", "eip155Block": 0, "eip158Block": 0, "byzantiumBlock": 0, "constantinopleBlock": 0, "petersburgBlock": 0, "istanbulBlock": 0, "ethash": {}}, "alloc": {"675eB8226a35256F638712Db74878f0A15d3D56E": {"balance": "999999999"}, "726808F08d63ADBa50137132a18170dE98326c98": {"balance": "999999999"}, "20cc565f1ac407d24a2a35AB9312cEC736880122": {"balance": "999999999"}, "1a5F6c239CeFfb300CDbA3031Ba4Ea5309E60380": {"balance": "999999999"}, "BB3E9561502ceaED131257765519876A250D374F": {"balance": "999999999"}}}' - genesis = Genesis(ConsensusMechanism.POW) - genesis.allocateBalance(self.eth_accounts) - genesis.setSealer(self.eth_accounts) - self.assertEqual(str(genesis),genesisCorrect) - - def test_allocate_balance_and_setSealer_POA(self) -> None: - genesisCorrect = '{"config": {"chainId": 10, "homesteadBlock": 0, "eip150Block": 0, "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000", "eip155Block": 0, "eip158Block": 0, "byzantiumBlock": 0, "constantinopleBlock": 0, "petersburgBlock": 0, "istanbulBlock": 0, "clique": {"period": 15, "epoch": 30000}}, "nonce": "0x0", "timestamp": "0x622a4e1a", "extraData": "0x0000000000000000000000000000000000000000000000000000000000000000675eB8226a35256F638712Db74878f0A15d3D56E726808F08d63ADBa50137132a18170dE98326c9820cc565f1ac407d24a2a35AB9312cEC7368801221a5F6c239CeFfb300CDbA3031Ba4Ea5309E60380BB3E9561502ceaED131257765519876A250D374F0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "gasLimit": "0x47b760", "difficulty": "0x1", "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "coinbase": "0x0000000000000000000000000000000000000000", "alloc": {"675eB8226a35256F638712Db74878f0A15d3D56E": {"balance": "999999999"}, "726808F08d63ADBa50137132a18170dE98326c98": {"balance": "999999999"}, "20cc565f1ac407d24a2a35AB9312cEC736880122": {"balance": "999999999"}, "1a5F6c239CeFfb300CDbA3031Ba4Ea5309E60380": {"balance": "999999999"}, "BB3E9561502ceaED131257765519876A250D374F": {"balance": "999999999"}}, "number": "0x0", "gasUsed": "0x0", "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "baseFeePerGas": null}' - genesis = Genesis(ConsensusMechanism.POA) - genesis.allocateBalance(self.eth_accounts) - genesis.setSealer(self.eth_accounts) - # print(genesis) - self.assertEqual(str(genesis),genesisCorrect) - -if __name__ == '__main__': - unittest.main() diff --git a/test/ethereum/cases/test_Run_POA.py b/test/ethereum/cases/test_Run_POA.py deleted file mode 100644 index 69618f2e8..000000000 --- a/test/ethereum/cases/test_Run_POA.py +++ /dev/null @@ -1,170 +0,0 @@ -#!/usr/bin/env python3 -# encoding: utf-8 - -import os -from time import sleep -import unittest -import subprocess -# from subprocess import CalledProcessError -from seedemu.services.EthereumService import * -import time - -def removeColoredText(color_text:str): - return re.sub(r'(\x9B|\x1B\[)[0-?]*[ -\/]*[@-~]', '', color_text) - -def isArray(test:str): - ''' - check a string is string array format or not - for example: ["1,","2"], ['1','2'] - ''' - regex = re.compile(r'\[[a-z,\",\',0-9,\,,\ ]*\]') - res = re.match(regex, test) - return bool(res) - - -class TestRunPOA(unittest.TestCase): - ''' - This is a test case to test ethereum service on Proof-Of-Authority consensus. - ''' - @classmethod - def setUpClass(cls) -> None: - ''' - A classmethod to setup the some thing before running this test case. - For this test case, it will render the network, build the containers and run the container for testing - ''' - os.system("cd ../resources/blockchain_poa; nohup /bin/bash build.sh; /bin/bash run.sh &") - sleep(300) # sleep 5 min to build and run container - return super().setUpClass() - - @classmethod - def tearDownClass(cls) -> None: - ''' - A classmethod to destruct the some thing after this test case is finished. - For this test case, it will down the containers and remove the networks of this test case - ''' - os.system("cd ../resources/blockchain_poa; /bin/bash down.sh") - return super().tearDownClass() - - def setUp(self) -> None: - ''' - setup some variables for test method - Here will get all the ethereum containers id for test method - ''' - cmd='docker ps -aqf "name=Ethereum-{}-"' - self.eth_array = [subprocess.check_output(cmd.format(i), shell=True).decode("utf-8").strip() for i in range(1,7)] - self.eth1, self.eth2, self.eth3, self.eth4, self.eth5, self.eth6 = self.eth_array - return super().setUp() - - def test_running(self): - ''' - Test the ethereum node is running or not. - If the node is not running, geth can not attach to this node and execute command. - This test method will try to list the account on each ethereum node, and assert the node's output. - If the output is not the list of account address, it means the node runns incorrectly. - ''' - for eth in self.eth_array: - cmd="docker exec -t {} geth attach --exec 'eth.accounts'".format(eth) - output = subprocess.check_output(cmd, shell=True).decode("utf-8").strip() - self.assertTrue(isArray(removeColoredText(output))) - - def test_prefund_account(self): - ''' - Test create prefund account api is executed correctly. - Checking whether a prefunded account is created on e3 and its balance - ''' - cmd="docker exec -t {} geth attach --exec 'eth.getBalance(eth.accounts[1])'".format(self.eth3) - output = subprocess.check_output(cmd, shell=True).decode("utf-8").strip() - self.assertEqual("8989898989", removeColoredText(output)) - - def test_import_account(self): - ''' - Test import prefund account api is executed correctly. - Checking whether a specific prefund account is imported on e4 by checking the address and checkd its balance - ''' - #test the import account exist - cmd="docker exec -t {} geth attach --exec 'eth.getBalance(\"675eb8226a35256f638712db74878f0a15d3d56e\")'".format(self.eth4) - output = subprocess.check_output(cmd, shell=True).decode("utf-8").strip() - self.assertEqual("989898989898", removeColoredText(output)) - - #test the balance - cmd="docker exec -t {} geth attach --exec 'eth.accounts'".format(self.eth4) - output = subprocess.check_output(cmd, shell=True).decode("utf-8").strip() - self.assertTrue('0x675eb8226a35256f638712db74878f0a15d3d56e' in removeColoredText(output[1:-1]).replace("\"","").replace(" ","").split(",")) - - def test_mining(self): - ''' - Test the node is mining or not - In this case, ethereum node 1-5 is mining, ethereum node 6 is not. - ''' - for eth in self.eth_array[:-1]: - cmd="docker exec -t {} geth attach --exec 'eth.mining'".format(eth) - output = subprocess.check_output(cmd, shell=True).decode("utf-8").strip() - self.assertEqual("true",removeColoredText(output)) - - # eth6 is not mining - cmd="docker exec -t {} geth attach --exec 'eth.mining'".format(self.eth6) - output = subprocess.check_output(cmd, shell=True).decode("utf-8").strip() - self.assertEqual("false",removeColoredText(output)) - - def test_consensus_mechanism(self): - ''' - Test all nodes is on POA consensus. - If a node runs on POA, it should have a module clique. So the method check whether all ethhereum nodes have module clique. - ''' - for eth in self.eth_array: - cmd="docker exec -t {} geth attach --exec 'web3.clique'".format(eth) - output = removeColoredText(subprocess.check_output(cmd, shell=True).decode("utf-8").strip()) - self.assertNotEqual(removeColoredText(output),"undefined") - - # def test_transation(self): - # ''' - # Test transation - # ''' - # # get destination account - # getReceiverAddrCmd = "docker exec -t {} geth attach --exec 'eth.accounts[2]'".format(self.eth6) - # receiverAddr = removeColoredText(subprocess.check_output(getReceiverAddrCmd, shell=True).decode("utf-8").strip()) - # regex = re.compile(r"\"0x[0-9,a-f,A-F]{40}\"") - # res = re.match(regex, receiverAddr) - # # output is an address - # self.assertTrue(bool(res)) - - # # unlock sender account - # unlockAccountCmd = "docker exec -t {} geth attach --exec 'personal.unlockAccount(\"0x675eb8226a35256f638712db74878f0a15d3d56e\",\"admin\")'".format(self.eth4) - # UnlockAccountOutput = removeColoredText(subprocess.check_output(unlockAccountCmd, shell=True).decode("utf-8").strip()) - # self.assertEqual(removeColoredText(UnlockAccountOutput),"true", "unlock account fail") - - # # send transation - # sendTransationCmd="docker exec -t {} geth attach --exec 'eth.sendTransaction({from: \"0x675eb8226a35256f638712db74878f0a15d3d56e\", to:\"{}\", value:\"100000000\"})'".format(self.eth4, receiverAddr.replace('"','')) - # sendTransationOutput = removeColoredText(subprocess.check_output(sendTransationCmd, shell=True).decode("utf-8").strip()) - # # output is the transation hash - # regex = re.compile(r"\"0x[0-9,a-f,A-F]{64}\"") - # res = re.match(regex, sendTransationOutput) - # self.assertTrue(bool(res)) - - # #wait for the transation - # startTime = time.time() - # pendingTransations = "" - # while True: - # sleep(300) - # # check transation - # getPendingTransationCmd="docker exec -t {} geth attach --exec 'eth.pendingTransactions'".format(self.eth4) - # pendingTransations = removeColoredText(subprocess.check_output(getPendingTransationCmd, shell=True).decode("utf-8").strip()) - # if pendingTransations == "[]": - # # the transation is finish - # break - # # if the transation can not finish in 35 minutes, regard it as time out - # if time.time() - startTime > 2100: - # self.fail("transation time out: transation can not be finished within half an hour") - - # # assert receiver's balance - # receiverBalanceCmd="docker exec -t {} geth attach --exec 'eth.getBalance('{}')'".format(self.eth6, receiverAddr.replace('"','')) - # receiverBalance = removeColoredText(subprocess.check_output(receiverBalanceCmd, shell=True).decode("utf-8").strip()) - # self.assertEqual(receiverBalance, "100000000") - - # # assert sender's balance - # senderBalanceCmd="docker exec -t {} geth attach --exec 'eth.getBalance('0x675eb8226a35256f638712db74878f0a15d3d56e')'".format(self.eth4) - # senderBalance = removeColoredText(subprocess.check_output(senderBalanceCmd, shell=True).decode("utf-8").strip()) - # self.assertEqual(senderBalance, "989798989898") - -if __name__ == '__main__': - unittest.main() \ No newline at end of file diff --git a/test/ethereum/cases/test_Run_POA_POW.py b/test/ethereum/cases/test_Run_POA_POW.py deleted file mode 100644 index a694df234..000000000 --- a/test/ethereum/cases/test_Run_POA_POW.py +++ /dev/null @@ -1,80 +0,0 @@ -#!/usr/bin/env python3 -# encoding: utf-8 - -import os -from time import sleep -import unittest -import subprocess -# from subprocess import CalledProcessError -from seedemu.services.EthereumService import * - -def removeColoredText(color_text:str): - return re.sub(r'(\x9B|\x1B\[)[0-?]*[ -\/]*[@-~]', '', color_text) - -def isArray(test:str): - regex = re.compile(r'\[[a-z,\",\',0-9,\,,\ ]*\]') - res = re.match(regex, test) - return bool(res) - -class TestIsArrayFunction(unittest.TestCase): - def test_true_array(self): - res = isArray('["0xb259ec1870f32a202c5a4779be7bd554f7dc6015", "0x906badd4a982fc0e107c1691f6e27abafa958425", "0xd72559d3200d6fb9bdd81f5aa704a6a1147ca15f"]') - self.assertIsNotNone(res) - self.assertTrue(res) - - def test_true_empty_array(self): - res = isArray('[]') - self.assertIsNotNone(res) - self.assertTrue(res) - - def test_false_array(self): - res = isArray('"0x906badd4a982fc0e107c1691f6e27abafa958425"') - self.assertIsNotNone(res) - self.assertFalse(res) - -class TestRunPOAPOW(unittest.TestCase): - @classmethod - def setUpClass(cls) -> None: - os.system("cd ../resources/blockchain_poa_pow; nohup /bin/bash build.sh; /bin/bash run.sh &") - sleep(300) # sleep 5 min to build and run container - return super().setUpClass() - - @classmethod - def tearDownClass(cls) -> None: - os.system("cd ../resources/blockchain_poa_pow; /bin/bash down.sh") - return super().tearDownClass() - - def setUp(self) -> None: - cmd='docker ps -aqf "name=Ethereum-{}-"' - self.eth_array = [subprocess.check_output(cmd.format(i), shell=True).decode("utf-8").strip() for i in range(1,8)] - self.eth1, self.eth2, self.eth3, self.eth4, self.eth5, self.eth6, self.eth7 = self.eth_array - return super().setUp() - - def test_running(self): - for eth in self.eth_array: - cmd="docker exec -t {} geth attach --exec 'eth.accounts'".format(eth) - output = subprocess.check_output(cmd, shell=True).decode("utf-8").strip() - self.assertTrue(isArray(removeColoredText(output))) - - def test_mining(self): - # check mining - for index, result in enumerate(["true","true","false","true","true","true","true"]): - if index + 1 % 3 == 0 and index + 1 <=6: - # boot node is not mining - cmd="docker exec -t {} geth attach --exec 'eth.mining'".format(self.eth_array[index]) - output = subprocess.check_output(cmd, shell=True).decode("utf-8").strip() - self.assertEqual(result,removeColoredText(output)) - - - def test_consensus_mechanism(self): - for eth in self.eth_array[:5]: - cmd="docker exec -t {} geth attach --exec 'web3.clique'".format(eth) - output = removeColoredText(subprocess.check_output(cmd, shell=True).decode("utf-8").strip()) - self.assertNotEqual(removeColoredText(output),"undefined") - for eth in self.eth_array[5:]: - cmd="docker exec -t {} geth attach --exec 'web3.ethash'".format(eth) - output = removeColoredText(subprocess.check_output(cmd, shell=True).decode("utf-8").strip()) - self.assertNotEqual(removeColoredText(output),"undefined") - -if __name__ == '__main__': - unittest.main() \ No newline at end of file diff --git a/test/ethereum/cases/test_Run_POW.py b/test/ethereum/cases/test_Run_POW.py deleted file mode 100644 index 935f221a5..000000000 --- a/test/ethereum/cases/test_Run_POW.py +++ /dev/null @@ -1,81 +0,0 @@ -#!/usr/bin/env python3 -# encoding: utf-8 - -import os -from time import sleep -import unittest -import subprocess -# from subprocess import CalledProcessError -from seedemu.services.EthereumService import * - -def removeColoredText(color_text:str): - return re.sub(r'(\x9B|\x1B\[)[0-?]*[ -\/]*[@-~]', '', color_text) - -def isArray(test:str): - regex = re.compile(r'\[[a-z,\",\',0-9,\,,\ ]*\]') - res = re.match(regex, test) - return bool(res) - - -class TestRunPOW(unittest.TestCase): - @classmethod - def setUpClass(cls) -> None: - os.system("cd ../resources/blockchain_pow; nohup /bin/bash build.sh; /bin/bash run.sh &") - sleep(300) # sleep 5 min to build and run container - return super().setUpClass() - - @classmethod - def tearDownClass(cls) -> None: - os.system("cd ../resources/blockchain_pow; /bin/bash down.sh") - return super().tearDownClass() - - def setUp(self) -> None: - cmd='docker ps -aqf "name=Ethereum-{}-"' - self.eth_array = [subprocess.check_output(cmd.format(i), shell=True).decode("utf-8").strip() for i in range(1,7)] - self.eth1, self.eth2, self.eth3, self.eth4, self.eth5, self.eth6 = self.eth_array - return super().setUp() - - def test_running(self): - for eth in self.eth_array: - cmd="docker exec -t {} geth attach --exec 'eth.accounts'".format(eth) - output = subprocess.check_output(cmd, shell=True).decode("utf-8").strip() - self.assertTrue(isArray(removeColoredText(output))) - - def test_prefund_account(self): - # check creat prefunded accounts on e3 - cmd="docker exec -t {} geth attach --exec 'eth.getBalance(eth.accounts[1])'".format(self.eth3) - output = subprocess.check_output(cmd, shell=True).decode("utf-8").strip() - self.assertEqual("8989898989", removeColoredText(output)) - - def test_import_account(self): - #test the import account exist - cmd="docker exec -t {} geth attach --exec 'eth.getBalance(\"675eb8226a35256f638712db74878f0a15d3d56e\")'".format(self.eth4) - output = subprocess.check_output(cmd, shell=True).decode("utf-8").strip() - self.assertEqual("989898989898", removeColoredText(output)) - - #test the balance - cmd="docker exec -t {} geth attach --exec 'eth.accounts'".format(self.eth4) - output = subprocess.check_output(cmd, shell=True).decode("utf-8").strip() - self.assertTrue('0x675eb8226a35256f638712db74878f0a15d3d56e' in removeColoredText(output[1:-1]).replace("\"","").replace(" ","").split(",")) - - def test_mining(self): - # check mining, only eth6 is not mining - for eth in self.eth_array[:-1]: - cmd="docker exec -t {} geth attach --exec 'eth.mining'".format(eth) - output = subprocess.check_output(cmd, shell=True).decode("utf-8").strip() - self.assertEqual("true",removeColoredText(output)) - - # eth6 is not mining - cmd="docker exec -t {} geth attach --exec 'eth.mining'".format(self.eth6) - output = subprocess.check_output(cmd, shell=True).decode("utf-8").strip() - self.assertEqual("false",removeColoredText(output)) - - def test_consensus_mechanism(self): - # check mining, only eth6 is not mining - for eth in self.eth_array: - cmd="docker exec -t {} geth attach --exec 'web3.ethash'".format(eth) - output = removeColoredText(subprocess.check_output(cmd, shell=True).decode("utf-8").strip()) - self.assertNotEqual(removeColoredText(output),"undefined") - -if __name__ == '__main__': - unittest.main() \ No newline at end of file diff --git a/test/ethereum/loader_ethereum.py b/test/ethereum/loader_ethereum.py deleted file mode 100644 index 31aab8931..000000000 --- a/test/ethereum/loader_ethereum.py +++ /dev/null @@ -1,33 +0,0 @@ -from importlib.abc import Loader -from operator import le -import os -import unittest - -from simplejson import load - -loader = unittest.TestLoader() -ethereumTestSuite = loader.discover("./cases",pattern='test_*.py') - -if __name__ == '__main__': - runner = unittest.TextTestRunner() - os.chdir(os.getcwd()+"/cases") - testResult = runner.run(ethereumTestSuite) - print("Ethereum Unit Testing") - print(testResult) - # testResult.wasSuccessful - # passSign = len(testResult.errors) == 0 and len(testResult.failures) == 0 - if testResult.wasSuccessful: - print('\033[32m'+'PASS' + '\033[0m') - else: - if len(testResult.errors) != 0: - print('\033[93m'+'================== Error ==================' + '\033[0m') - for index, error in enumerate(testResult.errors): - print("Error-{}".format(index+1)) - print(error[0]) - print(error[1]) - if len(testResult.failures) != 0: - print('\033[91m'+'==================Failure==================' + '\033[0m') - for index, failure in enumerate(testResult.failures): - print("Failure-{}".format(index+1)) - print(failure[0]) - print(failure[1]) \ No newline at end of file diff --git a/test/ethereum/resources/blockchain_poa/Contracts/contract.abi b/test/ethereum/resources/blockchain_poa/Contracts/contract.abi deleted file mode 100644 index da981a2e3..000000000 --- a/test/ethereum/resources/blockchain_poa/Contracts/contract.abi +++ /dev/null @@ -1 +0,0 @@ -[{"inputs":[{"internalType":"address payable","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"claimFunds","outputs":[],"stateMutability":"payable","type":"function"},{"stateMutability":"payable","type":"receive"}] diff --git a/test/ethereum/resources/blockchain_poa/Contracts/contract.sol b/test/ethereum/resources/blockchain_poa/Contracts/contract.sol deleted file mode 100644 index 09b437e76..000000000 --- a/test/ethereum/resources/blockchain_poa/Contracts/contract.sol +++ /dev/null @@ -1,13 +0,0 @@ -pragma solidity ^0.8.0; - -contract Crowdfunding { - uint256 amount; - - receive() external payable { - amount += msg.value; - } - - function claimFunds(address payable _to, uint _amount) public payable { - _to.transfer(_amount); - } -} \ No newline at end of file diff --git a/test/ethereum/resources/blockchain_poa/blockchain.py b/test/ethereum/resources/blockchain_poa/blockchain.py deleted file mode 100755 index 0e24581c3..000000000 --- a/test/ethereum/resources/blockchain_poa/blockchain.py +++ /dev/null @@ -1,51 +0,0 @@ -#!/usr/bin/env python3 -# encoding: utf-8 - -from seedemu.core import Emulator, Binding, Filter -from seedemu.mergers import DEFAULT_MERGERS -from seedemu.compiler import Docker -from os import mkdir, chdir, getcwd, path - - -emuA = Emulator() -emuB = Emulator() - -# Load the pre-built components and merge them -emuA.load('./base-component.bin') -emuB.load('./component-blockchain.bin') -emu = emuA.merge(emuB, DEFAULT_MERGERS) - -# Binding virtual nodes to physical nodes -emu.addBinding(Binding('eth1', filter = Filter(asn = 151))) -emu.addBinding(Binding('eth2', filter = Filter(asn = 152))) -emu.addBinding(Binding('eth3', filter = Filter(asn = 163))) -emu.addBinding(Binding('eth4', filter = Filter(asn = 164))) -emu.addBinding(Binding('eth5', filter = Filter(asn = 150))) -emu.addBinding(Binding('eth6', filter = Filter(asn = 170))) - -output = './output' - -def createDirectoryAtBase(base:str, directory:str, override:bool = False): - cur = getcwd() - if path.exists(base): - chdir(base) - if override: - rmtree(directory) - mkdir(directory) - chdir(cur) - - -saveState = True -def updateEthStates(): - if saveState: - createDirectoryAtBase(output, "eth-states/") - for i in range(1, 7): - createDirectoryAtBase(output, "eth-states/" + str(i)) - -# Render and compile -emu.render() - -# If output directory exists and override is set to false, we call exit(1) -# updateOutputdirectory will not be called -emu.compile(Docker(), output) -updateEthStates() diff --git a/test/ethereum/resources/blockchain_poa/build.sh b/test/ethereum/resources/blockchain_poa/build.sh deleted file mode 100755 index 44efd5ba9..000000000 --- a/test/ethereum/resources/blockchain_poa/build.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/bash - -export SAVE_STATE=True -# remove the output folder -sudo rm -rf output/ - -# initial the network -./mini-internet.py - -# build blockchain component -./component-blockchain.py - -# render -./blockchain.py - -# docker compose build -cd ./output -docker-compose build - -unset SAVE_STATE - diff --git a/test/ethereum/resources/blockchain_poa/component-blockchain.py b/test/ethereum/resources/blockchain_poa/component-blockchain.py deleted file mode 100755 index 6bcff6194..000000000 --- a/test/ethereum/resources/blockchain_poa/component-blockchain.py +++ /dev/null @@ -1,56 +0,0 @@ -#!/usr/bin/env python3 -# encoding: utf-8 - -from seedemu import * - -emu = Emulator() - -# Create the Ethereum layer -# saveState=True: will set the blockchain folder using `volumes`, -# so the blockchain data will be preserved when containers are deleted. -# Note: right now we need to manually create the folder for each node (see README.md). -eth = EthereumService(saveState = True) -eth.setBaseConsensusMechanism(mechanism=ConsensusMechanism.POA) - - -# Create Ethereum nodes (nodes in this layer are virtual) -e1 = eth.install("eth1") -e2 = eth.install("eth2") -e3 = eth.install("eth3") -e4 = eth.install("eth4") -e5 = eth.install("eth5") -e6 = eth.install("eth6") - -# Set bootnodes on e1 and e2. The other nodes can use these bootnodes to find peers. -# Start mining on e1 - e4 -e1.setBootNode(True).setBootNodeHttpPort(8081).startMiner() -e2.setBootNode(True).startMiner() -e3.startMiner() -e4.startMiner() - -# Create more accounts on e5 and e6 -e5.startMiner().createNewAccount(3) -e6.createNewAccount() - -# Create prefunded accounts on e3 -e3.createPrefundedAccounts(8989898989, 1, "admin") - -# Import prefunded accounts on e4 -e4.importPrefundedAccount(keyfileDirectory = "../keystore/UTC--2022-03-25T16-41-21.542086000Z--675eb8226a35256f638712db74878f0a15d3d56e",password="admin", balance="989898989898") - -# Create a smart contract and deploy it from node e3 -# We need to put the compiled smart contracts inside the Contracts/ folder -smart_contract = SmartContract("./Contracts/contract.bin", "./Contracts/contract.abi") -e3.deploySmartContract(smart_contract) - -# Customizing the display names (for visualization purpose) -emu.getVirtualNode('eth1').setDisplayName('Ethereum-1') -emu.getVirtualNode('eth2').setDisplayName('Ethereum-2') -emu.getVirtualNode('eth3').setDisplayName('Ethereum-3') -emu.getVirtualNode('eth4').setDisplayName('Ethereum-4') -emu.getVirtualNode('eth5').setDisplayName('Ethereum-5') -emu.getVirtualNode('eth6').setDisplayName('Ethereum-6') - -# Add the layer and save the component to a file -emu.addLayer(eth) -emu.dump('component-blockchain.bin') diff --git a/test/ethereum/resources/blockchain_poa/down.sh b/test/ethereum/resources/blockchain_poa/down.sh deleted file mode 100755 index 2825d270b..000000000 --- a/test/ethereum/resources/blockchain_poa/down.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash - -cd ./output - -docker-compose down - -cd .. - -sudo rm -rf ./output - diff --git a/test/ethereum/resources/blockchain_poa/mini-internet.py b/test/ethereum/resources/blockchain_poa/mini-internet.py deleted file mode 100755 index d5e12498d..000000000 --- a/test/ethereum/resources/blockchain_poa/mini-internet.py +++ /dev/null @@ -1,153 +0,0 @@ -#!/usr/bin/env python3 -# encoding: utf-8 - -from seedemu.layers import Base, Routing, Ebgp, Ibgp, Ospf, PeerRelationship, Dnssec -from seedemu.services import WebService, DomainNameService, DomainNameCachingService -from seedemu.services import CymruIpOriginService, ReverseDomainNameService, BgpLookingGlassService -from seedemu.compiler import Docker, Graphviz -from seedemu.hooks import ResolvConfHook -from seedemu.core import Emulator, Service, Binding, Filter -from seedemu.layers import Router -from seedemu.raps import OpenVpnRemoteAccessProvider -from seedemu.utilities import Makers - -from typing import List, Tuple, Dict - - -############################################################################### -emu = Emulator() -base = Base() -routing = Routing() -ebgp = Ebgp() -ibgp = Ibgp() -ospf = Ospf() -web = WebService() -ovpn = OpenVpnRemoteAccessProvider() - - -############################################################################### - -ix100 = base.createInternetExchange(100) -ix101 = base.createInternetExchange(101) -ix102 = base.createInternetExchange(102) -ix103 = base.createInternetExchange(103) -ix104 = base.createInternetExchange(104) -ix105 = base.createInternetExchange(105) - -# Customize names (for visualization purpose) -ix100.getPeeringLan().setDisplayName('NYC-100') -ix101.getPeeringLan().setDisplayName('San Jose-101') -ix102.getPeeringLan().setDisplayName('Chicago-102') -ix103.getPeeringLan().setDisplayName('Miami-103') -ix104.getPeeringLan().setDisplayName('Boston-104') -ix105.getPeeringLan().setDisplayName('Huston-105') - - -############################################################################### -# Create Transit Autonomous Systems - -## Tier 1 ASes -Makers.makeTransitAs(base, 2, [100, 101, 102, 105], - [(100, 101), (101, 102), (100, 105)] -) - -Makers.makeTransitAs(base, 3, [100, 103, 104, 105], - [(100, 103), (100, 105), (103, 105), (103, 104)] -) - -Makers.makeTransitAs(base, 4, [100, 102, 104], - [(100, 104), (102, 104)] -) - -## Tier 2 ASes -Makers.makeTransitAs(base, 11, [102, 105], [(102, 105)]) -Makers.makeTransitAs(base, 12, [101, 104], [(101, 104)]) - - -############################################################################### -# Create single-homed stub ASes. "None" means create a host only - -Makers.makeStubAs(emu, base, 150, 100, [web, None]) -Makers.makeStubAs(emu, base, 151, 100, [web, None]) - -Makers.makeStubAs(emu, base, 152, 101, [None, None]) -Makers.makeStubAs(emu, base, 153, 101, [web, None, None]) - -Makers.makeStubAs(emu, base, 154, 102, [None, web]) - -Makers.makeStubAs(emu, base, 160, 103, [web, None]) -Makers.makeStubAs(emu, base, 161, 103, [web, None]) -Makers.makeStubAs(emu, base, 162, 103, [web, None]) - -Makers.makeStubAs(emu, base, 163, 104, [web, None]) -Makers.makeStubAs(emu, base, 164, 104, [None, None]) - -Makers.makeStubAs(emu, base, 170, 105, [web, None]) -Makers.makeStubAs(emu, base, 171, 105, [None]) - - -# Add a host with customized IP address to AS-154 -as154 = base.getAutonomousSystem(154) -as154.createHost('host_2').joinNetwork('net0', address = '10.154.0.129') - - -# Create real-world AS. -# AS11872 is the Syracuse University's autonomous system - -as11872 = base.createAutonomousSystem(11872) -as11872.createRealWorldRouter('rw').joinNetwork('ix102', '10.102.0.118') - -# Allow outside computer to VPN into AS-152's network -as152 = base.getAutonomousSystem(152) -as152.getNetwork('net0').enableRemoteAccess(ovpn) - - -############################################################################### -# Peering via RS (route server). The default peering mode for RS is PeerRelationship.Peer, -# which means each AS will only export its customers and their own prefixes. -# We will use this peering relationship to peer all the ASes in an IX. -# None of them will provide transit service for others. - -ebgp.addRsPeers(100, [2, 3, 4]) -ebgp.addRsPeers(102, [2, 4]) -ebgp.addRsPeers(104, [3, 4]) -ebgp.addRsPeers(105, [2, 3]) - -# To buy transit services from another autonomous system, -# we will use private peering - -ebgp.addPrivatePeerings(100, [2], [150, 151], PeerRelationship.Provider) -ebgp.addPrivatePeerings(100, [3], [150], PeerRelationship.Provider) - -ebgp.addPrivatePeerings(101, [2], [12], PeerRelationship.Provider) -ebgp.addPrivatePeerings(101, [12], [152, 153], PeerRelationship.Provider) - -ebgp.addPrivatePeerings(102, [2, 4], [11, 154], PeerRelationship.Provider) -ebgp.addPrivatePeerings(102, [11], [154, 11872], PeerRelationship.Provider) - -ebgp.addPrivatePeerings(103, [3], [160, 161, 162], PeerRelationship.Provider) - -ebgp.addPrivatePeerings(104, [3, 4], [12], PeerRelationship.Provider) -ebgp.addPrivatePeerings(104, [4], [163], PeerRelationship.Provider) -ebgp.addPrivatePeerings(104, [12], [164], PeerRelationship.Provider) - -ebgp.addPrivatePeerings(105, [3], [11, 170], PeerRelationship.Provider) -ebgp.addPrivatePeerings(105, [11], [171], PeerRelationship.Provider) - - -############################################################################### - -# Add layers to the emulator -emu.addLayer(base) -emu.addLayer(routing) -emu.addLayer(ebgp) -emu.addLayer(ibgp) -emu.addLayer(ospf) -emu.addLayer(web) - -# Save it to a component file, so it can be used by other emulators -emu.dump('base-component.bin') - -# Uncomment the following if you want to generate the final emulation files -# emu.render() -# emu.compile(Docker(), './output') \ No newline at end of file diff --git a/test/ethereum/resources/blockchain_poa/run.sh b/test/ethereum/resources/blockchain_poa/run.sh deleted file mode 100755 index fafa3c3e3..000000000 --- a/test/ethereum/resources/blockchain_poa/run.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash - -cd ./output -docker-compose up - diff --git a/test/ethereum/resources/blockchain_poa_pow/blockchain.py b/test/ethereum/resources/blockchain_poa_pow/blockchain.py deleted file mode 100755 index f2451ef3c..000000000 --- a/test/ethereum/resources/blockchain_poa_pow/blockchain.py +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/env python3 -# encoding: utf-8 - -from seedemu.core import Emulator, Binding, Filter -from seedemu.mergers import DEFAULT_MERGERS -from seedemu.compiler import Docker -from os import mkdir, chdir, getcwd, path - - -emuA = Emulator() -emuB = Emulator() - -# Load the pre-built components and merge them -emuA.load('./base-component.bin') -emuB.load('./component-blockchain.bin') -emu = emuA.merge(emuB, DEFAULT_MERGERS) - -# Binding virtual nodes to physical nodes -start=1 -end=31 -for i in range(start, end): - emu.addBinding(Binding('eth{}'.format(i))) - # Binding virtual nodes to physical nodes - -output = './output' - -def createDirectoryAtBase(base:str, directory:str, override:bool = False): - cur = getcwd() - if path.exists(base): - chdir(base) - if override: - rmtree(directory) - mkdir(directory) - chdir(cur) - - -saveState = True -def updateEthStates(): - if saveState: - createDirectoryAtBase(output, "eth-states/") - for i in range(start, end): - createDirectoryAtBase(output, "eth-states/" + str(i)) - -# Render and compile -emu.render() - -# If output directory exists and override is set to false, we call exit(1) -# updateOutputdirectory will not be called -emu.compile(Docker(ethClientEnabled=False, clientEnabled=False), output) -updateEthStates() diff --git a/test/ethereum/resources/blockchain_poa_pow/build.sh b/test/ethereum/resources/blockchain_poa_pow/build.sh deleted file mode 100755 index 1888e55db..000000000 --- a/test/ethereum/resources/blockchain_poa_pow/build.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/bash - -export SAVE_STATE=True -# remove the output folder -sudo rm -rf output/ - -# initial the network -./nano-internet.py - -# build blockchain component -./component-blockchain.py - -# render -./blockchain.py - -# docker compose build -cd ./output -docker-compose build - -unset SAVE_STATE - diff --git a/test/ethereum/resources/blockchain_poa_pow/component-blockchain.py b/test/ethereum/resources/blockchain_poa_pow/component-blockchain.py deleted file mode 100755 index 281f4a243..000000000 --- a/test/ethereum/resources/blockchain_poa_pow/component-blockchain.py +++ /dev/null @@ -1,61 +0,0 @@ -#!/usr/bin/env python3 -# encoding: utf-8 - -from seedemu import * - -emu = Emulator() - -# Create the Ethereum layer -# saveState=True: will set the blockchain folder using `volumes`, -# manual: requires you to trigger the /tmp/run.sh bash files in each container to lunch the ethereum nodes -# so the blockchain data will be preserved when containers are deleted. -# Note: right now we need to manually create the folder for each node (see README.md). -eth = EthereumService(saveState = True, manual=False) - -eth.setBaseConsensusMechanism(ConsensusMechanism.POA) - -# Create Ethereum nodes (nodes in this layer are virtual) -start=1 -end=6 -sealers=[] -bootnodes=[] -hport=8544 -cport=8549 - -# Currently the minimum amount to have to be a validator in proof of stake -balance = 32 * pow(10, 8) - - - -# Setting a third of nodes as bootnodes -for i in range(start, end): - e = eth.install("eth{}".format(i)) - if i%3 == 0: - e.setBootNode(True) - bootnodes.append(i) - else: - e.createPrefundedAccounts(balance, 1) - e.unlockAccounts().startMiner() - sealers.append(i) - - e.enableExternalConnection() # not recommended for sealers in production mode - emu.getVirtualNode('eth{}'.format(i)).setDisplayName('Ethereum-{}'.format(i)).addPortForwarding(hport, cport) - hport = hport + 1 - -print("There are {} sealers and {} bootnodes".format(len(sealers), len(bootnodes))) -print("Sealers {}".format(sealers)) -print("Bootnodes {}".format(bootnodes)) - -start = end -end = start + 2 -for i in range(start, end): - e = eth.install("eth{}".format(i)) - e.setConsensusMechanism(ConsensusMechanism.POW) - e.unlockAccounts().startMiner() - emu.getVirtualNode("eth{}".format(i)).setDisplayName('Ethereum-{}'.format(i)) - -print("Created {} nodes that use PoW consensus mechanism".format(end - start)) - -# Add the layer and save the component to a file -emu.addLayer(eth) -emu.dump('component-blockchain.bin') diff --git a/test/ethereum/resources/blockchain_poa_pow/down.sh b/test/ethereum/resources/blockchain_poa_pow/down.sh deleted file mode 100755 index 2825d270b..000000000 --- a/test/ethereum/resources/blockchain_poa_pow/down.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash - -cd ./output - -docker-compose down - -cd .. - -sudo rm -rf ./output - diff --git a/test/ethereum/resources/blockchain_poa_pow/nano-internet.py b/test/ethereum/resources/blockchain_poa_pow/nano-internet.py deleted file mode 100755 index 7608a03d8..000000000 --- a/test/ethereum/resources/blockchain_poa_pow/nano-internet.py +++ /dev/null @@ -1,155 +0,0 @@ -#!/usr/bin/env python3 -# encoding: utf-8 - -from seedemu import * - - -# Create the Emulator -emu = Emulator() - -# Create the base layer -base = Base() - -############################################################################### -# Create Internet exchanges - -ix100 = base.createInternetExchange(100) -ix101 = base.createInternetExchange(101) -ix100.getPeeringLan().setDisplayName('New York-100') -ix101.getPeeringLan().setDisplayName('Chicago-101') - - -############################################################################### -# Create and set up a transit AS (AS-3) - -as3 = base.createAutonomousSystem(3) - -# Create 3 internal networks -as3.createNetwork('net0') -as3.createNetwork('net1') -as3.createNetwork('net2') -as3.createNetwork('net3') - -# Create four routers and link them in a linear structure: -# ix100 <--> r1 <--> r2 <--> r3 <--> r4 <--> ix101 -# r1 and r2 are BGP routers because they are connected to internet exchanges -as3.createRouter('r1').joinNetwork('net0').joinNetwork('ix100') -as3.createRouter('r2').joinNetwork('net0').joinNetwork('net1') -as3.createRouter('r3').joinNetwork('net1').joinNetwork('net2') -as3.createRouter('r4').joinNetwork('net2').joinNetwork('ix101') -as3.createRouter('r5').joinNetwork('net3').joinNetwork('net2') -for i in range(0, 10): - as3.createHost('host{}'.format(i)).joinNetwork('net3') -############################################################################### -# Create and set up the stub AS (AS-151) - -as151 = base.createAutonomousSystem(151) - -# Create an internal network and a router -as151.createNetwork('net0') -as151.createRouter('router0').joinNetwork('net0').joinNetwork('ix100') - -# Create two host nodes -as151.createHost('host0').joinNetwork('net0') -as151.createHost('host1').joinNetwork('net0', address = '10.151.0.80') -for i in range(2, 10): - as151.createHost('host{}'.format(i)).joinNetwork('net0') - -# Install additional software on a host -host0 = as151.getHost('host0') -host0.addSoftware('telnetd').addSoftware('telnet') - -# Run an additional command inside the container -# The command creates a new account inside the host (also sets its password) -host0.addBuildCommand('useradd -m -s /bin/bash seed && echo "seed:dees" | chpasswd') - -############################################################################### -# Create and set up the stub AS (AS-152) - - -as152 = base.createAutonomousSystem(152) -as152.createNetwork('net0') -as152.createRouter('router0').joinNetwork('net0').joinNetwork('ix101') -for i in range(0, 10): - as152.createHost('host{}'.format(i)).joinNetwork('net0') -# Install additional software on a host -as152.getHost('host0').addSoftware('telnet') - -############################################################################### -# Create and set up the stub AS (AS-153) - -# Use the utility function to create the AS -Makers.makeStubAs(emu, base, 153, 101, [None, None]) - -# Further customization -as153 = base.getAutonomousSystem(153) -as153.getHost('host_1').addSoftware('telnet') - -############################################################################### -# BGP peering - -# Create the Ebgp layer -ebgp = Ebgp() - -# Make AS-3 the internet service provider for all the stub ASes -ebgp.addPrivatePeering (100, 3, 151, abRelationship = PeerRelationship.Provider) -ebgp.addPrivatePeerings(101, [3], [152, 153], abRelationship = PeerRelationship.Provider) - -# Peer AS-152 and AS-153 directly as peers -ebgp.addPrivatePeering(101, 152, 153, abRelationship = PeerRelationship.Peer) - - -############################################################################### -# Web Service Layer - -# Create the WebService layer -web = WebService() - -# Create web service nodes (virtual nodes) -web.install('web01') -web.install('web02') - -# Bind the virtual nodes to physical nodes -emu.addBinding(Binding('web01', filter = Filter(nodeName = 'host0', asn = 151))) -emu.addBinding(Binding('web02', filter = Filter(nodeName = 'host0', asn = 152))) - - -############################################################################### - -emu.addLayer(base) -emu.addLayer(ebgp) -emu.addLayer(web) - -emu.addLayer(Routing()) -emu.addLayer(Ibgp()) -emu.addLayer(Ospf()) - -############################################################################### -# Save it to a component file, so it can be used by other emulators - -# This is optional -emu.dump('base-component.bin') - - -############################################################################### -# Rendering: This is where the actual binding happens - -emu.render() - -# Change the display name for the nodes hosting the web services -emu.getBindingFor('web01').setDisplayName('Web-1') -emu.getBindingFor('web02').setDisplayName('Web-2') - - -############################################################################### -# Compilation - -# Generate the Docker files -#emu.compile(Docker(), './output') - -# Generate other type of outputs -#emu.compile(Graphviz(), './others/graphs') -#emu.compile(DistributedDocker(), './others/distributed-docker') -#emu.compile(GcpDistributedDocker(), './others/gcp-distributed-docker') - - diff --git a/test/ethereum/resources/blockchain_poa_pow/run.sh b/test/ethereum/resources/blockchain_poa_pow/run.sh deleted file mode 100755 index fafa3c3e3..000000000 --- a/test/ethereum/resources/blockchain_poa_pow/run.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash - -cd ./output -docker-compose up - diff --git a/test/ethereum/resources/blockchain_pow/Contracts/contract.abi b/test/ethereum/resources/blockchain_pow/Contracts/contract.abi deleted file mode 100644 index da981a2e3..000000000 --- a/test/ethereum/resources/blockchain_pow/Contracts/contract.abi +++ /dev/null @@ -1 +0,0 @@ -[{"inputs":[{"internalType":"address payable","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"claimFunds","outputs":[],"stateMutability":"payable","type":"function"},{"stateMutability":"payable","type":"receive"}] diff --git a/test/ethereum/resources/blockchain_pow/Contracts/contract.sol b/test/ethereum/resources/blockchain_pow/Contracts/contract.sol deleted file mode 100644 index 09b437e76..000000000 --- a/test/ethereum/resources/blockchain_pow/Contracts/contract.sol +++ /dev/null @@ -1,13 +0,0 @@ -pragma solidity ^0.8.0; - -contract Crowdfunding { - uint256 amount; - - receive() external payable { - amount += msg.value; - } - - function claimFunds(address payable _to, uint _amount) public payable { - _to.transfer(_amount); - } -} \ No newline at end of file diff --git a/test/ethereum/resources/blockchain_pow/blockchain.py b/test/ethereum/resources/blockchain_pow/blockchain.py deleted file mode 100755 index 0e24581c3..000000000 --- a/test/ethereum/resources/blockchain_pow/blockchain.py +++ /dev/null @@ -1,51 +0,0 @@ -#!/usr/bin/env python3 -# encoding: utf-8 - -from seedemu.core import Emulator, Binding, Filter -from seedemu.mergers import DEFAULT_MERGERS -from seedemu.compiler import Docker -from os import mkdir, chdir, getcwd, path - - -emuA = Emulator() -emuB = Emulator() - -# Load the pre-built components and merge them -emuA.load('./base-component.bin') -emuB.load('./component-blockchain.bin') -emu = emuA.merge(emuB, DEFAULT_MERGERS) - -# Binding virtual nodes to physical nodes -emu.addBinding(Binding('eth1', filter = Filter(asn = 151))) -emu.addBinding(Binding('eth2', filter = Filter(asn = 152))) -emu.addBinding(Binding('eth3', filter = Filter(asn = 163))) -emu.addBinding(Binding('eth4', filter = Filter(asn = 164))) -emu.addBinding(Binding('eth5', filter = Filter(asn = 150))) -emu.addBinding(Binding('eth6', filter = Filter(asn = 170))) - -output = './output' - -def createDirectoryAtBase(base:str, directory:str, override:bool = False): - cur = getcwd() - if path.exists(base): - chdir(base) - if override: - rmtree(directory) - mkdir(directory) - chdir(cur) - - -saveState = True -def updateEthStates(): - if saveState: - createDirectoryAtBase(output, "eth-states/") - for i in range(1, 7): - createDirectoryAtBase(output, "eth-states/" + str(i)) - -# Render and compile -emu.render() - -# If output directory exists and override is set to false, we call exit(1) -# updateOutputdirectory will not be called -emu.compile(Docker(), output) -updateEthStates() diff --git a/test/ethereum/resources/blockchain_pow/build.sh b/test/ethereum/resources/blockchain_pow/build.sh deleted file mode 100755 index 44efd5ba9..000000000 --- a/test/ethereum/resources/blockchain_pow/build.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/bash - -export SAVE_STATE=True -# remove the output folder -sudo rm -rf output/ - -# initial the network -./mini-internet.py - -# build blockchain component -./component-blockchain.py - -# render -./blockchain.py - -# docker compose build -cd ./output -docker-compose build - -unset SAVE_STATE - diff --git a/test/ethereum/resources/blockchain_pow/component-blockchain.py b/test/ethereum/resources/blockchain_pow/component-blockchain.py deleted file mode 100755 index 9c5f23fb0..000000000 --- a/test/ethereum/resources/blockchain_pow/component-blockchain.py +++ /dev/null @@ -1,56 +0,0 @@ -#!/usr/bin/env python3 -# encoding: utf-8 - -from seedemu import * - -emu = Emulator() - -# Create the Ethereum layer -# saveState=True: will set the blockchain folder using `volumes`, -# so the blockchain data will be preserved when containers are deleted. -# Note: right now we need to manually create the folder for each node (see README.md). -eth = EthereumService(saveState = True) -eth.setBaseConsensusMechanism(mechanism=ConsensusMechanism.POW) - - -# Create Ethereum nodes (nodes in this layer are virtual) -e1 = eth.install("eth1") -e2 = eth.install("eth2") -e3 = eth.install("eth3") -e4 = eth.install("eth4") -e5 = eth.install("eth5") -e6 = eth.install("eth6") - -# Set bootnodes on e1 and e2. The other nodes can use these bootnodes to find peers. -# Start mining on e1 - e4 -e1.setBootNode(True).setBootNodeHttpPort(8081).startMiner() -e2.setBootNode(True).startMiner() -e3.startMiner() -e4.startMiner() - -# Create more accounts on e5 and e6 -e5.startMiner().createNewAccount(3) -e6.createNewAccount() - -# Create prefunded accounts on e3 -e3.createPrefundedAccounts(8989898989, 1, "admin") - -# Import prefunded accounts on e4 -e4.importPrefundedAccount(keyfileDirectory = "../keystore/UTC--2022-03-25T16-41-21.542086000Z--675eb8226a35256f638712db74878f0a15d3d56e",password="admin", balance="989898989898") - -# Create a smart contract and deploy it from node e3 -# We need to put the compiled smart contracts inside the Contracts/ folder -smart_contract = SmartContract("./Contracts/contract.bin", "./Contracts/contract.abi") -e3.deploySmartContract(smart_contract) - -# Customizing the display names (for visualization purpose) -emu.getVirtualNode('eth1').setDisplayName('Ethereum-1') -emu.getVirtualNode('eth2').setDisplayName('Ethereum-2') -emu.getVirtualNode('eth3').setDisplayName('Ethereum-3') -emu.getVirtualNode('eth4').setDisplayName('Ethereum-4') -emu.getVirtualNode('eth5').setDisplayName('Ethereum-5') -emu.getVirtualNode('eth6').setDisplayName('Ethereum-6') - -# Add the layer and save the component to a file -emu.addLayer(eth) -emu.dump('component-blockchain.bin') diff --git a/test/ethereum/resources/blockchain_pow/down.sh b/test/ethereum/resources/blockchain_pow/down.sh deleted file mode 100755 index 2825d270b..000000000 --- a/test/ethereum/resources/blockchain_pow/down.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash - -cd ./output - -docker-compose down - -cd .. - -sudo rm -rf ./output - diff --git a/test/ethereum/resources/blockchain_pow/mini-internet.py b/test/ethereum/resources/blockchain_pow/mini-internet.py deleted file mode 100755 index d5e12498d..000000000 --- a/test/ethereum/resources/blockchain_pow/mini-internet.py +++ /dev/null @@ -1,153 +0,0 @@ -#!/usr/bin/env python3 -# encoding: utf-8 - -from seedemu.layers import Base, Routing, Ebgp, Ibgp, Ospf, PeerRelationship, Dnssec -from seedemu.services import WebService, DomainNameService, DomainNameCachingService -from seedemu.services import CymruIpOriginService, ReverseDomainNameService, BgpLookingGlassService -from seedemu.compiler import Docker, Graphviz -from seedemu.hooks import ResolvConfHook -from seedemu.core import Emulator, Service, Binding, Filter -from seedemu.layers import Router -from seedemu.raps import OpenVpnRemoteAccessProvider -from seedemu.utilities import Makers - -from typing import List, Tuple, Dict - - -############################################################################### -emu = Emulator() -base = Base() -routing = Routing() -ebgp = Ebgp() -ibgp = Ibgp() -ospf = Ospf() -web = WebService() -ovpn = OpenVpnRemoteAccessProvider() - - -############################################################################### - -ix100 = base.createInternetExchange(100) -ix101 = base.createInternetExchange(101) -ix102 = base.createInternetExchange(102) -ix103 = base.createInternetExchange(103) -ix104 = base.createInternetExchange(104) -ix105 = base.createInternetExchange(105) - -# Customize names (for visualization purpose) -ix100.getPeeringLan().setDisplayName('NYC-100') -ix101.getPeeringLan().setDisplayName('San Jose-101') -ix102.getPeeringLan().setDisplayName('Chicago-102') -ix103.getPeeringLan().setDisplayName('Miami-103') -ix104.getPeeringLan().setDisplayName('Boston-104') -ix105.getPeeringLan().setDisplayName('Huston-105') - - -############################################################################### -# Create Transit Autonomous Systems - -## Tier 1 ASes -Makers.makeTransitAs(base, 2, [100, 101, 102, 105], - [(100, 101), (101, 102), (100, 105)] -) - -Makers.makeTransitAs(base, 3, [100, 103, 104, 105], - [(100, 103), (100, 105), (103, 105), (103, 104)] -) - -Makers.makeTransitAs(base, 4, [100, 102, 104], - [(100, 104), (102, 104)] -) - -## Tier 2 ASes -Makers.makeTransitAs(base, 11, [102, 105], [(102, 105)]) -Makers.makeTransitAs(base, 12, [101, 104], [(101, 104)]) - - -############################################################################### -# Create single-homed stub ASes. "None" means create a host only - -Makers.makeStubAs(emu, base, 150, 100, [web, None]) -Makers.makeStubAs(emu, base, 151, 100, [web, None]) - -Makers.makeStubAs(emu, base, 152, 101, [None, None]) -Makers.makeStubAs(emu, base, 153, 101, [web, None, None]) - -Makers.makeStubAs(emu, base, 154, 102, [None, web]) - -Makers.makeStubAs(emu, base, 160, 103, [web, None]) -Makers.makeStubAs(emu, base, 161, 103, [web, None]) -Makers.makeStubAs(emu, base, 162, 103, [web, None]) - -Makers.makeStubAs(emu, base, 163, 104, [web, None]) -Makers.makeStubAs(emu, base, 164, 104, [None, None]) - -Makers.makeStubAs(emu, base, 170, 105, [web, None]) -Makers.makeStubAs(emu, base, 171, 105, [None]) - - -# Add a host with customized IP address to AS-154 -as154 = base.getAutonomousSystem(154) -as154.createHost('host_2').joinNetwork('net0', address = '10.154.0.129') - - -# Create real-world AS. -# AS11872 is the Syracuse University's autonomous system - -as11872 = base.createAutonomousSystem(11872) -as11872.createRealWorldRouter('rw').joinNetwork('ix102', '10.102.0.118') - -# Allow outside computer to VPN into AS-152's network -as152 = base.getAutonomousSystem(152) -as152.getNetwork('net0').enableRemoteAccess(ovpn) - - -############################################################################### -# Peering via RS (route server). The default peering mode for RS is PeerRelationship.Peer, -# which means each AS will only export its customers and their own prefixes. -# We will use this peering relationship to peer all the ASes in an IX. -# None of them will provide transit service for others. - -ebgp.addRsPeers(100, [2, 3, 4]) -ebgp.addRsPeers(102, [2, 4]) -ebgp.addRsPeers(104, [3, 4]) -ebgp.addRsPeers(105, [2, 3]) - -# To buy transit services from another autonomous system, -# we will use private peering - -ebgp.addPrivatePeerings(100, [2], [150, 151], PeerRelationship.Provider) -ebgp.addPrivatePeerings(100, [3], [150], PeerRelationship.Provider) - -ebgp.addPrivatePeerings(101, [2], [12], PeerRelationship.Provider) -ebgp.addPrivatePeerings(101, [12], [152, 153], PeerRelationship.Provider) - -ebgp.addPrivatePeerings(102, [2, 4], [11, 154], PeerRelationship.Provider) -ebgp.addPrivatePeerings(102, [11], [154, 11872], PeerRelationship.Provider) - -ebgp.addPrivatePeerings(103, [3], [160, 161, 162], PeerRelationship.Provider) - -ebgp.addPrivatePeerings(104, [3, 4], [12], PeerRelationship.Provider) -ebgp.addPrivatePeerings(104, [4], [163], PeerRelationship.Provider) -ebgp.addPrivatePeerings(104, [12], [164], PeerRelationship.Provider) - -ebgp.addPrivatePeerings(105, [3], [11, 170], PeerRelationship.Provider) -ebgp.addPrivatePeerings(105, [11], [171], PeerRelationship.Provider) - - -############################################################################### - -# Add layers to the emulator -emu.addLayer(base) -emu.addLayer(routing) -emu.addLayer(ebgp) -emu.addLayer(ibgp) -emu.addLayer(ospf) -emu.addLayer(web) - -# Save it to a component file, so it can be used by other emulators -emu.dump('base-component.bin') - -# Uncomment the following if you want to generate the final emulation files -# emu.render() -# emu.compile(Docker(), './output') \ No newline at end of file diff --git a/test/ethereum/resources/blockchain_pow/run.sh b/test/ethereum/resources/blockchain_pow/run.sh deleted file mode 100755 index fafa3c3e3..000000000 --- a/test/ethereum/resources/blockchain_pow/run.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash - -cd ./output -docker-compose up - diff --git a/test/ethereum/resources/keystore/UTC--2022-03-25T16-41-21.542086000Z--675eb8226a35256f638712db74878f0a15d3d56e b/test/ethereum/resources/keystore/UTC--2022-03-25T16-41-21.542086000Z--675eb8226a35256f638712db74878f0a15d3d56e deleted file mode 100644 index 4f0e0be2e..000000000 --- a/test/ethereum/resources/keystore/UTC--2022-03-25T16-41-21.542086000Z--675eb8226a35256f638712db74878f0a15d3d56e +++ /dev/null @@ -1 +0,0 @@ -{"address": "675eb8226a35256f638712db74878f0a15d3d56e", "crypto": {"cipher": "aes-128-ctr", "cipherparams": {"iv": "cbc176365f3894af5e95cd2704ee61c4"}, "ciphertext": "371c37784906c9d37abc3900c958c752f41b60f6dfaeddc4bf2a6d2d774b028b", "kdf": "scrypt", "kdfparams": {"dklen": 32, "n": 262144, "r": 1, "p": 8, "salt": "93794d233d59b0ff5daa6e5eca345c4a"}, "mac": "b139214451b8559567a2d06d7a6d1109b107b23ed8b809c1e6ca6d1c9ec15526"}, "id": "464b1168-fcb5-45c0-8c48-5adc0f255ade", "version": 3} \ No newline at end of file diff --git a/test/ethereum/resources/keystore/UTC--2022-04-05T19-21-56.904952000Z--20cc565f1ac407d24a2a35ab9312cec736880122 b/test/ethereum/resources/keystore/UTC--2022-04-05T19-21-56.904952000Z--20cc565f1ac407d24a2a35ab9312cec736880122 deleted file mode 100644 index 967163e1b..000000000 --- a/test/ethereum/resources/keystore/UTC--2022-04-05T19-21-56.904952000Z--20cc565f1ac407d24a2a35ab9312cec736880122 +++ /dev/null @@ -1 +0,0 @@ -{"address": "20cc565f1ac407d24a2a35ab9312cec736880122", "crypto": {"cipher": "aes-128-ctr", "cipherparams": {"iv": "b29eeec4f0eaeb807fc2b9f9dedaaf88"}, "ciphertext": "033b63fad68747efb51ef242cb036822ddb1a00ff5aa909bfcc4fc34d2b65cb2", "kdf": "scrypt", "kdfparams": {"dklen": 32, "n": 262144, "r": 1, "p": 8, "salt": "230cf5c739a1cf64e0bf49c5ca947307"}, "mac": "c4456f00a96161c149cc9a62203a7f6b1c95bf5d5d49a980f59ceff1704b4e24"}, "id": "a62865d9-8045-4e48-b30a-700be4eec47f", "version": 3} \ No newline at end of file diff --git a/test/ethereum/resources/keystore/UTC--2022-04-05T19-21-58.462119000Z--bb3e9561502ceaed131257765519876a250d374f b/test/ethereum/resources/keystore/UTC--2022-04-05T19-21-58.462119000Z--bb3e9561502ceaed131257765519876a250d374f deleted file mode 100644 index 5d94b8d30..000000000 --- a/test/ethereum/resources/keystore/UTC--2022-04-05T19-21-58.462119000Z--bb3e9561502ceaed131257765519876a250d374f +++ /dev/null @@ -1 +0,0 @@ -{"address": "bb3e9561502ceaed131257765519876a250d374f", "crypto": {"cipher": "aes-128-ctr", "cipherparams": {"iv": "8f938c5f237179a436e3f09c5040c785"}, "ciphertext": "855faa703fde050654c683a4150696aa6281870073753ad532ea0fd24acb246e", "kdf": "scrypt", "kdfparams": {"dklen": 32, "n": 262144, "r": 1, "p": 8, "salt": "d86b25892d87cae731e74a5a4532f273"}, "mac": "af83a36f1657c8162124ce9d66870c03843746d253bceefba2ce52058bac6e18"}, "id": "6d53a23f-f7b6-4ddf-8bbc-c8568f6df7ed", "version": 3} \ No newline at end of file diff --git a/test/ethereum/resources/keystore/UTC--2022-04-05T19-21-59.864345000Z--726808f08d63adba50137132a18170de98326c98 b/test/ethereum/resources/keystore/UTC--2022-04-05T19-21-59.864345000Z--726808f08d63adba50137132a18170de98326c98 deleted file mode 100644 index 10f57500f..000000000 --- a/test/ethereum/resources/keystore/UTC--2022-04-05T19-21-59.864345000Z--726808f08d63adba50137132a18170de98326c98 +++ /dev/null @@ -1 +0,0 @@ -{"address": "726808f08d63adba50137132a18170de98326c98", "crypto": {"cipher": "aes-128-ctr", "cipherparams": {"iv": "c586136e60781d08c042a715340bbe4e"}, "ciphertext": "9fe8bfb7fa61913537ec3212bf31c0c24bb882ca2657afbcfe6ef36113267c51", "kdf": "scrypt", "kdfparams": {"dklen": 32, "n": 262144, "r": 1, "p": 8, "salt": "5da9b6264950b8111d3d26073ba1e555"}, "mac": "cc5c54add677960cb74264171265a610bd1df67f9014dd89ab2d8f07a07c21fb"}, "id": "ada1a9e8-6a43-4565-a3f5-352bca73b35e", "version": 3} \ No newline at end of file diff --git a/test/ethereum/resources/keystore/UTC--2022-04-05T19-22-01.348137000Z--1a5f6c239ceffb300cdba3031ba4ea5309e60380 b/test/ethereum/resources/keystore/UTC--2022-04-05T19-22-01.348137000Z--1a5f6c239ceffb300cdba3031ba4ea5309e60380 deleted file mode 100644 index 20ec1ef7f..000000000 --- a/test/ethereum/resources/keystore/UTC--2022-04-05T19-22-01.348137000Z--1a5f6c239ceffb300cdba3031ba4ea5309e60380 +++ /dev/null @@ -1 +0,0 @@ -{"address": "1a5f6c239ceffb300cdba3031ba4ea5309e60380", "crypto": {"cipher": "aes-128-ctr", "cipherparams": {"iv": "a09e72ccb8029a4ee93d7c70779a3f01"}, "ciphertext": "b34054f247d0de0585baa4207eabdb06b105e88e87116ead982cb6220f343ebb", "kdf": "scrypt", "kdfparams": {"dklen": 32, "n": 262144, "r": 1, "p": 8, "salt": "5f17db3fbcfe667e7295f0b56ad80acd"}, "mac": "1aa118e7ae4508f7a22c659f3aac8b5e417d4712c44dcddfebdb2a0683c1e3c0"}, "id": "22e8ac6a-1973-4eff-b1a1-1e41cf5c2bc3", "version": 3} \ No newline at end of file